PHOENIX-4917 Fix ClassCastException when projecting array elements in hash join


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/cea1c710
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/cea1c710
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/cea1c710

Branch: refs/heads/4.x-cdh5.15
Commit: cea1c710d79b7a1d3b9b7da765ff465b50efe4bf
Parents: 8774744
Author: Gerald Sangudi <gsang...@23andme.com>
Authored: Sun Sep 23 17:01:18 2018 +0100
Committer: Pedro Boado <pbo...@apache.org>
Committed: Wed Oct 17 22:49:38 2018 +0100

----------------------------------------------------------------------
 .../coprocessor/HashJoinRegionScanner.java      | 50 ++++++++++++++++----
 1 file changed, 42 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/cea1c710/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
index 96af154..70eaa03 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
@@ -50,6 +50,7 @@ import org.apache.phoenix.schema.ValueBitSet;
 import org.apache.phoenix.schema.tuple.MultiKeyValueTuple;
 import org.apache.phoenix.schema.tuple.PositionBasedResultTuple;
 import org.apache.phoenix.schema.tuple.ResultTuple;
+import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.ServerUtil;
 import org.apache.phoenix.util.TupleUtil;
@@ -207,19 +208,19 @@ public class HashJoinRegionScanner implements 
RegionScanner {
                         }
                         if (tempTuples[i] == null) {
                             Tuple joined = tempSrcBitSet[i] == 
ValueBitSet.EMPTY_VALUE_BITSET ?
-                                    lhs : TupleProjector.mergeProjectedValue(
-                                            (ProjectedValueTuple) lhs, schema, 
tempDestBitSet,
-                                            null, joinInfo.getSchemas()[i], 
tempSrcBitSet[i],
-                                            joinInfo.getFieldPositions()[i], 
useNewValueColumnQualifier);
+                                    lhs : mergeProjectedValue(
+                                            lhs, schema, tempDestBitSet, null,
+                                            joinInfo.getSchemas()[i], 
tempSrcBitSet[i],
+                                            joinInfo.getFieldPositions()[i]);
                             offerResult(joined, projected, result);
                             continue;
                         }
                         for (Tuple t : tempTuples[i]) {
                             Tuple joined = tempSrcBitSet[i] == 
ValueBitSet.EMPTY_VALUE_BITSET ?
-                                    lhs : TupleProjector.mergeProjectedValue(
-                                            (ProjectedValueTuple) lhs, schema, 
tempDestBitSet,
-                                            t, joinInfo.getSchemas()[i], 
tempSrcBitSet[i],
-                                            joinInfo.getFieldPositions()[i], 
useNewValueColumnQualifier);
+                                    lhs : mergeProjectedValue(
+                                            lhs, schema, tempDestBitSet, t,
+                                            joinInfo.getSchemas()[i], 
tempSrcBitSet[i],
+                                            joinInfo.getFieldPositions()[i]);
                             offerResult(joined, projected, result);
                         }
                     }
@@ -353,4 +354,37 @@ public class HashJoinRegionScanner implements 
RegionScanner {
         MultiKeyValueTuple multi = new MultiKeyValueTuple(cells);
         resultQueue.offer(multi);
     }
+
+    // PHOENIX-4917 Merge array element cell through hash join.
+    // Merge into first cell, then reattach array cell.
+    private Tuple mergeProjectedValue(
+        Tuple dest, KeyValueSchema destSchema, ValueBitSet destBitSet, Tuple 
src,
+        KeyValueSchema srcSchema, ValueBitSet srcBitSet, int offset)
+        throws IOException {
+
+        if (dest instanceof ProjectedValueTuple) {
+            return TupleProjector.mergeProjectedValue(
+                (ProjectedValueTuple) dest, destSchema, destBitSet, src,
+                srcSchema, srcBitSet, offset, useNewValueColumnQualifier);
+        }
+
+        ProjectedValueTuple first = projector.projectResults(
+            new SingleKeyValueTuple(dest.getValue(0)));
+        ProjectedValueTuple merged = TupleProjector.mergeProjectedValue(
+            first, destSchema, destBitSet, src, srcSchema,
+            srcBitSet, offset, useNewValueColumnQualifier);
+
+        int size = dest.size();
+        if (size == 1) {
+            return merged;
+        }
+
+        List<Cell> cells = new ArrayList<Cell>(size);
+        cells.add(merged.getValue(0));
+        for (int i = 1; i < size; i++) {
+            cells.add(dest.getValue(i));
+        }
+        MultiKeyValueTuple multi = new MultiKeyValueTuple(cells);
+        return multi;
+    }
 }

Reply via email to