Tartarus0zm commented on issue #1859:
URL: https://github.com/apache/auron/issues/1859#issuecomment-4181565860
@weiqingy Overall, LGTM
Here’s some POC code you can use as a reference.
- If we consider casting, we can determine the compatible types for the
input parameters in advance.
```java
public static RelDataType getCommonTypeForComparison(
RelDataType type1, RelDataType type2, RelDataTypeFactory
typeFactory) {
// 如果两者是相同的类型,直接返回
if (type1.getSqlTypeName().equals(type2.getSqlTypeName())) {
return type1;
}
// 使用 SqlTypeUtil 提供的共通类型判断
SqlTypeName typeName1 = type1.getSqlTypeName();
SqlTypeName typeName2 = type2.getSqlTypeName();
// 常用的提升逻辑,数字与浮点数结合为浮点数
if (SqlTypeUtil.isNumeric(type1) && SqlTypeUtil.isNumeric(type2)) {
if (typeName1 == SqlTypeName.DECIMAL || typeName2 ==
SqlTypeName.DECIMAL) {
return typeFactory.createSqlType(SqlTypeName.DECIMAL);
}
if ((typeName1 == SqlTypeName.BIGINT || typeName2 ==
SqlTypeName.BIGINT)
&& notApproxTypes(typeName1)
&& notApproxTypes(typeName2)) {
return typeFactory.createSqlType(SqlTypeName.BIGINT);
}
return typeFactory.createSqlType(SqlTypeName.DOUBLE);
}
// 处理其他类型的情况,例如字符类型
if (SqlTypeUtil.inCharFamily(type1) &&
SqlTypeUtil.inCharFamily(type2)) {
return typeFactory.createSqlType(SqlTypeName.VARCHAR);
}
// 可在此根据业务需要扩展
return null; // 如果不兼容,返回 null 或抛出异常
}
```
- Determine whether casting is required based on the type
```java
private static PhysicalExprNode castIfNecessary(RexNode expr,
RelDataType dataType, Schema nativeSchema)
throws Exception {
if
(dataType.getSqlTypeName().equals(expr.getType().getSqlTypeName())) {
return convertFlinkNodeToNativeExprNode(expr, nativeSchema);
}
return PhysicalExprNode.newBuilder()
.setTryCast(PhysicalTryCastNode.newBuilder()
.setExpr(convertFlinkNodeToNativeExprNode(expr,
nativeSchema))
.setArrowType(convertDataType(FlinkTypeFactory.toLogicalType(dataType)))
.build())
.build();
}
```
- Convert Flink's plus operation to Auron plus; other operations are similar.
```java
RexCall rexCall = (RexCall) rexNode;
SqlOperator sqlOperator = rexCall.getOperator();
if (sqlOperator == PLUS) {
// +
RelDataType outputType = rexCall.getType();
RelDataTypeFactory typeFactory = new
SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
RelDataType compatibleType = getCommonTypeForComparison(
rexCall.getOperands().get(0).getType(),
rexCall.getOperands().get(1).getType(),
typeFactory);
PhysicalExprNode plusNode = PhysicalExprNode.newBuilder()
.setBinaryExpr(PhysicalBinaryExprNode.newBuilder()
.setL(castIfNecessary(rexCall.getOperands().get(0), compatibleType,
nativeSchema))
.setR(castIfNecessary(rexCall.getOperands().get(1), compatibleType,
nativeSchema))
.setOp("Plus")
.build())
.build();
if
(!outputType.getSqlTypeName().equals(compatibleType.getSqlTypeName())) {
return PhysicalExprNode.newBuilder()
.setTryCast(PhysicalTryCastNode.newBuilder()
.setExpr(plusNode)
.setArrowType(convertDataType(FlinkTypeFactory.toLogicalType(outputType)))
.build())
.build();
}
return plusNode;
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]