You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ra...@apache.org on 2014/07/15 06:35:46 UTC
[5/6] PHOENIX-933 Local index support to Phoenix (Ram)
http://git-wip-us.apache.org/repos/asf/phoenix/blob/247ac8ee/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
new file mode 100644
index 0000000..5f7691b
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
@@ -0,0 +1,553 @@
+/*
+ * 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.index;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
+import org.apache.phoenix.hbase.index.IndexRegionSplitPolicy;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTable.IndexType;
+import org.apache.phoenix.schema.PTableKey;
+import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.MetaDataUtil;
+import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class LocalIndexIT extends BaseIndexIT {
+
+ @BeforeClass
+ public static void doSetup() throws Exception {
+ Map<String,String> props = Maps.newHashMapWithExpectedSize(3);
+ // Drop the HBase table metadata for this test
+ props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
+ // Must update config before starting server
+ setUpTestDriver(getUrl(), new ReadOnlyProps(props.entrySet().iterator()));
+ }
+
+ private void createBaseTable(String tableName, Integer saltBuckets, String splits) throws SQLException {
+ Connection conn = DriverManager.getConnection(getUrl());
+ String ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" +
+ "k1 INTEGER NOT NULL,\n" +
+ "k2 INTEGER NOT NULL,\n" +
+ "k3 INTEGER,\n" +
+ "v1 VARCHAR,\n" +
+ "CONSTRAINT pk PRIMARY KEY (t_id, k1, k2))\n"
+ + (saltBuckets != null && splits == null ? (",salt_buckets=" + saltBuckets) : ""
+ + (saltBuckets == null && splits != null ? (" split on " + splits) : ""));
+ conn.createStatement().execute(ddl);
+ conn.close();
+ }
+
+ @Test
+ public void testLocalIndexRoundTrip() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, null);
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ Connection conn2 = DriverManager.getConnection(getUrl());
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ conn1.createStatement().executeQuery("SELECT * FROM " + DATA_TABLE_FULL_NAME).next();
+ PTable localIndex = conn1.unwrap(PhoenixConnection.class).getMetaDataCache().getTable(new PTableKey(null,INDEX_TABLE_NAME));
+ assertEquals(IndexType.LOCAL, localIndex.getIndexType());
+ assertNotNull(localIndex.getViewIndexId());
+ }
+
+ @Test
+ public void testLocalIndexCreationWithSplitsShouldFail() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, null);
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ Connection conn2 = DriverManager.getConnection(getUrl());
+ try {
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)"+" split on (1,2,3)");
+ fail("Local index cannot be pre-split");
+ } catch (SQLException e) { }
+ try {
+ conn2.createStatement().executeQuery("SELECT * FROM " + DATA_TABLE_FULL_NAME).next();
+ conn2.unwrap(PhoenixConnection.class).getMetaDataCache().getTable(new PTableKey(null,INDEX_TABLE_NAME));
+ fail("Local index should not be created.");
+ } catch (TableNotFoundException e) { }
+ }
+
+ @Test
+ public void testLocalIndexCreationWithSaltingShouldFail() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, null);
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ Connection conn2 = DriverManager.getConnection(getUrl());
+ try {
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)"+" salt_buckets=16");
+ fail("Local index cannot be salted.");
+ } catch (SQLException e) { }
+ try {
+ conn2.createStatement().executeQuery("SELECT * FROM " + DATA_TABLE_FULL_NAME).next();
+ conn2.unwrap(PhoenixConnection.class).getMetaDataCache().getTable(new PTableKey(null,INDEX_TABLE_NAME));
+ fail("Local index should not be created.");
+ } catch (TableNotFoundException e) { }
+ }
+
+ @Test
+ public void testLocalIndexOnTableWithImmutableRows() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, null);
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ Connection conn2 = DriverManager.getConnection(getUrl());
+ try {
+ conn1.createStatement().execute("ALTER TABLE " + DATA_TABLE_NAME + " SET IMMUTABLE_ROWS=true");
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ fail("Local index aren't allowed on table with immutable rows");
+ } catch (SQLException e) { }
+ try {
+ conn2.createStatement().executeQuery("SELECT * FROM " + DATA_TABLE_FULL_NAME).next();
+ conn2.unwrap(PhoenixConnection.class).getMetaDataCache().getTable(new PTableKey(null,INDEX_TABLE_NAME));
+ fail("Local index should not be created.");
+ } catch (TableNotFoundException e) { }
+ }
+
+ @Test
+ public void testLocalIndexTableRegionSplitPolicyAndSplitKeys() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null,"('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ Connection conn2 = DriverManager.getConnection(getUrl());
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ conn2.createStatement().executeQuery("SELECT * FROM " + DATA_TABLE_FULL_NAME).next();
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ HTableDescriptor htd = admin.getTableDescriptor(TableName.valueOf(MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)));
+ assertEquals(IndexRegionSplitPolicy.class.getName(), htd.getValue(HTableDescriptor.SPLIT_POLICY));
+ HTable userTable = new HTable(admin.getConfiguration(),TableName.valueOf(DATA_TABLE_NAME));
+ HTable indexTable = new HTable(admin.getConfiguration(),TableName.valueOf(MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)));
+ assertEquals("Both user region and index table should have same split keys.", userTable.getStartKeys(), indexTable.getStartKeys());
+ }
+
+ @Test
+ public void testDropLocalIndexTable() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, null);
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ Connection conn2 = DriverManager.getConnection(getUrl());
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ conn2.createStatement().executeQuery("SELECT * FROM " + DATA_TABLE_FULL_NAME).next();
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ assertTrue("Local index table should be present.", admin.tableExists(TableName.valueOf(MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME))));
+ conn1.createStatement().execute("DROP TABLE "+ DATA_TABLE_NAME);
+ admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ assertFalse("Local index table should be deleted.", admin.tableExists(TableName.valueOf(MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME))));
+ ResultSet rs = conn2.createStatement().executeQuery("SELECT "
+ + PhoenixDatabaseMetaData.SEQUENCE_SCHEMA + ","
+ + PhoenixDatabaseMetaData.SEQUENCE_NAME
+ + " FROM " + PhoenixDatabaseMetaData.SEQUENCE_TABLE_NAME);
+ assertFalse("View index sequences should be deleted.", rs.next());
+ }
+
+ @Test
+ public void testPutsToLocalIndexTable() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, "('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('b',1,2,4,'z')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('f',1,2,3,'z')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('j',2,4,2,'a')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('q',3,1,1,'c')");
+ conn1.commit();
+ ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + INDEX_TABLE_NAME);
+ assertTrue(rs.next());
+ assertEquals(4, rs.getInt(1));
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ HTable indexTable = new HTable(admin.getConfiguration() ,TableName.valueOf(MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)));
+ Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
+ byte[][] startKeys = startEndKeys.getFirst();
+ byte[][] endKeys = startEndKeys.getSecond();
+ for (int i = 0; i < startKeys.length; i++) {
+ Scan s = new Scan();
+ s.setStartRow(startKeys[i]);
+ s.setStopRow(endKeys[i]);
+ ResultScanner scanner = indexTable.getScanner(s);
+ int count = 0;
+ for(Result r:scanner){
+ count++;
+ }
+ scanner.close();
+ assertEquals(1, count);
+ }
+ indexTable.close();
+ }
+
+ @Test
+ public void testBuildIndexWhenUserTableAlreadyHasData() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, "('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('b',1,2,4,'z')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('f',1,2,3,'z')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('j',2,4,2,'a')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('q',3,1,1,'c')");
+ conn1.commit();
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + INDEX_TABLE_NAME);
+ assertTrue(rs.next());
+ assertEquals(4, rs.getInt(1));
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ HTable indexTable = new HTable(admin.getConfiguration() ,TableName.valueOf(MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)));
+ Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
+ byte[][] startKeys = startEndKeys.getFirst();
+ byte[][] endKeys = startEndKeys.getSecond();
+ for (int i = 0; i < startKeys.length; i++) {
+ Scan s = new Scan();
+ s.setStartRow(startKeys[i]);
+ s.setStopRow(endKeys[i]);
+ ResultScanner scanner = indexTable.getScanner(s);
+ int count = 0;
+ for(Result r:scanner){
+ count++;
+ }
+ scanner.close();
+ assertEquals(1, count);
+ }
+ indexTable.close();
+ }
+
+ @Test
+ public void testLocalIndexScan() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, "('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ try{
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('a',1,2,5,'y')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('b',1,2,4,'z')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('f',1,2,3,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('e',1,2,3,'b')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('j',2,4,2,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+ conn1.commit();
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+
+ ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + INDEX_TABLE_NAME);
+ assertTrue(rs.next());
+
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ int numRegions = admin.getTableRegions(TableName.valueOf(DATA_TABLE_NAME)).size();
+
+ String query = "SELECT t_id, k1, k2,V1 FROM " + DATA_TABLE_NAME +" where v1='a'";
+ rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
+
+ assertEquals(
+ "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+ + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME) + " [-32768,'a']\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+
+ rs = conn1.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("f", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertTrue(rs.next());
+ assertEquals("j", rs.getString("t_id"));
+ assertEquals(2, rs.getInt("k1"));
+ assertEquals(4, rs.getInt("k2"));
+ assertFalse(rs.next());
+ query = "SELECT t_id, k1, k2,V1, k3 FROM " + DATA_TABLE_NAME +" where v1<='z' order by k3";
+ rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
+
+ assertEquals(
+ "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME) + " [-32768,*] - [-32768,'z']\n" +
+ " SERVER SORTED BY [K3]\n" +
+ "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+
+ rs = conn1.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals(1, rs.getInt("k3"));
+ assertTrue(rs.next());
+ assertEquals(2, rs.getInt("k3"));
+ assertTrue(rs.next());
+ assertEquals(3, rs.getInt("k3"));
+ assertTrue(rs.next());
+ assertEquals(3, rs.getInt("k3"));
+ assertTrue(rs.next());
+ assertEquals(4, rs.getInt("k3"));
+ assertTrue(rs.next());
+ assertEquals(5, rs.getInt("k3"));
+ assertFalse(rs.next());
+
+ query = "SELECT t_id, k1, k2,v1 from " + DATA_TABLE_FULL_NAME + " order by V1,t_id";
+ rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
+
+ assertEquals(
+ "CLIENT PARALLEL " + numRegions + "-WAY FULL SCAN OVER "
+ + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)+"\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+
+ rs = conn1.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("f", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertEquals("a", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("j", rs.getString("t_id"));
+ assertEquals(2, rs.getInt("k1"));
+ assertEquals(4, rs.getInt("k2"));
+ assertEquals("a", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("e", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertEquals("b", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("q", rs.getString("t_id"));
+ assertEquals(3, rs.getInt("k1"));
+ assertEquals(1, rs.getInt("k2"));
+ assertEquals("c", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("a", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertEquals("y", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("b", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertEquals("z", rs.getString("V1"));
+ } finally {
+ conn1.close();
+ }
+ }
+
+ @Test
+ public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, "('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ try{
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('b',1,2,4,'z')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('f',1,2,3,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('j',2,4,2,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+ conn1.commit();
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+
+ ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + INDEX_TABLE_NAME);
+ assertTrue(rs.next());
+
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ int numRegions = admin.getTableRegions(TableName.valueOf(DATA_TABLE_NAME)).size();
+
+ String query = "SELECT t_id, k1, k2, k3, V1 FROM " + DATA_TABLE_NAME +" where v1='a'";
+ rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
+
+ assertEquals(
+ "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+ + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME) + " [-32768,'a']\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+
+ rs = conn1.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("f", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertEquals(3, rs.getInt("k3"));
+ assertTrue(rs.next());
+ assertEquals("j", rs.getString("t_id"));
+ assertEquals(2, rs.getInt("k1"));
+ assertEquals(4, rs.getInt("k2"));
+ assertEquals(2, rs.getInt("k3"));
+ assertFalse(rs.next());
+
+ query = "SELECT t_id, k1, k2, k3, V1 from " + DATA_TABLE_FULL_NAME + " where v1<='z' order by V1,t_id";
+ rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
+
+ assertEquals(
+ "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+ + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)+" [-32768,*] - [-32768,'z']\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+
+ rs = conn1.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("f", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertEquals(3, rs.getInt("k3"));
+ assertEquals("a", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("j", rs.getString("t_id"));
+ assertEquals(2, rs.getInt("k1"));
+ assertEquals(4, rs.getInt("k2"));
+ assertEquals(2, rs.getInt("k3"));
+ assertEquals("a", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("q", rs.getString("t_id"));
+ assertEquals(3, rs.getInt("k1"));
+ assertEquals(1, rs.getInt("k2"));
+ assertEquals(1, rs.getInt("k3"));
+ assertEquals("c", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("b", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k1"));
+ assertEquals(2, rs.getInt("k2"));
+ assertEquals(4, rs.getInt("k3"));
+ assertEquals("z", rs.getString("V1"));
+
+ query = "SELECT t_id, V1, k3 from " + DATA_TABLE_FULL_NAME + " where v1 <='z' group by v1,t_id, k3";
+ rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
+
+ assertEquals(
+ "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+ + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)+" [-32768,*] - [-32768,'z']\n"
+ + " SERVER AGGREGATE INTO DISTINCT ROWS BY [V1, T_ID, K3]\n" + "CLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+
+ rs = conn1.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("f", rs.getString("t_id"));
+ assertEquals(3, rs.getInt("k3"));
+ assertEquals("a", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("j", rs.getString("t_id"));
+ assertEquals(2, rs.getInt("k3"));
+ assertEquals("a", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("q", rs.getString("t_id"));
+ assertEquals(1, rs.getInt("k3"));
+ assertEquals("c", rs.getString("V1"));
+ assertTrue(rs.next());
+ assertEquals("b", rs.getString("t_id"));
+ assertEquals(4, rs.getInt("k3"));
+ assertEquals("z", rs.getString("V1"));
+
+ query = "SELECT v1,sum(k3) from " + DATA_TABLE_FULL_NAME + " where v1 <='z' group by v1 order by v1";
+ PhoenixPreparedStatement statement = conn1.prepareStatement(query).unwrap(PhoenixPreparedStatement.class);
+ QueryPlan plan = statement.compileQuery("EXPLAIN " + query);
+ assertTrue(query, plan.getContext().getScan().getAttribute(BaseScannerRegionObserver.KEY_ORDERED_GROUP_BY_EXPRESSIONS) == null);
+ assertTrue(query, plan.getContext().getScan().getAttribute(BaseScannerRegionObserver.UNORDERED_GROUP_BY_EXPRESSIONS) != null);
+
+ rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
+ assertEquals(
+ "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+ + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)+" [-32768,*] - [-32768,'z']\n"
+ + " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [V1]\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+
+ rs = conn1.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ assertEquals("a", rs.getString(1));
+ assertEquals(5, rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("c", rs.getString(1));
+ assertEquals(1, rs.getInt(2));
+ assertTrue(rs.next());
+ assertEquals("z", rs.getString(1));
+ assertEquals(4, rs.getInt(2));
+ } finally {
+ conn1.close();
+ }
+ }
+
+ @Test
+ public void testIndexPlanSelectionIfBothGlobalAndLocalIndexesHasSameColumnsAndOrder() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, "('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('b',1,2,4,'z')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('f',1,2,3,'a')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('j',2,4,3,'a')");
+ conn1.createStatement().execute("UPSERT INTO "+DATA_TABLE_NAME+" values('q',3,1,1,'c')");
+ conn1.commit();
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ conn1.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + "2" + " ON " + DATA_TABLE_NAME + "(v1)");
+ String query = "SELECT t_id, k1, k2,V1 FROM " + DATA_TABLE_NAME +" where v1='a'";
+ ResultSet rs1 = conn1.createStatement().executeQuery("EXPLAIN "+ query);
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + INDEX_TABLE_NAME + "2" + " ['a']",QueryUtil.getExplainPlan(rs1));
+ conn1.close();
+ }
+
+ @Test
+ public void testDropLocalIndexShouldDeleteDataFromLocalIndexTable() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, "('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ try {
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('b',1,2,4,'z')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('f',1,2,3,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('j',2,4,2,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+ conn1.commit();
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ conn1.createStatement().execute("DROP INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME);
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ HTable indexTable = new HTable(admin.getConfiguration() ,TableName.valueOf(MetaDataUtil.getLocalIndexTableName(DATA_TABLE_NAME)));
+ Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
+ byte[][] startKeys = startEndKeys.getFirst();
+ byte[][] endKeys = startEndKeys.getSecond();
+ // No entry should be present in local index table after drop index.
+ for (int i = 0; i < startKeys.length; i++) {
+ Scan s = new Scan();
+ s.setStartRow(startKeys[i]);
+ s.setStopRow(endKeys[i]);
+ ResultScanner scanner = indexTable.getScanner(s);
+ int count = 0;
+ for(Result r:scanner){
+ count++;
+ }
+ scanner.close();
+ assertEquals(0, count);
+ }
+ indexTable.close();
+ } finally {
+ conn1.close();
+ }
+ }
+
+ @Test
+ public void testLocalIndexRowsShouldBeDeletedWhenUserTableRowsDeleted() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, "('e','i','o')");
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ try {
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('b',1,2,4,'z')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('f',1,2,3,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('j',2,4,2,'a')");
+ conn1.createStatement().execute("UPSERT INTO " + DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+ conn1.commit();
+ conn1.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_NAME + "(v1)");
+ conn1.createStatement().execute("DELETE FROM " + DATA_TABLE_NAME + " where v1='a'");
+ conn1.commit();
+ conn1 = DriverManager.getConnection(getUrl());
+ ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + INDEX_TABLE_NAME);
+ assertTrue(rs.next());
+ assertEquals(2, rs.getInt(1));
+ } finally {
+ conn1.close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/247ac8ee/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java
index fed948b..4db967a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java
@@ -38,6 +38,7 @@ import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
import org.apache.phoenix.end2end.HBaseManagedTimeTest;
import org.apache.phoenix.end2end.Shadower;
import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.MetaDataUtil;
import org.apache.phoenix.util.QueryUtil;
import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.TestUtil;
@@ -59,28 +60,49 @@ public class MutableIndexIT extends BaseMutableIndexIT {
props.put(QueryServices.MAX_INTRA_REGION_PARALLELIZATION_ATTRIB, Integer.toString(1));
// Forces server cache to be used
props.put(QueryServices.INDEX_MUTATE_BATCH_SIZE_THRESHOLD_ATTRIB, Integer.toString(2));
+ props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
// Must update config before starting server
props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
setUpTestDriver(getUrl(), new ReadOnlyProps(props.entrySet().iterator()));
}
-
+
@Test
public void testIndexWithNullableFixedWithCols() throws Exception {
+ testIndexWithNullableFixedWithCols(false);
+ }
+
+ @Test
+ public void testLocalIndexWithNullableFixedWithCols() throws Exception {
+ testIndexWithNullableFixedWithCols(true);
+ }
+
+ private void testIndexWithNullableFixedWithCols(boolean localIndex) throws Exception {
Properties props = new Properties(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
try {
createTestTable();
populateTestTable();
- String ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME
- + " (char_col1 ASC, int_col1 ASC)"
- + " INCLUDE (long_col1, long_col2)";
+ String ddl = null;
+ if(localIndex){
+ ddl = "CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME
+ + " (char_col1 ASC, int_col1 ASC)"
+ + " INCLUDE (long_col1, long_col2)";
+ } else {
+ ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME
+ + " (char_col1 ASC, int_col1 ASC)"
+ + " INCLUDE (long_col1, long_col2)";
+ }
PreparedStatement stmt = conn.prepareStatement(ddl);
stmt.execute();
String query = "SELECT d.char_col1, int_col1 from " + DATA_TABLE_FULL_NAME + " as d";
ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if (localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + MetaDataUtil.getLocalIndexTableName(DATA_TABLE_FULL_NAME)+"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -101,6 +123,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testIndexWithNullableDateCol() throws Exception {
+ testIndexWithNullableDateCol(false);
+ }
+
+ @Test
+ public void testLocalIndexWithNullableDateCol() throws Exception {
+ testIndexWithNullableDateCol(true);
+ }
+
+ private void testIndexWithNullableDateCol(boolean localIndex) throws Exception {
Properties props = new Properties(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
@@ -109,13 +140,22 @@ public class MutableIndexIT extends BaseMutableIndexIT {
createTestTable();
populateTestTable(date);
- String ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (date_col)";
+ String ddl = null;
+ if (localIndex) {
+ ddl = "CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (date_col)";
+ } else {
+ ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (date_col)";
+ }
PreparedStatement stmt = conn.prepareStatement(ddl);
stmt.execute();
String query = "SELECT int_pk from " + DATA_TABLE_FULL_NAME ;
ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if (localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME +"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -128,7 +168,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT date_col from " + DATA_TABLE_FULL_NAME + " order by date_col" ;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if (localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME + "\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -145,21 +189,42 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testCoveredColumnUpdates() throws Exception {
+ testCoveredColumnUpdates(false);
+ }
+
+ @Test
+ public void testCoveredColumnUpdatesWithLocalIndex() throws Exception {
+ testCoveredColumnUpdates(true);
+ }
+
+ private void testCoveredColumnUpdates(boolean localIndex) throws Exception {
Properties props = new Properties(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
try {
createTestTable();
populateTestTable();
- String ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME
- + " (char_col1 ASC, int_col1 ASC)"
- + " INCLUDE (long_col1, long_col2)";
+ String ddl = null;
+ if(localIndex) {
+ ddl = "CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME
+ + " (char_col1 ASC, int_col1 ASC)"
+ + " INCLUDE (long_col1, long_col2)";
+ } else {
+ ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME
+ + " (char_col1 ASC, int_col1 ASC)"
+ + " INCLUDE (long_col1, long_col2)";
+ }
+
PreparedStatement stmt = conn.prepareStatement(ddl);
stmt.execute();
String query = "SELECT char_col1, int_col1, long_col2 from " + DATA_TABLE_FULL_NAME;
ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if (localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME +"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -228,6 +293,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testSelectAllAndAliasWithIndex() throws Exception {
+ testSelectAllAndAliasWithIndex(false);
+ }
+
+ @Test
+ public void testSelectAllAndAliasWithLocalIndex() throws Exception {
+ testSelectAllAndAliasWithIndex(true);
+ }
+
+ private void testSelectAllAndAliasWithIndex(boolean localIndex) throws Exception {
String query;
ResultSet rs;
@@ -239,7 +313,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
- conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v2 DESC) INCLUDE (v1)");
+ if (localIndex) {
+ conn.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v2 DESC) INCLUDE (v1)");
+ } else {
+ conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v2 DESC) INCLUDE (v1)");
+ }
query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -257,7 +335,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if(localIndex){
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -278,9 +360,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT v1 as foo FROM " + DATA_TABLE_FULL_NAME + " WHERE v2 = '1' ORDER BY foo";
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER " +INDEX_TABLE_FULL_NAME + " [~'1']\n" +
- " SERVER SORTED BY [V1]\n" +
- "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ if(localIndex){
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _LOCAL_IDX_" +DATA_TABLE_FULL_NAME + " [-32768,~'1']\n" +
+ " SERVER SORTED BY [V1]\n" +
+ "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER " +INDEX_TABLE_FULL_NAME + " [~'1']\n" +
+ " SERVER SORTED BY [V1]\n" +
+ "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -291,6 +379,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testSelectCF() throws Exception {
+ testSelectCF(false);
+ }
+
+ @Test
+ public void testSelectCFWithLocalIndex() throws Exception {
+ testSelectCF(true);
+ }
+
+ private void testSelectCF(boolean localIndex) throws Exception {
String query;
ResultSet rs;
@@ -301,8 +398,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
-
- conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v2 DESC) INCLUDE (a.v1)");
+ if(localIndex) {
+ conn.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v2 DESC) INCLUDE (a.v1)");
+ } else {
+ conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v2 DESC) INCLUDE (a.v1)");
+ }
query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -326,7 +426,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT a.* FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if(localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
assertEquals("y",rs.getString(1));
@@ -343,6 +447,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testCoveredColumns() throws Exception {
+ testCoveredColumns(false);
+ }
+
+ @Test
+ public void testCoveredColumnsWithLocalIndex() throws Exception {
+ testCoveredColumns(true);
+ }
+
+ private void testCoveredColumns(boolean localIndex) throws Exception {
String query;
ResultSet rs;
@@ -354,7 +467,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
- conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1) INCLUDE (v2)");
+ if(localIndex) {
+ conn.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1) INCLUDE (v2)");
+ } else {
+ conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1) INCLUDE (v2)");
+ }
query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -390,7 +507,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if(localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -407,8 +528,12 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
-
+ if(localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME + "\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
+
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
assertEquals("a",rs.getString(1));
@@ -424,8 +549,12 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
-
+ if(localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
+
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
assertEquals("a",rs.getString(1));
@@ -436,6 +565,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testCompoundIndexKey() throws Exception {
+ testCompoundIndexKey(false);
+ }
+
+ @Test
+ public void testCompoundIndexKeyWithLocalIndex() throws Exception {
+ testCompoundIndexKey(true);
+ }
+
+ private void testCompoundIndexKey(boolean localIndex) throws Exception {
String query;
ResultSet rs;
@@ -448,8 +586,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
-
- conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+ if(localIndex) {
+ conn.createStatement().execute("CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+ } else {
+ conn.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+ }
query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -487,7 +628,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if (localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
//make sure the data table looks like what we expect
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -536,6 +681,16 @@ public class MutableIndexIT extends BaseMutableIndexIT {
}
+ @Test
+ public void testMultipleUpdatesToSingleRow() throws Exception {
+ testMultipleUpdatesToSingleRow(false);
+ }
+
+ @Test
+ public void testMultipleUpdatesToSingleRowWithLocalIndex() throws Exception {
+ testMultipleUpdatesToSingleRow(true);
+ }
+
/**
* There was a case where if there were multiple updates to a single row in the same batch, the
* index wouldn't be updated correctly as each element of the batch was evaluated with the state
@@ -544,8 +699,7 @@ public class MutableIndexIT extends BaseMutableIndexIT {
* and current + delete, but not current + put + delete.
* @throws Exception on failure
*/
- @Test
- public void testMultipleUpdatesToSingleRow() throws Exception {
+ private void testMultipleUpdatesToSingleRow(boolean localIndex) throws Exception {
String query;
ResultSet rs;
@@ -560,9 +714,14 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
-
- conn.createStatement().execute(
- "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+
+ if(localIndex) {
+ conn.createStatement().execute(
+ "CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+ } else {
+ conn.createStatement().execute(
+ "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+ }
query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -606,8 +765,13 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME,
- QueryUtil.getExplainPlan(rs));
+ if(localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME,
+ QueryUtil.getExplainPlan(rs));
+ }
// check that the data table matches as expected
rs = conn.createStatement().executeQuery(query);
@@ -681,6 +845,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testMultipleUpdatesAcrossRegions() throws Exception {
+ testMultipleUpdatesAcrossRegions(false);
+ }
+
+ @Test
+ public void testMultipleUpdatesAcrossRegionsWithLocalIndex() throws Exception {
+ testMultipleUpdatesAcrossRegions(true);
+ }
+
+ private void testMultipleUpdatesAcrossRegions(boolean localIndex) throws Exception {
String query;
ResultSet rs;
@@ -696,9 +869,14 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
-
- conn.createStatement().execute(
- "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+
+ if(localIndex) {
+ conn.createStatement().execute(
+ "CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+ } else {
+ conn.createStatement().execute(
+ "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+ }
query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -739,8 +917,13 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME,
- QueryUtil.getExplainPlan(rs));
+ if (localIndex) {
+ assertEquals("CLIENT PARALLEL 2-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME,
+ QueryUtil.getExplainPlan(rs));
+ }
// check that the data table matches as expected
rs = conn.createStatement().executeQuery(query);
@@ -761,6 +944,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testIndexWithCaseSensitiveCols() throws Exception {
+ testIndexWithCaseSensitiveCols(false);
+ }
+
+ @Test
+ public void testLocalIndexWithCaseSensitiveCols() throws Exception {
+ testIndexWithCaseSensitiveCols(true);
+ }
+
+ private void testIndexWithCaseSensitiveCols(boolean localIndex) throws Exception {
String query;
ResultSet rs;
@@ -772,8 +964,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM cs";
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
-
- conn.createStatement().execute("CREATE INDEX ics ON cs (\"v2\") INCLUDE (\"V1\")");
+ if (localIndex) {
+ conn.createStatement().execute("CREATE LOCAL INDEX ics ON cs (\"v2\") INCLUDE (\"V1\")");
+ } else {
+ conn.createStatement().execute("CREATE INDEX ics ON cs (\"v2\") INCLUDE (\"V1\")");
+ }
query = "SELECT * FROM ics";
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
@@ -791,7 +986,11 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT * FROM cs WHERE \"v2\" = '1'";
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER ICS ['1']", QueryUtil.getExplainPlan(rs));
+ if(localIndex){
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER _LOCAL_IDX_CS [-32768,'1']\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER ICS ['1']", QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -805,7 +1004,12 @@ public class MutableIndexIT extends BaseMutableIndexIT {
query = "SELECT \"V1\", \"V1\" as foo1, \"v2\" as foo, \"v2\" as \"Foo1\", \"v2\" FROM cs ORDER BY foo";
rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER ICS", QueryUtil.getExplainPlan(rs));
+ if(localIndex){
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_CS\nCLIENT MERGE SORT",
+ QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER ICS", QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
@@ -838,13 +1042,26 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testInFilterOnIndexedTable() throws Exception {
+ testInFilterOnIndexedTable(false);
+ }
+
+ @Test
+ public void testInFilterOnLocalIndexedTable() throws Exception {
+ testInFilterOnIndexedTable(true);
+ }
+
+ private void testInFilterOnIndexedTable(boolean localIndex) throws Exception {
Properties props = new Properties(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
try {
String ddl = "CREATE TABLE TEST (PK1 CHAR(2) NOT NULL PRIMARY KEY, CF1.COL1 BIGINT)";
conn.createStatement().execute(ddl);
- ddl = "CREATE INDEX IDX1 ON TEST (COL1)";
+ if(localIndex) {
+ ddl = "CREATE LOCAL INDEX IDX1 ON TEST (COL1)";
+ } else {
+ ddl = "CREATE INDEX IDX1 ON TEST (COL1)";
+ }
conn.createStatement().execute(ddl);
String query = "SELECT COUNT(COL1) FROM TEST WHERE COL1 IN (1,25,50,75,100)";
@@ -857,6 +1074,15 @@ public class MutableIndexIT extends BaseMutableIndexIT {
@Test
public void testIndexWithDecimalCol() throws Exception {
+ testIndexWithDecimalCol(false);
+ }
+
+ @Test
+ public void testLocalIndexWithDecimalCol() throws Exception {
+ testIndexWithDecimalCol(true);
+ }
+
+ private void testIndexWithDecimalCol(boolean localIndex) throws Exception {
Properties props = new Properties(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
conn.setAutoCommit(false);
@@ -865,13 +1091,22 @@ public class MutableIndexIT extends BaseMutableIndexIT {
createTestTable();
populateTestTable(date);
- String ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (decimal_pk) INCLUDE (decimal_col1, decimal_col2)";
+ String ddl = null;
+ if (localIndex) {
+ ddl = "CREATE LOCAL INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (decimal_pk) INCLUDE (decimal_col1, decimal_col2)";
+ } else {
+ ddl = "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (decimal_pk) INCLUDE (decimal_col1, decimal_col2)";
+ }
PreparedStatement stmt = conn.prepareStatement(ddl);
stmt.execute();
String query = "SELECT decimal_pk, decimal_col1, decimal_col2 from " + DATA_TABLE_FULL_NAME ;
ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
- assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ if(localIndex) {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER _LOCAL_IDX_" + DATA_TABLE_FULL_NAME+"\nCLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ } else {
+ assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + INDEX_TABLE_FULL_NAME, QueryUtil.getExplainPlan(rs));
+ }
rs = conn.createStatement().executeQuery(query);
assertTrue(rs.next());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/247ac8ee/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
new file mode 100644
index 0000000..cad56d0
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
@@ -0,0 +1,85 @@
+/*
+ * 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.index;
+
+import static org.junit.Assert.assertFalse;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.MetaDataUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class ViewIndexIT extends BaseIndexIT {
+
+ private String VIEW_NAME = "MY_VIEW";
+
+ @BeforeClass
+ public static void doSetup() throws Exception {
+ Map<String,String> props = Maps.newHashMapWithExpectedSize(3);
+ // Drop the HBase table metadata for this test
+ props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
+ // Must update config before starting server
+ setUpTestDriver(getUrl(), new ReadOnlyProps(props.entrySet().iterator()));
+ }
+
+ private void createBaseTable(String tableName, Integer saltBuckets, String splits) throws SQLException {
+ Connection conn = DriverManager.getConnection(getUrl());
+ String ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" +
+ "k1 INTEGER NOT NULL,\n" +
+ "k2 INTEGER NOT NULL,\n" +
+ "v1 VARCHAR,\n" +
+ "CONSTRAINT pk PRIMARY KEY (t_id, k1, k2))\n"
+ + (saltBuckets == null || splits != null ? "" : (",salt_buckets=" + saltBuckets)
+ + (saltBuckets != null || splits == null ? "" : ",splits=" + splits));
+ conn.createStatement().execute(ddl);
+ conn.close();
+ }
+
+ @Test
+ public void testDeleteViewIndexSequences() throws Exception {
+ createBaseTable(DATA_TABLE_NAME, null, null);
+ Connection conn1 = DriverManager.getConnection(getUrl());
+ Connection conn2 = DriverManager.getConnection(getUrl());
+ conn1.createStatement().execute("CREATE VIEW " + VIEW_NAME + " AS SELECT * FROM " + DATA_TABLE_NAME);
+ conn1.createStatement().execute("CREATE INDEX " + INDEX_TABLE_NAME + " ON " + VIEW_NAME + " (v1)");
+ conn2.createStatement().executeQuery("SELECT * FROM " + DATA_TABLE_FULL_NAME).next();
+ HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ conn1.createStatement().execute("DROP VIEW " + VIEW_NAME);
+ conn1.createStatement().execute("DROP TABLE "+ DATA_TABLE_NAME);
+ admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+ assertFalse("View index table should be deleted.", admin.tableExists(TableName.valueOf(MetaDataUtil.getViewIndexTableName(DATA_TABLE_NAME))));
+ ResultSet rs = conn2.createStatement().executeQuery("SELECT "
+ + PhoenixDatabaseMetaData.SEQUENCE_SCHEMA + ","
+ + PhoenixDatabaseMetaData.SEQUENCE_NAME
+ + " FROM " + PhoenixDatabaseMetaData.SEQUENCE_TABLE_NAME);
+ assertFalse("View index sequences should be deleted.", rs.next());
+ }
+}
\ No newline at end of file