You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Axis (Jira)" <ji...@apache.org> on 2019/12/24 10:21:00 UTC

[jira] [Updated] (CALCITE-3628) OOB when using CallCopyingArgHandler to copy sql nodes with hint

     [ https://issues.apache.org/jira/browse/CALCITE-3628?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Axis updated CALCITE-3628:
--------------------------
    Description: 
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)

 

  was:
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)

 


> 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
>            Priority: Major
>             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)