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