Repository: phoenix Updated Branches: refs/heads/calcite 6ec421c12 -> caf1c6ed9
PHOENIX-2781 Support multi-tenant secondary index in Calcite-Phoenix; Fix some resource leak in PhoenixCalciteConnection; Fix PhoenixTableScan costing to cope with CALCITE-1165; Refine test framework and fix local index testing. Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/caf1c6ed Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/caf1c6ed Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/caf1c6ed Branch: refs/heads/calcite Commit: caf1c6ed94e4a26e60bbe1ddbaadaae3adebca66 Parents: 6ec421c Author: maryannxue <maryann....@gmail.com> Authored: Wed Mar 30 22:37:02 2016 -0400 Committer: maryannxue <maryann....@gmail.com> Committed: Wed Mar 30 22:37:02 2016 -0400 ---------------------------------------------------------------------- .../apache/phoenix/calcite/BaseCalciteIT.java | 66 +++- .../phoenix/calcite/BaseCalciteIndexIT.java | 63 ++++ .../phoenix/calcite/CalciteGlobalIndexIT.java | 259 ++++++++++++++++ .../apache/phoenix/calcite/CalciteIndexIT.java | 306 ------------------- .../phoenix/calcite/CalciteLocalIndexIT.java | 277 +++++++++++++++++ .../calcite/jdbc/PhoenixCalciteFactory.java | 12 + .../apache/phoenix/calcite/PhoenixTable.java | 9 +- .../calcite/rel/PhoenixAbstractAggregate.java | 10 +- .../phoenix/calcite/rel/PhoenixTableScan.java | 3 +- .../rel/PhoenixToEnumerableConverter.java | 5 +- 10 files changed, 681 insertions(+), 329 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java index 65a9c6e..607a93f 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java @@ -46,6 +46,7 @@ import org.apache.phoenix.query.QueryServices; import org.apache.phoenix.schema.TableAlreadyExistsException; import org.apache.phoenix.util.PhoenixRuntime; import org.apache.phoenix.util.PropertiesUtil; +import org.apache.phoenix.util.QueryUtil; import org.apache.phoenix.util.ReadOnlyProps; import org.junit.BeforeClass; @@ -58,6 +59,7 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { Map<String,String> props = getDefaultProps(); props.put(QueryServices.RUN_UPDATE_STATS_ASYNC, Boolean.FALSE.toString()); props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(1000)); + props.put(QueryServices.THREAD_POOL_SIZE_ATTRIB, Integer.toString(200)); setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator())); } @@ -68,6 +70,20 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { public static Start start(Properties props) { return new Start(props); } + + public static Start startPhoenixStandalone(Properties props) { + return new Start(props) { + Connection createConnection() throws Exception { + return DriverManager.getConnection( + getUrl(), + props); + } + + String getExplainPlanString() { + return "explain"; + } + }; + } public static class Start { protected final Properties props; @@ -83,6 +99,10 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { + getUrl().substring(PhoenixRuntime.JDBC_PROTOCOL.length() + 1), props); } + + String getExplainPlanString() { + return "explain plan for"; + } public Sql sql(String sql) { return new Sql(this, sql); @@ -120,12 +140,6 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { this.sql = sql; } - public static List<Object[]> getResult(ResultSet resultSet) throws SQLException { - final List<Object[]> list = Lists.newArrayList(); - populateResult(resultSet, list); - return list; - } - private static void populateResult(ResultSet resultSet, List<Object[]> list) throws SQLException { final int columnCount = resultSet.getMetaData().getColumnCount(); while (resultSet.next()) { @@ -138,11 +152,11 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { } public Sql explainIs(String expected) throws SQLException { - final List<Object[]> list = getResult("explain plan for " + sql); - if (list.size() != 1) { - fail("explain should return 1 row, got " + list.size()); - } - String explain = (String) (list.get(0)[0]); + final Statement statement = start.getConnection().createStatement(); + final ResultSet resultSet = statement.executeQuery(start.getExplainPlanString() + " " + sql); + String explain = QueryUtil.getExplainPlan(resultSet); + resultSet.close(); + statement.close(); assertEquals(explain, expected); return this; } @@ -155,10 +169,11 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { return execute; } - public List<Object[]> getResult(String sql) throws SQLException { + public List<Object[]> getResult() throws SQLException { final Statement statement = start.getConnection().createStatement(); final ResultSet resultSet = statement.executeQuery(sql); - List<Object[]> list = getResult(resultSet); + final List<Object[]> list = Lists.newArrayList(); + populateResult(resultSet, list); resultSet.close(); statement.close(); return list; @@ -195,6 +210,20 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { return this; } + public Sql sameResultAsPhoenixStandalone() throws SQLException { + Start phoenixStart = startPhoenixStandalone(this.start.props); + List<Object[]> result = phoenixStart.sql(this.sql).getResult(); + phoenixStart.close(); + return resultIs(result.toArray(new Object[result.size()][])); + } + + public Sql sameResultAsPhoenixStandalone(int orderedCount) throws SQLException { + Start phoenixStart = startPhoenixStandalone(this.start.props); + List<Object[]> result = phoenixStart.sql(this.sql).getResult(); + phoenixStart.close(); + return resultIs(orderedCount, result.toArray(new Object[result.size()][])); + } + private void checkResultOrdered(ResultSet resultSet, Object[][] expected) throws SQLException { int expectedCount = expected.length; int count = 0; @@ -225,6 +254,9 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { expectedResults.add(row); } while (resultSet.next()) { + if (actualResults.size() >= expected.length) { + fail("Got more rows than expected after getting results: " + actualResults); + } // check the ordered part Object[] row = expected[actualResults.size()]; for (int i = 0; i < orderedCount; i++) { @@ -403,7 +435,9 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { conn.commit(); if (index != null) { - conn.createStatement().execute("CREATE " + index + " " + NOSALT_TABLE_SALTED_INDEX_NAME + " ON " + NOSALT_TABLE_NAME + " (col0) SALT_BUCKETS=4"); + conn.createStatement().execute( + "CREATE " + index + " " + NOSALT_TABLE_SALTED_INDEX_NAME + " ON " + NOSALT_TABLE_NAME + " (col0)" + + (index.toUpperCase().startsWith("LOCAL") ? "" : " SALT_BUCKETS=4")); conn.commit(); } @@ -423,7 +457,9 @@ public class BaseCalciteIT extends BaseClientManagedTimeIT { if (index != null) { conn.createStatement().execute("CREATE " + index + " " + SALTED_TABLE_NOSALT_INDEX_NAME + " ON " + SALTED_TABLE_NAME + " (col0)"); - conn.createStatement().execute("CREATE " + index + " " + SALTED_TABLE_SALTED_INDEX_NAME + " ON " + SALTED_TABLE_NAME + " (col1) INCLUDE (col0) SALT_BUCKETS=4"); + conn.createStatement().execute( + "CREATE " + index + " " + SALTED_TABLE_SALTED_INDEX_NAME + " ON " + SALTED_TABLE_NAME + " (col1) INCLUDE (col0)" + + (index.toUpperCase().startsWith("LOCAL") ? "" : " SALT_BUCKETS=4")); conn.commit(); } } catch (TableAlreadyExistsException e) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java new file mode 100644 index 0000000..62943aa --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.calcite; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.Properties; + +import org.junit.Before; + +public class BaseCalciteIndexIT extends BaseCalciteIT { + + private final boolean localIndex; + + public BaseCalciteIndexIT(boolean localIndex) { + this.localIndex = localIndex; + } + + @Before + public void initTable() throws Exception { + final String url = getUrl(); + final String index = localIndex ? "LOCAL INDEX" : "INDEX"; + initATableValues(getOrganizationId(), null, url); + initSaltedTables(index); + initMultiTenantTables(index); + Connection connection = DriverManager.getConnection(url); + connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX1 ON aTable (a_string) INCLUDE (b_string, x_integer)"); + connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX2 ON aTable (b_string) INCLUDE (a_string, y_integer)"); + connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX_FULL ON aTable (b_string) INCLUDE (a_string, a_integer, a_date, a_time, a_timestamp, x_decimal, x_long, x_integer, y_integer, a_byte, a_short, a_float, a_double, a_unsigned_float, a_unsigned_double)"); + connection.createStatement().execute("UPDATE STATISTICS ATABLE"); + connection.createStatement().execute("UPDATE STATISTICS " + NOSALT_TABLE_NAME); + connection.createStatement().execute("UPDATE STATISTICS " + SALTED_TABLE_NAME); + connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_TABLE); + connection.close(); + + Properties props = new Properties(); + props.setProperty("TenantId", "10"); + connection = DriverManager.getConnection(url, props); + connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_VIEW1); + connection.close(); + + props.setProperty("TenantId", "20"); + connection = DriverManager.getConnection(url, props); + connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_VIEW2); + connection.close(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/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 new file mode 100644 index 0000000..090f47f --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java @@ -0,0 +1,259 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.calcite; + +import static org.junit.Assert.fail; + +import java.sql.SQLException; +import java.util.Properties; + +import org.junit.Test; + +public class CalciteGlobalIndexIT extends BaseCalciteIndexIT { + + public CalciteGlobalIndexIT() { + super(false); + } + + @Test public void testIndex() throws Exception { + start(true, 1000f).sql("select * from aTable where b_string = 'b'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$1], ENTITY_ID=[$2], A_STRING=[$3], B_STRING=[$0], A_INTEGER=[$4], A_DATE=[$5], A_TIME=[$6], A_TIMESTAMP=[$7], X_DECIMAL=[$8], X_LONG=[$9], X_INTEGER=[$10], Y_INTEGER=[$11], A_BYTE=[$12], A_SHORT=[$13], A_FLOAT=[$14], A_DOUBLE=[$15], A_UNSIGNED_FLOAT=[$16], A_UNSIGNED_DOUBLE=[$17])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n") + .close(); + start(true, 1000f).sql("select x_integer from aTable") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(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" + + " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n") + .close(); + start(true, 1000000f).sql("select a_string from aTable order by organization_id") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(A_STRING=[$2], ORGANIZATION_ID=[$0])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]], scanOrder=[FORWARD])\n") + .close(); + start(true, 1000f).sql("select a_integer from aTable order by a_string") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerSort(sort0=[$1], dir0=[ASC])\n" + + " PhoenixServerProject(A_INTEGER=[$4], A_STRING=[$3])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_FULL]])\n") + .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" + + " PhoenixTableScan(table=[[phoenix, IDX1]], filter=[=($0, 'a')])\n") + .close(); + start(true, 1000f).sql("select a_string, b_string from aTable where b_string = 'b'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0])\n" + + " PhoenixTableScan(table=[[phoenix, IDX2]], filter=[=($0, 'b')])\n") + .close(); + start(true, 1000f).sql("select a_string, b_string, x_integer, y_integer from aTable where b_string = 'b'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0], X_INTEGER=[$10], Y_INTEGER=[$11])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n") + .close(); + start(true, 1000f).sql("select a_string, count(*) from aTable group by a_string") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{0}], EXPR$1=[COUNT()], isOrdered=[true])\n" + + " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n") + .close(); + } + + @Test public void testSaltedIndex() throws Exception { + start(true, 1f).sql("select count(*) from " + NOSALT_TABLE_NAME + " where col0 > 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n") + .resultIs(0, new Object[][]{{999L}}) + .close(); + start(true, 1f).sql("select mypk0, mypk1, col0 from " + NOSALT_TABLE_NAME + " where col0 <= 4") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n") + .resultIs(0, new Object[][] { + {2, 3, 4}, + {1, 2, 3}}) + .close(); + start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where mypk0 < 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[<($0, 3)])\n") + .resultIs(0, new Object[][] { + {1, 2, 3, 4}, + {2, 3, 4, 5}}) + .close(); + start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col0 > 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n") + .resultIs(0, new Object[][]{{999L}}) + .close(); + start(true, 1f).sql("select mypk0, mypk1, col0 from " + SALTED_TABLE_NAME + " where col0 <= 4") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n") + .resultIs(0, new Object[][] { + {2, 3, 4}, + {1, 2, 3}}) + .close(); + start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col1 > 4") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 4)])\n") + .resultIs(0, new Object[][]{{999L}}) + .close(); + start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where col1 <= 5 order by col1") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 5)], scanOrder=[FORWARD])\n") + .resultIs(new Object[][] { + {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") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerJoin(condition=[AND(=($0, $4), =($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") + .resultIs(0, new Object[][] { + {501, 502, 503, 504, 501, 502, 503, 504}}) + .close(); + } + + @Test public void testMultiTenant() throws Exception { + Properties props = getConnectionProps(true, 1f); + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '10' and id <= '0004'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '10'), <=($1, '0004'))])\n") + .resultIs(0, new Object[][] { + {"10", "0002", 3, 4, 5}, + {"10", "0003", 4, 5, 6}, + {"10", "0004", 5, 6, 7}}) + .close(); + + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '20' and col1 < 8") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(TENANT_ID=[$0], ID=[$2], COL0=[$3], COL1=[CAST($1):INTEGER], COL2=[$4])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '20'), <(CAST($1):INTEGER, 8))])\n") + .resultIs(0, new Object[][] { + {"20", "0004", 5, 6, 7}, + {"20", "0005", 6, 7, 8}}) + .close(); + + try { + start(props).sql("select * from " + MULTI_TENANT_VIEW1) + .explainIs("") + .close(); + fail("Should have got SQLException."); + } catch (SQLException e) { + } + + props.setProperty("TenantId", "15"); + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where id = '0284'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0284')])\n") + .resultIs(0, new Object[][] { + {"0284", 285, 286, 287}}) + .close(); + + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 > 1000") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 1000)])\n") + .resultIs(0, new Object[][] { + {"0999", 1000, 1001, 1002}, + {"1000", 1001, 1002, 1003}, + {"1001", 1002, 1003, 1004}, + {"1002", 1003, 1004, 1005}}) + .close(); + + try { + start(props).sql("select * from " + MULTI_TENANT_VIEW1) + .explainIs("") + .close(); + fail("Should have got SQLException."); + } catch (SQLException e) { + } + + props.setProperty("TenantId", "10"); + start(props).sql("select * from " + MULTI_TENANT_VIEW1 + " where id = '0512'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0512')])\n") + .resultIs(0, new Object[][] { + {"0512", 513, 514, 515}}) + .close(); + + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 <= 6") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 6)])\n") + .resultIs(0, new Object[][] { + {"0002", 3, 4, 5}, + {"0003", 4, 5, 6}, + {"0004", 5, 6, 7}}) + .close(); + + start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW1 + " where col0 >= 1000") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, S1, IDX_MULTITENANT_TEST_VIEW1]], filter=[>=(CAST($0):INTEGER, 1000)])\n") + .resultIs(0, new Object[][] { + {"0999", 1000}, + {"1000", 1001}, + {"1001", 1002}}) + .close(); + + props.setProperty("TenantId", "20"); + start(props).sql("select * from " + MULTI_TENANT_VIEW2 + " where id = '0765'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(>($3, 7), =(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0765'))])\n") + .resultIs(0, new Object[][] { + {"0765", 766, 767, 768}}) + .close(); + + start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " where col0 between 272 and 275") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], filter=[AND(>=(CAST($0):INTEGER, 272), <=(CAST($0):INTEGER, 275))])\n") + .resultIs(0, new Object[][] { + {"0271", 272}, + {"0272", 273}, + {"0273", 274}, + {"0274", 275}}) + .close(); + + start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " order by col0 limit 5") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixLimit(fetch=[5])\n" + + " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], scanOrder=[FORWARD])\n") + .resultIs(new Object[][] { + {"0005", 6}, + {"0006", 7}, + {"0007", 8}, + {"0008", 9}, + {"0009", 10}}) + .close(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIndexIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIndexIT.java deleted file mode 100644 index 067d0fc..0000000 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIndexIT.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.phoenix.calcite; - -import static org.junit.Assert.fail; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Properties; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -@RunWith(Parameterized.class) -public class CalciteIndexIT extends BaseCalciteIT { - - private final boolean localIndex; - - public CalciteIndexIT(boolean localIndex) { - this.localIndex = localIndex; - } - - @Parameters(name="localIndex = {0}") - public static Collection<Boolean[]> data() { - return Arrays.asList(new Boolean[][] { - { false }, { true } - }); - } - - @Before - public void initTable() throws Exception { - final String url = getUrl(); - final String index = localIndex ? "LOCAL INDEX" : "INDEX"; - initATableValues(getOrganizationId(), null, url); - initSaltedTables(index); - initMultiTenantTables(index); - Connection connection = DriverManager.getConnection(url); - connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX1 ON aTable (a_string) INCLUDE (b_string, x_integer)"); - connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX2 ON aTable (b_string) INCLUDE (a_string, y_integer)"); - connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX_FULL ON aTable (b_string) INCLUDE (a_string, a_integer, a_date, a_time, a_timestamp, x_decimal, x_long, x_integer, y_integer, a_byte, a_short, a_float, a_double, a_unsigned_float, a_unsigned_double)"); - connection.createStatement().execute("UPDATE STATISTICS ATABLE"); - connection.createStatement().execute("UPDATE STATISTICS " + NOSALT_TABLE_NAME); - connection.createStatement().execute("UPDATE STATISTICS " + SALTED_TABLE_NAME); - connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_TABLE); - connection.close(); - - Properties props = new Properties(); - props.setProperty("TenantId", "10"); - connection = DriverManager.getConnection(url, props); - connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_VIEW1); - connection.close(); - - props.setProperty("TenantId", "20"); - connection = DriverManager.getConnection(url, props); - connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_VIEW2); - connection.close(); - } - - @Test public void testIndex() throws Exception { - start(true, 1000f).sql("select * from aTable where b_string = 'b'") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(ORGANIZATION_ID=[$1], ENTITY_ID=[$2], A_STRING=[$3], B_STRING=[$0], A_INTEGER=[$4], A_DATE=[$5], A_TIME=[$6], A_TIMESTAMP=[$7], X_DECIMAL=[$8], X_LONG=[$9], X_INTEGER=[$10], Y_INTEGER=[$11], A_BYTE=[$12], A_SHORT=[$13], A_FLOAT=[$14], A_DOUBLE=[$15], A_UNSIGNED_FLOAT=[$16], A_UNSIGNED_DOUBLE=[$17])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n") - .close(); - start(true, 1000f).sql("select x_integer from aTable") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(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" + - " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n") - .close(); - start(true, 1000000f).sql("select a_string from aTable order by organization_id") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(A_STRING=[$2], ORGANIZATION_ID=[$0])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], scanOrder=[FORWARD])\n") - .close(); - start(true, 1000f).sql("select a_integer from aTable order by a_string") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerSort(sort0=[$1], dir0=[ASC])\n" + - " PhoenixServerProject(A_INTEGER=[$4], A_STRING=[$3])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_FULL]])\n") - .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" + - " PhoenixTableScan(table=[[phoenix, IDX1]], filter=[=($0, 'a')])\n") - .close(); - start(true, 1000f).sql("select a_string, b_string from aTable where b_string = 'b'") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0])\n" + - " PhoenixTableScan(table=[[phoenix, IDX2]], filter=[=($0, 'b')])\n") - .close(); - start(true, 1000f).sql("select a_string, b_string, x_integer, y_integer from aTable where b_string = 'b'") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0], X_INTEGER=[$10], Y_INTEGER=[$11])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n") - .close(); - start(true, 1000f).sql("select a_string, count(*) from aTable group by a_string") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerAggregate(group=[{0}], EXPR$1=[COUNT()], isOrdered=[true])\n" + - " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n") - .close(); - } - - @Test public void testSaltedIndex() throws Exception { - start(true, 1f).sql("select count(*) from " + NOSALT_TABLE_NAME + " where col0 > 3") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + - " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n") - .resultIs(0, new Object[][]{{999L}}) - .close(); - start(true, 1f).sql("select mypk0, mypk1, col0 from " + NOSALT_TABLE_NAME + " where col0 <= 4") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" + - " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n") - .resultIs(0, new Object[][] { - {2, 3, 4}, - {1, 2, 3}}) - .close(); - start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where mypk0 < 3") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[<($0, 3)])\n") - .resultIs(0, new Object[][] { - {1, 2, 3, 4}, - {2, 3, 4, 5}}) - .close(); - start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col0 > 3") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n") - .resultIs(0, new Object[][]{{999L}}) - .close(); - start(true, 1f).sql("select mypk0, mypk1, col0 from " + SALTED_TABLE_NAME + " where col0 <= 4") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n") - .resultIs(0, new Object[][] { - {2, 3, 4}, - {1, 2, 3}}) - .close(); - start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col1 > 4") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + - " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 4)])\n") - .resultIs(0, new Object[][]{{999L}}) - .close(); - start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where col1 <= 5 order by col1") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" + - " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 5)], scanOrder=[FORWARD])\n") - .resultIs(new Object[][] { - {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") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerJoin(condition=[AND(=($0, $4), =($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") - .resultIs(0, new Object[][] { - {501, 502, 503, 504, 501, 502, 503, 504}}) - .close(); - } - - @Test public void testMultiTenant() throws Exception { - Properties props = getConnectionProps(true, 1f); - start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '10' and id <= '0004'") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '10'), <=($1, '0004'))])\n") - .resultIs(0, new Object[][] { - {"10", "0002", 3, 4, 5}, - {"10", "0003", 4, 5, 6}, - {"10", "0004", 5, 6, 7}}) - .close(); - - start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '20' and col1 < 8") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(TENANT_ID=[$0], ID=[$2], COL0=[$3], COL1=[CAST($1):INTEGER], COL2=[$4])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '20'), <(CAST($1):INTEGER, 8))])\n") - .resultIs(0, new Object[][] { - {"20", "0004", 5, 6, 7}, - {"20", "0005", 6, 7, 8}}) - .close(); - - try { - start(props).sql("select * from " + MULTI_TENANT_VIEW1) - .explainIs("") - .close(); - fail("Should have got SQLException."); - } catch (SQLException e) { - } - - props.setProperty("TenantId", "15"); - start(props).sql("select * from " + MULTI_TENANT_TABLE + " where id = '0284'") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0284')])\n") - .resultIs(0, new Object[][] { - {"0284", 285, 286, 287}}) - .close(); - - start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 > 1000") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 1000)])\n") - .resultIs(0, new Object[][] { - {"0999", 1000, 1001, 1002}, - {"1000", 1001, 1002, 1003}, - {"1001", 1002, 1003, 1004}, - {"1002", 1003, 1004, 1005}}) - .close(); - - try { - start(props).sql("select * from " + MULTI_TENANT_VIEW1) - .explainIs("") - .close(); - fail("Should have got SQLException."); - } catch (SQLException e) { - } - - props.setProperty("TenantId", "10"); - start(props).sql("select * from " + MULTI_TENANT_VIEW1 + " where id = '0512'") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0512')])\n") - .resultIs(0, new Object[][] { - {"0512", 513, 514, 515}}) - .close(); - - start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 <= 6") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" + - " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 6)])\n") - .resultIs(0, new Object[][] { - {"0002", 3, 4, 5}, - {"0003", 4, 5, 6}, - {"0004", 5, 6, 7}}) - .close(); - - start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW1 + " where col0 >= 1000") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + - " PhoenixTableScan(table=[[phoenix, S1, IDX_MULTITENANT_TEST_VIEW1]], filter=[>=(CAST($0):INTEGER, 1000)])\n") - .resultIs(0, new Object[][] { - {"0999", 1000}, - {"1000", 1001}, - {"1001", 1002}}) - .close(); - - props.setProperty("TenantId", "20"); - start(props).sql("select * from " + MULTI_TENANT_VIEW2 + " where id = '0765'") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(>($3, 7), =(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0765'))])\n") - .resultIs(0, new Object[][] { - {"0765", 766, 767, 768}}) - .close(); - - start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " where col0 between 272 and 275") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + - " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], filter=[AND(>=(CAST($0):INTEGER, 272), <=(CAST($0):INTEGER, 275))])\n") - .resultIs(0, new Object[][] { - {"0271", 272}, - {"0272", 273}, - {"0273", 274}, - {"0274", 275}}) - .close(); - - start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " order by col0 limit 5") - .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixLimit(fetch=[5])\n" + - " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + - " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], scanOrder=[FORWARD])\n") - .resultIs(new Object[][] { - {"0005", 6}, - {"0006", 7}, - {"0007", 8}, - {"0008", 9}, - {"0009", 10}}) - .close(); - } - -} http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/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 new file mode 100644 index 0000000..30ec0bc --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteLocalIndexIT.java @@ -0,0 +1,277 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.calcite; + +import static org.junit.Assert.fail; + +import java.sql.SQLException; +import java.util.Properties; + +import org.junit.Test; + +public class CalciteLocalIndexIT extends BaseCalciteIndexIT { + + public CalciteLocalIndexIT() { + super(true); + } + + @Test public void testIndex() throws Exception { + start(true, 1000f).sql("select * from aTable where b_string = 'b'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ORGANIZATION_ID=[$1], ENTITY_ID=[$2], A_STRING=[$3], B_STRING=[$0], A_INTEGER=[$4], A_DATE=[$5], A_TIME=[$6], A_TIMESTAMP=[$7], X_DECIMAL=[$8], X_LONG=[$9], X_INTEGER=[$10], Y_INTEGER=[$11], A_BYTE=[$12], A_SHORT=[$13], A_FLOAT=[$14], A_DOUBLE=[$15], A_UNSIGNED_FLOAT=[$16], A_UNSIGNED_DOUBLE=[$17])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n") + .close(); + start(true, 1000f).sql("select x_integer from aTable") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(X_INTEGER=[$10])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + /*.explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(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" + + " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n") + .close(); + start(true, 1000000f).sql("select a_string from aTable order by organization_id") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(A_STRING=[$2], ORGANIZATION_ID=[$0])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]], scanOrder=[FORWARD])\n") + .close(); + start(true, 1000f).sql("select a_integer from aTable order by a_string") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerSort(sort0=[$1], dir0=[ASC])\n" + + " PhoenixServerProject(A_INTEGER=[$4], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") + /*.explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerSort(sort0=[$1], dir0=[ASC])\n" + + " PhoenixServerProject(A_INTEGER=[$4], A_STRING=[$3])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_FULL]])\n")*/ + .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" + + " PhoenixTableScan(table=[[phoenix, IDX1]], filter=[=($0, 'a')])\n") + .close(); + start(true, 1000f).sql("select a_string, b_string from aTable where b_string = 'b'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0])\n" + + " PhoenixTableScan(table=[[phoenix, IDX2]], filter=[=($0, 'b')])\n") + .close(); + start(true, 1000f).sql("select a_string, b_string, x_integer, y_integer from aTable where b_string = 'b'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0], X_INTEGER=[$10], Y_INTEGER=[$11])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n") + .close(); + start(true, 1000f).sql("select a_string, count(*) from aTable group by a_string") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{0}], EXPR$1=[COUNT()], isOrdered=[true])\n" + + " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n") + .close(); + } + + @Test public void testSaltedIndex() throws Exception { + start(true, 1f).sql("select count(*) from " + NOSALT_TABLE_NAME + " where col0 > 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n") + .resultIs(0, new Object[][]{{999L}}) + .close(); + start(true, 1f).sql("select mypk0, mypk1, col0 from " + NOSALT_TABLE_NAME + " where col0 <= 4") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n") + .resultIs(0, new Object[][] { + {2, 3, 4}, + {1, 2, 3}}) + .close(); + start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where mypk0 < 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[<($0, 3)])\n") + .resultIs(0, new Object[][] { + {1, 2, 3, 4}, + {2, 3, 4, 5}}) + .close(); + start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col0 > 3") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n") + .sameResultAsPhoenixStandalone(0) + /*.resultIs(0, new Object[][]{{999L}})*/ + .close(); + start(true, 1f).sql("select mypk0, mypk1, col0 from " + SALTED_TABLE_NAME + " where col0 <= 4") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n") + .resultIs(0, new Object[][] { + {2, 3, 4}, + {1, 2, 3}}) + .close(); + start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col1 > 4") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 4)])\n") + .sameResultAsPhoenixStandalone(0) + /*.resultIs(0, new Object[][]{{999L}})*/ + .close(); + start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where col1 <= 5 order by col1") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 5)], scanOrder=[FORWARD])\n") + .resultIs(new Object[][] { + {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") + .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" + + " 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")*/ + .resultIs(0, new Object[][] { + {501, 502, 503, 504, 501, 502, 503, 504}}) + .close(); + } + + @Test public void testMultiTenant() throws Exception { + Properties props = getConnectionProps(true, 1f); + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '10' and id <= '0004'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '10'), <=($1, '0004'))])\n") + .resultIs(0, new Object[][] { + {"10", "0002", 3, 4, 5}, + {"10", "0003", 4, 5, 6}, + {"10", "0004", 5, 6, 7}}) + .close(); + + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '20' and col1 < 8") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(TENANT_ID=[$0], ID=[$2], COL0=[$3], COL1=[CAST($1):INTEGER], COL2=[$4])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '20'), <(CAST($1):INTEGER, 8))])\n") +// .resultIs(0, new Object[][] { +// {"20", "0004", 5, 6, 7}, +// {"20", "0005", 6, 7, 8}}) + .close(); + + try { + start(props).sql("select * from " + MULTI_TENANT_VIEW1) + .explainIs("") + .close(); + fail("Should have got SQLException."); + } catch (SQLException e) { + } + + props.setProperty("TenantId", "15"); + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where id = '0284'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0284')])\n") + .resultIs(0, new Object[][] { + {"0284", 285, 286, 287}}) + .close(); + + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 > 1000") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 1000)])\n") +// .resultIs(0, new Object[][] { +// {"0999", 1000, 1001, 1002}, +// {"1000", 1001, 1002, 1003}, +// {"1001", 1002, 1003, 1004}, +// {"1002", 1003, 1004, 1005}}) + .close(); + + try { + start(props).sql("select * from " + MULTI_TENANT_VIEW1) + .explainIs("") + .close(); + fail("Should have got SQLException."); + } catch (SQLException e) { + } + + props.setProperty("TenantId", "10"); + start(props).sql("select * from " + MULTI_TENANT_VIEW1 + " where id = '0512'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0512')])\n") + .resultIs(0, new Object[][] { + {"0512", 513, 514, 515}}) + .close(); + + start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 <= 6") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" + + " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 6)])\n") +// .resultIs(0, new Object[][] { +// {"0002", 3, 4, 5}, +// {"0003", 4, 5, 6}, +// {"0004", 5, 6, 7}}) + .close(); + + start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW1 + " where col0 >= 1000") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, S1, IDX_MULTITENANT_TEST_VIEW1]], filter=[>=(CAST($0):INTEGER, 1000)])\n") + .sameResultAsPhoenixStandalone(0) + /*.resultIs(0, new Object[][] { + {"0999", 1000}, + {"1000", 1001}, + {"1001", 1002}})*/ + .close(); + + props.setProperty("TenantId", "20"); + start(props).sql("select * from " + MULTI_TENANT_VIEW2 + " where id = '0765'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(>($3, 7), =(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0765'))])\n") + .resultIs(0, new Object[][] { + {"0765", 766, 767, 768}}) + .close(); + + start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " where col0 between 272 and 275") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], filter=[AND(>=(CAST($0):INTEGER, 272), <=(CAST($0):INTEGER, 275))])\n") + .sameResultAsPhoenixStandalone(0) + /*.resultIs(0, new Object[][] { + {"0271", 272}, + {"0272", 273}, + {"0273", 274}, + {"0274", 275}})*/ + .close(); + + start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " order by col0 limit 5") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixLimit(fetch=[5])\n" + + " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" + + " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], scanOrder=[FORWARD])\n") + .sameResultAsPhoenixStandalone() + /*.resultIs(new Object[][] { + {"0005", 6}, + {"0006", 7}, + {"0007", 8}, + {"0008", 9}, + {"0009", 10}})*/ + .close(); + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java b/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java index e769b08..5b9fd1d 100644 --- a/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java +++ b/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java @@ -25,6 +25,7 @@ import org.apache.calcite.avatica.UnregisteredDriver; import org.apache.calcite.jdbc.CalciteConnectionImpl; import org.apache.calcite.jdbc.CalciteFactory; import org.apache.calcite.jdbc.Driver; +import org.apache.phoenix.calcite.PhoenixSchema; public class PhoenixCalciteFactory extends CalciteFactory { @@ -95,6 +96,17 @@ public class PhoenixCalciteFactory extends CalciteFactory { super(driver, factory, url, info, CalciteSchema.createRootSchema(true, false), typeFactory); } + + public void close() throws SQLException { + for (String subSchemaName : getRootSchema().getSubSchemaNames()) { + try { + PhoenixSchema phoenixSchema = getRootSchema() + .getSubSchema(subSchemaName).unwrap(PhoenixSchema.class); + phoenixSchema.pc.close(); + } catch (ClassCastException e) { + } + } + } } private static class PhoenixCalciteStatement extends CalciteStatement { http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/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 0b45322..1fcc9d3 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 @@ -2,6 +2,7 @@ package org.apache.phoenix.calcite; import java.io.IOException; import java.sql.SQLException; +import java.util.Iterator; import java.util.List; import org.apache.calcite.plan.RelOptTable; @@ -40,6 +41,7 @@ import org.apache.phoenix.schema.SortOrder; import org.apache.phoenix.schema.TableRef; import org.apache.phoenix.schema.stats.StatisticsUtil; import org.apache.phoenix.schema.types.PDataType; +import org.apache.phoenix.util.MetaDataUtil; import org.apache.phoenix.util.SchemaUtil; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -67,7 +69,12 @@ public class PhoenixTable extends AbstractTable implements TranslatableTable { List<PColumn> columns = Lists.newArrayList(pTable.getColumns()); if (pTable.getViewIndexId() != null) { - columns.remove((pTable.getBucketNum() == null ? 0 : 1) + (pTable.isMultiTenant() ? 1 : 0)); + for (Iterator<PColumn> iter = columns.iterator(); iter.hasNext();) { + if (iter.next().getName().getString().equals(MetaDataUtil.VIEW_INDEX_ID_COLUMN_NAME)) { + iter.remove(); + break; + } + } } if (pTable.isMultiTenant()) { columns.remove(pTable.getBucketNum() == null ? 0 : 1); http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractAggregate.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractAggregate.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractAggregate.java index de9f0c2..16c97cc 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractAggregate.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixAbstractAggregate.java @@ -17,7 +17,6 @@ import org.apache.calcite.rel.core.AggregateCall; import org.apache.calcite.rel.metadata.RelMetadataQuery; import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.ImmutableIntList; -import org.apache.calcite.util.Util; import org.apache.phoenix.calcite.CalciteUtils; import org.apache.phoenix.compile.GroupByCompiler.GroupBy; import org.apache.phoenix.compile.QueryPlan; @@ -105,9 +104,10 @@ abstract public class PhoenixAbstractAggregate extends Aggregate implements Phoe return planner.getCostFactory().makeInfiniteCost(); double rowCount = mq.getRowCount(this); - double bytesPerRow = mq.getAverageRowSize(this); - if (isOrderedGroupBy) { - rowCount = (rowCount * rowCount) / Util.nLogN(rowCount); + double spoolSize = 0; + if (!isOrderedGroupBy) { + double bytesPerRow = mq.getAverageRowSize(this); + spoolSize = rowCount * bytesPerRow * 6 /* map size */; } // Aggregates with more aggregate functions cost a bit more float multiplier = 1f + (float) aggCalls.size() * 0.125f; @@ -118,7 +118,7 @@ abstract public class PhoenixAbstractAggregate extends Aggregate implements Phoe multiplier += 0.0125f; } } - return planner.getCostFactory().makeCost(rowCount * multiplier * bytesPerRow, 0, 0); + return planner.getCostFactory().makeCost(rowCount * multiplier + spoolSize, 0, 0); } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/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 691b5ac..c510e3b 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 @@ -206,7 +206,8 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { } } return planner.getCostFactory() - .makeCost(byteCount, byteCount + 1, 0) + .makeCost(byteCount + 1, byteCount + 1, 0) + .multiplyBy(0.5) /* data scan only */ .multiplyBy(SERVER_FACTOR) .multiplyBy(PHOENIX_FACTOR); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/caf1c6ed/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 dd092a8..3d0aa22 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 @@ -58,7 +58,10 @@ public class PhoenixToEnumerableConverter extends ConverterImpl implements Enume } @Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { - return super.computeSelfCost(planner, mq).multiplyBy(.1); + return super.computeSelfCost(planner, mq) + .multiplyBy(.1) + .multiplyBy(PhoenixRel.PHOENIX_FACTOR) + .multiplyBy(PhoenixRel.SERVER_FACTOR); } @Override