8000
We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent 6214e2b commit c028fafCopy full SHA for c028faf
src/backend/parser/parse_relation.c
@@ -68,7 +68,7 @@ static int scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
68
const char *colname, int location,
69
int fuzzy_rte_penalty,
70
FuzzyAttrMatchState *fuzzystate);
71
-static void markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
+static void markRTEForSelectPriv(ParseState *pstate,
72
int rtindex, AttrNumber col);
73
static void expandRelation(Oid relid, Alias *eref,
74
int rtindex, int sublevels_up,
@@ -660,8 +660,8 @@ updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
660
* If found, return an appropriate Var node, else return NULL.
661
* If the name proves ambiguous within this nsitem, raise error.
662
663
- * Side effect: if we find a match, mark the item's RTE as requiring read
664
- * access for the column.
+ * Side effect: if we find a match, mark the corresponding RTE as requiring
+ * read access for the column.
665
*/
666
Node *
667
scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
@@ -990,21 +990,15 @@ searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colnam
990
991
/*
992
* markRTEForSelectPriv
993
- * Mark the specified column of an RTE as requiring SELECT privilege
+ * Mark the specified column of the RTE with index rtindex
994
+ * as requiring SELECT privilege
995
*
996
* col == InvalidAttrNumber means a "whole row" reference
- *
997
- * External callers should always pass the Var's RTE. Internally, we
998
- * allow NULL to be passed for the RTE and then look it up if needed;
999
- * this takes less code than requiring each internal recursion site
1000
- * to perform a lookup.
1001
1002
static void
1003
-markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
1004
- int rtindex, AttrNumber col)
+markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col)
1005
{
1006
- if (rte == NULL)
1007
- rte = rt_fetch(rtindex, pstate->p_rtable);
+ RangeTblEntry *rte = rt_fetch(rtindex, pstate->p_rtable);
1008
1009
if (rte->rtekind == RTE_RELATION)
1010
@@ -1036,13 +1030,13 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
1036
1030
1037
1031
int varno = ((RangeTblRef *) j->larg)->rtindex;
1038
1032
1039
- markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber);
1033
+ markRTEForSelectPriv(pstate, varno, InvalidAttrNumber);
1040
1034
}
1041
1035
else if (IsA(j->larg, JoinExpr))
1042
1043
int varno = ((JoinExpr *) j->larg)->rtindex;
1044
1045
1046
1047
else
1048
elog(ERROR, "unrecognized node type: %d",
@@ -1051,13 +1045,13 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
1051
1052
int varno = ((RangeTblRef *) j->rarg)->rtindex;
1053
1054
1055
1049
1056
1050
else if (IsA(j->rarg, JoinExpr))
1057
1058
int varno = ((JoinExpr *) j->rarg)->rtindex;
1059
1060
1061
1062
1063
@@ -1078,7 +1072,10 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
1078
1072
1079
1073
1080
1074
* markVarForSelectPriv
1081
- * Mark the RTE referenced by a Var as requiring SELECT privilege
1075
+ * Mark the RTE referenced by the Var as requiring SELECT privilege
1076
+ * for the Var's column (the Var could be a whole-row Var, too)
1077
+ *
+ * The rte argument is unused and will be removed later.
1082
1083
void
1084
markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte)
@@ -1089,7 +1086,7 @@ markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte)
1089
1086
/* Find the appropriate pstate if it's an uplevel Var */
1090
1087
for (lv = 0; lv < var->varlevelsup; lv++)
1091
1088
pstate = pstate->parentParseState;
1092
- markRTEForSelectPriv(pstate, rte, var->varno, var->varattno);
+ markRTEForSelectPriv(pstate, var->varno, var->varattno);
1093
1094
1095
@@ -3105,9 +3102,13 @@ expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem,
3105
3102
3106
3103
* Require read access to the table. This is normally redundant with the
3107
3104
* markVarForSelectPriv calls below, but not if the table has zero
3108
- * columns.
+ * columns. We need not do anything if the nsitem is for a join: its
+ * component tables will have been marked ACL_SELECT when they were added
+ * to the rangetable. (This step changes things only for the target
+ * relation of UPDATE/DELETE, which cannot be under a join.)
3109
3110
- rte->requiredPerms |= ACL_SELECT;
+ if (rte->rtekind == RTE_RELATION)
3111
+ rte->requiredPerms |= ACL_SELECT;
3112
3113
forboth(name, names, var, vars)
3114
src/backend/parser/parse_target.c
@@ -1384,9 +1384,13 @@ ExpandSingleTable(ParseState *pstate, ParseNamespaceItem *nsitem,
1384
1385
* Require read access to the table. This is normally redundant with
1386
* the markVarForSelectPriv calls below, but not if the table has zero
1387
1388
+ * component tables will have been marked ACL_SELECT when they were
1389
+ * added to the rangetable. (This step changes things only for the
1390
+ * target relation of UPDATE/DELETE, which cannot be under a join.)
1391
1392
1393
1394
1395
/* Require read access to each column */
1396
foreach(l, vars)
src/test/regress/expected/privileges.out
@@ -476,8 +476,54 @@ SELECT 1 FROM atest5 a JOIN atest5 b USING (two); -- fail
476
ERROR: permission denied for table atest5
477
SELECT 1 FROM atest5 a NATURAL JOIN atest5 b; -- fail
478
479
+SELECT * FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
480
+ERROR: permission denied for table atest5
481
+SELECT j.* FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
482
483
SELECT (j.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
484
485
+SELECT one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- ok
486
+ one
487
+-----
488
+ 1
489
+(1 row)
490
+
491
+SELECT j.one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- ok
492
493
494
495
496
497
+SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
498
499
+SELECT j.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
500
501
+SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
502
503
+SELECT j.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
504
505
+SELECT * FROM (atest5 a JOIN atest5 b USING (one)); -- fail
506
507
+SELECT a.* FROM (atest5 a JOIN atest5 b USING (one)); -- fail
508
509
+SELECT (a.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)); -- fail
510
511
+SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
512
513
+SELECT a.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
514
515
+SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
516
517
+SELECT b.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
518
519
+SELECT y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)); -- fail
520
521
+SELECT b.y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)); -- fail
522
523
+SELECT y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)); -- fail
524
525
+SELECT b.y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)); -- fail
526
527
SELECT 1 FROM atest5 WHERE two = 2; -- fail
528
529
SELECT * FROM atest1, atest5; -- fail
src/test/regress/sql/privileges.sql
@@ -303,7 +303,26 @@ SELECT 1 FROM atest5; -- ok
303
SELECT 1 FROM atest5 a JOIN atest5 b USING (one); -- ok
304
SELECT 1 FROM atest5 a JOIN atest5 b USING (two); -- fail
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
SELECT atest1.* FROM atest1, atest5; -- ok