You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by la...@apache.org on 2019/06/16 20:46:32 UTC

[phoenix] branch 4.x-HBase-1.5 updated (c8b794f -> 61ca52c)

This is an automated email from the ASF dual-hosted git repository.

larsh pushed a change to branch 4.x-HBase-1.5
in repository https://gitbox.apache.org/repos/asf/phoenix.git.


    from c8b794f  PHOENIX-5346 Add serial hint to SaltedIndexIT.
     new 4dc04e7  PHOENIX-5350 Speedup ParameterizedTransactionIT.
     new 1d3033d  PHOENIX-5328 Speedup InListIT.
     new 1a7f9e5  PHOENIX-5335 Breakup ViewIT.
     new 61ca52c  PHOENIX-5349 Speed up AlterTableWithViewsIT.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../phoenix/end2end/AlterTableWithViewsIT.java     |   5 +-
 .../java/org/apache/phoenix/end2end/InListIT.java  |   4 +-
 .../it/java/org/apache/phoenix/end2end/ViewIT.java | 641 +------------------
 .../org/apache/phoenix/end2end/ViewMetadataIT.java | 684 +++++++++++++++++++++
 .../phoenix/tx/ParameterizedTransactionIT.java     |  45 +-
 5 files changed, 718 insertions(+), 661 deletions(-)
 create mode 100644 phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewMetadataIT.java


[phoenix] 04/04: PHOENIX-5349 Speed up AlterTableWithViewsIT.

Posted by la...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

larsh pushed a commit to branch 4.x-HBase-1.5
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 61ca52c4296c9cbcdbf087ad7e95283bc7e7eb3d
Author: Lars Hofhansl <la...@apache.org>
AuthorDate: Sun Jun 16 13:45:14 2019 -0700

    PHOENIX-5349 Speed up AlterTableWithViewsIT.
---
 .../it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java    | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

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 82a119f..ebb238a 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
@@ -93,9 +93,8 @@ public class AlterTableWithViewsIT extends SplitSystemCatalogIT {
     // name is used by failsafe as file name in reports
     @Parameters(name = "AlterTableWithViewsIT_columnEncoded={0}, multiTenant={1}, salted={2}")
     public static Collection<Boolean[]> data() {
-        return Arrays.asList(new Boolean[][] { { false, false, false }, { false, false, true },
-                { false, true, false }, { false, true, true }, { true, false, false },
-                { true, false, true }, { true, true, false }, { true, true, true } });
+        return Arrays.asList(new Boolean[][] { { false, false, false }, { true, false, true },
+                { true, true, false }, { true, true, true } });
     }
     
     // transform PColumn to String


[phoenix] 02/04: PHOENIX-5328 Speedup InListIT.

Posted by la...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

larsh pushed a commit to branch 4.x-HBase-1.5
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 1d3033dda54eaddee5c16d92b5d67b118c774b70
Author: Lars Hofhansl <la...@apache.org>
AuthorDate: Sun Jun 16 13:23:41 2019 -0700

    PHOENIX-5328 Speedup InListIT.
---
 phoenix-core/src/it/java/org/apache/phoenix/end2end/InListIT.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/InListIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/InListIT.java
index 871f326..f74f7d7 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/InListIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/InListIT.java
@@ -169,10 +169,10 @@ public class InListIT extends ParallelStatsDisabledIT {
     
     // the different combinations to check each test against
     private static final List<Boolean> TENANCIES = Arrays.asList(false, true);
-    private static final List<? extends PDataType> INTEGER_TYPES = Arrays.asList(PInteger.INSTANCE, PLong.INSTANCE);
+    private static final List<? extends PDataType> INTEGER_TYPES = Arrays.asList(PInteger.INSTANCE);
     private static final List<Integer> SALT_BUCKET_NUMBERS = Arrays.asList(0, 4);
 
-    private static final List<String> HINTS = Arrays.asList("", "/*+ SKIP_SCAN */", "/*+ RANGE_SCAN */");
+    private static final List<String> HINTS = Arrays.asList("/*+ SKIP_SCAN */", "/*+ RANGE_SCAN */");
     
     /**
      * Tests the given where clause against the given upserts by comparing against the list of


[phoenix] 01/04: PHOENIX-5350 Speedup ParameterizedTransactionIT.

Posted by la...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

larsh pushed a commit to branch 4.x-HBase-1.5
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 4dc04e75bac112847c210d13067a57fdb9a5b757
Author: Lars Hofhansl <la...@apache.org>
AuthorDate: Sun Jun 16 13:19:49 2019 -0700

    PHOENIX-5350 Speedup ParameterizedTransactionIT.
---
 .../phoenix/tx/ParameterizedTransactionIT.java     | 45 ++++++++++++----------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/tx/ParameterizedTransactionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/tx/ParameterizedTransactionIT.java
index f94ec17..ed4e1e0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/tx/ParameterizedTransactionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/tx/ParameterizedTransactionIT.java
@@ -142,7 +142,7 @@ public class ParameterizedTransactionIT extends ParallelStatsDisabledIT {
         }
     }
     
-    @Test
+    // @Test - disabled, doesn't test anything new. TODO: Fix or remove.
     public void testTxnClosedCorrecty() throws Exception {
         String transTableName = generateUniqueName();
         String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
@@ -178,27 +178,18 @@ public class ParameterizedTransactionIT extends ParallelStatsDisabledIT {
     }
     
     @Test
-    public void testAutoCommitQuerySingleTable() throws Exception {
+    public void testAutoCommitQuery() throws Exception {
         String transTableName = generateUniqueName();
         String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
         try (Connection conn = DriverManager.getConnection(getUrl())) {
             conn.createStatement().execute("create table " + fullTableName + TestUtil.TEST_TABLE_SCHEMA + tableDDLOptions + (tableDDLOptions.length() > 0 ? "," : "") + "TRANSACTIONAL=true");
             conn.setAutoCommit(true);
-            // verify no rows returned
+            // verify no rows returned with single table
             ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + fullTableName);
             assertFalse(rs.next());
-        }
-    }
-    
-    @Test
-    public void testAutoCommitQueryMultiTables() throws Exception {
-        String transTableName = generateUniqueName();
-        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            conn.createStatement().execute("create table " + fullTableName + TestUtil.TEST_TABLE_SCHEMA + tableDDLOptions + (tableDDLOptions.length() > 0 ? "," : "") + "TRANSACTIONAL=true");
-            conn.setAutoCommit(true);
-            // verify no rows returned
-            ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + fullTableName + " x JOIN " + fullTableName + " y ON (x.long_pk = y.int_pk)");
+
+            // verify no rows returned with multiple tables
+            rs = conn.createStatement().executeQuery("SELECT * FROM " + fullTableName + " x JOIN " + fullTableName + " y ON (x.long_pk = y.int_pk)");
             assertFalse(rs.next());
         } 
     }
@@ -265,12 +256,14 @@ public class ParameterizedTransactionIT extends ParallelStatsDisabledIT {
     
     @Test
     public void testNoConflictDetectionForImmutableRows() throws Exception {
-        String transTableName = generateUniqueName();
-        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
-        Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("create table " + fullTableName + TestUtil.TEST_TABLE_SCHEMA + tableDDLOptions + (tableDDLOptions.length() > 0 ? "," : "") + "TRANSACTIONAL=true");
-        conn.createStatement().execute("ALTER TABLE " + fullTableName + " SET IMMUTABLE_ROWS=true");
-        testRowConflicts(fullTableName);
+        if (tableDDLOptions.contains("IMMUTABLE_ROWS=true")) {
+            // only need to test this for immutable rows
+            String transTableName = generateUniqueName();
+            String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
+            Connection conn = DriverManager.getConnection(getUrl());
+            conn.createStatement().execute("create table " + fullTableName + TestUtil.TEST_TABLE_SCHEMA + tableDDLOptions + (tableDDLOptions.length() > 0 ? "," : "") + "TRANSACTIONAL=true");
+            testRowConflicts(fullTableName);
+        }
     }
     
     @Test
@@ -351,6 +344,11 @@ public class ParameterizedTransactionIT extends ParallelStatsDisabledIT {
     
     @Test
     public void testNonTxToTxTableFailure() throws Exception {
+        if (tableDDLOptions.contains("COLUMN_ENCODED_BYTES")) {
+            // no need to test this with all variations of column encoding
+            return;
+        }
+
         String nonTxTableName = generateUniqueName();
 
         Connection conn = DriverManager.getConnection(getUrl());
@@ -398,6 +396,11 @@ public class ParameterizedTransactionIT extends ParallelStatsDisabledIT {
     
     @Test
     public void testCreateTableToBeTransactional() throws Exception {
+        if (tableDDLOptions.contains("COLUMN_ENCODED_BYTES")) {
+            // no need to test this with all variations of column encoding
+            return;
+        }
+
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
         String t1 = generateUniqueName();


[phoenix] 03/04: PHOENIX-5335 Breakup ViewIT.

Posted by la...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

larsh pushed a commit to branch 4.x-HBase-1.5
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 1a7f9e5533bed1d2540f8a5cfbadac08287e7855
Author: Lars Hofhansl <la...@apache.org>
AuthorDate: Sun Jun 16 13:24:54 2019 -0700

    PHOENIX-5335 Breakup ViewIT.
---
 .../it/java/org/apache/phoenix/end2end/ViewIT.java | 641 +------------------
 .../org/apache/phoenix/end2end/ViewMetadataIT.java | 684 +++++++++++++++++++++
 2 files changed, 690 insertions(+), 635 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
index 84fae7c..f2f7834 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
@@ -18,8 +18,6 @@
 package org.apache.phoenix.end2end;
 
 import static com.google.common.collect.Lists.newArrayListWithExpectedSize;
-import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MODIFY_VIEW_PK;
-import static org.apache.phoenix.exception.SQLExceptionCode.NOT_NULLABLE_COLUMN_IN_ROW_KEY;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
 import static org.apache.phoenix.util.TestUtil.analyzeTable;
 import static org.apache.phoenix.util.TestUtil.getAllSplits;
@@ -56,29 +54,19 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.curator.shaded.com.google.common.collect.Lists;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
-import org.apache.hadoop.hbase.HColumnDescriptor;
-import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.client.Admin;
-import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
-import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.coprocessor.BaseMetaDataEndpointObserver;
 import org.apache.phoenix.coprocessor.PhoenixMetaDataCoprocessorHost;
 import org.apache.phoenix.coprocessor.PhoenixMetaDataCoprocessorHost.PhoenixMetaDataControllerEnvironment;
 import org.apache.phoenix.exception.PhoenixIOException;
-import org.apache.phoenix.exception.SQLExceptionCode;
-import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
-import org.apache.phoenix.mapreduce.util.ConnectionUtil;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.schema.ColumnAlreadyExistsException;
 import org.apache.phoenix.schema.ConcurrentTableMutationException;
-import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ReadOnlyTableException;
@@ -98,8 +86,6 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
 import com.google.common.collect.Maps;
 @RunWith(Parameterized.class)
 public class ViewIT extends SplitSystemCatalogIT {
@@ -237,43 +223,6 @@ public class ViewIT extends SplitSystemCatalogIT {
     }
 
     @Test
-    public void testDisallowDropOfReferencedColumn() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
-        
-        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName1 + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE v2 != 'foo'";
-        conn.createStatement().execute(ddl);
-        
-        try {
-            conn.createStatement().execute("ALTER VIEW " + fullViewName1 + " DROP COLUMN v1");
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
-        }
-        
-        try {
-            conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v1");
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
-        }
-        try {
-            conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v2");
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
-        }
-        conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v3");
-        
-    }
-    
-    @Test
     public void testReadOnlyViewWithCaseSensitiveTableNames() throws Exception {
         Connection earlierCon = DriverManager.getConnection(getUrl());
         Connection conn = DriverManager.getConnection(getUrl());
@@ -376,287 +325,6 @@ public class ViewIT extends SplitSystemCatalogIT {
         assertEquals(5, count);
     }
 
-    
-    @Test
-    public void testViewAndTableInDifferentSchemasWithNamespaceMappingEnabled() throws Exception {
-        testViewAndTableInDifferentSchemas(true);
-    }
-
-    @Test
-    public void testViewAndTableInDifferentSchemas() throws Exception {
-        testViewAndTableInDifferentSchemas(false);
-
-    }
-
-    public void testViewAndTableInDifferentSchemas(boolean isNamespaceMapped) throws Exception {
-        Properties props = new Properties();
-        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
-        Connection conn = DriverManager.getConnection(getUrl(),props);
-        String tableName = "T_" + generateUniqueName();
-        String schemaName1 = SCHEMA1;
-        String fullTableName1 = SchemaUtil.getTableName(schemaName1, tableName);
-        String viewName1 = "V_" + generateUniqueName();
-        String viewSchemaName = SCHEMA2;
-        String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName1);
-        String viewName2 = "V_" + generateUniqueName();
-        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, viewName1);
-        
-        if (isNamespaceMapped) {
-            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName1);
-        }
-        String ddl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
-        conn.createStatement().execute(ddl);
-        assertTrue(admin.tableExists(SchemaUtil.getPhysicalTableName(SchemaUtil.normalizeIdentifier(fullTableName1),
-                conn.unwrap(PhoenixConnection.class).getQueryServices().getProps())));
-        
-        ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        
-        ddl = "CREATE VIEW " + fullViewName2 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        
-        conn.createStatement().executeQuery("SELECT * FROM " + fullViewName1);
-        conn.createStatement().executeQuery("SELECT * FROM " + fullViewName2);
-        ddl = "DROP VIEW " + viewName1;
-        try {
-            conn.createStatement().execute(ddl);
-            fail();
-        } catch (TableNotFoundException ignore) {
-        }
-        ddl = "DROP VIEW " + fullViewName1;
-        conn.createStatement().execute(ddl);
-        ddl = "DROP VIEW " + SchemaUtil.getTableName(viewSchemaName, generateUniqueName());
-        try {
-            conn.createStatement().execute(ddl);
-            fail();
-        } catch (TableNotFoundException ignore) {
-        }
-        ddl = "DROP TABLE " + fullTableName1;
-        ddl = "DROP VIEW " + fullViewName2;
-        conn.createStatement().execute(ddl);
-        ddl = "DROP TABLE " + fullTableName1;
-        conn.createStatement().execute(ddl);
-    }
-
-
-    @Test
-    public void testDisallowDropOfColumnOnParentTable() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + viewName + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
-        conn.createStatement().execute(ddl);
-        
-        try {
-            conn.createStatement().execute("ALTER TABLE " + fullTableName + " DROP COLUMN v1");
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
-        }
-    }
-   
-    @Test
-    public void testViewAndTableAndDropCascade() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
-        
-        String tableDdl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(tableDdl);
-        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        if (transactionProvider == null ||
-                !TransactionFactory.getTransactionProvider(
-                        TransactionFactory.Provider.valueOf(transactionProvider)).isUnsupported(Feature.ALLOW_LOCAL_INDEX)) {
-            String indexName = generateUniqueName();
-            ddl = "CREATE LOCAL INDEX " + indexName + " on " + fullViewName1 + "(v2)";
-            conn.createStatement().execute(ddl);
-        }
-        ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
-        conn.createStatement().execute(ddl);
-        
-        // dropping base table without cascade should fail
-        try {
-            conn.createStatement().execute("DROP TABLE " + fullTableName );
-            fail();
-        }
-        catch (SQLException e) {
-            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
-        }
-
-        // drop table cascade should succeed
-        conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
-        
-        validateViewDoesNotExist(conn, fullViewName1);
-        validateViewDoesNotExist(conn, fullViewName2);
-
-    }
-    
-    @Test
-    public void testRecreateDroppedTableWithChildViews() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
-        
-        String tableDdl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(tableDdl);
-        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        String indexName = generateUniqueName();
-        ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
-        conn.createStatement().execute(ddl);
-        
-        // drop table cascade should succeed
-        conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
-        
-        validateViewDoesNotExist(conn, fullViewName1);
-        validateViewDoesNotExist(conn, fullViewName2);
-
-        // recreate the table that was dropped
-        conn.createStatement().execute(tableDdl);
-        // the two child views should still not exist
-        try {
-            PhoenixRuntime.getTableNoCache(conn, fullViewName1);
-            fail();
-        } catch (SQLException e) {
-        }
-        try {
-            PhoenixRuntime.getTableNoCache(conn, fullViewName2);
-            fail();
-        } catch (SQLException e) {
-        }
-    }
-    
-    @Test
-    public void testRecreateIndexWhoseAncestorWasDropped() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String fullTableName2 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        
-        String tableDdl = "CREATE TABLE " + fullTableName1 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(tableDdl);
-        tableDdl = "CREATE TABLE " + fullTableName2 + "  (k INTEGER NOT NULL PRIMARY KEY, v3 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(tableDdl);
-        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        String indexName = generateUniqueName();
-        ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
-        conn.createStatement().execute(ddl);
-        try {
-                // this should fail because an index with this name is present
-            ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v1)";
-            conn.createStatement().execute(ddl);
-            fail();
-        }
-        catch(SQLException e) {
-        }
-        
-        // drop table cascade should succeed
-        conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
-        
-        // should be able to reuse the index name 
-        ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v3)";
-        conn.createStatement().execute(ddl);
-        
-        String fullIndexName = SchemaUtil.getTableName(SCHEMA2, indexName);
-        PTable index = PhoenixRuntime.getTableNoCache(conn, fullIndexName);
-        // the index should have v3 but not v2
-        validateCols(index);
-    }
-    
-    @Test
-    public void testRecreateViewWhoseParentWasDropped() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String fullTableName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
-        
-        String tableDdl = "CREATE TABLE " + fullTableName1 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(tableDdl);
-        tableDdl = "CREATE TABLE " + fullTableName2 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(tableDdl);
-        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        
-        // drop table cascade should succeed
-        conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
-        
-        // should be able to reuse the view name 
-        ddl = "CREATE VIEW " + fullViewName1 + " (v3 VARCHAR) AS SELECT * FROM " + fullTableName2 + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        
-        PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName1);
-        // the view should have v3 but not v2
-        validateCols(view);
-    }
-
-    private void validateCols(PTable table) {
-        final String prefix = table.getType() == PTableType.INDEX ? "0:" : "";
-        Predicate<PColumn> predicate = new Predicate<PColumn>() {
-            @Override
-            public boolean apply(PColumn col) {
-                return col.getName().getString().equals(prefix + "V3")
-                        || col.getName().getString().equals(prefix + "V2");
-            }
-        };
-        List<PColumn> colList = table.getColumns();
-        Collection<PColumn> filteredCols = Collections2.filter(colList, predicate);
-        assertEquals(1, filteredCols.size());
-        assertEquals(prefix + "V3", filteredCols.iterator().next().getName().getString());
-    }
-    
-    @Test
-    public void testViewAndTableAndDropCascadeWithIndexes() throws Exception {
-        // Setup - Tables and Views with Indexes
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
-        String indexName1 = "I_" + generateUniqueName();
-        String indexName2 = "I_" + generateUniqueName();
-        String indexName3 = "I_" + generateUniqueName();
-        
-        ddl = "CREATE INDEX " + indexName1 + " ON " + fullTableName + " (v1)";
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE INDEX " + indexName2 + " ON " + fullViewName1 + " (v2)";
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName2 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE INDEX " + indexName3 + " ON " + fullViewName2 + " (v2)";
-        conn.createStatement().execute(ddl);
-        
-
-        // Execute DROP...CASCADE
-        conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
-        
-        // Validate Views were deleted - Try and delete child views, should throw TableNotFoundException
-        validateViewDoesNotExist(conn, fullViewName1);
-        validateViewDoesNotExist(conn, fullViewName2);
-    }
-
-
-    private void validateViewDoesNotExist(Connection conn, String fullViewName)    throws SQLException {
-        try {
-            String ddl1 = "DROP VIEW " + fullViewName;
-            conn.createStatement().execute(ddl1);
-            fail("View " + fullViewName + " should have been deleted when parent was dropped");
-        } catch (TableNotFoundException e) {
-            //Expected
-        }
-    }
-    
     @Test
     public void testViewUsesTableGlobalIndex() throws Exception {
         testViewUsesTableIndex(false);
@@ -757,108 +425,6 @@ public class ViewIT extends SplitSystemCatalogIT {
     }
     
     @Test
-    public void testCreateViewDefinesPKConstraint() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-
-        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName + "(v2 VARCHAR, k3 VARCHAR, k4 INTEGER NOT NULL, CONSTRAINT PKVEW PRIMARY KEY (k3, k4)) AS SELECT * FROM " + fullTableName + " WHERE K1 = 1";
-        conn.createStatement().execute(ddl);
-        
-        PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName);
-        
-        // assert PK metadata
-        ResultSet rs =
-                conn.getMetaData().getPrimaryKeys(null,
-                    SchemaUtil.getSchemaNameFromFullName(fullViewName),
-                    SchemaUtil.getTableNameFromFullName(fullViewName));
-        assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
-    }
-    
-    @Test
-    public void testViewAddsPKColumn() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String viewName = generateUniqueName();
-        String fullViewName = SchemaUtil.getTableName(SCHEMA2, viewName);
-        
-        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
-        conn.createStatement().execute(ddl);
-        
-        ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
-        conn.createStatement().execute(ddl);
-
-        // assert PK metadata
-        ResultSet rs = conn.getMetaData().getPrimaryKeys(null, SCHEMA2, viewName);
-        assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
-    }
-    
-    @Test
-    public void testViewAddsPKColumnWhoseParentsLastPKIsVarLength() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-
-        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 VARCHAR NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
-        conn.createStatement().execute(ddl);
-        
-        ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
-        try {
-            conn.createStatement().execute(ddl);
-            fail("View cannot extend PK if parent's last PK is variable length. See https://issues.apache.org/jira/browse/PHOENIX-978.");
-        } catch (SQLException e) {
-            assertEquals(CANNOT_MODIFY_VIEW_PK.getErrorCode(), e.getErrorCode());
-        }
-        String fullViewName2 = "V_" + generateUniqueName();
-        ddl = "CREATE VIEW " + fullViewName2 + " (k3 VARCHAR PRIMARY KEY)  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
-        try {
-            conn.createStatement().execute(ddl);
-        } catch (SQLException e) {
-            assertEquals(CANNOT_MODIFY_VIEW_PK.getErrorCode(), e.getErrorCode());
-        }
-    }
-    
-    @Test(expected=ColumnAlreadyExistsException.class)
-    public void testViewAddsClashingPKColumn() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        
-        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
-        conn.createStatement().execute(ddl);
-        
-        ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k2 VARCHAR PRIMARY KEY, v2 INTEGER";
-        conn.createStatement().execute(ddl);
-    }
-
-    @Test
-    public void testViewAddsNotNullPKColumn() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))" + tableDDLOptions;
-        conn.createStatement().execute(ddl);
-        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
-        conn.createStatement().execute(ddl);
-        
-        try {
-            ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR NOT NULL PRIMARY KEY"; 
-            conn.createStatement().execute(ddl);
-            fail("can only add nullable PKs via ALTER VIEW/TABLE");
-        } catch (SQLException e) {
-            assertEquals(NOT_NULLABLE_COLUMN_IN_ROW_KEY.getErrorCode(), e.getErrorCode());
-        }
-    }
-    
-    @Test
     public void testQueryViewStatementOptimization() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
@@ -883,93 +449,6 @@ public class ViewIT extends SplitSystemCatalogIT {
         assertEquals(0, plan.getOrderBy().getOrderByExpressions().size());
     }
 
-    @Test
-    public void testCreateViewWithUpdateCacheFrquency() throws Exception {
-      Properties props = new Properties();
-      Connection conn1 = DriverManager.getConnection(getUrl(), props);
-      conn1.setAutoCommit(true);
-      String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-      String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-      conn1.createStatement().execute(
-        "CREATE TABLE "+tableName+" (k VARCHAR PRIMARY KEY, v1 VARCHAR, v2 VARCHAR) UPDATE_CACHE_FREQUENCY=1000000");
-      conn1.createStatement().execute("upsert into "+tableName+" values ('row1', 'value1', 'key1')");
-      conn1.createStatement().execute(
-        "CREATE VIEW "+viewName+" (v43 VARCHAR) AS SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
-      
-      ResultSet rs = conn1.createStatement()
-          .executeQuery("SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
-      assertTrue(rs.next());
-    }
-
-    @Test
-    public void testCreateViewMappedToExistingHbaseTableWithNamespaceMappingEnabled() throws Exception {
-        final String NS = "NS_" + generateUniqueName();
-        final String TBL = "TBL_" + generateUniqueName();
-        final String CF = "CF";
-
-        Properties props = new Properties();
-        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.TRUE.toString());
-
-        try (Connection conn = DriverManager.getConnection(getUrl(), props);
-                Admin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
-
-            conn.createStatement().execute("CREATE SCHEMA " + NS);
-
-            // test for a view that is in non-default schema
-            {
-                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, TBL));
-                desc.addFamily(new HColumnDescriptor(CF));
-                admin.createTable(desc);
-
-                String view1 = NS + "." + TBL;
-                conn.createStatement().execute(
-                        "CREATE VIEW " + view1 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
-
-                assertTrue(QueryUtil.getExplainPlan(
-                        conn.createStatement().executeQuery("explain select * from " + view1))
-                        .contains(NS + ":" + TBL));
-
-                conn.createStatement().execute("DROP VIEW " + view1);
-            }
-
-            // test for a view whose name contains a dot (e.g. "AAA.BBB") in default schema (for backward compatibility)
-            {
-                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS + "." + TBL));
-                desc.addFamily(new HColumnDescriptor(CF));
-                admin.createTable(desc);
-
-                String view2 = "\"" + NS + "." + TBL + "\"";
-                conn.createStatement().execute(
-                        "CREATE VIEW " + view2 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
-
-                assertTrue(QueryUtil
-                        .getExplainPlan(
-                                conn.createStatement().executeQuery("explain select * from " + view2))
-                        .contains(NS + "." + TBL));
-
-                conn.createStatement().execute("DROP VIEW " + view2);
-            }
-
-            // test for a view whose name contains a dot (e.g. "AAA.BBB") in non-default schema
-            {
-                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, NS + "." + TBL));
-                desc.addFamily(new HColumnDescriptor(CF));
-                admin.createTable(desc);
-
-                String view3 = NS + ".\"" + NS + "." + TBL + "\"";
-                conn.createStatement().execute(
-                        "CREATE VIEW " + view3 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
-
-                assertTrue(QueryUtil.getExplainPlan(
-                        conn.createStatement().executeQuery("explain select * from " + view3))
-                        .contains(NS + ":" + NS + "." + TBL));
-
-                conn.createStatement().execute("DROP VIEW " + view3);
-            }
-            conn.createStatement().execute("DROP SCHEMA " + NS);
-        }
-    }
-
     private void assertPKs(ResultSet rs, String[] expectedPKs) throws SQLException {
         List<String> pkCols = newArrayListWithExpectedSize(expectedPKs.length);
         while (rs.next()) {
@@ -989,10 +468,14 @@ public class ViewIT extends SplitSystemCatalogIT {
             String viewName3 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
             String viewName4 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
 
+            String myTableDDLOptions = tableDDLOptions;
+            if (myTableDDLOptions.length() != 0) myTableDDLOptions += ",";
+            myTableDDLOptions += "VERSIONS=1, MULTI_TENANT=true, IMMUTABLE_ROWS=TRUE, REPLICATION_SCOPE=1";
+
             // create global base table
             globalConn.createStatement().execute("CREATE TABLE " + tableName
-                    + " (TENANT_ID CHAR(15) NOT NULL, KEY_PREFIX CHAR(3) NOT NULL, CREATED_DATE DATE, CREATED_BY CHAR(15), SYSTEM_MODSTAMP DATE CONSTRAINT PK PRIMARY KEY (TENANT_ID, KEY_PREFIX)) VERSIONS=1, MULTI_TENANT=true, IMMUTABLE_ROWS=TRUE, REPLICATION_SCOPE=1");
-            
+                    + " (TENANT_ID CHAR(15) NOT NULL, KEY_PREFIX CHAR(3) NOT NULL, CREATED_DATE DATE, CREATED_BY CHAR(15), SYSTEM_MODSTAMP DATE CONSTRAINT PK PRIMARY KEY (TENANT_ID, KEY_PREFIX)) " + myTableDDLOptions);
+
             String tenantId = "tenantId";
             Properties tenantProps = new Properties();
             tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
@@ -1082,51 +565,6 @@ public class ViewIT extends SplitSystemCatalogIT {
         }
     }
 
-    @Test
-    public void testQueryWithSeparateConnectionForViewOnTableThatHasIndex() throws SQLException {
-        try (Connection conn = DriverManager.getConnection(getUrl());
-                Connection conn2 = DriverManager.getConnection(getUrl());
-                Statement s = conn.createStatement();
-                Statement s2 = conn2.createStatement()) {
-            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-            String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-            String indexName = generateUniqueName();
-            helpTestQueryForViewOnTableThatHasIndex(s, s2, tableName, viewName, indexName);
-        }
-    }
-
-    @Test
-    public void testQueryForViewOnTableThatHasIndex() throws SQLException {
-        try (Connection conn = DriverManager.getConnection(getUrl());
-                Statement s = conn.createStatement()) {
-            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-            String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-            String indexName = generateUniqueName();
-            helpTestQueryForViewOnTableThatHasIndex(s, s, tableName, viewName, indexName);
-        }
-    }
-
-    private void helpTestQueryForViewOnTableThatHasIndex(Statement s1, Statement s2, String tableName, String viewName, String indexName)
-            throws SQLException {
-        // Create a table
-        s1.execute("create table " + tableName + " (col1 varchar primary key, col2 varchar)");
-
-        // Create a view on the table
-        s1.execute("create view " + viewName + " (col3 varchar) as select * from " + tableName);
-        s1.executeQuery("select * from " + viewName);
-        // Create a index on the table
-        s1.execute("create index " + indexName + " ON " + tableName + " (col2)");
-
-        try (ResultSet rs =
-                s2.executeQuery("explain select /*+ INDEX(" + viewName + " " + indexName
-                        + ") */ * from " + viewName + " where col2 = 'aaa'")) {
-            String explainPlan = QueryUtil.getExplainPlan(rs);
-
-            // check if the query uses the index
-            assertTrue(explainPlan.contains(indexName));
-        }
-    }
-
     private void validate(String viewName, Connection tenantConn, String[] whereClauseArray,
             long[] expectedArray) throws SQLException {
         for (int i = 0; i < whereClauseArray.length; ++i) {
@@ -1154,28 +592,6 @@ public class ViewIT extends SplitSystemCatalogIT {
         tenantConn.commit();
     }
     
-    @Test
-    public void testUpdatingPropertyOnBaseTable() throws Exception {
-        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
-        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            conn.createStatement()
-                    .execute("create table " + fullTableName
-                            + "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY "
-                            + "(tenantId, pk1)) MULTI_TENANT=true");
-            conn.createStatement().execute("CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName);
-            
-            conn.createStatement()
-                    .execute("ALTER TABLE " + fullTableName + " set IMMUTABLE_ROWS = true");
-            
-            // fetch the latest tables
-            PTable table = PhoenixRuntime.getTableNoCache(conn, fullTableName);
-            PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName);
-            assertEquals("IMMUTABLE_ROWS property set incorrectly", true, table.isImmutableRows());
-            assertEquals("IMMUTABLE_ROWS property set incorrectly", true, view.isImmutableRows());
-        }
-    }
-
     public static String testUpdatableView(String fullTableName, String fullViewName, String fullChildViewName,
             String childViewDDL, Integer saltBuckets, String tableDDLOptions) throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
@@ -1363,51 +779,6 @@ public class ViewIT extends SplitSystemCatalogIT {
     }
 
     @Test
-    public void testCreateViewFromHBaseTable() throws Exception {
-        String tableNameStr = generateUniqueName();
-        String familyNameStr = generateUniqueName();
-
-        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(),
-                TestUtil.TEST_PROPERTIES).getAdmin();
-
-        HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableNameStr));
-        desc.addFamily(new HColumnDescriptor(familyNameStr));
-        admin.createTable(desc);
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        //PK is not specified, without where clause
-        try {
-            conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
-                    "\" (ROWKEY VARCHAR, \"" + familyNameStr + "\".a VARCHAR)");
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.PRIMARY_KEY_MISSING.getErrorCode(), e.getErrorCode());
-        }
-
-        // No error, as PK is specified
-        conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
-                "\" (ROWKEY VARCHAR PRIMARY KEY, \"" + familyNameStr + "\".a VARCHAR)");
-
-        conn.createStatement().executeUpdate("DROP VIEW \"" + tableNameStr + "\"");
-
-        //PK is not specified, with where clause
-        try {
-            conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
-                    "\" (ROWKEY VARCHAR, \"" + familyNameStr + "\".a VARCHAR) AS SELECT * FROM \""
-                    + tableNameStr + "\" WHERE ROWKEY = '1'");
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.PRIMARY_KEY_MISSING.getErrorCode(), e.getErrorCode());
-        }
-
-        conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
-                "\" (ROWKEY VARCHAR PRIMARY KEY, \"" + familyNameStr + "\".a VARCHAR) AS SELECT " +
-                "* FROM \"" + tableNameStr + "\" WHERE ROWKEY = '1'");
-
-        conn.createStatement().executeUpdate("DROP VIEW \"" + tableNameStr + "\"");
-    }
-    
-    @Test
     public void testConcurrentViewCreationAndTableDrop() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl())) {
             String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewMetadataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewMetadataIT.java
new file mode 100644
index 0000000..c283f58
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewMetadataIT.java
@@ -0,0 +1,684 @@
+package org.apache.phoenix.end2end;
+
+import static com.google.common.collect.Lists.newArrayListWithExpectedSize;
+import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MODIFY_VIEW_PK;
+import static org.apache.phoenix.exception.SQLExceptionCode.NOT_NULLABLE_COLUMN_IN_ROW_KEY;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+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.sql.Statement;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.phoenix.coprocessor.PhoenixMetaDataCoprocessorHost;
+import org.apache.phoenix.end2end.ViewIT.TestMetaDataRegionObserver;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.ColumnAlreadyExistsException;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Maps;
+
+public class ViewMetadataIT extends SplitSystemCatalogIT {
+    @BeforeClass
+    public static void doSetup() throws Exception {
+        NUM_SLAVES_BASE = 6;
+        Map<String, String> props = Collections.emptyMap();
+        boolean splitSystemCatalog = (driver == null);
+        Map<String, String> serverProps = Maps.newHashMapWithExpectedSize(1);
+        serverProps.put(QueryServices.PHOENIX_ACLS_ENABLED, "true");
+        serverProps.put(PhoenixMetaDataCoprocessorHost.PHOENIX_META_DATA_COPROCESSOR_CONF_KEY,
+            TestMetaDataRegionObserver.class.getName());
+        serverProps.put("hbase.coprocessor.abortonerror", "false");
+        setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()), new ReadOnlyProps(props.entrySet().iterator()));
+        // Split SYSTEM.CATALOG once after the mini-cluster is started
+        if (splitSystemCatalog) {
+            splitSystemCatalog();
+        }
+    }
+
+    @Test
+    public void testCreateViewWithUpdateCacheFrquency() throws Exception {
+      Properties props = new Properties();
+      Connection conn1 = DriverManager.getConnection(getUrl(), props);
+      conn1.setAutoCommit(true);
+      String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+      String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+      conn1.createStatement().execute(
+        "CREATE TABLE "+tableName+" (k VARCHAR PRIMARY KEY, v1 VARCHAR, v2 VARCHAR) UPDATE_CACHE_FREQUENCY=1000000");
+      conn1.createStatement().execute("upsert into "+tableName+" values ('row1', 'value1', 'key1')");
+      conn1.createStatement().execute(
+        "CREATE VIEW "+viewName+" (v43 VARCHAR) AS SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
+
+      ResultSet rs = conn1.createStatement()
+          .executeQuery("SELECT * FROM "+tableName+" WHERE v1 = 'value1'");
+      assertTrue(rs.next());
+    }
+
+    @Test
+    public void testCreateViewFromHBaseTable() throws Exception {
+        String tableNameStr = generateUniqueName();
+        String familyNameStr = generateUniqueName();
+
+        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(),
+                TestUtil.TEST_PROPERTIES).getAdmin();
+
+        HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableNameStr));
+        desc.addFamily(new HColumnDescriptor(familyNameStr));
+        admin.createTable(desc);
+        Connection conn = DriverManager.getConnection(getUrl());
+
+        //PK is not specified, without where clause
+        try {
+            conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
+                    "\" (ROWKEY VARCHAR, \"" + familyNameStr + "\".a VARCHAR)");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.PRIMARY_KEY_MISSING.getErrorCode(), e.getErrorCode());
+        }
+
+        // No error, as PK is specified
+        conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
+                "\" (ROWKEY VARCHAR PRIMARY KEY, \"" + familyNameStr + "\".a VARCHAR)");
+
+        conn.createStatement().executeUpdate("DROP VIEW \"" + tableNameStr + "\"");
+
+        //PK is not specified, with where clause
+        try {
+            conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
+                    "\" (ROWKEY VARCHAR, \"" + familyNameStr + "\".a VARCHAR) AS SELECT * FROM \""
+                    + tableNameStr + "\" WHERE ROWKEY = '1'");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.PRIMARY_KEY_MISSING.getErrorCode(), e.getErrorCode());
+        }
+
+        conn.createStatement().executeUpdate("CREATE VIEW \"" + tableNameStr +
+                "\" (ROWKEY VARCHAR PRIMARY KEY, \"" + familyNameStr + "\".a VARCHAR) AS SELECT " +
+                "* FROM \"" + tableNameStr + "\" WHERE ROWKEY = '1'");
+
+        conn.createStatement().executeUpdate("DROP VIEW \"" + tableNameStr + "\"");
+    }
+
+    @Test
+    public void testCreateViewMappedToExistingHbaseTableWithNamespaceMappingEnabled() throws Exception {
+        final String NS = "NS_" + generateUniqueName();
+        final String TBL = "TBL_" + generateUniqueName();
+        final String CF = "CF";
+
+        Properties props = new Properties();
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.TRUE.toString());
+
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);
+                Admin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+
+            conn.createStatement().execute("CREATE SCHEMA " + NS);
+
+            // test for a view that is in non-default schema
+            {
+                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, TBL));
+                desc.addFamily(new HColumnDescriptor(CF));
+                admin.createTable(desc);
+
+                String view1 = NS + "." + TBL;
+                conn.createStatement().execute(
+                        "CREATE VIEW " + view1 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+
+                assertTrue(QueryUtil.getExplainPlan(
+                        conn.createStatement().executeQuery("explain select * from " + view1))
+                        .contains(NS + ":" + TBL));
+
+                conn.createStatement().execute("DROP VIEW " + view1);
+            }
+
+            // test for a view whose name contains a dot (e.g. "AAA.BBB") in default schema (for backward compatibility)
+            {
+                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS + "." + TBL));
+                desc.addFamily(new HColumnDescriptor(CF));
+                admin.createTable(desc);
+
+                String view2 = "\"" + NS + "." + TBL + "\"";
+                conn.createStatement().execute(
+                        "CREATE VIEW " + view2 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+
+                assertTrue(QueryUtil
+                        .getExplainPlan(
+                                conn.createStatement().executeQuery("explain select * from " + view2))
+                        .contains(NS + "." + TBL));
+
+                conn.createStatement().execute("DROP VIEW " + view2);
+            }
+
+            // test for a view whose name contains a dot (e.g. "AAA.BBB") in non-default schema
+            {
+                HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(NS, NS + "." + TBL));
+                desc.addFamily(new HColumnDescriptor(CF));
+                admin.createTable(desc);
+
+                String view3 = NS + ".\"" + NS + "." + TBL + "\"";
+                conn.createStatement().execute(
+                        "CREATE VIEW " + view3 + " (PK VARCHAR PRIMARY KEY, " + CF + ".COL VARCHAR)");
+
+                assertTrue(QueryUtil.getExplainPlan(
+                        conn.createStatement().executeQuery("explain select * from " + view3))
+                        .contains(NS + ":" + NS + "." + TBL));
+
+                conn.createStatement().execute("DROP VIEW " + view3);
+            }
+            conn.createStatement().execute("DROP SCHEMA " + NS);
+        }
+    }
+
+    @Test
+    public void testRecreateDroppedTableWithChildViews() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+        String tableDdl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)";
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        String indexName = generateUniqueName();
+        ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
+        conn.createStatement().execute(ddl);
+
+        // drop table cascade should succeed
+        conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
+
+        validateViewDoesNotExist(conn, fullViewName1);
+        validateViewDoesNotExist(conn, fullViewName2);
+
+        // recreate the table that was dropped
+        conn.createStatement().execute(tableDdl);
+        // the two child views should still not exist
+        try {
+            PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+            fail();
+        } catch (SQLException e) {
+        }
+        try {
+            PhoenixRuntime.getTableNoCache(conn, fullViewName2);
+            fail();
+        } catch (SQLException e) {
+        }
+    }
+
+    @Test
+    public void testRecreateIndexWhoseAncestorWasDropped() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullTableName2 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
+        String tableDdl = "CREATE TABLE " + fullTableName1 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)";
+        conn.createStatement().execute(tableDdl);
+        tableDdl = "CREATE TABLE " + fullTableName2 + "  (k INTEGER NOT NULL PRIMARY KEY, v3 DATE)";
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        String indexName = generateUniqueName();
+        ddl = "CREATE INDEX " + indexName + " on " + fullViewName1 + "(v2)";
+        conn.createStatement().execute(ddl);
+        try {
+                // this should fail because an index with this name is present
+            ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v1)";
+            conn.createStatement().execute(ddl);
+            fail();
+        }
+        catch(SQLException e) {
+        }
+
+        // drop table cascade should succeed
+        conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
+
+        // should be able to reuse the index name 
+        ddl = "CREATE INDEX " + indexName + " on " + fullTableName2 + "(v3)";
+        conn.createStatement().execute(ddl);
+
+        String fullIndexName = SchemaUtil.getTableName(SCHEMA2, indexName);
+        PTable index = PhoenixRuntime.getTableNoCache(conn, fullIndexName);
+        // the index should have v3 but not v2
+        validateCols(index);
+    }
+
+    @Test
+    public void testRecreateViewWhoseParentWasDropped() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullTableName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+        String tableDdl = "CREATE TABLE " + fullTableName1 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)";
+        conn.createStatement().execute(tableDdl);
+        tableDdl = "CREATE TABLE " + fullTableName2 + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)";
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+
+        // drop table cascade should succeed
+        conn.createStatement().execute("DROP TABLE " + fullTableName1 + " CASCADE");
+
+        // should be able to reuse the view name 
+        ddl = "CREATE VIEW " + fullViewName1 + " (v3 VARCHAR) AS SELECT * FROM " + fullTableName2 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+
+        PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName1);
+        // the view should have v3 but not v2
+        validateCols(view);
+    }
+
+    @Test
+    public void testViewAndTableInDifferentSchemasWithNamespaceMappingEnabled() throws Exception {
+        testViewAndTableInDifferentSchemas(true);
+    }
+
+    @Test
+    public void testViewAndTableInDifferentSchemas() throws Exception {
+        testViewAndTableInDifferentSchemas(false);
+
+    }
+
+    public void testViewAndTableInDifferentSchemas(boolean isNamespaceMapped) throws Exception {
+        Properties props = new Properties();
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
+        Connection conn = DriverManager.getConnection(getUrl(),props);
+        String tableName = "T_" + generateUniqueName();
+        String schemaName1 = SCHEMA1;
+        String fullTableName1 = SchemaUtil.getTableName(schemaName1, tableName);
+        String viewName1 = "V_" + generateUniqueName();
+        String viewSchemaName = SCHEMA2;
+        String fullViewName1 = SchemaUtil.getTableName(viewSchemaName, viewName1);
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, viewName1);
+
+        if (isNamespaceMapped) {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName1);
+        }
+        String ddl = "CREATE TABLE " + fullTableName1 + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)";
+        HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
+        conn.createStatement().execute(ddl);
+        assertTrue(admin.tableExists(SchemaUtil.getPhysicalTableName(SchemaUtil.normalizeIdentifier(fullTableName1),
+                conn.unwrap(PhoenixConnection.class).getQueryServices().getProps())));
+
+        ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+
+        ddl = "CREATE VIEW " + fullViewName2 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName1 + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+
+        conn.createStatement().executeQuery("SELECT * FROM " + fullViewName1);
+        conn.createStatement().executeQuery("SELECT * FROM " + fullViewName2);
+        ddl = "DROP VIEW " + viewName1;
+        try {
+            conn.createStatement().execute(ddl);
+            fail();
+        } catch (TableNotFoundException ignore) {
+        }
+        ddl = "DROP VIEW " + fullViewName1;
+        conn.createStatement().execute(ddl);
+        ddl = "DROP VIEW " + SchemaUtil.getTableName(viewSchemaName, generateUniqueName());
+        try {
+            conn.createStatement().execute(ddl);
+            fail();
+        } catch (TableNotFoundException ignore) {
+        }
+        ddl = "DROP TABLE " + fullTableName1;
+        ddl = "DROP VIEW " + fullViewName2;
+        conn.createStatement().execute(ddl);
+        ddl = "DROP TABLE " + fullTableName1;
+        conn.createStatement().execute(ddl);
+    }
+
+    @Test
+    public void testViewAndTableAndDropCascade() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+        String tableDdl = "CREATE TABLE " + fullTableName + "  (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)";
+        conn.createStatement().execute(tableDdl);
+        String ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        String indexName = generateUniqueName();
+        ddl = "CREATE LOCAL INDEX " + indexName + " on " + fullViewName1 + "(v2)";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName2 + "(v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
+        conn.createStatement().execute(ddl);
+
+        // dropping base table without cascade should fail
+        try {
+            conn.createStatement().execute("DROP TABLE " + fullTableName );
+            fail();
+        }
+        catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+        }
+
+        // drop table cascade should succeed
+        conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
+
+        validateViewDoesNotExist(conn, fullViewName1);
+        validateViewDoesNotExist(conn, fullViewName2);
+
+    }
+
+    @Test
+    public void testUpdatingPropertyOnBaseTable() throws Exception {
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            conn.createStatement()
+                    .execute("create table " + fullTableName
+                            + "(tenantId CHAR(15) NOT NULL, pk1 integer NOT NULL, v varchar CONSTRAINT PK PRIMARY KEY "
+                            + "(tenantId, pk1)) MULTI_TENANT=true");
+            conn.createStatement().execute("CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName);
+
+            conn.createStatement()
+                    .execute("ALTER TABLE " + fullTableName + " set IMMUTABLE_ROWS = true");
+
+            // fetch the latest tables
+            PTable table = PhoenixRuntime.getTableNoCache(conn, fullTableName);
+            PTable view = PhoenixRuntime.getTableNoCache(conn, fullViewName);
+            assertEquals("IMMUTABLE_ROWS property set incorrectly", true, table.isImmutableRows());
+            assertEquals("IMMUTABLE_ROWS property set incorrectly", true, view.isImmutableRows());
+        }
+    }
+
+    @Test
+    public void testViewAddsPKColumnWhoseParentsLastPKIsVarLength() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 VARCHAR NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        conn.createStatement().execute(ddl);
+
+        ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
+        try {
+            conn.createStatement().execute(ddl);
+            fail("View cannot extend PK if parent's last PK is variable length. See https://issues.apache.org/jira/browse/PHOENIX-978.");
+        } catch (SQLException e) {
+            assertEquals(CANNOT_MODIFY_VIEW_PK.getErrorCode(), e.getErrorCode());
+        }
+        String fullViewName2 = "V_" + generateUniqueName();
+        ddl = "CREATE VIEW " + fullViewName2 + " (k3 VARCHAR PRIMARY KEY)  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        try {
+            conn.createStatement().execute(ddl);
+        } catch (SQLException e) {
+            assertEquals(CANNOT_MODIFY_VIEW_PK.getErrorCode(), e.getErrorCode());
+        }
+    }
+
+    @Test(expected=ColumnAlreadyExistsException.class)
+    public void testViewAddsClashingPKColumn() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        conn.createStatement().execute(ddl);
+
+        ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k2 VARCHAR PRIMARY KEY, v2 INTEGER";
+        conn.createStatement().execute(ddl);
+    }
+
+    @Test
+    public void testQueryWithSeparateConnectionForViewOnTableThatHasIndex() throws SQLException {
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection conn2 = DriverManager.getConnection(getUrl());
+                Statement s = conn.createStatement();
+                Statement s2 = conn2.createStatement()) {
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            String indexName = generateUniqueName();
+            helpTestQueryForViewOnTableThatHasIndex(s, s2, tableName, viewName, indexName);
+        }
+    }
+
+    @Test
+    public void testQueryForViewOnTableThatHasIndex() throws SQLException {
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Statement s = conn.createStatement()) {
+            String tableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+            String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+            String indexName = generateUniqueName();
+            helpTestQueryForViewOnTableThatHasIndex(s, s, tableName, viewName, indexName);
+        }
+    }
+
+    private void helpTestQueryForViewOnTableThatHasIndex(Statement s1, Statement s2, String tableName, String viewName, String indexName)
+            throws SQLException {
+        // Create a table
+        s1.execute("create table " + tableName + " (col1 varchar primary key, col2 varchar)");
+
+        // Create a view on the table
+        s1.execute("create view " + viewName + " (col3 varchar) as select * from " + tableName);
+        s1.executeQuery("select * from " + viewName);
+        // Create a index on the table
+        s1.execute("create index " + indexName + " ON " + tableName + " (col2)");
+
+        try (ResultSet rs =
+                s2.executeQuery("explain select /*+ INDEX(" + viewName + " " + indexName
+                        + ") */ * from " + viewName + " where col2 = 'aaa'")) {
+            String explainPlan = QueryUtil.getExplainPlan(rs);
+
+            // check if the query uses the index
+            assertTrue(explainPlan.contains(indexName));
+        }
+    }
+
+    @Test
+    public void testViewAndTableAndDropCascadeWithIndexes() throws Exception {
+        // Setup - Tables and Views with Indexes
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)";
+        conn.createStatement().execute(ddl);
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+        String indexName1 = "I_" + generateUniqueName();
+        String indexName2 = "I_" + generateUniqueName();
+        String indexName3 = "I_" + generateUniqueName();
+
+        ddl = "CREATE INDEX " + indexName1 + " ON " + fullTableName + " (v1)";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName1 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE INDEX " + indexName2 + " ON " + fullViewName1 + " (v2)";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName2 + " (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 10";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE INDEX " + indexName3 + " ON " + fullViewName2 + " (v2)";
+        conn.createStatement().execute(ddl);
+
+        // Execute DROP...CASCADE
+        conn.createStatement().execute("DROP TABLE " + fullTableName + " CASCADE");
+
+        // Validate Views were deleted - Try and delete child views, should throw TableNotFoundException
+        validateViewDoesNotExist(conn, fullViewName1);
+        validateViewDoesNotExist(conn, fullViewName2);
+    }
+
+    @Test
+    public void testViewAddsNotNullPKColumn() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        conn.createStatement().execute(ddl);
+
+        try {
+            ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR NOT NULL PRIMARY KEY"; 
+            conn.createStatement().execute(ddl);
+            fail("can only add nullable PKs via ALTER VIEW/TABLE");
+        } catch (SQLException e) {
+            assertEquals(NOT_NULLABLE_COLUMN_IN_ROW_KEY.getErrorCode(), e.getErrorCode());
+        }
+    }
+
+    @Test
+    public void testDisallowDropOfColumnOnParentTable() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + viewName + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        conn.createStatement().execute(ddl);
+
+        try {
+            conn.createStatement().execute("ALTER TABLE " + fullTableName + " DROP COLUMN v1");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+        }
+    }
+
+    @Test
+    public void testDisallowDropOfReferencedColumn() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+        String fullViewName2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName1 + "(v2 VARCHAR, v3 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName2 + " AS SELECT * FROM " + fullViewName1 + " WHERE v2 != 'foo'";
+        conn.createStatement().execute(ddl);
+
+        try {
+            conn.createStatement().execute("ALTER VIEW " + fullViewName1 + " DROP COLUMN v1");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+        }
+
+        try {
+            conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v1");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+        }
+        try {
+            conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v2");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
+        }
+        conn.createStatement().execute("ALTER VIEW " + fullViewName2 + " DROP COLUMN v3");
+    }
+
+    @Test
+    public void testViewAddsPKColumn() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String viewName = generateUniqueName();
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, viewName);
+
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName + "  AS SELECT * FROM " + fullTableName + " WHERE v1 = 1.0";
+        conn.createStatement().execute(ddl);
+
+        ddl = "ALTER VIEW " + fullViewName + " ADD k3 VARCHAR PRIMARY KEY, k4 VARCHAR PRIMARY KEY, v2 INTEGER";
+        conn.createStatement().execute(ddl);
+
+        // assert PK metadata
+        ResultSet rs = conn.getMetaData().getPrimaryKeys(null, SCHEMA2, viewName);
+        assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
+    }
+
+    @Test
+    public void testCreateViewDefinesPKConstraint() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String fullTableName = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+        String fullViewName = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+
+        String ddl = "CREATE TABLE " + fullTableName + " (k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 DECIMAL, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        conn.createStatement().execute(ddl);
+        ddl = "CREATE VIEW " + fullViewName + "(v2 VARCHAR, k3 VARCHAR, k4 INTEGER NOT NULL, CONSTRAINT PKVEW PRIMARY KEY (k3, k4)) AS SELECT * FROM " + fullTableName + " WHERE K1 = 1";
+        conn.createStatement().execute(ddl);
+
+        PhoenixRuntime.getTableNoCache(conn, fullViewName);
+
+        // assert PK metadata
+        ResultSet rs =
+                conn.getMetaData().getPrimaryKeys(null,
+                    SchemaUtil.getSchemaNameFromFullName(fullViewName),
+                    SchemaUtil.getTableNameFromFullName(fullViewName));
+        assertPKs(rs, new String[] {"K1", "K2", "K3", "K4"});
+    }
+
+    private void assertPKs(ResultSet rs, String[] expectedPKs) throws SQLException {
+        List<String> pkCols = newArrayListWithExpectedSize(expectedPKs.length);
+        while (rs.next()) {
+            pkCols.add(rs.getString("COLUMN_NAME"));
+        }
+        String[] actualPKs = pkCols.toArray(new String[0]);
+        assertArrayEquals(expectedPKs, actualPKs);
+    }
+
+    private void validateViewDoesNotExist(Connection conn, String fullViewName)    throws SQLException {
+        try {
+            String ddl1 = "DROP VIEW " + fullViewName;
+            conn.createStatement().execute(ddl1);
+            fail("View " + fullViewName + " should have been deleted when parent was dropped");
+        } catch (TableNotFoundException e) {
+            //Expected
+        }
+    }
+
+    private void validateCols(PTable table) {
+        final String prefix = table.getType() == PTableType.INDEX ? "0:" : "";
+        Predicate<PColumn> predicate = new Predicate<PColumn>() {
+            @Override
+            public boolean apply(PColumn col) {
+                return col.getName().getString().equals(prefix + "V3")
+                        || col.getName().getString().equals(prefix + "V2");
+            }
+        };
+        List<PColumn> colList = table.getColumns();
+        Collection<PColumn> filteredCols = Collections2.filter(colList, predicate);
+        assertEquals(1, filteredCols.size());
+        assertEquals(prefix + "V3", filteredCols.iterator().next().getName().getString());
+    }
+}