Description:
These two queries are equivalent because they implement the same filtering logic, albeit with different syntax.
In the original query, the COALESCE function evaluates the first condition (lineitem.l_returnflag) <= (lineitem.l_commitdate). If this condition is not NULL, it is used for filtering. Otherwise, the second condition ( 'p' ) in (lineitem.l_receiptdate, lineitem.l_linestatus) is evaluated.
In the rewritten query, a CASE WHEN statement explicitly handles the logic of COALESCE. If (l_returnflag <= l_commitdate) is not NULL, it uses this condition for filtering. Otherwise, it evaluates whether cast('p' as date) equals l_receiptdate or 'p' equals l_linestatus.
Both queries ultimately evaluate the same filtering criteria: prioritize the first condition if it is not NULL, and fallback to the second condition otherwise.
Further analysis reveals that in the query, the string 'p' is compared with two columns. In the rewritten SQL, explicit type conversion is used, causing 'p' to be explicitly cast to a date type. Although the original query performs an implicit type conversion to convert 'p' to a date type, the explicit type conversion in the rewritten SQL leads to the error.
How to repeat:
This link provides the exported sql file for the database:
https://github.com/LLuopeiqi/newtpcd/blob/main/mysql/tpcd.sql
--original
select all lineitem.l_commitdate as ref0 from lineitem
where coalesce((lineitem.l_returnflag) <= (lineitem.l_commitdate),
( 'p' ) in (lineitem.l_receiptdate, lineitem.l_linestatus));
return 6005 rows
--rewritten
SELECT l_commitdate AS ref0 FROM lineitem
WHERE CASE WHEN l_returnflag <= l_commitdate IS NOT NULL
THEN l_returnflag <= l_commitdate
ELSE cast('p' as date) = l_receiptdate OR 'p' = l_linestatus END;
return 5905 rows