Antalya 26.1 - Add ALTER TABLE MODIFY SETTING support for Hybrid watermarks #1659
Antalya 26.1 - Add ALTER TABLE MODIFY SETTING support for Hybrid watermarks #1659mkmkme wants to merge 2 commits intoantalya-26.1from
Conversation
Introduce hybridParam('name', 'type') pseudo-function for Hybrid engine
predicates, allowing segment boundaries to be changed at runtime via
ALTER TABLE ... MODIFY SETTING without recreating the table.
Key design decisions:
- hybridParam() takes exactly two arguments (name, type); all values
must be provided via ENGINE SETTINGS, keeping the API surface minimal
and eliminating default-value complexity.
- Watermark names must start with 'hybrid_watermark_' and exactly match
a declared hybridParam() in the predicates. Typos in both CREATE
SETTINGS and ALTER are rejected.
- Values are validated against the declared type at CREATE and ALTER
time, so invalid values never reach the runtime substitution path.
- Only hybrid_watermark_* settings are allowed on Hybrid tables;
regular DistributedSettings and RESET SETTING are rejected.
- Runtime watermark state uses MultiVersion<std::map> for lock-free
reads and deterministic serialization order in SHOW CREATE TABLE.
- In StorageDistributed::alter(), the watermark snapshot is published
before in-memory metadata to prevent concurrent readers from
observing new metadata with stale watermark values.
- Predicate validation at CREATE time substitutes the effective
SETTINGS value (not the type default) so value-sensitive expressions
are checked against realistic data.
Tests:
- Stateless tests covering CREATE, ALTER, DETACH/ATTACH persistence,
multi-watermark, type conflict, invalid values, typo rejection,
RESET SETTING rejection, and DistributedSettings rejection.
- Integration tests covering single-node, cross-node, and cluster()
table function flows, each self-contained with own setup/teardown.
Documentation updated with hybridParam() syntax, ALTER examples,
multi-watermark usage, and restriction notes.
Made-with: Cursor
|
AI audit note: This review comment was generated by AI (gpt-5.4). Audit update for PR #1659 (ALTER TABLE MODIFY SETTING support for Hybrid watermarks): Confirmed defects:Medium: ALTER MODIFY SETTING skips full predicate revalidation Example: CREATE TABLE t
ENGINE = Hybrid(
remote('localhost:9000', currentDatabase(), 'hot'),
dateDiff(hybridParam('hybrid_watermark_unit', 'String'), ts, now()) < 30,
remote('localhost:9000', currentDatabase(), 'cold'),
dateDiff(hybridParam('hybrid_watermark_unit', 'String'), ts, now()) >= 30
)
SETTINGS hybrid_watermark_unit = 'day'
AS hot;This CREATE should pass because But this ALTER is currently accepted too: ALTER TABLE t MODIFY SETTING hybrid_watermark_unit = 'banana';ALTER only validates that dateDiff('banana', ts, now()) < 30which is semantically invalid for Coverage summary: |
|
The above comment is a very good point by FWIW the previous |
| { | ||
| auto * arg_list = func->arguments->as<ASTExpressionList>(); | ||
| const auto & param_name = arg_list->children[0]->as<ASTLiteral>()->value.safeGet<String>(); | ||
| const auto & type_name = arg_list->children[1]->as<ASTLiteral>()->value.safeGet<String>(); |
There was a problem hiding this comment.
Does make sense to check children size before to avoid out of bound error?
| if (auto * func = node->as<ASTFunction>(); func && func->name == "hybridParam") | ||
| { | ||
| auto * arg_list = func->arguments ? func->arguments->as<ASTExpressionList>() : nullptr; | ||
| if (arg_list && arg_list->children.size() >= 2) |
| if (name_lit && type_lit) | ||
| result.emplace(name_lit->value.safeGet<String>(), type_lit->value.safeGet<String>()); | ||
| } | ||
| return; |
There was a problem hiding this comment.
Am I right that method collects only type for first hybridParam in predicate and exits here? Technically condition can have several parameters.
| std::optional<NameDependencies> name_deps{}; | ||
| for (const auto & command : commands) | ||
| { | ||
| if (command.type == AlterCommand::Type::MODIFY_SETTING) |
There was a problem hiding this comment.
NIT: I think now better to use switch-case instead of multiple ifs here.
Introduce
hybridParam('name', 'type')pseudo-function for Hybrid enginepredicates, allowing segment boundaries to be changed at runtime via
ALTER TABLE ... MODIFY SETTINGwithout recreating the table.Key design decisions:
hybridParam()takes exactly two arguments (name,type); all valuesmust be provided via ENGINE SETTINGS, keeping the API surface minimal
and eliminating default-value complexity.
'hybrid_watermark_'and exactly matcha declared
hybridParam()in the predicates. Typos in bothCREATE SETTINGSandALTERare rejected.CREATEand ALTERtime, so invalid values never reach the runtime substitution path.
regular DistributedSettings and RESET SETTING are rejected.
reads and deterministic serialization order in SHOW CREATE TABLE.
before in-memory metadata to prevent concurrent readers from
observing new metadata with stale watermark values.
SETTINGS value (not the type default) so value-sensitive expressions
are checked against realistic data.
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Added support for moving Hybrid table watermarks
CI/CD Options
Exclude tests:
Regression jobs to run: