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:15 UTC

[10/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/AlterTableWithViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
index ab3a4ab..e39d492 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
@@ -21,6 +21,8 @@ import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MUTATE_TABLE;
 import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -33,37 +35,46 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Properties;
+import java.util.List;
 
 import org.apache.commons.lang.ArrayUtils;
-import org.apache.hadoop.hbase.client.HTableInterface;
+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.client.Table;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.coprocessor.TephraTransactionalProcessor;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryConstants;
+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.PTableKey;
 import org.apache.phoenix.schema.PTableType;
-import org.apache.phoenix.util.PropertiesUtil;
-import org.apache.phoenix.util.StringUtil;
-import org.apache.phoenix.util.TestUtil;
+import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.SchemaUtil;
 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.Function;
+import com.google.common.collect.Lists;
+
 @RunWith(Parameterized.class)
-public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
-    
+public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
+
     private final boolean isMultiTenant;
     private final boolean columnEncoded;
-    
-    private final String TENANT_SPECIFIC_URL1 = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant1";
-    private final String TENANT_SPECIFIC_URL2 = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant2";
+    private final String TENANT_SPECIFIC_URL1 = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + TENANT1;
+    private final String TENANT_SPECIFIC_URL2 = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + TENANT2;
     
     public AlterTableWithViewsIT(boolean isMultiTenant, boolean columnEncoded) {
         this.isMultiTenant = isMultiTenant;
@@ -77,6 +88,14 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
                 { true, false }, { true, true } });
     }
     
+    // transform PColumn to String
+    private Function<PColumn,String> function = new Function<PColumn,String>(){
+        @Override
+        public String apply(PColumn input) {
+            return input.getName().getString();
+        }
+    };
+    
     private String generateDDL(String format) {
         return generateDDL("", format);
     }
@@ -101,8 +120,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
     public void testAddNewColumnsToBaseTableWithViews() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {       
-            String tableName = generateUniqueName();
-            String viewOfTable = tableName + "_VIEW";
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " ("
                             + " %s ID char(1) NOT NULL,"
                             + " COL1 integer NOT NULL,"
@@ -113,12 +133,13 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             // adding a new pk column and a new regular column
             conn.createStatement().execute("ALTER TABLE " + tableName + " ADD COL3 varchar(10) PRIMARY KEY, COL4 integer");
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "COL4");
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 7, 5, "ID", "COL1", "COL2", "COL3", "COL4", "VIEW_COL1", "VIEW_COL2");
+            // add/drop column to a base table are no longer propagated to child views
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
         } 
     }
     
@@ -126,9 +147,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
     public void testAlterPropertiesOfParentTable() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {       
-            String tableName = generateUniqueName();
-            String viewOfTable1 = tableName + "_VIEW1";
-            String viewOfTable2 = tableName + "_VIEW2";
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            String viewOfTable2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+            
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " ("
                             + " %s ID char(1) NOT NULL,"
                             + " COL1 integer NOT NULL,"
@@ -138,11 +160,12 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             conn.createStatement().execute(generateDDL("UPDATE_CACHE_FREQUENCY=2", ddlFormat));
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName);
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName);
+            
             viewConn.createStatement().execute("ALTER VIEW " + viewOfTable2 + " SET UPDATE_CACHE_FREQUENCY = 1");
             
             PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class);
             PTable table = phoenixConn.getTable(new PTableKey(null, tableName));
-            PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null;
+            PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
             assertFalse(table.isImmutableRows());
             assertEquals(2, table.getUpdateCacheFrequency());
             PTable viewTable1 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable1));
@@ -166,7 +189,7 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             
             viewTable1 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable1));
             assertTrue(viewTable1.isImmutableRows());
-            assertEquals(3, viewTable1.getUpdateCacheFrequency());
+            assertEquals(2, viewTable1.getUpdateCacheFrequency());
             
             viewTable2 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable2));
             assertTrue(viewTable2.isImmutableRows());
@@ -178,16 +201,20 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             
             ResultSet rs;
             DatabaseMetaData md = conn.getMetaData();
-            rs = md.getTables("", "", StringUtil.escapeLike(tableName), null);
+            rs =
+                    md.getTables("", SchemaUtil.getSchemaNameFromFullName(tableName),
+                        SchemaUtil.getTableNameFromFullName(tableName), null);
             assertTrue(rs.next());
             assertEquals(gpw, rs.getLong(PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH));
             
-            rs = md.getTables(null, "", StringUtil.escapeLike(viewOfTable1), null);
+            rs = md.getTables(null, SchemaUtil.getSchemaNameFromFullName(viewOfTable1),
+                SchemaUtil.getTableNameFromFullName(viewOfTable1), null);
             assertTrue(rs.next());
             rs.getLong(PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH);
             assertTrue(rs.wasNull());
 
-            rs = md.getTables(null, "", StringUtil.escapeLike(viewOfTable2), null);
+            rs = md.getTables(null, SchemaUtil.getSchemaNameFromFullName(viewOfTable2),
+                SchemaUtil.getTableNameFromFullName(viewOfTable2), null);
             assertTrue(rs.next());
             rs.getLong(PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH);
             assertTrue(rs.wasNull());
@@ -198,8 +225,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
     public void testDropColumnsFromBaseTableWithView() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {
-            String tableName = generateUniqueName();
-            String viewOfTable = tableName + "_VIEW";
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " (" + " %s ID char(1) NOT NULL,"
                             + " COL1 integer NOT NULL," + " COL2 bigint NOT NULL,"
                             + " COL3 varchar(10)," + " COL4 varchar(10)," + " COL5 varchar(10),"
@@ -212,15 +240,16 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             viewConn.createStatement()
                     .execute(
                         "CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6,
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6,
                 "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2");
 
             // drop two columns from the base table
             conn.createStatement().execute("ALTER TABLE " + tableName + " DROP COLUMN COL3, COL5");
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 4,
                 QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL4");
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 6, 4,
-                "ID", "COL1", "COL2", "COL4", "VIEW_COL1", "VIEW_COL2");
+            // the columns will still exist in the view metadata , but are excluded while combining parent table columns
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 8, 6,
+                "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2");
         }
     }
     
@@ -230,33 +259,35 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {
             conn.setAutoCommit(false);
             viewConn.setAutoCommit(false);
-            String tableName = generateUniqueName();
-            String viewOfTable = tableName + "_VIEW";
-
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " ("
                             + " %s ID char(10) NOT NULL,"
                             + " COL1 integer NOT NULL,"
                             + " COL2 bigint NOT NULL,"
+                            + " COL3 varchar,"
                             + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
                             + " ) %s";
             conn.createStatement().execute(generateDDL(ddlFormat));
-            assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+            assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3");
             
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256), VIEW_COL3 VARCHAR, VIEW_COL4 DECIMAL, VIEW_COL5 DECIMAL(10,2), VIEW_COL6 VARCHAR, CONSTRAINT pk PRIMARY KEY (VIEW_COL5, VIEW_COL6) ) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn,viewOfTable, PTableType.VIEW, tableName, 0, 9, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
+            assertTableDefinition(viewConn,viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
             
             // upsert single row into view
-            String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?, ?, ?, ?, ?)";
+            String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?, ?, ?, ?, ?, ?)";
             PreparedStatement stmt = viewConn.prepareStatement(dml);
             stmt.setString(1, "view1");
             stmt.setInt(2, 12);
             stmt.setInt(3, 13);
-            stmt.setInt(4, 14);
-            stmt.setString(5, "view5");
+            stmt.setString(4, "view4");
+            stmt.setInt(5, 15);
             stmt.setString(6, "view6");
-            stmt.setInt(7, 17);
+            stmt.setString(7, "view7");
             stmt.setInt(8, 18);
-            stmt.setString(9, "view9");
+            stmt.setInt(9, 19);
+            stmt.setString(10, "view10");
             stmt.execute();
             viewConn.commit();
             
@@ -297,8 +328,8 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             }
             
             // validate that there were no columns added to the table or view, if its table is column encoded the sequence number changes when we increment the cq counter
-            assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 1 : 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 9, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
+            assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 1 : 0, 4, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3");
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
             
             if (columnEncoded) {
                 try {
@@ -312,17 +343,19 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             else {
                 // should succeed 
                 conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL4 DECIMAL, VIEW_COL2 VARCHAR(256)");
-                assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL4", "VIEW_COL2");
-                assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 9, 5, "ID", "COL1", "COL2", "VIEW_COL4", "VIEW_COL2", "VIEW_COL1", "VIEW_COL3", "VIEW_COL5", "VIEW_COL6");
-            
+                assertTableDefinition(conn, tableName, PTableType.TABLE, null, columnEncoded ? 2 : 1, 6, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2");
+                // even though we added columns to the base table, the view metadata remains the same as the base table metadata changes are no longer propagated to the chid view
+                assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 10, 4, "ID", "COL1", "COL2", "COL3", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
+                
                 // query table
                 ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
                 assertTrue(rs.next());
                 assertEquals("view1", rs.getString("ID"));
                 assertEquals(12, rs.getInt("COL1"));
                 assertEquals(13, rs.getInt("COL2"));
-                assertEquals("view5", rs.getString("VIEW_COL2"));
-                assertEquals(17, rs.getInt("VIEW_COL4"));
+                assertEquals("view4", rs.getString("COL3"));
+                assertEquals("view6", rs.getString("VIEW_COL2"));
+                assertEquals(18, rs.getInt("VIEW_COL4"));
                 assertFalse(rs.next());
     
                 // query view
@@ -331,13 +364,20 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
                 assertEquals("view1", rs.getString("ID"));
                 assertEquals(12, rs.getInt("COL1"));
                 assertEquals(13, rs.getInt("COL2"));
-                assertEquals(14, rs.getInt("VIEW_COL1"));
-                assertEquals("view5", rs.getString("VIEW_COL2"));
-                assertEquals("view6", rs.getString("VIEW_COL3"));
-                assertEquals(17, rs.getInt("VIEW_COL4"));
-                assertEquals(18, rs.getInt("VIEW_COL5"));
-                assertEquals("view9", rs.getString("VIEW_COL6"));
+                assertEquals("view4", rs.getString("COL3"));
+                assertEquals(15, rs.getInt("VIEW_COL1"));
+                assertEquals("view6", rs.getString("VIEW_COL2"));
+                assertEquals("view7", rs.getString("VIEW_COL3"));
+                assertEquals(18, rs.getInt("VIEW_COL4"));
+                assertEquals(19, rs.getInt("VIEW_COL5"));
+                assertEquals("view10", rs.getString("VIEW_COL6"));
                 assertFalse(rs.next());
+                
+                // the base column count and ordinal positions of columns is updated in the ptable (at read time) 
+                PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
+                PTable view = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable));
+                assertEquals(isMultiTenant ? 5: 4, view.getBaseColumnCount());
+                assertColumnsMatch(view.getColumns(), "ID", "COL1", "COL2", "COL3", "VIEW_COL4", "VIEW_COL2", "VIEW_COL1", "VIEW_COL3", "VIEW_COL5", "VIEW_COL6");
             }
         } 
     }
@@ -348,8 +388,8 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {      
             conn.setAutoCommit(false);
             viewConn.setAutoCommit(false);
-            String tableName = generateUniqueName();
-            String viewOfTable = tableName + "_VIEW";
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
 
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " ("
                             + " %s ID char(10) NOT NULL,"
@@ -359,9 +399,13 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
                             + " ) %s";
             conn.createStatement().execute(generateDDL(ddlFormat));
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+            PTable table = PhoenixRuntime.getTableNoCache(conn, tableName.toUpperCase());
+            assertColumnsMatch(table.getColumns(), "ID", "COL1", "COL2");
             
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            PTable view = PhoenixRuntime.getTableNoCache(viewConn, viewOfTable.toUpperCase());
+            assertColumnsMatch(view.getColumns(), "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             // upsert single row into view
             String dml = "UPSERT INTO " + viewOfTable + " VALUES(?,?,?,?,?)";
@@ -431,7 +475,8 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             // add the pk column of the view to the base table
             conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL1 DECIMAL(10,2) PRIMARY KEY, VIEW_COL2 VARCHAR(256) PRIMARY KEY");
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, tableName, 1, 5, 5, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            // even though we added columns to the base table, the sequence number and base column count is not updated in the view metadata (in SYSTEM.CATALOG)
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             // query table
             ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
@@ -452,6 +497,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertEquals(14, rs.getInt("VIEW_COL1"));
             assertEquals("view5", rs.getString("VIEW_COL2"));
             assertFalse(rs.next());
+            
+            // the base column count is updated in the ptable
+            PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
+            view = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable));
+            assertEquals(isMultiTenant ? 4 : 3, view.getBaseColumnCount());
         } 
     }
     
