diff options
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r-- | src/backend/executor/execMain.c | 51 |
1 files changed, 14 insertions, 37 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 13a9b7da83b..79ef46f2614 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -56,6 +56,7 @@ #include "miscadmin.h" #include "parser/parse_relation.h" #include "parser/parsetree.h" +#include "rewrite/rewriteHandler.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "tcop/utility.h" @@ -1017,14 +1018,18 @@ InitPlan(QueryDesc *queryDesc, int eflags) * Generally the parser and/or planner should have noticed any such mistake * already, but let's make sure. * + * For MERGE, mergeActions is the list of actions that may be performed. The + * result relation is required to support every action, regardless of whether + * or not they are all executed. + * * Note: when changing this function, you probably also need to look at * CheckValidRowMarkRel. */ void -CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation) +CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, + List *mergeActions) { Relation resultRel = resultRelInfo->ri_RelationDesc; - TriggerDesc *trigDesc = resultRel->trigdesc; FdwRoutine *fdwroutine; switch (resultRel->rd_rel->relkind) @@ -1048,42 +1053,14 @@ CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation) case RELKIND_VIEW: /* - * Okay only if there's a suitable INSTEAD OF trigger. Messages - * here should match rewriteHandler.c's rewriteTargetView and - * RewriteQuery, except that we omit errdetail because we haven't - * got the information handy (and given that we really shouldn't - * get here anyway, it's not worth great exertion to get). + * Okay only if there's a suitable INSTEAD OF trigger. Otherwise, + * complain, but omit errdetail because we haven't got the + * information handy (and given that it really shouldn't happen, + * it's not worth great exertion to get). */ - switch (operation) - { - case CMD_INSERT: - if (!trigDesc || !trigDesc->trig_insert_instead_row) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot insert into view \"%s\"", - RelationGetRelationName(resultRel)), - errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule."))); - break; - case CMD_UPDATE: - if (!trigDesc || !trigDesc->trig_update_instead_row) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot update view \"%s\"", - RelationGetRelationName(resultRel)), - errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule."))); - break; - case CMD_DELETE: - if (!trigDesc || !trigDesc->trig_delete_instead_row) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot delete from view \"%s\"", - RelationGetRelationName(resultRel)), - errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule."))); - break; - default: - elog(ERROR, "unrecognized CmdType: %d", (int) operation); - break; - } + if (!view_has_instead_trigger(resultRel, operation, mergeActions)) + error_view_not_updatable(resultRel, operation, mergeActions, + NULL); break; case RELKIND_MATVIEW: if (!MatViewIncrementalMaintenanceIsEnabled()) |