From 01a88d792425310f3d6789d10d7001b99d5c01d8 Mon Sep 17 00:00:00 2001 From: Palash Chauhan Date: Fri, 21 Nov 2025 11:04:51 -0800 Subject: [PATCH] PHOENIX-7732 : Drop CDC should not throw TNFE when IF EXISTS is used (#2318) Co-authored-by: Palash Chauhan --- .../apache/phoenix/schema/MetaDataClient.java | 45 +++++++++++-------- .../phoenix/end2end/CDCDefinitionIT.java | 16 +++++++ 2 files changed, 43 insertions(+), 18 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 99ffe141566..edb38da970c 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 @@ -4060,26 +4060,35 @@ public MutationState dropCDC(DropCDCStatement statement) throws SQLException { String schemaName = statement.getTableName().getSchemaName(); String cdcTableName = statement.getCdcObjName().getName(); String parentTableName = statement.getTableName().getTableName(); - String indexName = CDCUtil.getCDCIndexName(statement.getCdcObjName().getName()); - // Mark CDC Stream as Disabled - long cdcIndexTimestamp = - connection.getTable(SchemaUtil.getTableName(schemaName, indexName)).getTimeStamp(); - String fullParentTableName = SchemaUtil.getTableName(schemaName, parentTableName); - String streamName = String.format(CDC_STREAM_NAME_FORMAT, fullParentTableName, cdcTableName, - cdcIndexTimestamp, CDCUtil.getCDCCreationUTCDateTime(cdcIndexTimestamp)); - markCDCStreamStatus(fullParentTableName, streamName, CDCUtil.CdcStreamStatus.DISABLED); - // Dropping the virtual CDC Table - dropTable(schemaName, cdcTableName, parentTableName, PTableType.CDC, statement.ifExists(), - false, false); - // Dropping the uncovered index associated with the CDC Table + boolean ifExists = statement.ifExists(); + MutationState mutationState = new MutationState(0, 0, connection); try { - return dropTable(schemaName, indexName, parentTableName, PTableType.INDEX, - statement.ifExists(), false, false); - } catch (SQLException e) { - throw new SQLExceptionInfo.Builder(SQLExceptionCode.fromErrorCode(e.getErrorCode())) - .setTableName(statement.getCdcObjName().getName()).setRootCause(e.getCause()).build() - .buildException(); + String indexName = CDCUtil.getCDCIndexName(statement.getCdcObjName().getName()); + // Mark CDC Stream as Disabled + long cdcIndexTimestamp = + connection.getTable(SchemaUtil.getTableName(schemaName, indexName)).getTimeStamp(); + String fullParentTableName = SchemaUtil.getTableName(schemaName, parentTableName); + String streamName = String.format(CDC_STREAM_NAME_FORMAT, fullParentTableName, cdcTableName, + cdcIndexTimestamp, CDCUtil.getCDCCreationUTCDateTime(cdcIndexTimestamp)); + markCDCStreamStatus(fullParentTableName, streamName, CDCUtil.CdcStreamStatus.DISABLED); + // Dropping the virtual CDC Table + dropTable(schemaName, cdcTableName, parentTableName, PTableType.CDC, statement.ifExists(), + false, false); + // Dropping the uncovered index associated with the CDC Table + try { + mutationState = dropTable(schemaName, indexName, parentTableName, PTableType.INDEX, + statement.ifExists(), false, false); + } catch (SQLException e) { + throw new SQLExceptionInfo.Builder(SQLExceptionCode.fromErrorCode(e.getErrorCode())) + .setTableName(statement.getCdcObjName().getName()).setRootCause(e.getCause()).build() + .buildException(); + } + } catch (MetaDataEntityNotFoundException e) { + if (!ifExists) { + throw e; + } } + return mutationState; } private void markCDCStreamStatus(String tableName, String streamName, diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CDCDefinitionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CDCDefinitionIT.java index 0aee3c9ab19..8e314b31704 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CDCDefinitionIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CDCDefinitionIT.java @@ -295,6 +295,22 @@ public void testIndexNameAfterCreateCDC() throws Exception { } } + @Test + public void testDropCDCIfExists() throws SQLException { + Properties props = new Properties(); + Connection conn = DriverManager.getConnection(getUrl(), props); + String tableName = generateUniqueName(); + String schemaName = null; + String viewName = forView ? generateUniqueName() : null; + String fullTableName = SchemaUtil.getTableName(schemaName, tableName); + if (forView) { + fullTableName = SchemaUtil.getTableName(schemaName, viewName); + } + String cdcName = generateUniqueName(); + String drop_cdc_sql = "DROP CDC IF EXISTS " + cdcName + " ON " + fullTableName; + conn.createStatement().execute(drop_cdc_sql); + } + @Test public void testDropCDC() throws SQLException { Properties props = new Properties();