In Postgres 16 BETA, should the ParseNamespaceItem have the same index as it's RangeTableEntry?

From: Farias de Oliveira <matheusfarias519(at)gmail(dot)com>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: In Postgres 16 BETA, should the ParseNamespaceItem have the same index as it's RangeTableEntry?
Date: 2023-07-13 19:14:32
Message-ID: CANQ0oxfxBKKTReQgSh_KbL99DqdjfBZTastC0XT2ZZMBkAhTQw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello, my name is Matheus Farias and this is the first time that I'm
sending an email to the pgsql-hackers list. I'm a software developer intern
at Bitnine Global Inc. and, along with other interns, we've been working on
updating Apache AGE with the latest version of Postgres, the REL_16_BETA
version. One of the main problems that we are facing is that the code was
reworked to update the permission checking and now some of the queries
return ERROR: invalid perminfoindex <rte->perminfoindex> in RTE with relid
<rte->relid>. This occurs due to one of the RTEs having perminfoindex = 0
and the relid containing a value.

AGE is a Postgres extension which allows us to execute openCypher commands
to create a graph with nodes and edges. There are two main tables that are
created: _ag_label_vertex and _ag_label_edge. Both of them will be the
parent label tables of every other vertex/edge label we create.

When we do a simple MATCH query to find all nodes with the v label:

SELECT * FROM cypher('cypher_set', $$MATCH (n:v)RETURN n
$$) AS (node agtype);

inside the add_rtes_to_flat_rtable() function, it goes inside a loop
where we can see the stored RTEs in root->parse->rtable:

// I've simplified what every RTE shows.

root->parse->rtable
[
(rtekind = RTE_SUBQUERY, relid = 0, perminfoindex = 0),
(rtekind = RTE_SUBQUERY, relid = 0, perminfoindex = 0),
(rtekind = RTE_SUBQUERY, relid = 0, perminfoindex = 0),
(rtekind = RTE_RELATION, relid = 16991, perminfoindex = 1)
]

But executing the query with a simple SET clause:

SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = 3
$$) AS (a agtype);

One of the RTEs of the RTE_RELATION type and relid with a not null
value has perminfoindex = 0

root->parse->rtable
[
(rtekind = RTE_SUBQUERY, relid = 0, perminfoindex = 0),
(rtekind = RTE_RELATION, relid = 16971, perminfoindex = 1),
(rtekind = RTE_RELATION, relid = 16971, perminfoindex = 1),
(rtekind = RTE_RELATION, relid = 16991, perminfoindex = 0)
]

the relid = 16991 is related to the child vertex label and the relid =
16971 related to the parent vertex label:

SELECT to_regclass('cypher_set._ag_label_vertex')::oid;
to_regclass -------------
16971
SELECT to_regclass('cypher_set.v')::oid;
to_regclass -------------
16991

With further inspection in AGE's code, after executing the SET query,
it goes inside transform_cypher_clause_as_subquery() function and the
ParseNamespaceItem has the following values:

{p_names = 0x1205638, p_rte = 0x11edb70, p_rtindex = 1, p_perminfo =
0x7f7f7f7f7f7f7f7f,
p_nscolumns = 0x1205848, p_rel_visible = true, p_cols_visible =
true, p_lateral_only = false,
p_lateral_ok = true}

And the pnsi->p_rte has:

{type = T_RangeTblEntry, rtekind = RTE_SUBQUERY, relid = 0, relkind =
0 '\000', rellockmode = 0,
tablesample = 0x0, perminfoindex = 0, subquery = 0x11ed710,
security_barrier = false,
jointype = JOIN_INNER, joinmergedcols = 0, joinaliasvars = 0x0,
joinleftcols = 0x0, joinrightcols = 0x0,
join_using_alias = 0x0, functions = 0x0, funcordinality = false,
tablefunc = 0x0, values_lists = 0x0,
ctename = 0x0, ctelevelsup = 0, self_reference = false, coltypes =
0x0, coltypmods = 0x0,
colcollations = 0x0, enrname = 0x0, enrtuples = 0, alias =
0x12055f0, eref = 0x1205638, lateral = false,
inh = false, inFromCl = true, securityQuals = 0x0}

Then it calls addNSItemToQuery(pstate, pnsi, true, false, true);. This
function adds the given nsitem/RTE as a top-level entry in the pstate's
join list and/or namespace list. I've been thinking if adding the
nsitem/RTE like this won't cause this error?

Also in handle_prev_clause it has the following line, which is going to add
all the rte's attributes to the current queries targetlist which, again,
I'm not sure if that's what causing the problem because the relid of the
rte is 0:

query->targetList = expandNSItemAttrs(pstate, pnsi, 0, true, -1);

If someone knows more about it, I would be grateful for any kind of
answer or help. AGE's source code can be found here:
https://github.com/apache/age

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jeff Davis 2023-07-13 19:14:52 Re: MERGE ... RETURNING
Previous Message Jeff Davis 2023-07-13 18:56:00 Re: Fix search_path for all maintenance commands