You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ya...@apache.org on 2020/07/17 04:42:38 UTC
[phoenix] branch master updated: PHOENIX-5924 RVC Offset does not
handle variable length fields exclusive scan boundary correctly
This is an automated email from the ASF dual-hosted git repository.
yanxinyi 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 28eb698 PHOENIX-5924 RVC Offset does not handle variable length fields exclusive scan boundary correctly
28eb698 is described below
commit 28eb6980a668dc3d98d387692aedf7bec863b6c7
Author: Daniel Wong <da...@salesforce.com>
AuthorDate: Thu Jul 16 18:21:37 2020 -0700
PHOENIX-5924 RVC Offset does not handle variable length fields exclusive scan boundary correctly
Signed-off-by: Xinyi Yan <xy...@salesforce.com>
---
.../end2end/RowValueConstructorOffsetIT.java | 39 ++++++++++++++++++++++
.../apache/phoenix/compile/RVCOffsetCompiler.java | 27 +++++++++++++--
2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java
index b91997b..38d4557 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java
@@ -30,6 +30,8 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
import org.apache.phoenix.compile.QueryPlan;
@@ -1011,4 +1013,41 @@ public class RowValueConstructorOffsetIT extends ParallelStatsDisabledIT {
}
}
+ @Test
+ public void rvcOffsetTrailingVariableLengthKeyTest() throws Exception {
+ String TEST_DDL = "CREATE TABLE IF NOT EXISTS TEST_SCHEMA (\n"
+ + " ORGANIZATION_ID VARCHAR(15), \n" + " TEST_ID VARCHAR(15), \n"
+ + " CREATED_DATE DATE, \n" + " LAST_UPDATE DATE\n"
+ + " CONSTRAINT TEST_SCHEMA_PK PRIMARY KEY (ORGANIZATION_ID, TEST_ID) \n" + ")";
+
+ try (Statement statement = conn.createStatement()) {
+ statement.execute(TEST_DDL);
+ }
+ //setup
+ List<String> upserts = new ArrayList<>();
+ upserts.add("UPSERT INTO TEST_SCHEMA(ORGANIZATION_ID,TEST_ID) VALUES ('1','1')");
+ upserts.add("UPSERT INTO TEST_SCHEMA(ORGANIZATION_ID,TEST_ID) VALUES ('1','10')");
+ upserts.add("UPSERT INTO TEST_SCHEMA(ORGANIZATION_ID,TEST_ID) VALUES ('2','2')");
+
+ for(String sql : upserts) {
+ try (Statement statement = conn.createStatement())
+
+ { statement.execute(sql); }
+ }
+
+ conn.commit();
+
+ String query = "SELECT * FROM TEST_SCHEMA OFFSET (ORGANIZATION_ID,TEST_ID) = ('1','1')";
+
+ try (Statement statement = conn.createStatement() ; ResultSet rs2 = statement.executeQuery(query) ) {
+ assertTrue(rs2.next());
+ assertEquals("1",rs2.getString(1));
+ assertEquals("10",rs2.getString(2));
+ assertTrue(rs2.next());
+ assertEquals("2",rs2.getString(1));
+ assertEquals("2",rs2.getString(2));
+ assertFalse(rs2.next());
+ }
+ }
+
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/RVCOffsetCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/RVCOffsetCompiler.java
index cc1cbe6..e665e3d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/RVCOffsetCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/RVCOffsetCompiler.java
@@ -19,6 +19,7 @@ package org.apache.phoenix.compile;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.phoenix.expression.AndExpression;
import org.apache.phoenix.expression.CoerceExpression;
@@ -37,12 +38,13 @@ import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.RowKeySchema;
import org.apache.phoenix.schema.RowValueConstructorOffsetInternalErrorException;
import org.apache.phoenix.schema.RowValueConstructorOffsetNotAllowedInQueryException;
import org.apache.phoenix.schema.RowValueConstructorOffsetNotCoercibleException;
import org.apache.phoenix.schema.TypeMismatchException;
-import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.ScanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -251,11 +253,32 @@ public class RVCOffsetCompiler {
"RVC Offset must be a point lookup.");
}
+
+ RowKeySchema.RowKeySchemaBuilder builder = new RowKeySchema.RowKeySchemaBuilder(columns.size());
+
+ for(PColumn column : columns) {
+ builder.addField(column, column.isNullable(), column.getSortOrder());
+ }
+
+ RowKeySchema rowKeySchema = builder.build();
+
+ //we make a ScanRange with 1 keyslots that cover the entire PK to reuse the code
+ KeyRange pointKeyRange = scanRanges.getScanRange();
+ KeyRange keyRange = KeyRange.getKeyRange(pointKeyRange.getLowerRange(), false, KeyRange.UNBOUND, true);
+ List<KeyRange> myRangeList = Lists.newArrayList(keyRange);
+ List<List<KeyRange>> slots = new ArrayList<>();
+ slots.add(myRangeList);
+ int[] slotSpan = new int[1];
+
+ //subtract 1 see ScanUtil.SINGLE_COLUMN_SLOT_SPAN is 0
+ slotSpan[0] = columns.size() - 1;
+ byte[] key = ScanUtil.getMinKey(rowKeySchema,slots,slotSpan);
+
// Note the use of ByteUtil.nextKey() to generate exclusive offset
CompiledOffset
compiledOffset =
new CompiledOffset(Optional.<Integer>absent(),
- Optional.of(ByteUtil.nextKey(scanRanges.getScanRange().getLowerRange())));
+ Optional.of(key));
return compiledOffset;
}