1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

Cleanups.

This commit is contained in:
Vadim B. Mikheev
1997-09-11 07:24:37 +00:00
parent b6f348cd33
commit a74613f478
4 changed files with 281 additions and 62 deletions

View File

@ -19,6 +19,7 @@
#include "catalog/pg_trigger.h" #include "catalog/pg_trigger.h"
#include "access/genam.h" #include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/valid.h"
#include "access/xact.h" #include "access/xact.h"
#include "storage/lmgr.h" #include "storage/lmgr.h"
#include "storage/bufmgr.h" #include "storage/bufmgr.h"
@ -38,6 +39,9 @@ void RelationBuildTriggers(Relation relation);
void FreeTriggerDesc(Relation relation); void FreeTriggerDesc(Relation relation);
static void DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger); static void DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger);
static HeapTuple
GetTupleForTrigger(Relation relation, ItemPointer tid,
bool before);
extern void fmgr_info(Oid procedureId, func_ptr * function, int *nargs); extern void fmgr_info(Oid procedureId, func_ptr * function, int *nargs);
extern GlobalMemory CacheCxt; extern GlobalMemory CacheCxt;
@ -555,21 +559,90 @@ DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger)
} }
HeapTuple HeapTuple
ExecBRInsertTriggers(Relation rel, HeapTuple tuple) ExecBRInsertTriggers(Relation rel, HeapTuple trigtuple)
{ {
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT]; int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT]; Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
HeapTuple newtuple = tuple; HeapTuple newtuple = trigtuple;
HeapTuple oldtuple;
int nargs; int nargs;
int i; int i;
CurrentTriggerData = (TriggerData *) palloc(sizeof(TriggerData)); SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
CurrentTriggerData->tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW; SaveTriggerData->tg_event =
CurrentTriggerData->tg_relation = rel; TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW | TRIGGER_EVENT_BEFORE;
CurrentTriggerData->tg_newtuple = NULL; SaveTriggerData->tg_relation = rel;
SaveTriggerData->tg_newtuple = NULL;
for (i = 0; i < ntrigs; i++) for (i = 0; i < ntrigs; i++)
{ {
CurrentTriggerData->tg_trigtuple = newtuple; CurrentTriggerData = SaveTriggerData;
CurrentTriggerData->tg_trigtuple = oldtuple = newtuple;
CurrentTriggerData->tg_trigger = trigger[i];
if (trigger[i]->tgfunc == NULL)
fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
if (newtuple == NULL)
break;
else if (oldtuple != newtuple && oldtuple != trigtuple)
pfree(oldtuple);
}
CurrentTriggerData = NULL;
pfree(SaveTriggerData);
return (newtuple);
}
void
ExecARInsertTriggers(Relation rel, HeapTuple trigtuple)
{
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT];
Trigger **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_INSERT];
int nargs;
int i;
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
SaveTriggerData->tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
SaveTriggerData->tg_relation = rel;
SaveTriggerData->tg_newtuple = NULL;
for (i = 0; i < ntrigs; i++)
{
CurrentTriggerData = SaveTriggerData;
CurrentTriggerData->tg_trigtuple = trigtuple;
CurrentTriggerData->tg_trigger = trigger[i];
if (trigger[i]->tgfunc == NULL)
fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
(void) ((*(trigger[i]->tgfunc)) ());
}
CurrentTriggerData = NULL;
pfree(SaveTriggerData);
return;
}
bool
ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
{
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_DELETE];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
HeapTuple trigtuple;
HeapTuple newtuple = NULL;
int nargs;
int i;
trigtuple = GetTupleForTrigger(rel, tupleid, true);
if (trigtuple == NULL)
return (false);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
SaveTriggerData->tg_event =
TRIGGER_EVENT_DELETE | TRIGGER_EVENT_ROW | TRIGGER_EVENT_BEFORE;
SaveTriggerData->tg_relation = rel;
SaveTriggerData->tg_newtuple = NULL;
for (i = 0; i < ntrigs; i++)
{
CurrentTriggerData = SaveTriggerData;
CurrentTriggerData->tg_trigtuple = trigtuple;
CurrentTriggerData->tg_trigger = trigger[i]; CurrentTriggerData->tg_trigger = trigger[i];
if (trigger[i]->tgfunc == NULL) if (trigger[i]->tgfunc == NULL)
fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs); fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
@ -577,42 +650,158 @@ ExecBRInsertTriggers(Relation rel, HeapTuple tuple)
if (newtuple == NULL) if (newtuple == NULL)
break; break;
} }
pfree(CurrentTriggerData);
CurrentTriggerData = NULL; CurrentTriggerData = NULL;
return (newtuple); pfree(SaveTriggerData);
} pfree(trigtuple);
void return ((newtuple == NULL) ? false : true);
ExecARInsertTriggers(Relation rel, HeapTuple tuple)
{
return;
}
bool
ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
{
return (true);
} }
void void
ExecARDeleteTriggers(Relation rel, ItemPointer tupleid) ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
{ {
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE];
Trigger **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_DELETE];
HeapTuple trigtuple;
int nargs;
int i;
trigtuple = GetTupleForTrigger(rel, tupleid, false);
Assert(trigtuple != NULL);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
SaveTriggerData->tg_event =
TRIGGER_EVENT_DELETE | TRIGGER_EVENT_ROW;
SaveTriggerData->tg_relation = rel;
SaveTriggerData->tg_newtuple = NULL;
for (i = 0; i < ntrigs; i++)
{
CurrentTriggerData = SaveTriggerData;
CurrentTriggerData->tg_trigtuple = trigtuple;
CurrentTriggerData->tg_trigger = trigger[i];
if (trigger[i]->tgfunc == NULL)
fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
(void) ((*(trigger[i]->tgfunc)) ());
}
CurrentTriggerData = NULL;
pfree(SaveTriggerData);
pfree(trigtuple);
return; return;
} }
HeapTuple HeapTuple
ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple) ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
{ {
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
HeapTuple trigtuple;
HeapTuple oldtuple;
HeapTuple intuple = newtuple;
int nargs;
int i;
return (tuple); trigtuple = GetTupleForTrigger(rel, tupleid, true);
if (trigtuple == NULL)
return (NULL);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
SaveTriggerData->tg_event =
TRIGGER_EVENT_UPDATE | TRIGGER_EVENT_ROW | TRIGGER_EVENT_BEFORE;
SaveTriggerData->tg_relation = rel;
for (i = 0; i < ntrigs; i++)
{
CurrentTriggerData = SaveTriggerData;
CurrentTriggerData->tg_trigtuple = trigtuple;
CurrentTriggerData->tg_newtuple = oldtuple = newtuple;
CurrentTriggerData->tg_trigger = trigger[i];
if (trigger[i]->tgfunc == NULL)
fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
if (newtuple == NULL)
break;
else if (oldtuple != newtuple && oldtuple != intuple)
pfree(oldtuple);
}
CurrentTriggerData = NULL;
pfree(SaveTriggerData);
pfree(trigtuple);
return (newtuple);
} }
void void
ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple) ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
{ {
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE];
Trigger **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_UPDATE];
HeapTuple trigtuple;
int nargs;
int i;
trigtuple = GetTupleForTrigger(rel, tupleid, false);
Assert(trigtuple != NULL);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
SaveTriggerData->tg_event =
TRIGGER_EVENT_UPDATE | TRIGGER_EVENT_ROW;
SaveTriggerData->tg_relation = rel;
for (i = 0; i < ntrigs; i++)
{
CurrentTriggerData = SaveTriggerData;
CurrentTriggerData->tg_trigtuple = trigtuple;
CurrentTriggerData->tg_newtuple = newtuple;
CurrentTriggerData->tg_trigger = trigger[i];
if (trigger[i]->tgfunc == NULL)
fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
(void) ((*(trigger[i]->tgfunc)) ());
}
CurrentTriggerData = NULL;
pfree(SaveTriggerData);
pfree(trigtuple);
return; return;
} }
static HeapTuple
GetTupleForTrigger(Relation relation, ItemPointer tid, bool before)
{
ItemId lp;
HeapTuple tuple;
PageHeader dp;
Buffer b;
b = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
if (!BufferIsValid(b))
elog(WARN, "GetTupleForTrigger: failed ReadBuffer");
dp = (PageHeader) BufferGetPage(b);
lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsUsed(lp));
tuple = (HeapTuple) PageGetItem((Page) dp, lp);
if (before)
{
if (TupleUpdatedByCurXactAndCmd(tuple))
{
elog(NOTICE, "GetTupleForTrigger: Non-functional delete/update");
ReleaseBuffer(b);
return (NULL);
}
if (!(tuple = heap_tuple_satisfies(lp, relation, b, dp,
NowTimeQual, 0, (ScanKey) NULL)))
{
ReleaseBuffer(b);
elog(WARN, "GetTupleForTrigger: (am)invalid tid");
}
}
tuple = heap_copytuple(tuple);
ReleaseBuffer(b);
return (tuple);
}

