Skip to content

Commit

Permalink
Fix Crash when Instead of View Trigger calls itself (babelfish-for-po…
Browse files Browse the repository at this point in the history
…stgresql#1970)

This change will fix crashes when an
Instead of Trigger on View calls itself directly and indirectly

Task: BABEL-2170
Signed-off-by: Deepakshi Mittal <[email protected]>
  • Loading branch information
deepakshi-mittal authored and Jason Teng committed Dec 28, 2023
1 parent fb0cebf commit 094c572
Show file tree
Hide file tree
Showing 3 changed files with 1,051 additions and 0 deletions.
54 changes: 54 additions & 0 deletions contrib/babelfishpg_tsql/src/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,60 @@ plsql_TriggerRecursiveCheck(ResultRelInfo *resultRelInfo)
return false;
}

/**
* Hook function to skip rewriting VIEW with base table if the VIEW has an instead of trigger
* Checks if view have an INSTEAD OF trigger at statement level
* If it does, we don't want to treat it as auto-updatable.
* Reference - src/backend/rewrite/rewriteHandler.c view_has_instead_trigger
*/
static bool
pltsql_bbfViewHasInsteadofTrigger(Relation view, CmdType event)
{
TriggerDesc *trigDesc = view->trigdesc;
if (triggerOids)
{
int i;
for (i = 0; i < trigDesc->numtriggers; i++)
{
Trigger *trigger = &trigDesc->triggers[i];
Oid current_tgoid = trigger->tgoid;
Oid prev_tgoid = InvalidOid;
prev_tgoid = lfirst_oid(list_tail(triggerOids));
if (prev_tgoid == current_tgoid)
{
return false; /** Direct recursive trigger case*/
}
else if (list_member_oid(triggerOids, current_tgoid))
{
/** Indirect recursive trigger case*/
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)")));
}
}
}

switch (event)
{
case CMD_INSERT:
if(trigDesc && trigDesc->trig_insert_instead_statement)
return true;
break;
case CMD_UPDATE:
if (trigDesc && trigDesc->trig_update_instead_statement)
return true;
break;
case CMD_DELETE:
if (trigDesc && trigDesc->trig_delete_instead_statement)
return true;
break;
default:
elog(ERROR, "unrecognized CmdType: %d", (int) event);
break;
}
return false;
}

/*
* Wrapper function that calls the initilization function.
* Calls the pre function call hook on the procname
Expand Down
Loading

0 comments on commit 094c572

Please sign in to comment.