feat(bindings): extent(tnumber) → tbox + bundle extent overloads in one set#49
Closed
estebanzimanyi wants to merge 1 commit into
Closed
Conversation
…ne set
Adds two new aggregate overloads:
- extent(tint) → tbox
- extent(tfloat) → tbox
Implementation in new module src/temporal/temporal_aggregates.cpp:
- TboxExtentState holds an inline TBox (period + value-span + flags),
fixed-size POD.
- TnumberExtentFunction copies the input Temporal blob into a heap
allocation before passing to MEOS tnumber_extent_transfn. On first
call MEOS palloc's a fresh TBox; we memcpy into state and free.
Subsequent calls expand the inline state via the same MEOS function.
- Combine merges two TBox states via tbox_expand (replicating MEOS's
inline path when both operands are non-null).
Refactors how extent() overloads are registered: previously each module
registered its own AggregateFunctionSet("extent"), which broke when
two modules both did it — DuckDB rejects overlap-by-name registrations
because CreateAggregateFunctionInfo has no GetAlterInfo override.
Now both span_aggregates.cpp and temporal_aggregates.cpp expose
AddExtentOverloads(AggregateFunctionSet&) that mutate a shared set. The
load site in LoadInternal builds one set, calls both, then registers
once.
This was referenced Apr 29, 2026
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds 2 new aggregate overloads:
```sql
SELECT extent(t) FROM (VALUES (tint '[1@2000-01-01, 5@2000-01-05]'),
(tint '[10@2000-01-03, 20@2000-01-08]')) tt(t);
-- TBOXINT XT([1, 21),[2000-01-01 00:00:00+00, 2000-01-08 00:00:00+00])
```
Implementation
New module: `src/temporal/temporal_aggregates.cpp` + `src/include/temporal/temporal_aggregates.hpp`.
API refactor (driven by adding the second module)
Previously each module registered its own `AggregateFunctionSet("extent")` directly via the loader. That worked when only `SpanAggregates` existed (PR #47). Adding `TemporalAggregates` with the same set name surfaced a DuckDB constraint: a second registration with the same aggregate name triggers an ALTER path, but `CreateAggregateFunctionInfo` doesn't override `GetAlterInfo()`, so it throws `NotImplementedException`.
Fix: both modules now expose `AddExtentOverloads(AggregateFunctionSet &)` that mutate a shared set. The load site in `LoadInternal` builds one set, calls both, then registers exactly once:
```cpp
AggregateFunctionSet extent_set("extent");
SpanAggregates::AddExtentOverloads(extent_set);
TemporalAggregates::AddExtentOverloads(extent_set);
loader.RegisterFunction(std::move(extent_set));
```
Stacked on
Test plan