agg_funcs Expression Audits#
Audit notes for expressions in this category that have been audited. Absence of an entry means the expression has not been audited yet, not that it is unsupported. See the user guide Spark Expression Support for current support status.
approx_count_distinct#
Spark 3.4.3 (2026-07-03): registered as
expression[HyperLogLogPlusPlus]("approx_count_distinct"), anImperativeAggregatethat hashes each non-null input withXxHash64(seed 42, floats normalized viaNormalizeNaNAndZero) and keeps a HyperLogLog++ register buffer ofnumWordsLongs (10 six-bit registers per word). The cardinality is estimated with linear counting for small inputs and bias-corrected HLL otherwise. Comet portsHyperLogLogPlusPlusHelperexactly, including the bias-correction tables, reuses Comet’s Spark-compatiblexxhash64for hashing, and stores the register buffer in Spark’s identical packed-Longlayout, so results are bit-identical to Spark and the partial-aggregation state matches Spark’saggBufferSchema(enabling mixed Comet/Spark partial and final aggregation).relativeSD(default 0.05) sets the precisionp. Comet supports the input types itsxxhash64hashes identically to Spark: boolean, integral, floating-point,DecimalTypewith precision <= 18, date/time, default-collation (UTF8_BINARY) string, and binary. Wider decimals (hashed throughBigDecimal) and collated strings (hashed via the collation sort key) fall back to Spark.Spark 3.5.8 (2026-07-03): algorithm and tables identical to 3.4.3.
Spark 4.0.1 (2026-07-03):
HyperLogLogPlusPlusHelpermoved tocatalyst.utilandXxHash64Function.hashgained collation parameters, but for the defaultUTF8_BINARYcollation and non-string types the hash value is unchanged, so results match 3.4.3.Spark 4.1.1 (2026-07-03): identical to 4.0.1.
any#
Spark 3.4.3 (audited 2026-05-26): registered as a SQL alias of
BoolOr, which extendsRuntimeReplaceableAggregatewithreplacement = Max(child). Catalyst rewritesany(x)tomax(x)before Comet sees the plan, soanyis served byCometMaxon aBooleanTypecolumn.Spark 3.5.8 (audited 2026-05-26): identical to 3.4.3.
Spark 4.0.1 (audited 2026-05-26): identical to 3.4.3.
approx_percentile#
Spark 3.4.3, 3.5.8, 4.0.1, 4.1.1 (audited 2026-07-02):
ApproximatePercentile(child, percentageExpression, accuracyExpression)is aTypedImperativeAggregatebacked by a Greenwald-KhannaPercentileDigestquantile summary with relative error1.0 / accuracy.childacceptsNumericType,DateType,TimestampType,TimestampNTZType, and interval types (all cast todoubleinternally);percentageis a single literal or literal array in[0.0, 1.0];accuracyis a positive literal (default 10000). NULL inputs are skipped; an empty or all-null group returns NULL.approx_percentileis a SQL alias for the primary function namepercentile_approx.CometApproxPercentilemaps the byte, short, int, long, float, and double input forms to a native Greenwald-Khanna quantile summary port with the same insert/compress/merge/query algorithm and relative error, casting the result back to the input type.percentageandaccuracymust be foldable literals, matching Spark. Date, timestamp, interval, and decimal inputs fall back to Spark.
avg#
Spark 3.4.3 (2026-05-26)
Spark 3.5.8 (2026-05-26): aggregate logic identical to 3.4.3
Spark 4.0.1 (2026-05-26): aggregate logic identical to 3.5.8; only
QueryContextimport path differs.YearMonthIntervalTypeandDayTimeIntervalTypeinputs (supported by Spark) fall back to Spark in Comet.
bit_and#
Spark 3.4.3 (2026-05-26)
Spark 3.5.8 (2026-05-26)
Spark 4.0.1 (2026-05-26)
collect_list#
Spark 3.4.3 (audited 2026-06-24):
CollectListextendsCollect[ArrayBuffer[Any]], returnsArrayType(child.dataType, containsNull = false), ignores NULL inputs inupdate()(Hive-compatible semantics), and yields an empty array asdefaultResult.nullable = false. NocheckInputDataTypesoverride, so any input type is accepted (including STRUCT, ARRAY, MAP). Registered as bothcollect_listandarray_aggaliases inFunctionRegistry.Spark 3.5.8 (audited 2026-06-24): identical to 3.4.3.
Spark 4.0.1 (audited 2026-06-24): only structural change is adding
with UnaryLike[Expression]to the case class (no behavior change).Spark 4.1.1 (audited 2026-06-24): identical to 4.0.1.
Comet implementation: native side delegates to
datafusion_spark::function::aggregate::collect::SparkCollectList, which wrapsArrayAggAccumulatorwithignore_nulls = trueand converts a final NULL accumulator state to an empty array (matching Spark’sdefaultResult). The native return type isList(Field, containsNull = true), while Spark usescontainsNull = false. Because nulls are filtered before insertion, no nulls actually appear in the array, so this is a schema-shape difference only and tests usingcheckSparkAnswerAndOperatoraccept it (same pattern already in use forcollect_set).Spark 4.2 (preview):
CollectListandCollectSetgain anignoreNullsfield (defaulttrue);RESPECT NULLSsets it tofalseand keeps null elements. The native path always drops nulls, soCometCollectShimreads the field per Spark version (alwaystrueon 3.4-4.1) andCometCollectList/CometCollectSetreportUnsupportedwhen it isfalse, falling back to Spark.
median#
Spark 3.4.3 (audited 2026-06-24):
Median(child)is aRuntimeReplaceableAggregatewithreplacement = Percentile(child, Literal(0.5)). Catalyst rewritesmedian(x)topercentile(x, 0.5)before Comet sees the plan, so it is served byCometPercentile.Spark 3.5.8 (audited 2026-06-24): identical to 3.4.3.
Spark 4.0.1 (audited 2026-06-24):
replacementbecomeslazy val; semantics unchanged.Spark 4.1.1 (audited 2026-06-24): identical to 4.0.1.
percentile#
Spark 3.4.3 (audited 2026-06-24):
Percentile(child, percentageExpression, frequencyExpression, ..., reverse)overPercentileBase. Exact percentile usingindex = p * (n - 1)linear interpolation, NULL inputs skipped, empty/all-null group returns NULL.CometPercentilemaps the single-literal-percentage, default-frequency, numeric-input, ascending form to DataFusion’spercentile_cont(same interpolation). Array-of-percentages, a non-default frequency argument, descending order, and interval inputs fall back to Spark.Spark 3.5.8 (audited 2026-06-24): ordering centralized via
PhysicalDataType.ordering; behavior identical to 3.4.3.Spark 4.0.1 (audited 2026-06-24): adds
PercentileCont/PercentileDiscbuilders andSupportsOrderingWithinGroup, enablingpercentile_cont(p) WITHIN GROUP (ORDER BY col), which rewrites toPercentile(col, p, reverse). The ascending form runs natively; theDESCform setsreverse = trueand falls back to Spark because the nativepercentile_contalways interpolates in ascending order.Spark 4.1.1 (audited 2026-06-24): identical to 4.0.1.
CometPercentilereportsCompatiblefor the single-literal-percentage, default-frequency, numeric-input, ascending form and runs it natively by default. Every other form isUnsupportedand falls back to Spark.