Serge Rielau created SPARK-60479:
------------------------------------

             Summary: Push down CHAR filters when read-side CHAR padding is 
enabled
                 Key: SPARK-60479
                 URL: https://issues.apache.org/jira/browse/SPARK-60479
             Project: Spark
          Issue Type: Bug
          Components: Spark Core
    Affects Versions: 5.0.0
            Reporter: Serge Rielau


spark.sql.readSideCharPadding defaults to true. For CHAR columns, 
ApplyCharTypePadding wraps the scan in 
StaticInvoke(CharVarcharCodegenUtils.readSidePadding, col, n) and strips CHAR 
metadata from the scan output.

JDBC / DSv2 filter translation (V2ExpressionBuilder / PushablePredicate) does 
not understand that StaticInvoke. A predicate such as CHAR_COL = 'Y' stays on 
the Spark side. Only pushable pieces such as IS NOT NULL go to the remote 
system, so JDBC tables (including Oracle CHAR(n)) are fully scanned.

With the flag off, the same predicate is rewritten as RPAD(col, n, ' ') = 'Y'. 
That form is translatable after SPARK-50692 / SPARK-51321, and dialects that 
implement RPAD (H2, Postgres, SQL Server) push it. Oracle's OSS dialect still 
does not list RPAD in isSupportedFunction, so Oracle JDBC would not push even 
that form today.

The padding rewrite is required for CHAR semantics. Pushdown should still 
happen, using an equivalent remote predicate.

Expected
With spark.sql.readSideCharPadding=true (and with 
spark.sql.charVarchar.standardSemantics.enabled=true, which also pads on read), 
CHAR comparisons and similar predicates against JDBC/DSv2 CHAR columns should 
push down when the dialect can evaluate the equivalent padding.

Example: WHERE prod_version_current = 'Y' on Oracle CHAR(1) should appear in 
the remote SQL as something like RPAD("PROD_VERSION_CURRENT", 1, ' ') = 'Y' (or 
an equivalent CHAR comparison), not only IS NOT NULL.

Spark-side read padding of the returned values can stay.

Proposed approach
Translate StaticInvoke of readSidePadding (and, if safe, charTypeReadSideCheck) 
in V2ExpressionBuilder to the same V2 RPAD expression already used for 
StringRPad, so existing RPAD-capable dialects keep working with the default 
config.
Add RPAD to OracleDialect.isSupportedFunction (Oracle already has RPAD).
Tests: JDBC V2 CHAR column + equality / IN / IS NOT NULL with the flag on and 
off; assert the pushed SQL contains the comparison, not only null checks. Cover 
at least H2; Oracle if the docker suite is in reach.
Do not push a bare col = 'Y' and rely on remote CHAR padding. Spark with 
read-side padding uses string equality on the padded value (RPAD(col, n, ' ') = 
lit). For CHAR(n) vs a shorter literal those are not the same as Oracle CHAR 
comparison.

Related
SPARK-40697: read-side CHAR padding (default true)
SPARK-50692: RPAD pushdown for predicate-side CHAR padding
SPARK-51321: SQL Server LPAD/RPAD
SPARK-58794: full CHAR/VARCHAR (this bug is independent of standard-semantics; 
it hits the default 3.4+ path)



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

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

Reply via email to