Skip to main content

Ledgers

What sverify knows about each engine, and what it found upstream

Sverify keeps two ledgers, both JSON documents in the repository with their provenance. The site renders them at build time, so the site’s search finds an entry by its id, engine, function, option or text, and the table below filters them.

All entries

IdKindProjectStatusOptionsSummary
DD-1bugDuckDBfiledlevenshtein counts bytes, not code points, on non-ASCII text, and reverse works on grapheme clusters.
DD-2bugDuckDBnot a bugerror() with a message built by concat shows a NULL argument as an empty string.
DD-3bugDuckDBfiledVAR_POP and STDDEV_POP of a single NaN are 0.0, not NaN; with a second value they are NaN.
DD-4bugDuckDBfiledread_parquet trusts a file's min/max statistics for doubles, which Parquet writers compute without NaN.
DD-5bugDuckDBfiledDuckDB exports HUGEINT and UHUGEINT to Arrow as decimal128(38, 0) without a range check.
DD-6bugDuckDBconfirmedleast and greatest on FLOAT return a value that is none of their arguments when the winner is -0.0 or a negative NaN: they compare sort keys and decode the …
DD-7bugDuckDBconfirmedA CASE whose later WHEN is a constant expression that raises fails while planning, even when no row reaches that WHEN: on a table where every row takes the …
DD-8bugDuckDBconfirmedThe documentation, not the engine: the numeric functions page (https://duckdb.org/docs/2.0/sql/functions/numeric.html, "Division and Modulo Operators") says …
DD-9bugDuckDBconfirmedThe documentation, not the engine: the numeric functions page (https://duckdb.org/docs/2.0/sql/functions/numeric.html, the operator table and the pow/power …
DF-1bugDataFusionfiledEXCEPT ALL is planned as a left anti join, which loses multiplicities.
DF-2bugDataFusionfixed upstreamFETCH FIRST n ROWS ONLY is dropped: the plan has no limit.
DF-3bugDataFusionfiledThe Substrait producer drops DISTINCT and FILTER (WHERE …) of a window aggregate: COUNT(DISTINCT s) OVER (…) counts every row.
DF-4bugDataFusionfiledGROUP BY k, k writes two grouping expressions, and the projection above reads the aggregate's columns shifted by one.
DF-5bugDataFusionnot a bugSELECT * of a NATURAL JOIN keeps both copies of the join columns.
DF-6bugDataFusionfixed upstreamThe Substrait producer writes FROM (VALUES …) as an empty virtual table: the rows are dropped.
DF-7bugDataFusionnot a bugSQL decimal literals beyond double precision are read as doubles: 100000000000000000000 > 99999999999999999999.99999 is false.
DF-8bugDataFusionfiledThe Substrait producer encodes grouping sets against the spec: the extra column is a bitmask where the spec says the grouping set's index, and the grouping …
DF-9bugDataFusionfiledThe Substrait producer registers no proper extension URNs (placeholder references).
DF-10bugDataFusionfiledThe Substrait consumer doesn't know Substrait's shift_left/shift_right.
DF-11bugDataFusionfixed upstreamNTILE(k) computes ⌊i · min(k, n) / n⌋ + 1, which spreads the larger buckets out; the SQL standard (and DuckDB, Spark, Snowflake, PostgreSQL) puts the n % k …
DL-1bugdelta-rsfiledDeltaTable.history() and DeltaTable.alter.set_table_properties() keep the GIL during object store requests.
DL-2bugdelta-rsconfirmedDeltaTable.history() on a table loaded at an older version (load_as_version) lists the latest commits, numbered as if the loaded version were the latest: …
IB-1bugIbisconfirmedIbis reads the deprecated pd.options.future.infer_string in PandasType.from_ibis (ibis/formats/pandas.py:60), so every execute() warns Pandas4Warning: The …
IB-2bugIbisconfirmedIbis's DuckDB SQL for TimeTruncate is DATE_TRUNC('HOUR', t) of a TIME, which DuckDB has no overload for, so t.time().truncate("h") fails to bind on DuckDB.
IB-3bugIbisconfirmedIbis's DuckDB SQL for argmin/argmax is FIRST(x ORDER BY key).
IB-4bugIbisconfirmedibis.window(preceding=10, following=-1) compiles to ROWS BETWEEN 10 preceding AND -1 following.
PL-1bugPolarsconfirmed% on floats computes x - y * floor(x / y), so a finite x % inf is NaN (inf * 0), where Python's %, which Polars's % follows on integers, gives x for positive …
PL-2bugPolarsconfirmedA Date is an Int32 of days, but chrono's NaiveDate covers only about ±262 000 years.
PL-3bugPolarsfiledWhen one side of a float /, // or % has length 1 and the other more (a literal divisor on a frame of two rows or more), Polars computes the reciprocal of the …
PL-4bugPolarsconfirmedExpr.log() on Float32 computes f32::log(x, base) with the default base math.e cast to Float32, that is ln(x) / ln(2.7182817), and ln(2.7182817) is 0.99999994 …
PL-5bugPolarsconfirmedpl.cov and pl.corr of Decimal columns raise InvalidOperationError on the streaming engine and succeed on the in-memory engine.
PL-6bugPolarsconfirmedCommon-subexpression elimination hoists a fallible expression that two when/then branches share (a strict cast) into a WITH_COLUMNS evaluated on every row, …
PL-7bugPolarsconfirmedPredicate pushdown merges a later filter into an earlier one unless the later predicate is fallible, and the fallible list (is_fallible_top_level, …
PL-8bugPolarsconfirmedThe documentation says float division follows IEEE 754, and division by a literal or one-row divisor does not.
PL-9bugPolarsconfirmedThe documentation of Expr.round (https://docs.pola.rs/api/python/stable/reference/expressions/api/polars.Expr.round.html, …
PL-10bugPolarsconfirmedThe documentation of Expr.nan_min and Series.nan_min (https://docs.pola.rs/api/python/stable/reference/expressions/api/polars.Expr.nan_min.html, …
PL-11bugPolarsconfirmedThe documentation of Expr.quantile (https://docs.pola.rs/api/python/stable/reference/expressions/api/polars.Expr.quantile.html, …
PL-12bugPolarsconfirmedThe documentation of list.get (https://docs.pola.rs/api/python/stable/reference/expressions/api/polars.Expr.list.get.html, …
PL-13bugPolarsconfirmedThe documentation of pl.when (https://docs.pola.rs/api/python/stable/reference/expressions/api/polars.when.html, …
SG-1bugSQLGlotfiledqualify resolves a name in WHERE/GROUP BY/HAVING that is both an input column and an output alias as the **alias**; DuckDB resolves it as the **column**.
SG-2bugSQLGlotnot a bugTranspiling between dialects keeps the text of an operator whose meaning differs: transpile("select 7/2", read="postgres", write="duckdb") gives SELECT 7 / 2 …
SG-3bugSQLGlotfiledDuckDB → DataFusion transpiling rewrites some functions with another meaning: strftime, top-n min(x, n), POSITIONAL/ASOF joins, TRY.
SG-4bugSQLGlotfiledThe tokenizer reads every underscore in a number as a digit separator.
SG-5bugSQLGlotfiledqualify expands t.* of the right table of a JOIN … USING without the USING columns; DuckDB keeps them in t.* (only * shows them once).
SG-6bugSQLGlotfiledDuckDB's TABLE t (SELECT * FROM t) does not parse: as a set operation's operand it fails, and on its own it parses as an alias.
SG-7bugSQLGlotfiledFrom 30.18, Drop reads its names from expressions, and one given as this is not written.
SG-8bugSQLGlotconfirmedIn the DuckDB dialect, an interval string of one unit followed by ago loses the ago: INTERVAL '1 day ago' reads as INTERVAL '1' DAY, a positive interval, …
SP-1bugSparkfiled-x of a DECIMAL with more than 34 significant digits rounds it to 34 digits, half to even, silently: -CAST('12345678901234567890123456789012345678' AS …
SP-2bugSparkfileddate_add(d, n) adds the days as Ints with no overflow check (DateAdd.nullSafeEval: start + d), so a result past 2³¹ - 1 days wraps to a valid but wrong date: …
SP-3bugSparkconfirmedAdding an interval to a timestamp near the end of the microsecond range raises a bare java.lang.ArithmeticException: long overflow with no error class or …
SP-4bugSparkconfirmedAn invalid constant regex ('a' RLIKE '(') raises INVALID_PARAMETER_VALUE.PATTERN on the interpreted path and a bare java.util.regex.PatternSyntaxException: …
SP-5bugSparkconfirmedfloor and ceil of a double return BIGINT.
SP-6bugSparkconfirmedto_timestamp of a year past the microsecond range raises a bare java.lang.ArithmeticException: long overflow with no error class or SQLSTATE, in both ANSI …
SP-7bugSparkconfirmedTIMESTAMP_SECONDS of a decimal with more than six fractional digits raises a bare java.lang.ArithmeticException: Rounding necessary with no error class or …
ST-1spec gapSubstraitconfirmedshift_left and shift_right (functions_arithmetic.yaml) do not say what a shift count below 0 or at least the base's width gives, nor whether shift_left may …
ST-2spec gapSubstraitconfirmedatan2 takes on_domain_error: [NAN, ERROR], but the YAML does not say what its domain is, so whether atan2(0, 0) is a domain error is open.
ST-3spec gapSubstraitconfirmedcorr says what no input gives (null); variance and std_dev say nothing about it, though they return nullable types.
ST-4spec gapSubstraitconfirmedfp32 and fp64 have IEEE 754's range and precision (type_classes.md), and equal is x == y, but nothing says how NaN and -0.0 compare, group, sort or deduplicate.
ST-5spec gapSubstraitconfirmedadd, subtract and multiply on fp32/fp64 have only rounding.
ST-6spec gapSubstraitconfirmedThe cast expression (specialized_record_expressions.md, Cast in algebra.proto) does not say how a cast from fp32/fp64 or a decimal to an integer rounds, and …
ST-7spec gapSubstraitconfirmedA sort field's direction is required (relations/basics.md), and the directions it lists are the four of NULL placement, a custom function and clustered.
ST-8spec gapSubstraitconfirmedfunctions_arithmetic_decimal.yaml gives each function's result type, and nothing about how a result with more digits than the result's scale is rounded: …
ST-9spec gapSubstraitconfirmedThe fp32 and fp64 implementations of add, subtract, multiply, divide, power, exp and the other elementary functions have no option for a result too large for …
ST-10spec gapSubstraitconfirmedupper and lower with char_set: UTF8 say the implementation "should follow the utf8_unicode_ci collations" of the Unicode Collation Algorithm (UTR #10), which …
ST-11spec gapSubstraitconfirmedpower of i64 (functions_arithmetic.yaml) returns i64 and takes only overflow.
ST-12spec gapSubstraitconfirmedIfThen and Switch short-circuit and coalesce stops at the first non-null argument, so the spec makes those lazy.
ST-13bugSubstraitconfirmedThirteen function test cases expect values their own inputs do not give.
ST-14bugSubstraitconfirmedlogb's YAML defines logb(x, b) => log_{b} (x): the value first, the base second.
ST-15bugSubstraitconfirmedForty-five test cases state an option their function's YAML does not have, or a value the option does not list.
ST-16spec gapSubstraitunverifiedon_log_zero lists NAN, ERROR and MINUS_INFINITY.
datafusion-S4fact (decimals)DataFusion 51.0.0no-finding, engine_testliteral_typesDecimal literals become doubles: frontend
datafusion-S3fact (relations)DataFusion 51.0.0no-finding, engine_testThe Substrait producer drops VALUES rows: refused by the replay
datafusion-S6fact (relations)DataFusion 51.0.0open, engine_testThe SQL frontend plans another query: frontend
duckdb-R6fact (aggregates)DuckDB 2.0.0deviation, probeoverflow avg_int_result agg.isumInteger sum: deviation: unbounded, and reported as a warning
duckdb-R7fact (aggregates)DuckDB 2.0.0fixed, probenonfinite_aggregates sum_order agg.fsumsum/avg of a double constant: fixed (#205)
duckdb-arg-min-nullsfact (aggregates)DuckDB 2.0.0no-finding, probetie_pick nan_order agg.pickARG_MIN/ARG_MAX: rows with a NULL on either side are skipped: FIRST(x ORDER BY y) over the rows where neither is NULL; ties are the engine's
duckdb-avg-doublefact (aggregates)DuckDB 2.0.0open, probesum_order rounding agg.fsumAVG of doubles: plain sum by the count: plain sum / n
duckdb-avg-intfact (aggregates)DuckDB 2.0.0open, probeavg_int_result empty_group_aggregates agg.isumAVG of integers: a DOUBLE from the exact sum: DOUBLE; exact integer sum, one division (in long double for INTEGER and BIGINT)
duckdb-corrfact (aggregates)DuckDB 2.0.0decided, probestat_algo stat_degenerate agg.statCORR: three separate states; NaN for one pair or zero variance: cov / (std_x · std_y); NaN where the reference is NULL; no clamp
duckdb-covarfact (aggregates)DuckDB 2.0.0open, engine_teststat_algo agg.statCOVAR_* of doubles: Welford co-moment, Chan merge: Welford co-moment; Chan merge
duckdb-float-sum-orderfact (aggregates)DuckDB 2.0.0open, probesum_order nan_creation rounding agg.fsumSUM and AVG of floats depend on the order of the rows; IEEE special values: order-dependent plain sum; fsum/favg Kahan; NaN from +inf and -inf
duckdb-kahan-sumfact (aggregates)DuckDB 2.0.0open, engine_testsum_order nonfinite_aggregateskahan_sum, fsum, sumkahan, favg: classic Kahan: classic Kahan (not Neumaier); NaN with an infinite input
duckdb-minmax-zero-signfact (aggregates)DuckDB 2.0.0shimmed, probezero_sign agg.orderMIN and MAX of floats: -0.0 and 0.0 tie, and the last one read wins: the zeros compare equal; the sign of the result depends on the order of the rows
duckdb-mode-tiesfact (aggregates)DuckDB 2.0.0decided, probetie_pick tie_order agg.pickMODE: ties go to the value seen first, in the order DuckDB reads the rows: ties are the engine's without ORDER BY; with one, the first in that order
duckdb-momentsfact (aggregates)DuckDB 2.0.0decided, proberaise_set nonfinite_aggregateskurtosis and skewness raise where a moment is out of range: decided: black-box aggregates that may raise
duckdb-nonfinite-aggregatesfact (aggregates)DuckDB 2.0.0open, probenonfinite_aggregates nan_creation stat_degenerate agg.stat agg.var±inf in variance, correlation and Kahan sums: NaN, no error (since 2.0)
duckdb-quantile-cont-interpolationfact (aggregates)DuckDB 2.0.0shimmed, probequantile_interp agg.quantQUANTILE_CONT: lo·(1−d) + hi·d in doubles, NaN between -inf and +inf: between the neighbours up to rounding; NaN between -inf and +inf; the written SQL clamps
duckdb-quantile-discfact (aggregates)DuckDB 2.0.0no-finding, probequantile_interp nan_order agg.orderQUANTILE_DISC: the value at position ⌈n·q⌉, exact for a decimal fraction: the reference's rule; a DOUBLE fraction rounds; negative fractions count from the top
duckdb-stat-arg-typesfact (aggregates)DuckDB 2.0.0open, proberounding stat_algo stat_degenerate agg.stat agg.varStatistical aggregates of integers and decimals: cast to DOUBLE first: one DOUBLE overload each; BIGINT and DECIMAL arguments are cast, then the doubles' …
duckdb-statistical-aggregatesfact (aggregates)DuckDB 2.0.0decided, probeempty_group_aggregatesproduct, mad, histogram, weighted_avg and bit_count: types and edge cases: decided: product and mad are black boxes; histogram and weighted_avg are refused; …
duckdb-sum-doublefact (aggregates)DuckDB 2.0.0open, probesum_order rounding empty_group_aggregates agg.fsum agg.isumSUM of doubles: plain sequential: plain recursive summation
duckdb-var-distributionfact (aggregates)DuckDB 2.0.0no-finding, probeagg.varvariance and stddev are the sample's: variance is var_samp, stddev is stddev_samp
duckdb-var-stddevfact (aggregates)DuckDB 2.0.0open, engine_teststat_algo agg.varVAR_* and STDDEV_* of doubles: Welford, Chan merge: Welford; Chan merge with fma; no clamp
duckdb-R8fact (casts)DuckDB 2.0.0no-finding, engine_testcast_failureA cast to a narrower integer that does not fit: no finding (verify: cast out of range error)
duckdb-R9fact (casts)DuckDB 2.0.0decided, probefloat_to_intCasts of doubles and decimals to integers: half to even and half away from zero: decided: truncate; DuckDB shim
duckdb-typeof-namesfact (casts)DuckDB 2.0.0decided, probetype_namestypeof: DuckDB's names of the types: decided: fold typeof of a column to DuckDB's name
duckdb-ulp-castsfact (casts)DuckDB 2.0.0open, probefp32Integer and decimal to DOUBLE and FLOAT: correctly rounded but from HUGEINT: BIGINT and DECIMAL ≤ 0.5 ulp; HUGEINT and DECIMAL(38, 0) < 1 ulp (0.625 seen)
duckdb-decimal-arithfact (decimals)DuckDB 2.0.0shimmed, probedecimal_result_type decimal_rescale raise_set overflow dec.arithDecimal result types: its own, capped at 18 digits while the operands fit 64 bits; rescaling rounds half away from zero: decimal_rescale: TIE_AWAY_FROM_ZERO …
duckdb-R12fact (doubles)DuckDB 2.0.0fixed, engine_testfp32fp32: fixed (#208): fp32 arithmetic refused until modelled
duckdb-R14fact (doubles)DuckDB 2.0.0decided, probezero_sign nan_zero_grouping fp.div-0.0 and 0.0: decided: one zero; DuckDB shim
duckdb-R15-atan2fact (doubles)DuckDB 2.0.0shimmed, probeon_domain_error fp.elematan2(0, 0): no option matches: 0, where the reference raises
duckdb-R15-double-arithfact (doubles)DuckDB 2.0.0shimmed, fuzznan_creation on_division_by_zero on_domain_error fp.arith fp.divDOUBLE + - * /: no option matches: NaN from ±inf; / by zero is IEEE
duckdb-R15-double-modulusfact (doubles)DuckDB 2.0.0shimmed, fuzznan_creation division_type fp.modDOUBLE % DOUBLE: no option matches: NaN for a zero divisor or an infinite dividend
duckdb-R15-elementaryfact (doubles)DuckDB 2.0.0no-finding, proberounding fp.elemabs, floor, ceil, exp, atan: the reference
duckdb-R15-math-domainfact (doubles)DuckDB 2.0.0shimmed, probeon_domain_error on_log_zero fp.elem fp.logpower, sqrt, ln, log10, log2, asin, acos, sin, cos, tan: no option matches: NaN outside the domain, -inf for a logarithm of 0
duckdb-R15-power-neginffact (doubles)DuckDB 2.0.0shimmed, probepower(-inf, y) for a finite non-integer y: IEEE's +inf or 0: IEEE value where the reference raises
duckdb-R15-roundfact (doubles)DuckDB 2.0.0no-finding, proberounding fp.roundround(DOUBLE): matches rounding: TIE_AWAY_FROM_ZERO
duckdb-R15-round-digitsfact (doubles)DuckDB 2.0.0no-finding, proberounding fp.roundround(DOUBLE, d) for d from -1000 to 400: the reference (DuckDB's formula since #335)
duckdb-R4fact (doubles)DuckDB 2.0.0fixed, fuzzon_division_by_zero nan_creation fp.modmodulus on doubles: fixed (#203): C's fmod (no such Substrait function)
duckdb-R5fact (doubles)DuckDB 2.0.0fixed, fuzzon_division_by_zero fp.divDouble division by zero: fixed (#204): an error unless the plan asks for IEEE, LIMIT or NULL
duckdb-double-overflowfact (doubles)DuckDB 2.0.0shimmed, probefloat_overflow agg.fsum fp.arith fp.divDouble operations that overflow give ±inf: IEEE: ±inf where the reference raises
duckdb-float-ieeefact (doubles)DuckDB 2.0.0no-finding, engine_testrounding fp.arith fp.divFLOAT and DOUBLE are IEEE 754 binary32 and binary64: rounding: TIE_TO_EVEN for + - * /: plain C++ float and double operations
duckdb-float-math-doublefact (doubles)DuckDB 2.0.0open, engine_testrounding on_domain_error on_log_zero fp.elem fp.log fp.roundMath functions compute in DOUBLE, also for FLOAT: fp32 inputs widen to DOUBLE and the result is DOUBLE; round(FLOAT) stays FLOAT
duckdb-float-signsfact (doubles)DuckDB 2.0.0shimmed, probezero_sign nan_kind cmp fp.arith fp.div fp.mod fp.negSigns of zero and NaN through FLOAT and DOUBLE operations: IEEE in arithmetic; one zero in comparisons, hashing and sort keys; FLOAT least/greatest canonicalise
duckdb-nan-equalityfact (doubles)DuckDB 2.0.0no-finding, probenan_equality nan_zero_grouping cmpNaN equals NaN, of either sign: in =, IN, grouping, DISTINCT, joins and set operations: nan_equality: NAN_IS_NAN natively
duckdb-nan-orderfact (doubles)DuckDB 2.0.0no-finding, fuzznan_order agg.order agg.quant cmpNaN compares greater than every other float: nan_order: GREATEST natively (docs)
duckdb-round-digits-2fact (doubles)DuckDB 2.0.0no-finding, proberounding fp.roundround(DOUBLE, d): an overflowing result keeps the input: the reference (DuckDB 2.0's formula, #335)
duckdb-signbitfact (doubles)DuckDB 2.0.0decided, probenan_kind zero_sign fp.negsignbit reads the sign of -0.0 and of NaN: recorded: signbit is a black box Lean evaluates away from zero and NaN
duckdb-ulp-arithfact (doubles)DuckDB 2.0.0no-finding, proberounding fp32 fp.arith fp.div+ - * / on DOUBLE and FLOAT round once: correctly rounded (≤ 0.5 ulp) in each type, also a division by a literal
duckdb-ulp-libmfact (doubles)DuckDB 2.0.0open, proberounding fp32 fp.elem fp.logElementary functions and logarithms: the platform libm on doubles: sqrt correctly rounded; macOS: tan 2.4 ulp, log(b, x) 1.4 ulp, the rest < 1 ulp; Linux: …
duckdb-ulp-roundfact (doubles)DuckDB 2.0.0no-finding, proberounding fp32 fp.roundround(x, d): one rounding after the decimal pick: result ≤ 0.5 ulp from the decimal it picks; the pick follows x·10^d, off the exact decimal on near-ties
duckdb-exec-filter-pushdownfact (execution)DuckDB 2.0.0open, probeevaluation_orderFilter pushdown: a raising filter crosses a join, and runs on one input even when the other is empty: raising filters kept above projections; pushed into …
duckdb-exec-platformfact (execution)DuckDB 2.0.0open, probeplatformPlatform dependence: IEEE where the hardware supports it: elementary functions call the C++ standard library, so the platform's libm; no bundled math library
duckdb-exec-row-orderfact (execution)DuckDB 2.0.0open, probeparallel_nondeterminismRow order and order-sensitive aggregates under parallel execution: insertion order kept for scans, WHERE, LIMIT, UNION ALL; not for joins, GROUP BY, aggregates
duckdb-exec-settingsfact (execution)DuckDB 2.0.0open, probesettingsSettings that change results: eleven documented settings change values or order; five are checked
duckdb-exec-short-circuitfact (execution)DuckDB 2.0.0open, fuzzevaluation_orderShort-circuit: CASE and COALESCE lazy, AND/OR lazy only in a filter: CASE, COALESCE lazy at run time, but a raising constant WHEN raises while planning …
duckdb-exec-size-limitsfact (execution)DuckDB 2.0.0open, engine_testsize_limitsSize limits: decimal width 38; strings and blobs 4 GiB - 1; vectors 128 GB: decimal width over 38, a string or blob over 2^32 - 1 bytes and a vector over 128 …
duckdb-exec-tryfact (execution)DuckDB 2.0.0open, engine_testtry_variantsTRY_CAST and TRY(…): which errors become NULL: TRY nulls invalid-input, out-of-range and conversion errors row by row; TRY_CAST nulls conversion failures, …
duckdb-F1fact (integers)DuckDB 2.0.0no-finding, engine_testimplicit_casts/ and // on integers: frontend
duckdb-F3fact (integers)DuckDB 2.0.0no-finding, engine_testliteral_typesInteger literal types: frontend
duckdb-R1fact (integers)DuckDB 2.0.0deviation, fuzzoverflow int.arithInteger overflow of + - * and negation: deviation: unbounded, and reported as a warning
duckdb-R1-minfact (integers)DuckDB 2.0.0no-finding, fuzzoverflow int.abs int.divabs(MIN) and divide(MIN, -1): no finding (verify: overflow error)
duckdb-R15-int-arithfact (integers)DuckDB 2.0.0no-finding, probeoverflow int.arithBIGINT + - * and -BIGINT: matches overflow: ERROR
duckdb-R15-int-dividefact (integers)DuckDB 2.0.0no-finding, probeon_division_by_zero overflow division_type int.divBIGINT // BIGINT: matches on_division_by_zero: ERROR
duckdb-R15-int-modulusfact (integers)DuckDB 2.0.0shimmed, probemin_mod_neg_one division_type raise_set overflow int.modBIGINT % BIGINT: no option matches: MIN % -1 raises
duckdb-R15-shift-leftfact (integers)DuckDB 2.0.0shimmed, probeshift_range raise_set int.shiftBIGINT << BIGINT: no option matches
duckdb-R15-shift-rightfact (integers)DuckDB 2.0.0shimmed, probeshift_range int.shiftBIGINT >> BIGINT: no option matches
duckdb-R2fact (integers)DuckDB 2.0.0no-finding, fuzzon_division_by_zero division_type int.divInteger division by zero: no finding (verify: division by zero error)
duckdb-R3fact (integers)DuckDB 2.0.0open, fuzzdivision_type on_division_by_zero int.modInteger modulus: zero divisor and sign: no finding; division_type open, no diff
duckdb-int-div-domainfact (integers)DuckDB 2.0.0no-finding, engine_teston_domain_error division_type int.divInteger // has no domain error: no finding: only a zero divisor and MIN // -1 fail
duckdb-int-powfact (integers)DuckDB 2.0.0shimmed, probeoverflow on_domain_error int.powpower has no integer overload: shimmed: DuckDB's power is of doubles; sverify writes integer powers as checked products
duckdb-IO1fact (io)DuckDB 2.0.0workaround, probecatalogs object_storesunity_catalog: ATTACH ignores a named secret unless it names it: use an unnamed secret, or ATTACH ...
duckdb-IO2fact (io)DuckDB 2.0.0workaround, probecatalogs object_storesunity_catalog: the vended endpoint_url is ignored: set s3_endpoint, s3_url_style, s3_use_ssl
duckdb-IO3fact (io)DuckDB 2.0.0open, probeobject_stores io_formatsdelta: access denied with table-scoped vended keys on MinIO: open
duckdb-R11fact (nested)DuckDB 2.0.0shimmed, engine_testlist_null_order agg.order list.orderOrdering comparisons of lists: fixed (#207): lexicographic; DuckDB shim
duckdb-list-indexfact (nested)DuckDB 2.0.0no-finding, probelist_indexingList indexing: 1-based, negative from the end, NULL out of range and at 0: 1-based; the written SQL adds 1 to Substrait's 0-based offset
duckdb-list-sumfact (nested)DuckDB 2.0.0decided, probeempty_group_aggregateslist_sum of integers is a HUGEINT, NULL without values: decided: a BIGINT in the model, which raises past its range
duckdb-list-vectorsfact (nested)DuckDB 2.0.0decided, proberaise_setVector functions of lists: NULL elements raise, a zero vector gives NaN: decided: black boxes with bounds that allow NaN
duckdb-struct-equalityfact (nested)DuckDB 2.0.0open, probestruct_equalityStructs: NULL fields equal in = and grouping; in order a NULL field is the greatest, also in <: structural equality, NULL = NULL inside; < two-valued with …
duckdb-unnestfact (nested)DuckDB 2.0.0no-finding, probeunnest_null_emptyUNNEST drops a NULL list and an empty one; parallel UNNESTs pad with NULL: no row for [] or NULL; [NULL] gives a NULL row
duckdb-kleenefact (nulls)DuckDB 2.0.0no-finding, probethree_valued_logicThree-valued AND, OR, NOT, IN; bool_and, bool_or skip NULLs: Kleene logic natively
duckdb-null-concatfact (nulls)DuckDB 2.0.0no-finding, probenull_handling str.concat|| propagates NULL; concat and concat_ws skip it; greatest, least skip it: null_handling: ACCEPT_NULLS for ||; concat is IGNORE_NULLS
duckdb-null-keysfact (nulls)DuckDB 2.0.0no-finding, probenull_join_keysNULL keys group together and do not match in = joins; IS NOT DISTINCT FROM matches them: NULLs group together; IS NOT DISTINCT FROM joins them; no <=>
duckdb-F2fact (relations)DuckDB 2.0.0no-finding, engine_testnull_orderNULLs in ORDER BY: frontend
duckdb-clusteredfact (relations)DuckDB 2.0.0no-finding, probeclusteredNo clustering-only sort: an ORDER BY on the keys: clustered: an ORDER BY on the keys
duckdb-set-operationsfact (relations)DuckDB 2.0.0no-finding, probeset_operations null_join_keysSet operations: bag UNION ALL; INTERSECT, EXCEPT with NULLs and NaNs equal; ALL keeps min(m, n) and m − n: native, as the reference's
duckdb-sort-tiesfact (relations)DuckDB 2.0.0no-finding, probetie_order agg.seq win.ntile win.rank win.valueTies of a sort and the input order of aggregates are not guaranteed: tie_order: any order (ORDER BY may not be stable)
duckdb-F4fact (strings)DuckDB 2.0.0no-finding, engine_testcase_sensitivity type_namesCollations, macros and identifiers: frontend
duckdb-R13fact (strings)DuckDB 2.0.0fixed, engine_testnegative_start string_positions str.subsubstring with a negative start: fixed (#209): WRAP_FROM_END
duckdb-R15-digestsfact (strings)DuckDB 2.0.0no-finding, probedigestsmd5, sha256 of VARCHAR: the reference
duckdb-R15-regexpfact (strings)DuckDB 2.0.0no-finding, proberegex_dialectregexp_extract, regexp_replace of constant patterns, on ASCII text: the reference (RE2's meaning, #50)
duckdb-case-mappingfact (strings)DuckDB 2.0.0shimmed, probechar_set str.caseupper, lower: Unicode's simple one-to-one case mappings: char_set: UTF8 with simple mappings; sverify guards non-ASCII text
duckdb-printffact (strings)DuckDB 2.0.0decided, probecast_formatting raise_setprintf and format: strict, raise on a format that does not fit: recorded: printf and format are black boxes that may raise
duckdb-string-match-casefact (strings)DuckDB 2.0.0no-finding, probecase_sensitivity string_positions str.matchLIKE, starts_with, strpos, replace: case-sensitive: CASE_SENSITIVE under the default BINARY collation
duckdb-substring-rangefact (strings)DuckDB 2.0.0fixed, probesubstring_range str.subsubstring raises for an offset or a length outside 32 bits: fixed (#336): the reference raises too
duckdb-R10fact (temporal)DuckDB 2.0.0fixed, engine_testcast_parsing timestamp_precisionCasts between date and timestamp literals: fixed (#206)
duckdb-date-rangefact (temporal)DuckDB 2.0.0shimmed, probedate_range raise_set time.arithDates past 9999 and before year 1: computed, up to DuckDB's own limits: computes past 0001-01-01 … 9999-12-31; the written plan guards
duckdb-time-plus-intervalfact (temporal)DuckDB 2.0.0no-finding, probetime_interval_months time.arithTIME ± INTERVAL wraps around midnight; no date_trunc of a TIME: no-finding: the reference wraps too; months refused
duckdb-time-zonesfact (temporal)DuckDB 2.0.0open, probetime_zonesTime zones: ICU, the session's TimeZone; a DST gap moves forward, an overlap takes standard time: time zones outside the model; DuckDB's are ICU's
duckdb-yearweekfact (temporal)DuckDB 2.0.0decided, probeweek_numberingyearweek subtracts the ISO week in the years up to 0, and raises in DuckDB's first year: decided: yearweek is a black box, NULL where DuckDB raises
duckdb-ntilefact (windows)DuckDB 2.0.0no-finding, probentile_spread raise_set win.ntileNTILE: the SQL standard's buckets, the larger first: ntile_spread: the SQL standard's
duckdb-window-arg-orderfact (windows)DuckDB 2.0.0open, engine_testRanking functions with an ORDER BY of their own rank within the frame: lead: the SQL lift drops the argument ordering and the frame of rank, percent_rank, …
duckdb-window-framefact (windows)DuckDB 2.0.0no-finding, probedefault_window_frame null_orderDefault frame: RANGE up to the current row's peers with an order, the whole partition without; NULLs last in ranks: SQL's default frame; ranks put NULLs last …
duckdb-window-sum-orderfact (windows)DuckDB 2.0.0open, probesum_order rounding agg.fsumWindowed SUM/AVG of doubles: a segment tree of fanout 16, or per-thread partials: a tree of sequential nodes (fanout 16) for framed windows; per-thread …
polars-arg-min-maxfact (aggregates)Polars py-2.1.0no-finding, probetie_pick agg.pickarg_min, arg_max: the first index of a tie: the first of tied rows
polars-avg-intfact (aggregates)Polars py-2.1.0open, probeavg_int_result empty_group_aggregates agg.isummean and median of integers: Float64: a double: the Float64 sum over the count
polars-corrfact (aggregates)Polars py-2.1.0open, probestat_algo stat_degenerate agg.statcorr: shared state; NaN for one pair or zero variance: dp_xy / sqrt(dp_xx · dp_yy); NaN where the reference is NULL; no clamp
polars-count-emptyfact (aggregates)Polars py-2.1.0no-finding, probeempty_group_aggregatescount skips NULLs; aggregates of nothing: count skips NULLs, len counts rows; min, first of NULLs are NULL
polars-covfact (aggregates)Polars py-2.1.0open, probestat_algo agg.statcov: two-pass blocks with Chan merge; Welford when grouped on streaming: two-pass per block + Chan (in memory; streaming ungrouped); Welford (streaming …
polars-first-lastfact (aggregates)Polars py-2.1.0no-finding, probetie_pick tie_order agg.pick agg.seqfirst, last: the first and last row in input order, NULL included: input order, deterministic; NULLs taken unless ignore_nulls=True
polars-mean-floatfact (aggregates)Polars py-2.1.0open, probesum_order rounding agg.fsummean of floats: the sum by the count: sum / n
polars-mean-float-streamingfact (aggregates)Polars py-2.1.0open, probesum_order rounding empty_group_aggregates agg.fsummean of floats on the streaming engine: varies between runs when grouped: f64 sum / n; grouped, the order of the additions varies between runs
polars-min-max-nanfact (aggregates)Polars py-2.1.0open, probenan_order agg.order cmpmin, max and max_horizontal skip NaN: NaN is ignored unless every value is NaN; nan_max propagates it
polars-min-max-zerofact (aggregates)Polars py-2.1.0open, probezero_sign agg.ordermin and max of ±0: the sign is the platform's: f64::min/simd_min pick the zero; -0.0 for min on arm64
polars-modefact (aggregates)Polars py-2.1.0open, probetie_pickmode returns every most frequent value: a list of all modes, in no stated order
polars-nonfinite-aggregatesfact (aggregates)Polars py-2.1.0open, probenonfinite_aggregates nan_creation float_overflow agg.fsumAggregates over ±inf: NaN: sum(inf, -inf) and std over inf are NaN
polars-quantilefact (aggregates)Polars py-2.1.0open, probequantile_interp agg.quantquantile: nearest by default, six methods: nearest by default; linear interpolates
polars-sum-floatfact (aggregates)Polars py-2.1.0open, probesum_order empty_group_aggregates rounding agg.fsumsum of floats: pairwise, Kahan when grouped: pairwise (full); Kahan (grouped, in memory); in turn (grouped, streaming); in the input's width
polars-sum-float-streamingfact (aggregates)Polars py-2.1.0open, probesum_order empty_group_aggregates rounding agg.fsumsum of floats on the streaming engine: in turn per group, scheduling-dependent: grouped: plain left-to-right; ungrouped: pairwise per morsel, grouping varies …
polars-sum-intfact (aggregates)Polars py-2.1.0open, probeoverflow empty_group_aggregates agg.isumsum of integers: widened below 32 bits, wraps at 32 and 64; 0 for no values: Int8/Int16 sum to Int64; Int32/Int64 wrap; empty is 0
polars-var-stdfact (aggregates)Polars py-2.1.0open, probestat_algo stat_degenerate rounding agg.varvar and std: two-pass blocks of 128, or Welford, by path: two-pass per 128-block with Chan merge (ungrouped); Welford (grouped); clamps below 0
polars-var-std-streamingfact (aggregates)Polars py-2.1.0open, probestat_algo stat_degenerate rounding agg.varvar/std on the streaming engine: ungrouped result varies between runs: Chan merge of per-morsel blocks (ungrouped, run-dependent); Welford per value (grouped)
polars-cast-double-to-intfact (casts)Polars py-2.1.0no-finding, probefloat_to_int cast_failureDouble to integer: truncates; out of range raises or is NULL: float_to_int: TRUNCATE; strict raises, strict=False NULL; wrap_numerical saturates
polars-cast-intfact (casts)Polars py-2.1.0no-finding, probecast_failureInteger to a narrower integer or decimal: raises, NULL, or wraps: strict raises, strict=False NULL, wrap_numerical wraps
polars-cast-stringfact (casts)Polars py-2.1.0open, probecast_parsing cast_formatting cast_failureCasts from and to strings: strict parsing; shortest round-trip for doubles; no string → bool or date
polars-cast-to-doublefact (casts)Polars py-2.1.0no-finding, probefp32Integer to double and double to float round to nearest: round to nearest even; overflow to ±inf
polars-ulp-castsfact (casts)Polars py-2.1.0no-finding, probefp32Integer and decimal to Float64 and Float32: correctly rounded: ≤ 0.5 ulp: Int64, Int128 and Decimal to Float64 and Float32
polars-decimal-arithfact (decimals)Polars py-2.1.0shimmed, probeoverflow decimal_rescale decimal_result_type raise_set dec.arithDecimals: 38 digits, the larger scale, half to even: Decimal(38, max(s₁, s₂)); rounds half to even; raises on overflow and on / 0
polars-decimal-castsfact (decimals)Polars py-2.1.0shimmed, probedecimal_rescale float_to_int cast_failure dec.arithDecimal casts: half to even, correctly rounded to double, truncated to integer: a smaller scale and a double round half to even; to a double correctly …
polars-decimal-comparefact (decimals)Polars py-2.1.0no-finding, probeDecimal comparisons: exact across scales and with integers: exact
polars-atan2fact (doubles)Polars py-2.1.0open, probeon_domain_error fp.elemarctan2(0, 0) is 0: 0, where the reference raises
polars-double-arithfact (doubles)Polars py-2.1.0open, probenan_creation float_overflow fp.arithDouble + - *: IEEE, NaN for inf - inf and 0 * inf: IEEE: NaN where the reference raises
polars-double-dividefact (doubles)Polars py-2.1.0open, probeon_division_by_zero nan_creation on_domain_error float_overflow fp.divDouble / between columns: IEEE: on_division_by_zero: IEEE, but ±inf / ±inf is NaN
polars-double-modulusfact (doubles)Polars py-2.1.0open, probedivision_type on_division_by_zero nan_creation zero_sign fp.modDouble %: x - y·floor(x / y): floor remainder; NaN for x % 0 and for finite x % ±inf
polars-double-scalar-divisorfact (doubles)Polars py-2.1.0open, proberounding nan_creation division_type fp.div fp.modDividing by a literal multiplies by its reciprocal: x / c is x * (1 / c): not correctly rounded, NaN or inf for a subnormal c; 49.0 % 49.0 is 49.0
polars-elem-roundingfact (doubles)Polars py-2.1.0open, proberounding fp.elemElementary functions: Rust's libm calls, in the column's float type: sqrt correctly rounded; the rest is the platform's libm; x ** n for a literal n from 2 …
polars-fp-ieeefact (doubles)Polars py-2.1.0no-finding, sourcerounding fp.arith fp.divFloat32 and Float64 arithmetic: IEEE 754 between columns: IEEE 754 rounding for + - *, and for / between two columns
polars-fp32fact (doubles)Polars py-2.1.0open, probefp32 implicit_castsFloat32 arithmetic stays in Float32, and pulls in a double literal: native single precision; Float32 + 0.1 is Float32
polars-int-float-comparefact (doubles)Polars py-2.1.0no-finding, probeimplicit_castsAn integer compared with a double: both as doubles: Int64 == Float64 compares in Float64
polars-log-basefact (doubles)Polars py-2.1.0open, proberounding fp.loglog10 and log(base) divide natural logarithms: ln(x) / ln(base): last-bit differences from log10, log2
polars-math-domainfact (doubles)Polars py-2.1.0open, probeon_domain_error on_log_zero fp.elem fp.logElementary functions: NaN outside the domain, -inf for log(0): on_domain_error: NAN; on_log_zero: MINUS_INFINITY
polars-nan-equalityfact (doubles)Polars py-2.1.0no-finding, probenan_equality nan_zero_grouping cmpNaN equals NaN: in ==, grouping, unique and joins: nan_equality: NAN_IS_NAN natively
polars-nan-orderfact (doubles)Polars py-2.1.0no-finding, probenan_order agg.quant cmpNaN sorts above +inf, in comparisons and in sorts: nan_order: GREATEST natively, ascending and descending
polars-nan-signfact (doubles)Polars py-2.1.0open, probenan_kindA NaN's sign survives: -NaN keeps its sign bit
polars-roundfact (doubles)Polars py-2.1.0open, proberounding fp.roundround(): half to even by default: rounding: TIE_TO_EVEN; TIE_AWAY_FROM_ZERO with mode='half_away_from_zero'
polars-round-digitsfact (doubles)Polars py-2.1.0open, proberounding fp.roundround(d): op(x · 10ᵈ) / 10ᵈ, no negative d: matches the reference on the edge cases; d < 0 refused
polars-scalar-divisorfact (doubles)Polars py-2.1.0decided, proberounding nan_creationDouble /, //, % by a scalar: a multiplication by the reciprocal: divide of doubles by a scalar rounds twice (2u, approx) and overflows below the smallest …
polars-ulp-arithfact (doubles)Polars py-2.1.0open, proberounding fp32 fp.arith fp.div fp.elem+ - * / round once; / by a literal and x ** n round more: column ops ≤ 0.5 ulp; x / c < 1.5 ulp (1.2 seen); x ** n for literal n in 3..9 up to n − 1 ulp (3.8 …
polars-ulp-libmfact (doubles)Polars py-2.1.0open, proberounding fp32 fp.elem fp.logElementary functions and logarithms: the platform libm per type; logs divide: fp64 as the libm (tan 2.3 ulp on macOS); log10, log(b) 1.5 to 2.1 ulp; Float32 …
polars-ulp-roundfact (doubles)Polars py-2.1.0open, proberounding fp32 fp.roundround(d): one rounding after the decimal pick: result ≤ 0.5 ulp from the decimal it picks; the pick follows x·10^d, off the exact decimal on near-ties
polars-zero-addfact (doubles)Polars py-2.1.0shimmed, probezero_signx + 0.0 and 0.0 - x keep or flip a zero's sign: zero_sign: not IEEE either, so up to one zero (canon)
polars-zero-orderfact (doubles)Polars py-2.1.0open, probezero_sign nan_zero_grouping cmp-0.0 equals 0.0 in comparisons, sorts, grouping and joins: one zero for equality and order; which zero a group or unique keeps depends on maintain_order
polars-zero-signfact (doubles)Polars py-2.1.0open, probezero_sign fp.arith fp.div fp.neg-0.0 in arithmetic: two zeros: IEEE: 1 / -0.0 is -inf
polars-zero-sign-streamingfact (doubles)Polars py-2.1.0open, probezero_sign fp.arith fp.div fp.neg-0.0 in arithmetic on the streaming engine: two zeros, literal shortcuts per morsel: IEEE: 1 / -0.0 is -inf; with a literal operand the sign depends on the …
polars-exec-cse-hoistfact (execution)Polars 2.1.0deviation, probeevaluation_orderCSE hoists a cast shared by when/then branches onto every row: deviation: a guarded strict cast raises when two branches share it (PL-6)
polars-exec-enginefact (execution)Polars py-2.1.0open, engine_testsettingsEngine choice: a lazy collect() runs on the streaming engine by default: auto is streaming for lazy queries, in memory for eager ones; four switches change it
polars-exec-platformfact (execution)Polars py-2.1.0open, probeplatformPlatform dependence: undocumented: elementary functions use Rust's f64 methods, so the platform's libm; integer powers below 10 by repeated multiplication
polars-exec-predicate-pushdownfact (execution)Polars py-2.1.0open, probeevaluation_orderStrict casts raise on the rows left after predicate pushdown: which rows a raising expression sees depends on the optimizer; sverify turns predicate pushdown …
polars-exec-row-orderfact (execution)Polars py-2.1.0open, probeparallel_nondeterminismRow order: groups, joins and unique keep no order unless asked: order only with maintain_order; a join's default order may change between runs
polars-exec-size-limitsfact (execution)Polars py-2.1.0open, engine_testsize_limitsSize limits: decimal precision 38; strings 4 GiB - 1 (panic past it); rows 2^32 - 1 by default: Decimal: at most 38 digits; a string or binary over u32::MAX …
polars-exec-streaming-fallbackfact (execution)Polars py-2.1.0open, engine_teststreaming_fallbackStreaming engine: operations handed to the in-memory engine: per-node fallback for opaque UDFs, some joins, some group-bys, keep-last unique, median and …
polars-exec-strict-falsefact (execution)Polars py-2.1.0open, engine_testtry_variantsNon-raising forms: strict=False and wrap_numerical: strict=False gives NULL for an invalid cast; wrap_numerical wraps
polars-exec-when-eagerfact (execution)Polars py-2.1.0open, probeevaluation_orderwhen/then/otherwise masks elementwise branches; &, | and coalesce evaluate every operand: an elementwise branch sees NULL on the rows its condition excludes; …
polars-implicit-castsfact (frontend)Polars py-2.1.0open, probeimplicit_castsType promotion: the wider type; literals adopt the column's: supertypes; a literal that fits keeps the column's type
polars-literal-typesfact (frontend)Polars py-2.1.0no-finding, probeliteral_typesLiteral types: Int32 up to 2³¹, then Int64, UInt64, Int128: the narrowest of Int32, Int64, UInt64, Int128
polars-type-namesfact (frontend)Polars py-2.1.0no-finding, probetype_namesPolars's names of the types: Int8 … Int128, UInt*, Float32, Float64, String, Decimal(precision, scale), …
polars-int-absfact (integers)Polars py-2.1.0open, probeoverflow int.absabs of an integer: abs(MIN) is MIN: wraps at MIN; the model's abs takes overflow: ERROR only
polars-int-arithfact (integers)Polars py-2.1.0open, probeoverflow int.arith int.powInteger + - *, unary - and **: wrap at the column's width: matches overflow: SILENT at every width
polars-int-div-domainfact (integers)Polars py-2.1.0no-finding, engine_teston_domain_error int.divInteger // has no domain error: every input is in the domain; zero divisors and MIN // -1 are other options
polars-int-dividefact (integers)Polars py-2.1.0open, probedivision_type on_division_by_zero overflow int.divInteger // floors, truncdiv truncates; NULL for a zero divisor: // floors, truncdiv truncates; x // 0 is NULL; MIN // -1 wraps
polars-int-mod-overflowfact (integers)Polars py-2.1.0no-finding, engine_testoverflow int.modInteger % never overflows: no overflow at any width; MIN % -1 is 0
polars-int-modulusfact (integers)Polars py-2.1.0open, probedivision_type on_division_by_zero min_mod_neg_one int.modInteger %: the floor remainder, NULL for a zero divisor: division_type: FLOOR; x % 0 is NULL; MIN % -1 is 0
polars-int-pow-exponentfact (integers)Polars py-2.1.0no-finding, probeon_domain_error int.powInteger **: a negative exponent fails the query: raises InvalidOperationError for a negative exponent
polars-int-shiftfact (integers)Polars py-2.1.0open, probeshift_range int.shiftNo bit-shift expressions: no << or >> on expressions
polars-int-true-dividefact (integers)Polars py-2.1.0open, probeimplicit_casts on_division_by_zeroInteger /: a division of doubles: Int64 / Int64 is Float64; / 0 is ±inf or NaN; a literal divisor multiplies by its reciprocal
polars-iofact (io)Polars py-2.1.0no-finding, probeio_formats object_stores catalogsI/O: scans and sinks, object stores by storage_options, a Unity catalog client: Parquet, CSV, IPC, NDJSON, Delta, Iceberg; cloud via storage_options; pl.Catalog
polars-explodefact (nested)Polars py-2.1.0open, probeunnest_null_emptyexplode keeps a row for a NULL list and drops an empty list: a NULL list gives a NULL row, [] no row; keep_nulls=False drops the NULL row too
polars-list-indexfact (nested)Polars py-2.1.0open, probelist_indexing raise_setlist.get: 0-based, negative from the end, out of range raises: 0-based; raises out of range unless null_on_oob=True
polars-list-orderfact (nested)Polars py-2.1.0open, probelist_null_order agg.order list.orderLists sort with NULL elements lowest; no < or min on lists: list_null_order: LEAST in sorts; list comparisons refused
polars-nested-equalityfact (nested)Polars py-2.1.0no-finding, probestruct_equalityLists and structs: NULL elements and fields compare equal: structural equality, NULL inside equals NULL
polars-kleenefact (nulls)Polars py-2.1.0no-finding, probethree_valued_logicBoolean logic is Kleene's; all and any skip NULLs by default: three-valued &, |, ~; all(ignore_nulls=False) is Kleene's
polars-null-keysfact (nulls)Polars py-2.1.0no-finding, probenull_join_keysNULL keys: one group; joins skip them by default: NULLs group together; nulls_equal=True joins them
polars-clusteredfact (relations)Polars py-2.1.0no-finding, probeclusteredNo clustering-only sort; sort clusters: a sort on the keys
polars-null-orderfact (relations)Polars py-2.1.0no-finding, probenull_ordersort: NULLs first, ascending and descending: NULLS_FIRST by default in both directions
polars-set-operationsfact (relations)Polars py-2.1.0no-finding, probeset_operations null_join_keysSet operations are concatenation, unique and semi/anti joins: UNION ALL is concat; INTERSECT, EXCEPT need nulls_equal=True and unique
polars-sort-stabilityfact (relations)Polars py-2.1.0no-finding, probetie_ordersort is stable on the probe, guaranteed only with maintain_order: ties keep input order (guaranteed with maintain_order=True)
polars-sort-stability-streamingfact (relations)Polars py-2.1.0no-finding, probetie_orderStreaming sort is unstable above the partition threshold without maintain_order: ties keep input order with maintain_order=True; without it, not above 32 MiB
polars-casefact (strings)Polars py-2.1.0no-finding, probechar_set str.caseto_uppercase, to_lowercase: Rust's Unicode mappings: char_set: UTF8, Rust's str::to_uppercase
polars-concatfact (strings)Polars py-2.1.0no-finding, probenull_handling str.concatconcat_str: NULL in, NULL out; ignore_nulls=True skips them: null_handling: ACCEPT_NULLS by default; IGNORE_NULLS with the flag
polars-lengthfact (strings)Polars py-2.1.0no-finding, probechar_setlen_chars counts code points; len_bytes bytes: character_length natively
polars-match-functionsfact (strings)Polars py-2.1.0no-finding, probecase_sensitivity str.matchstarts_with, ends_with, literal replace_all: native, case-sensitive
polars-regexfact (strings)Polars py-2.1.0open, proberegex_dialect case_sensitivityRegexes are Rust's regex crate: no backreferences or lookaround, Unicode classes: regex crate syntax; extract is NULL without a match; $1 in replacements
polars-reversefact (strings)Polars py-2.1.0open, probechar_setstr.reverse reverses grapheme clusters: graphemes, where the reference reverses code points
polars-string-functions-missingfact (strings)Polars py-2.1.0open, probedigestsNo levenshtein, digests, repeat, ascii or LIKE on expressions: missing from pl.Expr.str
polars-string-orderfact (strings)Polars py-2.1.0no-finding, probeStrings sort by UTF-8 bytes; False before True: code point order, no collation
polars-strposfact (strings)Polars py-2.1.0open, probenegative_start string_positions str.matchstr.find: a 0-based byte offset, NULL when absent: byte offset from 0; NULL where strpos is 0
polars-substringfact (strings)Polars py-2.1.0no-finding, probenegative_start string_positions str.substr.slice: 0-based, negative offsets from the end: substring with negative_start: WRAP_FROM_END, offset - 1
polars-substring-rangefact (strings)Polars py-2.1.0open, probesubstring_range str.substr.slice takes any 64-bit offset: computes for offsets past 32 bits; a negative length raises
polars-trimfact (strings)Polars py-2.1.0open, probestrip_chars() trims Unicode whitespace; with characters, those: btrim(s, ' ') natively; the default trims all whitespace
polars-date-partsfact (temporal)Polars py-2.1.0no-finding, probeweek_numberingDate parts: ISO weeks, weekday 1–7, floor before 1970: ISO week and year; Monday is 1; parts and epoch floor
polars-date-rangefact (temporal)Polars py-2.1.0open, probedate_range raise_set time.arithDates past 9999 and before year 1; out-of-range days panic: no date_range limit; Int32 days beyond chrono's range panic
polars-month-arithfact (temporal)Polars py-2.1.0no-finding, probedate_rangeoffset_by('1mo') clamps to the month's end: end-of-month clamping
polars-strftimefact (temporal)Polars py-2.1.0open, probecast_formattingstrftime is chrono's format: chrono's specifiers: %.f milliseconds here, %U Sunday weeks
polars-temporal-errorsfact (temporal)Polars py-2.1.0open, probetime_interval_months time_zones cast_parsing time.arithTIME + duration unsupported; DST gaps and invalid dates raise: raises where the reference refuses or computes
polars-timestamp-unitfact (temporal)Polars py-2.1.0no-finding, probetimestamp_precisionTimestamps are microseconds by default; nanoseconds reach 2262: Datetime('us'); ns casts fail past 2262-04-11
polars-rankfact (windows)Polars py-2.1.0open, probedefault_window_frame ntile_spread tie_order win.ntile win.rankrank: average by default; NULL ranks are NULL: rank('min') is RANK, 'dense' is DENSE_RANK, 'ordinal' is ROW_NUMBER
polars-window-valuesfact (windows)Polars py-2.1.0no-finding, probedefault_window_frame tie_order win.valueWindows: over keeps the input order inside a partition: first().over, shift(1).over, cum_sum().over in input order
spark-avg-doublefact (aggregates)Spark 4.3.0open, fuzzsum_orderAVG of doubles: plain sum by the count: plain sum / n
spark-avg-intfact (aggregates)Spark 4.3.0open, fuzzavg_int_result empty_group_aggregates agg.isumAVG of integers is a DOUBLE, summed in double: avg_int_result: DOUBLE; the sum is a double, so 64-bit inputs lose digits
spark-corrfact (aggregates)Spark 4.3.0open, fuzzstat_algo stat_degenerate agg.statCORR: shared Welford state; NULL for one pair or zero variance: ck / sqrt(xMk · yMk); NULL as in the reference; no clamp
spark-covarfact (aggregates)Spark 4.3.0open, fuzzstat_algo agg.statCOVAR_*: Welford co-moment, Chan merge: Welford co-moment; Chan merge
spark-first-lastfact (aggregates)Spark 4.3.0no-finding, probetie_pick tie_order parallel_nondeterminism agg.pick agg.seqfirst, last, any_value, mode, min_by/max_by take a row that depends on the partitioning: tie_pick: input order within a partition, partitions in completion …
spark-nonfinite-aggregatesfact (aggregates)Spark 4.3.0open, fuzznonfinite_aggregates nan_creation float_overflow stat_degenerate agg.fsumAggregates of ±inf and NaN: IEEE results, no raise: sum(inf, -inf) NaN; variance(inf, 1) NaN; sum(1e308, 1e308) +inf; NaN propagates
spark-quantilefact (aggregates)Spark 4.3.0open, fuzzquantile_interp agg.quantpercentile_cont and median interpolate linearly; percentile_disc takes the lower value, as a double: quantile_interp: cont linear at (n - 1)·p; disc the …
spark-sum-doublefact (aggregates)Spark 4.3.0open, fuzzsum_order rounding empty_group_aggregates parallel_nondeterminism agg.fsumSUM of doubles: plain, order by partitioning: plain recursive summation; order depends on partitioning
spark-sum-intfact (aggregates)Spark 4.3.0open, fuzzoverflow empty_group_aggregates parallel_nondeterminism agg.isumSUM of integers returns BIGINT; 64-bit partial sums raise (ANSI) or wrap: i8…i32 widen to BIGINT; i64: ERROR on a partial sum (ANSI), order-dependent; no …
spark-var-stddevfact (aggregates)Spark 4.3.0open, fuzzstat_algo stat_degenerate rounding agg.varVAR_* and STDDEV_*: Welford/West, Chan merge: Welford/West; Chan merge; no clamp
spark-cast-double-to-intfact (casts)Spark 4.3.0no-finding, probefloat_to_int cast_failureCasts to integers truncate; out of range raises (ANSI) or saturates and wraps: float_to_int: TRUNCATE; cast_failure: raise (ANSI), else INT/BIGINT saturate, …
spark-cast-stringfact (casts)Spark 4.3.0open, fuzzcast_parsing cast_formatting cast_failureCasts from and to strings: trimmed, lenient parsing; Java's double text: parse: trims, 1.5 → INT raises (ANSI) or truncates; doubles accept inf, nan, 1.5d, …
spark-decimal-arithfact (decimals)Spark 4.3.0no-finding, probeoverflow decimal_rescale decimal_result_type dec.arithDecimal arithmetic: Hive's result types, half up, overflow raises (ANSI) or NULL: result types borrow scale past 38 digits; decimal_rescale: …
spark-decimal-negatefact (decimals)Spark 4.3.0open, fuzzoverflow raise_set dec.arithNegation of decimals rounds to 34 significant digits, half to even (SP-1): -x, and abs(x) of a negative x, past 34 digits: rounded half to even, or a raise …
spark-double-arithfact (doubles)Spark 4.3.0open, fuzzrounding nan_creation float_overflow fp.arithDouble + - *: IEEE, NaN from inf - inf, ±inf on overflow: IEEE in both modes: nan_creation NaN, float_overflow ±inf
spark-double-dividefact (doubles)Spark 4.3.0open, fuzzon_division_by_zero nan_creation on_domain_error float_overflow rounding fp.divDouble /: a zero divisor raises (ANSI) or gives NULL, never inf: on_division_by_zero: ERROR (ANSI) or NULL; inf / inf NaN; overflow ±inf
spark-double-modulusfact (doubles)Spark 4.3.0open, fuzzdivision_type on_division_by_zero nan_creation zero_sign fp.modDouble %: Java's truncated remainder; pmod adds b to a negative remainder; zero divisor raises (ANSI) or NULL: %: fmod, fmod(x, ±inf) = x; zero divisor ERROR …
spark-elem-roundingfact (doubles)Spark 4.3.0open, fuzzrounding platform fp.elem fp.logElementary functions: StrictMath (fdlibm) for exp, logs, pow; java.lang.Math for the rest: exp, ln, log10, pow: fdlibm, the same everywhere; sqrt, trig: …
spark-fp32fact (doubles)Spark 4.3.0open, fuzzfp32 implicit_castsFLOAT +, -, * in single precision; / and ANSI FLOAT + INT are DOUBLE: FLOAT + - * FLOAT is FLOAT; FLOAT / FLOAT DOUBLE; FLOAT + INT: DOUBLE (ANSI) or FLOAT; …
spark-math-domainfact (doubles)Spark 4.3.0open, fuzzon_domain_error on_log_zero fp.elem fp.logMath domain errors: NaN for sqrt, asin, acos; NULL for logs of x ≤ 0: on_domain_error: NAN (sqrt, asin, acos, pow), NULL (logs); on_log_zero: NULL (ST-16)
spark-nan-equalityfact (doubles)Spark 4.3.0no-finding, probenan_equality nan_zero_grouping cmpNaN equals NaN in =, grouping, DISTINCT and joins: NAN_IS_NAN everywhere; -NaN groups with NaN
spark-nan-orderfact (doubles)Spark 4.3.0no-finding, probenan_order agg.order agg.quant cmpNaN sorts above +inf; max and greatest return NaN: nan_order: GREATEST in sorts, <, max, greatest, quantiles
spark-nan-signfact (doubles)Spark 4.3.0open, fuzznan_kind platformA NaN's sign survives arithmetic and shows; grouping normalises it: nan_kind: the sign bit is kept by -x; inf - inf is -NaN on x86-64
spark-roundfact (doubles)Spark 4.3.0open, fuzzrounding fp.roundround rounds half up on the double's shortest decimal; bround half even: round(x): TIE_AWAY_FROM_ZERO; round(x, d) on the decimal text: round(2.675, 2) is 2.68
spark-zero-orderfact (doubles)Spark 4.3.0open, fuzzzero_sign nan_zero_grouping agg.order cmpThe two zeros compare equal; grouping normalises to 0.0; min, max keep the first: =: -0.0 = 0.0; group key 0.0; sorts tie; min/max return the zero seen first
spark-zero-signfact (doubles)Spark 4.3.0open, fuzzzero_sign fp.arith fp.div fp.negTwo zeros in double arithmetic; a -0.0 literal is a decimal: IEEE zeros: -0.0 * 1 is -0.0, -(0.0) is -0.0; -0.0 without D is 0.0
spark-raise-setfact (errors)Spark 4.3.0open, fuzzraise_setWhere Spark raises beyond the reference, and where it errors without an error class: extra raises: INT positions, ANSI string casts, element_at(…, 0), …
spark-exec-evaluation-orderfact (execution)Spark 4.3.0no-finding, probeevaluation_orderCASE, IF, COALESCE are lazy; AND, OR short-circuit left to right; filters can move below projections: a guarded branch never raises; b <> 0 AND a div b > 1 …
spark-exec-parallelfact (execution)Spark 4.3.0open, fuzzparallel_nondeterminismResults that change with partitioning and timing: double SUM/AVG, BIGINT sum overflow, first/last, collect_list, sort and window ties
spark-exec-parser-cachefact (execution)Spark 4.3.0shimmed, probesettings size_limitsThe SQL parser's DFA cache is unbounded unless Spark manages it: A large statement pins hundreds of MB of driver heap until …
spark-exec-platformfact (execution)Spark 4.3.0open, fuzzplatformPlatform dependence: java.lang.Math intrinsics, the NaN sign, the JVM locale: last bits of sqrt… atan2 may vary; created NaN negative on x86-64; probes on …
spark-exec-settingsfact (execution)Spark 4.3.0open, fuzzsettingsThe session settings that change results: ansi.enabled, timestampType, session.timeZone, legacy.statisticalAggregate, decimalOperations.allowPrecisionLoss, …
spark-exec-size-limitsfact (execution)Spark 4.3.0open, fuzzsize_limitsLimits: decimals at 38 digits, strings and arrays below 2 GB: DECIMAL(39) refused; strings, binaries and arrays under 2³¹ bytes or elements
spark-exec-streaming-fallbackfact (execution)Spark 4.3.0no-finding, sourcestreaming_fallbackNo streaming fallback: sverify runs Spark batch queries: not applicable: batch execution only
spark-try-variantsfact (execution)Spark 4.3.0open, fuzztry_variantstry_* functions give NULL for their own errors only: try_cast, try_add, try_divide, try_sum, … : NULL on their errors, in both modes
spark-implicit-castsfact (frontend)Spark 4.3.0no-finding, probeimplicit_castsImplicit casts: ANSI promotes by precedence and parses strings strictly; legacy goes through double: ANSI: 1 + '2' is BIGINT 3, '1.5' + 1 raises; legacy: …
spark-literal-typesfact (frontend)Spark 4.3.0no-finding, probeliteral_typesLiterals: INT, then BIGINT, then DECIMAL; 1.5 is a decimal, 1e0 a double: 1 int; 2147483648 bigint; 1.5 decimal(2,1); 1e0, 1.5D double; suffixes Y S L F D BD
spark-type-namesfact (frontend)Spark 4.3.0no-finding, probetype_namesType names: Spark's (tinyint … bigint, float, double, decimal(p,s), timestamp_ntz): typeof gives Spark's names; TIMESTAMP is timestamp (LTZ) or timestamp_ntz …
spark-int-absfact (integers)Spark 4.3.0no-finding, probeoverflow int.absabs of integers: abs(MIN) raises under ANSI, is MIN without: ANSI on: overflow: ERROR; ANSI off: abs(MIN) is MIN
spark-int-arithfact (integers)Spark 4.3.0no-finding, probeoverflow int.arithInteger + - * and unary -: raise under ANSI, wrap without: ANSI on: overflow: ERROR at every width; ANSI off: SILENT
spark-int-dividefact (integers)Spark 4.3.0open, fuzzdivision_type on_division_by_zero overflow on_domain_error int.divdiv truncates and returns BIGINT; / on integers is a double division: div: truncate, BIGINT; zero divisor raises (ANSI) or NULL; MIN div -1 raises only at 64 …
spark-int-modulusfact (integers)Spark 4.3.0no-finding, probedivision_type on_division_by_zero min_mod_neg_one overflow int.mod% is the truncated remainder, pmod the floored one: %: TRUNCATE; MIN % -1 is 0; zero divisor raises (ANSI) or NULL
spark-int-powfact (integers)Spark 4.3.0open, fuzzoverflow on_domain_error int.powpower of integers returns a double: no integer power: power(2, 63) is 9.223372036854776E18
spark-int-shiftfact (integers)Spark 4.3.0open, fuzzshift_range int.shiftShifts promote to INT and take the count modulo the width: shiftleft(a, n): Java's <<, count mod 32 (INT) or mod 64 (BIGINT)
spark-iofact (io)Spark 4.3.0no-finding, engine_testio_formats object_stores catalogsI/O: Parquet, ORC, CSV, JSON, XML, text and Avro; Hadoop file systems; catalogs by configuration: data sources by format; s3a://, abfss://, gs:// through …
spark-explodefact (nested)Spark 4.3.0no-finding, probeunnest_null_emptyexplode drops NULL and empty arrays; explode_outer keeps a NULL row: unnest_null_empty: no row for NULL or []; OUTER adds one NULL row
spark-list-indexfact (nested)Spark 4.3.0open, fuzzlist_indexing raise_set settingselement_at is 1-based and counts back from the end; [] is 0-based; out of range raises (ANSI): element_at(a, i): 1-based, negative from the end, 0 raises; …
spark-list-orderfact (nested)Spark 4.3.0open, fuzzlist_null_order agg.order list.orderArrays order element-wise with a NULL element lowest, in < and in sorts: list_null_order: NULL element smallest, [1, NULL] < [1, 2] true; ascending sorts …
spark-nested-equalityfact (nested)Spark 4.3.0no-finding, probestruct_equalityStructs and arrays compare structurally, NULL fields equal: = on structs and arrays: structural, NULL fields and elements equal; ordered field by field
spark-concatfact (nulls)Spark 4.3.0no-finding, probenull_handling str.concatconcat and || are NULL with a NULL argument; concat_ws skips NULLs: null_handling: ACCEPT_NULLS native; concat_ws for IGNORE_NULLS
spark-kleenefact (nulls)Spark 4.3.0no-finding, probethree_valued_logicAND, OR, NOT are Kleene's; bool_and, bool_or skip NULLs: three-valued logic; boolean aggregates skip NULLs, NULL when all are
spark-null-keysfact (nulls)Spark 4.3.0no-finding, probenull_join_keysJoins on = skip NULL keys; <=> and IS NOT DISTINCT FROM match them; grouping puts NULLs together: = skips NULL; <=>, IS NOT DISTINCT FROM match; one NULL group
spark-clusteredfact (relations)Spark 4.3.0no-finding, probeclusteredDISTRIBUTE BY, SORT BY, CLUSTER BY: equal keys in one partition, sorted within it: clustered: DISTRIBUTE BY k puts equal keys together; SORT BY sorts each …
spark-null-orderfact (relations)Spark 4.3.0no-finding, probenull_orderNULLs first ascending, last descending: null_order: NULLS FIRST for ASC, NULLS LAST for DESC
spark-set-operationsfact (relations)Spark 4.3.0no-finding, probeset_operations null_join_keysUNION, INTERSECT, EXCEPT, with and without ALL: NULLs equal: SQL's set operations; NULLs (and NaN, ±0.0) equal; no order
spark-sort-stabilityfact (relations)Spark 4.3.0no-finding, probetie_order parallel_nondeterminismSorts are not stable across partitions; ties come in partition order: tie_order: ties in an order that changes with the partitioning and between runs
spark-casefact (strings)Spark 4.3.0no-finding, probechar_set settings str.caseupper, lower: Java's full Unicode mappings, in the JVM's default locale: char_set: UTF8 with full mappings (ß → SS, final sigma); ASCII fast path
spark-digestsfact (strings)Spark 4.3.0no-finding, probedigestsmd5, sha1, sha2, crc32: lowercase hex of the UTF-8 bytes: md5(s), sha2(s, 256): hex strings of the UTF-8 bytes; sha2 with a bad length is NULL
spark-match-functionsfact (strings)Spark 4.3.0no-finding, probecase_sensitivity str.matchLIKE, contains, startswith, instr, RLIKE, replace are case-sensitive: case_sensitivity: CASE_SENSITIVE; ILIKE and (?i) for the other, (?i) ASCII only
spark-regexfact (strings)Spark 4.3.0open, fuzzregex_dialect case_sensitivity raise_setRegexes are java.util.regex: ASCII classes, $1 references, '' without a match: Java's syntax; \\d, \\w ASCII; no match extracts ''; bad patterns raise
spark-string-plainfact (strings)Spark 4.3.0no-finding, probechar_setlength, reverse, trim, ascii, repeat, levenshtein: code points, spaces only: code points throughout; trim strips U+0020 only; native
spark-strposfact (strings)Spark 4.3.0no-finding, probestring_positions negative_start str.matchinstr, locate, position: 1-based characters, 0 when absent: string_positions: 1-based code points; 0 without a match
spark-substringfact (strings)Spark 4.3.0open, fuzznegative_start string_positions str.subsubstring: 1-based characters; a start of 0 is 1; negative counts from the end: negative_start: WRAP_FROM_END, 1-based code points; start 0 reads as 1
spark-substring-rangefact (strings)Spark 4.3.0open, fuzzsubstring_range raise_set str.subsubstring positions and lengths are INT: wider ones raise (ANSI) or wrap: substring_range: a BIGINT past 32 bits raises CAST_OVERFLOW (ANSI) or wraps
spark-date-rangefact (temporal)Spark 4.3.0open, fuzzdate_range raise_set time.arithDates and timestamps compute past 9999; date_add wraps at 2³¹ days (SP-2): date_range: no raise at 9999-12-31; day counts wrap; timestamps past 294247 raise …
spark-time-typefact (temporal)Spark 4.3.0no-finding, probetime_interval_months time.arithTIME is off by default; with it on, TIME + INTERVAL raises past midnight: time_interval_months: TIME unsupported by default; + INTERVAL 1 MONTH a type error
spark-time-zonesfact (temporal)Spark 4.3.0no-finding, probetime_zones settingsTime zones: the session's zone for TIMESTAMP_LTZ; a DST gap shifts forward, an overlap takes the earlier offset: LTZ in the session zone; gap → later wall …
spark-timestamp-precisionfact (temporal)Spark 4.3.0no-finding, probetimestamp_precisionTimestamps are microseconds; extra digits are dropped: microseconds, -290308 … +294247; nanoseconds truncated on parse
spark-week-partsfact (temporal)Spark 4.3.0no-finding, probeweek_numberingISO weeks; dayofweek from Sunday; date_trunc('week') to Monday; floors before 1970: ISO weekofyear, YEAROFWEEK, DOW_ISO; dayofweek 1 = Sunday; floor before …
spark-rankfact (windows)Spark 4.3.0no-finding, probentile_spread tie_order default_window_frame win.ntile win.rankRanking windows: SQL's rank, ntile spreads the remainder to the first buckets: SQL ranks, NULLs ranked first ascending; ntile front-loads; ties in arrival order
spark-window-valuesfact (windows)Spark 4.3.0no-finding, probedefault_window_frame tie_order parallel_nondeterminism win.valueWindow frames: RANGE … CURRENT ROW with an order, the whole partition without: default_window_frame: SQL's; lag, lead, nth_value as SQL; ties in arrival order