Skip to main content

Coverage

The characterization checklist, item by item, per engine

The checklist of characterization/areas.json: for each item, the facts that settle it on each engine and the strongest evidence among them, or missing. python -m sverify_dev.facts --coverage <engine> prints the same.

Engine Items settled Facts
DuckDB 68 of 69 101
Polars 69 of 69 103
DataFusion 1 of 69 3
Spark 69 of 69 71

integers

Item Question DuckDB Polars DataFusion Spark
overflow + - ×, negate, abs, MIN / -1 and integer sum past the declared width: raise, wrap or saturate, at which width. fuzz: duckdb-R6, duckdb-decimal-arith, duckdb-R1, duckdb-R1-min, duckdb-R15-int-arith, duckdb-R15-int-divide, duckdb-R15-int-modulus, duckdb-int-pow probe: polars-sum-int, polars-decimal-arith, polars-int-abs, polars-int-arith, polars-int-divide, polars-int-mod-overflow missing fuzz: spark-sum-int, spark-decimal-arith, spark-decimal-negate, spark-int-abs, spark-int-arith, spark-int-divide, spark-int-modulus, spark-int-pow
division_type Integer modulus (and divide): truncated or floored. fuzz: duckdb-R15-double-modulus, duckdb-R15-int-divide, duckdb-R15-int-modulus, duckdb-R2, duckdb-R3, duckdb-int-div-domain probe: polars-double-modulus, polars-double-scalar-divisor, polars-int-divide, polars-int-modulus missing fuzz: spark-double-modulus, spark-int-divide, spark-int-modulus
on_division_by_zero A zero divisor of integers and of doubles: error, NULL, IEEE or a limit. fuzz: duckdb-R15-double-arith, duckdb-R4, duckdb-R5, duckdb-R15-int-divide, duckdb-R2, duckdb-R3 probe: polars-double-divide, polars-double-modulus, polars-int-divide, polars-int-modulus, polars-int-true-divide missing fuzz: spark-double-divide, spark-double-modulus, spark-int-divide, spark-int-modulus
min_mod_neg_one MIN % -1: 0 or a raise. probe: duckdb-R15-int-modulus probe: polars-int-modulus missing probe: spark-int-modulus
shift_range Shifts by a negative count or by the width or more, and bits shifted out. probe: duckdb-R15-shift-left, duckdb-R15-shift-right probe: polars-int-shift missing fuzz: spark-int-shift

decimals

Item Question DuckDB Polars DataFusion Spark
decimal_rescale A result with more digits than its scale: how it rounds. probe: duckdb-decimal-arith probe: polars-decimal-arith, polars-decimal-casts missing probe: spark-decimal-arith
decimal_result_type The precision and scale of decimal arithmetic and aggregates, and overflow past 38 digits. probe: duckdb-decimal-arith probe: polars-decimal-arith missing probe: spark-decimal-arith

doubles

Item Question DuckDB Polars DataFusion Spark
rounding Rounding of arithmetic and of round (to d digits too). probe: duckdb-avg-double, duckdb-float-sum-order, duckdb-stat-arg-types, duckdb-sum-double, duckdb-R15-elementary, duckdb-R15-round, duckdb-float-ieee, duckdb-float-math-double, duckdb-round-digits-2, duckdb-ulp-arith, duckdb-ulp-libm, duckdb-ulp-round, duckdb-window-sum-order probe: polars-mean-float-streaming, polars-sum-float-streaming, polars-var-std-streaming, polars-double-scalar-divisor, polars-elem-rounding, polars-fp-ieee, polars-log-base, polars-round, polars-round-digits, polars-scalar-divisor, polars-ulp-arith, polars-ulp-libm, polars-ulp-round missing fuzz: spark-sum-double, spark-var-stddev, spark-double-arith, spark-double-divide, spark-elem-rounding, spark-round
on_domain_error sqrt, logs, asin, acos, atan2, power outside their domain: NaN, NULL or a raise. fuzz: duckdb-R15-atan2, duckdb-R15-double-arith, duckdb-R15-math-domain, duckdb-float-math-double, duckdb-int-div-domain, duckdb-int-pow probe: polars-atan2, polars-double-divide, polars-math-domain, polars-int-div-domain, polars-int-pow-exponent missing fuzz: spark-double-divide, spark-math-domain, spark-int-divide, spark-int-pow
on_log_zero A logarithm of zero: -inf, NaN or a raise. probe: duckdb-R15-math-domain, duckdb-float-math-double probe: polars-math-domain missing fuzz: spark-math-domain
nan_creation inf - inf, 0 · inf, inf / inf, fmod(inf, y), a sum of both infinities: NaN or a raise. fuzz: duckdb-float-sum-order, duckdb-nonfinite-aggregates, duckdb-R15-double-arith, duckdb-R15-double-modulus, duckdb-R4 probe: polars-nonfinite-aggregates, polars-double-arith, polars-double-divide, polars-double-modulus, polars-double-scalar-divisor, polars-scalar-divisor missing fuzz: spark-nonfinite-aggregates, spark-double-arith, spark-double-divide, spark-double-modulus
float_overflow A finite double operation whose result overflows: ±∞, or a raise (#575). probe: duckdb-double-overflow probe: polars-nonfinite-aggregates, polars-double-arith, polars-double-divide missing fuzz: spark-nonfinite-aggregates, spark-double-arith, spark-double-divide
nan_equality Is NaN equal to NaN in =, grouping, DISTINCT and joins. probe: duckdb-nan-equality probe: polars-nan-equality missing probe: spark-nan-equality
nan_order Where NaN sorts, and how MIN, MAX, <, greatest treat it. fuzz: duckdb-arg-min-nulls, duckdb-quantile-disc, duckdb-nan-order probe: polars-min-max-nan, polars-nan-order missing probe: spark-nan-order
nan_kind Does a NaN’s sign (or payload) survive and show. probe: duckdb-float-signs, duckdb-signbit probe: polars-nan-sign missing fuzz: spark-nan-sign
zero_sign -0.0 in arithmetic, comparison, sorting and grouping. probe: duckdb-minmax-zero-sign, duckdb-R14, duckdb-float-signs, duckdb-signbit probe: polars-min-max-zero, polars-double-modulus, polars-zero-add, polars-zero-order, polars-zero-sign-streaming missing fuzz: spark-double-modulus, spark-zero-order, spark-zero-sign
fp32 Single-precision arithmetic and its conversions. probe: duckdb-ulp-casts, duckdb-R12, duckdb-ulp-arith, duckdb-ulp-libm, duckdb-ulp-round probe: polars-cast-to-double, polars-ulp-casts, polars-fp32, polars-ulp-arith, polars-ulp-libm, polars-ulp-round missing fuzz: spark-fp32

strings

Item Question DuckDB Polars DataFusion Spark
char_set upper, lower: Unicode or ASCII mappings. probe: duckdb-case-mapping probe: polars-case, polars-length, polars-reverse missing probe: spark-case, spark-string-plain
case_sensitivity like, contains, starts_with, strpos, regexes: case-sensitive or not. probe: duckdb-F4, duckdb-string-match-case probe: polars-match-functions, polars-regex missing fuzz: spark-match-functions, spark-regex
substring_range substring offsets and lengths outside 32 bits. probe: duckdb-substring-range probe: polars-substring-range missing fuzz: spark-substring-range
negative_start substring with a negative or zero start; its indexing (characters or bytes, 0- or 1-based). engine_test: duckdb-R13 probe: polars-strpos, polars-substring missing fuzz: spark-strpos, spark-substring
string_positions What substring and strpos positions count: characters or bytes, from 0 or 1; strpos without a match. probe: duckdb-R13, duckdb-string-match-case probe: polars-strpos, polars-substring missing fuzz: spark-strpos, spark-substring
regex_dialect The regex engine and syntax, classes on non-ASCII text, a match that fails, replacement references. probe: duckdb-R15-regexp probe: polars-regex missing fuzz: spark-regex
digests md5, sha256 and other digests: present, and on which bytes. probe: duckdb-R15-digests probe: polars-string-functions-missing missing probe: spark-digests

temporal

Item Question DuckDB Polars DataFusion Spark
date_range Date and timestamp arithmetic past 0001-01-01 … 9999-12-31. probe: duckdb-date-range probe: polars-date-range, polars-month-arith missing fuzz: spark-date-range
time_interval_months TIME ± INTERVAL with months, and time arithmetic past midnight. probe: duckdb-time-plus-interval probe: polars-temporal-errors missing probe: spark-time-type
timestamp_precision The timestamp unit (s, ms, µs, ns) and its range. engine_test: duckdb-R10 probe: polars-timestamp-unit missing probe: spark-timestamp-precision
time_zones Time zones: DST gaps and overlaps, conversions. probe: duckdb-time-zones probe: polars-temporal-errors missing probe: spark-time-zones
week_numbering Week numbers, weekdays, ISO years, date_trunc to a week, parts before 1970. probe: duckdb-yearweek probe: polars-date-parts missing probe: spark-week-parts

casts

Item Question DuckDB Polars DataFusion Spark
float_to_int A double or decimal cast to an integer: truncate or round. probe: duckdb-R9 probe: polars-cast-double-to-int, polars-decimal-casts missing probe: spark-cast-double-to-int
cast_failure A cast that does not fit or parse: raise or NULL. engine_test: duckdb-R8 probe: polars-cast-double-to-int, polars-cast-int, polars-cast-string, polars-decimal-casts missing fuzz: spark-cast-double-to-int, spark-cast-string
cast_parsing Text to numbers, booleans and dates: what is accepted (spaces, signs, nan, inf, exponents). engine_test: duckdb-R10 probe: polars-cast-string, polars-temporal-errors missing fuzz: spark-cast-string
cast_formatting Numbers, booleans and dates to text: the format. probe: duckdb-printf probe: polars-cast-string, polars-strftime missing fuzz: spark-cast-string

nulls

Item Question DuckDB Polars DataFusion Spark
null_handling concat and other functions given a NULL: NULL or skip. probe: duckdb-null-concat probe: polars-concat missing probe: spark-concat
three_valued_logic and, or, not with NULLs; bool_and, bool_or over NULLs. probe: duckdb-kleene probe: polars-kleene missing probe: spark-kleene
null_join_keys Do NULL keys match in joins, and how IS NOT DISTINCT FROM is spelled. probe: duckdb-null-keys, duckdb-set-operations probe: polars-null-keys, polars-set-operations missing probe: spark-null-keys, spark-set-operations

nested

Item Question DuckDB Polars DataFusion Spark
list_null_order A NULL element deciding < of lists, in comparisons and in ORDER BY. engine_test: duckdb-R11 probe: polars-list-order missing fuzz: spark-list-order
list_indexing List indexing: base, negative and out-of-range indexes. probe: duckdb-list-index probe: polars-list-index missing fuzz: spark-list-index
struct_equality Equality and order of structs with NULL fields. probe: duckdb-struct-equality probe: polars-nested-equality missing probe: spark-nested-equality
unnest_null_empty UNNEST of a NULL list and of an empty one. probe: duckdb-unnest probe: polars-explode missing probe: spark-explode

aggregates

Item Question DuckDB Polars DataFusion Spark
avg_int_result avg of integers: its type and how it is computed. probe: duckdb-R6, duckdb-avg-int probe: polars-avg-int missing fuzz: spark-avg-int
sum_order The order and grouping of a double SUM, AVG. probe: duckdb-R7, duckdb-avg-double, duckdb-float-sum-order, duckdb-kahan-sum, duckdb-sum-double, duckdb-window-sum-order probe: polars-mean-float-streaming, polars-sum-float-streaming missing fuzz: spark-avg-double, spark-sum-double
stat_algo The algorithm of VAR_*, STDDEV_*, COVAR_*, CORR. probe: duckdb-corr, duckdb-covar, duckdb-stat-arg-types, duckdb-var-stddev probe: polars-corr, polars-cov, polars-var-std-streaming missing fuzz: spark-corr, spark-covar, spark-var-stddev
stat_degenerate CORR of one pair or a constant side; a statistical aggregate of a single value. probe: duckdb-corr, duckdb-nonfinite-aggregates, duckdb-stat-arg-types probe: polars-corr, polars-var-std-streaming missing fuzz: spark-corr, spark-nonfinite-aggregates, spark-var-stddev
quantile_interp QUANTILE_CONT, QUANTILE_DISC, MEDIAN: the position and interpolation. probe: duckdb-quantile-cont-interpolation, duckdb-quantile-disc probe: polars-quantile missing fuzz: spark-quantile
tie_pick Which row FIRST, LAST, ARG_MIN, ARG_MAX, any_value, MODE take among ties. probe: duckdb-arg-min-nulls, duckdb-mode-ties probe: polars-arg-min-max, polars-first-last, polars-mode missing probe: spark-first-last
empty_group_aggregates Aggregates of no rows or of NULLs only (SUM, COUNT, MIN, AVG). probe: duckdb-avg-int, duckdb-statistical-aggregates, duckdb-sum-double, duckdb-list-sum probe: polars-avg-int, polars-count-empty, polars-mean-float-streaming, polars-sum-float-streaming, polars-sum-int missing fuzz: spark-avg-int, spark-sum-double, spark-sum-int
nonfinite_aggregates Aggregates of ±inf and NaN inputs. probe: duckdb-R7, duckdb-kahan-sum, duckdb-moments, duckdb-nonfinite-aggregates probe: polars-nonfinite-aggregates missing fuzz: spark-nonfinite-aggregates

windows

Item Question DuckDB Polars DataFusion Spark
ntile_spread How NTILE spreads the remainder. probe: duckdb-ntile probe: polars-rank missing probe: spark-rank
default_window_frame The frame when none is given, with and without an order; rank functions over ties and NULLs. probe: duckdb-window-frame probe: polars-rank, polars-window-values missing probe: spark-rank, spark-window-values

relations

Item Question DuckDB Polars DataFusion Spark
tie_order The order of ties in a sort, STRING_AGG, collect, a window: stable or not. probe: duckdb-mode-ties, duckdb-sort-ties probe: polars-first-last, polars-sort-stability-streaming, polars-rank, polars-window-values missing probe: spark-first-last, spark-sort-stability, spark-rank, spark-window-values
null_order Where NULLs sort by default, ascending and descending. probe: duckdb-F2, duckdb-window-frame probe: polars-null-order missing probe: spark-null-order
clustered A sort that only clusters equal keys. probe: duckdb-clustered probe: polars-clustered missing probe: spark-clustered
set_operations UNION, INTERSECT, EXCEPT, with and without ALL: duplicates, NULLs, order. probe: duckdb-set-operations probe: polars-set-operations missing probe: spark-set-operations
nan_zero_grouping Grouping, DISTINCT and join keys with NaN and -0.0: one group, and which value represents it. probe: duckdb-R14, duckdb-nan-equality probe: polars-nan-equality, polars-zero-order missing fuzz: spark-nan-equality, spark-zero-order

errors

Item Question DuckDB Polars DataFusion Spark
raise_set Where the engine raises beyond the reference (D2): extra raises, and raises that are planning errors or panics. probe: duckdb-moments, duckdb-decimal-arith, duckdb-R15-int-modulus, duckdb-R15-shift-left, duckdb-list-vectors, duckdb-printf, duckdb-date-range, duckdb-ntile probe: polars-decimal-arith, polars-list-index, polars-date-range missing fuzz: spark-decimal-negate, spark-raise-set, spark-list-index, spark-regex, spark-substring-range, spark-date-range

execution

Item Question DuckDB Polars DataFusion Spark
evaluation_order Short-circuit in CASE, AND, OR, COALESCE: does the engine evaluate an expression on rows a filter or a branch removes, and raise there (division by zero, a failing cast)? This can break the reference’s no-error guarantee. fuzz: duckdb-exec-filter-pushdown, duckdb-exec-short-circuit probe: polars-exec-cse-hoist, polars-exec-predicate-pushdown, polars-exec-when-eager missing probe: spark-exec-evaluation-order
settings Which session settings change results: DuckDB’s default_null_order, integer_division, threads, …; Polars’s Config and environment variables. probe: duckdb-exec-settings engine_test: polars-exec-engine missing fuzz: spark-exec-parser-cache, spark-exec-settings, spark-list-index, spark-case, spark-time-zones
parallel_nondeterminism Results that change with the thread count or from run to run: the order of a double SUM, row order without ORDER BY, ties. probe: duckdb-exec-row-order probe: polars-exec-row-order missing fuzz: spark-first-last, spark-sum-double, spark-sum-int, spark-exec-parallel, spark-sort-stability, spark-window-values
platform Results that depend on the platform: libm (sin, pow, exp), NaN signs, SIMD paths; probes ran on macOS arm64, CI on Linux x86_64. probe: duckdb-exec-platform probe: polars-exec-platform missing fuzz: spark-elem-rounding, spark-nan-sign, spark-exec-platform
size_limits Limits on string, blob and list lengths, decimal precision, nesting depth, and what happens past them. engine_test: duckdb-exec-size-limits engine_test: polars-exec-size-limits missing fuzz: spark-exec-parser-cache, spark-exec-size-limits
streaming_fallback Operations a streaming engine cannot run itself and hands to its in-memory engine (Polars’s streaming engine, which sverify targets): which, and whether results differ. missing engine_test: polars-exec-streaming-fallback missing source: spark-exec-streaming-fallback
try_variants TRY_CAST, TRY(…) and other non-raising forms: which errors become NULL and which still raise. engine_test: duckdb-exec-try engine_test: polars-exec-strict-false missing fuzz: spark-try-variants

frontend

Item Question DuckDB Polars DataFusion Spark
type_names The engine’s names of the types. probe: duckdb-typeof-names, duckdb-F4 probe: polars-type-names missing probe: spark-type-names
implicit_casts Implicit casts and type promotion in arithmetic and comparisons. engine_test: duckdb-F1 probe: polars-fp32, polars-int-float-compare, polars-implicit-casts, polars-int-true-divide missing fuzz: spark-fp32, spark-implicit-casts
literal_types The types of literals. engine_test: duckdb-F3 probe: polars-literal-types engine_test: datafusion-S4 probe: spark-literal-types

io

Item Question DuckDB Polars DataFusion Spark
io_formats File formats read and written, and their type mappings. probe: duckdb-IO3 probe: polars-io missing engine_test: spark-io
object_stores Object stores and their credentials. probe: duckdb-IO1, duckdb-IO2, duckdb-IO3 probe: polars-io missing engine_test: spark-io
catalogs Catalogs (Unity, Iceberg, …) and how the engine attaches them. probe: duckdb-IO1, duckdb-IO2 probe: polars-io missing engine_test: spark-io