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:
Tom Lane 2015-03-30 14:59:49 -04:00
parent 701dcc983e
commit 542320c2bd
12 changed files with 115 additions and 102 deletions

View File

@ -78,7 +78,7 @@ SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3;
---------------------------------------------------- ----------------------------------------------------
Limit Limit
-> Index Only Scan using float4idx on float4tmp -> Index Only Scan using float4idx on float4tmp
Order By: (a <-> (-179)::real) Order By: (a <-> '-179'::real)
(3 rows) (3 rows)
SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3;

View File

@ -78,7 +78,7 @@ SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3;
----------------------------------------------------- -----------------------------------------------------
Limit Limit
-> Index Only Scan using float8idx on float8tmp -> Index Only Scan using float8idx on float8tmp
Order By: (a <-> (-1890)::double precision) Order By: (a <-> '-1890'::double precision)
(3 rows) (3 rows)
SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3;

View File

@ -78,7 +78,7 @@ SELECT a, a <-> '237' FROM int2tmp ORDER BY a <-> '237' LIMIT 3;
------------------------------------------------ ------------------------------------------------
Limit Limit
-> Index Only Scan using int2idx on int2tmp -> Index Only Scan using int2idx on int2tmp
Order By: (a <-> 237::smallint) Order By: (a <-> '237'::smallint)
(3 rows) (3 rows)
SELECT a, a <-> '237' FROM int2tmp ORDER BY a <-> '237' LIMIT 3; SELECT a, a <-> '237' FROM int2tmp ORDER BY a <-> '237' LIMIT 3;

View File

@ -75,10 +75,10 @@ SELECT count(*) FROM int8tmp WHERE a > 464571291354841::int8;
EXPLAIN (COSTS OFF) EXPLAIN (COSTS OFF)
SELECT a, a <-> '464571291354841' FROM int8tmp ORDER BY a <-> '464571291354841' LIMIT 3; SELECT a, a <-> '464571291354841' FROM int8tmp ORDER BY a <-> '464571291354841' LIMIT 3;
QUERY PLAN QUERY PLAN
--------------------------------------------------- -----------------------------------------------------
Limit Limit
-> Index Only Scan using int8idx on int8tmp -> Index Only Scan using int8idx on int8tmp
Order By: (a <-> 464571291354841::bigint) Order By: (a <-> '464571291354841'::bigint)
(3 rows) (3 rows)
SELECT a, a <-> '464571291354841' FROM int8tmp ORDER BY a <-> '464571291354841' LIMIT 3; SELECT a, a <-> '464571291354841' FROM int8tmp ORDER BY a <-> '464571291354841' LIMIT 3;

View File

@ -191,11 +191,11 @@ SET enable_bitmapscan=off;
EXPLAIN (COSTS OFF) EXPLAIN (COSTS OFF)
SELECT * FROM numerictmp WHERE a BETWEEN 1 AND 300 ORDER BY a; SELECT * FROM numerictmp WHERE a BETWEEN 1 AND 300 ORDER BY a;
QUERY PLAN QUERY PLAN
----------------------------------------------------------------- ---------------------------------------------------------------------
Sort Sort
Sort Key: a Sort Key: a
-> Index Only Scan using numericidx on numerictmp -> Index Only Scan using numericidx on numerictmp
Index Cond: ((a >= 1::numeric) AND (a <= 300::numeric)) Index Cond: ((a >= '1'::numeric) AND (a <= '300'::numeric))
(4 rows) (4 rows)
SELECT * FROM numerictmp WHERE a BETWEEN 1 AND 300 ORDER BY a; SELECT * FROM numerictmp WHERE a BETWEEN 1 AND 300 ORDER BY a;

View File

