You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@phoenix.apache.org by GitBox <gi...@apache.org> on 2020/07/16 02:49:47 UTC

[GitHub] [phoenix] dbwong opened a new pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

dbwong opened a new pull request #830:
URL: https://github.com/apache/phoenix/pull/830


   https://issues.apache.org/jira/browse/PHOENIX-6013
   
   Note this PR includes the non-merged PHOENIX-5924 changes which are required for some of the test cases.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] yanxinyi commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
yanxinyi commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455504520



##########
File path: phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java
##########
@@ -931,6 +933,101 @@ public void testIndexMultiColumnsMultiIndexesRVCOffset() throws SQLException {
         }
     }
 
+    @Test
+    public void testIndexMultiColumnsMultiIndexesVariableLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "k2 VARCHAR,\n" +
+                "k3 VARCHAR,\n" +
+                "k4 VARCHAR,\n" +
+                "k5 VARCHAR,\n" +
+                "k6 VARCHAR,\n" +
+                "v1 VARCHAR,\n" +
+                "v2 VARCHAR,\n" +
+                "v3 VARCHAR,\n" +
+                "v4 VARCHAR,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1, k2, k3, k4, k5, k6)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (k2 ,v1, k4)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1 ,k2, k3, k4, k5, k6)=('0','1',null,null,null,'2')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'0',0,'1',0,0,0,0,'2',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  k2,v1,k4 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k2,v1,k4,k1,k3,k5,k6)=('2',null,'4','1','3','5','6')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'2',0,0,'4',0,'1',0,'3',0,'5',0,'6',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+    }
+
+    @Test
+    public void testIndexMultiColumnsIndexedFixedLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "v1 TINYINT,\n" +
+                "v2 TINYINT,\n" +
+                "v3 TINYINT,\n" +
+                "v4 TINYINT,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (v1, k1, v2, v3)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1)=('-1')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'-','1',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (v1, k1, v2, v3)=(null,'a',null,0)";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            //decimal is used for fixed with types
+            byte[] expectedRow = new byte[] {0,'a',0,0,-128,1}; //note trailing 1 not 0 due to phoenix internal inconsistency

Review comment:
       i see. can you add this to the comment so that ppl can have a better understanding and also knowledge transfer, thx! 




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] yanxinyi commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
yanxinyi commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455501465



##########
File path: phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java
##########
@@ -931,6 +933,101 @@ public void testIndexMultiColumnsMultiIndexesRVCOffset() throws SQLException {
         }
     }
 
+    @Test
+    public void testIndexMultiColumnsMultiIndexesVariableLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "k2 VARCHAR,\n" +
+                "k3 VARCHAR,\n" +
+                "k4 VARCHAR,\n" +
+                "k5 VARCHAR,\n" +
+                "k6 VARCHAR,\n" +
+                "v1 VARCHAR,\n" +
+                "v2 VARCHAR,\n" +
+                "v3 VARCHAR,\n" +
+                "v4 VARCHAR,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1, k2, k3, k4, k5, k6)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (k2 ,v1, k4)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1 ,k2, k3, k4, k5, k6)=('0','1',null,null,null,'2')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'0',0,'1',0,0,0,0,'2',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  k2,v1,k4 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k2,v1,k4,k1,k3,k5,k6)=('2',null,'4','1','3','5','6')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'2',0,0,'4',0,'1',0,'3',0,'5',0,'6',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+    }
+
+    @Test
+    public void testIndexMultiColumnsIndexedFixedLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "v1 TINYINT,\n" +
+                "v2 TINYINT,\n" +
+                "v3 TINYINT,\n" +
+                "v4 TINYINT,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (v1, k1, v2, v3)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1)=('-1')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'-','1',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (v1, k1, v2, v3)=(null,'a',null,0)";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            //decimal is used for fixed with types
+            byte[] expectedRow = new byte[] {0,'a',0,0,-128,1}; //note trailing 1 not 0 due to phoenix internal inconsistency

Review comment:
       why -128?
   
   I thought it would be 0, 'a',0,0,0,1




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] yanxinyi commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
yanxinyi commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455503788



##########
File path: phoenix-core/src/test/java/org/apache/phoenix/compile/RVCOffsetCompilerTest.java
##########
@@ -148,12 +153,82 @@ public void buildListOfRowKeyColumnExpressionsIndexTest() throws Exception {
         expressions.add(expression1);
         expressions.add(expression2);
 
+        AndExpression expression = mock(AndExpression.class);
+        Mockito.when(expression.getChildren()).thenReturn(expressions);
+
+        List<RowKeyColumnExpression>
+                result =
+                offsetCompiler.buildListOfRowKeyColumnExpressions(expression, true);
+
+        assertEquals(2,result.size());
+        assertEquals(rvc1,result.get(0));
+        assertEquals(rvc2,result.get(1));
+    }
+
+    @Test
+    public void buildListOfRowKeyColumnExpressionsSingleNodeComparisonTest() throws Exception {
+        List<Expression> expressions = new ArrayList<>();
+
+        RowKeyColumnExpression rvc1 = new RowKeyColumnExpression();
+        RowKeyColumnExpression rvc2 = new RowKeyColumnExpression();

Review comment:
       nit: remove unused expression rvc2?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] yanxinyi commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
