[ 
https://issues.apache.org/jira/browse/PHOENIX-7212?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17817152#comment-17817152
 ] 

ASF GitHub Bot commented on PHOENIX-7212:
-----------------------------------------

tkhurana commented on code in PR #1823:
URL: https://github.com/apache/phoenix/pull/1823#discussion_r1488553793


##########
phoenix-core/src/test/java/org/apache/phoenix/cache/ServerMetadataCacheTest.java:
##########
@@ -1591,8 +1593,93 @@ public void 
testAncestorLastDDLMapPopulatedInDifferentClient() throws Exception
         }
     }
 
+    /**
+     * Test that tenant connections are able to learn about state change of an 
inherited index
+     * on their tenant views with different names.
+     */
+    @Test
+    public void testInheritedIndexOnTenantViewsDifferentNames() throws 
Exception {
+        testInheritedIndexOnTenantViews(false);
+    }
+
+    /**
+     * Test that tenant connections are able to learn about state change of an 
inherited index
+     * on their tenant views with same names.
+     */
+    @Test
+    public void testInheritedIndexOnTenantViewsSameNames() throws Exception {
+        testInheritedIndexOnTenantViews(true);
+    }
+
+    public void testInheritedIndexOnTenantViews(boolean sameTenantViewNames) 
throws Exception {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        String url = QueryUtil.getConnectionUrl(props, config, "client1");
+        ConnectionQueryServices cqs = driver.getConnectionQueryServices(url, 
props);
+        String baseTableName =  generateUniqueName();
+        String globalViewName = generateUniqueName();
+        String globalViewIndexName =  generateUniqueName();
+        String tenantViewName1 =  generateUniqueName();
+        String tenantViewName2 =  sameTenantViewNames ? tenantViewName1 : 
generateUniqueName();
+        try (Connection conn = cqs.connect(url, props)) {
+            // create table, view and view index
+            conn.createStatement().execute("CREATE TABLE " + baseTableName +
+                    " (TENANT_ID CHAR(9) NOT NULL, KP CHAR(3) NOT NULL, PK 
CHAR(3) NOT NULL, KV CHAR(2), KV2 CHAR(2) " +
+                    "CONSTRAINT PK PRIMARY KEY(TENANT_ID, KP, PK)) 
MULTI_TENANT=true,UPDATE_CACHE_FREQUENCY=NEVER");
+            conn.createStatement().execute("CREATE VIEW " + globalViewName +
+                    " AS SELECT * FROM " + baseTableName + " WHERE  KP = 
'001'");
+            conn.createStatement().execute("CREATE INDEX " + 
globalViewIndexName + " on " +
+                    globalViewName + " (KV) " + " INCLUDE (KV2) ASYNC");
+            String tenantId1 = "tenantId1";
+            String tenantId2 = "tenantId2";
+            Properties tenantProps1 = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+            Properties tenantProps2 = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+            tenantProps1.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, 
tenantId1);
+            tenantProps2.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, 
tenantId2);
+
+            //create tenant views and upsert one row, this updates all the 
timestamps in the client's cache
+            try (Connection tenantConn1 = cqs.connect(url, tenantProps1);
+                 Connection tenantConn2 = cqs.connect(url, tenantProps2)) {
+                tenantConn1.createStatement().execute("CREATE VIEW " + 
tenantViewName1 + " AS SELECT * FROM " + globalViewName);
+                tenantConn1.createStatement().execute("UPSERT INTO " + 
tenantViewName1 + " (PK, KV, KV2) VALUES " + "('PK1', 'KV', '01')");
+                tenantConn1.commit();
+
+                tenantConn2.createStatement().execute("CREATE VIEW " + 
tenantViewName2 + " AS SELECT * FROM " + globalViewName);
+                tenantConn2.createStatement().execute("UPSERT INTO " + 
tenantViewName2 + " (PK, KV, KV2) VALUES " + "('PK2', 'KV', '02')");
+                tenantConn2.commit();
+            }
+            // build global view index
+            IndexToolIT.runIndexTool(false, "", globalViewName,
+                    globalViewIndexName);
+
+            // query on secondary key should use inherited index for all 
tenant views.
+            try (Connection tenantConn1 = cqs.connect(url, tenantProps1);
+                 Connection tenantConn2 = cqs.connect(url, tenantProps2)) {
+
+                String query1 = "SELECT KV2 FROM  " + tenantViewName1 + " 
WHERE KV = 'KV'";
+                String query2 = "SELECT KV2 FROM  " + tenantViewName2 + " 
WHERE KV = 'KV'";
+
+                ResultSet rs = 
tenantConn1.createStatement().executeQuery(query1);
+                assertPlan((PhoenixResultSet) rs,  "", tenantViewName1 + "#" + 
globalViewIndexName);

Review Comment:
   Small nit: Instead of using `#` use the constant 
`CHILD_VIEW_INDEX_NAME_SEPARATOR` in the test code. There are multiple places 
where `#` is being used.





> Handle inherited indexes for tenant views when validating LAST_DDL_TIMESTAMPS
> -----------------------------------------------------------------------------
>
>                 Key: PHOENIX-7212
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-7212
>             Project: Phoenix
>          Issue Type: Sub-task
>            Reporter: Palash Chauhan
>            Assignee: Palash Chauhan
>            Priority: Major
>
> When a tenant view is resolved and it inherits an index from its parent 
> view/table, a PTable object for the inherited index is added to the list of 
> index PTables in the tenant view PTable object. This PTable object has a 
> modified name of the form `TenantView#Index` and has its tenantId attribute 
> set to that of the tenant view. 
> During a query/upsert, along with the table/view, we also add the indexes of 
> the table/view to the request for validating LAST_DDL_TIMESTAMP. We provide 
> the key of the PTables i.e. (tenantId, schemaName, tableName) to the server. 
> Server looks up its cache based on this key to find out the 
> LAST_DDL_TIMESTAMP and if the key is not present, it fetches the table from 
> SYSCAT. 
> Suppose we perform a query on a tenant view which has inherited an index 
> still in BUILDING state. After the query finishes, server would have cached 
> (tenantId,schema,table) for the actual global index. The index is then built 
> and its state changes to ACTIVE. Cache invalidation happens for the key 
> (null, schema, table). A subsequent query on the tenant view will 
> successfully validate the inherited index and will not learn about the state 
> change. 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to