mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Be more careful about printing constants in ruleutils.c.
The previous coding in get_const_expr() tried to avoid quoting integer, float, and numeric literals if at all possible. While that looks nice, it means that dumped expressions might re-parse to something that's semantically equivalent but not the exact same parsetree; for example a FLOAT8 constant would re-parse as a NUMERIC constant with a cast to FLOAT8. Though the result would be the same after constant-folding, this is problematic in certain contexts. In particular, Jeff Davis pointed out that this could cause unexpected failures in ALTER INHERIT operations because of child tables having not-exactly-equivalent CHECK expressions. Therefore, favor correctness over legibility and dump such constants in quotes except in the limited cases where they'll be interpreted as the same type even without any casting. This results in assorted small changes in the regression test outputs, and will affect display of user-defined views and rules similarly. The odds of that causing problems in the field seem non-negligible; given the lack of previous complaints, it seems best not to change this in the back branches.
This commit is contained in:
@ -104,11 +104,11 @@ set enable_mergejoin = off;
|
||||
--
|
||||
explain (costs off)
|
||||
select * from ec0 where ff = f1 and f1 = '42'::int8;
|
||||
QUERY PLAN
|
||||
----------------------------------
|
||||
QUERY PLAN
|
||||
-----------------------------------
|
||||
Index Scan using ec0_pkey on ec0
|
||||
Index Cond: (ff = 42::bigint)
|
||||
Filter: (f1 = 42::bigint)
|
||||
Index Cond: (ff = '42'::bigint)
|
||||
Filter: (f1 = '42'::bigint)
|
||||
(3 rows)
|
||||
|
||||
explain (costs off)
|
||||
@ -139,12 +139,12 @@ explain (costs off)
|
||||
|
||||
explain (costs off)
|
||||
select * from ec1, ec2 where ff = x1 and ff = '42'::int8;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------
|
||||
Nested Loop
|
||||
Join Filter: (ec1.ff = ec2.x1)
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: ((ff = 42::bigint) AND (ff = 42::bigint))
|
||||
Index Cond: ((ff = '42'::bigint) AND (ff = '42'::bigint))
|
||||
-> Seq Scan on ec2
|
||||
(5 rows)
|
||||
|
||||
@ -161,14 +161,14 @@ explain (costs off)
|
||||
|
||||
explain (costs off)
|
||||
select * from ec1, ec2 where ff = x1 and '42'::int8 = x1;
|
||||
QUERY PLAN
|
||||
----------------------------------------
|
||||
QUERY PLAN
|
||||
-----------------------------------------
|
||||
Nested Loop
|
||||
Join Filter: (ec1.ff = ec2.x1)
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: (ff = 42::bigint)
|
||||
Index Cond: (ff = '42'::bigint)
|
||||
-> Seq Scan on ec2
|
||||
Filter: (42::bigint = x1)
|
||||
Filter: ('42'::bigint = x1)
|
||||
(6 rows)
|
||||
|
||||
explain (costs off)
|
||||
@ -210,7 +210,7 @@ explain (costs off)
|
||||
-----------------------------------------------------
|
||||
Nested Loop
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: (ff = 42::bigint)
|
||||
Index Cond: (ff = '42'::bigint)
|
||||
-> Append
|
||||
-> Index Scan using ec1_expr2 on ec1 ec1_1
|
||||
Index Cond: (((ff + 2) + 1) = ec1.f1)
|
||||
@ -229,20 +229,20 @@ explain (costs off)
|
||||
union all
|
||||
select ff + 4 as x from ec1) as ss1
|
||||
where ss1.x = ec1.f1 and ec1.ff = 42::int8 and ec1.ff = ec1.f1;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------
|
||||
Nested Loop
|
||||
Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1)
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: ((ff = 42::bigint) AND (ff = 42::bigint))
|
||||
Index Cond: ((ff = '42'::bigint) AND (ff = '42'::bigint))
|
||||
Filter: (ff = f1)
|
||||
-> Append
|
||||
-> Index Scan using ec1_expr2 on ec1 ec1_1
|
||||
Index Cond: (((ff + 2) + 1) = 42::bigint)
|
||||
Index Cond: (((ff + 2) + 1) = '42'::bigint)
|
||||
-> Index Scan using ec1_expr3 on ec1 ec1_2
|
||||
Index Cond: (((ff + 3) + 1) = 42::bigint)
|
||||
Index Cond: (((ff + 3) + 1) = '42'::bigint)
|
||||
-> Index Scan using ec1_expr4 on ec1 ec1_3
|
||||
Index Cond: ((ff + 4) = 42::bigint)
|
||||
Index Cond: ((ff + 4) = '42'::bigint)
|
||||
(12 rows)
|
||||
|
||||
explain (costs off)
|
||||
@ -265,7 +265,7 @@ explain (costs off)
|
||||
Nested Loop
|
||||
-> Nested Loop
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: (ff = 42::bigint)
|
||||
Index Cond: (ff = '42'::bigint)
|
||||
-> Append
|
||||
-> Index Scan using ec1_expr2 on ec1 ec1_1
|
||||
Index Cond: (((ff + 2) + 1) = ec1.f1)
|
||||
@ -321,7 +321,7 @@ explain (costs off)
|
||||
-> Sort
|
||||
Sort Key: ec1.f1 USING <
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: (ff = 42::bigint)
|
||||
Index Cond: (ff = '42'::bigint)
|
||||
(20 rows)
|
||||
|
||||
-- check partially indexed scan
|
||||
@ -341,7 +341,7 @@ explain (costs off)
|
||||
-----------------------------------------------------
|
||||
Nested Loop
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: (ff = 42::bigint)
|
||||
Index Cond: (ff = '42'::bigint)
|
||||
-> Append
|
||||
-> Index Scan using ec1_expr2 on ec1 ec1_1
|
||||
Index Cond: (((ff + 2) + 1) = ec1.f1)
|
||||
@ -378,6 +378,6 @@ explain (costs off)
|
||||
-> Sort
|
||||
Sort Key: ec1.f1 USING <
|
||||
-> Index Scan using ec1_pkey on ec1
|
||||
Index Cond: (ff = 42::bigint)
|
||||
Index Cond: (ff = '42'::bigint)
|
||||
(14 rows)
|
||||
|
||||
|
@ -2544,16 +2544,16 @@ SELECT qq, unique1
|
||||
( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2
|
||||
USING (qq)
|
||||
INNER JOIN tenk1 c ON qq = unique2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
Nested Loop
|
||||
-> Hash Full Join
|
||||
Hash Cond: (COALESCE(a.q1, 0::bigint) = COALESCE(b.q2, (-1)::bigint))
|
||||
Hash Cond: (COALESCE(a.q1, '0'::bigint) = COALESCE(b.q2, '-1'::bigint))
|
||||
-> Seq Scan on int8_tbl a
|
||||
-> Hash
|
||||
-> Seq Scan on int8_tbl b
|
||||
-> Index Scan using tenk1_unique2 on tenk1 c
|
||||
Index Cond: (unique2 = COALESCE((COALESCE(a.q1, 0::bigint)), (COALESCE(b.q2, (-1)::bigint))))
|
||||
Index Cond: (unique2 = COALESCE((COALESCE(a.q1, '0'::bigint)), (COALESCE(b.q2, '-1'::bigint))))
|
||||
(8 rows)
|
||||
|
||||
SELECT qq, unique1
|
||||
@ -3003,10 +3003,10 @@ select * from
|
||||
) ss
|
||||
where fault = 122
|
||||
order by fault;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------------------------
|
||||
Nested Loop Left Join
|
||||
Filter: ((COALESCE(tenk1.unique1, (-1)) + int8_tbl.q1) = 122)
|
||||
Filter: ((COALESCE(tenk1.unique1, '-1'::integer) + int8_tbl.q1) = 122)
|
||||
-> Seq Scan on int8_tbl
|
||||
-> Index Scan using tenk1_unique2 on tenk1
|
||||
Index Cond: (int8_tbl.q2 = unique2)
|
||||
@ -4012,14 +4012,14 @@ explain (verbose, costs off)
|
||||
select * from
|
||||
int8_tbl a left join
|
||||
lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------
|
||||
Nested Loop Left Join
|
||||
Output: a.q1, a.q2, b.q1, b.q2, (COALESCE(a.q2, 42::bigint))
|
||||
Output: a.q1, a.q2, b.q1, b.q2, (COALESCE(a.q2, '42'::bigint))
|
||||
-> Seq Scan on public.int8_tbl a
|
||||
Output: a.q1, a.q2
|
||||
-> Seq Scan on public.int8_tbl b
|
||||
Output: b.q1, b.q2, COALESCE(a.q2, 42::bigint)
|
||||
Output: b.q1, b.q2, COALESCE(a.q2, '42'::bigint)
|
||||
Filter: (a.q2 = b.q1)
|
||||
(7 rows)
|
||||
|
||||
@ -4235,32 +4235,32 @@ select * from
|
||||
lateral (select q1, coalesce(ss1.x,q2) as y from int8_tbl d) ss2
|
||||
) on c.q2 = ss2.q1,
|
||||
lateral (select ss2.y offset 0) ss3;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Nested Loop
|
||||
Output: c.q1, c.q2, a.q1, a.q2, b.q1, (COALESCE(b.q2, 42::bigint)), d.q1, (COALESCE((COALESCE(b.q2, 42::bigint)), d.q2)), ((COALESCE((COALESCE(b.q2, 42::bigint)), d.q2)))
|
||||
Output: c.q1, c.q2, a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)), d.q1, (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)), ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)))
|
||||
-> Hash Right Join
|
||||
Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, 42::bigint)), (COALESCE((COALESCE(b.q2, 42::bigint)), d.q2))
|
||||
Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))
|
||||
Hash Cond: (d.q1 = c.q2)
|
||||
-> Nested Loop
|
||||
Output: a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, 42::bigint)), (COALESCE((COALESCE(b.q2, 42::bigint)), d.q2))
|
||||
Output: a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))
|
||||
-> Hash Left Join
|
||||
Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, 42::bigint))
|
||||
Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint))
|
||||
Hash Cond: (a.q2 = b.q1)
|
||||
-> Seq Scan on public.int8_tbl a
|
||||
Output: a.q1, a.q2
|
||||
-> Hash
|
||||
Output: b.q1, (COALESCE(b.q2, 42::bigint))
|
||||
Output: b.q1, (COALESCE(b.q2, '42'::bigint))
|
||||
-> Seq Scan on public.int8_tbl b
|
||||
Output: b.q1, COALESCE(b.q2, 42::bigint)
|
||||
Output: b.q1, COALESCE(b.q2, '42'::bigint)
|
||||
-> Seq Scan on public.int8_tbl d
|
||||
Output: d.q1, COALESCE((COALESCE(b.q2, 42::bigint)), d.q2)
|
||||
Output: d.q1, COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)
|
||||
-> Hash
|
||||
Output: c.q1, c.q2
|
||||
-> Seq Scan on public.int8_tbl c
|
||||
Output: c.q1, c.q2
|
||||
-> Result
|
||||
Output: (COALESCE((COALESCE(b.q2, 42::bigint)), d.q2))
|
||||
Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))
|
||||
(24 rows)
|
||||
|
||||
-- case that breaks the old ph_may_need optimization
|
||||
|
@ -284,10 +284,10 @@ ERROR: cannot compare dissimilar column types bigint and integer at record colu
|
||||
explain (costs off)
|
||||
select * from int8_tbl i8
|
||||
where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)');
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
Seq Scan on int8_tbl i8
|
||||
Filter: (i8.* = ANY (ARRAY[ROW(123::bigint, 456::bigint)::int8_tbl, '(4567890123456789,123)'::int8_tbl]))
|
||||
Filter: (i8.* = ANY (ARRAY[ROW('123'::bigint, '456'::bigint)::int8_tbl, '(4567890123456789,123)'::int8_tbl]))
|
||||
(2 rows)
|
||||
|
||||
select * from int8_tbl i8
|
||||
|
@ -654,13 +654,13 @@ SELECT * FROM
|
||||
UNION
|
||||
SELECT 2 AS t, 4 AS x) ss
|
||||
WHERE x > 3;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------
|
||||
Subquery Scan on ss
|
||||
Filter: (ss.x > 3)
|
||||
-> Unique
|
||||
-> Sort
|
||||
Sort Key: (1), (((random() * 3::double precision))::integer)
|
||||
Sort Key: (1), (((random() * '3'::double precision))::integer)
|
||||
-> Append
|
||||
-> Result
|
||||
-> Result
|
||||
|
@ -2083,8 +2083,8 @@ SELECT * FROM parent;
|
||||
EXPLAIN (VERBOSE, COSTS OFF)
|
||||
WITH wcte AS ( INSERT INTO int8_tbl VALUES ( 42, 47 ) RETURNING q2 )
|
||||
DELETE FROM a USING wcte WHERE aa = q2;
|
||||
QUERY PLAN
|
||||
------------------------------------------------
|
||||
QUERY PLAN
|
||||
----------------------------------------------------
|
||||
Delete on public.a
|
||||
Delete on public.a
|
||||
Delete on public.b
|
||||
@ -2094,7 +2094,7 @@ DELETE FROM a USING wcte WHERE aa = q2;
|
||||
-> Insert on public.int8_tbl
|
||||
Output: int8_tbl.q2
|
||||
-> Result
|
||||
Output: 42::bigint, 47::bigint
|
||||
Output: '42'::bigint, '47'::bigint
|
||||
-> Nested Loop
|
||||
Output: a.ctid, wcte.*
|
||||
Join Filter: (a.aa = wcte.q2)
|
||||
|
Reference in New Issue
Block a user