[ https://issues.apache.org/jira/browse/CALCITE-2336?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16496548#comment-16496548 ]
yuqi commented on CALCITE-2336: ------------------------------- [~xu fei] I suggest you check column size in function `validateInsert `, for example, should check row column size of insert should not less than size of select. see the patch [^1.patch] and you will get error information as below: ```java org.apache.calcite.tools.ValidationException: java.lang.IllegalArgumentException: Insert column size(1) should not less than that of select column(2) at org.apache.calcite.prepare.PlannerImpl.validate(PlannerImpl.java:196) at com.netease.yuqi.calcatetest.TestTwo.main(TestTwo.java:46) Caused by: java.lang.IllegalArgumentException: Insert column size(1) should not less than that of select column(2) at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122) at org.apache.calcite.sql.validate.SqlValidatorImpl.validateSelect(SqlValidatorImpl.java:3188) at org.apache.calcite.sql.validate.SqlValidatorImpl.validateInsert(SqlValidatorImpl.java:4175) at org.apache.calcite.sql.SqlInsert.validate(SqlInsert.java:148) at org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:915) at org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:625) at org.apache.calcite.prepare.PlannerImpl.validate(PlannerImpl.java:194) ... 1 more ``` > 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 > Priority: Major > Attachments: 1.patch > > > 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)