Repository: phoenix Updated Branches: refs/heads/calcite 1193e5afe -> 4f01c91ec
PHOENIX-2827 Support OFFSET in Calcite-Phoenix (Eric Lomore) Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/4f01c91e Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/4f01c91e Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/4f01c91e Branch: refs/heads/calcite Commit: 4f01c91ec78988058fbed1f31a51e2bf06db04a8 Parents: 1193e5a Author: maryannxue <maryann....@gmail.com> Authored: Mon Oct 3 13:09:26 2016 -0700 Committer: maryannxue <maryann....@gmail.com> Committed: Mon Oct 3 13:10:18 2016 -0700 ---------------------------------------------------------------------- .../org/apache/phoenix/calcite/CalciteIT.java | 259 ++++++++++++++----- .../phoenix/calcite/rel/PhoenixLimit.java | 17 +- .../rel/PhoenixToEnumerableConverter.java | 4 +- .../calcite/rules/PhoenixConverterRules.java | 3 +- .../phoenix/compile/ListJarsQueryPlan.java | 2 +- .../org/apache/phoenix/compile/QueryPlan.java | 11 +- .../apache/phoenix/compile/TraceQueryPlan.java | 2 +- .../apache/phoenix/execute/AggregatePlan.java | 17 +- .../phoenix/execute/ClientAggregatePlan.java | 15 +- .../apache/phoenix/execute/ClientScanPlan.java | 15 +- .../apache/phoenix/execute/CorrelatePlan.java | 12 +- .../phoenix/execute/DegenerateQueryPlan.java | 2 +- .../phoenix/execute/DelegateQueryPlan.java | 12 +- .../apache/phoenix/execute/HashJoinPlan.java | 4 +- .../execute/LiteralResultIterationPlan.java | 16 +- .../org/apache/phoenix/execute/ScanPlan.java | 16 +- .../phoenix/execute/SortMergeJoinPlan.java | 10 +- .../phoenix/execute/TupleProjectionPlan.java | 4 +- .../org/apache/phoenix/execute/UnionPlan.java | 11 +- .../apache/phoenix/execute/UnnestArrayPlan.java | 10 +- .../apache/phoenix/jdbc/PhoenixStatement.java | 2 +- .../query/ParallelIteratorsSplitTest.java | 2 +- 22 files changed, 300 insertions(+), 146 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/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 da6303b..abea491 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 @@ -280,19 +280,19 @@ public class CalciteIT extends BaseCalciteIT { " PhoenixServerProject(supplier_id=[$0], NAME=[$1])\n" + " PhoenixTableScan(table=[[phoenix, Join, SupplierTable]], scanOrder=[FORWARD])\n") .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") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixClientProject(order_id=[$0], NAME=[$4], PRICE=[$5], DISCOUNT2=[$6], QUANTITY=[$2])\n" + - " PhoenixLimit(fetch=[2])\n" + - " PhoenixClientJoin(condition=[=($1, $3)], joinType=[left])\n" + - " PhoenixClientSort(sort0=[$1], dir0=[ASC])\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" + - " PhoenixTableScan(table=[[phoenix, Join, ItemTable]], scanOrder=[FORWARD])\n") + + 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") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixClientProject(order_id=[$0], NAME=[$4], PRICE=[$5], DISCOUNT2=[$6], QUANTITY=[$2])\n" + + " PhoenixLimit(offset=[1], fetch=[2])\n" + + " PhoenixClientJoin(condition=[=($1, $3)], joinType=[left])\n" + + " PhoenixClientSort(sort0=[$1], dir0=[ASC])\n" + + " PhoenixLimit(offset=[1], 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" + + " PhoenixTableScan(table=[[phoenix, Join, ItemTable]], scanOrder=[FORWARD])\n") .close(); } @@ -316,22 +316,22 @@ public class CalciteIT extends BaseCalciteIT { {"00A423122312312", "a", "00D300000000XHP"}}) .close(); - 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") + 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" + - " PhoenixClientJoin(condition=[AND(=($1, $5), =($0, $4))], joinType=[inner])\n" + - " PhoenixClientJoin(condition=[AND(=($1, $3), =($0, $2))], joinType=[inner])\n" + + " PhoenixLimit(offset=[1], fetch=[8])\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" + + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + + " PhoenixServerSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + " PhoenixServerSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])\n" + - " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + - " PhoenixServerSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])\n" + - " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + - " PhoenixServerSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])\n" + - " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") .resultIs(0, new Object[][] { - {"00A123122312312", "a", "00D300000000XHP"}, {"00A223122312312", "a", "00D300000000XHP"}, {"00A323122312312", "a", "00D300000000XHP"}, {"00A423122312312", "a", "00D300000000XHP"}, @@ -385,7 +385,7 @@ public class CalciteIT extends BaseCalciteIT { {"00A223122312312", 1L}, {"00A323122312312", 1L}, {"00A423122312312", 1L}, - {"00B523122312312", 1L}, + {"00B523122312312", 1L}, {"00B623122312312", 1L}, {"00B723122312312", 1L}, {"00B823122312312", 1L}, @@ -610,8 +610,8 @@ public class CalciteIT extends BaseCalciteIT { .close(); } - @Test public void testSortWithLimit() throws Exception { - start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by a_string, entity_id limit 5") + @Test public void testSortWithLimitOffset() throws Exception { + start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by a_string, entity_id limit 5 offset 0") .explainIs("PhoenixToEnumerableConverter\n" + " PhoenixLimit(fetch=[5])\n" + " PhoenixServerSort(sort0=[$2], sort1=[$1], dir0=[ASC], dir1=[ASC])\n" + @@ -625,46 +625,45 @@ public class CalciteIT extends BaseCalciteIT { {"00D300000000XHP", "00B523122312312", "b"}}) .close(); - start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id, entity_id limit 5") + start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id, entity_id limit 5 offset 3") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixLimit(fetch=[5])\n" + + " PhoenixLimit(offset=[3], fetch=[5])\n" + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + " PhoenixTableScan(table=[[phoenix, ATABLE]], scanOrder=[FORWARD])\n") .resultIs(new Object[][] { - {"00D300000000XHP", "00A123122312312", "a"}, - {"00D300000000XHP", "00A223122312312", "a"}, - {"00D300000000XHP", "00A323122312312", "a"}, {"00D300000000XHP", "00A423122312312", "a"}, - {"00D300000000XHP", "00B523122312312", "b"}}) + {"00D300000000XHP", "00B523122312312", "b"}, + {"00D300000000XHP", "00B623122312312", "b"}, + {"00D300000000XHP", "00B723122312312", "b"}, + {"00D300000000XHP", "00B823122312312", "b"}}) .close(); - start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id DESC limit 5") + start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id DESC limit 5 offset 5") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixLimit(fetch=[5])\n" + + " PhoenixLimit(offset=[5], fetch=[5])\n" + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + " PhoenixTableScan(table=[[phoenix, ATABLE]], scanOrder=[REVERSE])\n") .resultIs(new Object[][] { - {"00D300000000XHP", "00C923122312312", "c"}, - {"00D300000000XHP", "00B823122312312", "b"}, - {"00D300000000XHP", "00B723122312312", "b"}, - {"00D300000000XHP", "00B623122312312", "b"}, - {"00D300000000XHP", "00B523122312312", "b"}}) + {"00D300000000XHP", "00A423122312312", "a"}, + {"00D300000000XHP", "00A323122312312", "a"}, + {"00D300000000XHP", "00A223122312312", "a"}, + {"00D300000000XHP", "00A123122312312", "a"}}) .close(); - start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id DESC, entity_id DESC limit 5") + start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id DESC, entity_id DESC limit 5 offset 2") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixLimit(fetch=[5])\n" + + " PhoenixLimit(offset=[2], fetch=[5])\n" + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + " PhoenixTableScan(table=[[phoenix, ATABLE]], scanOrder=[REVERSE])\n") .resultIs(new Object[][] { - {"00D300000000XHP", "00C923122312312", "c"}, - {"00D300000000XHP", "00B823122312312", "b"}, {"00D300000000XHP", "00B723122312312", "b"}, {"00D300000000XHP", "00B623122312312", "b"}, - {"00D300000000XHP", "00B523122312312", "b"}}) + {"00D300000000XHP", "00B523122312312", "b"}, + {"00D300000000XHP", "00A423122312312", "a"}, + {"00D300000000XHP", "00A323122312312", "a"}}) .close(); - start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id ASC, entity_id DESC limit 5") + start(false, 1000f).sql("select organization_id, entity_id, a_string from aTable order by organization_id ASC, entity_id DESC limit 5 offset 0") .explainIs("PhoenixToEnumerableConverter\n" + " PhoenixLimit(fetch=[5])\n" + " PhoenixServerSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[DESC])\n" + @@ -678,21 +677,21 @@ public class CalciteIT extends BaseCalciteIT { {"00D300000000XHP", "00B523122312312", "b"}}) .close(); - 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") + 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(fetch=[2])\n" + + " PhoenixLimit(offset=[1], fetch=[2])\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") .resultIs(new Object[][] { - {1L, "c"}, - {4L, "b"}}) + {4L, "b"}, + {4L, "a"}}) .close(); - start(false, 1000f).sql("select s.name, count(\"item_id\") from " + JOIN_SUPPLIER_TABLE_FULL_NAME + " s join " + JOIN_ITEM_TABLE_FULL_NAME + " i on s.\"supplier_id\" = i.\"supplier_id\" group by s.name order by count(\"item_id\"), s.name desc limit 3") + start(false, 1000f).sql("select s.name, count(\"item_id\") from " + JOIN_SUPPLIER_TABLE_FULL_NAME + " s join " + JOIN_ITEM_TABLE_FULL_NAME + " i on s.\"supplier_id\" = i.\"supplier_id\" group by s.name order by count(\"item_id\"), s.name desc limit 3 offset 1") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixLimit(fetch=[3])\n" + + " PhoenixLimit(offset=[1], fetch=[3])\n" + " PhoenixServerSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[DESC])\n" + " PhoenixServerAggregate(group=[{1}], EXPR$1=[COUNT()], isOrdered=[false])\n" + " PhoenixServerJoin(condition=[=($0, $2)], joinType=[inner])\n" + @@ -701,9 +700,9 @@ public class CalciteIT extends BaseCalciteIT { " PhoenixServerProject(supplier_id=[$5])\n" + " PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n") .resultIs(new Object[][] { - {"S6", 1L}, {"S5", 1L}, - {"S2", 2L}}) + {"S2", 2L}, + {"S1", 2L}}) .close(); 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") @@ -796,6 +795,134 @@ public class CalciteIT extends BaseCalciteIT { .close(); } + // PHOENIX CALCITE INTEGRATION : PHOENIX-2827 + @Test public void testLimitOffset() throws Exception { + start(false, 1000f).sql( + "select organization_id, entity_id, a_string from aTable limit 5 offset 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixLimit(offset=[3], fetch=[5])\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + .resultIs(new Object[][] { + { "00D300000000XHP", "00A423122312312", "a" }, + { "00D300000000XHP", "00B523122312312", "b" }, + { "00D300000000XHP", "00B623122312312", "b" }, + { "00D300000000XHP", "00B723122312312", "b" }, + { "00D300000000XHP", "00B823122312312", "b" }, }) + .close(); + + start(false, 1000f).sql( + "select organization_id, entity_id, a_string from aTable limit 13 offset 12") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixLimit(offset=[12], fetch=[13])\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + .resultIs(new Object[][] {}) + .close(); + + 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" + + " PhoenixServerAggregate(group=[{2}], EXPR$0=[COUNT()], isOrdered=[false])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + .resultIsSomeOf(2, new Object[][] { + {4L, "a"}, + {4L, "b"}, + {1L, "c"}}) + .close(); + + 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" + + " PhoenixServerJoin(condition=[=($2, $3)], joinType=[inner])\n" + + " PhoenixServerProject(item_id=[$0], NAME=[$1], supplier_id=[$5])\n" + + " PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n" + + " PhoenixServerProject(supplier_id=[$0], NAME=[$1])\n" + + " PhoenixTableScan(table=[[phoenix, Join, SupplierTable]])\n") + .resultIsSomeOf(3, new Object[][] { + { "0000000001", "T1", "0000000001", "S1" }, + { "0000000002", "T2", "0000000001", "S1" }, + { "0000000003", "T3", "0000000002", "S2" }, + { "0000000004", "T4", "0000000002", "S2" }, + { "0000000005", "T5", "0000000005", "S5" }, + { "0000000006", "T6", "0000000006", "S6" } }) + .close(); + + 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" + + " 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" + + " PhoenixValues(tuples=[[{ 1, 2 }, { 2, 4 }, { 3, 6 }]])\n") + .resultIs(new Object[][] {}) + .close(); + } + + @Test public void testOffset() throws Exception { + start(false, 1000f).sql( + "select organization_id, entity_id, a_string from aTable offset 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixLimit(offset=[3])\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + .resultIs(new Object[][] { + { "00D300000000XHP", "00A423122312312", "a" }, + { "00D300000000XHP", "00B523122312312", "b" }, + { "00D300000000XHP", "00B623122312312", "b" }, + { "00D300000000XHP", "00B723122312312", "b" }, + { "00D300000000XHP", "00B823122312312", "b" }, + { "00D300000000XHP", "00C923122312312", "c" }}) + .close(); + + 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" + + " PhoenixServerAggregate(group=[{2}], EXPR$0=[COUNT()], isOrdered=[false])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + .resultIsSomeOf(2, new Object[][] { + {4L, "a"}, + {4L, "b"}, + {1L, "c"}}) + .close(); + + 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" + + " PhoenixServerJoin(condition=[=($2, $3)], joinType=[inner])\n" + + " PhoenixServerProject(item_id=[$0], NAME=[$1], supplier_id=[$5])\n" + + " PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n" + + " PhoenixServerProject(supplier_id=[$0], NAME=[$1])\n" + + " PhoenixTableScan(table=[[phoenix, Join, SupplierTable]])\n") + .resultIs(new Object [][] {}) + .close(); + + start(false, 1000f).sql("SELECT x from (values (1, 2), (2, 4), (3, 6)) as t(x, y) offset 0") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixClientProject(X=[$0])\n" + + " PhoenixValues(tuples=[[{ 1, 2 }, { 2, 4 }, { 3, 6 }]])\n") + .resultIs(new Object[][] {{1},{2},{3}}) + .close(); + + 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" + + " PhoenixValues(tuples=[[{ 1, 2 }, { 2, 4 }, { 3, 6 }]])\n") + .resultIs(new Object[][] {}) + .close(); + } + @Ignore // CALCITE-1045 @Test public void testScalarSubquery() throws Exception { start(false, 1000f).sql("select \"item_id\", name, (select max(quantity) sq \n" @@ -874,22 +1001,20 @@ public class CalciteIT extends BaseCalciteIT { {"00B823122312312"}}) .close(); - start(false, 1000f).sql("select entity_id, a_string from atable where a_string = 'a' union all select entity_id, a_string from atable where a_string = 'c' order by entity_id desc limit 3") + start(false, 1000f).sql("select entity_id, a_string from atable where a_string = 'a' union all select entity_id, a_string from atable where a_string = 'c' order by entity_id desc limit 3 offset 1") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixLimit(fetch=[3])\n" + + " PhoenixLimit(offset=[1], fetch=[3])\n" + " PhoenixMergeSortUnion(all=[true])\n" + - " PhoenixLimit(fetch=[3])\n" + - " PhoenixServerSort(sort0=[$0], dir0=[DESC])\n" + - " PhoenixServerProject(ENTITY_ID=[$1], A_STRING=[$2])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'a')])\n" + - " PhoenixLimit(fetch=[3])\n" + - " PhoenixServerSort(sort0=[$0], dir0=[DESC])\n" + - " PhoenixServerProject(ENTITY_ID=[$1], A_STRING=[$2])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'c')])\n") + " PhoenixServerSort(sort0=[$0], dir0=[DESC])\n" + + " PhoenixServerProject(ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'a')])\n" + + " PhoenixServerSort(sort0=[$0], dir0=[DESC])\n" + + " PhoenixServerProject(ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'c')])\n") .resultIs(new Object[][] { - {"00C923122312312", "c"}, {"00A423122312312", "a"}, - {"00A323122312312", "a"}}) + {"00A323122312312", "a"}, + {"00A223122312312", "a"}}) .close(); start(false, 1000f).sql("select entity_id, a_string from atable where a_string = 'a' union all select entity_id, a_string from atable where a_string = 'c' order by entity_id desc") http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/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 50b6f2b..8406929 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 @@ -67,7 +67,6 @@ public class PhoenixLimit extends SingleRel implements PhoenixQueryRel { public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { if (!getInput().getConvention().satisfies(PhoenixConvention.GENERIC)) return planner.getCostFactory().makeInfiniteCost(); - double rowCount = mq.getRowCount(this); return planner.getCostFactory() .makeCost(rowCount, 0, 0) @@ -76,20 +75,24 @@ public class PhoenixLimit extends SingleRel implements PhoenixQueryRel { @Override public double estimateRowCount(RelMetadataQuery mq) { - double rows = super.estimateRowCount(mq); - return Math.min(RexLiteral.intValue(fetch), rows); + 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) { QueryPlan plan = implementor.visitInput(0, (PhoenixQueryRel) getInput()); - int fetchValue = RexLiteral.intValue(fetch); - if (plan.getLimit() == null) { - return plan.limit(fetchValue); + Integer fetch = this.fetch == null ? null : RexLiteral.intValue(this.fetch); + Integer offset = this.offset == null ? null : RexLiteral.intValue(this.offset); + + if (plan.getLimit() == null && plan.getOffset() == null) { + return plan.limit(fetch, offset); } return new ClientScanPlan(plan.getContext(), plan.getStatement(), implementor.getTableMapping().getTableRef(), RowProjector.EMPTY_PROJECTOR, - fetchValue, null, null, OrderBy.EMPTY_ORDER_BY, plan); + fetch, offset, null, OrderBy.EMPTY_ORDER_BY, plan); } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java index 5bc2c0d..5aef483 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixToEnumerableConverter.java @@ -121,8 +121,8 @@ public class PhoenixToEnumerableConverter extends ConverterImpl implements Enume return delegate.iterator(scanGrouper); } @Override - public QueryPlan limit(Integer limit) { - return delegate.limit(limit); + public QueryPlan limit(Integer limit, Integer offset) { + return delegate.limit(limit, offset); } @Override public ResultIterator iterator(ParallelScanGrouper scanGrouper, Scan scan) throws SQLException { http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/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 4347aa5..ca71ab1 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 @@ -232,8 +232,7 @@ public class PhoenixConverterRules { private static Predicate<LogicalSort> HAS_FETCH = new Predicate<LogicalSort>() { @Override public boolean apply(LogicalSort input) { - return input.offset == null - && input.fetch != null; + return input.fetch != null || input.offset != null; } }; http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java index a8c725a..bd23a36 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java @@ -243,7 +243,7 @@ public class ListJarsQueryPlan implements QueryPlan { } @Override - public QueryPlan limit(Integer limit) { + public QueryPlan limit(Integer limit, Integer offset) { return this; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java index 60cd1a7..aaf79d9 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java @@ -88,12 +88,13 @@ public interface QueryPlan extends StatementPlan { public boolean useRoundRobinIterator() throws SQLException; /** - * Create a copy of the current QueryPlan with a new limit value. + * Create a copy of the current QueryPlan with a new limit and offset value. * - * @param limit the new limit value. - * @return the new QueryPlan or the current QueryPlan if the limit - * value is unchanged or if the limit value does not make a + * @param limit the new limit value + * @param offset is the new offset value + * @return the new QueryPlan or the current QueryPlan if the limit & offset + * value is unchanged or if the limit & offset values do not make a * difference in the QueryPlan's behavior. */ - public QueryPlan limit(Integer limit); + public QueryPlan limit(Integer limit, Integer offset); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java index 833df2c..e79f634 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java @@ -261,7 +261,7 @@ public class TraceQueryPlan implements QueryPlan { } @Override - public QueryPlan limit(Integer limit) { + public QueryPlan limit(Integer limit, Integer offset) { return this; } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java index cd83c4d..dc86376 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java @@ -21,6 +21,7 @@ package org.apache.phoenix.execute; import java.sql.SQLException; import java.util.Collections; import java.util.List; +import java.util.Objects; import org.apache.hadoop.hbase.client.Scan; import org.apache.phoenix.compile.GroupByCompiler.GroupBy; @@ -268,11 +269,15 @@ public class AggregatePlan extends BaseQueryPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == this.limit || (limit != null && limit.equals(this.limit))) + public QueryPlan limit(Integer limit, Integer offset) { + if (Objects.equals(limit, this.limit) && + Objects.equals(offset, this.offset)) { return this; - - return new AggregatePlan(this.context, this.statement, this.tableRef, this.tableRefs.iterator().next(), this.projection, - limit, this.offset, this.orderBy, this.parallelIteratorFactory, this.groupBy, this.having, this.dynamicFilter); + } + + return new AggregatePlan(this.context, this.statement, this.tableRef, + this.tableRefs.iterator().next(), this.projection, + limit, offset, this.orderBy, this.parallelIteratorFactory, this.groupBy, + this.having, this.dynamicFilter); } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java index af93d92..f4afc19 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.sql.SQLException; import java.util.Collections; import java.util.List; +import java.util.Objects; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.KeyValue; @@ -247,12 +248,14 @@ public class ClientAggregatePlan extends ClientProcessingPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == this.limit || (limit != null && limit.equals(this.limit))) + public QueryPlan limit(Integer limit, Integer offset) { + if (Objects.equals(limit, this.limit) && + Objects.equals(offset, this.offset)) { return this; - - return new ClientAggregatePlan(this.context, this.statement, this.table, - this.projector, limit, this.offset, this.where, this.orderBy, this.groupBy, this.having, + } + + return new ClientAggregatePlan(this.context, this.statement, this.table, + this.projector, limit, offset, this.where, this.orderBy, this.groupBy, this.having, this.delegate, this.serverAggregators, this.clientAggregators); } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java index 26a0f28..8aec425 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java @@ -19,6 +19,7 @@ package org.apache.phoenix.execute; import java.sql.SQLException; import java.util.List; +import java.util.Objects; import org.apache.hadoop.hbase.client.Scan; import org.apache.phoenix.compile.ExplainPlan; @@ -106,12 +107,14 @@ public class ClientScanPlan extends ClientProcessingPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == this.limit || (limit != null && limit.equals(this.limit))) + public QueryPlan limit(Integer limit, Integer offset) { + if (Objects.equals(limit, this.limit) && + Objects.equals(offset, this.offset)) { return this; - + } + return new ClientScanPlan(this.context, this.statement, this.table, - this.projector, limit, this.offset, this.where, this.orderBy, this.delegate); - } + this.projector, limit, offset, this.where, this.orderBy, this.delegate); -} + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java index be0c7c0..adeb0db 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java @@ -204,12 +204,16 @@ public class CorrelatePlan extends DelegateQueryPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == null) + public Integer getOffset() { + return null; + } + + @Override + public QueryPlan limit(Integer limit, Integer offset) { + if (limit == null && offset == null) return this; return new ClientScanPlan(this.getContext(), this.getStatement(), this.getTableRef(), - this.getProjector(), limit, this.getOffset(), null, OrderBy.EMPTY_ORDER_BY, this); + this.getProjector(), limit, offset, null, OrderBy.EMPTY_ORDER_BY, this); } - } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java index 31ad0e9..3537bd1 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java @@ -63,7 +63,7 @@ public class DegenerateQueryPlan extends BaseQueryPlan { } @Override - public QueryPlan limit(Integer limit) { + public QueryPlan limit(Integer limit, Integer offset) { return this; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java index 3f120fd..4300245 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java @@ -122,12 +122,12 @@ public abstract class DelegateQueryPlan implements QueryPlan { return delegate.useRoundRobinIterator(); } - @Override - public Operation getOperation() { - return delegate.getOperation(); - } - - @Override + @Override + public Operation getOperation() { + return delegate.getOperation(); + } + + @Override public Integer getOffset() { return delegate.getOffset(); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java index 191b77c..9d08cef 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java @@ -449,8 +449,8 @@ public class HashJoinPlan extends DelegateQueryPlan { } @Override - public QueryPlan limit(Integer limit) { - QueryPlan delegate = this.delegate.limit(limit); + public QueryPlan limit(Integer limit, Integer offset) { + QueryPlan delegate = this.delegate.limit(limit, offset); if (delegate == this.delegate) return this; http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java index e5bf7fa..4955844 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java @@ -21,6 +21,7 @@ import java.sql.SQLException; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Objects; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Scan; @@ -113,12 +114,13 @@ public class LiteralResultIterationPlan extends BaseQueryPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == this.limit || (limit != null && limit.equals(this.limit))) + public QueryPlan limit(Integer limit, Integer offset) { + if (Objects.equals(limit, this.limit) && + Objects.equals(offset, this.offset)) { return this; - - return new LiteralResultIterationPlan(this.tuples, this.context, this.statement, this.tableRef, - this.projection, limit, this.offset, this.orderBy, this.parallelIteratorFactory); - } + } -} + return new LiteralResultIterationPlan(this.tuples, this.context, this.statement, this.tableRef, + this.projection, limit, offset, this.orderBy, this.parallelIteratorFactory); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java index d3d000b..6de9287 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java @@ -24,6 +24,7 @@ import static org.apache.phoenix.util.ScanUtil.isRoundRobinPossible; import java.sql.SQLException; import java.util.Collections; import java.util.List; +import java.util.Objects; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.client.Scan; @@ -269,16 +270,19 @@ public class ScanPlan extends BaseQueryPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == this.limit || (limit != null && limit.equals(this.limit))) + public QueryPlan limit(Integer limit, Integer offset) { + if (Objects.equals(limit, this.limit) && + Objects.equals(offset, this.offset)) { return this; - + } + try { - return new ScanPlan(this.context, this.statement, this.tableRef, this.tableRefs.iterator().next(), this.projection, - limit, this.offset, this.orderBy, this.parallelIteratorFactory, this.allowPageFilter, this.dynamicFilter); + return new ScanPlan(this.context, this.statement, this.tableRef, + this.tableRefs.iterator().next(), this.projection, + limit, offset, this.orderBy, this.parallelIteratorFactory, + this.allowPageFilter, this.dynamicFilter); } catch (SQLException e) { throw new RuntimeException(e); } } - } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java index 0d09274..bde1ed5 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java @@ -667,16 +667,18 @@ public class SortMergeJoinPlan implements QueryPlan { return false; } + @Override - public QueryPlan limit(Integer limit) { - if (limit == null) + public QueryPlan limit(Integer limit, Integer offset) { + if (limit == null && offset == null) return this; - + return new ClientScanPlan(this.getContext(), this.getStatement(), this.getTableRef(), - this.getProjector(), limit, this.getOffset(), null, OrderBy.EMPTY_ORDER_BY, this); + this.getProjector(), limit, offset, null, OrderBy.EMPTY_ORDER_BY, this); } public Set<TableRef> getSourceRefs() { return tableRefs; } } + http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java index 3952502..9f26b46 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java @@ -88,8 +88,8 @@ public class TupleProjectionPlan extends DelegateQueryPlan { } @Override - public QueryPlan limit(Integer limit) { - QueryPlan delegate = this.delegate.limit(limit); + public QueryPlan limit(Integer limit, Integer offset) { + QueryPlan delegate = this.delegate.limit(limit, offset); if (delegate == this.delegate) return this; http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java index 1467824..61d0144 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java @@ -21,6 +21,7 @@ import java.sql.ParameterMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; import org.apache.hadoop.hbase.client.Scan; @@ -203,12 +204,14 @@ public class UnionPlan implements QueryPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == this.limit || (limit != null && limit.equals(this.limit))) + public QueryPlan limit(Integer limit, Integer offset) { + if (Objects.equals(limit, this.limit) && + Objects.equals(offset, this.offset)) { return this; - + } + return new UnionPlan(this.parentContext, this.statement, this.tableRef, this.projector, - limit, this.offset, this.orderBy, this.groupBy, this.plans, this.paramMetaData); + limit, offset, this.orderBy, this.groupBy, this.plans, this.paramMetaData); } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java index 181f168..00cecf1 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java @@ -184,11 +184,11 @@ public class UnnestArrayPlan extends DelegateQueryPlan { } @Override - public QueryPlan limit(Integer limit) { - if (limit == null) + public QueryPlan limit(Integer limit, Integer offset) { + if (limit == null && offset == null) return this; - + return new ClientScanPlan(this.getContext(), this.getStatement(), this.getTableRef(), - this.getProjector(), limit, this.getOffset(), null, OrderBy.EMPTY_ORDER_BY, this); + this.getProjector(), limit, offset, null, OrderBy.EMPTY_ORDER_BY, this); } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java index a5b5779..2bbe595 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java @@ -591,7 +591,7 @@ public class PhoenixStatement implements Statement, SQLCloseable { } @Override - public QueryPlan limit(Integer limit) { + public QueryPlan limit(Integer limit, Integer offset) { return this; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/4f01c91e/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java index ecf31ab..0eb054e 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java @@ -473,7 +473,7 @@ public class ParallelIteratorsSplitTest extends BaseConnectionlessQueryTest { } @Override - public QueryPlan limit(Integer limit) { + public QueryPlan limit(Integer limit, Integer offset) { return this; }