aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r--src/backend/executor/execMain.c51
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())