View File

@ -50,7 +50,11 @@ static int
_SPI_execute_plan(_SPI_plan * plan, _SPI_execute_plan(_SPI_plan * plan,
char **Values, char *Nulls, int tcount); char **Values, char *Nulls, int tcount);
static _SPI_plan *_SPI_copy_plan(_SPI_plan *plan, bool local); #define _SPI_CPLAN_CURCXT 0
#define _SPI_CPLAN_PROCXT 1
#define _SPI_CPLAN_TOPCXT 2
static _SPI_plan *_SPI_copy_plan(_SPI_plan * plan, int location);
static int _SPI_begin_call(bool execmem); static int _SPI_begin_call(bool execmem);
static int _SPI_end_call(bool procmem); static int _SPI_end_call(bool procmem);
@ -108,7 +112,7 @@ SPI_connect()
if (_SPI_connected <= -1) if (_SPI_connected <= -1)
elog(FATAL, "SPI_connect: some connection(s) expected"); elog(FATAL, "SPI_connect: some connection(s) expected");
_SPI_stack = (_SPI_connection *) realloc(_SPI_stack, _SPI_stack = (_SPI_connection *) realloc(_SPI_stack,
(_SPI_connected + 1) * sizeof(_SPI_connection)); (_SPI_connected + 2) * sizeof(_SPI_connection));
} }
/* /*
@ -202,14 +206,16 @@ SPI_execp(void *plan, char **Values, char *Nulls, int tcount)
if (plan == NULL || tcount < 0) if (plan == NULL || tcount < 0)
return (SPI_ERROR_ARGUMENT); return (SPI_ERROR_ARGUMENT);
if (((_SPI_plan *) plan)->nargs > 0 && if (((_SPI_plan *) plan)->nargs > 0 && Values == NULL)
(Values == NULL || Nulls == NULL))
return (SPI_ERROR_PARAM); return (SPI_ERROR_PARAM);
res = _SPI_begin_call(true); res = _SPI_begin_call(true);
if (res < 0) if (res < 0)
return (res); return (res);
/* copy plan to current (executor) context */
plan = (void *) _SPI_copy_plan(plan, _SPI_CPLAN_CURCXT);
res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, tcount); res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, tcount);
_SPI_end_call(true); _SPI_end_call(true);
@ -237,8 +243,8 @@ SPI_prepare(char *src, int nargs, Oid *argtypes)
SPI_result = _SPI_execute(src, 0, plan); SPI_result = _SPI_execute(src, 0, plan);
if (SPI_result >= 0) /* copy plan to local space */ if (SPI_result >= 0) /* copy plan to procedure context */
plan = _SPI_copy_plan(plan, true); plan = _SPI_copy_plan(plan, _SPI_CPLAN_PROCXT);
else else
plan = NULL; plan = NULL;
@ -263,7 +269,7 @@ SPI_saveplan(void *plan)
if (SPI_result < 0) if (SPI_result < 0)
return (NULL); return (NULL);
newplan = _SPI_copy_plan((_SPI_plan *) plan, false); newplan = _SPI_copy_plan((_SPI_plan *) plan, _SPI_CPLAN_TOPCXT);
_SPI_curid--; _SPI_curid--;
SPI_result = 0; SPI_result = 0;
@ -289,6 +295,27 @@ SPI_fnumber(TupleDesc tupdesc, char *fname)
return (SPI_ERROR_NOATTRIBUTE); return (SPI_ERROR_NOATTRIBUTE);
} }
char *
SPI_fname(TupleDesc tupdesc, int fnumber)
{
SPI_result = 0;
if (_SPI_curid + 1 != _SPI_connected)
{
SPI_result = SPI_ERROR_UNCONNECTED;
return (NULL);
}
if (tupdesc->natts < fnumber || fnumber <= 0)
{
SPI_result = SPI_ERROR_NOATTRIBUTE;
return (NULL);
}
return (nameout(&(tupdesc->attrs[fnumber - 1]->attname)));
}
char * char *
SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
{ {
@ -606,7 +633,7 @@ _SPI_execute_plan(_SPI_plan *plan, char **Values, char *Nulls, int tcount)
{ {
paramLI->kind = PARAM_NUM; paramLI->kind = PARAM_NUM;
paramLI->id = k + 1; paramLI->id = k + 1;
paramLI->isnull = (Nulls[k] != 0); paramLI->isnull = (Nulls != NULL && Nulls[k] != 'n');
paramLI->value = (Datum) Values[k]; paramLI->value = (Datum) Values[k];
} }
paramLI->kind = PARAM_INVALID; paramLI->kind = PARAM_INVALID;
@ -692,7 +719,7 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
return (SPI_OK_CURSOR); return (SPI_OK_CURSOR);
} }
ExecutorRun(queryDesc, state, EXEC_RUN, tcount); ExecutorRun(queryDesc, state, EXEC_FOR, tcount);
_SPI_current->processed = state->es_processed; _SPI_current->processed = state->es_processed;
if (operation == CMD_SELECT && queryDesc->dest == SPI) if (operation == CMD_SELECT && queryDesc->dest == SPI)
@ -864,16 +891,16 @@ _SPI_checktuples(bool isRetrieveIntoRelation)
} }
static _SPI_plan * static _SPI_plan *
_SPI_copy_plan(_SPI_plan *plan, bool local) _SPI_copy_plan(_SPI_plan * plan, int location)
{ {
_SPI_plan *newplan; _SPI_plan *newplan;
MemoryContext oldcxt; MemoryContext oldcxt = NULL;
int i; int i;
if (local) if (location == _SPI_CPLAN_PROCXT)
oldcxt = MemoryContextSwitchTo((MemoryContext) oldcxt = MemoryContextSwitchTo((MemoryContext)
PortalGetVariableMemory(_SPI_current->portal)); PortalGetVariableMemory(_SPI_current->portal));
else else if (location == _SPI_CPLAN_TOPCXT)
oldcxt = MemoryContextSwitchTo(TopMemoryContext); oldcxt = MemoryContextSwitchTo(TopMemoryContext);
newplan = (_SPI_plan *) palloc(sizeof(_SPI_plan)); newplan = (_SPI_plan *) palloc(sizeof(_SPI_plan));
@ -895,6 +922,7 @@ _SPI_copy_plan(_SPI_plan *plan, bool local)
else else
newplan->argtypes = NULL; newplan->argtypes = NULL;
if (location != _SPI_CPLAN_CURCXT)
MemoryContextSwitchTo(oldcxt); MemoryContextSwitchTo(oldcxt);
return (newplan); return (newplan);

View File

@ -28,6 +28,7 @@
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/mcxt.h" #include "utils/mcxt.h"
#include "utils/portal.h" #include "utils/portal.h"
#include "utils/builtins.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/xact.h" #include "access/xact.h"
@ -77,6 +78,7 @@ extern void *SPI_prepare(char *src, int nargs, Oid *argtypes);
extern void *SPI_saveplan(void *plan); extern void *SPI_saveplan(void *plan);
extern int SPI_fnumber(TupleDesc tupdesc, char *fname); extern int SPI_fnumber(TupleDesc tupdesc, char *fname);
extern char *SPI_fname(TupleDesc tupdesc, int fnumber);
extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber); extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);
extern char *SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull); extern char *SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull);
extern char *SPI_gettype(TupleDesc tupdesc, int fnumber); extern char *SPI_gettype(TupleDesc tupdesc, int fnumber);