Pavel Gubin created CALCITE-2015:
------------------------------------
Summary: Planner generates incompatible plan
Key: CALCITE-2015
URL: https://issues.apache.org/jira/browse/CALCITE-2015
Project: Calcite
Issue Type: Bug
Components: core
Affects Versions: 1.14.0
Reporter: Pavel Gubin
Assignee: Julian Hyde
Rel tree was build using RelBuilder on foodmart dataset:
{code:java}
RelNode rel = b.scan("foodmart", "sales_fact_1998")
.scan("foodmart", "customer")
.join(JoinRelType.INNER, "customer_id")
.scan("foodmart", "store")
.join(JoinRelType.INNER, "store_id")
.filter(b.equals(b.field("coffee_bar"), b.literal(true)))
.project(
b.alias(b.field("lname"), "lastName"),
b.alias(b.field("store_name"), "storeName"),
b.alias(b.field("coffee_bar"), "coffeeBar"),
b.alias(b.field("unit_sales"), "unitSales")
)
.aggregate(b.groupKey(b.field("lastName"), b.field("storeName"),
b.field("coffeeBar")), b.sum(false, "unitSales",
b.field("unitSales")))
.build();
{code}
This tree is optimised to the following physical plan:
{noformat}
22:03:26.388 [main] DEBUG org.apache.calcite.prepare.Prepare - Plan after
physical tweaks: EnumerableAggregate(group=[{1, 6, 7}], unitSales=[$SUM0($4)]):
rowcount = 337.5, cumulative cost = {4466.6875 rows, 839.0 cpu, 0.0 io}, id =
11032
JdbcJoin(condition=[=($2, $0)], joinType=[inner]): rowcount = 3375.0,
cumulative cost = {4087.0 rows, 839.0 cpu, 0.0 io}, id = 11030
JdbcProject(customer_id=[$0], lname=[$2]): rowcount = 100.0, cumulative
cost = {180.0 rows, 261.0 cpu, 0.0 io}, id = 11018
JdbcTableScan(table=[[foodmart, customer]]): rowcount = 100.0, cumulative
cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 1
JdbcJoin(condition=[=($1, $3)], joinType=[inner]): rowcount = 225.0,
cumulative cost = {532.0 rows, 578.0 cpu, 0.0 io}, id = 11028
JdbcProject(customer_id=[$2], store_id=[$4], unit_sales=[$7]): rowcount =
100.0, cumulative cost = {180.0 rows, 341.0 cpu, 0.0 io}, id = 11021
JdbcTableScan(table=[[foodmart, sales_fact_1998]]): rowcount = 100.0,
cumulative cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 0
JdbcProject(store_id=[$0], store_name=[$3], coffee_bar=[$19]): rowcount =
15.0, cumulative cost = {127.0 rows, 237.0 cpu, 0.0 io}, id = 11026
JdbcFilter(condition=[=($19, true)]): rowcount = 15.0, cumulative cost
= {115.0 rows, 201.0 cpu, 0.0 io}, id = 11024
JdbcTableScan(table=[[foodmart, store]]): rowcount = 100.0,
cumulative cost = {100.0 rows, 101.0 cpu, 0.0 io}, id = 3
{noformat}
Which fails on execution:
{noformat}
Exception in thread "main" java.lang.RuntimeException: java.sql.SQLException:
Error while preparing statement [null]
at
org.apache.calcite.jdbc.CalciteConnectionImpl$1.prepare(CalciteConnectionImpl.java:172)
at Main.main(Main.java:68)
Caused by: java.sql.SQLException: Error while preparing statement [null]
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:210)
at
org.apache.calcite.jdbc.CalciteConnectionImpl.access$100(CalciteConnectionImpl.java:89)
at
org.apache.calcite.jdbc.CalciteConnectionImpl$1.prepare(CalciteConnectionImpl.java:168)
... 1 more
Caused by: java.lang.ClassCastException:
org.apache.calcite.adapter.jdbc.JdbcRules$JdbcJoin cannot be cast to
org.apache.calcite.adapter.enumerable.EnumerableRel
at
org.apache.calcite.adapter.enumerable.EnumerableAggregate.implement(EnumerableAggregate.java:105)
at
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.implementRoot(EnumerableRelImplementor.java:108)
at
org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:92)
at
org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.implement(CalcitePrepareImpl.java:1262)
at
org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.prepare_(CalcitePrepareImpl.java:1163)
at
org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.prepareRel(CalcitePrepareImpl.java:1113)
at
org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:807)
at
org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:640)
at
org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:610)
at
org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:221)
at
org.apache.calcite.jdbc.CalciteConnectionImpl.prepareStatement_(CalciteConnectionImpl.java:203)
... 3 more
{noformat}
It turns out that optimiser selects plan that cannot be executed because
{{EnumerableAggregate}} requires child to be {{EnumerableRel}}. Looking into
the optimiser output this plan actually the best one in terms of cost and the
plan where aggregation is done in JDBC is not as good. That's probably the
second problem because I'd like aggregate to be run rather in the DB.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)