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 2019/07/25 19:06:11 UTC

[phoenix] branch 4.14-HBase-1.4 updated: PHOENIX-5391 : MetadataClient - TenantId Map is not correctly updated with list of Table Refs

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

chinmayskulkarni pushed a commit to branch 4.14-HBase-1.4
in repository https://gitbox.apache.org/repos/asf/phoenix.git


The following commit(s) were added to refs/heads/4.14-HBase-1.4 by this push:
     new d9e2d0c  PHOENIX-5391 : MetadataClient - TenantId Map is not correctly updated with list of Table Refs
d9e2d0c is described below

commit d9e2d0c8523c608f7c64578c2f2a7f13a2851b68
Author: Viraj Jasani <vi...@gmail.com>
AuthorDate: Sun Jul 14 18:24:18 2019 +0530

    PHOENIX-5391 : MetadataClient - TenantId Map is not correctly updated with list of Table Refs
    
    Signed-off-by: Chinmay Kulkarni <ch...@gmail.com>
---
 .../apache/phoenix/end2end/DropIndexedColsIT.java  | 261 +++++++++++++++++++++
 .../org/apache/phoenix/schema/MetaDataClient.java  |  14 +-
 2 files changed, 269 insertions(+), 6 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropIndexedColsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropIndexedColsIT.java
