Background
The serde framework intends that an expression declares whether it can be accelerated through getSupportLevel, which returns Compatible, Incompatible, or Unsupported. The central dispatcher in QueryPlanSerde then translates Incompatible/Unsupported into the appropriate withFallbackReason fallback.
Several CometExpressionSerde.convert (and CometAggregateExpressionSerde.convert) implementations instead call withFallbackReason directly for decisions that are statically determinable from the expression (data types, negative decimal scale, whether an argument is a literal/foldable, etc.). Those decisions belong in getSupportLevel.
Calling withFallbackReason inside convert is only appropriate when rolling up child fallback reasons after a child failed to convert, or when the decision genuinely cannot be made until conversion is attempted. Note that getSupportLevel(expr) receives only the expression: checks that need inputs/binding (for example resolving an attribute against the input schema) must remain in convert.
Scope
Move static support decisions out of convert and into getSupportLevel across the expression and aggregate serdes. This is a behavior-preserving refactor: each case that previously fell back to Spark continues to fall back with the same reason.
This will be done as a series of PRs grouped by serde domain:
The cast path (CometCast) and the operator/scan/rule layers are out of scope: they do not have a getSupportLevel(expr) hook.
Background
The serde framework intends that an expression declares whether it can be accelerated through
getSupportLevel, which returnsCompatible,Incompatible, orUnsupported. The central dispatcher inQueryPlanSerdethen translatesIncompatible/Unsupportedinto the appropriatewithFallbackReasonfallback.Several
CometExpressionSerde.convert(andCometAggregateExpressionSerde.convert) implementations instead callwithFallbackReasondirectly for decisions that are statically determinable from the expression (data types, negative decimal scale, whether an argument is a literal/foldable, etc.). Those decisions belong ingetSupportLevel.Calling
withFallbackReasoninsideconvertis only appropriate when rolling up child fallback reasons after a child failed to convert, or when the decision genuinely cannot be made until conversion is attempted. Note thatgetSupportLevel(expr)receives only the expression: checks that needinputs/binding(for example resolving an attribute against the input schema) must remain inconvert.Scope
Move static support decisions out of
convertand intogetSupportLevelacross the expression and aggregate serdes. This is a behavior-preserving refactor: each case that previously fell back to Spark continues to fall back with the same reason.This will be done as a series of PRs grouped by serde domain:
arithmetic.scala,math.scala)strings.scala)arrays.scala)aggregates.scala)namedExpressions.scala,unixtime.scala,contraintExpressions.scala)The cast path (
CometCast) and the operator/scan/rule layers are out of scope: they do not have agetSupportLevel(expr)hook.