Commit 5815696b authored by Tom Lane's avatar Tom Lane

Make parser rely more heavily on the ParseNamespaceItem data structure.

When I added the ParseNamespaceItem data structure (in commit 5ebaaa49),
it wasn't very tightly integrated into the parser's APIs.  In the wake of
adding p_rtindex to that struct (commit b541e9ac), there is a good reason
to make more use of it: by passing around ParseNamespaceItem pointers
instead of bare RTE pointers, we can get rid of various messy methods for
passing back or deducing the rangetable index of an RTE during parsing.
Hence, refactor the addRangeTableEntryXXX functions to build and return
a ParseNamespaceItem struct, not just the RTE proper; and replace
addRTEtoQuery with addNSItemToQuery, which is passed a ParseNamespaceItem
rather than building one internally.

Also, add per-column data (a ParseNamespaceColumn array) to each
ParseNamespaceItem.  These arrays are built during addRangeTableEntryXXX,
where we have column type data at hand so that it's nearly free to fill
the data structure.  Later, when we need to build Vars referencing RTEs,
we can use the ParseNamespaceColumn info to avoid the rather expensive
operations done in get_rte_attribute_type() or expandRTE().
get_rte_attribute_type() is indeed dead code now, so I've removed it.
This makes for a useful improvement in parse analysis speed, around 20%
in one moderately-complex test query.

The ParseNamespaceColumn structs also include Var identity information
(varno/varattno).  That info isn't actually being used in this patch,
except that p_varno == 0 is a handy test for a dropped column.
A follow-on patch will make more use of it.

