Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Duplicate
-
None
-
None
-
None
Description
I register a table "users" with a single column, age. And try to insert two columns into the "users".
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);
Apparently, I want to see some error message like:
Number of INSERT target columns (1) does not equal number of source items (2)
But actually, I got message:
org.apache.calcite.tools.ValidationException: java.lang.IndexOutOfBoundsException: index (1) must be less than size (1)
which was confused.
Then I debug the code in SqlValidatorImpl#validateSelectList method.
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); } }
See the exception is throw from here, if selectItems's size more than targetRowType's field count
&& targetRowType.getFieldCount() >= i ? targetRowType.getFieldList().get(i).getType()
When I change it to this, I get what I need.
&& targetRowType.getFieldCount() - 1 >= i ? targetRowType.getFieldList().get(i).getType()
So is this a Bug ? Do we need fix it ?
Attachments
Attachments
Issue Links
- is duplicated by
-
CALCITE-3148 Validator throws IndexOutOfBoundsException for SqlInsert when source and sink have non-equal fields number
- Closed