@@ -459,9 +509,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
     public void testAddExistingViewPkColumnToBaseTableWithMultipleViews() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {
-            String tableName = generateUniqueName();
-            String viewOfTable1 = tableName + "_VIEW1";
-            String viewOfTable2 = tableName + "_VIEW2";
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            String viewOfTable2 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + "("
                             + " %s ID char(10) NOT NULL,"
                             + " COL1 integer NOT NULL,"
@@ -472,10 +523,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL3 VARCHAR(256), VIEW_COL4 DECIMAL(10,2) CONSTRAINT pk PRIMARY KEY (VIEW_COL3, VIEW_COL4)) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL3", "VIEW_COL4");
+            assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL3", "VIEW_COL4");
             
             try {
                 // should fail because there are two view with different pk columns
@@ -523,9 +574,10 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             conn.setAutoCommit(false);
             viewConn.setAutoCommit(false);
             viewConn2.setAutoCommit(false);
-            String tableName = generateUniqueName();
-            String viewOfTable1 = tableName + "_VIEW1";
-            String viewOfTable2 = tableName + "_VIEW2";
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            String viewOfTable2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+            
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + "("
                     + " %s ID char(10) NOT NULL,"
                     + " COL1 integer NOT NULL,"
@@ -536,11 +588,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             viewConn2.createStatement().execute("CREATE VIEW " + viewOfTable2 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM " + tableName);
-            assertTableDefinition(conn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
-            
+            assertTableDefinition(viewConn2, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3,  "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+
             // upsert single row into both view
             String dml = "UPSERT INTO " + viewOfTable1 + " VALUES(?,?,?,?,?)";
             PreparedStatement stmt = viewConn.prepareStatement(dml);
@@ -590,8 +642,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             
             conn.createStatement().execute("ALTER TABLE " + tableName + " ADD VIEW_COL1 DECIMAL(10,2) PRIMARY KEY, VIEW_COL2 VARCHAR(256) PRIMARY KEY");
             assertTableDefinition(conn, tableName, PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
-            assertTableDefinition(conn, viewOfTable1, PTableType.VIEW, tableName, 1, 5, 5, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
-            assertTableDefinition(conn, viewOfTable2, PTableType.VIEW, tableName, 1, 5, 5, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            // even though we added columns to the base table, the sequence number and base column count is not updated in the view metadata (in SYSTEM.CATALOG)
+            assertTableDefinition(viewConn, viewOfTable1, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            assertTableDefinition(viewConn, viewOfTable2, PTableType.VIEW, tableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             // query table
             ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
@@ -620,22 +673,37 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertEquals(14, rs.getInt("VIEW_COL1"));
             assertEquals("view5", rs.getString("VIEW_COL2"));
             assertFalse(rs.next());
+            
+            // the base column count is updated in the ptable
+            PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
+            PTable view1 = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable1));
+            PTable view2 = viewConn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable2));
+            assertEquals(isMultiTenant ? 4 : 3, view1.getBaseColumnCount());
+            assertEquals(isMultiTenant ? 4 : 3, view2.getBaseColumnCount());
         }
     }
     
-    public void assertTableDefinition(Connection conn, String tableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnNames) throws Exception {
+    public void assertTableDefinition(Connection conn, String fullTableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnNames) throws Exception {
         int delta = isMultiTenant ? 1 : 0;
         String[] cols;
-        if (isMultiTenant) {
+        if (isMultiTenant && tableType!=PTableType.VIEW) {
             cols = (String[])ArrayUtils.addAll(new String[]{"TENANT_ID"}, columnNames);
         }
         else {
             cols = columnNames;
         }
-        AlterMultiTenantTableWithViewsIT.assertTableDefinition(conn, tableName, tableType, parentTableName, sequenceNumber, columnCount + delta,
+        AlterMultiTenantTableWithViewsIT.assertTableDefinition(conn, fullTableName, tableType, parentTableName, sequenceNumber, columnCount + delta,
             baseColumnCount==QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT ? baseColumnCount : baseColumnCount +delta, cols);
     }
     
+    public void assertColumnsMatch(List<PColumn> actual, String... expected) {
+        List<String> expectedCols = Lists.newArrayList(expected);
+        if (isMultiTenant) {
+            expectedCols.add(0, "TENANT_ID");
+        }
+        assertEquals(expectedCols, Lists.transform(actual, function));
+    }
+    
     public static String getSystemCatalogEntriesForTable(Connection conn, String tableName, String message) throws Exception {
         StringBuilder sb = new StringBuilder(message);
         sb.append("\n\n\n");
@@ -654,73 +722,78 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
     }
     
     
-    
     @Test
     public void testAlteringViewThatHasChildViews() throws Exception {
-        String baseTable = generateUniqueName();
-        String childView = baseTable + "cildView";
-        String grandChildView = baseTable + "grandChildView";
+        String baseTable = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String childView = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String grandChildView = SchemaUtil.getTableName(SCHEMA4, generateUniqueName());
         try (Connection conn = DriverManager.getConnection(getUrl());
-                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {
-            String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTable + "  ("
-                    + " %s PK2 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR "
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK2)"
-                    + " ) %s";
+                Connection viewConn =
+                        isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn) {
+            String ddlFormat =
+                    "CREATE TABLE IF NOT EXISTS " + baseTable + "  ("
+                            + " %s PK2 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR "
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK2)" + " ) %s";
             conn.createStatement().execute(generateDDL(ddlFormat));
 
             String childViewDDL = "CREATE VIEW " + childView + " AS SELECT * FROM " + baseTable;
             viewConn.createStatement().execute(childViewDDL);
+            
+            PTable view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase());
+            assertColumnsMatch(view.getColumns(), "PK2", "V1", "V2");
 
+            String grandChildViewDDL =
+                    "CREATE VIEW " + grandChildView + " AS SELECT * FROM " + childView;
+            viewConn.createStatement().execute(grandChildViewDDL);
+            
             String addColumnToChildViewDDL =
                     "ALTER VIEW " + childView + " ADD CHILD_VIEW_COL VARCHAR";
             viewConn.createStatement().execute(addColumnToChildViewDDL);
 
-            String grandChildViewDDL =
-                    "CREATE VIEW " + grandChildView + " AS SELECT * FROM " + childView;
-            viewConn.createStatement().execute(grandChildViewDDL);
+            view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase());
+            assertColumnsMatch(view.getColumns(), "PK2", "V1", "V2", "CHILD_VIEW_COL");
+
+            PTable gcView = PhoenixRuntime.getTableNoCache(viewConn, grandChildView.toUpperCase());
+            assertColumnsMatch(gcView.getColumns(), "PK2", "V1", "V2", "CHILD_VIEW_COL");
 
             // dropping base table column from child view should succeed
             String dropColumnFromChildView = "ALTER VIEW " + childView + " DROP COLUMN V2";
             viewConn.createStatement().execute(dropColumnFromChildView);
+            view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase());
+            assertColumnsMatch(view.getColumns(), "PK2", "V1", "CHILD_VIEW_COL");
 
             // dropping view specific column from child view should succeed
             dropColumnFromChildView = "ALTER VIEW " + childView + " DROP COLUMN CHILD_VIEW_COL";
             viewConn.createStatement().execute(dropColumnFromChildView);
-            
+            view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase());
+            assertColumnsMatch(view.getColumns(), "PK2", "V1");
+
             // Adding column to view that has child views is allowed
             String addColumnToChildView = "ALTER VIEW " + childView + " ADD V5 VARCHAR";
             viewConn.createStatement().execute(addColumnToChildView);
-            // V5 column should be visible now for childView
-            viewConn.createStatement().execute("SELECT V5 FROM " + childView);    
-            
-            // However, column V5 shouldn't have propagated to grandChildView. Not till PHOENIX-2054 is fixed.
-            try {
-                viewConn.createStatement().execute("SELECT V5 FROM " + grandChildView);
-            } catch (SQLException e) {
-                assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
-            }
+            // V5 column should be visible now for both childView and grandChildView
+            viewConn.createStatement().execute("SELECT V5 FROM " + childView);
+            viewConn.createStatement().execute("SELECT V5 FROM " + grandChildView);
 
-            // dropping column from the grand child view, however, should work.
-            String dropColumnFromGrandChildView =
-                    "ALTER VIEW " + grandChildView + " DROP COLUMN CHILD_VIEW_COL";
-            viewConn.createStatement().execute(dropColumnFromGrandChildView);
+            view = PhoenixRuntime.getTableNoCache(viewConn, childView.toUpperCase());
+            assertColumnsMatch(view.getColumns(), "PK2", "V1", "V5");
 
-            // similarly, dropping column inherited from the base table should work.
-            dropColumnFromGrandChildView = "ALTER VIEW " + grandChildView + " DROP COLUMN V2";
-            viewConn.createStatement().execute(dropColumnFromGrandChildView);
+            // grand child view should have the same columns
+            gcView = PhoenixRuntime.getTableNoCache(viewConn, grandChildView.toUpperCase());
+            assertColumnsMatch(gcView.getColumns(), "PK2", "V1", "V5");
         }
     }
     
     @Test
     public void testDivergedViewsStayDiverged() throws Exception {
-        String baseTable = generateUniqueName();
-        String view1 = baseTable + "_VIEW1";
-        String view2 = baseTable + "_VIEW2";
+        String baseTable = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String view1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String view2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ;
                 Connection viewConn2 = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL2) : conn) {
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTable + " ("
-                    + " %s PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR "
+                    + " %s PK1 VARCHAR NOT NULL, V0 VARCHAR, V1 VARCHAR, V2 VARCHAR "
                     + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK1)"
                     + " ) %s";
             conn.createStatement().execute(generateDDL(ddlFormat));
@@ -734,8 +807,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             // Drop the column inherited from base table to make it diverged
             String dropColumn = "ALTER VIEW " + view1 + " DROP COLUMN V2";
             viewConn.createStatement().execute(dropColumn);
+            PTable table = PhoenixRuntime.getTableNoCache(viewConn, view1);
+            assertEquals(QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT, table.getBaseColumnCount());
             
-            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR";
+            // Add a new regular column and pk column  to the base table
+            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR, PK2 VARCHAR PRIMARY KEY";
             conn.createStatement().execute(alterBaseTable);
             
             // Column V3 shouldn't have propagated to the diverged view.
@@ -749,6 +825,43 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             // However, column V3 should have propagated to the non-diverged view.
             sql = "SELECT V3 FROM " + view2;
             viewConn2.createStatement().execute(sql);
+            
+            // PK2 should be in both views
+            sql = "SELECT PK2 FROM " + view1;
+            viewConn.createStatement().execute(sql);
+            sql = "SELECT PK2 FROM " + view2;
+            viewConn2.createStatement().execute(sql);
+            
+            // Drop a column from the base table
+            alterBaseTable = "ALTER TABLE " + baseTable + " DROP COLUMN V1";
+            conn.createStatement().execute(alterBaseTable);
+            
+            // V1 should be dropped from both diverged and non-diverged views
+            sql = "SELECT V1 FROM " + view1;
+            try {
+                viewConn.createStatement().execute(sql);
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+            }
+            sql = "SELECT V1 FROM " + view2;
+            try {
+                viewConn2.createStatement().execute(sql);
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+            }
+            
+            // V0 should be still exist in both diverged and non-diverged views
+            sql = "SELECT V0 FROM " + view1;
+            viewConn.createStatement().execute(sql);
+            sql = "SELECT V0 FROM " + view2;
+            viewConn2.createStatement().execute(sql);
+
+			// add the column that was dropped back to the view
+			String addColumn = "ALTER VIEW " + view1 + " ADD V2 VARCHAR";
+			viewConn.createStatement().execute(addColumn);
+			// V2 should not exist in the view
+			sql = "SELECT V0 FROM " + view1;
+			viewConn.createStatement().execute(sql);
         } 
     }
     
@@ -756,8 +869,9 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
     public void testMakeBaseTableTransactional() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {  
-            String baseTableName = "NONTXNTBL_" + generateUniqueName() + (isMultiTenant ? "0":"1");
-            String viewOfTable = baseTableName + "_VIEW";
+            String baseTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            
             String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTableName + " ("
                             + " %s ID char(1) NOT NULL,"
                             + " COL1 integer NOT NULL,"
@@ -768,11 +882,11 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertTableDefinition(conn, baseTableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
             viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM "+baseTableName);
-            assertTableDefinition(conn, viewOfTable, PTableType.VIEW, baseTableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            assertTableDefinition(viewConn, viewOfTable, PTableType.VIEW, baseTableName, 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
-            PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null;
+            PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
             PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class);
-            HTableInterface htable = phoenixConn.getQueryServices().getTable(Bytes.toBytes(baseTableName));
+            Table htable = phoenixConn.getQueryServices().getTable(Bytes.toBytes(baseTableName));
             assertFalse(htable.getTableDescriptor().getCoprocessors().contains(TephraTransactionalProcessor.class.getName()));
             assertFalse(phoenixConn.getTable(new PTableKey(null, baseTableName)).isTransactional());
             assertFalse(viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).isTransactional());
@@ -787,50 +901,50 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertTrue(viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).isTransactional());
         } 
     }
