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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ci:

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
rev: v0.16.9
hooks:
- id: ruff
args: [ --fix ]
Expand Down
37 changes: 18 additions & 19 deletions examples/adbc_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,21 @@ def read_adbc_named_table(name: str, conn):
return read_named_table(name, substrait_schema)


with adbc_driver_duckdb.dbapi.connect(":memory:") as conn:
with conn.cursor() as cur:
cur.adbc_ingest("AnswerToEverything", data)

cur.executescript("INSTALL substrait;")
cur.executescript("LOAD substrait;")

table = read_adbc_named_table("AnswerToEverything", conn)
table = filter(
table,
expression=scalar_function(
"extension:io.substrait:functions_comparison",
"gte",
expressions=[column("ints"), literal(3, i64())],
),
)

cur.execute(table(registry).SerializeToString())
print(cur.fetch_arrow_table())
with adbc_driver_duckdb.dbapi.connect(":memory:") as conn, conn.cursor() as cur:
cur.adbc_ingest("AnswerToEverything", data)

cur.executescript("INSTALL substrait;")
cur.executescript("LOAD substrait;")

table = read_adbc_named_table("AnswerToEverything", conn)
table = filter(
table,
expression=scalar_function(
"extension:io.substrait:functions_comparison",
"gte",
expressions=[column("ints"), literal(3, i64())],
),
)

cur.execute(table(registry).SerializeToString())
print(cur.fetch_arrow_table())
113 changes: 59 additions & 54 deletions pixi.lock

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ respect-gitignore = true
# should target minimum supported version
target-version = "py310"
lint.extend-select = ["I"]
# The public API raises plain `Exception`; switching to typed exceptions is a separate,
# user-visible change.
lint.extend-ignore = ["TRY002", "TRY004"]

[tool.ruff.lint.per-file-ignores]
# Naive datetimes are deliberate: they model Substrait's timezone-less timestamp literals.
"tests/**" = ["DTZ001"]
# Re-exports the generated protobuf modules wholesale.
"src/substrait/proto/__init__.py" = ["F401", "F403"]


[tool.pixi.workspace]
Expand All @@ -70,4 +79,4 @@ lint = "ruff check"
lint_fix = "ruff check --fix"

[tool.pixi.dependencies]
ruff = ">=0.14.10,<0.15"
ruff = ">=0.16.9,<0.17"
37 changes: 19 additions & 18 deletions src/substrait/builders/extended_expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import contextvars
import itertools
import uuid as uuid_module
from collections.abc import Callable, Iterable
from datetime import date, datetime, time, timedelta, timezone
from decimal import Decimal
from typing import Any, Callable, Iterable, Union
from typing import Any, Union

import substrait.algebra_pb2 as stalg
import substrait.extended_expression_pb2 as stee
Expand Down Expand Up @@ -55,7 +56,7 @@ def fresh_rel_anchors():
UnboundExtendedExpression = Callable[
[stp.NamedStruct, ExtensionRegistry], stee.ExtendedExpression
]
ExtendedExpressionOrUnbound = Union[stee.ExtendedExpression, UnboundExtendedExpression]
ExtendedExpressionOrUnbound = stee.ExtendedExpression | UnboundExtendedExpression


class EnumArg:
Expand Down Expand Up @@ -83,7 +84,7 @@ def __repr__(self) -> str:


def _alias_or_inferred(
alias: Union[Iterable[str], str, None],
alias: Iterable[str] | str | None,
op: str,
args: Iterable[str],
):
Expand Down Expand Up @@ -456,7 +457,7 @@ def _make_literal(value: Any, type: stp.Type) -> stalg.Expression.Literal:


def literal(
value: Any, type: stp.Type, alias: Union[Iterable[str], str, None] = None
value: Any, type: stp.Type, alias: Iterable[str] | str | None = None
) -> UnboundExtendedExpression:
"""Builds a resolver for ExtendedExpression containing a literal expression.

Expand All @@ -480,7 +481,7 @@ def resolve(
return build_scoped(resolve)


def outer_reference(field: Union[str, int], steps_out: int = 1):
def outer_reference(field: str | int, steps_out: int = 1):
"""A field reference to an enclosing query's column (a correlated reference).

