PHOENIX-3955: Ensure KEEP_DELETED_CELLS, REPLICATION_SCOPE, and TTL properties 
stay in sync between the physical data table and index tables


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/86fe2fc5
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/86fe2fc5
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/86fe2fc5

Branch: refs/heads/master
Commit: 86fe2fc5dfbebcf339aec42cce38b7a11e95186f
Parents: 9a818dd
Author: Chinmay Kulkarni <[email protected]>
Authored: Wed Oct 10 13:40:00 2018 -0700
Committer: Thomas D'Silva <[email protected]>
Committed: Wed Oct 10 16:28:23 2018 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AlterTableIT.java    |   4 +-
 .../org/apache/phoenix/end2end/BaseQueryIT.java |  15 +-
 .../apache/phoenix/end2end/CreateTableIT.java   |  26 +-
 .../phoenix/end2end/PropertiesInSyncIT.java     | 462 +++++++++++++++++++
 .../end2end/QueryDatabaseMetaDataIT.java        |   7 +-
 .../apache/phoenix/end2end/SetPropertyIT.java   |  47 +-
 .../org/apache/phoenix/tx/TransactionIT.java    |   4 +-
 .../phoenix/exception/SQLExceptionCode.java     |   7 +-
 .../query/ConnectionQueryServicesImpl.java      | 450 +++++++++++++-----
 .../apache/phoenix/schema/MetaDataClient.java   | 110 +++--
 .../apache/phoenix/schema/TableProperty.java    |   4 +-
 .../org/apache/phoenix/util/MetaDataUtil.java   |  44 +-
 .../org/apache/phoenix/util/UpgradeUtil.java    | 132 +++++-
 13 files changed, 1101 insertions(+), 211 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index 533b23a..64f0349 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -926,7 +926,7 @@ public class AlterTableIT extends ParallelStatsDisabledIT {
             // set HColumnProperty property when adding a pk column and other 
key value columns should work
             ddl = "ALTER TABLE "
                     + dataTableFullName
-                    + " ADD k3 DECIMAL PRIMARY KEY, col2 bigint, CF.col3 
bigint IN_MEMORY = true, CF.IN_MEMORY=false, CF.REPLICATION_SCOPE = 1";
+                    + " ADD k3 DECIMAL PRIMARY KEY, col2 bigint, CF.col3 
bigint IN_MEMORY = true, CF.IN_MEMORY=false, REPLICATION_SCOPE = 1";
             conn.createStatement().execute(ddl);
             // assert that k3 was added as new pk
             ResultSet rs = conn.getMetaData().getPrimaryKeys("", schemaName, 
dataTableName);
@@ -947,7 +947,7 @@ public class AlterTableIT extends ParallelStatsDisabledIT {
                 assertEquals(2, columnFamilies.length);
                 assertEquals("0", columnFamilies[0].getNameAsString());
                 assertEquals(true, columnFamilies[0].isInMemory());
-                assertEquals(0, columnFamilies[0].getScope());
+                assertEquals(1, columnFamilies[0].getScope());
                 assertEquals("CF", columnFamilies[1].getNameAsString());
                 assertEquals(false, columnFamilies[1].isInMemory());
                 assertEquals(1, columnFamilies[1].getScope());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseQueryIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseQueryIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseQueryIT.java
index ed3669c..e88dc57 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseQueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseQueryIT.java
@@ -53,20 +53,20 @@ public abstract class BaseQueryIT extends 
ParallelStatsDisabledIT {
     protected static final String[] GLOBAL_INDEX_DDLS =
             new String[] {
                     "CREATE INDEX %s ON %s (a_integer DESC) INCLUDE (" + "    
A_STRING, "
-                            + "    B_STRING, " + "    A_DATE) %s",
+                            + "    B_STRING, " + "    A_DATE)",
                     "CREATE INDEX %s ON %s (a_integer, a_string) INCLUDE (" + 
"    B_STRING, "
-                            + "    A_DATE) %s",
+                            + "    A_DATE)",
                     "CREATE INDEX %s ON %s (a_integer) INCLUDE (" + "    
A_STRING, "
-                            + "    B_STRING, " + "    A_DATE) %s",
+                            + "    B_STRING, " + "    A_DATE)",
                     NO_INDEX };
     protected static final String[] LOCAL_INDEX_DDLS =
             new String[] {
                     "CREATE LOCAL INDEX %s ON %s (a_integer DESC) INCLUDE (" + 
"    A_STRING, "
-                            + "    B_STRING, " + "    A_DATE) %s",
+                            + "    B_STRING, " + "    A_DATE)",
                     "CREATE LOCAL INDEX %s ON %s (a_integer, a_string) INCLUDE 
(" + "    B_STRING, "
-                            + "    A_DATE) %s",
+                            + "    A_DATE)",
                     "CREATE LOCAL INDEX %s ON %s (a_integer) INCLUDE (" + "    
A_STRING, "
-                            + "    B_STRING, " + "    A_DATE) %s" };
+                            + "    B_STRING, " + "    A_DATE)" };
     protected static String[] INDEX_DDLS;
     static {
         INDEX_DDLS = new String[GLOBAL_INDEX_DDLS.length + 
LOCAL_INDEX_DDLS.length];
@@ -108,8 +108,7 @@ public abstract class BaseQueryIT extends 
ParallelStatsDisabledIT {
         this.indexName = generateUniqueName();
         if (idxDdl.length() > 0) {
             this.indexDDL =
-                    String.format(idxDdl, indexName, tableName,
-                        keepDeletedCells ? "KEEP_DELETED_CELLS=true" : 
"KEEP_DELETED_CELLS=false");
+                    String.format(idxDdl, indexName, tableName);
             Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
             try (Connection conn = DriverManager.getConnection(getUrl(), 
props)) {
                 conn.createStatement().execute(this.indexDDL);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
index 19ca055..054a218 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
@@ -275,9 +275,9 @@ public class CreateTableIT extends ParallelStatsDisabledIT {
 
     /**
      * Tests that when: 1) DDL has both pk as well as key value columns 2) Key 
value columns have
-     * both default and explicit column family names 3) Replication scope 
specifier has the explicit
-     * column family name. Then: 1)REPLICATION_SCOPE is set. 2)The default 
column family has
-     * DEFAULT_REPLICATION_SCOPE. 3)The explicit column family has the 
REPLICATION_SCOPE specified
+     * both default and explicit column family names 3) Block size specifier 
has the explicit
+     * column family name. Then: 1)BLOCKSIZE is set. 2)The default column 
family has
+     * DEFAULT_BLOCKSIZE. 3)The explicit column family has the BLOCK_SIZE 
specified
      * in DDL.
      */
     @Test
@@ -287,7 +287,7 @@ public class CreateTableIT extends ParallelStatsDisabledIT {
                 "create table IF NOT EXISTS  " + tableName + "  (" + " id 
char(1) NOT NULL,"
                         + " col1 integer NOT NULL," + " b.col2 bigint," + " 
col3 bigint, "
                         + " CONSTRAINT NAME_PK PRIMARY KEY (id, col1)"
-                        + " ) b.REPLICATION_SCOPE=1, SALT_BUCKETS = 4";
+                        + " ) b.BLOCKSIZE=50000, SALT_BUCKETS = 4";
         Properties props = new Properties();
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.createStatement().execute(ddl);
@@ -296,16 +296,16 @@ public class CreateTableIT extends 
ParallelStatsDisabledIT {
                 
admin.getDescriptor(TableName.valueOf(tableName)).getColumnFamilies();
         assertEquals(2, columnFamilies.length);
         assertEquals("0", columnFamilies[0].getNameAsString());
-        assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_REPLICATION_SCOPE, 
columnFamilies[0].getScope());
+        assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
columnFamilies[0].getBlocksize());
         assertEquals("B", columnFamilies[1].getNameAsString());
-        assertEquals(1, columnFamilies[1].getScope());
+        assertEquals(50000, columnFamilies[1].getBlocksize());
     }
 
     /**
      * Tests that when: 1) DDL has both pk as well as key value columns 2) Key 
value columns have
-     * explicit column family names 3) Different REPLICATION_SCOPE specifiers 
for different column
-     * family names. Then: 1)REPLICATION_SCOPE is set. 2)Each explicit column 
family has the
-     * REPLICATION_SCOPE as specified in DDL.
+     * explicit column family names 3) Different BLOCKSIZE specifiers for 
different column
+     * family names. Then: 1)BLOCKSIZE is set. 2)Each explicit column family 
has the
+     * BLOCKSIZE as specified in DDL.
      */
     @Test
     public void testCreateTableColumnFamilyHBaseAttribs5() throws Exception {
@@ -314,7 +314,7 @@ public class CreateTableIT extends ParallelStatsDisabledIT {
                 "create table IF NOT EXISTS  " + tableName + "  (" + " id 
char(1) NOT NULL,"
                         + " col1 integer NOT NULL," + " b.col2 bigint," + " 
c.col3 bigint, "
                         + " CONSTRAINT NAME_PK PRIMARY KEY (id, col1)"
-                        + " ) b.REPLICATION_SCOPE=0, c.REPLICATION_SCOPE=1, 
SALT_BUCKETS = 4";
+                        + " ) b.BLOCKSIZE=50000, c.BLOCKSIZE=60000, 
SALT_BUCKETS = 4";
         Properties props = new Properties();
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.createStatement().execute(ddl);
@@ -323,9 +323,9 @@ public class CreateTableIT extends ParallelStatsDisabledIT {
                 
admin.getDescriptor(TableName.valueOf(tableName)).getColumnFamilies();
         assertEquals(2, columnFamilies.length);
         assertEquals("B", columnFamilies[0].getNameAsString());
-        assertEquals(0, columnFamilies[0].getScope());
+        assertEquals(50000, columnFamilies[0].getBlocksize());
         assertEquals("C", columnFamilies[1].getNameAsString());
-        assertEquals(1, columnFamilies[1].getScope());
+        assertEquals(60000, columnFamilies[1].getBlocksize());
     }
 
     /**
@@ -449,7 +449,7 @@ public class CreateTableIT extends ParallelStatsDisabledIT {
         try {
             conn.createStatement().execute(ddl);
         } catch (SQLException sqle) {
-            
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_TTL.getErrorCode(),
+            
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY.getErrorCode(),
                 sqle.getErrorCode());
         }
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/it/java/org/apache/phoenix/end2end/PropertiesInSyncIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PropertiesInSyncIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PropertiesInSyncIT.java
new file mode 100644
index 0000000..9569a97
--- /dev/null
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PropertiesInSyncIT.java
@@ -0,0 +1,462 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.end2end;
+
+import org.apache.hadoop.hbase.KeepDeletedCells;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
+import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
+import org.apache.hadoop.hbase.client.TableDescriptor;
+import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.util.MetaDataUtil;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static 
org.apache.phoenix.query.QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;
+import static 
org.apache.phoenix.util.MetaDataUtil.SYNCED_DATA_TABLE_AND_INDEX_PROPERTIES;
+import static org.apache.phoenix.util.MetaDataUtil.VIEW_INDEX_TABLE_PREFIX;
+import static org.apache.phoenix.util.UpgradeUtil.syncTableAndIndexProperties;
+
+/**
+ * Test properties that need to be kept in sync amongst all column families 
and indexes of a table
+ */
+public class PropertiesInSyncIT extends ParallelStatsDisabledIT {
+    private static final String COL_FAM1 = "CF1";
+    private static final String COL_FAM2 = "CF2";
+    private static final String NEW_CF = "NEW_CF";
+    private static final String DUMMY_PROP_VALUE = "dummy";
+    private static final int INITIAL_TTL_VALUE = 700;
+    private static final KeepDeletedCells INITIAL_KEEP_DELETED_CELLS_VALUE = 
KeepDeletedCells.TRUE;
+    private static final int INITIAL_REPLICATION_SCOPE_VALUE = 1;
+    private static final int MODIFIED_TTL_VALUE = INITIAL_TTL_VALUE + 300;
+    private static final KeepDeletedCells MODIFIED_KEEP_DELETED_CELLS_VALUE =
+            (INITIAL_KEEP_DELETED_CELLS_VALUE == KeepDeletedCells.TRUE) ? 
KeepDeletedCells.FALSE: KeepDeletedCells.TRUE;
+    private static final int MODIFIED_REPLICATION_SCOPE_VALUE = 
(INITIAL_REPLICATION_SCOPE_VALUE == 1) ? 0 : 1;
+
+
+    // Test that we disallow specifying synced properties to be set per column 
family when creating a table
+    @Test
+    public void testDisallowSyncedPropsToBeSetColFamSpecificCreateTable() 
throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = generateUniqueName();
+        for (String propName: SYNCED_DATA_TABLE_AND_INDEX_PROPERTIES) {
+            try {
+                conn.createStatement().execute("create table " + tableName
+                        + " (id INTEGER not null primary key, "
+                        + COL_FAM1 + ".name varchar(10), " + COL_FAM2 + ".flag 
boolean) "
+                        + COL_FAM1 + "." + propName + "=" + DUMMY_PROP_VALUE);
+                fail("Should fail with SQLException when setting synced 
property for a specific column family");
+            } catch (SQLException sqlE) {
+                assertEquals("Should fail to set synced property for a 
specific column family",
+                        
SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY.getErrorCode(), 
sqlE.getErrorCode());
+            }
+        }
+        conn.close();
+    }
+
+    // Test that all column families have the same value of synced properties 
when creating a table
+    @Test
+    public void testSyncedPropsAllColFamsCreateTable() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+        verifyHBaseColumnFamilyProperties(tableName, conn, false, false);
+        conn.close();
+    }
+
+    // Test that we disallow specifying synced properties to be set when 
creating an index on a physical table or a view
+    @Test
+    public void testDisallowSyncedPropsToBeSetCreateIndex() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+        String localIndexName = tableName + "_LOCAL_IDX";
+        String globalIndexName = tableName + "_GLOBAL_IDX";
+        String viewName = "VIEW_" + tableName;
+        conn.createStatement().execute("create view " + viewName
+                + " (new_col SMALLINT) as select * from " + tableName + " 
where id > 1");
+        for (String propName: SYNCED_DATA_TABLE_AND_INDEX_PROPERTIES) {
+            try {
+                conn.createStatement().execute("create local index " + 
localIndexName
+                        + " on " + tableName + "(name) "
+                        + propName + "=" + DUMMY_PROP_VALUE);
+                fail("Should fail with SQLException when setting synced 
property for a local index");
+            } catch (SQLException sqlE) {
+                assertEquals("Should fail to set synced property for a local 
index",
+                        
SQLExceptionCode.CANNOT_SET_OR_ALTER_PROPERTY_FOR_INDEX.getErrorCode(), 
sqlE.getErrorCode());
+            }
+            try {
+                conn.createStatement().execute("create index " + 
globalIndexName
+                        + " on " + tableName + "(flag) "
+                        + propName + "=" + DUMMY_PROP_VALUE);
+                fail("Should fail with SQLException when setting synced 
property for a global index");
+            } catch (SQLException sqlE) {
+                assertEquals("Should fail to set synced property for a global 
index",
+                        
SQLExceptionCode.CANNOT_SET_OR_ALTER_PROPERTY_FOR_INDEX.getErrorCode(), 
sqlE.getErrorCode());
+            }
+            try {
+                conn.createStatement().execute("create index view_index"
+                        + " on " + viewName + " (flag)" + propName + "=" + 
DUMMY_PROP_VALUE);
+                fail("Should fail with SQLException when setting synced 
property for a view index");
+            } catch (SQLException sqlE) {
+                assertEquals("Should fail to set synced property for a view 
index",
+                        
SQLExceptionCode.CANNOT_SET_OR_ALTER_PROPERTY_FOR_INDEX.getErrorCode(), 
sqlE.getErrorCode());
+            }
+        }
+        conn.close();
+    }
+
+    // Test that indexes have the same value of synced properties as their 
base table
+    @Test
+    public void testSyncedPropsBaseTableCreateIndex() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+        createIndexTable(conn, tableName, PTable.IndexType.LOCAL);
+        String globalIndexName = createIndexTable(conn, tableName, 
PTable.IndexType.GLOBAL);
+
+        // We pass the base table as the physical HBase table since our check 
includes checking the local index column family too
+        verifyHBaseColumnFamilyProperties(tableName, conn, false, false);
+        verifyHBaseColumnFamilyProperties(globalIndexName, conn, false, false);
+        conn.close();
+    }
+
+    // Test that the physical view index table has the same value of synced 
properties as its base table
+    @Test
+    public void testSyncedPropsBaseTableCreateViewIndex() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+        String viewIndexName = createIndexTable(conn, tableName, null);
+
+        verifyHBaseColumnFamilyProperties(tableName, conn, false, false);
+        verifyHBaseColumnFamilyProperties(viewIndexName, conn, false, false);
+        conn.close();
+    }
+
+    // Test that we disallow specifying synced properties to be set per column 
family when altering a table
+    @Test
+    public void testDisallowSyncedPropsToBeSetColFamSpecificAlterTable() 
throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+        StringBuilder alterAllSyncedPropsString = new StringBuilder();
+        String modPropString = COL_FAM1 + ".%s=" + DUMMY_PROP_VALUE + ",";
+        for (String propName: SYNCED_DATA_TABLE_AND_INDEX_PROPERTIES) {
+            try {
+                conn.createStatement().execute("alter table " + tableName
+                        + " set " + COL_FAM1 + "." + propName + "=" + 
DUMMY_PROP_VALUE);
+                fail("Should fail with SQLException when altering synced 
property for a specific column family");
+            } catch (SQLException sqlE) {
+                assertEquals("Should fail to alter synced property for a 
specific column family",
+                        
SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY.getErrorCode(), 
sqlE.getErrorCode());
+            }
+            alterAllSyncedPropsString.append(String.format(modPropString, 
propName));
+        }
+
+        // Test the same when we try to set all of these properties at once
+        try {
+            conn.createStatement().execute("alter table " + tableName + " set "
+                    + alterAllSyncedPropsString.substring(0, 
alterAllSyncedPropsString.length() - 1));
+            fail("Should fail with SQLException when altering synced 
properties for a specific column family");
+        } catch (SQLException sqlE) {
+            assertEquals("Should fail to alter synced properties for a 
specific column family",
+                    
SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY.getErrorCode(), 
sqlE.getErrorCode());
+        }
+        conn.close();
+    }
+
+    // Test that any alteration of the synced properties gets propagated to 
all indexes and the physical view index table
+    @Test
+    public void testAlterSyncedPropsPropagateToAllIndexesAndViewIndex() throws 
Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+        Set<String> tablesToCheck = new HashSet<>();
+        tablesToCheck.add(tableName);
+        for (int i=0; i<2; i++) {
+            tablesToCheck.add(createIndexTable(conn, tableName, 
PTable.IndexType.LOCAL));
+            tablesToCheck.add(createIndexTable(conn, tableName, 
PTable.IndexType.GLOBAL));
+        }
+        // Create a view and view index
+        tablesToCheck.add(createIndexTable(conn, tableName, null));
+
+        // Now alter the base table's properties. This should get propagated 
to all index tables
+        conn.createStatement().execute("alter table " + tableName + " set 
TTL=" + MODIFIED_TTL_VALUE
+                + ",KEEP_DELETED_CELLS=" + MODIFIED_KEEP_DELETED_CELLS_VALUE
+                + ",REPLICATION_SCOPE=" + MODIFIED_REPLICATION_SCOPE_VALUE);
+
+        for (String table: tablesToCheck) {
+            verifyHBaseColumnFamilyProperties(table, conn, true, false);
+        }
+
+        // Any indexes created henceforth should have the modified properties
+        String newGlobalIndex = createIndexTable(conn, tableName, 
PTable.IndexType.GLOBAL);
+        String newViewIndex = createIndexTable(conn, tableName, null);
+        verifyHBaseColumnFamilyProperties(newGlobalIndex, conn, true, false);
+        verifyHBaseColumnFamilyProperties(newViewIndex, conn, true, false);
+        conn.close();
+    }
+
+    // Test that any if we add a column family to a base table, it gets the 
synced properties
+    @Test
+    public void testAlterTableAddColumnFamilyGetsSyncedProps() throws 
Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+
+        // Test that we are not allowed to set any property to be kept in 
sync, specific to the new column family to be added
+        for (String propName: SYNCED_DATA_TABLE_AND_INDEX_PROPERTIES) {
+            try {
+                conn.createStatement().execute(
+                        "alter table " + tableName + " add " + NEW_CF + 
".new_column varchar(2) "
+                                + NEW_CF + "." + propName + "=" + 
DUMMY_PROP_VALUE);
+                fail("Should fail with SQLException when altering synced 
property for a specific column family when adding a column");
+            } catch (SQLException sqlE) {
+                assertEquals("Should fail to alter synced property for a 
specific column family when adding a column",
+                        
SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY.getErrorCode(), 
sqlE.getErrorCode());
+            }
+        }
+
+        // Test that when we add a new column (belonging to a new column 
family) and set any property that should be
+        // in sync, then the property is modified for all existing column 
families of the base table and its indexes
+        Set<String> tablesToCheck = new HashSet<>();
+        tablesToCheck.add(tableName);
+        for (int i=0; i<2; i++) {
+            tablesToCheck.add(createIndexTable(conn, tableName, 
PTable.IndexType.LOCAL));
+            tablesToCheck.add(createIndexTable(conn, tableName, 
PTable.IndexType.GLOBAL));
+        }
+        // Create a view and view index
+        tablesToCheck.add(createIndexTable(conn, tableName, null));
+
+        // Now add a new column family while simultaneously modifying 
properties to be kept in sync,
+        // as well as a property which does not need to be kept in sync. 
Properties to be kept in sync
+        // should get propagated to all index tables and already existing 
column families
+        conn.createStatement().execute(
+                "alter table " + tableName + " add " + NEW_CF + ".new_column 
varchar(2) "
+                + "KEEP_DELETED_CELLS=" + MODIFIED_KEEP_DELETED_CELLS_VALUE
+                + ",REPLICATION_SCOPE=" + MODIFIED_REPLICATION_SCOPE_VALUE
+                + ",BLOCKSIZE=300000");
+
+        for (String table: tablesToCheck) {
+            verifyHBaseColumnFamilyProperties(table, conn, true, true);
+        }
+        try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+            ColumnFamilyDescriptor[] columnFamilies = 
admin.getDescriptor(TableName.valueOf(tableName))
+                    .getColumnFamilies();
+            for (ColumnFamilyDescriptor cfd: columnFamilies) {
+                if (cfd.getNameAsString().equals(NEW_CF)) {
+                    assertEquals("Newly added column fmaily should have 
updated property",
+                            300000, cfd.getBlocksize());
+                } else {
+                    assertEquals("Existing column families should have default 
value for property",
+                            ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
cfd.getBlocksize());
+                }
+            }
+        }
+        conn.close();
+    }
+
+    // Test that we disallow altering a synced property for a global index 
table
+    @Test
+    public void testDisallowAlterGlobalIndexTable() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+        String tableName = createBaseTableWithProps(conn);
+        String globalIndexName = createIndexTable(conn, tableName, 
PTable.IndexType.GLOBAL);
+        for (String propName: SYNCED_DATA_TABLE_AND_INDEX_PROPERTIES) {
+            try {
+                conn.createStatement().execute("alter table " + 
globalIndexName + " set "
+                + propName + "=" + DUMMY_PROP_VALUE);
+                fail("Should fail with SQLException when altering synced 
property for a global index");
+            } catch (SQLException sqlE) {
+                assertEquals("Should fail to alter synced property for a 
global index",
+                        
SQLExceptionCode.CANNOT_SET_OR_ALTER_PROPERTY_FOR_INDEX.getErrorCode(), 
sqlE.getErrorCode());
+            }
+        }
+        conn.close();
+    }
+
+    // Test the upgrade code path for old client to new phoenix server cases 
in which the client
+    // may have tables which have column families and indexes whose properties 
are out of sync
+    @Test
+    public void testOldClientSyncPropsUpgradePath() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl(), new 
Properties());
+
+        String baseTableName = createBaseTableWithProps(conn);
+        String baseTableName1 = createBaseTableWithProps(conn);
+        Set<String> createdTables = new HashSet<>();
+        createdTables.add(baseTableName);
+        createdTables.add(baseTableName1);
+        // Create different indexes on the base table
+        for (int i=0; i<2; i++) {
+            createdTables.add(createIndexTable(conn, baseTableName, 
PTable.IndexType.GLOBAL));
+            createdTables.add(createIndexTable(conn, baseTableName, 
PTable.IndexType.LOCAL));
+            createdTables.add(createIndexTable(conn, baseTableName, null));
+            createdTables.add(createIndexTable(conn, baseTableName1, 
PTable.IndexType.GLOBAL));
+            createdTables.add(createIndexTable(conn, baseTableName1, 
PTable.IndexType.LOCAL));
+            createdTables.add(createIndexTable(conn, baseTableName1, null));
+        }
+        for (String t: createdTables) {
+            verifyHBaseColumnFamilyProperties(t, conn, false, false);
+        }
+
+        try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+            for (String tableName: createdTables) {
+                final TableDescriptor tableDescriptor;
+                final ColumnFamilyDescriptor defaultCF;
+                if (MetaDataUtil.isViewIndex(tableName)) {
+                    // We won't be able to get the PTable for a view index 
table
+                    tableDescriptor = 
conn.unwrap(PhoenixConnection.class).getQueryServices()
+                            .getTableDescriptor(Bytes.toBytes(tableName));
+                    defaultCF = 
tableDescriptor.getColumnFamily(DEFAULT_COLUMN_FAMILY_BYTES);
+                } else {
+                    PTable table = PhoenixRuntime.getTable(conn, tableName);
+                    tableDescriptor = 
conn.unwrap(PhoenixConnection.class).getQueryServices()
+                            
.getTableDescriptor(table.getPhysicalName().getBytes());
+                    defaultCF = 
tableDescriptor.getColumnFamily(SchemaUtil.getEmptyColumnFamily(table));
+                }
+
+                TableDescriptorBuilder tableDescBuilder = 
TableDescriptorBuilder.newBuilder(tableDescriptor);
+                if (tableName.equals(baseTableName) || 
tableName.equals(baseTableName1)) {
+                    for (ColumnFamilyDescriptor cfd: 
tableDescriptor.getColumnFamilies()) {
+                        // Modify all column families except the default 
column family for the base tables
+                        if (!cfd.equals(defaultCF)) {
+                            ColumnFamilyDescriptorBuilder cfdb = 
ColumnFamilyDescriptorBuilder.newBuilder(cfd);
+                            modifySyncedPropsForCF(cfdb);
+                            tableDescBuilder.modifyColumnFamily(cfdb.build());
+                        }
+                    }
+                } else {
+                    for (ColumnFamilyDescriptor cfd: 
tableDescriptor.getColumnFamilies()) {
+                        // Modify all column families for other tables
+                        ColumnFamilyDescriptorBuilder cfdb = 
ColumnFamilyDescriptorBuilder.newBuilder(cfd);
+                        modifySyncedPropsForCF(cfdb);
+                        tableDescBuilder.modifyColumnFamily(cfdb.build());
+                    }
+                }
+                admin.modifyTable(tableDescBuilder.build());
+            }
+        }
+        // Now synchronize required properties and verify HBase metadata 
property values
+        syncTableAndIndexProperties(conn.unwrap(PhoenixConnection.class),
+                
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin());
+        for (String t: createdTables) {
+            verifyHBaseColumnFamilyProperties(t, conn, false, false);
+        }
+        conn.close();
+    }
+
+    /**
+     * Helper method to modify the synced properties for a column family 
descriptor
+     * @param cfdb The column family descriptor builder object
+     * @throws SQLException
+     */
+    private void modifySyncedPropsForCF(ColumnFamilyDescriptorBuilder cfdb) 
throws SQLException {
+        cfdb.setTimeToLive(MODIFIED_TTL_VALUE);
+        cfdb.setKeepDeletedCells(MODIFIED_KEEP_DELETED_CELLS_VALUE);
+        cfdb.setScope(MODIFIED_REPLICATION_SCOPE_VALUE);
+    }
+
+    /**
+     * Helper method to create or alter a base table with specific values set 
for properties to be kept in sync
+     * @param conn Phoenix connection
+     * @return Name of the HBase table created
+     * @throws SQLException
+     */
+    private String createBaseTableWithProps(Connection conn) throws 
SQLException {
+        String tableName = generateUniqueName();
+        conn.createStatement().execute("create table " + tableName
+                + " (id INTEGER not null primary key, type varchar(5), "
+                + COL_FAM1 + ".name varchar(10), " + COL_FAM2 + ".flag 
boolean) "
+                + "TTL=" + INITIAL_TTL_VALUE + ",KEEP_DELETED_CELLS=" + 
INITIAL_KEEP_DELETED_CELLS_VALUE
+                + ",REPLICATION_SCOPE=" + INITIAL_REPLICATION_SCOPE_VALUE);
+        return tableName;
+    }
+
+    /**
+     * Helper method to create an index table on a base table.
+     * @param conn Phoenix connection
+     * @param baseTableName Name of the HBase base table on which to create an 
index
+     * @param indexType LOCAL, GLOBAL or if we pass in null as the indexType,
+     *                 we create a view and an index on that view for the 
given base table
+     * @return The physical HBase table corresponding to the index created
+     * @throws SQLException
+     */
+    private String createIndexTable(Connection conn, String baseTableName, 
PTable.IndexType indexType) throws SQLException {
+        // Create a view on top of the base table and then an index on that 
view
+        if (indexType == null) {
+            String viewName = "VIEW_" + baseTableName + "_" + 
generateUniqueName();
+            String viewIndexName = VIEW_INDEX_TABLE_PREFIX + baseTableName;
+            conn.createStatement().execute("create view " + viewName
+                    + " (new_col SMALLINT) as select * from " + baseTableName 
+ " where id > 1");
+            conn.createStatement().execute("create index view_index_" + 
generateUniqueName()
+                    + " on " + viewName + " (flag)");
+            return viewIndexName;
+        }
+        switch(indexType) {
+        case LOCAL:
+            String localIndexName = baseTableName + "_LOCAL_" + 
generateUniqueName();
+            conn.createStatement().execute(
+                    "create local index " + localIndexName + " on " + 
baseTableName + "(flag)");
+            return baseTableName;
+        case GLOBAL:
+            String globalIndexName = baseTableName + "_GLOBAL_" + 
generateUniqueName();
+            conn.createStatement()
+                    .execute("create index " + globalIndexName + " on " + 
baseTableName + "(name)");
+            return globalIndexName;
+        }
+        return baseTableName;
+    }
+
+    /**
+     * Helper method to verify HBase column family properties
+     * @param tableName Physical HBase table whose properties are to be 
verified
+     * @param conn Phoenix connection
+     * @param propModified true if we have altered any of the properties to be 
kept in sync, false otherwise
+     * @param ignoreTTL We cannot modfiy a table level property when adding a 
column, so in those cases,
+     *                 ignore the check for TTL modification
+     * @throws Exception
+     */
+    private void verifyHBaseColumnFamilyProperties(String tableName, 
Connection conn, boolean propModified,
+            boolean ignoreTTL) throws Exception {
+        final int expectedTTL = propModified ? 
MODIFIED_TTL_VALUE:INITIAL_TTL_VALUE;
+        final KeepDeletedCells expectedKeepDeletedCells = propModified ? 
MODIFIED_KEEP_DELETED_CELLS_VALUE: INITIAL_KEEP_DELETED_CELLS_VALUE;
+        final int expectedReplicationScope = propModified ? 
MODIFIED_REPLICATION_SCOPE_VALUE:INITIAL_REPLICATION_SCOPE_VALUE;
+
+        try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+            // Note that this includes the local index column family as well
+            ColumnFamilyDescriptor[] columnFamilies = 
admin.getDescriptor(TableName.valueOf(tableName))
+                    .getColumnFamilies();
+            for (ColumnFamilyDescriptor cfd: columnFamilies) {
+                if (!ignoreTTL) {
+                    assertEquals("Mismatch in TTL", expectedTTL, 
cfd.getTimeToLive());
+                }
+                assertEquals("Mismatch in KEEP_DELETED_CELLS", 
expectedKeepDeletedCells, cfd.getKeepDeletedCells());
+                assertEquals("Mismatch in REPLICATION_SCOPE", 
expectedReplicationScope, cfd.getScope());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
index 6e446d0..0d24233 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
@@ -765,24 +765,27 @@ public class QueryDatabaseMetaDataIT extends 
ParallelStatsDisabledIT {
             }
             admin.createTable(builder.build());
             createMDTestTable(pconn, tableName,
-                "a." + ColumnFamilyDescriptorBuilder.KEEP_DELETED_CELLS + "=" 
+ Boolean.TRUE);
+                "a." + ColumnFamilyDescriptorBuilder.BLOCKSIZE+ "=" + 50000);
 
             TableDescriptor descriptor = 
admin.getDescriptor(TableName.valueOf(htableName));
             assertEquals(3, descriptor.getColumnFamilies().length);
             ColumnFamilyDescriptor cdA = descriptor.getColumnFamily(cfA);
-            
assertNotEquals(ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED, 
cdA.getKeepDeletedCells());
+            assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED, 
cdA.getKeepDeletedCells());
+            assertNotEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
cdA.getBlocksize());
             assertEquals(DataBlockEncoding.NONE, cdA.getDataBlockEncoding()); 
// Overriden using
                                                                               
// WITH
             assertEquals(1, cdA.getMaxVersions());// Overriden using WITH
             ColumnFamilyDescriptor cdB = descriptor.getColumnFamily(cfB);
             // Allow KEEP_DELETED_CELLS to be false for VIEW
             assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED, 
cdB.getKeepDeletedCells());
+            assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
cdB.getBlocksize());
             assertEquals(DataBlockEncoding.NONE, cdB.getDataBlockEncoding()); 
