You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by la...@apache.org on 2021/03/04 20:45:15 UTC

[phoenix] branch 4.x updated: PHOENIX-6400 Do no use local index with uncovered columns in the WHERE clause.

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

larsh 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 aee3f83  PHOENIX-6400 Do no use local index with uncovered columns in the WHERE clause.
aee3f83 is described below

commit aee3f832af0fd128f9a1008fec8e53e59d30c6bc
Author: Lars <la...@apache.org>
AuthorDate: Wed Mar 3 13:01:07 2021 -0800

    PHOENIX-6400 Do no use local index with uncovered columns in the WHERE clause.
---
 .../apache/phoenix/end2end/index/LocalIndexIT.java | 37 ++++++++++++++++------
 .../org/apache/phoenix/compile/WhereCompiler.java  | 11 +++++++
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
index 14e85ab..276395e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
@@ -80,6 +80,26 @@ public class LocalIndexIT extends BaseLocalIndexIT {
     }
 
     @Test
+    public void testSelectFromIndexWithAdditionalWhereClause() throws Exception {
+        String tableName = schemaName + "." + generateUniqueName();
+        String indexName = "IDX_" + generateUniqueName();
+
+        Connection conn = getConnection();
+        conn.setAutoCommit(true);
+        if (isNamespaceMapped) {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
+        }
+
+        conn.createStatement().execute("CREATE TABLE " + tableName + " (pk INTEGER PRIMARY KEY, v1 FLOAT, v2 FLOAT)");
+        conn.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(1, 0.01, 1.0)");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT COUNT(*) FROM "+tableName+" WHERE v1 < 0.1 and v2 < 10.0");
+        rs.next();
+        assertEquals(1, rs.getInt(1));
+        rs.close();
+    }
+
+    @Test
     public void testDeleteFromLocalIndex() throws Exception {
         String tableName = schemaName + "." + generateUniqueName();
         String indexName = "IDX_" + generateUniqueName();
@@ -211,13 +231,13 @@ public class LocalIndexIT extends BaseLocalIndexIT {
                     QueryUtil.getExplainPlan(rs));
         rs.close();
 
-        // 4. Longer prefix on the index, use it.
+        // 4. Longer prefix on the index.
+        // Note: This cannot use the local index, see PHOENIX-6300
         rs = conn.createStatement().executeQuery("EXPLAIN SELECT v2 FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4 AND v1 = 3 AND v3 = 1");
         assertEquals(
             "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
-                    + physicalTableName + " [1,3,4,3]\n"
-                    + "    SERVER FILTER BY FIRST KEY ONLY AND \"V3\" = 1\n"
-                    + "CLIENT MERGE SORT",
+                    + physicalTableName + " [3,4]\n"
+                    + "    SERVER FILTER BY (V1 = 3.0 AND V3 = 1)",
                     QueryUtil.getExplainPlan(rs));
         rs.close();
     }
@@ -353,13 +373,12 @@ public class LocalIndexIT extends BaseLocalIndexIT {
                     QueryUtil.getExplainPlan(rs));
         rs.close();
 
-        // 10. Use index even when also filtering on non-indexed column
+        // 10. Cannot use index even when also filtering on non-indexed column, see PHOENIX-6400
         rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + tableName + " WHERE v2 = 2 AND v1 = 3");
         assertEquals(
-            "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
-                    + indexPhysicalTableName + " [1,2]\n"
-                            + "    SERVER FILTER BY FIRST KEY ONLY AND \"V1\" = 3.0\n"
-                            + "CLIENT MERGE SORT",
+            "CLIENT PARALLEL 1-WAY FULL SCAN OVER "
+                    + indexPhysicalTableName + "\n"
+                            + "    SERVER FILTER BY (V2 = 2.0 AND V1 = 3.0)",
                     QueryUtil.getExplainPlan(rs));
         rs.close();
 
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index a5fd6c3..558be36 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@ -59,6 +59,7 @@ import org.apache.phoenix.schema.ColumnRef;
 import org.apache.phoenix.schema.PColumnFamily;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTable.ImmutableStorageScheme;
+import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTable.QualifierEncodingScheme;
 import org.apache.phoenix.schema.PTable.ViewType;
 import org.apache.phoenix.schema.PTableType;
@@ -200,6 +201,16 @@ public class WhereCompiler {
                 return ref;
             }
             PTable table = ref.getTable();
+            // If current table in the context is local index and table in column reference is global that
+            // means the column is not present in the local index. Local indexes do not currently support this.
+            // Throwing this exception here will cause this plan to be ignored when enumerating possible plans
+            // during the optimizing phase.
+            if (context.getCurrentTable().getTable().getIndexType() == IndexType.LOCAL
+                    && (table.getIndexType() == null || table.getIndexType() == IndexType.GLOBAL)) {
+                String schemaNameStr = table.getSchemaName()==null?null:table.getSchemaName().getString();
+                String tableNameStr = table.getTableName()==null?null:table.getTableName().getString();
+                throw new ColumnNotFoundException(schemaNameStr, tableNameStr, null, ref.getColumn().getName().getString());
+            }
             // Track if we need to compare KeyValue during filter evaluation
             // using column family. If the column qualifier is enough, we
             // just use that.