in aios/sql/iquan/java/iquan_core/src/main/java/com/taobao/search/iquan/core/rel/plan/PlanWriteUtils.java [541:667]
private static Object innerFormatExprImpl(RexNode rexNode, List<RexNode> exprs, RelDataType rowType, boolean judgeFuncProperty) {
if (rexNode == null || rowType == null) {
return null;
}
if (rexNode instanceof RexLocalRef) {
RexLocalRef localRef = (RexLocalRef) rexNode;
if (exprs == null || localRef.getIndex() >= exprs.size()) {
throw new PlanWriteException("RexLocalRef index greater than exprs size");
}
RexNode newRexNode = exprs.get(localRef.getIndex());
return innerFormatExprImpl(newRexNode, exprs, rowType, judgeFuncProperty);
} else if (rexNode instanceof RexCall) {
RexCall call = (RexCall) rexNode;
SqlOperator operator = call.getOperator();
if (judgeFuncProperty && operator instanceof ScalarFunction) {
int idx = getConstIdxInUDF((ScalarFunction) operator);
if (idx >= 0) {
return innerFormatExprImpl(call.getOperands().get(idx), exprs, rowType, judgeFuncProperty);
}
}
String opName = operator.getName();
String opKind = operator.getKind().name();
Map<String, Object> attrMap = new TreeMap<>();
attrMap.put(ConstantDefine.OP, opName.isEmpty() ? opKind : opName);
attrMap.put(ConstantDefine.TYPE, formatSqlOperator(operator));
if (rexNode instanceof Match.RexMRAggCall) {
attrMap.put(ConstantDefine.ORDINAL, ((Match.RexMRAggCall) rexNode).ordinal);
}
if (opName.equals(ConstantDefine.CAST)) {
attrMap.put(ConstantDefine.CAST_TYPE, formatRelDataType(call.getType()));
}
List<Object> params = new ArrayList<>();
for (RexNode operand : call.getOperands()) {
params.add(innerFormatExprImpl(operand, exprs, rowType, judgeFuncProperty));
}
attrMap.put(ConstantDefine.PARAMS, params);
return attrMap;
} else if (rexNode instanceof RexInputRef) {
RexInputRef input = (RexInputRef) rexNode;
int index = input.getIndex();
String alpha = "";
if (rexNode instanceof RexPatternFieldRef) {
alpha = ((RexPatternFieldRef) rexNode).getAlpha();
}
String fieldName = PlanWriteUtils.formatFieldName(rowType.getFieldList().get(index).getName());
if (alpha.isEmpty()) {
return fieldName;
} else {
return alpha + ConstantDefine.DOT + fieldName;
}
} else if (rexNode instanceof RexFieldAccess) {
RexFieldAccess access = (RexFieldAccess) rexNode;
RelDataTypeField field = access.getField();
RexNode refExpr = access.getReferenceExpr();
Map<String, Object> attrMap = new TreeMap<>();
attrMap.put(ConstantDefine.OP, ConstantDefine.REX_ACCESS_FIELD);
attrMap.put(ConstantDefine.TYPE, ConstantDefine.OTHER);
attrMap.put(ConstantDefine.FIELD_NAME, field.getName());
attrMap.put(ConstantDefine.FIELD_TYPE, formatRelDataType(field.getType()));
if (refExpr instanceof RexLocalRef) {
List<Object> params = new ArrayList<>(1);
params.add(innerFormatExprImpl(refExpr, exprs, rowType, judgeFuncProperty));
List<String> paramTypes = new ArrayList<>(1);
paramTypes.add(formatRelDataType(refExpr.getType()));
attrMap.put(ConstantDefine.PARAMS, params);
attrMap.put(ConstantDefine.PARAM_TYPES, paramTypes);
} else if (refExpr instanceof RexVariable) {
List<String> params = new ArrayList<>(1);
params.add(((RexVariable) refExpr).getName());
List<String> paramTypes = new ArrayList<>(1);
paramTypes.add(formatRelDataType(refExpr.getType()));
attrMap.put(ConstantDefine.PARAMS, params);
attrMap.put(ConstantDefine.PARAM_TYPES, paramTypes);
}
return attrMap;
} else if (rexNode instanceof RexLiteral) {
RexLiteral literal = (RexLiteral) rexNode;
SqlTypeName fromType = literal.getTypeName();
SqlTypeName toType = literal.getType().getSqlTypeName();
if ((fromType == SqlTypeName.DECIMAL && toType == SqlTypeName.INTEGER)
|| (fromType == SqlTypeName.DECIMAL && toType == SqlTypeName.DOUBLE)
|| (fromType == SqlTypeName.DECIMAL && toType == SqlTypeName.FLOAT)
|| (fromType == SqlTypeName.DECIMAL && toType == SqlTypeName.BIGINT)
|| (fromType == SqlTypeName.CHAR && toType == SqlTypeName.VARCHAR)
|| (fromType == toType)) {
if (literal.getValue4() instanceof NlsString) {
return ((NlsString) literal.getValue4()).getValue();
} else {
return literal.getValue4();
}
}
Map<String, Object> attrMap = new TreeMap<>();
attrMap.put(ConstantDefine.OP, ConstantDefine.CAST);
attrMap.put(ConstantDefine.TYPE, FunctionType.FT_UDF.getName());
attrMap.put(ConstantDefine.CAST_TYPE, formatRelDataType(literal.getType()));
List<Object> params = new ArrayList<>();
if (literal.getValue4() instanceof NlsString) {
params.add(((NlsString) literal.getValue4()).getValue());
} else {
params.add(literal.getValue4());
}
attrMap.put(ConstantDefine.PARAMS, params);
return attrMap;
} else if (rexNode instanceof RexDynamicParam) {
RexDynamicParam dynamicParam = (RexDynamicParam) rexNode;
FieldType fieldType = IquanTypeFactory.createFieldType(dynamicParam.getType().getSqlTypeName());
if (!fieldType.isValid()) {
throw new PlanWriteException("Dynamic params does not support this type: "
+ dynamicParam.getType().getSqlTypeName());
}
return ConstantDefine.DYNAMIC_PARAMS_PREFIX
+ dynamicParam.getName()
+ ConstantDefine.DYNAMIC_PARAMS_SEPARATOR
+ fieldType.getName()
+ ConstantDefine.DYNAMIC_PARAMS_SUFFIX;
} else if (rexNode instanceof RexRangeRef) {
RexRangeRef ref = (RexRangeRef) rexNode;
return formatTable(ref);
} else {
throw new PlanWriteException("Expression does not support this type: " + rexNode.getClass().getSimpleName());
}
}