You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by vj...@apache.org on 2021/03/14 11:12:44 UTC

[phoenix] branch 4.16 updated (010ca2b -> 2c88e28)

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

vjasani pushed a change to branch 4.16
in repository https://gitbox.apache.org/repos/asf/phoenix.git.


    from 010ca2b  PHOENIX-6385 : For non-small Scan, not to use Scan#setSmall for HBase 2.x versions (#1167)
     new b69c201  PHOENIX-6409 Include local index uncovered columns merge in explain plan.
     new 2c88e28  PHOENIX-6409 : Test with new Explain API for local index uncovered columns merge (ADDENDUM)

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../phoenix/end2end/CostBasedDecisionIT.java       |  4 +
 .../apache/phoenix/end2end/index/LocalIndexIT.java | 99 +++++++++++++++-------
 .../phoenix/end2end/index/MutableIndexIT.java      |  1 +
 .../apache/phoenix/end2end/index/ViewIndexIT.java  |  1 +
 .../phoenix/end2end/join/HashJoinLocalIndexIT.java |  3 +
 .../phoenix/compile/ExplainPlanAttributes.java     | 23 ++++-
 .../org/apache/phoenix/iterate/ExplainTable.java   |  9 ++
 7 files changed, 109 insertions(+), 31 deletions(-)


[phoenix] 01/02: PHOENIX-6409 Include local index uncovered columns merge in explain plan.

Posted by vj...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vjasani pushed a commit to branch 4.16
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit b69c2014c5501fc16988c79c1e8df7f97b6a721a
Author: Lars <la...@apache.org>
AuthorDate: Thu Mar 11 13:25:35 2021 -0800

    PHOENIX-6409 Include local index uncovered columns merge in explain plan.
---
 .../phoenix/end2end/CostBasedDecisionIT.java       |  4 ++++
 .../apache/phoenix/end2end/index/LocalIndexIT.java | 13 ++++++++++++
 .../phoenix/end2end/index/MutableIndexIT.java      |  1 +
 .../apache/phoenix/end2end/index/ViewIndexIT.java  |  1 +
 .../phoenix/end2end/join/HashJoinLocalIndexIT.java |  3 +++
 .../phoenix/compile/ExplainPlanAttributes.java     | 23 ++++++++++++++++++++--
 .../org/apache/phoenix/iterate/ExplainTable.java   |  9 +++++++++
 7 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java
