PHOENIX-3522 Altering the mutability of a parent table does not propagate to 
the child views


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

Branch: refs/heads/encodecolumns2
Commit: 1704545b438bed47fa626c355a19f69d180883c6
Parents: af202f2
Author: Thomas D'Silva <tdsi...@salesforce.com>
Authored: Wed Dec 7 23:59:11 2016 -0800
Committer: Thomas D'Silva <tdsi...@salesforce.com>
Committed: Wed Dec 7 23:59:11 2016 -0800

----------------------------------------------------------------------
 .../phoenix/end2end/AlterTableWithViewsIT.java  | 40 +++++++++++++++++
 .../coprocessor/MetaDataEndpointImpl.java       | 47 +++++++++++++++++---
 .../apache/phoenix/schema/TableProperty.java    | 12 +++++
 3 files changed, 94 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/1704545b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
index e6bf2d2..6e4f5c0 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
@@ -42,6 +42,7 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
+import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.junit.Test;
@@ -97,6 +98,45 @@ public class AlterTableWithViewsIT extends 
ParallelStatsDisabledIT {
     }
     
     @Test
+    public void testAlterPropertiesOfParentTable() throws Exception {
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? 
DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {       
+            String tableName = generateUniqueName();
+            String viewOfTable = tableName + "_VIEW";
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS " + tableName + " ("
+                            + " %s ID char(1) NOT NULL,"
+                            + " COL1 integer NOT NULL,"
+                            + " COL2 bigint NOT NULL,"
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, 
COL2)"
+                            + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
+            viewConn.createStatement().execute("CREATE VIEW " + viewOfTable + 
" ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM " + 
tableName);
+            
+            PhoenixConnection phoenixConn = 
conn.unwrap(PhoenixConnection.class);
+            PTable table = phoenixConn.getTable(new PTableKey(null, 
tableName));
+            PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : 
null;
+            assertFalse(table.isImmutableRows());
+            assertEquals(0, table.getUpdateCacheFrequency());
+            PTable viewTable = 
viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, 
viewOfTable));
+            assertFalse(viewTable.isImmutableRows());
+            assertEquals(0, viewTable.getUpdateCacheFrequency());
+            
+            conn.createStatement().execute("ALTER TABLE " + tableName + " SET 
IMMUTABLE_ROWS=true, UPDATE_CACHE_FREQUENCY=123");
+            // query the view to force the table cache to be updated
+            viewConn.createStatement().execute("SELECT * FROM "+viewOfTable);
+            
+            phoenixConn = conn.unwrap(PhoenixConnection.class);
+            table = phoenixConn.getTable(new PTableKey(null, tableName));
+            assertTrue(table.isImmutableRows());
+            assertEquals(123, table.getUpdateCacheFrequency());
+            
+            viewTable = viewConn.unwrap(PhoenixConnection.class).getTable(new 
PTableKey(tenantId, viewOfTable));
+            assertTrue(viewTable.isImmutableRows());
+            assertEquals(123, viewTable.getUpdateCacheFrequency());
+        } 
+    }
+    
+    @Test
     public void testDropColumnsFromBaseTableWithView() throws Exception {
         try (Connection conn = DriverManager.getConnection(getUrl());
                 Connection viewConn = isMultiTenant ? 
DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/1704545b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 9a7b9e3..9ade0f5 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -78,7 +78,6 @@ import static 
org.apache.phoenix.util.SchemaUtil.getVarCharLength;
 import static org.apache.phoenix.util.SchemaUtil.getVarChars;
 
 import java.io.IOException;
-import java.sql.DriverManager;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -150,7 +149,6 @@ import 
org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionRequest
 import 
org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionResponse;
 import 
org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataResponse;
 import 
org.apache.phoenix.coprocessor.generated.MetaDataProtos.UpdateIndexStateRequest;
-import org.apache.phoenix.expression.ColumnExpression;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.KeyValueColumnExpression;
 import org.apache.phoenix.expression.LiteralExpression;
@@ -201,6 +199,7 @@ import org.apache.phoenix.schema.SequenceKey;
 import org.apache.phoenix.schema.SequenceNotFoundException;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.schema.TableProperty;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.tuple.ResultTuple;
 import org.apache.phoenix.schema.types.PBinary;
@@ -2151,20 +2150,39 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
         return false;
     }
     
-    private MetaDataMutationResult addColumnsToChildViews(PTable 
basePhysicalTable, List<Mutation> tableMetadata, List<Mutation> 
mutationsForAddingColumnsToViews, byte[] schemaName, byte[] tableName,
+    private MetaDataMutationResult 
addColumnsAndTablePropertiesToChildViews(PTable basePhysicalTable, 
List<Mutation> tableMetadata, List<Mutation> mutationsForAddingColumnsToViews, 
byte[] schemaName, byte[] tableName,
             List<ImmutableBytesPtr> invalidateList, long clientTimeStamp, 
TableViewFinderResult childViewsResult,
             HRegion region, List<RowLock> locks) throws IOException, 
SQLException {
-        List<PutWithOrdinalPosition> columnPutsForBaseTable = new 
ArrayList<>(tableMetadata.size());
+        List<PutWithOrdinalPosition> columnPutsForBaseTable = 
Lists.newArrayListWithExpectedSize(tableMetadata.size());
+        List<Cell> tablePropertyCells = 
Lists.newArrayListWithExpectedSize(tableMetadata.size());
         // Isolate the puts relevant to adding columns. Also figure out what 
kind of columns are being added.
         for (Mutation m : tableMetadata) {
             if (m instanceof Put) {
                 byte[][] rkmd = new byte[5][];
                 int pkCount = getVarChars(m.getRow(), rkmd);
+                // check if this put is for adding a column
                 if (pkCount > COLUMN_NAME_INDEX
                         && Bytes.compareTo(schemaName, 
rkmd[SCHEMA_NAME_INDEX]) == 0
                         && Bytes.compareTo(tableName, rkmd[TABLE_NAME_INDEX]) 
== 0) {
                     columnPutsForBaseTable.add(new 
PutWithOrdinalPosition((Put)m, getInteger((Put)m, TABLE_FAMILY_BYTES, 
ORDINAL_POSITION_BYTES)));
                 }
+                // check if the put is for a table property
+                else if (pkCount <= COLUMN_NAME_INDEX
+                        && Bytes.compareTo(schemaName, 
rkmd[SCHEMA_NAME_INDEX]) == 0
+                        && Bytes.compareTo(tableName, rkmd[TABLE_NAME_INDEX]) 
== 0) {
+                    for (Cell cell : 
m.getFamilyCellMap().get(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES)) {
+                        for (TableProperty tableProp : TableProperty.values()) 
{
+                            byte[] propNameBytes = 
Bytes.toBytes(tableProp.getPropertyName());
+                            if (Bytes.compareTo(propNameBytes, 0, 
propNameBytes.length, cell.getQualifierArray(), cell.getQualifierOffset(), 
cell.getQualifierLength())==0
+                                    && tableProp.isValidOnView() && 
tableProp.isMutable()) {
+                                Cell tablePropCell = 
CellUtil.createCell(cell.getRow(), CellUtil.cloneFamily(cell),
+                                    CellUtil.cloneQualifier(cell), 
cell.getTimestamp(), cell.getTypeByte(),
+                                    CellUtil.cloneValue(cell));
+                                tablePropertyCells.add(tablePropCell);
+                            }
+                        }
+                    }
+                }
             }
         }
         // Sort the puts by ordinal position 
@@ -2187,6 +2205,7 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
             List<PColumn> viewPkCols = new ArrayList<>(view.getPKColumns());
             boolean addingExistingPkCol = false;
             int numCols = view.getColumns().size();
+            // add the new columns to the child view
             for (PutWithOrdinalPosition p : columnPutsForBaseTable) {
                 Put baseTableColumnPut = p.put;
                 PColumn existingViewColumn = null;
@@ -2333,6 +2352,24 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
             addViewIndexesHeaderRowMutations(mutationsForAddingColumnsToViews, 
invalidateList, clientTimeStamp, view,
                     deltaNumPkColsSoFar);
             
+            // set table properties in child view
+            if (!tablePropertyCells.isEmpty()) {
+                Put viewHeaderRowPut = new Put(viewKey, clientTimeStamp);
+                for (Cell tablePropertyCell : tablePropertyCells) {
+                    viewHeaderRowPut.add(CellUtil.createCell(viewKey, 
CellUtil.cloneFamily(tablePropertyCell),
+                            CellUtil.cloneQualifier(tablePropertyCell), 
clientTimeStamp, tablePropertyCell.getTypeByte(),
+                            CellUtil.cloneValue(tablePropertyCell)));
+                }
+                byte[] viewSequencePtr = new 
byte[PLong.INSTANCE.getByteSize()];
+                PLong.INSTANCE.getCodec().encodeLong(view.getSequenceNumber() 
+ 1, viewSequencePtr, 0);
+                
viewHeaderRowPut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
+                        PhoenixDatabaseMetaData.TABLE_SEQ_NUM_BYTES, 
clientTimeStamp, viewSequencePtr);
+                // invalidate the view so that it is removed from the cache
+                invalidateList.add(new ImmutableBytesPtr(viewKey));
+
+                mutationsForAddingColumnsToViews.add(viewHeaderRowPut);
+            }
+            
             /*
              * Increment the sequence number by 1 if:
              * 1) For a diverged view, there were columns (pk columns) added 
to the view.
@@ -2790,7 +2827,7 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
                                         
EnvironmentEdgeManager.currentTimeMillis(), null);
                             } else {
                                 mutationsForAddingColumnsToViews = new 
ArrayList<>(childViewsResult.getResults().size() * tableMetaData.size());
-                                MetaDataMutationResult mutationResult = 
addColumnsToChildViews(table, tableMetaData, mutationsForAddingColumnsToViews, 
schemaName, tableName, invalidateList, clientTimeStamp,
+                                MetaDataMutationResult mutationResult = 
addColumnsAndTablePropertiesToChildViews(table, tableMetaData, 
mutationsForAddingColumnsToViews, schemaName, tableName, invalidateList, 
clientTimeStamp,
                                         childViewsResult, region, locks);
                                 // return if we were not able to add the 
column successfully
                                 if (mutationResult!=null)

http://git-wip-us.apache.org/repos/asf/phoenix/blob/1704545b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
index 26a7718..4f24c92 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
@@ -156,4 +156,16 @@ public enum TableProperty {
                }
        }
 
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public boolean isValidOnView() {
+        return isValidOnView;
+    }
+
+    public boolean isMutable() {
+        return isMutable;
+    }
+
 }

Reply via email to