You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Fei Xu (JIRA)" <ji...@apache.org> on 2018/05/30 08:41:00 UTC

[jira] [Created] (CALCITE-2336) SqlValidatorImpl throws java.lang.IndexOutOfBoundsException

Fei Xu created CALCITE-2336:
-------------------------------

             Summary: SqlValidatorImpl throws java.lang.IndexOutOfBoundsException
                 Key: CALCITE-2336
                 URL: https://issues.apache.org/jira/browse/CALCITE-2336
             Project: Calcite
          Issue Type: Bug
          Components: core
            Reporter: Fei Xu
            Assignee: Julian Hyde


I register a table "users" with a single column, age. And try to insert two columns into the "users".
{code:java}
    rootSchema = Frameworks.createRootSchema(true);
    rootSchema.add("USERS", new AbstractTable() {
      @Override public RelDataType getRowType(final RelDataTypeFactory typeFactory) {
        RelDataTypeFactory.FieldInfoBuilder builder = typeFactory.builder();
        builder.add("age", new BasicSqlType(new RelDataTypeSystemImpl() {}, SqlTypeName.CHAR));
        return builder.build();
      }
    });

    final FrameworkConfig config = Frameworks.newConfigBuilder()
        .parserConfig(SqlParser.Config.DEFAULT)
        .defaultSchema(rootSchema)
        .build();
    planner = Frameworks.getPlanner(config);
    dataContext = new MyDataContext(planner);

    SqlNode parse =
        planner.parse("insert into users select y, x\n"
            + "from (values (1, 'a'), (2, 'b'), (3, 'c')) as t(x, y)\n"
            + "where x > 1");

    SqlNode validate = planner.validate(parse);
{code}
Apparently, I want to see some error message like:
{code:java}
Number of INSERT target columns (1) does not equal number of source items (2)
{code}
But actually, I got message:
{code:java}
org.apache.calcite.tools.ValidationException: java.lang.IndexOutOfBoundsException: index (1) must be less than size (1)
{code}
which was confused.

Then I debug the code in SqlValidatorImpl#validateSelectList method.

 
{code:java}
protected RelDataType validateSelectList(
    final SqlNodeList selectItems,
    SqlSelect select,
    RelDataType targetRowType) {
  // First pass, ensure that aliases are unique. "*" and "TABLE.*" items
  // are ignored.

  // Validate SELECT list. Expand terms of the form "*" or "TABLE.*".
  final SqlValidatorScope selectScope = getSelectScope(select);
  final List<SqlNode> expandedSelectItems = new ArrayList<>();
  final Set<String> aliases = Sets.newHashSet();
  final List<Map.Entry<String, RelDataType>> fieldList = new ArrayList<>();

  for (int i = 0; i < selectItems.size(); i++) {
    SqlNode selectItem = selectItems.get(i);
    if (selectItem instanceof SqlSelect) {
      handleScalarSubQuery(
          select,
          (SqlSelect) selectItem,
          expandedSelectItems,
          aliases,
          fieldList);
    } else {
      expandSelectItem(
          selectItem,
          select,
          targetRowType.isStruct()
              && targetRowType.getFieldCount() >= i
              ? targetRowType.getFieldList().get(i).getType()
              : unknownType,
          expandedSelectItems,
          aliases,
          fieldList,
          false);
    }
  }
{code}
See the exception is throw from here, if selectItems's size more than targetRowType's field count
{code:java}
&& targetRowType.getFieldCount() >= i
? targetRowType.getFieldList().get(i).getType(){code}
When I change it to this, I get what I need.
{code:java}
&& targetRowType.getFieldCount() - 1 >= i  
? targetRowType.getFieldList().get(i).getType(){code}
So is this a Bug ? Do we need fix it ? 

 

 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)