Skip to content

fix: TopK aggregation drops groups whose MIN/MAX value is NULL - #23684

Open
u70b3 wants to merge 1 commit into
apache:mainfrom
u70b3:fix/grouped-topk-null-aggregate-values
Open

fix: TopK aggregation drops groups whose MIN/MAX value is NULL#23684
u70b3 wants to merge 1 commit into
apache:mainfrom
u70b3:fix/grouped-topk-null-aggregate-values

Conversation

@u70b3

@u70b3 u70b3 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

When TopKAggregation pushes a LIMIT into a MIN/MAX aggregate, a group whose aggregate inputs are all NULL can disappear instead of being returned with a NULL aggregate value.

The stream previously skipped NULL aggregate inputs without registering the group. This is correct for an individual MIN/MAX input, but not for a group whose inputs are all NULL.

There is also an important correctness boundary: nullable MIN/MAX with NULLS FIRST is not monotonic for a bounded aggregation. A group can start at NULL, later become non-NULL, and thereby move to a worse rank. Keeping only limit NULL candidates can therefore discard a group that belongs in the final result.

What changes are included?

  • Track up to limit all-NULL candidates alongside valued TopK groups and emit them for the parent sort to rank and truncate.
  • Correctly convert a tracked NULL group when its first value arrives, or unregister it when that value cannot enter the valued TopK.
  • Skip TopK pushdown for nullable MIN/MAX with NULLS FIRST; regular aggregation is used for exact results. TopK remains enabled for NULLS LAST, non-nullable MIN/MAX inputs, and GROUP BY-only/DISTINCT queries.
  • Replace the single reusable hash-table slot with a free-slot stack. A NULL-to-value conversion can free both the NULL registration and an evicted valued group, so retaining only one slot caused unbounded backing-store growth under repeated conversions.
  • Select NULL-aware insertion once per batch, keeping NULL bookkeeping off the common no-NULL per-row hot path.
  • Add regression coverage for all-NULL groups, mixed NULL/value batches, bounded NULL candidate backfill, evicted groups, hash-table slot reuse, and optimizer plan selection.

Are these changes tested?

Yes. The following passed on the final commit:

  • cargo fmt --all -- --check
  • cargo clippy --all-targets --all-features -- -D warnings
  • TopK physical-plan unit tests (33 tests)
  • aggregates_topk.slt and affected group_by.slt tests
  • The repository's extended workspace command with avro,json,backtrace,extended_tests,recursive_protection,parquet_encryption, including all 495 sqllogic files and extended/fuzz suites

Performance

The topk_aggregate 10-million-row time-series benchmark exposed an initial ~5.5% regression from checking NULL state on every row. Moving NULL handling to a batch-selected slow path removed the measurable regression.

Final 30-sample 95% intervals on the same machine and settings:

  • main: 25.630–26.436 ms
  • this PR: 25.151–27.061 ms

Are there any user-facing changes?

Queries that previously dropped all-NULL groups under ORDER BY <min/max> ... LIMIT now return correct SQL results. Nullable MIN/MAX queries using NULLS FIRST may use regular aggregation rather than the bounded TopK optimization to guarantee correctness. There are no API or configuration changes.

@github-actions github-actions Bot added sqllogictest SQL Logic Tests (.slt) physical-plan Changes to the physical-plan crate labels Jul 18, 2026
@u70b3
u70b3 force-pushed the fix/grouped-topk-null-aggregate-values branch from 9238ac1 to a7f380c Compare July 20, 2026 06:58
@github-actions github-actions Bot added the optimizer Optimizer rules label Jul 20, 2026
@u70b3
u70b3 force-pushed the fix/grouped-topk-null-aggregate-values branch from a7f380c to 3ee7c2f Compare July 21, 2026 01:14
@codecov-commenter

codecov-commenter commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.96296% with 69 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.84%. Comparing base (86da5a8) to head (99df683).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
.../physical-plan/src/aggregates/topk/priority_map.rs 80.90% 0 Missing and 38 partials ⚠️
...on/physical-plan/src/aggregates/topk/hash_table.rs 85.14% 20 Missing and 6 partials ⚠️
...afusion/physical-optimizer/src/topk_aggregation.rs 86.95% 0 Missing and 3 partials ⚠️
...hysical-plan/src/aggregates/grouped_topk_stream.rs 75.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #23684      +/-   ##
==========================================
+ Coverage   80.77%   80.84%   +0.07%     
==========================================
  Files        1096     1096              
  Lines      373769   374207     +438     
  Branches   373769   374207     +438     
==========================================
+ Hits       301909   302536     +627     
+ Misses      53850    53588     -262     
- Partials    18010    18083      +73     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@u70b3
u70b3 force-pushed the fix/grouped-topk-null-aggregate-values branch from 3ee7c2f to e0370ea Compare July 27, 2026 12:18
@u70b3

