Skip to content

Commit bdca82f

Browse files
committed
Add a relkind field to RangeTblEntry to avoid some syscache lookups.
The recent additions for FDW support required checking foreign-table-ness in several places in the parse/plan chain. While it's not clear whether that would really result in a noticeable slowdown, it seems best to avoid any performance risk by keeping a copy of the relation's relkind in RangeTblEntry. That might have some other uses later, anyway. Per discussion.
1 parent 1c51c7d commit bdca82f

File tree

19 files changed

+85
-74
lines changed

19 files changed

+85
-74
lines changed

src/backend/catalog/dependency.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,7 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
12841284
rte.type = T_RangeTblEntry;
12851285
rte.rtekind = RTE_RELATION;
12861286
rte.relid = relId;
1287+
rte.relkind = RELKIND_RELATION; /* no need for exactness here */
12871288

12881289
context.rtables = list_make1(list_make1(&rte));
12891290

src/backend/commands/copy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
763763
rte = makeNode(RangeTblEntry);
764764
rte->rtekind = RTE_RELATION;
765765
rte->relid = RelationGetRelid(rel);
766+
rte->relkind = rel->rd_rel->relkind;
766767
rte->requiredPerms = required_access;
767768

768769
tupDesc = RelationGetDescr(rel);

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,7 @@ _copyRangeTblEntry(RangeTblEntry *from)
19271927

19281928
COPY_SCALAR_FIELD(rtekind);
19291929
COPY_SCALAR_FIELD(relid);
1930+
COPY_SCALAR_FIELD(relkind);
19301931
COPY_NODE_FIELD(subquery);
19311932
COPY_SCALAR_FIELD(jointype);
19321933
COPY_NODE_FIELD(joinaliasvars);

