Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/dialect/aggregation-operators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,15 @@ Notes
- MERGE is an aggregate operation that processes all matching rows
- The operation sorts data internally, so pre-sorting is not required

.. note::

CLUSTER and MERGE cannot be combined in a single ``SELECT`` — MERGE
aggregates rows away while CLUSTER is a per-row window over those same rows,
so no single query expresses both. Transpiling ``SELECT MERGE(interval),
CLUSTER(interval) FROM features`` raises a ``ValueError``. Use them in
separate queries instead — for example, CLUSTER over a subquery, or MERGE
over one.

Related Operators
~~~~~~~~~~~~~~~~~

Expand Down
12 changes: 10 additions & 2 deletions src/giql/expander.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,15 @@ class ExpansionContext:
``capabilities`` and ``sqlglot_dialect``.
tables : Tables
The registered :class:`~giql.table.Tables` container.
registry : ExpanderRegistry | None
The registry the pass is resolving against. Carried so a whole-query
rewrite (CLUSTER / MERGE) can re-enter :func:`expand_operators` over the
SELECT it just restructured and expand sibling operators it copied into
it, honoring a custom-registry pass run. ``None`` for a standalone
context built outside the pass.
"""

__slots__ = ("node", "resolution", "target", "tables", "_alias_seq")
__slots__ = ("node", "resolution", "target", "tables", "registry", "_alias_seq")

def __init__(
self,
Expand All @@ -113,11 +119,13 @@ def __init__(
target: Target,
tables: Tables,
alias_seq: Callable[[], str] | None = None,
registry: ExpanderRegistry | None = None,
) -> None:
self.node = node
self.resolution = resolution
self.target = target
self.tables = tables
self.registry = registry
# A single sequence is threaded across every context built for one
# ``ExpandOperators`` run so aliases minted for sibling operators never
# collide; a standalone context falls back to its own sequence.
Expand Down Expand Up @@ -514,7 +522,7 @@ class sets ``GIQL_EXPAND = True`` *and* the registry resolves an expander for
"valid resolution metadata; pass 1 (resolve_operator_refs) must "
"run first and annotate every operator node."
)
ctx = ExpansionContext(node, resolution, target, tables, alias_seq)
ctx = ExpansionContext(node, resolution, target, tables, alias_seq, registry=reg)
replacement = fn(node, ctx)
if not isinstance(replacement, exp.Expression):
raise TypeError(
Expand Down
Loading
Loading