This is an automated email from the ASF dual-hosted git repository. ankit 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 5904404 PHOENIX-6023 Wrong result when issuing query for an immutable table with multiple column families (#833) 5904404 is described below commit 59044045189f275c75938d441e7a7d74e7670005 Author: Toshihiro Suzuki <brfrn...@gmail.com> AuthorDate: Tue Jul 21 09:09:28 2020 +0900 PHOENIX-6023 Wrong result when issuing query for an immutable table with multiple column families (#833) --- .../apache/phoenix/end2end/ImmutableTableIT.java | 101 +++++++++++++++++++++ .../org/apache/phoenix/compile/WhereCompiler.java | 33 +++++-- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ImmutableTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ImmutableTableIT.java new file mode 100644 index 0000000..9ae505d --- /dev/null +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ImmutableTableIT.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you maynot use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicablelaw or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.end2end; + +import org.junit.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; + +import static org.junit.Assert.assertEquals; + +public class ImmutableTableIT extends ParallelStatsDisabledIT { + + @Test + public void testQueryWithMultipleColumnFamiliesAndSingleConditionForImmutableTable() + throws Exception { + final String tn = generateUniqueName(); + final String url = getUrl(); + try (Connection conn = DriverManager.getConnection(url); + Statement stmt = conn.createStatement()) { + stmt.execute(String.format("CREATE TABLE %s (" + + "ID VARCHAR PRIMARY KEY," + + "COL1 VARCHAR," + + "COL2 VARCHAR" + + ") IMMUTABLE_ROWS = TRUE", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id0', '0', 'a')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id1', '1', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id2', '2', 'b')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id3', '3', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id4', '4', 'c')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id5', '5', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id6', '6', 'd')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id7', '7', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id8', '8', 'e')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id9', '9', NULL)", tn)); + conn.commit(); + + try (ResultSet rs = stmt.executeQuery(String.format( + "SELECT COL1 FROM %s WHERE COL2 IS NOT NULL", tn))) { + int count = 0; + while (rs.next()) { + count++; + } + assertEquals(5, count); + } + } + } + + @Test + public void testQueryWithMultipleColumnFamiliesAndMultipleConditionsForImmutableTable() + throws Exception { + final String tn = generateUniqueName(); + final String url = getUrl(); + try (Connection conn = DriverManager.getConnection(url); + Statement stmt = conn.createStatement()) { + stmt.execute(String.format("CREATE TABLE %s (" + + "ID VARCHAR PRIMARY KEY," + + "COL1 VARCHAR," + + "COL2 VARCHAR," + + "COL3 VARCHAR" + + ") IMMUTABLE_ROWS = TRUE", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id0', '0', '0', 'a')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id1', '1', '0', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id2', '2', '0', 'b')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id3', '3', '0', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id4', '4', '0', 'c')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id5', '5', '0', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id6', '6', '0', 'd')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id7', '7', '0', NULL)", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id8', '8', '0', 'e')", tn)); + stmt.execute(String.format("UPSERT INTO %s VALUES ('id9', '9', '0', NULL)", tn)); + conn.commit(); + + try (ResultSet rs = stmt.executeQuery(String.format( + "SELECT COL1 FROM %s WHERE COL3 IS NOT NULL AND COL2='0'", tn))) { + int count = 0; + while (rs.next()) { + count++; + } + assertEquals(5, count); + } + } + } +} diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java index fb294c0..62b2ed5 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java @@ -56,9 +56,9 @@ import org.apache.phoenix.query.QueryConstants; import org.apache.phoenix.schema.AmbiguousColumnException; import org.apache.phoenix.schema.ColumnNotFoundException; import org.apache.phoenix.schema.ColumnRef; +import org.apache.phoenix.schema.PColumnFamily; import org.apache.phoenix.schema.PTable; import org.apache.phoenix.schema.PTable.ImmutableStorageScheme; -import org.apache.phoenix.schema.PTable.IndexType; import org.apache.phoenix.schema.PTable.QualifierEncodingScheme; import org.apache.phoenix.schema.PTable.ViewType; import org.apache.phoenix.schema.PTableType; @@ -66,6 +66,7 @@ import org.apache.phoenix.schema.TableRef; import org.apache.phoenix.schema.TypeMismatchException; import org.apache.phoenix.schema.types.PBoolean; import org.apache.phoenix.util.ByteUtil; +import org.apache.phoenix.util.EncodedColumnsUtil; import org.apache.phoenix.util.ExpressionUtil; import org.apache.phoenix.util.ScanUtil; import org.apache.phoenix.util.SchemaUtil; @@ -195,16 +196,36 @@ public class WhereCompiler { @Override protected ColumnRef resolveColumn(ColumnParseNode node) throws SQLException { ColumnRef ref = super.resolveColumn(node); + if (disambiguateWithFamily) { + return ref; + } PTable table = ref.getTable(); // Track if we need to compare KeyValue during filter evaluation // using column family. If the column qualifier is enough, we // just use that. - try { - if (!SchemaUtil.isPKColumn(ref.getColumn())) { - table.getColumnForColumnName(ref.getColumn().getName().getString()); + if (!SchemaUtil.isPKColumn(ref.getColumn())) { + if (!EncodedColumnsUtil.usesEncodedColumnNames(table)) { + try { + table.getColumnForColumnName(ref.getColumn().getName().getString()); + } catch (AmbiguousColumnException e) { + disambiguateWithFamily = true; + } + } else { + for (PColumnFamily columnFamily : table.getColumnFamilies()) { + if (columnFamily.getName().equals(ref.getColumn().getFamilyName())) { + continue; + } + try { + table.getColumnForColumnQualifier(columnFamily.getName().getBytes(), + ref.getColumn().getColumnQualifierBytes()); + // If we find the same qualifier name with different columnFamily, + // then set disambiguateWithFamily to true + disambiguateWithFamily = true; + break; + } catch (ColumnNotFoundException ignore) { + } + } } - } catch (AmbiguousColumnException e) { - disambiguateWithFamily = true; } return ref; }