You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2017/02/04 06:00:08 UTC
[2/2] phoenix git commit: PHOENIX-3309 Divide query planning into
multiple stages
PHOENIX-3309 Divide query planning into multiple stages
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/36a31bf9
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/36a31bf9
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/36a31bf9
Branch: refs/heads/calcite
Commit: 36a31bf904ea0f12dd6aa7e3ab5e89ef8af427c2
Parents: 229f4c7
Author: maryannxue <ma...@gmail.com>
Authored: Thu Feb 2 23:36:08 2017 -0800
Committer: maryannxue <ma...@gmail.com>
Committed: Fri Feb 3 21:59:55 2017 -0800
----------------------------------------------------------------------
.../apache/phoenix/calcite/CalciteDMLIT.java | 6 +-
.../phoenix/calcite/CalciteGlobalIndexIT.java | 10 +-
.../org/apache/phoenix/calcite/CalciteIT.java | 78 ++--
.../phoenix/calcite/CalciteLocalIndexIT.java | 14 +-
.../phoenix/calcite/PhoenixPrepareImpl.java | 61 +--
.../apache/phoenix/calcite/PhoenixPrograms.java | 370 +++++++++++++++++++
.../apache/phoenix/calcite/PhoenixTable.java | 12 +-
.../calcite/metadata/PhoenixRelMdCollation.java | 85 ++++-
.../metadata/PhoenixRelMdMaxRowCount.java | 32 ++
.../calcite/metadata/PhoenixRelMdRowCount.java | 4 +-
.../calcite/metadata/PhoenixRelMdSize.java | 49 ++-
.../metadata/PhoenixRelMetadataProvider.java | 3 +-
.../org/apache/phoenix/calcite/rel/Limit.java | 40 ++
.../phoenix/calcite/rel/LogicalLimit.java | 45 +++
.../calcite/rel/PhoenixClientProject.java | 4 +-
.../phoenix/calcite/rel/PhoenixLimit.java | 25 +-
.../calcite/rel/PhoenixServerProject.java | 4 +-
.../phoenix/calcite/rel/PhoenixTableScan.java | 21 ++
.../calcite/rel/PhoenixTemporarySort.java | 2 +-
.../calcite/rules/PhoenixConverterRules.java | 26 +-
.../rules/PhoenixForwardTableScanRule.java | 13 +-
...hoenixJoinSingleValueAggregateMergeRule.java | 11 +-
.../rules/PhoenixOrderedAggregateRule.java | 9 +-
.../rules/PhoenixReverseTableScanRule.java | 9 +-
.../PhoenixSortServerJoinTransposeRule.java | 18 +-
.../rules/ProjectLimitTransposeRule.java | 37 ++
.../calcite/rules/ProjectSortTransposeRule.java | 70 ++++
.../phoenix/calcite/rules/SortSplitRule.java | 40 ++
28 files changed, 902 insertions(+), 196 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java
index 6417ad2..116fa50 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java
@@ -36,7 +36,7 @@ public class CalciteDMLIT extends BaseCalciteIT {
public void testUpsertValues() throws Exception {
start(PROPS).sql("upsert into atable(organization_id, entity_id) values('1', '1')")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixTableModify(table=[[phoenix, ATABLE]], operation=[INSERT], updateColumnList=[[]], flattened=[false])\n" +
+ " PhoenixTableModify(table=[[phoenix, ATABLE]], operation=[INSERT], flattened=[false])\n" +
" PhoenixClientProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[null], B_STRING=[null], A_INTEGER=[null], A_DATE=[null], A_TIME=[null], A_TIMESTAMP=[null], X_DECIMAL=[null], X_LONG=[null], X_INTEGER=[null], Y_INTEGER=[null], A_BYTE=[null], A_SHORT=[null], A_FLOAT=[null], A_DOUBLE=[null], A_UNSIGNED_FLOAT=[null], A_UNSIGNED_DOUBLE=[null])\n" +
" PhoenixValues(tuples=[[{ '1 ', '1 ' }]])\n")
.executeUpdate()
@@ -106,7 +106,7 @@ public class CalciteDMLIT extends BaseCalciteIT {
@Test public void testDelete() throws Exception {
start(PROPS).sql("upsert into atable(organization_id, entity_id) values('1', '1')")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixTableModify(table=[[phoenix, ATABLE]], operation=[INSERT], updateColumnList=[[]], flattened=[false])\n" +
+ " PhoenixTableModify(table=[[phoenix, ATABLE]], operation=[INSERT], flattened=[false])\n" +
" PhoenixClientProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[null], B_STRING=[null], A_INTEGER=[null], A_DATE=[null], A_TIME=[null], A_TIMESTAMP=[null], X_DECIMAL=[null], X_LONG=[null], X_INTEGER=[null], Y_INTEGER=[null], A_BYTE=[null], A_SHORT=[null], A_FLOAT=[null], A_DOUBLE=[null], A_UNSIGNED_FLOAT=[null], A_UNSIGNED_DOUBLE=[null])\n" +
" PhoenixValues(tuples=[[{ '1 ', '1 ' }]])\n")
.executeUpdate()
@@ -116,7 +116,7 @@ public class CalciteDMLIT extends BaseCalciteIT {
.close();
start(PROPS).sql("delete from atable where organization_id = '1' and entity_id = '1'")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixTableModify(table=[[phoenix, ATABLE]], operation=[DELETE], updateColumnList=[[]], flattened=[false])\n" +
+ " PhoenixTableModify(table=[[phoenix, ATABLE]], operation=[DELETE], flattened=[false])\n" +
" PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[AND(=($0, CAST('1'):CHAR(15) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL), =($1, CAST('1'):CHAR(15) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL))])\n")
.executeUpdate()
.close();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
index 090f47f..d5a95ff 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
@@ -38,12 +38,12 @@ public class CalciteGlobalIndexIT extends BaseCalciteIndexIT {
.close();
start(true, 1000f).sql("select x_integer from aTable")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixServerProject(X_INTEGER=[$4])\n" +
+ " PhoenixServerProject(0:X_INTEGER=[$4])\n" +
" PhoenixTableScan(table=[[phoenix, IDX1]])\n")
.close();
start(true, 1000f).sql("select a_string from aTable order by a_string")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixServerProject(A_STRING=[$0])\n" +
+ " PhoenixServerProject(0:A_STRING=[$0])\n" +
" PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n")
.close();
start(true, 1000000f).sql("select a_string from aTable order by organization_id")
@@ -59,7 +59,7 @@ public class CalciteGlobalIndexIT extends BaseCalciteIndexIT {
.close();
start(true, 1000f).sql("select a_string, b_string from aTable where a_string = 'a'")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixServerProject(A_STRING=[$0], B_STRING=[$3])\n" +
+ " PhoenixServerProject(0:A_STRING=[$0], 0:B_STRING=[$3])\n" +
" PhoenixTableScan(table=[[phoenix, IDX1]], filter=[=($0, 'a')])\n")
.close();
start(true, 1000f).sql("select a_string, b_string from aTable where b_string = 'b'")
@@ -129,9 +129,9 @@ public class CalciteGlobalIndexIT extends BaseCalciteIndexIT {
{1, 2, 3, 4},
{2, 3, 4, 5}})
.close();
- start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " s1, " + SALTED_TABLE_NAME + " s2 where s1.mypk0 = s2.mypk0 and s1.mypk1 = s2.mypk1 and s1.mypk0 > 500 and s2.col1 < 505")
+ start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " s1, " + SALTED_TABLE_NAME + " s2 where s1.mypk1 = s2.mypk1 and s1.mypk0 > 500 and s2.col1 < 505")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixServerJoin(condition=[AND(=($0, $4), =($1, $5))], joinType=[inner])\n" +
+ " PhoenixServerJoin(condition=[=($1, $5)], joinType=[inner])\n" +
" PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[>($0, 500)])\n" +
" PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" +
" PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<(CAST($0):INTEGER, 505)])\n")
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
index a649c7e..c26e0b5 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java
@@ -282,13 +282,13 @@ public class CalciteIT extends BaseCalciteIT {
.close();
start(false, 1000f).sql("SELECT \"order_id\", i.name, i.price, discount2, quantity FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o LEFT JOIN "
- + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" limit 2 offset 1")
+ + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" limit 2")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(order_id=[$0], NAME=[$4], PRICE=[$5], DISCOUNT2=[$6], QUANTITY=[$2])\n" +
- " PhoenixLimit(offset=[1], fetch=[2])\n" +
+ " PhoenixLimit(fetch=[2])\n" +
+ " PhoenixClientProject(order_id=[$0], NAME=[$4], PRICE=[$5], DISCOUNT2=[$6], QUANTITY=[$2])\n" +
" PhoenixClientJoin(condition=[=($1, $3)], joinType=[left])\n" +
" PhoenixClientSort(sort0=[$1], dir0=[ASC])\n" +
- " PhoenixLimit(offset=[1], fetch=[2])\n" +
+ " PhoenixLimit(fetch=[2])\n" +
" PhoenixServerProject(order_id=[$0], item_id=[$2], QUANTITY=[$4])\n" +
" PhoenixTableScan(table=[[phoenix, Join, OrderTable]])\n" +
" PhoenixServerProject(item_id=[$0], NAME=[$1], PRICE=[$2], DISCOUNT2=[$4])\n" +
@@ -318,8 +318,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("select t1.entity_id, t2.a_string, t3.organization_id from aTable t1 join aTable t2 on t1.entity_id = t2.entity_id and t1.organization_id = t2.organization_id join atable t3 on t1.entity_id = t3.entity_id and t1.organization_id = t3.organization_id limit 8 offset 1")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(ENTITY_ID=[$1], A_STRING=[$6], ORGANIZATION_ID=[$2])\n" +
- " PhoenixLimit(offset=[1], fetch=[8])\n" +
+ " PhoenixLimit(offset=[1], fetch=[8])\n" +
+ " PhoenixClientProject(ENTITY_ID=[$1], A_STRING=[$6], ORGANIZATION_ID=[$2])\n" +
" PhoenixClientJoin(condition=[AND(=($1, $5), =($0, $4))], joinType=[inner])\n" +
" PhoenixClientJoin(condition=[AND(=($1, $3), =($0, $2))], joinType=[inner])\n" +
" PhoenixServerSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])\n" +
@@ -679,8 +679,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("select count(entity_id), a_string from atable group by a_string order by count(entity_id), a_string desc limit 2 offset 1")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
- " PhoenixLimit(offset=[1], fetch=[2])\n" +
+ " PhoenixLimit(offset=[1], fetch=[2])\n" +
+ " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
" PhoenixServerSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[DESC])\n" +
" PhoenixServerAggregate(group=[{2}], EXPR$0=[COUNT()], isOrdered=[false])\n" +
" PhoenixTableScan(table=[[phoenix, ATABLE]])\n")
@@ -707,8 +707,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("SELECT item.\"item_id\", item.name, supp.\"supplier_id\", supp.name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " item JOIN " + JOIN_SUPPLIER_TABLE_FULL_NAME + " supp ON item.\"supplier_id\" = supp.\"supplier_id\" order by item.name desc limit 3")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
- " PhoenixLimit(fetch=[3])\n" +
+ " PhoenixLimit(fetch=[3])\n" +
+ " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
" PhoenixServerSort(sort0=[$1], dir0=[DESC])\n" +
" PhoenixServerJoin(condition=[=($2, $3)], joinType=[inner])\n" +
" PhoenixServerProject(item_id=[$0], NAME=[$1], supplier_id=[$5])\n" +
@@ -742,8 +742,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("select count(entity_id), a_string from atable group by a_string limit 2")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
- " PhoenixLimit(fetch=[2])\n" +
+ " PhoenixLimit(fetch=[2])\n" +
+ " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
" PhoenixServerAggregate(group=[{2}], EXPR$0=[COUNT()], isOrdered=[false])\n" +
" PhoenixTableScan(table=[[phoenix, ATABLE]])\n")
.resultIsSomeOf(2, new Object[][] {
@@ -770,8 +770,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("SELECT item.\"item_id\", item.name, supp.\"supplier_id\", supp.name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " item JOIN " + JOIN_SUPPLIER_TABLE_FULL_NAME + " supp ON item.\"supplier_id\" = supp.\"supplier_id\" limit 3")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
- " PhoenixLimit(fetch=[3])\n" +
+ " PhoenixLimit(fetch=[3])\n" +
+ " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
" PhoenixServerJoin(condition=[=($2, $3)], joinType=[inner])\n" +
" PhoenixServerProject(item_id=[$0], NAME=[$1], supplier_id=[$5])\n" +
" PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n" +
@@ -788,8 +788,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("SELECT x from (values (1, 2), (2, 4), (3, 6)) as t(x, y) limit 2")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(X=[$0])\n" +
- " PhoenixLimit(fetch=[2])\n" +
+ " PhoenixLimit(fetch=[2])\n" +
+ " PhoenixClientProject(X=[$0])\n" +
" PhoenixValues(tuples=[[{ 1, 2 }, { 2, 4 }, { 3, 6 }]])\n")
.resultIsSomeOf(2, new Object[][] {{1}, {2}, {3}})
.close();
@@ -822,8 +822,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("select count(entity_id), a_string from atable group by a_string limit 2 offset 0")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
- " PhoenixLimit(fetch=[2])\n" +
+ " PhoenixLimit(fetch=[2])\n" +
+ " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
" PhoenixServerAggregate(group=[{2}], EXPR$0=[COUNT()], isOrdered=[false])\n" +
" PhoenixTableScan(table=[[phoenix, ATABLE]])\n")
.resultIsSomeOf(2, new Object[][] {
@@ -834,8 +834,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("SELECT item.\"item_id\", item.name, supp.\"supplier_id\", supp.name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " item JOIN " + JOIN_SUPPLIER_TABLE_FULL_NAME + " supp ON item.\"supplier_id\" = supp.\"supplier_id\" limit 3 offset 3")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
- " PhoenixLimit(offset=[3], fetch=[3])\n" +
+ " PhoenixLimit(offset=[3], fetch=[3])\n" +
+ " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
" PhoenixServerJoin(condition=[=($2, $3)], joinType=[inner])\n" +
" PhoenixServerProject(item_id=[$0], NAME=[$1], supplier_id=[$5])\n" +
" PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n" +
@@ -852,16 +852,16 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("SELECT x from (values (1, 2), (2, 4), (3, 6)) as t(x, y) limit 2 offset 2")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(X=[$0])\n" +
- " PhoenixLimit(offset=[2], fetch=[2])\n" +
+ " PhoenixLimit(offset=[2], fetch=[2])\n" +
+ " PhoenixClientProject(X=[$0])\n" +
" PhoenixValues(tuples=[[{ 1, 2 }, { 2, 4 }, { 3, 6 }]])\n")
.resultIs(new Object[][] {{3}})
.close();
start(false, 1000f).sql("SELECT x from (values (1, 2), (2, 4), (3, 6)) as t(x, y) limit 3 offset 4")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(X=[$0])\n" +
- " PhoenixLimit(offset=[4], fetch=[3])\n" +
+ " PhoenixLimit(offset=[4], fetch=[3])\n" +
+ " PhoenixClientProject(X=[$0])\n" +
" PhoenixValues(tuples=[[{ 1, 2 }, { 2, 4 }, { 3, 6 }]])\n")
.resultIs(new Object[][] {})
.close();
@@ -931,8 +931,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("select count(entity_id), a_string from atable group by a_string offset 1")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
- " PhoenixLimit(offset=[1])\n" +
+ " PhoenixLimit(offset=[1])\n" +
+ " PhoenixClientProject(EXPR$0=[$1], A_STRING=[$0])\n" +
" PhoenixServerAggregate(group=[{2}], EXPR$0=[COUNT()], isOrdered=[false])\n" +
" PhoenixTableScan(table=[[phoenix, ATABLE]])\n")
.resultIsSomeOf(2, new Object[][] {
@@ -943,8 +943,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("SELECT item.\"item_id\", item.name, supp.\"supplier_id\", supp.name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " item JOIN " + JOIN_SUPPLIER_TABLE_FULL_NAME + " supp ON item.\"supplier_id\" = supp.\"supplier_id\" offset 7")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
- " PhoenixLimit(offset=[7])\n" +
+ " PhoenixLimit(offset=[7])\n" +
+ " PhoenixClientProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" +
" PhoenixServerJoin(condition=[=($2, $3)], joinType=[inner])\n" +
" PhoenixServerProject(item_id=[$0], NAME=[$1], supplier_id=[$5])\n" +
" PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n" +
@@ -962,8 +962,8 @@ public class CalciteIT extends BaseCalciteIT {
start(false, 1000f).sql("SELECT x from (values (1, 2), (2, 4), (3, 6)) as t(x, y) offset 3")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(X=[$0])\n" +
- " PhoenixLimit(offset=[3])\n" +
+ " PhoenixLimit(offset=[3])\n" +
+ " PhoenixClientProject(X=[$0])\n" +
" PhoenixValues(tuples=[[{ 1, 2 }, { 2, 4 }, { 3, 6 }]])\n")
.resultIs(new Object[][] {})
.close();
@@ -1213,14 +1213,15 @@ public class CalciteIT extends BaseCalciteIT {
" PhoenixTableScan(table=[[phoenix, Join, OrderTable]], filter=[=($cor0.item_id, $2)])\n";
String p3Decorrelated =
"PhoenixToEnumerableConverter\n" +
- " PhoenixClientSemiJoin(condition=[=($0, $2)], joinType=[inner])\n" +
+ " PhoenixClientSemiJoin(condition=[=($0, $3)], joinType=[inner])\n" +
" PhoenixServerProject(item_id=[$0], NAME=[$1])\n" +
" PhoenixTableScan(table=[[phoenix, Join, ItemTable]], scanOrder=[FORWARD])\n" +
- " PhoenixServerJoin(condition=[=($0, $1)], joinType=[inner])\n" +
- " PhoenixServerProject(item_id=[$0])\n" +
- " PhoenixTableScan(table=[[phoenix, Join, ItemTable]], scanOrder=[FORWARD])\n" +
- " PhoenixServerProject(item_id=[$2])\n" +
- " PhoenixTableScan(table=[[phoenix, Join, OrderTable]])\n";
+ " PhoenixClientProject(item_id=[$1], item_id0=[$0])\n" +
+ " PhoenixServerJoin(condition=[=($0, $1)], joinType=[inner])\n" +
+ " PhoenixServerProject(item_id=[$0])\n" +
+ " PhoenixTableScan(table=[[phoenix, Join, ItemTable]], scanOrder=[FORWARD])\n" +
+ " PhoenixServerProject(item_id=[$2])\n" +
+ " PhoenixTableScan(table=[[phoenix, Join, OrderTable]])\n";
start(correlProps).sql(q3).explainIs(p3Correlate).resultIs(0, r3).close();
start(decorrelProps).sql(q3).explainIs(p3Decorrelated).resultIs(0, r3).close();
@@ -1232,11 +1233,10 @@ public class CalciteIT extends BaseCalciteIT {
{"0000000006", "T6"}};
String p4Decorrelated =
"PhoenixToEnumerableConverter\n" +
- " PhoenixServerSemiJoin(condition=[=($0, $2)], joinType=[inner])\n" +
+ " PhoenixServerSemiJoin(condition=[=($0, $4)], joinType=[inner])\n" +
" PhoenixServerProject(item_id=[$0], NAME=[$1])\n" +
" PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n" +
- " PhoenixServerProject(item_id=[$2])\n" +
- " PhoenixTableScan(table=[[phoenix, Join, OrderTable]])\n";
+ " PhoenixTableScan(table=[[phoenix, Join, OrderTable]])\n";
start(decorrelProps).sql(q4).explainIs(p4Decorrelated).resultIs(0, r4).close();
String q5 = "select \"order_id\" from " + JOIN_ITEM_TABLE_FULL_NAME + " i JOIN " + JOIN_ORDER_TABLE_FULL_NAME + " o on o.\"item_id\" = i.\"item_id\" where quantity = (select max(quantity) from " + JOIN_ORDER_TABLE_FULL_NAME + " o2 JOIN " + JOIN_ITEM_TABLE_FULL_NAME + " i2 on o2.\"item_id\" = i2.\"item_id\" where i.\"supplier_id\" = i2.\"supplier_id\")";
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteLocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteLocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteLocalIndexIT.java
index 0c03715..15452b7 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteLocalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteLocalIndexIT.java
@@ -47,7 +47,7 @@ public class CalciteLocalIndexIT extends BaseCalciteIndexIT {
" PhoenixTableScan(table=[[phoenix, IDX1]])\n")*/
start1000.sql("select a_string from aTable order by a_string")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixServerProject(A_STRING=[$0])\n" +
+ " PhoenixServerProject(0:A_STRING=[$0])\n" +
" PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n");
start1000000.sql("select a_string from aTable order by organization_id")
.explainIs("PhoenixToEnumerableConverter\n" +
@@ -129,18 +129,12 @@ public class CalciteLocalIndexIT extends BaseCalciteIndexIT {
.resultIs(new Object[][] {
{1, 2, 3, 4},
{2, 3, 4, 5}});
- start1.sql("select * from " + SALTED_TABLE_NAME + " s1, " + SALTED_TABLE_NAME + " s2 where s1.mypk0 = s2.mypk0 and s1.mypk1 = s2.mypk1 and s1.mypk0 > 500 and s2.col1 < 505")
+ start1.sql("select * from " + SALTED_TABLE_NAME + " s1, " + SALTED_TABLE_NAME + " s2 where s1.mypk1 = s2.mypk1 and s1.mypk0 > 500 and s2.col1 < 505")
.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixClientProject(MYPK0=[$4], MYPK1=[$5], COL0=[$6], COL1=[$7], MYPK00=[$0], MYPK10=[$1], COL00=[$2], COL10=[$3])\n" +
- " PhoenixServerJoin(condition=[AND(=($4, $0), =($5, $1))], joinType=[inner])\n" +
- " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" +
- " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<(CAST($0):INTEGER, 505)])\n" +
- " PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[>($0, 500)])\n")
- /*.explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixServerJoin(condition=[AND(=($0, $4), =($1, $5))], joinType=[inner])\n" +
+ " PhoenixServerJoin(condition=[=($1, $5)], joinType=[inner])\n" +
" PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[>($0, 500)])\n" +
" PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" +
- " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<(CAST($0):INTEGER, 505)])\n")*/
+ " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<(CAST($0):INTEGER, 505)])\n")
.resultIs(0, new Object[][] {
{501, 502, 503, 504, 501, 502, 503, 504}});
start1.close();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java
index 9edc4de..11be55b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java
@@ -7,7 +7,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.calcite.adapter.enumerable.EnumerableRules;
import org.apache.calcite.jdbc.CalcitePrepare;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.linq4j.Queryable;
@@ -18,11 +17,6 @@ import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.prepare.CalcitePrepareImpl;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.convert.ConverterRule;
-import org.apache.calcite.rel.logical.LogicalSort;
-import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule;
-import org.apache.calcite.rel.rules.JoinCommuteRule;
-import org.apache.calcite.rel.rules.SortProjectTransposeRule;
-import org.apache.calcite.rel.rules.SortUnionTransposeRule;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.runtime.Hook.Closeable;
@@ -41,7 +35,6 @@ import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.parser.SqlParserUtil;
import org.apache.calcite.tools.Program;
-import org.apache.calcite.tools.Programs;
import org.apache.calcite.util.Holder;
import org.apache.calcite.util.NlsString;
import org.apache.hadoop.hbase.util.Pair;
@@ -62,17 +55,7 @@ import org.apache.phoenix.calcite.parse.SqlUploadJarsNode;
import org.apache.phoenix.calcite.parse.SqlUseSchema;
import org.apache.phoenix.calcite.parser.PhoenixParserImpl;
import org.apache.phoenix.calcite.rel.PhoenixRel;
-import org.apache.phoenix.calcite.rel.PhoenixServerProject;
-import org.apache.phoenix.calcite.rel.PhoenixTemporarySort;
import org.apache.phoenix.calcite.rules.PhoenixConverterRules.PhoenixToEnumerableConverterRule;
-import org.apache.phoenix.calcite.rules.PhoenixFilterScanMergeRule;
-import org.apache.phoenix.calcite.rules.PhoenixForwardTableScanRule;
-import org.apache.phoenix.calcite.rules.PhoenixJoinSingleValueAggregateMergeRule;
-import org.apache.phoenix.calcite.rules.PhoenixMergeSortUnionRule;
-import org.apache.phoenix.calcite.rules.PhoenixOrderedAggregateRule;
-import org.apache.phoenix.calcite.rules.PhoenixReverseTableScanRule;
-import org.apache.phoenix.calcite.rules.PhoenixSortServerJoinTransposeRule;
-import org.apache.phoenix.calcite.rules.PhoenixTableScanColumnRefRule;
import org.apache.phoenix.compile.BaseMutationPlan;
import org.apache.phoenix.compile.CreateIndexCompiler;
import org.apache.phoenix.compile.CreateSequenceCompiler;
@@ -162,17 +145,12 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl {
org.apache.calcite.plan.Context externalContext,
RelOptCostFactory costFactory) {
RelOptPlanner planner = super.createPlanner(prepareContext, externalContext, costFactory);
-
- planner.removeRule(EnumerableRules.ENUMERABLE_SEMI_JOIN_RULE);
- planner.removeRule(JoinCommuteRule.INSTANCE);
- planner.removeRule(AggregateExpandDistinctAggregatesRule.INSTANCE);
- planner.addRule(JoinCommuteRule.SWAP_OUTER);
- planner.removeRule(SortUnionTransposeRule.INSTANCE);
- planner.addRule(SortUnionTransposeRule.MATCH_NULL_FETCH);
- planner.addRule(new SortProjectTransposeRule(
- PhoenixTemporarySort.class,
- PhoenixServerProject.class,
- "PhoenixSortProjectTransposeRule"));
+ for (RelOptRule rule : PhoenixPrograms.EXCLUDED_VOLCANO_RULES) {
+ planner.removeRule(rule);
+ }
+ for (RelOptRule rule : ENUMERABLE_RULES) {
+ //planner.removeRule(rule);
+ }
final PhoenixConnection pc =
getPhoenixConnection(prepareContext.getRootSchema().plus());
@@ -190,16 +168,9 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl {
for (RelOptRule rule : this.defaultConverterRules) {
planner.addRule(rule);
}
- planner.addRule(PhoenixFilterScanMergeRule.INSTANCE);
- planner.addRule(PhoenixTableScanColumnRefRule.INSTANCE);
- planner.addRule(PhoenixJoinSingleValueAggregateMergeRule.INSTANCE);
- planner.addRule(PhoenixMergeSortUnionRule.INSTANCE);
- planner.addRule(PhoenixOrderedAggregateRule.INSTANCE);
- planner.addRule(PhoenixSortServerJoinTransposeRule.INSTANCE);
- planner.addRule(new PhoenixForwardTableScanRule(LogicalSort.class));
- planner.addRule(new PhoenixForwardTableScanRule(PhoenixTemporarySort.class));
- planner.addRule(new PhoenixReverseTableScanRule(LogicalSort.class));
- planner.addRule(new PhoenixReverseTableScanRule(PhoenixTemporarySort.class));
+ for (RelOptRule rule : PhoenixPrograms.ADDITIONAL_VOLCANO_RULES) {
+ planner.addRule(rule);
+ }
return planner;
}
@@ -209,7 +180,8 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl {
Queryable<T> queryable) {
List<Closeable> hooks = addHooks(
context.getRootSchema(),
- context.config().materializationsEnabled());
+ context.config().materializationsEnabled(),
+ context.config().forceDecorrelate());
try {
return super.prepareQueryable(context, queryable);
} finally {
@@ -226,7 +198,8 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl {
long maxRowCount) {
List<Closeable> hooks = addHooks(
context.getRootSchema(),
- context.config().materializationsEnabled());
+ context.config().materializationsEnabled(),
+ context.config().forceDecorrelate());
try {
return super.prepareSql(context, query, elementType, maxRowCount);
} finally {
@@ -236,7 +209,8 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl {
}
}
- private List<Closeable> addHooks(final CalciteSchema rootSchema, boolean materializationEnabled) {
+ private List<Closeable> addHooks(final CalciteSchema rootSchema,
+ boolean materializationEnabled, final boolean forceDecorrelate) {
final List<Closeable> hooks = Lists.newArrayList();
hooks.add(Hook.PARSE_TREE.add(new Function<Object[], Object>() {
@@ -272,7 +246,10 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl {
hooks.add(Hook.PROGRAM.add(new Function<Holder<Program>, Object>() {
@Override
public Object apply(Holder<Program> input) {
- input.set(Programs.standard(PhoenixRel.METADATA_PROVIDER));
+ input.set(
+ PhoenixPrograms.standard(
+ PhoenixRel.METADATA_PROVIDER,
+ forceDecorrelate));
return null;
}
}));
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrograms.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrograms.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrograms.java
new file mode 100644
index 0000000..58aa3c4
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrograms.java
@@ -0,0 +1,370 @@
+package org.apache.phoenix.calcite;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.calcite.adapter.enumerable.EnumerableRules;
+import org.apache.calcite.config.CalciteConnectionConfig;
+import org.apache.calcite.plan.RelOptCost;
+import org.apache.calcite.plan.RelOptLattice;
+import org.apache.calcite.plan.RelOptMaterialization;
+import org.apache.calcite.plan.RelOptMaterializations;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.logical.LogicalSort;
+import org.apache.calcite.rel.metadata.RelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule;
+import org.apache.calcite.rel.rules.AggregateJoinTransposeRule;
+import org.apache.calcite.rel.rules.AggregateProjectMergeRule;
+import org.apache.calcite.rel.rules.FilterAggregateTransposeRule;
+import org.apache.calcite.rel.rules.FilterCorrelateRule;
+import org.apache.calcite.rel.rules.FilterJoinRule;
+import org.apache.calcite.rel.rules.FilterMergeRule;
+import org.apache.calcite.rel.rules.FilterProjectTransposeRule;
+import org.apache.calcite.rel.rules.JoinCommuteRule;
+import org.apache.calcite.rel.rules.JoinPushExpressionsRule;
+import org.apache.calcite.rel.rules.MaterializedViewFilterScanRule;
+import org.apache.calcite.rel.rules.ProjectMergeRule;
+import org.apache.calcite.rel.rules.ProjectRemoveRule;
+import org.apache.calcite.rel.rules.SemiJoinRule;
+import org.apache.calcite.rel.rules.SortJoinTransposeRule;
+import org.apache.calcite.rel.rules.SortProjectTransposeRule;
+import org.apache.calcite.rel.rules.SortUnionTransposeRule;
+import org.apache.calcite.rel.rules.SubQueryRemoveRule;
+import org.apache.calcite.rel.rules.UnionToDistinctRule;
+import org.apache.calcite.runtime.Hook;
+import org.apache.calcite.sql2rel.RelDecorrelator;
+import org.apache.calcite.sql2rel.RelFieldTrimmer;
+import org.apache.calcite.tools.Program;
+import org.apache.calcite.tools.Programs;
+import org.apache.calcite.tools.RelBuilder;
+import org.apache.calcite.util.Pair;
+import org.apache.phoenix.calcite.rel.PhoenixServerProject;
+import org.apache.phoenix.calcite.rel.PhoenixServerSort;
+import org.apache.phoenix.calcite.rel.PhoenixTemporarySort;
+import org.apache.phoenix.calcite.rules.PhoenixFilterScanMergeRule;
+import org.apache.phoenix.calcite.rules.PhoenixForwardTableScanRule;
+import org.apache.phoenix.calcite.rules.PhoenixJoinSingleValueAggregateMergeRule;
+import org.apache.phoenix.calcite.rules.PhoenixMergeSortUnionRule;
+import org.apache.phoenix.calcite.rules.PhoenixOrderedAggregateRule;
+import org.apache.phoenix.calcite.rules.PhoenixReverseTableScanRule;
+import org.apache.phoenix.calcite.rules.PhoenixSortServerJoinTransposeRule;
+import org.apache.phoenix.calcite.rules.PhoenixTableScanColumnRefRule;
+import org.apache.phoenix.calcite.rules.ProjectLimitTransposeRule;
+import org.apache.phoenix.calcite.rules.ProjectSortTransposeRule;
+import org.apache.phoenix.calcite.rules.SortSplitRule;
+
+import com.google.common.collect.ImmutableList;
+
+public class PhoenixPrograms {
+
+ public static final RelOptRule[] EXCLUDED_VOLCANO_RULES =
+ new RelOptRule[] {
+ AggregateExpandDistinctAggregatesRule.INSTANCE,
+ AggregateJoinTransposeRule.INSTANCE,
+ //AggregateProjectMergeRule.INSTANCE,
+ FilterAggregateTransposeRule.INSTANCE,
+ FilterCorrelateRule.INSTANCE,
+ FilterJoinRule.FILTER_ON_JOIN,
+ FilterJoinRule.JOIN,
+ FilterMergeRule.INSTANCE,
+ FilterProjectTransposeRule.INSTANCE,
+ JoinCommuteRule.INSTANCE,
+ JoinPushExpressionsRule.INSTANCE,
+ ProjectRemoveRule.INSTANCE,
+ SemiJoinRule.INSTANCE,
+ SortJoinTransposeRule.INSTANCE,
+ SortUnionTransposeRule.INSTANCE,
+ UnionToDistinctRule.INSTANCE,
+ MaterializedViewFilterScanRule.INSTANCE,
+ EnumerableRules.ENUMERABLE_SEMI_JOIN_RULE,
+ };
+
+ public static final RelOptRule[] EXCLUDED_ENUMERABLE_RULES =
+ new RelOptRule[] {
+ EnumerableRules.ENUMERABLE_JOIN_RULE,
+ EnumerableRules.ENUMERABLE_MERGE_JOIN_RULE,
+ EnumerableRules.ENUMERABLE_SEMI_JOIN_RULE,
+ EnumerableRules.ENUMERABLE_CORRELATE_RULE,
+ EnumerableRules.ENUMERABLE_PROJECT_RULE,
+ EnumerableRules.ENUMERABLE_FILTER_RULE,
+ EnumerableRules.ENUMERABLE_AGGREGATE_RULE,
+ EnumerableRules.ENUMERABLE_SORT_RULE,
+ EnumerableRules.ENUMERABLE_LIMIT_RULE,
+ EnumerableRules.ENUMERABLE_UNION_RULE,
+ EnumerableRules.ENUMERABLE_INTERSECT_RULE,
+ EnumerableRules.ENUMERABLE_MINUS_RULE,
+ EnumerableRules.ENUMERABLE_TABLE_MODIFICATION_RULE,
+ EnumerableRules.ENUMERABLE_VALUES_RULE,
+ EnumerableRules.ENUMERABLE_WINDOW_RULE,
+ };
+
+ public static final RelOptRule[] ADDITIONAL_VOLCANO_RULES =
+ new RelOptRule[] {
+ JoinCommuteRule.SWAP_OUTER,
+ new SortProjectTransposeRule(
+ PhoenixTemporarySort.class,
+ PhoenixServerProject.class,
+ "PhoenixTemporarySortProjectTransposeRule"),
+ new SortProjectTransposeRule(
+ PhoenixServerSort.class,
+ PhoenixServerProject.class,
+ "PhoenixServerSortProjectTransposeRule"),
+ PhoenixMergeSortUnionRule.INSTANCE,
+ PhoenixOrderedAggregateRule.INSTANCE,
+ new PhoenixSortServerJoinTransposeRule(
+ PhoenixTemporarySort.class,
+ "PhoenixTemporarySortServerJoinTransposeRule"),
+ new PhoenixSortServerJoinTransposeRule(
+ PhoenixServerSort.class,
+ "PhoenixServerSortServerJoinTransposeRule"),
+ new PhoenixForwardTableScanRule(PhoenixTemporarySort.class),
+ new PhoenixReverseTableScanRule(PhoenixTemporarySort.class),
+ new PhoenixForwardTableScanRule(PhoenixServerSort.class),
+ new PhoenixReverseTableScanRule(PhoenixServerSort.class),
+ };
+
+ public static Program standard(
+ final RelMetadataProvider metadataProvider,
+ final boolean forceDecorrelate) {
+ final Program volcanoProgram = new Program() {
+ public RelNode run(RelOptPlanner planner, RelNode rel,
+ RelTraitSet requiredOutputTraits,
+ List<RelOptMaterialization> materializations,
+ List<RelOptLattice> lattices) {
+ final List<Pair<RelNode, List<RelOptMaterialization>>> materializationUses;
+ final Set<RelOptMaterialization> applicableMaterializations;
+ final CalciteConnectionConfig config =
+ planner.getContext().unwrap(CalciteConnectionConfig.class);
+ if (config != null && config.materializationsEnabled()) {
+ // Transform rels using materialized views.
+ materializationUses =
+ RelOptMaterializations.useMaterializedViews(rel, materializations);
+
+ // Add not used but potentially useful materialized views to the planner.
+ applicableMaterializations = new HashSet<>(
+ RelOptMaterializations.getApplicableMaterializations(
+ rel, materializations));
+ for (Pair<RelNode, List<RelOptMaterialization>> use : materializationUses) {
+ applicableMaterializations.removeAll(use.right);
+ }
+ } else {
+ materializationUses = Collections.emptyList();
+ applicableMaterializations = Collections.emptySet();
+ }
+
+ final List<RelOptRule> rules = planner.getRules();
+ // Plan for the original root rel.
+ Pair<RelNode, RelOptCost> res = planFor(
+ planner, rel, requiredOutputTraits,
+ rules, applicableMaterializations);
+ RelNode bestRel = res.left;
+ RelOptCost bestCost = res.right;
+ // Plan for transformed rels using materialized views and update the
+ // best cost as needed.
+ for (Pair<RelNode, List<RelOptMaterialization>> m : materializationUses) {
+ try {
+ final RelNode rel2 = m.left;
+ Hook.SUB.run(rel2);
+ res = planFor(planner, rel2, requiredOutputTraits,
+ rules, applicableMaterializations);
+ if (res.right.isLt(bestCost)) {
+ bestRel = res.left;
+ bestCost = res.right;
+ }
+ } catch (RelOptPlanner.CannotPlanException e) {
+ // Ignore
+ }
+ }
+ return bestRel;
+ }
+
+ private Pair<RelNode, RelOptCost> planFor(
+ RelOptPlanner planner, RelNode rel,
+ RelTraitSet requiredOutputTraits,
+ List<RelOptRule> rules,
+ Collection<RelOptMaterialization> materializations) {
+ final Program preProgram = pre(
+ metadataProvider, forceDecorrelate);
+ rel = preProgram.run(planner, rel, requiredOutputTraits,
+ Collections.<RelOptMaterialization>emptyList(),
+ Collections.<RelOptLattice>emptyList());
+ planner.clear();
+ for (RelOptRule rule : rules) {
+ planner.addRule(rule);
+ }
+ for (RelOptMaterialization m : materializations) {
+ planner.addMaterialization(m);
+ }
+
+ final RelNode rootRel2 =
+ rel.getTraitSet().equals(requiredOutputTraits)
+ ? rel
+ : planner.changeTraits(rel, requiredOutputTraits);
+ assert rootRel2 != null;
+
+ planner.setRoot(rootRel2);
+ final RelOptPlanner planner2 = planner.chooseDelegate();
+ final RelNode rootRel3 = planner2.findBestExp();
+ final RelMetadataQuery mq = RelMetadataQuery.instance();
+ final RelOptCost cost = planner2.getCost(rootRel3, mq);
+
+ return Pair.of(rootRel3, cost);
+ }
+ };
+
+ return Programs.sequence(
+ volcanoProgram,
+ // Second planner pass to do physical "tweaks". This the first time that
+ // EnumerableCalcRel is introduced.
+ Programs.calc(metadataProvider));
+ }
+
+ public static Program pre(
+ RelMetadataProvider metadataProvider, boolean forceDecorrelate) {
+ return Programs.sequence(
+ subquery(metadataProvider),
+ decorrelate(forceDecorrelate),
+ trimFields(),
+ prePlanning(metadataProvider));
+ }
+
+ protected static Program subquery(RelMetadataProvider metadataProvider) {
+ return Programs.hep(
+ ImmutableList.of((RelOptRule) SubQueryRemoveRule.FILTER,
+ SubQueryRemoveRule.PROJECT,
+ SubQueryRemoveRule.JOIN), true, metadataProvider);
+ }
+
+ protected static Program decorrelate(final boolean forceDecorrelate) {
+ return new Program() {
+ public RelNode run(RelOptPlanner planner, RelNode rel,
+ RelTraitSet requiredOutputTraits,
+ List<RelOptMaterialization> materializations,
+ List<RelOptLattice> lattices) {
+ if (forceDecorrelate) {
+ return RelDecorrelator.decorrelateQuery(rel);
+ }
+ return rel;
+ }
+ };
+ }
+
+ protected static Program trimFields() {
+ return new Program() {
+ public RelNode run(RelOptPlanner planner, RelNode rel,
+ RelTraitSet requiredOutputTraits,
+ List<RelOptMaterialization> materializations,
+ List<RelOptLattice> lattices) {
+ final RelBuilder relBuilder =
+ RelFactories.LOGICAL_BUILDER.create(
+ rel.getCluster(), null);
+ return new RelFieldTrimmer(null, relBuilder).trim(rel);
+ }
+ };
+ }
+
+ protected static Program prePlanning(RelMetadataProvider metadataProvider) {
+ final Program filterPushdown = repeat(
+ Programs.hep(
+ ImmutableList.of(
+ FilterCorrelateRule.INSTANCE,
+ FilterJoinRule.FILTER_ON_JOIN,
+ FilterJoinRule.JOIN,
+ FilterProjectTransposeRule.INSTANCE,
+ FilterAggregateTransposeRule.INSTANCE,
+ FilterMergeRule.INSTANCE),
+ true, metadataProvider));
+ final Program filterMerge = Programs.hep(
+ ImmutableList.of(PhoenixFilterScanMergeRule.INSTANCE),
+ true, metadataProvider);
+ final Program sortPushdown = Programs.sequence(
+ repeat(
+ Programs.hep(
+ ImmutableList.of(
+ SortProjectTransposeRule.INSTANCE,
+ SortJoinTransposeRule.INSTANCE,
+ SortUnionTransposeRule.MATCH_NULL_FETCH),
+ true, metadataProvider)),
+ Programs.hep(
+ ImmutableList.of(
+ SortSplitRule.INSTANCE),
+ true, metadataProvider),
+ // SortUnionTransposeRule does not work with offset != null, so
+ // we should give it one more try after SortSplitRule.
+ repeat(
+ Programs.hep(
+ ImmutableList.of(
+ SortUnionTransposeRule.MATCH_NULL_FETCH,
+ SortProjectTransposeRule.INSTANCE),
+ true, metadataProvider)));
+ final Program sortMerge = Programs.hep(
+ ImmutableList.of(
+ new PhoenixForwardTableScanRule(LogicalSort.class),
+ new PhoenixReverseTableScanRule(LogicalSort.class)),
+ true, metadataProvider);
+ final Program projectPushdown = repeat(
+ Programs.hep(
+ ImmutableList.of(
+ ProjectLimitTransposeRule.INSTANCE,
+ ProjectSortTransposeRule.INSTANCE),
+ true, metadataProvider));
+ final Program projectMerge = Programs.hep(
+ ImmutableList.of(
+ ProjectMergeRule.INSTANCE,
+ PhoenixTableScanColumnRefRule.INSTANCE,
+ ProjectRemoveRule.INSTANCE,
+ AggregateProjectMergeRule.INSTANCE),
+ true, metadataProvider);
+ final Program misc1 = Programs.hep(
+ ImmutableList.of(
+ ProjectRemoveRule.INSTANCE,
+ PhoenixJoinSingleValueAggregateMergeRule.INSTANCE,
+ AggregateJoinTransposeRule.INSTANCE,
+ JoinPushExpressionsRule.INSTANCE,
+ //PhoenixJoinCommuteRule.INSTANCE,
+ UnionToDistinctRule.INSTANCE),
+ true, metadataProvider);
+ final Program misc2 = Programs.hep(
+ ImmutableList.of(
+ SemiJoinRule.INSTANCE),
+ true, metadataProvider);
+ return Programs.sequence(
+ misc1,
+ filterPushdown,
+ filterMerge,
+ sortPushdown,
+ sortMerge,
+ projectPushdown,
+ projectMerge,
+ misc2);
+ }
+
+ private static Program repeat(final Program program) {
+ return new Program() {
+ @Override
+ public RelNode run(RelOptPlanner planner, RelNode rel,
+ RelTraitSet requiredOutputTraits,
+ List<RelOptMaterialization> materializations,
+ List<RelOptLattice> lattices) {
+ RelNode oldRel = rel;
+ rel = program.run(planner, oldRel,
+ requiredOutputTraits, materializations, lattices);
+ while (!RelOptUtil.toString(oldRel).equals(RelOptUtil.toString(rel))) {
+ oldRel = rel;
+ rel = program.run(planner, oldRel,
+ requiredOutputTraits, materializations, lattices);
+ }
+ return rel;
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
index b29969f..f3d44eb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java
@@ -96,8 +96,16 @@ public class PhoenixTable extends AbstractTable
StatementContext context = new StatementContext(stmt, resolver, new Scan(), new SequenceManager(stmt));
Pair<Long, Long> estimatedCount = BaseResultIterators.getEstimatedCount(context, pTable);
if (estimatedCount.getFirst() != null) {
- rowCount = estimatedCount.getFirst();
- byteCount = estimatedCount.getSecond();
+ // FIXME Right now the row count for local index is not correct.
+ if (dataTable == null) {
+ rowCount = estimatedCount.getFirst();
+ byteCount = estimatedCount.getSecond();
+ } else {
+ Pair<Long, Long> dataTableEstimatedCount =
+ BaseResultIterators.getEstimatedCount(context, dataTable.getTable());
+ rowCount = dataTableEstimatedCount.getFirst();
+ byteCount = dataTableEstimatedCount.getSecond();
+ }
} else {
// TODO The props might not be the same as server props.
int guidepostPerRegion = pc.getQueryServices().getProps().getInt(
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdCollation.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdCollation.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdCollation.java
index 281ed2b..7e9207d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdCollation.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdCollation.java
@@ -1,11 +1,20 @@
package org.apache.phoenix.calcite.metadata;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.JoinRelType;
+import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.metadata.BuiltInMetadata;
import org.apache.calcite.rel.metadata.MetadataDef;
import org.apache.calcite.rel.metadata.MetadataHandler;
@@ -13,17 +22,24 @@ import org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexCallBinding;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SemiJoinType;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableIntList;
+import org.apache.phoenix.calcite.rel.Limit;
import org.apache.phoenix.calcite.rel.PhoenixClientJoin;
import org.apache.phoenix.calcite.rel.PhoenixCorrelate;
-import org.apache.phoenix.calcite.rel.PhoenixLimit;
import org.apache.phoenix.calcite.rel.PhoenixMergeSortUnion;
import org.apache.phoenix.calcite.rel.PhoenixServerJoin;
import org.apache.phoenix.calcite.rel.PhoenixTableScan;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Multimap;
public class PhoenixRelMdCollation implements MetadataHandler<BuiltInMetadata.Collation> {
public static final RelMetadataProvider SOURCE =
@@ -37,6 +53,10 @@ public class PhoenixRelMdCollation implements MetadataHandler<BuiltInMetadata.Co
return BuiltInMetadata.Collation.DEF;
}
+ public ImmutableList<RelCollation> collations(Project project, RelMetadataQuery mq) {
+ return ImmutableList.copyOf(project(mq, project.getInput(), project.getProjects()));
+ }
+
public ImmutableList<RelCollation> collations(PhoenixTableScan tableScan, RelMetadataQuery mq) {
return ImmutableList.copyOf(tableScan.getCollationList());
}
@@ -45,7 +65,7 @@ public class PhoenixRelMdCollation implements MetadataHandler<BuiltInMetadata.Co
return ImmutableList.copyOf(correlate(mq, correlate.getLeft(), correlate.getRight(), correlate.getJoinType()));
}
- public ImmutableList<RelCollation> collations(PhoenixLimit limit, RelMetadataQuery mq) {
+ public ImmutableList<RelCollation> collations(Limit limit, RelMetadataQuery mq) {
return ImmutableList.copyOf(RelMdCollation.limit(mq, limit.getInput()));
}
@@ -94,4 +114,65 @@ public class PhoenixRelMdCollation implements MetadataHandler<BuiltInMetadata.Co
return builder.build();
}
+ public static List<RelCollation> project(RelMetadataQuery mq,
+ RelNode input, List<? extends RexNode> projects) {
+ final SortedSet<RelCollation> collations = new TreeSet<>();
+ final List<RelCollation> inputCollations = mq.collations(input);
+ if (inputCollations == null || inputCollations.isEmpty()) {
+ return ImmutableList.of();
+ }
+ final Multimap<Integer, Integer> targets = LinkedListMultimap.create();
+ final Map<Integer, SqlMonotonicity> targetsWithMonotonicity =
+ new HashMap<>();
+ for (Ord<? extends RexNode> project : Ord.zip(projects)) {
+ if (project.e instanceof RexInputRef) {
+ targets.put(((RexInputRef) project.e).getIndex(), project.i);
+ } else if (project.e instanceof RexCall) {
+ final RexCall call = (RexCall) project.e;
+ final RexCallBinding binding =
+ RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
+ targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
+ }
+ }
+ final List<RelFieldCollation> fieldCollations = new ArrayList<>();
+ for (RelCollation ic : inputCollations) {
+ if (ic.getFieldCollations().isEmpty()) {
+ continue;
+ }
+ fieldCollations.clear();
+ for (RelFieldCollation ifc : ic.getFieldCollations()) {
+ final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
+ if (integers.isEmpty()) {
+ break;
+ }
+ fieldCollations.add(ifc.copy(integers.iterator().next()));
+ }
+ if (!fieldCollations.isEmpty()) {
+ collations.add(RelCollations.of(fieldCollations));
+ }
+ }
+
+ final List<RelFieldCollation> fieldCollationsForRexCalls =
+ new ArrayList<>();
+ for (Map.Entry<Integer, SqlMonotonicity> entry
+ : targetsWithMonotonicity.entrySet()) {
+ final SqlMonotonicity value = entry.getValue();
+ switch (value) {
+ case NOT_MONOTONIC:
+ case CONSTANT:
+ break;
+ default:
+ fieldCollationsForRexCalls.add(
+ new RelFieldCollation(entry.getKey(),
+ RelFieldCollation.Direction.of(value)));
+ break;
+ }
+ }
+
+ if (!fieldCollationsForRexCalls.isEmpty()) {
+ collations.add(RelCollations.of(fieldCollationsForRexCalls));
+ }
+
+ return ImmutableList.copyOf(collations);
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdMaxRowCount.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdMaxRowCount.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdMaxRowCount.java
new file mode 100644
index 0000000..a425f05
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdMaxRowCount.java
@@ -0,0 +1,32 @@
+package org.apache.phoenix.calcite.metadata;
+
+import org.apache.calcite.plan.hep.HepRelVertex;
+import org.apache.calcite.rel.metadata.BuiltInMetadata;
+import org.apache.calcite.rel.metadata.MetadataDef;
+import org.apache.calcite.rel.metadata.MetadataHandler;
+import org.apache.calcite.rel.metadata.ReflectiveRelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.util.BuiltInMethod;
+import org.apache.phoenix.calcite.rel.Limit;
+
+public class PhoenixRelMdMaxRowCount implements MetadataHandler<BuiltInMetadata.MaxRowCount> {
+ public static final RelMetadataProvider SOURCE =
+ ReflectiveRelMetadataProvider.reflectiveSource(
+ BuiltInMethod.MAX_ROW_COUNT.method, new PhoenixRelMdMaxRowCount());
+
+ private PhoenixRelMdMaxRowCount() { }
+
+ @Override
+ public MetadataDef<BuiltInMetadata.MaxRowCount> getDef() {
+ return BuiltInMetadata.MaxRowCount.DEF;
+ }
+
+ public Double getMaxRowCount(HepRelVertex rel, RelMetadataQuery mq) {
+ return mq.getMaxRowCount(rel.getCurrentRel());
+ }
+
+ public Double getMaxRowCount(Limit rel, RelMetadataQuery mq) {
+ return rel.estimateRowCount(mq);
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdRowCount.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdRowCount.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdRowCount.java
index aab8624..da34f96 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdRowCount.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdRowCount.java
@@ -9,8 +9,8 @@ import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.phoenix.calcite.rel.Limit;
import org.apache.phoenix.calcite.rel.PhoenixAbstractAggregate;
-import org.apache.phoenix.calcite.rel.PhoenixLimit;
public class PhoenixRelMdRowCount implements MetadataHandler<BuiltInMetadata.RowCount> {
public static final RelMetadataProvider SOURCE =
@@ -43,7 +43,7 @@ public class PhoenixRelMdRowCount implements MetadataHandler<BuiltInMetadata.Row
}
}
- public Double getRowCount(PhoenixLimit rel, RelMetadataQuery mq) {
+ public Double getRowCount(Limit rel, RelMetadataQuery mq) {
return rel.estimateRowCount(mq);
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdSize.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdSize.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdSize.java
index 355de27..ee37195 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdSize.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMdSize.java
@@ -2,6 +2,15 @@ package org.apache.phoenix.calcite.metadata;
import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Aggregate;
+import org.apache.calcite.rel.core.Correlate;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.SemiJoin;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.Uncollect;
+import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rel.metadata.BuiltInMetadata;
import org.apache.calcite.rel.metadata.MetadataDef;
import org.apache.calcite.rel.metadata.MetadataHandler;
@@ -10,11 +19,8 @@ import org.apache.calcite.rel.metadata.RelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.phoenix.calcite.PhoenixTable;
-import org.apache.phoenix.calcite.rel.PhoenixAbstractAggregate;
-import org.apache.phoenix.calcite.rel.PhoenixAbstractProject;
-import org.apache.phoenix.calcite.rel.PhoenixAbstractSemiJoin;
+import org.apache.phoenix.calcite.rel.Limit;
import org.apache.phoenix.calcite.rel.PhoenixTableScan;
-import org.apache.phoenix.calcite.rel.PhoenixUnion;
public class PhoenixRelMdSize implements MetadataHandler<BuiltInMetadata.Size> {
/** Source for
@@ -30,7 +36,7 @@ public class PhoenixRelMdSize implements MetadataHandler<BuiltInMetadata.Size> {
return BuiltInMetadata.Size.DEF;
}
- public Double averageRowSize(PhoenixUnion rel, RelMetadataQuery mq) {
+ public Double averageRowSize(Union rel, RelMetadataQuery mq) {
double rowSize = 0;
for (RelNode input : rel.getInputs()) {
rowSize += mq.getAverageRowSize(input);
@@ -39,7 +45,7 @@ public class PhoenixRelMdSize implements MetadataHandler<BuiltInMetadata.Size> {
return rowSize / rel.getInputs().size();
}
- public Double averageRowSize(PhoenixAbstractAggregate rel, RelMetadataQuery mq) {
+ public Double averageRowSize(Aggregate rel, RelMetadataQuery mq) {
RelNode input = rel.getInput();
double rowSize = mq.getAverageRowSize(input);
rowSize = rowSize * (rel.getGroupCount() + rel.getAggCallList().size()) / input.getRowType().getFieldCount();
@@ -47,18 +53,43 @@ public class PhoenixRelMdSize implements MetadataHandler<BuiltInMetadata.Size> {
return rowSize;
}
- public Double averageRowSize(PhoenixAbstractProject rel, RelMetadataQuery mq) {
+ public Double averageRowSize(Project rel, RelMetadataQuery mq) {
RelNode input = rel.getInput();
double rowSize = mq.getAverageRowSize(input);
rowSize = rowSize * rel.getProjects().size() / input.getRowType().getFieldCount();
return rowSize;
}
-
- public Double averageRowSize(PhoenixAbstractSemiJoin rel, RelMetadataQuery mq) {
+
+ public Double averageRowSize(Filter rel, RelMetadataQuery mq) {
+ return mq.getAverageRowSize(rel.getInput());
+ }
+
+ public Double averageRowSize(Correlate rel, RelMetadataQuery mq) {
return mq.getAverageRowSize(rel.getLeft());
}
+
+ public Double averageRowSize(SemiJoin rel, RelMetadataQuery mq) {
+ return mq.getAverageRowSize(rel.getLeft());
+ }
+
+ public Double averageRowSize(Join rel, RelMetadataQuery mq) {
+ return mq.getAverageRowSize(rel.getLeft())
+ + mq.getAverageRowSize(rel.getRight());
+ }
+
+ public Double averageRowSize(Sort rel, RelMetadataQuery mq) {
+ return mq.getAverageRowSize(rel.getInput());
+ }
+ public Double averageRowSize(Limit rel, RelMetadataQuery mq) {
+ return mq.getAverageRowSize(rel.getInput());
+ }
+
+ public Double averageRowSize(Uncollect rel, RelMetadataQuery mq) {
+ return mq.getAverageRowSize(rel.getInput());
+ }
+
public Double averageRowSize(PhoenixTableScan rel, RelMetadataQuery mq) {
PhoenixTable phoenixTable = rel.getTable().unwrap(PhoenixTable.class);
return 1.0 * phoenixTable.byteCount / phoenixTable.rowCount;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMetadataProvider.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMetadataProvider.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMetadataProvider.java
index 2bbc237..1234a2e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMetadataProvider.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/metadata/PhoenixRelMetadataProvider.java
@@ -8,7 +8,8 @@ public class PhoenixRelMetadataProvider extends ChainedRelMetadataProvider {
public PhoenixRelMetadataProvider() {
super(ImmutableList.of(
- PhoenixRelMdRowCount.SOURCE,
+ PhoenixRelMdRowCount.SOURCE,
+ PhoenixRelMdMaxRowCount.SOURCE,
PhoenixRelMdCollation.SOURCE,
PhoenixRelMdSize.SOURCE,
DefaultRelMetadataProvider.INSTANCE));
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/Limit.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/Limit.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/Limit.java
new file mode 100644
index 0000000..95aa18a
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/Limit.java
@@ -0,0 +1,40 @@
+package org.apache.phoenix.calcite.rel;
+
+import java.util.List;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelWriter;
+import org.apache.calcite.rel.SingleRel;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+
+public abstract class Limit extends SingleRel {
+ public final RexNode offset;
+ public final RexNode fetch;
+
+ protected Limit(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode offset, RexNode fetch) {
+ super(cluster, traits, input);
+ this.offset = offset;
+ this.fetch = fetch;
+ }
+
+ public abstract Limit copy(RelTraitSet traitSet, List<RelNode> newInputs);
+
+ @Override
+ public RelWriter explainTerms(RelWriter pw) {
+ return super.explainTerms(pw)
+ .itemIf("offset", offset, offset != null)
+ .itemIf("fetch", fetch, fetch != null);
+ }
+
+ @Override
+ public double estimateRowCount(RelMetadataQuery mq) {
+ double rows = super.estimateRowCount(mq);
+ int offset = this.offset == null ? 0 : RexLiteral.intValue(this.offset);
+ int fetch = this.fetch == null ? Integer.MAX_VALUE : RexLiteral.intValue(this.fetch);
+ return Math.max(0, Math.min(fetch, rows - offset));
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/LogicalLimit.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/LogicalLimit.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/LogicalLimit.java
new file mode 100644
index 0000000..5fe7b66
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/LogicalLimit.java
@@ -0,0 +1,45 @@
+package org.apache.phoenix.calcite.rel;
+
+import java.util.List;
+
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.metadata.RelMdCollation;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rex.RexNode;
+import com.google.common.base.Supplier;
+
+public class LogicalLimit extends Limit {
+
+ public static LogicalLimit create(final RelNode input, RexNode offset, RexNode fetch) {
+ final RelOptCluster cluster = input.getCluster();
+ final RelMetadataQuery mq = RelMetadataQuery.instance();
+ final RelTraitSet traits =
+ cluster.traitSet().replace(Convention.NONE)
+ .replaceIfs(RelCollationTraitDef.INSTANCE,
+ new Supplier<List<RelCollation>>() {
+ public List<RelCollation> get() {
+ return RelMdCollation.limit(mq, input);
+ }
+ });
+ return new LogicalLimit(cluster, traits, input, offset, fetch);
+ }
+
+ private LogicalLimit(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode offset, RexNode fetch) {
+ super(cluster, traits, input, offset, fetch);
+ }
+
+ @Override
+ public LogicalLimit copy(
+ RelTraitSet traitSet,
+ List<RelNode> newInputs) {
+ return create(
+ sole(newInputs),
+ offset,
+ fetch);
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
index 58d3861..f10e97c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixClientProject.java
@@ -10,7 +10,6 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
@@ -18,6 +17,7 @@ import org.apache.hadoop.hbase.client.Scan;
import org.apache.phoenix.compile.QueryPlan;
import org.apache.phoenix.compile.RowProjector;
import org.apache.phoenix.compile.SequenceManager;
+import org.apache.phoenix.calcite.metadata.PhoenixRelMdCollation;
import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
import org.apache.phoenix.compile.StatementContext;
import org.apache.phoenix.execute.ClientScanPlan;
@@ -38,7 +38,7 @@ public class PhoenixClientProject extends PhoenixAbstractProject {
.replaceIfs(RelCollationTraitDef.INSTANCE,
new Supplier<List<RelCollation>>() {
public List<RelCollation> get() {
- return RelMdCollation.project(mq, input, projects);
+ return PhoenixRelMdCollation.project(mq, input, projects);
}
});
return new PhoenixClientProject(cluster, traits, input, projects, rowType);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
index 8406929..4c0f00e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java
@@ -9,8 +9,6 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.RelWriter;
-import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rex.RexLiteral;
@@ -22,9 +20,7 @@ import org.apache.phoenix.execute.ClientScanPlan;
import com.google.common.base.Supplier;
-public class PhoenixLimit extends SingleRel implements PhoenixQueryRel {
- public final RexNode offset;
- public final RexNode fetch;
+public class PhoenixLimit extends Limit implements PhoenixQueryRel {
public static PhoenixLimit create(final RelNode input, RexNode offset, RexNode fetch) {
final RelOptCluster cluster = input.getCluster();
@@ -41,9 +37,7 @@ public class PhoenixLimit extends SingleRel implements PhoenixQueryRel {
}
private PhoenixLimit(RelOptCluster cluster, RelTraitSet traits, RelNode input, RexNode offset, RexNode fetch) {
- super(cluster, traits, input);
- this.offset = offset;
- this.fetch = fetch;
+ super(cluster, traits, input, offset, fetch);
}
@Override
@@ -57,13 +51,6 @@ public class PhoenixLimit extends SingleRel implements PhoenixQueryRel {
}
@Override
- public RelWriter explainTerms(RelWriter pw) {
- return super.explainTerms(pw)
- .itemIf("offset", offset, offset != null)
- .itemIf("fetch", fetch, fetch != null);
- }
-
- @Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
if (!getInput().getConvention().satisfies(PhoenixConvention.GENERIC))
return planner.getCostFactory().makeInfiniteCost();
@@ -72,14 +59,6 @@ public class PhoenixLimit extends SingleRel implements PhoenixQueryRel {
.makeCost(rowCount, 0, 0)
.multiplyBy(PHOENIX_FACTOR);
}
-
- @Override
- public double estimateRowCount(RelMetadataQuery mq) {
- double rows = super.estimateRowCount(mq);
- int offset = this.offset == null ? 0 : RexLiteral.intValue(this.offset);
- int fetch = this.fetch == null ? Integer.MAX_VALUE : RexLiteral.intValue(this.fetch);
- return Math.max(0, Math.min(fetch, rows - offset));
- }
@Override
public QueryPlan implement(PhoenixRelImplementor implementor) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
index 7932c3f..9290ffe 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixServerProject.java
@@ -9,10 +9,10 @@ import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
-import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
+import org.apache.phoenix.calcite.metadata.PhoenixRelMdCollation;
import org.apache.phoenix.calcite.rel.PhoenixRelImplementor.ImplementorContext;
import org.apache.phoenix.compile.QueryPlan;
import org.apache.phoenix.execute.ScanPlan;
@@ -31,7 +31,7 @@ public class PhoenixServerProject extends PhoenixAbstractProject {
.replaceIfs(RelCollationTraitDef.INSTANCE,
new Supplier<List<RelCollation>>() {
public List<RelCollation> get() {
- return RelMdCollation.project(mq, input, projects);
+ return PhoenixRelMdCollation.project(mq, input, projects);
}
});
return new PhoenixServerProject(cluster, traits, input, projects, rowType);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
index 4474bac..f57f974 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java
@@ -2,6 +2,7 @@ package org.apache.phoenix.calcite.rel;
import java.sql.SQLException;
import java.util.List;
+import java.util.Objects;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptCost;
@@ -201,6 +202,26 @@ public class PhoenixTableScan extends TableScan implements PhoenixQueryRel {
.itemIf("extendedColumns", extendedColumnRef, !extendedColumnRef.isEmpty());
}
+ @Override public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof PhoenixTableScan)) {
+ return false;
+ }
+
+ PhoenixTableScan other = (PhoenixTableScan) obj;
+ return this.table.equals(other.table)
+ && Objects.equals(this.filter, other.filter)
+ && this.scanOrder == other.scanOrder
+ && this.extendedColumnRef.equals(other.extendedColumnRef);
+ }
+
+ @Override public int hashCode() {
+ return table.hashCode();
+ }
+
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
double byteCount;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTemporarySort.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTemporarySort.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTemporarySort.java
index 596212f..74976fb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTemporarySort.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTemporarySort.java
@@ -17,7 +17,7 @@ public class PhoenixTemporarySort extends PhoenixAbstractSort {
RelOptCluster cluster = input.getCluster();
collation = RelCollationTraitDef.INSTANCE.canonize(collation);
RelTraitSet traits =
- input.getTraitSet().replace(PhoenixConvention.SERVER).replace(collation);
+ input.getTraitSet().replace(input.getConvention()).replace(collation);
return new PhoenixTemporarySort(cluster, traits, input, collation);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/36a31bf9/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
index ca3e60e..4a8157b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java
@@ -40,6 +40,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlKind;
import org.apache.phoenix.calcite.CalciteUtils;
import org.apache.phoenix.calcite.PhoenixTable;
+import org.apache.phoenix.calcite.rel.LogicalLimit;
import org.apache.phoenix.calcite.rel.PhoenixAbstractAggregate;
import org.apache.phoenix.calcite.rel.PhoenixClientAggregate;
import org.apache.phoenix.calcite.rel.PhoenixClientJoin;
@@ -221,37 +222,22 @@ public class PhoenixConverterRules {
*/
public static class PhoenixLimitRule extends PhoenixConverterRule {
- private static Predicate<LogicalSort> HAS_FETCH = new Predicate<LogicalSort>() {
- @Override
- public boolean apply(LogicalSort input) {
- return input.fetch != null || input.offset != null;
- }
- };
-
public static final PhoenixLimitRule INSTANCE = new PhoenixLimitRule();
private PhoenixLimitRule() {
- super(LogicalSort.class,
- HAS_FETCH,
+ super(LogicalLimit.class,
Convention.NONE, PhoenixConvention.CLIENT, "PhoenixLimitRule");
}
public RelNode convert(RelNode rel) {
- final LogicalSort sort = (LogicalSort) rel;
- RelNode input = sort.getInput();
- if (!sort.getCollation().getFieldCollations().isEmpty()) {
- input = sort.copy(
- sort.getTraitSet(),
- sort.getInput(),
- sort.getCollation(),
- null, null);
- }
+ final LogicalLimit limit = (LogicalLimit) rel;
+ RelNode input = limit.getInput();
return PhoenixLimit.create(
convert(
input,
input.getTraitSet().replace(PhoenixConvention.GENERIC)),
- sort.offset,
- sort.fetch);
+ limit.offset,
+ limit.fetch);
}
}