Hi,

EXPLAIN command doesn't show testexpr. Sometimes it is not easy to understand a query plan. That I mean:

CREATE TABLE a (x integer, y integer);
EXPLAIN (COSTS OFF, VERBOSE) SELECT x, y FROM a upper
  WHERE y IN (SELECT y FROM a WHERE upper.y = x);
EXPLAIN (COSTS OFF, VERBOSE) SELECT x, y FROM a upper
  WHERE x+y IN (SELECT y FROM a WHERE upper.y = x);

These two explains have the same representation:
Seq Scan on public.a upper
   Output: upper.x, upper.y
   Filter: (SubPlan 1)
   SubPlan 1
     ->  Seq Scan on public.a
           Output: a.y
           Filter: (upper.y = a.x)

It is a bit annoying when you don't have original query or don't trust competence of a user who sent you this explain. In attachment - patch which solves this problem. I'm not completely sure that this option really needed and patch presents a proof of concept only.

--
regards,
Andrey Lepikhov
Postgres Professional
From db440802d84a96a98d0fb30672232e81e10c4598 Mon Sep 17 00:00:00 2001
From: Andrey Lepikhov <a.lepik...@postgrespro.ru>
Date: Tue, 24 Aug 2021 10:59:00 +0500
Subject: [PATCH] Improve EXPLAIN presentation

---
 src/backend/utils/adt/ruleutils.c             | 101 +++++++++++-------
 src/test/regress/expected/insert_conflict.out |   2 +-
 src/test/regress/expected/join.out            |   2 +-
 src/test/regress/expected/rowsecurity.out     |   6 +-
 src/test/regress/expected/select_parallel.out |  12 +--
 src/test/regress/expected/subselect.out       |  40 +++----
 src/test/regress/expected/updatable_views.out |  24 ++---
 7 files changed, 106 insertions(+), 81 deletions(-)

diff --git a/src/backend/utils/adt/ruleutils.c 
b/src/backend/utils/adt/ruleutils.c
index 4df8cc5abf..1c25769633 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -455,7 +455,10 @@ static void get_const_expr(Const *constval, 
deparse_context *context,
                                                   int showtype);
 static void get_const_collation(Const *constval, deparse_context *context);
 static void simple_quote_literal(StringInfo buf, const char *val);
+static void get_subplan_expr(SubPlan *subplan, deparse_context *context);
 static void get_sublink_expr(SubLink *sublink, deparse_context *context);
