Spark Expression Support#

This page is the complete reference for how Apache Comet handles each Spark built-in expression. Comet accelerates expressions either with a native (Rust) implementation or by dispatching to a Spark-compatible codegen path. When an expression is not supported, Comet transparently falls back to Spark for that part of the plan; results are unaffected.

Expressions marked βœ… Supported are enabled by default and produce Spark-compatible results.

Some βœ… Supported expressions have specific incompatible cases that are not run by default. Those cases must be opted into per expression with spark.comet.expression.EXPRNAME.allowIncompatible=true (where EXPRNAME is the Spark expression class name, for example Cast). There is no global opt-in. By default such a case either falls back to Spark (for example cast) or, when the expression has a Spark-compatible codegen-dispatch implementation, runs through that instead (for example the regex and JSON families). See Native and codegen-dispatch implementations for how Comet chooses.

Most expressions can also be disabled with spark.comet.expression.EXPRNAME.enabled=false, where EXPRNAME is the Spark expression class name (for example Length or StartsWith). See the Comet Configuration Guide for the full list.

Status legend#

Status

Meaning

βœ… Supported

Comet produces Spark-compatible results by default. Some inputs or forms may fall back to Spark, and any incompatible behavior is opt-in (off by default).

πŸ”œ Planned

Intended; tracked by an open issue or pull request.

Not currently planned#

Comet focuses acceleration on mainstream relational, string, datetime, math, and collection expressions. The following function families are not currently planned for native acceleration (they are not on the 1.0 roadmap): specialized functionality with narrow real-world analytics use and high implementation cost. They fall back to Spark and may be reconsidered based on demand:

  • Probabilistic sketches and approximate top-k (kll_sketch_*, hll_*, theta_*, count_min_sketch, bitmap_*, approx_top_k*): specialized data structures with exact-correctness traps.

  • Geospatial (st_*): brand-new Spark 4.1 functionality, specialized.

  • Avro / Protobuf codecs (from_avro, to_avro, from_protobuf, to_protobuf, schema_of_avro): format conversion belongs at the IO layer, not expression evaluation.

  • JVM reflection (java_method, reflect): niche, and they invoke arbitrary JVM methods (a security concern).

  • UTF-8 validation (is_valid_utf8, make_valid_utf8, validate_utf8, try_validate_utf8): niche Spark 4.x string-validation helpers.

  • Miscellaneous niche (histogram_numeric, version, sentences, quote): low-value or specialized functions with little benefit from native acceleration.

The file-metadata functions input_file_name, input_file_block_start, and input_file_block_length depend on scan-internal per-row file information rather than the expression layer; their support status is covered in the scan compatibility guide.

Note that median and mode are planned: they are mainstream exact aggregates. approx_count_distinct is supported because Comet ports Spark’s HyperLogLogPlusPlus exactly, so its result is bit-identical to Spark.

The tables below list every Spark built-in expression with its current status.

agg_funcs#

Function

Status

Notes

any

βœ…

any_value

βœ…

approx_count_distinct

βœ…

approx_percentile

βœ…

Byte, short, int, long, float, and double input; other input types fall back to Spark

array_agg

πŸ”œ

Array aggregate (related to collect_list, #2524)

avg

βœ…

Interval types fall back

bit_and

βœ…

bit_or

βœ…

bit_xor

βœ…

bool_and

βœ…

bool_or

βœ…

collect_list

πŸ”œ

#2524

collect_set

βœ…

corr

βœ…

count

βœ…

count_if

βœ…

covar_pop

βœ…

covar_samp

βœ…

every

βœ…

first

βœ…

first_value

βœ…

grouping

βœ…

Grouping indicator for ROLLUP/CUBE/GROUPING SETS

grouping_id

βœ…

Grouping indicator for ROLLUP/CUBE/GROUPING SETS

kurtosis

πŸ”œ

tracking #4098

last

βœ…

last_value

βœ…

listagg

πŸ”œ

String aggregation

max

βœ…

max_by

πŸ”œ

#3841

mean

βœ…

median

βœ…

Rewrites to percentile(col, 0.5) and runs natively for supported percentile inputs

min

βœ…

min_by

πŸ”œ

#3841

mode

πŸ”œ

#3970

percentile

βœ…

Single literal percentage on numeric input runs natively; array of percentages and a frequency argument fall back to Spark

percentile_cont

βœ…

Spark 4.0+ WITHIN GROUP (ORDER BY ...); ascending only runs natively, DESC falls back to Spark

percentile_disc

πŸ”œ

Percentile aggregate

regr_avgx

βœ…

Native: Spark rewrites to Average (tests in #4551)

regr_avgy

βœ…

Native: Spark rewrites to Average (tests in #4551)

regr_count

βœ…

Native: Spark rewrites to Count (tests in #4551)

regr_intercept

πŸ”œ

Falls back; can reuse covar_pop/var_pop accumulators (#4552)

regr_r2

πŸ”œ

Falls back; can reuse the corr accumulator (#4552)

regr_slope

πŸ”œ

Falls back; can reuse covar_pop/var_pop accumulators (#4552)

regr_sxx

πŸ”œ

Falls back; can reuse var_pop accumulator (#4552)

regr_sxy

πŸ”œ

Falls back; can reuse covar_pop accumulator (#4552)

regr_syy

πŸ”œ

Falls back; can reuse var_pop accumulator (#4552)

skewness

πŸ”œ

tracking #4098

some

βœ…

std

βœ…

stddev

βœ…

stddev_pop

βœ…

stddev_samp

βœ…

string_agg

πŸ”œ

String aggregation (alias of listagg)

sum

βœ…

try_avg

βœ…

Interval types fall back

try_sum

βœ…

var_pop

βœ…

var_samp

βœ…

variance

βœ…


array_funcs#

Function

Status

Notes

array

βœ…

array_append

βœ…

array_compact

βœ…

array_contains

βœ…

NaN/signed-zero handling may differ (details)

array_distinct

βœ…

NaN/signed-zero handling may differ (details)

array_except

βœ…

Routes through the JVM codegen dispatcher by default; the incompatible native path is opt-in via allowIncompatible (details)

array_insert

βœ…

array_intersect

βœ…

Routes through the JVM codegen dispatcher by default; the incompatible native path is opt-in via allowIncompatible (details)

array_join

βœ…

Routes through the JVM codegen dispatcher by default; the incompatible native path is opt-in via allowIncompatible (details)

array_max

βœ…

NaN ordering may differ (details)

array_min

βœ…

NaN ordering may differ (details)

array_position

βœ…

Binary/struct/map/null elements fall back

array_prepend

βœ…

array_remove

βœ…

array_repeat

βœ…

array_union

βœ…

NaN/signed-zero handling may differ (details)

arrays_overlap

βœ…

arrays_zip

βœ…

element_at

βœ…

flatten

βœ…

Binary/struct/map elements fall back

get

βœ…

sequence

βœ…

shuffle

βœ…

Binary/struct/map elements fall back

slice

βœ…

Native (#4149)

sort_array

βœ…

Nested struct/null arrays fall back


bitwise_funcs#

Function

Status

Notes

&

βœ…

<<

βœ…

>>

βœ…

>>>

βœ…

Operator alias for shiftrightunsigned (Spark 4.0+)

^

βœ…

bit_count

βœ…

bit_get

βœ…

getbit

βœ…

shiftright

βœ…

shiftrightunsigned

βœ…

|

βœ…

~

βœ…


collection_funcs#

Function

Status

Notes

array_size

βœ…

cardinality

βœ…

concat

βœ…

Binary/array children fall back

reverse

βœ…

Binary-element arrays fall back (Incompatible) (details)

size

βœ…


conditional_funcs#

Function

Status

Notes

coalesce

βœ…

if

βœ…

ifnull

βœ…

nanvl

βœ…

nullif

βœ…

nullifzero

βœ…

Lowers to if/= (Spark 4.0+)

nvl

βœ…

nvl2

βœ…

when

βœ…

zeroifnull

βœ…

Lowers to coalesce (Spark 4.0+)


conversion_funcs#

The type-name conversion functions (bigint, binary, boolean, date, decimal, double, float, int, smallint, string, timestamp, tinyint) are SQL aliases for CAST(... AS <type>) and share the support and caveats of cast.

Function

Status

Notes

cast

βœ…

Some casts fall back; float-to-decimal is opt-in (details)


csv_funcs#

Function

Status

Notes

from_csv

βœ…

schema_of_csv

βœ…

to_csv

βœ…


datetime_funcs#

Function

Status

Notes

add_months

βœ…

convert_timezone

βœ…

Routes through the JVM codegen dispatcher by default (handles all timezone forms); the native path is opt-in via allowIncompatible (details)

curdate

βœ…

Constant-folded to a literal (alias of current_date)

current_date

βœ…

Constant-folded to a literal before Comet sees the plan

current_time

πŸ”œ

Blocked on Spark 4.1 TIME type support (#4288)

current_timestamp

βœ…

Constant-folded to a literal before Comet sees the plan

current_timezone

βœ…

date_add

βœ…

date_diff

βœ…

date_format

βœ…

date_from_unix_date

βœ…

date_part

βœ…

date_sub

βœ…

date_trunc

βœ…

dateadd

βœ…

datediff

βœ…

datepart

βœ…

day

βœ…

dayname

βœ…

Abbreviated day name (Spark 4.0+)

dayofmonth

βœ…

dayofweek

βœ…

dayofyear

βœ…

extract

βœ…

from_unixtime

βœ…

from_utc_timestamp

βœ…

Routes through the JVM codegen dispatcher by default (handles all timezone forms); the native path is opt-in via allowIncompatible (details)

hour

βœ…

last_day

βœ…

localtimestamp

βœ…

make_date

βœ…

make_dt_interval

βœ…

make_interval

πŸ”œ

Produces legacy CalendarInterval; tracked by #4540

make_time

πŸ”œ

Spark 4.1 TIME type; tracked by #4288

make_timestamp

βœ…

make_timestamp_ltz

βœ…

2-arg TIME form falls back

make_timestamp_ntz

βœ…

2-arg TIME form falls back

make_ym_interval

βœ…

minute

βœ…

month

βœ…

monthname

βœ…

Abbreviated month name (Spark 4.0+)

months_between

βœ…

next_day

βœ…

now

βœ…

Constant-folded to a literal (alias of current_timestamp)

quarter

βœ…

second

βœ…

session_window

πŸ”œ

Batch session-window grouping falls back (UpdatingSessionsExec is not yet native); tracked by #4785

time_diff

πŸ”œ

Spark 4.1 TIME type; tracked by #4288

time_trunc

πŸ”œ

Spark 4.1 TIME type; tracked by #4288

timestamp_micros

βœ…

timestamp_millis

βœ…

timestamp_seconds

βœ…

to_date

βœ…

Rewrites to Cast (or Cast(GetTimestamp) with a format) before Comet sees the plan

to_time

πŸ”œ

Spark 4.1 TIME type; tracked by #4288

to_timestamp

βœ…

Rewrites to Cast (or GetTimestamp with a format) before Comet sees the plan

to_timestamp_ltz

βœ…

Rewrites to to_timestamp (TimestampType)

to_timestamp_ntz

βœ…

Rewrites to to_timestamp (TimestampNTZType)

to_unix_timestamp

βœ…

to_utc_timestamp

βœ…

Routes through the JVM codegen dispatcher by default (handles all timezone forms); the native path is opt-in via allowIncompatible (details)

trunc

βœ…

try_make_interval

πŸ”œ

Produces legacy CalendarInterval; tracked by #4540

try_make_timestamp

βœ…

try_to_date

βœ…

Rewrites to Cast/GetTimestamp before Comet sees the plan; same support as to_date

try_to_time

πŸ”œ

Spark 4.1 TIME type; tracked by #4288

try_to_timestamp

βœ…

Rewrites to Cast/GetTimestamp before Comet sees the plan; same support as to_timestamp

unix_date

βœ…

unix_micros

βœ…

unix_millis

βœ…

unix_seconds

βœ…

unix_timestamp

βœ…

weekday

βœ…

weekofyear

βœ…

window

βœ…

Batch tumbling and sliding time-window grouping runs natively

window_time

βœ…

Batch time-window grouping runs natively

year

βœ…


generator_funcs#

explode and posexplode are supported via CometExplodeExec (operator-level, not expression-level). The outer variants are wired but marked Incompatible; they require spark.comet.exec.explode.enabled=true and allowIncompatible.

Function

Status

Notes

explode

βœ…

via CometExplodeExec

explode_outer

βœ…

outer=true falls back (Incompatible) (audit)

inline

πŸ”œ

Operator-level generator (like explode)

inline_outer

πŸ”œ

Operator-level generator (like explode)

posexplode

βœ…

via CometExplodeExec

posexplode_outer

βœ…

outer=true falls back (Incompatible) (audit)

stack

πŸ”œ

Operator-level generator


hash_funcs#

Function

Status

Notes

crc32

βœ…

hash

βœ…

md5

βœ…

sha

βœ…

sha1

βœ…

sha2

βœ…

xxhash64

βœ…


json_funcs#

Function

Status

Notes

from_json

βœ…

Falls back by default; opt-in via allowIncompatible (audit)

get_json_object

βœ…

Some inputs need allowIncompatible (audit)

json_array_length

βœ…

Single-quoted/trailing JSON needs allowIncompatible (audit)

json_object_keys

βœ…

json_tuple

πŸ”œ

#3160

schema_of_json

βœ…

to_json

βœ…

Options and map/array inputs fall back (audit)


lambda_funcs#

Function

Status

Notes

aggregate

βœ…

array_sort

βœ…

exists

βœ…

filter

βœ…

General lambda routed through the JVM codegen dispatcher; the array_compact form runs natively

forall

βœ…

map_filter

βœ…

map_zip_with

βœ…

reduce

βœ…

transform

βœ…

transform_keys

βœ…

transform_values

βœ…

zip_with

βœ…


map_funcs#

Function

Status

Notes

element_at

βœ…

map

βœ…

Routed through the JVM codegen dispatcher

map_concat

βœ…

map_contains_key

βœ…

map_entries

βœ…

map_from_arrays

βœ…

map_from_entries

βœ…

BinaryType key/value falls back (Incompatible) (details)

map_keys

βœ…

map_values

βœ…

str_to_map

βœ…

try_element_at

βœ…

Lowers to element_at


math_funcs#

Function

Status

Notes

%

βœ…

*

βœ…

Interval multiplication falls back

+

βœ…

-

βœ…

/

βœ…

abs

βœ…

Interval types fall back

acos

βœ…

acosh

βœ…

asin

βœ…

asinh

βœ…

atan

βœ…

atan2

βœ…

atanh

βœ…

bin

βœ…

bround

βœ…

cbrt

βœ…

ceil

βœ…

Two-arg form falls back

ceiling

βœ…

conv

βœ…

cos

βœ…

cosh

βœ…

cot

βœ…

csc

βœ…

degrees

βœ…

div

βœ…

e

βœ…

Folds to a literal (like pi)

exp

βœ…

expm1

βœ…

factorial

βœ…

floor

βœ…

Two-arg form falls back

greatest

βœ…

hex

βœ…

hypot

βœ…

least

βœ…

ln

βœ…

log

βœ…

log10

βœ…

log1p

βœ…

log2

βœ…

mod

βœ…

negative

βœ…

pi

βœ…

pmod

βœ…

positive

βœ…

pow

βœ…

power

βœ…

radians

βœ…

rand

βœ…

randn

βœ…

random

βœ…

Alias for rand (Spark 4.0+); seed must be a literal

randstr

πŸ”œ

Random string (Spark 4.0+)

rint

βœ…

round

βœ…

Float/double inputs fall back

sec

βœ…

shiftleft

βœ…

sign

βœ…

signum

βœ…

sin

βœ…

sinh

βœ…

sqrt

βœ…

tan

βœ…

tanh

βœ…

try_add

βœ…

Datetime/interval form falls back

try_divide

βœ…

try_mod

βœ…

try_multiply

βœ…

try_subtract

βœ…

unhex

βœ…

uniform

βœ…

Constant-folded; literal arguments only (Spark 4.0+)

width_bucket

βœ…


misc_funcs#

Function

Status

Notes

aes_decrypt

βœ…

Routed through the JVM codegen dispatcher

aes_encrypt

βœ…

Routed through the JVM codegen dispatcher; nondeterministic IV by default

assert_true

πŸ”œ

Lowers to RaiseError, which falls back

current_catalog

βœ…

Resolved to a literal by the analyzer (ReplaceCurrentLike)

current_database

βœ…

Resolved to a literal by the analyzer (ReplaceCurrentLike)

current_schema

βœ…

Alias of current_database; resolved to a literal by the analyzer

current_user

βœ…

Resolved to a literal by the analyzer; same as user

equal_null

βœ…

Lowers to <=> (EqualNullSafe)

is_variant_null

πŸ”œ

tracking #4098

monotonically_increasing_id

βœ…

parse_json

πŸ”œ

tracking #4098

raise_error

πŸ”œ

Raises a runtime error

rand

βœ…

Seed must be a literal

randn

βœ…

Seed must be a literal

schema_of_variant

πŸ”œ

tracking #4098

schema_of_variant_agg

πŸ”œ

tracking #4098

session_user

βœ…

Alias of current_user; resolved to a literal by the analyzer

spark_partition_id

βœ…

to_variant_object

πŸ”œ

tracking #4098

try_aes_decrypt

βœ…

Routed through the JVM codegen dispatcher

try_parse_json

πŸ”œ

tracking #4098

try_variant_get

πŸ”œ

tracking #4098

typeof

βœ…

Foldable; resolved to a literal before Comet sees the plan

user

βœ…

Resolved to a literal by the Spark analyzer before reaching Comet

uuid

πŸ”œ

Nondeterministic random UUID

variant_get

πŸ”œ

tracking #4098


predicate_funcs#

Function

Status

Notes

!

βœ…

<

βœ…

<=

βœ…

<=>

βœ…

=

βœ…

==

βœ…

>

βœ…

>=

βœ…

and

βœ…

between

βœ…

ilike

βœ…

in

βœ…

isnan

βœ…

isnotnull

βœ…

isnull

βœ…

like

βœ…

not

βœ…

or

βœ…

regexp

βœ…

Falls back by default; opt-in via allowIncompatible (details)

regexp_like

βœ…

Falls back by default; opt-in via allowIncompatible (details)

rlike

βœ…

Falls back by default; opt-in via allowIncompatible (details)


string_funcs#

Function

Status

Notes

ascii

βœ…

base64

βœ…

bit_length

βœ…

btrim

βœ…

char

βœ…

char_length

βœ…

character_length

βœ…

chr

βœ…

collate

πŸ”œ

Spark collation (umbrella #2190)

collation

βœ…

Constant-folded to a literal (Spark 4.0+)

concat_ws

βœ…

contains

βœ…

decode

βœ…

elt

βœ…

encode

πŸ”œ

Lowers to StaticInvoke(encode) (not allowlisted); falls back

endswith

βœ…

find_in_set

βœ…

format_number

βœ…

format_string

βœ…

initcap

βœ…

instr

βœ…

lcase

βœ…

left

βœ…

len

βœ…

length

βœ…

levenshtein

βœ…

locate

βœ…

lower

βœ…

lpad

βœ…

ltrim

βœ…

luhn_check

βœ…

Native via StaticInvoke (tests: luhn_check.sql)

mask

βœ…

Routed through the JVM codegen dispatcher

octet_length

βœ…

overlay

βœ…

position

βœ…

printf

βœ…

regexp_count

βœ…

Runs natively (rewrites to size(regexp_extract_all(...)))

regexp_extract

βœ…

regexp_extract_all

βœ…

regexp_instr

βœ…

Routed through the JVM codegen dispatcher

regexp_replace

βœ…

regexp_substr

βœ…

Runs natively (rewrites to nullif(regexp_extract(...), ''))

repeat

βœ…

replace

βœ…

right

βœ…

rpad

βœ…

rtrim

βœ…

soundex

βœ…

space

βœ…

split

βœ…

split_part

βœ…

Spark 4.0+

startswith

βœ…

substr

βœ…

substring

βœ…

substring_index

βœ…

to_binary

βœ…

Hex form accelerated; other formats fall back

to_char

βœ…

to_number

βœ…

to_varchar

βœ…

translate

βœ…

Falls back by default; opt-in via allowIncompatible (#4463)

trim

βœ…

try_to_binary

βœ…

Runs natively (rewrites to try_eval(to_binary(...)))

try_to_number

βœ…

Routed through the JVM codegen dispatcher

ucase

βœ…

unbase64

βœ…

upper

βœ…


struct_funcs#

Function

Status

Notes

named_struct

βœ…

Duplicate field names fall back

struct

βœ…


url_funcs#

Function

Status

Notes

parse_url

βœ…

try_url_decode

βœ…

url_decode

βœ…

url_encode

βœ…


window_funcs#

Window functions run via CometWindowExec, which is enabled by default. Aggregate window functions (count, min, max, sum, avg, first_value, last_value), ranking functions (row_number, rank, dense_rank, percent_rank, cume_dist, ntile), and value-shift functions (lag, lead, nth_value) are all wired in the window serde and execute natively. Statistical aggregates such as stddev, var_pop, corr, and covar_pop run natively as plain aggregations but fall back to Spark when used as window functions. A handful of frame shapes also fall back. See window function compatibility for the full list of supported functions, frames, and fallback cases.

Function

Status

Notes

cume_dist

βœ…

via CometWindowExec

dense_rank

βœ…

via CometWindowExec

lag

βœ…

via CometWindowExec; non-literal default falls back (#4268)

lead

βœ…

via CometWindowExec; non-literal default falls back (#4268)

nth_value

βœ…

via CometWindowExec

ntile

βœ…

via CometWindowExec

percent_rank

βœ…

via CometWindowExec

rank

βœ…

via CometWindowExec

row_number

βœ…

via CometWindowExec


xml_funcs#

Function

Status

Notes

from_xml

βœ…

Spark 4.0+

schema_of_xml

βœ…

Spark 4.0+

to_xml

βœ…

Spark 4.0+

xpath

βœ…

xpath_boolean

βœ…

xpath_double

βœ…

xpath_float

βœ…

xpath_int

βœ…

xpath_long

βœ…

xpath_number

βœ…

Alias of xpath_double

xpath_short

βœ…

xpath_string

βœ…


Beyond SQL functions#

Comet also accelerates a number of Catalyst expressions that have no Spark SQL function name and therefore do not appear in the tables above. These arise from the DataFrame API, from SQL syntax other than function calls, or from the query optimizer. They include:

  • Operator and optimizer-injected expressions: runtime bloom-filter join probes (BloomFilterMightContain, BloomFilterAggregate), optimized IN sets (InSet), scalar subqueries (ScalarSubquery), and floating-point normalization (KnownFloatingPointNormalized).

  • Accessor expressions (subscript and field access, not functions): struct field access (col.field), array element access (arr[i]), and map value access (map[key]).

  • Internal decimal arithmetic: CheckOverflow, MakeDecimal, and UnscaledValue, which the analyzer inserts around decimal operations.

  • User-defined functions: Scala UDFs registered through the DataFrame or SQL API.

  • Structural expressions: aliases, attribute references, literals, sort orders, and CASE WHEN.

This list is illustrative, not exhaustive: the per-function tables are not the complete set of expressions Comet can accelerate.

See also#