This is an automated email from the ASF dual-hosted git repository. tkhurana 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 5dc4b8575b PHOENIX-7616 NPE when there are Conditional expressions on indexed columns 5dc4b8575b is described below commit 5dc4b8575b10aaf499c9a713a47a21e0871f490e Author: tkhurana <khurana.ta...@gmail.com> AuthorDate: Tue May 20 14:15:20 2025 -0700 PHOENIX-7616 NPE when there are Conditional expressions on indexed columns --- .../schema/CompiledConditionalTTLExpression.java | 2 +- .../phoenix/schema/ConditionalTTLExpressionIT.java | 75 +++++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/CompiledConditionalTTLExpression.java b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/CompiledConditionalTTLExpression.java index 2219bcb75b..3efeaeb7a3 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/CompiledConditionalTTLExpression.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/CompiledConditionalTTLExpression.java @@ -216,7 +216,7 @@ public class CompiledConditionalTTLExpression implements CompiledTTLExpression { return false; } Object value = PBoolean.INSTANCE.toObject(ptr); - return value.equals(Boolean.TRUE); + return Boolean.TRUE.equals(value); } /** diff --git a/phoenix-core/src/it/java/org/apache/phoenix/schema/ConditionalTTLExpressionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/schema/ConditionalTTLExpressionIT.java index 77e9886729..6fdc674a04 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/schema/ConditionalTTLExpressionIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/schema/ConditionalTTLExpressionIT.java @@ -28,8 +28,10 @@ import static org.apache.phoenix.mapreduce.index.PhoenixIndexToolJobCounters.BEF import static org.apache.phoenix.mapreduce.index.PhoenixIndexToolJobCounters.REBUILT_INDEX_ROW_COUNT; import static org.apache.phoenix.mapreduce.index.PhoenixIndexToolJobCounters.SCANNED_DATA_ROW_COUNT; import static org.apache.phoenix.schema.LiteralTTLExpression.TTL_EXPRESSION_FOREVER; +import static org.apache.phoenix.util.TestUtil.retainSingleQuotes; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -531,7 +533,6 @@ public class ConditionalTTLExpressionIT extends ParallelStatsDisabledIT { String ttlExpression = String.format( "TO_NUMBER(CURRENT_TIME()) - TO_NUMBER(PHOENIX_ROW_TIMESTAMP()) >= %d", ttl); createTable(ttlExpression); - createTable(ttlExpression); String tableName = schemaBuilder.getEntityTableName(); injectEdge(); int rowCount = 5; @@ -681,6 +682,78 @@ public class ConditionalTTLExpressionIT extends ParallelStatsDisabledIT { } } + @Test + public void testNullPKColumn() throws Exception { + if (tableLevelMaxLookback != 0) { + return; + } + String tableName = "T_" + generateUniqueName(); + String indexName = "I_" + generateUniqueName(); + String ddlTemplate = "create table %s (id1 varchar, id2 varchar, col1 varchar, " + + "col2 varchar constraint pk primary key(id1, id2)) %s"; + String ttlExpression = "id1='a'"; + tableDDLOptions += " ,IMMUTABLE_ROWS=true"; + if (!columnEncoded) { + tableDDLOptions += " ,IMMUTABLE_STORAGE_SCHEME='ONE_CELL_PER_COLUMN'"; + } else { + tableDDLOptions += " ,IMMUTABLE_STORAGE_SCHEME='SINGLE_CELL_ARRAY_WITH_OFFSETS'"; + } + String ddl = String.format(ddlTemplate, tableName, + String.format(tableDDLOptions, retainSingleQuotes(ttlExpression))); + String indexDDL = String.format("create index %s ON %s (col1) INCLUDE(col2) " + + "\"phoenix.max.lookback.age.seconds\" = %d", indexName, tableName, + tableLevelMaxLookback); + try (Connection conn = DriverManager.getConnection(getUrl())) { + conn.createStatement().execute(ddl); + conn.createStatement().execute(indexDDL); + // populate rows + conn.createStatement().execute("upsert into " + tableName + + " values('a', '0', 'col1', 'col2')"); + conn.createStatement().execute("upsert into " + tableName + + " values('a', '1', null, 'col2')"); + conn.createStatement().execute("upsert into " + tableName + + " values('b','0', 'col1', 'col2')"); + conn.createStatement().execute("upsert into " + tableName + + " values('b','1', null, 'col2')"); + conn.createStatement().execute("upsert into " + tableName + + " values(null, '0', 'col1', 'col2')"); + conn.commit(); + long actual = TestUtil.getRowCount(conn, tableName, true); + assertEquals(3, actual); + actual = TestUtil.getRowCountFromIndex(conn, tableName, indexName); + assertEquals(3, actual); + + // alter the ttl + ttlExpression = "id1 is null"; + ddl = "alter table %s set TTL='%s'"; + conn.createStatement().execute(String.format(ddl, tableName, ttlExpression)); + conn.unwrap(PhoenixConnection.class).getQueryServices().clearCache(); + actual = TestUtil.getRowCount(conn, tableName, true); + assertEquals(4, actual); + PTable table = PhoenixRuntime.getTableNoCache(conn, tableName); + assertEquals(TTLExpressionFactory.create(ttlExpression), table.getTTLExpression()); + PTable index = PhoenixRuntime.getTableNoCache(conn, indexName); + assertEquals(TTLExpressionFactory.create(ttlExpression), index.getTTLExpression()); + actual = TestUtil.getRowCountFromIndex(conn, tableName, indexName); + assertEquals(4, actual); + + // alter the ttl + ttlExpression = "col1='col1'"; + ddl = "alter table %s set TTL='%s'"; + conn.createStatement().execute(String.format(ddl, tableName, + retainSingleQuotes(ttlExpression))); + conn.unwrap(PhoenixConnection.class).getQueryServices().clearCache(); + actual = TestUtil.getRowCount(conn, tableName, true); + assertEquals(2, actual); + table = PhoenixRuntime.getTableNoCache(conn, tableName); + assertEquals(TTLExpressionFactory.create(ttlExpression), table.getTTLExpression()); + index = PhoenixRuntime.getTableNoCache(conn, indexName); + assertEquals(TTLExpressionFactory.create(ttlExpression), index.getTTLExpression()); + actual = TestUtil.getRowCountFromIndex(conn, tableName, indexName); + assertEquals(2, actual); + } + } + @Test public void testUnverifiedRows() throws Exception { if (tableLevelMaxLookback != 0) {