This is an automated email from the ASF dual-hosted git repository.

palashc 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 3050049d30 PHOENIX-7753 : Allow uncovered index creation on tables 
with relaxed conditional TTL (#2357)
3050049d30 is described below

commit 3050049d30f70c50dc8e3782beab5246361828c4
Author: Palash Chauhan <[email protected]>
AuthorDate: Thu Feb 5 16:20:03 2026 -0800

    PHOENIX-7753 : Allow uncovered index creation on tables with relaxed 
conditional TTL (#2357)
    
    Co-authored-by: Palash Chauhan 
<[email protected]>
---
 .../phoenix/schema/ConditionalTTLExpression.java   | 12 ++-
 .../phoenix/schema/LiteralTTLExpression.java       |  2 +-
 .../org/apache/phoenix/schema/MetaDataClient.java  | 18 +++--
 .../org/apache/phoenix/schema/TTLExpression.java   |  8 +-
 .../phoenix/coprocessor/MetaDataEndpointImpl.java  | 49 +++++++++---
 .../org/apache/phoenix/end2end/SetPropertyIT.java  | 44 +++++++++++
 .../schema/ConditionalTTLExpressionTest.java       | 87 +++++++++++++++-------
 7 files changed, 168 insertions(+), 52 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 a5ec9263df..d504cdff27 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 class ConditionalTTLExpression implements 
TTLExpression {
   /**
    * @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 6890ee121c..d791dcdd44 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 class LiteralTTLExpression implements TTLExpression, 
CompiledTTLExpressio
   }
 
   @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 1b8e898bd3..0da85f851d 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
@@ -131,6 +131,7 @@ import static 
org.apache.phoenix.schema.LiteralTTLExpression.TTL_EXPRESSION_NOT_
 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;
@@ -2402,11 +2403,14 @@ public class MetaDataClient {
    * @return TTL from hierarchy if defined otherwise TTL_NOT_DEFINED.
    * @throws TableNotFoundException if not able ot find any table in hierarchy
    */
-  private TTLExpression checkAndGetTTLFromHierarchy(PTable parent, String 
entityName)
-    throws SQLException {
+  private TTLExpression checkAndGetTTLFromHierarchy(PTable parent, String 
entityName,
+    IndexType indexType) throws SQLException {
     if (CDCUtil.isCDCIndex(entityName)) {
       return TTL_EXPRESSION_FOREVER;
     }
+    if (UNCOVERED_GLOBAL.equals(indexType) && parent.hasConditionalTTL() && 
!parent.isStrictTTL()) {
+      return TTL_EXPRESSION_NOT_DEFINED;
+    }
     return parent != null
       ? (parent.getType() == TABLE
         ? parent.getTTLExpression()
@@ -2516,7 +2520,7 @@ public class MetaDataClient {
             
SQLExceptionCode.TTL_SUPPORTED_FOR_TABLES_AND_VIEWS_ONLY).setSchemaName(schemaName)
               .setTableName(tableName).build().buildException();
         }
-        ttlFromHierarchy = checkAndGetTTLFromHierarchy(parent, tableName);
+        ttlFromHierarchy = checkAndGetTTLFromHierarchy(parent, tableName, 
indexType);
         if (!ttlFromHierarchy.equals(TTL_EXPRESSION_NOT_DEFINED)) {
           throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.TTL_ALREADY_DEFINED_IN_HIERARCHY)
             
.setSchemaName(schemaName).setTableName(tableName).build().buildException();
@@ -2530,7 +2534,7 @@ public class MetaDataClient {
         }
         ttl = getCompatibleTTLExpression(ttlProp, tableType, viewType, 
fullTableName);
       } else {
-        ttlFromHierarchy = checkAndGetTTLFromHierarchy(parent, tableName);
+        ttlFromHierarchy = checkAndGetTTLFromHierarchy(parent, tableName, 
indexType);
         if (!ttlFromHierarchy.equals(TTL_EXPRESSION_NOT_DEFINED)) {
           ttlFromHierarchy.validateTTLOnCreate(connection, statement, parent, 
tableProps);
         }
@@ -4856,7 +4860,7 @@ public class MetaDataClient {
           if (table.getType() != PTableType.TABLE) {
             ttlAlreadyDefined = checkAndGetTTLFromHierarchy(
               PhoenixRuntime.getTableNoCache(connection, 
table.getParentName().toString()),
-              tableName);
+              tableName, table.getIndexType());
           }
           if (!ttlAlreadyDefined.equals(TTL_EXPRESSION_NOT_DEFINED)) {
             throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.TTL_ALREADY_DEFINED_IN_HIERARCHY)
@@ -6541,7 +6545,9 @@ public class MetaDataClient {
       }
       if (metaProperties.getTTL() != table.getTTLExpression()) {
         TTLExpression newTTL = metaProperties.getTTL();
-        newTTL.validateTTLOnAlter(connection, table);
+        boolean isStrictTTL =
+          metaProperties.isStrictTTL() != null ? metaProperties.isStrictTTL : 
table.isStrictTTL();
+        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 ef4b65a0f0..313660cef9 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 @@ public interface TTLExpression {
 
   /**
    * 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-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
 
b/phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index c8ee55138c..9d3d0b3ca4 100644
--- 
a/phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ 
b/phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -92,6 +92,7 @@ import static 
org.apache.phoenix.query.QueryServices.SYSTEM_CATALOG_INDEXES_ENAB
 import static 
org.apache.phoenix.query.QueryServicesOptions.DEFAULT_SYSTEM_CATALOG_INDEXES_ENABLED;
 import static 
org.apache.phoenix.schema.LiteralTTLExpression.TTL_EXPRESSION_FOREVER;
 import static 
org.apache.phoenix.schema.LiteralTTLExpression.TTL_EXPRESSION_NOT_DEFINED;
+import static org.apache.phoenix.schema.PTable.IndexType.UNCOVERED_GLOBAL;
 import static org.apache.phoenix.schema.PTable.LinkType.PARENT_TABLE;
 import static org.apache.phoenix.schema.PTable.LinkType.PHYSICAL_TABLE;
 import static 
org.apache.phoenix.schema.PTable.LinkType.VIEW_INDEX_PARENT_TABLE;
@@ -227,6 +228,7 @@ import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.schema.ConditionalTTLExpression;
 import org.apache.phoenix.schema.MetaDataSplitPolicy;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnFamily;
@@ -1779,13 +1781,7 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements RegionCopr
       // If this is an index on Table get TTL from Table
       byte[] tableKey = getTableKey(tenantId == null ? null : 
tenantId.getBytes(),
         parentSchemaName == null ? null : parentSchemaName.getBytes(), 
parentTableName.getBytes());
-      ttl = getTTLForTable(tableKey, clientTimeStamp);
-    }
-    if (
-      tableType == INDEX && CDCUtil.isCDCIndex(tableName.getString())
-        && !ttl.equals(TTL_EXPRESSION_NOT_DEFINED)
-    ) {
-      ttl = TTL_EXPRESSION_FOREVER;
+      ttl = getTTLForParentTable(tableKey, clientTimeStamp, 
tableName.getString(), indexType);
     }
     builder.setTTL(ttl);
     builder.setEncodedCQCounter(cqCounter);
@@ -1887,7 +1883,7 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements RegionCopr
 
     // Return TTL defined at Table level for the given hierarchy as we didn't 
find TTL any of the
     // views.
-    return getTTLForTable(tableKey, clientTimeStamp);
+    return getTTLForParentTable(tableKey, clientTimeStamp, null, null);
 
   }
 
@@ -1900,12 +1896,17 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements RegionCopr
   }
 
   /***
-   * Get TTL Value stored in SYSCAT for a given table
+   * Get TTL Value stored in SYSCAT for a parent table of an index or a view
    * @param tableKey        of table for which we are fining TTL
    * @param clientTimeStamp client TimeStamp value
-   * @return TTL defined for a given table if it is null then return 
TTL_NOT_DEFINED(0)
+   * @param indexName       name of the index whose parent's ttl we are 
looking up
+   * @param indexType       type of the index whose parent's ttl we are 
looking up
+   * @return TTL defined for a given table if it is null then return 
TTL_NOT_DEFINED(0) For non-CDC
+   *         uncovered global indexes with conditional relaxed TTL parent, 
return
+   *         TTL_EXPRESSION_NOT_DEFINED For CDC index, return 
TTL_EXPRESSION_FOREVER
    */
-  private TTLExpression getTTLForTable(byte[] tableKey, long clientTimeStamp) 
throws IOException {
+  private TTLExpression getTTLForParentTable(byte[] tableKey, long 
clientTimeStamp,
+    String indexName, IndexType indexType) throws IOException {
     Scan scan = MetaDataUtil.newTableRowsScan(tableKey, MIN_TABLE_TIMESTAMP, 
clientTimeStamp);
     Table sysCat = ServerUtil.getHTableForCoprocessorScan(this.env,
       SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, 
env.getConfiguration()));
@@ -1918,7 +1919,22 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements RegionCopr
       if (result.getValue(TABLE_FAMILY_BYTES, TTL_BYTES) != null) {
         String ttlStr = (String) PVarchar.INSTANCE
           .toObject(result.getValue(DEFAULT_COLUMN_FAMILY_BYTES, TTL_BYTES));
-        return TTLExpressionFactory.create(ttlStr);
+        TTLExpression ttl = TTLExpressionFactory.create(ttlStr);
+        if (UNCOVERED_GLOBAL.equals(indexType)) {
+          if (CDCUtil.isCDCIndex(indexName)) {
+            if (!ttl.equals(TTL_EXPRESSION_NOT_DEFINED)) {
+              return TTL_EXPRESSION_FOREVER;
+            }
+          } else if (ttl instanceof ConditionalTTLExpression) {
+            byte[] isStrictTTLBytes = result.getValue(TABLE_FAMILY_BYTES, 
IS_STRICT_TTL_BYTES);
+            boolean isStrictTTL = isStrictTTLBytes != null
+              && 
Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(isStrictTTLBytes));
+            if (!isStrictTTL) {
+              return TTL_EXPRESSION_NOT_DEFINED;
+            }
+          }
+        }
+        return ttl;
       }
       result = scanner.next();
     } while (result != null);
@@ -3840,6 +3856,15 @@ public class MetaDataEndpointImpl extends 
MetaDataProtocol implements RegionCopr
         for (ImmutableBytesPtr invalidateKey : invalidateList) {
           metaDataCache.invalidate(invalidateKey);
         }
+        // Also invalidate indexes
+        if (table != null && table.getIndexes() != null) {
+          for (PTable index : table.getIndexes()) {
+            byte[] indexKey = SchemaUtil.getTableKey(tenantId,
+              index.getSchemaName() == null ? null : 
index.getSchemaName().getBytes(),
+              index.getTableName().getBytes());
+            metaDataCache.invalidate(new ImmutableBytesPtr(indexKey));
+          }
+        }
         // Get client timeStamp from mutations, since it may get updated by the
         // mutateRowsWithLocks call
         long currentTime = MetaDataUtil.getClientTimeStamp(tableMetadata);
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java
index 6f42280918..06e4b03aaf 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SetPropertyIT.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.end2end;
 import static 
org.apache.phoenix.coprocessorclient.BaseScannerRegionObserverConstants.PHOENIX_MAX_LOOKBACK_AGE_CONF_KEY;
 import static 
org.apache.phoenix.schema.LiteralTTLExpression.TTL_EXPRESSION_NOT_DEFINED;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+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.assertTrue;
@@ -41,6 +42,7 @@ import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.ConditionalTTLExpressionTest;
 import org.apache.phoenix.schema.LiteralTTLExpression;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
@@ -100,6 +102,48 @@ public abstract class SetPropertyIT extends 
ParallelStatsDisabledIT {
     return sb.toString();
   }
 
+  @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);
+      ConditionalTTLExpressionTest.assertConditionTTL(conn, tableName, ttl);
+      ConditionalTTLExpressionTest.assertTTL(conn, indexName, 
TTL_EXPRESSION_NOT_DEFINED);
+    }
+  }
+
+  @Test
+  public void testSettingCondTTLOnTableWithStrictLiteralTTLAndUncoveredIndex() 
throws Exception {
+    String ddlTemplate = "create table %s (id varchar not null primary key, "
+      + "col1 integer, col2 integer, col3 double, col4 varchar) TTL = 10000";
+    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', IS_STRICT_TTL = 
false", tableName,
+        retainSingleQuotes(ttl));
+      conn.createStatement().execute(ddl);
+      ConditionalTTLExpressionTest.assertConditionTTL(conn, tableName, ttl);
+      ConditionalTTLExpressionTest.assertIsStrictTTL(conn, tableName, false);
+      ConditionalTTLExpressionTest.assertTTL(conn, indexName, 
TTL_EXPRESSION_NOT_DEFINED);
+    }
+  }
+
   @Test
   public void testSetHColumnProperties() throws Exception {
     Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
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 b82dd5e72d..a0079999b8 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,18 +55,24 @@ import 
org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
 
 public class ConditionalTTLExpressionTest extends BaseConnectionlessQueryTest {
 
-  private static void assertConditonTTL(Connection conn, String tableName, 
String ttlExpr)
+  public static void assertConditionTTL(Connection conn, String tableName, 
String ttlExpr)
     throws SQLException {
     TTLExpression expected = new ConditionalTTLExpression(ttlExpr);
     assertTTL(conn, tableName, expected);
   }
 
-  private static void assertTTL(Connection conn, String tableName, 
TTLExpression expected)
+  public static void assertTTL(Connection conn, String tableName, 
TTLExpression expected)
     throws SQLException {
     PTable table = conn.unwrap(PhoenixConnection.class).getTable(tableName);
     assertEquals(expected, table.getTTLExpression());
   }
 
+  public static void assertIsStrictTTL(Connection conn, String tableName, 
boolean expected)
+    throws SQLException {
+    PTable table = conn.unwrap(PhoenixConnection.class).getTable(tableName);
+    assertEquals(expected, table.isStrictTTL());
+  }
+
   private void validateScan(Connection conn, String tableName, String query, 
String ttl,
     boolean useIndex, List<String> expectedColsInScan) throws SQLException {
     PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
@@ -105,7 +111,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +180,17 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +204,23 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +307,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +375,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +393,14 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +417,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +431,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +447,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +466,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
       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 +493,11 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
       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 +511,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +530,10 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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 +541,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
   }
 
   @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 +552,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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,7 +563,25 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
       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);
     }
   }
 
@@ -602,6 +626,15 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
       } 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));
+      try {
+        conn.createStatement().execute(ddl);
+        fail("Should have thrown ColumnNotFoundException");
+      } catch (SQLException e) {
+        assertTrue(e.getCause() instanceof ColumnNotFoundException);
+      }
     }
   }
 
@@ -615,7 +648,7 @@ public class ConditionalTTLExpressionTest extends 
BaseConnectionlessQueryTest {
     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);

Reply via email to