Discussion: https://postgr.es/m/2461.1577764221@sss.pgh.pa.us
parent 198c7153
...@@ -2531,7 +2531,7 @@ AddRelationNewConstraints(Relation rel, ...@@ -2531,7 +2531,7 @@ AddRelationNewConstraints(Relation rel,
TupleConstr *oldconstr; TupleConstr *oldconstr;
int numoldchecks; int numoldchecks;
ParseState *pstate; ParseState *pstate;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
int numchecks; int numchecks;
List *checknames; List *checknames;
ListCell *cell; ListCell *cell;
...@@ -2554,13 +2554,13 @@ AddRelationNewConstraints(Relation rel, ...@@ -2554,13 +2554,13 @@ AddRelationNewConstraints(Relation rel,
*/ */
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString; pstate->p_sourcetext = queryString;
rte = addRangeTableEntryForRelation(pstate, nsitem = addRangeTableEntryForRelation(pstate,
rel, rel,
AccessShareLock, AccessShareLock,
NULL, NULL,
false, false,
true); true);
addRTEtoQuery(pstate, rte, true, true, true); addNSItemToQuery(pstate, nsitem, true, true, true);
/* /*
* Process column default expressions. * Process column default expressions.
......
...@@ -882,6 +882,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, ...@@ -882,6 +882,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
if (stmt->relation) if (stmt->relation)
{ {
LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock; LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock;
ParseNamespaceItem *nsitem;
RangeTblEntry *rte; RangeTblEntry *rte;
TupleDesc tupDesc; TupleDesc tupDesc;
List *attnums; List *attnums;
...@@ -894,14 +895,15 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, ...@@ -894,14 +895,15 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
relid = RelationGetRelid(rel); relid = RelationGetRelid(rel);
rte = addRangeTableEntryForRelation(pstate, rel, lockmode, nsitem = addRangeTableEntryForRelation(pstate, rel, lockmode,
NULL, false, false); NULL, false, false);
rte = nsitem->p_rte;
rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT); rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
if (stmt->whereClause) if (stmt->whereClause)
{ {
/* add rte to column namespace */ /* add nsitem to query namespace */
addRTEtoQuery(pstate, rte, false, true, true); addNSItemToQuery(pstate, nsitem, false, true, true);
/* Transform the raw expression tree */ /* Transform the raw expression tree */
whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE); whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE);
......
...@@ -568,9 +568,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) ...@@ -568,9 +568,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
qual_expr = stringToNode(qual_value); qual_expr = stringToNode(qual_value);
/* Add this rel to the parsestate's rangetable, for dependencies */ /* Add this rel to the parsestate's rangetable, for dependencies */
addRangeTableEntryForRelation(qual_pstate, rel, (void) addRangeTableEntryForRelation(qual_pstate, rel,
AccessShareLock, AccessShareLock,
NULL, false, false); NULL, false, false);
qual_parse_rtable = qual_pstate->p_rtable; qual_parse_rtable = qual_pstate->p_rtable;
free_parsestate(qual_pstate); free_parsestate(qual_pstate);
...@@ -592,9 +592,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) ...@@ -592,9 +592,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
with_check_qual = stringToNode(with_check_value); with_check_qual = stringToNode(with_check_value);
/* Add this rel to the parsestate's rangetable, for dependencies */ /* Add this rel to the parsestate's rangetable, for dependencies */
addRangeTableEntryForRelation(with_check_pstate, rel, (void) addRangeTableEntryForRelation(with_check_pstate, rel,
AccessShareLock, AccessShareLock,
NULL, false, false); NULL, false, false);
with_check_parse_rtable = with_check_pstate->p_rtable; with_check_parse_rtable = with_check_pstate->p_rtable;
free_parsestate(with_check_pstate); free_parsestate(with_check_pstate);
...@@ -699,7 +699,7 @@ CreatePolicy(CreatePolicyStmt *stmt) ...@@ -699,7 +699,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
ArrayType *role_ids; ArrayType *role_ids;
ParseState *qual_pstate; ParseState *qual_pstate;
ParseState *with_check_pstate; ParseState *with_check_pstate;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
Node *qual; Node *qual;
Node *with_check_qual; Node *with_check_qual;
ScanKeyData skey[2]; ScanKeyData skey[2];
...@@ -755,16 +755,16 @@ CreatePolicy(CreatePolicyStmt *stmt) ...@@ -755,16 +755,16 @@ CreatePolicy(CreatePolicyStmt *stmt)
target_table = relation_open(table_id, NoLock); target_table = relation_open(table_id, NoLock);
/* Add for the regular security quals */ /* Add for the regular security quals */
rte = addRangeTableEntryForRelation(qual_pstate, target_table, nsitem = addRangeTableEntryForRelation(qual_pstate, target_table,
AccessShareLock, AccessShareLock,
NULL, false, false); NULL, false, false);
addRTEtoQuery(qual_pstate, rte, false, true, true); addNSItemToQuery(qual_pstate, nsitem, false, true, true);
/* Add for the with-check quals */ /* Add for the with-check quals */
rte = addRangeTableEntryForRelation(with_check_pstate, target_table, nsitem = addRangeTableEntryForRelation(with_check_pstate, target_table,
AccessShareLock, AccessShareLock,
NULL, false, false); NULL, false, false);
addRTEtoQuery(with_check_pstate, rte, false, true, true); addNSItemToQuery(with_check_pstate, nsitem, false, true, true);
qual = transformWhereClause(qual_pstate, qual = transformWhereClause(qual_pstate,
copyObject(stmt->qual), copyObject(stmt->qual),
...@@ -933,14 +933,14 @@ AlterPolicy(AlterPolicyStmt *stmt) ...@@ -933,14 +933,14 @@ AlterPolicy(AlterPolicyStmt *stmt)
/* Parse the using policy clause */ /* Parse the using policy clause */
if (stmt->qual) if (stmt->qual)
{ {
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
ParseState *qual_pstate = make_parsestate(NULL); ParseState *qual_pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(qual_pstate, target_table, nsitem = addRangeTableEntryForRelation(qual_pstate, target_table,
AccessShareLock, AccessShareLock,
NULL, false, false); NULL, false, false);
addRTEtoQuery(qual_pstate, rte, false, true, true); addNSItemToQuery(qual_pstate, nsitem, false, true, true);
qual = transformWhereClause(qual_pstate, copyObject(stmt->qual), qual = transformWhereClause(qual_pstate, copyObject(stmt->qual),
EXPR_KIND_POLICY, EXPR_KIND_POLICY,
...@@ -956,14 +956,14 @@ AlterPolicy(AlterPolicyStmt *stmt) ...@@ -956,14 +956,14 @@ AlterPolicy(AlterPolicyStmt *stmt)
/* Parse the with-check policy clause */ /* Parse the with-check policy clause */
if (stmt->with_check) if (stmt->with_check)
{ {
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
ParseState *with_check_pstate = make_parsestate(NULL); ParseState *with_check_pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(with_check_pstate, target_table, nsitem = addRangeTableEntryForRelation(with_check_pstate, target_table,
AccessShareLock, AccessShareLock,
NULL, false, false); NULL, false, false);
addRTEtoQuery(with_check_pstate, rte, false, true, true); addNSItemToQuery(with_check_pstate, nsitem, false, true, true);
with_check_qual = transformWhereClause(with_check_pstate, with_check_qual = transformWhereClause(with_check_pstate,
copyObject(stmt->with_check), copyObject(stmt->with_check),
...@@ -1107,9 +1107,9 @@ AlterPolicy(AlterPolicyStmt *stmt) ...@@ -1107,9 +1107,9 @@ AlterPolicy(AlterPolicyStmt *stmt)
qual = stringToNode(qual_value); qual = stringToNode(qual_value);
/* Add this rel to the parsestate's rangetable, for dependencies */ /* Add this rel to the parsestate's rangetable, for dependencies */
addRangeTableEntryForRelation(qual_pstate, target_table, (void) addRangeTableEntryForRelation(qual_pstate, target_table,
AccessShareLock, AccessShareLock,
NULL, false, false); NULL, false, false);
qual_parse_rtable = qual_pstate->p_rtable; qual_parse_rtable = qual_pstate->p_rtable;
free_parsestate(qual_pstate); free_parsestate(qual_pstate);
...@@ -1149,9 +1149,10 @@ AlterPolicy(AlterPolicyStmt *stmt) ...@@ -1149,9 +1149,10 @@ AlterPolicy(AlterPolicyStmt *stmt)
with_check_qual = stringToNode(with_check_value); with_check_qual = stringToNode(with_check_value);
/* Add this rel to the parsestate's rangetable, for dependencies */ /* Add this rel to the parsestate's rangetable, for dependencies */
addRangeTableEntryForRelation(with_check_pstate, target_table, (void) addRangeTableEntryForRelation(with_check_pstate,
AccessShareLock, target_table,
NULL, false, false); AccessShareLock,
NULL, false, false);
with_check_parse_rtable = with_check_pstate->p_rtable; with_check_parse_rtable = with_check_pstate->p_rtable;
free_parsestate(with_check_pstate); free_parsestate(with_check_pstate);
......
...@@ -918,7 +918,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ...@@ -918,7 +918,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
defaultPartOid; defaultPartOid;
Relation parent, Relation parent,
defaultRel = NULL; defaultRel = NULL;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
/* Already have strong enough lock on the parent */ /* Already have strong enough lock on the parent */
parent = table_open(parentId, NoLock); parent = table_open(parentId, NoLock);
...@@ -962,13 +962,14 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ...@@ -962,13 +962,14 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
pstate->p_sourcetext = queryString; pstate->p_sourcetext = queryString;
/* /*
* Add an RTE containing this relation, so that transformExpr called * Add an nsitem containing this relation, so that transformExpr
* on partition bound expressions is able to report errors using a * called on partition bound expressions is able to report errors
* proper context. * using a proper context.
*/ */
rte = addRangeTableEntryForRelation(pstate, rel, AccessShareLock, nsitem = addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
NULL, false, false); NULL, false, false);
addRTEtoQuery(pstate, rte, false, true, true); addNSItemToQuery(pstate, nsitem, false, true, true);
bound = transformPartitionBound(pstate, parent, stmt->partbound); bound = transformPartitionBound(pstate, parent, stmt->partbound);
/* /*
...@@ -14970,7 +14971,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) ...@@ -14970,7 +14971,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
{ {
PartitionSpec *newspec; PartitionSpec *newspec;
ParseState *pstate; ParseState *pstate;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
ListCell *l; ListCell *l;
newspec = makeNode(PartitionSpec); newspec = makeNode(PartitionSpec);
...@@ -15004,9 +15005,9 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) ...@@ -15004,9 +15005,9 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
* rangetable entry. We need a ParseState for transformExpr. * rangetable entry. We need a ParseState for transformExpr.
*/ */
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(pstate, rel, AccessShareLock, nsitem = addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
NULL, false, true); NULL, false, true);
addRTEtoQuery(pstate, rte, true, true, true); addNSItemToQuery(pstate, nsitem, true, true, true);
/* take care of any partition expressions */ /* take care of any partition expressions */
foreach(l, partspec->partParams) foreach(l, partspec->partParams)
......
...@@ -565,7 +565,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, ...@@ -565,7 +565,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
if (!whenClause && stmt->whenClause) if (!whenClause && stmt->whenClause)
{ {
ParseState *pstate; ParseState *pstate;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
List *varList; List *varList;
ListCell *lc; ListCell *lc;
...@@ -574,20 +574,20 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, ...@@ -574,20 +574,20 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
pstate->p_sourcetext = queryString; pstate->p_sourcetext = queryString;
/* /*
* Set up RTEs for OLD and NEW references. * Set up nsitems for OLD and NEW references.
* *
* 'OLD' must always have varno equal to 1 and 'NEW' equal to 2. * 'OLD' must always have varno equal to 1 and 'NEW' equal to 2.
*/ */
rte = addRangeTableEntryForRelation(pstate, rel, nsitem = addRangeTableEntryForRelation(pstate, rel,
AccessShareLock, AccessShareLock,
makeAlias("old", NIL), makeAlias("old", NIL),
false, false); false, false);
addRTEtoQuery(pstate, rte, false, true, true); addNSItemToQuery(pstate, nsitem, false, true, true);
rte = addRangeTableEntryForRelation(pstate, rel, nsitem = addRangeTableEntryForRelation(pstate, rel,
AccessShareLock, AccessShareLock,
makeAlias("new", NIL), makeAlias("new", NIL),
false, false); false, false);
addRTEtoQuery(pstate, rte, false, true, true); addNSItemToQuery(pstate, nsitem, false, true, true);
/* Transform expression. Copy to be sure we don't modify original */ /* Transform expression. Copy to be sure we don't modify original */
whenClause = transformWhereClause(pstate, whenClause = transformWhereClause(pstate,
......
...@@ -341,6 +341,7 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) ...@@ -341,6 +341,7 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
{ {
Relation viewRel; Relation viewRel;
List *new_rt; List *new_rt;
ParseNamespaceItem *nsitem;
RangeTblEntry *rt_entry1, RangeTblEntry *rt_entry1,
*rt_entry2; *rt_entry2;
ParseState *pstate; ParseState *pstate;
...@@ -365,14 +366,17 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) ...@@ -365,14 +366,17 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
* Create the 2 new range table entries and form the new range table... * Create the 2 new range table entries and form the new range table...
* OLD first, then NEW.... * OLD first, then NEW....
*/ */
rt_entry1 = addRangeTableEntryForRelation(pstate, viewRel, nsitem = addRangeTableEntryForRelation(pstate, viewRel,
AccessShareLock, AccessShareLock,
makeAlias("old", NIL), makeAlias("old", NIL),
false, false); false, false);
rt_entry2 = addRangeTableEntryForRelation(pstate, viewRel, rt_entry1 = nsitem->p_rte;
AccessShareLock, nsitem = addRangeTableEntryForRelation(pstate, viewRel,
makeAlias("new", NIL), AccessShareLock,
false, false); makeAlias("new", NIL),
false, false);
rt_entry2 = nsitem->p_rte;
/* Must override addRangeTableEntry's default access-check flags */ /* Must override addRangeTableEntry's default access-check flags */
rt_entry1->requiredPerms = 0; rt_entry1->requiredPerms = 0;
rt_entry2->requiredPerms = 0; rt_entry2->requiredPerms = 0;
......
...@@ -1217,6 +1217,7 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, ...@@ -1217,6 +1217,7 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
Query *subselect = (Query *) sublink->subselect; Query *subselect = (Query *) sublink->subselect;
Relids upper_varnos; Relids upper_varnos;
int rtindex; int rtindex;
ParseNamespaceItem *nsitem;
RangeTblEntry *rte; RangeTblEntry *rte;
RangeTblRef *rtr; RangeTblRef *rtr;
List *subquery_vars; List *subquery_vars;
...@@ -1264,11 +1265,12 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, ...@@ -1264,11 +1265,12 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
* below). Therefore this is a lot easier than what pull_up_subqueries has * below). Therefore this is a lot easier than what pull_up_subqueries has
* to go through. * to go through.
*/ */
rte = addRangeTableEntryForSubquery(pstate, nsitem = addRangeTableEntryForSubquery(pstate,
subselect, subselect,
makeAlias("ANY_subquery", NIL), makeAlias("ANY_subquery", NIL),
false, false,
false); false);
rte = nsitem->p_rte;
parse->rtable = lappend(parse->rtable, rte); parse->rtable = lappend(parse->rtable, rte);
rtindex = list_length(parse->rtable); rtindex = list_length(parse->rtable);
......
This diff is collapsed.
This diff is collapsed.
...@@ -1010,11 +1010,10 @@ coerce_record_to_complex(ParseState *pstate, Node *node, ...@@ -1010,11 +1010,10 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
int rtindex = ((Var *) node)->varno; int rtindex = ((Var *) node)->varno;
int sublevels_up = ((Var *) node)->varlevelsup; int sublevels_up = ((Var *) node)->varlevelsup;
int vlocation = ((Var *) node)->location; int vlocation = ((Var *) node)->location;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
rte = GetRTEByRangeTablePosn(pstate, rtindex, sublevels_up); nsitem = GetNSItemByRangeTablePosn(pstate, rtindex, sublevels_up);
expandRTE(rte, rtindex, sublevels_up, vlocation, false, args = expandNSItemVars(nsitem, sublevels_up, vlocation, NULL);
NULL, &args);
} }
else else
ereport(ERROR, ereport(ERROR,
......
...@@ -2656,8 +2656,8 @@ static Node * ...@@ -2656,8 +2656,8 @@ static Node *
transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr) transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr)
{ {
/* CURRENT OF can only appear at top level of UPDATE/DELETE */ /* CURRENT OF can only appear at top level of UPDATE/DELETE */
Assert(pstate->p_target_rtindex > 0); Assert(pstate->p_target_nsitem != NULL);
cexpr->cvarno = pstate->p_target_rtindex; cexpr->cvarno = pstate->p_target_nsitem->p_rtindex;
/* /*
* Check to see if the cursor name matches a parameter of type REFCURSOR. * Check to see if the cursor name matches a parameter of type REFCURSOR.
......
This diff is collapsed.
...@@ -551,7 +551,7 @@ transformAssignedExpr(ParseState *pstate, ...@@ -551,7 +551,7 @@ transformAssignedExpr(ParseState *pstate,
*/ */
Var *var; Var *var;
var = makeVar(pstate->p_target_rtindex, attrno, var = makeVar(pstate->p_target_nsitem->p_rtindex, attrno,
attrtype, attrtypmod, attrcollation, 0); attrtype, attrtypmod, attrcollation, 0);
var->location = location; var->location = location;
...@@ -1359,8 +1359,7 @@ ExpandSingleTable(ParseState *pstate, ParseNamespaceItem *nsitem, ...@@ -1359,8 +1359,7 @@ ExpandSingleTable(ParseState *pstate, ParseNamespaceItem *nsitem,
List *vars; List *vars;
ListCell *l; ListCell *l;
expandRTE(rte, nsitem->p_rtindex, sublevels_up, location, false, vars = expandNSItemVars(nsitem, sublevels_up, location, NULL);
NULL, &vars);
/* /*
* Require read access to the table. This is normally redundant with * Require read access to the table. This is normally redundant with
...@@ -1496,6 +1495,12 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup) ...@@ -1496,6 +1495,12 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
Assert(IsA(var, Var)); Assert(IsA(var, Var));
Assert(var->vartype == RECORDOID); Assert(var->vartype == RECORDOID);
/*
* Note: it's tempting to use GetNSItemByRangeTablePosn here so that we
* can use expandNSItemVars instead of expandRTE; but that does not work
* for some of the recursion cases below, where we have consed up a
* ParseState that lacks p_namespace data.
*/
netlevelsup = var->varlevelsup + levelsup; netlevelsup = var->varlevelsup + levelsup;
rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup); rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
attnum = var->varattno; attnum = var->varattno;
......
...@@ -2598,7 +2598,7 @@ IndexStmt * ...@@ -2598,7 +2598,7 @@ IndexStmt *
transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString)
{ {
ParseState *pstate; ParseState *pstate;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
ListCell *l; ListCell *l;
Relation rel; Relation rel;
...@@ -2622,12 +2622,12 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) ...@@ -2622,12 +2622,12 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString)
* relation, but we still need to open it. * relation, but we still need to open it.
*/ */
rel = relation_open(relid, NoLock); rel = relation_open(relid, NoLock);
rte = addRangeTableEntryForRelation(pstate, rel, nsitem = addRangeTableEntryForRelation(pstate, rel,
AccessShareLock, AccessShareLock,
NULL, false, true); NULL, false, true);
/* no to join list, yes to namespaces */ /* no to join list, yes to namespaces */
addRTEtoQuery(pstate, rte, false, true, true); addNSItemToQuery(pstate, nsitem, false, true, true);
/* take care of the where clause */ /* take care of the where clause */
if (stmt->whereClause) if (stmt->whereClause)
...@@ -2707,8 +2707,8 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, ...@@ -2707,8 +2707,8 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
{ {
Relation rel; Relation rel;
ParseState *pstate; ParseState *pstate;
RangeTblEntry *oldrte; ParseNamespaceItem *oldnsitem;
RangeTblEntry *newrte; ParseNamespaceItem *newnsitem;
/* /*
* To avoid deadlock, make sure the first thing we do is grab * To avoid deadlock, make sure the first thing we do is grab
...@@ -2729,20 +2729,20 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, ...@@ -2729,20 +2729,20 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
/* /*
* NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to 2. * NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to 2.
* Set up their RTEs in the main pstate for use in parsing the rule * Set up their ParseNamespaceItems in the main pstate for use in parsing
* qualification. * the rule qualification.
*/ */
oldrte = addRangeTableEntryForRelation(pstate, rel, oldnsitem = addRangeTableEntryForRelation(pstate, rel,
AccessShareLock, AccessShareLock,
makeAlias("old", NIL), makeAlias("old", NIL),
false, false); false, false);
newrte = addRangeTableEntryForRelation(pstate, rel, newnsitem = addRangeTableEntryForRelation(pstate, rel,
AccessShareLock, AccessShareLock,
makeAlias("new", NIL), makeAlias("new", NIL),
false, false); false, false);
/* Must override addRangeTableEntry's default access-check flags */ /* Must override addRangeTableEntry's default access-check flags */
oldrte->requiredPerms = 0; oldnsitem->p_rte->requiredPerms = 0;
newrte->requiredPerms = 0; newnsitem->p_rte->requiredPerms = 0;
/* /*
* They must be in the namespace too for lookup purposes, but only add the * They must be in the namespace too for lookup purposes, but only add the
...@@ -2754,17 +2754,17 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, ...@@ -2754,17 +2754,17 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
switch (stmt->event) switch (stmt->event)
{ {
case CMD_SELECT: case CMD_SELECT:
addRTEtoQuery(pstate, oldrte, false, true, true); addNSItemToQuery(pstate, oldnsitem, false, true, true);
break; break;
case CMD_UPDATE: case CMD_UPDATE:
addRTEtoQuery(pstate, oldrte, false, true, true); addNSItemToQuery(pstate, oldnsitem, false, true, true);
addRTEtoQuery(pstate, newrte, false, true, true); addNSItemToQuery(pstate, newnsitem, false, true, true);
break; break;
case CMD_INSERT: case CMD_INSERT:
addRTEtoQuery(pstate, newrte, false, true, true); addNSItemToQuery(pstate, newnsitem, false, true, true);
break; break;
case CMD_DELETE: case CMD_DELETE:
addRTEtoQuery(pstate, oldrte, false, true, true); addNSItemToQuery(pstate, oldnsitem, false, true, true);
break; break;
default: default:
elog(ERROR, "unrecognized event type: %d", elog(ERROR, "unrecognized event type: %d",
...@@ -2832,18 +2832,18 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, ...@@ -2832,18 +2832,18 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
* nor "*" in the rule actions. We decide later whether to put * nor "*" in the rule actions. We decide later whether to put
* them in the joinlist. * them in the joinlist.
*/ */
oldrte = addRangeTableEntryForRelation(sub_pstate, rel, oldnsitem = addRangeTableEntryForRelation(sub_pstate, rel,
AccessShareLock, AccessShareLock,
makeAlias("old", NIL), makeAlias("old", NIL),
false, false); false, false);
newrte = addRangeTableEntryForRelation(sub_pstate, rel, newnsitem = addRangeTableEntryForRelation(sub_pstate, rel,
AccessShareLock, AccessShareLock,
makeAlias("new", NIL), makeAlias("new", NIL),
false, false); false, false);
oldrte->requiredPerms = 0; oldnsitem->p_rte->requiredPerms = 0;
newrte->requiredPerms = 0; newnsitem->p_rte->requiredPerms = 0;
addRTEtoQuery(sub_pstate, oldrte, false, true, false); addNSItemToQuery(sub_pstate, oldnsitem, false, true, false);
addRTEtoQuery(sub_pstate, newrte, false, true, false); addNSItemToQuery(sub_pstate, newnsitem, false, true, false);
/* Transform the rule action statement */ /* Transform the rule action statement */
top_subqry = transformStmt(sub_pstate, top_subqry = transformStmt(sub_pstate,
...@@ -2967,6 +2967,8 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, ...@@ -2967,6 +2967,8 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
*/ */
if (has_old || (has_new && stmt->event == CMD_UPDATE)) if (has_old || (has_new && stmt->event == CMD_UPDATE))
{ {
RangeTblRef *rtr;
/* /*
* If sub_qry is a setop, manipulating its jointree will do no * If sub_qry is a setop, manipulating its jointree will do no
* good at all, because the jointree is dummy. (This should be * good at all, because the jointree is dummy. (This should be
...@@ -2976,11 +2978,11 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, ...@@ -2976,11 +2978,11 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented"))); errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
/* hack so we can use addRTEtoQuery() */ /* hackishly add OLD to the already-built FROM clause */
sub_pstate->p_rtable = sub_qry->rtable; rtr = makeNode(RangeTblRef);
sub_pstate->p_joinlist = sub_qry->jointree->fromlist; rtr->rtindex = oldnsitem->p_rtindex;
addRTEtoQuery(sub_pstate, oldrte, true, false, false); sub_qry->jointree->fromlist =
sub_qry->jointree->fromlist = sub_pstate->p_joinlist; lappend(sub_qry->jointree->fromlist, rtr);
} }
newactions = lappend(newactions, top_subqry); newactions = lappend(newactions, top_subqry);
...@@ -3025,7 +3027,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, ...@@ -3025,7 +3027,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
List *newcmds = NIL; List *newcmds = NIL;
bool skipValidation = true; bool skipValidation = true;
AlterTableCmd *newcmd; AlterTableCmd *newcmd;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
/* /*
* We must not scribble on the passed-in AlterTableStmt, so copy it. (This * We must not scribble on the passed-in AlterTableStmt, so copy it. (This
...@@ -3040,13 +3042,13 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, ...@@ -3040,13 +3042,13 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
/* Set up pstate */ /* Set up pstate */
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString; pstate->p_sourcetext = queryString;
rte = addRangeTableEntryForRelation(pstate, nsitem = addRangeTableEntryForRelation(pstate,
rel, rel,
AccessShareLock, AccessShareLock,
NULL, NULL,
false, false,
true); true);
addRTEtoQuery(pstate, rte, false, true, true); addNSItemToQuery(pstate, nsitem, false, true, true);
/* Set up CreateStmtContext */ /* Set up CreateStmtContext */
cxt.pstate = pstate; cxt.pstate = pstate;
......
...@@ -777,8 +777,8 @@ copy_table(Relation rel) ...@@ -777,8 +777,8 @@ copy_table(Relation rel)
copybuf = makeStringInfo(); copybuf = makeStringInfo();
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
addRangeTableEntryForRelation(pstate, rel, AccessShareLock, (void) addRangeTableEntryForRelation(pstate, rel, AccessShareLock,
NULL, false, false); NULL, false, false);
attnamelist = make_copy_attnamelist(relmapentry); attnamelist = make_copy_attnamelist(relmapentry);
cstate = BeginCopyFrom(pstate, rel, NULL, false, copy_read_data, attnamelist, NIL); cstate = BeginCopyFrom(pstate, rel, NULL, false, copy_read_data, attnamelist, NIL);
......
...@@ -3227,6 +3227,7 @@ rewriteTargetView(Query *parsetree, Relation view) ...@@ -3227,6 +3227,7 @@ rewriteTargetView(Query *parsetree, Relation view)
{ {
Index old_exclRelIndex, Index old_exclRelIndex,
new_exclRelIndex; new_exclRelIndex;
ParseNamespaceItem *new_exclNSItem;
RangeTblEntry *new_exclRte; RangeTblEntry *new_exclRte;
List *tmp_tlist; List *tmp_tlist;
...@@ -3261,11 +3262,12 @@ rewriteTargetView(Query *parsetree, Relation view) ...@@ -3261,11 +3262,12 @@ rewriteTargetView(Query *parsetree, Relation view)
*/ */
old_exclRelIndex = parsetree->onConflict->exclRelIndex; old_exclRelIndex = parsetree->onConflict->exclRelIndex;
new_exclRte = addRangeTableEntryForRelation(make_parsestate(NULL), new_exclNSItem = addRangeTableEntryForRelation(make_parsestate(NULL),
base_rel, base_rel,
RowExclusiveLock, RowExclusiveLock,
makeAlias("excluded", NIL), makeAlias("excluded", NIL),
false, false); false, false);
new_exclRte = new_exclNSItem->p_rte;
new_exclRte->relkind = RELKIND_COMPOSITE_TYPE; new_exclRte->relkind = RELKIND_COMPOSITE_TYPE;
new_exclRte->requiredPerms = 0; new_exclRte->requiredPerms = 0;
/* other permissions fields in new_exclRte are already empty */ /* other permissions fields in new_exclRte are already empty */
......
...@@ -19,6 +19,11 @@ ...@@ -19,6 +19,11 @@
#include "utils/relcache.h" #include "utils/relcache.h"
/* Forward references for some structs declared below */
typedef struct ParseState ParseState;
typedef struct ParseNamespaceItem ParseNamespaceItem;
typedef struct ParseNamespaceColumn ParseNamespaceColumn;
/* /*
* Expression kinds distinguished by transformExpr(). Many of these are not * Expression kinds distinguished by transformExpr(). Many of these are not
* semantically distinct so far as expression transformation goes; rather, * semantically distinct so far as expression transformation goes; rather,
...@@ -79,8 +84,6 @@ typedef enum ParseExprKind ...@@ -79,8 +84,6 @@ typedef enum ParseExprKind
/* /*
* Function signatures for parser hooks * Function signatures for parser hooks
*/ */
typedef struct ParseState ParseState;
typedef Node *(*PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref); typedef Node *(*PreParseColumnRefHook) (ParseState *pstate, ColumnRef *cref);
typedef Node *(*PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var); typedef Node *(*PostParseColumnRefHook) (ParseState *pstate, ColumnRef *cref, Node *var);
typedef Node *(*ParseParamRefHook) (ParseState *pstate, ParamRef *pref); typedef Node *(*ParseParamRefHook) (ParseState *pstate, ParamRef *pref);
...@@ -132,9 +135,7 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param, ...@@ -132,9 +135,7 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param,
* *
* p_target_relation: target relation, if query is INSERT, UPDATE, or DELETE. * p_target_relation: target relation, if query is INSERT, UPDATE, or DELETE.
* *
* p_target_rangetblentry: target relation's entry in the rtable list. * p_target_nsitem: target relation's ParseNamespaceItem.
*
* p_target_rtindex: target relation's index in the rtable list.
* *
* p_is_insert: true to process assignment expressions like INSERT, false * p_is_insert: true to process assignment expressions like INSERT, false
* to process them like UPDATE. (Note this can change intra-statement, for * to process them like UPDATE. (Note this can change intra-statement, for
...@@ -174,7 +175,7 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param, ...@@ -174,7 +175,7 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param,
*/ */
struct ParseState struct ParseState
{ {
struct ParseState *parentParseState; /* stack link */ ParseState *parentParseState; /* stack link */
const char *p_sourcetext; /* source text, or NULL if not available */ const char *p_sourcetext; /* source text, or NULL if not available */
List *p_rtable; /* range table so far */ List *p_rtable; /* range table so far */
List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */ List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */
...@@ -187,8 +188,7 @@ struct ParseState ...@@ -187,8 +188,7 @@ struct ParseState
List *p_future_ctes; /* common table exprs not yet in namespace */ List *p_future_ctes; /* common table exprs not yet in namespace */
CommonTableExpr *p_parent_cte; /* this query's containing CTE */ CommonTableExpr *p_parent_cte; /* this query's containing CTE */
Relation p_target_relation; /* INSERT/UPDATE/DELETE target rel */ Relation p_target_relation; /* INSERT/UPDATE/DELETE target rel */
RangeTblEntry *p_target_rangetblentry; /* target rel's RTE, or NULL */ ParseNamespaceItem *p_target_nsitem; /* target rel's NSItem, or NULL */
int p_target_rtindex; /* target rel's RT index, or 0 */
bool p_is_insert; /* process assignment like INSERT not UPDATE */ bool p_is_insert; /* process assignment like INSERT not UPDATE */
List *p_windowdefs; /* raw representations of window clauses */ List *p_windowdefs; /* raw representations of window clauses */
ParseExprKind p_expr_kind; /* what kind of expression we're parsing */ ParseExprKind p_expr_kind; /* what kind of expression we're parsing */
...@@ -225,6 +225,9 @@ struct ParseState ...@@ -225,6 +225,9 @@ struct ParseState
/* /*
* An element of a namespace list. * An element of a namespace list.
* *
* The p_nscolumns array contains info showing how to construct Vars
* referencing corresponding elements of the RTE's colnames list.
*
* Namespace items with p_rel_visible set define which RTEs are accessible by * Namespace items with p_rel_visible set define which RTEs are accessible by
* qualified names, while those with p_cols_visible set define which RTEs are * qualified names, while those with p_cols_visible set define which RTEs are
* accessible by unqualified names. These sets are different because a JOIN * accessible by unqualified names. These sets are different because a JOIN
...@@ -249,15 +252,49 @@ struct ParseState ...@@ -249,15 +252,49 @@ struct ParseState
* are more complicated than "must have different alias names", so in practice * are more complicated than "must have different alias names", so in practice
* code searching a namespace list has to check for ambiguous references. * code searching a namespace list has to check for ambiguous references.
*/ */
typedef struct ParseNamespaceItem struct ParseNamespaceItem
{ {
RangeTblEntry *p_rte; /* The relation's rangetable entry */ RangeTblEntry *p_rte; /* The relation's rangetable entry */
int p_rtindex; /* The relation's index in the rangetable */ int p_rtindex; /* The relation's index in the rangetable */
/* array of same length as p_rte->eref->colnames: */
ParseNamespaceColumn *p_nscolumns; /* per-column data */
bool p_rel_visible; /* Relation name is visible? */ bool p_rel_visible; /* Relation name is visible? */
bool p_cols_visible; /* Column names visible as unqualified refs? */ bool p_cols_visible; /* Column names visible as unqualified refs? */
bool p_lateral_only; /* Is only visible to LATERAL expressions? */ bool p_lateral_only; /* Is only visible to LATERAL expressions? */
bool p_lateral_ok; /* If so, does join type allow use? */ bool p_lateral_ok; /* If so, does join type allow use? */
} ParseNamespaceItem; };
/*
* Data about one column of a ParseNamespaceItem.
*
* We track the info needed to construct a Var referencing the column
* (but only for user-defined columns; system column references and
* whole-row references are handled separately).
*
* p_varno and p_varattno identify the semantic referent, which is a
* base-relation column unless the reference is to a join USING column that
* isn't semantically equivalent to either join input column (because it is a
* FULL join or the input column requires a type coercion). In those cases
* p_varno and p_varattno refer to the JOIN RTE.
*
* p_varnosyn and p_varattnosyn are either identical to p_varno/p_varattno,
* or they specify the column's position in an aliased JOIN RTE that hides
* the semantic referent RTE's refname. (That could be either the JOIN RTE
* in which this ParseNamespaceColumn entry exists, or some lower join level.)
*
* If an RTE contains a dropped column, its ParseNamespaceColumn struct
* is all-zeroes. (Conventionally, test for p_varno == 0 to detect this.)
*/
struct ParseNamespaceColumn
{
Index p_varno; /* rangetable index */
AttrNumber p_varattno; /* attribute number of the column */
Oid p_vartype; /* pg_type OID */
int32 p_vartypmod; /* type modifier value */
Oid p_varcollid; /* OID of collation, or InvalidOid */
Index p_varnosyn; /* rangetable index of syntactic referent */
AttrNumber p_varattnosyn; /* attribute number of syntactic referent */
};
/* Support for parser_errposition_callback function */ /* Support for parser_errposition_callback function */
typedef struct ParseCallbackState typedef struct ParseCallbackState
......
...@@ -45,66 +45,70 @@ extern void markVarForSelectPriv(ParseState *pstate, Var *var, ...@@ -45,66 +45,70 @@ extern void markVarForSelectPriv(ParseState *pstate, Var *var,
RangeTblEntry *rte); RangeTblEntry *rte);
extern Relation parserOpenTable(ParseState *pstate, const RangeVar *relation, extern Relation parserOpenTable(ParseState *pstate, const RangeVar *relation,
int lockmode); int lockmode);
extern RangeTblEntry *addRangeTableEntry(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntry(ParseState *pstate,
RangeVar *relation, RangeVar *relation,
Alias *alias, Alias *alias,
bool inh, bool inh,
bool inFromCl); bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForRelation(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntryForRelation(ParseState *pstate,
Relation rel, Relation rel,
int lockmode, int lockmode,
Alias *alias, Alias *alias,
bool inh, bool inh,
bool inFromCl); bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForSubquery(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntryForSubquery(ParseState *pstate,
Query *subquery, Query *subquery,
Alias *alias, Alias *alias,
bool lateral, bool lateral,
bool inFromCl); bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForFunction(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntryForFunction(ParseState *pstate,
List *funcnames, List *funcnames,
List *funcexprs, List *funcexprs,
List *coldeflists, List *coldeflists,
RangeFunction *rangefunc, RangeFunction *rangefunc,
bool lateral, bool lateral,
bool inFromCl); bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForValues(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntryForValues(ParseState *pstate,
List *exprs, List *exprs,
List *coltypes, List *coltypes,
List *coltypmods, List *coltypmods,
List *colcollations, List *colcollations,
Alias *alias, Alias *alias,
bool lateral, bool lateral,
bool inFromCl); bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForTableFunc(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntryForTableFunc(ParseState *pstate,
TableFunc *tf, TableFunc *tf,
Alias *alias,
bool lateral,
bool inFromCl);
extern ParseNamespaceItem *addRangeTableEntryForJoin(ParseState *pstate,
List *colnames,
ParseNamespaceColumn *nscolumns,
JoinType jointype,
List *aliasvars,
Alias *alias, Alias *alias,
bool lateral,
bool inFromCl); bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForJoin(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntryForCTE(ParseState *pstate,
List *colnames, CommonTableExpr *cte,
JoinType jointype, Index levelsup,
List *aliasvars, RangeVar *rv,
Alias *alias, bool inFromCl);
bool inFromCl); extern ParseNamespaceItem *addRangeTableEntryForENR(ParseState *pstate,
extern RangeTblEntry *addRangeTableEntryForCTE(ParseState *pstate, RangeVar *rv,
CommonTableExpr *cte, bool inFromCl);
Index levelsup,
RangeVar *rv,
bool inFromCl);
extern RangeTblEntry *addRangeTableEntryForENR(ParseState *pstate,
RangeVar *rv,
bool inFromCl);
extern bool isLockedRefname(ParseState *pstate, const char *refname); extern bool isLockedRefname(ParseState *pstate, const char *refname);
extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, extern void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem,
bool addToJoinList, bool addToJoinList,
bool addToRelNameSpace, bool addToVarNameSpace); bool addToRelNameSpace, bool addToVarNameSpace);
extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) pg_attribute_noreturn(); extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) pg_attribute_noreturn();
extern void errorMissingColumn(ParseState *pstate, extern void errorMissingColumn(ParseState *pstate,
const char *relname, const char *colname, int location) pg_attribute_noreturn(); const char *relname, const char *colname, int location) pg_attribute_noreturn();
extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
int location, bool include_dropped, int location, bool include_dropped,
List **colnames, List **colvars); List **colnames, List **colvars);
extern List *expandNSItemVars(ParseNamespaceItem *nsitem,
int sublevels_up, int location,
List **colnames);
extern List *expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem, extern List *expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem,
int sublevels_up, int location); int sublevels_up, int location);
extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK); extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK);
......
...@@ -38,15 +38,7 @@ ...@@ -38,15 +38,7 @@
extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum); extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum);
/* /*
* Given an RTE and an attribute number, return the appropriate * Check whether an attribute of an RTE has been dropped
* type and typemod info for that attribute of that RTE.
*/
extern void get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
Oid *vartype, int32 *vartypmod, Oid *varcollid);
/*
* Check whether an attribute of an RTE has been dropped (note that
* get_rte_attribute_type will fail on such an attr)
*/ */
extern bool get_rte_attribute_is_dropped(RangeTblEntry *rte, extern bool get_rte_attribute_is_dropped(RangeTblEntry *rte,
AttrNumber attnum); AttrNumber attnum);
......
...@@ -70,7 +70,7 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation) ...@@ -70,7 +70,7 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation)
Node *e; Node *e;
ColumnRef *c; ColumnRef *c;
ParseState *qual_pstate; ParseState *qual_pstate;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
if (strcmp(RelationGetRelationName(relation), "rls_test_permissive") != 0 && if (strcmp(RelationGetRelationName(relation), "rls_test_permissive") != 0 &&
strcmp(RelationGetRelationName(relation), "rls_test_both") != 0) strcmp(RelationGetRelationName(relation), "rls_test_both") != 0)
...@@ -78,9 +78,10 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation) ...@@ -78,9 +78,10 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation)
qual_pstate = make_parsestate(NULL); qual_pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(qual_pstate, relation, AccessShareLock, nsitem = addRangeTableEntryForRelation(qual_pstate,
NULL, false, false); relation, AccessShareLock,
addRTEtoQuery(qual_pstate, rte, false, true, true); NULL, false, false);
addNSItemToQuery(qual_pstate, nsitem, false, true, true);
role = ObjectIdGetDatum(ACL_ID_PUBLIC); role = ObjectIdGetDatum(ACL_ID_PUBLIC);
...@@ -134,8 +135,7 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation relation) ...@@ -134,8 +135,7 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation relation)
Node *e; Node *e;
ColumnRef *c; ColumnRef *c;
ParseState *qual_pstate; ParseState *qual_pstate;
RangeTblEntry *rte; ParseNamespaceItem *nsitem;
if (strcmp(RelationGetRelationName(relation), "rls_test_restrictive") != 0 && if (strcmp(RelationGetRelationName(relation), "rls_test_restrictive") != 0 &&
strcmp(RelationGetRelationName(relation), "rls_test_both") != 0) strcmp(RelationGetRelationName(relation), "rls_test_both") != 0)
...@@ -143,9 +143,10 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation relation) ...@@ -143,9 +143,10 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation relation)
qual_pstate = make_parsestate(NULL); qual_pstate = make_parsestate(NULL);
rte = addRangeTableEntryForRelation(qual_pstate, relation, AccessShareLock, nsitem = addRangeTableEntryForRelation(qual_pstate,
NULL, false, false); relation, AccessShareLock,
addRTEtoQuery(qual_pstate, rte, false, true, true); NULL, false, false);
addNSItemToQuery(qual_pstate, nsitem, false, true, true);
role = ObjectIdGetDatum(ACL_ID_PUBLIC); role = ObjectIdGetDatum(ACL_ID_PUBLIC);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment