Skip to content

PHOENIX-5236 Multiple dynamic columns in WHERE clause is not working#2480

Open
xavifeds8 wants to merge 1 commit into
apache:masterfrom
xavifeds8:PHOENIX-5236
Open

PHOENIX-5236 Multiple dynamic columns in WHERE clause is not working#2480
xavifeds8 wants to merge 1 commit into
apache:masterfrom
xavifeds8:PHOENIX-5236

Conversation

@xavifeds8
Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Added a ScanUtil.hasDynamicColumns(table) check in WhereCompiler.setScanFilter() so that when the WHERE clause references multiple columns and the table has dynamic columns, Phoenix falls back to MultiCQKeyValueComparisonFilter (HashMap-based, raw byte comparison) instead of MultiEncodedCQKeyValueComparisonFilter (array-based, expects encoded integer qualifiers).

Why are the changes needed?

When a table uses column encoding (the default) and the WHERE clause filters on multiple dynamic columns, Phoenix selects MultiEncodedCQKeyValueComparisonFilter. This filter calls encodingScheme.decode() on each column qualifier, expecting a 2-4 byte encoded integer.
Dynamic columns use the actual column name as the qualifier (e.g., "POPULATION" = 10 bytes), causing InvalidQualifierBytesException: Expected length: 2. Actual: 10.
Single dynamic column in WHERE works fine because SingleCQKeyValueComparisonFilter uses raw byte comparison. The workaround was COLUMN_ENCODED_BYTES=NONE on table creation, which defeats the purpose of encoding.

Does this PR introduce any user-facing change?

Yes. Queries with multiple dynamic columns in the WHERE clause now work correctly on tables with column encoding enabled (the default). Previously these queries threw InvalidQualifierBytesException. No workaround (COLUMN_ENCODED_BYTES=NONE) is needed anymore

How was this patch tested?

5 new unit tests in WhereCompilerTest verifying correct filter selection:

  1. Single dynamic column → SingleCQKeyValueComparisonFilter
  2. Multiple dynamic columns → MultiCQKeyValueComparisonFilter (not Encoded)
  3. Multiple schema columns → MultiEncodedCQKeyValueComparisonFilter (no regression)
  4. Non-encoded table → MultiCQKeyValueComparisonFilter
  5. Single schema column → SingleCQKeyValueComparisonFilter

1 new integration test in DynamicColumnIT covering 7 scenarios:

  1. No dynamic columns (baseline)
  2. 1 dynamic column in WHERE
  3. 2 dynamic columns in WHERE
  4. 3 dynamic columns in WHERE
  5. 1 schema + 2 dynamic (mixed)
  6. 2 dynamic + 1 schema (mixed)
  7. Dynamic columns compared to each other

Was this patch authored or co-authored using generative AI tooling?

Yes. This patch was co-authored with Claude Code opus-4.6.

@xavifeds8
Copy link
Copy Markdown
Contributor Author

EARLIER BEHAVIOUR:
1 row selected (0.012 seconds)
0: jdbc:phoenix:> DROP TABLE IF EXISTS test_no_workaround CASCADE;

No rows affected (0.948 seconds)
0: jdbc:phoenix:> CREATE TABLE test_no_workaround (
. . . . . . . .)> id VARCHAR PRIMARY KEY,
. . . . . . . .)> name VARCHAR
. . . . . . . .)> );
No rows affected (0.63 seconds)
0: jdbc:phoenix:> UPSERT INTO test_no_workaround(id, name, city VARCHAR, department VARCHAR, age INTEGER)
. . . .semicolon> VALUES ('1', 'John Doe', 'Chennai', 'Engineering', 30);
. . . . . . . . >
. . . . . . . . > UPSERT INTO test_no_workaround(id, name, city VARCHAR, department VARCHAR, age INTEGER)
. . . .semicolon> VALUES ('2', 'Jane Smith', 'Mumbai', 'Marketing', 28);
. . . . . . . . >
. . . . . . . . > UPSERT INTO test_no_workaround(id, name, city VARCHAR, department VARCHAR, age INTEGER)
. . . .semicolon> VALUES ('3', 'Bob Wilson', 'Bangalore', 'Engineering', 35);

1 row affected (0.006 seconds)
1 row affected (0.004 seconds)
1 row affected (0.003 seconds)
0: jdbc:phoenix:> SELECT id, name, city, department
. . . .semicolon> FROM test_no_workaround(city VARCHAR, department VARCHAR)
. . . .semicolon> WHERE city = 'Chennai' AND department = 'Engineering';
org.apache.phoenix.schema.PTable$QualifierEncodingScheme$InvalidQualifierBytesException: Invalid number of qualifier bytes. Expected length: 4. Actual: 4
at org.apache.phoenix.schema.PTable$QualifierEncodingScheme.getReservedQualifier(PTable.java:549)
at org.apache.phoenix.schema.PTable$QualifierEncodingScheme.access$400(PTable.java:318)
at org.apache.phoenix.schema.PTable$QualifierEncodingScheme$3.decode(PTable.java:398)
at org.apache.phoenix.filter.MultiEncodedCQKeyValueComparisonFilter$1.visit(MultiEncodedCQKeyValueComparisonFilter.java:182)
at

CURRENT BEHAVIOUR :

0: jdbc:phoenix:> DROP TABLE IF EXISTS test_no_workaround CASCADE;
. . . . . . . . > CREATE TABLE test_no_workaround (id VARCHAR PRIMARY KEY, name VARCHAR);
. . . . . . . . > UPSERT INTO test_no_workaround(id, name, city VARCHAR, department VARCHAR, age INTEGER) VALUES ('1', 'John Doe', '
Chennai', 'Engineering', 30);
. . . . . . . . > UPSERT INTO test_no_workaround(id, name, city VARCHAR, department VARCHAR, age INTEGER) VALUES ('2', 'Jane Smith',
'Mumbai', 'Marketing', 28);
. . . . . . . . > UPSERT INTO test_no_workaround(id, name, city VARCHAR, department VARCHAR, age INTEGER) VALUES ('3', 'Bob Wilson',
'Bangalore', 'Engineering', 35);
. . . . . . . . > SELECT id, name, city, department FROM test_no_workaround(city VARCHAR, department VARCHAR) WHERE city = 'Chennai'
AND department = 'Engineering';

No rows affected (0.071 seconds)
No rows affected (0.734 seconds)
1 row affected (0.021 seconds)
1 row affected (0.004 seconds)
1 row affected (0.002 seconds)
+----+----------+---------+-------------+
| ID | NAME | CITY | DEPARTMENT |
+----+----------+---------+-------------+
| 1 | John Doe | Chennai | Engineering |
+----+----------+---------+-------------+
1 row selected (0.026 seconds)
0: jdbc:phoenix:> SELECT id, name, city, department FROM test_no_workaround(city VARCHAR, department VARCHAR) WHERE city = 'Chennai'
AND department = 'Engineering';
+----+----------+---------+-------------+
| ID | NAME | CITY | DEPARTMENT |
+----+----------+---------+-------------+
| 1 | John Doe | Chennai | Engineering |
+----+----------+---------+-------------+
1 row selected (0.015 seconds)
0: jdbc:phoenix:>

@xavifeds8
Copy link
Copy Markdown
Contributor Author

@virajjasani / @NihalJain can you please review this ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant