You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by go...@apache.org on 2022/03/04 01:02:09 UTC
[phoenix] branch master updated: PHOENIX-6659 RVC query fix for variable column + fixed column
This is an automated email from the ASF dual-hosted git repository.
gokcen 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 74e4548 PHOENIX-6659 RVC query fix for variable column + fixed column
74e4548 is described below
commit 74e4548117c7e26715d2b14dd3768b1043801aca
Author: Gokcen Iskender <gi...@salesforce.com>
AuthorDate: Wed Mar 2 19:30:11 2022 -0800
PHOENIX-6659 RVC query fix for variable column + fixed column
Signed-off-by: Gokcen Iskender <go...@gmail.com>
---
.../phoenix/end2end/RowValueConstructorIT.java | 2 +-
.../apache/phoenix/end2end/SkipScanQueryIT.java | 97 ++++++++++++++++++++++
.../org/apache/phoenix/compile/WhereOptimizer.java | 13 +--
3 files changed, 106 insertions(+), 6 deletions(-)
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java
index f03e436..47d6327 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java
@@ -369,7 +369,7 @@ public class RowValueConstructorIT extends ParallelStatsDisabledIT {
count++;
}
// we have key values (7,5) (8,4) and (9,3) present in aTable. So the query should return the 3 records.
- assertTrue(count == 3);
+ assertEquals(3, count);
} finally {
conn.close();
}
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java
index 3c835a5..74c9300 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SkipScanQueryIT.java
@@ -42,8 +42,10 @@ import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.compile.ExplainPlan;
import org.apache.phoenix.compile.QueryPlan;
import org.apache.phoenix.filter.SkipScanFilter;
+import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.util.TestUtil;
import org.apache.phoenix.util.SchemaUtil;
@@ -717,6 +719,101 @@ public class SkipScanQueryIT extends ParallelStatsDisabledIT {
}
@Test
+ public void testRVCBug6659() throws Exception {
+ String tableName = generateUniqueName();
+ String ddl = "CREATE TABLE " + tableName + " (PK1 VARCHAR NOT NULL, PK2 INTEGER NOT NULL, " +
+ "PK3 BIGINT NOT NULL CONSTRAINT PK PRIMARY KEY (PK1,PK2,PK3))";
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ conn.createStatement().execute(ddl);
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a',0,1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a',1,1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a',2,1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a',3,1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a',3,2)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a',4,1)");
+ conn.commit();
+ String query = "SELECT * FROM " + tableName +
+ " WHERE (PK1 = 'a') AND (PK1,PK2,PK3) <= ('a',3,1)";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ int rowCnt = 0;
+ do {
+ rowCnt++;
+ } while (rs.next());
+ assertEquals(4, rowCnt);
+ }
+ }
+
+ @Test
+ public void testRVCBug6659_Delete() throws Exception {
+ String tableName = generateUniqueName();
+ String ddl = "CREATE TABLE " + tableName + " (PK1 DOUBLE NOT NULL, PK2 INTEGER NOT NULL, " +
+ " CONSTRAINT PK PRIMARY KEY (PK1,PK2))";
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ conn.createStatement().execute(ddl);
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(10.0,10)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(20.0,20)");
+ conn.commit();
+ String query = "DELETE FROM " + tableName +
+ " WHERE (PK1,PK2) IN ((10.0, 10),(20.0, 20))";
+ conn.createStatement().execute(query);
+ conn.commit();
+ ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + tableName);
+ assertFalse(rs.next());
+ }
+ }
+
+ @Test
+ public void testRVCBug6659_AllVarchar() throws Exception {
+ String tableName = generateUniqueName();
+ String ddl = "CREATE TABLE " + tableName + " (PK1 VARCHAR NOT NULL, PK2 VARCHAR NOT NULL, " +
+ "PK3 BIGINT NOT NULL CONSTRAINT PK PRIMARY KEY (PK1,PK2,PK3))";
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ conn.createStatement().execute(ddl);
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a','0',1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a','1',1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a','3',1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a','3',2)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES('a','4',1)");
+ conn.commit();
+ String query = "SELECT * FROM " + tableName +
+ " WHERE (PK1 = 'a') AND (PK1,PK2,PK3) <= ('a','3',1)";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ int rowCnt = 0;
+ do {
+ rowCnt++;
+ } while (rs.next());
+ assertEquals(3, rowCnt);
+ }
+ }
+
+ @Test
+ public void testRVCBug6659_IntVarcharBigint() throws Exception {
+ String tableName = generateUniqueName();
+ String ddl = "CREATE TABLE " + tableName + " (PK1 INTEGER NOT NULL, PK2 VARCHAR NOT NULL, " +
+ "PK3 BIGINT NOT NULL CONSTRAINT PK PRIMARY KEY (PK1,PK2,PK3))";
+ try (Connection conn = DriverManager.getConnection(getUrl())) {
+ conn.createStatement().execute(ddl);
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(1,'0',1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(1,'1',1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(1,'3',1)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(1,'3',2)");
+ conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES(1,'4',1)");
+ conn.commit();
+ String query = "SELECT * FROM " + tableName +
+ " WHERE (PK1 = 1) AND (PK1,PK2,PK3) <= (1,'3',1)";
+ ResultSet rs = conn.createStatement().executeQuery(query);
+ assertTrue(rs.next());
+ int rowCnt = 0;
+ do {
+ rowCnt++;
+ } while (rs.next());
+ assertEquals(3, rowCnt);
+ }
+ }
+
+ @Test
public void testKeyRangesContainsAllValues() throws Exception {
String tableName = generateUniqueName();
String ddl = "CREATE TABLE IF NOT EXISTS " + tableName + "(" +
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java
index 65bbbfd..e0f5da3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java
@@ -29,6 +29,7 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import org.apache.phoenix.expression.DelegateExpression;
import org.apache.phoenix.thirdparty.com.google.common.base.Optional;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
@@ -361,8 +362,10 @@ public class WhereOptimizer {
}
}
- private static KeyRange getTrailingRange(RowKeySchema rowKeySchema, int pkPos, KeyRange range, KeyRange clippedResult, ImmutableBytesWritable ptr) {
- int separatorLength = rowKeySchema.getField(pkPos).getDataType().isFixedWidth() ? 0 : 1;
+ private static KeyRange getTrailingRange(RowKeySchema rowKeySchema, int clippedPkPos, KeyRange range, KeyRange clippedResult, ImmutableBytesWritable ptr) {
+ // We are interested in the clipped part's Seperator. Since we combined first part, we need to
+ // remove its separator from the trailing parts' start
+ int clippedSepLength= rowKeySchema.getField(clippedPkPos).getDataType().isFixedWidth() ? 0 : 1;
byte[] lowerRange = KeyRange.UNBOUND;
boolean lowerInclusive = false;
// Lower range of trailing part of RVC must be true, so we can form a new range to intersect going forward
@@ -370,7 +373,7 @@ public class WhereOptimizer {
&& range.getLowerRange().length > clippedResult.getLowerRange().length
&& Bytes.startsWith(range.getLowerRange(), clippedResult.getLowerRange())) {
lowerRange = range.getLowerRange();
- int offset = clippedResult.getLowerRange().length + separatorLength;
+ int offset = clippedResult.getLowerRange().length + clippedSepLength;
ptr.set(lowerRange, offset, lowerRange.length - offset);
lowerRange = ptr.copyBytes();
lowerInclusive = range.isLowerInclusive();
@@ -381,7 +384,7 @@ public class WhereOptimizer {
&& range.getUpperRange().length > clippedResult.getUpperRange().length
&& Bytes.startsWith(range.getUpperRange(), clippedResult.getUpperRange())) {
upperRange = range.getUpperRange();
- int offset = clippedResult.getUpperRange().length + separatorLength;
+ int offset = clippedResult.getUpperRange().length + clippedSepLength;
ptr.set(upperRange, offset, upperRange.length - offset);
upperRange = ptr.copyBytes();
upperInclusive = range.isUpperInclusive();
@@ -1307,7 +1310,7 @@ public class WhereOptimizer {
// code doesn't work correctly for WhereOptimizerTest.testMultiSlotTrailingIntersect()
if (result.isSingleKey() && !(range.isSingleKey() && otherRange.isSingleKey())) {
int trailingPkPos = pkPos + Math.min(minSpan, otherMinSpan);
- KeyRange trailingRange = getTrailingRange(rowKeySchema, trailingPkPos, minSpan > otherMinSpan ? range : otherRange, result, ptr);
+ KeyRange trailingRange = getTrailingRange(rowKeySchema, pkPos, minSpan > otherMinSpan ? range : otherRange, result, ptr);
trailingRanges[trailingPkPos] = trailingRanges[trailingPkPos].intersect(trailingRange);
} else {
// Add back clipped part of range