Uploaded image for project: 'Calcite'
  1. Calcite
  2. CALCITE-3628

OOB when using CallCopyingArgHandler to copy sql nodes with hint

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 1.22.0
    • Fix Version/s: 1.22.0
    • Component/s: core
    • Labels:
      None

      Description

      Hello, 

          When we use the CallCopyingArgHandler to copy the sql node tree, we will get OOB.

      java.lang.ArrayIndexOutOfBoundsException: 10
                at org.apache.calcite.sql.SqlSelectOperator.createCall
                ...

       

      I find calcite has been supported SqlHint in commit (bf40ad33e7ee85ff426ddc493fe6d9a5bfe6a208).

      And the function createCall in SqlSelect has been changed:

      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
        } 

      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:

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

       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)

       

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              Axis Axis
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: