Fix description and grouping of RangeTblEntry.inh

The inh field of RangeTblEntry was doubly confusingly documented.
Some parts of the code insisted that it was only valid for
RTE_RELATION entries, other parts said the field was valid for all
entries.  Neither was quite correct.  More correctly, the field is
valid for RTE_RELATION entries but is also used in the planner for
RTE_SUBQUERY entries.  So it makes more sense to group it with other
fields that are primarily for RTE_RELATION but borrowed by
RTE_SUBQUERY.  (The exact position was chosen so that it is next to
relkind for better struct packing, and next to relid, since relid and
inh are sort of the input fields and the others are filled in later.)
Also add documentation for the planner's use at the struct definition.

Discussion: https://www.postgresql.org/message-id/6c1fbccc-85c8-40d3-b08b-4f47f2093711@eisentraut.org
This commit is contained in:
Peter Eisentraut 2024-03-07 11:50:24 +01:00
parent 1f1d73a8b8
commit 6d470211e5
6 changed files with 16 additions and 18 deletions

View File

@ -503,6 +503,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
{
case RTE_RELATION:
WRITE_OID_FIELD(relid);
WRITE_BOOL_FIELD(inh);
WRITE_CHAR_FIELD(relkind);
WRITE_INT_FIELD(rellockmode);
WRITE_UINT_FIELD(perminfoindex);
@ -513,6 +514,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
WRITE_BOOL_FIELD(security_barrier);
/* we re-use these RELATION fields, too: */
WRITE_OID_FIELD(relid);
WRITE_BOOL_FIELD(inh);
WRITE_CHAR_FIELD(relkind);
WRITE_INT_FIELD(rellockmode);
WRITE_UINT_FIELD(perminfoindex);
@ -564,7 +566,6 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
}
WRITE_BOOL_FIELD(lateral);
WRITE_BOOL_FIELD(inh);
WRITE_BOOL_FIELD(inFromCl);
WRITE_NODE_FIELD(securityQuals);
}

View File

