kazantsev-maksim commented on PR #4744:
URL: 
https://github.com/apache/datafusion-comet/pull/4744#issuecomment-5750035150

   Thanks for the guidance, @sunchao! Moving strict masking into the native 
physical path via `ShortCircuitBinaryExpr` cleanly resolves the evaluation 
semantics without having to maintain fragile AST whitelists/blacklists in Scala.
   
   ### Implementation Details
   
   1. **`ShortCircuitBinaryExpr` (`lambda.rs`):**
      - **SQL Three-Valued Logic (3VL):**
        - **`AND`**: RHS is evaluated only when LHS is `TRUE` or `NULL` 
(skipped when LHS is strictly `FALSE`).
        - **`OR`**: RHS is evaluated only when LHS is `FALSE` or `NULL` 
(skipped when LHS is strictly `TRUE`).
      - **Zero-row / unneeded RHS short-circuit:** When no elements require RHS 
evaluation (`true_count == 0`), RHS evaluation is skipped entirely. This 
protects stateful expressions (`monotonically_increasing_id`, `rand`) and 
fallible operations (`1 DIV x`, `element_at(..., 0)`, `abs(INT_MIN)`).
      - **Masked evaluation via `evaluate_selection`:** When a subset of rows 
requires the RHS, we evaluate via DataFusion's 
`PhysicalExpr::evaluate_selection`, which filters the batch and scatters the 
result back into place while preserving original element order. The arrays are 
then combined using Arrow's Kleene boolean logic (`and_kleene` / `or_kleene`).
      - Implements `children()`, `with_new_children()`, and `fmt_sql()` to 
seamlessly support optimizer projection rewriting.
   
   2. **Recursive Planning (`planner.rs`):**
      - Added `rewrite_short_circuit_binary` in `PhysicalPlanner`, which 
recursively walks the planned lambda body tree and replaces `BinaryExpr` 
(`Operator::And` and `Operator::Or`) with `ShortCircuitBinaryExpr`.
      - Preserved `EmptyBatchGuardExpr` to protect zero-row batches at the 
outer lambda boundary.
   
   3. **Scala Serde Cleanup & Fallbacks (`CometHighOrderFunction.scala`):**
      - Removed AST whitelists for `AND` / `OR`. Supported expressions such as 
`LIKE`, string functions, and nested struct access (`x.id IS NOT NULL AND 
x.name LIKE 'a%'`) now remain fully native.
      - Retained `try-catch NonFatal` during speculative serialization to 
prevent eager planning exceptions (e.g. `cast.eval()` in guarded branches).
      - Retained codegen dispatch fallback for guarded fallible branches in 
`CASE WHEN`, `IF`, and `COALESCE`.
   
   4. **Documentation Updates:**
      - Updated the `## lambda_funcs` documentation table: `filter` is now 
documented as **`Hybrid`** (single-argument lambdas and `array_compact` run 
natively with strict per-element masking; multi-argument lambdas with index and 
unsupported shapes fall back to JVM codegen dispatch).
      - Updated ScalaDoc on `CometHighOrderFunction` and configuration 
docstrings.
   
   ### Regression Test Coverage
   
   Added native SQL fixture tests under ANSI mode covering:
   - **All 5 reported cases:**
     - Stateful counter: `x = 0 OR monotonically_increasing_id() = 0` (counter 
no longer advances speculatively).
     - PRNG state: `x = 0 OR rand(42L) > 0.5`.
     - Non-ANSI runtime failure: `x = 0 OR element_at(array(1, 2), 0) = 1` 
(index 0 is protected).
     - Arithmetic overflow: `x = 0 OR abs(-2147483648) > 0`.
     - Division by zero: `x <> 0 AND (1 DIV x) > 0` and `x = 0 OR (1 DIV x) > 
0`.
   - **Nullable boolean conditions (3VL):**
     - Evaluates RHS when LHS is `NULL` (e.g. `(x > 0) OR (x IS NULL)` 
preserving `NULL` elements).
   - **Nested predicates:**
     - Multi-level compound predicates combining `AND` and `OR` with division 
guards.
   - **Empty & mixed array batches:**
     - `[]` and `NULL` rows with `1 DIV spark_partition_id()`.
   - **Baseline control:**
     - Standard comparisons (`x > 0 AND x < 10`) continue to execute natively.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to