mirror of
https://github.com/postgres/postgres.git
synced 2025-04-20 00:42:27 +03:00
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.
This commit is contained in:
parent
1c51c7d5ff
commit
bdca82f44d
@ -1284,6 +1284,7 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
|
|||||||
rte.type = T_RangeTblEntry;
|
rte.type = T_RangeTblEntry;
|
||||||
rte.rtekind = RTE_RELATION;
|
rte.rtekind = RTE_RELATION;
|
||||||
rte.relid = relId;
|
rte.relid = relId;
|
||||||
|
rte.relkind = RELKIND_RELATION; /* no need for exactness here */
|
||||||
|
|
||||||
context.rtables = list_make1(list_make1(&rte));
|
context.rtables = list_make1(list_make1(&rte));
|
||||||
|
|
||||||
|
@ -763,6 +763,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
|||||||
rte = makeNode(RangeTblEntry);
|
rte = makeNode(RangeTblEntry);
|
||||||
rte->rtekind = RTE_RELATION;
|
rte->rtekind = RTE_RELATION;
|
||||||
rte->relid = RelationGetRelid(rel);
|
rte->relid = RelationGetRelid(rel);
|
||||||
|
rte->relkind = rel->rd_rel->relkind;
|
||||||
rte->requiredPerms = required_access;
|
rte->requiredPerms = required_access;
|
||||||
|
|
||||||
tupDesc = RelationGetDescr(rel);
|
tupDesc = RelationGetDescr(rel);
|
||||||
|
@ -1927,6 +1927,7 @@ _copyRangeTblEntry(RangeTblEntry *from)
|
|||||||
|
|
||||||
COPY_SCALAR_FIELD(rtekind);
|
COPY_SCALAR_FIELD(rtekind);
|
||||||
COPY_SCALAR_FIELD(relid);
|
COPY_SCALAR_FIELD(relid);
|
||||||
|
COPY_SCALAR_FIELD(relkind);
|
||||||
COPY_NODE_FIELD(subquery);
|
COPY_NODE_FIELD(subquery);
|
||||||
COPY_SCALAR_FIELD(jointype);
|
COPY_SCALAR_FIELD(jointype);
|
||||||
COPY_NODE_FIELD(joinaliasvars);
|
COPY_NODE_FIELD(joinaliasvars);
|
||||||
|
@ -2286,6 +2286,7 @@ _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
|
|||||||
{
|
{
|
||||||
COMPARE_SCALAR_FIELD(rtekind);
|
COMPARE_SCALAR_FIELD(rtekind);
|
||||||
COMPARE_SCALAR_FIELD(relid);
|
COMPARE_SCALAR_FIELD(relid);
|
||||||
|
COMPARE_SCALAR_FIELD(relkind);
|
||||||
COMPARE_NODE_FIELD(subquery);
|
COMPARE_NODE_FIELD(subquery);
|
||||||
COMPARE_SCALAR_FIELD(jointype);
|
COMPARE_SCALAR_FIELD(jointype);
|
||||||
COMPARE_NODE_FIELD(joinaliasvars);
|
COMPARE_NODE_FIELD(joinaliasvars);
|
||||||
|
@ -1671,7 +1671,6 @@ range_table_walker(List *rtable,
|
|||||||
switch (rte->rtekind)
|
switch (rte->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
case RTE_SPECIAL:
|
|
||||||
case RTE_CTE:
|
case RTE_CTE:
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
break;
|
break;
|
||||||
@ -2374,7 +2373,6 @@ range_table_mutator(List *rtable,
|
|||||||
switch (rte->rtekind)
|
switch (rte->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
case RTE_SPECIAL:
|
|
||||||
case RTE_CTE:
|
case RTE_CTE:
|
||||||
/* we don't bother to copy eref, aliases, etc; OK? */
|
/* we don't bother to copy eref, aliases, etc; OK? */
|
||||||
break;
|
break;
|
||||||
|
@ -2275,8 +2275,8 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
|
|||||||
switch (node->rtekind)
|
switch (node->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
case RTE_SPECIAL:
|
|
||||||
WRITE_OID_FIELD(relid);
|
WRITE_OID_FIELD(relid);
|
||||||
|
WRITE_CHAR_FIELD(relkind);
|
||||||
break;
|
break;
|
||||||
case RTE_SUBQUERY:
|
case RTE_SUBQUERY:
|
||||||
WRITE_NODE_FIELD(subquery);
|
WRITE_NODE_FIELD(subquery);
|
||||||
|
@ -265,8 +265,8 @@ print_rt(List *rtable)
|
|||||||
switch (rte->rtekind)
|
switch (rte->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
printf("%d\t%s\t%u",
|
printf("%d\t%s\t%u\t%c",
|
||||||
i, rte->eref->aliasname, rte->relid);
|
i, rte->eref->aliasname, rte->relid, rte->relkind);
|
||||||
break;
|
break;
|
||||||
case RTE_SUBQUERY:
|
case RTE_SUBQUERY:
|
||||||
printf("%d\t%s\t[subquery]",
|
printf("%d\t%s\t[subquery]",
|
||||||
@ -276,10 +276,6 @@ print_rt(List *rtable)
|
|||||||
printf("%d\t%s\t[join]",
|
printf("%d\t%s\t[join]",
|
||||||
i, rte->eref->aliasname);
|
i, rte->eref->aliasname);
|
||||||
break;
|
break;
|
||||||
case RTE_SPECIAL:
|
|
||||||
printf("%d\t%s\t[special]",
|
|
||||||
i, rte->eref->aliasname);
|
|
||||||
break;
|
|
||||||
case RTE_FUNCTION:
|
case RTE_FUNCTION:
|
||||||
printf("%d\t%s\t[rangefunction]",
|
printf("%d\t%s\t[rangefunction]",
|
||||||
i, rte->eref->aliasname);
|
i, rte->eref->aliasname);
|
||||||
|
@ -1171,8 +1171,8 @@ _readRangeTblEntry(void)
|
|||||||
switch (local_node->rtekind)
|
switch (local_node->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
case RTE_SPECIAL:
|
|
||||||
READ_OID_FIELD(relid);
|
READ_OID_FIELD(relid);
|
||||||
|
READ_CHAR_FIELD(relkind);
|
||||||
break;
|
break;
|
||||||
case RTE_SUBQUERY:
|
case RTE_SUBQUERY:
|
||||||
READ_NODE_FIELD(subquery);
|
READ_NODE_FIELD(subquery);
|
||||||
|
@ -176,41 +176,44 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
/* It's an "append relation", process accordingly */
|
/* It's an "append relation", process accordingly */
|
||||||
set_append_rel_pathlist(root, rel, rti, rte);
|
set_append_rel_pathlist(root, rel, rti, rte);
|
||||||
}
|
}
|
||||||
else if (rel->rtekind == RTE_SUBQUERY)
|
|
||||||
{
|
|
||||||
/* Subquery --- generate a separate plan for it */
|
|
||||||
set_subquery_pathlist(root, rel, rti, rte);
|
|
||||||
}
|
|
||||||
else if (rel->rtekind == RTE_FUNCTION)
|
|
||||||
{
|
|
||||||
/* RangeFunction --- generate a suitable path for it */
|
|
||||||
set_function_pathlist(root, rel, rte);
|
|
||||||
}
|
|
||||||
else if (rel->rtekind == RTE_VALUES)
|
|
||||||
{
|
|
||||||
/* Values list --- generate a suitable path for it */
|
|
||||||
set_values_pathlist(root, rel, rte);
|
|
||||||
}
|
|
||||||
else if (rel->rtekind == RTE_CTE)
|
|
||||||
{
|
|
||||||
/* CTE reference --- generate a suitable path for it */
|
|
||||||
if (rte->self_reference)
|
|
||||||
set_worktable_pathlist(root, rel, rte);
|
|
||||||
else
|
|
||||||
set_cte_pathlist(root, rel, rte);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assert(rel->rtekind == RTE_RELATION);
|
switch (rel->rtekind)
|
||||||
if (get_rel_relkind(rte->relid) == RELKIND_FOREIGN_TABLE)
|
|
||||||
{
|
{
|
||||||
/* Foreign table */
|
case RTE_RELATION:
|
||||||
set_foreign_pathlist(root, rel, rte);
|
if (rte->relkind == RELKIND_FOREIGN_TABLE)
|
||||||
}
|
{
|
||||||
else
|
/* Foreign table */
|
||||||
{
|
set_foreign_pathlist(root, rel, rte);
|
||||||
/* Plain relation */
|
}
|
||||||
set_plain_rel_pathlist(root, rel, rte);
|
else
|
||||||
|
{
|
||||||
|
/* Plain relation */
|
||||||
|
set_plain_rel_pathlist(root, rel, rte);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RTE_SUBQUERY:
|
||||||
|
/* Subquery --- generate a separate plan for it */
|
||||||
|
set_subquery_pathlist(root, rel, rti, rte);
|
||||||
|
break;
|
||||||
|
case RTE_FUNCTION:
|
||||||
|
/* RangeFunction --- generate a suitable path for it */
|
||||||
|
set_function_pathlist(root, rel, rte);
|
||||||
|
break;
|
||||||
|
case RTE_VALUES:
|
||||||
|
/* Values list --- generate a suitable path for it */
|
||||||
|
set_values_pathlist(root, rel, rte);
|
||||||
|
break;
|
||||||
|
case RTE_CTE:
|
||||||
|
/* CTE reference --- generate a suitable path for it */
|
||||||
|
if (rte->self_reference)
|
||||||
|
set_worktable_pathlist(root, rel, rte);
|
||||||
|
else
|
||||||
|
set_cte_pathlist(root, rel, rte);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unexpected rtekind: %d", (int) rel->rtekind);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1915,7 +1915,7 @@ preprocess_rowmarks(PlannerInfo *root)
|
|||||||
newrc->rowmarkId = ++(root->glob->lastRowMarkId);
|
newrc->rowmarkId = ++(root->glob->lastRowMarkId);
|
||||||
/* real tables support REFERENCE, anything else needs COPY */
|
/* real tables support REFERENCE, anything else needs COPY */
|
||||||
if (rte->rtekind == RTE_RELATION &&
|
if (rte->rtekind == RTE_RELATION &&
|
||||||
get_rel_relkind(rte->relid) != RELKIND_FOREIGN_TABLE)
|
rte->relkind != RELKIND_FOREIGN_TABLE)
|
||||||
newrc->markType = ROW_MARK_REFERENCE;
|
newrc->markType = ROW_MARK_REFERENCE;
|
||||||
else
|
else
|
||||||
newrc->markType = ROW_MARK_COPY;
|
newrc->markType = ROW_MARK_COPY;
|
||||||
@ -3078,6 +3078,7 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
|
|||||||
rte = makeNode(RangeTblEntry);
|
rte = makeNode(RangeTblEntry);
|
||||||
rte->rtekind = RTE_RELATION;
|
rte->rtekind = RTE_RELATION;
|
||||||
rte->relid = tableOid;
|
rte->relid = tableOid;
|
||||||
|
rte->relkind = RELKIND_RELATION;
|
||||||
rte->inh = false;
|
rte->inh = false;
|
||||||
rte->inFromCl = true;
|
rte->inFromCl = true;
|
||||||
query->rtable = list_make1(rte);
|
query->rtable = list_make1(rte);
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
#include "parser/parse_target.h"
|
#include "parser/parse_target.h"
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
#include "rewrite/rewriteManip.h"
|
#include "rewrite/rewriteManip.h"
|
||||||
#include "utils/lsyscache.h"
|
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
|
||||||
|
|
||||||
@ -2178,13 +2177,11 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
|
|||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
/* ignore foreign tables */
|
/* ignore foreign tables */
|
||||||
if (get_rel_relkind(rte->relid) != RELKIND_FOREIGN_TABLE)
|
if (rte->relkind == RELKIND_FOREIGN_TABLE)
|
||||||
{
|
break;
|
||||||
applyLockingClause(qry, i,
|
applyLockingClause(qry, i,
|
||||||
lc->forUpdate, lc->noWait,
|
lc->forUpdate, lc->noWait, pushedDown);
|
||||||
pushedDown);
|
rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
|
||||||
rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case RTE_SUBQUERY:
|
case RTE_SUBQUERY:
|
||||||
applyLockingClause(qry, i,
|
applyLockingClause(qry, i,
|
||||||
@ -2231,11 +2228,11 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
|
|||||||
switch (rte->rtekind)
|
switch (rte->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
if (get_rel_relkind(rte->relid) == RELKIND_FOREIGN_TABLE)
|
if (rte->relkind == RELKIND_FOREIGN_TABLE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("SELECT FOR UPDATE/SHARE cannot be used with foreign table \"%s\"",
|
errmsg("SELECT FOR UPDATE/SHARE cannot be used with foreign table \"%s\"",
|
||||||
get_rel_name(rte->relid)),
|
rte->eref->aliasname),
|
||||||
parser_errposition(pstate, thisrel->location)));
|
parser_errposition(pstate, thisrel->location)));
|
||||||
applyLockingClause(qry, i,
|
applyLockingClause(qry, i,
|
||||||
lc->forUpdate, lc->noWait,
|
lc->forUpdate, lc->noWait,
|
||||||
@ -2256,12 +2253,6 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc,
|
|||||||
errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a join"),
|
errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a join"),
|
||||||
parser_errposition(pstate, thisrel->location)));
|
parser_errposition(pstate, thisrel->location)));
|
||||||
break;
|
break;
|
||||||
case RTE_SPECIAL:
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
||||||
errmsg("SELECT FOR UPDATE/SHARE cannot be applied to NEW or OLD"),
|
|
||||||
parser_errposition(pstate, thisrel->location)));
|
|
||||||
break;
|
|
||||||
case RTE_FUNCTION:
|
case RTE_FUNCTION:
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
@ -894,6 +894,7 @@ addRangeTableEntry(ParseState *pstate,
|
|||||||
lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
|
lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
|
||||||
rel = parserOpenTable(pstate, relation, lockmode);
|
rel = parserOpenTable(pstate, relation, lockmode);
|
||||||
rte->relid = RelationGetRelid(rel);
|
rte->relid = RelationGetRelid(rel);
|
||||||
|
rte->relkind = rel->rd_rel->relkind;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build the list of effective column names using user-supplied aliases
|
* Build the list of effective column names using user-supplied aliases
|
||||||
@ -956,6 +957,7 @@ addRangeTableEntryForRelation(ParseState *pstate,
|
|||||||
rte->rtekind = RTE_RELATION;
|
rte->rtekind = RTE_RELATION;
|
||||||
rte->alias = alias;
|
rte->alias = alias;
|
||||||
rte->relid = RelationGetRelid(rel);
|
rte->relid = RelationGetRelid(rel);
|
||||||
|
rte->relkind = rel->rd_rel->relkind;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build the list of effective column names using user-supplied aliases
|
* Build the list of effective column names using user-supplied aliases
|
||||||
|
@ -305,7 +305,6 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
|
|||||||
markTargetListOrigin(pstate, tle, aliasvar, netlevelsup);
|
markTargetListOrigin(pstate, tle, aliasvar, netlevelsup);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RTE_SPECIAL:
|
|
||||||
case RTE_FUNCTION:
|
case RTE_FUNCTION:
|
||||||
case RTE_VALUES:
|
case RTE_VALUES:
|
||||||
/* not a simple relation, leave it unmarked */
|
/* not a simple relation, leave it unmarked */
|
||||||
@ -1357,7 +1356,6 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
|
|||||||
switch (rte->rtekind)
|
switch (rte->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
case RTE_SPECIAL:
|
|
||||||
case RTE_VALUES:
|
case RTE_VALUES:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -144,6 +144,13 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
|
|||||||
lockmode = AccessShareLock;
|
lockmode = AccessShareLock;
|
||||||
|
|
||||||
rel = heap_open(rte->relid, lockmode);
|
rel = heap_open(rte->relid, lockmode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* While we have the relation open, update the RTE's relkind,
|
||||||
|
* just in case it changed since this rule was made.
|
||||||
|
*/
|
||||||
|
rte->relkind = rel->rd_rel->relkind;
|
||||||
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1393,7 +1400,7 @@ markQueryForLocking(Query *qry, Node *jtnode,
|
|||||||
if (rte->rtekind == RTE_RELATION)
|
if (rte->rtekind == RTE_RELATION)
|
||||||
{
|
{
|
||||||
/* ignore foreign tables */
|
/* ignore foreign tables */
|
||||||
if (get_rel_relkind(rte->relid) != RELKIND_FOREIGN_TABLE)
|
if (rte->relkind != RELKIND_FOREIGN_TABLE)
|
||||||
{
|
{
|
||||||
applyLockingClause(qry, rti, forUpdate, noWait, pushedDown);
|
applyLockingClause(qry, rti, forUpdate, noWait, pushedDown);
|
||||||
rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
|
rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
|
||||||
|
@ -2651,11 +2651,13 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
|
|||||||
pkrte = makeNode(RangeTblEntry);
|
pkrte = makeNode(RangeTblEntry);
|
||||||
pkrte->rtekind = RTE_RELATION;
|
pkrte->rtekind = RTE_RELATION;
|
||||||
pkrte->relid = RelationGetRelid(pk_rel);
|
pkrte->relid = RelationGetRelid(pk_rel);
|
||||||
|
pkrte->relkind = pk_rel->rd_rel->relkind;
|
||||||
pkrte->requiredPerms = ACL_SELECT;
|
pkrte->requiredPerms = ACL_SELECT;
|
||||||
|
|
||||||
fkrte = makeNode(RangeTblEntry);
|
fkrte = makeNode(RangeTblEntry);
|
||||||
fkrte->rtekind = RTE_RELATION;
|
fkrte->rtekind = RTE_RELATION;
|
||||||
fkrte->relid = RelationGetRelid(fk_rel);
|
fkrte->relid = RelationGetRelid(fk_rel);
|
||||||
|
fkrte->relkind = fk_rel->rd_rel->relkind;
|
||||||
fkrte->requiredPerms = ACL_SELECT;
|
fkrte->requiredPerms = ACL_SELECT;
|
||||||
|
|
||||||
for (i = 0; i < riinfo.nkeys; i++)
|
for (i = 0; i < riinfo.nkeys; i++)
|
||||||
|
@ -628,6 +628,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
|
|||||||
if (!isnull)
|
if (!isnull)
|
||||||
{
|
{
|
||||||
Node *qual;
|
Node *qual;
|
||||||
|
char relkind;
|
||||||
deparse_context context;
|
deparse_context context;
|
||||||
deparse_namespace dpns;
|
deparse_namespace dpns;
|
||||||
RangeTblEntry *oldrte;
|
RangeTblEntry *oldrte;
|
||||||
@ -637,10 +638,13 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
|
|||||||
|
|
||||||
qual = stringToNode(TextDatumGetCString(value));
|
qual = stringToNode(TextDatumGetCString(value));
|
||||||
|
|
||||||
|
relkind = get_rel_relkind(trigrec->tgrelid);
|
||||||
|
|
||||||
/* Build minimal OLD and NEW RTEs for the rel */
|
/* Build minimal OLD and NEW RTEs for the rel */
|
||||||
oldrte = makeNode(RangeTblEntry);
|
oldrte = makeNode(RangeTblEntry);
|
||||||
oldrte->rtekind = RTE_RELATION;
|
oldrte->rtekind = RTE_RELATION;
|
||||||
oldrte->relid = trigrec->tgrelid;
|
oldrte->relid = trigrec->tgrelid;
|
||||||
|
oldrte->relkind = relkind;
|
||||||
oldrte->eref = makeAlias("old", NIL);
|
oldrte->eref = makeAlias("old", NIL);
|
||||||
oldrte->inh = false;
|
oldrte->inh = false;
|
||||||
oldrte->inFromCl = true;
|
oldrte->inFromCl = true;
|
||||||
@ -648,6 +652,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
|
|||||||
newrte = makeNode(RangeTblEntry);
|
newrte = makeNode(RangeTblEntry);
|
||||||
newrte->rtekind = RTE_RELATION;
|
newrte->rtekind = RTE_RELATION;
|
||||||
newrte->relid = trigrec->tgrelid;
|
newrte->relid = trigrec->tgrelid;
|
||||||
|
newrte->relkind = relkind;
|
||||||
newrte->eref = makeAlias("new", NIL);
|
newrte->eref = makeAlias("new", NIL);
|
||||||
newrte->inh = false;
|
newrte->inh = false;
|
||||||
newrte->inFromCl = true;
|
newrte->inFromCl = true;
|
||||||
@ -2125,6 +2130,7 @@ deparse_context_for(const char *aliasname, Oid relid)
|
|||||||
rte = makeNode(RangeTblEntry);
|
rte = makeNode(RangeTblEntry);
|
||||||
rte->rtekind = RTE_RELATION;
|
rte->rtekind = RTE_RELATION;
|
||||||
rte->relid = relid;
|
rte->relid = relid;
|
||||||
|
rte->relkind = RELKIND_RELATION; /* no need for exactness here */
|
||||||
rte->eref = makeAlias(aliasname, NIL);
|
rte->eref = makeAlias(aliasname, NIL);
|
||||||
rte->inh = false;
|
rte->inh = false;
|
||||||
rte->inFromCl = true;
|
rte->inFromCl = true;
|
||||||
@ -4004,7 +4010,6 @@ get_name_for_var_field(Var *var, int fieldno,
|
|||||||
switch (rte->rtekind)
|
switch (rte->rtekind)
|
||||||
{
|
{
|
||||||
case RTE_RELATION:
|
case RTE_RELATION:
|
||||||
case RTE_SPECIAL:
|
|
||||||
case RTE_VALUES:
|
case RTE_VALUES:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 201102221
|
#define CATALOG_VERSION_NO 201102222
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,7 +49,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO
|
|||||||
Oid reltoastidxid; /* if toast table, OID of chunk_id index */
|
Oid reltoastidxid; /* if toast table, OID of chunk_id index */
|
||||||
bool relhasindex; /* T if has (or has had) any indexes */
|
bool relhasindex; /* T if has (or has had) any indexes */
|
||||||
bool relisshared; /* T if shared across databases */
|
bool relisshared; /* T if shared across databases */
|
||||||
char relpersistence; /* see RELPERSISTENCE_xxx constants */
|
char relpersistence; /* see RELPERSISTENCE_xxx constants below */
|
||||||
char relkind; /* see RELKIND_xxx constants below */
|
char relkind; /* see RELKIND_xxx constants below */
|
||||||
int2 relnatts; /* number of user attributes */
|
int2 relnatts; /* number of user attributes */
|
||||||
|
|
||||||
@ -139,17 +139,18 @@ DESCR("");
|
|||||||
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_ ));
|
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_ ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
|
|
||||||
|
|
||||||
|
#define RELKIND_RELATION 'r' /* ordinary table */
|
||||||
#define RELKIND_INDEX 'i' /* secondary index */
|
#define RELKIND_INDEX 'i' /* secondary index */
|
||||||
#define RELKIND_RELATION 'r' /* ordinary cataloged heap */
|
#define RELKIND_SEQUENCE 'S' /* sequence object */
|
||||||
#define RELKIND_SEQUENCE 'S' /* SEQUENCE relation */
|
#define RELKIND_TOASTVALUE 't' /* for out-of-line values */
|
||||||
#define RELKIND_UNCATALOGED 'u' /* temporary heap */
|
|
||||||
#define RELKIND_TOASTVALUE 't' /* moved off huge values */
|
|
||||||
#define RELKIND_VIEW 'v' /* view */
|
#define RELKIND_VIEW 'v' /* view */
|
||||||
#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */
|
#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */
|
||||||
#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */
|
#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */
|
||||||
|
#define RELKIND_UNCATALOGED 'u' /* not yet cataloged */
|
||||||
|
|
||||||
#define RELPERSISTENCE_PERMANENT 'p'
|
#define RELPERSISTENCE_PERMANENT 'p' /* regular table */
|
||||||
#define RELPERSISTENCE_UNLOGGED 'u'
|
#define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */
|
||||||
#define RELPERSISTENCE_TEMP 't'
|
#define RELPERSISTENCE_TEMP 't' /* temporary table */
|
||||||
|
|
||||||
#endif /* PG_CLASS_H */
|
#endif /* PG_CLASS_H */
|
||||||
|
@ -597,6 +597,9 @@ typedef struct XmlSerialize
|
|||||||
* like outer joins and join-output-column aliasing.) Other special
|
* like outer joins and join-output-column aliasing.) Other special
|
||||||
* RTE types also exist, as indicated by RTEKind.
|
* RTE types also exist, as indicated by RTEKind.
|
||||||
*
|
*
|
||||||
|
* Note that we consider RTE_RELATION to cover anything that has a pg_class
|
||||||
|
* entry. relkind distinguishes the sub-cases.
|
||||||
|
*
|
||||||
* alias is an Alias node representing the AS alias-clause attached to the
|
* alias is an Alias node representing the AS alias-clause attached to the
|
||||||
* FROM expression, or NULL if no clause.
|
* FROM expression, or NULL if no clause.
|
||||||
*
|
*
|
||||||
@ -643,7 +646,7 @@ typedef struct XmlSerialize
|
|||||||
* indicates no permissions checking). If checkAsUser is not zero,
|
* indicates no permissions checking). If checkAsUser is not zero,
|
||||||
* then do the permissions checks using the access rights of that user,
|
* then do the permissions checks using the access rights of that user,
|
||||||
* not the current effective user ID. (This allows rules to act as
|
* not the current effective user ID. (This allows rules to act as
|
||||||
* setuid gateways.)
|
* setuid gateways.) Permissions checks only apply to RELATION RTEs.
|
||||||
*
|
*
|
||||||
* For SELECT/INSERT/UPDATE permissions, if the user doesn't have
|
* For SELECT/INSERT/UPDATE permissions, if the user doesn't have
|
||||||
* table-wide permissions then it is sufficient to have the permissions
|
* table-wide permissions then it is sufficient to have the permissions
|
||||||
@ -660,7 +663,6 @@ typedef enum RTEKind
|
|||||||
RTE_RELATION, /* ordinary relation reference */
|
RTE_RELATION, /* ordinary relation reference */
|
||||||
RTE_SUBQUERY, /* subquery in FROM */
|
RTE_SUBQUERY, /* subquery in FROM */
|
||||||
RTE_JOIN, /* join */
|
RTE_JOIN, /* join */
|
||||||
RTE_SPECIAL, /* special rule relation (NEW or OLD) */
|
|
||||||
RTE_FUNCTION, /* function in FROM */
|
RTE_FUNCTION, /* function in FROM */
|
||||||
RTE_VALUES, /* VALUES (<exprlist>), (<exprlist>), ... */
|
RTE_VALUES, /* VALUES (<exprlist>), (<exprlist>), ... */
|
||||||
RTE_CTE /* common table expr (WITH list element) */
|
RTE_CTE /* common table expr (WITH list element) */
|
||||||
@ -682,6 +684,7 @@ typedef struct RangeTblEntry
|
|||||||
* Fields valid for a plain relation RTE (else zero):
|
* Fields valid for a plain relation RTE (else zero):
|
||||||
*/
|
*/
|
||||||
Oid relid; /* OID of the relation */
|
Oid relid; /* OID of the relation */
|
||||||
|
char relkind; /* relation kind (see pg_class.relkind) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fields valid for a subquery RTE (else NULL):
|
* Fields valid for a subquery RTE (else NULL):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user