adriangb commented on code in PR #23729:
URL: https://github.com/apache/datafusion/pull/23729#discussion_r3639500452


##########
datafusion/sqllogictest/test_files/simplify_expr.slt:
##########
@@ -146,3 +146,235 @@ logical_plan
 physical_plan
 01)ProjectionExec: expr=[column1@0 = 1 as opt1, column1@0 = 2 AND column1@0 != 
2 as noopt1, column1@0 = 4 as opt2, column1@0 != 5 AND column1@0 = 5 as noopt2]
 02)--DataSourceExec: partitions=1, partition_sizes=[1]
+
+# ------------------------------------------------------------------------
+# Unwrapping Date32 <-> Date64 casts in comparison predicates.
+#
+# `Date32` counts whole days since the epoch; `Date64` counts milliseconds.
+# Widening a `Date32` column up to `Date64` (`date32_col -> Date64`) is
+# injective, so a comparison against a whole-day `Date64` literal can be
+# rewritten onto the bare `Date32` column. Narrowing a `Date64` column down to
+# `Date32` truncates the milliseconds to the day (many-to-one) and must NOT be
+# rewritten: `CAST(date64 AS Date32) = <day>` matches any millisecond within
+# that day. Arrow does not require `Date64` values to fall on a day boundary
+# (arrow-rs#5288), so the table below intentionally stores sub-day `Date64`
+# values (ids 2 and 4) to exercise that hazard.
+#
+# The `Date64` column is built from raw millisecond values with `arrow_cast`;
+# `2025-01-01 00:00` = 1735689600000 ms (day 20089), `2025-01-01 12:00` adds
+# 43200000 ms. `1969-12-31 00:00` = -86400000 ms (day -1); `1969-12-31 12:00`
+# = -43200000 ms (a pre-epoch sub-day value).
+statement ok
+create table date_unwrap as
+select
+  c.id,
+  arrow_cast(c.d32, 'Date32') as d32,
+  arrow_cast(c.d64ms, 'Date64') as d64
+from (values
+  (1, '2025-01-01', 1735689600000),
+  (2, '2025-01-01', 1735732800000),
+  (3, '1969-12-31', -86400000),
+  (4, '1969-12-31', -43200000),
+  (5, NULL,         NULL)
+) as c(id, d32, d64ms);
+
+query IDD
+select id, d32, d64 from date_unwrap order by id;
+----
+1 2025-01-01 2025-01-01T00:00:00
+2 2025-01-01 2025-01-01T12:00:00
+3 1969-12-31 1969-12-31T00:00:00
+4 1969-12-31 1969-12-31T12:00:00
+5 NULL NULL
+
+# --- Widening Date32 -> Date64: folds onto the bare column ---------------
+# The plan for these widening queries is what changes when the optimization is
+# enabled: the CAST moves off the column and onto the (whole-day) literal.
+query TT
+explain select id from date_unwrap where arrow_cast(d32, 'Date64') = 
arrow_cast(1735689600000, 'Date64');
+----
+logical_plan
+01)Projection: date_unwrap.id
+02)--Filter: date_unwrap.d32 = Date32("2025-01-01")
+03)----TableScan: date_unwrap projection=[id, d32]
+physical_plan
+01)FilterExec: d32@1 = 2025-01-01, projection=[id@0]
+02)--DataSourceExec: partitions=1, partition_sizes=[1]
+
+query I
+select id from date_unwrap where arrow_cast(d32, 'Date64') = 
arrow_cast(1735689600000, 'Date64') order by id;
+----
+1
+2
+
+# Range operators fold too (Date32 -> Date64 is monotonic).

Review Comment:
   Added 73ff3d1



-- 
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