Transforms are named functions applied to property values in expressions, forming pipelines that are applied
right-to-left (functional composition order).
"sum:items.price"// sum of items.price values "round:avg:scores"// pipeline: avg applied first, then round
Warning
The set of supported transforms is closed: only the names listed below are valid. Expressions and criteria
referencing unknown transforms are rejected outright by isExpression and isProbe. Pipes that violate the
structural composition rules (for example, aggregate after aggregate) are likewise rejected outright.
Transforms must also be well-typed: a transform whose declared domain is met by no branch of its input type (for
example, abs on a string) is rejected, while over a union-typed input the transform applies to its compatible
branches and ignores the incompatible ones, whose values resolve to undefined for a scalar transform and drop
from the input set for an aggregate.
Type Mapping
Transforms operate on JSON values but their semantics are defined in terms
of XPath 2.0 / XSD 1.0 types.
The domain and range columns in the table below use the following type shorthands:
literal — any comparable literal: xsd:boolean, numeric, xsd:string, or temporal; excludes IRI
references, nested resources, and Dictionary values, which lack an ordering
numeric — xsd:integer | xsd:decimal | xsd:float | xsd:double, mapped to JSON number
(IEEE 754 double); note that JSON numbers can only represent a subset of xsd:integer and xsd:decimal values
temporal — xsd:dateTime | xsd:date | xsd:time, mapped to JSON string; note that
temporal types may be accepted only by a specific subset of temporal transforms. xsd:duration is not a
temporal processing type and is treated as an opaque xsd:string
String-to-string transform pipes (for example, lower, upper) may also be applied to Dictionary
values: the pipe is applied individually to each string value in the dictionary. The min/max
aggregates require an ordering that localised text lacks, so it lies outside their domain.
Transform
Definition
Domain
Range
aggregates
Summarise a set of values (bag semantics; no implicit dedup)
count
Count values; 0 for empty sets
any
xsd:integer
min
Select minimum value; undefined for empty sets
literal
same as input
max
Select maximum value; undefined for empty sets
literal
same as input
sum
Sum numeric values; 0 for empty sets
numeric
same as input
avg
Average numeric values; undefined for empty sets
numeric
xsd:decimal
numeric
Transform numeric values
abs
Compute absolute value
numeric
same as input
floor
Floor to largest integer ≤ value
numeric
same as input
ceil
Ceiling to smallest integer ≥ value
numeric
same as input
round
Round to nearest integer
numeric
same as input
textual
Transform string values
lower
Convert to lowercase
xsd:string
same as input
upper
Convert to uppercase
xsd:string
same as input
length
Compute character length
xsd:string
xsd:integer
temporal
Extract components from ISO 8601 date/time
year
Extract year component
temporal
xsd:integer
month
Extract month component
temporal
xsd:integer
day
Extract day component
temporal
xsd:integer
hours
Extract hours component
temporal
xsd:integer
minutes
Extract minutes component
temporal
xsd:integer
seconds
Extract seconds component
temporal
xsd:decimal
avg always yields xsd:decimal: the spec narrows its range to xsd:float/xsd:double for those inputs, but that
processing-space distinction is not preserved on egress, so the effective range is uniformly xsd:decimal.
Aggregate Semantics
Aggregates use bag semantics: every contributing value counts toward the result with no implicit deduplication. The
expression path determines the input — count: (empty path) counts the input rows, while a non-empty path (for
example, sum:price) ranges over the values resolved by the path for each input row, with multi-valued path
fan-outs contributing every resolved value individually. Distinct-value aggregates are obtained through grouping (see
the Aggregate Grouping section) by projecting the value of interest as a non-aggregate
binding.
Error Handling
A transform must be well-typed: a transform whose declared domain is met by no branch of its input type is
rejected. Over a union-typed input, the transform applies to its compatible branches and treats each
incompatible-branch value like undefined: a scalar transform maps it to undefined, and an aggregate skips it
before computing the result. See Transform Pipes and
Aggregate Transforms for the full adopted semantics, including empty set
behaviour, multi-valued properties, and type promotion rules.
The supported set is restricted to the intersection of well-defined counterparts across XPath 2.0, SPARQL 1.1,
SQL:2011, and GQL:2024; see Client-Driven Retrieval for the
cross-backend design approach and Target Backends
for backend-specific adjustments.
Value transforms for computed expressions.
Transforms are named functions applied to property values in expressions, forming pipelines that are applied right-to-left (functional composition order).
The set of supported transforms is closed: only the names listed below are valid. Expressions and criteria referencing unknown transforms are rejected outright by
isExpressionandisProbe. Pipes that violate the structural composition rules (for example, aggregate after aggregate) are likewise rejected outright. Transforms must also be well-typed: a transform whose declared domain is met by no branch of its input type (for example,abson a string) is rejected, while over a union-typed input the transform applies to its compatible branches and ignores the incompatible ones, whose values resolve toundefinedfor a scalar transform and drop from the input set for an aggregate.Type Mapping
Transforms operate on JSON values but their semantics are defined in terms of XPath 2.0 / XSD 1.0 types. The domain and range columns in the table below use the following type shorthands:
xsd:boolean, numeric,xsd:string, or temporal; excludes IRI references, nested resources, and Dictionary values, which lack an orderingxsd:integer|xsd:decimal|xsd:float|xsd:double, mapped to JSONnumber(IEEE 754 double); note that JSON numbers can only represent a subset ofxsd:integerandxsd:decimalvaluesxsd:dateTime|xsd:date|xsd:time, mapped to JSONstring; note that temporal types may be accepted only by a specific subset of temporal transforms.xsd:durationis not a temporal processing type and is treated as an opaquexsd:stringString-to-string transform pipes (for example,
lower,upper) may also be applied to Dictionary values: the pipe is applied individually to each string value in the dictionary. Themin/maxaggregates require an ordering that localised text lacks, so it lies outside their domain.count0for empty setsxsd:integerminundefinedfor empty setsmaxundefinedfor empty setssum0for empty setsavgundefinedfor empty setsxsd:decimalabsfloorceilroundlowerxsd:stringupperxsd:stringlengthxsd:stringxsd:integeryearxsd:integermonthxsd:integerdayxsd:integerhoursxsd:integerminutesxsd:integersecondsxsd:decimalavgalways yieldsxsd:decimal: the spec narrows its range toxsd:float/xsd:doublefor those inputs, but that processing-space distinction is not preserved on egress, so the effective range is uniformlyxsd:decimal.Aggregate Semantics
Aggregates use bag semantics: every contributing value counts toward the result with no implicit deduplication. The expression path determines the input —
count:(empty path) counts the input rows, while a non-empty path (for example,sum:price) ranges over the values resolved by the path for each input row, with multi-valued path fan-outs contributing every resolved value individually. Distinct-value aggregates are obtained through grouping (see the Aggregate Grouping section) by projecting the value of interest as a non-aggregate binding.Error Handling
A transform must be well-typed: a transform whose declared domain is met by no branch of its input type is rejected. Over a union-typed input, the transform applies to its compatible branches and treats each incompatible-branch value like
undefined: a scalar transform maps it toundefined, and an aggregate skips it before computing the result. See Transform Pipes and Aggregate Transforms for the full adopted semantics, including empty set behaviour, multi-valued properties, and type promotion rules.The supported set is restricted to the intersection of well-defined counterparts across XPath 2.0, SPARQL 1.1, SQL:2011, and GQL:2024; see Client-Driven Retrieval for the cross-backend design approach and Target Backends for backend-specific adjustments.