+static bool get_subselect_expr(SubLinkType subLinkType, Node *testexpr,
+                                                          deparse_context 
*context);
 static void get_tablefunc(TableFunc *tf, deparse_context *context,
                                                  bool showimplicit);
 static void get_from_clause(Query *query, const char *prefix,
@@ -8536,20 +8539,7 @@ get_rule_expr(Node *node, deparse_context *context,
                        break;
 
                case T_SubPlan:
-                       {
-                               SubPlan    *subplan = (SubPlan *) node;
-
-                               /*
-                                * We cannot see an already-planned subplan in 
rule deparsing,
-                                * only while EXPLAINing a query plan.  We 
don't try to
-                                * reconstruct the original SQL, just reference 
the subplan
-                                * that appears elsewhere in EXPLAIN's result.
-                                */
-                               if (subplan->useHashTable)
-                                       appendStringInfo(buf, "(hashed %s)", 
subplan->plan_name);
-                               else
-                                       appendStringInfo(buf, "(%s)", 
subplan->plan_name);
-                       }
+                       get_subplan_expr((SubPlan *) node, context);
                        break;
 
                case T_AlternativeSubPlan:
@@ -10358,6 +10348,31 @@ simple_quote_literal(StringInfo buf, const char *val)
 }
 
 
+static void
+get_subplan_expr(SubPlan *subplan, deparse_context *context)
+{
+       StringInfo      buf = context->buf;
+
+       if (subplan->testexpr)
+               appendStringInfoChar(buf, '(');
+
+       (void) get_subselect_expr(subplan->subLinkType, subplan->testexpr, 
context);
+
+       /*
+        * We cannot see an already-planned subplan in rule deparsing,
+        * only while EXPLAINing a query plan.  We don't try to
+        * reconstruct the original SQL, just reference the subplan
+        * that appears elsewhere in EXPLAIN's result.
+        */
+       if (subplan->useHashTable)
+               appendStringInfo(buf, "(hashed %s)", subplan->plan_name);
+       else
+               appendStringInfo(buf, "(%s)", subplan->plan_name);
+
+       if (subplan->testexpr)
+               appendStringInfoChar(buf, ')');
+}
+
 /* ----------
  * get_sublink_expr                    - Parse back a sublink
  * ----------
@@ -10367,14 +10382,35 @@ get_sublink_expr(SubLink *sublink, deparse_context 
*context)
 {
        StringInfo      buf = context->buf;
        Query      *query = (Query *) (sublink->subselect);
-       char       *opname = NULL;
-       bool            need_paren;
+       bool            need_paren = true;
 
        if (sublink->subLinkType == ARRAY_SUBLINK)
                appendStringInfoString(buf, "ARRAY(");
        else
                appendStringInfoChar(buf, '(');
 
+       need_paren = get_subselect_expr(sublink->subLinkType, 
sublink->testexpr, context);
+
+       if (need_paren)
+               appendStringInfoChar(buf, '(');
+
+       get_query_def(query, buf, context->namespaces, NULL,
+                                 context->prettyFlags, context->wrapColumn,
+                                 context->indentLevel);
+
+       if (need_paren)
+               appendStringInfoString(buf, "))");
+       else if (query)
+               appendStringInfoChar(buf, ')');
+}
+
+static bool
+get_subselect_expr(SubLinkType subLinkType, Node *testexpr, deparse_context 
*context)
+{
+       StringInfo      buf = context->buf;
+       char       *opname = NULL;
+       bool            need_paren;
+
        /*
         * Note that we print the name of only the first operator, when there 
are
         * multiple combining operators.  This is an approximation that could go
@@ -10382,19 +10418,19 @@ get_sublink_expr(SubLink *sublink, deparse_context 
*context)
         * operators, etc) but there is not a whole lot we can do about it, 
since
         * the syntax allows only one operator to be shown.
         */
-       if (sublink->testexpr)
+       if (testexpr)
        {
-               if (IsA(sublink->testexpr, OpExpr))
+               if (IsA(testexpr, OpExpr))
                {
                        /* single combining operator */
-                       OpExpr     *opexpr = (OpExpr *) sublink->testexpr;
+                       OpExpr     *opexpr = (OpExpr *) testexpr;
 
                        get_rule_expr(linitial(opexpr->args), context, true);
                        opname = generate_operator_name(opexpr->opno,
                                                                                
        exprType(linitial(opexpr->args)),
                                                                                
        exprType(lsecond(opexpr->args)));
                }
-               else if (IsA(sublink->testexpr, BoolExpr))
+               else if (IsA(testexpr, BoolExpr))
                {
                        /* multiple combining operators, = or <> cases */
                        char       *sep;
@@ -10402,7 +10438,7 @@ get_sublink_expr(SubLink *sublink, deparse_context 
*context)
 
                        appendStringInfoChar(buf, '(');
                        sep = "";
-                       foreach(l, ((BoolExpr *) sublink->testexpr)->args)
+                       foreach(l, ((BoolExpr *) testexpr)->args)
                        {
                                OpExpr     *opexpr = lfirst_node(OpExpr, l);
 
@@ -10416,10 +10452,10 @@ get_sublink_expr(SubLink *sublink, deparse_context 
*context)
                        }
                        appendStringInfoChar(buf, ')');
                }
-               else if (IsA(sublink->testexpr, RowCompareExpr))
+               else if (IsA(testexpr, RowCompareExpr))
                {
                        /* multiple combining operators, < <= > >= cases */
-                       RowCompareExpr *rcexpr = (RowCompareExpr *) 
sublink->testexpr;
+                       RowCompareExpr *rcexpr = (RowCompareExpr *) testexpr;
 
                        appendStringInfoChar(buf, '(');
                        get_rule_expr((Node *) rcexpr->largs, context, true);
@@ -10430,12 +10466,12 @@ get_sublink_expr(SubLink *sublink, deparse_context 
*context)
                }
                else
                        elog(ERROR, "unrecognized testexpr type: %d",
-                                (int) nodeTag(sublink->testexpr));
+                                (int) nodeTag(testexpr));
        }
 
        need_paren = true;
 
-       switch (sublink->subLinkType)
+       switch (subLinkType)
        {
                case EXISTS_SUBLINK:
                        appendStringInfoString(buf, "EXISTS ");
@@ -10465,21 +10501,10 @@ get_sublink_expr(SubLink *sublink, deparse_context 
*context)
                case CTE_SUBLINK:               /* shouldn't occur in a SubLink 
*/
                default:
                        elog(ERROR, "unrecognized sublink type: %d",
-                                (int) sublink->subLinkType);
+                                (int) subLinkType);
                        break;
        }
-
-       if (need_paren)
-               appendStringInfoChar(buf, '(');
-
-       get_query_def(query, buf, context->namespaces, NULL,
-                                 context->prettyFlags, context->wrapColumn,
-                                 context->indentLevel);
-
-       if (need_paren)
-               appendStringInfoString(buf, "))");
-       else
-               appendStringInfoChar(buf, ')');
+       return need_paren;
 }
 
 
diff --git a/src/test/regress/expected/insert_conflict.out 
b/src/test/regress/expected/insert_conflict.out
index 66d8633e3e..8ac7756925 100644
--- a/src/test/regress/expected/insert_conflict.out
+++ b/src/test/regress/expected/insert_conflict.out
@@ -50,7 +50,7 @@ explain (costs off) insert into insertconflicttest values(0, 
'Crowberry') on con
  Insert on insertconflicttest
    Conflict Resolution: UPDATE
    Conflict Arbiter Indexes: op_index_key, collation_index_key, both_index_key
-   Conflict Filter: (SubPlan 1)
+   Conflict Filter: EXISTS (SubPlan 1)
    ->  Result
    SubPlan 1
      ->  Index Only Scan using both_index_expr_key on insertconflicttest ii
