You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2018/09/24 15:28:13 UTC

[08/50] [abbrv] phoenix git commit: PHOENIX-3534 Support multi region SYSTEM.CATALOG table (Thomas D'Silva and Rahul Gidwani)

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
index 34292ba..fdfd75b 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
@@ -28,172 +28,119 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.IOException;
+import java.math.BigDecimal;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
+import org.apache.curator.shaded.com.google.common.collect.Lists;
+import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 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.Mutation;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.coprocessor.ObserverContext;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
+import org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver;
+import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.exception.PhoenixIOException;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.ColumnAlreadyExistsException;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ReadOnlyTableException;
 import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
 import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Maps;
 
+@RunWith(Parameterized.class)
+public class ViewIT extends SplitSystemCatalogIT {
 
-public class ViewIT extends BaseViewIT {
-	
-    public ViewIT(boolean transactional) {
-		super(transactional);
-	}
-
-    @Test
-    public void testReadOnlyOnReadOnlyView() throws Exception {
-        Connection earlierCon = DriverManager.getConnection(getUrl());
-        Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE) "+ tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        String fullParentViewName = "V_" + generateUniqueName();
-        ddl = "CREATE VIEW " + fullParentViewName + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        try {
-            conn.createStatement().execute("UPSERT INTO " + fullParentViewName + " VALUES(1)");
-            fail();
-        } catch (ReadOnlyTableException e) {
-            
-        }
-        for (int i = 0; i < 10; i++) {
-            conn.createStatement().execute("UPSERT INTO " + fullTableName + " VALUES(" + i + ")");
-        }
-        conn.commit();
-        
-        analyzeTable(conn, fullParentViewName, transactional);
-        
-        List<KeyRange> splits = getAllSplits(conn, fullParentViewName);
-        assertEquals(4, splits.size());
-        
-        int count = 0;
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k FROM " + fullTableName);
-        while (rs.next()) {
-            assertEquals(count++, rs.getInt(1));
-        }
-        assertEquals(10, count);
-        
-        count = 0;
-        rs = conn.createStatement().executeQuery("SELECT k FROM " + fullParentViewName);
-        while (rs.next()) {
-            count++;
-            assertEquals(count + 5, rs.getInt(1));
-        }
-        assertEquals(4, count);
-        count = 0;
-        rs = earlierCon.createStatement().executeQuery("SELECT k FROM " + fullParentViewName);
-        while (rs.next()) {
-            count++;
-            assertEquals(count + 5, rs.getInt(1));
-        }
-        assertEquals(4, count);
-        String fullViewName = "V_" + generateUniqueName();
-        ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullParentViewName + " WHERE k < 9";
-        conn.createStatement().execute(ddl);
-        try {
-            conn.createStatement().execute("UPSERT INTO " + fullViewName + " VALUES(1)");
-            fail();
-        } catch (ReadOnlyTableException e) {
-            
-        } finally {
-            conn.close();
-        }
+    protected String tableDDLOptions;
+    protected boolean transactional;
 
-        conn = DriverManager.getConnection(getUrl());
-        count = 0;
-        rs = conn.createStatement().executeQuery("SELECT k FROM " + fullViewName);
-        while (rs.next()) {
-            count++;
-            assertEquals(count + 5, rs.getInt(1));
+    public ViewIT(boolean transactional) {
+        StringBuilder optionBuilder = new StringBuilder();
+        this.transactional = transactional;
+        if (transactional) {
+            optionBuilder.append(" TRANSACTIONAL=true ");
         }
-        assertEquals(3, count);
+        this.tableDDLOptions = optionBuilder.toString();
     }
 
-    @Test
-    public void testNonSaltedUpdatableViewWithIndex() throws Exception {
-        testUpdatableViewWithIndex(null, false);
-    }
-    
-    @Test
-    public void testNonSaltedUpdatableViewWithLocalIndex() throws Exception {
-        testUpdatableViewWithIndex(null, true);
+    @Parameters(name = "transactional = {0}")
+    public static Collection<Boolean> data() {
+        return Arrays.asList(new Boolean[] { false, true });
     }
     
-    @Test
-    public void testUpdatableOnUpdatableView() throws Exception {
-        String viewName = testUpdatableView(null);
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullViewName = "V_" + generateUniqueName();
-        String ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + viewName + " WHERE k3 = 2";
-        conn.createStatement().execute(ddl);
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName);
-        assertTrue(rs.next());
-        assertEquals(1, rs.getInt(1));
-        assertEquals(109, rs.getInt(2));
-        assertEquals(2, rs.getInt(3));
-        assertFalse(rs.next());
-
-        conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2) VALUES(122)");
-        conn.commit();
-        rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName + " WHERE k2 >= 120");
-        assertTrue(rs.next());
-        assertEquals(1, rs.getInt(1));
-        assertEquals(122, rs.getInt(2));
-        assertEquals(2, rs.getInt(3));
-        assertFalse(rs.next());
-        
-        try {
-            conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,k3) VALUES(123,3)");
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode());
-        }
-
-        try {
-            conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,k3) select k2, 3 from " + fullViewName);
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode());
+    @BeforeClass
+    public static void doSetup() throws Exception {
+        NUM_SLAVES_BASE = 6;
+        Map<String, String> props = Collections.emptyMap();
+        boolean splitSystemCatalog = (driver == null);
+        Map<String, String> serverProps = Maps.newHashMapWithExpectedSize(1);
+        serverProps.put("hbase.coprocessor.region.classes", FailingRegionObserver.class.getName());
+        serverProps.put("hbase.coprocessor.abortonerror", "false");
+        setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()), new ReadOnlyProps(props.entrySet().iterator()));
+        // Split SYSTEM.CATALOG once after the mini-cluster is started
+        if (splitSystemCatalog) {
+            splitSystemCatalog();
         }
     }
-
+    
     @Test
     public void testReadOnlyOnUpdatableView() throws Exception {
-        String viewName = testUpdatableView(null);
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+        String ddl =
+                "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1
+                        + " WHERE k3 > 1 and k3 < 50";
+        testUpdatableView(fullTableName, fullViewName1, fullViewName2, ddl, null, tableDDLOptions);
         Connection conn = DriverManager.getConnection(getUrl());
-        String fullViewName = "V_" + generateUniqueName();
-        String ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + viewName + " WHERE k3 > 1 and k3 < 50";
-        conn.createStatement().execute(ddl);
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName);
+        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName2);
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(109, rs.getInt(2));
         assertEquals(2, rs.getInt(3));
         assertFalse(rs.next());
-
         try {
-            conn.createStatement().execute("UPSERT INTO " + fullViewName + " VALUES(1)");
+            conn.createStatement().execute("UPSERT INTO " + fullViewName2 + " VALUES(1)");
             fail();
         } catch (ReadOnlyTableException e) {
             
@@ -201,22 +148,27 @@ public class ViewIT extends BaseViewIT {
         
         conn.createStatement().execute("UPSERT INTO " + fullTableName + "(k1, k2,k3) VALUES(1, 122, 5)");
         conn.commit();
-        rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName + " WHERE k2 >= 120");
+        rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName2 + " WHERE k2 >= 120");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(122, rs.getInt(2));
         assertEquals(5, rs.getInt(3));
         assertFalse(rs.next());
     }
-    
+
     @Test
     public void testDisallowDropOfReferencedColumn() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+        
         String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String fullViewName1 = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + fullViewName1 + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
         conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE v2 != 'foo'";
