Skip to content

Build a typed temporal aggregate without a Spark Column - #158

Merged
estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:codegen/spark4-aggregates
Oct 5, 2026
Merged

estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:codegen/spark4-aggregates

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

The builder that the spark-sql engine emits for a temporal aggregate of the
typed surface made its expression through the public Column API: it applied
functions.udaf to new Column(argument) and read the expression back with
Column.expr(). Spark 4 removes both, the Column of Spark 4 carrying a
ColumnNode rather than an Expression, so the generated TemporalAggregates
does not compile against Spark 4.

The builder now makes the Catalyst aggregate itself, as the scalar builder of
MeosSqlRuntime makes a ScalaUDF: a ScalaAggregator over the argument
expressions, the Typed aggregator and the expression encoders of its input
and its buffer, turned into an aggregate expression. The constructor and
encoderFor have the same signatures in Spark 3.5 and Spark 4, so the
generated class compiles against both, and MobilitySpark moves to Spark 4
without a window in which its build and this generator disagree.

Witness: with the generator of main, MobilitySpark with Spark 4.0.1 fails to
compile TemporalAggregates, "no suitable constructor found for
Column(Expression)".

Measured: MobilitySpark main regenerated with this generator against
MobilityDB 7128c9344a passes its suite, 34 tests and no build warning, with
Spark 3.5.1 and with Spark 4.0.1, the temporal aggregates of
GeneratedSqlSurfaceTest among them. The codegen tests pass, 106 tests.

The builder that the spark-sql engine emits for a temporal aggregate of the
typed surface made its expression through the public Column API: it applied
functions.udaf to new Column(argument) and read the expression back with
Column.expr(). Spark 4 removes both, the Column of Spark 4 carrying a
ColumnNode rather than an Expression, so the generated TemporalAggregates
does not compile against Spark 4.

The builder now makes the Catalyst aggregate itself, as the scalar builder of
MeosSqlRuntime makes a ScalaUDF: a ScalaAggregator over the argument
expressions, the Typed aggregator and the expression encoders of its input
and its buffer, turned into an aggregate expression. The constructor and
encoderFor have the same signatures in Spark 3.5 and Spark 4, so the
generated class compiles against both, and MobilitySpark moves to Spark 4
without a window in which its build and this generator disagree.

Witness: with the generator of main, MobilitySpark with Spark 4.0.1 fails to
compile TemporalAggregates, "no suitable constructor found for
Column(Expression)".

Measured: MobilitySpark main regenerated with this generator against
MobilityDB 7128c9344a passes its suite, 34 tests and no build warning, with
Spark 3.5.1 and with Spark 4.0.1, the temporal aggregates of
GeneratedSqlSurfaceTest among them. The codegen tests pass, 106 tests.
@estebanzimanyi
estebanzimanyi merged commit 53ca034 into MobilityDB:main Oct 5, 2026
2 checks passed
estebanzimanyi added a commit to MobilityDB/MobilitySpark that referenced this pull request Oct 5, 2026
The pom moves spark-core and spark-sql from 3.5.1 to 4.0.1, and the job of
the workflow names Spark 4.0. Spark 4.0 is the release the book's chapters on
Spark run with Apache Sedona 1.8 and Delta Lake 4.0, whose environment
rebuilt MobilitySpark against Spark 4.0 by editing this pom.

The generated surface compiles against Spark 4 since MobilityDB/JMEOS#158,
which builds a typed temporal aggregate without a Spark Column: before it,
the generator applied functions.udaf to new Column(Expression), which Spark 4
removes, and TemporalAggregates did not compile.

Measured: tools/refresh-from-master.sh from scratch, against MobilityDB
270106028b and JMEOS main 53ca034, passes the suite, 34 tests, with no build
warning.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant