PHOENIX-2915 Dropping of Index can still leave some non-replayed writes in WAL


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

Branch: refs/heads/4.x-HBase-1.0
Commit: a747b459a15ed271f536b1b08fab416eb5f03fb7
Parents: 5a5da14
Author: Ankit Singhal <ankitsingha...@gmail.com>
Authored: Fri Jun 10 16:26:08 2016 +0530
Committer: Ankit Singhal <ankitsingha...@gmail.com>
Committed: Fri Jun 10 16:26:08 2016 +0530

----------------------------------------------------------------------
 .../query/ConnectionQueryServicesImpl.java      | 58 +++++++++++++-------
 1 file changed, 39 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/a747b459/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index c6d8683..b51be5d 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -1530,7 +1530,8 @@ public class ConnectionQueryServicesImpl extends 
DelegateQueryServices implement
     }
 
     @Override
-    public MetaDataMutationResult dropTable(final List<Mutation> 
tableMetaData, final PTableType tableType, final boolean cascade) throws 
SQLException {
+    public MetaDataMutationResult dropTable(final List<Mutation> 
tableMetaData, final PTableType tableType,
+            final boolean cascade) throws SQLException {
         byte[][] rowKeyMetadata = new byte[3][];
         SchemaUtil.getVarChars(tableMetaData.get(0).getRow(), rowKeyMetadata);
         byte[] tenantIdBytes = 
rowKeyMetadata[PhoenixDatabaseMetaData.TENANT_ID_INDEX];
@@ -1565,18 +1566,14 @@ public class ConnectionQueryServicesImpl extends 
DelegateQueryServices implement
         case TABLE_ALREADY_EXISTS:
             ReadOnlyProps props = this.getProps();
             boolean dropMetadata = props.getBoolean(DROP_METADATA_ATTRIB, 
DEFAULT_DROP_METADATA);
+            PTable table = result.getTable();
             if (dropMetadata) {
+                flushParentPhysicalTable(table);
                 dropTables(result.getTableNamesToDelete());
             }
             invalidateTables(result.getTableNamesToDelete());
             if (tableType == PTableType.TABLE) {
-                boolean isNamespaceMapped = 
result.getTable().isNamespaceMapped();
-                byte[] physicalName;
-                if (!isNamespaceMapped) {
-                    physicalName = SchemaUtil.getTableNameAsBytes(schemaBytes, 
tableBytes);
-                } else {
-                    physicalName = TableName.valueOf(schemaBytes, 
tableBytes).getName();
-                }
+                byte[] physicalName = table.getPhysicalName().getBytes();
                 long timestamp = 
MetaDataUtil.getClientTimeStamp(tableMetaData);
                 ensureViewIndexTableDropped(physicalName, timestamp);
                 ensureLocalIndexTableDropped(physicalName, timestamp);
@@ -1589,6 +1586,25 @@ public class ConnectionQueryServicesImpl extends 
DelegateQueryServices implement
           return result;
     }
 
+    /*
+     * PHOENIX-2915 while dropping index, flush data table to avoid stale WAL 
edits of indexes 1. Flush parent table if
+     * dropping view has indexes 2. Dropping table indexes 3. Dropping view 
indexes
+     */
+    private void flushParentPhysicalTable(PTable table) throws SQLException {
+        byte[] parentPhysicalTableName = null;
+        if (PTableType.VIEW == table.getType()) {
+            if (!table.getIndexes().isEmpty()) {
+                parentPhysicalTableName = table.getPhysicalName().getBytes();
+            }
+        } else if (PTableType.INDEX == table.getType()) {
+            PTable parentTable = getTable(null, 
table.getParentName().getString(), HConstants.LATEST_TIMESTAMP);
+            parentPhysicalTableName = parentTable.getPhysicalName().getBytes();
+        }
+        if (parentPhysicalTableName != null) {
+            flushTable(parentPhysicalTableName);
+        }
+    }
+
     @Override
     public MetaDataMutationResult dropFunction(final List<Mutation> 
functionData, final boolean ifExists) throws SQLException {
         byte[][] rowKeyMetadata = new byte[2][];
@@ -1660,31 +1676,35 @@ public class ConnectionQueryServicesImpl extends 
DelegateQueryServices implement
 
     private void ensureViewIndexTableCreated(PName tenantId, byte[] 
physicalIndexTableName, long timestamp,
             boolean isNamespaceMapped) throws SQLException {
-        PTable table;
         String name = Bytes
                 
.toString(SchemaUtil.getParentTableNameFromIndexTable(physicalIndexTableName,
                         MetaDataUtil.VIEW_INDEX_TABLE_PREFIX))
                 .replace(QueryConstants.NAMESPACE_SEPARATOR, 
QueryConstants.NAME_SEPARATOR);
-        
+        PTable table = getTable(tenantId, name, timestamp);
+        ensureViewIndexTableCreated(table, timestamp, isNamespaceMapped);
+    }
+
+    private PTable getTable(PName tenantId, String fullTableName, long 
timestamp) throws SQLException {
+        PTable table;
         try {
             PMetaData metadata = latestMetaData;
             if (metadata == null) {
                 throwConnectionClosedException();
             }
-            table = metadata.getTableRef(new PTableKey(tenantId, 
name)).getTable();
-            if (table.getTimeStamp() >= timestamp) { // Table in cache is 
newer than client timestamp which shouldn't be the case
+            table = metadata.getTableRef(new PTableKey(tenantId, 
fullTableName)).getTable();
+            if (table.getTimeStamp() >= timestamp) { // Table in cache is 
newer than client timestamp which shouldn't be
+                                                     // the case
                 throw new 
TableNotFoundException(table.getSchemaName().getString(), 
table.getTableName().getString());
             }
         } catch (TableNotFoundException e) {
-            byte[] schemaName = 
Bytes.toBytes(SchemaUtil.getSchemaNameFromFullName(name));
-            byte[] tableName = 
Bytes.toBytes(SchemaUtil.getTableNameFromFullName(name));
-            MetaDataMutationResult result = this.getTable(null, schemaName, 
tableName, HConstants.LATEST_TIMESTAMP, timestamp);
+            byte[] schemaName = 
Bytes.toBytes(SchemaUtil.getSchemaNameFromFullName(fullTableName));
+            byte[] tableName = 
Bytes.toBytes(SchemaUtil.getTableNameFromFullName(fullTableName));
+            MetaDataMutationResult result = this.getTable(null, schemaName, 
tableName, HConstants.LATEST_TIMESTAMP,
+                    timestamp);
             table = result.getTable();
-            if (table == null) {
-                throw e;
-            }
+            if (table == null) { throw e; }
         }
-        ensureViewIndexTableCreated(table, timestamp, isNamespaceMapped);
+        return table;
     }
 
        private void ensureViewIndexTableCreated(PTable table, long timestamp, 
boolean isNamespaceMapped)

Reply via email to