new file mode 100644
index 0000000..1e1a31b
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropIndexedColsIT.java
@@ -0,0 +1,261 @@
+/*
+ * 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 java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
+
+@RunWith(Parameterized.class)
+public class DropIndexedColsIT extends ParallelStatsDisabledIT {
+
+  private static final String CREATE_TABLE_COL_QUERY = " (%s k VARCHAR NOT NULL, v1 VARCHAR, " +
+      "v2 VARCHAR, v3 VARCHAR, v4 VARCHAR, v5 VARCHAR CONSTRAINT PK PRIMARY KEY(%s k))%s";
+  private static final String CREATE_TABLE = "CREATE TABLE ";
+  private static final String CREATE_VIEW = "CREATE VIEW ";
+  private static final String CREATE_INDEX = "CREATE INDEX ";
+  private static final String SELECT_ALL_FROM = "SELECT * FROM ";
+  private static final String UPSERT_INTO = "UPSERT INTO ";
+  private static final String ALTER_TABLE = "ALTER TABLE ";
+  private static final String TENANT1 = "tenant1";
+  private static final String SCHEMA1 = "schema1";
+  private static final String SCHEMA2 = "schema2";
+  private static final String SCHEMA3 = "schema3";
+  private static final String SCHEMA4 = "schema4";
+
+  private final boolean salted;
+  private final String TENANT_SPECIFIC_URL = getUrl() + ';' + TENANT_ID_ATTRIB + "=" + TENANT1;
+
+  public DropIndexedColsIT(boolean salted) {
+    this.salted = salted;
+  }
+
+  @Parameterized.Parameters(name = "DropIndexedColsIT_salted={0}")
+  public static Collection<Boolean> data() {
+    return Arrays.asList(false, true);
+  }
+
+  @Test
+  public void testDropIndexedColsMultiTables() throws Exception {
+    try (Connection conn = DriverManager.getConnection(getUrl());
+         Connection viewConn = DriverManager.getConnection(TENANT_SPECIFIC_URL)) {
+      String tableWithView1 = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+      String tableWithView2 = SchemaUtil.getTableName(SCHEMA3, generateUniqueName());
+
+      String viewOfTable1 = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+      String viewOfTable2 = SchemaUtil.getTableName(SCHEMA4, generateUniqueName());
+
+      String viewSchemaName1 = SchemaUtil.getSchemaNameFromFullName(viewOfTable1);
+      String viewSchemaName2 = SchemaUtil.getSchemaNameFromFullName(viewOfTable2);
+
+      String viewIndex1 = generateUniqueName();
+      String viewIndex2 = generateUniqueName();
+      String viewIndex3 = generateUniqueName();
+      String viewIndex4 = generateUniqueName();
+      String viewIndex5 = generateUniqueName();
+
+      String fullNameViewIndex1 = SchemaUtil.getTableName(viewSchemaName1, viewIndex1);
+      String fullNameViewIndex2 = SchemaUtil.getTableName(viewSchemaName1, viewIndex2);
+      String fullNameViewIndex3 = SchemaUtil.getTableName(viewSchemaName2, viewIndex3);
+      String fullNameViewIndex4 = SchemaUtil.getTableName(viewSchemaName2, viewIndex4);
+
+      conn.setAutoCommit(false);
+      viewConn.setAutoCommit(false);
+      String ddlFormat = new StringBuilder()
+          .append(CREATE_TABLE)
+          .append(tableWithView1)
+          .append(CREATE_TABLE_COL_QUERY).toString();
+      String ddlFormat2 = new StringBuilder()
+          .append(CREATE_TABLE)
+          .append(tableWithView2)
+          .append(CREATE_TABLE_COL_QUERY).toString();
+      conn.createStatement().execute(generateDDL(ddlFormat));
+      conn.createStatement().execute(generateDDL(ddlFormat2));
+      viewConn.createStatement().execute(new StringBuilder(CREATE_VIEW)
+          .append(viewOfTable1)
+          .append(" ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM ")
+          .append(tableWithView1).toString());
+      viewConn.createStatement().execute(new StringBuilder(CREATE_VIEW)
+          .append(viewOfTable2)
+          .append(" ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM ")
+          .append(tableWithView2).toString());
+
+      viewConn.createStatement().execute(CREATE_INDEX + viewIndex1 + " ON " + viewOfTable1
+          + "(v2) INCLUDE (v4)");
+      viewConn.createStatement().execute(CREATE_INDEX + viewIndex2 + " ON " + viewOfTable1
+          + "(v1) INCLUDE (v4)");
+      viewConn.createStatement().execute(CREATE_INDEX + viewIndex3 + " ON " + viewOfTable2
+          + "(v2) INCLUDE (v4)");
+      viewConn.createStatement().execute(CREATE_INDEX + viewIndex4 + " ON " + viewOfTable2
+          + "(v1) INCLUDE (v4)");
+      viewConn.createStatement().execute(CREATE_INDEX + viewIndex5 + " ON " + viewOfTable2
+          + "(v3) INCLUDE (v4)");
+
+
+      viewConn.createStatement().execute(SELECT_ALL_FROM + fullNameViewIndex1);
+      viewConn.createStatement().execute(SELECT_ALL_FROM + fullNameViewIndex2);
+      viewConn.createStatement().execute(SELECT_ALL_FROM + fullNameViewIndex3);
+      viewConn.createStatement().execute(SELECT_ALL_FROM + fullNameViewIndex4);
+
+
+      // upsert a single row
+      PreparedStatement stmt = viewConn.prepareStatement(UPSERT_INTO + viewOfTable1
+          + " VALUES(?,?,?,?,?,?,?,?)");
+      stmt.setString(1, "a");
+      stmt.setString(2, "b");
+      stmt.setString(3, "c");
+      stmt.setString(4, "d");
+      stmt.setString(5, "e");
+      stmt.setString(6, "f");
+      stmt.setInt(7, 1);
+      stmt.setString(8, "g");
+      stmt.execute();
+      viewConn.commit();
+
+      stmt = viewConn.prepareStatement(UPSERT_INTO + viewOfTable2
+          + " VALUES(?,?,?,?,?,?,?,?)");
+      stmt.setString(1, "a");
+      stmt.setString(2, "b");
+      stmt.setString(3, "c");
+      stmt.setString(4, "d");
+      stmt.setString(5, "e");
+      stmt.setString(6, "f");
+      stmt.setInt(7, 1);
+      stmt.setString(8, "g");
+      stmt.execute();
+      viewConn.commit();
+
+      conn.createStatement().execute(ALTER_TABLE + tableWithView1 + " DROP COLUMN v2, v3, v5 ");
+      conn.createStatement().execute(ALTER_TABLE + tableWithView2 + " DROP COLUMN " +
+          "v1, v2, v3, v5 ");
+      // verify columns were dropped
+      droppedColumnTest(conn, "v2", tableWithView1);
+      droppedColumnTest(conn, "v3", tableWithView1);
+      droppedColumnTest(conn, "v5", tableWithView1);
+      droppedColumnTest(conn, "v1", tableWithView2);
+      droppedColumnTest(conn, "v2", tableWithView2);
+      droppedColumnTest(conn, "v3", tableWithView2);
+      droppedColumnTest(conn, "v5", tableWithView2);
+
+    }
+  }
+
+  @Test
+  public void testDropIndexedColsSingleTable() throws Exception {
+    try (Connection conn = DriverManager.getConnection(getUrl());
+         Connection viewConn = DriverManager.getConnection(TENANT_SPECIFIC_URL)) {
+      String tableWithView = SchemaUtil.getTableName(SCHEMA1, generateUniqueName());
+      String viewOfTable = SchemaUtil.getTableName(SCHEMA2, generateUniqueName());
+      String viewSchemaName = SchemaUtil.getSchemaNameFromFullName(viewOfTable);
+
+      String viewIndex1 = generateUniqueName();
+      String viewIndex2 = generateUniqueName();
+
+      String fullNameViewIndex1 = SchemaUtil.getTableName(viewSchemaName, viewIndex1);
+      String fullNameViewIndex2 = SchemaUtil.getTableName(viewSchemaName, viewIndex2);
+
+      conn.setAutoCommit(false);
+      viewConn.setAutoCommit(false);
+      String ddlFormat = new StringBuilder()
+          .append(CREATE_TABLE)
+          .append(tableWithView)
+          .append(CREATE_TABLE_COL_QUERY).toString();
+      conn.createStatement().execute(generateDDL(ddlFormat));
+      viewConn.createStatement().execute(new StringBuilder(CREATE_VIEW)
+          .append(viewOfTable)
+          .append(" ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM ")
+          .append(tableWithView).toString());
+
+      viewConn.createStatement().execute(CREATE_INDEX + viewIndex1 + " ON " + viewOfTable
+          + "(v2) INCLUDE (v4)");
+      viewConn.createStatement().execute(CREATE_INDEX + viewIndex2 + " ON " + viewOfTable
+          + "(v1) INCLUDE (v4)");
+
+      viewConn.createStatement().execute(SELECT_ALL_FROM + fullNameViewIndex1);
+      viewConn.createStatement().execute(SELECT_ALL_FROM + fullNameViewIndex2);
+
+      // upsert a single row
+      PreparedStatement stmt = viewConn.prepareStatement(UPSERT_INTO + viewOfTable
+          + " VALUES(?,?,?,?,?,?,?,?)");
+      stmt.setString(1, "a");
+      stmt.setString(2, "b");
+      stmt.setString(3, "c");
+      stmt.setString(4, "d");
+      stmt.setString(5, "e");
+      stmt.setString(6, "f");
+      stmt.setInt(7, 1);
+      stmt.setString(8, "g");
+      stmt.execute();
+      viewConn.commit();
+
+      // verify the index was created
+      PhoenixConnection pconn = viewConn.unwrap(PhoenixConnection.class);
+      PName tenantId = PNameFactory.newName(TENANT1);
+      conn.createStatement().execute(ALTER_TABLE + tableWithView + " DROP COLUMN v2, v3, v5 ");
+      // verify columns were dropped
+      droppedColumnTest(conn, "v2", tableWithView);
+      droppedColumnTest(conn, "v3", tableWithView);
+      droppedColumnTest(conn, "v5", tableWithView);
+
+    }
+  }
+
+
+  private String generateDDL(String format) {
+    StringBuilder ddlGeneratorBuilder = new StringBuilder();
+    if (ddlGeneratorBuilder.length() != 0) {
+      ddlGeneratorBuilder.append(",");
+    }
+    ddlGeneratorBuilder.append("MULTI_TENANT=true");
+    if (salted) {
+      if (ddlGeneratorBuilder.length() != 0) {
+        ddlGeneratorBuilder.append(",");
+      }
+      ddlGeneratorBuilder.append("SALT_BUCKETS=4");
+    }
+    return String.format(format, "TENANT_ID VARCHAR NOT NULL, ", "TENANT_ID, ",
+        ddlGeneratorBuilder.toString());
+  }
+
+  private void droppedColumnTest(Connection conn, String column, String table)
+      throws SQLException {
+    try {
+      conn.createStatement().execute("SELECT " + column + " FROM " + table);
+      Assert.fail("Column should have been dropped");
+    } catch (ColumnNotFoundException e) {
+      // Empty block
+    }
+  }
+
+}
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 6d39c25..60147fb 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
@@ -3834,14 +3834,16 @@ public class MetaDataClient {
                                         table.isMultiTenant(), table.isNamespaceMapped(), table.getImmutableStorageScheme(), table.getEncodingScheme(), table.getEncodedCQCounter(), table.useStatsForParallelization());
                                 TableRef indexTableRef = new TableRef(viewIndexTable);
                                 PName indexTableTenantId = sharedTableState.getTenantId();
-                                if (indexTableTenantId==null) {
+                                if (indexTableTenantId == null) {
                                     tableRefsToDrop.add(indexTableRef);
-                                }
-                                else {
-                                    if (!tenantIdTableRefMap.containsKey(indexTableTenantId)) {
-                                        tenantIdTableRefMap.put(indexTableTenantId.getString(), Lists.<TableRef>newArrayList());
+                                } else {
+                                    if (!tenantIdTableRefMap.containsKey(
+                                            indexTableTenantId.getString())) {
+                                        tenantIdTableRefMap.put(indexTableTenantId.getString(),
+                                            Lists.<TableRef>newArrayList());
                                     }
-                                    tenantIdTableRefMap.get(indexTableTenantId.getString()).add(indexTableRef);
+                                    tenantIdTableRefMap.get(indexTableTenantId.getString())
+                                            .add(indexTableRef);
                                 }
 
                             }