danny0405 commented on a change in pull request #1338: [CALCITE-3210] Fix the
bug that RelToSqlConverter converts "cast(null as $type)" just as null
URL: https://github.com/apache/calcite/pull/1338#discussion_r309006316
##########
File path:
core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
##########
@@ -195,15 +198,78 @@ public Result visit(Project e) {
final Builder builder =
x.builder(e, Clause.SELECT);
final List<SqlNode> selectList = new ArrayList<>();
+
+ final boolean checkNull = isCastNullNeeded(stack);
for (RexNode ref : e.getChildExps()) {
SqlNode sqlExpr = builder.context.toSql(null, ref);
+ if (checkNull && SqlUtil.isNullLiteral(sqlExpr, false)) {
+ sqlExpr = castNullType(sqlExpr,
e.getRowType().getFieldList().get(selectList.size()));
+ }
addSelect(selectList, sqlExpr, e.getRowType());
}
builder.setSelect(new SqlNodeList(selectList, POS));
return builder.result();
}
+ /**
+ * Returns whether a NULL literal in the SELECT clause needs to be wrapped
in a CAST.
+ * @param stack stack of visit
+ * @return If null needs to be casted then return true, otherwise return
false.
+ * There are several cases to handle :
+ * 1. If a Project is under a Join or other operator which not instance of
SingleRel,
+ * and there may be some SingleRel which is not Project between the
project and none SingleRel,
+ * NULL needs to be wrapped in a CAST.
+ * Here is an example,
+ * "SELECT * FROM (SELECT CAST(NULL AS INT) AS c1, c2 FROM t1) AS t1
+ * JOIN (SELECT c3, c4 FROM t2) AS t2 ON c2 = c3"
+ *
+ * 2. If a Project is under another Project,
+ * and there may be some SingleRel which is not Project between these two
Project,
+ * NULL needs to be wrapped in a CAST.
+ * Here is an example,
+ * "SELECT * FROM (SELECT CAST(NULL AS INT) AS c1, c2 FROM t1) as t1
WHERE c2 = 10"
+ *
+ * 3. If a Project is under a TableModify,
+ * and there may be some SingleRel which is not Project between the
Project and TableModify,
+ * because that the type of NULL can be inferred by the target table of
TableModify,
+ * so NULL does not need to be wrapped in a CAST.
+ * Here is an example,
+ * "INSERT INTO t SELECT CAST(NULL AS INT) AS c1, c2 FROM t1"
Review comment:
What do you mean by "SingleRel", i didn't see any in your example.
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services