index e2f5cfb..15414a8 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CostBasedDecisionIT.java
@@ -361,10 +361,12 @@ public class CostBasedDecisionIT extends BaseUniqueNamesOwnClusterIT {
             verifyQueryPlan(query,
                     "UNION ALL OVER 2 QUERIES\n" +
                     "    CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" +
+                    "        SERVER MERGE [0.C2]\n" +
                     "        SERVER FILTER BY FIRST KEY ONLY AND \"ROWKEY\" <= 'z'\n" +
                     "        SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"C1\"]\n" +
                     "    CLIENT MERGE SORT\n" +
                     "    CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" +
+                    "        SERVER MERGE [0.C2]\n" +
                     "        SERVER FILTER BY FIRST KEY ONLY AND \"ROWKEY\" >= 'a'\n" +
                     "        SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"C1\"]\n" +
                     "    CLIENT MERGE SORT");
@@ -413,11 +415,13 @@ public class CostBasedDecisionIT extends BaseUniqueNamesOwnClusterIT {
             // Use the optimal plan based on cost when stats become available.
             verifyQueryPlan(query,
                     "CLIENT PARALLEL 626-WAY RANGE SCAN OVER " + tableName + " [1,'X0'] - [1,'X1']\n" +
+                    "    SERVER MERGE [0.C2]\n" +
                     "    SERVER FILTER BY FIRST KEY ONLY\n" +
                     "    SERVER SORTED BY [\"T1.:ROWKEY\"]\n" +
                     "CLIENT MERGE SORT\n" +
                     "    PARALLEL INNER-JOIN TABLE 0\n" +
                     "        CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + tableName + " [1]\n" +
+                    "            SERVER MERGE [0.C2]\n" +
                     "            SERVER FILTER BY FIRST KEY ONLY AND \"ROWKEY\" <= 'z'\n" +
                     "            SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"C1\"]\n" +
                     "        CLIENT MERGE SORT\n" +
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 2de2c94..9bff734 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
@@ -308,6 +308,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         assertEquals(
             "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
                     + physicalTableName + " [1,3,4,3]\n"
+                    + "    SERVER MERGE [0.V3]\n"
                     + "    SERVER FILTER BY FIRST KEY ONLY AND \"V3\" = 1\n"
                     + "CLIENT MERGE SORT",
                     QueryUtil.getExplainPlan(rs));
@@ -337,6 +338,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         assertEquals(
             "CLIENT PARALLEL 16-WAY RANGE SCAN OVER "
                     + indexPhysicalTableName + " [1,2,3]\n"
+                    + "    SERVER MERGE [0.V1]\n"
                     + "    SERVER FILTER BY FIRST KEY ONLY\n"
                     + "CLIENT MERGE SORT",
                     QueryUtil.getExplainPlan(rs));
@@ -382,6 +384,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         assertEquals(
             "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
                     + indexPhysicalTableName + " [1]\n"
+                            + "    SERVER MERGE [0.V1]\n"
                             + "    SERVER FILTER BY FIRST KEY ONLY\n"
                             + "CLIENT MERGE SORT",
                     QueryUtil.getExplainPlan(rs));
@@ -402,6 +405,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         assertEquals(
             "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
                     + indexPhysicalTableName + " [1,2]\n"
+                            + "    SERVER MERGE [0.V1]\n"
                             + "    SERVER FILTER BY FIRST KEY ONLY\n"
                             + "CLIENT MERGE SORT",
                     QueryUtil.getExplainPlan(rs));
@@ -430,6 +434,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         assertEquals(
             "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
                     + indexPhysicalTableName + " [1,2]\n"
+                            + "    SERVER MERGE [0.V1]\n"
                             + "    SERVER FILTER BY FIRST KEY ONLY\n"
                             + "CLIENT MERGE SORT",
                     QueryUtil.getExplainPlan(rs));
@@ -440,6 +445,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         assertEquals(
             "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
                     + indexPhysicalTableName + " [1,2]\n"
+                            + "    SERVER MERGE [0.V1]\n"
                             + "    SERVER FILTER BY FIRST KEY ONLY AND TO_INTEGER(\"V4\") = 4\n"
                             + "CLIENT MERGE SORT",
                     QueryUtil.getExplainPlan(rs));
@@ -450,6 +456,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         assertEquals(
             "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
                     + indexPhysicalTableName + " [1,2]\n"
+                    + "    SERVER MERGE [0.V1]\n"
                     + "    SERVER FILTER BY FIRST KEY ONLY AND \"V1\" = 3.0\n"
                     + "CLIENT MERGE SORT",
                     QueryUtil.getExplainPlan(rs));
@@ -656,6 +663,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
                         + indexPhysicalTableName + " [1]\n"
+                                + "    SERVER MERGE [0.K3]\n"
                                 + "    SERVER FILTER BY FIRST KEY ONLY\n"
                                 + "CLIENT MERGE SORT",
                         QueryUtil.getExplainPlan(rs));
@@ -678,6 +686,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY REVERSE RANGE SCAN OVER "
                         + indexPhysicalTableName + " [1]\n"
+                                + "    SERVER MERGE [0.K3]\n"
                                 + "    SERVER FILTER BY FIRST KEY ONLY\n"
                                 + "CLIENT MERGE SORT",
                         QueryUtil.getExplainPlan(rs));
@@ -773,6 +782,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
                         + indexPhysicalTableName + " [1,'a']\n"
+                                + "    SERVER MERGE [0.K3]\n"
                                 + "    SERVER FILTER BY FIRST KEY ONLY\n"
                                 + "CLIENT MERGE SORT",
                         QueryUtil.getExplainPlan(rs));
@@ -796,6 +806,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
                         + indexPhysicalTableName +" [1,*] - [1,'z']\n"
+                        + "    SERVER MERGE [0.K3]\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                          + "CLIENT MERGE SORT",
                 QueryUtil.getExplainPlan(rs));
@@ -832,6 +843,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
                         + indexPhysicalTableName +" [1,*] - [1,'z']\n"
+                        + "    SERVER MERGE [0.K3]\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "    SERVER AGGREGATE INTO DISTINCT ROWS BY [\"V1\", \"T_ID\", \"K3\"]\nCLIENT MERGE SORT",
                 QueryUtil.getExplainPlan(rs));
@@ -860,6 +872,7 @@ public class LocalIndexIT extends BaseLocalIndexIT {
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
                         + indexPhysicalTableName +" [1,*] - [1,'z']\n"
+                        + "    SERVER MERGE [0.K3]\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "    SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"V1\"]\nCLIENT MERGE SORT",
                 QueryUtil.getExplainPlan(rs));
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java
index dfc7a8a..32d2bb6 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java
@@ -187,6 +187,7 @@ public class MutableIndexIT extends ParallelStatsDisabledIT {
                 query = "SELECT b.* from " + fullTableName + " where int_col1 = 4 AND char_col1 = 'chara'";
                 rs = conn.createStatement().executeQuery("EXPLAIN " + query);
                 assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + fullTableName +" [1,'chara',4]\n" +
+                        "    SERVER MERGE [B.VARCHAR_COL2, B.CHAR_COL2, B.INT_COL2, B.DECIMAL_COL2, B.DATE_COL]\n" +
                         "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
                 rs = conn.createStatement().executeQuery(query);
                 assertTrue(rs.next());
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 cbb6be2..4d9ea7f 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
@@ -239,6 +239,7 @@ public class ViewIndexIT extends SplitSystemCatalogIT {
             ResultSet rs = conn1.prepareStatement("EXPLAIN " + sql).executeQuery();
             assertEquals(
                 "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + SchemaUtil.getPhysicalTableName(Bytes.toBytes(fullTableName), isNamespaceMapped) + " [1,'10',100]\n" +
+                    "    SERVER MERGE [0.V1]\n" +
                     "    SERVER FILTER BY FIRST KEY ONLY\n" +
                     "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
             rs = conn1.prepareStatement(sql).executeQuery();
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java
index 6046677..0f9e00c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java
@@ -463,6 +463,7 @@ public class HashJoinLocalIndexIT extends HashJoinIT {
                  *     WHERE s.name = 'S1' AND i.name < 'T6'
                  */
                 "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SUPPLIER_TABLE_FULL_NAME + " [1,'S1']\n" + 
+                "    SERVER MERGE [0.PHONE]\n" +
                 "    SERVER FILTER BY FIRST KEY ONLY\n" + 
                 "CLIENT MERGE SORT\n" + 
                 "    PARALLEL INNER-JOIN TABLE 0\n" + 
@@ -479,6 +480,7 @@ public class HashJoinLocalIndexIT extends HashJoinIT {
                  *     GROUP BY phone
                  */
                 "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SUPPLIER_TABLE_FULL_NAME + " [1,'S1']\n" + 
+                "    SERVER MERGE [0.PHONE]\n" +
                 "    SERVER FILTER BY FIRST KEY ONLY\n" + 
                 "    SERVER AGGREGATE INTO DISTINCT ROWS BY [\"S.PHONE\"]\n" + 
                 "CLIENT MERGE SORT\n" + 
@@ -495,6 +497,7 @@ public class HashJoinLocalIndexIT extends HashJoinIT {
                  *     WHERE s.name <= 'S3'
                  */
                 "CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SUPPLIER_TABLE_FULL_NAME + " [1,*] - [1,'S3']\n" +
+                "    SERVER MERGE [0.PHONE]\n" +
                 "    SERVER FILTER BY FIRST KEY ONLY\n" + 
                 "    SERVER AGGREGATE INTO SINGLE ROW\n" +
                 "    PARALLEL LEFT-JOIN TABLE 0\n" +
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
index 855ce96..4e5856c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
@@ -18,9 +18,12 @@
 
 package org.apache.phoenix.compile;
 
+import java.util.Set;
+
 import org.apache.hadoop.hbase.client.Consistency;
 import org.apache.phoenix.parse.HintNode;
 import org.apache.phoenix.parse.HintNode.Hint;
+import org.apache.phoenix.schema.PColumn;
 
 /**
  * ExplainPlan attributes that contain individual attributes of ExplainPlan
@@ -69,6 +72,7 @@ public class ExplainPlanAttributes {
     // For non-Join queries related Plans, rhsJoinQueryExplainPlan will always
     // be null
     private final ExplainPlanAttributes rhsJoinQueryExplainPlan;
+    private Set<PColumn> serverMergeColumns;
 
     private static final ExplainPlanAttributes EXPLAIN_PLAN_INSTANCE =
         new ExplainPlanAttributes();
@@ -107,6 +111,7 @@ public class ExplainPlanAttributes {
         this.clientCursorName = null;
         this.clientSortAlgo = null;
         this.rhsJoinQueryExplainPlan = null;
+        this.serverMergeColumns = null;
     }
 
     public ExplainPlanAttributes(String abstractExplainPlan,
@@ -126,7 +131,8 @@ public class ExplainPlanAttributes {
             Integer clientOffset, Integer clientRowLimit,
             Integer clientSequenceCount, String clientCursorName,
             String clientSortAlgo,
-            ExplainPlanAttributes rhsJoinQueryExplainPlan) {
+            ExplainPlanAttributes rhsJoinQueryExplainPlan,
+            Set<PColumn> serverMergeColumns) {
         this.abstractExplainPlan = abstractExplainPlan;
         this.splitsChunk = splitsChunk;
         this.estimatedRows = estimatedRows;
@@ -160,6 +166,7 @@ public class ExplainPlanAttributes {
         this.clientCursorName = clientCursorName;
         this.clientSortAlgo = clientSortAlgo;
         this.rhsJoinQueryExplainPlan = rhsJoinQueryExplainPlan;
+        this.serverMergeColumns = serverMergeColumns;
     }
 
     public String getAbstractExplainPlan() {
@@ -294,6 +301,10 @@ public class ExplainPlanAttributes {
         return rhsJoinQueryExplainPlan;
     }
 
+    public Set<PColumn> getServerMergeColumns() {
+        return serverMergeColumns;
+    }
+
     public static ExplainPlanAttributes getDefaultExplainPlan() {
         return EXPLAIN_PLAN_INSTANCE;
     }
@@ -332,6 +343,7 @@ public class ExplainPlanAttributes {
         private String clientCursorName;
         private String clientSortAlgo;
         private ExplainPlanAttributes rhsJoinQueryExplainPlan;
+        private Set<PColumn> serverMergeColumns;
 
         public ExplainPlanAttributesBuilder() {
             // default
@@ -383,6 +395,7 @@ public class ExplainPlanAttributes {
             this.clientSortAlgo = explainPlanAttributes.getClientSortAlgo();
             this.rhsJoinQueryExplainPlan =
                 explainPlanAttributes.getRhsJoinQueryExplainPlan();
+            this.serverMergeColumns = explainPlanAttributes.getServerMergeColumns();
         }
 
         public ExplainPlanAttributesBuilder setAbstractExplainPlan(
@@ -580,6 +593,12 @@ public class ExplainPlanAttributes {
             return this;
         }
 
+        public ExplainPlanAttributesBuilder setServerMergeColumns(
+                Set<PColumn> columns) {
+            this.serverMergeColumns = columns;
+            return this;
+        }
+
         public ExplainPlanAttributes build() {
             return new ExplainPlanAttributes(abstractExplainPlan, splitsChunk,
                 estimatedRows, estimatedSizeInBytes, iteratorTypeAndScanSize,
@@ -592,7 +611,7 @@ public class ExplainPlanAttributes {
                 clientFilterBy, clientAggregate, clientSortedBy,
                 clientAfterAggregate, clientDistinctFilter, clientOffset,
                 clientRowLimit, clientSequenceCount, clientCursorName,
-                clientSortAlgo, rhsJoinQueryExplainPlan);
+                clientSortAlgo, rhsJoinQueryExplainPlan, serverMergeColumns);
         }
     }
 }
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
index 163364c..c3ab8f1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Set;
 
 import org.apache.hadoop.hbase.client.Consistency;
 import org.apache.hadoop.hbase.client.Scan;
@@ -44,6 +45,7 @@ import org.apache.phoenix.parse.HintNode;
 import org.apache.phoenix.parse.HintNode.Hint;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.KeyRange.Bound;
+import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.RowKeySchema;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableRef;
@@ -178,6 +180,13 @@ public abstract class ExplainTable {
                 }
             } while (filterIterator.hasNext());
         }
+        Set<PColumn> dataColumns = context.getDataColumns();
+        if (dataColumns != null && !dataColumns.isEmpty()) {
+            planSteps.add("    SERVER MERGE " + dataColumns.toString());
+            if (explainPlanAttributesBuilder != null) {
+                explainPlanAttributesBuilder.setServerMergeColumns(dataColumns);
+            }
+        }
         String whereFilterStr = null;
         if (whereFilter != null) {
             whereFilterStr = whereFilter.toString();


[phoenix] 02/02: PHOENIX-6409 : Test with new Explain API for local index uncovered columns merge (ADDENDUM)

Posted by vj...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vjasani pushed a commit to branch 4.16
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 2c88e28a8162c568ef79b653059a04fc6b37ac76
Author: Viraj Jasani <vj...@apache.org>
AuthorDate: Sun Mar 14 16:25:29 2021 +0530

    PHOENIX-6409 : Test with new Explain API for local index uncovered columns merge (ADDENDUM)
---
 .../apache/phoenix/end2end/index/LocalIndexIT.java | 88 ++++++++++++++--------
 .../phoenix/compile/ExplainPlanAttributes.java     |  2 +-
 2 files changed, 59 insertions(+), 31 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 9bff734..9f79107 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
@@ -54,11 +54,14 @@ import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.FSUtils;
 import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.compile.ExplainPlan;
+import org.apache.phoenix.compile.ExplainPlanAttributes;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
 import org.apache.phoenix.end2end.ExplainPlanWithStatsEnabledIT.Estimate;
 import org.apache.phoenix.hbase.index.IndexRegionSplitPolicy;
 import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
 import org.apache.phoenix.jdbc.PhoenixResultSet;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.QueryConstants;
@@ -277,42 +280,67 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         conn.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(pk1,pk2,v1,v2)");
 
         // 1. same prefix length, no other restrictions, but v3 is in the SELECT. Use the main table.
-        ResultSet rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4");
-        assertEquals(
-            "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
-                    + physicalTableName + " [3,4]",
-                    QueryUtil.getExplainPlan(rs));
-        rs.close();
+        ExplainPlan explainPlan = conn.prepareStatement("SELECT * FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4")
+                .unwrap(PhoenixPreparedStatement.class).optimizeQuery()
+                .getExplainPlan();
+        ExplainPlanAttributes explainPlanAttributes =
+                explainPlan.getPlanStepsAsAttributes();
+        assertEquals("PARALLEL 1-WAY",
+                explainPlanAttributes.getIteratorTypeAndScanSize());
+        assertEquals("RANGE SCAN ",
+                explainPlanAttributes.getExplainScanType());
+        assertEquals(physicalTableName.toString(), explainPlanAttributes.getTableName());
+        assertEquals(" [3,4]", explainPlanAttributes.getKeyRanges());
 
         // 2. same prefix length, no other restrictions. Only index columns used. Use the index.
-        rs = conn.createStatement().executeQuery("EXPLAIN SELECT v2 FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4");
-        assertEquals(
-                "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
-                        + indexPhysicalTableName + " [1,3,4]\n"
-                                + "    SERVER FILTER BY FIRST KEY ONLY\n"
-                                + "CLIENT MERGE SORT",
-                        QueryUtil.getExplainPlan(rs));
-        rs.close();
+        explainPlan = conn.prepareStatement("SELECT v2 FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4")
+                .unwrap(PhoenixPreparedStatement.class).optimizeQuery()
+                .getExplainPlan();
+        explainPlanAttributes =
+                explainPlan.getPlanStepsAsAttributes();
+        assertEquals("PARALLEL 1-WAY",
+                explainPlanAttributes.getIteratorTypeAndScanSize());
+        assertEquals("RANGE SCAN ",
+                explainPlanAttributes.getExplainScanType());
+        assertEquals(indexPhysicalTableName, explainPlanAttributes.getTableName());
+        assertEquals(" [1,3,4]", explainPlanAttributes.getKeyRanges());
+        assertEquals("SERVER FILTER BY FIRST KEY ONLY",
+                explainPlanAttributes.getServerWhereFilter());
+        assertEquals("CLIENT MERGE SORT",
+                explainPlanAttributes.getClientSortAlgo());
 
         // 3. same prefix length, but there's a column not on the index
-        rs = conn.createStatement().executeQuery("EXPLAIN SELECT v2 FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4 AND v3 = 1");
-        assertEquals(
-            "CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
-                    + physicalTableName + " [3,4]\n"
-                    + "    SERVER FILTER BY V3 = 1",
-                    QueryUtil.getExplainPlan(rs));
-        rs.close();
+        explainPlan = conn.prepareStatement("SELECT v2 FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4 AND v3 = 1")
+                .unwrap(PhoenixPreparedStatement.class).optimizeQuery()
+                .getExplainPlan();
+        explainPlanAttributes =
+                explainPlan.getPlanStepsAsAttributes();
+        assertEquals("PARALLEL 1-WAY",
+                explainPlanAttributes.getIteratorTypeAndScanSize());
+        assertEquals("RANGE SCAN ",
+                explainPlanAttributes.getExplainScanType());
+        assertEquals(physicalTableName.toString(), explainPlanAttributes.getTableName());
+        assertEquals(" [3,4]", explainPlanAttributes.getKeyRanges());
+        assertEquals("SERVER FILTER BY V3 = 1",
+                explainPlanAttributes.getServerWhereFilter());
 
         // 4. Longer prefix on the index, use it.
-        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 MERGE [0.V3]\n"
-                    + "    SERVER FILTER BY FIRST KEY ONLY AND \"V3\" = 1\n"
-                    + "CLIENT MERGE SORT",
-                    QueryUtil.getExplainPlan(rs));
-        rs.close();
+        explainPlan = conn.prepareStatement("SELECT v2 FROM " + tableName + " WHERE pk1 = 3 AND pk2 = 4 AND v1 = 3 AND v3 = 1")
+                .unwrap(PhoenixPreparedStatement.class).optimizeQuery()
+                .getExplainPlan();
+        explainPlanAttributes =
+                explainPlan.getPlanStepsAsAttributes();
+        assertEquals("PARALLEL 1-WAY",
+                explainPlanAttributes.getIteratorTypeAndScanSize());
+        assertEquals("RANGE SCAN ",
+                explainPlanAttributes.getExplainScanType());
+        assertEquals(physicalTableName.toString(), explainPlanAttributes.getTableName());
+        assertEquals(" [1,3,4,3]", explainPlanAttributes.getKeyRanges());
+        assertEquals("[0.V3]", explainPlanAttributes.getServerMergeColumns().toString());
+        assertEquals("SERVER FILTER BY FIRST KEY ONLY AND \"V3\" = 1",
+                explainPlanAttributes.getServerWhereFilter());
+        assertEquals("CLIENT MERGE SORT",
+                explainPlanAttributes.getClientSortAlgo());
     }
 
     @Test
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
index 4e5856c..258a7ee 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
@@ -72,7 +72,7 @@ public class ExplainPlanAttributes {
     // For non-Join queries related Plans, rhsJoinQueryExplainPlan will always
     // be null
     private final ExplainPlanAttributes rhsJoinQueryExplainPlan;
-    private Set<PColumn> serverMergeColumns;
+    private final Set<PColumn> serverMergeColumns;
 
     private static final ExplainPlanAttributes EXPLAIN_PLAN_INSTANCE =
         new ExplainPlanAttributes();