Axis created CALCITE-3628: ----------------------------- Summary: OOB when using CallCopyingArgHandler to copy sql nodes with hint Key: CALCITE-3628 URL: https://issues.apache.org/jira/browse/CALCITE-3628 Project: Calcite Issue Type: Bug Components: core Affects Versions: 1.22.0 Reporter: Axis Fix For: 1.22.0
Hello, When we use the CallCopyingArgHandler to copy the sql node tree, we will get OOB. {code:java} java.lang.ArrayIndexOutOfBoundsException: 10 at org.apache.calcite.sql.SqlSelectOperator.createCall ...{code} I find calcite has been supported SqlHint in commit (bf40ad33e7ee85ff426ddc493fe6d9a5bfe6a208). And the function createCall in SqlSelect has been changed: {code:java} public class SqlSelectOperator extends SqlOperator { public static final SqlSelectOperator INSTANCE = new SqlSelectOperator(); //~ Constructors ----------------------------------------------------------- private SqlSelectOperator() { super("SELECT", SqlKind.SELECT, 2, true, ReturnTypes.SCOPE, null, null); } //~ Methods ---------------------------------------------------------------- public SqlSyntax getSyntax() { return SqlSyntax.SPECIAL; } public SqlCall createCall( SqlLiteral functionQualifier, SqlParserPos pos, SqlNode... operands) { assert functionQualifier == null; return new SqlSelect(pos, (SqlNodeList) operands[0], (SqlNodeList) operands[1], operands[2], operands[3], (SqlNodeList) operands[4], operands[5], (SqlNodeList) operands[6], (SqlNodeList) operands[7], operands[8], operands[9], (SqlNodeList) operands[10]); --> Sql hints array } {code} operator[10] might be SqlHints array in SqlSelect. When developer wants to copy the sql node tree using CallCopyingArgHandler. It will call the follow the code: {code:java} protected class CallCopyingArgHandler implements ArgHandler<SqlNode> { boolean update; SqlNode[] clonedOperands; private final SqlCall call; private final boolean alwaysCopy; public CallCopyingArgHandler(SqlCall call, boolean alwaysCopy) { this.call = call; this.update = false; final List<SqlNode> operands = call.getOperandList(); ---> sqlSelect operators this.clonedOperands = operands.toArray(new SqlNode[0]); this.alwaysCopy = alwaysCopy; } public SqlNode result() { if (update || alwaysCopy) { return call.getOperator().createCall( call.getFunctionQuantifier(), call.getParserPosition(), clonedOperands); --> SqlSelect operstors } else { return call; } } {code} When the code invoke the "result" method, it will call the SqlSelect::createCall, and pass the call.getOperandList() as the dynamic params. But SqlSelect's operator only have 10 operators (not contain hints) -- This message was sent by Atlassian Jira (v8.3.4#803005)