mirror of
https://github.com/postgres/postgres.git
synced 2025-08-21 10:42:50 +03:00
Support MERGE into updatable views.
This allows the target relation of MERGE to be an auto-updatable or trigger-updatable view, and includes support for WITH CHECK OPTION, security barrier views, and security invoker views. A trigger-updatable view must have INSTEAD OF triggers for every type of action (INSERT, UPDATE, and DELETE) mentioned in the MERGE command. An auto-updatable view must not have any INSTEAD OF triggers. Mixing auto-update and trigger-update actions (i.e., having a partial set of INSTEAD OF triggers) is not supported. Rule-updatable views are also not supported, since there is no rewriter support for non-SELECT rules with MERGE operations. Dean Rasheed, reviewed by Jian He and Alvaro Herrera. Discussion: https://postgr.es/m/CAEZATCVcB1g0nmxuEc-A+gGB0HnfcGQNGYH7gS=7rq0u0zOBXA@mail.gmail.com
This commit is contained in:
@@ -172,28 +172,27 @@ transformMergeStmt(ParseState *pstate, MergeStmt *stmt)
|
||||
* Set up the MERGE target table. The target table is added to the
|
||||
* namespace below and to joinlist in transform_MERGE_to_join, so don't do
|
||||
* it here.
|
||||
*
|
||||
* Initially mergeTargetRelation is the same as resultRelation, so data is
|
||||
* read from the table being updated. However, that might be changed by
|
||||
* the rewriter, if the target is a trigger-updatable view, to allow
|
||||
* target data to be read from the expanded view query while updating the
|
||||
* original view relation.
|
||||
*/
|
||||
qry->resultRelation = setTargetTable(pstate, stmt->relation,
|
||||
stmt->relation->inh,
|
||||
false, targetPerms);
|
||||
qry->mergeTargetRelation = qry->resultRelation;
|
||||
|
||||
/*
|
||||
* MERGE is unsupported in various cases
|
||||
*/
|
||||
/* The target relation must be a table or a view */
|
||||
if (pstate->p_target_relation->rd_rel->relkind != RELKIND_RELATION &&
|
||||
pstate->p_target_relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
|
||||
pstate->p_target_relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
|
||||
pstate->p_target_relation->rd_rel->relkind != RELKIND_VIEW)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot execute MERGE on relation \"%s\"",
|
||||
RelationGetRelationName(pstate->p_target_relation)),
|
||||
errdetail_relkind_not_supported(pstate->p_target_relation->rd_rel->relkind)));
|
||||
if (pstate->p_target_relation->rd_rules != NULL &&
|
||||
pstate->p_target_relation->rd_rules->numLocks > 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot execute MERGE on relation \"%s\"",
|
||||
RelationGetRelationName(pstate->p_target_relation)),
|
||||
errdetail("MERGE is not supported for relations with rules.")));
|
||||
|
||||
/* Now transform the source relation to produce the source RTE. */
|
||||
transformFromClause(pstate,
|
||||
|
Reference in New Issue
Block a user