You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2015/03/04 23:40:37 UTC
[02/50] [abbrv] phoenix git commit: PHOENIX-1610 Incorrect subquery
results caused by unpaired contextStack push/pop
PHOENIX-1610 Incorrect subquery results caused by unpaired contextStack push/pop
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/1c58f442
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/1c58f442
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/1c58f442
Branch: refs/heads/calcite
Commit: 1c58f442dea6c19745a119f53e47e78ce9e2ef76
Parents: d058a41
Author: maryannxue <we...@intel.com>
Authored: Thu Jan 29 11:42:24 2015 -0500
Committer: maryannxue <we...@intel.com>
Committed: Thu Jan 29 11:42:24 2015 -0500
----------------------------------------------------------------------
.../apache/phoenix/end2end/DerivedTableIT.java | 9 +++
.../org/apache/phoenix/end2end/HashJoinIT.java | 52 ++++++++--------
.../org/apache/phoenix/end2end/SubqueryIT.java | 10 ++--
.../end2end/SubqueryUsingSortMergeJoinIT.java | 10 ++--
phoenix-core/src/main/antlr3/PhoenixSQL.g | 6 +-
.../apache/phoenix/compile/QueryCompiler.java | 12 ++--
.../apache/phoenix/execute/HashJoinPlan.java | 63 ++++----------------
.../phoenix/expression/InListExpression.java | 9 +--
.../apache/phoenix/join/HashCacheClient.java | 58 +++++++++++++++---
.../apache/phoenix/optimize/QueryOptimizer.java | 2 +-
.../java/org/apache/phoenix/parse/HintNode.java | 8 +--
11 files changed, 120 insertions(+), 119 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
index 727293f..7a418bd 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
@@ -667,6 +667,15 @@ public class DerivedTableIT extends BaseClientManagedTimeIT {
assertEquals(2,rs.getInt(1));
assertFalse(rs.next());
+
+ // count (subquery)
+ query = "SELECT count(*) FROM (SELECT * FROM aTable WHERE (organization_id, entity_id) in (SELECT organization_id, entity_id FROM aTable WHERE a_byte != 8)) AS t";
+ statement = conn.prepareStatement(query);
+ rs = statement.executeQuery();
+ assertTrue (rs.next());
+ assertEquals(8,rs.getInt(1));
+
+ assertFalse(rs.next());
} finally {
conn.close();
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
index 9a95ea4..a699d48 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
@@ -229,7 +229,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (I2.item_id)",
+ " DYNAMIC SERVER FILTER BY item_id IN (I2.item_id)",
/*
* testSelfJoin()
* SELECT i1.name, i2.name FROM joinItemTable i1
@@ -241,7 +241,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT MERGE SORT\n" +
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (I2.supplier_id)",
+ " DYNAMIC SERVER FILTER BY item_id IN (I2.supplier_id)",
/*
* testStarJoin()
* SELECT order_id, c.name, i.name iname, quantity, o.date
@@ -270,7 +270,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + "\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (O.item_id)",
+ " DYNAMIC SERVER FILTER BY item_id IN (O.item_id)",
/*
* testSubJoin()
* SELECT * FROM joinCustomerTable c
@@ -415,11 +415,11 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " DYNAMIC SERVER FILTER BY supplier_id BETWEEN MIN/MAX OF (I.supplier_id)\n" +
+ " DYNAMIC SERVER FILTER BY supplier_id IN (I.supplier_id)\n" +
" JOIN-SCANNER 4 ROW LIMIT",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col1 = rhs.col2
*/
@@ -430,7 +430,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT MERGE SORT",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col2
*/
@@ -442,7 +442,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" DYNAMIC SERVER FILTER BY COL0 IN (RHS.COL2)",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col1 AND lhs.col1 = rhs.col2
*/
@@ -454,7 +454,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" DYNAMIC SERVER FILTER BY (COL0, COL1) IN ((RHS.COL1, RHS.COL2))",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col1 AND lhs.col2 = rhs.col3 - 1 AND lhs.col1 = rhs.col2
*/
@@ -592,7 +592,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (I2.:item_id)",
+ " DYNAMIC SERVER FILTER BY item_id IN (I2.:item_id)",
/*
* testSelfJoin()
* SELECT i1.name, i2.name FROM joinItemTable i1
@@ -782,11 +782,11 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_SCHEMA + ".idx_item\n" +
" PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " DYNAMIC SERVER FILTER BY supplier_id BETWEEN MIN/MAX OF (I.0:supplier_id)\n" +
+ " DYNAMIC SERVER FILTER BY supplier_id IN (I.0:supplier_id)\n" +
" JOIN-SCANNER 4 ROW LIMIT",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col1 = rhs.col2
*/
@@ -797,7 +797,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT MERGE SORT",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col2
*/
@@ -809,7 +809,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" DYNAMIC SERVER FILTER BY COL0 IN (RHS.COL2)",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col1 AND lhs.col1 = rhs.col2
*/
@@ -821,7 +821,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" DYNAMIC SERVER FILTER BY (COL0, COL1) IN ((RHS.COL1, RHS.COL2))",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col1 AND lhs.col2 = rhs.col3 - 1 AND lhs.col1 = rhs.col2
*/
@@ -970,7 +970,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER "+ MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+ JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (I2.:item_id)",
+ " DYNAMIC SERVER FILTER BY item_id IN (I2.:item_id)",
/*
* testSelfJoin()
* SELECT i1.name, i2.name FROM joinItemTable i1
@@ -984,7 +984,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" PARALLEL INNER-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+ JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (I2.0:supplier_id)",
+ " DYNAMIC SERVER FILTER BY item_id IN (I2.0:supplier_id)",
/*
* testStarJoin()
* SELECT order_id, c.name, i.name iname, quantity, o.date
@@ -1020,7 +1020,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_CUSTOMER_TABLE_DISPLAY_NAME+" [-32768]\n"+
" SERVER FILTER BY FIRST KEY ONLY\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (O.item_id)",
+ " DYNAMIC SERVER FILTER BY item_id IN (O.item_id)",
/*
* testSubJoin()
* SELECT * FROM joinCustomerTable c
@@ -1172,11 +1172,11 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT MERGE SORT\n" +
" PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " DYNAMIC SERVER FILTER BY supplier_id BETWEEN MIN/MAX OF (I.0:supplier_id)\n" +
+ " DYNAMIC SERVER FILTER BY supplier_id IN (I.0:supplier_id)\n" +
" JOIN-SCANNER 4 ROW LIMIT",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col1 = rhs.col2
*/
@@ -1187,7 +1187,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT MERGE SORT",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col2
*/
@@ -1199,7 +1199,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" DYNAMIC SERVER FILTER BY COL0 IN (RHS.COL2)",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col1 AND lhs.col1 = rhs.col2
*/
@@ -1211,7 +1211,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" DYNAMIC SERVER FILTER BY (COL0, COL1) IN ((RHS.COL1, RHS.COL2))",
/*
* testJoinWithKeyRangeOptimization()
- * SELECT (*SKIP_SCAN_HASH_JOIN*) lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
+ * SELECT lhs.col0, lhs.col1, lhs.col2, rhs.col0, rhs.col1, rhs.col2
* FROM TEMP_TABLE_COMPOSITE_PK lhs
* JOIN TEMP_TABLE_COMPOSITE_PK rhs ON lhs.col0 = rhs.col1 AND lhs.col2 = rhs.col3 - 1 AND lhs.col1 = rhs.col2
*/
@@ -3549,7 +3549,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
conn.commit();
// No leading part of PK
- String query = "SELECT /*+ SKIP_SCAN_HASH_JOIN*/ lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ String query = "SELECT lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ tempTableWithCompositePK + " lhs JOIN "
+ tempTableWithCompositePK + " rhs ON lhs.col1 = rhs.col2";
PreparedStatement statement = conn.prepareStatement(query);
@@ -3579,7 +3579,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
assertEquals(plans[21], QueryUtil.getExplainPlan(rs));
// Two parts of PK but only one leading part
- query = "SELECT /*+ SKIP_SCAN_HASH_JOIN*/ lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ query = "SELECT lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ tempTableWithCompositePK + " lhs JOIN "
+ tempTableWithCompositePK + " rhs ON lhs.col2 = rhs.col3 AND lhs.col0 = rhs.col2";
statement = conn.prepareStatement(query);
@@ -3600,7 +3600,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
assertEquals(plans[22], QueryUtil.getExplainPlan(rs));
// Two leading parts of PK
- query = "SELECT /*+ SKIP_SCAN_HASH_JOIN*/ lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ query = "SELECT lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ tempTableWithCompositePK + " lhs JOIN "
+ tempTableWithCompositePK + " rhs ON lhs.col1 = rhs.col2 AND lhs.col0 = rhs.col1";
statement = conn.prepareStatement(query);
@@ -3630,7 +3630,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
assertEquals(plans[23], QueryUtil.getExplainPlan(rs));
// All parts of PK
- query = "SELECT /*+ SKIP_SCAN_HASH_JOIN*/ lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ query = "SELECT lhs.col0, lhs.col1, lhs.col2, lhs.col3, rhs.col0, rhs.col1, rhs.col2, rhs.col3 FROM "
+ tempTableWithCompositePK + " lhs JOIN "
+ tempTableWithCompositePK + " rhs ON lhs.col1 = rhs.col2 AND lhs.col2 = rhs.col3 - 1 AND lhs.col0 = rhs.col1";
statement = conn.prepareStatement(query);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
index 066790c..85e562c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryIT.java
@@ -139,11 +139,11 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id, NAME\\]\n" +
" CLIENT MERGE SORT\n" +
- " PARALLEL SEMI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
+ " SKIP-SCAN-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(\\$\\d+.\\$\\d+\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(\\$\\d+.\\$\\d+\\)\n" +
" AFTER-JOIN SERVER FILTER BY \\(\\$\\d+.\\$\\d+ IS NOT NULL OR \\$\\d+.\\$\\d+ IS NOT NULL\\)",
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
@@ -165,7 +165,7 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(O.item_id\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(O.item_id\\)\n" +
" AFTER-JOIN SERVER FILTER BY \\(I.NAME = 'T2' OR O.QUANTITY > \\$\\d+.\\$\\d+\\)\n" +
" DYNAMIC SERVER FILTER BY customer_id IN \\(\\$\\d+.\\$\\d+\\)"
}});
@@ -289,7 +289,7 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(\\$\\d+.\\$\\d+\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(\\$\\d+.\\$\\d+\\)\n" +
" AFTER-JOIN SERVER FILTER BY \\(\\$\\d+.\\$\\d+ IS NOT NULL OR \\$\\d+.\\$\\d+ IS NOT NULL\\)",
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
@@ -314,7 +314,7 @@ public class SubqueryIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(O.item_id\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(O.item_id\\)\n" +
" AFTER-JOIN SERVER FILTER BY \\(I.0:NAME = 'T2' OR O.QUANTITY > \\$\\d+.\\$\\d+\\)\n" +
" DYNAMIC SERVER FILTER BY customer_id IN \\(\\$\\d+.\\$\\d+\\)"
}});
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
index bbb84ba..82b1c68 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
@@ -143,11 +143,11 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id, NAME\\]\n" +
" CLIENT MERGE SORT\n" +
" CLIENT SORTED BY \\[item_id, NAME\\]\n" +
- " PARALLEL SEMI-JOIN TABLE 0 \\(SKIP MERGE\\)\n" +
+ " SKIP-SCAN-JOIN TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(\\$\\d+.\\$\\d+\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(\\$\\d+.\\$\\d+\\)\n" +
"CLIENT FILTER BY \\(\\$\\d+.\\$\\d+ IS NOT NULL OR \\$\\d+.\\$\\d+ IS NOT NULL\\)",
"SORT-MERGE-JOIN \\(SEMI\\) TABLES\n" +
@@ -163,7 +163,7 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(O.item_id\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(O.item_id\\)\n" +
" AFTER-JOIN SERVER FILTER BY \\(I.NAME = 'T2' OR O.QUANTITY > \\$\\d+.\\$\\d+\\)",
}});
testCases.add(new String[][] {
@@ -285,7 +285,7 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(\\$\\d+.\\$\\d+\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(\\$\\d+.\\$\\d+\\)\n" +
"CLIENT FILTER BY \\(\\$\\d+.\\$\\d+ IS NOT NULL OR \\$\\d+.\\$\\d+ IS NOT NULL\\)",
"SORT-MERGE-JOIN \\(SEMI\\) TABLES\n" +
@@ -305,7 +305,7 @@ public class SubqueryUsingSortMergeJoinIT extends BaseHBaseManagedTimeIT {
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY \\[item_id\\]\n" +
" CLIENT MERGE SORT\n" +
- " DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF \\(O.item_id\\)\n" +
+ " DYNAMIC SERVER FILTER BY item_id IN \\(O.item_id\\)\n" +
" AFTER-JOIN SERVER FILTER BY \\(I.0:NAME = 'T2' OR O.QUANTITY > \\$\\d+.\\$\\d+\\)",
}});
return testCases;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/main/antlr3/PhoenixSQL.g
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index 0a4ea7a..bcf26be 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -362,8 +362,9 @@ non_select_node returns [BindableStatement ret]
| s=create_sequence_node
| s=drop_sequence_node
| s=update_statistics_node
- | s=explain_node) { contextStack.pop(); $ret = s; }
+ | s=explain_node) { $ret = s; }
;
+finally{ contextStack.pop(); }
explain_node returns [BindableStatement ret]
: EXPLAIN q=oneStatement {$ret=factory.explain(q);}
@@ -567,8 +568,9 @@ select_node returns [SelectStatement ret]
(HAVING having=expression)?
(ORDER BY order=order_by)?
(LIMIT l=limit)?
- { ParseContext context = contextStack.pop(); $ret = factory.select(from, null, d!=null, sel, where, group, having, order, l, getBindCount(), context.isAggregate(), context.hasSequences()); }
+ { ParseContext context = contextStack.peek(); $ret = factory.select(from, null, d!=null, sel, where, group, having, order, l, getBindCount(), context.isAggregate(), context.hasSequences()); }
;
+finally{ contextStack.pop(); }
// Parse a full select expression structure.
hinted_select_node returns [SelectStatement ret]
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 014e73a..9642489 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -101,6 +101,7 @@ public class QueryCompiler {
private final ParallelIteratorFactory parallelIteratorFactory;
private final SequenceManager sequenceManager;
private final boolean useSortMergeJoin;
+ private final boolean noChildParentJoinOptimization;
public QueryCompiler(PhoenixStatement statement, SelectStatement select, ColumnResolver resolver) throws SQLException {
this(statement, select, resolver, Collections.<PDatum>emptyList(), null, new SequenceManager(statement));
@@ -115,6 +116,7 @@ public class QueryCompiler {
this.parallelIteratorFactory = parallelIteratorFactory;
this.sequenceManager = sequenceManager;
this.useSortMergeJoin = select.getHint().hasHint(Hint.USE_SORT_MERGE_JOIN);
+ this.noChildParentJoinOptimization = select.getHint().hasHint(Hint.NO_CHILD_PARENT_JOIN_OPTIMIZATION);
if (statement.getConnection().getQueryServices().getLowestClusterHBaseVersion() >= PhoenixDatabaseMetaData.ESSENTIAL_FAMILY_VERSION_THRESHOLD) {
this.scan.setAttribute(LOAD_COLUMN_FAMILIES_ON_DEMAND_ATTR, QueryConstants.TRUE);
}
@@ -259,16 +261,14 @@ public class QueryCompiler {
joinExpressions[i] = joinConditions.getFirst();
List<Expression> hashExpressions = joinConditions.getSecond();
Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null);
- boolean complete = getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), tableRef, joinSpec.getType(), joinExpressions[i], hashExpressions);
+ boolean optimized = getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), tableRef, joinSpec.getType(), joinExpressions[i], hashExpressions);
Expression keyRangeLhsExpression = keyRangeExpressions.getFirst();
Expression keyRangeRhsExpression = keyRangeExpressions.getSecond();
- boolean hasFilters = joinSpec.getJoinTable().hasFilters();
- boolean optimized = complete && hasFilters;
joinTypes[i] = joinSpec.getType();
if (i < count - 1) {
fieldPositions[i + 1] = fieldPositions[i] + (tables[i] == null ? 0 : (tables[i].getColumns().size() - tables[i].getPKColumns().size()));
}
- subPlans[i] = new HashSubPlan(i, joinPlan, optimized ? null : hashExpressions, joinSpec.isSingleValueOnly(), keyRangeLhsExpression, keyRangeRhsExpression, hasFilters);
+ subPlans[i] = new HashSubPlan(i, joinPlan, optimized ? null : hashExpressions, joinSpec.isSingleValueOnly(), keyRangeLhsExpression, keyRangeRhsExpression);
}
if (needsProject) {
TupleProjector.serializeProjectorIntoScan(context.getScan(), initialProjectedTable.createTupleProjector());
@@ -339,7 +339,7 @@ public class QueryCompiler {
HashJoinInfo joinInfo = new HashJoinInfo(projectedTable.getTable(), joinIds, new List[] {joinExpressions}, new JoinType[] {type == JoinType.Right ? JoinType.Left : type}, new boolean[] {true}, new PTable[] {lhsTable}, new int[] {fieldPosition}, postJoinFilterExpression, limit, forceProjection);
Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null);
getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), rhsTableRef, type, joinExpressions, hashExpressions);
- return HashJoinPlan.create(joinTable.getStatement(), rhsPlan, joinInfo, new HashSubPlan[] {new HashSubPlan(0, lhsPlan, hashExpressions, false, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond(), lhsJoin.hasFilters())});
+ return HashJoinPlan.create(joinTable.getStatement(), rhsPlan, joinInfo, new HashSubPlan[] {new HashSubPlan(0, lhsPlan, hashExpressions, false, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond())});
}
JoinTable lhsJoin = joinTable.getSubJoinTableWithoutPostFilters();
@@ -395,7 +395,7 @@ public class QueryCompiler {
}
private boolean getKeyExpressionCombinations(Pair<Expression, Expression> combination, StatementContext context, SelectStatement select, TableRef table, JoinType type, final List<Expression> joinExpressions, final List<Expression> hashExpressions) throws SQLException {
- if (type != JoinType.Inner && type != JoinType.Semi)
+ if ((type != JoinType.Inner && type != JoinType.Semi) || this.noChildParentJoinOptimization)
return false;
Scan scanCopy = ScanUtil.newScan(context.getScan());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
index db2a29d..aea075d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
@@ -31,7 +31,6 @@ import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.client.Scan;
-import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.cache.ServerCacheClient.ServerCache;
import org.apache.phoenix.compile.ColumnProjector;
@@ -44,8 +43,6 @@ import org.apache.phoenix.compile.StatementContext;
import org.apache.phoenix.compile.WhereCompiler;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
-import org.apache.phoenix.expression.AndExpression;
-import org.apache.phoenix.expression.ComparisonExpression;
import org.apache.phoenix.expression.Determinism;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.InListExpression;
@@ -58,7 +55,6 @@ import org.apache.phoenix.job.JobManager.JobCallable;
import org.apache.phoenix.join.HashCacheClient;
import org.apache.phoenix.join.HashJoinInfo;
import org.apache.phoenix.parse.FilterableStatement;
-import org.apache.phoenix.parse.HintNode.Hint;
import org.apache.phoenix.parse.ParseNode;
import org.apache.phoenix.parse.SQLParser;
import org.apache.phoenix.parse.SelectStatement;
@@ -82,8 +78,6 @@ public class HashJoinPlan extends DelegateQueryPlan {
private final HashJoinInfo joinInfo;
private final SubPlan[] subPlans;
private final boolean recompileWhereClause;
- private final boolean forceHashJoinRangeScan;
- private final boolean forceHashJoinSkipScan;
private List<SQLCloseable> dependencies;
private HashCacheClient hashClient;
private int maxServerCacheTimeToLive;
@@ -115,8 +109,6 @@ public class HashJoinPlan extends DelegateQueryPlan {
this.joinInfo = joinInfo;
this.subPlans = subPlans;
this.recompileWhereClause = recompileWhereClause;
- this.forceHashJoinRangeScan = plan.getStatement().getHint().hasHint(Hint.RANGE_SCAN_HASH_JOIN);
- this.forceHashJoinSkipScan = plan.getStatement().getHint().hasHint(Hint.SKIP_SCAN_HASH_JOIN);
}
@Override
@@ -200,39 +192,14 @@ public class HashJoinPlan extends DelegateQueryPlan {
}
private Expression createKeyRangeExpression(Expression lhsExpression,
- Expression rhsExpression, List<ImmutableBytesWritable> rhsValues,
- ImmutableBytesWritable ptr, boolean hasFilters) throws SQLException {
+ Expression rhsExpression, List<Expression> rhsValues,
+ ImmutableBytesWritable ptr) throws SQLException {
if (rhsValues.isEmpty())
- return LiteralExpression.newConstant(false, PBoolean.INSTANCE, Determinism.ALWAYS);
+ return LiteralExpression.newConstant(false, PBoolean.INSTANCE, Determinism.ALWAYS);
- PDataType type = rhsExpression.getDataType();
- if (!useInClause(hasFilters)) {
- ImmutableBytesWritable minValue = rhsValues.get(0);
- ImmutableBytesWritable maxValue = rhsValues.get(0);
- for (ImmutableBytesWritable value : rhsValues) {
- if (value.compareTo(minValue) < 0) {
- minValue = value;
- }
- if (value.compareTo(maxValue) > 0) {
- maxValue = value;
- }
- }
-
- return AndExpression.create(Lists.newArrayList(
- ComparisonExpression.create(CompareOp.GREATER_OR_EQUAL, Lists.newArrayList(lhsExpression, LiteralExpression.newConstant(type.toObject(minValue), type)), ptr),
- ComparisonExpression.create(CompareOp.LESS_OR_EQUAL, Lists.newArrayList(lhsExpression, LiteralExpression.newConstant(type.toObject(maxValue), type)), ptr)));
- }
+ rhsValues.add(0, lhsExpression);
- List<Expression> children = Lists.newArrayList(lhsExpression);
- for (ImmutableBytesWritable value : rhsValues) {
- children.add(LiteralExpression.newConstant(type.toObject(value), type));
- }
-
- return InListExpression.create(children, false, ptr, false);
- }
-
- private boolean useInClause(boolean hasFilters) {
- return this.forceHashJoinSkipScan || (!this.forceHashJoinRangeScan && hasFilters);
+ return InListExpression.create(rhsValues, false, ptr);
}
@Override
@@ -345,29 +312,26 @@ public class HashJoinPlan extends DelegateQueryPlan {
private final boolean singleValueOnly;
private final Expression keyRangeLhsExpression;
private final Expression keyRangeRhsExpression;
- private final boolean hasFilters;
public HashSubPlan(int index, QueryPlan subPlan,
List<Expression> hashExpressions,
boolean singleValueOnly,
Expression keyRangeLhsExpression,
- Expression keyRangeRhsExpression,
- boolean hasFilters) {
+ Expression keyRangeRhsExpression) {
this.index = index;
this.plan = subPlan;
this.hashExpressions = hashExpressions;
this.singleValueOnly = singleValueOnly;
this.keyRangeLhsExpression = keyRangeLhsExpression;
this.keyRangeRhsExpression = keyRangeRhsExpression;
- this.hasFilters = hasFilters;
}
@Override
public Object execute(HashJoinPlan parent) throws SQLException {
ScanRanges ranges = parent.delegate.getContext().getScanRanges();
- List<ImmutableBytesWritable> keyRangeRhsValues = null;
+ List<Expression> keyRangeRhsValues = null;
if (keyRangeRhsExpression != null) {
- keyRangeRhsValues = Lists.<ImmutableBytesWritable>newArrayList();
+ keyRangeRhsValues = Lists.<Expression>newArrayList();
}
ServerCache cache = null;
if (hashExpressions != null) {
@@ -383,15 +347,11 @@ public class HashJoinPlan extends DelegateQueryPlan {
ResultIterator iterator = plan.iterator();
for (Tuple result = iterator.next(); result != null; result = iterator.next()) {
// Evaluate key expressions for hash join key range optimization.
- ImmutableBytesWritable value = new ImmutableBytesWritable();
- keyRangeRhsExpression.reset();
- if (keyRangeRhsExpression.evaluate(result, value)) {
- keyRangeRhsValues.add(value);
- }
+ keyRangeRhsValues.add(HashCacheClient.evaluateKeyExpression(keyRangeRhsExpression, result, plan.getContext().getTempPtr()));
}
}
if (keyRangeRhsValues != null) {
- parent.keyRangeExpressions.add(parent.createKeyRangeExpression(keyRangeLhsExpression, keyRangeRhsExpression, keyRangeRhsValues, plan.getContext().getTempPtr(), hasFilters));
+ parent.keyRangeExpressions.add(parent.createKeyRangeExpression(keyRangeLhsExpression, keyRangeRhsExpression, keyRangeRhsValues, plan.getContext().getTempPtr()));
}
return cache;
}
@@ -430,8 +390,7 @@ public class HashJoinPlan extends DelegateQueryPlan {
return Collections.<String> emptyList();
String step = " DYNAMIC SERVER FILTER BY " + keyRangeLhsExpression.toString()
- + (parent.useInClause(hasFilters) ? " IN " : " BETWEEN MIN/MAX OF ")
- + "(" + keyRangeRhsExpression.toString() + ")";
+ + " IN (" + keyRangeRhsExpression.toString() + ")";
return Collections.<String> singletonList(step);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
index 772db97..63178db 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/InListExpression.java
@@ -58,19 +58,12 @@ public class InListExpression extends BaseSingleExpression {
private List<Expression> keyExpressions; // client side only
public static Expression create (List<Expression> children, boolean isNegate, ImmutableBytesWritable ptr) throws SQLException {
- return create(children, isNegate, ptr, true);
- }
-
- public static Expression create (List<Expression> children, boolean isNegate, ImmutableBytesWritable ptr, boolean allowShortcut) throws SQLException {
Expression firstChild = children.get(0);
if (firstChild.isStateless() && (!firstChild.evaluate(null, ptr) || ptr.getLength() == 0)) {
return LiteralExpression.newConstant(null, PBoolean.INSTANCE, firstChild.getDeterminism());
}
- // We set allowShortcut to false for child/parent join optimization since we
- // compare RVC expressions with literal expressions and we want to avoid
- // RVC-rewrite operation in ComparisonExpression.create().
- if (allowShortcut && children.size() == 2) {
+ if (children.size() == 2) {
return ComparisonExpression.create(isNegate ? CompareOp.NOT_EQUAL : CompareOp.EQUAL, children, ptr);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/main/java/org/apache/phoenix/join/HashCacheClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/join/HashCacheClient.java b/phoenix-core/src/main/java/org/apache/phoenix/join/HashCacheClient.java
index 6494603..f13b28e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/join/HashCacheClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/join/HashCacheClient.java
@@ -30,18 +30,22 @@ import org.apache.phoenix.cache.ServerCacheClient.ServerCache;
import org.apache.phoenix.compile.ScanRanges;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.ExpressionType;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.RowValueConstructorExpression;
import org.apache.phoenix.iterate.ResultIterator;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.util.ServerUtil;
import org.apache.phoenix.util.TrustedByteArrayOutputStream;
import org.apache.phoenix.util.TupleUtil;
-
import org.iq80.snappy.Snappy;
+import com.google.common.collect.Lists;
+
/**
*
* Client for adding cache of one side of a join to region servers
@@ -70,7 +74,7 @@ public class HashCacheClient {
* @throws MaxServerCacheSizeExceededException if size of hash cache exceeds max allowed
* size
*/
- public ServerCache addHashCache(ScanRanges keyRanges, ResultIterator iterator, long estimatedSize, List<Expression> onExpressions, boolean singleValueOnly, TableRef cacheUsingTableRef, Expression keyRangeRhsExpression, List<ImmutableBytesWritable> keyRangeRhsValues) throws SQLException {
+ public ServerCache addHashCache(ScanRanges keyRanges, ResultIterator iterator, long estimatedSize, List<Expression> onExpressions, boolean singleValueOnly, TableRef cacheUsingTableRef, Expression keyRangeRhsExpression, List<Expression> keyRangeRhsValues) throws SQLException {
/**
* Serialize and compress hashCacheTable
*/
@@ -79,7 +83,7 @@ public class HashCacheClient {
return serverCache.addServerCache(keyRanges, ptr, new HashCacheFactory(), cacheUsingTableRef);
}
- private void serialize(ImmutableBytesWritable ptr, ResultIterator iterator, long estimatedSize, List<Expression> onExpressions, boolean singleValueOnly, Expression keyRangeRhsExpression, List<ImmutableBytesWritable> keyRangeRhsValues) throws SQLException {
+ private void serialize(ImmutableBytesWritable ptr, ResultIterator iterator, long estimatedSize, List<Expression> onExpressions, boolean singleValueOnly, Expression keyRangeRhsExpression, List<Expression> keyRangeRhsValues) throws SQLException {
long maxSize = serverCache.getConnection().getQueryServices().getProps().getLong(QueryServices.MAX_SERVER_CACHE_SIZE_ATTRIB, QueryServicesOptions.DEFAULT_MAX_SERVER_CACHE_SIZE);
estimatedSize = Math.min(estimatedSize, maxSize);
if (estimatedSize > Integer.MAX_VALUE) {
@@ -98,6 +102,7 @@ public class HashCacheClient {
out.writeInt(exprSize * (singleValueOnly ? -1 : 1));
int nRows = 0;
out.writeInt(nRows); // In the end will be replaced with total number of rows
+ ImmutableBytesWritable tempPtr = new ImmutableBytesWritable();
for (Tuple result = iterator.next(); result != null; result = iterator.next()) {
TupleUtil.write(result, out);
if (baOut.size() > maxSize) {
@@ -105,11 +110,7 @@ public class HashCacheClient {
}
// Evaluate key expressions for hash join key range optimization.
if (keyRangeRhsExpression != null) {
- ImmutableBytesWritable value = new ImmutableBytesWritable();
- keyRangeRhsExpression.reset();
- if (keyRangeRhsExpression.evaluate(result, value)) {
- keyRangeRhsValues.add(value);
- }
+ keyRangeRhsValues.add(evaluateKeyExpression(keyRangeRhsExpression, result, tempPtr));
}
nRows++;
}
@@ -136,4 +137,45 @@ public class HashCacheClient {
iterator.close();
}
}
+
+ /**
+ * Evaluate the RHS key expression and wrap the result as a new Expression.
+ * Unlike other types of Expression which will be evaluated and wrapped as a
+ * single LiteralExpression, RowValueConstructorExpression should be handled
+ * differently. We should evaluate each child of RVC and wrap them into a new
+ * RVC Expression, in order to make sure that the later coercion between the
+ * LHS key expression and this RHS key expression will be successful.
+ *
+ * @param keyExpression the RHS key expression
+ * @param tuple the input tuple
+ * @param ptr the temporary pointer
+ * @return the Expression containing the evaluated result
+ * @throws SQLException
+ */
+ public static Expression evaluateKeyExpression(Expression keyExpression, Tuple tuple, ImmutableBytesWritable ptr) throws SQLException {
+ if (!(keyExpression instanceof RowValueConstructorExpression)) {
+ PDataType type = keyExpression.getDataType();
+ keyExpression.reset();
+ if (keyExpression.evaluate(tuple, ptr)) {
+ return LiteralExpression.newConstant(type.toObject(ptr), type);
+ }
+
+ return LiteralExpression.newConstant(null, type);
+ }
+
+ List<Expression> children = keyExpression.getChildren();
+ List<Expression> values = Lists.newArrayListWithExpectedSize(children.size());
+ for (Expression child : children) {
+ PDataType type = child.getDataType();
+ child.reset();
+ if (child.evaluate(tuple, ptr)) {
+ values.add(LiteralExpression.newConstant(type.toObject(ptr), type));
+ } else {
+ values.add(LiteralExpression.newConstant(null, type));
+ }
+ }
+ // The early evaluation of this constant expression is not necessary, for it
+ // might be coerced later.
+ return new RowValueConstructorExpression(values, false);
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
index 7a2d313..9c5c2cd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
@@ -291,7 +291,7 @@ public class QueryOptimizer {
if (extractedCondition != null) {
outerWhere = FACTORY.and(Lists.newArrayList(outerWhere, extractedCondition));
}
- HintNode hint = HintNode.combine(HintNode.subtract(indexSelect.getHint(), new Hint[] {Hint.INDEX, Hint.RANGE_SCAN_HASH_JOIN}), FACTORY.hint("NO_INDEX SKIP_SCAN_HASH_JOIN"));
+ HintNode hint = HintNode.combine(HintNode.subtract(indexSelect.getHint(), new Hint[] {Hint.INDEX, Hint.NO_CHILD_PARENT_JOIN_OPTIMIZATION}), FACTORY.hint("NO_INDEX"));
SelectStatement query = FACTORY.select(dataSelect, hint, outerWhere);
ColumnResolver queryResolver = FromCompiler.getResolverForQuery(query, statement.getConnection());
query = SubqueryRewriter.transform(query, queryResolver, statement.getConnection());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/1c58f442/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java
index 5ee8016..94f9bfb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java
@@ -47,13 +47,9 @@ public class HintNode {
*/
SKIP_SCAN,
/**
- * Forces a range scan when full or partial primary key is used as join keys.
+ * Prevents the usage of child-parent-join optimization.
*/
- RANGE_SCAN_HASH_JOIN,
- /**
- * Forces a skip scan when full or partial primary key is used as join keys.
- */
- SKIP_SCAN_HASH_JOIN,
+ NO_CHILD_PARENT_JOIN_OPTIMIZATION,
/**
* Prevents the usage of indexes, forcing usage
* of the data table for a query.