diff options
Diffstat (limited to 'src/backend/rewrite')
-rw-r--r-- | src/backend/rewrite/rewriteHandler.c | 9 | ||||
-rw-r--r-- | src/backend/rewrite/rowsecurity.c | 28 |
2 files changed, 26 insertions, 11 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 7a46e8b3541..9fd05b15e73 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -3833,9 +3833,9 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length) ListCell *lc1; /* - * First, recursively process any insert/update/delete statements in WITH - * clauses. (We have to do this first because the WITH clauses may get - * copied into rule actions below.) + * First, recursively process any insert/update/delete/merge statements in + * WITH clauses. (We have to do this first because the WITH clauses may + * get copied into rule actions below.) */ foreach(lc1, parsetree->cteList) { @@ -3860,7 +3860,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length) if (!(ctequery->commandType == CMD_SELECT || ctequery->commandType == CMD_UPDATE || ctequery->commandType == CMD_INSERT || - ctequery->commandType == CMD_DELETE)) + ctequery->commandType == CMD_DELETE || + ctequery->commandType == CMD_MERGE)) { /* * Currently it could only be NOTIFY; this error message will diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c index 450af27c7f5..59fd305dd7b 100644 --- a/src/backend/rewrite/rowsecurity.c +++ b/src/backend/rewrite/rowsecurity.c @@ -384,10 +384,10 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, * on the final action we take. * * We already fetched the SELECT policies above, to check existing rows, - * but we must also check that new rows created by UPDATE actions are - * visible, if SELECT rights are required for this relation. We don't do - * this for INSERT actions, since an INSERT command would only do this - * check if it had a RETURNING list, and MERGE does not support RETURNING. + * but we must also check that new rows created by INSERT/UPDATE actions + * are visible, if SELECT rights are required. For INSERT actions, we only + * do this if RETURNING is specified, to be consistent with a plain INSERT + * command, which can only require SELECT rights when RETURNING is used. * * We don't push the UPDATE/DELETE USING quals to the RTE because we don't * really want to apply them while scanning the relation since we don't @@ -409,6 +409,8 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, List *merge_delete_restrictive_policies; List *merge_insert_permissive_policies; List *merge_insert_restrictive_policies; + List *merge_select_permissive_policies = NIL; + List *merge_select_restrictive_policies = NIL; /* * Fetch the UPDATE policies and set them up to execute on the @@ -446,9 +448,6 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, */ if (perminfo->requiredPerms & ACL_SELECT) { - List *merge_select_permissive_policies; - List *merge_select_restrictive_policies; - get_policies_for_relation(rel, CMD_SELECT, user_id, &merge_select_permissive_policies, &merge_select_restrictive_policies); @@ -497,6 +496,21 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, withCheckOptions, hasSubLinks, false); + + /* + * Add ALL/SELECT policies as WCO_RLS_INSERT_CHECK WCOs, to ensure + * that the inserted row is visible when executing an INSERT action, + * if RETURNING is specified and SELECT rights are required for this + * relation. + */ + if (perminfo->requiredPerms & ACL_SELECT && root->returningList) + add_with_check_options(rel, rt_index, + WCO_RLS_INSERT_CHECK, + merge_select_permissive_policies, + merge_select_restrictive_policies, + withCheckOptions, + hasSubLinks, + true); } table_close(rel, NoLock); |