29 Commits

Author SHA1 Message Date
kosiew b477816c86 Enforce explicit opt-in for WITHIN GROUP syntax in aggregate UDAFs (#18607)
## Which issue does this PR close?

Closes #18109.

## Rationale for this change

Previously, the SQL planner accepted `WITHIN GROUP` clauses for all
aggregate UDAFs, even those that did not explicitly support ordered-set
semantics. This behavior was too permissive and inconsistent with
PostgreSQL. For example, queries such as `SUM(x) WITHIN GROUP (ORDER BY
x)` were allowed, even though `SUM` is not an ordered-set aggregate.

This PR enforces stricter validation so that only UDAFs that explicitly
return `true` from `supports_within_group_clause()` may use `WITHIN
GROUP`. All other aggregates now produce a clear planner error when this
syntax is used.

## What changes are included in this PR?

* Added type alias `WithinGroupExtraction` to simplify complex tuple
return types used by helper functions.
* Introduced a new helper method `extract_and_prepend_within_group_args`
to centralize logic for handling `WITHIN GROUP` argument rewriting.
* Updated the planner to:

* Validate that only UDAFs with `supports_within_group_clause()` can
accept `WITHIN GROUP`.
* Prepend `WITHIN GROUP` ordering expressions to function arguments only
for supported ordered-set aggregates.
* Produce clear error messages when `WITHIN GROUP` is used incorrectly.
* Added comprehensive unit tests verifying correct behavior and failure
cases:

* `WITHIN GROUP` rejected for non-ordered-set aggregates (`MIN`, `SUM`,
etc.).
* `WITHIN GROUP` accepted for ordered-set aggregates such as
`percentile_cont`.
* Validation for named arguments, multiple ordering expressions, and
semantic conflicts with `OVER` clauses.
* Updated SQL logic tests (`aggregate.slt`) to reflect new rejection
behavior.
* Updated documentation:

* `aggregate_functions.md` and developer docs to clarify when and how
`WITHIN GROUP` can be used.
* `upgrading.md` to inform users of this stricter enforcement and
migration guidance.

## Are these changes tested?

 Yes.

* New tests in `sql_integration.rs` validate acceptance, rejection, and
argument behavior of `WITHIN GROUP` for both valid and invalid cases.
* SQL logic tests (`aggregate.slt`) include negative test cases
confirming planner rejections.

## Are there any user-facing changes?

 Yes.

* Users attempting to use `WITHIN GROUP` with regular aggregates (e.g.
`SUM`, `AVG`, `MIN`, `MAX`) will now see a planner error:

  > `WITHIN GROUP is only supported for ordered-set aggregate functions`

* Documentation has been updated to clearly describe `WITHIN GROUP`
semantics and provide examples of valid and invalid usage.

No API-breaking changes were introduced; only stricter planner
validation and improved error messaging.
2025-11-14 02:46:47 +00:00
Adrian Garcia Badaracco c84e3cf5a5 feat: Add percentile_cont aggregate function (#17988)
## Summary

Adds exact `percentile_cont` aggregate function as the counterpart to
the existing `approx_percentile_cont` function.

## What changes were made?

### New Implementation
- Created `percentile_cont.rs` with full implementation
- `PercentileCont` struct implementing `AggregateUDFImpl`
- `PercentileContAccumulator` for standard aggregation
- `DistinctPercentileContAccumulator` for DISTINCT mode
- `PercentileContGroupsAccumulator` for efficient grouped aggregation
- `calculate_percentile` function with linear interpolation

### Features
- **Exact calculation**: Stores all values in memory for precise results
- **WITHIN GROUP syntax**: Supports `WITHIN GROUP (ORDER BY ...)` 
- **Interpolation**: Uses linear interpolation between values
- **All numeric types**: Works with integers, floats, and decimals
- **Ordered-set aggregate**: Properly marked as
`is_ordered_set_aggregate()`
- **GROUP BY support**: Efficient grouped aggregation via
GroupsAccumulator

### Tests
Added comprehensive tests in `aggregate.slt`:
- Error conditions validation
- Basic percentile calculations (0.0, 0.25, 0.5, 0.75, 1.0)
- Comparison with `median` function
- Ascending and descending order
- GROUP BY aggregation
- NULL handling
- Edge cases (empty sets, single values)
- Float interpolation
- Various numeric data types

## Example Usage

```sql
-- Basic usage with WITHIN GROUP syntax
SELECT percentile_cont(0.75) WITHIN GROUP (ORDER BY column_name) 
FROM table_name;

-- With GROUP BY
SELECT category, percentile_cont(0.95) WITHIN GROUP (ORDER BY value)
FROM sales
GROUP BY category;

-- Compare with median (percentile_cont(0.5) == median)
SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY price) FROM products;
```

## Performance Considerations

Like `median`, this function stores all values in memory before
computing results. For large datasets or when approximation is
acceptable, use `approx_percentile_cont` instead.

## Related Issues

Closes #6714

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-17 04:05:54 +00:00
Geoffrey Claude 3f422a1746 feat: Support FILTER clause in aggregate window functions (#17378)
* feat: Support `FILTER` clause in aggregate window functions

* fix: Box `WindowFunction` in `ExprFuncKind` enum to reduce enum total size

As suggested by `clippy`:

```
warning: large size difference between variants
   --> datafusion/expr/src/expr_fn.rs:772:1
    |
772 | / pub enum ExprFuncKind {
773 | |     Aggregate(AggregateFunction),
    | |     ---------------------------- the second-largest variant contains at least 72 bytes
774 | |     Window(WindowFunction),
    | |     ---------------------- the largest variant contains at least 288 bytes
775 | | }
    | |_^ the entire enum is at least 288 bytes
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
    = note: `#[warn(clippy::large_enum_variant)]` on by default
help: consider boxing the large fields to reduce the total size of the enum
    |
774 -     Window(WindowFunction),
774 +     Window(Box<WindowFunction>),
    |
```

* test: Add DataFrame API test for FILTER clause on aggregate window functions

* docs: Update aggregate and window function documentation with FILTER support

* docs: Link missing proto fields to github issue in TODO comment
2025-09-05 22:18:23 +10:00
Andrew Lamb eaf614d38e (Re)Support old syntax for approx_percentile_cont and approx_percentile_cont_with_weight (#16999)
* Add sqllogictests

* Allow both new and old sytanx for approx_percentile_cont and approx_percentile_cont_with_weight

* Update docs

* Add documentation and more tests
2025-08-13 08:44:44 -04:00
Liam Bao 183ff6643a Support centroids config for approx_percentile_cont_with_weight (#17003)
* Support centroids config for `approx_percentile_cont_with_weight`

* Match two functions' signature

* Update docs

* Address comments and unify centroids config
2025-08-06 12:00:14 +02:00
aditya singh rathore 2a90ff606d Added Example for Statistical Functions in Docs (#16927)
* Update aggregate_functions.md

* Update aggregate_functions.md

* formating fix

* Update aggregate_functions.md

* Update docs/source/user-guide/sql/aggregate_functions.md

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>

* Update docs/source/user-guide/sql/aggregate_functions.md

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>

* Update docs/source/user-guide/sql/aggregate_functions.md

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>

* Update aggregate_functions.md

* Update aggregate_functions.md

* Update aggregate_functions.md

* Add examples to code

* Alamb Update

* Updated docs , build

* prettier

* Updates + prettier

---------

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
2025-07-31 16:45:14 -04:00
Garam Choi e41c02c699 Support WITHIN GROUP syntax to standardize certain existing aggregate functions (#13511)
* Add within group variable to aggregate function and arguments

* Support within group and disable null handling for ordered set aggregate functions (#13511)

* Refactored function to match updated signature

* Modify proto to support within group clause

* Modify physical planner and accumulator to support ordered set aggregate function

* Support session management for ordered set aggregate functions

* Align code, tests, and examples with changes to aggregate function logic

* Ensure compatibility with new `within_group` and `order_by` handling.

* Adjust tests and examples to align with the new logic.

* Fix typo in existing comments

* Enhance test

* Add test cases for changed signature

* Update signature in docs

* Fix bug : handle missing within_group when applying children tree node

* Change the signature of approx_percentile_cont for consistency

* Add missing within_group for expr display

* Handle edge case when over and within group clause are used together

* Apply clippy advice: avoids too many arguments

* Add new test cases using descending order

* Apply cargo fmt

* Revert unintended submodule changes

* Apply prettier guidance

* Apply doc guidance by update_function_doc.sh

* Rollback WITHIN GROUP and related logic after converting it into expr

* Make it not to handle redundant logic

* Rollback ordered set aggregate functions from session to save same info in udf itself

* Convert within group to order by when converting sql to expr

* Add function to determine it is ordered-set aggregate function

* Rollback within group from proto

* Utilize within group as order by in functions-aggregate

* Apply clippy

* Convert order by to within group

* Apply cargo fmt

* Remove plain line breaks

* Remove duplicated column arg in schema name

* Refactor boolean functions to just return primitive type

* Make within group necessary in the signature of existing ordered set aggr funcs

* Apply cargo fmt

* Support a single ordering expression in the signature

* Apply cargo fmt

* Add dataframe function test cases to verify descending ordering

* Apply cargo fmt

* Apply code reviews

* Uses order by consistently after done with sql

* Remove redundant comment

* Serve more clear error msg

* Handle error cases in the same code block

* Update error msg in test as corresponding code changed

* fix

---------

Co-authored-by: Jay Zhan <jayzhan211@gmail.com>
2025-04-23 18:46:03 +08:00
Gabriel cde8690bc5 Add a STRING_AGG implementation based on ARRAY_AGG for reusing funcionality (#14412) 2025-04-15 13:51:45 -04:00
Gabriel a05514cab8 Add support for DISTINCT + ORDER BY in ARRAY_AGG (#14413)
* Add support for DISTINCT and ORDER BY in ARRAY_AGG

* Add DISTINCT + ORDER BY docs

* Add some more sqllogictests

* Update aggregate_functions.md
2025-03-26 17:22:32 -04:00
Dawei H. 3f900ac5e1 Test all examples from library-user-guide & user-guide docs (#14544)
* add mut annotation

* fix rust examples

* fix rust examples

* update

* fix first doctest

* fix first doctest

* fix more doctest

* fix more doctest

* fix more doctest

* adopt rustdoc syntax

* adopt rustdoc syntax

* adopt rustdoc syntax

* fix more doctest

* add missing imports

* final udtf

* reenable

* remove dep

* run prettier

* api-health

* update doc

* update doc

* temp fix

* fix doc

* fix async schema provider

* fix async schema provider

* fix doc

* fix doc

* reorder

* refactor

* s

* finish

* minor update

* add missing docs

* add deps (#3)

* fix doctest

* update doc

* fix doctest

* fix doctest

* tweak showkeys

* fix doctest

* fix doctest

* fix doctest

* fix doctest

* update to use user_doc

* add rustdoc preprocessing

* fix dir

* revert to original doc

* add allocator

* mark type

* update

* fix doctest

* add doctest

* add doctest

* fix doctest

* fix doctest

* fix doctest

* fix doctest

* fix doctest

* fix doctest

* fix doctest

* fix doctest

* fix doctest

* prettier format

* revert change to datafusion-testing

* add apache header

* install cmake in setup-builder for ci workflow dependency

* taplo + fix snmalloc

* Update function docs

* preprocess user-guide

* Render examples as sql

* fix intro

* fix docs via script

---------

Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
2025-02-10 10:29:44 -05:00
Oleks V b312ac167e Doc gen: Migrate aggregate functions doc to attribute based. (#13646)
* Doc gen: Migrate aggregate functions doc to attribute based.
2024-12-05 08:20:21 -08:00
Bruce Ritchie 223bb02fce docs: switch completely to generated docs for scalar and aggregate functions (#13161)
* Remove _new docs, update index, update docs build script to point to main .md files for aggregate & scalar function pages.

* update documentation
2024-10-29 14:39:48 -04:00
Andrew Lamb 227908ff16 Migrate documentation for regr* aggregate functions to code (#12871)
* Migrate documentation for regr* functions to code

* Fix double expression

* Fix logical conflict
2024-10-22 11:07:24 -04:00
Jonathan Chen a8d3fae21d Migrate documentation for Aggregate Functions to code (#12861)
* aggregate function migration

* fmt fix
2024-10-11 09:58:41 -04:00
Andrew Lamb e0b807ba9c Improve description of function migration (#12743) 2024-10-09 19:32:15 -04:00
Andrew Lamb 7d36059958 Remove redundant aggregate/window/scalar function documentation (#12745)
* remove redundant aggregate documentation

* remove redundant window documentation

* remove rudundant scalar functions
2024-10-08 11:02:02 -04:00
Andrew Lamb b3bf3af36e Port / Add Documentation for VarianceSample and VariancePopulation (#12742) 2024-10-07 06:41:52 -04:00
Dharan Aditya 322d835269 Move kurtosis_pop to datafusion-functions-extra and out of core (#12647)
Co-authored-by: Dharan Aditya <dharan.guthula@datapelago.com>
2024-09-28 11:19:10 +08:00
Jax Liu 5ff5a6c924 Implement kurtosis_pop UDAF (#12273)
* implement kurtosis_pop udaf

* add tests

* add empty end line

* fix MSRV check

* fix the null input and enhance tests

* refactor the aggregation

* address the review comments

* add the doc for kurtois_pop

* fix the doc style

* use coercible signature

* remove unused cast
2024-09-04 15:19:38 +08:00
Piotr Findeisen 1b3a7af673 Fix count() docs around including null values (#11293)
The count aggregate was documented to count null values, but it does not
do that. The implemented behavior is correct, so let's fix docs.
2024-07-06 07:08:58 -04:00
Yongting You d1361d56b9 Add regr_*() aggregate functions (#7211) 2023-08-08 08:21:29 -04:00
Yongting You a9561a0f06 Add regr_slope() aggregate function (#7135) 2023-08-01 16:33:23 -04:00
Mustafa Akur f54f514a49 Add support for FIRST_VALUE, LAST_VALUE Aggregate Functions (#6445)
* Naive test pass

i

* Add new tests and simplifications

* move tests to the .slt file

* update requirement

* update tests

* Add support for partiallyOrdered aggregation sensitive.

* Resolve linter errors

* update comments

* minor changes

* retract changes in generated

* update proto files

* Simplifications

* Make types consistent in schema, and data

* Update todos

* Convert API to vector

* Convert get_finest to handle Vector inputs

* simplifications, update comment

* initial commit, add test

* Add support for FIRST Aggregate function.

* Add support for last aggregate

* Update cargo.lock

* Remove distinct, and limit from First and last aggregate.

* Add reverse for First and Last Aggregator

* Update cargo lock

* Minor code simplifications

* Update comment

* Update documents

* Fix projection pushdown bug

* fix projection push down failure bug

* combine first_agg and last_agg parsers

* Update documentation

* Update subproject

* initial commit

* Add test code

* initial version

* simplify prints

* minor changes

* sqllogictests pass

* All tests pass

* update proto function names

* Minor changes

* do not consider ordering requirement in ordering insensitive aggregators

* Reject aggregate order by for window functions.

* simplifications

* Fix cargo lock file

* Update comment

* Rename aggregator first and last

* minor change

* Comment improvements

* Remove count from First,Last accumulators

* Address reviews

* Remove camel to upper snake util, make aggregate function names explicit

* update the test

---------

Co-authored-by: Mehmet Ozan Kabak <ozankabak@gmail.com>
Co-authored-by: berkaysynnada <berkay.sahin@synnada.ai>
2023-05-26 17:23:13 -04:00
Mustafa Akur d8a92be182 Add support for ordering sensitive aggregation (#6332)
* Naive test pass

i

* Add new tests and simplifications

* move tests to the .slt file

* update requirement

* update tests

* Add support for partiallyOrdered aggregation sensitive.

* Resolve linter errors

* update comments

* minor changes

* retract changes in generated

* update proto files

* Simplifications

* Make types consistent in schema, and data

* Update todos

* Convert API to vector

* Convert get_finest to handle Vector inputs

* simplifications, update comment

* Minor code simplifications

* Update comment

* Update documents

* fix projection push down failure bug

* Simplifications, Address reviews

* Update comment

* Resolve linter errors

---------

Co-authored-by: Mehmet Ozan Kabak <ozankabak@gmail.com>
2023-05-15 12:43:48 -04:00
Igor Izvekov 93ff57e6e0 feat: support bitwise and boolean aggregate functions (#6276)
* feat: bitwise and boolean aggregate functions

* feat: SQL implementation

* feat: proto

* fix: import modules in proto

* fix: sqllogictests

* feat: docs

* fix: clippy

* refactor: bit_and_or_xor.rs and bool_and_or.rs

* feat: macro_rules for bitwise aggregate operations

* feat: bitwise aggregate functions in pg_compat
2023-05-15 10:19:51 -04:00
Jeffrey 3ad7734a7e Update sql doc (#6025)
* Update/touch-up user-guide sql doc pages

* Update ddl doc
2023-04-17 06:31:46 -04:00
Scott Anderson 9632c8e681 chore: update sql function documentation (#5780)
* chore: update sql function documentation

* chore: remove sql syntax hl from sql function sigs

* chore: ran prettier on modified markdown

* chore: update sql function docs to address PR review

* chore: added arrow_cast documenation, mention unicode support in chr
2023-03-30 12:42:19 -04:00
Yang Jiang 929eb6d860 Support number of centroids in approx_percentile_cont (#3146)
* Support number of histogram bins in approx_percentile_cont

* add args check and UT

* add doc
2022-08-17 05:15:37 -04:00
Rich a09e1aeb5f add docs for approx functions (#2082)
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
2022-03-27 13:36:29 -07:00