-    
+
     @Test
     public void testAlterTablePropertyOnView() throws Exception {
-    	try (Connection conn = DriverManager.getConnection(getUrl());
+        try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {  
-            String baseTableName = "NONTXNTBL_" + generateUniqueName() + (isMultiTenant ? "0":"1");
-            String viewOfTable = baseTableName + "_VIEW";
-            
-	        String ddl = "CREATE TABLE " + baseTableName + " (\n"
-	                +"%s ID VARCHAR(15) NOT NULL,\n"
-	                + " COL1 integer NOT NULL,"
-	                +"CREATED_DATE DATE,\n"
-	                +"CONSTRAINT PK PRIMARY KEY (%s ID, COL1)) %s";
-	        conn.createStatement().execute(generateDDL(ddl));
-	        ddl = "CREATE VIEW " + viewOfTable + " AS SELECT * FROM " + baseTableName;
-	        viewConn.createStatement().execute(ddl);
-	        
-	        try {
-	        	viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET IMMUTABLE_ROWS = true");
-	            fail();
-	        } catch (SQLException e) {
-	            assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode());
-	        }
-	        
-        	viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET UPDATE_CACHE_FREQUENCY = 100");
-        	viewConn.createStatement().execute("SELECT * FROM "+ viewOfTable);
-        	PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null;
-        	assertEquals(100, viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).getUpdateCacheFrequency());
-	        
-	        try {
-	        	viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET APPEND_ONLY_SCHEMA = true");
-	            fail();
-	        } catch (SQLException e) {
-	            assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode());
-	        }
-    	}
+            String baseTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            
+            String ddl = "CREATE TABLE " + baseTableName + " (\n"
+                    +"%s ID VARCHAR(15) NOT NULL,\n"
+                    + " COL1 integer NOT NULL,"
+                    +"CREATED_DATE DATE,\n"
+                    +"CONSTRAINT PK PRIMARY KEY (%s ID, COL1)) %s";
+            conn.createStatement().execute(generateDDL(ddl));
+            ddl = "CREATE VIEW " + viewOfTable + " AS SELECT * FROM " + baseTableName;
+            viewConn.createStatement().execute(ddl);
+            
+            try {
+                viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET IMMUTABLE_ROWS = true");
+                fail();
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode());
+            }
+            
+            viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET UPDATE_CACHE_FREQUENCY = 100");
+            viewConn.createStatement().execute("SELECT * FROM "+ viewOfTable);
+            PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
+            assertEquals(100, viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable)).getUpdateCacheFrequency());
+            
+            try {
+                viewConn.createStatement().execute("ALTER VIEW " + viewOfTable + " SET APPEND_ONLY_SCHEMA = true");
+                fail();
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW.getErrorCode(), e.getErrorCode());
+            }
+        }
     }
     
     @Test
     public void testAlterAppendOnlySchema() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {  
-            String baseTableName = "NONTXNTBL_" + generateUniqueName() + (isMultiTenant ? "0":"1");
-            String viewOfTable = baseTableName + "_VIEW";
+            String baseTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
             
             String ddl = "CREATE TABLE " + baseTableName + " (\n"
                     +"%s ID VARCHAR(15) NOT NULL,\n"
@@ -843,7 +957,7 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             
             PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class);
             PTable table = phoenixConn.getTable(new PTableKey(null, baseTableName));
-            PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null;
+            PName tenantId = isMultiTenant ? PNameFactory.newName(TENANT1) : null;
             assertFalse(table.isAppendOnlySchema());
             PTable viewTable = viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, viewOfTable));
             assertFalse(viewTable.isAppendOnlySchema());
@@ -866,45 +980,112 @@ public class AlterTableWithViewsIT extends ParallelStatsDisabledIT {
             assertTrue(viewTable.isAppendOnlySchema());
         }
     }
-
+    
     @Test
