aboutsummaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rewriteHandler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite/rewriteHandler.c')
-rw-r--r--src/backend/rewrite/rewriteHandler.c67
1 files changed, 61 insertions, 6 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 9cd96fd17ef..27d4f718843 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -59,6 +59,12 @@ typedef struct acquireLocksOnSubLinks_context
bool for_execute; /* AcquireRewriteLocks' forExecute param */
} acquireLocksOnSubLinks_context;
+typedef struct fireRIRonSubLink_context
+{
+ List *activeRIRs;
+ bool hasRowSecurity;
+} fireRIRonSubLink_context;
+
static bool acquireLocksOnSubLinks(Node *node,
acquireLocksOnSubLinks_context *context);
static Query *rewriteRuleAction(Query *parsetree,
@@ -1849,6 +1855,12 @@ ApplyRetrieveRule(Query *parsetree,
rule_action = fireRIRrules(rule_action, activeRIRs);
/*
+ * Make sure the query is marked as having row security if the view query
+ * does.
+ */
+ parsetree->hasRowSecurity |= rule_action->hasRowSecurity;
+
+ /*
* Now, plug the view query in as a subselect, converting the relation's
* original RTE to a subquery RTE.
*/
@@ -1961,7 +1973,7 @@ markQueryForLocking(Query *qry, Node *jtnode,
* the SubLink's subselect link with the possibly-rewritten subquery.
*/
static bool
-fireRIRonSubLink(Node *node, List *activeRIRs)
+fireRIRonSubLink(Node *node, fireRIRonSubLink_context *context)
{
if (node == NULL)
return false;
@@ -1971,7 +1983,13 @@ fireRIRonSubLink(Node *node, List *activeRIRs)
/* Do what we came for */
sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect,
- activeRIRs);
+ context->activeRIRs);
+
+ /*
+ * Remember if any of the sublinks have row security.
+ */
+ context->hasRowSecurity |= ((Query *) sub->subselect)->hasRowSecurity;
+
/* Fall through to process lefthand args of SubLink */
}
@@ -1980,7 +1998,7 @@ fireRIRonSubLink(Node *node, List *activeRIRs)
* subselects of subselects for us.
*/
return expression_tree_walker(node, fireRIRonSubLink,
- (void *) activeRIRs);
+ (void *) context);
}
@@ -2041,6 +2059,13 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
if (rte->rtekind == RTE_SUBQUERY)
{
rte->subquery = fireRIRrules(rte->subquery, activeRIRs);
+
+ /*
+ * While we are here, make sure the query is marked as having row
+ * security if any of its subqueries do.
+ */
+ parsetree->hasRowSecurity |= rte->subquery->hasRowSecurity;
+
continue;
}
@@ -2154,6 +2179,12 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
cte->ctequery = (Node *)
fireRIRrules((Query *) cte->ctequery, activeRIRs);
+
+ /*
+ * While we are here, make sure the query is marked as having row
+ * security if any of its CTEs do.
+ */
+ parsetree->hasRowSecurity |= ((Query *) cte->ctequery)->hasRowSecurity;
}
/*
@@ -2161,9 +2192,22 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
* the rtable and cteList.
*/
if (parsetree->hasSubLinks)
- query_tree_walker(parsetree, fireRIRonSubLink, (void *) activeRIRs,
+ {
+ fireRIRonSubLink_context context;
+
+ context.activeRIRs = activeRIRs;
+ context.hasRowSecurity = false;
+
+ query_tree_walker(parsetree, fireRIRonSubLink, (void *) &context,
QTW_IGNORE_RC_SUBQUERIES);
+ /*
+ * Make sure the query is marked as having row security if any of its
+ * sublinks do.
+ */
+ parsetree->hasRowSecurity |= context.hasRowSecurity;
+ }
+
/*
* Apply any row-level security policies. We do this last because it
* requires special recursion detection if the new quals have sublink
@@ -2202,6 +2246,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
if (hasSubLinks)
{
acquireLocksOnSubLinks_context context;
+ fireRIRonSubLink_context fire_context;
/*
* Recursively process the new quals, checking for infinite
@@ -2232,11 +2277,21 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
* Now that we have the locks on anything added by
* get_row_security_policies, fire any RIR rules for them.
*/
+ fire_context.activeRIRs = activeRIRs;
+ fire_context.hasRowSecurity = false;
+
expression_tree_walker((Node *) securityQuals,
- fireRIRonSubLink, (void *) activeRIRs);
+ fireRIRonSubLink, (void *) &fire_context);
expression_tree_walker((Node *) withCheckOptions,
- fireRIRonSubLink, (void *) activeRIRs);
+ fireRIRonSubLink, (void *) &fire_context);
+
+ /*
+ * We can ignore the value of fire_context.hasRowSecurity
+ * since we only reach this code in cases where hasRowSecurity
+ * is already true.
+ */
+ Assert(hasRowSecurity);
activeRIRs = list_delete_last(activeRIRs);
}