@ -874,7 +874,7 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1;
Output: c1, c2, c3, c4, c5, c6, c7, c8 Output: c1, c2, c3, c4, c5, c6, c7, c8
-> Foreign Scan on public.ft1 t1 -> Foreign Scan on public.ft1 t1
Output: c1, c2, c3, c4, c5, c6, c7, c8 Output: c1, c2, c3, c4, c5, c6, c7, c8
Filter: (t1.tableoid = 1259::oid) Filter: (t1.tableoid = '1259'::oid)
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
(6 rows) (6 rows)

View File

@ -15,6 +15,7 @@
*/ */
#include "postgres.h" #include "postgres.h"
#include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
@ -7977,6 +7978,13 @@ get_coercion_expr(Node *arg, deparse_context *context,
* right above it. Avoid generating redundant output. However, beware of * right above it. Avoid generating redundant output. However, beware of
* suppressing casts when the user actually wrote something like * suppressing casts when the user actually wrote something like
* 'foo'::text::char(3). * 'foo'::text::char(3).
*
* Note: it might seem that we are missing the possibility of needing to
* print a COLLATE clause for such a Const. However, a Const could only
* have nondefault collation in a post-constant-folding tree, in which the
* length coercion would have been folded too. See also the special
* handling of CollateExpr in coerce_to_target_type(): any collation
* marking will be above the coercion node, not below it.
*/ */
if (arg && IsA(arg, Const) && if (arg && IsA(arg, Const) &&
((Const *) arg)->consttype == resulttype && ((Const *) arg)->consttype == resulttype &&
@ -8007,8 +8015,9 @@ get_coercion_expr(Node *arg, deparse_context *context,
* the right type by default. * the right type by default.
* *
* If the Const's collation isn't default for its type, show that too. * If the Const's collation isn't default for its type, show that too.
* This can only happen in trees that have been through constant-folding. * We mustn't do this when showtype is -1 (since that means the caller will
* We assume we don't need to do this when showtype is -1. * print "::typename", and we can't put a COLLATE clause in between). It's
* caller's responsibility that collation isn't missed in such cases.
* ---------- * ----------
*/ */
static void static void
@ -8018,8 +8027,7 @@ get_const_expr(Const *constval, deparse_context *context, int showtype)
Oid typoutput; Oid typoutput;
bool typIsVarlena; bool typIsVarlena;
char *extval; char *extval;
bool isfloat = false; bool needlabel = false;
bool needlabel;
if (constval->constisnull) if (constval->constisnull)
{ {
@ -8045,40 +8053,42 @@ get_const_expr(Const *constval, deparse_context *context, int showtype)
switch (constval->consttype) switch (constval->consttype)
{ {
case INT2OID:
case INT4OID: case INT4OID:
case INT8OID:
case OIDOID:
case FLOAT4OID:
case FLOAT8OID:
case NUMERICOID:
{
/* /*
* These types are printed without quotes unless they contain * INT4 can be printed without any decoration, unless it is
* values that aren't accepted by the scanner unquoted (e.g., * negative; in that case print it as '-nnn'::integer to ensure
* 'NaN'). Note that strtod() and friends might accept NaN, * that the output will re-parse as a constant, not as a constant
* so we can't use that to test. * plus operator. In most cases we could get away with printing
* * (-nnn) instead, because of the way that gram.y handles negative
* In reality we only need to defend against infinity and NaN, * literals; but that doesn't work for INT_MIN, and it doesn't
* so we need not get too crazy about pattern matching here. * seem that much prettier anyway.
*
* There is a special-case gotcha: if the constant is signed,
* we need to parenthesize it, else the parser might see a
* leading plus/minus as binding less tightly than adjacent
* operators --- particularly, the cast that we might attach
* below.
*/ */
if (strspn(extval, "0123456789+-eE.") == strlen(extval)) if (extval[0] != '-')
{ appendStringInfoString(buf, extval);
if (extval[0] == '+' || extval[0] == '-') else
appendStringInfo(buf, "(%s)", extval); {
else appendStringInfo(buf, "'%s'", extval);
needlabel = true; /* we must attach a cast */
}
break;
case NUMERICOID:
/*
* NUMERIC can be printed without quotes if it looks like a float
* constant (not an integer, and not Infinity or NaN) and doesn't
* have a leading sign (for the same reason as for INT4).
*/
if (isdigit((unsigned char) extval[0]) &&
strcspn(extval, "eE.") != strlen(extval))
{
appendStringInfoString(buf, extval); appendStringInfoString(buf, extval);
if (strcspn(extval, "eE.") != strlen(extval))
isfloat = true; /* it looks like a float */
} }
else else
{
appendStringInfo(buf, "'%s'", extval); appendStringInfo(buf, "'%s'", extval);
needlabel = true; /* we must attach a cast */
} }
break; break;
@ -8114,18 +8124,21 @@ get_const_expr(Const *constval, deparse_context *context, int showtype)
switch (constval->consttype) switch (constval->consttype)
{ {
case BOOLOID: case BOOLOID:
case INT4OID:
case UNKNOWNOID: case UNKNOWNOID:
/* These types can be left unlabeled */ /* These types can be left unlabeled */
needlabel = false; needlabel = false;
break; break;
case INT4OID:
/* We determined above whether a label is needed */
break;
case NUMERICOID: case NUMERICOID:
/* /*
* Float-looking constants will be typed as numeric, but if * Float-looking constants will be typed as numeric, which we
* there's a specific typmod we need to show it. * checked above; but if there's a nondefault typmod we need to
* show it.
*/ */
needlabel = !isfloat || (constval->consttypmod >= 0); needlabel |= (constval->consttypmod >= 0);
break; break;
default: default:
needlabel = true; needlabel = true;

View File

@ -105,10 +105,10 @@ set enable_mergejoin = off;
explain (costs off) explain (costs off)
select * from ec0 where ff = f1 and f1 = '42'::int8; select * from ec0 where ff = f1 and f1 = '42'::int8;
QUERY PLAN QUERY PLAN
---------------------------------- -----------------------------------
Index Scan using ec0_pkey on ec0 Index Scan using ec0_pkey on ec0
Index Cond: (ff = 42::bigint) Index Cond: (ff = '42'::bigint)
Filter: (f1 = 42::bigint) Filter: (f1 = '42'::bigint)
(3 rows) (3 rows)
explain (costs off) explain (costs off)
@ -140,11 +140,11 @@ explain (costs off)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and ff = '42'::int8; select * from ec1, ec2 where ff = x1 and ff = '42'::int8;
QUERY PLAN QUERY PLAN
--------------------------------------------------------------- -------------------------------------------------------------------
Nested Loop Nested Loop
Join Filter: (ec1.ff = ec2.x1) Join Filter: (ec1.ff = ec2.x1)
-> Index Scan using ec1_pkey on ec1 -> 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 -> Seq Scan on ec2
(5 rows) (5 rows)
@ -162,13 +162,13 @@ explain (costs off)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and '42'::int8 = x1; select * from ec1, ec2 where ff = x1 and '42'::int8 = x1;
QUERY PLAN QUERY PLAN
---------------------------------------- -----------------------------------------
Nested Loop Nested Loop
Join Filter: (ec1.ff = ec2.x1) Join Filter: (ec1.ff = ec2.x1)
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = 42::bigint) Index Cond: (ff = '42'::bigint)
-> Seq Scan on ec2 -> Seq Scan on ec2
Filter: (42::bigint = x1) Filter: ('42'::bigint = x1)
(6 rows) (6 rows)
explain (costs off) explain (costs off)
@ -210,7 +210,7 @@ explain (costs off)
----------------------------------------------------- -----------------------------------------------------
Nested Loop Nested Loop
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = 42::bigint) Index Cond: (ff = '42'::bigint)
-> Append -> Append
-> Index Scan using ec1_expr2 on ec1 ec1_1 -> Index Scan using ec1_expr2 on ec1 ec1_1
Index Cond: (((ff + 2) + 1) = ec1.f1) Index Cond: (((ff + 2) + 1) = ec1.f1)
@ -230,19 +230,19 @@ explain (costs off)
select ff + 4 as x from ec1) as ss1 select ff + 4 as x from ec1) as ss1
where ss1.x = ec1.f1 and ec1.ff = 42::int8 and ec1.ff = ec1.f1; where ss1.x = ec1.f1 and ec1.ff = 42::int8 and ec1.ff = ec1.f1;
QUERY PLAN QUERY PLAN
--------------------------------------------------------------- -------------------------------------------------------------------
Nested Loop Nested Loop
Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1) Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1)
-> Index Scan using ec1_pkey on ec1 -> 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) Filter: (ff = f1)
-> Append -> Append
-> Index Scan using ec1_expr2 on ec1 ec1_1 -> 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 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 Scan using ec1_expr4 on ec1 ec1_3
Index Cond: ((ff + 4) = 42::bigint) Index Cond: ((ff + 4) = '42'::bigint)
(12 rows) (12 rows)
explain (costs off) explain (costs off)
@ -265,7 +265,7 @@ explain (costs off)
Nested Loop Nested Loop
-> Nested Loop -> Nested Loop
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = 42::bigint) Index Cond: (ff = '42'::bigint)
-> Append -> Append
-> Index Scan using ec1_expr2 on ec1 ec1_1 -> Index Scan using ec1_expr2 on ec1 ec1_1
Index Cond: (((ff + 2) + 1) = ec1.f1) Index Cond: (((ff + 2) + 1) = ec1.f1)
@ -321,7 +321,7 @@ explain (costs off)
-> Sort -> Sort
Sort Key: ec1.f1 USING < Sort Key: ec1.f1 USING <
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = 42::bigint) Index Cond: (ff = '42'::bigint)
(20 rows) (20 rows)
-- check partially indexed scan -- check partially indexed scan
@ -341,7 +341,7 @@ explain (costs off)
----------------------------------------------------- -----------------------------------------------------
Nested Loop Nested Loop
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = 42::bigint) Index Cond: (ff = '42'::bigint)
-> Append -> Append
-> Index Scan using ec1_expr2 on ec1 ec1_1 -> Index Scan using ec1_expr2 on ec1 ec1_1
Index Cond: (((ff + 2) + 1) = ec1.f1) Index Cond: (((ff + 2) + 1) = ec1.f1)
@ -378,6 +378,6 @@ explain (costs off)
-> Sort -> Sort
Sort Key: ec1.f1 USING < Sort Key: ec1.f1 USING <
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = 42::bigint) Index Cond: (ff = '42'::bigint)
(14 rows) (14 rows)