Only valid inside a subquery; ``steps_out`` counts query-nesting levels
Expand Down Expand Up @@ -538,7 +539,7 @@ def __init__(self, rel_anchor: int, schema: stp.NamedStruct):
self._rel_anchor = rel_anchor
self._schema = schema

def column(self, field: Union[str, int]):
def column(self, field: str | int):
"""A correlated reference to the left row's ``field`` (name or index)."""
rel_anchor = self._rel_anchor
schema = self._schema
Expand Down Expand Up @@ -570,7 +571,7 @@ def resolve(
return build_scoped(resolve)


def column(field: Union[str, int], alias: Union[Iterable[str], str, None] = None):
def column(field: str | int, alias: Iterable[str] | str | None = None):
"""Builds a resolver for ExtendedExpression containing a FieldReference expression

Accepts either an index or a field name of a desired field.
Expand Down Expand Up @@ -624,8 +625,8 @@ def scalar_function(
urn: str,
function: str,
expressions: Iterable[ExtendedExpressionOrUnbound],
alias: Union[Iterable[str], str, None] = None,
options: Union[dict, None] = None,
alias: Iterable[str] | str | None = None,
options: dict | None = None,
):
"""Builds a resolver for ExtendedExpression containing a ScalarFunction expression.

Expand Down Expand Up @@ -678,14 +679,14 @@ def aggregate_function(
urn: str,
function: str,
expressions: Iterable[ExtendedExpressionOrUnbound],
alias: Union[Iterable[str], str, None] = None,
alias: Iterable[str] | str | None = None,
invocation: Union[
"stalg.AggregateFunction.AggregationInvocation.ValueType", None
] = None,
sorts: Iterable[
tuple[ExtendedExpressionOrUnbound, "stalg.SortField.SortDirection.ValueType"]
] = (),
options: Union[dict, None] = None,
options: dict | None = None,
):
"""Builds a resolver for ExtendedExpression containing a AggregateFunction measure.

Expand Down Expand Up @@ -751,8 +752,8 @@ def window_function(
function: str,
expressions: Iterable[ExtendedExpressionOrUnbound],
partitions: Iterable[ExtendedExpressionOrUnbound] = [],
alias: Union[Iterable[str], str, None] = None,
options: Union[dict, None] = None,
alias: Iterable[str] | str | None = None,
options: dict | None = None,
):
"""Builds a resolver for ExtendedExpression containing a WindowFunction expression"""

Expand Down Expand Up @@ -807,7 +808,7 @@ def resolve(
def if_then(
ifs: Iterable[tuple[ExtendedExpressionOrUnbound, ExtendedExpressionOrUnbound]],
_else: ExtendedExpressionOrUnbound,
alias: Union[Iterable[str], str, None] = None,
alias: Iterable[str] | str | None = None,
):
"""Builds a resolver for ExtendedExpression containing an IfThen expression"""

Expand Down Expand Up @@ -990,7 +991,7 @@ def resolve(
def cast(
input: ExtendedExpressionOrUnbound,
type: stp.Type,
alias: Union[Iterable[str], str, None] = None,
alias: Iterable[str] | str | None = None,
):
"""Builds a resolver for ExtendedExpression containing a cast expression"""

Expand Down Expand Up @@ -1078,7 +1079,7 @@ def _inner_rel(query, registry: ExtensionRegistry, base_schema) -> stalg.Rel:
return rel


def scalar_subquery(query, alias: Union[str, None] = None):
def scalar_subquery(query, alias: str | None = None):
"""A scalar (one-row, one-column) subquery expression."""

def resolve(base_schema, registry):
Expand All @@ -1091,7 +1092,7 @@ def resolve(base_schema, registry):
return build_scoped(resolve)


def set_predicate(query, op, alias: Union[str, None] = None):
def set_predicate(query, op, alias: str | None = None):
"""An EXISTS / UNIQUE subquery predicate."""

def resolve(base_schema, registry):
Expand All @@ -1106,7 +1107,7 @@ def resolve(base_schema, registry):
return build_scoped(resolve)


def in_predicate(needles, query, alias: Union[str, None] = None):
def in_predicate(needles, query, alias: str | None = None):
"""A ``needles IN (subquery)`` predicate."""

def resolve(base_schema, registry):
Expand Down
Loading
Loading