Skip to content

Commit

Permalink
Support for Instead of Trigger On Views in Babelfish
Browse files Browse the repository at this point in the history
Currently Postgres does not support Instead of Trigger
On Views for DML queries.

On running such a query on VIEW, query rewriting substitutes
view with underlying base table.
Added a hook for skipping the substitution for DML
query on the VIEW.

This change will add support for Instaed of Triggers
for DML queries when using Babelfish.

Task: BABEL-2170

Signed-off-by: Deepakshi Mittal <[email protected]>
  • Loading branch information
deepakshi-mittal committed Oct 2, 2023
1 parent dce7212 commit df30c57
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 11 deletions.
6 changes: 0 additions & 6 deletions src/backend/commands/trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,6 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString,
RelationGetRelationName(rel)),
errdetail("Triggers on foreign tables cannot have transition tables.")));

if (rel->rd_rel->relkind == RELKIND_VIEW)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is a view",
RelationGetRelationName(rel)),
errdetail("Triggers on views cannot have transition tables.")));

/*
* We currently don't allow row-level triggers with transition
Expand Down
7 changes: 4 additions & 3 deletions src/backend/executor/execMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include "jit/jit.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "parser/parser.h"
#include "parser/parsetree.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
Expand Down Expand Up @@ -1029,23 +1030,23 @@ CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation)
switch (operation)
{
case CMD_INSERT:
if (!trigDesc || !trigDesc->trig_insert_instead_row)
if (!trigDesc || (!trigDesc->trig_insert_instead_row && (sql_dialect == SQL_DIALECT_TSQL && !trigDesc->trig_insert_instead_statement)))
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)
if (!trigDesc || (!trigDesc->trig_update_instead_row && (sql_dialect == SQL_DIALECT_TSQL && !trigDesc->trig_update_instead_statement)))
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)
if (!trigDesc || (!trigDesc->trig_delete_instead_row && (sql_dialect == SQL_DIALECT_TSQL && !trigDesc->trig_delete_instead_statement)))
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("cannot delete from view \"%s\"",
Expand Down
8 changes: 6 additions & 2 deletions src/backend/rewrite/rewriteHandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
#include "parser/analyze.h"
#include "parser/parser.h"
#include "parser/parse_coerce.h"
#include "parser/parse_relation.h"
#include "parser/parsetree.h"
Expand All @@ -45,6 +46,7 @@
#include "utils/lsyscache.h"
#include "utils/rel.h"

ViewInsteadStmtTrigger_hook_type ViewInsteadStmtTrigger_hook = NULL;

/* We use a list of these to detect recursion in RewriteQuery */
typedef struct rewrite_event
Expand Down Expand Up @@ -1472,7 +1474,8 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
*/
isAutoUpdatableView = false;
if (target_relation->rd_rel->relkind == RELKIND_VIEW &&
!view_has_instead_trigger(target_relation, CMD_INSERT))
(!view_has_instead_trigger(target_relation, CMD_INSERT) &&
!(sql_dialect == SQL_DIALECT_TSQL && ViewInsteadStmtTrigger_hook && (ViewInsteadStmtTrigger_hook)(target_relation, CMD_INSERT))))
{
List *locks;
bool hasUpdate;
Expand Down Expand Up @@ -3953,7 +3956,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length)
*/
if (!instead &&
rt_entry_relation->rd_rel->relkind == RELKIND_VIEW &&
!view_has_instead_trigger(rt_entry_relation, event))
(!view_has_instead_trigger(rt_entry_relation, event)
&& !(sql_dialect == SQL_DIALECT_TSQL && ViewInsteadStmtTrigger_hook && (ViewInsteadStmtTrigger_hook)(rt_entry_relation, event))))
{
/*
* If there were any qualified INSTEAD rules, don't allow the view
Expand Down
3 changes: 3 additions & 0 deletions src/include/executor/executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;
typedef bool (*TriggerRecuresiveCheck_hook_type) (ResultRelInfo *resultRelInfo);
extern PGDLLIMPORT TriggerRecuresiveCheck_hook_type TriggerRecuresiveCheck_hook;

typedef bool (*ViewInsteadStmtTrigger_hook_type) (Relation view, CmdType event);
extern PGDLLIMPORT ViewInsteadStmtTrigger_hook_type ViewInsteadStmtTrigger_hook;

typedef bool (*check_rowcount_hook_type) (int es_processed);
extern PGDLLIMPORT check_rowcount_hook_type check_rowcount_hook;

Expand Down

0 comments on commit df30c57

Please sign in to comment.