u70b3 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Hi @kosiew — this PR has been open for ~2 weeks with CI fully green (40/40). Since you've reviewed the recent TopK changes (#23091, #23096), would you mind taking a look when you have a moment? It's a correctness fix for TopK aggregation silently dropping groups whose MIN/MAX value is NULL (#23440, #22190). Happy to address any feedback. Thanks!

@u70b3
u70b3 force-pushed the fix/grouped-topk-null-aggregate-values branch from e0370ea to c5bb62e Compare July 30, 2026 03:29
@kosiew

kosiew commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

run benchmark topk_aggregate

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5128408464-1299-v789s 6.12.85+ #1 SMP Mon May 11 08:17:35 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/grouped-topk-null-aggregate-values (c5bb62e) to 2f25454 (merge-base) diff using: topk_aggregate
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)

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_grouped-topk-null-aggregate-values
-----                                                             ----                                   --------------------------------------
aggregate 10000000 time-series rows                               1.00     61.8±5.68ms        ? ?/sec    1.03     63.9±7.22ms        ? ?/sec
aggregate 10000000 worst-case rows                                1.00     61.7±6.31ms        ? ?/sec    1.07     65.9±7.48ms        ? ?/sec
distinct 10000000 rows asc [TopK]                                 1.00      5.8±0.12ms        ? ?/sec    1.03      5.9±0.08ms        ? ?/sec
distinct 10000000 rows asc [no TopK]                              1.00     51.7±2.59ms        ? ?/sec    1.06     54.6±2.69ms        ? ?/sec
distinct 10000000 rows desc [TopK]                                1.00      5.8±0.18ms        ? ?/sec    1.02      5.9±0.07ms        ? ?/sec
distinct 10000000 rows desc [no TopK]                             1.00     51.2±2.99ms        ? ?/sec    1.06     54.0±2.49ms        ? ?/sec
string aggregate 10000000 time-series rows [Utf8View]             1.03     53.2±2.35ms        ? ?/sec    1.00     51.8±2.24ms        ? ?/sec
string aggregate 10000000 time-series rows [Utf8]                 1.03     51.0±2.07ms        ? ?/sec    1.00     49.7±1.50ms        ? ?/sec
string aggregate 10000000 worst-case rows [Utf8View]              1.00   295.7±15.59ms        ? ?/sec    1.04   307.1±15.81ms        ? ?/sec
string aggregate 10000000 worst-case rows [Utf8]                  1.00   305.1±11.85ms        ? ?/sec    1.00   304.4±13.17ms        ? ?/sec
top k=10 aggregate 10000000 time-series rows                      1.00     11.7±0.32ms        ? ?/sec    1.04     12.1±0.50ms        ? ?/sec
top k=10 aggregate 10000000 time-series rows [Utf8View]           1.00     13.0±0.57ms        ? ?/sec    1.01     13.2±0.49ms        ? ?/sec
top k=10 aggregate 10000000 worst-case rows                       1.00     18.1±0.88ms        ? ?/sec    1.05     19.1±1.33ms        ? ?/sec
top k=10 aggregate 10000000 worst-case rows [Utf8View]            1.00     19.8±1.00ms        ? ?/sec    1.02     20.2±1.12ms        ? ?/sec
top k=10 string aggregate 10000000 time-series rows [Utf8View]    1.00     11.6±0.29ms        ? ?/sec    1.01     11.6±0.28ms        ? ?/sec
top k=10 string aggregate 10000000 time-series rows [Utf8]        1.00      9.8±0.26ms        ? ?/sec    1.01      9.9±0.16ms        ? ?/sec
top k=10 string aggregate 10000000 worst-case rows [Utf8View]     1.00     11.6±0.33ms        ? ?/sec    1.00     11.7±0.36ms        ? ?/sec
top k=10 string aggregate 10000000 worst-case rows [Utf8]         1.00      9.8±0.15ms        ? ?/sec    1.01      9.9±0.20ms        ? ?/sec

Resource Usage

topk_aggregate — base (merge-base)

Metric Value
Wall time 1145.3s
Peak memory 2.1 GiB
Avg memory 324.2 MiB
CPU user 2049.4s
CPU sys 115.2s
Peak spill 0 B

topk_aggregate — branch

Metric Value
Wall time 1095.2s
Peak memory 2.1 GiB
Avg memory 317.0 MiB
CPU user 2027.7s
CPU sys 121.4s
Peak spill 0 B

File an issue against this benchmark runner

@kosiew

kosiew commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

