PHOENIX-2356 Set TRANSACTIONAL to true for derived views when transitioning to 
transactional table


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

Branch: refs/heads/calcite
Commit: 93acc2788049b12ecda4b962dfdde9f0b6ed4fed
Parents: a8238f9
Author: Thomas D'Silva <tdsi...@salesforce.com>
Authored: Fri Dec 4 12:09:04 2015 -0800
Committer: Thomas D'Silva <tdsi...@salesforce.com>
Committed: Mon Dec 7 12:04:59 2015 -0800

----------------------------------------------------------------------
 .../phoenix/end2end/AlterTableWithViewsIT.java  | 48 +++++++++++++++++++-
 .../coprocessor/MetaDataEndpointImpl.java       | 43 +++++++++++-------
 2 files changed, 73 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/93acc278/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 3f311ea..e3d78ea 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
@@ -34,9 +34,11 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.exception.SQLExceptionCode;
@@ -44,19 +46,32 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.ReadOnlyProps;
 import org.apache.phoenix.util.SchemaUtil;
-import org.junit.Assert;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
+import co.cask.tephra.hbase11.coprocessor.TransactionProcessor;
+
 import com.google.common.base.Objects;
+import com.google.common.collect.Maps;
 
 public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
+       
+       @BeforeClass
+    @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
+    public static void doSetup() throws Exception {
+        Map<String,String> props = Maps.newHashMapWithExpectedSize(1);
+        props.put(QueryServices.TRANSACTIONS_ENABLED, Boolean.toString(true));
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+    }
     
     @Test
     public void testAddNewColumnsToBaseTableWithViews() throws Exception {
@@ -1096,6 +1111,37 @@ public class AlterTableWithViewsIT extends 
BaseHBaseManagedTimeIT {
         }
     }
     
+    @Test
+    public void testMakeBaseTableTransactional() throws Exception {
+        try (Connection conn = DriverManager.getConnection(getUrl())) {       
+            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS 
TABLEWITHVIEW ("
+                    + " ID char(1) NOT NULL,"
+                    + " COL1 integer NOT NULL,"
+                    + " COL2 bigint NOT NULL,"
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
+                    + " )");
+            assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, 
null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+            
+            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( 
VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM TABLEWITHVIEW");
+            assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, 
"TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
+            
+            HTableInterface htable = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("TABLEWITHVIEW"));
+            
assertFalse(htable.getTableDescriptor().getCoprocessors().contains(TransactionProcessor.class.getName()));
+            assertFalse(conn.unwrap(PhoenixConnection.class).getTable(new 
PTableKey(null, "TABLEWITHVIEW")).isTransactional());
+            assertFalse(conn.unwrap(PhoenixConnection.class).getTable(new 
PTableKey(null, "VIEWOFTABLE")).isTransactional());
+            
+            // make the base table transactional
+            conn.createStatement().execute("ALTER TABLE TABLEWITHVIEW SET 
TRANSACTIONAL=true");
+            // query the view to force the table cache to be updated
+            conn.createStatement().execute("SELECT * FROM VIEWOFTABLE");
+            htable = 
conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("TABLEWITHVIEW"));
+            
assertTrue(htable.getTableDescriptor().getCoprocessors().contains(TransactionProcessor.class.getName()));
+            assertTrue(conn.unwrap(PhoenixConnection.class).getTable(new 
PTableKey(null, "TABLEWITHVIEW")).isTransactional());
+            assertTrue(conn.unwrap(PhoenixConnection.class).getTable(new 
PTableKey(null, "VIEWOFTABLE")).isTransactional());
+        } 
+    
+    }
+    
     private static long getTableSequenceNumber(PhoenixConnection conn, String 
tableName) throws SQLException {
         PTable table = conn.getTable(new PTableKey(conn.getTenantId(), 
SchemaUtil.normalizeIdentifier(tableName)));
         return table.getSequenceNumber();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/93acc278/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 7c80f23..f997149 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
@@ -1805,7 +1805,22 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
         return columnKey;
     }
     
-    MetaDataMutationResult addRowsToChildViews(PTable basePhysicalTable, 
List<Mutation> tableMetadata, List<Mutation> mutationsForAddingColumnsToViews, 
byte[] schemaName, byte[] tableName,
+    private boolean switchAttribute(PTable table, boolean currAttribute, 
List<Mutation> tableMetaData, byte[] attrQualifier) {
+        for (Mutation m : tableMetaData) {
+            if (m instanceof Put) {
+                Put p = (Put)m;
+                List<Cell> cells = p.get(TABLE_FAMILY_BYTES, attrQualifier);
+                if (cells != null && cells.size() > 0) {
+                    Cell cell = cells.get(0);
+                    boolean newAttribute = 
(boolean)PBoolean.INSTANCE.toObject(cell.getValueArray(), 
cell.getValueOffset(), cell.getValueLength()); 
+                    return currAttribute != newAttribute;
+                }
+            }
+        }
+        return false;
+    }
+    
+    private MetaDataMutationResult addRowsToChildViews(PTable 
basePhysicalTable, List<Mutation> tableMetadata, List<Mutation> 
mutationsForAddingColumnsToViews, byte[] schemaName, byte[] tableName,
             List<ImmutableBytesPtr> invalidateList, long clientTimeStamp, 
TableViewFinderResult childViewsResult,
             Region region, List<RowLock> locks) throws IOException, 
SQLException {
         List<PutWithOrdinalPosition> columnPutsForBaseTable = new 
ArrayList<>(tableMetadata.size());
@@ -2043,6 +2058,15 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
             if (view.rowKeyOrderOptimizable()) {
                 
UpgradeUtil.addRowKeyOrderOptimizableCell(mutationsForAddingColumnsToViews, 
viewKey, clientTimeStamp);
             }
+            
+            // if switching from from non tx to tx
+            if (!basePhysicalTable.isTransactional() && 
switchAttribute(basePhysicalTable, basePhysicalTable.isTransactional(), 
tableMetadata, TRANSACTIONAL_BYTES)) {
+               invalidateList.add(new ImmutableBytesPtr(viewKey));
+               Put put = new Put(viewKey);
+                put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
+                               TRANSACTIONAL_BYTES, clientTimeStamp, 
PBoolean.INSTANCE.toBytes(true));
+                mutationsForAddingColumnsToViews.add(put);
+            }
         }
         return null;
     }
@@ -2267,7 +2291,7 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
                             if (!childViewsResult.allViewsInSingleRegion() 
                                     || table.getBaseColumnCount() == 0 
                                     || !request.hasClientVersion()
-                                    || switchTenancy(table, tableMetaData)) {
+                                    || switchAttribute(table, 
table.isMultiTenant(), tableMetaData, MULTI_TENANT_BYTES)) {
                                 return new 
MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION,
                                         
EnvironmentEdgeManager.currentTimeMillis(), null);
                             } else {
@@ -2354,21 +2378,6 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements Coprocesso
                     tableMetaData.addAll(mutationsForAddingColumnsToViews);
                     return null;
                 }
-
-                private boolean switchTenancy(PTable table, List<Mutation> 
tableMetaData) {
-                    for (Mutation m : tableMetaData) {
-                        if (m instanceof Put) {
-                            Put p = (Put)m;
-                            List<Cell> cells = p.get(TABLE_FAMILY_BYTES, 
MULTI_TENANT_BYTES);
-                            if (cells != null && cells.size() > 0) {
-                                Cell cell = cells.get(0);
-                                boolean isMutlitenantProp = 
(boolean)PBoolean.INSTANCE.toObject(cell.getValueArray(), 
cell.getValueOffset(), cell.getValueLength()); 
-                                return table.isMultiTenant() != 
isMutlitenantProp;
-                            }
-                        }
-                    }
-                    return false;
-                }
             });
             if (result != null) {
                 done.run(MetaDataMutationResult.toProto(result));

Reply via email to