This is an automated email from the ASF dual-hosted git repository. kadir 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 6cd188d PHOENIX-5589 GlobalIndexChecker does not populate global index related attributes for certain queries 6cd188d is described below commit 6cd188d514b19d0a6ee7040a97c6fb43789f3d55 Author: Kadir <kozde...@salesforce.com> AuthorDate: Tue Nov 26 12:07:30 2019 -0800 PHOENIX-5589 GlobalIndexChecker does not populate global index related attributes for certain queries --- .../end2end/index/GlobalIndexCheckerIT.java | 64 ++++++++++++++++++++++ .../java/org/apache/phoenix/util/IndexUtil.java | 7 +++ 2 files changed, 71 insertions(+) diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexCheckerIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexCheckerIT.java index 7c823ea..9a1bf59 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexCheckerIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/GlobalIndexCheckerIT.java @@ -30,11 +30,14 @@ import java.sql.SQLException; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Properties; import com.google.common.collect.Maps; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.CellScanner; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; @@ -44,6 +47,8 @@ import org.apache.phoenix.end2end.BaseUniqueNamesOwnClusterIT; import org.apache.phoenix.end2end.IndexToolIT; import org.apache.phoenix.hbase.index.IndexRegionObserver; import org.apache.phoenix.jdbc.PhoenixConnection; +import org.apache.phoenix.schema.PTable; +import org.apache.phoenix.util.PhoenixRuntime; import org.apache.phoenix.util.QueryUtil; import org.apache.phoenix.util.ReadOnlyProps; import org.apache.phoenix.util.TestUtil; @@ -467,6 +472,65 @@ public class GlobalIndexCheckerIT extends BaseUniqueNamesOwnClusterIT { } } + @Test + public void testViewIndexRowUpdate() throws Exception { + if (async) { + // No need to run the same test twice one for async = true and the other for async = false + return; + } + try (Connection conn = DriverManager.getConnection(getUrl())) { + // Create a base table + String dataTableName = generateUniqueName(); + conn.createStatement().execute("create table " + dataTableName + + " (oid varchar(10) not null, kp char(3) not null, val1 varchar(10)" + + "CONSTRAINT pk PRIMARY KEY (oid, kp)) COLUMN_ENCODED_BYTES=0, MULTI_TENANT=true"); + // Create a view on the base table + String viewName = generateUniqueName(); + conn.createStatement().execute("CREATE VIEW " + viewName + " (id char(10) not null, " + + "val2 varchar, val3 varchar, CONSTRAINT pk PRIMARY KEY (id)) AS SELECT * FROM " + dataTableName + + " WHERE kp = '0EC'"); + // Create an index on the view + String indexName = generateUniqueName(); + conn.createStatement().execute("CREATE INDEX " + indexName + " on " + + viewName + " (val2) include (val3)"); + Properties props = new Properties(); + props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, "o1"); + try (Connection tenantConn = DriverManager.getConnection(getUrl(), props)) { + // Configure IndexRegionObserver to fail the last write phase (i.e., the post index update phase) + // This will leave index rows unverified + // Create a view of the view + String childViewName = generateUniqueName(); + tenantConn.createStatement().execute("CREATE VIEW " + childViewName + " (zid CHAR(15)) " + + "AS SELECT * FROM " + viewName); + // Create another view of the child view + String grandChildViewName = generateUniqueName(); + tenantConn.createStatement().execute("CREATE VIEW " + grandChildViewName + " (val4 CHAR(15)) " + + "AS SELECT * FROM " + childViewName); + IndexRegionObserver.setFailPostIndexUpdatesForTesting(true); + tenantConn.createStatement().execute("upsert into " + childViewName + " (zid, id, val1, val2, val3) VALUES('z1','1', 'a1','b1','c1')"); + tenantConn.commit(); + IndexRegionObserver.setFailPostIndexUpdatesForTesting(false); + // Activate read repair + String selectSql = "select val3 from " + childViewName + " WHERE val2 = 'b1'"; + ResultSet rs = tenantConn.createStatement().executeQuery(selectSql); + assertTrue(rs.next()); + assertEquals("c1", rs.getString("val3")); + // Configure IndexRegionObserver to fail the last write phase (i.e., the post index update phase) + // This will leave index rows unverified + IndexRegionObserver.setFailPostIndexUpdatesForTesting(true); + tenantConn.createStatement().execute("upsert into " + grandChildViewName + " (zid, id, val2, val3, val4) VALUES('z1', '2', 'b2', 'c2', 'd1')"); + tenantConn.commit(); + IndexRegionObserver.setFailPostIndexUpdatesForTesting(false); + // Activate read repair + selectSql = "select id, val3 from " + grandChildViewName + " WHERE val2 = 'b2'"; + rs = tenantConn.createStatement().executeQuery(selectSql); + assertTrue(rs.next()); + assertEquals("2", rs.getString("id")); + assertEquals("c2", rs.getString("val3")); + } + } + } + static private void commitWithException(Connection conn) { try { conn.commit(); diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java index 7b0bf09..4944c45 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java @@ -964,6 +964,13 @@ public class IndexUtil { // This index table must be being deleted. No need to set the scan attributes return; } + // MetaDataClient modifies the index table name for view indexes if the parent view of an index has a child + // view. This, we need to recreate a PTable object with the correct table name for the rest of this code to work + if (indexTable.getViewIndexId() != null && indexTable.getName().getString().contains(QueryConstants.CHILD_VIEW_INDEX_NAME_SEPARATOR)) { + int lastIndexOf = indexTable.getName().getString().lastIndexOf(QueryConstants.CHILD_VIEW_INDEX_NAME_SEPARATOR); + String indexName = indexTable.getName().getString().substring(lastIndexOf + 1); + indexTable = PhoenixRuntime.getTable(phoenixConnection, indexName); + } if (!dataTable.getIndexes().contains(indexTable)) { return; }