You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ch...@apache.org on 2019/06/02 05:55:20 UTC
[phoenix] branch master updated: PHOENIX-5307 Fix
HashJoinMoreIT.testBug2961 failing after PHOENIX-5262
This is an automated email from the ASF dual-hosted git repository.
chenglei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/master by this push:
new 27bc714 PHOENIX-5307 Fix HashJoinMoreIT.testBug2961 failing after PHOENIX-5262
27bc714 is described below
commit 27bc7140de826929fdad4c4027b609dc20b0dbe3
Author: chenglei <ch...@apache.org>
AuthorDate: Sun Jun 2 13:54:41 2019 +0800
PHOENIX-5307 Fix HashJoinMoreIT.testBug2961 failing after PHOENIX-5262
---
.../java/org/apache/phoenix/util/ScanUtil.java | 11 +-
.../apache/phoenix/compile/WhereCompilerTest.java | 60 +++++++++++
.../java/org/apache/phoenix/util/ScanUtilTest.java | 117 +++++++++++++++++++++
3 files changed, 185 insertions(+), 3 deletions(-)
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
index 131d98b..0a37411 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
@@ -447,10 +447,15 @@ public class ScanUtil {
&& (fieldIndex < schema.getMaxFields() || inclusiveUpper || exclusiveLower) ) ) ) {
key[offset++] = sepByte;
// Set lastInclusiveUpperSingleKey back to false if this is the last pk column
- // as we don't want to increment the null byte in this case
+ // as we don't want to increment the QueryConstants.SEPARATOR_BYTE byte in this case.
// To test if this is the last pk column we need to consider the span of this slot
- // and the field index to see if this slot considers the last column
- lastInclusiveUpperSingleKey &= (fieldIndex + slotSpan[i]) < schema.getMaxFields()-1;
+ // and the field index to see if this slot considers the last column.
+ // But if last field of rowKey is variable length and also DESC, the trailing 0xFF
+ // is not removed when stored in HBASE, so for such case, we should not set
+ // lastInclusiveUpperSingleKey back to false.
+ if(sepByte != QueryConstants.DESC_SEPARATOR_BYTE) {
+ lastInclusiveUpperSingleKey &= (fieldIndex + slotSpan[i]) < schema.getMaxFields()-1;
+ }
}
if (exclusiveUpper) {
// Cannot include anything else on the key, as otherwise
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
index b84ead0..ce3135b 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
@@ -38,6 +38,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.math.BigDecimal;
+import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.SQLException;
@@ -70,6 +71,7 @@ import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.RowKeyValueAccessor;
import org.apache.phoenix.schema.SaltingUtil;
+import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.schema.types.PChar;
import org.apache.phoenix.schema.types.PLong;
@@ -80,6 +82,7 @@ import org.apache.phoenix.util.NumberUtil;
import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.util.StringUtil;
+import org.apache.phoenix.util.TestUtil;
import org.junit.Ignore;
import org.junit.Test;
@@ -1023,4 +1026,61 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
assertEquals(FETCH_SIZE, pstmt.getFetchSize());
assertEquals(FETCH_SIZE, scan.getCaching());
}
+
+ @Test
+ public void testLastPkColumnIsVariableLengthAndDescBug5307() throws Exception {
+ Connection conn = null;
+ try {
+ conn = DriverManager.getConnection(getUrl());
+ String sql = "CREATE TABLE t1 (\n" +
+ "OBJECT_VERSION VARCHAR NOT NULL,\n" +
+ "LOC VARCHAR,\n" +
+ "CONSTRAINT PK PRIMARY KEY (OBJECT_VERSION DESC))";
+ conn.createStatement().execute(sql);
+
+ byte[] startKey = ByteUtil.concat(
+ PVarchar.INSTANCE.toBytes("2222", SortOrder.DESC),
+ QueryConstants.DESC_SEPARATOR_BYTE_ARRAY);
+ byte[] endKey = ByteUtil.concat(
+ PVarchar.INSTANCE.toBytes("1111", SortOrder.DESC),
+ QueryConstants.DESC_SEPARATOR_BYTE_ARRAY);
+ ByteUtil.nextKey(endKey, endKey.length);
+ sql = "SELECT /*+ RANGE_SCAN */ OBJ.OBJECT_VERSION, OBJ.LOC from t1 AS OBJ "+
+ "where OBJ.OBJECT_VERSION in ('1111','2222')";
+ QueryPlan queryPlan = TestUtil.getOptimizeQueryPlan(conn, sql);
+ Scan scan = queryPlan.getContext().getScan();
+ assertArrayEquals(startKey, scan.getStartRow());
+ assertArrayEquals(endKey, scan.getStopRow());
+
+ sql = "CREATE TABLE t2 (\n" +
+ "OBJECT_ID VARCHAR NOT NULL,\n" +
+ "OBJECT_VERSION VARCHAR NOT NULL,\n" +
+ "LOC VARCHAR,\n" +
+ "CONSTRAINT PK PRIMARY KEY (OBJECT_ID, OBJECT_VERSION DESC))";
+ conn.createStatement().execute(sql);
+
+ startKey = ByteUtil.concat(
+ PVarchar.INSTANCE.toBytes("obj1", SortOrder.ASC),
+ QueryConstants.SEPARATOR_BYTE_ARRAY,
+ PVarchar.INSTANCE.toBytes("2222", SortOrder.DESC),
+ QueryConstants.DESC_SEPARATOR_BYTE_ARRAY);
+ endKey = ByteUtil.concat(
+ PVarchar.INSTANCE.toBytes("obj3", SortOrder.ASC),
+ QueryConstants.SEPARATOR_BYTE_ARRAY,
+ PVarchar.INSTANCE.toBytes("1111", SortOrder.DESC),
+ QueryConstants.DESC_SEPARATOR_BYTE_ARRAY);
+ ByteUtil.nextKey(endKey, endKey.length);
+ sql = "SELECT OBJ.OBJECT_ID, OBJ.OBJECT_VERSION, OBJ.LOC from t2 AS OBJ "+
+ "where (OBJ.OBJECT_ID, OBJ.OBJECT_VERSION) in (('obj1', '2222'),('obj2', '1111'),('obj3', '1111'))";
+ queryPlan = TestUtil.getOptimizeQueryPlan(conn, sql);
+ scan = queryPlan.getContext().getScan();
+ assertArrayEquals(startKey, scan.getStartRow());
+ assertArrayEquals(endKey, scan.getStopRow());
+ }
+ finally {
+ if(conn != null) {
+ conn.close();
+ }
+ }
+ }
}
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/ScanUtilTest.java b/phoenix-core/src/test/java/org/apache/phoenix/util/ScanUtilTest.java
index 6310640..2d1afba 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/ScanUtilTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/ScanUtilTest.java
@@ -19,6 +19,7 @@ package org.apache.phoenix.util;
import static org.junit.Assert.assertArrayEquals;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -348,5 +349,121 @@ public class ScanUtilTest {
System.arraycopy(key, 0, actualKey, 0, offset);
assertArrayEquals(new byte[] { 0, 5, 0 }, actualKey);
}
+
+ @Test
+ public void testLastPkColumnIsVariableLengthAndDescBug5307() throws Exception{
+ RowKeySchemaBuilder rowKeySchemaBuilder = new RowKeySchemaBuilder(2);
+
+ rowKeySchemaBuilder.addField(new PDatum() {
+ @Override
+ public boolean isNullable() {
+ return false;
+ }
+
+ @Override
+ public PDataType getDataType() {
+ return PVarchar.INSTANCE;
+ }
+
+ @Override
+ public Integer getMaxLength() {
+ return null;
+ }
+
+ @Override
+ public Integer getScale() {
+ return null;
+ }
+
+ @Override
+ public SortOrder getSortOrder() {
+ return SortOrder.getDefault();
+ }
+ }, false, SortOrder.getDefault());
+
+ rowKeySchemaBuilder.addField(new PDatum() {
+ @Override
+ public boolean isNullable() {
+ return false;
+ }
+
+ @Override
+ public PDataType getDataType() {
+ return PVarchar.INSTANCE;
+ }
+
+ @Override
+ public Integer getMaxLength() {
+ return null;
+ }
+
+ @Override
+ public Integer getScale() {
+ return null;
+ }
+
+ @Override
+ public SortOrder getSortOrder() {
+ return SortOrder.DESC;
+ }
+ }, false, SortOrder.DESC);
+
+ rowKeySchemaBuilder.rowKeyOrderOptimizable(true);
+ RowKeySchema rowKeySchema = rowKeySchemaBuilder.build();
+ //it is [[obj1, obj2, obj3], [\xCD\xCD\xCD\xCD, \xCE\xCE\xCE\xCE, \xCE\xCE\xCE\xCE]]
+ List<List<KeyRange>> rowKeySlotRangesList = Arrays.asList(
+ Arrays.asList(
+ KeyRange.getKeyRange(PVarchar.INSTANCE.toBytes("obj1", SortOrder.ASC)),
+ KeyRange.getKeyRange(PVarchar.INSTANCE.toBytes("obj2", SortOrder.ASC)),
+ KeyRange.getKeyRange(PVarchar.INSTANCE.toBytes("obj3", SortOrder.ASC))),
+ Arrays.asList(
+ KeyRange.getKeyRange(PVarchar.INSTANCE.toBytes("2222", SortOrder.DESC)),
+ KeyRange.getKeyRange(PVarchar.INSTANCE.toBytes("1111", SortOrder.DESC)),
+ KeyRange.getKeyRange(PVarchar.INSTANCE.toBytes("1111", SortOrder.DESC))));
+
+ int[] rowKeySlotSpans = new int[]{0,0};
+ byte[] rowKey = new byte[1024];
+ int[] rowKeySlotRangesIndexes = new int[]{0,0};
+ int rowKeyLength = ScanUtil.setKey(
+ rowKeySchema,
+ rowKeySlotRangesList,
+ rowKeySlotSpans,
+ rowKeySlotRangesIndexes,
+ Bound.LOWER,
+ rowKey,
+ 0,
+ 0,
+ 2);
+ byte[] startKey = Arrays.copyOf(rowKey, rowKeyLength);
+
+ rowKeySlotRangesIndexes = new int[]{2,2};
+ rowKey = new byte[1024];
+ rowKeyLength = ScanUtil.setKey(
+ rowKeySchema,
+ rowKeySlotRangesList,
+ rowKeySlotSpans,
+ rowKeySlotRangesIndexes,
+ Bound.UPPER,
+ rowKey,
+ 0,
+ 0,
+ 2);
+ byte[] endKey = Arrays.copyOf(rowKey, rowKeyLength);
+
+ byte[] expectedStartKey = ByteUtil.concat(
+ PVarchar.INSTANCE.toBytes("obj1", SortOrder.ASC),
+ QueryConstants.SEPARATOR_BYTE_ARRAY,
+ PVarchar.INSTANCE.toBytes("2222", SortOrder.DESC),
+ QueryConstants.DESC_SEPARATOR_BYTE_ARRAY);
+ byte[] expectedEndKey = ByteUtil.concat(
+ PVarchar.INSTANCE.toBytes("obj3", SortOrder.ASC),
+ QueryConstants.SEPARATOR_BYTE_ARRAY,
+ PVarchar.INSTANCE.toBytes("1111", SortOrder.DESC),
+ QueryConstants.DESC_SEPARATOR_BYTE_ARRAY);
+ ByteUtil.nextKey(expectedEndKey, expectedEndKey.length);
+
+ assertArrayEquals(expectedStartKey, startKey);
+ assertArrayEquals(expectedEndKey, endKey);
+ }
}
}