From 43894ccee9ffd8c10ababc7b89d8754a0f82218a Mon Sep 17 00:00:00 2001 From: Palash Chauhan Date: Fri, 23 Jan 2026 15:33:53 -0800 Subject: [PATCH 1/3] PHOENIX-7753 : Allow uncovered index creation on tables with relaxed conditional TTL --- .../apache/phoenix/schema/MetaDataClient.java | 11 ++- .../schema/ConditionalTTLExpressionTest.java | 74 ++++++++++++------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java index edb38da970c..4795c39dcf5 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java @@ -2529,7 +2529,11 @@ private PTable createTableInternal(CreateTableStatement statement, byte[][] spli } else { ttlFromHierarchy = checkAndGetTTLFromHierarchy(parent, tableName); if (!ttlFromHierarchy.equals(TTL_EXPRESSION_NOT_DEFINED)) { - ttlFromHierarchy.validateTTLOnCreate(connection, statement, parent, tableProps); + if (parent.hasConditionalTTL() && !parent.isStrictTTL()) { + ttlFromHierarchy = TTL_EXPRESSION_NOT_DEFINED; + } else { + ttlFromHierarchy.validateTTLOnCreate(connection, statement, parent, tableProps); + } } } @@ -6413,7 +6417,10 @@ private boolean evaluateStmtProperties(MetaProperties metaProperties, } if (metaProperties.getTTL() != table.getTTLExpression()) { TTLExpression newTTL = metaProperties.getTTL(); - newTTL.validateTTLOnAlter(connection, table); + boolean isStrictTTL = metaProperties.isStrictTTL() != null ? metaProperties.isStrictTTL : true; + if (!(newTTL instanceof ConditionalTTLExpression) || isStrictTTL) { + newTTL.validateTTLOnAlter(connection, table); + } metaPropertiesEvaluated.setTTL(getCompatibleTTLExpression(metaProperties.getTTL(), table.getType(), table.getViewType(), table.getName().toString())); changingPhoenixTableProperty = true; diff --git a/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java index b82dd5e72d8..b81a9998130 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java @@ -55,7 +55,7 @@ public class ConditionalTTLExpressionTest extends BaseConnectionlessQueryTest { - private static void assertConditonTTL(Connection conn, String tableName, String ttlExpr) + private static void assertConditionTTL(Connection conn, String tableName, String ttlExpr) throws SQLException { TTLExpression expected = new ConditionalTTLExpression(ttlExpr); assertTTL(conn, tableName, expected); @@ -105,7 +105,7 @@ public void testBasicExpression() throws SQLException { String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); String query = String.format("SELECT count(*) from %s where k1 > 3", tableName); validateScan(conn, tableName, query, ttl, false, Lists.newArrayList("col1")); } @@ -174,17 +174,17 @@ public void testSingleNonDefaultColumnFamilyIsAllowed() throws SQLException { String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); // create global index String indexName = "I_" + generateUniqueName(); ddl = String.format("create index %s on %s (col2) include(col1)", indexName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); // create local index indexName = "L_" + generateUniqueName(); ddl = String.format("create local index %s on %s (col2) include(col1)", indexName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); } } @@ -198,23 +198,23 @@ public void testDefaultColumnFamily() throws SQLException { String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); // create view String viewName = "GV_" + generateUniqueName(); ddl = String.format("create view %s (col3 varchar) as select * from %s where k1 = 2", viewName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, viewName, ttl); + assertConditionTTL(conn, viewName, ttl); // create global index String indexName = "I_" + generateUniqueName(); ddl = String.format("create index %s on %s (col2) include(col1)", indexName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); // create local index indexName = "L_" + generateUniqueName(); ddl = String.format("create local index %s on %s (col2) include(col1)", indexName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); } } @@ -301,7 +301,7 @@ public void testMultipleColumnFamilyNotAllowedOnAddColumn3() throws SQLException String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); // add a new column in a different column family String alterDDL = String.format("alter table %s add A.col3 varchar", tableName); try { @@ -369,7 +369,7 @@ public void testNullExpression() throws SQLException { String ddl = String.format(ddlTemplate, tableName, ttl); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); String query = String.format("SELECT count(*) from %s", tableName); validateScan(conn, tableName, query, ttl, false, Lists.newArrayList("col1", "col2")); } @@ -387,14 +387,14 @@ public void testBooleanColumn() throws SQLException { try (Connection conn = DriverManager.getConnection(getUrl())) { String ddl = String.format(ddlTemplate, tableName, ttl); conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); query = String.format("SELECT k1, k2 from %s where (k1,k2) IN ((1,2), (3,4))", tableName); validateScan(conn, tableName, query, ttl, false, Lists.newArrayList("expired")); ddl = String.format(indexTemplate, indexName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); // validate the scan on index query = String.format("SELECT count(*) from %s", tableName); @@ -411,7 +411,7 @@ public void testNot() throws SQLException { String ddl = String.format(ddlTemplate, tableName, ttl); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); } } @@ -425,7 +425,7 @@ public void testPhoenixRowTimestamp() throws SQLException { String query; try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); query = String.format("select col1 from %s where k1 = 7 AND k2 > 12", tableName); validateScan(conn, tableName, query, ttl, false, Lists.newArrayList("col1")); } @@ -441,7 +441,7 @@ public void testBooleanCaseExpression() throws SQLException { String ddl = String.format(ddlTemplate, tableName, ttl); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, expectedTTLExpr); + assertConditionTTL(conn, tableName, expectedTTLExpr); } } @@ -460,7 +460,7 @@ public void testCondTTLOnTopLevelView() throws SQLException { ddl = String.format(viewTemplate, viewName, tableName, ttl); conn.createStatement().execute(ddl); assertTTL(conn, tableName, TTL_EXPRESSION_NOT_DEFINED); - assertConditonTTL(conn, viewName, ttl); + assertConditionTTL(conn, viewName, ttl); String query = String.format("select k3 from %s", viewName); validateScan(conn, viewName, query, ttl, false, Lists.newArrayList("k2", "k3")); } @@ -487,11 +487,11 @@ public void testCondTTLOnMultiLevelView() throws SQLException { conn.createStatement().execute(ddl); assertTTL(conn, tableName, TTL_EXPRESSION_NOT_DEFINED); assertTTL(conn, parentView, TTL_EXPRESSION_NOT_DEFINED); - assertConditonTTL(conn, childView, ttl); + assertConditionTTL(conn, childView, ttl); // create an index on child view ddl = String.format(indexOnChildTemplate, indexName, childView); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); } } @@ -505,7 +505,7 @@ public void testInListTTLExpr() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl())) { String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); query = String.format("select col1 from %s where id IN ('abc', 'fff')", tableName); validateScan(conn, tableName, query, ttl, false, Lists.newArrayList("col1", "col2")); } @@ -524,10 +524,10 @@ public void testPartialIndex() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl())) { String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); ddl = String.format(indexTemplate, indexName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); query = String.format("select col3 from %s where col1 > 60", tableName); validateScan(conn, tableName, query, ttl, true, Lists.newArrayList("0:col2", "0:col3", "0:col4")); @@ -535,7 +535,7 @@ public void testPartialIndex() throws Exception { } @Test - public void testUncoveredIndex() throws Exception { + public void testUncoveredIndexStrictTTL() throws Exception { String ddlTemplate = "create table %s (id varchar not null primary key, " + "col1 integer, col2 integer, col3 double, col4 varchar) TTL = '%s'"; String tableName = generateUniqueName(); @@ -546,7 +546,7 @@ public void testUncoveredIndex() throws Exception { try (Connection conn = DriverManager.getConnection(getUrl())) { String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); ddl = String.format(indexTemplate, indexName, tableName); try { conn.createStatement().execute(ddl); @@ -557,10 +557,28 @@ public void testUncoveredIndex() throws Exception { indexTemplate = "create uncovered index %s on %s (col4, col2) "; ddl = String.format(indexTemplate, indexName, tableName); conn.createStatement().execute(ddl); - assertConditonTTL(conn, indexName, ttl); + assertConditionTTL(conn, indexName, ttl); } } + @Test + public void testUncoveredIndexRelaxedTTL() throws Exception { + String ddlTemplate = "create table %s (id varchar not null primary key, " + + "col1 integer, col2 integer, col3 double, col4 varchar) TTL = '%s', IS_STRICT_TTL=false"; + String tableName = generateUniqueName(); + String indexTemplate = "create uncovered index %s on %s (col1) "; + String indexName = generateUniqueName(); + String ttl = "col2 > 100 AND col4='expired'"; + try (Connection conn = DriverManager.getConnection(getUrl())) { + String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); + conn.createStatement().execute(ddl); + assertConditionTTL(conn, tableName, ttl); + ddl = String.format(indexTemplate, indexName, tableName); + conn.createStatement().execute(ddl); + assertTTL(conn, indexName, TTL_EXPRESSION_NOT_DEFINED); + } + } + @Test public void testCreatingIndexWithMissingExprCols() throws Exception { String ddlTemplate = "create table %s (id varchar not null primary key, " @@ -602,6 +620,10 @@ public void testSettingCondTTLOnTableWithIndexWithMissingExprCols() throws Excep } catch (SQLException e) { assertTrue(e.getCause() instanceof ColumnNotFoundException); } + // relaxed ttl + ddl = String.format("alter table %s set TTL = '%s', IS_STRICT_TTL = false", tableName, retainSingleQuotes(ttl)); + conn.createStatement().execute(ddl); + assertTTL(conn, indexName, TTL_EXPRESSION_NOT_DEFINED); } } @@ -615,7 +637,7 @@ public void testScanColumns() throws Exception { String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); try (Connection conn = DriverManager.getConnection(getUrl())) { conn.createStatement().execute(ddl); - assertConditonTTL(conn, tableName, ttl); + assertConditionTTL(conn, tableName, ttl); String query = String.format("select * from %s where k1 > 3", tableName); // select * so all columns should be read validateScan(conn, tableName, query, ttl, false, Collections.EMPTY_LIST); From 14ec5e087c21dc64f303803e7f4cf592e79c8956 Mon Sep 17 00:00:00 2001 From: Palash Chauhan Date: Fri, 23 Jan 2026 15:44:17 -0800 Subject: [PATCH 2/3] spotless and more tests --- .../apache/phoenix/schema/MetaDataClient.java | 15 +++--- .../schema/ConditionalTTLExpressionTest.java | 54 +++++++++++++------ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java index 4795c39dcf5..481b44bfa9e 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java @@ -2529,11 +2529,11 @@ private PTable createTableInternal(CreateTableStatement statement, byte[][] spli } else { ttlFromHierarchy = checkAndGetTTLFromHierarchy(parent, tableName); if (!ttlFromHierarchy.equals(TTL_EXPRESSION_NOT_DEFINED)) { - if (parent.hasConditionalTTL() && !parent.isStrictTTL()) { - ttlFromHierarchy = TTL_EXPRESSION_NOT_DEFINED; - } else { - ttlFromHierarchy.validateTTLOnCreate(connection, statement, parent, tableProps); - } + if (parent.hasConditionalTTL() && !parent.isStrictTTL()) { + ttlFromHierarchy = TTL_EXPRESSION_NOT_DEFINED; + } else { + ttlFromHierarchy.validateTTLOnCreate(connection, statement, parent, tableProps); + } } } @@ -6417,9 +6417,10 @@ private boolean evaluateStmtProperties(MetaProperties metaProperties, } if (metaProperties.getTTL() != table.getTTLExpression()) { TTLExpression newTTL = metaProperties.getTTL(); - boolean isStrictTTL = metaProperties.isStrictTTL() != null ? metaProperties.isStrictTTL : true; + boolean isStrictTTL = + metaProperties.isStrictTTL() != null ? metaProperties.isStrictTTL : table.isStrictTTL(); if (!(newTTL instanceof ConditionalTTLExpression) || isStrictTTL) { - newTTL.validateTTLOnAlter(connection, table); + newTTL.validateTTLOnAlter(connection, table); } metaPropertiesEvaluated.setTTL(getCompatibleTTLExpression(metaProperties.getTTL(), table.getType(), table.getViewType(), table.getName().toString())); diff --git a/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java index b81a9998130..7e6fa9128f2 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java @@ -561,23 +561,23 @@ public void testUncoveredIndexStrictTTL() throws Exception { } } - @Test - public void testUncoveredIndexRelaxedTTL() throws Exception { - String ddlTemplate = "create table %s (id varchar not null primary key, " - + "col1 integer, col2 integer, col3 double, col4 varchar) TTL = '%s', IS_STRICT_TTL=false"; - String tableName = generateUniqueName(); - String indexTemplate = "create uncovered index %s on %s (col1) "; - String indexName = generateUniqueName(); - String ttl = "col2 > 100 AND col4='expired'"; - try (Connection conn = DriverManager.getConnection(getUrl())) { - String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); - conn.createStatement().execute(ddl); - assertConditionTTL(conn, tableName, ttl); - ddl = String.format(indexTemplate, indexName, tableName); - conn.createStatement().execute(ddl); - assertTTL(conn, indexName, TTL_EXPRESSION_NOT_DEFINED); - } + @Test + public void testUncoveredIndexRelaxedTTL() throws Exception { + String ddlTemplate = "create table %s (id varchar not null primary key, " + + "col1 integer, col2 integer, col3 double, col4 varchar) TTL = '%s', IS_STRICT_TTL=false"; + String tableName = generateUniqueName(); + String indexTemplate = "create uncovered index %s on %s (col1) "; + String indexName = generateUniqueName(); + String ttl = "col2 > 100 AND col4='expired'"; + try (Connection conn = DriverManager.getConnection(getUrl())) { + String ddl = String.format(ddlTemplate, tableName, retainSingleQuotes(ttl)); + conn.createStatement().execute(ddl); + assertConditionTTL(conn, tableName, ttl); + ddl = String.format(indexTemplate, indexName, tableName); + conn.createStatement().execute(ddl); + assertTTL(conn, indexName, TTL_EXPRESSION_NOT_DEFINED); } + } @Test public void testCreatingIndexWithMissingExprCols() throws Exception { @@ -621,7 +621,27 @@ public void testSettingCondTTLOnTableWithIndexWithMissingExprCols() throws Excep assertTrue(e.getCause() instanceof ColumnNotFoundException); } // relaxed ttl - ddl = String.format("alter table %s set TTL = '%s', IS_STRICT_TTL = false", tableName, retainSingleQuotes(ttl)); + ddl = String.format("alter table %s set TTL = '%s', IS_STRICT_TTL = false", tableName, + retainSingleQuotes(ttl)); + conn.createStatement().execute(ddl); + assertTTL(conn, indexName, TTL_EXPRESSION_NOT_DEFINED); + } + } + + @Test + public void testSettingCondTTLOnTableWithRelaxedTTLAndUncoveredIndex() throws Exception { + String ddlTemplate = "create table %s (id varchar not null primary key, " + + "col1 integer, col2 integer, col3 double, col4 varchar) IS_STRICT_TTL = false"; + String tableName = generateUniqueName(); + String indexTemplate = "create uncovered index %s on %s (col1)"; + String indexName = generateUniqueName(); + String ttl = "col2 > 100 AND col4='expired'"; + try (Connection conn = DriverManager.getConnection(getUrl())) { + String ddl = String.format(ddlTemplate, tableName); + conn.createStatement().execute(ddl); + ddl = String.format(indexTemplate, indexName, tableName); + conn.createStatement().execute(ddl); + ddl = String.format("alter table %s set TTL = '%s'", tableName, retainSingleQuotes(ttl)); conn.createStatement().execute(ddl); assertTTL(conn, indexName, TTL_EXPRESSION_NOT_DEFINED); } From 2940014e5603785bde9d34b8bb8bb0d9fe17a087 Mon Sep 17 00:00:00 2001 From: Palash Chauhan Date: Thu, 29 Jan 2026 14:38:37 -0800 Subject: [PATCH 3/3] review fixes --- .../phoenix/schema/ConditionalTTLExpression.java | 12 +++++++++--- .../apache/phoenix/schema/LiteralTTLExpression.java | 2 +- .../org/apache/phoenix/schema/MetaDataClient.java | 10 ++++++---- .../org/apache/phoenix/schema/TTLExpression.java | 8 +++++--- .../phoenix/schema/ConditionalTTLExpressionTest.java | 8 ++++++-- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/ConditionalTTLExpression.java b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/ConditionalTTLExpression.java index a5ec9263df3..d504cdff27b 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/ConditionalTTLExpression.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/ConditionalTTLExpression.java @@ -18,6 +18,7 @@ package org.apache.phoenix.schema; import static org.apache.phoenix.schema.PTable.ImmutableStorageScheme.ONE_CELL_PER_COLUMN; +import static org.apache.phoenix.schema.PTable.IndexType.UNCOVERED_GLOBAL; import static org.apache.phoenix.schema.PTable.QualifierEncodingScheme.NON_ENCODED_QUALIFIERS; import static org.apache.phoenix.schema.PTableType.CDC; import static org.apache.phoenix.schema.PTableType.VIEW; @@ -181,17 +182,22 @@ public void validateTTLOnCreate(PhoenixConnection conn, CreateTableStatement cre /** * @param table TABLE | VIEW referenced in ALTER statement */ - public void validateTTLOnAlter(PhoenixConnection conn, PTable table) throws SQLException { + public void validateTTLOnAlter(PhoenixConnection conn, PTable table, boolean isStrictTTL) + throws SQLException { // first validate the expression on the entity being changed validateTTLExpression(conn, table, null); for (PTable index : table.getIndexes()) { try { - if (CDCUtil.isCDCIndex(index)) { + if ( + CDCUtil.isCDCIndex(index) + || (!isStrictTTL && UNCOVERED_GLOBAL.equals(index.getIndexType())) + ) { // CDC index doesn't inherit ConditionTTL expression + // skip validation if index is uncovered and TTL is not strict continue; } - // verify that the new expression is covered by all the existing indexes + // verify that the new expression is covered by all the existing covered indexes buildExpression(conn, index, table); } catch (ColumnNotFoundException | ColumnFamilyNotFoundException e) { throw new SQLException( diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/LiteralTTLExpression.java b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/LiteralTTLExpression.java index 6890ee121cc..d791dcdd449 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/LiteralTTLExpression.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/LiteralTTLExpression.java @@ -89,7 +89,7 @@ public void validateTTLOnCreate(PhoenixConnection conn, CreateTableStatement cre } @Override - public void validateTTLOnAlter(PhoenixConnection connection, PTable table) { + public void validateTTLOnAlter(PhoenixConnection connection, PTable table, boolean isStrictTTL) { } @Override diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java index 481b44bfa9e..0852edef9da 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java @@ -129,6 +129,7 @@ import static org.apache.phoenix.schema.PTable.EncodedCQCounter.NULL_COUNTER; import static org.apache.phoenix.schema.PTable.ImmutableStorageScheme.ONE_CELL_PER_COLUMN; import static org.apache.phoenix.schema.PTable.ImmutableStorageScheme.SINGLE_CELL_ARRAY_WITH_OFFSETS; +import static org.apache.phoenix.schema.PTable.IndexType.UNCOVERED_GLOBAL; import static org.apache.phoenix.schema.PTable.QualifierEncodingScheme.NON_ENCODED_QUALIFIERS; import static org.apache.phoenix.schema.PTable.ViewType.MAPPED; import static org.apache.phoenix.schema.PTableType.CDC; @@ -2529,7 +2530,10 @@ private PTable createTableInternal(CreateTableStatement statement, byte[][] spli } else { ttlFromHierarchy = checkAndGetTTLFromHierarchy(parent, tableName); if (!ttlFromHierarchy.equals(TTL_EXPRESSION_NOT_DEFINED)) { - if (parent.hasConditionalTTL() && !parent.isStrictTTL()) { + if ( + UNCOVERED_GLOBAL.equals(indexType) && parent.hasConditionalTTL() + && !parent.isStrictTTL() + ) { ttlFromHierarchy = TTL_EXPRESSION_NOT_DEFINED; } else { ttlFromHierarchy.validateTTLOnCreate(connection, statement, parent, tableProps); @@ -6419,9 +6423,7 @@ private boolean evaluateStmtProperties(MetaProperties metaProperties, TTLExpression newTTL = metaProperties.getTTL(); boolean isStrictTTL = metaProperties.isStrictTTL() != null ? metaProperties.isStrictTTL : table.isStrictTTL(); - if (!(newTTL instanceof ConditionalTTLExpression) || isStrictTTL) { - newTTL.validateTTLOnAlter(connection, table); - } + newTTL.validateTTLOnAlter(connection, table, isStrictTTL); metaPropertiesEvaluated.setTTL(getCompatibleTTLExpression(metaProperties.getTTL(), table.getType(), table.getViewType(), table.getName().toString())); changingPhoenixTableProperty = true; diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/TTLExpression.java b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/TTLExpression.java index ef4b65a0f0a..313660cef9d 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/schema/TTLExpression.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/schema/TTLExpression.java @@ -44,10 +44,12 @@ void validateTTLOnCreate(PhoenixConnection conn, CreateTableStatement create, PT /** * Validate the TTL expression on ALTER [TABLE | VIEW] - * @param connection Phoenix connection - * @param table PTable of the entity being changed + * @param connection Phoenix connection + * @param table PTable of the entity being changed + * @param isStrictTTL True if the TTL being set is strict */ - void validateTTLOnAlter(PhoenixConnection connection, PTable table) throws SQLException; + void validateTTLOnAlter(PhoenixConnection connection, PTable table, boolean isStrictTTL) + throws SQLException; /** * Compile the TTL expression so that it can be evaluated against of a row of cells diff --git a/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java index 7e6fa9128f2..5de46ead0c8 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/schema/ConditionalTTLExpressionTest.java @@ -623,8 +623,12 @@ public void testSettingCondTTLOnTableWithIndexWithMissingExprCols() throws Excep // relaxed ttl ddl = String.format("alter table %s set TTL = '%s', IS_STRICT_TTL = false", tableName, retainSingleQuotes(ttl)); - conn.createStatement().execute(ddl); - assertTTL(conn, indexName, TTL_EXPRESSION_NOT_DEFINED); + try { + conn.createStatement().execute(ddl); + fail("Should have thrown ColumnNotFoundException"); + } catch (SQLException e) { + assertTrue(e.getCause() instanceof ColumnNotFoundException); + } } }