diff --git a/src/test/regress/expected/join.out 
b/src/test/regress/expected/join.out
index f3589d0dbb..bfc50f7a75 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -5899,7 +5899,7 @@ lateral (select * from int8_tbl t1,
                Filter: (t1.q1 = ss2.q2)
                ->  Seq Scan on public.int8_tbl t2
                      Output: t2.q1, t2.q2
-                     Filter: (SubPlan 3)
+                     Filter: (t2.q1 IN (SubPlan 3))
                      SubPlan 3
                        ->  Result
                              Output: t3.q2
diff --git a/src/test/regress/expected/rowsecurity.out 
b/src/test/regress/expected/rowsecurity.out
index 89397e41f0..1e34c41480 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -1440,7 +1440,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM only s1 WHERE f_leak(b);
                         QUERY PLAN                         
 -----------------------------------------------------------
  Seq Scan on s1
-   Filter: ((hashed SubPlan 1) AND f_leak(b))
+   Filter: ((a IN (hashed SubPlan 1)) AND f_leak(b))
    SubPlan 1
      ->  Seq Scan on s2
            Filter: (((x % 2) = 0) AND (y ~~ '%2f%'::text))
@@ -1462,7 +1462,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM s1 WHERE f_leak(b);
                         QUERY PLAN                         
 -----------------------------------------------------------
  Seq Scan on s1
-   Filter: ((hashed SubPlan 1) AND f_leak(b))
+   Filter: ((a IN (hashed SubPlan 1)) AND f_leak(b))
    SubPlan 1
      ->  Seq Scan on s2
            Filter: (((x % 2) = 0) AND (y ~~ '%af%'::text))
@@ -1484,7 +1484,7 @@ EXPLAIN (COSTS OFF) SELECT (SELECT x FROM s1 LIMIT 1) xx, 
* FROM s2 WHERE y like
    SubPlan 2
      ->  Limit
            ->  Seq Scan on s1
-                 Filter: (hashed SubPlan 1)
+                 Filter: (a IN (hashed SubPlan 1))
                  SubPlan 1
                    ->  Seq Scan on s2 s2_1
                          Filter: (((x % 2) = 0) AND (y ~~ '%af%'::text))
diff --git a/src/test/regress/expected/select_parallel.out 
b/src/test/regress/expected/select_parallel.out
index 4ea1aa7dfd..bd77033882 100644
--- a/src/test/regress/expected/select_parallel.out
+++ b/src/test/regress/expected/select_parallel.out
@@ -291,14 +291,14 @@ alter table tenk2 set (parallel_workers = 0);
 explain (costs off)
        select count(*) from tenk1 where (two, four) not in
        (select hundred, thousand from tenk2 where thousand > 100);
-                      QUERY PLAN                      
-------------------------------------------------------
+                              QUERY PLAN                               
+-----------------------------------------------------------------------
  Finalize Aggregate
    ->  Gather
          Workers Planned: 4
          ->  Partial Aggregate
                ->  Parallel Seq Scan on tenk1
-                     Filter: (NOT (hashed SubPlan 1))
+                     Filter: (NOT ((two, four) IN (hashed SubPlan 1)))
                      SubPlan 1
                        ->  Seq Scan on tenk2
                              Filter: (thousand > 100)
@@ -315,10 +315,10 @@ select count(*) from tenk1 where (two, four) not in
 explain (costs off)
        select * from tenk1 where (unique1 + random())::integer not in
        (select ten from tenk2);
-             QUERY PLAN             
-------------------------------------
+                                         QUERY PLAN                            
              
+---------------------------------------------------------------------------------------------
  Seq Scan on tenk1
-   Filter: (NOT (hashed SubPlan 1))
+   Filter: (NOT ((((unique1)::double precision + random()))::integer IN 
(hashed SubPlan 1)))
    SubPlan 1
      ->  Seq Scan on tenk2
 (4 rows)
diff --git a/src/test/regress/expected/subselect.out 
b/src/test/regress/expected/subselect.out
index 30615dd6bc..2bc2f0ba56 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -258,7 +258,7 @@ select 1 = all (select (select 1));
             QUERY PLAN             
 -----------------------------------
  Result
-   Output: (SubPlan 2)
+   Output: (1 = ALL (SubPlan 2))
    SubPlan 2
      ->  Materialize
            Output: ($0)
@@ -308,7 +308,7 @@ select * from int4_tbl o where exists
               QUERY PLAN              
 --------------------------------------
  Seq Scan on int4_tbl o
-   Filter: (SubPlan 1)
+   Filter: EXISTS (SubPlan 1)
    SubPlan 1
      ->  Limit
            ->  Seq Scan on int4_tbl i
@@ -771,10 +771,10 @@ select * from outer_text where (f1, f2) not in (select * 
from inner_text);
 --
 explain (verbose, costs off)
 select 'foo'::text in (select 'bar'::name union all select 'bar'::name);
-             QUERY PLAN              
--------------------------------------
+                  QUERY PLAN                   
+-----------------------------------------------
  Result
-   Output: (hashed SubPlan 1)
+   Output: ('foo'::text IN (hashed SubPlan 1))
    SubPlan 1
      ->  Append
            ->  Result
@@ -815,10 +815,10 @@ language sql as 'select $1::text = $2';
 create operator = (procedure=bogus_int8_text_eq, leftarg=int8, rightarg=text);
 explain (costs off)
 select * from int8_tbl where q1 in (select c1 from inner_text);
-           QUERY PLAN           
---------------------------------
+                  QUERY PLAN                  
+----------------------------------------------
  Seq Scan on int8_tbl
-   Filter: (hashed SubPlan 1)
+   Filter: ((q1)::text IN (hashed SubPlan 1))
    SubPlan 1
      ->  Seq Scan on inner_text
 (4 rows)
@@ -836,10 +836,10 @@ create or replace function bogus_int8_text_eq(int8, text) 
returns boolean
 language sql as 'select $1::text = $2 and $1::text = $2';
 explain (costs off)
 select * from int8_tbl where q1 in (select c1 from inner_text);
-           QUERY PLAN           
---------------------------------
+                         QUERY PLAN                         
+------------------------------------------------------------
  Seq Scan on int8_tbl
-   Filter: (hashed SubPlan 1)
+   Filter: (((q1)::text, (q1)::text) IN (hashed SubPlan 1))
    SubPlan 1
      ->  Seq Scan on inner_text
 (4 rows)
@@ -860,7 +860,7 @@ select * from int8_tbl where q1 in (select c1 from 
inner_text);
               QUERY PLAN              
 --------------------------------------
  Seq Scan on int8_tbl
-   Filter: (SubPlan 1)
+   Filter: ($0 IN (SubPlan 1))
    SubPlan 1
      ->  Materialize
            ->  Seq Scan on inner_text
@@ -880,11 +880,11 @@ rollback;  -- to get rid of the bogus operator
 explain (costs off)
 select count(*) from tenk1 t
 where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0);
-                          QUERY PLAN                          
---------------------------------------------------------------
+                           QUERY PLAN                           
+----------------------------------------------------------------
  Aggregate
    ->  Seq Scan on tenk1 t
-         Filter: ((hashed SubPlan 2) OR (ten < 0))
+         Filter: ((unique2 IN (hashed SubPlan 2)) OR (ten < 0))
          SubPlan 2
            ->  Index Only Scan using tenk1_unique1 on tenk1 k
 (5 rows)
@@ -905,7 +905,7 @@ where (exists(select 1 from tenk1 k where k.unique1 = 
t.unique2) or ten < 0)
  Aggregate
    ->  Bitmap Heap Scan on tenk1 t
          Recheck Cond: (thousand = 1)
-         Filter: ((SubPlan 1) OR (ten < 0))
+         Filter: (EXISTS (SubPlan 1) OR (ten < 0))
          ->  Bitmap Index Scan on tenk1_thous_tenthous
                Index Cond: (thousand = 1)
          SubPlan 1
@@ -1011,14 +1011,14 @@ where o.ten = 0;
                                                                                
          QUERY PLAN                                                            
                              
 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Aggregate
-   Output: sum((((hashed SubPlan 1)))::integer)
+   Output: sum((((i.ten IN (hashed SubPlan 1))))::integer)
    ->  Nested Loop
-         Output: ((hashed SubPlan 1))
+         Output: ((i.ten IN (hashed SubPlan 1)))
          ->  Seq Scan on public.onek o
                Output: o.unique1, o.unique2, o.two, o.four, o.ten, o.twenty, 
o.hundred, o.thousand, o.twothousand, o.fivethous, o.tenthous, o.odd, o.even, 
o.stringu1, o.stringu2, o.string4
                Filter: (o.ten = 0)
          ->  Index Scan using onek_unique1 on public.onek i
-               Output: (hashed SubPlan 1), random()
+               Output: (i.ten IN (hashed SubPlan 1)), random()
                Index Cond: (i.unique1 = o.unique1)
                SubPlan 1
                  ->  Seq Scan on public.int4_tbl
@@ -1213,7 +1213,7 @@ select * from int4_tbl where
 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Nested Loop Semi Join
    Output: int4_tbl.f1
-   Join Filter: (CASE WHEN (hashed SubPlan 1) THEN int4_tbl.f1 ELSE 
NULL::integer END = b.ten)
+   Join Filter: (CASE WHEN (int4_tbl.f1 IN (hashed SubPlan 1)) THEN 
int4_tbl.f1 ELSE NULL::integer END = b.ten)
    ->  Seq Scan on public.int4_tbl
          Output: int4_tbl.f1
    ->  Seq Scan on public.tenk1 b
diff --git a/src/test/regress/expected/updatable_views.out 
b/src/test/regress/expected/updatable_views.out
index cdff914b93..b4e91573c7 100644
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -2327,8 +2327,8 @@ SELECT * FROM v1 WHERE a=8;
 
 EXPLAIN (VERBOSE, COSTS OFF)
 UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
-                                             QUERY PLAN                        
                      
------------------------------------------------------------------------------------------------------
+                                                 QUERY PLAN                    
                             
+------------------------------------------------------------------------------------------------------------
  Update on public.t1
    Update on public.t1 t1_1
    Update on public.t11 t1_2
@@ -2340,7 +2340,7 @@ UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a 
< 7 AND a != 6;
                ->  Index Scan using t1_a_idx on public.t1 t1_1
                      Output: t1_1.tableoid, t1_1.ctid
                      Index Cond: ((t1_1.a > 5) AND (t1_1.a < 7))
-                     Filter: ((t1_1.a <> 6) AND (SubPlan 1) AND snoop(t1_1.a) 
AND leakproof(t1_1.a))
+                     Filter: ((t1_1.a <> 6) AND EXISTS (SubPlan 1) AND 
snoop(t1_1.a) AND leakproof(t1_1.a))
                      SubPlan 1
                        ->  Append
                              ->  Seq Scan on public.t12 t12_1
@@ -2350,15 +2350,15 @@ UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND 
a < 7 AND a != 6;
                ->  Index Scan using t11_a_idx on public.t11 t1_2
                      Output: t1_2.tableoid, t1_2.ctid
                      Index Cond: ((t1_2.a > 5) AND (t1_2.a < 7))
-                     Filter: ((t1_2.a <> 6) AND (SubPlan 1) AND snoop(t1_2.a) 
AND leakproof(t1_2.a))
+                     Filter: ((t1_2.a <> 6) AND EXISTS (SubPlan 1) AND 
snoop(t1_2.a) AND leakproof(t1_2.a))
                ->  Index Scan using t12_a_idx on public.t12 t1_3
                      Output: t1_3.tableoid, t1_3.ctid
                      Index Cond: ((t1_3.a > 5) AND (t1_3.a < 7))
-                     Filter: ((t1_3.a <> 6) AND (SubPlan 1) AND snoop(t1_3.a) 
AND leakproof(t1_3.a))
+                     Filter: ((t1_3.a <> 6) AND EXISTS (SubPlan 1) AND 
snoop(t1_3.a) AND leakproof(t1_3.a))
                ->  Index Scan using t111_a_idx on public.t111 t1_4
                      Output: t1_4.tableoid, t1_4.ctid
                      Index Cond: ((t1_4.a > 5) AND (t1_4.a < 7))
-                     Filter: ((t1_4.a <> 6) AND (SubPlan 1) AND snoop(t1_4.a) 
AND leakproof(t1_4.a))
+                     Filter: ((t1_4.a <> 6) AND EXISTS (SubPlan 1) AND 
snoop(t1_4.a) AND leakproof(t1_4.a))
 (30 rows)
 
 UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
@@ -2374,8 +2374,8 @@ SELECT * FROM t1 WHERE a=100; -- Nothing should have been 
changed to 100
 
 EXPLAIN (VERBOSE, COSTS OFF)
 UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
-                                    QUERY PLAN                                 
    
------------------------------------------------------------------------------------
+                                        QUERY PLAN                             
           
+------------------------------------------------------------------------------------------
  Update on public.t1
    Update on public.t1 t1_1
    Update on public.t11 t1_2
@@ -2387,7 +2387,7 @@ UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a 
= 8;
                ->  Index Scan using t1_a_idx on public.t1 t1_1
                      Output: t1_1.a, t1_1.tableoid, t1_1.ctid
                      Index Cond: ((t1_1.a > 5) AND (t1_1.a = 8))
-                     Filter: ((SubPlan 1) AND snoop(t1_1.a) AND 
leakproof(t1_1.a))
+                     Filter: (EXISTS (SubPlan 1) AND snoop(t1_1.a) AND 
leakproof(t1_1.a))
                      SubPlan 1
                        ->  Append
                              ->  Seq Scan on public.t12 t12_1
@@ -2397,15 +2397,15 @@ UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND 
a = 8;
                ->  Index Scan using t11_a_idx on public.t11 t1_2
                      Output: t1_2.a, t1_2.tableoid, t1_2.ctid
                      Index Cond: ((t1_2.a > 5) AND (t1_2.a = 8))
-                     Filter: ((SubPlan 1) AND snoop(t1_2.a) AND 
leakproof(t1_2.a))
+                     Filter: (EXISTS (SubPlan 1) AND snoop(t1_2.a) AND 
leakproof(t1_2.a))
                ->  Index Scan using t12_a_idx on public.t12 t1_3
                      Output: t1_3.a, t1_3.tableoid, t1_3.ctid
                      Index Cond: ((t1_3.a > 5) AND (t1_3.a = 8))
-                     Filter: ((SubPlan 1) AND snoop(t1_3.a) AND 
leakproof(t1_3.a))
+                     Filter: (EXISTS (SubPlan 1) AND snoop(t1_3.a) AND 
leakproof(t1_3.a))
                ->  Index Scan using t111_a_idx on public.t111 t1_4
                      Output: t1_4.a, t1_4.tableoid, t1_4.ctid
                      Index Cond: ((t1_4.a > 5) AND (t1_4.a = 8))
-                     Filter: ((SubPlan 1) AND snoop(t1_4.a) AND 
leakproof(t1_4.a))
+                     Filter: (EXISTS (SubPlan 1) AND snoop(t1_4.a) AND 
leakproof(t1_4.a))
 (30 rows)
 
 UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
-- 
2.25.1

Reply via email to