You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by st...@apache.org on 2023/08/01 12:59:58 UTC
[phoenix] branch master updated: PHOENIX-5833 Fix Incorrect results with RVCs and AND operator
This is an automated email from the ASF dual-hosted git repository.
stoty 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 3e26042666 PHOENIX-5833 Fix Incorrect results with RVCs and AND operator
3e26042666 is described below
commit 3e26042666f48bb7e51b4294183b7022320fdd66
Author: Daniel Wong <da...@salesforce.com>
AuthorDate: Tue Apr 21 16:58:13 2020 -0700
PHOENIX-5833 Fix Incorrect results with RVCs and AND operator
---
.../phoenix/end2end/RowValueConstructorIT.java | 41 ++++++++++++++++++++++
.../org/apache/phoenix/compile/WhereOptimizer.java | 4 +++
.../apache/phoenix/compile/WhereOptimizerTest.java | 34 +++++++++++++++---
3 files changed, 75 insertions(+), 4 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 dee1792c90..270b81bb76 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
@@ -36,6 +36,7 @@ import static org.apache.phoenix.util.TestUtil.ROW7;
import static org.apache.phoenix.util.TestUtil.ROW8;
import static org.apache.phoenix.util.TestUtil.ROW9;
import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -47,6 +48,7 @@ import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
import java.sql.Timestamp;
import java.util.List;
import java.util.Properties;
@@ -54,6 +56,7 @@ import java.util.Properties;
import org.apache.phoenix.compile.ExplainPlan;
import org.apache.phoenix.compile.ExplainPlanAttributes;
import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
+import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.PropertiesUtil;
@@ -1734,6 +1737,44 @@ public class RowValueConstructorIT extends ParallelStatsDisabledIT {
}
}
+ @Test
+ public void testRVCConjunction() throws Exception {
+ try (Connection conn = DriverManager.getConnection(getUrl())){
+
+ String tableName = generateUniqueName();
+ String ddl = String.format("create table %s(a varchar(10) not null, b varchar(10) not null, c varchar(10) not null constraint pk primary key(a, b, c))",tableName);
+ String upsert = String.format("upsert into %s values(?, ?, ?)", tableName);
+
+ try( Statement statement = conn.createStatement()){
+ statement.execute(ddl);
+ }
+
+ try( PreparedStatement statement = conn.prepareStatement(upsert)){
+ statement.setString(1,"abc");
+ statement.setString(2,"def");
+ statement.setString(3,"RRSQ_IMKKL");
+ statement.executeUpdate();
+ statement.setString(3,"RRS_ZYTDT");
+ statement.executeUpdate();
+ }
+ conn.commit();
+
+ String conjunctionSelect = String.format("select A, B, C from %s where (A, B, C) > ('abc', 'def', 'RRSQ_IMKKL') AND C like 'RRS\\\\_%%'",tableName);
+ try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(conjunctionSelect)) {
+ assertTrue(rs.next());
+ assertEquals("abc",rs.getString(1));
+ assertEquals("def",rs.getString(2));
+ assertEquals("RRS_ZYTDT",rs.getString(3));
+ PhoenixStatement phoenixStatement = statement.unwrap(PhoenixStatement.class);
+
+ byte[] lowerBound = phoenixStatement.getQueryPlan().getScans().get(0).get(0).getStartRow();
+ byte[] expected = new byte[] {'a','b','c',0,'d','e','f',0,'R','R','S','_'};
+ assertArrayEquals(expected,lowerBound);
+ assertFalse(rs.next());
+ }
+ }
+ }
+
private StringBuilder generateQueryToTest(int numItemsInClause, String fullViewName) {
StringBuilder querySb =
new StringBuilder("SELECT OBJECT_ID,OBJECT_DATA2,OBJECT_DATA FROM " + fullViewName);
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 21011c24b4..b7a3d0aa2d 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
@@ -1458,6 +1458,7 @@ public class WhereOptimizer {
return KeyRange.EMPTY_RANGE;
}
// If we're not dealing with single keys, then we can use our normal intersection
+ // however, if we truncate a span then we need to change exclusive to inclusive
if (otherRange.intersect(KeyRange.getKeyRange(trailingBytes)) == KeyRange.EMPTY_RANGE) {
// Exit early since the upper range is the same as the lower range
if (result.isSingleKey()) {
@@ -1465,6 +1466,9 @@ public class WhereOptimizer {
}
ptr.set(result.getLowerRange(), 0, lowerOffset - separatorLength);
lowerRange = ptr.copyBytes();
+ if(pkPos < otherPKPos && !lowerInclusive) {
+ lowerInclusive = true;
+ }
}
}
boolean upperInclusive = result.isUpperInclusive();
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java
index e46386afac..cdf14ccd9c 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java
@@ -2663,7 +2663,7 @@ public class WhereOptimizerTest extends BaseConnectionlessQueryTest {
assertEquals(
Arrays.asList(
Arrays.asList(
- KeyRange.getKeyRange(PChar.INSTANCE.toBytes("A"), false, PChar.INSTANCE.toBytes("D"), true)
+ KeyRange.getKeyRange(PChar.INSTANCE.toBytes("A"), true, PChar.INSTANCE.toBytes("D"), true)
),
Arrays.asList(
KeyRange.getKeyRange(PChar.INSTANCE.toBytes("EE"), true, KeyRange.UNBOUND, false)
@@ -2671,7 +2671,7 @@ public class WhereOptimizerTest extends BaseConnectionlessQueryTest {
),
rowKeyRanges
);
- assertArrayEquals(PChar.INSTANCE.toBytes("BEE"), scan.getStartRow());
+ assertArrayEquals(PChar.INSTANCE.toBytes("AEE"), scan.getStartRow());
assertArrayEquals(PChar.INSTANCE.toBytes("E"), scan.getStopRow());
}
}
@@ -2726,11 +2726,37 @@ public class WhereOptimizerTest extends BaseConnectionlessQueryTest {
String query = "SELECT * FROM T WHERE A = 'C' and (A,B,C) > ('C','B','X') and C='C'";
QueryPlan queryPlan = TestUtil.getOptimizeQueryPlan(conn, query);
Scan scan = queryPlan.getContext().getScan();
- assertArrayEquals(ByteUtil.concat(PChar.INSTANCE.toBytes("C"), PChar.INSTANCE.toBytes("C"), PChar.INSTANCE.toBytes("C")), scan.getStartRow());
+ //
+ // Note: The optimal scan boundary for the above query is ['CCC' - *), however, I don't see an easy way to fix this currently so prioritizing. Opened JIRA PHOENIX-5885
+ assertArrayEquals(ByteUtil.concat(PChar.INSTANCE.toBytes("C"), PChar.INSTANCE.toBytes("B"), PChar.INSTANCE.toBytes("C")), scan.getStartRow());
assertArrayEquals(PChar.INSTANCE.toBytes("D"), scan.getStopRow());
}
}
-
+
+ @Test
+ public void testEqualityAndGreaterThanRVC2() throws SQLException {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+ conn.createStatement().execute("CREATE TABLE T (\n" +
+ " A CHAR(1) NOT NULL,\n" +
+ " B CHAR(1) NOT NULL,\n" +
+ " C CHAR(1) NOT NULL,\n" +
+ " D CHAR(1) NOT NULL,\n" +
+ " CONSTRAINT PK PRIMARY KEY (\n" +
+ " A,\n" +
+ " B,\n" +
+ " C,\n" +
+ " D\n" +
+ " )\n" +
+ ")");
+ String query = "SELECT * FROM T WHERE A = 'C' and (A,B,C) > ('C','B','A') and C='C'";
+ QueryPlan queryPlan = TestUtil.getOptimizeQueryPlan(conn, query);
+ Scan scan = queryPlan.getContext().getScan();
+ assertArrayEquals(ByteUtil.concat(PChar.INSTANCE.toBytes("C"), PChar.INSTANCE.toBytes("B"), PChar.INSTANCE.toBytes("C")), scan.getStartRow());
+ assertArrayEquals(PChar.INSTANCE.toBytes("D"), scan.getStopRow());
+ }
+ }
+
@Test
public void testOrExpressionNonLeadingPKPushToScanBug4602() throws Exception {
Connection conn = null;