-    public void testAlterTableWithIndexesExtendPk() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        conn.setAutoCommit(false);
-        String tableName = generateUniqueName();
-        String indexName1 = "I_" + generateUniqueName();
-        String indexName2 = "I_" + generateUniqueName();
+    public void testDroppingIndexedColDropsViewIndex() throws Exception {
+        try (Connection conn =DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn  ) {
+            String tableWithView = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            String viewSchemaName = SchemaUtil.getSchemaNameFromFullName(viewOfTable);
+            String viewIndex1 = generateUniqueName();
+            String viewIndex2 = generateUniqueName();
+            String fullNameViewIndex1 = SchemaUtil.getTableName(viewSchemaName, viewIndex1);
+            String fullNameViewIndex2 = SchemaUtil.getTableName(viewSchemaName, viewIndex2);
+            
+            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";
+            conn.createStatement().execute(generateDDL(ddlFormat));
+            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 " + fullNameViewIndex1 );
+            } 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();
 
-        try {
-            String ddl = "CREATE TABLE " + tableName +
-            " (ORG_ID CHAR(15) NOT NULL," +
-            " PARTITION_KEY CHAR(3) NOT NULL, " +
-            " ACTIVITY_DATE DATE NOT NULL, " +
-            " FK1_ID CHAR(15) NOT NULL, " +
-            " FK2_ID CHAR(15) NOT NULL, " +
-            " TYPE VARCHAR NOT NULL, " +
-            " IS_OPEN BOOLEAN " +
-            " CONSTRAINT PKVIEW PRIMARY KEY " +
-            "(" +
-            "ORG_ID, PARTITION_KEY, ACTIVITY_DATE, FK1_ID, FK2_ID, TYPE" +
-            "))";
-            createTestTable(getUrl(), ddl);
-            
-            String idx1ddl = "CREATE INDEX " + indexName1 + " ON " + tableName + " (FK1_ID, ACTIVITY_DATE DESC) INCLUDE (IS_OPEN)";
-            PreparedStatement stmt1 = conn.prepareStatement(idx1ddl);
-            stmt1.execute();
-            
-            String idx2ddl = "CREATE INDEX " + indexName2 + " ON " + tableName + " (FK2_ID, ACTIVITY_DATE DESC) INCLUDE (IS_OPEN)";
-            PreparedStatement stmt2 = conn.prepareStatement(idx2ddl);
-            stmt2.execute();
-        
-            ddl = "ALTER TABLE " + tableName + " ADD SOURCE VARCHAR(25) NULL PRIMARY KEY";
-            PreparedStatement stmt3 = conn.prepareStatement(ddl);
-            stmt3.execute();
-        } finally {
-            conn.close();
+            // 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,  fullNameViewIndex1 ));
+            byte[] viewIndexPhysicalTable = viewIndex.getPhysicalName().getBytes();
+            assertNotNull("Can't find view index", viewIndex);
+            assertEquals("Unexpected number of indexes ", 2, view.getIndexes().size());
+            assertEquals("Unexpected index ",  fullNameViewIndex1 , view.getIndexes().get(0).getName()
+                    .getString());
+            assertEquals("Unexpected index ",  fullNameViewIndex2 , 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 " + fullNameViewIndex1 );
+                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,  fullNameViewIndex1 ));
+                fail("View index should have been dropped");
+            } catch (TableNotFoundException e) {
+            }
+            assertEquals("Unexpected number of indexes ", 1, view.getIndexes().size());
+            assertEquals("Unexpected index ",  fullNameViewIndex2 , 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(), fullNameViewIndex2));
+            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(fullNameViewIndex2 + " 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/AppendOnlySchemaIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java
index d601beb..b39c4f0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AppendOnlySchemaIT.java
@@ -109,7 +109,9 @@ public class AppendOnlySchemaIT extends ParallelStatsDisabledIT {
             }
             
             // verify getTable rpcs
-            verify(connectionQueryServices, sameClient ? never() : times(1)).getTable((PName)isNull(), eq(new byte[0]), eq(Bytes.toBytes(viewName)), anyLong(), anyLong());
+            verify(connectionQueryServices, sameClient ? never() : times(1)).getTable(
+                (PName) isNull(), eq(new byte[0]), eq(Bytes.toBytes(viewName)), anyLong(),
+                anyLong(), eq(false), eq(false), (PTable) isNull());
             
             // verify no create table rpcs
             verify(connectionQueryServices, never()).createTable(anyListOf(Mutation.class),

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
index c61d970..9bd689e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseTenantSpecificViewIndexIT.java
@@ -32,13 +32,12 @@ import java.util.Set;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.collect.Lists;
 
-public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT {
+public class BaseTenantSpecificViewIndexIT extends SplitSystemCatalogIT {
     
-    public static final String TENANT1_ID = "tenant1";
-    public static final String TENANT2_ID = "tenant2";
     public static final String NON_STRING_TENANT_ID = "1234";
     
     protected Set<Pair<String, String>> tenantViewsToDelete = newHashSet();
@@ -48,12 +47,13 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT {
     }
     
     protected void testUpdatableView(Integer saltBuckets, boolean localIndex) throws Exception {
-        String tableName = generateUniqueName();
+        String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         createBaseTable(tableName, saltBuckets, true);
-        Connection conn = createTenantConnection(TENANT1_ID);
+        Connection conn = createTenantConnection(TENANT1);
         try {
-            String viewName = createAndPopulateTenantView(conn, TENANT1_ID, tableName, "");
-            createAndVerifyIndex(conn, viewName, tableName, saltBuckets, TENANT1_ID, "", localIndex);
+            createAndPopulateTenantView(conn, TENANT1, tableName, "", viewName);
+            createAndVerifyIndex(conn, viewName, tableName, saltBuckets, TENANT1, "", localIndex);
             verifyViewData(conn, viewName, "");
         } finally {
             try { conn.close();} catch (Exception ignored) {}
@@ -61,11 +61,12 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT {
     }
 
     protected void testUpdatableViewNonString(Integer saltBuckets, boolean localIndex) throws Exception {
-        String tableName = generateUniqueName();
+        String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         createBaseTable(tableName, saltBuckets, false);
         Connection conn = createTenantConnection(NON_STRING_TENANT_ID);
         try {
-            String viewName = createAndPopulateTenantView(conn, NON_STRING_TENANT_ID, tableName, "");
+            createAndPopulateTenantView(conn, NON_STRING_TENANT_ID, tableName, "", viewName);
             createAndVerifyIndexNonStringTenantId(conn, viewName, tableName, NON_STRING_TENANT_ID, "");
             verifyViewData(conn, viewName, "");
         } finally {
@@ -78,20 +79,22 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT {
     }
 
     protected void testUpdatableViewsWithSameNameDifferentTenants(Integer saltBuckets, boolean localIndex) throws Exception {
-        String tableName = generateUniqueName();
+        String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String viewName2 = SchemaUtil.getTableName(SCHEMA4, generateUniqueName());
         createBaseTable(tableName, saltBuckets, true);
-        Connection conn1 = createTenantConnection(TENANT1_ID);
-        Connection conn2 = createTenantConnection(TENANT2_ID);
+        Connection conn1 = createTenantConnection(TENANT1);
+        Connection conn2 = createTenantConnection(TENANT2);
         try {
             String prefixForTenant1Data = "TI";
             String prefixForTenant2Data = "TII";
             
             // tenant views with same name for two different tables
-            String viewName1 = createAndPopulateTenantView(conn1, TENANT1_ID, tableName, prefixForTenant1Data);
-            String viewName2 = createAndPopulateTenantView(conn2, TENANT2_ID, tableName, prefixForTenant2Data);
+            createAndPopulateTenantView(conn1, TENANT1, tableName, prefixForTenant1Data, viewName1);
+            createAndPopulateTenantView(conn2, TENANT2, tableName, prefixForTenant2Data, viewName2);
             
-            createAndVerifyIndex(conn1, viewName1, tableName, saltBuckets, TENANT1_ID, prefixForTenant1Data, localIndex);
-            createAndVerifyIndex(conn2, viewName2, tableName, saltBuckets, TENANT2_ID, prefixForTenant2Data, localIndex);
+            createAndVerifyIndex(conn1, viewName1, tableName, saltBuckets, TENANT1, prefixForTenant1Data, localIndex);
+            createAndVerifyIndex(conn2, viewName2, tableName, saltBuckets, TENANT2, prefixForTenant2Data, localIndex);
             
             verifyViewData(conn1, viewName1, prefixForTenant1Data);
             verifyViewData(conn2, viewName2, prefixForTenant2Data);
@@ -114,8 +117,7 @@ public class BaseTenantSpecificViewIndexIT extends ParallelStatsDisabledIT {
         conn.close();
     }
     
-    private String createAndPopulateTenantView(Connection conn, String tenantId, String baseTable, String valuePrefix) throws SQLException {
-        String viewName = generateUniqueName();
+    private String createAndPopulateTenantView(Connection conn, String tenantId, String baseTable, String valuePrefix, String viewName) throws SQLException {
         String ddl = "CREATE VIEW " + viewName + "(v2 VARCHAR) AS SELECT * FROM " + baseTable + " WHERE k1 = 1";
         conn.createStatement().execute(ddl);
         tenantViewsToDelete.add(new Pair<String, String>(tenantId, viewName ));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java
index abaa2f6..0dc4410 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ExplainPlanWithStatsEnabledIT.java
@@ -692,7 +692,7 @@ public class ExplainPlanWithStatsEnabledIT extends ParallelStatsEnabledIT {
             assertTrue(info.getEstimateInfoTs() > 0);
 
             conn.createStatement()
-                    .execute("ALTER TABLE " + viewName + " SET USE_STATS_FOR_PARALLELIZATION=true");
+                    .execute("ALTER VIEW " + viewName + " SET USE_STATS_FOR_PARALLELIZATION=true");
             sql = "SELECT COUNT(*) FROM " + viewName;
             // query the view
             rs = conn.createStatement().executeQuery(sql);
@@ -1202,33 +1202,44 @@ public class ExplainPlanWithStatsEnabledIT extends ParallelStatsEnabledIT {
         assertEquals("B", rs.getString(1));
     }
 
-	@Test
-	public void testUseStatsForParallelizationProperyOnViewIndex() throws SQLException {
-		String tableName = generateUniqueName();
-		String viewName = generateUniqueName();
-		String tenantViewName = generateUniqueName();
-		String viewIndexName = generateUniqueName();
-		boolean useStats = !DEFAULT_USE_STATS_FOR_PARALLELIZATION;
-		try (Connection conn = DriverManager.getConnection(getUrl())) {
-			conn.createStatement()
-					.execute("create table " + tableName
-							+ "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY "
-							+ "(tenantId, pk1)) MULTI_TENANT=true");
-			try (Connection tenantConn = getTenantConnection("tenant1")) {
-				conn.createStatement().execute("CREATE VIEW " + viewName + " AS SELECT * FROM " + tableName);
-				conn.createStatement().execute("CREATE INDEX " + viewIndexName + " on " + viewName + " (v) ");
-				tenantConn.createStatement().execute("CREATE VIEW " + tenantViewName + " AS SELECT * FROM " + viewName);
-				conn.createStatement()
-						.execute("ALTER TABLE " + tableName + " set USE_STATS_FOR_PARALLELIZATION=" + useStats);
-				// fetch the latest view ptable 
-				PhoenixRuntime.getTableNoCache(tenantConn, viewName);
-				PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
-				PTable viewIndex = phxConn.getTable(new PTableKey(phxConn.getTenantId(), viewIndexName));
-				assertEquals("USE_STATS_FOR_PARALLELIZATION property set incorrectly", useStats,
-						PhoenixConfigurationUtil
-								.getStatsForParallelizationProp(tenantConn.unwrap(PhoenixConnection.class), viewIndex));
-			}
-		}
-	}
+    @Test
+    public void testUseStatsForParallelizationProperyOnViewIndex() throws SQLException {
+        String tableName = generateUniqueName();
+        String viewName = generateUniqueName();
+        String tenantViewName = generateUniqueName();
+        String viewIndexName = generateUniqueName();
+        boolean useStats = !DEFAULT_USE_STATS_FOR_PARALLELIZATION;
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            conn.createStatement()
+                    .execute("create table " + tableName
+                            + "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY "
+                            + "(tenantId, pk1)) MULTI_TENANT=true");
+            try (Connection tenantConn = getTenantConnection("tenant1")) {
+                conn.createStatement().execute("CREATE VIEW " + viewName + " AS SELECT * FROM " + tableName);
+                conn.createStatement().execute("CREATE INDEX " + viewIndexName + " on " + viewName + " (v) ");
+                tenantConn.createStatement().execute("CREATE VIEW " + tenantViewName + " AS SELECT * FROM " + viewName);
+                conn.createStatement()
+                        .execute("ALTER TABLE " + tableName + " set USE_STATS_FOR_PARALLELIZATION=" + useStats);
+                // changing a property on a base table does not change the property on a view
+                validatePropertyOnViewIndex(viewName, viewIndexName, !useStats, conn, tenantConn);
+
+                // need to explicitly change the property on the view
+                conn.createStatement()
+                        .execute("ALTER VIEW " + viewName + " set USE_STATS_FOR_PARALLELIZATION=" + useStats);
+                validatePropertyOnViewIndex(viewName, viewIndexName, useStats, conn, tenantConn);
+            }
+        }
+    }
+
+    private void validatePropertyOnViewIndex(String viewName, String viewIndexName, boolean useStats, Connection conn,
+            Connection tenantConn) throws SQLException, TableNotFoundException {
+        // fetch the latest view ptable
+        PhoenixRuntime.getTableNoCache(tenantConn, viewName);
+        PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
+        PTable viewIndex = phxConn.getTable(new PTableKey(phxConn.getTenantId(), viewIndexName));
+        assertEquals("USE_STATS_FOR_PARALLELIZATION property set incorrectly", useStats,
+                PhoenixConfigurationUtil
+                        .getStatsForParallelizationProp(tenantConn.unwrap(PhoenixConnection.class), viewIndex));
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java
index 627e453..d253f6e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MigrateSystemTablesToSystemNamespaceIT.java
@@ -63,10 +63,10 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest {
 
     private static final Set<String> PHOENIX_SYSTEM_TABLES = new HashSet<>(Arrays.asList(
             "SYSTEM.CATALOG", "SYSTEM.SEQUENCE", "SYSTEM.STATS", "SYSTEM.FUNCTION",
-            "SYSTEM.MUTEX","SYSTEM.LOG"));
+            "SYSTEM.MUTEX","SYSTEM.LOG", "SYSTEM.CHILD_LINK"));
     private static final Set<String> PHOENIX_NAMESPACE_MAPPED_SYSTEM_TABLES = new HashSet<>(
             Arrays.asList("SYSTEM:CATALOG", "SYSTEM:SEQUENCE", "SYSTEM:STATS", "SYSTEM:FUNCTION",
-                    "SYSTEM:MUTEX","SYSTEM:LOG"));
+                    "SYSTEM:MUTEX","SYSTEM:LOG", "SYSTEM:CHILD_LINK"));
     private static final String SCHEMA_NAME = "MIGRATETEST";
     private static final String TABLE_NAME =
             SCHEMA_NAME + "." + MigrateSystemTablesToSystemNamespaceIT.class.getSimpleName().toUpperCase();
@@ -86,12 +86,10 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest {
     final UserGroupInformation user4 =
             UserGroupInformation.createUserForTesting("user4", new String[0]);
 
-
-    @Before
-    public final void doSetup() throws Exception {
+    public final void doSetup(boolean systemMappingEnabled) throws Exception {
         testUtil = new HBaseTestingUtility();
         Configuration conf = testUtil.getConfiguration();
-        enableNamespacesOnServer(conf);
+        enableNamespacesOnServer(conf, systemMappingEnabled);
         configureRandomHMasterPort(conf);
         testUtil.startMiniCluster(1);
     }
@@ -110,9 +108,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest {
 
     // Tests that client can create and read tables on a fresh HBase cluster with
     // system namespace mapping enabled from the start
-    @Test
-    public void freshClientsCreateNamespaceMappedSystemTables() throws IOException, InterruptedException {
-
+	@Test
+	public void freshClientsCreateNamespaceMappedSystemTables() throws Exception {
+        doSetup(true);
         user1.doAs(new PrivilegedExceptionAction<Void>() {
             @Override
             public Void run() throws Exception {
@@ -137,9 +135,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest {
     }
 
     // Tests that NEWER clients can read tables on HBase cluster after system tables are migrated
-    @Test
-    public void migrateSystemTablesInExistingCluster() throws IOException, InterruptedException {
-
+	@Test
+	public void migrateSystemTablesInExistingCluster() throws Exception {
+		doSetup(false);
         user1.doAs(new PrivilegedExceptionAction<Void>() {
             @Override
             public Void run() throws Exception {
@@ -167,9 +165,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest {
 
     // Tests that OLDER clients fail after system tables are migrated
     // Clients should be restarted with new properties which are consistent on both client and server
-    @Test
-    public void oldClientsAfterSystemTableMigrationShouldFail() throws IOException, InterruptedException {
-
+	@Test
+	public void oldClientsAfterSystemTableMigrationShouldFail() throws Exception {
+        doSetup(true);
         user1.doAs(new PrivilegedExceptionAction<Void>() {
             @Override
             public Void run() throws Exception {
@@ -202,9 +200,9 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest {
 
     // Tests that only one client can migrate the system table to system namespace
     // Migrate process acquires lock in SYSMUTEX table
-    @Test
-    public void onlyOneClientCanMigrate() throws IOException, InterruptedException, SQLException {
-
+	@Test
+	public void onlyOneClientCanMigrate() throws Exception {
+        doSetup(false);
         user1.doAs(new PrivilegedExceptionAction<Void>() {
             @Override
             public Void run() throws Exception {
@@ -291,8 +289,10 @@ public class MigrateSystemTablesToSystemNamespaceIT extends BaseTest {
         }
     }
 
-    private void enableNamespacesOnServer(Configuration conf) {
+    private void enableNamespacesOnServer(Configuration conf, boolean systemMappingEnabled) {
         conf.set(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.TRUE.toString());
+		conf.set(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE,
+				systemMappingEnabled ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
     }
 
     // For PHOENIX-4389 (Flapping tests SystemTablePermissionsIT and MigrateSystemTablesToSystemNamespaceIT)

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java
index c93d2aa..255a8b2 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixDriverIT.java
@@ -174,30 +174,24 @@ public class PhoenixDriverIT extends BaseUniqueNamesOwnClusterIT {
         String schemaName = "S_" + generateUniqueName();
         String tableName = "T_" + generateUniqueName();
         String phoenixFullTableName = SchemaUtil.getTableName(schemaName, tableName);
-        String viewName1 = "VC_" + generateUniqueName();
-        String viewName2 = "VB_" + generateUniqueName();
+        String viewName1 = "VB_" + generateUniqueName();
+        String viewName2 = "VC_" + generateUniqueName();
 
         try (Connection conn = createConnection(null, false)) {
             conn.createStatement().execute("CREATE TABLE " + phoenixFullTableName
                     + "(k VARCHAR not null, v INTEGER not null, f INTEGER, g INTEGER NULL, h INTEGER NULL CONSTRAINT pk PRIMARY KEY(k,v)) MULTI_TENANT=true");
         }
-        try (Connection conn = createConnection("tenant1", false)) {
-            // create view
-            conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName1
-                    + " (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName);
-            // create child view
-            conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName2
-                    + " (col2 VARCHAR) AS SELECT * FROM " + schemaName + "." + viewName1);
-        }
 
-        String tenant2 = "tenant2";
-        try (Connection conn = createConnection(tenant2, false)) {
-            // creating another view in a second tenant but same view name
-            conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName1
-                    + " (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName);
-            // creating child view with a second tenant
-            conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName2
-                    + " (col2 VARCHAR) AS SELECT * FROM " + schemaName + "." + viewName1);
+        String[] tenantIds = new String[] { "tenant1", "tenant2" };
+        for (String tenantId : tenantIds) {
+            try (Connection conn = createConnection(tenantId, false)) {
+                // create view
+                conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName1
+                        + " (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName);
+                // create child view
+                conn.createStatement().execute("CREATE VIEW " + schemaName + "." + viewName2
+                        + " (col2 VARCHAR) AS SELECT * FROM " + schemaName + "." + viewName1);
+            }
         }
 
         try (Connection conn = createConnection(null, true)) {
@@ -209,14 +203,15 @@ public class PhoenixDriverIT extends BaseUniqueNamesOwnClusterIT {
             try (PhoenixConnection phxConn =
                     DriverManager.getConnection(url, props).unwrap(PhoenixConnection.class)) {
                 UpgradeUtil.upgradeTable(phxConn, phoenixFullTableName);
-                UpgradeUtil.mapChildViewsToNamespace(phxConn, phoenixFullTableName, props);
             }
 
             // verify physical table link
             String physicalTableName =
                     SchemaUtil.getPhysicalHBaseTableName(schemaName, tableName, true).getString();
-            assertEquals(physicalTableName, getPhysicalTable(conn, tenant2, schemaName, viewName1));
-            assertEquals(physicalTableName, getPhysicalTable(conn, tenant2, schemaName, viewName2));
+            for (String tenantId : tenantIds) {
+                assertEquals(physicalTableName, getPhysicalTable(conn, tenantId, schemaName, viewName1));
+                assertEquals(physicalTableName, getPhysicalTable(conn, tenantId, schemaName, viewName2));
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
index 4f84304..90f9db6 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
@@ -19,6 +19,7 @@ package org.apache.phoenix.end2end;
 
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CHILD_LINK_TABLE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_FUNCTION_TABLE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_SEQUENCE;
 import static org.apache.phoenix.util.TestUtil.ATABLE_NAME;
@@ -162,6 +163,10 @@ public class QueryDatabaseMetaDataIT extends ParallelStatsDisabledIT {
             assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE"));
             assertTrue(rs.next());
             assertEquals(SYSTEM_CATALOG_SCHEMA, rs.getString("TABLE_SCHEM"));
+            assertEquals(SYSTEM_CHILD_LINK_TABLE, rs.getString("TABLE_NAME"));
+            assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE"));
+            assertTrue(rs.next());
+            assertEquals(SYSTEM_CATALOG_SCHEMA, rs.getString("TABLE_SCHEM"));
             assertEquals(SYSTEM_FUNCTION_TABLE, rs.getString("TABLE_NAME"));
             assertEquals(PTableType.SYSTEM.toString(), rs.getString("TABLE_TYPE"));
             assertTrue(rs.next());
@@ -342,7 +347,7 @@ public class QueryDatabaseMetaDataIT extends ParallelStatsDisabledIT {
     @Test
     public void testSchemaMetadataScan() throws SQLException {
         String table1 = generateUniqueName();
-        String schema1 = generateUniqueName();
+        String schema1 = "Z_" + generateUniqueName();
         String fullTable1 = schema1 + "." + table1;
         ensureTableCreated(getUrl(), fullTable1, CUSTOM_ENTITY_DATA_FULL_NAME, null);
         String fullTable2 = generateUniqueName();
@@ -1095,7 +1100,7 @@ public class QueryDatabaseMetaDataIT extends ParallelStatsDisabledIT {
         // Retrieve the database metadata
         DatabaseMetaData dbmd = conn.getMetaData();
         ResultSet rs = dbmd.getColumns(null, null, null, null);
-        rs.next();
+        assertTrue(rs.next());
 
         // Lookup column by name, this should return null but not throw an exception
         String remarks = rs.getString("REMARKS");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java
deleted file mode 100644
index e7518f6..0000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SaltedViewIT.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.phoenix.end2end;
-
-import org.junit.Test;
-
-
-public class SaltedViewIT extends BaseViewIT {
-
-	public SaltedViewIT(boolean transactional) {
-		super(transactional);
-	}
-
-	/**
-     * Salted tests must be in their own test file to ensure that the underlying
-     * table is dropped. Otherwise, the splits may not be performed.
-     * TODO: we should throw in that case
-     * 
-     * @throws Exception
-     */
-    @Test
-    public void testSaltedUpdatableViewWithIndex() throws Exception {
-        testUpdatableViewWithIndex(3, false);
-    }
-
-    @Test
-    public void testSaltedUpdatableViewWithLocalIndex() throws Exception {
-        testUpdatableViewWithIndex(3, true);
-    }
-}