private static void getExprHashValues()

in aios/sql/iquan/java/iquan_core/src/main/java/com/taobao/search/iquan/core/rel/plan/PlanWriteUtils.java [978:1072]


    private static void getExprHashValues(RexNode rexNode, List<RexNode> exprList, RelDataType rowType, Set<String> hashFields,
                                          Map<String, Set<String>> hashValuesMap, Map<String, String> hashValuesSepMap, int level) {
        if (rexNode == null || rowType == null || level >= 2) {
            return;
        }

        if (rexNode instanceof RexLocalRef) {
            RexLocalRef localRef = (RexLocalRef) rexNode;
            if (exprList == null || localRef.getIndex() >= exprList.size()) {
                throw new PlanWriteException("RexLocalRef index greater than exprs size");
            }
            RexNode newRexNode = exprList.get(localRef.getIndex());
            getExprHashValues(newRexNode, exprList, rowType, hashFields, hashValuesMap, hashValuesSepMap, level);
            return;
        }

        if (!(rexNode instanceof RexCall)) {
            return;
        }

        RexCall call = (RexCall) rexNode;
        SqlOperator operator = call.getOperator();
        String opName = operator.getName();
        opName = opName.isEmpty() ? operator.getKind().name().toUpperCase() : opName.toUpperCase();

        if (level < 1 && opName.equals(ConstantDefine.AND)) {
            List<RexNode> operands = call.getOperands();
            for (RexNode operand : operands) {
                getExprHashValues(operand, exprList, rowType, hashFields, hashValuesMap, hashValuesSepMap, level + 1);
            }
            return;
        }

        if (opName.equals(ConstantDefine.EQUAL) || opName.equals(ConstantDefine.IN)) {
            List<RexNode> operands = call.getOperands();
            assert operands.size() >= 2;

            String fieldName = getFieldName(operands.get(0), exprList, rowType);
            if (fieldName == null || fieldName.isEmpty() || !hashFields.contains(fieldName)) {
                return;
            }
            String newFieldName = formatFieldName(fieldName);
            if (hashValuesMap.containsKey(newFieldName)) {
                return;
            }

            Set<String> values = new TreeSet<>();
            for (int i = 1; i < operands.size(); ++i) {
                RexNode operand = operands.get(i);
                String value = getFieldValue(operand, exprList);
                if (value == null || value.isEmpty()) {
                    continue;
                }
                values.add(value);
            }
            hashValuesMap.put(newFieldName, values);
            return;
        }

        if (opName.equals(ConstantDefine.CONTAIN)
                || opName.equals(ConstantDefine.CONTAIN2)
                || opName.equals(ConstantDefine.HA_IN)) {
            List<RexNode> operands = call.getOperands();
            if (operands.size() < 2 || operands.size() > 3) {
                throw new PlanWriteException(String.format("Operator %s params num %d is not support", opName, operands.size()));
            }

            String fieldName = getFieldName(operands.get(0), exprList, rowType);
            if (fieldName == null || fieldName.isEmpty() || !hashFields.contains(fieldName)) {
                return;
            }
            String newFieldName = formatFieldName(fieldName);
            if (hashValuesMap.containsKey(newFieldName)) {
                return;
            }

            String value = getFieldValue(operands.get(1), exprList);
            if (StringUtils.isEmpty(value)) {
                return;
            }
            Set<String> values = new TreeSet<>();
            values.add(value);

            String separator = null;
            if (operands.size() >= 3) {
                separator = getFieldValue(operands.get(2), exprList);
            }
            if (separator == null || separator.isEmpty()) {
                separator = ConstantDefine.VERTICAL_LINE;
            }
            hashValuesMap.put(newFieldName, values);
            hashValuesSepMap.put(newFieldName, separator);
            return;
        }
    }