Thread

Commits

  1. Fix usage of whole-row variables in WCO and RLS policy expressions.

  2. Fix parent of WCO qual.

  1. Wrong parent node for WCO expressions in nodeModifyTable.c?

    Andres Freund <andres@anarazel.de> — 2018-12-05T22:52:13Z

    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