Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix description and grouping of RangeTblEntry.inh
authorPeter Eisentraut <peter@eisentraut.org>
Thu, 7 Mar 2024 10:50:24 +0000 (11:50 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Thu, 7 Mar 2024 11:13:09 +0000 (12:13 +0100)
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

src/backend/nodes/outfuncs.c
src/backend/nodes/queryjumblefuncs.c
src/backend/nodes/readfuncs.c
src/backend/parser/parse_relation.c
src/include/catalog/catversion.h
src/include/nodes/parsenodes.h

index ef5c58ad102c90960e3987728f77346bee66982a..29cbc83bd9ff5ed7a6be0beece960ca7b0b51fcb 100644 (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);
 }
index 426112fa37b7d60bf817a297c4b186fde6018124..2c116c8728889ad4c15be81e0b9524aefc604a93 100644 (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);
index 70af513614d61795b42062e8b5130332309024e2..a122407c880aaf551c79e49c0ff6b39731b96665 100644 (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);
 
index 34a0ec59019b144331ffe95f012b5f54e2c31ec3..6f5d9e26925b694fb99682fd176c418c62170695 100644 (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;
 
    /*
index bedc2a0d722ad031072d307c268228d54d0fcc6c..e8dad22597b4fb37478a3051978d7a1b86047728 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 202403052
+#define CATALOG_VERSION_NO 202403071
 
 #endif
index 24f5c06bb6247c9ad68ab106dd974354ba9f4285..aef4fb7c335f68ede07bb16dc1b424712e36b6c1 100644 (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;