aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-exec.c53
-rw-r--r--src/interfaces/libpq/libpq-events.c3
-rw-r--r--src/interfaces/libpq/libpq-int.h3
3 files changed, 34 insertions, 25 deletions
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 7db303ce008..00889c8a7d7 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.198 2008/09/17 04:31:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.199 2008/09/19 16:40:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -331,10 +331,7 @@ PQcopyResult(const PGresult *src, int flags)
if (flags & PG_COPYRES_NOTICEHOOKS)
dest->noticeHooks = src->noticeHooks;
- /*
- * Wants to copy PGEvents? NB: this should be last, as we don't want
- * to trigger RESULTDESTROY events on a useless PGresult.
- */
+ /* Wants to copy PGEvents? */
if ((flags & PG_COPYRES_EVENTS) && src->nEvents > 0)
{
dest->events = dupEvents(src->events, src->nEvents);
@@ -349,15 +346,19 @@ PQcopyResult(const PGresult *src, int flags)
/* Okay, trigger PGEVT_RESULTCOPY event */
for (i = 0; i < dest->nEvents; i++)
{
- PGEventResultCopy evt;
-
- evt.src = src;
- evt.dest = dest;
- if (!dest->events[i].proc(PGEVT_RESULTCOPY, &evt,
- dest->events[i].passThrough))
+ if (src->events[i].resultInitialized)
{
- PQclear(dest);
- return NULL;
+ PGEventResultCopy evt;
+
+ evt.src = src;
+ evt.dest = dest;
+ if (!dest->events[i].proc(PGEVT_RESULTCOPY, &evt,
+ dest->events[i].passThrough))
+ {
+ PQclear(dest);
+ return NULL;
+ }
+ dest->events[i].resultInitialized = TRUE;
}
}
@@ -365,8 +366,9 @@ PQcopyResult(const PGresult *src, int flags)
}
/*
- * Copy an array of PGEvents (with no extra space for more)
- * Does not duplicate the event instance data, sets this to NULL
+ * Copy an array of PGEvents (with no extra space for more).
+ * Does not duplicate the event instance data, sets this to NULL.
+ * Also, the resultInitialized flags are all cleared.
*/
static PGEvent *
dupEvents(PGEvent *events, int count)
@@ -381,13 +383,13 @@ dupEvents(PGEvent *events, int count)
if (!newEvents)
return NULL;
- memcpy(newEvents, events, count * sizeof(PGEvent));
-
- /* NULL out the data pointers and deep copy names */
for (i = 0; i < count; i++)
{
+ newEvents[i].proc = events[i].proc;
+ newEvents[i].passThrough = events[i].passThrough;
newEvents[i].data = NULL;
- newEvents[i].name = strdup(newEvents[i].name);
+ newEvents[i].resultInitialized = FALSE;
+ newEvents[i].name = strdup(events[i].name);
if (!newEvents[i].name)
{
while (--i >= 0)
@@ -666,11 +668,15 @@ PQclear(PGresult *res)
for (i = 0; i < res->nEvents; i++)
{
- PGEventResultDestroy evt;
+ /* only send DESTROY to successfully-initialized event procs */
+ if (res->events[i].resultInitialized)
+ {
+ PGEventResultDestroy evt;
- evt.result = res;
- (void) res->events[i].proc(PGEVT_RESULTDESTROY, &evt,
- res->events[i].passThrough);
+ evt.result = res;
+ (void) res->events[i].proc(PGEVT_RESULTDESTROY, &evt,
+ res->events[i].passThrough);
+ }
free(res->events[i].name);
}
@@ -1612,6 +1618,7 @@ PQgetResult(PGconn *conn)
res->resultStatus = PGRES_FATAL_ERROR;
break;
}
+ res->events[i].resultInitialized = TRUE;
}
}
diff --git a/src/interfaces/libpq/libpq-events.c b/src/interfaces/libpq/libpq-events.c
index 7d3d1cb26c1..9f46336a58b 100644
--- a/src/interfaces/libpq/libpq-events.c
+++ b/src/interfaces/libpq/libpq-events.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-events.c,v 1.1 2008/09/17 04:31:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-events.c,v 1.2 2008/09/19 16:40:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -76,6 +76,7 @@ PQregisterEventProc(PGconn *conn, PGEventProc proc,
return FALSE;
conn->events[conn->nEvents].passThrough = passThrough;
conn->events[conn->nEvents].data = NULL;
+ conn->events[conn->nEvents].resultInitialized = FALSE;
conn->nEvents++;
regevt.conn = conn;
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index fd29c092148..b29057bde95 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.132 2008/09/17 04:31:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.133 2008/09/19 16:40:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -156,6 +156,7 @@ typedef struct PGEvent
char *name; /* used only for error messages */
void *passThrough; /* pointer supplied at registration time */
void *data; /* optional state (instance) data */
+ bool resultInitialized; /* T if RESULTCREATE/COPY succeeded */
} PGEvent;
struct pg_result