Wrong parent node for WCO expressions in nodeModifyTable.c?

From: Andres Freund <andres(at)anarazel(dot)de>
To: pgsql-hackers(at)postgresql(dot)org, Stephen Frost <sfrost(at)snowman(dot)net>
Subject: Wrong parent node for WCO expressions in nodeModifyTable.c?
Date: 2018-12-05 22:52:13
Message-ID: 20181205225213.hiwa3kgoxeybqcqv@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Stephen, All,

While working on the pluggable storage patchset I noticed that it
initializes the WCO expression like:

/*
* Initialize any WITH CHECK OPTION constraints if needed.
*/
resultRelInfo = mtstate->resultRelInfo;
i = 0;
foreach(l, node->withCheckOptionLists)
{
List *wcoList = (List *) lfirst(l);
List *wcoExprs = NIL;
ListCell *ll;

foreach(ll, wcoList)
{
WithCheckOption *wco = (WithCheckOption *) lfirst(ll);
ExprState *wcoExpr = ExecInitQual((List *) wco->qual,
mtstate->mt_plans[i]);

wcoExprs = lappend(wcoExprs, wcoExpr);
}

resultRelInfo->ri_WithCheckOptions = wcoList;
resultRelInfo->ri_WithCheckOptionExprs = wcoExprs;
resultRelInfo++;
i++;
}

note that the parent node for the qual is the plan the tuples originate
from, *not* the target relation. That seems wrong.

It does cause a problem for pluggable storage, but I wonder if it's a
problem beyond that. The fact that the parent is wrong means we'll
anchor subplans within the qual to the wrong parent. Replacing the
parent with &mtstate->ps itself, there are regression test differences:

ERROR: new row violates check option for view "rw_view1"
DETAIL: Failing row contains (15).
EXPLAIN (costs off) INSERT INTO rw_view1 VALUES (5);
- QUERY PLAN
----------------------------------------------------------------
+ QUERY PLAN
+---------------------------------------------------------
Insert on base_tbl b
-> Result
- SubPlan 1
- -> Index Only Scan using ref_tbl_pkey on ref_tbl r
- Index Cond: (a = b.a)
- SubPlan 2
- -> Seq Scan on ref_tbl r_1
+ SubPlan 1
+ -> Index Only Scan using ref_tbl_pkey on ref_tbl r
+ Index Cond: (a = b.a)
+ SubPlan 2
+ -> Seq Scan on ref_tbl r_1
(7 rows)

EXPLAIN (costs off) UPDATE rw_view1 SET a = a + 5;
- QUERY PLAN
------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------
Update on base_tbl b
-> Hash Join
Hash Cond: (b.a = r.a)
-> Seq Scan on base_tbl b
-> Hash
-> Seq Scan on ref_tbl r
- SubPlan 1
- -> Index Only Scan using ref_tbl_pkey on ref_tbl r_1
- Index Cond: (a = b.a)
- SubPlan 2
- -> Seq Scan on ref_tbl r_2
+ SubPlan 1
+ -> Index Only Scan using ref_tbl_pkey on ref_tbl r_1
+ Index Cond: (a = b.a)
+ SubPlan 2
+ -> Seq Scan on ref_tbl r_2
(11 rows)

DROP TABLE base_tbl, ref_tbl CASCADE;

And the new output certainly looks more correct to me.

Stephen, I have not researched this much, but is there a chance this
could cause trouble in the backbranches?

Greetings,

Andres Freund

Browse pgsql-hackers by date

  From Date Subject
Next Message Petr Jelinek 2018-12-05 23:55:09 Re: Connection slots reserved for replication
Previous Message Alvaro Herrera 2018-12-05 22:50:23 \gexec \watch