Repository navigation
fix: inline UUID and Decimal results in two-phase comparison queries on ClickHouse - #10051
Merged
Merged
Conversation
…on ClickHouse The ClickHouse dialect only inlined result types with native Go bindings, so a UUID dimension or a Decimal measure made SelectInlineResults return ErrOptimizationFailure and comparison queries silently aggregated the whole comparison range instead of only the dimension values on the page. UUID and Decimal values are now inlined as CAST(? AS <raw type>), which keeps the inlined column joinable with the original column. The two-phase rewrite also logs why it skips a comparison query at debug level.
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The focused change has driver and executor regression coverage with no identified blocking issues, though tests were not executed during this review.
No open issues 🎉
What changed in this PR
This PR keeps ClickHouse comparison queries on the optimized two-phase path when base results contain UUID or Decimal values, avoiding full aggregation of the comparison range.
Changes:
- Allows UUID and Decimal results to be inlined with casts that preserve their ClickHouse types.
- Adds driver round-trip tests for UUID, Decimal, nullable variants, and Date values.
- Adds an executor regression test checking comparison results and query-log evidence of the optimized path.
| File | Description |
|---|---|
| runtime/metricsview/executor/executor_rewrite_two_phase_comparisons_integration_test.go | Verifies comparison correctness and use of cast, inlined base results. |
| runtime/drivers/clickhouse/olap_test.go | Tests value and type preservation when inlining results. |
| runtime/drivers/clickhouse/dialect.go | Supports UUID and Decimal inlining through explicit casts. |
Review effort: Balanced
pjain1
approved these changes
Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Comparison queries with a row limit are rewritten to two phases: the base range is queried first and its rows are inlined with
FROM VALUESinto the comparison query, which then only aggregates the dimension values on the page. The ClickHouse dialect only inlined types with native Go bindings, so aUUIDdimension or aDecimalmeasure madeSelectInlineResultsreturnErrOptimizationFailureand the query silently fell back to aggregating the whole comparison range. On a high-cardinality id dimension that is aGROUP BYover every id in the comparison range to look up a handful of values.SelectInlineResultsfor ClickHouse now acceptsUUIDandDecimalfields and inlines them asCAST(? AS <raw type>), e.g.CAST(? AS Nullable(UUID))orCAST(? AS Decimal(38, 2)). The driver binds both as quoted strings, whichVALUESwould otherwise turn into aStringcolumn that ClickHouse refuses to join with the original column (NO_COMMON_TYPE,ILLEGAL_TYPE_OF_ARGUMENTonisNotDistinctFrom).UUID,Nullable(UUID),Decimal,Nullable(Decimal)andDatevalues, and an executor integration test that runs a comparison leaderboard on a nullableUUIDdimension with aDecimalmeasure, compares it with a hand-written single query, and checkssystem.query_logthat the second phase ran with the inlined, cast base results.Steps to reproduce:
UUIDcolumn (or a measure that sums aDecimalcolumn) to a metrics view and open its explore dashboard with a time comparison enabled.FROM VALUES; the comparison side is a fullGROUP BYover the comparison range. After: the second phase inlines the base rows asFROM VALUES((CAST(? AS UUID), ...))and filters the comparison side with<dimension> IN (...).Checklist: