Skip to content

fix: SanityCheckPlan error when a per-partition constant leads an ordering - #27191

Open
jayzhan211 wants to merge 19 commits into
apache:mainfrom
jayzhan211:fix/per-partition-constant-ordering
Open

jayzhan211 wants to merge 19 commits into
apache:mainfrom
jayzhan211:fix/per-partition-constant-ordering

Conversation

@jayzhan211

@jayzhan211 jayzhan211 commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

Queries that planned in earlier releases fail with SanityCheckPlan when a window's input ordering starts with a per-partition constant or is proven through an equality such as a = CAST(c AS DATE). Across 7,440 generated query runs, main has 62 failures on queries that plan on 55.2.0, and this PR has none, with the same rows wherever both plan.

There are three causes. In each one, window planning and SanityCheckPlan reach different answers about whether the input is sorted:

Introduced by Example Why they disagree
#23528 (in 55.0.0) The #26762 query Normalized orderings keep per-partition constants, but add_constants drops them, so window planning sees [total] and SanityCheckPlan sees [k, total]
#25922 (on branch-56) A window on c over a TopK on (k, a, c), with k a per-partition constant and a = CAST(c AS DATE) add_constants discovers that [a, c] implies [c], but an ordering added after the equality doesn't
#26747 (on branch-56) A window on (k, c) over a TopK on (k, a, c), where a isn't selected The sort is removed below a projection because its input has the ordering, and the projection can't prove it

This PR replaces #27140 and keeps its commit.

What changes are included in this PR?

Start reading at add_orderings. It is the decision I most want reviewed, because it makes the optimizer claim more orderings, and a wrong claim means wrong results.

Where Change Fixes
SortKeyWalk::new An ordering's head skips leading fixed expressions before the first key is pinned #23528
add_orderings Discover the orderings a new ordering implies through known equalities, as add_constants and add_equal_conditions already do, for any key and past the constants an ordering keeps: [k, a, c] with a = CAST(c AS DATE) implies [k, c] #25922, #26747
handle_projection_pushdown If the input has the ordering but the projection can't prove it, keep the sort above the projection The failures the first row would otherwise add, when a projection drops a leading per-partition constant
RepartitionExec Clear per-partition constants before adding the merge ordering, as SortPreservingMergeExec does Otherwise the second row keeps [c] from [k, a, c] after a merge, where it holds only within each partition
SortKeyWalk::is_fixed Return early for a column that isn't pinned or constant The first row made single-key checks about 30% slower

Who is affected. Plans with an ordering that starts with a per-partition constant, or that is proven through an equality or a column a projection drops. It can't stop halfway.

No API change. Discovery in add_orderings can fail only on an expression that doesn't match the schema. That implied ordering is then left out, which can cost a sort but not change results.

Worst case. 4 of the 7,440 generated runs plan a sort that main doesn't: a GROUP BY k, c over a TopK on (a, c) with a = CAST(c AS DATE), at 4 partitions. Knowing [c], the aggregate streams on c and sorts on c after its hash repartition. main picks the same aggregate when the ordering is known before the equality. 392 runs have fewer sorts.

What is the testing strategy for this PR?

  • window.slt covers each cause, including a merge of partitions above the sort, and checks the plans. Removing any one of the first three changes, limiting discovery to the first key, or not skipping constants makes tests fail, in window.slt or in the unit tests for the walk and for implied orderings. A RepartitionExec unit test covers the merge.
  • All SLT files pass with no existing plan changing, as do the physical_optimizer integration tests and the equivalence fuzz tests.
  • A sweep of functions that look order-preserving but aren't found no wrong ordering. Details below.
Generated query runs, benchmarks, rejected alternatives, and queries that still fail

Generated runs. Each sweep runs at target_partitions 1 and 4. A regression plans on the reference build and fails on the other build.

Sweep Runs main, vs 55.2.0 main, vs before #23528 This PR, vs both
Per-partition constants: 6 inputs, 3 orderings, 5 projections, up to 12 consumers 2,016 0 4 0
Orderings proven through a = CAST(c AS DATE) 3,120 56 56 0
An operator between the ordering and the consumer: joins of each type on either side, filter, aggregate, union 1,584 6 36 0
head = f(arg) for CAST(x AS VARCHAR), ABS, negation, modulo, upper and order-preserving functions, in all 4 sort directions 720 0 0 0, and no wrong ordering

The results are the same with this patch on branch-56, where all SLT files pass as well. Compared with main on the runs that plan on both, the rows are the same, 4 runs have more sorts (see the worst case above) and 392 have fewer.

Benchmarks. equivalence_properties, best of 10 alternating runs on a busy laptop, so approximate: single-key checks are 6-12% slower (about 20-40 ns), and window-heavy orderings are 24-33% faster.

Benchmark main This PR
ordering_satisfy/1_key/8 359 ns 380 ns
ordering_satisfy_requirement/1_key/8 307 ns 329 ns
find_longest_permutation/1_expr/32 306 ns 344 ns
window/4 1,543 ns 1,181 ns
window/32 7,319 ns 4,889 ns

Rejected.

  • Having add_constants keep per-partition constants fails test_eliminate_redundant_monotonic_sorts.
  • Labelling lower(g) as a uniform constant isn't enough, because a constant from an aggregate without GROUP BY really is per-partition.
  • Having the projection leave a per-partition constant it drops out of its orderings, instead of the check in handle_projection_pushdown, makes 2 generated queries fail SanityCheckPlan: a window over a GROUP BY whose input ordering leads with such a constant.
  • Applying the projection check to every node in pushdown_sorts_helper only fixes one more query, and that query already fails on every release, so I kept the narrower check.

Still failing, not regressions. A window over a UNION ALL of two TopKs that have v AS w fails on every build I tried, including before #23528:

SELECT *, ROW_NUMBER() OVER (ORDER BY w) AS r FROM (
  SELECT k, v, w FROM (SELECT k, v, v AS w FROM (SELECT lower(g) AS k, v FROM t5 WHERE g = 'a') ORDER BY k, v LIMIT 30)
  UNION ALL
  SELECT k, v, w FROM (SELECT k, v, v AS w FROM (SELECT lower(g) AS k, v FROM t5 WHERE g = 'a') ORDER BY k, v LIMIT 30)
) ORDER BY r;

Are there any user-facing changes?

Affected queries plan again. This is a candidate for branch-56, where it applies without conflicts.

alamb and others added 2 commits November 7, 2026 13:03
A normal ordering keeps a constant whose value differs between partitions
(`AcrossPartitions::Heterogeneous`, since apache#23528), so such a constant can
lead a normal ordering. `SortKeyWalk` assumed every ordering's head was at
index 0 until the first key was pinned, so it treated the constant as the
head and did not see the expression after it. A window ordered by
`(total DESC, k)` over an input ordered by `[k, total]`, with `k` constant
within each partition, then failed `SanityCheckPlan`.

Compute the initial heads past leading fixed expressions, as the walk
already does after each pin.

Closes apache#26762

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added physical-expr Changes to the physical-expr crates optimizer Optimizer rules sqllogictest SQL Logic Tests (.slt) labels Nov 7, 2026
@jayzhan211

Copy link
Copy Markdown
Contributor Author

run benchmark sql_planner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6702859918-4581-nnfft 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/per-partition-constant-ordering (6e6a8ae) to 4bf32cb (merge-base) diff

Run configuration
run benchmark sql_planner

Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/per-partition-constant-ordering (6e6a8ae) to 4bf32cb (merge-base) diff

Run configuration
run benchmark sql_planner
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

group                                                 HEAD                                   fix_per-partition-constant-ordering
-----                                                 ----                                   -----------------------------------
logical_aggregate_with_join                           1.00    315.0±1.59µs        ? ?/sec    1.01    319.2±1.74µs        ? ?/sec
logical_correlated_subquery_exists                    1.00    211.4±1.45µs        ? ?/sec    1.00    212.4±1.30µs        ? ?/sec
logical_correlated_subquery_in                        1.00    212.9±0.71µs        ? ?/sec    1.01    214.7±0.81µs        ? ?/sec
logical_distinct_many_columns                         1.01    259.5±0.98µs        ? ?/sec    1.00    257.6±1.28µs        ? ?/sec
logical_join_4_with_agg_and_filter                    1.00    192.1±0.77µs        ? ?/sec    1.05    200.7±1.12µs        ? ?/sec
logical_join_8_with_agg_sort_limit                    1.00    334.9±1.81µs        ? ?/sec    1.02    343.0±2.66µs        ? ?/sec
logical_join_chain_16                                 1.00    622.2±4.02µs        ? ?/sec    1.01    627.1±3.29µs        ? ?/sec
logical_join_chain_4                                  1.00     73.7±0.28µs        ? ?/sec    1.02     75.5±0.42µs        ? ?/sec
logical_join_chain_8                                  1.00    201.5±1.20µs        ? ?/sec    1.01    204.0±1.03µs        ? ?/sec
logical_multiple_subqueries                           1.00    399.3±1.64µs        ? ?/sec    1.02    406.0±2.20µs        ? ?/sec
logical_nested_cte_4_levels                           1.00    192.7±1.17µs        ? ?/sec    1.04    199.5±1.04µs        ? ?/sec
logical_plan_struct_join_agg_sort                     1.00    123.3±0.82µs        ? ?/sec    1.03    127.3±0.91µs        ? ?/sec
logical_plan_tpcds_all                                1.00     70.9±0.74ms        ? ?/sec    1.01     71.5±0.68ms        ? ?/sec
logical_plan_tpch_all                                 1.00      5.2±0.02ms        ? ?/sec    1.00      5.2±0.01ms        ? ?/sec
logical_scalar_subquery                               1.00    220.1±1.53µs        ? ?/sec    1.01    222.5±1.64µs        ? ?/sec
logical_select_all_from_1000                          1.00      2.3±0.01ms        ? ?/sec    1.00      2.3±0.01ms        ? ?/sec
logical_select_one_from_700                           1.00    233.2±2.06µs        ? ?/sec    1.00    232.7±1.70µs        ? ?/sec
logical_trivial_join_high_numbered_columns            1.00    194.9±1.53µs        ? ?/sec    1.01    196.9±1.53µs        ? ?/sec
logical_trivial_join_low_numbered_columns             1.00    193.8±1.44µs        ? ?/sec    1.01    196.7±1.45µs        ? ?/sec
logical_union_4_branches                              1.00    316.7±1.65µs        ? ?/sec    1.02    321.6±1.55µs        ? ?/sec
logical_union_8_branches                              1.00    643.3±6.31µs        ? ?/sec    1.01    647.0±3.47µs        ? ?/sec
logical_wide_aggregate_1000_exprs                     1.00     20.9±0.06ms        ? ?/sec    1.00     20.9±0.04ms        ? ?/sec
logical_wide_aggregate_100_exprs                      1.00   1455.4±1.89µs        ? ?/sec    1.01   1465.0±3.65µs        ? ?/sec
logical_wide_case_50_exprs                            1.00   1426.6±3.99µs        ? ?/sec    1.00   1428.8±3.16µs        ? ?/sec
logical_wide_filter_200_predicates                    1.00   1072.5±5.61µs        ? ?/sec    1.00   1076.2±5.71µs        ? ?/sec
logical_wide_filter_50_predicates                     1.00    324.0±0.97µs        ? ?/sec    1.00    324.6±1.03µs        ? ?/sec
optimizer_correlated_exists                           1.00    220.3±0.72µs        ? ?/sec    1.00    219.5±0.50µs        ? ?/sec
optimizer_join_4_with_agg_filter                      1.00    380.5±1.73µs        ? ?/sec    1.01    383.7±1.63µs        ? ?/sec
optimizer_join_chain_4                                1.00    137.5±0.27µs        ? ?/sec    1.00    137.2±0.27µs        ? ?/sec
optimizer_join_chain_8                                1.00    369.2±0.60µs        ? ?/sec    1.00    370.4±1.14µs        ? ?/sec
optimizer_select_all_from_1000                        1.00      2.4±0.01ms        ? ?/sec    1.00      2.4±0.01ms        ? ?/sec
optimizer_select_one_from_700                         1.00    239.6±1.35µs        ? ?/sec    1.00    239.0±1.20µs        ? ?/sec
optimizer_tpcds_all                                   1.00    229.9±0.37ms        ? ?/sec    1.01    231.4±0.22ms        ? ?/sec
optimizer_tpch_all                                    1.00     14.1±0.05ms        ? ?/sec    1.00     14.1±0.03ms        ? ?/sec
optimizer_wide_aggregate_100                          1.00   1759.3±3.84µs        ? ?/sec    1.00   1767.6±6.06µs        ? ?/sec
optimizer_wide_filter_200                             1.00      3.1±0.01ms        ? ?/sec    1.01      3.1±0.01ms        ? ?/sec
optimizer_wide_projection_stack_all                   1.00      5.8±0.02ms        ? ?/sec    1.00      5.8±0.01ms        ? ?/sec
optimizer_wide_projection_stack_half                  1.00      4.0±0.01ms        ? ?/sec    1.00      4.0±0.01ms        ? ?/sec
physical_cte_materialized_chain_6                     1.00      2.4±0.01ms        ? ?/sec    1.01      2.4±0.00ms        ? ?/sec
physical_cte_materialized_one_ref                     1.00    716.9±1.70µs        ? ?/sec    1.02    728.0±1.38µs        ? ?/sec
physical_cte_materialized_two_refs                    1.00    968.0±2.32µs        ? ?/sec    1.01    973.5±1.59µs        ? ?/sec
physical_cte_mixed                                    1.01      3.1±0.01ms        ? ?/sec    1.00      3.0±0.00ms        ? ?/sec
physical_cte_not_materialized_chain_6                 1.02     17.8±0.08ms        ? ?/sec    1.00     17.5±0.04ms        ? ?/sec
physical_cte_not_materialized_one_ref                 1.00    657.6±3.43µs        ? ?/sec    1.01    665.9±1.17µs        ? ?/sec
physical_cte_not_materialized_two_refs                1.00   1192.4±7.44µs        ? ?/sec    1.01   1200.6±3.65µs        ? ?/sec
physical_cte_unmarked_chain_6                         1.01     17.7±0.15ms        ? ?/sec    1.00     17.5±0.06ms        ? ?/sec
physical_cte_unmarked_one_ref                         1.00    662.4±1.74µs        ? ?/sec    1.00    663.0±1.76µs        ? ?/sec
physical_cte_unmarked_two_refs                        1.00   1191.5±3.12µs        ? ?/sec    1.00   1195.7±3.21µs        ? ?/sec
physical_intersection                                 1.00    521.5±2.33µs        ? ?/sec    1.00    523.6±1.97µs        ? ?/sec
physical_join_consider_sort                           1.00    975.9±5.99µs        ? ?/sec    1.00    978.9±6.56µs        ? ?/sec
physical_join_distinct                                1.00    190.8±1.31µs        ? ?/sec    1.02    193.8±1.32µs        ? ?/sec
physical_many_self_joins                              1.00      5.5±0.02ms        ? ?/sec    1.00      5.5±0.02ms        ? ?/sec
physical_plan_clickbench_all                          1.00    128.0±0.55ms        ? ?/sec    1.00    128.2±0.62ms        ? ?/sec
physical_plan_clickbench_q1                           1.03  1292.7±16.77µs        ? ?/sec    1.00   1261.2±9.91µs        ? ?/sec
physical_plan_clickbench_q10                          1.00   1875.1±6.85µs        ? ?/sec    1.01  1896.6±19.16µs        ? ?/sec
physical_plan_clickbench_q11                          1.01      2.0±0.01ms        ? ?/sec    1.00  1996.4±11.21µs        ? ?/sec
physical_plan_clickbench_q12                          1.00      2.0±0.01ms        ? ?/sec    1.02      2.1±0.01ms        ? ?/sec
physical_plan_clickbench_q13                          1.01   1889.3±7.71µs        ? ?/sec    1.00  1876.0±12.47µs        ? ?/sec
physical_plan_clickbench_q14                          1.00  1976.4±10.36µs        ? ?/sec    1.01  1990.9±12.76µs        ? ?/sec
physical_plan_clickbench_q15                          1.00   1905.4±7.78µs        ? ?/sec    1.01  1931.5±11.22µs        ? ?/sec
physical_plan_clickbench_q16                          1.00   1620.7±7.42µs        ? ?/sec    1.00   1625.2±8.70µs        ? ?/sec
physical_plan_clickbench_q17                          1.00  1667.7±25.02µs        ? ?/sec    1.00   1666.8±9.35µs        ? ?/sec
physical_plan_clickbench_q18                          1.00   1508.8±6.61µs        ? ?/sec    1.00   1507.4±5.87µs        ? ?/sec
physical_plan_clickbench_q19                          1.00   1872.2±9.30µs        ? ?/sec    1.00   1865.2±8.79µs        ? ?/sec
physical_plan_clickbench_q2                           1.00  1628.5±19.21µs        ? ?/sec    1.02   1653.6±8.81µs        ? ?/sec
physical_plan_clickbench_q20                          1.02   1486.2±5.61µs        ? ?/sec    1.00   1452.1±8.42µs        ? ?/sec
physical_plan_clickbench_q21                          1.00   1628.6±8.75µs        ? ?/sec    1.02  1663.6±15.39µs        ? ?/sec
physical_plan_clickbench_q22                          1.00  1963.5±13.54µs        ? ?/sec    1.02      2.0±0.01ms        ? ?/sec
physical_plan_clickbench_q23                          1.00      2.1±0.01ms        ? ?/sec    1.01      2.1±0.01ms        ? ?/sec
physical_plan_clickbench_q24                          1.00      4.7±0.02ms        ? ?/sec    1.02      4.8±0.03ms        ? ?/sec
physical_plan_clickbench_q25                          1.00  1757.6±11.20µs        ? ?/sec    1.03  1809.7±10.20µs        ? ?/sec
physical_plan_clickbench_q26                          1.00   1624.6±9.59µs        ? ?/sec    1.00  1632.4±11.07µs        ? ?/sec
physical_plan_clickbench_q27                          1.00   1767.0±8.30µs        ? ?/sec    1.02  1801.8±11.34µs        ? ?/sec
physical_plan_clickbench_q28                          1.00      2.1±0.01ms        ? ?/sec    1.04      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q29                          1.00      2.2±0.01ms        ? ?/sec    1.01      2.2±0.02ms        ? ?/sec
physical_plan_clickbench_q3                           1.00  1502.0±11.07µs        ? ?/sec    1.03   1551.5±8.48µs        ? ?/sec
physical_plan_clickbench_q30                          1.00     11.5±0.05ms        ? ?/sec    1.00     11.6±0.03ms        ? ?/sec
physical_plan_clickbench_q31                          1.00      2.2±0.02ms        ? ?/sec    1.02      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q32                          1.01      2.2±0.01ms        ? ?/sec    1.00      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q33                          1.01   1848.8±8.04µs        ? ?/sec    1.00  1837.4±11.03µs        ? ?/sec
physical_plan_clickbench_q34                          1.01   1657.4±8.34µs        ? ?/sec    1.00   1643.9±8.44µs        ? ?/sec
physical_plan_clickbench_q35                          1.00   1668.6±7.68µs        ? ?/sec    1.00   1661.3±8.40µs        ? ?/sec
physical_plan_clickbench_q36                          1.00  1912.2±16.56µs        ? ?/sec    1.00  1920.7±18.61µs        ? ?/sec
physical_plan_clickbench_q37                          1.02      2.4±0.02ms        ? ?/sec    1.00      2.4±0.01ms        ? ?/sec
physical_plan_clickbench_q38                          1.00      2.4±0.02ms        ? ?/sec    1.00      2.4±0.01ms        ? ?/sec
physical_plan_clickbench_q39                          1.00      2.4±0.01ms        ? ?/sec    1.00      2.4±0.02ms        ? ?/sec
physical_plan_clickbench_q4                           1.00   1346.6±8.22µs        ? ?/sec    1.01   1361.8±9.18µs        ? ?/sec
physical_plan_clickbench_q40                          1.00      3.1±0.02ms        ? ?/sec    1.00      3.1±0.02ms        ? ?/sec
physical_plan_clickbench_q41                          1.00      2.7±0.01ms        ? ?/sec    1.00      2.7±0.02ms        ? ?/sec
physical_plan_clickbench_q42                          1.00      2.7±0.02ms        ? ?/sec    1.01      2.7±0.02ms        ? ?/sec
physical_plan_clickbench_q43                          1.02      3.0±0.02ms        ? ?/sec    1.00      2.9±0.02ms        ? ?/sec
physical_plan_clickbench_q44                          1.01  1441.6±10.60µs        ? ?/sec    1.00   1433.8±9.87µs        ? ?/sec
physical_plan_clickbench_q45                          1.01   1456.5±8.92µs        ? ?/sec    1.00   1445.9±7.80µs        ? ?/sec
physical_plan_clickbench_q46                          1.01   1694.3±9.57µs        ? ?/sec    1.00  1681.7±10.52µs        ? ?/sec
physical_plan_clickbench_q47                          1.02      2.3±0.02ms        ? ?/sec    1.00      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q48                          1.02      2.5±0.01ms        ? ?/sec    1.00      2.4±0.01ms        ? ?/sec
physical_plan_clickbench_q49                          1.02      2.5±0.02ms        ? ?/sec    1.00      2.5±0.02ms        ? ?/sec
physical_plan_clickbench_q5                           1.00   1440.4±6.67µs        ? ?/sec    1.01   1459.4±7.43µs        ? ?/sec
physical_plan_clickbench_q50                          1.02      2.6±0.03ms        ? ?/sec    1.00      2.6±0.02ms        ? ?/sec
physical_plan_clickbench_q51                          1.04   1879.8±5.06µs        ? ?/sec    1.00   1805.2±9.85µs        ? ?/sec
physical_plan_clickbench_q52                          1.01      2.2±0.01ms        ? ?/sec    1.00      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q53                          1.01   1638.6±9.87µs        ? ?/sec    1.00   1624.3±9.44µs        ? ?/sec
physical_plan_clickbench_q54                          1.00  1639.8±11.79µs        ? ?/sec    1.01   1659.0±8.81µs        ? ?/sec
physical_plan_clickbench_q55                          1.00   1574.2±7.72µs        ? ?/sec    1.02   1607.2±7.67µs        ? ?/sec
physical_plan_clickbench_q56                          1.00   1572.0±8.86µs        ? ?/sec    1.00   1570.2±9.23µs        ? ?/sec
physical_plan_clickbench_q57                          1.00   1717.8±9.53µs        ? ?/sec    1.00   1725.9±9.51µs        ? ?/sec
physical_plan_clickbench_q58                          1.00      2.1±0.01ms        ? ?/sec    1.01      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q59                          1.00   1579.6±8.35µs        ? ?/sec    1.00   1574.0±7.83µs        ? ?/sec
physical_plan_clickbench_q6                           1.00   1469.1±7.46µs        ? ?/sec    1.02  1497.9±11.31µs        ? ?/sec
physical_plan_clickbench_q60                          1.00   1577.2±6.53µs        ? ?/sec    1.00   1571.6±7.57µs        ? ?/sec
physical_plan_clickbench_q7                           1.00   1296.1±7.55µs        ? ?/sec    1.00   1302.5±6.76µs        ? ?/sec
physical_plan_clickbench_q8                           1.00   1803.9±9.20µs        ? ?/sec    1.03  1862.0±10.69µs        ? ?/sec
physical_plan_clickbench_q9                           1.00   1718.8±7.03µs        ? ?/sec    1.01  1730.9±11.65µs        ? ?/sec
physical_plan_struct_join_agg_sort                    1.00   1190.0±2.53µs        ? ?/sec    1.00   1184.4±3.30µs        ? ?/sec
physical_plan_tpcds_all                               1.00    545.7±2.69ms        ? ?/sec    1.00    545.9±0.60ms        ? ?/sec
physical_plan_tpch_all                                1.00     38.8±0.14ms        ? ?/sec    1.01     39.1±0.06ms        ? ?/sec
physical_plan_tpch_q1                                 1.00   1336.2±2.44µs        ? ?/sec    1.03   1373.7±4.92µs        ? ?/sec
physical_plan_tpch_q10                                1.01      2.1±0.01ms        ? ?/sec    1.00      2.1±0.00ms        ? ?/sec
physical_plan_tpch_q11                                1.00      2.1±0.01ms        ? ?/sec    1.01      2.2±0.00ms        ? ?/sec
physical_plan_tpch_q12                                1.00   1208.2±2.70µs        ? ?/sec    1.01   1216.0±3.75µs        ? ?/sec
physical_plan_tpch_q13                                1.00    972.7±5.62µs        ? ?/sec    1.00    972.2±1.61µs        ? ?/sec
physical_plan_tpch_q14                                1.00   1176.4±3.24µs        ? ?/sec    1.01   1188.9±2.60µs        ? ?/sec
physical_plan_tpch_q16                                1.01   1564.3±4.89µs        ? ?/sec    1.00   1550.4±2.12µs        ? ?/sec
physical_plan_tpch_q17                                1.00   1503.7±6.86µs        ? ?/sec    1.03   1544.8±3.26µs        ? ?/sec
physical_plan_tpch_q18                                1.01   1763.5±9.35µs        ? ?/sec    1.00  1745.0±14.69µs        ? ?/sec
physical_plan_tpch_q19                                1.00  1943.1±15.54µs        ? ?/sec    1.01   1958.7±3.60µs        ? ?/sec
physical_plan_tpch_q2                                 1.00      3.2±0.00ms        ? ?/sec    1.01      3.2±0.00ms        ? ?/sec
physical_plan_tpch_q20                                1.01   1979.5±9.18µs        ? ?/sec    1.00   1969.0±3.01µs        ? ?/sec
physical_plan_tpch_q21                                1.01      2.4±0.00ms        ? ?/sec    1.00      2.4±0.00ms        ? ?/sec
physical_plan_tpch_q22                                1.01   1466.1±3.03µs        ? ?/sec    1.00   1458.6±2.37µs        ? ?/sec
physical_plan_tpch_q3                                 1.00   1558.0±2.79µs        ? ?/sec    1.00   1564.0±2.04µs        ? ?/sec
physical_plan_tpch_q4                                 1.00   1051.4±2.22µs        ? ?/sec    1.03   1078.6±2.74µs        ? ?/sec
physical_plan_tpch_q5                                 1.00      2.0±0.03ms        ? ?/sec    1.00      2.0±0.00ms        ? ?/sec
physical_plan_tpch_q6                                 1.00    585.9±1.51µs        ? ?/sec    1.01    591.4±1.48µs        ? ?/sec
physical_plan_tpch_q7                                 1.00      2.4±0.01ms        ? ?/sec    1.00      2.4±0.00ms        ? ?/sec
physical_plan_tpch_q8                                 1.00      3.1±0.02ms        ? ?/sec    1.00      3.1±0.00ms        ? ?/sec
physical_plan_tpch_q9                                 1.01      2.4±0.01ms        ? ?/sec    1.00      2.4±0.00ms        ? ?/sec
physical_select_aggregates_from_200                   1.00      5.9±0.01ms        ? ?/sec    1.00      5.9±0.03ms        ? ?/sec
physical_select_all_from_1000                         1.00      5.7±0.01ms        ? ?/sec    1.00      5.7±0.01ms        ? ?/sec
physical_select_one_from_700                          1.00    643.7±2.73µs        ? ?/sec    1.01    647.8±2.70µs        ? ?/sec
physical_sorted_union_order_by_10_int64               1.00      3.4±0.00ms        ? ?/sec    1.00      3.4±0.01ms        ? ?/sec
physical_sorted_union_order_by_10_uint64              1.00      7.2±0.01ms        ? ?/sec    1.00      7.2±0.01ms        ? ?/sec
physical_sorted_union_order_by_50_int64               1.00     66.2±0.21ms        ? ?/sec    1.00     66.1±0.27ms        ? ?/sec
physical_sorted_union_order_by_50_uint64              1.00    302.9±1.80ms        ? ?/sec    1.00    302.3±1.05ms        ? ?/sec
physical_theta_join_consider_sort                     1.00   1000.7±5.49µs        ? ?/sec    1.00   1003.3±6.28µs        ? ?/sec
physical_unnest_to_join                               1.00    565.1±2.47µs        ? ?/sec    1.00    562.8±2.55µs        ? ?/sec
physical_window_function_partition_by_12_on_values    1.00    614.6±1.60µs        ? ?/sec    1.02    624.6±1.46µs        ? ?/sec
physical_window_function_partition_by_30_on_values    1.00   1161.5±2.65µs        ? ?/sec    1.00   1165.6±2.52µs        ? ?/sec
physical_window_function_partition_by_4_on_values     1.00    386.9±1.34µs        ? ?/sec    1.04    401.1±4.23µs        ? ?/sec
physical_window_function_partition_by_7_on_values     1.00    467.8±1.74µs        ? ?/sec    1.02    479.0±1.30µs        ? ?/sec
physical_window_function_partition_by_8_on_values     1.00    500.7±1.33µs        ? ?/sec    1.01    507.7±1.37µs        ? ?/sec
with_param_values_many_columns                        1.00    239.1±1.23µs        ? ?/sec    1.01    241.4±1.26µs        ? ?/sec

Resource Usage

sql_planner — base (merge-base)

Metric Value
Wall time 2130.5s
Peak memory 149.1 MiB
Avg memory 104.8 MiB
CPU user 2143.8s
CPU sys 1.8s
Peak spill 0 B

sql_planner — branch

Metric Value
Wall time 2175.5s
Peak memory 149.3 MiB
Avg memory 102.3 MiB
CPU user 2149.3s
CPU sys 1.6s
Peak spill 0 B

File an issue against this benchmark runner

@jayzhan211

Copy link
Copy Markdown
Contributor Author

run benchmark sql_planner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6703930530-4588-9s72j 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/per-partition-constant-ordering (c777864) to 4bf32cb (merge-base) diff

Run configuration
run benchmark sql_planner

Results will be posted here when complete


File an issue against this benchmark runner

@kumarUjjawal kumarUjjawal 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.

Thank you @jayzhan211 for taking care of this

Left few comments please take a look

Comment on lines +64 to +66
if normal
.iter()
.any(|ordering| walk.is_fixed(&ordering[0].expr))

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.

Cache initial head offsets instead of rescanning each walk

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same answer as on the comment about the scan in SortKeyWalk::new, a few lines up: the planning benchmarks are flat, so I'd rather not add a cache.

let implied: Vec<_> = normal_orderings
.iter()
.filter_map(|ordering| {
self.implied_ordering(&ordering[0], ordering[1..].iter())

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.

add_orderings looks for an implied ordering only through ordering[0]. Normal orderings keep heterogeneous (per-partition) constants, so when such a constant leads the ordering the equality behind it is never used, and the order-dependence this commit removes is still there.

.iter()
.any(|ordering| walk.is_fixed(&ordering[0].expr))
{
walk.head_idxs = normal

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.

SortKeyWalk::new moves heads past leading fixed expressions but never runs the implied-ordering discovery that pin runs for moved heads. A head exposed this way implies nothing until some key has been pinned.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I closed this in discovery rather than in the walk: add_orderings and discover_new_orderings now look past leading constants. SortKeyWalk::new runs on every ordering check and its result is dropped when the walk ends, so a ProjectionExec above couldn't use it. With the ordering stored, a window on c over a TopK on (k, a, c) with a not selected no longer needs a sort at one partition.

query DPI
SELECT a, c, ROW_NUMBER() OVER (ORDER BY c) AS r
FROM (SELECT a, c FROM ordered_through_cast WHERE a = CAST(c AS DATE) ORDER BY a, c LIMIT 10)
ORDER BY r;

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.

The new test "The same with a per-partition constant leading the sort" (and the merge variant) checks only result rows, not the plan, so it cannot tell whether [c] was derived or whether a sort was just added.

if projection_exec
.input()
.equivalence_properties()
.ordering_satisfy_requirement(requirements.first().clone())?

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.

The new guard compares requirements.first() with parent_required.first(), but these can be different alternatives: remap_requirement_through_projection uses filter_map, which silently drops alternatives it cannot remap.

// may not be able to do: the proof can depend on a column that it drops,
// such as a leading per-partition constant. Keep the sort above the
// projection in that case.
if projection_exec

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.

Altitude: the "input has the ordering but the node cannot prove it" guard is added only for ProjectionExec. HashJoinExec with an embedded projection (handle_hash_join) also drops columns before pushing a remapped requirement to its right child, so it can fail the same #26747 way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This can't happen with the default optimizer rules: the physical planner builds HashJoinExec without a projection, and ProjectionPushdown, which embeds one, runs after EnsureRequirements. I ran the shape, a window on (g, c) over a join whose right side is a TopK on (g, a, c) with a not selected, and it plans at 1 and 4 partitions. A custom rule order that embeds the projection earlier could hit this. If anyone has one, I'm happy to open an issue for it.

// a constant may lead it. Within a partition it has one value, so it
// is fixed and the head is the first expression after it.
let normal = &props.oeq_cache.normal_cls;
if normal

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.

Every SortKeyWalk::new (i.e. every ordering_satisfy / ordering_satisfy_requirement call) now scans all normal orderings and runs is_fixed (hash lookups, equivalence-class lookups, recursion into children) to find head offsets. Those offsets depend only on props.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When the heads are columns, this is two lookups per ordering, and the sql_planner bot run on c777864f7c is flat: physical_plan_tpch_all unchanged, physical_plan_clickbench_all +1%, physical_plan_tpcds_all -3%, worst single query +3%. A cached list of heads would have to be kept correct by every path that changes constants or orderings (add_constants, add_orderings, update_oeq_cache, clear_orderings, clear_per_partition_constants). That's more state for no visible gain, so I'd leave it out unless a benchmark shows a cost.

.filter_map(|ordering| {
self.implied_ordering(&ordering[0], ordering[1..].iter())
.ok()
.flatten()

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.

.ok().flatten() silently discards errors from implied_ordering (e.g. data_type or Interval::make_unbounded failures). The equivalent call in discover_new_orderings propagates them with ?.

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.

I agree it would be good not to drop the errors

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

add_ordering and add_orderings now return Result, so this error reaches the caller. SortPreservingMergeExec::new and RepartitionExec::with_preserve_order can't return one without changing their signatures (57 and 20 call sites), so they panic on it, as SortExec::new already does. In practice it takes an expression that doesn't match the schema. @alamb let me know if you'd rather change those two signatures as well.

.input()
.equivalence_properties()
.ordering_satisfy_requirement(requirements.first().clone())?
&& !projection_exec

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.

The guard recomputes projection_exec.equivalence_properties().ordering_satisfy_requirement(parent_required.first()). The caller pushdown_sorts_helper has already computed this as satisfy_parent (line 264) for the same plan and requirement.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

After the change for your comment on alternatives, this checks the alternative that gets pushed down, which isn't always the first one that satisfy_parent checked. Reusing it would also add a parameter to pushdown_requirement_to_children that only this branch reads. The check only runs when the input already has the ordering, so I'd keep it.

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.

discover_new_orderings now duplicates work: it computes implied_ordering for each leading ordering and passes the results to add_orderings, which immediately recomputes implied_ordering on those results and recurses again, each level re-normalizing and calling update_map.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These aren't the same computation: discover_new_orderings derives from an ordering, and add_orderings then derives from what that ordering implied. The recursion is what finds chains. With d = CAST(a), a = CAST(c) and ordering [d, a, c], [c] is found with it and missed with one level, and implied_orderings_chain covers that. It only runs when something was implied.

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/per-partition-constant-ordering (c777864) to 4bf32cb (merge-base) diff

Run configuration
run benchmark sql_planner
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

group                                                 HEAD                                    fix_per-partition-constant-ordering
-----                                                 ----                                    -----------------------------------
logical_aggregate_with_join                           1.01    319.1±1.96µs        ? ?/sec     1.00    316.5±4.00µs        ? ?/sec
logical_correlated_subquery_exists                    1.01    212.7±1.48µs        ? ?/sec     1.00    210.0±1.57µs        ? ?/sec
logical_correlated_subquery_in                        1.02    215.2±1.08µs        ? ?/sec     1.00    211.0±1.21µs        ? ?/sec
logical_distinct_many_columns                         1.02    258.4±0.82µs        ? ?/sec     1.00    253.4±1.18µs        ? ?/sec
logical_join_4_with_agg_and_filter                    1.06    200.8±1.33µs        ? ?/sec     1.00    190.2±0.77µs        ? ?/sec
logical_join_8_with_agg_sort_limit                    1.03    343.6±1.93µs        ? ?/sec     1.00    332.0±1.80µs        ? ?/sec
logical_join_chain_16                                 1.03    627.7±2.66µs        ? ?/sec     1.00    610.8±2.61µs        ? ?/sec
logical_join_chain_4                                  1.00     73.8±0.34µs        ? ?/sec     1.00     73.9±0.33µs        ? ?/sec
logical_join_chain_8                                  1.02    200.4±0.74µs        ? ?/sec     1.00    196.8±0.84µs        ? ?/sec
logical_multiple_subqueries                           1.01    402.3±2.68µs        ? ?/sec     1.00    398.1±2.11µs        ? ?/sec
logical_nested_cte_4_levels                           1.02    199.4±1.86µs        ? ?/sec     1.00    194.8±1.47µs        ? ?/sec
logical_plan_struct_join_agg_sort                     1.02    129.3±0.84µs        ? ?/sec     1.00    126.6±1.09µs        ? ?/sec
logical_plan_tpcds_all                                1.00     70.5±0.14ms        ? ?/sec     1.02     72.2±0.17ms        ? ?/sec
logical_plan_tpch_all                                 1.02      5.3±0.07ms        ? ?/sec     1.00      5.2±0.02ms        ? ?/sec
logical_scalar_subquery                               1.01    220.6±1.65µs        ? ?/sec     1.00    217.8±1.51µs        ? ?/sec
logical_select_all_from_1000                          1.00      2.4±0.01ms        ? ?/sec     1.00      2.4±0.01ms        ? ?/sec
logical_select_one_from_700                           1.01    232.9±1.79µs        ? ?/sec     1.00    230.6±1.77µs        ? ?/sec
logical_trivial_join_high_numbered_columns            1.01    196.4±1.51µs        ? ?/sec     1.00    193.6±2.35µs        ? ?/sec
logical_trivial_join_low_numbered_columns             1.02    195.8±1.68µs        ? ?/sec     1.00    191.5±1.35µs        ? ?/sec
logical_union_4_branches                              1.02    318.2±1.39µs        ? ?/sec     1.00    312.5±1.43µs        ? ?/sec
logical_union_8_branches                              1.03    646.2±2.35µs        ? ?/sec     1.00    629.6±1.67µs        ? ?/sec
logical_wide_aggregate_1000_exprs                     1.00     20.9±0.06ms        ? ?/sec     1.00     20.8±0.04ms        ? ?/sec
logical_wide_aggregate_100_exprs                      1.00   1458.4±2.77µs        ? ?/sec     1.00   1452.7±2.35µs        ? ?/sec
logical_wide_case_50_exprs                            1.00   1425.5±4.47µs        ? ?/sec     1.00   1422.1±2.49µs        ? ?/sec
logical_wide_filter_200_predicates                    1.00   1079.4±5.81µs        ? ?/sec     1.00   1079.8±6.33µs        ? ?/sec
logical_wide_filter_50_predicates                     1.01    325.3±1.09µs        ? ?/sec     1.00    322.4±2.61µs        ? ?/sec
optimizer_correlated_exists                           1.01    220.4±1.17µs        ? ?/sec     1.00    218.8±1.19µs        ? ?/sec
optimizer_join_4_with_agg_filter                      1.01    384.7±2.04µs        ? ?/sec     1.00    380.0±1.59µs        ? ?/sec
optimizer_join_chain_4                                1.00    136.9±0.43µs        ? ?/sec     1.00    136.2±0.24µs        ? ?/sec
optimizer_join_chain_8                                1.01    369.6±1.14µs        ? ?/sec     1.00    367.2±0.73µs        ? ?/sec
optimizer_select_all_from_1000                        1.01      2.4±0.01ms        ? ?/sec     1.00      2.4±0.01ms        ? ?/sec
optimizer_select_one_from_700                         1.01    238.8±0.58µs        ? ?/sec     1.00    235.4±0.55µs        ? ?/sec
optimizer_tpcds_all                                   1.00    228.4±0.50ms        ? ?/sec     1.00    229.3±0.56ms        ? ?/sec
optimizer_tpch_all                                    1.00     14.0±0.03ms        ? ?/sec     1.00     14.0±0.04ms        ? ?/sec
optimizer_wide_aggregate_100                          1.00   1763.5±2.65µs        ? ?/sec     1.00   1765.2±4.38µs        ? ?/sec
optimizer_wide_filter_200                             1.00      3.1±0.01ms        ? ?/sec     1.00      3.1±0.01ms        ? ?/sec
optimizer_wide_projection_stack_all                   1.01      5.8±0.01ms        ? ?/sec     1.00      5.8±0.02ms        ? ?/sec
optimizer_wide_projection_stack_half                  1.00      4.0±0.00ms        ? ?/sec     1.00      4.0±0.01ms        ? ?/sec
physical_cte_materialized_chain_6                     1.02      2.4±0.02ms        ? ?/sec     1.00      2.4±0.00ms        ? ?/sec
physical_cte_materialized_one_ref                     1.01    739.6±2.51µs        ? ?/sec     1.00    735.6±4.14µs        ? ?/sec
physical_cte_materialized_two_refs                    1.04    993.8±7.12µs        ? ?/sec     1.00    958.1±1.23µs        ? ?/sec
physical_cte_mixed                                    1.00      3.1±0.01ms        ? ?/sec     1.00      3.1±0.01ms        ? ?/sec
physical_cte_not_materialized_chain_6                 1.01     17.5±0.03ms        ? ?/sec     1.00     17.3±0.03ms        ? ?/sec
physical_cte_not_materialized_one_ref                 1.02    681.2±1.24µs        ? ?/sec     1.00    667.0±1.11µs        ? ?/sec
physical_cte_not_materialized_two_refs                1.01   1208.8±2.20µs        ? ?/sec     1.00   1197.3±2.32µs        ? ?/sec
physical_cte_unmarked_chain_6                         1.02     17.5±0.03ms        ? ?/sec     1.00     17.2±0.03ms        ? ?/sec
physical_cte_unmarked_one_ref                         1.02    669.1±1.68µs        ? ?/sec     1.00    654.9±2.58µs        ? ?/sec
physical_cte_unmarked_two_refs                        1.03   1214.7±2.65µs        ? ?/sec     1.00   1179.9±3.22µs        ? ?/sec
physical_intersection                                 1.03    530.3±2.16µs        ? ?/sec     1.00    513.7±2.94µs        ? ?/sec
physical_join_consider_sort                           1.01    992.8±2.37µs        ? ?/sec     1.00    985.0±1.98µs        ? ?/sec
physical_join_distinct                                1.01    191.1±1.44µs        ? ?/sec     1.00    188.5±1.56µs        ? ?/sec
physical_many_self_joins                              1.01      5.5±0.01ms        ? ?/sec     1.00      5.4±0.01ms        ? ?/sec
physical_plan_clickbench_all                          1.00    128.5±0.33ms        ? ?/sec     1.01    129.7±0.81ms        ? ?/sec
physical_plan_clickbench_q1                           1.08  1385.5±76.70µs        ? ?/sec     1.00  1277.4±10.65µs        ? ?/sec
physical_plan_clickbench_q10                          1.10      2.0±0.21ms        ? ?/sec     1.00   1835.6±7.91µs        ? ?/sec
physical_plan_clickbench_q11                          1.12      2.2±0.12ms        ? ?/sec     1.00  1987.8±11.30µs        ? ?/sec
physical_plan_clickbench_q12                          1.09      2.3±0.12ms        ? ?/sec     1.00      2.1±0.01ms        ? ?/sec
physical_plan_clickbench_q13                          1.08      2.0±0.10ms        ? ?/sec     1.00   1876.9±8.17µs        ? ?/sec
physical_plan_clickbench_q14                          1.05      2.1±0.11ms        ? ?/sec     1.00      2.0±0.01ms        ? ?/sec
physical_plan_clickbench_q15                          1.05      2.0±0.07ms        ? ?/sec     1.00   1918.1±8.29µs        ? ?/sec
physical_plan_clickbench_q16                          1.00  1658.3±36.29µs        ? ?/sec     1.00   1661.1±7.97µs        ? ?/sec
physical_plan_clickbench_q17                          1.08  1811.9±95.39µs        ? ?/sec     1.00   1677.0±9.59µs        ? ?/sec
physical_plan_clickbench_q18                          1.08  1638.4±76.21µs        ? ?/sec     1.00   1518.7±7.63µs        ? ?/sec
physical_plan_clickbench_q19                          1.10      2.0±0.11ms        ? ?/sec     1.00   1850.1±9.12µs        ? ?/sec
physical_plan_clickbench_q2                           1.12  1828.8±102.51µs        ? ?/sec    1.00   1636.7±7.90µs        ? ?/sec
physical_plan_clickbench_q20                          1.08  1588.4±67.22µs        ? ?/sec     1.00   1475.0±9.83µs        ? ?/sec
physical_plan_clickbench_q21                          1.12  1821.5±95.77µs        ? ?/sec     1.00   1619.4±7.77µs        ? ?/sec
physical_plan_clickbench_q22                          1.11      2.2±0.11ms        ? ?/sec     1.00   1964.3±8.84µs        ? ?/sec
physical_plan_clickbench_q23                          1.11      2.3±0.10ms        ? ?/sec     1.00      2.1±0.01ms        ? ?/sec
physical_plan_clickbench_q24                          1.10      5.2±0.14ms        ? ?/sec     1.00      4.7±0.02ms        ? ?/sec
physical_plan_clickbench_q25                          1.10  1934.3±110.57µs        ? ?/sec    1.00   1762.8±7.44µs        ? ?/sec
physical_plan_clickbench_q26                          1.11  1795.3±109.29µs        ? ?/sec    1.00   1622.1±7.68µs        ? ?/sec
physical_plan_clickbench_q27                          1.11  1984.0±80.26µs        ? ?/sec     1.00   1788.4±7.73µs        ? ?/sec
physical_plan_clickbench_q28                          1.15      2.4±0.12ms        ? ?/sec     1.00      2.1±0.01ms        ? ?/sec
physical_plan_clickbench_q29                          1.13      2.5±0.11ms        ? ?/sec     1.00      2.2±0.02ms        ? ?/sec
physical_plan_clickbench_q3                           1.10  1643.3±106.64µs        ? ?/sec    1.00   1499.7±7.42µs        ? ?/sec
physical_plan_clickbench_q30                          1.06     12.2±0.13ms        ? ?/sec     1.00     11.6±0.02ms        ? ?/sec
physical_plan_clickbench_q31                          1.09      2.4±0.07ms        ? ?/sec     1.00      2.2±0.02ms        ? ?/sec
physical_plan_clickbench_q32                          1.07      2.3±0.07ms        ? ?/sec     1.00      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q33                          1.03  1874.0±27.14µs        ? ?/sec     1.00   1816.0±7.48µs        ? ?/sec
physical_plan_clickbench_q34                          1.02  1646.2±32.83µs        ? ?/sec     1.00   1613.5±8.02µs        ? ?/sec
physical_plan_clickbench_q35                          1.00  1691.6±26.93µs        ? ?/sec     1.00   1687.9±9.84µs        ? ?/sec
physical_plan_clickbench_q36                          1.01  1933.4±26.56µs        ? ?/sec     1.00   1915.9±9.71µs        ? ?/sec
physical_plan_clickbench_q37                          1.02      2.4±0.05ms        ? ?/sec     1.00      2.3±0.01ms        ? ?/sec
physical_plan_clickbench_q38                          1.00      2.4±0.03ms        ? ?/sec     1.03      2.4±0.01ms        ? ?/sec
physical_plan_clickbench_q39                          1.00      2.4±0.01ms        ? ?/sec     1.01      2.5±0.01ms        ? ?/sec
physical_plan_clickbench_q4                           1.08  1443.3±61.83µs        ? ?/sec     1.00   1335.7±9.33µs        ? ?/sec
physical_plan_clickbench_q40                          1.00      3.1±0.01ms        ? ?/sec     1.00      3.1±0.01ms        ? ?/sec
physical_plan_clickbench_q41                          1.03      2.7±0.01ms        ? ?/sec     1.00      2.7±0.01ms        ? ?/sec
physical_plan_clickbench_q42                          1.01      2.7±0.01ms        ? ?/sec     1.00      2.7±0.01ms        ? ?/sec
physical_plan_clickbench_q43                          1.00      2.9±0.01ms        ? ?/sec     1.00      2.9±0.01ms        ? ?/sec
physical_plan_clickbench_q44                          1.00   1414.9±6.39µs        ? ?/sec     1.01   1434.5±7.02µs        ? ?/sec
physical_plan_clickbench_q45                          1.00   1414.7±4.38µs        ? ?/sec     1.01   1434.1±8.44µs        ? ?/sec
physical_plan_clickbench_q46                          1.01   1676.8±5.22µs        ? ?/sec     1.00  1663.8±11.82µs        ? ?/sec
physical_plan_clickbench_q47                          1.01      2.2±0.01ms        ? ?/sec     1.00      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q48                          1.01      2.4±0.01ms        ? ?/sec     1.00      2.4±0.01ms        ? ?/sec
physical_plan_clickbench_q49                          1.02      2.5±0.01ms        ? ?/sec     1.00      2.4±0.01ms        ? ?/sec
physical_plan_clickbench_q5                           1.08  1569.9±71.86µs        ? ?/sec     1.00   1457.4±7.04µs        ? ?/sec
physical_plan_clickbench_q50                          1.01      2.6±0.01ms        ? ?/sec     1.00      2.6±0.01ms        ? ?/sec
physical_plan_clickbench_q51                          1.01  1801.6±42.00µs        ? ?/sec     1.00   1790.8±7.68µs        ? ?/sec
physical_plan_clickbench_q52                          1.00      2.2±0.01ms        ? ?/sec     1.03      2.2±0.01ms        ? ?/sec
physical_plan_clickbench_q53                          1.01   1628.0±6.24µs        ? ?/sec     1.00   1619.0±7.12µs        ? ?/sec
physical_plan_clickbench_q54                          1.00   1603.7±5.42µs        ? ?/sec     1.00   1604.1±6.84µs        ? ?/sec
physical_plan_clickbench_q55                          1.00   1569.4±5.95µs        ? ?/sec     1.01   1582.1±8.92µs        ? ?/sec
physical_plan_clickbench_q56                          1.00   1568.9±6.34µs        ? ?/sec     1.02   1595.0±9.41µs        ? ?/sec
physical_plan_clickbench_q57                          1.02  1726.8±14.31µs        ? ?/sec     1.00   1689.2±7.86µs        ? ?/sec
physical_plan_clickbench_q58                          1.02      2.1±0.01ms        ? ?/sec     1.00      2.1±0.01ms        ? ?/sec
physical_plan_clickbench_q59                          1.02   1591.4±5.71µs        ? ?/sec     1.00   1562.8±7.32µs        ? ?/sec
physical_plan_clickbench_q6                           1.08  1574.7±86.02µs        ? ?/sec     1.00   1453.4±7.50µs        ? ?/sec
physical_plan_clickbench_q60                          1.00   1564.0±4.70µs        ? ?/sec     1.02   1600.7±9.14µs        ? ?/sec
physical_plan_clickbench_q7                           1.09  1401.6±93.93µs        ? ?/sec     1.00   1291.0±6.77µs        ? ?/sec
physical_plan_clickbench_q8                           1.09      2.0±0.12ms        ? ?/sec     1.00   1847.8±7.59µs        ? ?/sec
physical_plan_clickbench_q9                           1.04  1861.9±75.99µs        ? ?/sec     1.00   1795.5±7.48µs        ? ?/sec
physical_plan_struct_join_agg_sort                    1.01   1199.6±2.73µs        ? ?/sec     1.00   1192.1±2.33µs        ? ?/sec
physical_plan_tpcds_all                               1.03   558.2±14.01ms        ? ?/sec     1.00    542.1±0.43ms        ? ?/sec
physical_plan_tpch_all                                1.00     39.1±0.42ms        ? ?/sec     1.00     39.1±0.05ms        ? ?/sec
physical_plan_tpch_q1                                 1.03   1385.9±6.68µs        ? ?/sec     1.00   1347.2±2.61µs        ? ?/sec
physical_plan_tpch_q10                                1.00      2.1±0.02ms        ? ?/sec     1.01      2.1±0.01ms        ? ?/sec
physical_plan_tpch_q11                                1.01      2.1±0.00ms        ? ?/sec     1.00      2.1±0.00ms        ? ?/sec
physical_plan_tpch_q12                                1.01   1231.3±3.06µs        ? ?/sec     1.00   1219.4±2.57µs        ? ?/sec
physical_plan_tpch_q13                                1.00    976.5±3.83µs        ? ?/sec     1.01    981.7±1.93µs        ? ?/sec
physical_plan_tpch_q14                                1.03   1196.7±3.34µs        ? ?/sec     1.00   1166.9±2.13µs        ? ?/sec
physical_plan_tpch_q16                                1.00   1594.3±3.68µs        ? ?/sec     1.00   1598.0±2.75µs        ? ?/sec
physical_plan_tpch_q17                                1.00  1525.5±34.12µs        ? ?/sec     1.01   1543.5±2.54µs        ? ?/sec
physical_plan_tpch_q18                                1.02   1756.8±4.51µs        ? ?/sec     1.00   1729.8±2.64µs        ? ?/sec
physical_plan_tpch_q19                                1.02   1955.9±3.03µs        ? ?/sec     1.00   1923.3±3.38µs        ? ?/sec
physical_plan_tpch_q2                                 1.02      3.3±0.01ms        ? ?/sec     1.00      3.2±0.00ms        ? ?/sec
physical_plan_tpch_q20                                1.00  1983.6±10.33µs        ? ?/sec     1.00  1980.8±16.82µs        ? ?/sec
physical_plan_tpch_q21                                1.00      2.4±0.02ms        ? ?/sec     1.00      2.4±0.00ms        ? ?/sec
physical_plan_tpch_q22                                1.01   1500.1±2.52µs        ? ?/sec     1.00   1492.1±4.70µs        ? ?/sec
physical_plan_tpch_q3                                 1.00   1578.6±3.81µs        ? ?/sec     1.00   1574.6±2.97µs        ? ?/sec
physical_plan_tpch_q4                                 1.02  1068.8±11.26µs        ? ?/sec     1.00   1049.7±2.45µs        ? ?/sec
physical_plan_tpch_q5                                 1.01      2.1±0.00ms        ? ?/sec     1.00      2.0±0.00ms        ? ?/sec
physical_plan_tpch_q6                                 1.03    608.3±1.25µs        ? ?/sec     1.00    588.1±1.35µs        ? ?/sec
physical_plan_tpch_q7                                 1.00      2.4±0.00ms        ? ?/sec     1.00      2.4±0.00ms        ? ?/sec
physical_plan_tpch_q8                                 1.00      3.1±0.00ms        ? ?/sec     1.00      3.1±0.00ms        ? ?/sec
physical_plan_tpch_q9                                 1.01      2.4±0.00ms        ? ?/sec     1.00      2.4±0.03ms        ? ?/sec
physical_select_aggregates_from_200                   1.00      5.9±0.01ms        ? ?/sec     1.00      5.9±0.01ms        ? ?/sec
physical_select_all_from_1000                         1.00      5.8±0.03ms        ? ?/sec     1.00      5.8±0.02ms        ? ?/sec
physical_select_one_from_700                          1.01    644.9±2.89µs        ? ?/sec     1.00    637.2±4.50µs        ? ?/sec
physical_sorted_union_order_by_10_int64               1.01      3.4±0.00ms        ? ?/sec     1.00      3.4±0.00ms        ? ?/sec
physical_sorted_union_order_by_10_uint64              1.00      7.3±0.01ms        ? ?/sec     1.00      7.2±0.01ms        ? ?/sec
physical_sorted_union_order_by_50_int64               1.01     65.8±0.20ms        ? ?/sec     1.00     65.3±0.16ms        ? ?/sec
physical_sorted_union_order_by_50_uint64              1.00    298.9±1.01ms        ? ?/sec     1.00    298.4±1.10ms        ? ?/sec
physical_theta_join_consider_sort                     1.00   1002.6±2.74µs        ? ?/sec     1.00   1005.1±2.64µs        ? ?/sec
physical_unnest_to_join                               1.02    571.3±2.26µs        ? ?/sec     1.00    559.7±2.29µs        ? ?/sec
physical_window_function_partition_by_12_on_values    1.01    627.3±1.02µs        ? ?/sec     1.00    621.4±2.12µs        ? ?/sec
physical_window_function_partition_by_30_on_values    1.00   1172.6±2.13µs        ? ?/sec     1.00   1168.0±3.14µs        ? ?/sec
physical_window_function_partition_by_4_on_values     1.00    391.9±0.85µs        ? ?/sec     1.01    394.9±0.98µs        ? ?/sec
physical_window_function_partition_by_7_on_values     1.00    477.6±1.40µs        ? ?/sec     1.00    477.1±4.96µs        ? ?/sec
physical_window_function_partition_by_8_on_values     1.00    506.8±1.30µs        ? ?/sec     1.00    508.9±1.62µs        ? ?/sec
with_param_values_many_columns                        1.01    241.8±1.36µs        ? ?/sec     1.00    240.5±1.34µs        ? ?/sec

Resource Usage

sql_planner — base (merge-base)

Metric Value
Wall time 1890.4s
Peak memory 149.2 MiB
Avg memory 116.1 MiB
CPU user 2118.7s
CPU sys 1.6s
Peak spill 0 B

sql_planner — branch

Metric Value
Wall time 2105.5s
Peak memory 147.8 MiB
Avg memory 104.0 MiB
CPU user 2129.3s
CPU sys 1.6s
Peak spill 0 B

File an issue against this benchmark runner

@github-actions github-actions Bot added documentation Improvements or additions to documentation core Core DataFusion crate functions Changes to functions implementation datasource Changes to the datasource crate physical-plan Changes to the physical-plan crate labels Nov 7, 2026
@jayzhan211 jayzhan211 removed the physical-plan Changes to the physical-plan crate label Nov 9, 2026
@jayzhan211

Copy link
Copy Markdown
Contributor Author

run benchmark sql_planner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6741909956-4671-nvgq7 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/per-partition-constant-ordering (434a127) to 4bf32cb (merge-base) diff

Run configuration
run benchmark sql_planner

Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/per-partition-constant-ordering (434a127) to 4bf32cb (merge-base) diff

Run configuration
run benchmark sql_planner
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

group                                                 HEAD                                   fix_per-partition-constant-ordering
-----                                                 ----                                   -----------------------------------
logical_aggregate_with_join                           1.00    316.2±2.23µs        ? ?/sec    1.00    317.7±1.76µs        ? ?/sec
logical_correlated_subquery_exists                    1.00    209.3±1.45µs        ? ?/sec    1.02    212.7±1.96µs        ? ?/sec
logical_correlated_subquery_in                        1.00    211.9±1.29µs        ? ?/sec    1.02    216.0±0.68µs        ? ?/sec
logical_distinct_many_columns                         1.00    255.1±1.08µs        ? ?/sec    1.01    258.0±0.99µs        ? ?/sec
logical_join_4_with_agg_and_filter                    1.00    190.1±1.07µs        ? ?/sec    1.06    201.3±1.20µs        ? ?/sec
logical_join_8_with_agg_sort_limit                    1.00    336.3±2.74µs        ? ?/sec    1.03    346.1±2.39µs        ? ?/sec
logical_join_chain_16                                 1.00    623.9±3.04µs        ? ?/sec    1.00    622.1±2.86µs        ? ?/sec
logical_join_chain_4                                  1.00     74.4±0.34µs        ? ?/sec    1.01     75.0±0.46µs        ? ?/sec
logical_join_chain_8                                  1.00    201.0±1.14µs        ? ?/sec    1.00    200.2±0.67µs        ? ?/sec
logical_multiple_subqueries                           1.00    395.3±2.14µs        ? ?/sec    1.03    408.3±2.49µs        ? ?/sec
logical_nested_cte_4_levels                           1.00    192.6±1.14µs        ? ?/sec    1.04    200.1±0.52µs        ? ?/sec
logical_plan_struct_join_agg_sort                     1.00    120.7±1.67µs        ? ?/sec    1.04    125.1±0.34µs        ? ?/sec
logical_plan_tpcds_all                                1.00     70.2±0.46ms        ? ?/sec    1.05     74.1±0.94ms        ? ?/sec
logical_plan_tpch_all                                 1.00      5.0±0.02ms        ? ?/sec    1.06      5.3±0.04ms        ? ?/sec
logical_scalar_subquery                               1.00    223.0±2.24µs        ? ?/sec    1.00    223.8±1.74µs        ? ?/sec
logical_select_all_from_1000                          1.00      2.3±0.01ms        ? ?/sec    1.00      2.3±0.01ms        ? ?/sec
logical_select_one_from_700                           1.01    235.0±2.03µs        ? ?/sec    1.00    232.9±2.22µs        ? ?/sec
logical_trivial_join_high_numbered_columns            1.00    195.2±1.47µs        ? ?/sec    1.01    196.9±1.38µs        ? ?/sec
logical_trivial_join_low_numbered_columns             1.00    194.2±1.58µs        ? ?/sec    1.01    196.2±1.41µs        ? ?/sec
logical_union_4_branches                              1.00    315.2±1.57µs        ? ?/sec    1.02    320.6±2.85µs        ? ?/sec
logical_union_8_branches                              1.00    638.5±6.81µs        ? ?/sec    1.02    651.7±6.29µs        ? ?/sec
logical_wide_aggregate_1000_exprs                     1.00     21.3±0.10ms        ? ?/sec    1.02     21.7±0.16ms        ? ?/sec
logical_wide_aggregate_100_exprs                      1.00   1468.6±3.73µs        ? ?/sec    1.00   1469.2±7.69µs        ? ?/sec
logical_wide_case_50_exprs                            1.00   1425.9±4.25µs        ? ?/sec    1.01  1435.3±12.16µs        ? ?/sec
logical_wide_filter_200_predicates                    1.00   1072.0±6.18µs        ? ?/sec    1.01   1078.5±6.69µs        ? ?/sec
logical_wide_filter_50_predicates                     1.00    317.4±0.99µs        ? ?/sec    1.03    326.5±1.13µs        ? ?/sec
optimizer_correlated_exists                           1.00    220.4±0.84µs        ? ?/sec    1.01    222.2±1.08µs        ? ?/sec
optimizer_join_4_with_agg_filter                      1.00    380.3±1.35µs        ? ?/sec    1.01    385.4±1.41µs        ? ?/sec
optimizer_join_chain_4                                1.00    136.9±0.67µs        ? ?/sec    1.00    136.4±0.52µs        ? ?/sec
optimizer_join_chain_8                                1.00    365.6±1.32µs        ? ?/sec    1.01    369.2±1.62µs        ? ?/sec
optimizer_select_all_from_1000                        1.00      2.4±0.01ms        ? ?/sec    1.01      2.4±0.01ms        ? ?/sec
optimizer_select_one_from_700                         1.00    236.4±0.60µs        ? ?/sec    1.01    238.5±0.83µs        ? ?/sec
optimizer_tpcds_all                                   1.00    232.5±2.55ms        ? ?/sec    1.04    240.7±2.35ms        ? ?/sec
optimizer_tpch_all                                    1.00     14.3±0.12ms        ? ?/sec    1.02     14.6±0.11ms        ? ?/sec
optimizer_wide_aggregate_100                          1.00   1762.3±2.54µs        ? ?/sec    1.00   1770.8±5.99µs        ? ?/sec
optimizer_wide_filter_200                             1.00      3.1±0.01ms        ? ?/sec    1.02      3.2±0.03ms        ? ?/sec
optimizer_wide_projection_stack_all                   1.00      5.8±0.02ms        ? ?/sec    1.03      6.0±0.03ms        ? ?/sec
optimizer_wide_projection_stack_half                  1.00      4.0±0.02ms        ? ?/sec    1.04      4.2±0.04ms        ? ?/sec
physical_cte_materialized_chain_6                     1.00      2.4±0.01ms        ? ?/sec    1.14      2.7±0.07ms        ? ?/sec
physical_cte_materialized_one_ref                     1.00    714.6±1.84µs        ? ?/sec    1.05    748.8±7.08µs        ? ?/sec
physical_cte_materialized_two_refs                    1.00    966.5±2.49µs        ? ?/sec    1.06  1027.1±36.63µs        ? ?/sec
physical_cte_mixed                                    1.00      3.1±0.03ms        ? ?/sec    1.14      3.5±0.07ms        ? ?/sec
physical_cte_not_materialized_chain_6                 1.00     18.0±0.05ms        ? ?/sec    1.04     18.7±0.14ms        ? ?/sec
physical_cte_not_materialized_one_ref                 1.00    660.6±2.69µs        ? ?/sec    1.04    685.1±5.91µs        ? ?/sec
physical_cte_not_materialized_two_refs                1.00   1197.6±5.84µs        ? ?/sec    1.06  1275.4±41.85µs        ? ?/sec
physical_cte_unmarked_chain_6                         1.00     18.0±0.05ms        ? ?/sec    1.02     18.4±0.14ms        ? ?/sec
physical_cte_unmarked_one_ref                         1.00    654.6±1.27µs        ? ?/sec    1.04    680.6±5.57µs        ? ?/sec
physical_cte_unmarked_two_refs                        1.00   1180.9±3.48µs        ? ?/sec    1.09  1290.4±28.61µs        ? ?/sec
physical_intersection                                 1.00    517.7±2.59µs        ? ?/sec    1.01    521.0±1.95µs        ? ?/sec
physical_join_consider_sort                           1.00    971.7±2.46µs        ? ?/sec    1.00    976.3±2.47µs        ? ?/sec
physical_join_distinct                                1.01    193.7±2.05µs        ? ?/sec    1.00    191.6±1.36µs        ? ?/sec
physical_many_self_joins                              1.00      5.5±0.05ms        ? ?/sec    1.00      5.5±0.05ms        ? ?/sec
physical_plan_clickbench_all                          1.00    137.0±1.50ms        ? ?/sec    1.02    139.6±3.22ms        ? ?/sec
physical_plan_clickbench_q1                           1.02  1318.2±15.12µs        ? ?/sec    1.00  1296.0±15.98µs        ? ?/sec
physical_plan_clickbench_q10                          1.00  1938.8±35.68µs        ? ?/sec    1.00  1941.5±38.14µs        ? ?/sec
physical_plan_clickbench_q11                          1.01      2.1±0.06ms        ? ?/sec    1.00      2.1±0.06ms        ? ?/sec
physical_plan_clickbench_q12                          1.00      2.1±0.03ms        ? ?/sec    1.01      2.2±0.06ms        ? ?/sec
physical_plan_clickbench_q13                          1.02  1992.9±37.57µs        ? ?/sec    1.00  1962.5±50.20µs        ? ?/sec
physical_plan_clickbench_q14                          1.03      2.1±0.05ms        ? ?/sec    1.00      2.1±0.04ms        ? ?/sec
physical_plan_clickbench_q15                          1.04      2.1±0.08ms        ? ?/sec    1.00      2.0±0.06ms        ? ?/sec
physical_plan_clickbench_q16                          1.00  1701.4±42.71µs        ? ?/sec    1.02  1743.1±35.40µs        ? ?/sec
physical_plan_clickbench_q17                          1.03  1759.1±29.98µs        ? ?/sec    1.00  1708.2±27.28µs        ? ?/sec
physical_plan_clickbench_q18                          1.02  1600.9±29.24µs        ? ?/sec    1.00  1563.0±25.09µs        ? ?/sec
physical_plan_clickbench_q19                          1.01  1968.0±31.71µs        ? ?/sec    1.00  1954.9±31.80µs        ? ?/sec
physical_plan_clickbench_q2                           1.02  1777.8±37.36µs        ? ?/sec    1.00  1748.4±27.43µs        ? ?/sec
physical_plan_clickbench_q20                          1.01  1556.4±24.87µs        ? ?/sec    1.00  1542.8±29.24µs        ? ?/sec
physical_plan_clickbench_q21                          1.01  1768.1±37.93µs        ? ?/sec    1.00  1750.2±40.49µs        ? ?/sec
physical_plan_clickbench_q22                          1.00      2.1±0.05ms        ? ?/sec    1.03      2.2±0.05ms        ? ?/sec
physical_plan_clickbench_q23                          1.00      2.3±0.07ms        ? ?/sec    1.03      2.3±0.07ms        ? ?/sec
physical_plan_clickbench_q24                          1.00      5.0±0.12ms        ? ?/sec    1.03      5.2±0.09ms        ? ?/sec
physical_plan_clickbench_q25                          1.02  1898.0±29.79µs        ? ?/sec    1.00  1857.1±50.22µs        ? ?/sec
physical_plan_clickbench_q26                          1.00  1722.2±34.56µs        ? ?/sec    1.02  1759.5±26.86µs        ? ?/sec
physical_plan_clickbench_q27                          1.02  1923.2±32.55µs        ? ?/sec    1.00  1892.8±61.12µs        ? ?/sec
physical_plan_clickbench_q28                          1.00      2.3±0.07ms        ? ?/sec    1.00      2.3±0.07ms        ? ?/sec
physical_plan_clickbench_q29                          1.00      2.3±0.05ms        ? ?/sec    1.04      2.4±0.07ms        ? ?/sec
physical_plan_clickbench_q3                           1.02  1601.0±27.23µs        ? ?/sec    1.00  1574.6±27.65µs        ? ?/sec
physical_plan_clickbench_q30                          1.01     12.0±0.15ms        ? ?/sec    1.00     11.9±0.15ms        ? ?/sec
physical_plan_clickbench_q31                          1.00      2.4±0.07ms        ? ?/sec    1.02      2.4±0.06ms        ? ?/sec
physical_plan_clickbench_q32                          1.00      2.3±0.08ms        ? ?/sec    1.03      2.4±0.07ms        ? ?/sec
physical_plan_clickbench_q33                          1.04  1906.8±31.41µs        ? ?/sec    1.00   1827.6±8.42µs        ? ?/sec
physical_plan_clickbench_q34                          1.03  1736.6±42.06µs        ? ?/sec    1.00  1679.0±25.77µs        ? ?/sec
physical_plan_clickbench_q35                          1.02  1745.6±31.34µs        ? ?/sec    1.00  1708.6±25.77µs        ? ?/sec
physical_plan_clickbench_q36                          1.02  1998.7±45.96µs        ? ?/sec    1.00  1968.1±92.29µs        ? ?/sec
physical_plan_clickbench_q37                          1.01      2.6±0.05ms        ? ?/sec    1.00      2.6±0.10ms        ? ?/sec
physical_plan_clickbench_q38                          1.00      2.6±0.08ms        ? ?/sec    1.02      2.6±0.08ms        ? ?/sec
physical_plan_clickbench_q39                          1.01      2.6±0.05ms        ? ?/sec    1.00      2.6±0.06ms        ? ?/sec
physical_plan_clickbench_q4                           1.02  1451.5±23.28µs        ? ?/sec    1.00  1423.8±22.01µs        ? ?/sec
physical_plan_clickbench_q40                          1.02      3.4±0.08ms        ? ?/sec    1.00      3.3±0.11ms        ? ?/sec
physical_plan_clickbench_q41                          1.00      2.9±0.09ms        ? ?/sec    1.04      3.0±0.14ms        ? ?/sec
physical_plan_clickbench_q42                          1.00      2.9±0.10ms        ? ?/sec    1.02      3.0±0.06ms        ? ?/sec
physical_plan_clickbench_q43                          1.00      3.2±0.08ms        ? ?/sec    1.00      3.2±0.09ms        ? ?/sec
physical_plan_clickbench_q44                          1.00  1496.3±26.89µs        ? ?/sec    1.00  1498.8±23.27µs        ? ?/sec
physical_plan_clickbench_q45                          1.00  1486.9±16.81µs        ? ?/sec    1.02  1513.5±17.96µs        ? ?/sec
physical_plan_clickbench_q46                          1.00  1739.2±26.09µs        ? ?/sec    1.03  1791.2±23.73µs        ? ?/sec
physical_plan_clickbench_q47                          1.00      2.4±0.05ms        ? ?/sec    1.01      2.4±0.05ms        ? ?/sec
physical_plan_clickbench_q48                          1.00      2.5±0.07ms        ? ?/sec    1.06      2.7±0.07ms        ? ?/sec
physical_plan_clickbench_q49                          1.00      2.6±0.07ms        ? ?/sec    1.04      2.7±0.05ms        ? ?/sec
physical_plan_clickbench_q5                           1.00  1513.1±23.51µs        ? ?/sec    1.01  1529.3±15.54µs        ? ?/sec
physical_plan_clickbench_q50                          1.00      2.7±0.07ms        ? ?/sec    1.04      2.8±0.07ms        ? ?/sec
physical_plan_clickbench_q51                          1.01  1895.0±34.72µs        ? ?/sec    1.00  1885.2±37.52µs        ? ?/sec
physical_plan_clickbench_q52                          1.00      2.3±0.05ms        ? ?/sec    1.01      2.3±0.06ms        ? ?/sec
physical_plan_clickbench_q53                          1.00  1693.4±24.68µs        ? ?/sec    1.02  1731.0±26.92µs        ? ?/sec
physical_plan_clickbench_q54                          1.01  1730.4±23.98µs        ? ?/sec    1.00  1716.4±52.67µs        ? ?/sec
physical_plan_clickbench_q55                          1.00  1624.7±28.07µs        ? ?/sec    1.03  1670.5±62.13µs        ? ?/sec
physical_plan_clickbench_q56                          1.00  1647.7±17.07µs        ? ?/sec    1.01  1661.3±30.18µs        ? ?/sec
physical_plan_clickbench_q57                          1.00  1841.7±36.32µs        ? ?/sec    1.04  1914.8±52.59µs        ? ?/sec
physical_plan_clickbench_q58                          1.00      2.2±0.06ms        ? ?/sec    1.02      2.3±0.06ms        ? ?/sec
physical_plan_clickbench_q59                          1.00  1638.0±32.11µs        ? ?/sec    1.02  1663.1±42.36µs        ? ?/sec
physical_plan_clickbench_q6                           1.00  1531.8±21.72µs        ? ?/sec    1.00  1531.9±21.21µs        ? ?/sec
physical_plan_clickbench_q60                          1.00  1648.2±16.58µs        ? ?/sec    1.02  1686.6±31.97µs        ? ?/sec
physical_plan_clickbench_q7                           1.00  1357.5±22.75µs        ? ?/sec    1.01  1367.0±21.79µs        ? ?/sec
physical_plan_clickbench_q8                           1.00  1918.8±44.94µs        ? ?/sec    1.01  1940.2±41.96µs        ? ?/sec
physical_plan_clickbench_q9                           1.00  1798.1±34.93µs        ? ?/sec    1.01  1816.3±40.79µs        ? ?/sec
physical_plan_struct_join_agg_sort                    1.00   1189.4±4.17µs        ? ?/sec    1.02   1218.6±6.77µs        ? ?/sec
physical_plan_tpcds_all                               1.00    558.4±6.93ms        ? ?/sec    1.00    560.1±7.57ms        ? ?/sec
physical_plan_tpch_all                                1.00     39.3±0.41ms        ? ?/sec    1.01     39.5±0.41ms        ? ?/sec
physical_plan_tpch_q1                                 1.00   1347.7±5.53µs        ? ?/sec    1.01  1365.7±11.02µs        ? ?/sec
physical_plan_tpch_q10                                1.00      2.1±0.03ms        ? ?/sec    1.02      2.1±0.02ms        ? ?/sec
physical_plan_tpch_q11                                1.00      2.1±0.02ms        ? ?/sec    1.02      2.1±0.02ms        ? ?/sec
physical_plan_tpch_q12                                1.00   1203.7±7.93µs        ? ?/sec    1.02   1229.4±7.72µs        ? ?/sec
physical_plan_tpch_q13                                1.00    960.3±2.30µs        ? ?/sec    1.02    976.3±4.49µs        ? ?/sec
physical_plan_tpch_q14                                1.00   1170.1±5.47µs        ? ?/sec    1.03   1200.0±5.69µs        ? ?/sec
physical_plan_tpch_q16                                1.00  1586.9±40.44µs        ? ?/sec    1.00   1580.6±8.07µs        ? ?/sec
physical_plan_tpch_q17                                1.02  1553.7±24.08µs        ? ?/sec    1.00   1516.8±8.23µs        ? ?/sec
physical_plan_tpch_q18                                1.02  1771.3±25.38µs        ? ?/sec    1.00  1744.3±17.50µs        ? ?/sec
physical_plan_tpch_q19                                1.01  1963.3±20.87µs        ? ?/sec    1.00   1936.0±7.78µs        ? ?/sec
physical_plan_tpch_q2                                 1.00      3.2±0.04ms        ? ?/sec    1.02      3.3±0.08ms        ? ?/sec
physical_plan_tpch_q20                                1.00  1972.4±17.10µs        ? ?/sec    1.00  1972.0±10.25µs        ? ?/sec
physical_plan_tpch_q21                                1.01      2.4±0.03ms        ? ?/sec    1.00      2.4±0.02ms        ? ?/sec
physical_plan_tpch_q22                                1.00  1486.7±16.56µs        ? ?/sec    1.00   1479.3±7.19µs        ? ?/sec
physical_plan_tpch_q3                                 1.00   1559.0±8.34µs        ? ?/sec    1.03   1601.8±7.77µs        ? ?/sec
physical_plan_tpch_q4                                 1.00   1041.8±4.77µs        ? ?/sec    1.02   1064.6±4.60µs        ? ?/sec
physical_plan_tpch_q5                                 1.00      2.0±0.01ms        ? ?/sec    1.03      2.1±0.02ms        ? ?/sec
physical_plan_tpch_q6                                 1.00    586.2±1.42µs        ? ?/sec    1.04    608.7±1.79µs        ? ?/sec
physical_plan_tpch_q7                                 1.00      2.4±0.02ms        ? ?/sec    1.03      2.5±0.04ms        ? ?/sec
physical_plan_tpch_q8                                 1.00      3.1±0.05ms        ? ?/sec    1.01      3.2±0.06ms        ? ?/sec
physical_plan_tpch_q9                                 1.00      2.3±0.02ms        ? ?/sec    1.01      2.4±0.02ms        ? ?/sec
physical_select_aggregates_from_200                   1.00      6.0±0.07ms        ? ?/sec    1.00      5.9±0.07ms        ? ?/sec
physical_select_all_from_1000                         1.01      5.8±0.05ms        ? ?/sec    1.00      5.8±0.06ms        ? ?/sec
physical_select_one_from_700                          1.00    638.4±3.67µs        ? ?/sec    1.00    636.2±2.60µs        ? ?/sec
physical_sorted_union_order_by_10_int64               1.00      3.5±0.03ms        ? ?/sec    1.02      3.5±0.05ms        ? ?/sec
physical_sorted_union_order_by_10_uint64              1.00      7.3±0.06ms        ? ?/sec    1.03      7.5±0.11ms        ? ?/sec
physical_sorted_union_order_by_50_int64               1.00     67.3±0.52ms        ? ?/sec    1.02     68.6±0.56ms        ? ?/sec
physical_sorted_union_order_by_50_uint64              1.00    309.7±2.62ms        ? ?/sec    1.01    311.5±3.06ms        ? ?/sec
physical_theta_join_consider_sort                     1.00   1000.3±2.13µs        ? ?/sec    1.00  1004.1±10.62µs        ? ?/sec
physical_unnest_to_join                               1.00    554.9±2.88µs        ? ?/sec    1.01    558.7±2.27µs        ? ?/sec
physical_window_function_partition_by_12_on_values    1.00    609.0±1.56µs        ? ?/sec    1.02    622.5±1.42µs        ? ?/sec
physical_window_function_partition_by_30_on_values    1.00   1159.6±2.43µs        ? ?/sec    1.01   1167.8±3.09µs        ? ?/sec
physical_window_function_partition_by_4_on_values     1.00    392.5±1.38µs        ? ?/sec    1.00    393.2±1.84µs        ? ?/sec
physical_window_function_partition_by_7_on_values     1.00    475.5±1.01µs        ? ?/sec    1.01    480.0±1.66µs        ? ?/sec
physical_window_function_partition_by_8_on_values     1.00    499.2±1.57µs        ? ?/sec    1.02    507.9±1.77µs        ? ?/sec
with_param_values_many_columns                        1.00    240.9±1.47µs        ? ?/sec    1.00    239.9±1.66µs        ? ?/sec

Resource Usage

sql_planner — base (merge-base)

Metric Value
Wall time 1930.4s
Peak memory 147.9 MiB
Avg memory 114.1 MiB
CPU user 2146.5s
CPU sys 1.6s
Peak spill 0 B

sql_planner — branch

Metric Value
Wall time 2135.5s
Peak memory 144.2 MiB
Avg memory 101.1 MiB
CPU user 2142.3s
CPU sys 1.8s
Peak spill 0 B

File an issue against this benchmark runner

@alamb alamb 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.

I think this one is ok, thank you for working on it @jayzhan211

I am still not very happy with the current state of the EquivalenceProperties and SortWalkKey (I realize you did not cause this). Specifically the fact that there are now explicit "implied" orderings in addition to equivalence properties seems like they partially duplicate significant functionality.

This PR seems to be adding more (complicated) code to add implied ordering in another path, rather than unifying the behavior. I realize unifying the logic is too much for a bug fix. It would be really nice to try and unify all this spaghetti as a follow on, otherwise we are going to be chasing bugs down in this code indefinitely

I also spent a while writing up what I think SortKeyWalk actually does

/// For each ordering (the normal orderings of `props`, then `implied`),
/// the index of its head. Empty until the first pin, so that a walk with
/// nothing pinned allocates nothing; until then every head is at index 0.
/// the index of its head. Empty until a head moves, so that a walk that

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.

I found all this talk about head super confusing so I tried to document it better

if class.is_some_and(|class| class.constant.is_some()) {
return true;
}
// A column is only fixed if it is pinned or constant:

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.

isn't it more like a varying column can't be fixed (by definition?)

/// input is sorted by `c`, and the projection proves `score` (`c` renamed),
/// but not `score % 2`, so the requirement can be pushed down.
#[test]
fn projection_guard_compares_the_pushed_alternative() -> Result<()> {

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.

what is this tet comparing? I am pretty confused

Ok(())
}

/// Returns the orderings that the normal ordering `ordering` implies. If a

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.

It would help me here to write out the examples more clearly: add whitespace between input and outputs, and explain them in more detail -- for example how I have done on #27266

let mut implied = vec![];
for (idx, key) in keys.iter().enumerate() {
if let Some(rest) =
self.implied_ordering(key, keys[idx + 1..].iter().copied())?

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.

I also vote to return ok() and leave a comment explaining why the error is ignored

This will make it less disruptive to backport

Then we can make a PR to main perhaps to propagate the error

/// constants that a normal ordering can keep (those that differ between
/// partitions) are left out, because within a partition they have one
/// value.
fn implied_by(&self, ordering: &LexOrdering) -> Result<Vec<Vec<PhysicalSortExpr>>> {

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.

I wonder why this doesn't return Result<Vec<LexicalOrdering>> which I think is what the PhysicaSortExpr represent

@alamb alamb mentioned this pull request Nov 9, 2026
35 of 57 tasks
@jayzhan211

Copy link
Copy Markdown
Contributor Author

I think this one is ok, thank you for working on it @jayzhan211

I am still not very happy with the current state of the EquivalenceProperties and SortWalkKey (I realize you did not cause this). Specifically the fact that there are now explicit "implied" orderings in addition to equivalence properties seems like they partially duplicate significant functionality.

This PR seems to be adding more (complicated) code to add implied ordering in another path, rather than unifying the behavior. I realize unifying the logic is too much for a bug fix. It would be really nice to try and unify all this spaghetti as a follow on, otherwise we are going to be chasing bugs down in this code indefinitely

I also spent a while writing up what I think SortKeyWalk actually does

I've also found equivalence properties overly complicated, and the "walk" PR is my first step toward simplifying them. I'd like to revisit them and come up with a version that's easier to understand!

@kosiew kosiew 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.

@jayzhan211, thank you for addressing the window ordering regressions. The changes make ordering inference consistent across property registration paths and preserve valid plans that previously failed sanity checks. The approach looks appropriate, and I found no blocking correctness issues during static inspection.

The architectural boundaries are sound. Implied orderings belong in equivalence-property discovery, while the projection pushdown guard appropriately retains an explicit sort when the projection cannot establish the required ordering. This avoids relying on ordering information that does not survive the projection boundary.

The regression coverage is substantial, and the reported generated-query results support the fix. I have one optional suggestion to strengthen sort-direction coverage. I am approving the change. I did not independently run the Rust or SQL tests.

equality_first.add_equal_conditions(Arc::clone(&cast_c), Arc::clone(&a))?;
equality_first.add_ordering(ordering.clone());

let mut ordering_first = EquivalenceProperties::new(Arc::clone(&schema));

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.

Could we parameterize implied_ordering_does_not_depend_on_call_order over sort options? It would be useful to cover matching descending directions and verify that [a DESC, c ASC] does not imply global [c ASC] across distinct dates, with both equality/ordering insertion orders. The reported generated sweep already covers all four directions, so this would provide focused regression coverage.

@viirya viirya left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the updates. Storing [k, c] fixed the extra sort, and returning to .ok() keeps this easy to backport. One more thing before merging: an existing caller now depends on call order (see the inline comment on add_orderings).

/// Adds new orderings into the existing ordering equivalence class.
/// Adds new orderings into the existing ordering equivalence class, along
/// with the orderings they imply through known equalities.
pub fn add_orderings(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Now that add_orderings derives implied orderings, a caller that adds an ordering before clearing per-partition constants keeps orderings that no longer hold. RepartitionExec::eq_properties_helper does this: it calls add_ordering(merge key) and then clear_per_partition_constants(). SortPreservingMergeExec::compute_properties clears first.

With k a Heterogeneous constant, CAST(c AS DATE) = a, and merge key [k, a, c], the repartition order leaves ordering_satisfy([c]) true, although [c] doesn't hold once partitions with different k are merged. The SPM order gives false. Could eq_properties_helper clear the constants before add_ordering, the way SPM does? I don't see a SQL path to this today, because UnionExec drops equalities, so it mainly affects custom plans and any future source of per-partition constants.

@alamb

alamb commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

I've also found equivalence properties overly complicated, and the "walk" PR is my first step toward simplifying them. I'd like to revisit them and come up with a version that's easier to understand!

That would be amazing thank you @jayzhan211 -- I agree SortWalkkey is a great first step

limadog9 pushed a commit to limadog9/datafusion that referenced this pull request Nov 11, 2026
## Which issue does this PR close?

- split out of apache#27234.

## Rationale for this change

While reviewing apache#27191 I was
researching how `EquivalenceProperties` tracks orderings, equal
expressions, constants and groupings, and wanted to write down what I
learned so others do not have to repeat it.

The concepts were documented in pieces across several structs, with no
single place that explained them together.

## What changes are included in this PR?

Rustdoc only. The `EquivalenceProperties` doc in
`datafusion/physical-expr/src/equivalence/properties/mod.rs` becomes the
hub that the other struct docs link to. It keeps the existing examples
and adds:

## What is the testing strategy for this PR?

CI

## Are there any user-facing changes?

No.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Jay Zhan <jayzhan211@gmail.com>
Comment on lines +403 to +405
let mut implied = vec![];
for ordering in &normal_orderings {
implied.extend(self.implied_by(ordering).unwrap_or_default());

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.

Should we clear repartition constants before deriving merge orderings?

Comment on lines +413 to +415
// Each implied ordering is shorter than the one implying it, so this
// terminates:
self.add_orderings(implied);

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.

can we use a deduplicated worklist and avoid expanding already-known candidates?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Each round's implied orderings are now deduplicated before they are expanded. I didn't skip candidates that are already in the class: remove_redundant_entries drops the repeats anyway, and skipping them would rely on every earlier call having derived their implied orderings.

if let Some(rest) =
self.implied_ordering(key, keys[idx + 1..].iter().copied())?
{
let prefix = keys[..idx].iter().copied().cloned();

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.

IMO the Simpler fix would be: keep the constants in the stored implied ordering (store [k, c], not [c]). SortKeyWalk::new already skips a leading fixed head, so [c] still holds within a partition, and clearing k then removes it correctly.

wdyt?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This handles a leading constant, but not one between a key and its arguments, as in implied_ordering_past_a_constant_between_keys: [a, k, c] with a = CAST(c AS DATE) would store [k, c]. That holds within each partition, but not after RepartitionExec merges on [a, k, c]. Rows from two partitions on the same date come out as k = 1, 2, and the next date starts again at k = 1. Since the merge adds the ordering before clearing k, [k, c] would still be kept.

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.

I don't understand the implications of this comment

Specifically, if we didn't do this change, would we get wrong plans / errors? Or is it just a missed optimization opportunity?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'd keep [c] in this PR. As viirya says, the RepartitionExec call order needs fixing either way, and that fix is now in the PR. With it, SortPreservingMergeExec, RepartitionExec and CoalescePartitionsExec all drop [c] when they merge partitions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the issue is not critical but the change is quite small

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It was a wrong-result risk, not a missed optimization: before the reorder, the merged output could claim [c] although it doesn't hold, so a sort above it could be removed and rows come out in the wrong order. We don't know a SQL query that reaches it, which is why it wasn't critical. 2ceaba5 fixes it, and test_preserve_order_drops_per_partition_implied_ordering covers it.

}
if !new_orderings.is_empty() {
self.add_orderings(new_orderings);
new_orderings.extend(self.implied_by(ordering)?);

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.

discover_new_orderings still passes implied_by errors up with ?, while add_orderings ignores them. implied_by now checks every key, not just ordering[0], so whether the call fails still depends on the order of calls.

// such as a leading per-partition constant. Keep the sort above the
// projection in that case. Alternatives that cannot be remapped are not
// pushed down, so compare against the first one that can.
let pushed = parent_required.iter().find(|required| {

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.

should we walk the alternatives once and keep the first (original, remapped) pair, or have the remap helper return it.

self.oeq_cache.update_map();
// Each implied ordering is shorter than the one implying it, so this
// terminates:
self.add_orderings(implied);

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.

add_orderings passes implied back to itself without removing duplicates. Each level also runs remove_redundant_entries (O(n²)) and update_map over the whole class, so the work can grow with the number of key subsets.

statement ok
set datafusion.execution.target_partitions = 4;

query IIII

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.

The new 4-partition case (SELECT SUM(v) AS k, COUNT(*) AS c ...) only checks result rows, with no EXPLAIN. It cannot show whether a sort was avoided or added.

.iter()
.any(|ordering| walk.is_fixed(&ordering[0].expr))
{
walk.head_idxs = normal

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.

SortKeyWalk::new repeats the head-moving logic in pin (lines 177-180: move head_idx forward while is_fixed) as a separate position scan, so the rule for picking a head now lives in two places.

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.

The walk does not derive it because nothing is pinned. This is the order dependence the new comment says must not happen.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I couldn't get an order dependence from new_with_orderings. It starts with no equalities, and add_equal_conditions and add_constants both re-derive the implied orderings of every stored ordering. With k a per-partition constant and a = CAST(c AS DATE), ordering_satisfy([c]) is true for [a, c] and for [k, a, c], whichever of the equality and the constant is added first, and the same as with add_ordering. Which sequence of calls do you have in mind?

@viirya viirya left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The RepartitionExec call order from my last comment is still open. It's the only one of the new comments I'd hold the merge for. The others can be follow-ups. Keeping the constants in the implied ordering doesn't remove the need for the call-order fix (see the reply inline).

@alamb

alamb commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

FWIW I think it is important for this particular to fix the regression so we can safely backport to branch_56 and get the release out; I think we should try to minimize the impact / need for any other changes

I think the number of comments on this PR is indicative of how complex this code is and there are many ways we can improve it, but I would like to suggest we leave improvements to future follow on PR

@jayzhan211

Copy link
Copy Markdown
Contributor Author

Address all!

@kumarUjjawal kumarUjjawal 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.

Thank you @jayzhan211 for all the iterations.

I think we are in a good enough position to move forward with this. Other improvements will be in further follow ups.

@viirya viirya left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The RepartitionExec fix and its test cover what I raised. Thanks for all the iterations.

STUNSLAP pushed a commit to STUNSLAP/IIIllllIIl that referenced this pull request Nov 11, 2026
…he#27237)

## Which issue does this PR close?

- N/A, documentation only.

## Rationale for this change

While reviewing apache#27191 I was
researching how `EquivalenceProperties` tracks orderings and groupings,
and wanted to write down what I learned so others do not have to repeat
it.

The `GroupingEquivalenceClass` docs described the property in prose but
had no example, and did not say how it relates to
`OrderingEquivalenceClass`, which it parallels.

## What changes are included in this PR?

Rustdoc only, in `datafusion/physical-expr/src/equivalence/grouping.rs`:

Split out of a larger documentation PR
(apache#27234) for easier review.

## What is the testing strategy for this PR?

CI

## Are there any user-facing changes?

No.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

optimizer Optimizer rules physical-expr Changes to the physical-expr crates sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

REGRESSION: Window ordered by (total DESC, k) fails SanityCheckPlan when k is a function of a filtered constant column

6 participants