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; + } }