Since #9108 (c4da4ff), ComparativeBoolNode::dsqlPass() converts a string literal to the type of the other operand at prepare time. The conversion is applied to every ComparativeBoolNode, including the pattern matching operators. There, the literal is a pattern matched against the text form of the operand, not a value of the operand's type. So valid queries that work in 5.0 now fail to prepare in master:
recreate table t (d date, tm time, ts timestamp, dbl double precision, df decfloat(16), i128 int128);
insert into t values (date '2024-09-05', time '10:00:00', timestamp '2024-09-05 10:00:00', 3.5, 3.5, 35);
commit;
select count(*) from t where d like '2024%'; -- conversion error from string "2024%"
select count(*) from t where d containing '-09-'; -- conversion error from string "-09-"
select count(*) from t where d starting with '2024'; -- conversion error from string "2024"
select count(*) from t where d similar to '2024%'; -- conversion error from string "2024%"
select count(*) from t where ts like '%10:00%'; -- conversion error from string "%10:00%"
select count(*) from t where tm like '10%'; -- Invalid time zone region: %
select count(*) from t where dbl like '3%'; -- conversion error from string "3%"
select count(*) from t where df like '3%'; -- conversion error from string "3%"
select count(*) from t where i128 like '3%'; -- conversion error from string "3%"
All of these return 1 in 5.0.
When the pattern happens to be a valid literal of the operand type, the result silently changes instead. The pattern is converted to a date and then back to text in the default format:
select count(*) from t where d like '5-SEP-2024'; -- master: 1, 5.0: 0
select count(*) from t where d containing '5.9.2024'; -- master: 1, 5.0: 0
Exact numerics (SMALLINT/INTEGER/BIGINT/NUMERIC) aren't affected, because MAKE_constant_from_literal() doesn't convert to them.
Proposed fix (PR #9185): call convertLiteralToOperand() only for the comparison operators (=, <>, <, <=, >, >=, IS [NOT] DISTINCT FROM, BETWEEN), where the literal really is a value of the operand type. The prepare-time conversion of #9108 is kept for those operators.
Since #9108 (c4da4ff),
ComparativeBoolNode::dsqlPass()converts a string literal to the type of the other operand at prepare time. The conversion is applied to everyComparativeBoolNode, including the pattern matching operators. There, the literal is a pattern matched against the text form of the operand, not a value of the operand's type. So valid queries that work in 5.0 now fail to prepare in master:All of these return 1 in 5.0.
When the pattern happens to be a valid literal of the operand type, the result silently changes instead. The pattern is converted to a date and then back to text in the default format:
Exact numerics (SMALLINT/INTEGER/BIGINT/NUMERIC) aren't affected, because
MAKE_constant_from_literal()doesn't convert to them.Proposed fix (PR #9185): call
convertLiteralToOperand()only for the comparison operators (=,<>,<,<=,>,>=,IS [NOT] DISTINCT FROM,BETWEEN), where the literal really is a value of the operand type. The prepare-time conversion of #9108 is kept for those operators.