// Should keep the
                                                                               
// original value.
             // CF c should stay the same since it's not a Phoenix cf.
             ColumnFamilyDescriptor cdC = descriptor.getColumnFamily(cfC);
             assertNotNull("Column family not found", cdC);
             assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_KEEP_DELETED, 
cdC.getKeepDeletedCells());
+            assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
cdC.getBlocksize());
             assertFalse(SchemaUtil.DEFAULT_DATA_BLOCK_ENCODING == 
cdC.getDataBlockEncoding());
             
assertTrue(descriptor.hasCoprocessor(UngroupedAggregateRegionObserver.class.getName()));
             
assertTrue(descriptor.hasCoprocessor(GroupedAggregateRegionObserver.class.getName()));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java
index fc8c474..8d60676 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java
@@ -166,7 +166,8 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
         assertImmutableRows(conn, dataTableFullName, true);
         ddl = "ALTER TABLE " + dataTableFullName + " SET COMPACTION_ENABLED = 
FALSE, VERSIONS = 10";
         conn.createStatement().execute(ddl);
-        ddl = "ALTER TABLE " + dataTableFullName + " SET COMPACTION_ENABLED = 
FALSE, CF1.MIN_VERSIONS = 1, CF2.MIN_VERSIONS = 3, MIN_VERSIONS = 8, 
CF1.KEEP_DELETED_CELLS = true, KEEP_DELETED_CELLS = false";
+        ddl = "ALTER TABLE " + dataTableFullName + " SET COMPACTION_ENABLED = 
FALSE, CF1.MIN_VERSIONS = 1, CF2.MIN_VERSIONS = 3, " +
+                "MIN_VERSIONS = 8, CF1.BLOCKSIZE = 50000, KEEP_DELETED_CELLS = 
false";
         conn.createStatement().execute(ddl);
 
         try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
@@ -177,16 +178,19 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
             assertEquals("0", columnFamilies[0].getNameAsString());
             assertEquals(8, columnFamilies[0].getMinVersions());
             assertEquals(10, columnFamilies[0].getMaxVersions());
+            assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
columnFamilies[0].getBlocksize());
             assertEquals(KeepDeletedCells.FALSE, 
columnFamilies[0].getKeepDeletedCells());
 
             assertEquals("CF1", columnFamilies[1].getNameAsString());
             assertEquals(1, columnFamilies[1].getMinVersions());
             assertEquals(10, columnFamilies[1].getMaxVersions());
-            assertEquals(KeepDeletedCells.TRUE, 
columnFamilies[1].getKeepDeletedCells());
+            assertEquals(50000, columnFamilies[1].getBlocksize());
+            assertEquals(KeepDeletedCells.FALSE, 
columnFamilies[1].getKeepDeletedCells());
 
             assertEquals("CF2", columnFamilies[2].getNameAsString());
             assertEquals(3, columnFamilies[2].getMinVersions());
             assertEquals(10, columnFamilies[2].getMaxVersions());
+            assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
columnFamilies[2].getBlocksize());
             assertEquals(KeepDeletedCells.FALSE, 
columnFamilies[2].getKeepDeletedCells());
 
             assertEquals(Boolean.toString(false), 
tableDesc.getValue(TableDescriptorBuilder.COMPACTION_ENABLED));
@@ -252,7 +256,7 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
             conn1.createStatement().execute(ddl);
             fail();
         } catch (SQLException e) {
-            
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_TTL.getErrorCode(), 
e.getErrorCode());
+            
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY.getErrorCode(),
 e.getErrorCode());
         }
     }
 
@@ -268,7 +272,7 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
                 +"CONSTRAINT PK PRIMARY KEY (ID1, ID2)) " + 
generateDDLOptions("SALT_BUCKETS = 8");
         Connection conn1 = DriverManager.getConnection(getUrl(), props);
         conn1.createStatement().execute(ddl);
-        ddl = "ALTER TABLE " + dataTableFullName + " SET CF.REPLICATION_SCOPE 
= 1";
+        ddl = "ALTER TABLE " + dataTableFullName + " SET CF.BLOCKSIZE = 50000";
         try {
             conn1.createStatement().execute(ddl);
             fail();
@@ -385,7 +389,7 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
         conn.createStatement().execute(ddl);
         assertImmutableRows(conn, dataTableFullName, true);
         ddl = "ALTER TABLE  " + dataTableFullName
-                + " SET COMPACTION_ENABLED = FALSE, CF.REPLICATION_SCOPE=1, 
IMMUTABLE_ROWS = TRUE, TTL=1000";
+                + " SET COMPACTION_ENABLED = FALSE, CF.BLOCKSIZE=50000, 
IMMUTABLE_ROWS = TRUE, TTL=1000";
         conn.createStatement().execute(ddl);
         assertImmutableRows(conn, dataTableFullName, true);
         try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
@@ -393,11 +397,13 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
             ColumnFamilyDescriptor[] columnFamilies = 
tableDesc.getColumnFamilies();
             assertEquals(2, columnFamilies.length);
             assertEquals("CF", columnFamilies[0].getNameAsString());
-            assertEquals(1, columnFamilies[0].getScope());
+            
assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_REPLICATION_SCOPE, 
columnFamilies[0].getScope());
             assertEquals(1000, columnFamilies[0].getTimeToLive());