yanxinyi commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455500807



##########
File path: phoenix-core/src/main/java/org/apache/phoenix/compile/RVCOffsetCompiler.java
##########
@@ -283,19 +276,34 @@ public CompiledOffset getRVCOffset(StatementContext context, FilterableStatement
         return compiledOffset;
     }
 
-    @VisibleForTesting List<RowKeyColumnExpression> buildListOfRowKeyColumnExpressions(
-            List<Expression> expressions, boolean isIndex)
-            throws RowValueConstructorOffsetNotCoercibleException {
+    @VisibleForTesting
+    List<RowKeyColumnExpression> buildListOfRowKeyColumnExpressions (
+            Expression whereExpression, boolean isIndex)
+            throws RowValueConstructorOffsetNotCoercibleException, RowValueConstructorOffsetInternalErrorException {
+
+        List<Expression> expressions;
+        if((whereExpression instanceof  AndExpression)) {

Review comment:
       nit: two spaces




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] yanxinyi commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
yanxinyi commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455504031



##########
File path: phoenix-core/src/test/java/org/apache/phoenix/compile/RVCOffsetCompilerTest.java
##########
@@ -148,12 +153,82 @@ public void buildListOfRowKeyColumnExpressionsIndexTest() throws Exception {
         expressions.add(expression1);
         expressions.add(expression2);
 
+        AndExpression expression = mock(AndExpression.class);
+        Mockito.when(expression.getChildren()).thenReturn(expressions);
+
+        List<RowKeyColumnExpression>
+                result =
+                offsetCompiler.buildListOfRowKeyColumnExpressions(expression, true);
+
+        assertEquals(2,result.size());
+        assertEquals(rvc1,result.get(0));
+        assertEquals(rvc2,result.get(1));
+    }
+
+    @Test
+    public void buildListOfRowKeyColumnExpressionsSingleNodeComparisonTest() throws Exception {
+        List<Expression> expressions = new ArrayList<>();
+
+        RowKeyColumnExpression rvc1 = new RowKeyColumnExpression();
+        RowKeyColumnExpression rvc2 = new RowKeyColumnExpression();
+
+        ComparisonExpression expression1 = mock(ComparisonExpression.class);
+
+        Mockito.when(expression1.getChildren()).thenReturn(Lists.<Expression>newArrayList(rvc1));
+
+        List<RowKeyColumnExpression>
+                result =
+                offsetCompiler.buildListOfRowKeyColumnExpressions(expression1, false);
+
+        assertEquals(1,result.size());
+        assertEquals(rvc1,result.get(0));
+    }
+
+    @Test
+    public void buildListOfRowKeyColumnExpressionsSingleNodeIsNullTest() throws Exception {
+        List<Expression> expressions = new ArrayList<>();
+
+        RowKeyColumnExpression rvc1 = new RowKeyColumnExpression();
+        RowKeyColumnExpression rvc2 = new RowKeyColumnExpression();
+
+        IsNullExpression expression1 = mock(IsNullExpression.class);

Review comment:
       nit: renaming to `expression` since no expression2 here




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] yanxinyi commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
yanxinyi commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455503788



##########
File path: phoenix-core/src/test/java/org/apache/phoenix/compile/RVCOffsetCompilerTest.java
##########
@@ -148,12 +153,82 @@ public void buildListOfRowKeyColumnExpressionsIndexTest() throws Exception {
         expressions.add(expression1);
         expressions.add(expression2);
 
+        AndExpression expression = mock(AndExpression.class);
+        Mockito.when(expression.getChildren()).thenReturn(expressions);
+
+        List<RowKeyColumnExpression>
+                result =
+                offsetCompiler.buildListOfRowKeyColumnExpressions(expression, true);
+
+        assertEquals(2,result.size());
+        assertEquals(rvc1,result.get(0));
+        assertEquals(rvc2,result.get(1));
+    }
+
+    @Test
+    public void buildListOfRowKeyColumnExpressionsSingleNodeComparisonTest() throws Exception {
+        List<Expression> expressions = new ArrayList<>();
+
+        RowKeyColumnExpression rvc1 = new RowKeyColumnExpression();
+        RowKeyColumnExpression rvc2 = new RowKeyColumnExpression();

Review comment:
       remove unused expression rvc2?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] dbwong commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
dbwong commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455504618



##########
File path: phoenix-core/src/test/java/org/apache/phoenix/compile/RVCOffsetCompilerTest.java
##########
@@ -148,12 +153,82 @@ public void buildListOfRowKeyColumnExpressionsIndexTest() throws Exception {
         expressions.add(expression1);
         expressions.add(expression2);
 
+        AndExpression expression = mock(AndExpression.class);
+        Mockito.when(expression.getChildren()).thenReturn(expressions);
+
+        List<RowKeyColumnExpression>
+                result =
+                offsetCompiler.buildListOfRowKeyColumnExpressions(expression, true);
+
+        assertEquals(2,result.size());
+        assertEquals(rvc1,result.get(0));
+        assertEquals(rvc2,result.get(1));
+    }
+
+    @Test
+    public void buildListOfRowKeyColumnExpressionsSingleNodeComparisonTest() throws Exception {
+        List<Expression> expressions = new ArrayList<>();
+
+        RowKeyColumnExpression rvc1 = new RowKeyColumnExpression();
+        RowKeyColumnExpression rvc2 = new RowKeyColumnExpression();

Review comment:
       will do

##########
File path: phoenix-core/src/test/java/org/apache/phoenix/compile/RVCOffsetCompilerTest.java
##########
@@ -148,12 +153,82 @@ public void buildListOfRowKeyColumnExpressionsIndexTest() throws Exception {
         expressions.add(expression1);
         expressions.add(expression2);
 
+        AndExpression expression = mock(AndExpression.class);
+        Mockito.when(expression.getChildren()).thenReturn(expressions);
+
+        List<RowKeyColumnExpression>
+                result =
+                offsetCompiler.buildListOfRowKeyColumnExpressions(expression, true);
+
+        assertEquals(2,result.size());
+        assertEquals(rvc1,result.get(0));
+        assertEquals(rvc2,result.get(1));
+    }
+
+    @Test
+    public void buildListOfRowKeyColumnExpressionsSingleNodeComparisonTest() throws Exception {
+        List<Expression> expressions = new ArrayList<>();
+
+        RowKeyColumnExpression rvc1 = new RowKeyColumnExpression();
+        RowKeyColumnExpression rvc2 = new RowKeyColumnExpression();
+
+        ComparisonExpression expression1 = mock(ComparisonExpression.class);
+
+        Mockito.when(expression1.getChildren()).thenReturn(Lists.<Expression>newArrayList(rvc1));
+
+        List<RowKeyColumnExpression>
+                result =
+                offsetCompiler.buildListOfRowKeyColumnExpressions(expression1, false);
+
+        assertEquals(1,result.size());
+        assertEquals(rvc1,result.get(0));
+    }
+
+    @Test
+    public void buildListOfRowKeyColumnExpressionsSingleNodeIsNullTest() throws Exception {
+        List<Expression> expressions = new ArrayList<>();
+
+        RowKeyColumnExpression rvc1 = new RowKeyColumnExpression();
+        RowKeyColumnExpression rvc2 = new RowKeyColumnExpression();
+
+        IsNullExpression expression1 = mock(IsNullExpression.class);

Review comment:
       will do




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] dbwong commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
dbwong commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455505467



##########
File path: phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java
##########
@@ -931,6 +933,101 @@ public void testIndexMultiColumnsMultiIndexesRVCOffset() throws SQLException {
         }
     }
 
+    @Test
+    public void testIndexMultiColumnsMultiIndexesVariableLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "k2 VARCHAR,\n" +
+                "k3 VARCHAR,\n" +
+                "k4 VARCHAR,\n" +
+                "k5 VARCHAR,\n" +
+                "k6 VARCHAR,\n" +
+                "v1 VARCHAR,\n" +
+                "v2 VARCHAR,\n" +
+                "v3 VARCHAR,\n" +
+                "v4 VARCHAR,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1, k2, k3, k4, k5, k6)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (k2 ,v1, k4)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1 ,k2, k3, k4, k5, k6)=('0','1',null,null,null,'2')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'0',0,'1',0,0,0,0,'2',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  k2,v1,k4 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k2,v1,k4,k1,k3,k5,k6)=('2',null,'4','1','3','5','6')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'2',0,0,'4',0,'1',0,'3',0,'5',0,'6',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+    }
+
+    @Test
+    public void testIndexMultiColumnsIndexedFixedLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "v1 TINYINT,\n" +
+                "v2 TINYINT,\n" +
+                "v3 TINYINT,\n" +
+                "v4 TINYINT,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (v1, k1, v2, v3)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1)=('-1')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'-','1',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (v1, k1, v2, v3)=(null,'a',null,0)";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            //decimal is used for fixed with types
+            byte[] expectedRow = new byte[] {0,'a',0,0,-128,1}; //note trailing 1 not 0 due to phoenix internal inconsistency

Review comment:
       sure




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] dbwong commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
dbwong commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455504583



##########
File path: phoenix-core/src/main/java/org/apache/phoenix/compile/RVCOffsetCompiler.java
##########
@@ -283,19 +276,34 @@ public CompiledOffset getRVCOffset(StatementContext context, FilterableStatement
         return compiledOffset;
     }
 
-    @VisibleForTesting List<RowKeyColumnExpression> buildListOfRowKeyColumnExpressions(
-            List<Expression> expressions, boolean isIndex)
-            throws RowValueConstructorOffsetNotCoercibleException {
+    @VisibleForTesting
+    List<RowKeyColumnExpression> buildListOfRowKeyColumnExpressions (
+            Expression whereExpression, boolean isIndex)
+            throws RowValueConstructorOffsetNotCoercibleException, RowValueConstructorOffsetInternalErrorException {
+
+        List<Expression> expressions;
+        if((whereExpression instanceof  AndExpression)) {

Review comment:
       will do




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] gjacoby126 commented on pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
gjacoby126 commented on pull request #830:
URL: https://github.com/apache/phoenix/pull/830#issuecomment-729926590


   JIRA is already resolved. Closing. 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] dbwong commented on a change in pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
dbwong commented on a change in pull request #830:
URL: https://github.com/apache/phoenix/pull/830#discussion_r455502999



##########
File path: phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorOffsetIT.java
##########
@@ -931,6 +933,101 @@ public void testIndexMultiColumnsMultiIndexesRVCOffset() throws SQLException {
         }
     }
 
+    @Test
+    public void testIndexMultiColumnsMultiIndexesVariableLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "k2 VARCHAR,\n" +
+                "k3 VARCHAR,\n" +
+                "k4 VARCHAR,\n" +
+                "k5 VARCHAR,\n" +
+                "k6 VARCHAR,\n" +
+                "v1 VARCHAR,\n" +
+                "v2 VARCHAR,\n" +
+                "v3 VARCHAR,\n" +
+                "v4 VARCHAR,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1, k2, k3, k4, k5, k6)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (k2 ,v1, k4)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1 ,k2, k3, k4, k5, k6)=('0','1',null,null,null,'2')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'0',0,'1',0,0,0,0,'2',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  k2,v1,k4 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k2,v1,k4,k1,k3,k5,k6)=('2',null,'4','1','3','5','6')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'2',0,0,'4',0,'1',0,'3',0,'5',0,'6',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+    }
+
+    @Test
+    public void testIndexMultiColumnsIndexedFixedLengthNullLiteralsRVCOffset() throws SQLException {
+        String ddlTemplate = "CREATE TABLE %s (k1 VARCHAR,\n" +
+                "v1 TINYINT,\n" +
+                "v2 TINYINT,\n" +
+                "v3 TINYINT,\n" +
+                "v4 TINYINT,\n" +
+                "CONSTRAINT pk PRIMARY KEY (k1)) ";
+
+        String longKeyTableName = "T_" + generateUniqueName();
+        String longKeyIndex1Name =  "INDEX_1_" + longKeyTableName;
+
+        String ddl = String.format(ddlTemplate,longKeyTableName);
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(ddl);
+        }
+
+        String createIndex1 = "CREATE INDEX IF NOT EXISTS " + longKeyIndex1Name + " ON " + longKeyTableName + " (v1, k1, v2, v3)";
+
+        try(Statement statement = conn.createStatement()) {
+            statement.execute(createIndex1);
+        }
+
+        String sql0 = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (k1)=('-1')";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql0)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            byte[] expectedRow = new byte[] {'-','1',1}; //note trailing 1 not 0 due to phoenix internal inconsistency
+            assertArrayEquals(expectedRow,startRow);
+        }
+
+        String sql = "SELECT  v1,v3 FROM " + longKeyTableName + " LIMIT 3 OFFSET (v1, k1, v2, v3)=(null,'a',null,0)";
+        try(Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
+            PhoenixResultSet phoenixResultSet = rs.unwrap(PhoenixResultSet.class);
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().size());
+            assertEquals(1,phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).size());
+            byte[] startRow = phoenixResultSet.getStatement().getQueryPlan().getScans().get(0).get(0).getStartRow();
+            //decimal is used for fixed with types
+            byte[] expectedRow = new byte[] {0,'a',0,0,-128,1}; //note trailing 1 not 0 due to phoenix internal inconsistency

Review comment:
       we represent fixed integer keys as decimal form in the index as they need to be variable length.  -128 normal two's compliment form would be 0b10000000 but we flip the leading edge to keep the rowkey sorted, yielding 0.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [phoenix] gjacoby126 closed pull request #830: PHOENIX-6013 RVC Offset does not handle coerced literal nulls properly

Posted by GitBox <gi...@apache.org>.
gjacoby126 closed pull request #830:
URL: https://github.com/apache/phoenix/pull/830


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org