[
https://issues.apache.org/jira/browse/CALCITE-2336?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16496143#comment-16496143
]
Fei Xu commented on CALCITE-2336:
---------------------------------
Well, would you please execute the following unit test in
org.apache.calcite.test.InterpreterTest to verify ?, I found the problem when I
use calcite in my own application. So I write a temporary test case.
{code:java}
@Test public void testIndexOutOfBoundsException() throws Exception {
rootSchema = Frameworks.createRootSchema(true);
rootSchema.add("USERS", new AbstractTable() {
@Override public RelDataType getRowType(final RelDataTypeFactory
typeFactory) {
RelDataTypeFactory.FieldInfoBuilder builder = typeFactory.builder();
// builder.add("name", new BasicSqlType(new RelDataTypeSystemImpl() {},
SqlTypeName.BIGINT));
builder.add("name", typeFactory.createSqlType(SqlTypeName.INTEGER));
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);
// RelNode convert = planner.rel(validate).rel;
// final Interpreter interpreter = new Interpreter(dataContext, convert);
// assertRows(interpreter, "[0]", "[10]", "[20]", "[30]");
}
{code}
> 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
>
> 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)