@@ -59,6 +59,12 @@ typedef struct acquireLocksOnSubLinks_context
59
59
bool for_execute ; /* AcquireRewriteLocks' forExecute param */
60
60
} acquireLocksOnSubLinks_context ;
61
61
62
+ typedef struct fireRIRonSubLink_context
63
+ {
64
+ List * activeRIRs ;
65
+ bool hasRowSecurity ;
66
+ } fireRIRonSubLink_context ;
67
+
62
68
static bool acquireLocksOnSubLinks (Node * node ,
63
69
acquireLocksOnSubLinks_context * context );
64
70
static Query * rewriteRuleAction (Query * parsetree ,
@@ -1856,6 +1862,12 @@ ApplyRetrieveRule(Query *parsetree,
1856
1862
*/
1857
1863
rule_action = fireRIRrules (rule_action , activeRIRs );
1858
1864
1865
+ /*
1866
+ * Make sure the query is marked as having row security if the view query
1867
+ * does.
1868
+ */
1869
+ parsetree -> hasRowSecurity |= rule_action -> hasRowSecurity ;
1870
+
1859
1871
/*
1860
1872
* Now, plug the view query in as a subselect, converting the relation's
1861
1873
* original RTE to a subquery RTE.
@@ -1981,7 +1993,7 @@ markQueryForLocking(Query *qry, Node *jtnode,
1981
1993
* the SubLink's subselect link with the possibly-rewritten subquery.
1982
1994
*/
1983
1995
static bool
1984
- fireRIRonSubLink (Node * node , List * activeRIRs )
1996
+ fireRIRonSubLink (Node * node , fireRIRonSubLink_context * context )
1985
1997
{
1986
1998
if (node == NULL )
1987
1999
return false;
@@ -1991,7 +2003,13 @@ fireRIRonSubLink(Node *node, List *activeRIRs)
1991
2003
1992
2004
/* Do what we came for */
1993
2005
sub -> subselect = (Node * ) fireRIRrules ((Query * ) sub -> subselect ,
1994
- activeRIRs );
2006
+ context -> activeRIRs );
2007
+
2008
+ /*
2009
+ * Remember if any of the sublinks have row security.
2010
+ */
2011
+ context -> hasRowSecurity |= ((Query * ) sub -> subselect )-> hasRowSecurity ;
2012
+
1995
2013
/* Fall through to process lefthand args of SubLink */
1996
2014
}
1997
2015
@@ -2000,7 +2018,7 @@ fireRIRonSubLink(Node *node, List *activeRIRs)
2000
2018
* subselects of subselects for us.
2001
2019
*/
2002
2020
return expression_tree_walker (node , fireRIRonSubLink ,
2003
- (void * ) activeRIRs );
2021
+ (void * ) context );
2004
2022
}
2005
2023
2006
2024
@@ -2061,6 +2079,13 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
2061
2079
if (rte -> rtekind == RTE_SUBQUERY )
2062
2080
{
2063
2081
rte -> subquery = fireRIRrules (rte -> subquery , activeRIRs );
2082
+
2083
+ /*
2084
+ * While we are here, make sure the query is marked as having row
2085
+ * security if any of its subqueries do.
2086
+ */
2087
+ parsetree -> hasRowSecurity |= rte -> subquery -> hasRowSecurity ;
2088
+
2064
2089
continue ;
2065
2090
}
2066
2091
@@ -2174,16 +2199,35 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
2174
2199
2175
2200
cte -> ctequery = (Node * )
2176
2201
fireRIRrules ((Query * ) cte -> ctequery , activeRIRs );
2202
+
2203
+ /*
2204
+ * While we are here, make sure the query is marked as having row
2205
+ * security if any of its CTEs do.
2206
+ */
2207
+ parsetree -> hasRowSecurity |= ((Query * ) cte -> ctequery )-> hasRowSecurity ;
2177
2208
}
2178
2209
2179
2210
/*
2180
2211
* Recurse into sublink subqueries, too. But we already did the ones in
2181
2212
* the rtable and cteList.
2182
2213
*/
2183
2214
if (parsetree -> hasSubLinks )
2184
- query_tree_walker (parsetree , fireRIRonSubLink , (void * ) activeRIRs ,
2215
+ {
2216
+ fireRIRonSubLink_context context ;
2217
+
2218
+ context .activeRIRs = activeRIRs ;
2219
+ context .hasRowSecurity = false;
2220
+
2221
+ query_tree_walker (parsetree , fireRIRonSubLink , (void * ) & context ,
2185
2222
QTW_IGNORE_RC_SUBQUERIES );
2186
2223
2224
+ /*
2225
+ * Make sure the query is marked as having row security if any of its
2226
+ * sublinks do.
2227
+ */
2228
+ parsetree -> hasRowSecurity |= context .hasRowSecurity ;
2229
+ }
2230
+
2187
2231
/*
2188
2232
* Apply any row-level security policies. We do this last because it
2189
2233
* requires special recursion detection if the new quals have sublink
@@ -2222,6 +2266,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
2222
2266
if (hasSubLinks )
2223
2267
{
2224
2268
acquireLocksOnSubLinks_context context ;
2269
+ fireRIRonSubLink_context fire_context ;
2225
2270
2226
2271
/*
2227
2272
* Recursively process the new quals, checking for infinite
@@ -2252,11 +2297,21 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
2252
2297
* Now that we have the locks on anything added by
2253
2298
* get_row_security_policies, fire any RIR rules for them.
2254
2299
*/
2300
+ fire_context .activeRIRs = activeRIRs ;
2301
+ fire_context .hasRowSecurity = false;
2302
+
2255
2303
expression_tree_walker ((Node * ) securityQuals ,
2256
- fireRIRonSubLink , (void * ) activeRIRs );
2304
+ fireRIRonSubLink , (void * ) & fire_context );
2257
2305
2258
2306
expression_tree_walker ((Node * ) withCheckOptions ,
2259
- fireRIRonSubLink , (void * ) activeRIRs );
2307
+ fireRIRonSubLink , (void * ) & fire_context );
2308
+
2309
+ /*
2310
+ * We can ignore the value of fire_context.hasRowSecurity
2311
+ * since we only reach this code in cases where hasRowSecurity
2312
+ * is already true.
2313
+ */
2314
+ Assert (hasRowSecurity );
2260
2315
2261
2316
activeRIRs = list_delete_last (activeRIRs );
2262
2317
}
0 commit comments