[ 
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)

Reply via email to