Native Evaluation Semantics
Native SQL Support lists what the GPU path evaluates. This page states what happens on the rows it evaluates: which operations can fail the query, which rows they fail on, and where the result can differ from DataFusion. The rule throughout is that native evaluation fails on the same rows as DataFusion and never fails where DataFusion succeeds. A row with a null operand never fails.
Checked operations
Guarded evaluation
DataFusion evaluates a CASE branch only on the rows its condition selects:
ELSE where no condition is true, each WHEN after the first where no earlier
WHEN selected the row, and in CASE base WHEN value the value only where
base is not null. A null condition counts as not true. For l AND r it skips
r on some batches where l is false, and for l OR r where l is true.
The native evaluator visits every row. Lowering therefore sets the fallible
operand to null on the rows DataFusion would not evaluate: the divisor of an
integer / or %, the right operand of a timestamp + or -, and the input
of a cast that range-checks. For AND the operation runs where the left
operand is true or null, and for OR where it is false or null. A decided row
takes its value from the left operand alone, so results do not change.
CASE WHEN n <> 0 THEN total / n END -- never divides by zero
CASE WHEN n >= 0 THEN total / n END -- fails on a row with n = 0, as on DataFusion
WHERE n <> 0 AND total / n > 1 -- never divides by zero
WHERE n >= 0 AND total / n > 1 -- fails on a row with n = 0, as on DataFusion
- A decimal
/and a timestamp+or-are always guarded, because any pair of operands can overflow. A literal integer divisor other than0and-1, and a cast whose target holds every value of the source type, cannot fail and are evaluated as they are. - A nested
CASEapplies the restrictions of every enclosing branch. - Each
WHENcondition, orAND/ORterm, that divides, casts or does timestamp arithmetic doubles the restrictions of the branches or terms after it. A chain of about eight such conditions stays on DataFusion. - Native evaluation is more permissive in one case: DataFusion skips the right operand only on some batches, and when it evaluates a decided row that fails, DataFusion fails the query while native evaluation returns the result.
Where checked operations are not evaluated
Integer /, any %, and timestamp + or - are not evaluated inside reader
predicates or join residual conditions. A reader predicate with one of them
stays a filter after the scan, and a join residual with one of them keeps the
join on DataFusion. A join residual with a decimal / keeps the join on
DataFusion as well.
These rules are pinned by the semantic contract tests in
algeon-cudf,
the expression contract tests in
algeon-datafusion
and the CPU comparison tests in
native_runtime_pruning_tests_gpu.