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;
}
}