View File

@ -2545,15 +2545,15 @@ SELECT qq, unique1
USING (qq) USING (qq)
INNER JOIN tenk1 c ON qq = unique2; INNER JOIN tenk1 c ON qq = unique2;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
Nested Loop Nested Loop
-> Hash Full Join -> 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 -> Seq Scan on int8_tbl a
-> Hash -> Hash
-> Seq Scan on int8_tbl b -> Seq Scan on int8_tbl b
-> Index Scan using tenk1_unique2 on tenk1 c -> 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) (8 rows)
SELECT qq, unique1 SELECT qq, unique1
@ -3004,9 +3004,9 @@ select * from
where fault = 122 where fault = 122
order by fault; order by fault;
QUERY PLAN QUERY PLAN
----------------------------------------------------------------- --------------------------------------------------------------------------
Nested Loop Left Join 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 -> Seq Scan on int8_tbl
-> Index Scan using tenk1_unique2 on tenk1 -> Index Scan using tenk1_unique2 on tenk1
Index Cond: (int8_tbl.q2 = unique2) Index Cond: (int8_tbl.q2 = unique2)
@ -4013,13 +4013,13 @@ select * from
int8_tbl a left join int8_tbl a left join
lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; 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 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 -> Seq Scan on public.int8_tbl a
Output: a.q1, a.q2 Output: a.q1, a.q2
-> Seq Scan on public.int8_tbl b -> 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) Filter: (a.q2 = b.q1)
(7 rows) (7 rows)
@ -4236,31 +4236,31 @@ select * from
) on c.q2 = ss2.q1, ) on c.q2 = ss2.q1,
lateral (select ss2.y offset 0) ss3; lateral (select ss2.y offset 0) ss3;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop 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 -> 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) Hash Cond: (d.q1 = c.q2)
-> Nested Loop -> 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 -> 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) Hash Cond: (a.q2 = b.q1)
-> Seq Scan on public.int8_tbl a -> Seq Scan on public.int8_tbl a
Output: a.q1, a.q2 Output: a.q1, a.q2
-> Hash -> Hash
Output: b.q1, (COALESCE(b.q2, 42::bigint)) Output: b.q1, (COALESCE(b.q2, '42'::bigint))
-> Seq Scan on public.int8_tbl b -> 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 -> 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 -> Hash
Output: c.q1, c.q2 Output: c.q1, c.q2
-> Seq Scan on public.int8_tbl c -> Seq Scan on public.int8_tbl c
Output: c.q1, c.q2 Output: c.q1, c.q2
-> Result -> Result
Output: (COALESCE((COALESCE(b.q2, 42::bigint)), d.q2)) Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))
(24 rows) (24 rows)
-- case that breaks the old ph_may_need optimization -- case that breaks the old ph_may_need optimization

