mirror of
https://github.com/postgres/postgres.git
synced 2025-10-16 17:07:43 +03:00
PL/Python: Refactor for event trigger support
Change is_trigger type from boolean to enum. That's a preparation for adding event trigger support. Author: Euler Taveira <euler@eulerto.com> Co-authored-by: Dimitri Fontaine <dimitri@2ndQuadrant.fr> Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/03f03515-2068-4f5b-b357-8fb540883c38%40app.fastmail.com
This commit is contained in:
@@ -509,7 +509,7 @@ PLy_function_save_args(PLyProcedure *proc)
|
|||||||
Py_XINCREF(result->args);
|
Py_XINCREF(result->args);
|
||||||
|
|
||||||
/* If it's a trigger, also save "TD" */
|
/* If it's a trigger, also save "TD" */
|
||||||
if (proc->is_trigger)
|
if (proc->is_trigger == PLPY_TRIGGER)
|
||||||
{
|
{
|
||||||
result->td = PyDict_GetItemString(proc->globals, "TD");
|
result->td = PyDict_GetItemString(proc->globals, "TD");
|
||||||
Py_XINCREF(result->td);
|
Py_XINCREF(result->td);
|
||||||
|
@@ -38,7 +38,7 @@ PG_FUNCTION_INFO_V1(plpython3_call_handler);
|
|||||||
PG_FUNCTION_INFO_V1(plpython3_inline_handler);
|
PG_FUNCTION_INFO_V1(plpython3_inline_handler);
|
||||||
|
|
||||||
|
|
||||||
static bool PLy_procedure_is_trigger(Form_pg_proc procStruct);
|
static PLyTrigType PLy_procedure_is_trigger(Form_pg_proc procStruct);
|
||||||
static void plpython_error_callback(void *arg);
|
static void plpython_error_callback(void *arg);
|
||||||
static void plpython_inline_error_callback(void *arg);
|
static void plpython_inline_error_callback(void *arg);
|
||||||
static void PLy_init_interp(void);
|
static void PLy_init_interp(void);
|
||||||
@@ -163,7 +163,7 @@ plpython3_validator(PG_FUNCTION_ARGS)
|
|||||||
Oid funcoid = PG_GETARG_OID(0);
|
Oid funcoid = PG_GETARG_OID(0);
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Form_pg_proc procStruct;
|
Form_pg_proc procStruct;
|
||||||
bool is_trigger;
|
PLyTrigType is_trigger;
|
||||||
|
|
||||||
if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
|
if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
@@ -235,14 +235,14 @@ plpython3_call_handler(PG_FUNCTION_ARGS)
|
|||||||
Relation tgrel = ((TriggerData *) fcinfo->context)->tg_relation;
|
Relation tgrel = ((TriggerData *) fcinfo->context)->tg_relation;
|
||||||
HeapTuple trv;
|
HeapTuple trv;
|
||||||
|
|
||||||
proc = PLy_procedure_get(funcoid, RelationGetRelid(tgrel), true);
|
proc = PLy_procedure_get(funcoid, RelationGetRelid(tgrel), PLPY_TRIGGER);
|
||||||
exec_ctx->curr_proc = proc;
|
exec_ctx->curr_proc = proc;
|
||||||
trv = PLy_exec_trigger(fcinfo, proc);
|
trv = PLy_exec_trigger(fcinfo, proc);
|
||||||
retval = PointerGetDatum(trv);
|
retval = PointerGetDatum(trv);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
proc = PLy_procedure_get(funcoid, InvalidOid, false);
|
proc = PLy_procedure_get(funcoid, InvalidOid, PLPY_NOT_TRIGGER);
|
||||||
exec_ctx->curr_proc = proc;
|
exec_ctx->curr_proc = proc;
|
||||||
retval = PLy_exec_function(fcinfo, proc);
|
retval = PLy_exec_function(fcinfo, proc);
|
||||||
}
|
}
|
||||||
@@ -336,10 +336,22 @@ plpython3_inline_handler(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static PLyTrigType
|
||||||
PLy_procedure_is_trigger(Form_pg_proc procStruct)
|
PLy_procedure_is_trigger(Form_pg_proc procStruct)
|
||||||
{
|
{
|
||||||
return (procStruct->prorettype == TRIGGEROID);
|
PLyTrigType ret;
|
||||||
|
|
||||||
|
switch (procStruct->prorettype)
|
||||||
|
{
|
||||||
|
case TRIGGEROID:
|
||||||
|
ret = PLPY_TRIGGER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = PLPY_NOT_TRIGGER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
static HTAB *PLy_procedure_cache = NULL;
|
static HTAB *PLy_procedure_cache = NULL;
|
||||||
|
|
||||||
static PLyProcedure *PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger);
|
static PLyProcedure *PLy_procedure_create(HeapTuple procTup, Oid fn_oid, PLyTrigType is_trigger);
|
||||||
static bool PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup);
|
static bool PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup);
|
||||||
static char *PLy_procedure_munge_source(const char *name, const char *src);
|
static char *PLy_procedure_munge_source(const char *name, const char *src);
|
||||||
|
|
||||||
@@ -63,15 +63,20 @@ PLy_procedure_name(PLyProcedure *proc)
|
|||||||
* be used with, so no sensible fn_rel can be passed.
|
* be used with, so no sensible fn_rel can be passed.
|
||||||
*/
|
*/
|
||||||
PLyProcedure *
|
PLyProcedure *
|
||||||
PLy_procedure_get(Oid fn_oid, Oid fn_rel, bool is_trigger)
|
PLy_procedure_get(Oid fn_oid, Oid fn_rel, PLyTrigType is_trigger)
|
||||||
{
|
{
|
||||||
bool use_cache = !(is_trigger && fn_rel == InvalidOid);
|
bool use_cache;
|
||||||
HeapTuple procTup;
|
HeapTuple procTup;
|
||||||
PLyProcedureKey key;
|
PLyProcedureKey key;
|
||||||
PLyProcedureEntry *volatile entry = NULL;
|
PLyProcedureEntry *volatile entry = NULL;
|
||||||
PLyProcedure *volatile proc = NULL;
|
PLyProcedure *volatile proc = NULL;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
|
if (is_trigger == PLPY_TRIGGER && fn_rel == InvalidOid)
|
||||||
|
use_cache = false;
|
||||||
|
else
|
||||||
|
use_cache = true;
|
||||||
|
|
||||||
procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid));
|
procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid));
|
||||||
if (!HeapTupleIsValid(procTup))
|
if (!HeapTupleIsValid(procTup))
|
||||||
elog(ERROR, "cache lookup failed for function %u", fn_oid);
|
elog(ERROR, "cache lookup failed for function %u", fn_oid);
|
||||||
@@ -127,7 +132,7 @@ PLy_procedure_get(Oid fn_oid, Oid fn_rel, bool is_trigger)
|
|||||||
* Create a new PLyProcedure structure
|
* Create a new PLyProcedure structure
|
||||||
*/
|
*/
|
||||||
static PLyProcedure *
|
static PLyProcedure *
|
||||||
PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
|
PLy_procedure_create(HeapTuple procTup, Oid fn_oid, PLyTrigType is_trigger)
|
||||||
{
|
{
|
||||||
char procName[NAMEDATALEN + 256];
|
char procName[NAMEDATALEN + 256];
|
||||||
Form_pg_proc procStruct;
|
Form_pg_proc procStruct;
|
||||||
@@ -200,7 +205,7 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
|
|||||||
* get information required for output conversion of the return value,
|
* get information required for output conversion of the return value,
|
||||||
* but only if this isn't a trigger.
|
* but only if this isn't a trigger.
|
||||||
*/
|
*/
|
||||||
if (!is_trigger)
|
if (is_trigger == PLPY_NOT_TRIGGER)
|
||||||
{
|
{
|
||||||
Oid rettype = procStruct->prorettype;
|
Oid rettype = procStruct->prorettype;
|
||||||
HeapTuple rvTypeTup;
|
HeapTuple rvTypeTup;
|
||||||
|
@@ -11,6 +11,15 @@
|
|||||||
extern void init_procedure_caches(void);
|
extern void init_procedure_caches(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trigger type
|
||||||
|
*/
|
||||||
|
typedef enum PLyTrigType
|
||||||
|
{
|
||||||
|
PLPY_TRIGGER,
|
||||||
|
PLPY_NOT_TRIGGER,
|
||||||
|
} PLyTrigType;
|
||||||
|
|
||||||
/* saved arguments for outer recursion level or set-returning function */
|
/* saved arguments for outer recursion level or set-returning function */
|
||||||
typedef struct PLySavedArgs
|
typedef struct PLySavedArgs
|
||||||
{
|
{
|
||||||
@@ -33,7 +42,7 @@ typedef struct PLyProcedure
|
|||||||
bool fn_readonly;
|
bool fn_readonly;
|
||||||
bool is_setof; /* true, if function returns result set */
|
bool is_setof; /* true, if function returns result set */
|
||||||
bool is_procedure;
|
bool is_procedure;
|
||||||
bool is_trigger; /* called as trigger? */
|
PLyTrigType is_trigger; /* called as trigger? */
|
||||||
PLyObToDatum result; /* Function result output conversion info */
|
PLyObToDatum result; /* Function result output conversion info */
|
||||||
PLyDatumToOb result_in; /* For converting input tuples in a trigger */
|
PLyDatumToOb result_in; /* For converting input tuples in a trigger */
|
||||||
char *src; /* textual procedure code, after mangling */
|
char *src; /* textual procedure code, after mangling */
|
||||||
@@ -65,7 +74,7 @@ typedef struct PLyProcedureEntry
|
|||||||
|
|
||||||
/* PLyProcedure manipulation */
|
/* PLyProcedure manipulation */
|
||||||
extern char *PLy_procedure_name(PLyProcedure *proc);
|
extern char *PLy_procedure_name(PLyProcedure *proc);
|
||||||
extern PLyProcedure *PLy_procedure_get(Oid fn_oid, Oid fn_rel, bool is_trigger);
|
extern PLyProcedure *PLy_procedure_get(Oid fn_oid, Oid fn_rel, PLyTrigType is_trigger);
|
||||||
extern void PLy_procedure_compile(PLyProcedure *proc, const char *src);
|
extern void PLy_procedure_compile(PLyProcedure *proc, const char *src);
|
||||||
extern void PLy_procedure_delete(PLyProcedure *proc);
|
extern void PLy_procedure_delete(PLyProcedure *proc);
|
||||||
|
|
||||||
|
@@ -1990,6 +1990,7 @@ PLyScalarToOb
|
|||||||
PLySubtransactionData
|
PLySubtransactionData
|
||||||
PLySubtransactionObject
|
PLySubtransactionObject
|
||||||
PLyTransformToOb
|
PLyTransformToOb
|
||||||
|
PLyTrigType
|
||||||
PLyTupleToOb
|
PLyTupleToOb
|
||||||
PLyUnicode_FromStringAndSize_t
|
PLyUnicode_FromStringAndSize_t
|
||||||
PLy_elog_impl_t
|
PLy_elog_impl_t
|
||||||
|
Reference in New Issue
Block a user