http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseJoinIT.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseJoinIT.java index 0000000,f1c1808..1b3731c mode 000000,100644..100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseJoinIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseJoinIT.java @@@ -1,0 -1,456 +1,456 @@@ + /* + * 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.end2end; + + import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertTrue; + + import java.sql.Connection; + import java.sql.Date; + import java.sql.DriverManager; + import java.sql.PreparedStatement; + import java.sql.SQLException; + import java.sql.Timestamp; + import java.text.SimpleDateFormat; + import java.util.Map; + import java.util.regex.Pattern; + + import org.apache.phoenix.util.SchemaUtil; + import org.apache.phoenix.util.StringUtil; + import org.junit.Before; + + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.Maps; + + public abstract class BaseJoinIT extends ParallelStatsDisabledIT { - protected static final String JOIN_SCHEMA = "Join"; - protected static final String JOIN_ORDER_TABLE = "OrderTable"; - protected static final String JOIN_CUSTOMER_TABLE = "CustomerTable"; - protected static final String JOIN_ITEM_TABLE = "ItemTable"; - protected static final String JOIN_SUPPLIER_TABLE = "SupplierTable"; - protected static final String JOIN_COITEM_TABLE = "CoitemTable"; - protected static final String JOIN_ORDER_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_ORDER_TABLE + '"'; - protected static final String JOIN_CUSTOMER_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_CUSTOMER_TABLE + '"'; - protected static final String JOIN_ITEM_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_ITEM_TABLE + '"'; - protected static final String JOIN_SUPPLIER_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_SUPPLIER_TABLE + '"'; - protected static final String JOIN_COITEM_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_COITEM_TABLE + '"'; ++ public static final String JOIN_SCHEMA = "Join"; ++ public static final String JOIN_ORDER_TABLE = "OrderTable"; ++ public static final String JOIN_CUSTOMER_TABLE = "CustomerTable"; ++ public static final String JOIN_ITEM_TABLE = "ItemTable"; ++ public static final String JOIN_SUPPLIER_TABLE = "SupplierTable"; ++ public static final String JOIN_COITEM_TABLE = "CoitemTable"; ++ public static final String JOIN_ORDER_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_ORDER_TABLE + '"'; ++ public static final String JOIN_CUSTOMER_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_CUSTOMER_TABLE + '"'; ++ public static final String JOIN_ITEM_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_ITEM_TABLE + '"'; ++ public static final String JOIN_SUPPLIER_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_SUPPLIER_TABLE + '"'; ++ public static final String JOIN_COITEM_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_COITEM_TABLE + '"'; + + private static final Map<String,String> tableDDLMap; + + static { + ImmutableMap.Builder<String,String> builder = ImmutableMap.builder(); + builder.put(JOIN_ORDER_TABLE_FULL_NAME, "create table " + JOIN_ORDER_TABLE_FULL_NAME + + " (\"order_id\" varchar(15) not null primary key, " + + " \"customer_id\" varchar(10), " + + " \"item_id\" varchar(10), " + + " price integer, " + + " quantity integer, " + - " date timestamp)"); ++ " \"DATE\" timestamp)"); + builder.put(JOIN_CUSTOMER_TABLE_FULL_NAME, "create table " + JOIN_CUSTOMER_TABLE_FULL_NAME + + " (\"customer_id\" varchar(10) not null primary key, " + + " name varchar, " + + " phone varchar(12), " + + " address varchar, " + + " loc_id varchar(5), " + - " date date)"); ++ " \"DATE\" date)"); + builder.put(JOIN_ITEM_TABLE_FULL_NAME, "create table " + JOIN_ITEM_TABLE_FULL_NAME + + " (\"item_id\" varchar(10) not null primary key, " + + " name varchar, " + + " price integer, " + + " discount1 integer, " + + " discount2 integer, " + + " \"supplier_id\" varchar(10), " + + " description varchar)"); + builder.put(JOIN_SUPPLIER_TABLE_FULL_NAME, "create table " + JOIN_SUPPLIER_TABLE_FULL_NAME + + " (\"supplier_id\" varchar(10) not null primary key, " + + " name varchar, " + + " phone varchar(12), " + + " address varchar, " + + " loc_id varchar(5))"); + builder.put(JOIN_COITEM_TABLE_FULL_NAME, "create table " + JOIN_COITEM_TABLE_FULL_NAME + + " (item_id varchar(10) NOT NULL, " + + " item_name varchar NOT NULL, " + + " co_item_id varchar(10), " + + " co_item_name varchar " + + " CONSTRAINT pk PRIMARY KEY (item_id, item_name)) " + + " SALT_BUCKETS=4"); + tableDDLMap = builder.build(); + } + + protected String seqName; + protected String schemaName; + protected final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + protected final String[] plans; + private final String[] indexDDL; + private final Map<String,String> virtualNameToRealNameMap = Maps.newHashMap(); + + public BaseJoinIT(String[] indexDDL, String[] plans) { + this.indexDDL = indexDDL; + this.plans = plans; + } + + protected String getTableName(Connection conn, String virtualName) throws Exception { + String realName = virtualNameToRealNameMap.get(virtualName); + if (realName == null) { + realName = SchemaUtil.getTableName(schemaName, generateUniqueName()); + virtualNameToRealNameMap.put(virtualName, realName); + createTable(conn, virtualName, realName); + initValues(conn, virtualName, realName); + createIndexes(conn, virtualName, realName); + } + return realName; + } + - protected String getDisplayTableName(Connection conn, String virtualName) throws Exception { ++ public String getDisplayTableName(Connection conn, String virtualName) throws Exception { + return getTableName(conn, virtualName); + } + - private void createTable(Connection conn, String virtualName, String realName) throws SQLException { ++ public static void createTable(Connection conn, String virtualName, String realName) throws SQLException { + String ddl = tableDDLMap.get(virtualName); + if (ddl == null) { + throw new IllegalStateException("Expected to find " + virtualName + " in " + tableDDLMap); + } + ddl = ddl.replace(virtualName, realName); + conn.createStatement().execute(ddl); + } + + @Before + public void createSchema() throws SQLException { + Connection conn = DriverManager.getConnection(getUrl()); + try { + schemaName = "S_" + generateUniqueName(); + seqName = "SEQ_" + generateUniqueName(); + conn.createStatement().execute("CREATE SEQUENCE " + seqName); + } finally { + conn.close(); + } + } + + private String translateToVirtualPlan(String actualPlan) { + int size = virtualNameToRealNameMap.size(); + String[] virtualNames = new String[size+1]; + String[] realNames = new String[size+1]; + int count = 0; + for (Map.Entry<String, String>entry : virtualNameToRealNameMap.entrySet()) { + virtualNames[count] = entry.getKey(); + realNames[count] = entry.getValue(); + count++; + } + realNames[count] = schemaName; + virtualNames[count]= JOIN_SCHEMA; + String convertedPlan = StringUtil.replace(actualPlan, realNames, virtualNames); + return convertedPlan; + } + + protected void assertPlansMatch(String virtualPlanRegEx, String actualPlan) { + String convertedPlan = translateToVirtualPlan(actualPlan); + assertTrue("\"" + convertedPlan + "\" does not match \"" + virtualPlanRegEx + "\"", Pattern.matches(virtualPlanRegEx, convertedPlan)); + } + + protected void assertPlansEqual(String virtualPlan, String actualPlan) { + String convertedPlan = translateToVirtualPlan(actualPlan); + assertEquals(virtualPlan, convertedPlan); + } + - private static void initValues(Connection conn, String virtualName, String realName) throws Exception { ++ public static void initValues(Connection conn, String virtualName, String realName) throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + if (virtualName.equals(JOIN_CUSTOMER_TABLE_FULL_NAME)) { + // Insert into customer table + PreparedStatement stmt = conn.prepareStatement( + "upsert into " + realName + + " (\"customer_id\", " + + " NAME, " + + " PHONE, " + + " ADDRESS, " + + " LOC_ID, " + - " DATE) " + ++ " \"DATE\") " + + "values (?, ?, ?, ?, ?, ?)"); + stmt.setString(1, "0000000001"); + stmt.setString(2, "C1"); + stmt.setString(3, "999-999-1111"); + stmt.setString(4, "101 XXX Street"); + stmt.setString(5, "10001"); + stmt.setDate(6, new Date(format.parse("2013-11-01 10:20:36").getTime())); + stmt.execute(); + + stmt.setString(1, "0000000002"); + stmt.setString(2, "C2"); + stmt.setString(3, "999-999-2222"); + stmt.setString(4, "202 XXX Street"); + stmt.setString(5, null); + stmt.setDate(6, new Date(format.parse("2013-11-25 16:45:07").getTime())); + stmt.execute(); + + stmt.setString(1, "0000000003"); + stmt.setString(2, "C3"); + stmt.setString(3, "999-999-3333"); + stmt.setString(4, "303 XXX Street"); + stmt.setString(5, null); + stmt.setDate(6, new Date(format.parse("2013-11-25 10:06:29").getTime())); + stmt.execute(); + + stmt.setString(1, "0000000004"); + stmt.setString(2, "C4"); + stmt.setString(3, "999-999-4444"); + stmt.setString(4, "404 XXX Street"); + stmt.setString(5, "10004"); + stmt.setDate(6, new Date(format.parse("2013-11-22 14:22:56").getTime())); + stmt.execute(); + + stmt.setString(1, "0000000005"); + stmt.setString(2, "C5"); + stmt.setString(3, "999-999-5555"); + stmt.setString(4, "505 XXX Street"); + stmt.setString(5, "10005"); + stmt.setDate(6, new Date(format.parse("2013-11-27 09:37:50").getTime())); + stmt.execute(); + + stmt.setString(1, "0000000006"); + stmt.setString(2, "C6"); + stmt.setString(3, "999-999-6666"); + stmt.setString(4, "606 XXX Street"); + stmt.setString(5, "10001"); + stmt.setDate(6, new Date(format.parse("2013-11-01 10:20:36").getTime())); + stmt.execute(); + } else if (virtualName.equals(JOIN_ITEM_TABLE_FULL_NAME)) { + + // Insert into item table + PreparedStatement stmt = conn.prepareStatement( + "upsert into " + realName + + " (\"item_id\", " + + " NAME, " + + " PRICE, " + + " DISCOUNT1, " + + " DISCOUNT2, " + + " \"supplier_id\", " + + " DESCRIPTION) " + + "values (?, ?, ?, ?, ?, ?, ?)"); + stmt.setString(1, "0000000001"); + stmt.setString(2, "T1"); + stmt.setInt(3, 100); + stmt.setInt(4, 5); + stmt.setInt(5, 10); + stmt.setString(6, "0000000001"); + stmt.setString(7, "Item T1"); + stmt.execute(); + + stmt.setString(1, "0000000002"); + stmt.setString(2, "T2"); + stmt.setInt(3, 200); + stmt.setInt(4, 5); + stmt.setInt(5, 8); + stmt.setString(6, "0000000001"); + stmt.setString(7, "Item T2"); + stmt.execute(); + + stmt.setString(1, "0000000003"); + stmt.setString(2, "T3"); + stmt.setInt(3, 300); + stmt.setInt(4, 8); + stmt.setInt(5, 12); + stmt.setString(6, "0000000002"); + stmt.setString(7, "Item T3"); + stmt.execute(); + + stmt.setString(1, "0000000004"); + stmt.setString(2, "T4"); + stmt.setInt(3, 400); + stmt.setInt(4, 6); + stmt.setInt(5, 10); + stmt.setString(6, "0000000002"); + stmt.setString(7, "Item T4"); + stmt.execute(); + + stmt.setString(1, "0000000005"); + stmt.setString(2, "T5"); + stmt.setInt(3, 500); + stmt.setInt(4, 8); + stmt.setInt(5, 15); + stmt.setString(6, "0000000005"); + stmt.setString(7, "Item T5"); + stmt.execute(); + + stmt.setString(1, "0000000006"); + stmt.setString(2, "T6"); + stmt.setInt(3, 600); + stmt.setInt(4, 8); + stmt.setInt(5, 15); + stmt.setString(6, "0000000006"); + stmt.setString(7, "Item T6"); + stmt.execute(); + + stmt.setString(1, "invalid001"); + stmt.setString(2, "INVALID-1"); + stmt.setInt(3, 0); + stmt.setInt(4, 0); + stmt.setInt(5, 0); + stmt.setString(6, "0000000000"); + stmt.setString(7, "Invalid item for join test"); + stmt.execute(); + } else if (virtualName.equals(JOIN_SUPPLIER_TABLE_FULL_NAME)) { + + // Insert into supplier table + PreparedStatement stmt = conn.prepareStatement( + "upsert into " + realName + + " (\"supplier_id\", " + + " NAME, " + + " PHONE, " + + " ADDRESS, " + + " LOC_ID) " + + "values (?, ?, ?, ?, ?)"); + stmt.setString(1, "0000000001"); + stmt.setString(2, "S1"); + stmt.setString(3, "888-888-1111"); + stmt.setString(4, "101 YYY Street"); + stmt.setString(5, "10001"); + stmt.execute(); + + stmt.setString(1, "0000000002"); + stmt.setString(2, "S2"); + stmt.setString(3, "888-888-2222"); + stmt.setString(4, "202 YYY Street"); + stmt.setString(5, "10002"); + stmt.execute(); + + stmt.setString(1, "0000000003"); + stmt.setString(2, "S3"); + stmt.setString(3, "888-888-3333"); + stmt.setString(4, "303 YYY Street"); + stmt.setString(5, null); + stmt.execute(); + + stmt.setString(1, "0000000004"); + stmt.setString(2, "S4"); + stmt.setString(3, "888-888-4444"); + stmt.setString(4, "404 YYY Street"); + stmt.setString(5, null); + stmt.execute(); + + stmt.setString(1, "0000000005"); + stmt.setString(2, "S5"); + stmt.setString(3, "888-888-5555"); + stmt.setString(4, "505 YYY Street"); + stmt.setString(5, "10005"); + stmt.execute(); + + stmt.setString(1, "0000000006"); + stmt.setString(2, "S6"); + stmt.setString(3, "888-888-6666"); + stmt.setString(4, "606 YYY Street"); + stmt.setString(5, "10006"); + stmt.execute(); + } else if (virtualName.equals(JOIN_ORDER_TABLE_FULL_NAME)) { + + // Insert into order table + PreparedStatement stmt = conn.prepareStatement( + "upsert into " + realName + + " (\"order_id\", " + + " \"customer_id\", " + + " \"item_id\", " + + " PRICE, " + + " QUANTITY," + - " DATE) " + ++ " \"DATE\") " + + "values (?, ?, ?, ?, ?, ?)"); + stmt.setString(1, "000000000000001"); + stmt.setString(2, "0000000004"); + stmt.setString(3, "0000000001"); + stmt.setInt(4, 100); + stmt.setInt(5, 1000); + stmt.setTimestamp(6, new Timestamp(format.parse("2013-11-22 14:22:56").getTime())); + stmt.execute(); + + stmt.setString(1, "000000000000002"); + stmt.setString(2, "0000000003"); + stmt.setString(3, "0000000006"); + stmt.setInt(4, 552); + stmt.setInt(5, 2000); + stmt.setTimestamp(6, new Timestamp(format.parse("2013-11-25 10:06:29").getTime())); + stmt.execute(); + + stmt.setString(1, "000000000000003"); + stmt.setString(2, "0000000002"); + stmt.setString(3, "0000000002"); + stmt.setInt(4, 190); + stmt.setInt(5, 3000); + stmt.setTimestamp(6, new Timestamp(format.parse("2013-11-25 16:45:07").getTime())); + stmt.execute(); + + stmt.setString(1, "000000000000004"); + stmt.setString(2, "0000000004"); + stmt.setString(3, "0000000006"); + stmt.setInt(4, 510); + stmt.setInt(5, 4000); + stmt.setTimestamp(6, new Timestamp(format.parse("2013-11-26 13:26:04").getTime())); + stmt.execute(); + + stmt.setString(1, "000000000000005"); + stmt.setString(2, "0000000005"); + stmt.setString(3, "0000000003"); + stmt.setInt(4, 264); + stmt.setInt(5, 5000); + stmt.setTimestamp(6, new Timestamp(format.parse("2013-11-27 09:37:50").getTime())); + stmt.execute(); + } else if (virtualName.equals(JOIN_COITEM_TABLE_FULL_NAME)) { + // Insert into coitem table + PreparedStatement stmt = conn.prepareStatement( + "upsert into " + realName + + " (item_id, " + + " item_name, " + + " co_item_id, " + + " co_item_name) " + + "values (?, ?, ?, ?)"); + stmt.setString(1, "0000000001"); + stmt.setString(2, "T1"); + stmt.setString(3, "0000000002"); + stmt.setString(4, "T3"); + stmt.execute(); + + stmt.setString(1, "0000000004"); + stmt.setString(2, "T4"); + stmt.setString(3, "0000000003"); + stmt.setString(4, "T3"); + stmt.execute(); + + stmt.setString(1, "0000000003"); + stmt.setString(2, "T4"); + stmt.setString(3, "0000000005"); + stmt.setString(4, "T5"); + stmt.execute(); + + stmt.setString(1, "0000000006"); + stmt.setString(2, "T6"); + stmt.setString(3, "0000000001"); + stmt.setString(4, "T1"); + stmt.execute(); + } + + conn.commit(); + } + + protected void createIndexes(Connection conn, String virtualName, String realName) throws Exception { + if (indexDDL != null && indexDDL.length > 0) { + for (String ddl : indexDDL) { + String newDDL = ddl.replace(virtualName, realName); + if (!newDDL.equals(ddl)) { + conn.createStatement().execute(newDDL); + } + } + } + } + + }
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseOwnClusterIT.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseOwnClusterIT.java index 222efcb,44bd3a1..d76cdfd --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseOwnClusterIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseOwnClusterIT.java @@@ -27,4 -29,9 +29,9 @@@ public class BaseOwnClusterIT extends B public static void doTeardown() throws Exception { tearDownMiniCluster(); } + + @After + public void cleanUpAfterTest() throws Exception { - deletePriorMetaData(HConstants.LATEST_TIMESTAMP, getUrl()); ++ deletePriorMetaData(HConstants.LATEST_TIMESTAMP, getOldUrl()); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java index 7afed13,0d42e27..baf8e9a --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java @@@ -1605,24 -1557,27 +1557,27 @@@ public class HashJoinIT extends BaseJoi @Test public void testStarJoin() throws Exception { - String[] query = new String[5]; - query[0] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o JOIN " - + JOIN_CUSTOMER_TABLE_FULL_NAME + " c ON o.\"customer_id\" = c.\"customer_id\" JOIN " - + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" ORDER BY \"order_id\""; - query[1] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o, " - + JOIN_CUSTOMER_TABLE_FULL_NAME + " c, " - + JOIN_ITEM_TABLE_FULL_NAME + " i WHERE o.\"item_id\" = i.\"item_id\" AND o.\"customer_id\" = c.\"customer_id\" ORDER BY \"order_id\""; - query[2] = "SELECT /*+ NO_STAR_JOIN*/ \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o JOIN " - + JOIN_CUSTOMER_TABLE_FULL_NAME + " c ON o.\"customer_id\" = c.\"customer_id\" JOIN " - + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" ORDER BY \"order_id\""; - query[3] = "SELECT /*+ NO_STAR_JOIN*/ \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM (" + JOIN_ORDER_TABLE_FULL_NAME + " o, " - + JOIN_CUSTOMER_TABLE_FULL_NAME + " c), " - + JOIN_ITEM_TABLE_FULL_NAME + " i WHERE o.\"item_id\" = i.\"item_id\" AND o.\"customer_id\" = c.\"customer_id\" ORDER BY \"order_id\""; - query[4] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o, (" - + JOIN_CUSTOMER_TABLE_FULL_NAME + " c, " - + JOIN_ITEM_TABLE_FULL_NAME + " i) WHERE o.\"item_id\" = i.\"item_id\" AND o.\"customer_id\" = c.\"customer_id\" ORDER BY \"order_id\""; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(getUrl(), props); + String tableName1 = getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME); + String tableName2 = getTableName(conn, JOIN_CUSTOMER_TABLE_FULL_NAME); + String tableName3 = getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME); + String[] query = new String[5]; - query[0] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.date FROM " + tableName1 + " o JOIN " ++ query[0] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + tableName1 + " o JOIN " + + tableName2 + " c ON o.\"customer_id\" = c.\"customer_id\" JOIN " + + tableName3 + " i ON o.\"item_id\" = i.\"item_id\" ORDER BY \"order_id\""; - query[1] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.date FROM " + tableName1 + " o, " ++ query[1] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + tableName1 + " o, " + + tableName2 + " c, " + + tableName3 + " i WHERE o.\"item_id\" = i.\"item_id\" AND o.\"customer_id\" = c.\"customer_id\" ORDER BY \"order_id\""; - query[2] = "SELECT /*+ NO_STAR_JOIN*/ \"order_id\", c.name, i.name iname, quantity, o.date FROM " + tableName1 + " o JOIN " ++ query[2] = "SELECT /*+ NO_STAR_JOIN*/ \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + tableName1 + " o JOIN " + + tableName2 + " c ON o.\"customer_id\" = c.\"customer_id\" JOIN " + + tableName3 + " i ON o.\"item_id\" = i.\"item_id\" ORDER BY \"order_id\""; - query[3] = "SELECT /*+ NO_STAR_JOIN*/ \"order_id\", c.name, i.name iname, quantity, o.date FROM (" + tableName1 + " o, " ++ query[3] = "SELECT /*+ NO_STAR_JOIN*/ \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM (" + tableName1 + " o, " + + tableName2 + " c), " + + tableName3 + " i WHERE o.\"item_id\" = i.\"item_id\" AND o.\"customer_id\" = c.\"customer_id\" ORDER BY \"order_id\""; - query[4] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.date FROM " + tableName1 + " o, (" ++ query[4] = "SELECT \"order_id\", c.name, i.name iname, quantity, o.\"DATE\" FROM " + tableName1 + " o, (" + + tableName2 + " c, " + + tableName3 + " i) WHERE o.\"item_id\" = i.\"item_id\" AND o.\"customer_id\" = c.\"customer_id\" ORDER BY \"order_id\""; try { for (int i = 0; i < query.length; i++) { PreparedStatement statement = conn.prepareStatement(query[i]); @@@ -1831,14 -1790,17 +1790,17 @@@ @Test public void testLeftRightJoin() throws Exception { - String query1 = "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o LEFT JOIN " - + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" RIGHT JOIN " - + JOIN_SUPPLIER_TABLE_FULL_NAME + " s ON i.\"supplier_id\" = s.\"supplier_id\" ORDER BY \"order_id\", s.\"supplier_id\" DESC"; - String query2 = "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o LEFT JOIN " - + "(" + JOIN_ITEM_TABLE_FULL_NAME + " i RIGHT JOIN " + JOIN_SUPPLIER_TABLE_FULL_NAME + " s ON i.\"supplier_id\" = s.\"supplier_id\")" - + " ON o.\"item_id\" = i.\"item_id\" ORDER BY \"order_id\", s.\"supplier_id\" DESC"; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(getUrl(), props); + String tableName1 = getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME); + String tableName2 = getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME); + String tableName3 = getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME); - String query1 = "SELECT \"order_id\", i.name, s.name, quantity, date FROM " + tableName1 + " o LEFT JOIN " ++ String query1 = "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + tableName1 + " o LEFT JOIN " + + tableName2 + " i ON o.\"item_id\" = i.\"item_id\" RIGHT JOIN " + + tableName3 + " s ON i.\"supplier_id\" = s.\"supplier_id\" ORDER BY \"order_id\", s.\"supplier_id\" DESC"; - String query2 = "SELECT \"order_id\", i.name, s.name, quantity, date FROM " + tableName1 + " o LEFT JOIN " ++ String query2 = "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + tableName1 + " o LEFT JOIN " + + "(" + tableName2 + " i RIGHT JOIN " + tableName3 + " s ON i.\"supplier_id\" = s.\"supplier_id\")" + + " ON o.\"item_id\" = i.\"item_id\" ORDER BY \"order_id\", s.\"supplier_id\" DESC"; try { PreparedStatement statement = conn.prepareStatement(query1); ResultSet rs = statement.executeQuery(); @@@ -1934,15 -1896,15 +1896,15 @@@ @Test public void testMultiLeftJoin() throws Exception { - String[] queries = { - "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o LEFT JOIN " - + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" LEFT JOIN " - + JOIN_SUPPLIER_TABLE_FULL_NAME + " s ON i.\"supplier_id\" = s.\"supplier_id\"", - "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o LEFT JOIN " - + "(" + JOIN_ITEM_TABLE_FULL_NAME + " i LEFT JOIN " + JOIN_SUPPLIER_TABLE_FULL_NAME + " s ON i.\"supplier_id\" = s.\"supplier_id\") " - + "ON o.\"item_id\" = i.\"item_id\""}; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(getUrl(), props); + String[] queries = { - "SELECT \"order_id\", i.name, s.name, quantity, date FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o LEFT JOIN " ++ "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o LEFT JOIN " + + getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME) + " i ON o.\"item_id\" = i.\"item_id\" LEFT JOIN " + + getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME) + " s ON i.\"supplier_id\" = s.\"supplier_id\"", - "SELECT \"order_id\", i.name, s.name, quantity, date FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o LEFT JOIN " ++ "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o LEFT JOIN " + + "(" + getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME) + " i LEFT JOIN " + getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME) + " s ON i.\"supplier_id\" = s.\"supplier_id\") " + + "ON o.\"item_id\" = i.\"item_id\""}; try { for (String query : queries) { PreparedStatement statement = conn.prepareStatement(query); @@@ -1987,12 -1949,12 +1949,12 @@@ @Test public void testMultiRightJoin() throws Exception { - String query = "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o RIGHT JOIN " - + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" RIGHT JOIN " - + JOIN_SUPPLIER_TABLE_FULL_NAME + " s ON i.\"supplier_id\" = s.\"supplier_id\" ORDER BY \"order_id\", s.\"supplier_id\" DESC"; - Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(getUrl(), props); - String query = "SELECT \"order_id\", i.name, s.name, quantity, date FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o RIGHT JOIN " ++ String query = "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o RIGHT JOIN " + + getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME) + " i ON o.\"item_id\" = i.\"item_id\" RIGHT JOIN " + + getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME) + " s ON i.\"supplier_id\" = s.\"supplier_id\" ORDER BY \"order_id\", s.\"supplier_id\" DESC"; + try { PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); @@@ -2064,10 -2026,10 +2026,10 @@@ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); props.setProperty(QueryServices.SCAN_RESULT_CHUNK_SIZE, "1"); Connection conn = DriverManager.getConnection(getUrl(), props); - String query = "SELECT \"order_id\", i.name, s.name, quantity, date FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o RIGHT JOIN " ++ String query = "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o RIGHT JOIN " + + getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME) + " i ON o.\"item_id\" = i.\"item_id\" RIGHT JOIN " + + getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME) + " s ON i.\"supplier_id\" = s.\"supplier_id\" ORDER BY \"order_id\", s.\"supplier_id\" DESC"; + try { PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); @@@ -2444,10 -2406,10 +2406,10 @@@ @Test public void testJoinWithDifferentDateJoinKeyTypes() throws Exception { - String query = "SELECT \"order_id\", c.name, o.\"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o INNER JOIN " - + JOIN_CUSTOMER_TABLE_FULL_NAME + " c ON o.\"customer_id\" = c.\"customer_id\" AND o.\"DATE\" = c.\"DATE\""; Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(getUrl(), props); - String query = "SELECT \"order_id\", c.name, o.date FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o INNER JOIN " - + getTableName(conn, JOIN_CUSTOMER_TABLE_FULL_NAME) + " c ON o.\"customer_id\" = c.\"customer_id\" AND o.date = c.date"; ++ String query = "SELECT \"order_id\", c.name, o.\"DATE\" FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o INNER JOIN " ++ + getTableName(conn, JOIN_CUSTOMER_TABLE_FULL_NAME) + " c ON o.\"customer_id\" = c.\"customer_id\" AND o.\"DATE\" = c.\"DATE\""; try { PreparedStatement statement = conn.prepareStatement(query); ResultSet rs = statement.executeQuery(); @@@ -2662,14 -2624,14 +2624,14 @@@ + " item_name varchar not null, " + " supplier_name varchar, " + " quantity integer, " - + " date timestamp " + + " \"DATE\" timestamp " + " CONSTRAINT pk PRIMARY KEY (\"order_id\", item_name))"); conn.createStatement().execute("UPSERT INTO " + tempTable - + "(\"order_id\", item_name, supplier_name, quantity, date) " - + "SELECT \"order_id\", i.name, s.name, quantity, date FROM " + + "(\"order_id\", item_name, supplier_name, quantity, \"DATE\") " + + "SELECT \"order_id\", i.name, s.name, quantity, \"DATE\" FROM " - + JOIN_ORDER_TABLE_FULL_NAME + " o LEFT JOIN " - + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" LEFT JOIN " - + JOIN_SUPPLIER_TABLE_FULL_NAME + " s ON i.\"supplier_id\" = s.\"supplier_id\""); + + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + " o LEFT JOIN " + + getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME) + " i ON o.\"item_id\" = i.\"item_id\" LEFT JOIN " + + getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME) + " s ON i.\"supplier_id\" = s.\"supplier_id\""); conn.createStatement().execute("UPSERT INTO " + tempTable + "(\"order_id\", item_name, quantity) " + "SELECT 'ORDER_SUM', i.name, sum(quantity) FROM " @@@ -3150,17 -3112,17 +3112,17 @@@ @Test public void testNestedSubqueries() throws Exception { - String query1 = "SELECT q.iname, count(c.name), min(q.sname), max(o.quantity) FROM (SELECT \"customer_id\" cid, \"item_id\" iid, quantity FROM " + JOIN_ORDER_TABLE_FULL_NAME + ") AS o LEFT JOIN " - + "(SELECT i.iid iid, s.name sname, i.name iname FROM (SELECT \"supplier_id\" sid, name FROM " + JOIN_SUPPLIER_TABLE_FULL_NAME + ") AS s RIGHT JOIN (SELECT \"item_id\" iid, name, \"supplier_id\" sid FROM " + JOIN_ITEM_TABLE_FULL_NAME + ") AS i ON i.sid = s.sid) AS q" + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + Connection conn = DriverManager.getConnection(getUrl(), props); + String query1 = "SELECT q.iname, count(c.name), min(q.sname), max(o.quantity) FROM (SELECT \"customer_id\" cid, \"item_id\" iid, quantity FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + ") AS o LEFT JOIN " + + "(SELECT i.iid iid, s.name sname, i.name iname FROM (SELECT \"supplier_id\" sid, name FROM " + getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME) + ") AS s RIGHT JOIN (SELECT \"item_id\" iid, name, \"supplier_id\" sid FROM " + getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME) + ") AS i ON i.sid = s.sid) AS q" + " ON o.iid = q.iid LEFT JOIN (SELECT \"customer_id\" cid, name FROM " - + JOIN_CUSTOMER_TABLE_FULL_NAME + ") AS c ON c.cid = o.cid GROUP BY q.iname ORDER BY q.iname"; - String query2 = "SELECT * FROM (SELECT \"customer_id\" cid, name, phone, address, loc_id, \"DATE\" FROM " + JOIN_CUSTOMER_TABLE_FULL_NAME + ") AS c INNER JOIN " - + "(SELECT o.oid ooid, o.cid ocid, o.iid oiid, o.price * o.quantity, o.\"DATE\" odate, qi.iiid iiid, qi.iname iname, qi.iprice iprice, qi.idiscount1 idiscount1, qi.idiscount2 idiscount2, qi.isid isid, qi.idescription idescription, qi.ssid ssid, qi.sname sname, qi.sphone sphone, qi.saddress saddress, qi.sloc_id sloc_id FROM (SELECT \"item_id\" iid, \"customer_id\" cid, \"order_id\" oid, price, quantity, \"DATE\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + ") AS o INNER JOIN " - + "(SELECT i.iid iiid, i.name iname, i.price iprice, i.discount1 idiscount1, i.discount2 idiscount2, i.sid isid, i.description idescription, s.sid ssid, s.name sname, s.phone sphone, s.address saddress, s.loc_id sloc_id FROM (SELECT \"supplier_id\" sid, name, phone, address, loc_id FROM " + JOIN_SUPPLIER_TABLE_FULL_NAME + ") AS s RIGHT JOIN (SELECT \"item_id\" iid, name, price, discount1, discount2, \"supplier_id\" sid, description FROM " + JOIN_ITEM_TABLE_FULL_NAME + ") AS i ON i.sid = s.sid) as qi" + + getTableName(conn, JOIN_CUSTOMER_TABLE_FULL_NAME) + ") AS c ON c.cid = o.cid GROUP BY q.iname ORDER BY q.iname"; - String query2 = "SELECT * FROM (SELECT \"customer_id\" cid, name, phone, address, loc_id, date FROM " + getTableName(conn, JOIN_CUSTOMER_TABLE_FULL_NAME) + ") AS c INNER JOIN " - + "(SELECT o.oid ooid, o.cid ocid, o.iid oiid, o.price * o.quantity, o.date odate, qi.iiid iiid, qi.iname iname, qi.iprice iprice, qi.idiscount1 idiscount1, qi.idiscount2 idiscount2, qi.isid isid, qi.idescription idescription, qi.ssid ssid, qi.sname sname, qi.sphone sphone, qi.saddress saddress, qi.sloc_id sloc_id FROM (SELECT \"item_id\" iid, \"customer_id\" cid, \"order_id\" oid, price, quantity, date FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + ") AS o INNER JOIN " ++ String query2 = "SELECT * FROM (SELECT \"customer_id\" cid, name, phone, address, loc_id, \"DATE\" FROM " + getTableName(conn, JOIN_CUSTOMER_TABLE_FULL_NAME) + ") AS c INNER JOIN " ++ + "(SELECT o.oid ooid, o.cid ocid, o.iid oiid, o.price * o.quantity, o.\"DATE\" odate, qi.iiid iiid, qi.iname iname, qi.iprice iprice, qi.idiscount1 idiscount1, qi.idiscount2 idiscount2, qi.isid isid, qi.idescription idescription, qi.ssid ssid, qi.sname sname, qi.sphone sphone, qi.saddress saddress, qi.sloc_id sloc_id FROM (SELECT \"item_id\" iid, \"customer_id\" cid, \"order_id\" oid, price, quantity, \"DATE\" FROM " + getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME) + ") AS o INNER JOIN " + + "(SELECT i.iid iiid, i.name iname, i.price iprice, i.discount1 idiscount1, i.discount2 idiscount2, i.sid isid, i.description idescription, s.sid ssid, s.name sname, s.phone sphone, s.address saddress, s.loc_id sloc_id FROM (SELECT \"supplier_id\" sid, name, phone, address, loc_id FROM " + getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME) + ") AS s RIGHT JOIN (SELECT \"item_id\" iid, name, price, discount1, discount2, \"supplier_id\" sid, description FROM " + getTableName(conn, JOIN_ITEM_TABLE_FULL_NAME) + ") AS i ON i.sid = s.sid) as qi" + " ON o.iid = qi.iiid) as qo ON c.cid = qo.ocid" + " WHERE c.cid <= '0000000005' AND qo.ooid != '000000000000003' AND qo.iname != 'T3' ORDER BY c.cid, qo.iname"; - Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); - Connection conn = DriverManager.getConnection(getUrl(), props); try { PreparedStatement statement = conn.prepareStatement(query1); ResultSet rs = statement.executeQuery(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/it/java/org/apache/phoenix/end2end/OrderByIT.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java index b5461ce,0000000..d00161b mode 100644,000000..100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixPrepareImpl.java @@@ -1,497 -1,0 +1,497 @@@ +package org.apache.phoenix.calcite; + +import java.lang.reflect.Type; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.calcite.adapter.enumerable.EnumerableRules; +import org.apache.calcite.jdbc.CalcitePrepare; +import org.apache.calcite.jdbc.CalciteSchema; +import org.apache.calcite.linq4j.Queryable; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelOptCostFactory; +import org.apache.calcite.plan.RelOptPlanner; +import org.apache.calcite.plan.RelOptRule; +import org.apache.calcite.prepare.CalcitePrepareImpl; +import org.apache.calcite.prepare.Prepare.Materialization; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.logical.LogicalSort; +import org.apache.calcite.rel.rules.JoinCommuteRule; +import org.apache.calcite.rel.rules.SortProjectTransposeRule; +import org.apache.calcite.rel.rules.SortUnionTransposeRule; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.runtime.Hook; +import org.apache.calcite.runtime.Hook.Closeable; +import org.apache.calcite.schema.SchemaPlus; +import org.apache.calcite.sql.SqlColumnDefInPkConstraintNode; +import org.apache.calcite.sql.SqlColumnDefNode; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlIndexExpressionNode; +import org.apache.calcite.sql.SqlKind; +import org.apache.calcite.sql.SqlLiteral; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.SqlOptionNode; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.parser.SqlParserUtil; +import org.apache.calcite.tools.Program; +import org.apache.calcite.tools.Programs; +import org.apache.calcite.util.Holder; +import org.apache.calcite.util.NlsString; +import org.apache.hadoop.hbase.util.Pair; +import org.apache.phoenix.calcite.parse.SqlCreateIndex; +import org.apache.phoenix.calcite.parse.SqlCreateSequence; +import org.apache.phoenix.calcite.parse.SqlCreateTable; +import org.apache.phoenix.calcite.parse.SqlDropIndex; +import org.apache.phoenix.calcite.parse.SqlDropSequence; +import org.apache.phoenix.calcite.parse.SqlDropTable; +import org.apache.phoenix.calcite.parse.SqlUpdateStatistics; +import org.apache.phoenix.calcite.parser.PhoenixParserImpl; +import org.apache.phoenix.calcite.rel.PhoenixRel; +import org.apache.phoenix.calcite.rel.PhoenixServerProject; +import org.apache.phoenix.calcite.rel.PhoenixTemporarySort; +import org.apache.phoenix.calcite.rules.PhoenixFilterScanMergeRule; +import org.apache.phoenix.calcite.rules.PhoenixForwardTableScanRule; +import org.apache.phoenix.calcite.rules.PhoenixJoinSingleValueAggregateMergeRule; +import org.apache.phoenix.calcite.rules.PhoenixMergeSortUnionRule; +import org.apache.phoenix.calcite.rules.PhoenixOrderedAggregateRule; +import org.apache.phoenix.calcite.rules.PhoenixReverseTableScanRule; +import org.apache.phoenix.calcite.rules.PhoenixSortServerJoinTransposeRule; +import org.apache.phoenix.calcite.rules.PhoenixTableScanColumnRefRule; +import org.apache.phoenix.compile.CreateIndexCompiler; +import org.apache.phoenix.compile.CreateSequenceCompiler; +import org.apache.phoenix.compile.CreateTableCompiler; +import org.apache.phoenix.compile.MutationPlan; +import org.apache.phoenix.jdbc.PhoenixConnection; +import org.apache.phoenix.jdbc.PhoenixStatement; +import org.apache.phoenix.jdbc.PhoenixStatement.Operation; +import org.apache.phoenix.parse.ColumnDef; +import org.apache.phoenix.parse.ColumnDefInPkConstraint; +import org.apache.phoenix.parse.ColumnName; +import org.apache.phoenix.parse.CreateIndexStatement; +import org.apache.phoenix.parse.CreateSequenceStatement; +import org.apache.phoenix.parse.CreateTableStatement; +import org.apache.phoenix.parse.DropIndexStatement; +import org.apache.phoenix.parse.DropSequenceStatement; +import org.apache.phoenix.parse.DropTableStatement; +import org.apache.phoenix.parse.IndexKeyConstraint; +import org.apache.phoenix.parse.NamedNode; +import org.apache.phoenix.parse.NamedTableNode; +import org.apache.phoenix.parse.ParseNode; +import org.apache.phoenix.parse.ParseNodeFactory; +import org.apache.phoenix.parse.PrimaryKeyConstraint; +import org.apache.phoenix.parse.SQLParser; +import org.apache.phoenix.parse.TableName; +import org.apache.phoenix.parse.UDFParseNode; +import org.apache.phoenix.parse.UpdateStatisticsStatement; +import org.apache.phoenix.schema.MetaDataClient; +import org.apache.phoenix.schema.PTable.IndexType; +import org.apache.phoenix.schema.PTableType; +import org.apache.phoenix.schema.SortOrder; + +import com.google.common.base.Function; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Lists; + +public class PhoenixPrepareImpl extends CalcitePrepareImpl { + public static final ThreadLocal<String> THREAD_SQL_STRING = + new ThreadLocal<>(); + + protected final RelOptRule[] defaultConverterRules; + + public PhoenixPrepareImpl(RelOptRule[] defaultConverterRules) { + super(); + this.defaultConverterRules = defaultConverterRules; + } + + @Override + protected SqlParser.ConfigBuilder createParserConfig() { + return super.createParserConfig() + .setParserFactory(PhoenixParserImpl.FACTORY); + } + + protected SqlParser createParser(String sql, + SqlParser.ConfigBuilder parserConfig) { + THREAD_SQL_STRING.set(sql); + return SqlParser.create(sql, parserConfig.build()); + } + + @Override + protected RelOptCluster createCluster(RelOptPlanner planner, + RexBuilder rexBuilder) { + RelOptCluster cluster = super.createCluster(planner, rexBuilder); + cluster.setMetadataProvider(PhoenixRel.METADATA_PROVIDER); + return cluster; + } + + @Override + protected RelOptPlanner createPlanner( + final CalcitePrepare.Context prepareContext, + org.apache.calcite.plan.Context externalContext, + RelOptCostFactory costFactory) { + RelOptPlanner planner = super.createPlanner(prepareContext, externalContext, costFactory); + + planner.removeRule(EnumerableRules.ENUMERABLE_SEMI_JOIN_RULE); + planner.removeRule(JoinCommuteRule.INSTANCE); + planner.addRule(JoinCommuteRule.SWAP_OUTER); + planner.removeRule(SortUnionTransposeRule.INSTANCE); + planner.addRule(SortUnionTransposeRule.MATCH_NULL_FETCH); + planner.addRule(new SortProjectTransposeRule( + PhoenixTemporarySort.class, + PhoenixServerProject.class, + "PhoenixSortProjectTransposeRule")); + + for (RelOptRule rule : this.defaultConverterRules) { + planner.addRule(rule); + } + planner.addRule(PhoenixFilterScanMergeRule.INSTANCE); + planner.addRule(PhoenixTableScanColumnRefRule.INSTANCE); + planner.addRule(PhoenixJoinSingleValueAggregateMergeRule.INSTANCE); + planner.addRule(PhoenixMergeSortUnionRule.INSTANCE); + planner.addRule(PhoenixOrderedAggregateRule.INSTANCE); + planner.addRule(PhoenixSortServerJoinTransposeRule.INSTANCE); + planner.addRule(new PhoenixForwardTableScanRule(LogicalSort.class)); + planner.addRule(new PhoenixForwardTableScanRule(PhoenixTemporarySort.class)); + planner.addRule(new PhoenixReverseTableScanRule(LogicalSort.class)); + planner.addRule(new PhoenixReverseTableScanRule(PhoenixTemporarySort.class)); + + return planner; + } + + public <T> CalciteSignature<T> prepareQueryable( + Context context, + Queryable<T> queryable) { + List<Closeable> hooks = addHooks( + context.getRootSchema(), + context.config().materializationsEnabled()); + try { + return super.prepareQueryable(context, queryable); + } finally { + for (Closeable hook : hooks) { + hook.close(); + } + } + } + + public <T> CalciteSignature<T> prepareSql( + Context context, + Query<T> query, + Type elementType, + long maxRowCount) { + List<Closeable> hooks = addHooks( + context.getRootSchema(), + context.config().materializationsEnabled()); + try { + return super.prepareSql(context, query, elementType, maxRowCount); + } finally { + for (Closeable hook : hooks) { + hook.close(); + } + } + } + + private List<Closeable> addHooks(final CalciteSchema rootSchema, boolean materializationEnabled) { + final List<Closeable> hooks = Lists.newArrayList(); + + hooks.add(Hook.PARSE_TREE.add(new Function<Object[], Object>() { + @Override + public Object apply(Object[] input) { + for (CalciteSchema schema : rootSchema.getSubSchemaMap().values()) { + if (schema.schema instanceof PhoenixSchema) { + ((PhoenixSchema) schema.schema).clear(); + for (CalciteSchema subSchema : schema.getSubSchemaMap().values()) { + ((PhoenixSchema) subSchema.schema).clear(); + } + } + } + return null; + } + })); + + hooks.add(Hook.TRIMMED.add(new Function<RelNode, Object>() { + @Override + public Object apply(RelNode root) { + for (CalciteSchema schema : rootSchema.getSubSchemaMap().values()) { + if (schema.schema instanceof PhoenixSchema) { + ((PhoenixSchema) schema.schema).defineIndexesAsMaterializations(); + for (CalciteSchema subSchema : schema.getSubSchemaMap().values()) { + ((PhoenixSchema) subSchema.schema).defineIndexesAsMaterializations(); + } + } + } + return null; + } + })); + + hooks.add(Hook.PROGRAM.add(new Function<org.apache.calcite.util.Pair<List<Materialization>, Holder<Program>>, Object>() { + @Override + public Object apply( + org.apache.calcite.util.Pair<List<Materialization>, Holder<Program>> input) { + input.getValue().set(Programs.standard(PhoenixRel.METADATA_PROVIDER)); + return null; + } + })); + + return hooks; + } + + @Override + public void executeDdl(Context context, SqlNode node) { + try { + final ParseNodeFactory nodeFactory = new ParseNodeFactory(); + final PhoenixConnection connection = getPhoenixConnection(context.getRootSchema().plus()); + switch (node.getKind()) { + case CREATE_TABLE: + case CREATE_VIEW: { + final SqlCreateTable table = (SqlCreateTable) node; + final PTableType tableType = table.getKind() == SqlKind.CREATE_TABLE ? PTableType.TABLE : PTableType.VIEW; + final TableName name; + if (table.tableName.isSimple()) { + name = TableName.create(null, table.tableName.getSimple()); + } else { + name = TableName.create(table.tableName.names.get(0), table.tableName.names.get(1)); + } + final ListMultimap<String, Pair<String, Object>> props = convertOptions(table.tableOptions); + final List<ColumnDef> columnDefs = Lists.newArrayList(); + for (SqlNode columnDef : table.columnDefs) { + columnDefs.add(((SqlColumnDefNode) columnDef).columnDef); + } + final PrimaryKeyConstraint pkConstraint; + if (table.pkConstraint == null) { + pkConstraint = null; + } else { + final List<ColumnDefInPkConstraint> pkColumns = Lists.newArrayList(); + for (SqlNode pkColumn : table.pkConstraintColumnDefs) { + pkColumns.add(((SqlColumnDefInPkConstraintNode) pkColumn).pkConstraint); + } + pkConstraint = nodeFactory.primaryKey(table.pkConstraint.getSimple(), pkColumns); + } + final TableName baseTableName; + final ParseNode where; + if (table.baseTableName == null) { + baseTableName = tableType == PTableType.TABLE ? null : name; + where = null; + } else { + if (table.baseTableName.isSimple()) { + baseTableName = TableName.create(null, table.baseTableName.getSimple()); + } else { + baseTableName = TableName.create(table.baseTableName.names.get(0), table.baseTableName.names.get(1)); + } + where = convertSqlNodeToParseNode(table.whereNode); + } + final List<ParseNode> splitNodes = convertSplits(table.splitKeyList, nodeFactory); + final CreateTableStatement create = nodeFactory.createTable( + name, props, columnDefs, pkConstraint, + splitNodes, tableType, table.ifNotExists.booleanValue(), + baseTableName, where, 0); + try (final PhoenixStatement stmt = new PhoenixStatement(connection)) { + final CreateTableCompiler compiler = new CreateTableCompiler(stmt, Operation.UPSERT); + final MutationPlan plan = compiler.compile(create); + plan.execute(); + } + break; + } + case CREATE_INDEX: { + final SqlCreateIndex index = (SqlCreateIndex) node; + final NamedNode name = NamedNode.caseSensitiveNamedNode(index.indexName.getSimple()); + final IndexType indexType = index.isLocal.booleanValue() ? IndexType.LOCAL : IndexType.GLOBAL; + final TableName dataTableName; + if (index.dataTableName.isSimple()) { + dataTableName = TableName.create(null, index.dataTableName.getSimple()); + } else { + dataTableName = TableName.create(index.dataTableName.names.get(0), index.dataTableName.names.get(1)); + } + final NamedTableNode dataTable = NamedTableNode.create(dataTableName); + final List<Pair<ParseNode, SortOrder>> indexKeys = Lists.newArrayList(); + for (SqlNode e : index.expressions) { + SqlIndexExpressionNode indexExpression = (SqlIndexExpressionNode) e; + ParseNode exprNode = convertSqlNodeToParseNode(indexExpression.expression); + indexKeys.add(new Pair<ParseNode, SortOrder>(exprNode, indexExpression.sortOrder)); + } + final IndexKeyConstraint indexKeyConstraint = nodeFactory.indexKey(indexKeys); + final List<ColumnName> includeColumns; + if (SqlNodeList.isEmptyList(index.includeColumns)) { + includeColumns = null; + } else { + includeColumns = Lists.newArrayList(); + for (SqlNode e : index.includeColumns) { + SqlIdentifier n = (SqlIdentifier) e; + ColumnName columnName; + if (n.isSimple()) { + columnName = ColumnName.caseSensitiveColumnName(n.getSimple()); + } else { + columnName = ColumnName.caseSensitiveColumnName(n.names.get(0), n.names.get(1)); + } + includeColumns.add(columnName); + } + } + final ListMultimap<String, Pair<String, Object>> props = convertOptions(index.indexOptions); + final List<ParseNode> splitNodes = convertSplits(index.splitKeyList, nodeFactory); + // TODO + final Map<String, UDFParseNode> udfParseNodes = new HashMap<String, UDFParseNode>(); + final CreateIndexStatement create = nodeFactory.createIndex( + name, dataTable, indexKeyConstraint, includeColumns, + splitNodes, props, index.ifNotExists.booleanValue(), + indexType, index.async.booleanValue(), 0, udfParseNodes); + try (final PhoenixStatement stmt = new PhoenixStatement(connection)) { + final CreateIndexCompiler compiler = new CreateIndexCompiler(stmt, Operation.UPSERT); + final MutationPlan plan = compiler.compile(create); + plan.execute(); + } + break; + } + case CREATE_SEQUENCE: { + final SqlCreateSequence sequence = (SqlCreateSequence) node; + final TableName name; + if (sequence.sequenceName.isSimple()) { + name = TableName.create(null, sequence.sequenceName.getSimple()); + } else { + name = TableName.create(sequence.sequenceName.names.get(0), sequence.sequenceName.names.get(1)); + } - final ParseNode startWith = nodeFactory.literal(sequence.startWith.intValue(true)); - final ParseNode incrementBy = nodeFactory.literal(sequence.incrementBy.intValue(true)); - final ParseNode minValue = nodeFactory.literal(sequence.minValue.intValue(true)); - final ParseNode maxValue = nodeFactory.literal(sequence.maxValue.intValue(true)); - final ParseNode cache = nodeFactory.literal(sequence.cache.intValue(true)); ++ final ParseNode startWith = sequence.startWith == null ? null : nodeFactory.literal(sequence.startWith.intValue(true)); ++ final ParseNode incrementBy = sequence.incrementBy == null ? null : nodeFactory.literal(sequence.incrementBy.intValue(true)); ++ final ParseNode minValue = sequence.minValue == null ? null : nodeFactory.literal(sequence.minValue.intValue(true)); ++ final ParseNode maxValue = sequence.maxValue == null ? null : nodeFactory.literal(sequence.maxValue.intValue(true)); ++ final ParseNode cache = sequence.cache == null ? null : nodeFactory.literal(sequence.cache.intValue(true)); + final CreateSequenceStatement create = nodeFactory.createSequence(name, startWith, incrementBy, cache, minValue, maxValue, sequence.cycle.booleanValue(), sequence.ifNotExists.booleanValue(), 0); + try (final PhoenixStatement stmt = new PhoenixStatement(connection)) { + final CreateSequenceCompiler compiler = new CreateSequenceCompiler(stmt, Operation.UPSERT); + final MutationPlan plan = compiler.compile(create); + plan.execute(); + } + break; + } + case DROP_TABLE: + case DROP_VIEW: { + final SqlDropTable table = (SqlDropTable) node; + final PTableType tableType = table.getKind() == SqlKind.DROP_TABLE ? PTableType.TABLE : PTableType.VIEW; + final TableName name; + if (table.tableName.isSimple()) { + name = TableName.create(null, table.tableName.getSimple()); + } else { + name = TableName.create(table.tableName.names.get(0), table.tableName.names.get(1)); + } + final DropTableStatement drop = nodeFactory.dropTable( + name, tableType, table.ifExists.booleanValue(), table.cascade.booleanValue()); + MetaDataClient client = new MetaDataClient(connection); + client.dropTable(drop); + break; + } + case DROP_INDEX: { + final SqlDropIndex index = (SqlDropIndex) node; + final NamedNode name = NamedNode.caseSensitiveNamedNode(index.indexName.getSimple()); + final TableName dataTableName; + if (index.dataTableName.isSimple()) { + dataTableName = TableName.create(null, index.dataTableName.getSimple()); + } else { + dataTableName = TableName.create(index.dataTableName.names.get(0), index.dataTableName.names.get(1)); + } + final DropIndexStatement drop = nodeFactory.dropIndex(name, dataTableName, index.ifExists.booleanValue()); + MetaDataClient client = new MetaDataClient(connection); + client.dropIndex(drop); + break; + } + case DROP_SEQUENCE: { + final SqlDropSequence sequence = (SqlDropSequence) node; + final TableName name; + if (sequence.sequenceName.isSimple()) { + name = TableName.create(null, sequence.sequenceName.getSimple()); + } else { + name = TableName.create(sequence.sequenceName.names.get(0), sequence.sequenceName.names.get(1)); + } + final DropSequenceStatement drop = nodeFactory.dropSequence(name, sequence.ifExists.booleanValue(), 0); + MetaDataClient client = new MetaDataClient(connection); + client.dropSequence(drop); + break; + } + case OTHER_DDL: { + if (node instanceof SqlUpdateStatistics) { + SqlUpdateStatistics updateStatsNode = (SqlUpdateStatistics) node; + final TableName name; + if (updateStatsNode.tableName.isSimple()) { + name = TableName.create(null, updateStatsNode.tableName.getSimple()); + } else { + name = TableName.create(updateStatsNode.tableName.names.get(0), updateStatsNode.tableName.names.get(1)); + } + final NamedTableNode table = NamedTableNode.create(name); + final Map<String, Object> props = new HashMap<String, Object>(); + for (SqlNode optionNode : updateStatsNode.options) { + SqlOptionNode option = (SqlOptionNode) optionNode; + props.put(option.propertyName, option.value); + } + final UpdateStatisticsStatement updateStatsStmt = nodeFactory.updateStatistics(table, updateStatsNode.scope, props); + MetaDataClient client = new MetaDataClient(connection); + client.updateStatistics(updateStatsStmt); + } else { + throw new AssertionError("unknown DDL node " + node.getClass()); + } + break; + } + default: + throw new AssertionError("unknown DDL type " + node.getKind() + " " + node.getClass()); + } + } catch (SQLException ex) { + throw new RuntimeException(ex); + } + } + + private static ParseNode convertSqlNodeToParseNode(SqlNode sqlNode) throws SQLException { + if (sqlNode == null) { + return null; + } + + String sql = THREAD_SQL_STRING.get(); + SqlParserPos pos = sqlNode.getParserPosition(); + int start = SqlParserUtil.lineColToIndex(sql, pos.getLineNum(), pos.getColumnNum()); + int end = SqlParserUtil.lineColToIndex(sql, pos.getEndLineNum(), pos.getEndColumnNum()); + String sqlString = sql.substring(start, end + 1); + return new SQLParser(sqlString).parseExpression(); + } + + private static ListMultimap<String, Pair<String, Object>> convertOptions(SqlNodeList options) { + final ListMultimap<String, Pair<String, Object>> props; + if (SqlNodeList.isEmptyList(options)) { + props = null; + } else { + props = ArrayListMultimap.<String, Pair<String, Object>>create(); + for (SqlNode optionNode : options) { + SqlOptionNode option = (SqlOptionNode) optionNode; + props.put(option.familyName, new Pair<String, Object>(option.propertyName, option.value)); + } + } + + return props; + } + + private static List<ParseNode> convertSplits(SqlNodeList splitKeyList, ParseNodeFactory nodeFactory) { + final List<ParseNode> splits; + if (SqlNodeList.isEmptyList(splitKeyList)) { + splits = null; + } else { + splits = Lists.newArrayList(); + for (SqlNode splitKey : splitKeyList) { + final SqlLiteral key = (SqlLiteral) splitKey; + splits.add(nodeFactory.literal(((NlsString) key.getValue()).toString())); + } + } + + return splits; + } + + private static PhoenixConnection getPhoenixConnection(SchemaPlus rootSchema) { + for (String subSchemaName : rootSchema.getSubSchemaNames()) { + try { + PhoenixSchema phoenixSchema = rootSchema + .getSubSchema(subSchemaName).unwrap(PhoenixSchema.class); + return phoenixSchema.pc; + } catch (ClassCastException e) { + } + } + + throw new RuntimeException("Phoenix schema not found."); + } +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java index 4d343b4,58fb151..1afff27 --- a/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java @@@ -386,9 -380,9 +386,9 @@@ public final class QueryUtil server = Joiner.on(',').join(servers); String znodeParent = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT, HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT); - String url = getUrl(server, port, znodeParent, principal); + String url = getUrl(server, port, znodeParent, principal, isCalciteEnabled); // Mainly for testing to tack on the test=true part to ensure driver is found on server - String extraArgs = conf.get(QueryServices.EXTRA_JDBC_ARGUMENTS_ATTRIB, QueryServicesOptions.DEFAULT_EXTRA_JDBC_ARGUMENTS); + String extraArgs = props.getProperty(QueryServices.EXTRA_JDBC_ARGUMENTS_ATTRIB, conf.get(QueryServices.EXTRA_JDBC_ARGUMENTS_ATTRIB, QueryServicesOptions.DEFAULT_EXTRA_JDBC_ARGUMENTS)); if (extraArgs.length() > 0) { url += extraArgs + PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java index dccf4a9,b74cefb..4af7ede --- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java @@@ -113,20 -102,17 +108,17 @@@ public class BaseConnectionlessQueryTes @BeforeClass public static void doSetup() throws Exception { - String url = getUrl(); - startServer(getUrl()); + startServer(getOldUrl()); - ensureTableCreated(url, ATABLE_NAME); - ensureTableCreated(url, ENTITY_HISTORY_TABLE_NAME); - ensureTableCreated(url, FUNKY_NAME); - ensureTableCreated(url, PTSDB_NAME); - ensureTableCreated(url, PTSDB2_NAME); - ensureTableCreated(url, PTSDB3_NAME); - ensureTableCreated(url, MULTI_CF_NAME); - ensureTableCreated(url, JOIN_ORDER_TABLE_FULL_NAME); - ensureTableCreated(url, JOIN_CUSTOMER_TABLE_FULL_NAME); - ensureTableCreated(url, JOIN_ITEM_TABLE_FULL_NAME); - ensureTableCreated(url, JOIN_SUPPLIER_TABLE_FULL_NAME); - ensureTableCreated(url, TABLE_WITH_ARRAY); + ensureTableCreated(getUrl(), ATABLE_NAME); + ensureTableCreated(getUrl(), ENTITY_HISTORY_TABLE_NAME); + ensureTableCreated(getUrl(), FUNKY_NAME); + ensureTableCreated(getUrl(), PTSDB_NAME); + ensureTableCreated(getUrl(), PTSDB2_NAME); + ensureTableCreated(getUrl(), PTSDB3_NAME); + ensureTableCreated(getUrl(), MULTI_CF_NAME); + ensureTableCreated(getUrl(), TABLE_WITH_ARRAY); + + Properties props = new Properties(); props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(HConstants.LATEST_TIMESTAMP)); PhoenixConnection conn = DriverManager.getConnection(PHOENIX_CONNECTIONLESS_JDBC_URL, props).unwrap(PhoenixConnection.class); http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java index 7dfa9cc,bdcd520..d53134f --- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java @@@ -95,10 -89,7 +89,8 @@@ import java.sql.DriverManager import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; - import java.sql.Timestamp; import java.sql.Types; - import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Iterator; import java.util.List; @@@ -533,7 -458,7 +467,7 @@@ public abstract class BaseTest config.set(TxConstants.Manager.CFG_TX_SNAPSHOT_DIR, tmpFolder.newFolder().getAbsolutePath()); config.setInt(TxConstants.Manager.CFG_TX_TIMEOUT, DEFAULT_TXN_TIMEOUT_SECONDS); -- ConnectionInfo connInfo = ConnectionInfo.create(getUrl()); ++ ConnectionInfo connInfo = ConnectionInfo.create(getOldUrl()); zkClient = ZKClientServices.delegate( ZKClients.reWatchOnExpire( ZKClients.retryOnFailure( @@@ -553,11 -478,17 +487,18 @@@ txService.startAndWait(); } - protected static String checkClusterInitialized(ReadOnlyProps overrideProps) throws Exception { + private static String checkClusterInitialized(ReadOnlyProps serverProps) throws Exception { if (!clusterInitialized) { - url = setUpTestCluster(config, overrideProps); + url = setUpTestCluster(config, serverProps); + calciteUrl = url.replaceFirst(PhoenixRuntime.JDBC_PROTOCOL, PhoenixRuntime.JDBC_PROTOCOL_CALCITE); clusterInitialized = true; + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + logger.info("SHUTDOWN: halting JVM now"); + Runtime.getRuntime().halt(0); + } + }); } return url; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7ca8e4b3/pom.xml ----------------------------------------------------------------------
