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

[09/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/SplitSystemCatalogIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogIT.java
new file mode 100644
index 0000000..51d3b86
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogIT.java
@@ -0,0 +1,80 @@
+/*
+ * 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 java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.curator.shaded.com.google.common.collect.Lists;
+import org.apache.phoenix.query.BaseTest;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.BeforeClass;
+import org.junit.experimental.categories.Category;
+
+import com.google.common.collect.Maps;
+
+/**
+ * Base class for tests that run with split SYSTEM.CATALOG.
+ * 
+ */
+@Category(SplitSystemCatalogTests.class)
+public class SplitSystemCatalogIT extends BaseTest {
+
+    protected static String SCHEMA1 = "SCHEMA1";
+    protected static String SCHEMA2 = "SCHEMA2";
+    protected static String SCHEMA3 = "SCHEMA3";
+    protected static String SCHEMA4 = "SCHEMA4";
+
+    protected static String TENANT1 = "tenant1";
+    protected static String TENANT2 = "tenant2";
+
+    @BeforeClass
+    public static void doSetup() throws Exception {
+        NUM_SLAVES_BASE = 6;
+        Map<String, String> props = Collections.emptyMap();
+        boolean splitSystemCatalog = (driver == null);
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+        // Split SYSTEM.CATALOG once after the mini-cluster is started
+        if (splitSystemCatalog) {
+            splitSystemCatalog();
+        }
+    }
+    
+    protected static void splitSystemCatalog() throws SQLException, Exception {
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+        }
+        String tableName = "TABLE";
+        String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, tableName);
+        String fullTableName2 = SchemaUtil.getTableName(SCHEMA2, tableName);
+        String fullTableName3 = SchemaUtil.getTableName(SCHEMA3, tableName);
+        String fullTableName4 = SchemaUtil.getTableName(SCHEMA4, tableName);
+        ArrayList<String> tableList = Lists.newArrayList(fullTableName1, fullTableName2, fullTableName3);
+        Map<String, List<String>> tenantToTableMap = Maps.newHashMap();
+        tenantToTableMap.put(null, tableList);
+        tenantToTableMap.put(TENANT1, Lists.newArrayList(fullTableName2, fullTableName3));
+        tenantToTableMap.put(TENANT2, Lists.newArrayList(fullTableName4));
+        splitSystemCatalog(tenantToTableMap);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java
new file mode 100644
index 0000000..27fc5c6
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SplitSystemCatalogTests.java
@@ -0,0 +1,11 @@
+package org.apache.phoenix.end2end;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface SplitSystemCatalogTests {
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java
new file mode 100644
index 0000000..e25415a
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsEnabledSplitSystemCatalogIT.java
@@ -0,0 +1,244 @@
+package org.apache.phoenix.end2end;
+
+import static org.apache.phoenix.util.TestUtil.analyzeTable;
+import static org.apache.phoenix.util.TestUtil.getAllSplits;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.KeyRange;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.ReadOnlyTableException;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.ScanUtil;
+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.collect.Maps;
+
+@RunWith(Parameterized.class)
+public class StatsEnabledSplitSystemCatalogIT extends BaseUniqueNamesOwnClusterIT {
+	
+	private String tableDDLOptions;
+	private boolean transactional;
+
+	public StatsEnabledSplitSystemCatalogIT(boolean transactional) {
+	        StringBuilder optionBuilder = new StringBuilder();
+	        this.transactional = transactional;
+	        if (transactional) {
+	            optionBuilder.append(" TRANSACTIONAL=true ");
+	        }
+	        this.tableDDLOptions = optionBuilder.toString();
+	    }
+
+	@Parameters(name = "transactional = {0}")
+	public static Collection<Boolean> data() {
+		return Arrays.asList(new Boolean[] { false, true });
+	}
+	
+	@BeforeClass
+    public static void doSetup() throws Exception {
+        NUM_SLAVES_BASE = 3;
+        Map<String, String> props = Maps.newHashMapWithExpectedSize(1);
+        props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(20));
+        props.put(QueryServices.STATS_UPDATE_FREQ_MS_ATTRIB, Long.toString(5));
+        props.put(QueryServices.USE_STATS_FOR_PARALLELIZATION, Boolean.toString(true));
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+    }
+
+	/**
+     * 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);
+    }
+	
+	@Test
+    public void testNonSaltedUpdatableViewWithIndex() throws Exception {
+        testUpdatableViewWithIndex(null, false);
+    }
+    
+    @Test
+    public void testNonSaltedUpdatableViewWithLocalIndex() throws Exception {
+        testUpdatableViewWithIndex(null, true);
+    }
+    
+    @Test
+    public void testUpdatableOnUpdatableView() throws Exception {
+        String fullTableName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName());
+        String ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE k3 = 2";
+        ViewIT.testUpdatableView(fullTableName, fullViewName1, fullViewName2, ddl, null, tableDDLOptions);
+        Connection conn = DriverManager.getConnection(getUrl());
+        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());
+        
+        conn.createStatement().execute("UPSERT INTO " + fullViewName2 + "(k2) VALUES(122)");
+        conn.commit();
+        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(2, rs.getInt(3));
+        assertFalse(rs.next());
+        
+        try {
+            conn.createStatement().execute("UPSERT INTO " + fullViewName2 + "(k2,k3) VALUES(123,3)");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode());
+        }
+
+        try {
+            conn.createStatement().execute("UPSERT INTO " + fullViewName2 + "(k2,k3) select k2, 3 from " + fullViewName1);
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN.getErrorCode(), e.getErrorCode());
+        }
+    }
+    
+    private void testUpdatableViewWithIndex(Integer saltBuckets, boolean localIndex) throws Exception {
+        String schemaName = TestUtil.DEFAULT_SCHEMA_NAME + "_" + generateUniqueName();
+        String tableName = "T_" + generateUniqueName();
+        String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
+        String viewName = "V_" + generateUniqueName();
+        ViewIT.testUpdatableView(fullTableName, viewName, null, null, saltBuckets, tableDDLOptions);
+        Pair<String, Scan> pair = ViewIT.testUpdatableViewIndex(fullTableName, saltBuckets, localIndex, viewName);
+        Scan scan = pair.getSecond();
+        String physicalTableName = pair.getFirst();
+        // Confirm that dropping the view also deletes the rows in the index
+        if (saltBuckets == null) {
+            try (Connection conn = DriverManager.getConnection(getUrl())) {
+                HTableInterface htable = conn.unwrap(PhoenixConnection.class).getQueryServices()
+                        .getTable(Bytes.toBytes(physicalTableName));
+                if (ScanUtil.isLocalIndex(scan)) {
+                    ScanUtil.setLocalIndexAttributes(scan, 0, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY,
+                            scan.getStartRow(), scan.getStopRow());
+                }
+                ResultScanner scanner = htable.getScanner(scan);
+                Result result = scanner.next();
+                // Confirm index has rows
+                assertTrue(result != null && !result.isEmpty());
+
+                conn.createStatement().execute("DROP VIEW " + viewName);
+
+                // Confirm index has no rows after view is dropped
+                scanner = htable.getScanner(scan);
+                result = scanner.next();
+                assertTrue(result == null || result.isEmpty());
+            }
+        }
+    }
+    
+    @Test
+    public void testReadOnlyOnReadOnlyView() throws Exception {
+        Connection earlierCon = DriverManager.getConnection(getUrl());
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName());
+        String fullParentViewName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(generateUniqueName(), generateUniqueName());
+        
+        String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE) "+ tableDDLOptions;
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullParentViewName + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullParentViewName + " WHERE k < 9";
+        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);
+        
+        try {
+            conn.createStatement().execute("UPSERT INTO " + fullViewName + " VALUES(1)");
+            fail();
+        } catch (ReadOnlyTableException e) {
+            
+        } finally {
+            conn.close();
+        }
+
+        conn = DriverManager.getConnection(getUrl());
+        count = 0;
+        rs = conn.createStatement().executeQuery("SELECT k FROM " + fullViewName);
+        while (rs.next()) {
+            count++;
+            assertEquals(count + 5, rs.getInt(1));
+        }
+        assertEquals(3, count);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java
index 689eb20..aa2d971 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogCreationOnConnectionIT.java
@@ -17,6 +17,22 @@
  */
 package org.apache.phoenix.end2end;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HConstants;
@@ -28,7 +44,11 @@ import org.apache.phoenix.exception.UpgradeRequiredException;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver;
 import org.apache.phoenix.jdbc.PhoenixTestDriver;
-import org.apache.phoenix.query.*;
+import org.apache.phoenix.query.ConnectionQueryServices;
+import org.apache.phoenix.query.ConnectionQueryServicesImpl;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.query.QueryServicesTestImpl;
 import org.apache.phoenix.util.ReadOnlyProps;
 import org.apache.phoenix.util.UpgradeUtil;
 import org.junit.After;
@@ -36,14 +56,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.*;
-import java.util.concurrent.TimeoutException;
-
-import static org.junit.Assert.*;
-
 @Category(NeedsOwnMiniClusterTest.class)
 public class SystemCatalogCreationOnConnectionIT {
     private HBaseTestingUtility testUtil = null;
@@ -60,11 +72,11 @@ public class SystemCatalogCreationOnConnectionIT {
 
     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 class PhoenixSysCatCreationServices extends ConnectionQueryServicesImpl {
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java
index 6f49518..8a41fad 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemCatalogIT.java
@@ -23,6 +23,8 @@ import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.Collections;
+import java.util.Map;
 import java.util.Properties;
 
 import org.apache.hadoop.hbase.DoNotRetryIOException;
@@ -30,30 +32,34 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.RegionLocator;
 import org.apache.phoenix.query.BaseTest;
+import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.util.PhoenixRuntime;
-import org.junit.After;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import com.google.common.collect.Maps;
+
 @Category(NeedsOwnMiniClusterTest.class)
 public class SystemCatalogIT extends BaseTest {
     private HBaseTestingUtility testUtil = null;
-
-    @After
-    public void cleanup() throws Exception {
-        if (null != testUtil) {
-          testUtil.shutdownMiniCluster();
-          testUtil = null;
-        }
-    }
+    
+	@BeforeClass
+	public static void doSetup() throws Exception {
+		Map<String, String> serverProps = Maps.newHashMapWithExpectedSize(1);
+		serverProps.put(QueryServices.SYSTEM_CATALOG_SPLITTABLE, "false");
+		Map<String, String> clientProps = Collections.emptyMap();
+		setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()),
+				new ReadOnlyProps(clientProps.entrySet().iterator()));
+	}
 
     /**
-     * Make sure that SYSTEM.CATALOG cannot be split, even with schemas and multi-tenant views
+     * Make sure that SYSTEM.CATALOG cannot be split if QueryServices.SYSTEM_CATALOG_SPLITTABLE is false
      */
     @Test
     public void testSystemTableSplit() throws Exception {
-        testUtil = new HBaseTestingUtility();
-        testUtil.startMiniCluster(1);
+        testUtil = getUtility();
         for (int i=0; i<10; i++) {
             createTable("schema"+i+".table_"+i);
         }
@@ -63,7 +69,6 @@ public class SystemCatalogIT extends BaseTest {
         try {
             // now attempt to split SYSTEM.CATALOG
             testUtil.getHBaseAdmin().split(systemCatalog);
-
             // make sure the split finishes (there's no synchronous splitting before HBase 2.x)
             testUtil.getHBaseAdmin().disableTable(systemCatalog);
             testUtil.getHBaseAdmin().enableTable(systemCatalog);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
index 34a1312..dd6f7f7 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
@@ -379,11 +379,12 @@ public class TenantSpecificTablesDDLIT extends BaseTenantSpecificTablesIT {
 			connTenant2 = DriverManager.getConnection(PHOENIX_JDBC_TENANT_SPECIFIC_URL2, props);
 	        validateTenantViewIsDropped(connTenant2);
 	        
+	        // TODO uncomment after PHOENIX-4764 is implemented
 	        // Validate Tenant Metadata is gone for the Tenant Table TENANT_TABLE_NAME
-            rs = meta.getTables(null, "", StringUtil.escapeLike(TENANT_TABLE_NAME), new String[] {PTableType.VIEW.getValue().getString()});
-            assertFalse(rs.next());
-            rs = meta.getTables(null, "", StringUtil.escapeLike(tenantTable2), new String[] {PTableType.VIEW.getValue().getString()});
-            assertFalse(rs.next());
+//            rs = meta.getTables(null, "", StringUtil.escapeLike(TENANT_TABLE_NAME), new String[] {PTableType.VIEW.getValue().getString()});
+//            assertFalse(rs.next());
+//            rs = meta.getTables(null, "", StringUtil.escapeLike(tenantTable2), new String[] {PTableType.VIEW.getValue().getString()});
+//            assertFalse(rs.next());
             
             rs = meta.getTables(null, "", StringUtil.escapeLike(TENANT_TABLE_NAME_NO_TENANT_TYPE_ID), new String[] {PTableType.VIEW.getValue().getString()});
             assertTrue(rs.next());
@@ -491,6 +492,8 @@ public class TenantSpecificTablesDDLIT extends BaseTenantSpecificTablesIT {
             assertTrue(rs.next());
             assertTableMetaData(rs, PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA, PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE, PTableType.SYSTEM);
             assertTrue(rs.next());
+            assertTableMetaData(rs, PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA, PhoenixDatabaseMetaData.SYSTEM_CHILD_LINK_TABLE, PTableType.SYSTEM);
+            assertTrue(rs.next());
             assertTableMetaData(rs, SYSTEM_CATALOG_SCHEMA, SYSTEM_FUNCTION_TABLE, SYSTEM);
             assertTrue(rs.next());
             assertTableMetaData(rs, PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA, PhoenixDatabaseMetaData.SYSTEM_LOG_TABLE, PTableType.SYSTEM);
@@ -530,7 +533,7 @@ public class TenantSpecificTablesDDLIT extends BaseTenantSpecificTablesIT {
             assertTrue(rs.next());
             // (tenant_id column is not visible in tenant-specific connection)
             assertColumnMetaData(rs, null, TENANT_TABLE_NAME, "tenant_type_id", 2);
-            assertEquals(1, rs.getInt(KEY_SEQ));
+            assertEquals(1, rs.getShort(KEY_SEQ));
             assertTrue(rs.next());
             assertColumnMetaData(rs, null, TENANT_TABLE_NAME, "id", 3);
             assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java
index d5da0aa..31f3569 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificViewIndexIT.java
@@ -29,20 +29,23 @@ import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
-import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.PNameFactory;
-import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.SchemaUtil;
 import org.junit.Test;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
 
 public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT {
 	
@@ -115,38 +118,40 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT {
     }
 
     private void testMultiCFViewIndex(boolean localIndex, boolean isNamespaceEnabled) throws Exception {
-        String tableName = "XYZ." + generateUniqueName();
-        String baseViewName = generateUniqueName() ;
+        String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String viewName2 = SchemaUtil.getTableName(SCHEMA4, generateUniqueName());
         createTableAndValidate(tableName, isNamespaceEnabled);
-        createViewAndIndexesWithTenantId(tableName, baseViewName, localIndex, "b", isNamespaceEnabled);
-        createViewAndIndexesWithTenantId(tableName, baseViewName, localIndex, "a", isNamespaceEnabled);
-
-        String sequenceNameA = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName("a"), isNamespaceEnabled);
-        String sequenceNameB = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName("b"), isNamespaceEnabled);
+        String tenantId1 = TENANT1;
+        String tenantId2 = TENANT2;
+        createViewAndIndexesWithTenantId(tableName, viewName1, localIndex, tenantId1, isNamespaceEnabled);
+        createViewAndIndexesWithTenantId(tableName, viewName2, localIndex, tenantId2, isNamespaceEnabled);
+        
+        String sequenceNameA = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName(tenantId2), isNamespaceEnabled);
+        String sequenceNameB = getViewIndexSequenceName(PNameFactory.newName(tableName), PNameFactory.newName(tenantId1), isNamespaceEnabled);
         String sequenceSchemaName = getViewIndexSequenceSchemaName(PNameFactory.newName(tableName), isNamespaceEnabled);
-        verifySequenceValue(isNamespaceEnabled? "a" : null, sequenceNameA, sequenceSchemaName, -32767);
-        verifySequenceValue(isNamespaceEnabled? "b" : null, sequenceNameB, sequenceSchemaName, -32767);
+        verifySequenceValue(isNamespaceEnabled? tenantId2 : null, sequenceNameA, sequenceSchemaName, -32767);
+        verifySequenceValue(isNamespaceEnabled? tenantId1 : null, sequenceNameB, sequenceSchemaName, -32767);
 
         Properties props = new Properties();
-        props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "a");
+        props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId2);
         try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
-            conn.createStatement().execute("DROP VIEW  " + baseViewName + "_a");
+            conn.createStatement().execute("DROP VIEW  " + viewName2);
         }
-        props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "b");
+        props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId1);
         try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
-            conn.createStatement().execute("DROP VIEW  " + baseViewName + "_b");
+            conn.createStatement().execute("DROP VIEW  " + viewName1);
         }
         DriverManager.getConnection(getUrl()).createStatement().execute("DROP TABLE " + tableName + " CASCADE");
 
-        verifySequenceNotExists(isNamespaceEnabled? "a" : null, sequenceNameA, sequenceSchemaName);
-        verifySequenceNotExists(isNamespaceEnabled? "b" : null, sequenceNameB, sequenceSchemaName);
+        verifySequenceNotExists(isNamespaceEnabled? tenantId2 : null, sequenceNameA, sequenceSchemaName);
+        verifySequenceNotExists(isNamespaceEnabled? tenantId1 : null, sequenceNameB, sequenceSchemaName);
     }
 
-    private void createViewAndIndexesWithTenantId(String tableName,String baseViewName, boolean localIndex, String tenantId,
+    private void createViewAndIndexesWithTenantId(String tableName, String viewName, boolean localIndex, String tenantId,
             boolean isNamespaceMapped) throws Exception {
         Properties props = new Properties();
-        String viewName = baseViewName + "_" + tenantId;
-        String indexName = "idx_" + viewName;
+        String indexName = "I_"+ generateUniqueName();
         if (tenantId != null) {
             props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
         }
@@ -239,15 +244,15 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT {
         assertFalse(rs.next());
 
         conn.close();
-
     }
     
     @Test
     public void testNonPaddedTenantId() throws Exception {
-        String tenantId1 = "org1";
-        String tenantId2 = "org2";
-        String tableName = generateUniqueName();
-        String viewName = generateUniqueName();
+        String tenantId1 = TENANT1;
+        String tenantId2 = TENANT2;
+        String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        
         String ddl = "CREATE TABLE " + tableName + " (tenantId char(15) NOT NULL, pk1 varchar NOT NULL, pk2 INTEGER NOT NULL, val1 VARCHAR CONSTRAINT pk primary key (tenantId,pk1,pk2)) MULTI_TENANT = true";
         Connection conn = DriverManager.getConnection(getUrl());
         conn.createStatement().execute(ddl);
@@ -288,10 +293,11 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT {
     }
     
     @Test
-    public void testOverlappingDatesFilter() throws SQLException {
-        String tenantUrl = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant1" + ";" + QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB + "=true";
-        String tableName = generateUniqueName();
-        String viewName = generateUniqueName();
+    public void testOverlappingDatesFilter() throws Exception {
+        String tenantId = TENANT1;
+        String tenantUrl = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + tenantId + ";" + QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB + "=true";
+        String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
         String ddl = "CREATE TABLE " + tableName 
                 + "(ORGANIZATION_ID CHAR(15) NOT NULL, "
                 + "PARENT_TYPE CHAR(3) NOT NULL, "
@@ -315,7 +321,9 @@ public class TenantSpecificViewIndexIT extends BaseTenantSpecificViewIndexIT {
                     + "ORDER BY PARENT_TYPE,CREATED_DATE LIMIT 501";
             
             ResultSet rs = viewConn.createStatement().executeQuery(query);
-            String expectedPlanFormat = "CLIENT SERIAL 1-WAY RANGE SCAN OVER IDX ['tenant1        ','001','%s 00:00:00.001'] - ['tenant1        ','001','%s 00:00:00.000']" + "\n" +
+            String exptectedIndexName = SchemaUtil.getTableName(SCHEMA1, "IDX");
+            String expectedPlanFormat = "CLIENT SERIAL 1-WAY RANGE SCAN OVER " + exptectedIndexName
+                    + " ['tenant1        ','001','%s 00:00:00.001'] - ['tenant1        ','001','%s 00:00:00.000']" + "\n" +
                         "    SERVER FILTER BY FIRST KEY ONLY" + "\n" +
                         "    SERVER 501 ROW LIMIT" + "\n" +
                         "CLIENT 501 ROW LIMIT";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93fdd5ba/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
index 48a49b2..2b866a5 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
@@ -17,13 +17,9 @@
  */
 package org.apache.phoenix.end2end;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.apache.phoenix.query.ConnectionQueryServicesImpl.UPGRADE_MUTEX;
 import static org.apache.phoenix.query.ConnectionQueryServicesImpl.UPGRADE_MUTEX_UNLOCKED;
-import static org.apache.phoenix.query.QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT;
-import static org.apache.phoenix.query.QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT;
-import static org.apache.phoenix.util.UpgradeUtil.SELECT_BASE_COLUMN_COUNT_FROM_HEADER_ROW;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -36,8 +32,6 @@ import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.Callable;
@@ -47,11 +41,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.curator.shaded.com.google.common.collect.Sets;
-import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Put;
-import org.apache.hadoop.hbase.client.RowMutations;
 import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
@@ -77,91 +69,10 @@ import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TestUtil;
 import org.apache.phoenix.util.UpgradeUtil;
-import org.junit.Before;
 import org.junit.Test;
 
 public class UpgradeIT extends ParallelStatsDisabledIT {
 
-    private String tenantId;
-    
-    @Before
-    public void generateTenantId() {
-        tenantId = "T_" + generateUniqueName();
-    }
-
-    @Test
-    public void testUpgradeForTenantViewWithSameColumnsAsBaseTable() throws Exception {
-        String tableWithViewName = generateUniqueName();
-        String viewTableName = generateUniqueName();
-        testViewUpgrade(true, tenantId, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.EQUAL);
-        testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2",
-            ColumnDiff.EQUAL);
-        testViewUpgrade(true, tenantId, null, tableWithViewName + "3", viewTableName + "SCHEMA", viewTableName + "3",
-            ColumnDiff.EQUAL);
-        testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "4", viewTableName + "SCHEMA", viewTableName + "4",
-            ColumnDiff.EQUAL);
-        testViewUpgrade(true, tenantId, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5",
-            ColumnDiff.EQUAL);
-    }
-
-    @Test
-    public void testUpgradeForTenantViewWithMoreColumnsThanBaseTable() throws Exception {
-        String tableWithViewName = generateUniqueName();
-        String viewTableName = generateUniqueName();
-        testViewUpgrade(true, tenantId, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.MORE);
-        testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2",
-            ColumnDiff.MORE);
-        testViewUpgrade(true, tenantId, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3",
-            ColumnDiff.MORE);
-        testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4",
-            ColumnDiff.MORE);
-        testViewUpgrade(true, tenantId, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5",
-            ColumnDiff.MORE);
-    }
-
-    @Test
-    public void testUpgradeForViewWithSameColumnsAsBaseTable() throws Exception {
-        String tableWithViewName = generateUniqueName();
-        String viewTableName = generateUniqueName();
-        testViewUpgrade(false, null, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.EQUAL);
-        testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2",
-            ColumnDiff.EQUAL);
-        testViewUpgrade(false, null, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3",
-            ColumnDiff.EQUAL);
-        testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4",
-            ColumnDiff.EQUAL);
-        testViewUpgrade(false, null, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5",
-            ColumnDiff.EQUAL);
-    }
-
-    @Test
-    public void testUpgradeForViewWithMoreColumnsThanBaseTable() throws Exception {
-        String tableWithViewName = generateUniqueName();
-        String viewTableName = generateUniqueName();
-        testViewUpgrade(false, null, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.MORE);
-        testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2", ColumnDiff.MORE);
-        testViewUpgrade(false, null, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3", ColumnDiff.MORE);
-        testViewUpgrade(false, null, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4",
-            ColumnDiff.MORE);
-        testViewUpgrade(false, null, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5",
-            ColumnDiff.MORE);
-    }
-
-    @Test
-    public void testSettingBaseColumnCountWhenBaseTableColumnDropped() throws Exception {
-        String tableWithViewName = generateUniqueName();
-        String viewTableName = generateUniqueName();
-        testViewUpgrade(true, tenantId, null, tableWithViewName + "1", null, viewTableName + "1", ColumnDiff.MORE);
-        testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "", null, viewTableName + "2",
-            ColumnDiff.LESS);
-        testViewUpgrade(true, tenantId, null, tableWithViewName + "3", "VIEWSCHEMA", viewTableName + "3",
-            ColumnDiff.LESS);
-        testViewUpgrade(true, tenantId, "TABLESCHEMA", tableWithViewName + "4", "VIEWSCHEMA", viewTableName + "4",
-            ColumnDiff.LESS);
-        testViewUpgrade(true, tenantId, "SAMESCHEMA", tableWithViewName + "5", "SAMESCHEMA", viewTableName + "5",
-            ColumnDiff.LESS);
-    }
-
     @Test
     public void testMapTableToNamespaceDuringUpgrade()
             throws SQLException, IOException, IllegalArgumentException, InterruptedException {
@@ -232,7 +143,6 @@ public class UpgradeIT extends ParallelStatsDisabledIT {
             admin.close();
             PhoenixConnection phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class);
             UpgradeUtil.upgradeTable(phxConn, phoenixFullTableName);
-            UpgradeUtil.mapChildViewsToNamespace(phxConn, phoenixFullTableName,props);
             phxConn.close();
             props = new Properties();
             phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class);
@@ -366,7 +276,6 @@ public class UpgradeIT extends ParallelStatsDisabledIT {
         props.setProperty(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE, Boolean.toString(false));
         PhoenixConnection phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class);
         UpgradeUtil.upgradeTable(phxConn, phoenixFullTableName);
-        UpgradeUtil.mapChildViewsToNamespace(phxConn,phoenixFullTableName,props);
         props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
         phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class);
         // purge MetaDataCache except for system tables
@@ -423,222 +332,7 @@ public class UpgradeIT extends ParallelStatsDisabledIT {
         assertTrue(rs.next());
         assertTrue(rs.getString(1).contains(hbaseTableName));
     }
-    
-
-    @Test
-    public void testSettingBaseColumnCountForMultipleViewsOnTable() throws Exception {
-        String baseSchema = "S_" + generateUniqueName();
-        String baseTable = "T_" + generateUniqueName();
-        String fullBaseTableName = SchemaUtil.getTableName(baseSchema, baseTable);
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String baseTableDDL = "CREATE TABLE " + fullBaseTableName + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 INTEGER, V2 INTEGER CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true";
-            conn.createStatement().execute(baseTableDDL);
-
-            String[] tenants = new String[] {"T_" + generateUniqueName(), "T_" + generateUniqueName()};
-            Collections.sort(Arrays.asList(tenants));
-            String[] tenantViews = new String[] {"V_" + generateUniqueName(), "V_" + generateUniqueName(), "V_" + generateUniqueName()};
-            Collections.sort(Arrays.asList(tenantViews));
-            String[] globalViews = new String[] {"G_" + generateUniqueName(), "G_" + generateUniqueName(), "G_" + generateUniqueName()};
-            Collections.sort(Arrays.asList(globalViews));
-            for (int i = 0; i < 2; i++) {
-                // Create views for tenants;
-                String tenant = tenants[i];
-                try (Connection tenantConn = createTenantConnection(tenant)) {
-                    String view = tenantViews[0];
-                    // view with its own column
-                    String viewDDL = "CREATE VIEW " + view + " AS SELECT * FROM " + fullBaseTableName;
-                    tenantConn.createStatement().execute(viewDDL);
-                    String addCols = "ALTER VIEW " + view + " ADD COL1 VARCHAR ";
-                    tenantConn.createStatement().execute(addCols);
-                    removeBaseColumnCountKV(tenant, null, view);
-
-                    // view that has the last base table column removed
-                    view = tenantViews[1];
-                    viewDDL = "CREATE VIEW " + view + " AS SELECT * FROM " + fullBaseTableName;
-                    tenantConn.createStatement().execute(viewDDL);
-                    String droplastBaseCol = "ALTER VIEW " + view + " DROP COLUMN V2";
-                    tenantConn.createStatement().execute(droplastBaseCol);
-                    removeBaseColumnCountKV(tenant, null, view);
-
-                    // view that has the middle base table column removed
-                    view = tenantViews[2];
-                    viewDDL = "CREATE VIEW " + view + " AS SELECT * FROM " + fullBaseTableName;
-                    tenantConn.createStatement().execute(viewDDL);
-                    String dropMiddileBaseCol = "ALTER VIEW " + view + " DROP COLUMN V1";
-                    tenantConn.createStatement().execute(dropMiddileBaseCol);
-                    removeBaseColumnCountKV(tenant, null, view);
-                }
-            }
-
-            // create global views
-            try (Connection globalConn = DriverManager.getConnection(getUrl())) {
-                String globalView = globalViews[0];
-                // view with its own column
-                String viewDDL = "CREATE VIEW " + globalView + " AS SELECT * FROM " + fullBaseTableName;
-                globalConn.createStatement().execute(viewDDL);
-                String addCols = "ALTER VIEW " + globalView + " ADD COL1 VARCHAR ";
-                globalConn.createStatement().execute(addCols);
-                removeBaseColumnCountKV(null, null, globalView);
-
-                // view that has the last base table column removed
-                globalView = globalViews[1];
-                viewDDL = "CREATE VIEW " + globalView + " AS SELECT * FROM " + fullBaseTableName;
-                globalConn.createStatement().execute(viewDDL);
-                String droplastBaseCol = "ALTER VIEW " + globalView + " DROP COLUMN V2";
-                globalConn.createStatement().execute(droplastBaseCol);
-                removeBaseColumnCountKV(null, null, globalView);
-
-                // view that has the middle base table column removed
-                globalView = globalViews[2];
-                viewDDL = "CREATE VIEW " + globalView + " AS SELECT * FROM " + fullBaseTableName;
-                globalConn.createStatement().execute(viewDDL);
-                String dropMiddileBaseCol = "ALTER VIEW " + globalView + " DROP COLUMN V1";
-                globalConn.createStatement().execute(dropMiddileBaseCol);
-                removeBaseColumnCountKV(null, null, globalView);
-            }
-            
-            // run upgrade
-            upgradeTo4_5_0(conn);
-            
-            // Verify base column counts for tenant specific views
-            for (int i = 0; i < 2 ; i++) {
-                String tenantId = tenants[i];
-                checkBaseColumnCount(tenantId, null, tenantViews[0], 4);
-                checkBaseColumnCount(tenantId, null, tenantViews[1], DIVERGED_VIEW_BASE_COLUMN_COUNT);
-                checkBaseColumnCount(tenantId, null, tenantViews[2], DIVERGED_VIEW_BASE_COLUMN_COUNT);
-            }
-            
-            // Verify base column count for global views
-            checkBaseColumnCount(null, null, globalViews[0], 4);
-            checkBaseColumnCount(null, null, globalViews[1], DIVERGED_VIEW_BASE_COLUMN_COUNT);
-            checkBaseColumnCount(null, null, globalViews[2], DIVERGED_VIEW_BASE_COLUMN_COUNT);
-        }
-        
         
-    }
-
-    private static void upgradeTo4_5_0(Connection conn) throws SQLException {
-        PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
-        pconn.setRunningUpgrade(true);
-        UpgradeUtil.upgradeTo4_5_0(pconn);
-    }
-    
-    private enum ColumnDiff {
-        MORE, EQUAL, LESS
-    };
-
-    private void testViewUpgrade(boolean tenantView, String tenantId, String baseTableSchema,
-            String baseTableName, String viewSchema, String viewName, ColumnDiff diff)
-            throws Exception {
-        if (tenantView) {
-            checkNotNull(tenantId);
-        } else {
-            checkArgument(tenantId == null);
-        }
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullViewName = SchemaUtil.getTableName(viewSchema, viewName);
-        String fullBaseTableName = SchemaUtil.getTableName(baseTableSchema, baseTableName);
-        try {
-            int expectedBaseColumnCount;
-            conn.createStatement().execute(
-                "CREATE TABLE IF NOT EXISTS " + fullBaseTableName + " ("
-                        + " TENANT_ID CHAR(15) NOT NULL, " + " PK1 integer NOT NULL, "
-                        + "PK2 bigint NOT NULL, " + "CF1.V1 VARCHAR, " + "CF2.V2 VARCHAR, "
-                        + "V3 CHAR(100) ARRAY[4] "
-                        + " CONSTRAINT NAME_PK PRIMARY KEY (TENANT_ID, PK1, PK2)"
-                        + " ) MULTI_TENANT= true");
-            
-            // create a view with same columns as base table.
-            try (Connection conn2 = getConnection(tenantView, tenantId)) {
-                conn2.createStatement().execute(
-                    "CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullBaseTableName);
-            }
-
-            if (diff == ColumnDiff.MORE) {
-                    // add a column to the view
-                    try (Connection conn3 = getConnection(tenantView, tenantId)) {
-                        conn3.createStatement().execute(
-                            "ALTER VIEW " + fullViewName + " ADD VIEW_COL1 VARCHAR");
-                    }
-            }
-            if (diff == ColumnDiff.LESS) {
-                try (Connection conn3 = getConnection(tenantView, tenantId)) {
-                    conn3.createStatement().execute(
-                        "ALTER VIEW " + fullViewName + " DROP COLUMN CF2.V2");
-                }
-                expectedBaseColumnCount = DIVERGED_VIEW_BASE_COLUMN_COUNT;
-            } else {
-                expectedBaseColumnCount = 6;
-            }
-
-            checkBaseColumnCount(tenantId, viewSchema, viewName, expectedBaseColumnCount);
-            checkBaseColumnCount(null, baseTableSchema, baseTableName, BASE_TABLE_BASE_COLUMN_COUNT);
-            
-            // remove base column count kv so we can check whether the upgrade code is setting the 
-            // base column count correctly.
-            removeBaseColumnCountKV(tenantId, viewSchema, viewName);
-            removeBaseColumnCountKV(null, baseTableSchema, baseTableName);
-
-            // assert that the removing base column count key value worked correctly.
-            checkBaseColumnCount(tenantId, viewSchema, viewName, 0);
-            checkBaseColumnCount(null, baseTableSchema, baseTableName, 0);
-            
-            // run upgrade
-            upgradeTo4_5_0(conn);
-
-            checkBaseColumnCount(tenantId, viewSchema, viewName, expectedBaseColumnCount);
-            checkBaseColumnCount(null, baseTableSchema, baseTableName, BASE_TABLE_BASE_COLUMN_COUNT);
-        } finally {
-            conn.close();
-        }
-    }
-
-    private static void checkBaseColumnCount(String tenantId, String schemaName, String tableName,
-            int expectedBaseColumnCount) throws Exception {
-        checkNotNull(tableName);
-        Connection conn = DriverManager.getConnection(getUrl());
-        String sql = SELECT_BASE_COLUMN_COUNT_FROM_HEADER_ROW;
-        sql =
-                String.format(sql, tenantId == null ? " IS NULL " : " = ? ",
-                    schemaName == null ? "IS NULL" : " = ? ");
-        int paramIndex = 1;
-        PreparedStatement stmt = conn.prepareStatement(sql);
-        if (tenantId != null) {
-            stmt.setString(paramIndex++, tenantId);
-        }
-        if (schemaName != null) {
-            stmt.setString(paramIndex++, schemaName);
-        }
-        stmt.setString(paramIndex, tableName);
-        ResultSet rs = stmt.executeQuery();
-        assertTrue(rs.next());
-        assertEquals(expectedBaseColumnCount, rs.getInt(1));
-        assertFalse(rs.next());
-    }
-
-    private static void
-            removeBaseColumnCountKV(String tenantId, String schemaName, String tableName)
-                    throws Exception {
-        byte[] rowKey =
-                SchemaUtil.getTableKey(tenantId == null ? new byte[0] : Bytes.toBytes(tenantId),
-                    schemaName == null ? new byte[0] : Bytes.toBytes(schemaName),
-                    Bytes.toBytes(tableName));
-        Put viewColumnDefinitionPut = new Put(rowKey, HConstants.LATEST_TIMESTAMP);
-        viewColumnDefinitionPut.addColumn(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
-            PhoenixDatabaseMetaData.BASE_COLUMN_COUNT_BYTES, HConstants.LATEST_TIMESTAMP, null);
-
-        try (PhoenixConnection conn =
-                (DriverManager.getConnection(getUrl())).unwrap(PhoenixConnection.class)) {
-            try (HTableInterface htable =
-                    conn.getQueryServices().getTable(
-                        Bytes.toBytes(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME))) {
-                RowMutations mutations = new RowMutations(rowKey);
-                mutations.add(viewColumnDefinitionPut);
-                htable.mutateRow(mutations);
-            }
-        }
-    }
-    
     @Test
     public void testUpgradeRequiredPreventsSQL() throws SQLException {
         String tableName = generateUniqueName();
@@ -709,8 +403,8 @@ public class UpgradeIT extends ParallelStatsDisabledIT {
                     return true;
                 }
             };
-            try (PhoenixConnection phxConn = new PhoenixConnection(servicesWithUpgrade,
-                    conn.unwrap(PhoenixConnection.class), HConstants.LATEST_TIMESTAMP)) {
+            try (PhoenixConnection phxConn = new PhoenixConnection(conn.unwrap(PhoenixConnection.class),
+                    servicesWithUpgrade, conn.getClientInfo())) {
                 // Because upgrade is required, this SQL should fail.
                 try {
                     phxConn.createStatement().executeQuery("SELECT * FROM " + tableName);
@@ -842,7 +536,7 @@ public class UpgradeIT extends ParallelStatsDisabledIT {
     }
     
     @Test
-    public void testAddParentChildLinks() throws Exception {
+    public void testMoveParentChildLinks() throws Exception {
         String schema = "S_" + generateUniqueName();
         String table1 = "T_" + generateUniqueName();
         String table2 = "T_" + generateUniqueName();
@@ -882,13 +576,16 @@ public class UpgradeIT extends ParallelStatsDisabledIT {
             Set<String> expectedChildLinkSet = getChildLinks(conn);
 
             // delete all the child links
-            conn.createStatement().execute("DELETE FROM SYSTEM.CATALOG WHERE LINK_TYPE = "
+            conn.createStatement().execute("DELETE FROM SYSTEM.CHILD_LINK WHERE LINK_TYPE = "
                     + LinkType.CHILD_TABLE.getSerializedValue());
 
             // re-create them by running the upgrade code
             PhoenixConnection phxMetaConn = metaConn.unwrap(PhoenixConnection.class);
             phxMetaConn.setRunningUpgrade(true);
+            // create the parent-> child links in SYSTEM.CATALOG
             UpgradeUtil.addParentToChildLinks(phxMetaConn);
+            // move the parent->child links to SYSTEM.CHILD_LINK
+            UpgradeUtil.moveChildLinks(phxMetaConn);
             Set<String> actualChildLinkSet = getChildLinks(conn);
 
             assertEquals("Unexpected child links", expectedChildLinkSet, actualChildLinkSet);
@@ -898,7 +595,7 @@ public class UpgradeIT extends ParallelStatsDisabledIT {
     private Set<String> getChildLinks(Connection conn) throws SQLException {
         ResultSet rs =
                 conn.createStatement().executeQuery(
-                    "SELECT TENANT_ID, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, COLUMN_FAMILY FROM SYSTEM.CATALOG WHERE LINK_TYPE = "
+                    "SELECT TENANT_ID, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, COLUMN_FAMILY FROM SYSTEM.CHILD_LINK WHERE LINK_TYPE = "
                             + LinkType.CHILD_TABLE.getSerializedValue());
         Set<String> childLinkSet = Sets.newHashSet();
         while (rs.next()) {