Thread

Commits

  1. Add a test case for a316a3bc

  2. Correctly set userid of subquery relations' child rels

  3. Fix buggy recursion in flatten_rtes_walker().

  4. Remove some dead code in selfuncs.c

  5. Update outdated comment in ApplyRetrieveRule

  6. Rework query relation permission checking

  7. Generalize ri_RootToPartitionMap to use for non-partition children

  8. Stop accessing checkAsUser via RTE in some cases

  9. Add 'missing_ok' argument to build_attrmap_by_name

  1. ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-06-30T13:33:44Z

    Hi,
    
    Last year in [1], I had briefly mentioned $subject.  I'm starting this
    thread to propose a small patch to alleviate the inefficiency of that
    case.
    
    As also mentioned in [1], when running -Mprepared benchmarks
    (plan_cache_mode = force_generic_plan) using partitioned tables,
    ExecRTCheckPerms() tends to show up in the profile, especially with
    large partition counts.  Granted it's lurking behind
    AcquireExecutorLocks(), LockReleaseAll() et al, but still seems like a
    problem we should do something about.
    
    The problem is that it loops over the entire range table even though
    only one or handful of those entries actually need their permissions
    checked.  Most entries, especially those of partition child tables
    have their requiredPerms set to 0, which David pointed out to me in
    [2], so what ExecCheckRTPerms() does in their case is pure overhead.
    
    An idea to fix that is to store the RT indexes of the entries that
    have non-0 requiredPerms into a separate list or a bitmapset in
    PlannedStmt.  I thought of two implementation ideas for how to set
    that:
    
    1. Put add_rtes_to_flat_rtable() in the charge of populating it:
    
    @@ -324,12 +324,18 @@ add_rtes_to_flat_rtable(PlannerInfo *root, bool recursing)
         * flattened rangetable match up with their original indexes.  When
         * recursing, we only care about extracting relation RTEs.
         */
    +   rti = 1;
        foreach(lc, root->parse->rtable)
        {
            RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
    
            if (!recursing || rte->rtekind == RTE_RELATION)
    +       {
                add_rte_to_flat_rtable(glob, rte);
    +           if (rte->requiredPerms != 0)
    +               glob->checkPermRels = bms_add_member(glob->checkPermRels, rti);
    +       }
    +       rti++
        }
    
    2. Start populating checkPermRels in ParseState (parse_relation.c),
    passing it along in Query through the rewriter and finally the
    planner.
    
    1 seems very simple, but appears to add overhead to what is likely a
    oft-taken path.  Also, the newly added code would have to run as many
    times as there are partitions, which sounds like a dealbreaker to me.
    
    2 can seem a bit complex.  Given that the set is tracked in Query,
    special care is needed to handle views and subqueries correctly,
    because those features involve intricate manipulation of Query nodes
    and their range tables.  However, most of that special care code
    remains out of the busy paths.  Also, none of that code touches
    partition/child RTEs, so unaffected by how many of them there are.
    
    For now, I have implemented the idea 2 as the attached patch.  While
    it passes make check-world, I am not fully confident yet that it
    correctly handles all the cases involving views and subqueries.
    
    So while still kind of PoC, will add this to July CF for keeping track.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
    [1] https://www.postgresql.org/message-id/CA+HiwqG7ZruBmmih3wPsBZ4s0H2EhywrnXEduckY5Hr3fWzPWA@mail.gmail.com
    [2] https://www.postgresql.org/message-id/CAApHDvqPzsMcKLRpmNpUW97PmaQDTmD7b2BayEPS5AN4LY-0bA%40mail.gmail.com
    
  2. Re: ExecRTCheckPerms() and many prunable partitions

    David Rowley <dgrowleyml@gmail.com> — 2021-06-30T14:33:46Z

    On Thu, 1 Jul 2021 at 01:34, Amit Langote <amitlangote09@gmail.com> wrote:
    > For now, I have implemented the idea 2 as the attached patch.
    
    I only just had a fleeting glance at the patch. Aren't you
    accidentally missing the 0th RTE here?
    
    + while ((rti = bms_next_member(checkPermRels, rti)) > 0)
      {
    - RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
    + RangeTblEntry *rte = (RangeTblEntry *) list_nth(rangeTable, rti - 1);
    
    I'd have expected >= 0 rather than > 0.
    
    David
    
    
    
    
  3. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-06-30T14:58:23Z

    On Wed, Jun 30, 2021 at 23:34 David Rowley <dgrowleyml@gmail.com> wrote:
    
    > On Thu, 1 Jul 2021 at 01:34, Amit Langote <amitlangote09@gmail.com> wrote:
    > > For now, I have implemented the idea 2 as the attached patch.
    >
    > I only just had a fleeting glance at the patch. Aren't you
    > accidentally missing the 0th RTE here?
    >
    > + while ((rti = bms_next_member(checkPermRels, rti)) > 0)
    >   {
    > - RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
    > + RangeTblEntry *rte = (RangeTblEntry *) list_nth(rangeTable, rti - 1);
    >
    > I'd have expected >= 0 rather than > 0.
    
    
    Hmm, a valid RT index cannot be 0, so that seems fine to me.  Note that RT
    indexes are added as-is to that bitmapset, not after subtracting 1.
    
    > --
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  4. Re: ExecRTCheckPerms() and many prunable partitions

    David Rowley <dgrowleyml@gmail.com> — 2021-06-30T22:51:51Z

    On Thu, 1 Jul 2021 at 02:58, Amit Langote <amitlangote09@gmail.com> wrote:
    >
    > On Wed, Jun 30, 2021 at 23:34 David Rowley <dgrowleyml@gmail.com> wrote:
    >> + while ((rti = bms_next_member(checkPermRels, rti)) > 0)
    >>   {
    >> - RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
    >> + RangeTblEntry *rte = (RangeTblEntry *) list_nth(rangeTable, rti - 1);
    >>
    >> I'd have expected >= 0 rather than > 0.
    >
    > Hmm, a valid RT index cannot be 0, so that seems fine to me.  Note that RT indexes are added as-is to that bitmapset, not after subtracting 1.
    
    Oh, you're right. My mistake.
    
    David
    
    
    
    
  5. Re: ExecRTCheckPerms() and many prunable partitions

    Tom Lane <tgl@sss.pgh.pa.us> — 2021-07-01T15:45:03Z

    Amit Langote <amitlangote09@gmail.com> writes:
    > The problem is that it loops over the entire range table even though
    > only one or handful of those entries actually need their permissions
    > checked.  Most entries, especially those of partition child tables
    > have their requiredPerms set to 0, which David pointed out to me in
    > [2], so what ExecCheckRTPerms() does in their case is pure overhead.
    
    > An idea to fix that is to store the RT indexes of the entries that
    > have non-0 requiredPerms into a separate list or a bitmapset in
    > PlannedStmt.
    
    I think perhaps we ought to be more ambitious than that, and consider
    separating the list of permissions-to-check from the rtable entirely.
    Your patch hardly qualifies as non-invasive, plus it seems to invite
    errors of omission, while if we changed the data structure altogether
    then the compiler would help find any not-updated code.
    
    But the main reason that this strikes me as possibly a good idea
    is that I was just taking another look at the complaint in [1],
    where I wrote
    
    >> I think it's impossible to avoid less-than-O(N^2) growth on this sort
    >> of case.  For example, the v2 subquery initially has RTEs for v2 itself
    >> plus v1.  When we flatten v1 into v2, v2 acquires the RTEs from v1,
    >> namely v1 itself plus foo.  Similarly, once vK-1 is pulled up into vK,
    >> there are going to be order-of-K entries in vK's rtable, and that stacking
    >> makes for O(N^2) work overall just in manipulating the rtable.
    >> 
    >> We can't get rid of these rtable entries altogether, since all of them
    >> represent table privilege checks that the executor will need to do.
    
    Perhaps, if we separated the rtable from the required-permissions data
    structure, then we could avoid pulling up otherwise-useless RTEs when
    flattening a view (or even better, not make the extra RTEs in the
    first place??), and thus possibly avoid that exponential planning-time
    growth for nested views.
    
    Or maybe not.  But I think we should take a hard look at whether
    separating these data structures could solve both of these problems
    at once.
    
    			regards, tom lane
    
    [1] https://www.postgresql.org/message-id/flat/797aff54-b49b-4914-9ff9-aa42564a4d7d%40www.fastmail.com
    
    
    
    
  6. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-07-02T00:40:47Z

    On Fri, Jul 2, 2021 at 12:45 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Amit Langote <amitlangote09@gmail.com> writes:
    > > The problem is that it loops over the entire range table even though
    > > only one or handful of those entries actually need their permissions
    > > checked.  Most entries, especially those of partition child tables
    > > have their requiredPerms set to 0, which David pointed out to me in
    > > [2], so what ExecCheckRTPerms() does in their case is pure overhead.
    >
    > > An idea to fix that is to store the RT indexes of the entries that
    > > have non-0 requiredPerms into a separate list or a bitmapset in
    > > PlannedStmt.
    >
    > I think perhaps we ought to be more ambitious than that, and consider
    > separating the list of permissions-to-check from the rtable entirely.
    > Your patch hardly qualifies as non-invasive, plus it seems to invite
    > errors of omission, while if we changed the data structure altogether
    > then the compiler would help find any not-updated code.
    >
    > But the main reason that this strikes me as possibly a good idea
    > is that I was just taking another look at the complaint in [1],
    > where I wrote
    >
    > >> I think it's impossible to avoid less-than-O(N^2) growth on this sort
    > >> of case.  For example, the v2 subquery initially has RTEs for v2 itself
    > >> plus v1.  When we flatten v1 into v2, v2 acquires the RTEs from v1,
    > >> namely v1 itself plus foo.  Similarly, once vK-1 is pulled up into vK,
    > >> there are going to be order-of-K entries in vK's rtable, and that stacking
    > >> makes for O(N^2) work overall just in manipulating the rtable.
    > >>
    > >> We can't get rid of these rtable entries altogether, since all of them
    > >> represent table privilege checks that the executor will need to do.
    >
    > Perhaps, if we separated the rtable from the required-permissions data
    > structure, then we could avoid pulling up otherwise-useless RTEs when
    > flattening a view (or even better, not make the extra RTEs in the
    > first place??), and thus possibly avoid that exponential planning-time
    > growth for nested views.
    >
    > Or maybe not.  But I think we should take a hard look at whether
    > separating these data structures could solve both of these problems
    > at once.
    
    Ah, okay.  I'll think about decoupling the permission checking stuff
    from the range table data structure.
    
    Thanks for the feedback.
    
    I'll mark the CF entry as WoA, unless you'd rather I just mark it RwF.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  7. Re: ExecRTCheckPerms() and many prunable partitions

    David Rowley <dgrowleyml@gmail.com> — 2021-07-07T04:41:13Z

    On Fri, 2 Jul 2021 at 12:41, Amit Langote <amitlangote09@gmail.com> wrote:
    > I'll mark the CF entry as WoA, unless you'd rather I just mark it RwF.
    
    I've set it to waiting on author. It was still set to needs review.
    
    If you think you'll not get time to write the patch during this CF,
    feel free to bump it out.
    
    David
    
    
    
    
  8. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-07-07T07:12:49Z

    On Wed, Jul 7, 2021 at 1:41 PM David Rowley <dgrowleyml@gmail.com> wrote:
    > On Fri, 2 Jul 2021 at 12:41, Amit Langote <amitlangote09@gmail.com> wrote:
    > > I'll mark the CF entry as WoA, unless you'd rather I just mark it RwF.
    >
    > I've set it to waiting on author. It was still set to needs review.
    
    Sorry it slipped my mind to do that and thanks.
    
    > If you think you'll not get time to write the patch during this CF,
    > feel free to bump it out.
    
    I will try to post an update next week if not later this week,
    hopefully with an updated patch.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  9. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-07-29T08:40:00Z

    On Fri, Jul 2, 2021 at 9:40 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Fri, Jul 2, 2021 at 12:45 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > > I think perhaps we ought to be more ambitious than that, and consider
    > > separating the list of permissions-to-check from the rtable entirely.
    > > Your patch hardly qualifies as non-invasive, plus it seems to invite
    > > errors of omission, while if we changed the data structure altogether
    > > then the compiler would help find any not-updated code.
    > >
    > > But the main reason that this strikes me as possibly a good idea
    > > is that I was just taking another look at the complaint in [1],
    > > where I wrote
    > >
    > > >> I think it's impossible to avoid less-than-O(N^2) growth on this sort
    > > >> of case.  For example, the v2 subquery initially has RTEs for v2 itself
    > > >> plus v1.  When we flatten v1 into v2, v2 acquires the RTEs from v1,
    > > >> namely v1 itself plus foo.  Similarly, once vK-1 is pulled up into vK,
    > > >> there are going to be order-of-K entries in vK's rtable, and that stacking
    > > >> makes for O(N^2) work overall just in manipulating the rtable.
    > > >>
    > > >> We can't get rid of these rtable entries altogether, since all of them
    > > >> represent table privilege checks that the executor will need to do.
    > >
    > > Perhaps, if we separated the rtable from the required-permissions data
    > > structure, then we could avoid pulling up otherwise-useless RTEs when
    > > flattening a view (or even better, not make the extra RTEs in the
    > > first place??), and thus possibly avoid that exponential planning-time
    > > growth for nested views.
    > >
    > > Or maybe not.  But I think we should take a hard look at whether
    > > separating these data structures could solve both of these problems
    > > at once.
    >
    > Ah, okay.  I'll think about decoupling the permission checking stuff
    > from the range table data structure.
    
    I have finished with the attached.  Sorry about the delay.
    
    Think I've managed to get the first part done -- getting the
    permission-checking info out of the range table -- but have not
    seriously attempted the second -- doing away with the OLD/NEW range
    table entries in the view/rule action queries, assuming that is what
    you meant in the quoted.
    
    One design point I think might need reconsidering is that the list of
    the new RelPermissionInfo nodes that holds the permission-checking
    info for relations has to be looked up with a linear search using the
    relation OID, whereas it was basically free before if a particular of
    code had the RTE handy.  Maybe I need to check if the overhead of that
    is noticeable in some cases.
    
    As there's not much time left in this CF, I've bumped the entry to the next one.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  10. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-08-20T13:46:17Z

    On Thu, Jul 29, 2021 at 5:40 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Fri, Jul 2, 2021 at 9:40 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > > On Fri, Jul 2, 2021 at 12:45 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > > > Perhaps, if we separated the rtable from the required-permissions data
    > > > structure, then we could avoid pulling up otherwise-useless RTEs when
    > > > flattening a view (or even better, not make the extra RTEs in the
    > > > first place??), and thus possibly avoid that exponential planning-time
    > > > growth for nested views.
    >
    > Think I've managed to get the first part done -- getting the
    > permission-checking info out of the range table -- but have not
    > seriously attempted the second -- doing away with the OLD/NEW range
    > table entries in the view/rule action queries, assuming that is what
    > you meant in the quoted.
    
    I took a stab at the 2nd part, implemented in the attached 0002.
    
    The patch removes UpdateRangeTableOfViewParse() which would add the
    dummy OLD/NEW entries to a view rule's action query's rtable, citing
    these reasons:
    
    - * These extra RT entries are not actually used in the query,
    - * except for run-time locking and permission checking.
    
    0001 makes them unnecessary for permission checking.  Though, a
    RELATION-kind RTE still be must be present in the rtable for run-time
    locking, so I adjusted ApplyRetrieveRule() as follows:
    
    @@ -1803,16 +1804,26 @@ ApplyRetrieveRule(Query *parsetree,
         * original RTE to a subquery RTE.
         */
        rte = rt_fetch(rt_index, parsetree->rtable);
    +   subquery_rte = rte;
    
    -   rte->rtekind = RTE_SUBQUERY;
    -   rte->subquery = rule_action;
    -   rte->security_barrier = RelationIsSecurityView(relation);
    +   /*
    +    * Before modifying, store a copy of itself so as to serve as the entry
    +    * to be used by the executor to lock the view relation and for the
    +    * planner to be able to record the view relation OID in the PlannedStmt
    +    * that it produces for the query.
    +    */
    +   rte = copyObject(rte);
    +   parsetree->rtable = lappend(parsetree->rtable, rte);
    +
    +   subquery_rte->rtekind = RTE_SUBQUERY;
    +   subquery_rte->subquery = rule_action;
    +   subquery_rte->security_barrier = RelationIsSecurityView(relation);
        /* Clear fields that should not be set in a subquery RTE */
    -   rte->relid = InvalidOid;
    -   rte->relkind = 0;
    -   rte->rellockmode = 0;
    -   rte->tablesample = NULL;
    -   rte->inh = false;           /* must not be set for a subquery */
    +   subquery_rte->relid = InvalidOid;
    +   subquery_rte->relkind = 0;
    +   subquery_rte->rellockmode = 0;
    +   subquery_rte->tablesample = NULL;
    +   subquery_rte->inh = false;          /* must not be set for a subquery */
    
        return parsetree;
     }
    
    Outputs for a bunch of regression tests needed to be adjusted to
    account for that pg_get_viewdef() no longer qualifies view column
    names in the deparsed queries, that is, if they reference only a
    single relation.   Previously, those dummy OLD/NEW entries tricked
    make_ruledef(), get_query_def() et al into setting
    deparse_context.varprefix to true.  contrib/postgre_fdw test output
    likewise needed adjustment due to its deparse code being impacted by
    those dummy entries no longer being present, I believe.
    
    I haven't yet checked how this further improves the performance for
    the case discussed at [1] that prompted this.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
    [1] https://www.postgresql.org/message-id/flat/797aff54-b49b-4914-9ff9-aa42564a4d7d%40www.fastmail.com
    
  11. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-08-26T09:13:33Z

    On Fri, Aug 20, 2021 at 10:46 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Thu, Jul 29, 2021 at 5:40 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > On Fri, Jul 2, 2021 at 9:40 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > On Fri, Jul 2, 2021 at 12:45 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > > > > Perhaps, if we separated the rtable from the required-permissions data
    > > > > structure, then we could avoid pulling up otherwise-useless RTEs when
    > > > > flattening a view (or even better, not make the extra RTEs in the
    > > > > first place??), and thus possibly avoid that exponential planning-time
    > > > > growth for nested views.
    > >
    > > Think I've managed to get the first part done -- getting the
    > > permission-checking info out of the range table -- but have not
    > > seriously attempted the second -- doing away with the OLD/NEW range
    > > table entries in the view/rule action queries, assuming that is what
    > > you meant in the quoted.
    >
    > I took a stab at the 2nd part, implemented in the attached 0002.
    >
    > The patch removes UpdateRangeTableOfViewParse() which would add the
    > dummy OLD/NEW entries to a view rule's action query's rtable
    >
    > I haven't yet checked how this further improves the performance for
    > the case discussed at [1] that prompted this.
    >
    > [1] https://www.postgresql.org/message-id/flat/797aff54-b49b-4914-9ff9-aa42564a4d7d%40www.fastmail.com
    
    I checked the time required to do explain select * from v512 (worst
    case), using the setup described at the above link and I get the
    following numbers:
    
    HEAD: 119.774 ms
    0001  : 129.802 ms
    0002  : 109.456 ms
    
    So it appears that applying only 0001 makes things a bit worse for
    this case.  That seems to have to do with the following addition in
    pull_up_simple_subquery():
    
    @@ -1131,6 +1131,9 @@ pull_up_simple_subquery(PlannerInfo *root, Node
    *jtnode, RangeTblEntry *rte,
         */
        parse->rtable = list_concat(parse->rtable, subquery->rtable);
    
    +   parse->relpermlist = MergeRelPermissionInfos(parse->relpermlist,
    +                                                subquery->relpermlist);
    +
    
    What it does is pull up the RelPermissionInfo nodes in the subquery
    being pulled up into the parent query and it's not a simple
    list_concat(), because I decided that it's better to de-duplicate the
    entries for a given relation OID even across subqueries.
    
    Things get better than HEAD with 0002, because less work needs to be
    done in the rewriter when copying the subqueries into the main query,
    especially the range table, which only has 1 entry now, not 3 per
    view.
    
    Attached updated patches.  I wrote a longer commit message for 0002 this time.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  12. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2021-09-06T19:35:20Z

    Got this warning:
    
    /pgsql/source/master/contrib/postgres_fdw/postgres_fdw.c: In function 'GetResultRelCheckAsUser':
    /pgsql/source/master/contrib/postgres_fdw/postgres_fdw.c:1898:7: warning: unused variable 'result' [-Wunused-variable]
      Oid  result;
           ^~~~~~
    
    I think the idea that GetRelPermissionInfo always has to scan the
    complete list by OID is a nonstarter.  Maybe it would be possible to
    store the list index of the PermissionInfo element in the RelOptInfo or
    the RTE?  Maybe use special negative values if unknown (it knows to
    search the first time) or known non-existant (probably a coding error
    condition, maybe not necessary to have this)
    
    -- 
    Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
    
    
    
    
  13. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-09-10T03:22:30Z

    Thanks Alvaro for taking a look at this.
    
    On Tue, Sep 7, 2021 at 4:35 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > Got this warning:
    >
    > /pgsql/source/master/contrib/postgres_fdw/postgres_fdw.c: In function 'GetResultRelCheckAsUser':
    > /pgsql/source/master/contrib/postgres_fdw/postgres_fdw.c:1898:7: warning: unused variable 'result' [-Wunused-variable]
    >   Oid  result;
    >        ^~~~~~
    
    Fixed.
    
    > I think the idea that GetRelPermissionInfo always has to scan the
    > complete list by OID is a nonstarter.  Maybe it would be possible to
    > store the list index of the PermissionInfo element in the RelOptInfo or
    > the RTE?  Maybe use special negative values if unknown (it knows to
    > search the first time) or known non-existant (probably a coding error
    > condition, maybe not necessary to have this)
    
    I implemented this by adding an Index field in RangeTblEntry, because
    GetRelPermissionInfo() is used in all phases of query processing and
    only RTEs exist from start to end.  I did have to spend some time
    getting that approach right (get `make check` to pass!), especially to
    ensure that the indexes remain in sync during the merging of
    RelPermissionInfo across subqueries.  The comments I wrote around
    GetRelPermissionInfo(), MergeRelPermissionInfos() functions should
    hopefully make things clear.  Though, I do have a slightly uneasy
    feeling around the fact that RTEs now store information that is
    computed using some non-trivial logic, whereas most other fields are
    simple catalog state or trivial details extracted from how the query
    is spelled out by the user.
    
    I also noticed that setrefs.c: add_rtes_to_flat_rtable() was still
    doing things -- adding dead subquery RTEs and any RTEs referenced in
    the underlying subquery to flat rtable -- that the new approach of
    permissions handling makes unnecessary.  I fixed that oversight in the
    updated patch.  A benefit from that simplification is that there is
    now a single loop over rtable in that function rather than two that
    were needed before.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  14. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2021-12-20T07:13:04Z

    On Fri, Sep 10, 2021 at 12:22 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Tue, Sep 7, 2021 at 4:35 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > I think the idea that GetRelPermissionInfo always has to scan the
    > > complete list by OID is a nonstarter.  Maybe it would be possible to
    > > store the list index of the PermissionInfo element in the RelOptInfo or
    > > the RTE?  Maybe use special negative values if unknown (it knows to
    > > search the first time) or known non-existant (probably a coding error
    > > condition, maybe not necessary to have this)
    >
    > I implemented this by adding an Index field in RangeTblEntry, because
    > GetRelPermissionInfo() is used in all phases of query processing and
    > only RTEs exist from start to end.  I did have to spend some time
    > getting that approach right (get `make check` to pass!), especially to
    > ensure that the indexes remain in sync during the merging of
    > RelPermissionInfo across subqueries.  The comments I wrote around
    > GetRelPermissionInfo(), MergeRelPermissionInfos() functions should
    > hopefully make things clear.  Though, I do have a slightly uneasy
    > feeling around the fact that RTEs now store information that is
    > computed using some non-trivial logic, whereas most other fields are
    > simple catalog state or trivial details extracted from how the query
    > is spelled out by the user.
    >
    > I also noticed that setrefs.c: add_rtes_to_flat_rtable() was still
    > doing things -- adding dead subquery RTEs and any RTEs referenced in
    > the underlying subquery to flat rtable -- that the new approach of
    > permissions handling makes unnecessary.  I fixed that oversight in the
    > updated patch.  A benefit from that simplification is that there is
    > now a single loop over rtable in that function rather than two that
    > were needed before.
    
    Patch 0002 needed a rebase, because a conflicting change to
    expected/rules.out has since been committed.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  15. Re: ExecRTCheckPerms() and many prunable partitions

    Julien Rouhaud <rjuju123@gmail.com> — 2022-01-13T03:10:05Z

    Hi,
    
    On Mon, Dec 20, 2021 at 04:13:04PM +0900, Amit Langote wrote:
    > 
    > Patch 0002 needed a rebase, because a conflicting change to
    > expected/rules.out has since been committed.
    
    The cfbot reports new conflicts since about a week ago with this patch:
    
    Latest failure: https://cirrus-ci.com/task/4686414276198400 and
    https://api.cirrus-ci.com/v1/artifact/task/4686414276198400/regress_diffs/src/test/regress/regression.diffs
    
    diff -U3 /tmp/cirrus-ci-build/src/test/regress/expected/xml.out /tmp/cirrus-ci-build/src/test/regress/results/xml.out
    --- /tmp/cirrus-ci-build/src/test/regress/expected/xml.out	2022-01-12 05:24:02.795477001 +0000
    +++ /tmp/cirrus-ci-build/src/test/regress/results/xml.out	2022-01-12 05:28:20.329086031 +0000
    @@ -603,12 +603,12 @@
     CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
     SELECT table_name, view_definition FROM information_schema.views
       WHERE table_name LIKE 'xmlview%' ORDER BY 1;
    - table_name |                                                  view_definition
    -------------+-------------------------------------------------------------------------------------------------------------------
    + table_name |                                              view_definition
    +------------+------------------------------------------------------------------------------------------------------------
      xmlview1   |  SELECT xmlcomment('test'::text) AS xmlcomment;
      xmlview2   |  SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
      xmlview3   |  SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
    - xmlview4   |  SELECT XMLELEMENT(NAME employee, XMLFOREST(emp.name AS name, emp.age AS age, emp.salary AS pay)) AS "xmlelement"+
    + xmlview4   |  SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement"     +
                 |    FROM emp;
      xmlview5   |  SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
      xmlview6   |  SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
    diff -U3 /tmp/cirrus-ci-build/src/test/regress/expected/compression.out /tmp/cirrus-ci-build/src/test/regress/results/compression.out
    --- /tmp/cirrus-ci-build/src/test/regress/expected/compression.out	2022-01-12 05:24:02.739471690 +0000
    +++ /tmp/cirrus-ci-build/src/test/regress/results/compression.out	2022-01-12 05:28:23.537403929 +0000
    @@ -187,7 +187,7 @@
     --------+------+-----------+----------+---------+----------+-------------+--------------+-------------
      x      | text |           |          |         | extended |             |              |
     View definition:
    - SELECT cmdata1.f1 AS x
    + SELECT f1 AS x
        FROM cmdata1;
    
     SELECT pg_column_compression(f1) FROM cmdata1;
    @@ -274,7 +274,7 @@
     --------+------+-----------+----------+---------+----------+-------------+--------------+-------------
      x      | text |           |          |         | extended | lz4         |              |
     View definition:
    - SELECT cmdata1.f1 AS x
    + SELECT f1 AS x
        FROM cmdata1;
    
    Could you send a rebased patch?  In the meantime I'll switch the cf entry to
    Waiting on Author.
    
    
    
    
  16. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-01-13T06:39:12Z

    On Thu, Jan 13, 2022 at 12:10 PM Julien Rouhaud <rjuju123@gmail.com> wrote:
    > On Mon, Dec 20, 2021 at 04:13:04PM +0900, Amit Langote wrote:
    > >
    > > Patch 0002 needed a rebase, because a conflicting change to
    > > expected/rules.out has since been committed.
    >
    > The cfbot reports new conflicts since about a week ago with this patch:
    
    I had noticed that too and was meaning to send a new version.  Thanks
    for the reminder.
    
    > Latest failure: https://cirrus-ci.com/task/4686414276198400 and
    > https://api.cirrus-ci.com/v1/artifact/task/4686414276198400/regress_diffs/src/test/regress/regression.diffs
    >
    > diff -U3 /tmp/cirrus-ci-build/src/test/regress/expected/xml.out /tmp/cirrus-ci-build/src/test/regress/results/xml.out
    > --- /tmp/cirrus-ci-build/src/test/regress/expected/xml.out      2022-01-12 05:24:02.795477001 +0000
    > +++ /tmp/cirrus-ci-build/src/test/regress/results/xml.out       2022-01-12 05:28:20.329086031 +0000
    > @@ -603,12 +603,12 @@
    >  CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
    >  SELECT table_name, view_definition FROM information_schema.views
    >    WHERE table_name LIKE 'xmlview%' ORDER BY 1;
    > - table_name |                                                  view_definition
    > -------------+-------------------------------------------------------------------------------------------------------------------
    > + table_name |                                              view_definition
    > +------------+------------------------------------------------------------------------------------------------------------
    >   xmlview1   |  SELECT xmlcomment('test'::text) AS xmlcomment;
    >   xmlview2   |  SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
    >   xmlview3   |  SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
    > - xmlview4   |  SELECT XMLELEMENT(NAME employee, XMLFOREST(emp.name AS name, emp.age AS age, emp.salary AS pay)) AS "xmlelement"+
    > + xmlview4   |  SELECT XMLELEMENT(NAME employee, XMLFOREST(name AS name, age AS age, salary AS pay)) AS "xmlelement"     +
    >              |    FROM emp;
    >   xmlview5   |  SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
    >   xmlview6   |  SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
    > diff -U3 /tmp/cirrus-ci-build/src/test/regress/expected/compression.out /tmp/cirrus-ci-build/src/test/regress/results/compression.out
    > --- /tmp/cirrus-ci-build/src/test/regress/expected/compression.out      2022-01-12 05:24:02.739471690 +0000
    > +++ /tmp/cirrus-ci-build/src/test/regress/results/compression.out       2022-01-12 05:28:23.537403929 +0000
    > @@ -187,7 +187,7 @@
    >  --------+------+-----------+----------+---------+----------+-------------+--------------+-------------
    >   x      | text |           |          |         | extended |             |              |
    >  View definition:
    > - SELECT cmdata1.f1 AS x
    > + SELECT f1 AS x
    >     FROM cmdata1;
    >
    >  SELECT pg_column_compression(f1) FROM cmdata1;
    > @@ -274,7 +274,7 @@
    >  --------+------+-----------+----------+---------+----------+-------------+--------------+-------------
    >   x      | text |           |          |         | extended | lz4         |              |
    >  View definition:
    > - SELECT cmdata1.f1 AS x
    > + SELECT f1 AS x
    >     FROM cmdata1;
    >
    > Could you send a rebased patch?  In the meantime I'll switch the cf entry to
    > Waiting on Author.
    
    Turns out I had never compiled this patch set to exercise xml and lz4
    tests, whose output files contained view definitions shown using \d
    that also needed to be updated in the 0002 patch.
    
    Fixed in the attached updated version.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  17. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-01-17T11:50:42Z

    On Thu, Jan 13, 2022 at 3:39 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Thu, Jan 13, 2022 at 12:10 PM Julien Rouhaud <rjuju123@gmail.com> wrote:
    > > On Mon, Dec 20, 2021 at 04:13:04PM +0900, Amit Langote wrote:
    > > > Patch 0002 needed a rebase, because a conflicting change to
    > > > expected/rules.out has since been committed.
    > >
    > > The cfbot reports new conflicts since about a week ago with this patch:
    > > Could you send a rebased patch?  In the meantime I'll switch the cf entry to
    > > Waiting on Author.
    >
    > Turns out I had never compiled this patch set to exercise xml and lz4
    > tests, whose output files contained view definitions shown using \d
    > that also needed to be updated in the 0002 patch.
    >
    > Fixed in the attached updated version.
    
    cfbot tells me it found a conflict when applying v7 on the latest
    HEAD.  Fixed in the attached v8.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  18. Re: ExecRTCheckPerms() and many prunable partitions

    Zhihong Yu <zyu@yugabyte.com> — 2022-01-17T15:45:06Z

    On Mon, Jan 17, 2022 at 3:51 AM Amit Langote <amitlangote09@gmail.com>
    wrote:
    
    > On Thu, Jan 13, 2022 at 3:39 PM Amit Langote <amitlangote09@gmail.com>
    > wrote:
    > > On Thu, Jan 13, 2022 at 12:10 PM Julien Rouhaud <rjuju123@gmail.com>
    > wrote:
    > > > On Mon, Dec 20, 2021 at 04:13:04PM +0900, Amit Langote wrote:
    > > > > Patch 0002 needed a rebase, because a conflicting change to
    > > > > expected/rules.out has since been committed.
    > > >
    > > > The cfbot reports new conflicts since about a week ago with this patch:
    > > > Could you send a rebased patch?  In the meantime I'll switch the cf
    > entry to
    > > > Waiting on Author.
    > >
    > > Turns out I had never compiled this patch set to exercise xml and lz4
    > > tests, whose output files contained view definitions shown using \d
    > > that also needed to be updated in the 0002 patch.
    > >
    > > Fixed in the attached updated version.
    >
    > cfbot tells me it found a conflict when applying v7 on the latest
    > HEAD.  Fixed in the attached v8.
    >
    > Hi,
    For patch 02, in the description:
    
    present for locking views during execition
    
    Typo: execution.
    
    +    * to be used by the executor to lock the view relation and for the
    +    * planner to be able to record the view relation OID in the PlannedStmt
    +    * that it produces for the query.
    
    I think the sentence about executor can be placed after the sentence for
    the planner.
    
    For patch 01, GetRelPermissionInfo():
    
    +       return perminfo;
    +   }
    +   else
    
    keyword 'else' is not needed - the else block can be left-indented.
    
    Cheers
    
  19. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-03-14T07:36:53Z

    On Tue, Jan 18, 2022 at 12:42 AM Zhihong Yu <zyu@yugabyte.com> wrote:
    > Hi,
    > For patch 02, in the description:
    
    Thanks for looking.
    
    > present for locking views during execition
    >
    > Typo: execution.
    >
    > +    * to be used by the executor to lock the view relation and for the
    > +    * planner to be able to record the view relation OID in the PlannedStmt
    > +    * that it produces for the query.
    >
    > I think the sentence about executor can be placed after the sentence for the planner.
    
    Fixed.
    
    > For patch 01, GetRelPermissionInfo():
    >
    > +       return perminfo;
    > +   }
    > +   else
    >
    > keyword 'else' is not needed - the else block can be left-indented.
    
    OK, done.
    
    Also needed fixes when rebasing.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  20. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-03-23T07:03:04Z

    On Mon, Mar 14, 2022 at 4:36 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > Also needed fixes when rebasing.
    
    Needed another rebase.
    
    As the changes being made with the patch are non-trivial and the patch
    hasn't been reviewed very significantly since Alvaro's comments back
    in Sept 2021 which I've since addressed, I'm thinking of pushing this
    one into the version 16 dev cycle.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  21. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-03-23T09:49:53Z

    On 2022-Mar-23, Amit Langote wrote:
    
    > As the changes being made with the patch are non-trivial and the patch
    > hasn't been reviewed very significantly since Alvaro's comments back
    > in Sept 2021 which I've since addressed, I'm thinking of pushing this
    > one into the version 16 dev cycle.
    
    Let's not get ahead of ourselves.  The commitfest is not yet over.
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    "La virtud es el justo medio entre dos defectos" (Aristóteles)
    
    
    
    
  22. Re: ExecRTCheckPerms() and many prunable partitions

    Zhihong Yu <zyu@yugabyte.com> — 2022-03-23T21:02:10Z

    On Wed, Mar 23, 2022 at 12:03 AM Amit Langote <amitlangote09@gmail.com>
    wrote:
    
    > On Mon, Mar 14, 2022 at 4:36 PM Amit Langote <amitlangote09@gmail.com>
    > wrote:
    > > Also needed fixes when rebasing.
    >
    > Needed another rebase.
    >
    > As the changes being made with the patch are non-trivial and the patch
    > hasn't been reviewed very significantly since Alvaro's comments back
    > in Sept 2021 which I've since addressed, I'm thinking of pushing this
    > one into the version 16 dev cycle.
    >
    > --
    > Amit Langote
    > EDB: http://www.enterprisedb.com
    
    Hi,
    For patch 1:
    
    bq. makes permissions-checking needlessly expensive when many inheritance
    children are added to the range range
    
    'range' is repeated in the above sentence.
    
    +ExecCheckOneRelPerms(RelPermissionInfo *perminfo)
    
    Since RelPermissionInfo is for one relation, I think the 'One' in func name
    can be dropped.
    
    +       else                    /* this isn't a child result rel */
    +           resultRelInfo->ri_RootToChildMap = NULL;
    ...
    +       resultRelInfo->ri_RootToChildMapValid = true;
    
    Should the assignment of true value be moved into the if block (in the else
    block, ri_RootToChildMap is assigned NULL) ?
    
    +   /* Looks like the RTE doesn't, so try to find it the hard way. */
    
    doesn't -> doesn't know
    
    Cheers
    
  23. Re: ExecRTCheckPerms() and many prunable partitions

    David Rowley <dgrowleyml@gmail.com> — 2022-03-24T19:46:09Z

    On Wed, 23 Mar 2022 at 20:03, Amit Langote <amitlangote09@gmail.com> wrote:
    >
    > On Mon, Mar 14, 2022 at 4:36 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > Also needed fixes when rebasing.
    >
    > Needed another rebase.
    
    I had a look at the v10-0001 patch. I agree that it seems to be a good
    idea to separate out the required permission checks rather than having
    the Bitmapset to index the interesting range table entries.
    
    One thing that I could just not determine from looking at the patch
    was if there's meant to be just 1 RelPermissionInfo per RTE or per rel
    Oid. None of the comments helped me understand this and
    MergeRelPermissionInfos() seems to exist that appears to try and
    uniquify this to some extent.  I just see no code that does this
    process for a single query level. I've provided more detail on this in
    #5 below.
    
    Here's my complete review of v10-0001:
    
    1. ExecCheckPermisssions -> ExecCheckPermissions
    
    2. I think you'll want to move the userid field away from below a
    comment that claims the following fields are for foreign tables only.
    
      /* Information about foreign tables and foreign joins */
      Oid serverid; /* identifies server for the table or join */
    - Oid userid; /* identifies user to check access as */
    + Oid userid; /* identifies user to check access as; set
    + * in non-foreign table relations too! */
    
    3. This should use READ_OID_FIELD()
    
    READ_INT_FIELD(checkAsUser);
    
    and this one:
    
    READ_INT_FIELD(relid);
    
    4.  This looks wrong:
    
    - rel->userid = rte->checkAsUser;
    + if (rte->rtekind == RTE_RELATION)
    + {
    + /* otherrels use the root parent's value. */
    + rel->userid = parent ? parent->userid :
    + GetRelPermissionInfo(root->parse->relpermlist,
    + rte, false)->checkAsUser;
    + }
    
    If 'parent' is false then you'll assign the result of
    GetRelPermissionInfo (a RelPermissionInfo *) to an Oid.
    
    5. I'm not sure if there's a case that can break this one, but I'm not
    very confident that there's not one:
    
    I'm not sure I agree with how you've coded GetRelPermissionInfo().
    You're searching for a RelPermissionInfo based on the table's Oid.  If
    you have multiple RelPermissionInfos for the same Oid then this will
    just find the first one and return it, but that might not be the one
    for the RangeTblEntry in question.
    
    Here's an example of the sort of thing that could have problems with this:
    
    postgres=# create role bob;
    CREATE ROLE
    postgres=# create table ab (a int, b int);
    CREATE TABLE
    postgres=# grant all (a) on table ab to bob;
    GRANT
    postgres=# set session authorization bob;
    SET
    postgres=> update ab set a = (select b from ab);
    ERROR:  permission denied for table ab
    
    The patch does correctly ERROR out here on permission failure, but as
    far as I can see, that's just due to the fact that we're checking the
    permissions of all items in the PlannedStmt.relpermlist List.  If
    there had been code that had tried to find the RelPermissionInfo based
    on the relation's Oid then we'd have accidentally found that we only
    need an UPDATE permission on (a).  SELECT on (b) wouldn't have been
    checked.
    
    As far as I can see, to fix that you'd either need to store the RTI of
    the RelPermissionInfo and lookup based on that, or you'd have to
    bms_union() all the columns and bitwise OR the required permissions
    and ensure you only have 1 RelPermissionInfo per Oid.
    
    The fact that I have two entries when I debug InitPlan() seems to
    disagree with what the comment in AddRelPermissionInfo() is claiming
    should happen:
    
    /*
    * To prevent duplicate entries for a given relation, check if already in
    * the list.
    */
    
    I'm not clear on if the list is meant to be unique on Oid or not.
    
    6. acesss?
    
    - * Set flags and access permissions.
    + * Set flags and initialize acesss permissions.
    
    7. I was expecting to see an |= here:
    
    + /* "merge" proprties. */
    + dest_perminfo->inh = src_perminfo->inh;
    
    Why is a plain assignment ok?
    
    8. Some indentation problems here:
    
    @@ -3170,6 +3148,8 @@ rewriteTargetView(Query *parsetree, Relation view)
    
      base_rt_index = rtr->rtindex;
      base_rte = rt_fetch(base_rt_index, viewquery->rtable);
    +base_perminfo = GetRelPermissionInfo(viewquery->relpermlist, base_rte,
    + false);
    
    9. You can use foreach_current_index(lc) + 1 in:
    
    + i = 0;
    + foreach(lc, relpermlist)
    + {
    + perminfo = (RelPermissionInfo *) lfirst(lc);
    + if (perminfo->relid == rte->relid)
    + {
    + /* And set the index in RTE. */
    + rte->perminfoindex = i + 1;
    + return perminfo;
    + }
    + i++;
    + }
    
    10. I think the double quote is not in the correct place in this comment:
    
      List    *finalrtable; /* "flat" rangetable for executor */
    
    + List    *finalrelpermlist; /* "flat list of RelPermissionInfo "*/
    
    
    11. Looks like an accidental change:
    
    +++ b/src/include/optimizer/planner.h
    @@ -58,4 +58,5 @@ extern Path *get_cheapest_fractional_path(RelOptInfo *rel,
    
     extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr);
    
    +
    
    12. These need to be broken into multiple lines:
    
    +extern RelPermissionInfo *AddRelPermissionInfo(List **relpermlist,
    RangeTblEntry *rte);
    +extern void MergeRelPermissionInfos(Query *dest_query, List *src_relpermlist);
    +extern RelPermissionInfo *GetRelPermissionInfo(List *relpermlist,
    RangeTblEntry *rte, bool missing_ok);
    
    David
    
    
    
    
  24. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-03-31T03:16:02Z

    On Fri, Mar 25, 2022 at 4:46 AM David Rowley <dgrowleyml@gmail.com> wrote:
    > I had a look at the v10-0001 patch. I agree that it seems to be a good
    > idea to separate out the required permission checks rather than having
    > the Bitmapset to index the interesting range table entries.
    
    Thanks David for taking a look at this.
    
    > One thing that I could just not determine from looking at the patch
    > was if there's meant to be just 1 RelPermissionInfo per RTE or per rel
    > Oid.
    
    It's the latter.
    
    > None of the comments helped me understand this
    
    I agree that the comment above the RelPermissionInfo struct definition
    missed mentioning this really important bit.  I've tried fixing that
    as:
    
    @@ -1142,7 +1142,9 @@ typedef struct RangeTblEntry
      *         Per-relation information for permission checking. Added to the query
      *         by the parser when populating the query range table and subsequently
      *         editorialized on by the rewriter and the planner.  There is an entry
    - *         each for all RTE_RELATION entries present in the range table.
    + *         each for all RTE_RELATION entries present in the range table, though
    + *         different RTEs for the same relation share the
    RelPermissionInfo, that
    + *         is, there is only one RelPermissionInfo containing a given relid.
    
    > and
    > MergeRelPermissionInfos() seems to exist that appears to try and
    > uniquify this to some extent.  I just see no code that does this
    > process for a single query level. I've provided more detail on this in
    > #5 below.
    >
    > Here's my complete review of v10-0001:
    >
    > 1. ExecCheckPermisssions -> ExecCheckPermissions
    
    Fixed.
    
    > 2. I think you'll want to move the userid field away from below a
    > comment that claims the following fields are for foreign tables only.
    >
    >   /* Information about foreign tables and foreign joins */
    >   Oid serverid; /* identifies server for the table or join */
    > - Oid userid; /* identifies user to check access as */
    > + Oid userid; /* identifies user to check access as; set
    > + * in non-foreign table relations too! */
    
    Actually, I realized that the comment should not have been touched to
    begin with.  Reverted.
    
    > 3. This should use READ_OID_FIELD()
    >
    > READ_INT_FIELD(checkAsUser);
    >
    > and this one:
    >
    > READ_INT_FIELD(relid);
    
    Fixed.
    
    > 4.  This looks wrong:
    >
    > - rel->userid = rte->checkAsUser;
    > + if (rte->rtekind == RTE_RELATION)
    > + {
    > + /* otherrels use the root parent's value. */
    > + rel->userid = parent ? parent->userid :
    > + GetRelPermissionInfo(root->parse->relpermlist,
    > + rte, false)->checkAsUser;
    > + }
    >
    > If 'parent' is false then you'll assign the result of
    > GetRelPermissionInfo (a RelPermissionInfo *) to an Oid.
    
    Hmm, I don't see a problem, because what's being assigned is
    `GetRelPermissionInfo(...)->checkAsUser`.
    
    Anyway, I rewrote the block more verbosely as:
    
        if (rte->rtekind == RTE_RELATION)
        {
    -       /* otherrels use the root parent's value. */
    -       rel->userid = parent ? parent->userid :
    -           GetRelPermissionInfo(root->parse->relpermlist,
    -                                rte, false)->checkAsUser;
    +       /*
    +        * Get the userid from the relation's RelPermissionInfo, though
    +        * only the tables mentioned in query are assigned RelPermissionInfos.
    +        * Child relations (otherrels) simply use the parent's value.
    +        */
    +       if (parent == NULL)
    +       {
    +           RelPermissionInfo *perminfo =
    +               GetRelPermissionInfo(root->parse->relpermlist, rte, false);
    +
    +           rel->userid = perminfo->checkAsUser;
    +       }
    +       else
    +           rel->userid = parent->userid;
        }
    +   else
    +       rel->userid = InvalidOid;
    
    > 5. I'm not sure if there's a case that can break this one, but I'm not
    > very confident that there's not one:
    >
    > I'm not sure I agree with how you've coded GetRelPermissionInfo().
    > You're searching for a RelPermissionInfo based on the table's Oid.  If
    > you have multiple RelPermissionInfos for the same Oid then this will
    > just find the first one and return it, but that might not be the one
    > for the RangeTblEntry in question.
    >
    > Here's an example of the sort of thing that could have problems with this:
    >
    > postgres=# create role bob;
    > CREATE ROLE
    > postgres=# create table ab (a int, b int);
    > CREATE TABLE
    > postgres=# grant all (a) on table ab to bob;
    > GRANT
    > postgres=# set session authorization bob;
    > SET
    > postgres=> update ab set a = (select b from ab);
    > ERROR:  permission denied for table ab
    >
    > The patch does correctly ERROR out here on permission failure, but as
    > far as I can see, that's just due to the fact that we're checking the
    > permissions of all items in the PlannedStmt.relpermlist List.  If
    > there had been code that had tried to find the RelPermissionInfo based
    > on the relation's Oid then we'd have accidentally found that we only
    > need an UPDATE permission on (a).  SELECT on (b) wouldn't have been
    > checked.
    >
    > As far as I can see, to fix that you'd either need to store the RTI of
    > the RelPermissionInfo and lookup based on that, or you'd have to
    > bms_union() all the columns and bitwise OR the required permissions
    > and ensure you only have 1 RelPermissionInfo per Oid.
    >
    > The fact that I have two entries when I debug InitPlan() seems to
    > disagree with what the comment in AddRelPermissionInfo() is claiming
    > should happen:
    >
    > /*
    > * To prevent duplicate entries for a given relation, check if already in
    > * the list.
    > */
    >
    > I'm not clear on if the list is meant to be unique on Oid or not.
    
    Yeah, it is, but it seems that the code I added in
    add_rtes_to_flat_rtable() to accumulate various subplans' relpermlists
    into finalrelpermlist didn't actually bother to unique'ify the list.
    It used list_concat() to combine finalrelpermlist and a given
    subplan's relpermlist, instead of MergeRelPemissionInfos to merge the
    two lists.
    
    I've fixed that in the attached and can now see that the plan for the
    query in your example ends up with just one RelPermissionInfo which
    combines the permissions and column bitmapsets for all operations.
    
    > 6. acesss?
    >
    > - * Set flags and access permissions.
    > + * Set flags and initialize acesss permissions.
    >
    > 7. I was expecting to see an |= here:
    >
    > + /* "merge" proprties. */
    > + dest_perminfo->inh = src_perminfo->inh;
    >
    > Why is a plain assignment ok?
    
    You're perhaps right that |= is correct.  I forget the details but I
    think I added 'inh' field to RelPemissionInfo to get some tests in
    sepgsql contrib module to pass and those tests apparently didn't mind
    the current coding.
    
    > 8. Some indentation problems here:
    >
    > @@ -3170,6 +3148,8 @@ rewriteTargetView(Query *parsetree, Relation view)
    >
    >   base_rt_index = rtr->rtindex;
    >   base_rte = rt_fetch(base_rt_index, viewquery->rtable);
    > +base_perminfo = GetRelPermissionInfo(viewquery->relpermlist, base_rte,
    > + false);
    
    Fixed.
    
    >
    > 9. You can use foreach_current_index(lc) + 1 in:
    >
    > + i = 0;
    > + foreach(lc, relpermlist)
    > + {
    > + perminfo = (RelPermissionInfo *) lfirst(lc);
    > + if (perminfo->relid == rte->relid)
    > + {
    > + /* And set the index in RTE. */
    > + rte->perminfoindex = i + 1;
    > + return perminfo;
    > + }
    > + i++;
    > + }
    
    Oh, nice tip.  Done.
    
    > 10. I think the double quote is not in the correct place in this comment:
    >
    >   List    *finalrtable; /* "flat" rangetable for executor */
    >
    > + List    *finalrelpermlist; /* "flat list of RelPermissionInfo "*/
    >
    >
    > 11. Looks like an accidental change:
    >
    > +++ b/src/include/optimizer/planner.h
    > @@ -58,4 +58,5 @@ extern Path *get_cheapest_fractional_path(RelOptInfo *rel,
    >
    >  extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr);
    >
    > +
    >
    > 12. These need to be broken into multiple lines:
    >
    > +extern RelPermissionInfo *AddRelPermissionInfo(List **relpermlist,
    > RangeTblEntry *rte);
    > +extern void MergeRelPermissionInfos(Query *dest_query, List *src_relpermlist);
    > +extern RelPermissionInfo *GetRelPermissionInfo(List *relpermlist,
    > RangeTblEntry *rte, bool missing_ok);
    
    All fixed.
    
    v11 attached.
    
    --
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  25. Re: ExecRTCheckPerms() and many prunable partitions

    Greg Stark <stark@mit.edu> — 2022-04-05T14:26:58Z

    This is failing regression tests. I don't understand how this patch
    could be affecting this test though. Perhaps it's a problem with the
    json patches that were committed recently -- but they don't seem to be
    causing other patches to fail.
    
    
    diff -U3 /tmp/cirrus-ci-build/src/test/regress/expected/jsonb_sqljson.out
    /tmp/cirrus-ci-build/src/test/regress/results/jsonb_sqljson.out
    --- /tmp/cirrus-ci-build/src/test/regress/expected/jsonb_sqljson.out
    2022-04-05 12:15:40.590168291 +0000
    +++ /tmp/cirrus-ci-build/src/test/regress/results/jsonb_sqljson.out
    2022-04-05 12:20:17.338045137 +0000
    @@ -1159,37 +1159,37 @@
      );
     \sv jsonb_table_view
     CREATE OR REPLACE VIEW public.jsonb_table_view AS
    - SELECT "json_table".id,
    -    "json_table".id2,
    -    "json_table"."int",
    -    "json_table".text,
    -    "json_table"."char(4)",
    -    "json_table".bool,
    -    "json_table"."numeric",
    -    "json_table".domain,
    -    "json_table".js,
    -    "json_table".jb,
    -    "json_table".jst,
    -    "json_table".jsc,
    -    "json_table".jsv,
    -    "json_table".jsb,
    -    "json_table".jsbq,
    -    "json_table".aaa,
    -    "json_table".aaa1,
    -    "json_table".exists1,
    -    "json_table".exists2,
    -    "json_table".exists3,
    -    "json_table".js2,
    -    "json_table".jsb2w,
    -    "json_table".jsb2q,
    -    "json_table".ia,
    -    "json_table".ta,
    -    "json_table".jba,
    -    "json_table".a1,
    -    "json_table".b1,
    -    "json_table".a11,
    -    "json_table".a21,
    -    "json_table".a22
    + SELECT id,
    +    id2,
    +    "int",
    +    text,
    +    "char(4)",
    +    bool,
    +    "numeric",
    +    domain,
    +    js,
    +    jb,
    +    jst,
    +    jsc,
    +    jsv,
    +    jsb,
    +    jsbq,
    +    aaa,
    +    aaa1,
    +    exists1,
    +    exists2,
    +    exists3,
    +    js2,
    +    jsb2w,
    +    jsb2q,
    +    ia,
    +    ta,
    +    jba,
    +    a1,
    +    b1,
    +    a11,
    +    a21,
    +    a22
        FROM JSON_TABLE(
                 'null'::jsonb, '$[*]'
                 PASSING
    
    
    On Wed, 30 Mar 2022 at 23:16, Amit Langote <amitlangote09@gmail.com> wrote:
    >
    > On Fri, Mar 25, 2022 at 4:46 AM David Rowley <dgrowleyml@gmail.com> wrote:
    > > I had a look at the v10-0001 patch. I agree that it seems to be a good
    > > idea to separate out the required permission checks rather than having
    > > the Bitmapset to index the interesting range table entries.
    >
    > Thanks David for taking a look at this.
    >
    > > One thing that I could just not determine from looking at the patch
    > > was if there's meant to be just 1 RelPermissionInfo per RTE or per rel
    > > Oid.
    >
    > It's the latter.
    >
    > > None of the comments helped me understand this
    >
    > I agree that the comment above the RelPermissionInfo struct definition
    > missed mentioning this really important bit.  I've tried fixing that
    > as:
    >
    > @@ -1142,7 +1142,9 @@ typedef struct RangeTblEntry
    >   *         Per-relation information for permission checking. Added to the query
    >   *         by the parser when populating the query range table and subsequently
    >   *         editorialized on by the rewriter and the planner.  There is an entry
    > - *         each for all RTE_RELATION entries present in the range table.
    > + *         each for all RTE_RELATION entries present in the range table, though
    > + *         different RTEs for the same relation share the
    > RelPermissionInfo, that
    > + *         is, there is only one RelPermissionInfo containing a given relid.
    >
    > > and
    > > MergeRelPermissionInfos() seems to exist that appears to try and
    > > uniquify this to some extent.  I just see no code that does this
    > > process for a single query level. I've provided more detail on this in
    > > #5 below.
    > >
    > > Here's my complete review of v10-0001:
    > >
    > > 1. ExecCheckPermisssions -> ExecCheckPermissions
    >
    > Fixed.
    >
    > > 2. I think you'll want to move the userid field away from below a
    > > comment that claims the following fields are for foreign tables only.
    > >
    > >   /* Information about foreign tables and foreign joins */
    > >   Oid serverid; /* identifies server for the table or join */
    > > - Oid userid; /* identifies user to check access as */
    > > + Oid userid; /* identifies user to check access as; set
    > > + * in non-foreign table relations too! */
    >
    > Actually, I realized that the comment should not have been touched to
    > begin with.  Reverted.
    >
    > > 3. This should use READ_OID_FIELD()
    > >
    > > READ_INT_FIELD(checkAsUser);
    > >
    > > and this one:
    > >
    > > READ_INT_FIELD(relid);
    >
    > Fixed.
    >
    > > 4.  This looks wrong:
    > >
    > > - rel->userid = rte->checkAsUser;
    > > + if (rte->rtekind == RTE_RELATION)
    > > + {
    > > + /* otherrels use the root parent's value. */
    > > + rel->userid = parent ? parent->userid :
    > > + GetRelPermissionInfo(root->parse->relpermlist,
    > > + rte, false)->checkAsUser;
    > > + }
    > >
    > > If 'parent' is false then you'll assign the result of
    > > GetRelPermissionInfo (a RelPermissionInfo *) to an Oid.
    >
    > Hmm, I don't see a problem, because what's being assigned is
    > `GetRelPermissionInfo(...)->checkAsUser`.
    >
    > Anyway, I rewrote the block more verbosely as:
    >
    >     if (rte->rtekind == RTE_RELATION)
    >     {
    > -       /* otherrels use the root parent's value. */
    > -       rel->userid = parent ? parent->userid :
    > -           GetRelPermissionInfo(root->parse->relpermlist,
    > -                                rte, false)->checkAsUser;
    > +       /*
    > +        * Get the userid from the relation's RelPermissionInfo, though
    > +        * only the tables mentioned in query are assigned RelPermissionInfos.
    > +        * Child relations (otherrels) simply use the parent's value.
    > +        */
    > +       if (parent == NULL)
    > +       {
    > +           RelPermissionInfo *perminfo =
    > +               GetRelPermissionInfo(root->parse->relpermlist, rte, false);
    > +
    > +           rel->userid = perminfo->checkAsUser;
    > +       }
    > +       else
    > +           rel->userid = parent->userid;
    >     }
    > +   else
    > +       rel->userid = InvalidOid;
    >
    > > 5. I'm not sure if there's a case that can break this one, but I'm not
    > > very confident that there's not one:
    > >
    > > I'm not sure I agree with how you've coded GetRelPermissionInfo().
    > > You're searching for a RelPermissionInfo based on the table's Oid.  If
    > > you have multiple RelPermissionInfos for the same Oid then this will
    > > just find the first one and return it, but that might not be the one
    > > for the RangeTblEntry in question.
    > >
    > > Here's an example of the sort of thing that could have problems with this:
    > >
    > > postgres=# create role bob;
    > > CREATE ROLE
    > > postgres=# create table ab (a int, b int);
    > > CREATE TABLE
    > > postgres=# grant all (a) on table ab to bob;
    > > GRANT
    > > postgres=# set session authorization bob;
    > > SET
    > > postgres=> update ab set a = (select b from ab);
    > > ERROR:  permission denied for table ab
    > >
    > > The patch does correctly ERROR out here on permission failure, but as
    > > far as I can see, that's just due to the fact that we're checking the
    > > permissions of all items in the PlannedStmt.relpermlist List.  If
    > > there had been code that had tried to find the RelPermissionInfo based
    > > on the relation's Oid then we'd have accidentally found that we only
    > > need an UPDATE permission on (a).  SELECT on (b) wouldn't have been
    > > checked.
    > >
    > > As far as I can see, to fix that you'd either need to store the RTI of
    > > the RelPermissionInfo and lookup based on that, or you'd have to
    > > bms_union() all the columns and bitwise OR the required permissions
    > > and ensure you only have 1 RelPermissionInfo per Oid.
    > >
    > > The fact that I have two entries when I debug InitPlan() seems to
    > > disagree with what the comment in AddRelPermissionInfo() is claiming
    > > should happen:
    > >
    > > /*
    > > * To prevent duplicate entries for a given relation, check if already in
    > > * the list.
    > > */
    > >
    > > I'm not clear on if the list is meant to be unique on Oid or not.
    >
    > Yeah, it is, but it seems that the code I added in
    > add_rtes_to_flat_rtable() to accumulate various subplans' relpermlists
    > into finalrelpermlist didn't actually bother to unique'ify the list.
    > It used list_concat() to combine finalrelpermlist and a given
    > subplan's relpermlist, instead of MergeRelPemissionInfos to merge the
    > two lists.
    >
    > I've fixed that in the attached and can now see that the plan for the
    > query in your example ends up with just one RelPermissionInfo which
    > combines the permissions and column bitmapsets for all operations.
    >
    > > 6. acesss?
    > >
    > > - * Set flags and access permissions.
    > > + * Set flags and initialize acesss permissions.
    > >
    > > 7. I was expecting to see an |= here:
    > >
    > > + /* "merge" proprties. */
    > > + dest_perminfo->inh = src_perminfo->inh;
    > >
    > > Why is a plain assignment ok?
    >
    > You're perhaps right that |= is correct.  I forget the details but I
    > think I added 'inh' field to RelPemissionInfo to get some tests in
    > sepgsql contrib module to pass and those tests apparently didn't mind
    > the current coding.
    >
    > > 8. Some indentation problems here:
    > >
    > > @@ -3170,6 +3148,8 @@ rewriteTargetView(Query *parsetree, Relation view)
    > >
    > >   base_rt_index = rtr->rtindex;
    > >   base_rte = rt_fetch(base_rt_index, viewquery->rtable);
    > > +base_perminfo = GetRelPermissionInfo(viewquery->relpermlist, base_rte,
    > > + false);
    >
    > Fixed.
    >
    > >
    > > 9. You can use foreach_current_index(lc) + 1 in:
    > >
    > > + i = 0;
    > > + foreach(lc, relpermlist)
    > > + {
    > > + perminfo = (RelPermissionInfo *) lfirst(lc);
    > > + if (perminfo->relid == rte->relid)
    > > + {
    > > + /* And set the index in RTE. */
    > > + rte->perminfoindex = i + 1;
    > > + return perminfo;
    > > + }
    > > + i++;
    > > + }
    >
    > Oh, nice tip.  Done.
    >
    > > 10. I think the double quote is not in the correct place in this comment:
    > >
    > >   List    *finalrtable; /* "flat" rangetable for executor */
    > >
    > > + List    *finalrelpermlist; /* "flat list of RelPermissionInfo "*/
    > >
    > >
    > > 11. Looks like an accidental change:
    > >
    > > +++ b/src/include/optimizer/planner.h
    > > @@ -58,4 +58,5 @@ extern Path *get_cheapest_fractional_path(RelOptInfo *rel,
    > >
    > >  extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr);
    > >
    > > +
    > >
    > > 12. These need to be broken into multiple lines:
    > >
    > > +extern RelPermissionInfo *AddRelPermissionInfo(List **relpermlist,
    > > RangeTblEntry *rte);
    > > +extern void MergeRelPermissionInfos(Query *dest_query, List *src_relpermlist);
    > > +extern RelPermissionInfo *GetRelPermissionInfo(List *relpermlist,
    > > RangeTblEntry *rte, bool missing_ok);
    >
    > All fixed.
    >
    > v11 attached.
    >
    > --
    > Amit Langote
    > EDB: http://www.enterprisedb.com
    
    
    
    --
    greg
    
    
    
    
  26. Re: ExecRTCheckPerms() and many prunable partitions

    David Rowley <dgrowleyml@gmail.com> — 2022-04-05T20:21:40Z

    On Wed, 6 Apr 2022 at 02:27, Greg Stark <stark@mit.edu> wrote:
    >
    > This is failing regression tests. I don't understand how this patch
    > could be affecting this test though. Perhaps it's a problem with the
    > json patches that were committed recently -- but they don't seem to be
    > causing other patches to fail.
    
    I think this will just be related to the useprefix =
    list_length(es->rtable) > 1; in show_plan_tlist().  There's likely not
    much point in keeping the RTE for the view anymore. IIRC it was just
    there to check permissions. Amit has now added another way of doing
    those.
    
    David
    
    
    
    
  27. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-04-06T01:18:48Z

    On Wed, Apr 6, 2022 at 5:22 AM David Rowley <dgrowleyml@gmail.com> wrote:
    > On Wed, 6 Apr 2022 at 02:27, Greg Stark <stark@mit.edu> wrote:
    > >
    > > This is failing regression tests. I don't understand how this patch
    > > could be affecting this test though. Perhaps it's a problem with the
    > > json patches that were committed recently -- but they don't seem to be
    > > causing other patches to fail.
    >
    > I think this will just be related to the useprefix =
    > list_length(es->rtable) > 1; in show_plan_tlist().  There's likely not
    > much point in keeping the RTE for the view anymore. IIRC it was just
    > there to check permissions. Amit has now added another way of doing
    > those.
    
    That is correct.
    
    I have rebased the patch and updated expected output of the failing test.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  28. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-04-11T05:41:16Z

    Rebased to keep the cfbot green for now.
    
    -- 
    Amit Langote
    EDB: http://www.enterprisedb.com
    
  29. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-07-06T03:25:42Z

    On Mon, Apr 11, 2022 at 2:41 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > Rebased to keep the cfbot green for now.
    
    And again to fix the rules.out conflicts.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  30. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-07-13T08:00:29Z

    Rebased over 964d01ae90.
    
    
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  31. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-07-27T03:14:10Z

    On Wed, Jul 13, 2022 at 5:00 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > Rebased over 964d01ae90.
    
    Rebased over 2d04277121f.
    
    
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  32. Re: ExecRTCheckPerms() and many prunable partitions

    Tom Lane <tgl@sss.pgh.pa.us> — 2022-07-27T21:04:15Z

    Amit Langote <amitlangote09@gmail.com> writes:
    > [ v16 patches ]
    
    I took a quick look at this ...
    
    I think that the notion behind MergeRelPermissionInfos, ie that
    a single RelPermissionInfo can represent *all* the checks for
    a given table OID, is fundamentally wrong.  For example, when
    merging a view into an outer query that references a table
    also used by the view, the checkAsUser fields might be different,
    and the permissions to check might be different, and the columns
    those permissions need to hold for might be different.  Blindly
    bms_union'ing the column sets will lead to requiring far more
    permissions than the query should require.  Conversely, this
    approach could lead to allowing cases we should reject, if you
    happen to "merge" checkAsUser in a way that ends in checking as a
    higher-privilege user than should be checked.
    
    I'm inclined to think that you should abandon the idea of
    merging RelPermissionInfos at all.  It can only buy us much
    in the case of self-joins, which ought to be rare.  It'd
    be better to just say "there is one RelPermissionInfo for
    each RTE requiring any sort of permissions check".  Either
    that or you need to complicate RelPermissionInfo a lot, but
    I don't see the advantage.
    
    It'd likely be better to rename ExecutorCheckPerms_hook,
    say to ExecCheckPermissions_hook given the rename of
    ExecCheckRTPerms.  As it stands, it *looks* like the API
    of that hook has not changed, when it has.  Better to
    break calling code visibly than to make people debug their
    way to an understanding that the List contents are no longer
    what they expected.  A different idea could be to pass both
    the rangetable and relpermlist, again making the API break obvious
    (and who's to say a hook might not still want the rangetable?)
    
    In parsenodes.h:
    +    List       *relpermlist;    /* list of RTEPermissionInfo nodes for
    +                                 * the RTE_RELATION entries in rtable */
    
    I find this comment not very future-proof, if indeed it's strictly
    correct even today.  Maybe better "list of RelPermissionInfo nodes for
    rangetable entries having perminfoindex > 0".  Likewise for the comment
    in RangeTableEntry: there's no compelling reason to assume that all and
    only RELATION RTEs will have RelPermissionInfo.  Even if that remains
    true at parse time it's falsified during planning.
    
    Also note typo in node name: that comment is the only reference to
    "RTEPermissionInfo" AFAICS.  Although, given the redefinition I
    suggest above, arguably "RTEPermissionInfo" is the better name?
    
    I'm confused as to why RelPermissionInfo.inh exists.  It doesn't
    seem to me that permissions checking should care about child rels.
    
    Why did you add checkAsUser to ForeignScan (and not any other scan
    plan nodes)?  At best that's pretty asymmetric, but it seems mighty
    bogus: under what circumstances would an FDW need to know that but
    not any of the other RelPermissionInfo fields?  This seems to
    indicate that someplace we should work harder at making the
    RelPermissionInfo list available to FDWs.  (CustomScan providers
    might have similar issues, btw.)
    
    I've not looked at much of the actual code, just the .h file changes.
    Haven't studied 0002 either.
    
    			regards, tom lane
    
    
    
    
  33. Re: ExecRTCheckPerms() and many prunable partitions

    Tom Lane <tgl@sss.pgh.pa.us> — 2022-07-27T21:18:38Z

    ... One more thing: maybe we should rethink where to put
    extraUpdatedCols.  Between the facts that it's not used for
    actual permissions checks, and that it's calculated by the
    rewriter not parser, it doesn't seem like it really belongs
    in RelPermissionInfo.  Should we keep it in RangeTblEntry?
    Should it go somewhere else entirely?  I'm just speculating,
    but now is a good time to think about it.
    
    			regards, tom lane
    
    
    
    
  34. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-09-07T09:23:06Z

    On Thu, Jul 28, 2022 at 6:04 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Amit Langote <amitlangote09@gmail.com> writes:
    > > [ v16 patches ]
    >
    > I took a quick look at this ...
    
    Thanks for the review and sorry about the delay.
    
    > I think that the notion behind MergeRelPermissionInfos, ie that
    > a single RelPermissionInfo can represent *all* the checks for
    > a given table OID, is fundamentally wrong.  For example, when
    > merging a view into an outer query that references a table
    > also used by the view, the checkAsUser fields might be different,
    > and the permissions to check might be different, and the columns
    > those permissions need to hold for might be different.  Blindly
    > bms_union'ing the column sets will lead to requiring far more
    > permissions than the query should require.  Conversely, this
    > approach could lead to allowing cases we should reject, if you
    > happen to "merge" checkAsUser in a way that ends in checking as a
    > higher-privilege user than should be checked.
    >
    > I'm inclined to think that you should abandon the idea of
    > merging RelPermissionInfos at all.  It can only buy us much
    > in the case of self-joins, which ought to be rare.  It'd
    > be better to just say "there is one RelPermissionInfo for
    > each RTE requiring any sort of permissions check".  Either
    > that or you need to complicate RelPermissionInfo a lot, but
    > I don't see the advantage.
    
    OK, I agree that the complexity of sharing a RelPermissionInfo between
    RTEs far exceeds any performance benefit to be had from it.
    
    I have changed things so that there's one RelPermissionInfo for every
    RTE_RELATION entry in the range table, except those that the planner
    adds when expanding inheritance.
    
    > It'd likely be better to rename ExecutorCheckPerms_hook,
    > say to ExecCheckPermissions_hook given the rename of
    > ExecCheckRTPerms.  As it stands, it *looks* like the API
    > of that hook has not changed, when it has.  Better to
    > break calling code visibly than to make people debug their
    > way to an understanding that the List contents are no longer
    > what they expected.  A different idea could be to pass both
    > the rangetable and relpermlist, again making the API break obvious
    > (and who's to say a hook might not still want the rangetable?)
    
    I agree it'd be better to break the API more explicitly.  Actually, I
    decided to adopt both of these suggestions: renamed the hook and kept
    the rangeTable parameter.
    
    > In parsenodes.h:
    > +    List       *relpermlist;    /* list of RTEPermissionInfo nodes for
    > +                                 * the RTE_RELATION entries in rtable */
    >
    > I find this comment not very future-proof, if indeed it's strictly
    > correct even today.  Maybe better "list of RelPermissionInfo nodes for
    > rangetable entries having perminfoindex > 0".  Likewise for the comment
    > in RangeTableEntry: there's no compelling reason to assume that all and
    > only RELATION RTEs will have RelPermissionInfo.  Even if that remains
    > true at parse time it's falsified during planning.
    
    Ah right, inheritance children's RTE_RELATION entries don't have one.
    I've fixed the comment.
    
    > Also note typo in node name: that comment is the only reference to
    > "RTEPermissionInfo" AFAICS.  Although, given the redefinition I
    > suggest above, arguably "RTEPermissionInfo" is the better name?
    
    Agreed.  I've renamed RelPermissionInfo to RTEPermissionInfo and
    relpermlist to rtepermlist.
    
    > I'm confused as to why RelPermissionInfo.inh exists.  It doesn't
    > seem to me that permissions checking should care about child rels.
    
    I had to do this for contrib/sepgsql, sepgsql_dml_privileges() has this:
    
            /*
             * If this RangeTblEntry is also supposed to reference inherited
             * tables, we need to check security label of the child tables. So, we
             * expand rte->relid into list of OIDs of inheritance hierarchy, then
             * checker routine will be invoked for each relations.
             */
            if (!rte->inh)
                tableIds = list_make1_oid(rte->relid);
            else
                tableIds = find_all_inheritors(rte->relid, NoLock, NULL);
    
    > Why did you add checkAsUser to ForeignScan (and not any other scan
    > plan nodes)?  At best that's pretty asymmetric, but it seems mighty
    > bogus: under what circumstances would an FDW need to know that but
    > not any of the other RelPermissionInfo fields?  This seems to
    > indicate that someplace we should work harder at making the
    > RelPermissionInfo list available to FDWs.  (CustomScan providers
    > might have similar issues, btw.)
    
    I think I had tried doing what you are suggesting -- getting the
    checkAsUser from a RelPermissionInfo rather than putting that in
    ForeignScan -- though we can't do it, because we need the userid for
    child foreign table relations, for which we don't create a
    RelPermissionInfo.  ForeignScan nodes for child relations don't store
    their root parent's RT index, so we can't get the checkAsUser using
    the root parent's RelPermissionInfo, like I could do for child foreign
    table "result" relations using ResultRelInfo.ri_RootResultRelInfo.
    
    As to why an FDW may not need to know any of the other
    RelPermissionInfo fields, IIUC, ExecCheckPermissions() would have done
    everything that ought to be done *locally* using that information.
    Whatever the remote side needs to know wrt access permission checking
    should have been put in fdw_private, no?
    
    On Thu, Jul 28, 2022 at 6:18 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > ... One more thing: maybe we should rethink where to put
    > extraUpdatedCols.  Between the facts that it's not used for
    > actual permissions checks, and that it's calculated by the
    > rewriter not parser, it doesn't seem like it really belongs
    > in RelPermissionInfo.  Should we keep it in RangeTblEntry?
    > Should it go somewhere else entirely?  I'm just speculating,
    > but now is a good time to think about it.
    
    Indeed, extraUpdatedCols doesn't really seem to belong in
    RelPermissionInfo, so I have left it in RangeTblEntry.
    
    Attached updated patches.
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  35. Re: ExecRTCheckPerms() and many prunable partitions

    Andres Freund <andres@anarazel.de> — 2022-10-02T17:10:36Z

    Hi,
    
    On 2022-09-07 18:23:06 +0900, Amit Langote wrote:
    > Attached updated patches.
    
    Thanks to Justin's recent patch (89d16b63527) to add
    -DRELCACHE_FORCE_RELEASE -DCOPY_PARSE_PLAN_TREES -DWRITE_READ_PARSE_PLAN_TREES -DRAW_EXPRESSION_COVERAGE_TEST
    to the FreeBSD ci task we now see the following:
    
    https://cirrus-ci.com/task/4772259058417664
    https://api.cirrus-ci.com/v1/artifact/task/4772259058417664/testrun/build/testrun/main/regress/regression.diffs
    
    diff -U3 /tmp/cirrus-ci-build/src/test/regress/expected/updatable_views.out /tmp/cirrus-ci-build/build/testrun/main/regress/results/updatable_views.out
    --- /tmp/cirrus-ci-build/src/test/regress/expected/updatable_views.out	2022-10-02 10:37:08.888945000 +0000
    +++ /tmp/cirrus-ci-build/build/testrun/main/regress/results/updatable_views.out	2022-10-02 10:40:26.947887000 +0000
    @@ -1727,14 +1727,16 @@
     (4 rows)
    
     UPDATE base_tbl SET id = 2000 WHERE id = 2;
    +WARNING:  outfuncs/readfuncs failed to produce an equal rewritten parse tree
     UPDATE rw_view1 SET id = 3000 WHERE id = 3;
    +WARNING:  outfuncs/readfuncs failed to produce an equal rewritten parse tree
     SELECT * FROM base_tbl;
       id  | idplus1
     ------+---------
         1 |       2
         4 |       5
    - 2000 |    2001
    - 3000 |    3001
    + 2000 |       3
    + 3000 |       4
     (4 rows)
    
     DROP TABLE base_tbl CASCADE;
    
    and many more.
    
    Greetings,
    
    Andres Freund
    
    
    
    
  36. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-03T09:10:13Z

    Hi,
    
    On Mon, Oct 3, 2022 at 2:10 AM Andres Freund <andres@anarazel.de> wrote:
    > On 2022-09-07 18:23:06 +0900, Amit Langote wrote:
    > > Attached updated patches.
    >
    > Thanks to Justin's recent patch (89d16b63527) to add
    > -DRELCACHE_FORCE_RELEASE -DCOPY_PARSE_PLAN_TREES -DWRITE_READ_PARSE_PLAN_TREES -DRAW_EXPRESSION_COVERAGE_TEST
    > to the FreeBSD ci task we now see the following:
    >
    > https://cirrus-ci.com/task/4772259058417664
    > https://api.cirrus-ci.com/v1/artifact/task/4772259058417664/testrun/build/testrun/main/regress/regression.diffs
    >
    > diff -U3 /tmp/cirrus-ci-build/src/test/regress/expected/updatable_views.out /tmp/cirrus-ci-build/build/testrun/main/regress/results/updatable_views.out
    > --- /tmp/cirrus-ci-build/src/test/regress/expected/updatable_views.out  2022-10-02 10:37:08.888945000 +0000
    > +++ /tmp/cirrus-ci-build/build/testrun/main/regress/results/updatable_views.out 2022-10-02 10:40:26.947887000 +0000
    > @@ -1727,14 +1727,16 @@
    >  (4 rows)
    >
    >  UPDATE base_tbl SET id = 2000 WHERE id = 2;
    > +WARNING:  outfuncs/readfuncs failed to produce an equal rewritten parse tree
    >  UPDATE rw_view1 SET id = 3000 WHERE id = 3;
    > +WARNING:  outfuncs/readfuncs failed to produce an equal rewritten parse tree
    >  SELECT * FROM base_tbl;
    >    id  | idplus1
    >  ------+---------
    >      1 |       2
    >      4 |       5
    > - 2000 |    2001
    > - 3000 |    3001
    > + 2000 |       3
    > + 3000 |       4
    >  (4 rows)
    >
    >  DROP TABLE base_tbl CASCADE;
    >
    > and many more.
    
    Thanks for the heads up.  Grateful for those new -D flags.
    
    Turns out I had forgotten to update out/readRangeTblEntry() after
    bringing extraUpdatedCols back into RangeTblEntry per Tom's comment.
    
    Fixed in the attached.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  37. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-04T03:45:30Z

    On Thu, Jul 28, 2022 at 6:18 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > ... One more thing: maybe we should rethink where to put
    > extraUpdatedCols.  Between the facts that it's not used for
    > actual permissions checks, and that it's calculated by the
    > rewriter not parser, it doesn't seem like it really belongs
    > in RelPermissionInfo.  Should we keep it in RangeTblEntry?
    > Should it go somewhere else entirely?  I'm just speculating,
    > but now is a good time to think about it.
    
    After fixing the issue related to this mentioned by Andres, I started
    thinking more about this, especially the "Should it go somewhere else
    entirely?" part.
    
    I've kept extraUpdatedCols in RangeTblEntry in the latest patch, but
    perhaps it makes sense to put that into Query?  So, the stanza in
    RewriteQuery() that sets extraUpdatedCols will be changed as:
    
    @@ -3769,7 +3769,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
                                        NULL, 0, NULL);
    
                /* Also populate extraUpdatedCols (for generated columns) */
    -           fill_extraUpdatedCols(rt_entry, rt_perminfo, rt_entry_relation);
    +           parsetree->extraUpdatedCols =
    +               get_extraUpdatedCols(rt_entry, rt_perminfo, rt_entry_relation);
            }
            else if (event == CMD_MERGE)
            {
    
    Then, like withCheckOptionLists et al, have grouping_planner()
    populate an extraUpdatedColsBitmaps in ModifyTable.
    ExecInitModifyTable() will assign them directly into ResultRelInfos.
    That way, anyplace in the executor that needs to look at
    extraUpdatedCols of a given result relation can get that from its
    ResultRelInfo, rather than from the RangeTblEntry as now.
    
    Thoughts?
    
    
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  38. Re: ExecRTCheckPerms() and many prunable partitions

    Tom Lane <tgl@sss.pgh.pa.us> — 2022-10-04T03:54:27Z

    Amit Langote <amitlangote09@gmail.com> writes:
    > On Thu, Jul 28, 2022 at 6:18 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    >> ... One more thing: maybe we should rethink where to put
    >> extraUpdatedCols.  Between the facts that it's not used for
    >> actual permissions checks, and that it's calculated by the
    >> rewriter not parser, it doesn't seem like it really belongs
    >> in RelPermissionInfo.  Should we keep it in RangeTblEntry?
    >> Should it go somewhere else entirely?  I'm just speculating,
    >> but now is a good time to think about it.
    
    > I've kept extraUpdatedCols in RangeTblEntry in the latest patch, but
    > perhaps it makes sense to put that into Query?
    
    That's got morally the same problem as keeping it in RangeTblEntry:
    those are structures that are built by the parser.  Hacking on them
    later isn't terribly clean.
    
    I wonder if it could make sense to postpone calculation of the
    extraUpdatedCols out of the rewriter and into the planner, with
    the idea that it ends up $someplace in the finished plan tree
    but isn't part of the original parsetree.
    
    A different aspect of this is that putting it in Query doesn't
    make a lot of sense unless there is only one version of the
    bitmap per Query.  In simple UPDATEs that would be true, but
    I think that inherited/partitioned UPDATEs would need one per
    result relation, which is likely the reason it got dumped in
    RangeTblEntry to begin with.
    
    			regards, tom lane
    
    
    
    
  39. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-04T04:11:08Z

    On Tue, Oct 4, 2022 at 12:54 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Amit Langote <amitlangote09@gmail.com> writes:
    > > On Thu, Jul 28, 2022 at 6:18 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > >> ... One more thing: maybe we should rethink where to put
    > >> extraUpdatedCols.  Between the facts that it's not used for
    > >> actual permissions checks, and that it's calculated by the
    > >> rewriter not parser, it doesn't seem like it really belongs
    > >> in RelPermissionInfo.  Should we keep it in RangeTblEntry?
    > >> Should it go somewhere else entirely?  I'm just speculating,
    > >> but now is a good time to think about it.
    >
    > > I've kept extraUpdatedCols in RangeTblEntry in the latest patch, but
    > > perhaps it makes sense to put that into Query?
    >
    > That's got morally the same problem as keeping it in RangeTblEntry:
    > those are structures that are built by the parser.  Hacking on them
    > later isn't terribly clean.
    >
    > I wonder if it could make sense to postpone calculation of the
    > extraUpdatedCols out of the rewriter and into the planner, with
    > the idea that it ends up $someplace in the finished plan tree
    > but isn't part of the original parsetree.
    
    Looking at PlannerInfo.update_colnos, something that's needed for
    execution but not in Query, maybe we can make preprocess_targetlist()
    also populate an PlannerInfo.extraUpdatedCols?
    
    > A different aspect of this is that putting it in Query doesn't
    > make a lot of sense unless there is only one version of the
    > bitmap per Query.  In simple UPDATEs that would be true, but
    > I think that inherited/partitioned UPDATEs would need one per
    > result relation, which is likely the reason it got dumped in
    > RangeTblEntry to begin with.
    
    Yeah, so if we have PlannerInfos.extraUpdatedCols as the root table's
    version of that, grouping_planner() can make copies for all result
    relations and put the list in ModifyTable.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  40. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-06T13:29:46Z

    On Tue, Oct 4, 2022 at 1:11 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Tue, Oct 4, 2022 at 12:54 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > > Amit Langote <amitlangote09@gmail.com> writes:
    > > > On Thu, Jul 28, 2022 at 6:18 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > > >> ... One more thing: maybe we should rethink where to put
    > > >> extraUpdatedCols.  Between the facts that it's not used for
    > > >> actual permissions checks, and that it's calculated by the
    > > >> rewriter not parser, it doesn't seem like it really belongs
    > > >> in RelPermissionInfo.  Should we keep it in RangeTblEntry?
    > > >> Should it go somewhere else entirely?  I'm just speculating,
    > > >> but now is a good time to think about it.
    > >
    > > > I've kept extraUpdatedCols in RangeTblEntry in the latest patch, but
    > > > perhaps it makes sense to put that into Query?
    > >
    > > That's got morally the same problem as keeping it in RangeTblEntry:
    > > those are structures that are built by the parser.  Hacking on them
    > > later isn't terribly clean.
    > >
    > > I wonder if it could make sense to postpone calculation of the
    > > extraUpdatedCols out of the rewriter and into the planner, with
    > > the idea that it ends up $someplace in the finished plan tree
    > > but isn't part of the original parsetree.
    >
    > Looking at PlannerInfo.update_colnos, something that's needed for
    > execution but not in Query, maybe we can make preprocess_targetlist()
    > also populate an PlannerInfo.extraUpdatedCols?
    >
    > > A different aspect of this is that putting it in Query doesn't
    > > make a lot of sense unless there is only one version of the
    > > bitmap per Query.  In simple UPDATEs that would be true, but
    > > I think that inherited/partitioned UPDATEs would need one per
    > > result relation, which is likely the reason it got dumped in
    > > RangeTblEntry to begin with.
    >
    > Yeah, so if we have PlannerInfos.extraUpdatedCols as the root table's
    > version of that, grouping_planner() can make copies for all result
    > relations and put the list in ModifyTable.
    
    I tried in the attached 0004.  ModifyTable gets a new member
    extraUpdatedColsBitmaps, which is List of Bitmapset "nodes".
    
    Actually, List of Bitmapsets turned out to be something that doesn't
    just-work with our Node infrastructure, which I found out thanks to
    -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    first-class support for copy/equal/write/read support for Bitmapsets,
    such that writeNode() can write appropriately labeled versions of them
    and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    didn't actually go ahead and make *all* Bitmapsets in the plan trees
    to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    just use *_NODE_FIELD().
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  41. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-07T01:04:26Z

    On Thu, Oct 6, 2022 at 10:29 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > Actually, List of Bitmapsets turned out to be something that doesn't
    > just-work with our Node infrastructure, which I found out thanks to
    > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > first-class support for copy/equal/write/read support for Bitmapsets,
    > such that writeNode() can write appropriately labeled versions of them
    > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > just use *_NODE_FIELD().
    
    All meson builds on the cfbot machines seem to have failed, maybe
    because I didn't update src/include/nodes/meson.build to add
    'nodes/bitmapset.h' to the `node_support_input_i` collection.  Here's
    an updated version assuming that's the problem.  (Will set up meson
    builds on my machine to avoid this in the future.)
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  42. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-07T04:25:42Z

    On Fri, Oct 7, 2022 at 10:04 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Thu, Oct 6, 2022 at 10:29 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > Actually, List of Bitmapsets turned out to be something that doesn't
    > > just-work with our Node infrastructure, which I found out thanks to
    > > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > > first-class support for copy/equal/write/read support for Bitmapsets,
    > > such that writeNode() can write appropriately labeled versions of them
    > > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > > just use *_NODE_FIELD().
    >
    > All meson builds on the cfbot machines seem to have failed, maybe
    > because I didn't update src/include/nodes/meson.build to add
    > 'nodes/bitmapset.h' to the `node_support_input_i` collection.  Here's
    > an updated version assuming that's the problem.  (Will set up meson
    > builds on my machine to avoid this in the future.)
    
    And... noticed that a postgres_fdw test failed, because
    _readBitmapset() not having been changed to set NodeTag would
    "corrupt" any Bitmapsets that were created with it set.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  43. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-07T06:49:56Z

    On Fri, Oct 7, 2022 at 1:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Fri, Oct 7, 2022 at 10:04 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > > On Thu, Oct 6, 2022 at 10:29 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > Actually, List of Bitmapsets turned out to be something that doesn't
    > > > just-work with our Node infrastructure, which I found out thanks to
    > > > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > > > first-class support for copy/equal/write/read support for Bitmapsets,
    > > > such that writeNode() can write appropriately labeled versions of them
    > > > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > > > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > > > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > > > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > > > just use *_NODE_FIELD().
    > >
    > > All meson builds on the cfbot machines seem to have failed, maybe
    > > because I didn't update src/include/nodes/meson.build to add
    > > 'nodes/bitmapset.h' to the `node_support_input_i` collection.  Here's
    > > an updated version assuming that's the problem.  (Will set up meson
    > > builds on my machine to avoid this in the future.)
    >
    > And... noticed that a postgres_fdw test failed, because
    > _readBitmapset() not having been changed to set NodeTag would
    > "corrupt" any Bitmapsets that were created with it set.
    
    Broke the other cases while fixing the above.  Attaching a new version
    again.  In the latest version, I'm setting Bitmapset.type by hand with
    an XXX comment nearby saying that it would be nice to change that to
    makeNode(Bitmapset), which I know sounds pretty ad-hoc.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  44. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-07T07:31:16Z

    On Fri, Oct 7, 2022 at 3:49 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Fri, Oct 7, 2022 at 1:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > On Fri, Oct 7, 2022 at 10:04 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > On Thu, Oct 6, 2022 at 10:29 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > Actually, List of Bitmapsets turned out to be something that doesn't
    > > > > just-work with our Node infrastructure, which I found out thanks to
    > > > > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > > > > first-class support for copy/equal/write/read support for Bitmapsets,
    > > > > such that writeNode() can write appropriately labeled versions of them
    > > > > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > > > > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > > > > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > > > > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > > > > just use *_NODE_FIELD().
    > > >
    > > > All meson builds on the cfbot machines seem to have failed, maybe
    > > > because I didn't update src/include/nodes/meson.build to add
    > > > 'nodes/bitmapset.h' to the `node_support_input_i` collection.  Here's
    > > > an updated version assuming that's the problem.  (Will set up meson
    > > > builds on my machine to avoid this in the future.)
    > >
    > > And... noticed that a postgres_fdw test failed, because
    > > _readBitmapset() not having been changed to set NodeTag would
    > > "corrupt" any Bitmapsets that were created with it set.
    >
    > Broke the other cases while fixing the above.  Attaching a new version
    > again.  In the latest version, I'm setting Bitmapset.type by hand with
    > an XXX comment nearby saying that it would be nice to change that to
    > makeNode(Bitmapset), which I know sounds pretty ad-hoc.
    
    Sorry, I attached the wrong patches with the last email.  The
    "correct" v22 attached this time.
    
    Wondering if it might be a good idea to reorder the patches such that
    the changes that move extraUpdatedCols out of RangeTblEntry (patches
    0003 and 0004) can be considered/applied independently of the changes
    that move permission-checking-related fields out of RangeTblEntry
    (patch 0001).  The former seem more straightforward except of course
    the Bitmapset node infrastructure changes.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  45. Re: ExecRTCheckPerms() and many prunable partitions

    Peter Eisentraut <peter.eisentraut@enterprisedb.com> — 2022-10-12T13:49:56Z

    On 06.10.22 15:29, Amit Langote wrote:
    > I tried in the attached 0004.  ModifyTable gets a new member
    > extraUpdatedColsBitmaps, which is List of Bitmapset "nodes".
    > 
    > Actually, List of Bitmapsets turned out to be something that doesn't
    > just-work with our Node infrastructure, which I found out thanks to
    > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > first-class support for copy/equal/write/read support for Bitmapsets,
    > such that writeNode() can write appropriately labeled versions of them
    > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > didn't actually go ahead and make*all*  Bitmapsets in the plan trees
    > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > just use *_NODE_FIELD().
    
    Seeing that on 64-bit platforms we have a 4-byte padding gap in the 
    Bitmapset struct, sticking a node tag in there seems pretty sensible. 
    So turning Bitmapset into a proper Node and then making the other 
    adjustments you describe makes sense to me.
    
    Making a new thread about this might be best.
    
    (I can't currently comment on the rest of the patch set.  So I don't 
    know if you'll really end up needing lists of bitmapsets.  But from here 
    it looks like turning bitmapsets into nodes might be a worthwhile change 
    just by itself.)
    
    
    
    
    
  46. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-13T08:14:30Z

    On Wed, Oct 12, 2022 at 10:50 PM Peter Eisentraut
    <peter.eisentraut@enterprisedb.com> wrote:
    > On 06.10.22 15:29, Amit Langote wrote:
    > > I tried in the attached 0004.  ModifyTable gets a new member
    > > extraUpdatedColsBitmaps, which is List of Bitmapset "nodes".
    > >
    > > Actually, List of Bitmapsets turned out to be something that doesn't
    > > just-work with our Node infrastructure, which I found out thanks to
    > > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > > first-class support for copy/equal/write/read support for Bitmapsets,
    > > such that writeNode() can write appropriately labeled versions of them
    > > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > > didn't actually go ahead and make*all*  Bitmapsets in the plan trees
    > > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > > just use *_NODE_FIELD().
    >
    > Seeing that on 64-bit platforms we have a 4-byte padding gap in the
    > Bitmapset struct, sticking a node tag in there seems pretty sensible.
    > So turning Bitmapset into a proper Node and then making the other
    > adjustments you describe makes sense to me.
    >
    > Making a new thread about this might be best.
    >
    > (I can't currently comment on the rest of the patch set.  So I don't
    > know if you'll really end up needing lists of bitmapsets.  But from here
    > it looks like turning bitmapsets into nodes might be a worthwhile change
    > just by itself.)
    
    Ok, thanks.  I'll start a new thread about it.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  47. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-10-15T06:00:58Z

    On Fri, Oct 7, 2022 at 4:31 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Fri, Oct 7, 2022 at 3:49 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > On Fri, Oct 7, 2022 at 1:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > On Fri, Oct 7, 2022 at 10:04 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > On Thu, Oct 6, 2022 at 10:29 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > > Actually, List of Bitmapsets turned out to be something that doesn't
    > > > > > just-work with our Node infrastructure, which I found out thanks to
    > > > > > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > > > > > first-class support for copy/equal/write/read support for Bitmapsets,
    > > > > > such that writeNode() can write appropriately labeled versions of them
    > > > > > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > > > > > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > > > > > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > > > > > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > > > > > just use *_NODE_FIELD().
    > > > >
    > > > > All meson builds on the cfbot machines seem to have failed, maybe
    > > > > because I didn't update src/include/nodes/meson.build to add
    > > > > 'nodes/bitmapset.h' to the `node_support_input_i` collection.  Here's
    > > > > an updated version assuming that's the problem.  (Will set up meson
    > > > > builds on my machine to avoid this in the future.)
    > > >
    > > > And... noticed that a postgres_fdw test failed, because
    > > > _readBitmapset() not having been changed to set NodeTag would
    > > > "corrupt" any Bitmapsets that were created with it set.
    > >
    > > Broke the other cases while fixing the above.  Attaching a new version
    > > again.  In the latest version, I'm setting Bitmapset.type by hand with
    > > an XXX comment nearby saying that it would be nice to change that to
    > > makeNode(Bitmapset), which I know sounds pretty ad-hoc.
    >
    > Sorry, I attached the wrong patches with the last email.  The
    > "correct" v22 attached this time.
    
    Rebased over c037471832.
    
    
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  48. Re: ExecRTCheckPerms() and many prunable partitions

    Ian Lawrence Barwick <barwick@gmail.com> — 2022-11-03T23:46:02Z

    2022年10月15日(土) 15:01 Amit Langote <amitlangote09@gmail.com>:
    >
    > On Fri, Oct 7, 2022 at 4:31 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > On Fri, Oct 7, 2022 at 3:49 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > On Fri, Oct 7, 2022 at 1:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > On Fri, Oct 7, 2022 at 10:04 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > > On Thu, Oct 6, 2022 at 10:29 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > > > Actually, List of Bitmapsets turned out to be something that doesn't
    > > > > > > just-work with our Node infrastructure, which I found out thanks to
    > > > > > > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > > > > > > first-class support for copy/equal/write/read support for Bitmapsets,
    > > > > > > such that writeNode() can write appropriately labeled versions of them
    > > > > > > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > > > > > > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > > > > > > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > > > > > > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > > > > > > just use *_NODE_FIELD().
    > > > > >
    > > > > > All meson builds on the cfbot machines seem to have failed, maybe
    > > > > > because I didn't update src/include/nodes/meson.build to add
    > > > > > 'nodes/bitmapset.h' to the `node_support_input_i` collection.  Here's
    > > > > > an updated version assuming that's the problem.  (Will set up meson
    > > > > > builds on my machine to avoid this in the future.)
    > > > >
    > > > > And... noticed that a postgres_fdw test failed, because
    > > > > _readBitmapset() not having been changed to set NodeTag would
    > > > > "corrupt" any Bitmapsets that were created with it set.
    > > >
    > > > Broke the other cases while fixing the above.  Attaching a new version
    > > > again.  In the latest version, I'm setting Bitmapset.type by hand with
    > > > an XXX comment nearby saying that it would be nice to change that to
    > > > makeNode(Bitmapset), which I know sounds pretty ad-hoc.
    > >
    > > Sorry, I attached the wrong patches with the last email.  The
    > > "correct" v22 attached this time.
    >
    > Rebased over c037471832.
    
    This entry was marked as "Needs review" in the CommitFest app but cfbot
    reports the patch no longer applies.
    
    We've marked it as "Waiting on Author". As CommitFest 2022-11 is
    currently underway, this would be an excellent time update the patch.
    
    Once you think the patchset is ready for review again, you (or any
    interested party) can  move the patch entry forward by visiting
    
        https://commitfest.postgresql.org/40/3224/
    
    and changing the status to "Needs review".
    
    
    Thanks
    
    Ian Barwick
    
    
    
    
  49. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-07T07:03:45Z

    On Fri, Nov 4, 2022 at 8:46 AM Ian Lawrence Barwick <barwick@gmail.com> wrote:
    > 2022年10月15日(土) 15:01 Amit Langote <amitlangote09@gmail.com>:
    > > On Fri, Oct 7, 2022 at 4:31 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > On Fri, Oct 7, 2022 at 3:49 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > On Fri, Oct 7, 2022 at 1:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > > On Fri, Oct 7, 2022 at 10:04 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > > > On Thu, Oct 6, 2022 at 10:29 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > > > > > Actually, List of Bitmapsets turned out to be something that doesn't
    > > > > > > > just-work with our Node infrastructure, which I found out thanks to
    > > > > > > > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > > > > > > > first-class support for copy/equal/write/read support for Bitmapsets,
    > > > > > > > such that writeNode() can write appropriately labeled versions of them
    > > > > > > > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > > > > > > > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > > > > > > > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > > > > > > > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > > > > > > > just use *_NODE_FIELD().
    > > > > > >
    > > > > > > All meson builds on the cfbot machines seem to have failed, maybe
    > > > > > > because I didn't update src/include/nodes/meson.build to add
    > > > > > > 'nodes/bitmapset.h' to the `node_support_input_i` collection.  Here's
    > > > > > > an updated version assuming that's the problem.  (Will set up meson
    > > > > > > builds on my machine to avoid this in the future.)
    > > > > >
    > > > > > And... noticed that a postgres_fdw test failed, because
    > > > > > _readBitmapset() not having been changed to set NodeTag would
    > > > > > "corrupt" any Bitmapsets that were created with it set.
    > > > >
    > > > > Broke the other cases while fixing the above.  Attaching a new version
    > > > > again.  In the latest version, I'm setting Bitmapset.type by hand with
    > > > > an XXX comment nearby saying that it would be nice to change that to
    > > > > makeNode(Bitmapset), which I know sounds pretty ad-hoc.
    > > >
    > > > Sorry, I attached the wrong patches with the last email.  The
    > > > "correct" v22 attached this time.
    > >
    > > Rebased over c037471832.
    >
    > This entry was marked as "Needs review" in the CommitFest app but cfbot
    > reports the patch no longer applies.
    >
    > We've marked it as "Waiting on Author". As CommitFest 2022-11 is
    > currently underway, this would be an excellent time update the patch.
    
    Thanks for the heads up.
    
    > Once you think the patchset is ready for review again, you (or any
    > interested party) can  move the patch entry forward by visiting
    >
    >     https://commitfest.postgresql.org/40/3224/
    >
    > and changing the status to "Needs review".
    
    Rebased patch attached and done.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  50. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-11-10T11:58:01Z

    Hello
    
    I've been trying to understand what 0001 does.  One thing that strikes
    me is that it seems like it'd be easy to have bugs because of modifying
    the perminfo list inadequately.  I couldn't find any cross-check that
    some perminfo element that we obtain for a rte does actually match the
    relation we wanted to check.  Maybe we could add a test in some central
    place that perminfo->relid equals rte->relid?
    
    A related point is that concatenating lists doesn't seem to worry about
    not processing one element multiple times and ending up with bogus offsets.
    (I suppose you still have to let an element be processed multiple times
    in case you have nested subqueries?  I wonder how good is the test
    coverage for such scenarios.)
    
    Why do callers of add_rte_to_flat_rtable() have to modify the rte's
    perminfoindex themselves, instead of having the function do it for them?
    That looks strange.  But also it's odd that flatten_unplanned_rtes
    concatenates the two lists after all the perminfoindexes have been
    modified, rather than doing both things (adding each RTEs perminfo to
    the global list and offsetting the index) as we walk the list, in
    flatten_rtes_walker.  It looks like these two actions are disconnected
    from one another, but unless I misunderstand, in reality the opposite is
    true.
    
    I think the API of ConcatRTEPermissionInfoLists is a bit weird.  Why not
    have the function return the resulting list instead, just like
    list_append?  It is more verbose, but it seems easier to grok.
    
    Two trivial changes attached.  (Maybe 0002 is not correct, if you're
    also trying to reference finalrtepermlist; but in that case I think the
    original may have been misleading as well.)
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    
  51. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-11-10T12:19:51Z

    On 2022-Oct-06, Amit Langote wrote:
    
    > Actually, List of Bitmapsets turned out to be something that doesn't
    > just-work with our Node infrastructure, which I found out thanks to
    > -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > first-class support for copy/equal/write/read support for Bitmapsets,
    > such that writeNode() can write appropriately labeled versions of them
    > and nodeRead() can read them as Bitmapsets.  That's done in 0003.  I
    > didn't actually go ahead and make *all* Bitmapsets in the plan trees
    > to be Nodes, but maybe 0003 can be expanded to do that.  We won't need
    > to make gen_node_support.pl emit *_BITMAPSET_FIELD() blurbs then; can
    > just use *_NODE_FIELD().
    
    Hmm, is this related to what Tom posted as part of his 0004 in
    https://postgr.es/m/2901865.1667685211@sss.pgh.pa.us
    
    -- 
    Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
    
    
    
    
  52. Re: ExecRTCheckPerms() and many prunable partitions

    Tom Lane <tgl@sss.pgh.pa.us> — 2022-11-11T16:46:16Z

    Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
    > On 2022-Oct-06, Amit Langote wrote:
    >> Actually, List of Bitmapsets turned out to be something that doesn't
    >> just-work with our Node infrastructure, which I found out thanks to
    >> -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    >> first-class support for copy/equal/write/read support for Bitmapsets,
    
    > Hmm, is this related to what Tom posted as part of his 0004 in
    > https://postgr.es/m/2901865.1667685211@sss.pgh.pa.us
    
    It could be.  For some reason I thought that Amit had withdrawn
    his proposal to make Bitmapsets be Nodes.  But if it's still live,
    then the data structure I invented in my 0004 could plausibly be
    replaced by a List of Bitmapsets.
    
    The code I was using that for would rather have fixed-size arrays
    of Bitmapsets than variable-size Lists, mainly because it always
    knows ab initio what the max length of the array will be.  But
    I don't think that the preference is so strong that it justifies
    a private data structure.
    
    The main thing I was wondering about in connection with that
    was whether to assume that there could be other future applications
    of the logic to perform multi-bitmapset union, intersection,
    etc.  If so, then I'd be inclined to choose different naming and
    put those functions in or near to bitmapset.c.  It doesn't look
    like Amit's code needs anything like that, but maybe somebody
    has an idea about other applications?
    
    Anyway, I concur with Peter's upthread comment that making
    Bitmapsets be Nodes is probably justifiable all by itself.
    The lack of a Node tag in them now is just because in a 32-bit
    world it seemed like unnecessary bloat.  But on 64-bit machines
    it's free, and we aren't optimizing for 32-bit any more.
    
    I do not like the details of v24-0003 at all though, because
    it seems to envision that a "node Bitmapset" is a different
    thing from a raw Bitmapset.  That can only lead to bugs ---
    why would we not make it the case that every Bitmapset is
    properly labeled with the node tag?
    
    Also, although I'm on board with making Bitmapsets be Nodes,
    I don't think I'm on board with changing their dump format.
    Planner node dumps would get enormously bulkier and less
    readable if we changed things like
    
       :relids (b 1 2)
    
    to
    
       :relids
          {BITMAPSET
           (b 1 2)
          }
    
    or whatever the output would look like as the patch stands.
    So that needs a bit more effort, but it's surely manageable.
    
    			regards, tom lane
    
    
    
    
  53. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-14T07:32:43Z

    On Sat, Nov 12, 2022 at 1:46 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
    > > On 2022-Oct-06, Amit Langote wrote:
    > >> Actually, List of Bitmapsets turned out to be something that doesn't
    > >> just-work with our Node infrastructure, which I found out thanks to
    > >> -DWRITE_READ_PARSE_PLAN_TREES.  So, I had to go ahead and add
    > >> first-class support for copy/equal/write/read support for Bitmapsets,
    >
    > > Hmm, is this related to what Tom posted as part of his 0004 in
    > > https://postgr.es/m/2901865.1667685211@sss.pgh.pa.us
    >
    > It could be.  For some reason I thought that Amit had withdrawn
    > his proposal to make Bitmapsets be Nodes.
    
    I think you are referring to [1] that I had forgotten to link to here.
    I did reimplement a data structure in my patch on the "Re: generic
    plans and initial pruning" thread to stop using a List of Bitmapsets,
    so the Bitmapset as Nodes functionality became unnecessary there,
    though I still need it for the proposal here to move
    extraUpdatedColumns (patch 0004) into ModifyTable node.
    
    > The code I was using that for would rather have fixed-size arrays
    > of Bitmapsets than variable-size Lists, mainly because it always
    > knows ab initio what the max length of the array will be.  But
    > I don't think that the preference is so strong that it justifies
    > a private data structure.
    >
    > The main thing I was wondering about in connection with that
    > was whether to assume that there could be other future applications
    > of the logic to perform multi-bitmapset union, intersection,
    > etc.  If so, then I'd be inclined to choose different naming and
    > put those functions in or near to bitmapset.c.  It doesn't look
    > like Amit's code needs anything like that, but maybe somebody
    > has an idea about other applications?
    
    Yes, simple storage of multiple Bitmapsets in a List somewhere in a
    parse/plan tree sounded like that would have wider enough use to add
    proper node support for.   Assuming you mean trying to generalize
    VarAttnoSet in your patch 0004 posted at [2], I wonder if you want to
    somehow make its indexability by varno / RT index a part of the
    interface of the generic code you're thinking for it?  For example,
    varattnoset_*_members collection of routines in that patch seem to
    assume that the Bitmapsets at a given index in the provided pair of
    VarAttnoSets are somehow related -- covering to the same base relation
    in this case.  That does not sound very generalizable but maybe that
    is not what you are thinking at all.
    
    > Anyway, I concur with Peter's upthread comment that making
    > Bitmapsets be Nodes is probably justifiable all by itself.
    > The lack of a Node tag in them now is just because in a 32-bit
    > world it seemed like unnecessary bloat.  But on 64-bit machines
    > it's free, and we aren't optimizing for 32-bit any more.
    >
    > I do not like the details of v24-0003 at all though, because
    > it seems to envision that a "node Bitmapset" is a different
    > thing from a raw Bitmapset.  That can only lead to bugs ---
    > why would we not make it the case that every Bitmapset is
    > properly labeled with the node tag?
    
    Yeah, I just didn't think hard enough to realize that having
    bitmapset.c itself set the node tag is essentially free, and it looks
    like a better design anyway than the design where callers get to
    choose to make the bitmapset they are manipulating a Node or not.
    
    > Also, although I'm on board with making Bitmapsets be Nodes,
    > I don't think I'm on board with changing their dump format.
    > Planner node dumps would get enormously bulkier and less
    > readable if we changed things like
    >
    >    :relids (b 1 2)
    >
    > to
    >
    >    :relids
    >       {BITMAPSET
    >        (b 1 2)
    >       }
    >
    > or whatever the output would look like as the patch stands.
    > So that needs a bit more effort, but it's surely manageable.
    
    Agreed with leaving the dump format unchanged or not bloating it.
    
    Thanks a lot for 5e1f3b9ebf6e5.
    
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    [1] https://www.postgresql.org/message-id/CA+HiwqG8L3DVoZauJi1-eorLnnoM6VcfJCCauQX8=ofi-qMYCQ@mail.gmail.com
    [2] https://www.postgresql.org/message-id/2901865.1667685211%40sss.pgh.pa.us
    
    
    
    
  54. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-11-16T11:44:02Z

    On 2022-Nov-10, Alvaro Herrera wrote:
    
    > I couldn't find any cross-check that
    > some perminfo element that we obtain for a rte does actually match the
    > relation we wanted to check.  Maybe we could add a test in some central
    > place that perminfo->relid equals rte->relid?
    
    I hadn't looked hard enough.  This is already in GetRTEPermissionInfo().
    
    
    > A related point is that concatenating lists doesn't seem to worry about
    > not processing one element multiple times and ending up with bogus offsets.
    
    > I think the API of ConcatRTEPermissionInfoLists is a bit weird.  Why not
    > have the function return the resulting list instead, just like
    > list_append?  It is more verbose, but it seems easier to grok.
    
    Another point related to this.  I noticed that everyplace we do
    ConcatRTEPermissionInfoLists, it is followed by list_append'ing the RT
    list themselves.  This is strange.  Maybe that's the wrong way to look
    at this, and instead we should have a function that does both things
    together: pass both rtables and rtepermlists and smash them all
    together.
    
    I attach your 0001 again with a bunch of other fixups (I don't include
    your 0002ff).  I've pushed this to see the CI results, and so far it's
    looking good (hasn't finished yet though):
    https://cirrus-ci.com/build/5126818977021952
    
    I'll have a look at 0002 now.
    
    -- 
    Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
    
  55. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-21T12:03:43Z

    Hi Alvaro,
    
    On Thu, Nov 10, 2022 at 8:58 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > Hello
    >
    > I've been trying to understand what 0001 does.
    
    Thanks a lot for taking a look.
    
    > A related point is that concatenating lists doesn't seem to worry about
    > not processing one element multiple times and ending up with bogus offsets.
    
    Could you please clarify what you mean by "an element" here?  Are you
    are implying that any given relation, no matter how many times it
    occurs in a query (possibly via view rule expansion), should end up
    with only one RTEPermissionInfo node covering all its occurrences in
    the combined/final rtepermlist, as a result of concatenation/merging
    of rtepermlists of different Queries?  Versions of the patch prior to
    v17 did it that way, but Tom didn't like that approach much [1], so I
    switched to the current implementation where the merging of two
    Queries' range tables using list_concat() is accompanied by the
    merging of their rtepermlists, again, using list_concat().  So, if the
    same table has multiple RTEs in a query, so will there be multiple
    corresponding RTEPermissionInfos.
    
    > (I suppose you still have to let an element be processed multiple times
    > in case you have nested subqueries?  I wonder how good is the test
    > coverage for such scenarios.)
    
    ISTM the existing tests cover a good portion of the changes being made
    here, but I guess I'm only saying that because I have spent a
    non-trivial amount of time debugging the test failures across many
    files over different versions of the patch, especially those that
    involve views.
    
    Do you think it might be better to add some new tests as part of this
    patch than simply relying on the existing tests not failing?
    
    > Why do callers of add_rte_to_flat_rtable() have to modify the rte's
    > perminfoindex themselves, instead of having the function do it for them?
    > That looks strange.  But also it's odd that flatten_unplanned_rtes
    > concatenates the two lists after all the perminfoindexes have been
    > modified, rather than doing both things (adding each RTEs perminfo to
    > the global list and offsetting the index) as we walk the list, in
    > flatten_rtes_walker.  It looks like these two actions are disconnected
    > from one another, but unless I misunderstand, in reality the opposite is
    > true.
    
    OK, I have moved the step of updating perminfoindex into
    add_rte_to_flat_rtable(), where it looks up the RTEPermissionInfo for
    an RTE being added using GetRTEPermissionInfo() and lappend()'s it to
    finalrtepermlist before updating the index.  For flatten_rtes_walker()
    then to rely on that facility, I needed to make some changes to its
    arguments to pass the correct Query node to pick the rtepermlist from.
    Overall, setrefs.c changes now hopefully look saner than in the last
    version.
    
    As soon as I made that change, I noticed a bunch of ERRORs in
    regression tests due to the checks in GetRTEPermissionInfo(), though
    none that looked like live bugs.  Though I did find some others as I
    was reworking the code to fix those errors, which I have fixed too.
    
    > I think the API of ConcatRTEPermissionInfoLists is a bit weird.  Why not
    > have the function return the resulting list instead, just like
    > list_append?  It is more verbose, but it seems easier to grok.
    
    Agreed, I have merged your delta patch into 0001.
    
    On Wed, Nov 16, 2022 at 8:44 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > A related point is that concatenating lists doesn't seem to worry about
    > > not processing one element multiple times and ending up with bogus offsets.
    >
    > > I think the API of ConcatRTEPermissionInfoLists is a bit weird.  Why not
    > > have the function return the resulting list instead, just like
    > > list_append?  It is more verbose, but it seems easier to grok.
    >
    > Another point related to this.  I noticed that everyplace we do
    > ConcatRTEPermissionInfoLists, it is followed by list_append'ing the RT
    > list themselves.  This is strange.  Maybe that's the wrong way to look
    > at this, and instead we should have a function that does both things
    > together: pass both rtables and rtepermlists and smash them all
    > together.
    
    OK, how does the attached 0002 look in that regard?  In it, I have
    renamed ConcatRTEPermissionInfoLists() to CombineRangeTables() which
    does all that.  Though, given the needs of rewriteRuleAction(), the
    API of it may look a bit weird.  (Only posting it separately for the
    ease of comparison.)
    
    > I attach your 0001 again with a bunch of other fixups (I don't include
    > your 0002ff).  I've pushed this to see the CI results, and so far it's
    > looking good (hasn't finished yet though):
    > https://cirrus-ci.com/build/5126818977021952
    
    I have merged all.
    
    While working on these changes, I realized that 0002 (the patch to
    remove OLD/NEW RTEs from the stored view query's range table) was
    going a bit too far by removing UpdateRangeTableOfViewParse()
    altogether.  You may have noticed that a RTE_RELATION entry for the
    view relation is needed anyway for permission checking, locking, etc.
    and the patch was making the rewriter add one explicitly, whereas the
    OLD RTE would be playing that role previously.  In the updated
    version, I have decided to keep UpdateRangeTableOfViewParse() while
    removing the code in it that adds the NEW RTE, which is totally
    unnecessary.  Also removed the rewriter changes that were needed
    previously.  Most of the previous version of the patch was a whole
    bunch of regression test output changes, because the stored view
    query's range table would be changed such that deparsed version of
    those queries need no longer qualify output columns (only 1 entry in
    the range table in those cases), though I didn't necessarily think
    that that looked better.  In the new version, because the stored view
    query contains the OLD entry, those qualifications stay, and so none
    of the regression test changes are necessary anymore.  postgres_fdw
    ones are unrelated and noted in the commit message.
    
    [1] https://www.postgresql.org/message-id/3094251.1658955855%40sss.pgh.pa.us
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  56. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-21T12:46:03Z

    On Mon, Nov 21, 2022 at 9:03 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Thu, Nov 10, 2022 at 8:58 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > Why do callers of add_rte_to_flat_rtable() have to modify the rte's
    > > perminfoindex themselves, instead of having the function do it for them?
    > > That looks strange.  But also it's odd that flatten_unplanned_rtes
    > > concatenates the two lists after all the perminfoindexes have been
    > > modified, rather than doing both things (adding each RTEs perminfo to
    > > the global list and offsetting the index) as we walk the list, in
    > > flatten_rtes_walker.  It looks like these two actions are disconnected
    > > from one another, but unless I misunderstand, in reality the opposite is
    > > true.
    >
    > OK, I have moved the step of updating perminfoindex into
    > add_rte_to_flat_rtable(), where it looks up the RTEPermissionInfo for
    > an RTE being added using GetRTEPermissionInfo() and lappend()'s it to
    > finalrtepermlist before updating the index.  For flatten_rtes_walker()
    > then to rely on that facility, I needed to make some changes to its
    > arguments to pass the correct Query node to pick the rtepermlist from.
    > Overall, setrefs.c changes now hopefully look saner than in the last
    > version.
    >
    > As soon as I made that change, I noticed a bunch of ERRORs in
    > regression tests due to the checks in GetRTEPermissionInfo(), though
    > none that looked like live bugs.
    
    I figured the no-live-bugs part warrants some clarification.  The
    plan-time errors that I saw were caused in many cases by an RTE not
    pointing into the correct list or having incorrect perminfoindex, most
    or all of those cases involving views.  Passing a wrong perminfoindex
    to the executor, though obviously not good and fixed in the latest
    version, wasn't a problem in those cases, because none of those tests
    would cause the executor to use the perminfoindex, such as by calling
    GetRTEPermissionInfo().  I thought about that being problematic in
    terms of our coverage of perminfoindex related code in the executor,
    but don't really see how we could improve that situation as far as
    views are concerned, because the executor is only concerned about
    checking permissions for views and perminfoindex is irrelevant in that
    path, because the RTEPermissionInfos are accessed directly from
    es_rtepermlist.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  57. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-25T11:28:37Z

    On Mon, Nov 21, 2022 at 9:03 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Wed, Nov 16, 2022 at 8:44 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > > A related point is that concatenating lists doesn't seem to worry about
    > > > not processing one element multiple times and ending up with bogus offsets.
    > >
    > > > I think the API of ConcatRTEPermissionInfoLists is a bit weird.  Why not
    > > > have the function return the resulting list instead, just like
    > > > list_append?  It is more verbose, but it seems easier to grok.
    > >
    > > Another point related to this.  I noticed that everyplace we do
    > > ConcatRTEPermissionInfoLists, it is followed by list_append'ing the RT
    > > list themselves.  This is strange.  Maybe that's the wrong way to look
    > > at this, and instead we should have a function that does both things
    > > together: pass both rtables and rtepermlists and smash them all
    > > together.
    >
    > OK, how does the attached 0002 look in that regard?  In it, I have
    > renamed ConcatRTEPermissionInfoLists() to CombineRangeTables() which
    > does all that.  Though, given the needs of rewriteRuleAction(), the
    > API of it may look a bit weird.  (Only posting it separately for the
    > ease of comparison.)
    
    Here's a revised version in which I've revised the code near the call
    site of CombineRangeTables() in rewriteRuleAction() such that the
    weirdness of that API in the last version becomes unnecessary.  When
    doing those changes, I realized that we perhaps need some new tests to
    exercise rewriteRuleAction(), especially to test the order of checking
    permissions present in the (combined) range table of rewritten action
    query, though I have not added them yet.
    
    I've included a new patch (0002) that I've also posted at [1] for this
    patch set to compile/work.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    [1] https://www.postgresql.org/message-id/CA%2BHiwqHbv4xQd-yHx0LWA04AybA%2BGQPy66UJxt8m32gB6zCYQQ%40mail.gmail.com
    
  58. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-11-29T09:27:08Z

    Thanks for the new version, in particular thank you for fixing the
    annoyance with the CombineRangeTables API.
    
    0002 was already pushed upstream, so we can forget about it.  I also
    pushed the addition of missing_ok to build_attrmap_by_name{,_if_req}.
    So this series needed a refresh, which is attached here, and tests are
    running: https://cirrus-ci.com/build/4880219807416320
    
    
    As for 0001+0003, here it is once again with a few fixups.  There are
    two nontrivial changes here:
    
    1. in get_rel_all_updated_cols (née GetRelAllUpdatedCols, which I
    changed because it didn't match the naming style in inherits.c) you were
    doing determining the relid to use in a roundabout way, then asserting
    it is a value you already know:
    
    -   use_relid = rel->top_parent_relids == NULL ? rel->relid :
    -       bms_singleton_member(rel->top_parent_relids);
    -   Assert(use_relid == root->parse->resultRelation);
    
    Why not just use root->parse->resultRelation in the first place?
    My 0002 does that.
    
    2. my 0005 moves a block in add_rte_to_flat_rtable one level out:
    there's no need to put it inside the rtekind == RTE_RELATION block, and
    the comment in that block failed to mention that we copied the
    RTEPermissionInfo; we can just let it work on the 'perminfoindex > 0'
    condition.  Also, the comment is a bit misleading, and I changed it
    some, but maybe not sufficiently: after add_rte_to_flat_rtable, the same
    RTEPermissionInfo node will serve two RTEs: one in the Query struct,
    whose perminfoindex corresponds to Query->rtepermlist; and the other in
    PlannerGlobal->finalrtable, whose index corresponds to
    PlannerGlobal->finalrtepermlist.  I was initially thinking that the old
    RTE would result in a "corrupted" state, but that doesn't appear to be
    the case.  (Also: I made it grab the RTEPermissionInfo using
    rte->perminfoindex, not newrte->perminfoindex, because that seems
    slightly bogus, even if they are identical because of the memcpy.)
    
    The other changes are cosmetic.
    
    I do not include here your 0004 and 0005.  (I think we can deal with
    those separately later.)
    
    -- 
    Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
    
  59. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-29T13:37:56Z

    Hi Alvaro,
    
    Thanks for taking a look and all the fixup patches.  Was working on
    that test I said we should add and then was spending some time
    cleaning things up and breaking some things out into their patches,
    mainly for the ease of review.
    
    On Tue, Nov 29, 2022 at 6:27 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > Thanks for the new version, in particular thank you for fixing the
    > annoyance with the CombineRangeTables API.
    
    OK, now that you seem to think that looks good, I've merged it into
    the main patch.
    
    > 0002 was already pushed upstream, so we can forget about it.  I also
    > pushed the addition of missing_ok to build_attrmap_by_name{,_if_req}.
    
    Yeah, I thought that needed to be broken out and had done so in my
    local repo.  Thanks for pushing that bit.
    
    > As for 0001+0003, here it is once again with a few fixups.  There are
    > two nontrivial changes here:
    >
    > 1. in get_rel_all_updated_cols (née GetRelAllUpdatedCols, which I
    > changed because it didn't match the naming style in inherits.c) you were
    > doing determining the relid to use in a roundabout way, then asserting
    > it is a value you already know:
    >
    > -   use_relid = rel->top_parent_relids == NULL ? rel->relid :
    > -       bms_singleton_member(rel->top_parent_relids);
    > -   Assert(use_relid == root->parse->resultRelation);
    
    > Why not just use root->parse->resultRelation in the first place?
    
    Facepalm, yes.
    
    > My 0002 does that.
    
    Merged.
    
    > 2. my 0005 moves a block in add_rte_to_flat_rtable one level out:
    > there's no need to put it inside the rtekind == RTE_RELATION block, and
    > the comment in that block failed to mention that we copied the
    > RTEPermissionInfo; we can just let it work on the 'perminfoindex > 0'
    > condition.
    
    Yes, agree that's better.
    
    >  Also, the comment is a bit misleading, and I changed it
    > some, but maybe not sufficiently: after add_rte_to_flat_rtable, the same
    > RTEPermissionInfo node will serve two RTEs: one in the Query struct,
    > whose perminfoindex corresponds to Query->rtepermlist; and the other in
    > PlannerGlobal->finalrtable, whose index corresponds to
    > PlannerGlobal->finalrtepermlist.  I was initially thinking that the old
    > RTE would result in a "corrupted" state, but that doesn't appear to be
    > the case.  (Also: I made it grab the RTEPermissionInfo using
    > rte->perminfoindex, not newrte->perminfoindex, because that seems
    > slightly bogus, even if they are identical because of the memcpy.)
    
    Interesting point about two different RTEs (in different lists)
    pointing to the same RTEPermissionInfo, also in different lists.
    Maybe, we should have the following there so that the PlannedStmt's
    contents don't point into the Query?
    
        newperminfo = copyObject(perminfo);
    
    > The other changes are cosmetic.
    
    Thanks, I've merged all.  I do wonder that it is only in PlannedStmt
    that the list is called something that is not "rtepermlist", but I'm
    fine with it if you prefer that.
    
    > I do not include here your 0004 and 0005.  (I think we can deal with
    > those separately later.)
    
    OK, I have not attached them with this email either.
    
    As I mentioned above, I've broken a couple of other changes out into
    their own patches that I've put before the main patch.  0001 adds
    ExecGetRootToChildMap().  I thought it would be better to write in the
    commit message why the new map is necessary for the main patch.   0002
    contains changes that has to do with changing how we access
    checkAsUser in some foreign table planning/execution code sites.
    Thought it might be better to describe it separately too.
    
    0003 is the main patch into which I've merged both my patch that
    invents CombineRangeTables() that I had posted separately before and
    all of your fixups.  In it, you will see a new test case that I have
    added in rules.sql to exercise the permission checking order stuff
    that I had said I may have broken with this patch, especially the
    hunks that change rewriteRuleAction().  That test would be broken with
    v24, but not after the changes to add_rtes_to_flat_rtable() that I
    made to address your review comment that blindly list_concat'ing
    finalrtepermlist and Query's rtepermlist doesn't look very robust,
    which it indeed wasn't [1].
    
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    [1] So, rewriteRuleAction(), with previous "wrong" versions of the
    patch (~v26), would combine the original query's and action query's
    rtepermlists in the "wrong" order, that is, not in the order in which
    RTEs appear in the combined rtable.   But because
    add_rtes_to_flat_rtable() now (v26~) adds perminfos into
    finalrtepermlist in the RTE order using lappend(), that wrongness of
    rewriteRuleAction() would be masked -- no execution-time failure of
    the test.  Anyway, I've also fixed rewriteRuleAction() to be "correct"
    in v27, so it is the least wrong version AFAIK ;).
    
  60. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-11-29T18:04:44Z

    On 2022-Nov-29, Amit Langote wrote:
    
    > Maybe, we should have the following there so that the PlannedStmt's
    > contents don't point into the Query?
    > 
    >     newperminfo = copyObject(perminfo);
    
    Hmm, I suppose if we want a separate RTEPermissionInfo node, we should
    instead do GetRTEPermissionInfo(rte) followed by
    AddRTEPermissionInfo(newrte) and avoid the somewhat cowboy-ish coding
    there.
    
    -- 
    Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
    
    
    
    
  61. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-30T02:56:54Z

    On Wed, Nov 30, 2022 at 3:04 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > On 2022-Nov-29, Amit Langote wrote:
    >
    > > Maybe, we should have the following there so that the PlannedStmt's
    > > contents don't point into the Query?
    > >
    > >     newperminfo = copyObject(perminfo);
    >
    > Hmm, I suppose if we want a separate RTEPermissionInfo node, we should
    > instead do GetRTEPermissionInfo(rte) followed by
    > AddRTEPermissionInfo(newrte) and avoid the somewhat cowboy-ish coding
    > there.
    
    OK, something like the attached?
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  62. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-11-30T06:45:53Z

    On Wed, Nov 30, 2022 at 11:56 AM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Wed, Nov 30, 2022 at 3:04 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > On 2022-Nov-29, Amit Langote wrote:
    > >
    > > > Maybe, we should have the following there so that the PlannedStmt's
    > > > contents don't point into the Query?
    > > >
    > > >     newperminfo = copyObject(perminfo);
    > >
    > > Hmm, I suppose if we want a separate RTEPermissionInfo node, we should
    > > instead do GetRTEPermissionInfo(rte) followed by
    > > AddRTEPermissionInfo(newrte) and avoid the somewhat cowboy-ish coding
    > > there.
    >
    > OK, something like the attached?
    
    Thinking more about the patch I sent, which has this:
    
    +       /* Get the existing one from this query's rtepermlist. */
            perminfo = GetRTEPermissionInfo(rtepermlist, newrte);
    -       glob->finalrtepermlist = lappend(glob->finalrtepermlist, perminfo);
    -       newrte->perminfoindex = list_length(glob->finalrtepermlist);
    +
    +       /*
    +        * Add a new one to finalrtepermlist and copy the contents of the
    +        * existing one into it.  Note that AddRTEPermissionInfo() also
    +        * updates newrte->perminfoindex to point to newperminfo in
    +        * finalrtepermlist.
    +        */
    +       newrte->perminfoindex = 0;  /* expected by AddRTEPermissionInfo() */
    +       newperminfo = AddRTEPermissionInfo(&glob->finalrtepermlist, newrte);
    +       memcpy(newperminfo, perminfo, sizeof(RTEPermissionInfo));
    
    Note that simple memcpy'ing would lead to the selectedCols, etc.
    bitmapsets being shared between the Query and the PlannedStmt, which
    may be considered as not good.  But maybe that's fine, because the
    same is true for RangeTblEntry members that do have substructure such
    as the various Alias fields that are not reset?  Code paths that like
    to keep a PlannedStmt to be decoupled from the corresponding Query,
    such as plancache.c, do copy the former, so shared sub-structure in
    the default case may be fine after all.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  63. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-11-30T08:32:15Z

    Hello
    
    On 2022-Nov-29, Amit Langote wrote:
    
    > Thanks for taking a look and all the fixup patches.  Was working on
    > that test I said we should add and then was spending some time
    > cleaning things up and breaking some things out into their patches,
    > mainly for the ease of review.
    
    Right, excellent.  Thanks for this new version.  It looks pretty good to
    me now.
    
    > On Tue, Nov 29, 2022 at 6:27 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    
    > > The other changes are cosmetic.
    > 
    > Thanks, I've merged all.  I do wonder that it is only in PlannedStmt
    > that the list is called something that is not "rtepermlist", but I'm
    > fine with it if you prefer that.
    
    I was unsure about that one myself; I just changed it because that
    struct uses camelCaseNaming, which the others do not, so it seemed fine
    in the other places but not there.  As for changing "list" to "infos",
    it seems to me we tend to avoid naming a list as "list", so.  (Maybe I
    would change the others to be foo_rteperminfos.  Unless these naming
    choices were already bikeshedded to its present form upthread and I
    missed it?)
    
    > As I mentioned above, I've broken a couple of other changes out into
    > their own patches that I've put before the main patch.  0001 adds
    > ExecGetRootToChildMap().  I thought it would be better to write in the
    > commit message why the new map is necessary for the main patch.
    
    I was thinking about this one and it seemed too closely tied to
    ExecGetInsertedCols to be committed separately.  Notice how there is a
    comment that mentions that function in your 0001, but that function
    itself still uses ri_RootToPartitionMap, so before your 0003 the comment
    is bogus.  And there's now quite some duplicity between
    ri_RootToPartitionMap and ri_RootToChildMap, which I think it would be
    better to reduce.  I mean, rather than add a new field it would be
    better to repurpose the old one:
    
    - ExecGetRootToChildMap should return TupleConversionMap *
    - every place that accesses ri_RootToPartitionMap directly should be
      using ExecGetRootToChildMap() instead
    - ExecGetRootToChildMap passes build_attrmap_by_name_if_req
      !resultRelInfo->ri_RelationDesc->rd_rel->relispartition
      as third argument to build_attrmap_by_name_if_req (rather than
      constant true), so that we keep the tuple compatibility checking we
      have there currently.
    
    
    > 0002 contains changes that has to do with changing how we access
    > checkAsUser in some foreign table planning/execution code sites.
    > Thought it might be better to describe it separately too.
    
    I'll get this one pushed soon, it seems good to me.  (I'll edit to not
    use Oid as boolean.)
    
    -- 
    Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
    
    
    
    
  64. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-12-01T10:49:54Z

    Hello,
    
    This didn't apply, so I rebased it on current master, excluding the one
    I already pushed.  No further changes.
    
    -- 
    Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
    "No me acuerdo, pero no es cierto.  No es cierto, y si fuera cierto,
     no me acuerdo."                 (Augusto Pinochet a una corte de justicia)
    
  65. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-12-02T07:41:11Z

    Hi Alvaro,
    
    On Wed, Nov 30, 2022 at 5:32 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > On Tue, Nov 29, 2022 at 6:27 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > Thanks, I've merged all.  I do wonder that it is only in PlannedStmt
    > > that the list is called something that is not "rtepermlist", but I'm
    > > fine with it if you prefer that.
    >
    > I was unsure about that one myself; I just changed it because that
    > struct uses camelCaseNaming, which the others do not, so it seemed fine
    > in the other places but not there.  As for changing "list" to "infos",
    > it seems to me we tend to avoid naming a list as "list", so.  (Maybe I
    > would change the others to be foo_rteperminfos.  Unless these naming
    > choices were already bikeshedded to its present form upthread and I
    > missed it?)
    
    No, I think it was I who came up with the "..list" naming and
    basically just stuck with it.
    
    Actually, I don't mind changing to "...infos", which I have done in
    the attached updated patch.
    
    > > As I mentioned above, I've broken a couple of other changes out into
    > > their own patches that I've put before the main patch.  0001 adds
    > > ExecGetRootToChildMap().  I thought it would be better to write in the
    > > commit message why the new map is necessary for the main patch.
    >
    > I was thinking about this one and it seemed too closely tied to
    > ExecGetInsertedCols to be committed separately.  Notice how there is a
    > comment that mentions that function in your 0001, but that function
    > itself still uses ri_RootToPartitionMap, so before your 0003 the comment
    > is bogus.  And there's now quite some duplicity between
    > ri_RootToPartitionMap and ri_RootToChildMap, which I think it would be
    > better to reduce.  I mean, rather than add a new field it would be
    > better to repurpose the old one:
    >
    > - ExecGetRootToChildMap should return TupleConversionMap *
    > - every place that accesses ri_RootToPartitionMap directly should be
    >   using ExecGetRootToChildMap() instead
    > - ExecGetRootToChildMap passes build_attrmap_by_name_if_req
    >   !resultRelInfo->ri_RelationDesc->rd_rel->relispartition
    >   as third argument to build_attrmap_by_name_if_req (rather than
    >   constant true), so that we keep the tuple compatibility checking we
    >   have there currently.
    
    This sounds like a better idea than adding a new AttrMap, so done this
    way in the attached 0001.
    
    > > 0002 contains changes that has to do with changing how we access
    > > checkAsUser in some foreign table planning/execution code sites.
    > > Thought it might be better to describe it separately too.
    >
    > I'll get this one pushed soon, it seems good to me.  (I'll edit to not
    > use Oid as boolean.)
    
    Thanks for committing that one.
    
    I've also merged into 0002 the delta patch I had posted earlier to add
    a copy of RTEPermInfos into the flattened permInfos list instead of
    adding the Query's copy.
    
    --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  66. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-12-02T07:44:05Z

    On Fri, Dec 2, 2022 at 4:41 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > Hi Alvaro,
    >
    > On Wed, Nov 30, 2022 at 5:32 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > > On Tue, Nov 29, 2022 at 6:27 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > > Thanks, I've merged all.  I do wonder that it is only in PlannedStmt
    > > > that the list is called something that is not "rtepermlist", but I'm
    > > > fine with it if you prefer that.
    > >
    > > I was unsure about that one myself; I just changed it because that
    > > struct uses camelCaseNaming, which the others do not, so it seemed fine
    > > in the other places but not there.  As for changing "list" to "infos",
    > > it seems to me we tend to avoid naming a list as "list", so.  (Maybe I
    > > would change the others to be foo_rteperminfos.  Unless these naming
    > > choices were already bikeshedded to its present form upthread and I
    > > missed it?)
    >
    > No, I think it was I who came up with the "..list" naming and
    > basically just stuck with it.
    >
    > Actually, I don't mind changing to "...infos", which I have done in
    > the attached updated patch.
    >
    > > > As I mentioned above, I've broken a couple of other changes out into
    > > > their own patches that I've put before the main patch.  0001 adds
    > > > ExecGetRootToChildMap().  I thought it would be better to write in the
    > > > commit message why the new map is necessary for the main patch.
    > >
    > > I was thinking about this one and it seemed too closely tied to
    > > ExecGetInsertedCols to be committed separately.  Notice how there is a
    > > comment that mentions that function in your 0001, but that function
    > > itself still uses ri_RootToPartitionMap, so before your 0003 the comment
    > > is bogus.  And there's now quite some duplicity between
    > > ri_RootToPartitionMap and ri_RootToChildMap, which I think it would be
    > > better to reduce.  I mean, rather than add a new field it would be
    > > better to repurpose the old one:
    > >
    > > - ExecGetRootToChildMap should return TupleConversionMap *
    > > - every place that accesses ri_RootToPartitionMap directly should be
    > >   using ExecGetRootToChildMap() instead
    > > - ExecGetRootToChildMap passes build_attrmap_by_name_if_req
    > >   !resultRelInfo->ri_RelationDesc->rd_rel->relispartition
    > >   as third argument to build_attrmap_by_name_if_req (rather than
    > >   constant true), so that we keep the tuple compatibility checking we
    > >   have there currently.
    >
    > This sounds like a better idea than adding a new AttrMap, so done this
    > way in the attached 0001.
    >
    > > > 0002 contains changes that has to do with changing how we access
    > > > checkAsUser in some foreign table planning/execution code sites.
    > > > Thought it might be better to describe it separately too.
    > >
    > > I'll get this one pushed soon, it seems good to me.  (I'll edit to not
    > > use Oid as boolean.)
    >
    > Thanks for committing that one.
    >
    > I've also merged into 0002 the delta patch I had posted earlier to add
    > a copy of RTEPermInfos into the flattened permInfos list instead of
    > adding the Query's copy.
    
    Oops, hit send before attaching anything.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  67. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-12-02T09:59:54Z

    Hello,
    
    On 2022-Dec-02, Amit Langote wrote:
    
    > This sounds like a better idea than adding a new AttrMap, so done this
    > way in the attached 0001.
    
    Thanks for doing that!  I have pushed it, but I renamed
    ri_RootToPartitionMap to ri_RootToChildMap and moved it to another spot
    in ResultRelInfo, which allows to simplify the comments.
    
    > I've also merged into 0002 the delta patch I had posted earlier to add
    > a copy of RTEPermInfos into the flattened permInfos list instead of
    > adding the Query's copy.
    
    Great.  At this point I have no other comments, except that in both
    parse_relation.c and rewriteManip.c you've chosen to add the new
    functions at the bottom of each file, which is seldom a good choice.
    I think in the case of CombineRangeTables it should be the very first
    function in the file, before all the walker-type stuff; and for
    Add/GetRTEPermissionInfo I would suggest that right below
    addRangeTableEntryForENR might be a decent choice (need to fix the .h
    files to match, of course.)
    
    -- 
    Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
    "World domination is proceeding according to plan"        (Andrew Morton)
    
    
    
    
  68. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-12-02T11:13:28Z

    On Fri, Dec 2, 2022 at 7:00 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > On 2022-Dec-02, Amit Langote wrote:
    > > This sounds like a better idea than adding a new AttrMap, so done this
    > > way in the attached 0001.
    >
    > Thanks for doing that!  I have pushed it, but I renamed
    > ri_RootToPartitionMap to ri_RootToChildMap and moved it to another spot
    > in ResultRelInfo, which allows to simplify the comments.
    
    Thanks.
    
    > > I've also merged into 0002 the delta patch I had posted earlier to add
    > > a copy of RTEPermInfos into the flattened permInfos list instead of
    > > adding the Query's copy.
    >
    > Great.  At this point I have no other comments, except that in both
    > parse_relation.c and rewriteManip.c you've chosen to add the new
    > functions at the bottom of each file, which is seldom a good choice.
    > I think in the case of CombineRangeTables it should be the very first
    > function in the file, before all the walker-type stuff; and for
    > Add/GetRTEPermissionInfo I would suggest that right below
    > addRangeTableEntryForENR might be a decent choice (need to fix the .h
    > files to match, of course.)
    
    Okay, I've moved the functions and their .h declarations to the places
    you suggest.  While at it, I also uncapitalized Add/Get, because
    that's how the nearby functions in the header are named.
    
    Thanks again for the review.  The patch looks much better than it did
    3 weeks ago.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  69. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-12-05T03:09:27Z

    On Fri, Dec 2, 2022 at 8:13 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Fri, Dec 2, 2022 at 7:00 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > Great.  At this point I have no other comments, except that in both
    > > parse_relation.c and rewriteManip.c you've chosen to add the new
    > > functions at the bottom of each file, which is seldom a good choice.
    > > I think in the case of CombineRangeTables it should be the very first
    > > function in the file, before all the walker-type stuff; and for
    > > Add/GetRTEPermissionInfo I would suggest that right below
    > > addRangeTableEntryForENR might be a decent choice (need to fix the .h
    > > files to match, of course.)
    >
    > Okay, I've moved the functions and their .h declarations to the places
    > you suggest.  While at it, I also uncapitalized Add/Get, because
    > that's how the nearby functions in the header are named.
    >
    > Thanks again for the review.  The patch looks much better than it did
    > 3 weeks ago.
    
    Rebased over 2605643a3a9d.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  70. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-12-06T15:19:05Z

    I have pushed this finally.
    
    I made two further changes:
    
    1. there was no reason to rename ExecCheckPerms_hook, since its
       signature was changing anyway.  I reverted it to the original name.
    
    2. I couldn't find any reason to expose ExecGetRTEPermissionInfo, and
       given that it's a one-line function, I removed it.
    
    Maybe you had a reason to add ExecGetRTEPermissionInfo, thinking about
    external callers; if so please discuss it.
    
    I'll mark this commitfest entry as committed soon; please post the other
    two patches you had in this series in a new thread.
    
    -- 
    Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
    
    
    
    
  71. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-12-07T07:01:18Z

    On Wed, Dec 7, 2022 at 12:19 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > I have pushed this finally.
    
    Thanks a lot.
    
    > I made two further changes:
    >
    > 1. there was no reason to rename ExecCheckPerms_hook, since its
    >    signature was changing anyway.  I reverted it to the original name.
    
    Sure, that makes sense.
    
    > 2. I couldn't find any reason to expose ExecGetRTEPermissionInfo, and
    >    given that it's a one-line function, I removed it.
    >
    > Maybe you had a reason to add ExecGetRTEPermissionInfo, thinking about
    > external callers; if so please discuss it.
    
    My thinking was that it might be better to have a macro/function that
    takes EState, not es_rteperminfos, from the callers.  Kind of like how
    there is exec_rt_fetch().  Though, that is only a cosmetic
    consideration, so I don't want to insist.
    
    > I'll mark this commitfest entry as committed soon; please post the other
    > two patches you had in this series in a new thread.
    
    Will do, thanks.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  72. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-12-07T08:47:13Z

    On Wed, Dec 7, 2022 at 4:01 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Wed, Dec 7, 2022 at 12:19 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > > I have pushed this finally.
    >>
    > > I'll mark this commitfest entry as committed soon; please post the other
    > > two patches you had in this series in a new thread.
    >
    > Will do, thanks.
    
    While doing that, I noticed that I had missed updating at least one
    comment which still says that permission checking is done off of the
    range table.  Attached patch fixes that.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  73. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-12-07T10:42:59Z

    On 2022-Dec-06, Alvaro Herrera wrote:
    
    > I have pushed this finally.
    > 
    > I made two further changes:
    
    Actually, I made one further change that I forgot to mention -- I
    changed the API of CombineRangeTables once again; the committed patch
    has it this way:
    
    +/*
    + * CombineRangeTables
    + *         Adds the RTEs of 'src_rtable' into 'dst_rtable'
    + *
    + * This also adds the RTEPermissionInfos of 'src_perminfos' (belonging to the
    + * RTEs in 'src_rtable') into *dst_perminfos and also updates perminfoindex of
    + * the RTEs in 'src_rtable' to now point to the perminfos' indexes in
    + * *dst_perminfos.
    + *
    + * Note that this changes both 'dst_rtable' and 'dst_perminfo' destructively,
    + * so the caller should have better passed safe-to-modify copies.
    + */
    +void
    +CombineRangeTables(List **dst_rtable, List **dst_perminfos,
    +                  List *src_rtable, List *src_perminfos)
    
    The original one had the target rangetable first, then the source
    RT+perminfos, and the target perminfos at the end.  This seemed
    inconsistent and potentially confusing.  I also changed the argument
    names (from using numbers to "dst/src" monikers) and removed the
    behavior of returning the list: ISTM it did turn out to be a bad idea
    after all.
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    
    
    
    
  74. Re: ExecRTCheckPerms() and many prunable partitions

    Amit Langote <amitlangote09@gmail.com> — 2022-12-07T10:50:11Z

    On Wed, Dec 7, 2022 at 7:43 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > On 2022-Dec-06, Alvaro Herrera wrote:
    > > I have pushed this finally.
    > >
    > > I made two further changes:
    >
    > Actually, I made one further change that I forgot to mention -- I
    > changed the API of CombineRangeTables once again; the committed patch
    > has it this way:
    >
    > +/*
    > + * CombineRangeTables
    > + *         Adds the RTEs of 'src_rtable' into 'dst_rtable'
    > + *
    > + * This also adds the RTEPermissionInfos of 'src_perminfos' (belonging to the
    > + * RTEs in 'src_rtable') into *dst_perminfos and also updates perminfoindex of
    > + * the RTEs in 'src_rtable' to now point to the perminfos' indexes in
    > + * *dst_perminfos.
    > + *
    > + * Note that this changes both 'dst_rtable' and 'dst_perminfo' destructively,
    > + * so the caller should have better passed safe-to-modify copies.
    > + */
    > +void
    > +CombineRangeTables(List **dst_rtable, List **dst_perminfos,
    > +                  List *src_rtable, List *src_perminfos)
    >
    > The original one had the target rangetable first, then the source
    > RT+perminfos, and the target perminfos at the end.  This seemed
    > inconsistent and potentially confusing.  I also changed the argument
    > names (from using numbers to "dst/src" monikers) and removed the
    > behavior of returning the list: ISTM it did turn out to be a bad idea
    > after all.
    
    This looks better to me too.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
    
    
    
  75. Re: ExecRTCheckPerms() and many prunable partitions

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2022-12-07T11:44:15Z

    On 2022-Dec-07, Amit Langote wrote:
    
    > While doing that, I noticed that I had missed updating at least one
    > comment which still says that permission checking is done off of the
    > range table.  Attached patch fixes that.
    
    Pushed, thanks.
    
    -- 
    Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
    
    
    
    
  76. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Justin Pryzby <pryzby@telsasoft.com> — 2022-12-10T20:17:53Z

    On Tue, Nov 29, 2022 at 10:37:56PM +0900, Amit Langote wrote:
    > 0002 contains changes that has to do with changing how we access
    > checkAsUser in some foreign table planning/execution code sites.
    > Thought it might be better to describe it separately too.
    
    This was committed as 599b33b94:
        Stop accessing checkAsUser via RTE in some cases
    
    Which does this in a couple places in selfuncs.c:
    
                                    if (!vardata->acl_ok &&
                                        root->append_rel_array != NULL)
                                    {   
                                        AppendRelInfo *appinfo;
                                        Index       varno = index->rel->relid;
    
                                        appinfo = root->append_rel_array[varno];
                                        while (appinfo &&
                                               planner_rt_fetch(appinfo->parent_relid,
                                                                root)->rtekind == RTE_RELATION)
                                        {   
                                            varno = appinfo->parent_relid;
                                            appinfo = root->append_rel_array[varno];
                                        }
                                        if (varno != index->rel->relid)
                                        {   
                                            /* Repeat access check on this rel */
                                            rte = planner_rt_fetch(varno, root);
                                            Assert(rte->rtekind == RTE_RELATION);
    
    -                                       userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
    +                                       userid = OidIsValid(onerel->userid) ?
    +                                           onerel->userid : GetUserId();
    
                                            vardata->acl_ok =
                                                rte->securityQuals == NIL &&
                                                (pg_class_aclcheck(rte->relid,
                                                                   userid,
                                                                   ACL_SELECT) == ACLCHECK_OK);
                                        }
                                    }
    
    
    The original code rechecks rte->checkAsUser with the rte of the parent
    rel.  The patch changed to access onerel instead, but that's not updated
    after looping to find the parent.
    
    Is that okay ?  It doesn't seem intentional, since "userid" is still
    being recomputed, but based on onerel, which hasn't changed.  The
    original intent (since 553d2ec27) is to recheck the parent's
    "checkAsUser".  
    
    It seems like this would matter for partitioned tables, when the
    partition isn't readable, but its parent is, and accessed via a view
    owned by another user?
    
    -- 
    Justin
    
    
    
    
  77. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Amit Langote <amitlangote09@gmail.com> — 2022-12-11T09:25:48Z

    Hi,
    
    On Sun, Dec 11, 2022 at 5:17 AM Justin Pryzby <pryzby@telsasoft.com> wrote:
    > On Tue, Nov 29, 2022 at 10:37:56PM +0900, Amit Langote wrote:
    > > 0002 contains changes that has to do with changing how we access
    > > checkAsUser in some foreign table planning/execution code sites.
    > > Thought it might be better to describe it separately too.
    >
    > This was committed as 599b33b94:
    >     Stop accessing checkAsUser via RTE in some cases
    >
    > Which does this in a couple places in selfuncs.c:
    >
    >                                 if (!vardata->acl_ok &&
    >                                     root->append_rel_array != NULL)
    >                                 {
    >                                     AppendRelInfo *appinfo;
    >                                     Index       varno = index->rel->relid;
    >
    >                                     appinfo = root->append_rel_array[varno];
    >                                     while (appinfo &&
    >                                            planner_rt_fetch(appinfo->parent_relid,
    >                                                             root)->rtekind == RTE_RELATION)
    >                                     {
    >                                         varno = appinfo->parent_relid;
    >                                         appinfo = root->append_rel_array[varno];
    >                                     }
    >                                     if (varno != index->rel->relid)
    >                                     {
    >                                         /* Repeat access check on this rel */
    >                                         rte = planner_rt_fetch(varno, root);
    >                                         Assert(rte->rtekind == RTE_RELATION);
    >
    > -                                       userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
    > +                                       userid = OidIsValid(onerel->userid) ?
    > +                                           onerel->userid : GetUserId();
    >
    >                                         vardata->acl_ok =
    >                                             rte->securityQuals == NIL &&
    >                                             (pg_class_aclcheck(rte->relid,
    >                                                                userid,
    >                                                                ACL_SELECT) == ACLCHECK_OK);
    >                                     }
    >                                 }
    >
    >
    > The original code rechecks rte->checkAsUser with the rte of the parent
    > rel.  The patch changed to access onerel instead, but that's not updated
    > after looping to find the parent.
    >
    > Is that okay ?  It doesn't seem intentional, since "userid" is still
    > being recomputed, but based on onerel, which hasn't changed.  The
    > original intent (since 553d2ec27) is to recheck the parent's
    > "checkAsUser".
    >
    > It seems like this would matter for partitioned tables, when the
    > partition isn't readable, but its parent is, and accessed via a view
    > owned by another user?
    
    Thanks for pointing this out.
    
    I think these blocks which are rewriting userid to basically the same
    value should have been removed from these sites as part of 599b33b94.
    Even before that commit, the checkAsUser value should have been the
    same in the RTE of both the child relation passed to these functions
    and that of the root parent that's looked up by looping.  That's
    because expand_single_inheritance_child(), which adds child RTEs,
    copies the parent RTE's checkAsUser, that is, as of commit 599b33b94.
    A later commit a61b1f74823c has removed the checkAsUser field from
    RangeTblEntry.
    
    Moreover, 599b33b94 adds some code in build_simple_rel() to set a
    given rel's userid value by copying it from the parent rel, such that
    the userid value would be the same in all relations in a given
    inheritance tree.
    
    I've attached 0001 to remove those extraneous code blocks and add a
    comment mentioning that userid need not be recomputed.
    
    While staring at the build_simple_rel() bit mentioned above, I
    realized that this code fails to set userid correctly in the
    inheritance parent rels that are child relations of subquery parent
    relations, such as UNION ALL subqueries.  In that case, instead of
    copying the userid (= 0) of the parent rel, the child should look up
    its own RTEPermissionInfo, which should be there, and use the
    checkAsUser value from there.  I've attached 0002 to fix this hole.  I
    am not sure whether there's a way to add a test case for this in the
    core suite.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  78. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Justin Pryzby <pryzby@telsasoft.com> — 2022-12-11T14:21:58Z

    On Sun, Dec 11, 2022 at 06:25:48PM +0900, Amit Langote wrote:
    > On Sun, Dec 11, 2022 at 5:17 AM Justin Pryzby <pryzby@telsasoft.com> wrote:
    > > The original code rechecks rte->checkAsUser with the rte of the parent
    > > rel.  The patch changed to access onerel instead, but that's not updated
    > > after looping to find the parent.
    > >
    > > Is that okay ?  It doesn't seem intentional, since "userid" is still
    > > being recomputed, but based on onerel, which hasn't changed.  The
    > > original intent (since 553d2ec27) is to recheck the parent's
    > > "checkAsUser".
    > >
    > > It seems like this would matter for partitioned tables, when the
    > > partition isn't readable, but its parent is, and accessed via a view
    > > owned by another user?
    > 
    > Thanks for pointing this out.
    > 
    > I think these blocks which are rewriting userid to basically the same
    > value should have been removed from these sites as part of 599b33b94.
    
    I thought maybe; thanks for checking.
    
    Little nitpicks:
    
    001:
    Fine to use the same userid as it's same in all
    => the same
    
    002:
    give that it's a subquery rel.
    => given
    
    -- 
    Justin
    
    
    
    
  79. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Amit Langote <amitlangote09@gmail.com> — 2022-12-12T06:23:22Z

    On Sun, Dec 11, 2022 at 6:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > I've attached 0001 to remove those extraneous code blocks and add a
    > comment mentioning that userid need not be recomputed.
    >
    > While staring at the build_simple_rel() bit mentioned above, I
    > realized that this code fails to set userid correctly in the
    > inheritance parent rels that are child relations of subquery parent
    > relations, such as UNION ALL subqueries.  In that case, instead of
    > copying the userid (= 0) of the parent rel, the child should look up
    > its own RTEPermissionInfo, which should be there, and use the
    > checkAsUser value from there.  I've attached 0002 to fix this hole.  I
    > am not sure whether there's a way to add a test case for this in the
    > core suite.
    
    Ah, I realized we could just expand the test added by 553d2ec27 with a
    wrapper view (to test checkAsUser functionality) and a UNION ALL query
    over the view (to test this change).
    
    I've done that in the attached updated patch, in which I've also
    addressed Justin's comments.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  80. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Justin Pryzby <pryzby@telsasoft.com> — 2022-12-21T19:44:11Z

    Alvaro could you comment on this ?
    
    
    
    
  81. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Justin Pryzby <pryzby@telsasoft.com> — 2023-01-05T21:12:20Z

    On Wed, Dec 21, 2022 at 01:44:11PM -0600, Justin Pryzby wrote:
    > Alvaro could you comment on this ?
    
    I added here so it's not forgotten.
    https://commitfest.postgresql.org/42/4107/
    
    
    
    
  82. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Tom Lane <tgl@sss.pgh.pa.us> — 2023-01-05T21:25:41Z

    Justin Pryzby <pryzby@telsasoft.com> writes:
    > On Wed, Dec 21, 2022 at 01:44:11PM -0600, Justin Pryzby wrote:
    >> Alvaro could you comment on this ?
    
    I believe Alvaro's on vacation for a few days more.
    
    			regards, tom lane
    
    
    
    
  83. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2023-01-17T10:26:54Z

    On 2022-Dec-12, Amit Langote wrote:
    
    > On Sun, Dec 11, 2022 at 6:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > I've attached 0001 to remove those extraneous code blocks and add a
    > > comment mentioning that userid need not be recomputed.
    > >
    > > While staring at the build_simple_rel() bit mentioned above, I
    > > realized that this code fails to set userid correctly in the
    > > inheritance parent rels that are child relations of subquery parent
    > > relations, such as UNION ALL subqueries.  In that case, instead of
    > > copying the userid (= 0) of the parent rel, the child should look up
    > > its own RTEPermissionInfo, which should be there, and use the
    > > checkAsUser value from there.  I've attached 0002 to fix this hole.  I
    > > am not sure whether there's a way to add a test case for this in the
    > > core suite.
    > 
    > Ah, I realized we could just expand the test added by 553d2ec27 with a
    > wrapper view (to test checkAsUser functionality) and a UNION ALL query
    > over the view (to test this change).
    
    Hmm, but if I run this test without the code change in 0002, the test
    also passes (to wit: the plan still has two hash joins), so I understand
    that either you're testing something that's not changed by the patch,
    or the test case itself isn't really what you wanted.
    
    As for 0001, it seems simpler to me to put the 'userid' variable in the
    same scope as 'onerel', and then compute it just once and don't bother
    with it at all afterwards, as in the attached.
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    Al principio era UNIX, y UNIX habló y dijo: "Hello world\n".
    No dijo "Hello New Jersey\n", ni "Hello USA\n".
    
  84. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Amit Langote <amitlangote09@gmail.com> — 2023-01-19T11:16:16Z

    On Tue, Jan 17, 2023 at 7:33 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > On 2022-Dec-12, Amit Langote wrote:
    > > On Sun, Dec 11, 2022 at 6:25 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > > I've attached 0001 to remove those extraneous code blocks and add a
    > > > comment mentioning that userid need not be recomputed.
    > > >
    > > > While staring at the build_simple_rel() bit mentioned above, I
    > > > realized that this code fails to set userid correctly in the
    > > > inheritance parent rels that are child relations of subquery parent
    > > > relations, such as UNION ALL subqueries.  In that case, instead of
    > > > copying the userid (= 0) of the parent rel, the child should look up
    > > > its own RTEPermissionInfo, which should be there, and use the
    > > > checkAsUser value from there.  I've attached 0002 to fix this hole.  I
    > > > am not sure whether there's a way to add a test case for this in the
    > > > core suite.
    > >
    > > Ah, I realized we could just expand the test added by 553d2ec27 with a
    > > wrapper view (to test checkAsUser functionality) and a UNION ALL query
    > > over the view (to test this change).
    >
    > Hmm, but if I run this test without the code change in 0002, the test
    > also passes (to wit: the plan still has two hash joins), so I understand
    > that either you're testing something that's not changed by the patch,
    > or the test case itself isn't really what you wanted.
    
    Yeah, the test case is bogus. :-(.
    
    It seems that, with the test as written, it's not the partitioned
    table referenced in the view's query that becomes a child of the UNION
    ALL parent subquery, but the subquery itself.  The bug being fixed in
    0002 doesn't affect the planning of this query at all, because child
    subquery is planned independently of the main query involving UNION
    ALL because of it being unable to be pushed up into the latter.  We
    want the partitioned table referenced in the child subquery to become
    a child of the UNION ALL parent subquery for the bug to be relevant.
    
    I tried rewriting the test such that the view's subquery does get
    pulled up such that the partitioned table becomes a child of the UNION
    ALL subquery.  By attaching a debugger, I do see the bug affecting the
    planning of this query, but still not in a way that changes the plan.
    I will keep trying but in the meantime I'm attaching 0001 to show the
    rewritten query and the plan.
    
    > As for 0001, it seems simpler to me to put the 'userid' variable in the
    > same scope as 'onerel', and then compute it just once and don't bother
    > with it at all afterwards, as in the attached.
    
    That sounds better.  Attached as 0002.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  85. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2023-01-19T12:25:20Z

    On 2023-Jan-19, Amit Langote wrote:
    
    > It seems that, with the test as written, it's not the partitioned
    > table referenced in the view's query that becomes a child of the UNION
    > ALL parent subquery, but the subquery itself.  The bug being fixed in
    > 0002 doesn't affect the planning of this query at all, because child
    > subquery is planned independently of the main query involving UNION
    > ALL because of it being unable to be pushed up into the latter.  We
    > want the partitioned table referenced in the child subquery to become
    > a child of the UNION ALL parent subquery for the bug to be relevant.
    > 
    > I tried rewriting the test such that the view's subquery does get
    > pulled up such that the partitioned table becomes a child of the UNION
    > ALL subquery.  By attaching a debugger, I do see the bug affecting the
    > planning of this query, but still not in a way that changes the plan.
    > I will keep trying but in the meantime I'm attaching 0001 to show the
    > rewritten query and the plan.
    
    Thanks for spending time tracking down a test case.  I'll try to have a
    look later today.
    
    > > As for 0001, it seems simpler to me to put the 'userid' variable in the
    > > same scope as 'onerel', and then compute it just once and don't bother
    > > with it at all afterwards, as in the attached.
    > 
    > That sounds better.  Attached as 0002.
    
    Pushed this one, thank you.
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    
    
    
    
  86. Re: ExecRTCheckPerms() and many prunable partitions (sqlsmith)

    Justin Pryzby <pryzby@telsasoft.com> — 2023-02-12T23:37:11Z

    On Tue, Nov 29, 2022 at 10:37:56PM +0900, Amit Langote wrote:
    > 0002 contains changes that has to do with changing how we access
    > checkAsUser in some foreign table planning/execution code sites.
    > Thought it might be better to describe it separately too.
    
    This was committed as 599b33b94:
        Stop accessing checkAsUser via RTE in some cases
    
    That seems to add various elog()s which are hit frequently by sqlsmith:
    
    postgres=# select from
    (select transaction
    from pg_prepared_xacts
    right join pg_available_extensions
    on false limit 0) where false;
    ERROR:  permission info at index 2 (with relid=1262) does not match provided RTE (with relid=12081)
    
    postgres=# select from (select confl_tablespace
    from pg_stat_database_conflicts
    where datname <> (select 'af')
    limit 1) where false;
    ERROR:  invalid perminfoindex 1 in RTE with relid 12271
    
    
    
    
    
  87. Re: ExecRTCheckPerms() and many prunable partitions (sqlsmith)

    Amit Langote <amitlangote09@gmail.com> — 2023-02-13T08:14:44Z

    On Mon, Feb 13, 2023 at 5:07 Justin Pryzby <pryzby@telsasoft.com> wrote:
    
    > On Tue, Nov 29, 2022 at 10:37:56PM +0900, Amit Langote wrote:
    > > 0002 contains changes that has to do with changing how we access
    > > checkAsUser in some foreign table planning/execution code sites.
    > > Thought it might be better to describe it separately too.
    >
    > This was committed as 599b33b94:
    >     Stop accessing checkAsUser via RTE in some cases
    >
    > That seems to add various elog()s which are hit frequently by sqlsmith:
    >
    > postgres=# select from
    > (select transaction
    > from pg_prepared_xacts
    > right join pg_available_extensions
    > on false limit 0) where false;
    > ERROR:  permission info at index 2 (with relid=1262) does not match
    > provided RTE (with relid=12081)
    >
    > postgres=# select from (select confl_tablespace
    > from pg_stat_database_conflicts
    > where datname <> (select 'af')
    > limit 1) where false;
    > ERROR:  invalid perminfoindex 1 in RTE with relid 12271
    
    
    Thanks for the report.  I’ll take a look once I’m back at a computer in a
    few days.
    
    > --
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  88. Re: ExecRTCheckPerms() and many prunable partitions (sqlsmith)

    Tom Lane <tgl@sss.pgh.pa.us> — 2023-02-13T17:01:38Z

    Amit Langote <amitlangote09@gmail.com> writes:
    > On Mon, Feb 13, 2023 at 5:07 Justin Pryzby <pryzby@telsasoft.com> wrote:
    >> That seems to add various elog()s which are hit frequently by sqlsmith:
    
    > Thanks for the report.  I’ll take a look once I’m back at a computer in a
    > few days.
    
    Looks like we already have a diagnosis and fix [1].  I'll get that
    pushed.
    
    			regards, tom lane
    
    [1] https://www.postgresql.org/message-id/CAHewXNnnNySD_YcKNuFpQDV2gxWA7_YLWqHmYVcyoOYxn8kY2A%40mail.gmail.com
    
    
    
    
  89. Re: ExecRTCheckPerms() and many prunable partitions (sqlsmith)

    Amit Langote <amitlangote09@gmail.com> — 2023-02-14T05:44:59Z

    On Mon, Feb 13, 2023 at 22:31 Tom Lane <tgl@sss.pgh.pa.us> wrote:
    
    > Amit Langote <amitlangote09@gmail.com> writes:
    > > On Mon, Feb 13, 2023 at 5:07 Justin Pryzby <pryzby@telsasoft.com> wrote:
    > >> That seems to add various elog()s which are hit frequently by sqlsmith:
    >
    > > Thanks for the report.  I’ll take a look once I’m back at a computer in a
    > > few days.
    >
    > Looks like we already have a diagnosis and fix [1].  I'll get that
    > pushed.
    >
    >                         regards, tom lane
    >
    > [1]
    > https://www.postgresql.org/message-id/CAHewXNnnNySD_YcKNuFpQDV2gxWA7_YLWqHmYVcyoOYxn8kY2A%40mail.gmail.com
    
    
    Oh, thanks a lot.
    
    >
    > <https://www.postgresql.org/message-id/CAHewXNnnNySD_YcKNuFpQDV2gxWA7_YLWqHmYVcyoOYxn8kY2A%40mail.gmail.com>
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  90. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2023-02-17T12:02:46Z

    On 2022-Dec-11, Amit Langote wrote:
    
    > While staring at the build_simple_rel() bit mentioned above, I
    > realized that this code fails to set userid correctly in the
    > inheritance parent rels that are child relations of subquery parent
    > relations, such as UNION ALL subqueries.  In that case, instead of
    > copying the userid (= 0) of the parent rel, the child should look up
    > its own RTEPermissionInfo, which should be there, and use the
    > checkAsUser value from there.  I've attached 0002 to fix this hole.  I
    > am not sure whether there's a way to add a test case for this in the
    > core suite.
    
    I gave this a look and I thought it was clearer to have the new
    condition depend on rel->reloptkind instead parent or no.
    
    I tried a few things for a new test case, but I was unable to find
    anything useful.  Maybe an intermediate view, I thought; no dice.
    Maybe one with a security barrier would do?  Anyway, for now I just kept
    what you added in v2.
    
    -- 
    Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
    
  91. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2023-02-17T12:05:58Z

    On 2023-Feb-17, Alvaro Herrera wrote:
    
    > I tried a few things for a new test case, but I was unable to find
    > anything useful.  Maybe an intermediate view, I thought; no dice.
    > Maybe one with a security barrier would do?  Anyway, for now I just kept
    > what you added in v2.
    
    Sorry, I failed to keep count of the patch version correctly.  The test
    case here is what you sent in v3 [1], and consequently the patch I just
    attached should have been labelled v4.
    
    [1] https://postgr.es/m/CA+HiwqF6ricH7HFCkyrK72c=KN-PRkdncxdLmU_mEQx=DRAkJA@mail.gmail.com
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    "La vida es para el que se aventura"
    
    
    
    
  92. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Amit Langote <amitlangote09@gmail.com> — 2023-02-20T07:56:22Z

    On Fri, Feb 17, 2023 at 9:02 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    > On 2022-Dec-11, Amit Langote wrote:
    > > While staring at the build_simple_rel() bit mentioned above, I
    > > realized that this code fails to set userid correctly in the
    > > inheritance parent rels that are child relations of subquery parent
    > > relations, such as UNION ALL subqueries.  In that case, instead of
    > > copying the userid (= 0) of the parent rel, the child should look up
    > > its own RTEPermissionInfo, which should be there, and use the
    > > checkAsUser value from there.  I've attached 0002 to fix this hole.  I
    > > am not sure whether there's a way to add a test case for this in the
    > > core suite.
    >
    > I gave this a look and I thought it was clearer to have the new
    > condition depend on rel->reloptkind instead parent or no.
    
    Thanks for looking into this again.  I agree the condition with
    reloptkind might be better.
    
    > I tried a few things for a new test case, but I was unable to find
    > anything useful.  Maybe an intermediate view, I thought; no dice.
    > Maybe one with a security barrier would do?  Anyway, for now I just kept
    > what you added in v2.
    
    Hmm, I'm fine with leaving the test case out if it doesn't really test
    the code we're changing, as you also pointed out?
    
    One more thing we could try is come up with a postgres_fdw test case,
    because it uses the RelOptInfo.userid value for remote-costs-based
    path size estimation.  But adding a test case to contrib module's
    suite test a core planner change might seem strange, ;-).
    
    Attaching v4 without the test case.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  93. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2023-02-20T15:19:13Z

    On 2023-Feb-20, Amit Langote wrote:
    
    > On Fri, Feb 17, 2023 at 9:02 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
    
    > > I tried a few things for a new test case, but I was unable to find
    > > anything useful.  Maybe an intermediate view, I thought; no dice.
    > > Maybe one with a security barrier would do?  Anyway, for now I just kept
    > > what you added in v2.
    > 
    > Hmm, I'm fine with leaving the test case out if it doesn't really test
    > the code we're changing, as you also pointed out?
    
    Yeah, pushed like that.
    
    > One more thing we could try is come up with a postgres_fdw test case,
    > because it uses the RelOptInfo.userid value for remote-costs-based
    > path size estimation.  But adding a test case to contrib module's
    > suite test a core planner change might seem strange, ;-).
    
    Maybe.  Perhaps adding it in a separate file there is okay?
    
    -- 
    Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
    "Small aircraft do not crash frequently ... usually only once!"
                                      (ponder, http://thedailywtf.com/)
    
    
    
    
  94. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Tom Lane <tgl@sss.pgh.pa.us> — 2023-02-20T15:40:10Z

    Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
    > On 2023-Feb-20, Amit Langote wrote:
    >> One more thing we could try is come up with a postgres_fdw test case,
    >> because it uses the RelOptInfo.userid value for remote-costs-based
    >> path size estimation.  But adding a test case to contrib module's
    >> suite test a core planner change might seem strange, ;-).
    
    > Maybe.  Perhaps adding it in a separate file there is okay?
    
    There is plenty of stuff in contrib module tests that is really
    there to test core-code behavior.  (You could indeed argue that
    *all* of contrib is there for that purpose.)  If it's not
    convenient to test something without an extension, just do it
    and don't sweat about that.
    
    			regards, tom lane
    
    
    
    
  95. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Amit Langote <amitlangote09@gmail.com> — 2023-02-21T07:12:14Z

    On Tue, Feb 21, 2023 at 12:40 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
    > > On 2023-Feb-20, Amit Langote wrote:
    > >> One more thing we could try is come up with a postgres_fdw test case,
    > >> because it uses the RelOptInfo.userid value for remote-costs-based
    > >> path size estimation.  But adding a test case to contrib module's
    > >> suite test a core planner change might seem strange, ;-).
    >
    > > Maybe.  Perhaps adding it in a separate file there is okay?
    >
    > There is plenty of stuff in contrib module tests that is really
    > there to test core-code behavior.  (You could indeed argue that
    > *all* of contrib is there for that purpose.)  If it's not
    > convenient to test something without an extension, just do it
    > and don't sweat about that.
    
    OK.  Attached adds a test case to postgres_fdw's suite.  You can see
    that it fails without a316a3bc.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  96. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Amit Langote <amitlangote09@gmail.com> — 2023-06-28T07:30:54Z

    Hi,
    
    On Tue, Feb 21, 2023 at 4:12 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > On Tue, Feb 21, 2023 at 12:40 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > > Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
    > > > On 2023-Feb-20, Amit Langote wrote:
    > > >> One more thing we could try is come up with a postgres_fdw test case,
    > > >> because it uses the RelOptInfo.userid value for remote-costs-based
    > > >> path size estimation.  But adding a test case to contrib module's
    > > >> suite test a core planner change might seem strange, ;-).
    > >
    > > > Maybe.  Perhaps adding it in a separate file there is okay?
    > >
    > > There is plenty of stuff in contrib module tests that is really
    > > there to test core-code behavior.  (You could indeed argue that
    > > *all* of contrib is there for that purpose.)  If it's not
    > > convenient to test something without an extension, just do it
    > > and don't sweat about that.
    >
    > OK.  Attached adds a test case to postgres_fdw's suite.  You can see
    > that it fails without a316a3bc.
    
    Noticed that there's an RfC entry for this in the next CF.  Here's an
    updated version of the patch where I updated the comments a bit and
    the commit message.
    
    I'm thinking of pushing this on Friday barring objections.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com
    
  97. Re: ExecRTCheckPerms() and many prunable partitions (checkAsUser)

    Amit Langote <amitlangote09@gmail.com> — 2023-06-30T06:54:38Z

    On Wed, Jun 28, 2023 at 4:30 PM Amit Langote <amitlangote09@gmail.com> wrote:
    >
    > Hi,
    >
    > On Tue, Feb 21, 2023 at 4:12 PM Amit Langote <amitlangote09@gmail.com> wrote:
    > > On Tue, Feb 21, 2023 at 12:40 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > > > Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
    > > > > On 2023-Feb-20, Amit Langote wrote:
    > > > >> One more thing we could try is come up with a postgres_fdw test case,
    > > > >> because it uses the RelOptInfo.userid value for remote-costs-based
    > > > >> path size estimation.  But adding a test case to contrib module's
    > > > >> suite test a core planner change might seem strange, ;-).
    > > >
    > > > > Maybe.  Perhaps adding it in a separate file there is okay?
    > > >
    > > > There is plenty of stuff in contrib module tests that is really
    > > > there to test core-code behavior.  (You could indeed argue that
    > > > *all* of contrib is there for that purpose.)  If it's not
    > > > convenient to test something without an extension, just do it
    > > > and don't sweat about that.
    > >
    > > OK.  Attached adds a test case to postgres_fdw's suite.  You can see
    > > that it fails without a316a3bc.
    >
    > Noticed that there's an RfC entry for this in the next CF.  Here's an
    > updated version of the patch where I updated the comments a bit and
    > the commit message.
    >
    > I'm thinking of pushing this on Friday barring objections.
    
    Seeing none, I've pushed this to HEAD and 16.
    
    Marking the CF entry as committed.
    
    -- 
    Thanks, Amit Langote
    EDB: http://www.enterprisedb.com