+        conn.createStatement().execute(ddl);
         
         try {
             conn.createStatement().execute("ALTER VIEW " + fullViewName1 + " DROP COLUMN v1");
@@ -225,10 +177,6 @@ public class ViewIT extends BaseViewIT {
             assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
         }
         
-        String fullViewName2 = "V_" + generateUniqueName();
-        ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE v2 != 'foo'";
-        conn.createStatement().execute(ddl);
-
         try {
             conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v1");
             fail();
@@ -249,12 +197,16 @@ public class ViewIT extends BaseViewIT {
     public void testReadOnlyViewWithCaseSensitiveTableNames() throws Exception {
         Connection earlierCon = DriverManager.getConnection(getUrl());
         Connection conn = DriverManager.getConnection(getUrl());
+        String schemaName = TestUtil.DEFAULT_SCHEMA_NAME + "_" + generateUniqueName();
         String caseSensitiveTableName = "\"t_" + generateUniqueName() + "\"" ;
-        String ddl = "CREATE TABLE " + caseSensitiveTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
+        String fullTableName = SchemaUtil.getTableName(schemaName, caseSensitiveTableName);
         String caseSensitiveViewName = "\"v_" + generateUniqueName() + "\"" ;
-        ddl = "CREATE VIEW " + caseSensitiveViewName + " (v2 VARCHAR) AS SELECT * FROM " + caseSensitiveTableName + " WHERE k > 5";
+
+        String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
         conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + caseSensitiveViewName + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        
         try {
             conn.createStatement().execute("UPSERT INTO " + caseSensitiveViewName + " VALUES(1)");
             fail();
@@ -262,7 +214,7 @@ public class ViewIT extends BaseViewIT {
             
         }
         for (int i = 0; i < 10; i++) {
-            conn.createStatement().execute("UPSERT INTO " + caseSensitiveTableName + " VALUES(" + i + ")");
+            conn.createStatement().execute("UPSERT INTO " + fullTableName + " VALUES(" + i + ")");
         }
         conn.commit();
         
@@ -285,11 +237,14 @@ public class ViewIT extends BaseViewIT {
     @Test
     public void testReadOnlyViewWithCaseSensitiveColumnNames() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         String ddl = "CREATE TABLE " + fullTableName + " (\"k\" INTEGER NOT NULL PRIMARY KEY, \"v1\" INTEGER, \"a\".v2 VARCHAR)" + tableDDLOptions;
+
         conn.createStatement().execute(ddl);
-        String viewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + viewName + " (v VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE \"k\" > 5 and \"v1\" > 1";
         conn.createStatement().execute(ddl);
+        
         try {
             conn.createStatement().execute("UPSERT INTO " + viewName + " VALUES(1)");
             fail();
@@ -313,11 +268,14 @@ public class ViewIT extends BaseViewIT {
     @Test
     public void testViewWithCurrentDate() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
         String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 INTEGER, v2 DATE)" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String viewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + viewName + " (v VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v2 > CURRENT_DATE()-5 AND v2 > DATE '2010-01-01'";
         conn.createStatement().execute(ddl);
+        
         try {
             conn.createStatement().execute("UPSERT INTO " + viewName + " VALUES(1)");
             fail();
@@ -354,27 +312,33 @@ public class ViewIT extends BaseViewIT {
         Properties props = new Properties();
         props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
         Connection conn = DriverManager.getConnection(getUrl(),props);
-        String schemaName1 = "S_" + generateUniqueName();
+        String tableName = "T_" + generateUniqueName();
+        String schemaName1 = SCHEMA1;
         String fullTableName1 = SchemaUtil.getTableName(schemaName1, tableName);
+        String viewName1 = "V_" + generateUniqueName();
+        String viewSchemaName = SCHEMA2;
+        String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName1);
+        String viewName2 = "V_" + generateUniqueName();
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, viewName1);
+        
         if (isNamespaceMapped) {
             conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName1);
         }
-		String ddl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        String ddl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
         HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
         conn.createStatement().execute(ddl);
         assertTrue(admin.tableExists(SchemaUtil.getPhysicalTableName(SchemaUtil.normalizeIdentifier(fullTableName1),
                 conn.unwrap(PhoenixConnection.class).getQueryServices().getProps())));
-        String viewName = "V_" + generateUniqueName();
-        String viewSchemaName = "S_" + generateUniqueName();
-        String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName);
+        
         ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
         conn.createStatement().execute(ddl);
-        String fullViewName2 = "V_" + generateUniqueName();
+        
         ddl = "CREATE VIEW " + fullViewName2 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
         conn.createStatement().execute(ddl);
+        
         conn.createStatement().executeQuery("SELECT * FROM " + fullViewName1);
         conn.createStatement().executeQuery("SELECT * FROM " + fullViewName2);
-        ddl = "DROP VIEW " + viewName;
+        ddl = "DROP VIEW " + viewName1;
         try {
             conn.createStatement().execute(ddl);
             fail();
@@ -389,20 +353,20 @@ public class ViewIT extends BaseViewIT {
         } catch (TableNotFoundException ignore) {
         }
         ddl = "DROP TABLE " + fullTableName1;
-        validateCannotDropTableWithChildViewsWithoutCascade(conn, fullTableName1);
         ddl = "DROP VIEW " + fullViewName2;
         conn.createStatement().execute(ddl);
         ddl = "DROP TABLE " + fullTableName1;
         conn.createStatement().execute(ddl);
     }
 
-    
+
     @Test
     public void testDisallowDropOfColumnOnParentTable() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String viewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + viewName + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
         conn.createStatement().execute(ddl);
         
@@ -416,46 +380,171 @@ public class ViewIT extends BaseViewIT {
    
     @Test
     public void testViewAndTableAndDropCascade() throws Exception {
-    	// Setup
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        String viewName = "V_" + generateUniqueName();
-        String viewSchemaName = "S_" + generateUniqueName();
-        String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName);
-        ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+        
+        String tableDdl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
         conn.createStatement().execute(ddl);
-        ddl = "CREATE LOCAL INDEX idx on " + fullViewName1 + "(v2)";
+        String indexName = generateUniqueName();
+        ddl = "CREATE LOCAL INDEX " + indexName + " on " + fullViewName1 + "(v2)";
         conn.createStatement().execute(ddl);
-        String fullViewName2 = SchemaUtil.getTableName(viewSchemaName, "V_" + generateUniqueName());
         ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
         conn.createStatement().execute(ddl);
+        
+        // dropping base table without cascade should fail
+        try {
+            conn.createStatement().execute("DROP TABLE " + fullTableName );
+            fail();
+        }
+        catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+        }
 
-        validateCannotDropTableWithChildViewsWithoutCascade(conn, fullTableName);
+        // drop table cascade should succeed
+        conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
         
-        // Execute DROP...CASCADE
+        validateViewDoesNotExist(conn, fullViewName1);
+        validateViewDoesNotExist(conn, fullViewName2);
+
+    }
+    
+    @Test
+    public void testRecreateDroppedTableWithChildViews() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+        
+        String tableDdl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        String indexName = generateUniqueName();
+        ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
+        conn.createStatement().execute(ddl);
+        
+        // drop table cascade should succeed
         conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
         
         validateViewDoesNotExist(conn, fullViewName1);
         validateViewDoesNotExist(conn, fullViewName2);
+
+        // recreate the table that was dropped
+        conn.createStatement().execute(tableDdl);
+        // the two child views should still not exist
+        try {
+            PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+            fail();
+        } catch (SQLException e) {
+        }
+        try {
+            PhoenixRuntime.getTableNoCache(conn, fullViewName2);
+            fail();
+        } catch (SQLException e) {
+        }
     }
     
     @Test
-    public void testViewAndTableAndDropCascadeWithIndexes() throws Exception {
+    public void testRecreateIndexWhoseAncestorWasDropped() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullTableName2 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         
-    	// Setup - Tables and Views with Indexes
-    	Connection conn = DriverManager.getConnection(getUrl());
-		if (tableDDLOptions.length()!=0)
-			tableDDLOptions+=",";
-		tableDDLOptions+="IMMUTABLE_ROWS=true";
+        String tableDdl = "CREATE TABLE " + fullTableName1 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        conn.createStatement().execute(tableDdl);
+        tableDdl = "CREATE TABLE " + fullTableName2 + "  (k INTEGER NOT NULL PRIMARY KEY, v3 DATE)" + tableDDLOptions;
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        String indexName = generateUniqueName();
+        ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
+        conn.createStatement().execute(ddl);
+        try {
+                // this should fail because an index with this name is present
+            ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v1)";
+            conn.createStatement().execute(ddl);
+            fail();
+        }
+        catch(SQLException e) {
+        }
+        
+        // drop table cascade should succeed
+        conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
+        
+        // should be able to reuse the index name 
+        ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v3)";
+        conn.createStatement().execute(ddl);
+        
+        String fullIndexName = SchemaUtil.getTableName(SCHEMA2, indexName);
+        PTable index = PhoenixRuntime.getTableNoCache(conn, fullIndexName);
+        // the index should have v3 but not v2
+        validateCols(index);
+    }
+    
+    @Test
+    public void testRecreateViewWhoseParentWasDropped() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullTableName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+        
+        String tableDdl = "CREATE TABLE " + fullTableName1 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        conn.createStatement().execute(tableDdl);
+        tableDdl = "CREATE TABLE " + fullTableName2 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        
+        // drop table cascade should succeed
+        conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
+        
+        // should be able to reuse the view name 
+        ddl = "CREATE VIEW " + fullViewName1 + " (v3 VARCHAR) AS SELECT * FROM " + fullTableName2 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        
+        PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+        // the view should have v3 but not v2
+        validateCols(view);
+    }
+
+    private void validateCols(PTable table) {
+        final String prefix = table.getType() == PTableType.INDEX ? "0:" : "";
+        Predicate<PColumn> predicate = new Predicate<PColumn>() {
+            @Override
+            public boolean apply(PColumn col) {
+                return col.getName().getString().equals(prefix + "V3")
+                        || col.getName().getString().equals(prefix + "V2");
+            }
+        };
+        List<PColumn> colList = table.getColumns();
+        Collection<PColumn> filteredCols = Collections2.filter(colList, predicate);
+        assertEquals(1, filteredCols.size());
+        assertEquals(prefix + "V3", filteredCols.iterator().next().getName().getString());
+    }
+    
+    @Test
+    public void testViewAndTableAndDropCascadeWithIndexes() throws Exception {
+        // Setup - Tables and Views with Indexes
+        Connection conn = DriverManager.getConnection(getUrl());
+        if (tableDDLOptions.length()!=0)
+            tableDDLOptions+=",";
+        tableDDLOptions+="IMMUTABLE_ROWS=true";
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
         String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String viewSchemaName = "S_" + generateUniqueName();
-        String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, "V_" + generateUniqueName());
-        String fullViewName2 = SchemaUtil.getTableName(viewSchemaName, "V_" + generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
         String indexName1 = "I_" + generateUniqueName();
         String indexName2 = "I_" + generateUniqueName();
         String indexName3 = "I_" + generateUniqueName();
+        
         ddl = "CREATE INDEX " + indexName1 + " ON " + fullTableName + " (v1)";
         conn.createStatement().execute(ddl);
         ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
@@ -466,9 +555,8 @@ public class ViewIT extends BaseViewIT {
         conn.createStatement().execute(ddl);
         ddl = "CREATE INDEX " + indexName3 + " ON " + fullViewName2 + " (v2)";
         conn.createStatement().execute(ddl);
-
-        validateCannotDropTableWithChildViewsWithoutCascade(conn, fullTableName);
         
+
         // Execute DROP...CASCADE
         conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
         
@@ -478,28 +566,16 @@ public class ViewIT extends BaseViewIT {
     }
 
 
-	private void validateCannotDropTableWithChildViewsWithoutCascade(Connection conn, String tableName) throws SQLException {
-		String ddl;
-		try {
-	        ddl = "DROP TABLE " + tableName;
-	        conn.createStatement().execute(ddl);
-	        fail("Should not be able to drop table " + tableName + " with child views without explictly specifying CASCADE");
-        }  catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
-        }
-	}
-
-
-	private void validateViewDoesNotExist(Connection conn, String fullViewName)	throws SQLException {
-		try {
-        	String ddl1 = "DROP VIEW " + fullViewName;
+    private void validateViewDoesNotExist(Connection conn, String fullViewName)    throws SQLException {
+        try {
+            String ddl1 = "DROP VIEW " + fullViewName;
             conn.createStatement().execute(ddl1);
             fail("View " + fullViewName + " should have been deleted when parent was dropped");
         } catch (TableNotFoundException e) {
-        	//Expected
+            //Expected
         }
-	}
-	
+    }
+    
     @Test
     public void testViewUsesTableGlobalIndex() throws Exception {
         testViewUsesTableIndex(false);
@@ -515,17 +591,17 @@ public class ViewIT extends BaseViewIT {
         ResultSet rs;
         // Use unique name for table with local index as otherwise we run into issues
         // when we attempt to drop the table (with the drop metadata option set to false
-        String fullTableName = this.fullTableName + (localIndex ? "_WITH_LI" : "_WITHOUT_LI");
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName()) + (localIndex ? "_WITH_LI" : "_WITHOUT_LI");
         Connection conn = DriverManager.getConnection(getUrl());
         String ddl = "CREATE TABLE " + fullTableName + "  (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, k3 DECIMAL, s1 VARCHAR, s2 VARCHAR CONSTRAINT pk PRIMARY KEY (k1, k2, k3))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
         String indexName1 = "I_" + generateUniqueName();
-        String fullIndexName1 = SchemaUtil.getTableName(schemaName, indexName1);
+        String fullIndexName1 = SchemaUtil.getTableName(SCHEMA1, indexName1);
         conn.createStatement().execute("CREATE " + (localIndex ? "LOCAL " : "") + " INDEX " + indexName1 + " ON " + fullTableName + "(k3, k2) INCLUDE(s1, s2)");
         String indexName2 = "I_" + generateUniqueName();
         conn.createStatement().execute("CREATE INDEX " + indexName2 + " ON " + fullTableName + "(k3, k2, s2)");
         
-        String fullViewName = "V_" + generateUniqueName();
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE s1 = 'foo'";
         conn.createStatement().execute(ddl);
         String[] s1Values = {"foo","bar"};
@@ -564,15 +640,20 @@ public class ViewIT extends BaseViewIT {
     @Test
     public void testCreateViewDefinesPKColumn() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        
         String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String fullViewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + fullViewName + "(v2 VARCHAR, k3 VARCHAR PRIMARY KEY) AS SELECT * FROM " + fullTableName + " WHERE K1 = 1";
         conn.createStatement().execute(ddl);
 
         // assert PK metadata
-        ResultSet rs = conn.getMetaData().getPrimaryKeys(null, null, fullViewName);
-        assertPKs(rs, new String[] {"K1", "K2", "K3"});
+        ResultSet rs =
+                conn.getMetaData().getPrimaryKeys(null,
+                    SchemaUtil.getSchemaNameFromFullName(fullViewName),
+                    SchemaUtil.getTableNameFromFullName(fullViewName));
+        assertPKs(rs, new String[] {"K3"});
         
         // sanity check upserts into base table and view
         conn.createStatement().executeUpdate("upsert into " + fullTableName + " (k1, k2, v1) values (1, 1, 1)");
@@ -593,43 +674,54 @@ public class ViewIT extends BaseViewIT {
     @Test
     public void testCreateViewDefinesPKConstraint() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
         String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String fullViewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + fullViewName + "(v2 VARCHAR, k3 VARCHAR, k4 INTEGER NOT NULL, CONSTRAINT PKVEW PRIMARY KEY (k3, k4)) AS SELECT * FROM " + fullTableName + " WHERE K1 = 1";
         conn.createStatement().execute(ddl);
-
+        
         // assert PK metadata
-        ResultSet rs = conn.getMetaData().getPrimaryKeys(null, null, fullViewName);
-        assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
+        ResultSet rs =
+                conn.getMetaData().getPrimaryKeys(null,
+                    SchemaUtil.getSchemaNameFromFullName(fullViewName),
+                    SchemaUtil.getTableNameFromFullName(fullViewName));
+        assertPKs(rs, new String[] {"K3", "K4"});
     }
     
     @Test
     public void testViewAddsPKColumn() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName2 = fullTableName;
-		String ddl = "CREATE TABLE " + fullTableName2 + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = generateUniqueName();
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, viewName);
+        
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String fullViewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
         conn.createStatement().execute(ddl);
+        
         ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
         conn.createStatement().execute(ddl);
 
         // assert PK metadata
-        ResultSet rs = conn.getMetaData().getPrimaryKeys(null, null, fullViewName);
-        assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
+        ResultSet rs = conn.getMetaData().getPrimaryKeys(null, SCHEMA2, viewName);
+        assertPKs(rs, new String[] {"K3", "K4"});
     }
     
     @Test
     public void testViewAddsPKColumnWhoseParentsLastPKIsVarLength() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
         String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 VARCHAR NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String fullViewName1 = "V_" + generateUniqueName();
-        ddl = "CREATE VIEW " + fullViewName1 + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
         conn.createStatement().execute(ddl);
-        ddl = "ALTER VIEW " + fullViewName1 + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
+        
+        ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
         try {
             conn.createStatement().execute(ddl);
             fail("View cannot extend PK if parent's last PK is variable length. See https://issues.apache.org/jira/browse/PHOENIX-978.");
@@ -639,7 +731,7 @@ public class ViewIT extends BaseViewIT {
         String fullViewName2 = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + fullViewName2 + " (k3 VARCHAR PRIMARY KEY)  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
         try {
-        	conn.createStatement().execute(ddl);
+            conn.createStatement().execute(ddl);
         } catch (SQLException e) {
             assertEquals(CANNOT_MODIFY_VIEW_PK.getErrorCode(), e.getErrorCode());
         }
@@ -648,23 +740,28 @@ public class ViewIT extends BaseViewIT {
     @Test(expected=ColumnAlreadyExistsException.class)
     public void testViewAddsClashingPKColumn() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        
         String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String fullViewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
         conn.createStatement().execute(ddl);
+        
         ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k2 VARCHAR PRIMARY KEY, v2 INTEGER";
         conn.createStatement().execute(ddl);
     }
-    
+
     @Test
     public void testViewAddsNotNullPKColumn() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(ddl);
-        String fullViewName = "V_" + generateUniqueName();
         ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
         conn.createStatement().execute(ddl);
+        
         try {
             ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR NOT NULL PRIMARY KEY"; 
             conn.createStatement().execute(ddl);
@@ -677,15 +774,17 @@ public class ViewIT extends BaseViewIT {
     @Test
     public void testQueryViewStatementOptimization() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
         String sql = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
         conn.createStatement().execute(sql);
-        String fullViewName1 = "V_" + generateUniqueName();
         sql = "CREATE VIEW " + fullViewName1 + "  AS SELECT * FROM " + fullTableName;
         conn.createStatement().execute(sql);
-        String fullViewName2 = "V_" + generateUniqueName();
         sql = "CREATE VIEW " + fullViewName2 + "  AS SELECT * FROM " + fullTableName + " WHERE k1 = 1.0";
         conn.createStatement().execute(sql);
         
+        
         sql = "SELECT * FROM " + fullViewName1 + " order by k1, k2";
         PreparedStatement stmt = conn.prepareStatement(sql);
         QueryPlan plan = PhoenixRuntime.getOptimizedQueryPlan(stmt);
@@ -702,13 +801,14 @@ public class ViewIT extends BaseViewIT {
       Properties props = new Properties();
       Connection conn1 = DriverManager.getConnection(getUrl(), props);
       conn1.setAutoCommit(true);
-      String tableName=generateUniqueName();
-      String viewName=generateUniqueName();
+      String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+      String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
       conn1.createStatement().execute(
         "CREATE TABLE "+tableName+" (k VARCHAR PRIMARY KEY, v1 VARCHAR, v2 VARCHAR) UPDATE_CACHE_FREQUENCY=1000000");
       conn1.createStatement().execute("upsert into "+tableName+" values ('row1', 'value1', 'key1')");
       conn1.createStatement().execute(
         "CREATE VIEW "+viewName+" (v43 VARCHAR) AS SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
+      
       ResultSet rs = conn1.createStatement()
           .executeQuery("SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
       assertTrue(rs.next());
@@ -724,60 +824,59 @@ public class ViewIT extends BaseViewIT {
         props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.TRUE.toString());
 
         try (Connection conn = DriverManager.getConnection(getUrl(), props);
-            HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+                HBaseAdmin admin =
+                        conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
 
             conn.createStatement().execute("CREATE SCHEMA " + NS);
 
             // test for a view that is in non-default schema
-            {
-                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, TBL));
-                desc.addFamily(new HColumnDescriptor(CF));
-                admin.createTable(desc);
+            HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, TBL));
+            desc.addFamily(new HColumnDescriptor(CF));
+            admin.createTable(desc);
 
-                String view = NS + "." + TBL;
-                conn.createStatement().execute(
-                    "CREATE VIEW " + view + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+            String view1 = NS + "." + TBL;
+            conn.createStatement().execute(
+                "CREATE VIEW " + view1 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
 
-                assertTrue(QueryUtil.getExplainPlan(
-                    conn.createStatement().executeQuery("explain select * from " + view))
+            assertTrue(QueryUtil
+                    .getExplainPlan(
+                        conn.createStatement().executeQuery("explain select * from " + view1))
                     .contains(NS + ":" + TBL));
 
-                conn.createStatement().execute("DROP VIEW " + view);
-            }
+            
 
-            // test for a view whose name contains a dot (e.g. "AAA.BBB") in default schema (for backward compatibility)
-            {
-                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS + "." + TBL));
-                desc.addFamily(new HColumnDescriptor(CF));
-                admin.createTable(desc);
+            // test for a view whose name contains a dot (e.g. "AAA.BBB") in default schema (for
+            // backward compatibility)
+            desc = new HTableDescriptor(TableName.valueOf(NS + "." + TBL));
+            desc.addFamily(new HColumnDescriptor(CF));
+            admin.createTable(desc);
 
-                String view = "\"" + NS + "." + TBL + "\"";
-                conn.createStatement().execute(
-                    "CREATE VIEW " + view + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+            String view2 = "\"" + NS + "." + TBL + "\"";
+            conn.createStatement().execute(
+                "CREATE VIEW " + view2 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
 
-                assertTrue(QueryUtil.getExplainPlan(
-                    conn.createStatement().executeQuery("explain select * from " + view))
+            assertTrue(QueryUtil
+                    .getExplainPlan(
+                        conn.createStatement().executeQuery("explain select * from " + view2))
                     .contains(NS + "." + TBL));
 
-                conn.createStatement().execute("DROP VIEW " + view);
-            }
-
             // test for a view whose name contains a dot (e.g. "AAA.BBB") in non-default schema
-            {
-                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, NS + "." + TBL));
-                desc.addFamily(new HColumnDescriptor(CF));
-                admin.createTable(desc);
+            desc = new HTableDescriptor(TableName.valueOf(NS, NS + "." + TBL));
+            desc.addFamily(new HColumnDescriptor(CF));
+            admin.createTable(desc);
 
-                String view = NS + ".\"" + NS + "." + TBL + "\"";
-                conn.createStatement().execute(
-                    "CREATE VIEW " + view + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+            String view3 = NS + ".\"" + NS + "." + TBL + "\"";
+            conn.createStatement().execute(
+                "CREATE VIEW " + view3 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
 
-                assertTrue(QueryUtil.getExplainPlan(
-                    conn.createStatement().executeQuery("explain select * from " + view))
+            assertTrue(QueryUtil
+                    .getExplainPlan(
+                        conn.createStatement().executeQuery("explain select * from " + view3))
                     .contains(NS + ":" + NS + "." + TBL));
-
-                conn.createStatement().execute("DROP VIEW " + view);
-            }
+            
+            conn.createStatement().execute("DROP VIEW " + view1);
+            conn.createStatement().execute("DROP VIEW " + view2);
+            conn.createStatement().execute("DROP VIEW " + view3);
 
             conn.createStatement().execute("DROP SCHEMA " + NS);
         }
@@ -793,14 +892,14 @@ public class ViewIT extends BaseViewIT {
     }
 
     @Test
-    public void testCompositeDescPK() throws SQLException {
+    public void testCompositeDescPK() throws Exception {
         Properties props = new Properties();
         try (Connection globalConn = DriverManager.getConnection(getUrl(), props)) {
-            String tableName = generateUniqueName();
-            String viewName1 = generateUniqueName();
-            String viewName2 = generateUniqueName();
-            String viewName3 = generateUniqueName();
-            String viewName4 = generateUniqueName();
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            String viewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+            String viewName3 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewName4 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
 
             // create global base table
             globalConn.createStatement().execute("CREATE TABLE " + tableName
@@ -823,6 +922,17 @@ public class ViewIT extends BaseViewIT {
                                 + " (pk1 VARCHAR(10) NOT NULL, pk2 VARCHAR(10) NOT NULL, col1 DATE, col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC)) AS SELECT * FROM "
                                 + tableName + " WHERE KEY_PREFIX = 'abc' ");
 
+                // view with composite PK with multiple Date PK values DESC
+                tenantConn.createStatement()
+                        .execute("CREATE VIEW " + viewName3
+                                + " (pk1 DATE(10) NOT NULL, pk2 DATE(10) NOT NULL, col1 VARCHAR(10), col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC)) AS SELECT * FROM "
+                                + tableName + " WHERE KEY_PREFIX = 'ab3' ");
+                
+                tenantConn.createStatement()
+                .execute("CREATE VIEW " + viewName4
+                        + " (pk1 DATE(10) NOT NULL, pk2 DECIMAL NOT NULL, pk3 VARCHAR(10) NOT NULL, col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC, pk3 DESC)) AS SELECT * FROM "
+                        + tableName + " WHERE KEY_PREFIX = 'ab4' ");
+
                 // upsert rows
                 upsertRows(viewName1, tenantConn);
                 upsertRows(viewName2, tenantConn);
@@ -835,12 +945,6 @@ public class ViewIT extends BaseViewIT {
                 validate(viewName1, tenantConn, whereClauses, expectedArray);
                 validate(viewName2, tenantConn, whereClauses, expectedArray);
 
-                // view with composite PK with multiple Date PK values DESC
-                tenantConn.createStatement()
-                        .execute("CREATE VIEW " + viewName3
-                                + " (pk1 DATE(10) NOT NULL, pk2 DATE(10) NOT NULL, col1 VARCHAR(10), col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC)) AS SELECT * FROM "
-                                + tableName + " WHERE KEY_PREFIX = 'ab3' ");
-
                 tenantConn.createStatement().execute("UPSERT INTO " + viewName3
                         + " (pk1, pk2, col1, col3) VALUES (TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss'), TO_DATE('2017-10-16 21:00:00', 'yyyy-MM-dd HH:mm:ss'), 'txt1', 10)");
                 tenantConn.createStatement().execute("UPSERT INTO " + viewName3
@@ -862,11 +966,6 @@ public class ViewIT extends BaseViewIT {
                                 "pk1 < TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss')" };
                 validate(viewName3, tenantConn, view3WhereClauses, expectedArray);
 
-                tenantConn.createStatement()
-                        .execute("CREATE VIEW " + viewName4
-                                + " (pk1 DATE(10) NOT NULL, pk2 DECIMAL NOT NULL, pk3 VARCHAR(10) NOT NULL, col3 DECIMAL CONSTRAINT PK PRIMARY KEY (pk1 DESC, pk2 DESC, pk3 DESC)) AS SELECT * FROM "
-                                + tableName + " WHERE KEY_PREFIX = 'ab4' ");
-
                 tenantConn.createStatement().execute("UPSERT INTO " + viewName4
                         + " (pk1, pk2, pk3, col3) VALUES (TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss'), 1, 'txt1', 10)");
                 tenantConn.createStatement().execute("UPSERT INTO " + viewName4
@@ -901,8 +1000,8 @@ public class ViewIT extends BaseViewIT {
                 Connection conn2 = DriverManager.getConnection(getUrl());
                 Statement s = conn.createStatement();
                 Statement s2 = conn2.createStatement()) {
-            String tableName = generateUniqueName();
-            String viewName = generateUniqueName();
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
             String indexName = generateUniqueName();
             helpTestQueryForViewOnTableThatHasIndex(s, s2, tableName, viewName, indexName);
         }
@@ -912,8 +1011,8 @@ public class ViewIT extends BaseViewIT {
     public void testQueryForViewOnTableThatHasIndex() throws SQLException {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Statement s = conn.createStatement()) {
-            String tableName = generateUniqueName();
-            String viewName = generateUniqueName();
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
             String indexName = generateUniqueName();
             helpTestQueryForViewOnTableThatHasIndex(s, s, tableName, viewName, indexName);
         }
@@ -966,4 +1065,237 @@ public class ViewIT extends BaseViewIT {
                 + " (pk1, pk2, col1, col3) VALUES ('testb', 'testa', TO_DATE('2017-10-16 22:00:00', 'yyyy-MM-dd HH:mm:ss'), 10)");
         tenantConn.commit();
     }
+    
+    @Test
+    public void testUpdatingPropertyOnBaseTable() throws Exception {
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            conn.createStatement()
+                    .execute("create table " + fullTableName
+                            + "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY "
+                            + "(tenantId, pk1)) MULTI_TENANT=true");
+            conn.createStatement().execute("CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName);
+            
+            conn.createStatement()
+                    .execute("ALTER TABLE " + fullTableName + " set IMMUTABLE_ROWS = true");
+            
+            // fetch the latest tables
+            PTable table = PhoenixRuntime.getTableNoCache(conn, fullTableName);
+            PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName);
+            assertEquals("IMMUTABLE_ROWS property set incorrectly", true, table.isImmutableRows());
+            assertEquals("IMMUTABLE_ROWS property set incorrectly", true, view.isImmutableRows());
+        }
+    }
+
+    public static String testUpdatableView(String fullTableName, String fullViewName, String fullChildViewName,
+            String childViewDDL, Integer saltBuckets, String tableDDLOptions) throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        if (saltBuckets != null) {
+            if (tableDDLOptions.length() != 0)
+                tableDDLOptions += ",";
+            tableDDLOptions += (" SALT_BUCKETS=" + saltBuckets);
+        }
+        String ddl = "CREATE TABLE " + fullTableName
+                + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, k3 DECIMAL, s VARCHAR CONSTRAINT pk PRIMARY KEY (k1, k2, k3))"
+                + tableDDLOptions;
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName + " WHERE k1 = 1";
+        conn.createStatement().execute(ddl);
+        ArrayList<String> splitPoints = Lists.newArrayList(fullTableName, fullViewName);
+        if (fullChildViewName != null) {
+            conn.createStatement().execute(childViewDDL);
+            splitPoints.add(fullChildViewName);
+        }
+
+        for (int i = 0; i < 10; i++) {
+            conn.createStatement().execute("UPSERT INTO " + fullTableName + " VALUES(" + (i % 4) + "," + (i + 100) + ","
+                    + (i > 5 ? 2 : 1) + ")");
+        }
+        conn.commit();
+        ResultSet rs;
+
+        rs = conn.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(10, rs.getInt(1));
+        rs = conn.createStatement().executeQuery("SELECT count(*) FROM " + fullViewName);
+        assertTrue(rs.next());
+        assertEquals(3, rs.getInt(1));
+        rs = conn.createStatement().executeQuery("SELECT k1, k2, k3 FROM " + fullViewName);
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+        assertEquals(101, rs.getInt(2));
+        assertEquals(1, rs.getInt(3));
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+        assertEquals(105, rs.getInt(2));
+        assertEquals(1, rs.getInt(3));
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+        assertEquals(109, rs.getInt(2));
+        assertEquals(2, rs.getInt(3));
+        assertFalse(rs.next());
+
+        conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,S,k3) VALUES(120,'foo',50.0)");
+        conn.createStatement().execute("UPSERT INTO " + fullViewName + "(k2,S,k3) VALUES(121,'bar',51.0)");
+        conn.commit();
+        rs = conn.createStatement().executeQuery("SELECT k1, k2 FROM " + fullViewName + " WHERE k2 >= 120");
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+        assertEquals(120, rs.getInt(2));
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+        assertEquals(121, rs.getInt(2));
+        assertFalse(rs.next());
+        conn.close();
+        return fullViewName;
+    }
+
+    public static Pair<String, Scan> testUpdatableViewIndex(String fullTableName, Integer saltBuckets,
+            boolean localIndex, String viewName) throws Exception {
+        ResultSet rs;
+        Connection conn = DriverManager.getConnection(getUrl());
+        String viewIndexName1 = "I_" + generateUniqueName();
+        String viewIndexPhysicalName = MetaDataUtil.getViewIndexPhysicalName(fullTableName);
+        if (localIndex) {
+            conn.createStatement().execute("CREATE LOCAL INDEX " + viewIndexName1 + " on " + viewName + "(k3)");
+        } else {
+            conn.createStatement().execute("CREATE INDEX " + viewIndexName1 + " on " + viewName + "(k3) include (s)");
+        }
+        conn.createStatement().execute("UPSERT INTO " + viewName + "(k2,S,k3) VALUES(120,'foo',50.0)");
+        conn.commit();
+
+        analyzeTable(conn, viewName);
+        List<KeyRange> splits = getAllSplits(conn, viewIndexName1);
+        // More guideposts with salted, since it's already pre-split at salt
+        // buckets
+        assertEquals(saltBuckets == null ? 6 : 8, splits.size());
+
+        String query = "SELECT k1, k2, k3, s FROM " + viewName + " WHERE k3 = 51.0";
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+        assertEquals(121, rs.getInt(2));
+        assertTrue(BigDecimal.valueOf(51.0).compareTo(rs.getBigDecimal(3)) == 0);
+        assertEquals("bar", rs.getString(4));
+        assertFalse(rs.next());
+        rs = conn.createStatement().executeQuery("EXPLAIN " + query);
+        String queryPlan = QueryUtil.getExplainPlan(rs);
+        if (localIndex) {
+            assertEquals("CLIENT PARALLEL " + (saltBuckets == null ? 1 : saltBuckets) + "-WAY RANGE SCAN OVER "
+                    + fullTableName + " [1,51]\n" + "    SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT",
+                    queryPlan);
+        } else {
+            assertEquals(saltBuckets == null
+                    ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + viewIndexPhysicalName + " [" + Short.MIN_VALUE + ",51]"
+                    : "CLIENT PARALLEL " + saltBuckets + "-WAY RANGE SCAN OVER " + viewIndexPhysicalName + " [0,"
+                            + Short.MIN_VALUE + ",51] - [" + (saltBuckets.intValue() - 1) + "," + Short.MIN_VALUE
+                            + ",51]\nCLIENT MERGE SORT",
+                    queryPlan);
+        }
+
+        String viewIndexName2 = "I_" + generateUniqueName();
+        if (localIndex) {
+            conn.createStatement().execute("CREATE LOCAL INDEX " + viewIndexName2 + " on " + viewName + "(s)");
+        } else {
+            conn.createStatement().execute("CREATE INDEX " + viewIndexName2 + " on " + viewName + "(s)");
+        }
+
+        // new index hasn't been analyzed yet
+        splits = getAllSplits(conn, viewIndexName2);
+        assertEquals(saltBuckets == null ? 1 : 3, splits.size());
+
+        // analyze table should analyze all view data
+        analyzeTable(conn, fullTableName);
+        splits = getAllSplits(conn, viewIndexName2);
+        assertEquals(saltBuckets == null ? 6 : 8, splits.size());
+
+        query = "SELECT k1, k2, s FROM " + viewName + " WHERE s = 'foo'";
+        Statement statement = conn.createStatement();
+        rs = statement.executeQuery(query);
+        Scan scan = statement.unwrap(PhoenixStatement.class).getQueryPlan().getContext().getScan();
+        assertTrue(rs.next());
+        assertEquals(1, rs.getInt(1));
+        assertEquals(120, rs.getInt(2));
+        assertEquals("foo", rs.getString(3));
+        assertFalse(rs.next());
+        rs = conn.createStatement().executeQuery("EXPLAIN " + query);
+        String physicalTableName;
+        if (localIndex) {
+            physicalTableName = fullTableName;
+            assertEquals("CLIENT PARALLEL " + (saltBuckets == null ? 1 : saltBuckets) + "-WAY RANGE SCAN OVER "
+                    + fullTableName + " [" + (2) + ",'foo']\n" + "    SERVER FILTER BY FIRST KEY ONLY\n"
+                    + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+        } else {
+            physicalTableName = viewIndexPhysicalName;
+            assertEquals(
+                    saltBuckets == null
+                            ? "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + viewIndexPhysicalName + " ["
+                                    + (Short.MIN_VALUE + 1) + ",'foo']\n" + "    SERVER FILTER BY FIRST KEY ONLY"
+                            : "CLIENT PARALLEL " + saltBuckets + "-WAY RANGE SCAN OVER " + viewIndexPhysicalName
+                                    + " [0," + (Short.MIN_VALUE + 1) + ",'foo'] - [" + (saltBuckets.intValue() - 1)
+                                    + "," + (Short.MIN_VALUE + 1) + ",'foo']\n"
+                                    + "    SERVER FILTER BY FIRST KEY ONLY\n" + "CLIENT MERGE SORT",
+                    QueryUtil.getExplainPlan(rs));
+        }
+        conn.close();
+        return new Pair<>(physicalTableName, scan);
+    }
+    
+    @Test
+    public void testChildViewCreationFails() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, FAILED_VIEWNAME);
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+        
+        String tableDdl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        try {
+            conn.createStatement().execute(ddl);
+            fail();
+        }
+        catch (PhoenixIOException e){
+        }
+        ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
+        conn.createStatement().execute(ddl);
+        
+        // the first child view should not exist
+        try {
+            PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+            fail();
+        } catch (SQLException e) {
+        }
+        
+        // we should be able to load the table
+        PhoenixRuntime.getTableNoCache(conn, fullTableName);
+        // we should be able to load the second view
+        PhoenixRuntime.getTableNoCache(conn, fullViewName2);
+    }
+    
+    private static final String FAILED_VIEWNAME = "FAILED_VIEW";
+    private static final byte[] ROWKEY_TO_FAIL_BYTES = SchemaUtil.getTableKey(null, Bytes.toBytes(SCHEMA2),
+            Bytes.toBytes(FAILED_VIEWNAME));
+    
+    public static class FailingRegionObserver extends SimpleRegionObserver {
+        @Override
+        public void preBatchMutate(ObserverContext<RegionCoprocessorEnvironment> c,
+                MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
+            if (shouldFail(c, miniBatchOp.getOperation(0))) {
+                // throwing anything other than instances of IOException result
+                // in this coprocessor being unloaded
+                // DoNotRetryIOException tells HBase not to retry this mutation
+                // multiple times
+                throw new DoNotRetryIOException();
+            }
+        }
+
+        private boolean shouldFail(ObserverContext<RegionCoprocessorEnvironment> c, Mutation m) {
+            TableName tableName = c.getEnvironment().getRegion().getRegionInfo().getTable();
+            return tableName.equals(PhoenixDatabaseMetaData.SYSTEM_CATALOG_HBASE_TABLE_NAME)
+                    && (Bytes.equals(ROWKEY_TO_FAIL_BYTES, m.getRow()));
+        }
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
index f914256..d86037c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseIndexIT.java
@@ -48,6 +48,7 @@ import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
@@ -124,6 +125,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
         String tableName = "TBL_" + generateUniqueName();
         String indexName = "IND_" + generateUniqueName();
         String fullTableName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, tableName);
+        String fullIndexName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, indexName);
 
         try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
             conn.setAutoCommit(false);
@@ -140,12 +142,12 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
             ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
             if(localIndex) {
                 assertEquals(
-                        "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" +
+                        "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + fullTableName + " [1]\n" +
                                 "    SERVER FILTER BY FIRST KEY ONLY\n" +
                                 "CLIENT MERGE SORT",
                                 QueryUtil.getExplainPlan(rs));
             } else {
-                assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + indexName + "\n"
+                assertEquals("CLIENT PARALLEL 1-WAY FULL SCAN OVER " + fullIndexName + "\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY", QueryUtil.getExplainPlan(rs));
             }
 
@@ -168,7 +170,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
             rs = conn.createStatement().executeQuery(query);
             assertTrue(rs.next());
 
-            query = "SELECT char_col1, int_col1 from "+indexName;
+            query = "SELECT char_col1, int_col1 from "+fullIndexName;
             try{
                 rs = conn.createStatement().executeQuery(query);
                 fail();
@@ -500,7 +502,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
             Statement stmt = conn.createStatement();
             stmt.execute(ddl);
 
-            query = "SELECT * FROM " + tableName;
+            query = "SELECT * FROM " + fullTableName;
             rs = conn.createStatement().executeQuery(query);
             assertFalse(rs.next());
 
@@ -772,10 +774,25 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
             conn.createStatement().execute(ddl);
 
             stmt = conn.prepareStatement("UPSERT INTO " + fullTableName + "(k, v1) VALUES(?,?)");
-            stmt.setString(1, "a");
-            stmt.setString(2, "y");
+            if (mutable) {
+	            stmt.setString(1, "a");
+	            stmt.setString(2, "y");
+	            stmt.execute();
+	            conn.commit();
+            }
+            stmt.setString(1, "b");
+            stmt.setString(2, "x");
             stmt.execute();
             conn.commit();
+	            
+            // the index table is one row
+            HTable table = new HTable(getUtility().getConfiguration(), fullTableName);
+            ResultScanner resultScanner = table.getScanner(new Scan());
+            for (Result result : resultScanner) {
+            	System.out.println(result);
+            }
+            resultScanner.close();
+            table.close();
 
             query = "SELECT * FROM " + fullTableName;
 
@@ -783,10 +800,15 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
             rs = conn.createStatement().executeQuery(query);
             assertTrue(rs.next());
             assertEquals("a", rs.getString(1));
-            assertEquals("y", rs.getString(2));
+            assertEquals(mutable ? "y" : "x", rs.getString(2));
+            assertEquals("1", rs.getString(3));
+            assertTrue(rs.next());
+            assertEquals("b", rs.getString(1));
+            assertEquals("x", rs.getString(2));
+            assertNull(rs.getString(3));
             assertFalse(rs.next());
+            }
         }
-    }
 
     @Test
     public void testMultipleUpdatesAcrossRegions() throws Exception {
@@ -1069,6 +1091,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
         String tableName = "TBL_" + generateUniqueName();
         String indexName = "IND_" + generateUniqueName();
         String fullTableName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, tableName);
+        String fullIndexeName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, indexName);
         // Check system tables priorities.
         try (HBaseAdmin admin = driver.getConnectionQueryServices(null, null).getAdmin(); 
                 Connection c = DriverManager.getConnection(getUrl())) {
@@ -1107,7 +1130,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
 
             if (!localIndex && mutable) {
                 HTableDescriptor indexTable = admin.getTableDescriptor(
-                        org.apache.hadoop.hbase.TableName.valueOf(indexName));
+                        org.apache.hadoop.hbase.TableName.valueOf(fullIndexeName));
                 val = indexTable.getValue("PRIORITY");
                 assertNotNull("PRIORITY is not set for table:" + indexTable, val);
                 assertTrue(Integer.parseInt(val) >= PhoenixRpcSchedulerFactory.getIndexPriority(config));
@@ -1140,7 +1163,7 @@ public abstract class BaseIndexIT extends ParallelStatsDisabledIT {
                 ddl += "(p1 desc, p2))";
             }
             stmt.executeUpdate(ddl);
-            ddl = "CREATE "+ (localIndex ? "LOCAL " : "") + " INDEX " + fullIndexName + " on " + fullTableName + "(a)";
+            ddl = "CREATE "+ (localIndex ? "LOCAL " : "") + " INDEX " + indexName + " on " + fullTableName + "(a)";
             stmt.executeUpdate(ddl);
 
             // upsert a single row

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
index 6c8f9e8..f3ee2cb 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ChildViewsUseParentViewIndexIT.java
@@ -29,7 +29,11 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Properties;
 
+import org.apache.hadoop.hbase.HConstants;
 import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
 import org.junit.Test;
 
@@ -111,7 +115,8 @@ public class ChildViewsUseParentViewIndexIT extends ParallelStatsDisabledIT {
             // create child of parent view that should be able to use the parent's index
             String childViewDdl = "CREATE VIEW " + childViewName1 + " AS SELECT * FROM " + parentViewName + " WHERE A2 = 'Y'";
             conn.createStatement().execute(childViewDdl);
-            
+
+            PTable childViewPTable = PhoenixRuntime.getTableNoCache(conn, childViewName1);
             // create child of parent view that should *not* be able to use the parent's index
             String grandChildViewDdl1 = "CREATE VIEW " + childViewName2 + " AS SELECT * FROM " + childViewName1 + " WHERE A3 = 'Z'";
             conn.createStatement().execute(grandChildViewDdl1);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
index 28aa1e9..e19284a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropColumnIT.java
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.end2end.index;
 
-import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -50,7 +49,6 @@ import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PName;
-import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableKey;
@@ -411,119 +409,4 @@ public class DropColumnIT extends ParallelStatsDisabledIT {
         }
     }
     
-    @Test
-    public void testDroppingIndexedColDropsViewIndex() throws Exception {
-        helpTestDroppingIndexedColDropsViewIndex(false);
-    }
-    
-    @Test
-    public void testDroppingIndexedColDropsMultiTenantViewIndex() throws Exception {
-        helpTestDroppingIndexedColDropsViewIndex(true);
-    }
-    
-    public void helpTestDroppingIndexedColDropsViewIndex(boolean isMultiTenant) throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        props.setProperty(TENANT_ID_ATTRIB, TENANT_ID);
-        try (Connection conn = getConnection();
-                Connection viewConn = isMultiTenant ? getConnection(props) : conn ) {
-            String tableWithView = generateUniqueName();
-            String viewOfTable = generateUniqueName();
-            String viewIndex1 = generateUniqueName();
-            String viewIndex2 = generateUniqueName();
-            
-            conn.setAutoCommit(false);
-            viewConn.setAutoCommit(false);
-            String ddlFormat = "CREATE TABLE " + tableWithView + " (%s k VARCHAR NOT NULL, v1 VARCHAR, v2 VARCHAR, v3 VARCHAR, v4 VARCHAR CONSTRAINT PK PRIMARY KEY(%s k))%s";
-            String ddl = String.format(ddlFormat, isMultiTenant ? "TENANT_ID VARCHAR NOT NULL, " : "",
-                    isMultiTenant ? "TENANT_ID, " : "", isMultiTenant ? "MULTI_TENANT=true" : "");
-            conn.createStatement().execute(ddl);
-            viewConn.createStatement()
-                    .execute(
-                        "CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableWithView );
-            // create an index with the column that will be dropped
-            viewConn.createStatement().execute("CREATE INDEX " + viewIndex1 + " ON " + viewOfTable + "(v2) INCLUDE (v4)");
-            // create an index without the column that will be dropped
-            viewConn.createStatement().execute("CREATE INDEX " + viewIndex2 + " ON " + viewOfTable + "(v1) INCLUDE (v4)");
-            // verify index was created
-            try {
-                viewConn.createStatement().execute("SELECT * FROM " + viewIndex1 );
-            } catch (TableNotFoundException e) {
-                fail("Index on view was not created");
-            }
-            
-            // upsert a single row
-            PreparedStatement stmt = viewConn.prepareStatement("UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?,?,?)");
-            stmt.setString(1, "a");
-            stmt.setString(2, "b");
-            stmt.setString(3, "c");
-            stmt.setString(4, "d");
-            stmt.setString(5, "e");
-            stmt.setInt(6, 1);
-            stmt.setString(7, "g");
-            stmt.execute();
-            viewConn.commit();
-
-            // verify the index was created
-            PhoenixConnection pconn = viewConn.unwrap(PhoenixConnection.class);
-            PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null; 
-            PTable view = pconn.getTable(new PTableKey(tenantId,  viewOfTable ));
-            PTable viewIndex = pconn.getTable(new PTableKey(tenantId,  viewIndex1 ));
-            byte[] viewIndexPhysicalTable = viewIndex.getPhysicalName().getBytes();
-            assertNotNull("Can't find view index", viewIndex);
-            assertEquals("Unexpected number of indexes ", 2, view.getIndexes().size());
-            assertEquals("Unexpected index ",  viewIndex1 , view.getIndexes().get(0).getName()
-                    .getString());
-            assertEquals("Unexpected index ",  viewIndex2 , view.getIndexes().get(1).getName()
-                .getString());
-            
-            // drop two columns
-            conn.createStatement().execute("ALTER TABLE " + tableWithView + " DROP COLUMN v2, v3 ");
-            
-            // verify columns were dropped
-            try {
-                conn.createStatement().execute("SELECT v2 FROM " + tableWithView );
-                fail("Column should have been dropped");
-            } catch (ColumnNotFoundException e) {
-            }
-            try {
-                conn.createStatement().execute("SELECT v3 FROM " + tableWithView );
-                fail("Column should have been dropped");
-            } catch (ColumnNotFoundException e) {
-            }
-            
-            // verify index metadata was dropped
-            try {
-                viewConn.createStatement().execute("SELECT * FROM " + viewIndex1 );
-                fail("Index metadata should have been dropped");
-            } catch (TableNotFoundException e) {
-            }
-            
-            pconn = viewConn.unwrap(PhoenixConnection.class);
-            view = pconn.getTable(new PTableKey(tenantId,  viewOfTable ));
-            try {
-                viewIndex = pconn.getTable(new PTableKey(tenantId,  viewIndex1 ));
-                fail("View index should have been dropped");
-            } catch (TableNotFoundException e) {
-            }
-            assertEquals("Unexpected number of indexes ", 1, view.getIndexes().size());
-            assertEquals("Unexpected index ",  viewIndex2 , view.getIndexes().get(0).getName().getString());
-            
-            // verify that the physical index view table is *not* dropped
-            conn.unwrap(PhoenixConnection.class).getQueryServices().getTableDescriptor(viewIndexPhysicalTable);
-            
-            // scan the physical table and verify there is a single row for the second local index
-            Scan scan = new Scan();
-            HTable table = (HTable) conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(viewIndexPhysicalTable);
-            ResultScanner results = table.getScanner(scan);
-            Result result = results.next();
-            assertNotNull(result);
-            PTable viewIndexPTable = pconn.getTable(new PTableKey(pconn.getTenantId(), viewIndex2));
-            PColumn column = viewIndexPTable.getColumnForColumnName(IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V4"));
-            byte[] cq = column.getColumnQualifierBytes();
-            // there should be a single row belonging to VIEWINDEX2 
-            assertNotNull(viewIndex2 + " row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, cq));
-            assertNull(results.next());
-        }
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
index 986c317..21fa312 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java
@@ -422,7 +422,7 @@ public class IndexMetadataIT extends ParallelStatsDisabledIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "create table test_table (char_pk varchar not null,"
+            String ddl = "create table " + generateUniqueName() + " (char_pk varchar not null,"
         		+ " int_col integer, long_col integer, int_col integer"
         		+ " constraint pk primary key (char_pk))";
             conn.createStatement().execute(ddl);
@@ -440,7 +440,7 @@ public class IndexMetadataIT extends ParallelStatsDisabledIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "create table test_table (char_pk varchar not null,"
+            String ddl = "create table " + generateUniqueName() + " (char_pk varchar not null,"
         		+ " a.int_col integer, a.long_col integer,"
         		+ " a.int_col integer, b.long_col integer"
         		+ " constraint pk primary key (char_pk))";