Skip to content

fix: inline UUID and Decimal results in two-phase comparison queries on ClickHouse - #10051

Merged
nishantmonu51 merged 2 commits into
mainfrom
nishant/two-phase-comparison-uuid-decimal
Oct 22, 2026
Merged

nishantmonu51 merged 2 commits into
mainfrom
nishant/two-phase-comparison-uuid-decimal

Conversation

@nishantmonu51

@nishantmonu51 nishantmonu51 commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Comparison queries with a row limit are rewritten to two phases: the base range is queried first and its rows are inlined with FROM VALUES into the comparison query, which then only aggregates the dimension values on the page. The ClickHouse dialect only inlined types with native Go bindings, so a UUID dimension or a Decimal measure made SelectInlineResults return ErrOptimizationFailure and the query silently fell back to aggregating the whole comparison range. On a high-cardinality id dimension that is a GROUP BY over every id in the comparison range to look up a handful of values.

  • SelectInlineResults for ClickHouse now accepts UUID and Decimal fields and inlines them as CAST(? AS <raw type>), e.g. CAST(? AS Nullable(UUID)) or CAST(? AS Decimal(38, 2)). The driver binds both as quoted strings, which VALUES would otherwise turn into a String column that ClickHouse refuses to join with the original column (NO_COMMON_TYPE, ILLEGAL_TYPE_OF_ARGUMENT on isNotDistinctFrom).
  • Tests: a driver-level round trip of inlined UUID, Nullable(UUID), Decimal, Nullable(Decimal) and Date values, and an executor integration test that runs a comparison leaderboard on a nullable UUID dimension with a Decimal measure, compares it with a hand-written single query, and checks system.query_log that the second phase ran with the inlined, cast base results.

Steps to reproduce:

  1. On a ClickHouse project, add a dimension on a UUID column (or a measure that sums a Decimal column) to a metrics view and open its explore dashboard with a time comparison enabled.
  2. Look at the leaderboard query in the ClickHouse query log.
  3. Before: no FROM VALUES; the comparison side is a full GROUP BY over the comparison range. After: the second phase inlines the base rows as FROM VALUES((CAST(? AS UUID), ...)) and filters the comparison side with <dimension> IN (...).

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

…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.
@nishantmonu51
nishantmonu51 requested a review from pjain1 October 21, 2026 21:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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

@nishantmonu51
nishantmonu51 merged commit 6795028 into main Oct 22, 2026
15 of 16 checks passed
@nishantmonu51
nishantmonu51 deleted the nishant/two-phase-comparison-uuid-decimal branch October 22, 2026 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants