@@ -1046,6 +1046,36 @@ def replace_group_concat(match):
10461046
10471047 expr = re .sub (r"GROUP_CONCAT\s*\((.+?)\)" , replace_group_concat , expr , flags = re .IGNORECASE )
10481048
1049+ # TIMESTAMPDIFF(YEAR, d1, d2) → EXTRACT(YEAR FROM AGE(d2, d1))::int
1050+ # TIMESTAMPDIFF(MONTH, d1, d2) → year*12 + month from AGE
1051+ # TIMESTAMPDIFF(DAY, d1, d2) → (d2::date - d1::date)
1052+ def replace_timestampdiff (match ):
1053+ unit = match .group (1 ).upper ()
1054+ date1 = match .group (2 ).strip ()
1055+ date2 = match .group (3 ).strip ()
1056+ if unit == "YEAR" :
1057+ return f"EXTRACT(YEAR FROM AGE({ date2 } , { date1 } ))::int"
1058+ elif unit == "MONTH" :
1059+ return f"(EXTRACT(YEAR FROM AGE({ date2 } , { date1 } )) * 12 + EXTRACT(MONTH FROM AGE({ date2 } , { date1 } )))::int"
1060+ elif unit == "DAY" :
1061+ return f"({ date2 } ::date - { date1 } ::date)"
1062+ else :
1063+ # For other units, fall back to extracting from interval
1064+ return f"EXTRACT({ unit } FROM AGE({ date2 } , { date1 } ))::int"
1065+
1066+ expr = re .sub (
1067+ r"TIMESTAMPDIFF\s*\(\s*(\w+)\s*,\s*(.+?)\s*,\s*(.+?)\s*\)" ,
1068+ replace_timestampdiff ,
1069+ expr ,
1070+ flags = re .IGNORECASE ,
1071+ )
1072+
1073+ # CURDATE() → CURRENT_DATE
1074+ expr = re .sub (r"CURDATE\s*\(\s*\)" , "CURRENT_DATE" , expr , flags = re .IGNORECASE )
1075+
1076+ # NOW() → CURRENT_TIMESTAMP (already works but ensure compatibility)
1077+ expr = re .sub (r"\bNOW\s*\(\s*\)" , "CURRENT_TIMESTAMP" , expr , flags = re .IGNORECASE )
1078+
10491079 return expr
10501080
10511081 # =========================================================================
0 commit comments