API coverage¶
spark-connect-scala3 follows the public Scala API of Apache Spark's own Spark
Connect client, currently the Apache Spark 4.3.0 surface. It speaks the Spark
Connect 4.3.0 protocol and is verified end to end against live Apache Spark 3.5,
4.0, 4.1, 4.2, and 4.3 servers; an API that Apache Spark added in a given release
needs a server at least that new (see
Version compatibility). The plans the
client builds are checked against the ones Apache Spark 4.3.0's client builds for
the same calls. This page records exactly what is and is not implemented so there
are no surprises.
Supported¶
| Area | What is covered |
|---|---|
SparkSession |
builder (remote, config, create/getOrCreate), sql (commands run eagerly; named, positional, and java.util.Map parameters), typed range, table, createDataFrame/createDataset, emptyDataFrame/emptyDataset, tvf (table-valued functions), executeCommand, conf, catalog, read, readStream, streams, pipeline, version, newSession/cloneSession, tags (addTag/removeTag/getTags/clearTags), interrupts (interruptAll/interruptTag/interruptOperation), time, withActive, active and default session management, implicits, stop/close (releases the server-side session) |
Dataset / DataFrame |
select/selectExpr (including typed select of up to five TypedColumns), filter/where, withColumn(s)/withColumnRenamed(s)/withMetadata, drop, join/crossJoin/lateralJoin/joinWith, nearestByJoin, zip, zipWithIndex, groupBy/rollup/cube/groupingSets/agg/pivot, orderBy/sort/sortWithinPartitions, limit/offset/tail, distinct/dropDuplicates/dropDuplicatesWithinWatermark, union/unionByName/intersect(All)/except(All), sample/randomSplit(AsList), repartition/repartitionByRange/repartitionById/coalesce, hint, unpivot/melt, transpose, transform, toJSON, describe/summary, na, stat, observe, withWatermark, checkpoint/localCheckpoint, persist/cache/unpersist/storageLevel, subquery expressions (scalar/exists), colRegex/metadataColumn, to(Local)Iterator, collect/count/head/take/first/show, schema/columns/dtypes/printSchema/explain/inputFiles, sameSemantics/semanticHash, temp/global-temp view creation. Operators that keep the row shape keep the element type, so a Dataset[T] stays a Dataset[T] |
Column |
full expression algebra: arithmetic, comparison, and boolean operators (plus the Java-friendly plus/equalTo/gt/... aliases), like/rlike/ilike, contains/startsWith/endsWith, isin/isInCollection/isin(dataset), between, isNull/isNotNull/isNaN, cast/try_cast, substr, getItem/getField/apply, withField/dropFields, when/otherwise, over, asc/desc with null ordering, outer, transform, as[T] (typed columns), bitwise operators, explain |
functions |
every built-in function of Apache Spark 4.3.0 except udf/udaf, with the same overloads: aggregate, string, math, date/time, array/map/struct, JSON/CSV/XML, URL, Variant, sketches (HLL, KLL, Theta, Tuple), geospatial (st_*), vectors, partition transforms (partitioning.*), higher-order (lambda) functions, call_function, typedLit, broadcast, and window functions |
Window / WindowSpec |
partitionBy, orderBy, rowsBetween, rangeBetween |
| Data sources | DataFrameReader/DataFrameWriter for CSV, JSON, XML, Parquet, ORC, text, JDBC (including partitioned and predicate reads), and tables, with options, schema, partitionBy/bucketBy/sortBy/clusterBy, save modes, saveAsTable/insertInto, and withSchemaEvolution; textFile (Dataset[String]); parse an in-memory Dataset[String] as CSV/JSON/XML; change data capture (read.changes); DataFrameWriterV2 (writeTo); MergeIntoWriter (df.mergeInto(...), MERGE INTO) |
| SQL | spark.sql(...) with named and positional parameters (commands execute immediately, queries stay lazy); temporary and global temporary views; table-valued functions through spark.tvf |
| Catalog | spark.catalog with typed listings (Dataset[CatalogMetadata], Dataset[Database], Dataset[Table], Dataset[Column], Dataset[Function], Dataset[TablePartition]) and patterns: catalogs, databases, tables, views, columns, functions, and partitions; existence checks and getters; createTable/createExternalTable (eager); createDatabase/dropDatabase/dropTable/dropView/truncateTable/analyzeTable/getTableProperties/getCreateTableString; temp-view drops; cache management (including a storage level) |
| Structured Streaming | DataStreamReader (including name, changes, textFile, xml) and DataStreamWriter (including clusterBy), OutputMode, triggers (ProcessingTime/Once/AvailableNow/Continuous/RealTime), start/toTable, StreamingQuery, StreamingQueryManager, and StreamingQueryListener registration (addListener/removeListener/listListeners) with client-side event dispatch |
| Declarative Pipelines | build graphs of tables, materialized views, temporary views, sinks, flows, and Auto CDC flows, then run them on the server |
| Plugin extensions | build a Relation.extension from a packed protobuf message (SparkSession.newDataFrame/newRelation, Dataset.relation/plan) for server-side RelationPlugins such as GraphFrames |
| Typed Datasets | as[T], createDataset, emptyDataset, typed range, typed select, joinWith, and typed catalog listings, with compile-time Encoder derivation for case classes, tuples, primitives (and their boxed Java forms), java.time values, Option, collections, and maps, plus the Encoders factories (Encoders.product, Encoders.tuple, Encoders.STRING, ...); typed actions return T |
| Observation | Observation for collecting named aggregate metrics while a query runs (get/getAsJava); errors the server reports for the metrics are raised from get |
| Config | RuntimeConfig (spark.conf.get/getOption/getAll/set/unset/isModifiable) |
| Types | every Spark SQL type, including TimeType, the nanosecond timestamp types, VariantType, GeometryType/GeographyType, CharType/VarcharType, and user-defined types (decoded as their SQL type); DataType.sql/catalogString, StructType.toDDL |
| Results | Apache Arrow IPC decoding into name-addressable Rows (Row.json/prettyJson, getGeometry/getGeography, getJavaMap, ...); connection-string parsing (sc://host:port/;k=v); bearer-token auth (implies TLS); server errors surfaced as typed Spark exceptions (AnalysisException/ParseException/SparkException) with the server message, error class (getCondition), message parameters, SQL state, server stack trace, and the operation id |
| Resiliency | automatic retry of transient gRPC failures (exponential backoff + jitter); reattachable execution that resumes a broken ExecutePlan result stream via ReattachExecute (with ReleaseExecute to free server buffers); per-RPC deadlines (RpcDeadlines) with automatic reattach on DEADLINE_EXCEEDED; gRPC keepalive. All on by default, and working against Spark 3.5+ |
| Operations | an operation id and the thread's tags on every execution, SparkConnectClient.getOperationId(error), and getOperationStatuses |
Not supported¶
These are deliberately out of scope.
- User-defined functions (UDFs/UDAFs and typed
Aggregators). Registering or applying a Scala closure runs user JVM code on the server, which this client does not transport (functions.udf/udaf,spark.udf). - Streaming
foreach/foreachBatchsinks. Same reason: they execute a user function per row/batch on the server. All built-in sinks (parquet/console/memory/kafka/...) are supported. - Typed
Datasetoperations that take a Scala closure.as[T],createDataset, typed columns, andjoinWithare supported (encoder-only, no closure), but the operations below run a user function on the server and are not available:- typed
map/flatMap/mapPartitions/foreach/reduce, andfilter(T => Boolean) groupByKeyandKeyValueGroupedDataset(mapGroups,flatMapGroups,cogroup, typedagg) Use the relational API (select/agg/functions) for these.
- typed
- In-process JVM state.
SparkContext,Dataset.rdd,queryExecution,sessionState, andsharedStateexist only inside a classic (non-Connect) Spark driver. - Artifact upload (
addArtifact(s)). Shipping local JARs/files to the server is only needed for UDF code. - MLlib over Connect (
spark.mlequivalents). Not exposed here. - Classic-only builder settings.
Builder.masterandBuilder.enableHiveSupportare accepted for source compatibility but do nothing, as in Apache Spark's Connect client. - Protocol messages that are not standard Scala API. A handful of Spark
Connect relations/commands have no plain Scala DataFrame method because they
exist for other languages or for closure execution: the closure relations
(
mapPartitions,groupMap/coGroupMap,applyInPandasWithState), Python user-defined table functions and data sources, the ML relations/commands, the pipelineExecuteOutputFlowscommand, and internal optimization relations (server-cached and chunked local relations).
Differences from Apache Spark's client¶
StreamingQuery.idandrunIdareStrings rather thanjava.util.UUIDs, andlastProgress/recentProgressreturn the progress JSON rather thanStreamingQueryProgressobjects.spark.streams.getaccepts either form.- Local data (
createDataFrame,createDataset) is sent inline in the plan; there is no plan compression or artifact-backed chunking, so one local collection is bounded by the server's gRPC message size limit (128 MiB by default). - Encoders are derived at compile time for the shapes listed above. The bean,
Kryo, Java-serialization, and UDT-specific encoders (
Encoders.bean,Encoders.kryo,Encoders.javaSerialization) are not provided. Row.json/prettyJsonrender date and timestamp values with theirtoStringform.
Why these are excluded¶
UDFs, foreach/foreachBatch, and the typed closure operations all require
sending user-compiled JVM code to the server (artifact upload + class loading),
which is a separate, security-sensitive subsystem outside this client's scope.
The encoder-derivation half of the typed Dataset[T] API does not require that,
so it is fully supported; only the closure-driven typed operations listed above
remain out of scope.