View File

@ -285,9 +285,9 @@ explain (costs off)
select * from int8_tbl i8 select * from int8_tbl i8
where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)'); where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)');
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------
Seq Scan on int8_tbl i8 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) (2 rows)
select * from int8_tbl i8 select * from int8_tbl i8

View File

@ -655,12 +655,12 @@ SELECT * FROM
SELECT 2 AS t, 4 AS x) ss SELECT 2 AS t, 4 AS x) ss
WHERE x > 3; WHERE x > 3;
QUERY PLAN QUERY PLAN
---------------------------------------------------------------------------- ------------------------------------------------------------------------------
Subquery Scan on ss Subquery Scan on ss
Filter: (ss.x > 3) Filter: (ss.x > 3)
-> Unique -> Unique
-> Sort -> Sort
Sort Key: (1), (((random() * 3::double precision))::integer) Sort Key: (1), (((random() * '3'::double precision))::integer)
-> Append -> Append
-> Result -> Result
-> Result -> Result

View File

@ -2084,7 +2084,7 @@ EXPLAIN (VERBOSE, COSTS OFF)
WITH wcte AS ( INSERT INTO int8_tbl VALUES ( 42, 47 ) RETURNING q2 ) WITH wcte AS ( INSERT INTO int8_tbl VALUES ( 42, 47 ) RETURNING q2 )
DELETE FROM a USING wcte WHERE aa = q2; DELETE FROM a USING wcte WHERE aa = q2;
QUERY PLAN QUERY PLAN
------------------------------------------------ ----------------------------------------------------
Delete on public.a Delete on public.a
Delete on public.a Delete on public.a
Delete on public.b Delete on public.b
@ -2094,7 +2094,7 @@ DELETE FROM a USING wcte WHERE aa = q2;
-> Insert on public.int8_tbl -> Insert on public.int8_tbl
Output: int8_tbl.q2 Output: int8_tbl.q2
-> Result -> Result
Output: 42::bigint, 47::bigint Output: '42'::bigint, '47'::bigint
-> Nested Loop -> Nested Loop
Output: a.ctid, wcte.* Output: a.ctid, wcte.*
Join Filter: (a.aa = wcte.q2) Join Filter: (a.aa = wcte.q2)