Skip to content

Commit

Permalink
BABEL: fix the bug instead of trigger behaves wrongly in recursively …
Browse files Browse the repository at this point in the history
…call (yugabyte#31)

recursively call the instead of trigger may lose the last DML to the triggered table

in previous impl, recursively trigger a instead of trigger will not do any
changes into the triggered table, as for the last triggered DML, it
shouldn't do the instead of procedure, what it should do is to do DML in
the table, since the last DML in a recursive trig chain should not
trig it's trigger

Task: BABEL-3115 & BABEL-3116 & BABEL-3118
Signed-off-by: Zhibai Song <[email protected]>
Co-authored-by: Zhibai Song <[email protected]>
(cherry picked from commit 0a65a6039e60fbe1017689f9b91ffdc28875719d)
  • Loading branch information
rishabhtanwar29 authored and abhinab-yb committed Nov 14, 2024
1 parent be3a935 commit d034044
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/postgres/src/backend/commands/trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -5384,7 +5384,7 @@ isTsqlInsteadofTriggerExecution(EState *estate, ResultRelInfo *relinfo, TriggerE
{
Trigger *trigger = &trigdesc->triggers[i];
if (TriggerEnabled(estate, relinfo, trigger, event, NULL, NULL, NULL)){
return true;
return !TsqlRecuresiveCheck(relinfo);
}
}
return false;
Expand Down Expand Up @@ -7394,6 +7394,12 @@ void BeginCompositeTriggers(MemoryContext curCxt)
compositeTriggers.curCxt = curCxt;
}

bool TsqlRecuresiveCheck(ResultRelInfo *resultRelInfo){
if (TriggerRecuresiveCheck_hook)
return TriggerRecuresiveCheck_hook(resultRelInfo);
else return false;
}

/*
* End current nesting level for trigger from TSQL executor
* If there is trigger data at current level, fire all trigger
Expand Down
1 change: 1 addition & 0 deletions src/postgres/src/backend/executor/execMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ ExecutorRun_hook_type ExecutorRun_hook = NULL;
ExecutorFinish_hook_type ExecutorFinish_hook = NULL;
ExecutorEnd_hook_type ExecutorEnd_hook = NULL;

TriggerRecuresiveCheck_hook_type TriggerRecuresiveCheck_hook = NULL;
/* Hook for plugin to get control in ExecCheckRTPerms() */
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook = NULL;

Expand Down
8 changes: 7 additions & 1 deletion src/postgres/src/backend/executor/nodeModifyTable.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,9 +927,11 @@ ExecInsert(ModifyTableContext *context,
return NULL; /* "do nothing" */
}
else if (sql_dialect == SQL_DIALECT_TSQL && resultRelInfo->ri_TrigDesc &&
resultRelInfo->ri_TrigDesc->trig_insert_instead_statement){
resultRelInfo->ri_TrigDesc->trig_insert_instead_statement && !TsqlRecuresiveCheck(resultRelInfo)){
ExecIRInsertTriggersTSQL(estate, resultRelInfo, slot, mtstate->mt_transition_capture);
// if it's a statement level IOT trigger, only get the transition table
if (canSetTag)
(estate->es_processed)++;
return NULL;
}
else if (resultRelInfo->ri_FdwRoutine)
Expand Down Expand Up @@ -1585,6 +1587,8 @@ ExecDelete(ModifyTableContext *context,
isTsqlInsteadofTriggerExecution(estate, resultRelInfo, TRIGGER_EVENT_DELETE))
{
ExecIRDeleteTriggersTSQL(estate, resultRelInfo, tupleid, oldtuple, context->mtstate->mt_transition_capture);
if (canSetTag)
(estate->es_processed)++;
return NULL;
}

Expand Down Expand Up @@ -2722,6 +2726,8 @@ ExecUpdate(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
isTsqlInsteadofTriggerExecution(estate, resultRelInfo, TRIGGER_EVENT_INSTEAD))
{
ExecIRUpdateTriggersTSQL(estate, resultRelInfo, tupleid, oldtuple, slot, recheckIndexes, context->mtstate->mt_transition_capture);
if (canSetTag)
(estate->es_processed)++;
return NULL;
}

Expand Down
2 changes: 2 additions & 0 deletions src/postgres/src/include/commands/trigger.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,4 +320,6 @@ extern bool HasNonRITrigger(const TriggerDesc* trigDesc);
extern void BeginCompositeTriggers(MemoryContext curCxt);
extern void EndCompositeTriggers(bool error);

extern bool TsqlRecuresiveCheck(ResultRelInfo *resultRelInfo);

#endif /* TRIGGER_H */
2 changes: 2 additions & 0 deletions src/postgres/src/include/executor/executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ extern PGDLLIMPORT ExecutorEnd_hook_type ExecutorEnd_hook;
typedef bool (*ExecutorCheckPerms_hook_type) (List *, bool);
extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;

typedef bool (*TriggerRecuresiveCheck_hook_type) (ResultRelInfo *resultRelInfo);
extern PGDLLIMPORT TriggerRecuresiveCheck_hook_type TriggerRecuresiveCheck_hook;

/*
* prototypes from functions in execAmi.c
Expand Down
2 changes: 2 additions & 0 deletions src/postgres/src/include/utils/guc.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ extern PGDLLIMPORT double log_xact_sample_rate;
extern PGDLLIMPORT char *backtrace_functions;
extern PGDLLIMPORT char *backtrace_symbol_list;

extern bool pltsql_recursive_triggers;

extern PGDLLIMPORT int temp_file_limit;

extern PGDLLIMPORT int num_temp_buffers;
Expand Down
1 change: 1 addition & 0 deletions src/postgres/src/tools/pgindent/typedefs.list
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ ExecStatus
ExecStatusType
ExecuteStmt
ExecutorCheckPerms_hook_type
TriggerRecuresiveCheck_hook_type
ExecutorEnd_hook_type
ExecutorFinish_hook_type
ExecutorRun_hook_type
Expand Down

0 comments on commit d034044

Please sign in to comment.