@ -364,8 +364,8 @@ _jumbleRangeTblEntry(JumbleState *jstate, Node *node)
{
case RTE_RELATION:
JUMBLE_FIELD(relid);
JUMBLE_NODE(tablesample);
JUMBLE_FIELD(inh);
JUMBLE_NODE(tablesample);
break;
case RTE_SUBQUERY:
JUMBLE_NODE(subquery);

View File

@ -357,6 +357,7 @@ _readRangeTblEntry(void)
{
case RTE_RELATION:
READ_OID_FIELD(relid);
READ_BOOL_FIELD(inh);
READ_CHAR_FIELD(relkind);
READ_INT_FIELD(rellockmode);
READ_UINT_FIELD(perminfoindex);
@ -367,6 +368,7 @@ _readRangeTblEntry(void)
READ_BOOL_FIELD(security_barrier);
/* we re-use these RELATION fields, too: */
READ_OID_FIELD(relid);
READ_BOOL_FIELD(inh);
READ_CHAR_FIELD(relkind);
READ_INT_FIELD(rellockmode);
READ_UINT_FIELD(perminfoindex);
@ -428,7 +430,6 @@ _readRangeTblEntry(void)
}
READ_BOOL_FIELD(lateral);
READ_BOOL_FIELD(inh);
READ_BOOL_FIELD(inFromCl);
READ_NODE_FIELD(securityQuals);

View File

@ -1500,6 +1500,7 @@ addRangeTableEntry(ParseState *pstate,
*/
rel = parserOpenTable(pstate, relation, lockmode);
rte->relid = RelationGetRelid(rel);
rte->inh = inh;
rte->relkind = rel->rd_rel->relkind;
rte->rellockmode = lockmode;
@ -1517,7 +1518,6 @@ addRangeTableEntry(ParseState *pstate,
* which is the right thing for all except target tables.
*/
rte->lateral = false;
rte->inh = inh;
rte->inFromCl = inFromCl;
perminfo = addRTEPermissionInfo(&pstate->p_rteperminfos, rte);
@ -1585,6 +1585,7 @@ addRangeTableEntryForRelation(ParseState *pstate,
rte->rtekind = RTE_RELATION;
rte->alias = alias;
rte->relid = RelationGetRelid(rel);
rte->inh = inh;
rte->relkind = rel->rd_rel->relkind;
rte->rellockmode = lockmode;
@ -1602,7 +1603,6 @@ addRangeTableEntryForRelation(ParseState *pstate,
* which is the right thing for all except target tables.
*/
rte->lateral = false;
rte->inh = inh;
rte->inFromCl = inFromCl;
perminfo = addRTEPermissionInfo(&pstate->p_rteperminfos, rte);
@ -1700,7 +1700,6 @@ addRangeTableEntryForSubquery(ParseState *pstate,
* addRTEPermissionInfo().
*/
rte->lateral = lateral;
rte->inh = false; /* never true for subqueries */
rte->inFromCl = inFromCl;
/*
@ -2023,7 +2022,6 @@ addRangeTableEntryForFunction(ParseState *pstate,
* ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
*/
rte->lateral = lateral;
rte->inh = false; /* never true for functions */
rte->inFromCl = inFromCl;
/*
@ -2108,7 +2106,6 @@ addRangeTableEntryForTableFunc(ParseState *pstate,
* ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
*/
rte->lateral = lateral;
rte->inh = false; /* never true for tablefunc RTEs */
rte->inFromCl = inFromCl;
/*
@ -2189,7 +2186,6 @@ addRangeTableEntryForValues(ParseState *pstate,
* addRTEPermissionInfo().
*/
rte->lateral = lateral;
rte->inh = false; /* never true for values RTEs */
rte->inFromCl = inFromCl;
/*
@ -2280,7 +2276,6 @@ addRangeTableEntryForJoin(ParseState *pstate,
* addRTEPermissionInfo().
*/
rte->lateral = false;
rte->inh = false; /* never true for joins */
rte->inFromCl = inFromCl;
/*
@ -2425,7 +2420,6 @@ addRangeTableEntryForCTE(ParseState *pstate,
* addRTEPermissionInfo().
*/
rte->lateral = false;
rte->inh = false; /* never true for subqueries */
rte->inFromCl = inFromCl;
/*
@ -2545,7 +2539,6 @@ addRangeTableEntryForENR(ParseState *pstate,
* addRTEPermissionInfo().
*/
rte->lateral = false;
rte->inh = false; /* never true for ENRs */
rte->inFromCl = inFromCl;
/*

View File

@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202403052
#define CATALOG_VERSION_NO 202403071
#endif

View File

@ -989,10 +989,6 @@ typedef struct PartitionCmd
* them from the joinaliasvars list, because that would affect the attnums
* of Vars referencing the rest of the list.)
*
* inh is true for relation references that should be expanded to include
* inheritance children, if the rel has any. This *must* be false for
* RTEs other than RTE_RELATION entries.
*
* inFromCl marks those range variables that are listed in the FROM clause.
* It's false for RTEs that are added to a query behind the scenes, such
* as the NEW and OLD variables for a rule, or the subqueries of a UNION.
@ -1041,6 +1037,13 @@ typedef struct RangeTblEntry
/*
* Fields valid for a plain relation RTE (else zero):
*
* inh is true for relation references that should be expanded to include
* inheritance children, if the rel has any. In the parser, this will
* only be true for RTE_RELATION entries. The planner also uses this
* field to mark RTE_SUBQUERY entries that contain UNION ALL queries that
* it has flattened into pulled-up subqueries (creating a structure much
* like the effects of inheritance).
*
* rellockmode is really LOCKMODE, but it's declared int to avoid having
* to include lock-related headers here. It must be RowExclusiveLock if
* the RTE is an INSERT/UPDATE/DELETE/MERGE target, else RowShareLock if
@ -1070,6 +1073,7 @@ typedef struct RangeTblEntry
* tables to be invalidated if the underlying table is altered.
*/
Oid relid; /* OID of the relation */
bool inh; /* inheritance requested? */
char relkind; /* relation kind (see pg_class.relkind) */
int rellockmode; /* lock level that query requires on the rel */
Index perminfoindex; /* index of RTEPermissionInfo entry, or 0 */
@ -1199,7 +1203,6 @@ typedef struct RangeTblEntry
Alias *alias; /* user-written alias clause, if any */
Alias *eref; /* expanded reference names */
bool lateral; /* subquery, function, or values is LATERAL? */
bool inh; /* inheritance requested? */
bool inFromCl; /* present in FROM clause? */
List *securityQuals; /* security barrier quals to apply, if any */
} RangeTblEntry;