litiliu
05/29/2026, 7:15 AMauto.create.table.enabled.
PR: https://github.com/apache/flink-cdc/pull/4420
JIRA: https://issues.apache.org/jira/browse/FLINK-39797
The option defaults to true to preserve the current behavior. When set to false, the Fluss sink will fail if the target table does not already exist, instead of creating it automatically. This is useful for users who want to manage Fluss table creation explicitly.
Would appreciate your review when you have time. Thanks!litiliu
05/29/2026, 7:38 AMHongshun Wang
05/29/2026, 7:54 AMlitiliu
05/29/2026, 8:12 AMlitiliu
06/01/2026, 8:02 AMschema.create.mode.
The default remains CREATE_IF_NOT_EXISTS, so existing behavior is unchanged. For ERROR_IF_NOT_EXISTS, the framework wraps the sink MetadataApplier and skips table creation on `CreateTableEvent`; instead it checks that the target schema exists and validates compatibility through a new SupportsExistingSchemaValidation interface.
Fluss now validates existing columns, primary keys, and partition keys. MaxCompute validates schema and primary key. Unsupported sinks will fail fast when configured with ERROR_IF_NOT_EXISTS.
Would appreciate your review when you have time. Thanks!litiliu
06/05/2026, 7:44 AMkunni
06/07/2026, 5:38 AMschema.create.mode parameter to achieve it.
Schema validation on existing tables should be the default behavior of MetadataApplier, not something gated behind a configuration option. When a CreateTableEvent arrives:
- If the table doesn't exist β create it (as we do today).
- If the table already exists β validate schema compatibility (columns, primary keys, partition keys, etc.) and skip creation if compatible, or throw an exception if not.
This is a correctness concern, not a mode choice.
The ERROR_IF_NOT_EXISTS mode addresses a fairly niche scenario β requiring tables to be pre-created. In practice, users can already achieve this through database-level permission controls (e.g., not granting CREATE TABLE privileges). Adding a framework-level parameter for this seems like over-engineering.
From an implementation perspective, the SchemaCreateModeMetadataApplier wrapper adds an extra layer that every call passes through, but the validation logic is inherently sink-specific (e.g., Fluss needs to verify PKs and partition keys, Iceberg may need to verify field IDs). It would be more natural to put this validation directly inside each sink's MetadataApplier implementation.
My suggestion: enhance MetadataApplier to handle existing-table validation as part of its default CreateTableEvent processing, without introducing a new config parameter or wrapper class. This achieves the same goal with less complexity.litiliu
06/08/2026, 6:40 AMtarget.table.create.mode, and it only controls whether Flink CDC is allowed to create a missing target table.
In ERROR_IF_NOT_EXISTS mode, the framework only checks whether the target table already exists before delegating the CreateTableEvent to the original sink MetadataApplier. If the table does not exist, it fails early. If the table exists, the original sink-specific logic still runs as before, including any existing schema/PK/partition-key compatibility checks.
I agree that database-level permissions can be used as a workaround in some cases. However, I think it is not fully equivalent to an explicit pipeline policy. Permission control depends on the target system and deployment setup, and failures usually surface as system-specific permission errors after the sink attempts table creation.
With target.table.create.mode=ERROR_IF_NOT_EXISTS, users can declare the expected behavior directly in the pipeline config, and the framework can fail fast with a consistent error before automatic table creation is attempted. I kept this as a framework-level option because this capability is not Fluss-specific: other connectors may also need a clear way to require target tables to be pre-created and explicitly disable automatic table creation, while preserving the default CREATE_IF_NOT_EXISTS behavior for compatibility.
What do you think about this updated direction?