Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)