You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Stamatis Zampetakis (Jira)" <ji...@apache.org> on 2022/02/21 13:19:00 UTC

[jira] [Commented] (CALCITE-5016) NPE: "variable $cor0 is not found", "Unable to implement EnumerableCorrelate" in nested ARRAY() query

    [ https://issues.apache.org/jira/browse/CALCITE-5016?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17495519#comment-17495519 ] 

Stamatis Zampetakis commented on CALCITE-5016:
----------------------------------------------

Hey [~gavinray] can you check if this is a duplicate of CALCITE-4188?

> NPE: "variable $cor0 is not found", "Unable to implement EnumerableCorrelate" in nested ARRAY() query
> -----------------------------------------------------------------------------------------------------
>
>                 Key: CALCITE-5016
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5016
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.30.0
>            Reporter: Gavin Ray
>            Priority: Major
>
> If you remove the WHERE clause in the inner part, it will run:
> {code:sql}
> -- Remove this where clause to fix the bug
> WHERE
>      "users"."house_id" = "houses"."id"
> {code}
> Here is a reproduction:
> {code:java}
> import org.apache.calcite.adapter.jdbc.JdbcSchema;
> import org.apache.calcite.jdbc.CalciteConnection;
> import org.apache.calcite.jdbc.Driver;
> import org.apache.calcite.rel.RelNode;
> import org.apache.calcite.schema.SchemaPlus;
> import org.apache.calcite.sql.SqlNode;
> import org.apache.calcite.sql.parser.SqlParseException;
> import org.apache.calcite.sql.parser.SqlParser;
> import org.apache.calcite.tools.*;
> import org.hsqldb.jdbc.JDBCDataSource;
> import java.sql.*;
> public class HouseUserTodoSchemaTest {
>     static String ddl = """
>             CREATE TABLE "houses" (
>                 "id" INTEGER NOT NULL,
>                 "address" VARCHAR(255) NOT NULL,
>             );
>             CREATE TABLE "users" (
>                 "id" INTEGER NOT NULL,
>                 "name" VARCHAR(255) NOT NULL,
>                 "house_id" INTEGER NOT NULL
>             );
>             CREATE TABLE "todos" (
>                 "id" INTEGER NOT NULL,
>                 "description" VARCHAR(255) NOT NULL,
>                 "user_id" INTEGER NOT NULL
>             );
>             """;
>     static String dml = """
>             INSERT INTO "houses" VALUES (1, '123 Main St');
>             INSERT INTO "houses" VALUES (2, '456 Ocean Ave');
>                             
>             INSERT INTO "users" VALUES (1, 'Alice', 1);
>             INSERT INTO "users" VALUES (2, 'Bob', 1);
>             INSERT INTO "users" VALUES (3, 'Carol', 2);
>                             
>             INSERT INTO "todos" VALUES (1, 'Buy milk', 1);
>             INSERT INTO "todos" VALUES (2, 'Buy eggs', 1);
>             INSERT INTO "todos" VALUES (3, 'Buy bread', 2);
>             INSERT INTO "todos" VALUES (4, 'Vacuum', 3);
>             """;
>     static String query = """
>                 SELECT
>                 "houses"."id",
>                 "houses"."address",
>                 ARRAY(
>                     SELECT
>                         "users"."id",
>                         "users"."name",
>                         ARRAY(
>                             SELECT
>                                 "todos"."id",
>                                 "todos"."description"
>                             FROM
>                                 "todos"
>                             WHERE
>                                 "todos"."user_id" = "users"."id"
>                         ) AS "todos"
>                     FROM
>                         "users"
>                     -- Remove this where clause to fix the bug
>                     WHERE
>                         "users"."house_id" = "houses"."id"
>                 ) AS "users"
>             FROM
>                 "houses"
>             """;
>     public static void main(String[] args) throws SqlParseException, ValidationException, RelConversionException, ClassNotFoundException, SQLException {
>         JDBCDataSource hsqldb = new org.hsqldb.jdbc.JDBCDataSource();
>         hsqldb.setDatabase("jdbc:hsqldb:mem:house_user_todo");
>         try (Connection connection = hsqldb.getConnection()) {
>             try (Statement statement = connection.createStatement()) {
>                 statement.execute(ddl);
>                 statement.execute(dml);
>             }
>         }
>         SchemaPlus rootSchema = Frameworks.createRootSchema(false);
>         rootSchema.add("house_user_todo", JdbcSchema.create(rootSchema, "house_user_todo", hsqldb, null, null));
>         FrameworkConfig config = Frameworks.newConfigBuilder()
>                 .parserConfig(SqlParser.config().withCaseSensitive(false))
>                 .defaultSchema(rootSchema.getSubSchema("house_user_todo"))
>                 .build();
>         Planner planner = Frameworks.getPlanner(config);
>         SqlNode sqlNode = planner.parse(query);
>         SqlNode validated = planner.validate(sqlNode);
>         RelNode relNode = planner.rel(validated).project();
>         Class.forName(Driver.class.getName());
>         Connection connection = DriverManager.getConnection(Driver.CONNECT_STRING_PREFIX);
>         CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
>         RelRunner runner = calciteConnection.unwrap(RelRunner.class);
>         try (PreparedStatement ps = runner.prepareStatement(relNode)) {
>             ResultSet rs = ps.executeQuery();
>             while (rs.next()) {
>                 ResultSetMetaData md = rs.getMetaData();
>                 for (int i = 1; i <= md.getColumnCount(); i++) {
>                     System.out.print(md.getColumnName(i) + ": ");
>                     System.out.println(rs.getObject(i));
>                 }
>                 System.out.println();
>             }
>         }
>     }
> }
> {code}
> And the stack trace:
> {code:java}
> Exception in thread "main" java.sql.SQLException: Error while preparing plan [LogicalProject(id=[$0], address=[$1], users=[$2])
>   LogicalCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{0}])
>     JdbcTableScan(table=[[house_user_todo, houses]])
>     Collect(field=[EXPR$0])
>       LogicalProject(id=[$0], name=[$1], todos=[$3])
>         LogicalCorrelate(correlation=[$cor1], joinType=[inner], requiredColumns=[{0}])
>           LogicalFilter(condition=[=($2, $cor0.id)])
>             JdbcTableScan(table=[[house_user_todo, users]])
>           Collect(field=[EXPR$0])
>             LogicalProject(id=[$0], description=[$1])
>               LogicalFilter(condition=[=($2, $cor1.id)])
>                 JdbcTableScan(table=[[house_user_todo, todos]])
> ]
> 	at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
> 	at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
> 	at org.apache.calcite.jdbc.CalciteConnectionImpl.prepareStatement_(CalciteConnectionImpl.java:239)
> 	at org.apache.calcite.jdbc.CalciteConnectionImpl.access$100(CalciteConnectionImpl.java:101)
> 	at org.apache.calcite.jdbc.CalciteConnectionImpl$2.prepareStatement(CalciteConnectionImpl.java:188)
> 	at com.example.HouseUserTodoSchemaTest.main(HouseUserTodoSchemaTest.java:105)
> Caused by: java.lang.IllegalStateException: Unable to implement EnumerableCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{0}]): rowcount = 22500.0, cumulative cost = {318610.0 rows, 562611.0 cpu, 0.0 io}, id = 252
> Caused by: java.lang.IllegalStateException: Unable to implement EnumerableCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{0}]): rowcount = 22500.0, cumulative cost = {318610.0 rows, 562611.0 cpu, 0.0 io}, id = 252
>   JdbcToEnumerableConverter: rowcount = 100.0, cumulative cost = {110.0 rows, 111.0 cpu, 0.0 io}, id = 230
>     JdbcTableScan(table=[[house_user_todo, houses]]): rowcount = 100.0, cumulative cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 15
>   EnumerableCollect(field=[EXPR$0]): rowcount = 225.0, cumulative cost = {2959.0 rows, 5625.0 cpu, 0.0 io}, id = 250
>     EnumerableCalc(expr#0..3=[{inputs}], proj#0..1=[{exprs}], todos=[$t3]): rowcount = 225.0, cumulative cost = {2734.0 rows, 5400.0 cpu, 0.0 io}, id = 254
>       EnumerableCorrelate(correlation=[$cor1], joinType=[inner], requiredColumns=[{0}]): rowcount = 225.0, cumulative cost = {2509.0 rows, 3825.0 cpu, 0.0 io}, id = 246
>         JdbcToEnumerableConverter: rowcount = 15.0, cumulative cost = {116.5 rows, 202.5 cpu, 0.0 io}, id = 235
>           JdbcFilter(condition=[=($2, $cor0.id)]): rowcount = 15.0, cumulative cost = {115.0 rows, 201.0 cpu, 0.0 io}, id = 233
>             JdbcTableScan(table=[[house_user_todo, users]]): rowcount = 100.0, cumulative cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 16
>         EnumerableCollect(field=[EXPR$0]): rowcount = 15.0, cumulative cost = {143.5 rows, 241.5 cpu, 0.0 io}, id = 244
>           JdbcToEnumerableConverter: rowcount = 15.0, cumulative cost = {128.5 rows, 226.5 cpu, 0.0 io}, id = 242
>             JdbcProject(id=[$0], description=[$1]): rowcount = 15.0, cumulative cost = {127.0 rows, 225.0 cpu, 0.0 io}, id = 240
>               JdbcFilter(condition=[=($2, $cor1.id)]): rowcount = 15.0, cumulative cost = {115.0 rows, 201.0 cpu, 0.0 io}, id = 238
>                 JdbcTableScan(table=[[house_user_todo, todos]]): rowcount = 100.0, cumulative cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 18
> 	at org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.implementRoot(EnumerableRelImplementor.java:114)
> 	at org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:114)
> 	at org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.implement(CalcitePrepareImpl.java:1130)
> 	at org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.prepare_(CalcitePrepareImpl.java:1032)
> 	at org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.prepareRel(CalcitePrepareImpl.java:988)
> 	at org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:668)
> 	at org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:513)
> 	at org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:483)
> 	at org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:249)
> 	at org.apache.calcite.jdbc.CalciteConnectionImpl.prepareStatement_(CalciteConnectionImpl.java:229)
> 	... 3 more
> 	Suppressed: java.lang.NullPointerException: variable $cor0 is not found
> 		at java.base/java.util.Objects.requireNonNull(Objects.java:334)
> 		at org.apache.calcite.rel.rel2sql.SqlImplementor$BaseContext.getAliasContext(SqlImplementor.java:1429)
> 		at org.apache.calcite.rel.rel2sql.SqlImplementor$Context.toSql(SqlImplementor.java:628)
> 		at org.apache.calcite.rel.rel2sql.SqlImplementor$Context.toSql(SqlImplementor.java:1069)
> 		at org.apache.calcite.rel.rel2sql.SqlImplementor$Context.callToSql(SqlImplementor.java:776)
> 		at org.apache.calcite.rel.rel2sql.SqlImplementor$Context.toSql(SqlImplementor.java:750)
> 		at org.apache.calcite.rel.rel2sql.RelToSqlConverter.visit(RelToSqlConverter.java:427)
> 		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
> 		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 		at java.base/java.lang.reflect.Method.invoke(Method.java:568)
> 		at org.apache.calcite.util.ReflectUtil$2.invoke(ReflectUtil.java:531)
> 		at org.apache.calcite.rel.rel2sql.RelToSqlConverter.dispatch(RelToSqlConverter.java:139)
> 		at org.apache.calcite.rel.rel2sql.RelToSqlConverter.visitInput(RelToSqlConverter.java:147)
> 		at org.apache.calcite.rel.rel2sql.SqlImplementor.visitInput(SqlImplementor.java:201)
> 		at org.apache.calcite.rel.rel2sql.SqlImplementor.visitInput(SqlImplementor.java:189)
> 		at org.apache.calcite.adapter.jdbc.JdbcToEnumerableConverter.generateSql(JdbcToEnumerableConverter.java:351)
> 		at org.apache.calcite.adapter.jdbc.JdbcToEnumerableConverter.implement(JdbcToEnumerableConverter.java:107)
> 		at org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:104)
> 		at org.apache.calcite.adapter.enumerable.EnumerableCorrelate.implement(EnumerableCorrelate.java:113)
> 		at org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:104)
> 		at org.apache.calcite.adapter.enumerable.EnumerableCalc.implement(EnumerableCalc.java:118)
> 		at org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:104)
> 		at org.apache.calcite.adapter.enumerable.EnumerableCollect.implement(EnumerableCollect.java:81)
> 		at org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:104)
> 		at org.apache.calcite.adapter.enumerable.EnumerableCorrelate.implement(EnumerableCorrelate.java:139)
> 		at org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.implementRoot(EnumerableRelImplementor.java:111)
> 		... 12 more
> {code}



--
This message was sent by Atlassian Jira
(v8.20.1#820001)