run benchmark topk_aggregate

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5128903933-1300-xfzt4 6.12.85+ #1 SMP Mon May 11 08:17:35 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/grouped-topk-null-aggregate-values (c5bb62e) to 2f25454 (merge-base) diff using: topk_aggregate
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)

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_grouped-topk-null-aggregate-values
-----                                                             ----                                   --------------------------------------
aggregate 10000000 time-series rows                               1.05     71.9±6.79ms        ? ?/sec    1.00     68.5±6.87ms        ? ?/sec
aggregate 10000000 worst-case rows                                1.12     72.5±6.77ms        ? ?/sec    1.00     64.8±6.33ms        ? ?/sec
distinct 10000000 rows asc [TopK]                                 1.00      5.8±0.06ms        ? ?/sec    1.04      6.0±0.10ms        ? ?/sec
distinct 10000000 rows asc [no TopK]                              1.00     52.8±2.99ms        ? ?/sec    1.05     55.4±3.61ms        ? ?/sec
distinct 10000000 rows desc [TopK]                                1.00      5.8±0.06ms        ? ?/sec    1.04      6.0±0.07ms        ? ?/sec
distinct 10000000 rows desc [no TopK]                             1.00     53.5±3.13ms        ? ?/sec    1.05     56.1±2.45ms        ? ?/sec
string aggregate 10000000 time-series rows [Utf8View]             1.02     54.5±2.87ms        ? ?/sec    1.00     53.3±2.45ms        ? ?/sec
string aggregate 10000000 time-series rows [Utf8]                 1.04     51.9±2.52ms        ? ?/sec    1.00     50.0±2.31ms        ? ?/sec
string aggregate 10000000 worst-case rows [Utf8View]              1.00   303.3±16.99ms        ? ?/sec    1.02   308.1±21.41ms        ? ?/sec
string aggregate 10000000 worst-case rows [Utf8]                  1.05   313.9±12.75ms        ? ?/sec    1.00   298.4±12.47ms        ? ?/sec
top k=10 aggregate 10000000 time-series rows                      1.00     12.0±0.49ms        ? ?/sec    1.01     12.1±0.43ms        ? ?/sec
top k=10 aggregate 10000000 time-series rows [Utf8View]           1.00     13.2±0.53ms        ? ?/sec    1.01     13.3±0.50ms        ? ?/sec
top k=10 aggregate 10000000 worst-case rows                       1.00     18.7±1.25ms        ? ?/sec    1.01     18.9±1.32ms        ? ?/sec
top k=10 aggregate 10000000 worst-case rows [Utf8View]            1.00     20.2±1.21ms        ? ?/sec    1.01     20.5±1.09ms        ? ?/sec
top k=10 string aggregate 10000000 time-series rows [Utf8View]    1.00     11.6±0.25ms        ? ?/sec    1.01     11.7±0.32ms        ? ?/sec
top k=10 string aggregate 10000000 time-series rows [Utf8]        1.01     10.1±0.47ms        ? ?/sec    1.00     10.0±0.27ms        ? ?/sec
top k=10 string aggregate 10000000 worst-case rows [Utf8View]     1.00     11.6±0.24ms        ? ?/sec    1.01     11.7±0.27ms        ? ?/sec
top k=10 string aggregate 10000000 worst-case rows [Utf8]         1.00      9.9±0.21ms        ? ?/sec    1.01      9.9±0.18ms        ? ?/sec

Resource Usage

topk_aggregate — base (merge-base)

Metric Value
Wall time 800.2s
Peak memory 2.1 GiB
Avg memory 472.1 MiB
CPU user 2082.6s
CPU sys 118.8s
Peak spill 0 B

topk_aggregate — branch

Metric Value
Wall time 785.2s
Peak memory 2.1 GiB
Avg memory 465.7 MiB
CPU user 2004.9s
CPU sys 116.1s
Peak spill 0 B

File an issue against this benchmark runner

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

@u70b3

Looks good overall. I found one non-blocking test coverage suggestion.


# issue #22190: single all-NULL group, MIN ASC NULLS LAST LIMIT 20
query R
SELECT min_y FROM (SELECT s, MIN(y) AS min_y FROM t0 GROUP BY s) ORDER BY min_y ASC NULLS LAST LIMIT 20;

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 NULLS LAST all-NULL regression should still exercise bounded TopK aggregation, but this test currently checks only the final result. Could we add a nearby EXPLAIN assertion that verifies AggregateExec ... lim=[...] for one NULLS LAST all-NULL or mixed case? That would help ensure this coverage does not accidentally pass through the regular aggregation fallback.

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.

Added a nearby EXPLAIN assertion for the NULLS LAST all-NULL case, verifying that the physical plan retains AggregateExec with lim=[20]. Thanks!

Grouped TopK aggregation previously dropped groups whose MIN/MAX inputs were all NULL. Track bounded all-NULL candidates alongside valued groups and emit them for the final sort to rank and truncate. Handle NULL-to-value transitions, fully reuse freed hash-table slots, and keep NULL bookkeeping off the common no-NULL hot path.

Nullable MIN/MAX with NULLS FIRST is not monotonic for bounded aggregation: a group can move from NULL to a worse non-NULL rank. Skip the TopK pushdown in that case to preserve exact results while retaining it for NULLS LAST and non-nullable inputs.

Closes apache#23440, closes apache#22190.
@u70b3
u70b3 force-pushed the fix/grouped-topk-null-aggregate-values branch from c5bb62e to 99df683 Compare July 30, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

4 participants