src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,6 +2286,7 @@ _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
22862286
{
22872287
COMPARE_SCALAR_FIELD(rtekind);
22882288
COMPARE_SCALAR_FIELD(relid);
2289+
COMPARE_SCALAR_FIELD(relkind);
22892290
COMPARE_NODE_FIELD(subquery);
22902291
COMPARE_SCALAR_FIELD(jointype);
22912292
COMPARE_NODE_FIELD(joinaliasvars);

src/backend/nodes/nodeFuncs.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,7 +1671,6 @@ range_table_walker(List *rtable,
16711671
switch (rte->rtekind)
16721672
{
16731673
case RTE_RELATION:
1674-
case RTE_SPECIAL:
16751674
case RTE_CTE:
16761675
/* nothing to do */
16771676
break;
@@ -2374,7 +2373,6 @@ range_table_mutator(List *rtable,
23742373
switch (rte->rtekind)
23752374
{
23762375
case RTE_RELATION:
2377-
case RTE_SPECIAL:
23782376
case RTE_CTE:
23792377
/* we don't bother to copy eref, aliases, etc; OK? */
23802378
break;

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2275,8 +2275,8 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
22752275
switch (node->rtekind)
22762276
{
22772277
case RTE_RELATION:
2278-
case RTE_SPECIAL:
22792278
WRITE_OID_FIELD(relid);
2279+
WRITE_CHAR_FIELD(relkind);
22802280
break;
22812281
case RTE_SUBQUERY:
22822282
WRITE_NODE_FIELD(subquery);

src/backend/nodes/print.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ print_rt(List *rtable)
265265
switch (rte->rtekind)
266266
{
267267
case RTE_RELATION:
268-
printf("%d\t%s\t%u",
269-
i, rte->eref->aliasname, rte->relid);
268+
printf("%d\t%s\t%u\t%c",
269+
i, rte->eref->aliasname, rte->relid, rte->relkind);
270270
break;
271271
case RTE_SUBQUERY:
272272
printf("%d\t%s\t[subquery]",
@@ -276,10 +276,6 @@ print_rt(List *rtable)
276276
printf("%d\t%s\t[join]",
277277
i, rte->eref->aliasname);
278278
break;
279-
case RTE_SPECIAL:
280-
printf("%d\t%s\t[special]",
281-
i, rte->eref->aliasname);
282-
break;
283279
case RTE_FUNCTION:
284280
printf("%d\t%s\t[rangefunction]",
285281
i, rte->eref->aliasname);

src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,8 +1171,8 @@ _readRangeTblEntry(void)
11711171
switch (local_node->rtekind)
11721172
{
11731173
case RTE_RELATION:
1174-
case RTE_SPECIAL:
11751174
READ_OID_FIELD(relid);
1175+
READ_CHAR_FIELD(relkind);
11761176
break;
11771177
case RTE_SUBQUERY:
11781178
READ_NODE_FIELD(subquery);

src/backend/optimizer/path/allpaths.c

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -176,41 +176,44 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
176176
/* It's an "append relation", process accordingly */
177177
set_append_rel_pathlist(root, rel, rti, rte);
178178
}
179-
else if (rel->rtekind == RTE_SUBQUERY)
180-
{
181-
/* Subquery --- generate a separate plan for it */
182-
set_subquery_pathlist(root, rel, rti, rte);
183-
}
184-
else if (rel->rtekind == RTE_FUNCTION)
185-
{
186-
/* RangeFunction --- generate a suitable path for it */
187-
set_function_pathlist(root, rel, rte);
188-
}
189-
else if (rel->rtekind == RTE_VALUES)
190-
{
191-
/* Values list --- generate a suitable path for it */
192-
set_values_pathlist(root, rel, rte);
193-
}
194-
else if (rel->rtekind == RTE_CTE)
195-
{
196-
/* CTE reference --- generate a suitable path for it */
197-
if (rte->self_reference)
198-
set_worktable_pathlist(root, rel, rte);
199-
else
200-
set_cte_pathlist(root, rel, rte);
201-
}
202179
else
203180
{
204-
Assert(rel->rtekind == RTE_RELATION);
205-
if (get_rel_relkind(rte->relid) == RELKIND_FOREIGN_TABLE)
206-
{
207-
/* Foreign table */
208-
set_foreign_pathlist(root, rel, rte);
209-
}
210-
else
181+
switch (rel->rtekind)
211182
{
212-
/* Plain relation */
213-
set_plain_rel_pathlist(root, rel, rte);
183+
case RTE_RELATION:
184+
if (rte->relkind == RELKIND_FOREIGN_TABLE)
185+
{
186+
/* Foreign table */
187+
set_foreign_pathlist(root, rel, rte);
188+
}
189+
else
190+
{
191+
/* Plain relation */
192+
set_plain_rel_pathlist(root, rel, rte);
193+
}
194+
break;
195+
case RTE_SUBQUERY:
196+
/* Subquery --- generate a separate plan for it */
197+
set_subquery_pathlist(root, rel, rti, rte);
198+
break;
199+
case RTE_FUNCTION:
200+
/* RangeFunction --- generate a suitable path for it */
201+
set_function_pathlist(root, rel, rte);
202+
break;
203+
case RTE_VALUES:
204+
/* Values list --- generate a suitable path for it */
205+
set_values_pathlist(root, rel, rte);
206+
break;
207+
case RTE_CTE:
208+
/* CTE reference --- generate a suitable path for it */
209+
if (rte->self_reference)
210+
set_worktable_pathlist(root, rel, rte);
211+
else
212+
set_cte_pathlist(root, rel, rte);
213+
break;
214+
default:
215+
elog(ERROR, "unexpected rtekind: %d", (int) rel->rtekind);
216+
break;
214217
}
215218
}
216219

src/backend/optimizer/plan/planner.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1915,7 +1915,7 @@ preprocess_rowmarks(PlannerInfo *root)
19151915
newrc->rowmarkId = ++(root->glob->lastRowMarkId);
19161916
/* real tables support REFERENCE, anything else needs COPY */
19171917
if (rte->rtekind == RTE_RELATION &&
1918-
get_rel_relkind(rte->relid) != RELKIND_FOREIGN_TABLE)
1918+
rte->relkind != RELKIND_FOREIGN_TABLE)
19191919
newrc->markType = ROW_MARK_REFERENCE;
19201920
else
19211921
newrc->markType = ROW_MARK_COPY;
@@ -3078,6 +3078,7 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
30783078
rte = makeNode(RangeTblEntry);
30793079
rte->rtekind = RTE_RELATION;
30803080
rte->relid = tableOid;
3081+
rte->relkind = RELKIND_RELATION;
30813082
rte->inh = false;
30823083
rte->inFromCl = true;
30833084
query->rtable = list_make1(rte);

src/backend/parser/analyze.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
#include "parser/parse_target.h"
4141
#include "parser/parsetree.h"
4242
#include "rewrite/rewriteManip.h"
43-
#include "utils/lsyscache.h"
4443
#include "utils/rel.h"
4544

4645

@@ -2178,13 +2177,11 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
21782177
{
21792178
case RTE_RELATION:
21802179
/* ignore foreign tables */
2181-
if (get_rel_relkind(rte->relid) != RELKIND_FOREIGN_TABLE)
2182-
{
2183-
applyLockingClause(qry, i,
2184-
lc->forUpdate, lc->noWait,
2185-
pushedDown);
2186-
rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
2187-
}
2180+
if (rte->relkind == RELKIND_FOREIGN_TABLE)
2181+
break;
2182+
applyLockingClause(qry, i,
2183+
lc->forUpdate, lc->noWait, pushedDown);
2184+
rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
21882185
break;
21892186
case RTE_SUBQUERY:
21902187
applyLockingClause(qry, i,
@@ -2231,11 +2228,11 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
22312228
switch (rte->rtekind)
22322229
{
22332230
case RTE_RELATION:
2234-
if (get_rel_relkind(rte->relid) == RELKIND_FOREIGN_TABLE)
2231+
if (rte->relkind == RELKIND_FOREIGN_TABLE)
22352232
ereport(ERROR,
22362233
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
22372234
errmsg("SELECT FOR UPDATE/SHARE cannot be used with foreign table \"%s\"",
2238-
get_rel_name(rte->relid)),
2235+
rte->eref->aliasname),
22392236
parser_errposition(pstate, thisrel->location)));
22402237
applyLockingClause(qry, i,
22412238
lc->forUpdate, lc->noWait,
@@ -2256,12 +2253,6 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
22562253
errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a join"),
22572254
parser_errposition(pstate, thisrel->location)));
22582255
break;
2259-
case RTE_SPECIAL:
2260-
ereport(ERROR,
2261-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2262-
errmsg("SELECT FOR UPDATE/SHARE cannot be applied to NEW or OLD"),
2263-
parser_errposition(pstate, thisrel->location)));
2264-
break;
22652256
case RTE_FUNCTION:
22662257
ereport(ERROR,
22672258
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

src/backend/parser/parse_relation.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ addRangeTableEntry(ParseState *pstate,
894894
lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
895895
rel = parserOpenTable(pstate, relation, lockmode);
896896
rte->relid = RelationGetRelid(rel);
897+
rte->relkind = rel->rd_rel->relkind;
897898

898899
/*
899900
* Build the list of effective column names using user-supplied aliases
@@ -956,6 +957,7 @@ addRangeTableEntryForRelation(ParseState *pstate,
956957
rte->rtekind = RTE_RELATION;
957958
rte->alias = alias;
958959
rte->relid = RelationGetRelid(rel);
960+
rte->relkind = rel->rd_rel->relkind;
959961

960962
/*
961963
* Build the list of effective column names using user-supplied aliases

src/backend/parser/parse_target.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
305305
markTargetListOrigin(pstate, tle, aliasvar, netlevelsup);
306306
}
307307
break;
308-
case RTE_SPECIAL:
309308
case RTE_FUNCTION:
310309
case RTE_VALUES:
311310
/* not a simple relation, leave it unmarked */
@@ -1357,7 +1356,6 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
13571356
switch (rte->rtekind)
13581357
{
13591358
case RTE_RELATION:
1360-
case RTE_SPECIAL:
13611359
case RTE_VALUES:
13621360

13631361
/*

src/backend/rewrite/rewriteHandler.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
144144
lockmode = AccessShareLock;
145145

146146
rel = heap_open(rte->relid, lockmode);
147+
148+
/*
149+
* While we have the relation open, update the RTE's relkind,
150+
* just in case it changed since this rule was made.
151+
*/
152+
rte->relkind = rel->rd_rel->relkind;
153+
147154
heap_close(rel, NoLock);
148155
break;
149156

@@ -1393,7 +1400,7 @@ markQueryForLocking(Query *qry, Node *jtnode,
13931400
if (rte->rtekind == RTE_RELATION)
13941401
{
13951402
/* ignore foreign tables */
1396-
if (get_rel_relkind(rte->relid) != RELKIND_FOREIGN_TABLE)
1403+
if (rte->relkind != RELKIND_FOREIGN_TABLE)
13971404
{
13981405
applyLockingClause(qry, rti, forUpdate, noWait, pushedDown);
13991406
rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;

src/backend/utils/adt/ri_triggers.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,11 +2651,13 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
26512651
pkrte = makeNode(RangeTblEntry);
26522652
pkrte->rtekind = RTE_RELATION;
26532653
pkrte->relid = RelationGetRelid(pk_rel);
2654+
pkrte->relkind = pk_rel->rd_rel->relkind;
26542655
pkrte->requiredPerms = ACL_SELECT;
26552656

26562657
fkrte = makeNode(RangeTblEntry);
26572658
fkrte->rtekind = RTE_RELATION;
26582659
fkrte->relid = RelationGetRelid(fk_rel);
2660+
fkrte->relkind = fk_rel->rd_rel->relkind;
26592661
fkrte->requiredPerms = ACL_SELECT;
26602662

26612663
for (i = 0; i < riinfo.nkeys; i++)

src/backend/utils/adt/ruleutils.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
628628
if (!isnull)
629629
{
630630
Node *qual;
631+
char relkind;
631632
deparse_context context;
632633
deparse_namespace dpns;
633634
RangeTblEntry *oldrte;
@@ -637,17 +638,21 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
637638

638639
qual = stringToNode(TextDatumGetCString(value));
639640

641+
relkind = get_rel_relkind(trigrec->tgrelid);
642+
640643
/* Build minimal OLD and NEW RTEs for the rel */
641644
oldrte = makeNode(RangeTblEntry);
642645
oldrte->rtekind = RTE_RELATION;
643646
oldrte->relid = trigrec->tgrelid;
647+
oldrte->relkind = relkind;
644648
oldrte->eref = makeAlias("old", NIL);
645649
oldrte->inh = false;
646650
oldrte->inFromCl = true;
647651

648652
newrte = makeNode(RangeTblEntry);
649653
newrte->rtekind = RTE_RELATION;
650654
newrte->relid = trigrec->tgrelid;
655+
newrte->relkind = relkind;
651656
newrte->eref = makeAlias("new", NIL);
652657
newrte->inh = false;
653658
newrte->inFromCl = true;
@@ -2125,6 +2130,7 @@ deparse_context_for(const char *aliasname, Oid relid)
21252130
rte = makeNode(RangeTblEntry);
21262131
rte->rtekind = RTE_RELATION;
21272132
rte->relid = relid;
2133+
rte->relkind = RELKIND_RELATION; /* no need for exactness here */
21282134
rte->eref = makeAlias(aliasname, NIL);
21292135
rte->inh = false;
21302136
rte->inFromCl = true;
@@ -4004,7 +4010,6 @@ get_name_for_var_field(Var *var, int fieldno,
40044010
switch (rte->rtekind)
40054011
{
40064012
case RTE_RELATION:
4007-
case RTE_SPECIAL:
40084013
case RTE_VALUES:
40094014

40104015
/*

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201102221
56+
#define CATALOG_VERSION_NO 201102222
5757

5858
#endif

src/include/catalog/pg_class.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO
4949
Oid reltoastidxid; /* if toast table, OID of chunk_id index */
5050
bool relhasindex; /* T if has (or has had) any indexes */
5151
bool relisshared; /* T if shared across databases */
52-
char relpersistence; /* see RELPERSISTENCE_xxx constants */
52+
char relpersistence; /* see RELPERSISTENCE_xxx constants below */
5353
char relkind; /* see RELKIND_xxx constants below */
5454
int2 relnatts; /* number of user attributes */
5555

@@ -139,17 +139,18 @@ DESCR("");
139139
DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 26 0 t f f f f 3 _null_ _null_ ));
140140
DESCR("");
141141

142+
143+
#define RELKIND_RELATION 'r' /* ordinary table */
142144
#define RELKIND_INDEX 'i' /* secondary index */
143-
#define RELKIND_RELATION 'r' /* ordinary cataloged heap */
144-
#define RELKIND_SEQUENCE 'S' /* SEQUENCE relation */
145-
#define RELKIND_UNCATALOGED 'u' /* temporary heap */
146-
#define RELKIND_TOASTVALUE 't' /* moved off huge values */
145+
#define RELKIND_SEQUENCE 'S' /* sequence object */
146+
#define RELKIND_TOASTVALUE 't' /* for out-of-line values */
147147
#define RELKIND_VIEW 'v' /* view */
148148
#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */
149149
#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */
150+
#define RELKIND_UNCATALOGED 'u' /* not yet cataloged */
150151

151-
#define RELPERSISTENCE_PERMANENT 'p'
152-
#define RELPERSISTENCE_UNLOGGED 'u'
153-
#define RELPERSISTENCE_TEMP 't'
152+
#define RELPERSISTENCE_PERMANENT 'p' /* regular table */
153+
#define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */
154+
#define RELPERSISTENCE_TEMP 't' /* temporary table */
154155

155156
#endif /* PG_CLASS_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy