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)