Repository navigation
Conversation
…ty/ClickHouse into data_lake_clustering_read
…9.2-with-panic-safe-ffi) Co-authored-by: Cursor <cursoragent@cursor.com>
…9.2-with-panic-safe-ffi)
…ty/ClickHouse into data_lake_clustering_read
|
This PR is dependent on changes to delta-kernel-rs |
Audit Report: Altinity/ClickHouse PR #2395PR: Altinity/ClickHouse#2395 — Read clustering columns from delta lake and use it for data skipping AI audit note: This review comment was generated by AI (claude-opus-4.6). ScopeThis PR adds support for reading Delta Lake liquid clustering columns from domain metadata ( Files changed
Call GraphTransition Matrix
Confirmed DefectsMedium: Clustering columns not invalidated on credential-rotation snapshot rebuild
Code evidence ( // Line 760: kernel_snapshot_state is reset, but clustering_columns is NOT
kernel_snapshot_state.reset();
initOrUpdateSnapshot();
snapshot_stats = getSnapshotStatsImpl();
// clustering_columns still holds old value hereCode evidence ( void TableSnapshot::initOrUpdateClusteringColumns() const
{
if (clustering_columns.has_value()) // <-- returns early with stale data
return;
// ...
}Medium:
|
…ty/ClickHouse into data_lake_clustering_read
|
AI audit note: This review comment was generated by AI (claude-4.6-opus). Audit update for PR Altinity/ClickHouse#2395 (Delta Lake liquid-clustering predicate fallback): Scope
Call GraphConfirmed defects:Low: Trivial
Coverage summary:
Additional observations (not defects):
|
|
TESTING |
|
@subkanthi pls do not forget to add the corresponding labels (port-antalya in particular) |
|
|
||
| addSettingsChanges(settings_changes_history, "26.6", | ||
| { | ||
| {"delta_lake_clustering_predicate_fallback", false, true, "New setting to enable clustering-aware predicate fallback for Delta Lake tables with Liquid Clustering."}, |
There was a problem hiding this comment.
Must be only in Antalya section above.
| return schema->physical_names_map; | ||
| } | ||
|
|
||
| const DB::Names & TableSnapshot::getClusteringColumns() const |
There was a problem hiding this comment.
I did not find where is this method called. Is it used, or just dead code?
There was a problem hiding this comment.
yes this function is not used, removed.
|
|
||
| if (!result) | ||
| { | ||
| LOG_TRACE(log, "No delta.clustering domain metadata found — table is not liquid-clustered"); |
There was a problem hiding this comment.
I think make sense to add a table name in message.
There was a problem hiding this comment.
TableSnapshot does not store the table name, but added the table location. IKernelHelper::getTableLocation()
| logical_columns = std::move(physical_columns); | ||
| } | ||
|
|
||
| LOG_TRACE(log, "Clustering columns: {}", fmt::join(logical_columns, ", ")); |
There was a problem hiding this comment.
Make sense to add table name here too.
There was a problem hiding this comment.
Same here added IKernelHelper::getTableLocation()
|
|
||
| auto arr = obj->getArray("clusteringColumns"); | ||
| if (!arr) | ||
| throw DB::Exception(DB::ErrorCodes::BAD_ARGUMENTS, "delta.clustering: missing clusteringColumns array"); |
There was a problem hiding this comment.
I thing BAD_ARGUMENTS is incorrect code here. It is used for arguments in queries, when here is some metadata incosistency.
There was a problem hiding this comment.
Replaced with INCORRECT_DATA error code.
| { | ||
| throw DB::Exception( | ||
| DB::ErrorCodes::BAD_ARGUMENTS, | ||
| "Failed to parse delta.clustering domain metadata: {}", e.displayText()); |
There was a problem hiding this comment.
The same as above about error code.
And what is going on when this exception thrown? Does customer have an opinion to execute query in old way?
There was a problem hiding this comment.
Replaced with INCORRECT_DATA error code.
| } | ||
|
|
||
| void TableSnapshot::initOrUpdateClusteringColumns() const | ||
| { |
There was a problem hiding this comment.
As I understand this method called in any case, but clustering_columns is used only when delta_lake_clustering_predicate_fallback=1. Make sense to check this setting here to avoid useless snapshot parsing when feature is turned off.
There was a problem hiding this comment.
Added logic to run initOrUpdateClusteringColumns only if delta_lake_clustering_predicate_fallback is set.
const bool need_clustering_columns = filter_dag
&& settings[DB::Setting::delta_lake_enable_engine_predicate]
&& settings[DB::Setting::delta_lake_clustering_predicate_fallback];
if (need_clustering_columns)
initOrUpdateClusteringColumns();
…ty/ClickHouse into data_lake_clustering_read
|
@ianton-ru can u please check this, i have addressed all comments. |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c9dbbc8ab0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| auto result = KernelUtils::unwrapResult( | ||
| ffi::get_domain_metadata_internal( | ||
| state->snapshot.get(), | ||
| KernelUtils::toDeltaString("delta.clustering"), | ||
| state->engine.get(), | ||
| KernelUtils::allocateString), | ||
| "get_domain_metadata_internal(delta.clustering)"); |
There was a problem hiding this comment.
Retry clustering metadata reads after credential rotation
When a cached snapshot uses catalog-vended temporary credentials that refresh only after an ExpiredToken, this new domain-metadata read runs with the stale engine and lets the resulting DELTA_KERNEL_ERROR escape. Because it happens before constructing Iterator, the existing scan retry cannot call refreshCredentials; consequently, the first filtered query after token expiry fails even though ordinary scans and stats recover. Apply the same refresh/rebuild/one-shot retry used by the other snapshot operations around this FFI call.
Useful? React with 👍 / 👎.
| # Tolerate pull failures for images that are expected to be present | ||
| # locally (e.g. CLICKHOUSE_CI_MIN_TESTED_VERSION tags that only exist | ||
| # in a private registry); `docker compose up` will use the local image. | ||
| images_pull_cmd = self.base_cmd + ["pull", "--ignore-pull-failures"] |
There was a problem hiding this comment.
Keep pull failures visible to the retry wrapper
For any ordinary registry failure, this flag suppresses the failure that run_and_check must observe to trigger its three retries. Docker documents --ignore-pull-failures as pulling what it can while ignoring failed images (Docker CLI reference); therefore a flaky pull can silently leave a stale same-tag image in place and run integration tests against it, or defer a missing-image failure until compose up without the intended pull retries. Limit the exception to the known local-only image rather than applying it to every service image.
AGENTS.md reference: AGENTS.md:L153-L153
Useful? React with 👍 / 👎.
| { | ||
| {"object_storage_cluster_fallback_to_local_if_empty", false, false, "New setting"}, | ||
| {"use_puffin_files_cache", false, true, "Enables cache of parsed Puffin file content such as deletion vectors."}, | ||
| {"delta_lake_clustering_predicate_fallback", false, true, "New setting to enable clustering-aware predicate fallback for Delta Lake tables with Liquid Clustering."}, |
There was a problem hiding this comment.
Record the setting at its actual release version
This commit is based on 26.6.8.20002, but the newly introduced setting is recorded as having changed in 26.6.2.20001. As a result, a user selecting compatibility with any intervening release such as 26.6.7 will not have the setting reverted to false, even though that release predates the feature. Move this history entry to the version that actually ships the new default so compatibility profiles reproduce the requested release behavior.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
moved to 26.6.8.20002 section
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e8453b94bc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /* schema */nullptr), | ||
| "scan"); | ||
|
|
||
| if (engine_predicate_exception && enable_clustering_predicate_fallback && !clustering_columns.empty()) |
There was a problem hiding this comment.
Trigger fallback for unsupported predicate nodes
For the intended a = 42 AND cityHash64(b) != 0 case, unsupported functions return VISITOR_FAILED_OR_UNSUPPORTED from EngineIterator::getNextImpl without setting engine_predicate_exception; only thrown exceptions populate that pointer. Consequently this condition is false, the clustering fallback and its profile event never run, and the newly added fallback test observes zero hits. Detect unsupported translation explicitly rather than using only the exception pointer.
Useful? React with 👍 / 👎.
| # Full scan — note the total scanned files. | ||
| full_scan_id = f"{TABLE_NAME}_full_scan" | ||
| instance.query(f"SELECT count() FROM {TABLE_NAME}", query_id=full_scan_id) |
There was a problem hiding this comment.
Force the baseline query to scan files
With delta-kernel enabled, an unfiltered SELECT count() uses totalRows() and the trivial-count optimization, whose stats visitor does not increment DeltaLakeScannedFiles. Therefore full_scan_files is zero while the filtered point query scans at least one file, so the later point_scan_files < full_scan_files assertion fails instead of testing pruning. Disable optimize_trivial_count_query for this baseline or read an actual column.
Useful? React with 👍 / 👎.
CI triage for
|
closes: ##2394
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Read clustering columns from
delta-kernel-rsand use that for data skipping.CI/CD Options
Exclude tests:
Regression jobs to run: