Skip to content

[pull] main from apache:main - #265

Merged
pull[bot] merged 3 commits into
buraksenn:mainfrom
apache:main
Jun 9, 2026
Merged

pull[bot] merged 3 commits into
buraksenn:mainfrom
apache:main

Conversation

@pull

@pull pull Bot commented Jun 9, 2026 •

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

crm26 and others added 3 commits June 8, 2026 19:20
## Which issue does this PR close?

Partial of #21536 — `array_sum` (first of the array aggregates in the
series).

## Rationale for this change

Continues the per-function split sequence requested by @alamb on #21536.
Four sibling PRs already merged: `cosine_distance` (#21542),
`inner_product` (#21861), `array_normalize` (#22013), `array_scale`
(#22466). `array_add` is in flight as #22459 by @SubhamSinghal.

`array_sum` is the first of the three array-aggregate functions (sum,
product, avg). Its semantics set the pattern for the other two
aggregates.

## What changes are included in this PR?

- New scalar UDF `array_sum(array)` in
`datafusion/functions-nested/src/array_sum.rs`
- Module wire-up + registration in
`datafusion/functions-nested/src/lib.rs`
- SLT tests at `datafusion/sqllogictest/test_files/array_sum.slt`
- Auto-generated docs entry in
`docs/source/user-guide/sql/scalar_functions.md`

**Signature:** \`List/LargeList/FixedSizeList<numeric>\` in, \`Float64\`
out (one scalar per row). Numeric inner types coerced to \`Float64\`.

**NULL semantics — SQL aggregate convention (deliberate divergence from
binary-op siblings):**
- NULL row → NULL row out
- NULL elements are **skipped**, matching PostgreSQL \`array_sum\`,
DuckDB \`list_sum\`, Spark \`aggregate\`. Binary-op siblings
(\`inner_product\`, \`array_normalize\`) null-row on NULL element
because their per-element operation is undefined on NULL; aggregates
conventionally skip NULLs in SQL.
- All-NULL row → NULL out (matches \`SUM(...)\` over an all-NULL column)

- **Empty array → NULL** (matches sibling `array_product` #22703,
PostgreSQL, DuckDB `list_sum`, SQL Standard SUM-of-empty-set)

**Alias:** \`list_sum\` (matches the precedent of
\`array_normalize\`→\`list_normalize\`, \`array_scale\`→\`list_scale\`).

## Are these changes tested?

Yes. SLT covers happy paths, empty arrays, NULL row, NULL elements (mix
+ all-NULL), all list variants (List/LargeList/FixedSizeList), numeric
coercion (Float32/Int64/integer literals), multi-row composition, error
paths, return type, and the \`list_sum\` alias.

## Are there any user-facing changes?

Yes — new SQL scalar function \`array_sum(array)\` and its alias
\`list_sum\`.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Closes #18825

Add a `union_coercion` rule so that comparisons between a Union column
and an opaque scalar pick the scalar type whenever any union variant can
be cast to it. The execution side is already handled by arrow-rs's
`cast(Union -> T)` (arrow 58.3.0+), which extracts values from the
matching variant and emits NULL for rows whose active variant is not
castable to the target

---------

Co-authored-by: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ilter evaluation (#22704)

## Which issue does this PR close?

<!-- No tracking issue; this is a standalone benchmark contribution. -->

This PR does not close an issue. It adds a benchmark suite to support
work and
discussion around predicate ordering in filter evaluation (e.g. the
static
reordering in #22343 and the runtime/statistics-based reordering
explored in
#22698). It deliberately benchmarks *no specific implementation* — see
below.

## Rationale for this change

Conjunctive (`AND`) filter evaluation in `FilterExec` is a left-deep
`BinaryExpr(And)` chain, and the order conjuncts are evaluated in can
change
runtime by large factors: once a leading conjunct passes few enough rows
the
batch is physically compacted before the rest, so a cheap-and-selective
predicate evaluated early saves later predicates work. Predicate
ordering is
therefore an active area (static heuristics, runtime/adaptive schemes,
cost
models).

There is currently no benchmark suite that isolates the dimensions that
drive
this. Existing macro-benchmarks (TPC-H/DS, ClickBench) only incidentally
exercise filter ordering, so they can't show *why* a change to ordering
helped
or hurt, or guard the order-insensitive case against regressions.

## What changes are included in this PR?

A new SQL benchmark suite, `benchmarks/sql_benchmarks/predicate_eval`,
built on
the existing `.benchmark` template framework (no engine code, no new
Rust). It
sets no engine config of its own and measures DataFusion's built-in
short-circuit
by default; a system under test is toggled purely via its native
`DATAFUSION_EXECUTION_*` env var (the bench harness builds its
`SessionContext`
with `SessionConfig::from_env`), so the same scenarios can characterise
the
baseline, a static heuristic, an adaptive scheme, or a cost model and be
compared apples-to-apples.

It is organised into 10 subgroups (select with `BENCH_SUBGROUP`), each
varying
one property of conjunctive filter evaluation while holding the others
fixed:

| Subgroup | What it varies (others held fixed) |
|---|---|
| `costsel` | cost and selectivity point in different directions
(expensive predicate is the selective one) |
| `cost` | per-predicate cost, at equal selectivity |
| `selectivity` | per-predicate selectivity, at equal cost |
| `cardinality` | conjunct count `k = 2/4/8/16` |
| `width` | string-column width (`PRED_FILL` = 2 / 30 / 170 chars) |
| `scale` | row count `5k / 100k / 5M / 50M` |
| `neutral` | predicates are interchangeable (equal cost, none
selective) — an order-insensitive control |
| `correlation` | conditional vs marginal selectivity (independent /
positively / anti-correlated) |
| `drift` | selectivity that changes across the scan |
| `nulls` | null density (two- vs three-valued predicate results) |

Each query's comment notes the per-predicate cost/selectivity that the
data
generation hides from the SQL. Data is synthetic and generated inline by
each
subgroup's load SQL (no external files); `PRED_ROWS` sizes it and
`PRED_FILL`
sets string width. Wired into `bench.sh` (`./bench.sh run
predicate_eval`) and
documented in `benchmarks/sql_benchmarks/README.md`.

The design was informed by surveying how Velox drives the analogous
decision
(it ranks by cycles-per-row-eliminated, `time / (rows_in - rows_out)`).

> Note: the `scale` subgroup's `q52`/`q53` build 5M / 50M-row tables
(the latter
> ~9 GB); run a single point with `BENCH_QUERY` if that is too heavy.

## Are these changes tested?

These are benchmark definitions, not engine code. Each `.benchmark`
includes an
`assert` that the generated table is non-empty, and every subgroup was
run
locally at small `PRED_ROWS` to confirm the suite parses, loads,
asserts, and
executes end-to-end. The queries are order-invariant (`SELECT count(*)
...`), so
any predicate-ordering system can also be checked for correctness by
diffing
counts with the optimization on vs. off.

## Are there any user-facing changes?

No. This only adds an opt-in benchmark suite and its documentation; no
public
API, engine behavior, or default configuration changes.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pull pull Bot locked and limited conversation to collaborators Jun 9, 2026
@pull pull Bot added the ⤵️ pull label Jun 9, 2026
@pull
pull Bot merged commit 0f8a121 into buraksenn:main Jun 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants