diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/interfaces/libpq/fe-exec.c | 53 | ||||
-rw-r--r-- | src/interfaces/libpq/libpq-events.c | 3 | ||||
-rw-r--r-- | src/interfaces/libpq/libpq-int.h | 3 |
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 |