+            assertEquals(50000, columnFamilies[0].getBlocksize());
             assertEquals("XYZ", columnFamilies[1].getNameAsString());
             
assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_REPLICATION_SCOPE, 
columnFamilies[1].getScope());
             assertEquals(1000, columnFamilies[1].getTimeToLive());
+            assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
columnFamilies[1].getBlocksize());
             assertEquals(Boolean.toString(false), 
tableDesc.getValue(TableDescriptorBuilder.COMPACTION_ENABLED));
         }
     }
@@ -447,20 +453,20 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
                     .execute(
                             "ALTER TABLE "
                                     + dataTableFullName
-                                    + " ADD col4 integer, CF1.col5 integer, 
CF2.col6 integer IN_MEMORY=true, CF1.REPLICATION_SCOPE=1, CF2.IN_MEMORY=false 
");
+                                    + " ADD col4 integer, CF1.col5 integer, 
CF2.col6 integer IN_MEMORY=true, REPLICATION_SCOPE=1, CF2.IN_MEMORY=false ");
             try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
                 ColumnFamilyDescriptor[] columnFamilies = 
admin.getDescriptor(TableName.valueOf(dataTableFullName))
                         .getColumnFamilies();
                 assertEquals(3, columnFamilies.length);
                 assertEquals("0", columnFamilies[0].getNameAsString());
                 assertTrue(columnFamilies[0].isInMemory());
-                assertEquals(0, columnFamilies[0].getScope());
+                assertEquals(1, columnFamilies[0].getScope());
                 assertEquals("CF1", columnFamilies[1].getNameAsString());
                 assertTrue(columnFamilies[1].isInMemory());
                 assertEquals(1, columnFamilies[1].getScope());
                 assertEquals("CF2", columnFamilies[2].getNameAsString());
                 assertFalse(columnFamilies[2].isInMemory());
-                assertEquals(0, columnFamilies[2].getScope());
+                assertEquals(1, columnFamilies[2].getScope());
             }
         } finally {
             conn.close();
@@ -481,7 +487,8 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
                     .execute(
                             "ALTER TABLE "
                                     + dataTableFullName
-                                    + " ADD col4 integer, CF1.col5 integer, 
CF2.col6 integer IN_MEMORY=true, CF1.REPLICATION_SCOPE=1, CF2.IN_MEMORY=false, 
XYZ.REPLICATION_SCOPE=1 ");
+                                    + " ADD col4 integer, CF1.col5 integer, 
CF2.col6 integer IN_MEMORY=true, CF1.BLOCKSIZE=50000, "
+                                    + "CF2.IN_MEMORY=false, 
REPLICATION_SCOPE=1 ");
             try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
                 ColumnFamilyDescriptor[] columnFamilies = 
admin.getDescriptor(TableName.valueOf(dataTableFullName))
                         .getColumnFamilies();
@@ -489,9 +496,10 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
                 assertEquals("CF1", columnFamilies[0].getNameAsString());
                 assertTrue(columnFamilies[0].isInMemory());
                 assertEquals(1, columnFamilies[0].getScope());
+                assertEquals(50000, columnFamilies[0].getBlocksize());
                 assertEquals("CF2", columnFamilies[1].getNameAsString());
                 assertFalse(columnFamilies[1].isInMemory());
-                assertEquals(0, columnFamilies[1].getScope());
+                assertEquals(1, columnFamilies[1].getScope());
                 assertEquals("XYZ", columnFamilies[2].getNameAsString());
                 assertTrue(columnFamilies[2].isInMemory());
                 assertEquals(1, columnFamilies[2].getScope());
@@ -514,7 +522,7 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
             try {
                 conn.createStatement().execute(
                         "ALTER TABLE " + dataTableFullName
-                                + " ADD col4 integer CF1.REPLICATION_SCOPE=1, 
XYZ.IN_MEMORY=true ");
+                                + " ADD col4 integer CF1.BLOCKSIZE=50000, 
XYZ.IN_MEMORY=true ");
                 fail();
             } catch(SQLException e) {
                 
assertEquals(SQLExceptionCode.CANNOT_SET_PROPERTY_FOR_COLUMN_NOT_ADDED.getErrorCode(),
 e.getErrorCode());
@@ -538,14 +546,15 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
                     .execute(
                             "ALTER TABLE "
                                     + dataTableFullName
-                                    + " ADD col4 integer, CF1.col5 integer, 
CF2.col6 integer, CF3.col7 integer CF1.REPLICATION_SCOPE=1, 
CF1.IN_MEMORY=false, IN_MEMORY=true ");
+                                    + " ADD col4 integer, CF1.col5 integer, 
CF2.col6 integer, CF3.col7 integer CF1.BLOCKSIZE=50000, CF1.IN_MEMORY=false, 
IN_MEMORY=true ");
             try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
                 ColumnFamilyDescriptor[] columnFamilies = 
admin.getDescriptor(TableName.valueOf(dataTableFullName))
                         .getColumnFamilies();
                 assertEquals(4, columnFamilies.length);
                 assertEquals("CF1", columnFamilies[0].getNameAsString());
                 assertFalse(columnFamilies[0].isInMemory());
-                assertEquals(1, columnFamilies[0].getScope());
+                assertEquals(0, columnFamilies[0].getScope());
+                assertEquals(50000, columnFamilies[0].getBlocksize());
                 assertEquals("CF2", columnFamilies[1].getNameAsString());
                 assertTrue(columnFamilies[1].isInMemory());
                 assertEquals(0, columnFamilies[1].getScope());
@@ -572,7 +581,7 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
         try {
             conn.createStatement().execute(ddl);
             conn.createStatement().execute(
-                    "ALTER TABLE " + dataTableFullName + " ADD col4 integer 
XYZ.REPLICATION_SCOPE=1 ");
+                    "ALTER TABLE " + dataTableFullName + " ADD col4 integer 
REPLICATION_SCOPE=1, XYZ.BLOCKSIZE=50000");
             conn.createStatement()
                     .execute("ALTER TABLE " + dataTableFullName + " ADD 
XYZ.col5 integer IN_MEMORY=true ");
             try (Admin admin = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
@@ -581,10 +590,12 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
                 assertEquals(2, columnFamilies.length);
                 assertEquals("CF1", columnFamilies[0].getNameAsString());
                 assertFalse(columnFamilies[0].isInMemory());
-                assertEquals(0, columnFamilies[0].getScope());
+                assertEquals(1, columnFamilies[0].getScope());
+                assertEquals(ColumnFamilyDescriptorBuilder.DEFAULT_BLOCKSIZE, 
columnFamilies[0].getBlocksize());
                 assertEquals("XYZ", columnFamilies[1].getNameAsString());
                 assertTrue(columnFamilies[1].isInMemory());
                 assertEquals(1, columnFamilies[1].getScope());
+                assertEquals(50000, columnFamilies[1].getBlocksize());
             }
         } finally {
             conn.close();
@@ -729,7 +740,7 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
             conn.createStatement().execute(ddl);
             fail();
         } catch (SQLException e) {
-            
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_TTL.getErrorCode(), 
e.getErrorCode());
+            
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY.getErrorCode(),
 e.getErrorCode());
         } finally {
             conn.close();
         }
@@ -924,7 +935,7 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
                 assertEquals(1000, columnFamilies[0].getTimeToLive());
                 assertEquals("XYZ", columnFamilies[1].getNameAsString());
                 assertEquals(false, columnFamilies[1].isInMemory());
-                assertEquals(86400, columnFamilies[1].getTimeToLive());
+                assertEquals(1000, columnFamilies[1].getTimeToLive());
             }
 
             // the new column will be assigned to the column family XYZ. With 
the a KV column getting added for XYZ,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
index 00a6e2f..0c28006 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
@@ -328,8 +328,8 @@ public class TransactionIT  extends ParallelStatsDisabledIT 
{
 
         Connection conn = DriverManager.getConnection(getUrl());
         conn.createStatement().execute("CREATE TABLE " + nonTxTableName + "1(k 
INTEGER PRIMARY KEY, a.v VARCHAR, b.v VARCHAR, c.v VARCHAR) TTL=1000");
-        conn.createStatement().execute("CREATE INDEX " + idx1 + " ON " + 
nonTxTableName + "1(a.v, b.v) TTL=1000");
-        conn.createStatement().execute("CREATE INDEX " + idx2 + " ON " + 
nonTxTableName + "1(c.v) INCLUDE (a.v, b.v) TTL=1000");
+        conn.createStatement().execute("CREATE INDEX " + idx1 + " ON " + 
nonTxTableName + "1(a.v, b.v)");
+        conn.createStatement().execute("CREATE INDEX " + idx2 + " ON " + 
nonTxTableName + "1(c.v) INCLUDE (a.v, b.v)");
 
         try {
             conn.createStatement().execute("ALTER TABLE " + nonTxTableName + 
"1 SET TRANSACTIONAL=true," + tableDDLOptions);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/86fe2fc5/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java 
b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index c0a81ec..8cb9247 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -260,7 +260,9 @@ public enum SQLExceptionCode {
     TOO_MANY_INDEXES(1047, "43A04", "Too many indexes have already been 
created on the physical table."),
     NO_LOCAL_INDEX_ON_TABLE_WITH_IMMUTABLE_ROWS(1048,"43A05","Local indexes 
aren't allowed on tables with immutable rows."),
     COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY(1049, "43A06", "Column family not 
allowed for table properties."),
-    COLUMN_FAMILY_NOT_ALLOWED_FOR_TTL(1050, "43A07", "Setting TTL for a column 
family not supported. You can only have TTL for the entire table."),
+    COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY(1050, "43A07", "Setting  or 
altering any of the following properties: "
+            + MetaDataUtil.SYNCED_DATA_TABLE_AND_INDEX_PROPERTIES.toString()
+            + " for a column family is not supported since they must be kept 
in sync. You can only set these properties for the entire table."),
     CANNOT_ALTER_PROPERTY(1051, "43A08", "Property can be specified or changed 
only when creating a table."),
     CANNOT_SET_PROPERTY_FOR_COLUMN_NOT_ADDED(1052, "43A09", "Property cannot 
be specified for a column family that is not being added or modified."),
     CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN(1053, "43A10", "Table level property 
cannot be set when adding a column."),
@@ -297,12 +299,13 @@ public enum SQLExceptionCode {
     UNKNOWN_TRANSACTION_PROVIDER(1089,"44A20", "Unknown TRANSACTION_PROVIDER: 
"),
     CANNOT_START_TXN_IF_TXN_DISABLED(1091, "44A22", "Cannot start transaction 
if transactions are disabled."),
     CANNOT_MIX_TXN_PROVIDERS(1092, "44A23", "Cannot mix transaction providers: 
"),
-    CANNOT_ALTER_TABLE_FROM_NON_TXN_TO_TXNL(1093, "44A24", "Cannot alter table 
from non transactional to transactional for"),
+    CANNOT_ALTER_TABLE_FROM_NON_TXN_TO_TXNL(1093, "44A24", "Cannot alter table 
from non transactional to transactional for "),
     UNSUPPORTED_COLUMN_ENCODING_FOR_TXN_PROVIDER(1094, "44A25", "Column 
encoding is not supported for"),
     UNSUPPORTED_STORAGE_FORMAT_FOR_TXN_PROVIDER(1095, "44A26", "Only 
ONE_CELL_PER_COLUMN storage scheme is supported for"),
     CANNOT_SWITCH_TXN_PROVIDERS(1096, "44A27", "Cannot switch transaction 
providers."),
     TTL_UNSUPPORTED_FOR_TXN_TABLE(10947, "44A28", "TTL is not supported for"),
     CANNOT_CREATE_LOCAL_INDEX_FOR_TXN_TABLE(10948, "44A29", "Local indexes 
cannot be created for"),
+    CANNOT_SET_OR_ALTER_PROPERTY_FOR_INDEX(10949, "44A30", "Cannot set or 
alter the following properties on an index: "
 
     /** Sequence related */
     SEQUENCE_ALREADY_EXIST(1200, "42Z00", "Sequence already exists.", new 
Factory() {

Reply via email to