You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ch...@apache.org on 2020/11/05 20:23:42 UTC

[phoenix] branch 4.x updated: PHOENIX-6083 View index creation does a checkAndPut on an incorrect row key

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

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


The following commit(s) were added to refs/heads/4.x by this push:
     new 9f91707  PHOENIX-6083 View index creation does a checkAndPut on an incorrect row key
9f91707 is described below

commit 9f91707f5f0fe108d316ebda8df8b38aadd63b16
Author: Richard Antal <an...@gmail.com>
AuthorDate: Mon Nov 2 17:45:14 2020 +0100

    PHOENIX-6083 View index creation does a checkAndPut on an incorrect row key
---
 .../apache/phoenix/end2end/index/ViewIndexIT.java  | 60 ++++++++++++++++++++++
 .../org/apache/phoenix/schema/MetaDataClient.java  | 22 +++++---
 2 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
index 9a3f648..5856fbc 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
@@ -44,6 +44,9 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.TableName;
@@ -116,6 +119,63 @@ public class ViewIndexIT extends SplitSystemCatalogIT {
         conn.close();
     }
 
+    @Test
+    public void testDroppingColumnWhileCreatingIndex() throws Exception {
+        String schemaName = "S1";
+        String tableName = generateUniqueName();
+        String viewSchemaName = "S1";
+        final String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
+        final String indexName = "IND_" + generateUniqueName();
+        String viewName = "VIEW_" + generateUniqueName();
+        final String fullViewName = SchemaUtil.getTableName(viewSchemaName, viewName);
+
+        createBaseTable(schemaName, tableName, false, null, null, true);
+        try (Connection conn = getConnection()) {
+            conn.setAutoCommit(true);
+            conn.createStatement().execute("CREATE VIEW " + fullViewName + " AS SELECT * FROM " + fullTableName);
+            conn.commit();
+            final AtomicInteger exceptionCode = new AtomicInteger();
+            final CountDownLatch doneSignal = new CountDownLatch(2);
+            Runnable r1 = new Runnable() {
+
+                @Override public void run() {
+                    try {
+                        conn.createStatement().execute("CREATE INDEX " + indexName + " ON " + fullViewName + " (v1)");
+                    } catch (SQLException e) {
+                        exceptionCode.set(e.getErrorCode());
+                        throw new RuntimeException(e);
+                    } finally {
+                        doneSignal.countDown();
+                    }
+                }
+
+            };
+            Runnable r2 = new Runnable() {
+
+                @Override public void run() {
+                    try {
+                        conn.createStatement().execute("ALTER TABLE " + fullTableName + " DROP COLUMN v1");
+                    } catch (SQLException e) {
+                        exceptionCode.set(e.getErrorCode());
+                        throw new RuntimeException(e);
+                    } finally {
+                        doneSignal.countDown();
+                    }
+                }
+
+            };
+            Thread t1 = new Thread(r1);
+            t1.start();
+            Thread t2 = new Thread(r2);
+            t2.start();
+
+            t1.join();
+            t2.join();
+            doneSignal.await(60, TimeUnit.SECONDS);
+            assertEquals(exceptionCode.get(), 301);
+        }
+    }
+
     private void createView(Connection conn, String schemaName, String viewName, String baseTableName) throws SQLException {
         if (isNamespaceMapped) {
             conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 27daf66..7c9fa08 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -1682,12 +1682,17 @@ public class MetaDataClient {
                 for (ColumnName colName : requiredCols) {
                     // acquire the mutex using the global physical table name to
                     // prevent this column from being dropped while the view is being created
+                    String colNameSeparatedByDot = colName.getColumnName()
+                            .replace(QueryConstants.NAMESPACE_SEPARATOR,
+                                     QueryConstants.NAME_SEPARATOR);
+                    // indexed column name have a ':' between the column family and column name
+                    // We would like to have '.' like in other column names
                     boolean acquiredMutex = writeCell(null, physicalSchemaName, physicalTableName,
-                            colName.toString());
+                            colNameSeparatedByDot);
                     if (!acquiredMutex) {
                         throw new ConcurrentTableMutationException(physicalSchemaName, physicalTableName);
                     }
-                    acquiredColumnMutexSet.add(colName.toString());
+                    acquiredColumnMutexSet.add(colNameSeparatedByDot);
                 }
             }
 
@@ -2865,11 +2870,11 @@ public class MetaDataClient {
                             // acquire the mutex using the global physical table name to
                             // prevent this column from being dropped while the view is being created
                             boolean acquiredMutex = writeCell(null, parentPhysicalSchemaName, parentPhysicalTableName,
-                                    column.getName().getString());
+                                    column.toString());
                             if (!acquiredMutex) {
                                 throw new ConcurrentTableMutationException(parentPhysicalSchemaName, parentPhysicalTableName);
                             }
-                            acquiredColumnMutexSet.add(column.getName().getString());
+                            acquiredColumnMutexSet.add(column.toString());
                         }
                     }
                     Short keySeq = SchemaUtil.isPKColumn(column) ? ++nextKeySeq : null;
@@ -4000,11 +4005,11 @@ public class MetaDataClient {
                     // prevent creating the same column on a table or view with
                     // a conflicting type etc
                     boolean acquiredMutex = writeCell(null, physicalSchemaName, physicalTableName,
-                        pColumn.getName().getString());
+                        pColumn.toString());
                     if (!acquiredMutex) {
                         throw new ConcurrentTableMutationException(physicalSchemaName, physicalTableName);
                     }
-                    acquiredColumnMutexSet.add(pColumn.getName().getString());
+                    acquiredColumnMutexSet.add(pColumn.toString());
                 }
                 MetaDataMutationResult result = connection.getQueryServices().addColumn(tableMetaData, table,
                         getParentTable(table), properties, colFamiliesForPColumnsToBeAdded, columns);
@@ -4335,11 +4340,12 @@ public class MetaDataClient {
                                 .setColumnName(columnToDrop.getName().getString()).build().buildException();
                     }
                     columnsToDrop.add(new ColumnRef(columnRef.getTableRef(), columnToDrop.getPosition()));
-                    boolean acquiredMutex = writeCell(null, physicalSchemaName, physicalTableName, columnToDrop.getName().getString());
+                    boolean acquiredMutex = writeCell(null, physicalSchemaName,
+                            physicalTableName, columnToDrop.toString());
                     if (!acquiredMutex) {
                         throw new ConcurrentTableMutationException(physicalSchemaName, physicalTableName);
                     }
-                    acquiredColumnMutexSet.add(columnToDrop.getName().getString());
+                    acquiredColumnMutexSet.add(columnToDrop.toString());
                 }
 
                 dropColumnMutations(table, tableColumnsToDrop);