aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_clause.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-01-22 20:16:10 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-01-22 20:16:10 +0000
commit3cb5d6580a335e0b7fcf25da7fcebee3a776edb4 (patch)
tree53580564c946729c7f352b0dc26c7ee389a9d3a6 /src/backend/parser/parse_clause.c
parentbf136cf6e376ae1a636341e5c8471c55299f9122 (diff)
downloadpostgresql-3cb5d6580a335e0b7fcf25da7fcebee3a776edb4.tar.gz
postgresql-3cb5d6580a335e0b7fcf25da7fcebee3a776edb4.zip
Support column-level privileges, as required by SQL standard.
Stephen Frost, with help from KaiGai Kohei and others
Diffstat (limited to 'src/backend/parser/parse_clause.c')
-rw-r--r--src/backend/parser/parse_clause.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 93e393f8379..7e9fb9c071a 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.185 2009/01/01 17:23:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.186 2009/01/22 20:16:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,7 @@ static void extractRemainingColumns(List *common_colnames,
List *src_colnames, List *src_colvars,
List **res_colnames, List **res_colvars);
static Node *transformJoinUsingClause(ParseState *pstate,
+ RangeTblEntry *leftRTE, RangeTblEntry *rightRTE,
List *leftVars, List *rightVars);
static Node *transformJoinOnClause(ParseState *pstate, JoinExpr *j,
RangeTblEntry *l_rte,
@@ -194,8 +195,7 @@ setTargetTable(ParseState *pstate, RangeVar *relation,
*
* If we find an explicit reference to the rel later during parse
* analysis, we will add the ACL_SELECT bit back again; see
- * scanRTEForColumn (for simple field references), ExpandColumnRefStar
- * (for foo.*) and ExpandAllTables (for *).
+ * markVarForSelectPriv and its callers.
*/
rte->requiredPerms = requiredPerms;
@@ -305,7 +305,9 @@ extractRemainingColumns(List *common_colnames,
* Result is a transformed qualification expression.
*/
static Node *
-transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
+transformJoinUsingClause(ParseState *pstate,
+ RangeTblEntry *leftRTE, RangeTblEntry *rightRTE,
+ List *leftVars, List *rightVars)
{
Node *result = NULL;
ListCell *lvars,
@@ -315,17 +317,25 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
* We cheat a little bit here by building an untransformed operator tree
* whose leaves are the already-transformed Vars. This is OK because
* transformExpr() won't complain about already-transformed subnodes.
+ * However, this does mean that we have to mark the columns as requiring
+ * SELECT privilege for ourselves; transformExpr() won't do it.
*/
forboth(lvars, leftVars, rvars, rightVars)
{
- Node *lvar = (Node *) lfirst(lvars);
- Node *rvar = (Node *) lfirst(rvars);
+ Var *lvar = (Var *) lfirst(lvars);
+ Var *rvar = (Var *) lfirst(rvars);
A_Expr *e;
+ /* Require read access to the join variables */
+ markVarForSelectPriv(pstate, lvar, leftRTE);
+ markVarForSelectPriv(pstate, rvar, rightRTE);
+
+ /* Now create the lvar = rvar join condition */
e = makeSimpleA_Expr(AEXPR_OP, "=",
copyObject(lvar), copyObject(rvar),
-1);
+ /* And combine into an AND clause, if multiple join columns */
if (result == NULL)
result = (Node *) e;
else
@@ -728,6 +738,7 @@ transformFromClauseItem(ParseState *pstate, Node *n,
*r_colvars,
*res_colvars;
RangeTblEntry *rte;
+ int k;
/*
* Recursively process the left and right subtrees
@@ -912,6 +923,8 @@ transformFromClauseItem(ParseState *pstate, Node *n,
}
j->quals = transformJoinUsingClause(pstate,
+ l_rte,
+ r_rte,
l_usingvars,
r_usingvars);
}
@@ -972,6 +985,12 @@ transformFromClauseItem(ParseState *pstate, Node *n,
*top_rte = rte;
*top_rti = j->rtindex;
+ /* make a matching link to the JoinExpr for later use */
+ for (k = list_length(pstate->p_joinexprs) + 1; k < j->rtindex; k++)
+ pstate->p_joinexprs = lappend(pstate->p_joinexprs, NULL);
+ pstate->p_joinexprs = lappend(pstate->p_joinexprs, j);
+ Assert(list_length(pstate->p_joinexprs) == j->rtindex);
+
/*
* Prepare returned namespace list. If the JOIN has an alias then it
* hides the contained RTEs as far as the relnamespace goes;