aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/trigger.c29
-rw-r--r--src/backend/executor/execMain.c39
-rw-r--r--src/pl/plpgsql/src/gram.c26
3 files changed, 51 insertions, 43 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index a5e27227cf2..aac9f2599f5 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -42,7 +42,7 @@ void FreeTriggerDesc(Relation relation);
static void DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger);
static HeapTuple GetTupleForTrigger(EState *estate, ItemPointer tid,
- bool before);
+ TupleTableSlot **newSlot);
extern GlobalMemory CacheCxt;
@@ -664,9 +664,10 @@ ExecBRDeleteTriggers(EState *estate, ItemPointer tupleid)
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
HeapTuple trigtuple;
HeapTuple newtuple = NULL;
+ TupleTableSlot *newSlot;
int i;
- trigtuple = GetTupleForTrigger(estate, tupleid, true);
+ trigtuple = GetTupleForTrigger(estate, tupleid, &newSlot);
if (trigtuple == NULL)
return false;
@@ -701,7 +702,7 @@ ExecARDeleteTriggers(EState *estate, ItemPointer tupleid)
HeapTuple trigtuple;
int i;
- trigtuple = GetTupleForTrigger(estate, tupleid, false);
+ trigtuple = GetTupleForTrigger(estate, tupleid, NULL);
Assert(trigtuple != NULL);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
@@ -732,12 +733,20 @@ ExecBRUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
HeapTuple trigtuple;
HeapTuple oldtuple;
HeapTuple intuple = newtuple;
+ TupleTableSlot *newSlot;
int i;
- trigtuple = GetTupleForTrigger(estate, tupleid, true);
+ trigtuple = GetTupleForTrigger(estate, tupleid, &newSlot);
if (trigtuple == NULL)
return NULL;
+ /*
+ * In READ COMMITTED isolevel it's possible that newtuple
+ * was changed due to concurrent update.
+ */
+ if (newSlot != NULL)
+ intuple = newtuple = ExecRemoveJunk(estate->es_junkFilter, newSlot);
+
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
SaveTriggerData->tg_event =
TRIGGER_EVENT_UPDATE | TRIGGER_EVENT_ROW | TRIGGER_EVENT_BEFORE;
@@ -770,7 +779,7 @@ ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
HeapTuple trigtuple;
int i;
- trigtuple = GetTupleForTrigger(estate, tupleid, false);
+ trigtuple = GetTupleForTrigger(estate, tupleid, NULL);
Assert(trigtuple != NULL);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
@@ -794,20 +803,21 @@ ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
extern TupleTableSlot *EvalPlanQual(EState *estate, Index rti, ItemPointer tid);
static HeapTuple
-GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
+GetTupleForTrigger(EState *estate, ItemPointer tid, TupleTableSlot **newSlot)
{
Relation relation = estate->es_result_relation_info->ri_RelationDesc;
HeapTupleData tuple;
HeapTuple result;
Buffer buffer;
- if (before)
+ if (newSlot != NULL)
{
int test;
/*
* mark tuple for update
*/
+ *newSlot = NULL;
tuple.t_self = *tid;
ltrmark:;
test = heap_mark4update(relation, &tuple, &buffer);
@@ -826,13 +836,14 @@ ltrmark:;
elog(ERROR, "Can't serialize access due to concurrent update");
else if (!(ItemPointerEquals(&(tuple.t_self), tid)))
{
- TupleTableSlot *slot = EvalPlanQual(estate,
+ TupleTableSlot *epqslot = EvalPlanQual(estate,
estate->es_result_relation_info->ri_RangeTableIndex,
&(tuple.t_self));
- if (!(TupIsNull(slot)))
+ if (!(TupIsNull(epqslot)))
{
*tid = tuple.t_self;
+ *newSlot = epqslot;
goto ltrmark;
}
}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index ba4d09eaa38..f074ce951fd 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.67 1999/01/29 10:15:09 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.68 1999/01/29 11:56:00 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -66,7 +66,7 @@ static void EndPlan(Plan *plan, EState *estate);
static TupleTableSlot *ExecutePlan(EState *estate, Plan *plan,
CmdType operation, int numberTuples, ScanDirection direction,
DestReceiver *destfunc);
-static void ExecRetrieve(TupleTableSlot *slot,
+static void ExecRetrieve(TupleTableSlot *slot,
DestReceiver *destfunc,
EState *estate);
static void ExecAppend(TupleTableSlot *slot, ItemPointer tupleid,
@@ -170,11 +170,11 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
TupleTableSlot *
ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
{
- CmdType operation;
- Plan *plan;
+ CmdType operation;
+ Plan *plan;
TupleTableSlot *result;
- CommandDest dest;
- void (*destination) ();
+ CommandDest dest;
+ DestReceiver *destfunc;
/******************
* sanity checks
@@ -190,10 +190,19 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
operation = queryDesc->operation;
plan = queryDesc->plantree;
dest = queryDesc->dest;
- destination = (void (*) ()) DestToFunction(dest);
+ destfunc = DestToFunction(dest);
estate->es_processed = 0;
estate->es_lastoid = InvalidOid;
+ /******************
+ * FIXME: the dest setup function ought to be handed the tuple desc
+ * for the tuples to be output, but I'm not quite sure how to get that
+ * info at this point. For now, passing NULL is OK because no existing
+ * dest setup function actually uses the pointer.
+ ******************
+ */
+ (*destfunc->setup) (destfunc, (TupleDesc) NULL);
+
switch (feature)
{
@@ -203,7 +212,7 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
operation,
ALL_TUPLES,
ForwardScanDirection,
- destination);
+ destfunc);
break;
case EXEC_FOR:
result = ExecutePlan(estate,
@@ -211,7 +220,7 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
operation,
count,
ForwardScanDirection,
- destination);
+ destfunc);
break;
/******************
@@ -224,7 +233,7 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
operation,
count,
BackwardScanDirection,
- destination);
+ destfunc);
break;
/******************
@@ -238,7 +247,7 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
operation,
ONE_TUPLE,
ForwardScanDirection,
- destination);
+ destfunc);
break;
default:
result = NULL;
@@ -246,6 +255,8 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count)
break;
}
+ (*destfunc->cleanup) (destfunc);
+
return result;
}
@@ -756,7 +767,7 @@ ExecutePlan(EState *estate,
CmdType operation,
int numberTuples,
ScanDirection direction,
- DestReceiver *destfunc)
+ DestReceiver* destfunc)
{
JunkFilter *junkfilter;
@@ -941,7 +952,7 @@ lmark:;
{
case CMD_SELECT:
ExecRetrieve(slot, /* slot containing tuple */
- destfunc, /* print function */
+ destfunc, /* destination's tuple-receiver obj */
estate); /* */
result = slot;
break;
@@ -1024,7 +1035,7 @@ ExecRetrieve(TupleTableSlot *slot,
* send the tuple to the front end (or the screen)
******************
*/
- (*printfunc) (tuple, attrtype);
+ (*destfunc->receiveTuple) (tuple, attrtype, destfunc);
IncrRetrieved();
(estate->es_processed)++;
}
diff --git a/src/pl/plpgsql/src/gram.c b/src/pl/plpgsql/src/gram.c
index 2d4ef46a1b1..2ca9936c32e 100644
--- a/src/pl/plpgsql/src/gram.c
+++ b/src/pl/plpgsql/src/gram.c
@@ -65,7 +65,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/gram.c,v 1.3 1999/01/28 11:50:41 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/gram.c,v 1.4 1999/01/29 11:56:01 vadim Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -414,7 +414,7 @@ static const short yycheck[] = { 21,
152, 62
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/share/bison.simple"
+#line 3 "/usr/share/misc/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -467,16 +467,6 @@ void *alloca ();
#endif /* not GNU C. */
#endif /* alloca not defined. */
-#ifdef __cplusplus
-extern "C" {
- void yyerror(char *);
- int yylex();
-};
-#else
- extern void yyerror(char *);
- extern int yylex();
-#endif
-
/* This is the parser code that is written into each bison parser
when the %semantic_parser declaration is not specified in the grammar.
It was written by Richard Stallman by simplifying the hairy parser
@@ -573,13 +563,9 @@ int yydebug; /* nonzero means print parse trace */
#define YYMAXDEPTH 10000
#endif
-#ifndef YYPARSE_RETURN_TYPE
-#define YYPARSE_RETURN_TYPE int
-#endif
-
/* Prevent warning if -Wstrict-prototypes. */
#ifdef __GNUC__
-YYPARSE_RETURN_TYPE yyparse (void);
+int yyparse (void);
#endif
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
@@ -621,7 +607,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
-#line 196 "/usr/share/bison.simple"
+#line 196 "/usr/share/misc/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -642,7 +628,7 @@ __yy_memcpy (char *to, char *from, int count)
#define YYPARSE_PARAM_DECL
#endif /* not YYPARSE_PARAM */
-YYPARSE_RETURN_TYPE
+int
yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
{
@@ -1905,7 +1891,7 @@ case 105:
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/share/bison.simple"
+#line 498 "/usr/share/misc/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;