--- lib/rserv.c 2000/12/20 17:22:35 1.1.1.1 +++ lib/rserv.c 2003/11/03 21:30:37 1.5 @@ -3,10 +3,10 @@ * (c) 2000 Vadim Mikheev, PostgreSQL Inc. */ -#include "executor/spi.h" /* this is what you need to work with SPI */ +#include "executor/spi.h" /* this is what you need to work with SPI */ #include "commands/trigger.h" /* -"- and triggers */ -#include "utils/tqual.h" /* -"- and SnapshotData */ -#include /* tolower () */ +#include "utils/tqual.h" /* -"- and SnapshotData */ +#include /* tolower () */ #ifdef PG_FUNCTION_INFO_V1 #define CurrentTriggerData ((TriggerData *) fcinfo->context) @@ -16,18 +16,22 @@ PG_FUNCTION_INFO_V1(_rserv_log_); PG_FUNCTION_INFO_V1(_rserv_sync_); PG_FUNCTION_INFO_V1(_rserv_debug_); -Datum _rserv_log_(PG_FUNCTION_ARGS); -Datum _rserv_sync_(PG_FUNCTION_ARGS); -Datum _rserv_debug_(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(_rserv_xid_); +Datum _rserv_log_(PG_FUNCTION_ARGS); +Datum _rserv_sync_(PG_FUNCTION_ARGS); +Datum _rserv_debug_(PG_FUNCTION_ARGS); +Datum _rserv_xid_(PG_FUNCTION_ARGS); + #else HeapTuple _rserv_log_(void); int32 _rserv_sync_(int32); int32 _rserv_debug_(int32); +int32 _rserv_xid_(void); #endif static int debug = 0; -static char* OutputValue(char *key, char *buf, int size); +static char *OutputValue(char *key, char *buf, int size); #ifdef PG_FUNCTION_INFO_V1 Datum @@ -42,17 +46,18 @@ char **args; /* argument: argnum */ Relation rel; /* triggered relation */ HeapTuple tuple; /* tuple to return */ - HeapTuple newtuple = NULL;/* tuple to return */ + HeapTuple newtuple = NULL; /* tuple to return */ TupleDesc tupdesc; /* tuple description */ int keynum; char *key; char *okey; char *newkey = NULL; - int deleted; + int deleted, inserted, updated; char sql[8192]; char outbuf[8192]; char oidbuf[64]; int ret; + int server; /* Called by trigger manager ? */ if (!CurrentTriggerData) @@ -68,10 +73,11 @@ nargs = trigger->tgnargs; args = trigger->tgargs; - if (nargs != 1) /* odd number of arguments! */ - elog(ERROR, "_rserv_log_: need in *one* argument"); + if (nargs != 2) /* odd number of arguments! */ + elog(ERROR, "_rserv_log_: need in *two* arguments, key number and server number"); keynum = atoi(args[0]); + server = atoi(args[1]); if (keynum < 0 && keynum != ObjectIdAttributeNumber) elog(ERROR, "_rserv_log_: invalid keynum %d", keynum); @@ -79,11 +85,18 @@ rel = CurrentTriggerData->tg_relation; tupdesc = rel->rd_att; - deleted = (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) ? + deleted = (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) ? 1 : 0; - if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) + inserted = (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) ? 1 : 0; + + updated = 0; + if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) { + updated = 1; newtuple = CurrentTriggerData->tg_newtuple; + } + +#ifndef PG_FUNCTION_INFO_V1 /* * Setting CurrentTriggerData to NULL prevents direct calls to trigger @@ -91,6 +104,7 @@ * by trigger manager code only. */ CurrentTriggerData = NULL; +#endif /* Connect to SPI manager */ if ((ret = SPI_connect()) < 0) @@ -98,7 +112,7 @@ if (keynum == ObjectIdAttributeNumber) { - sprintf(oidbuf, "%u", tuple->t_data->t_oid); + snprintf(oidbuf, sizeof(oidbuf), "%u", HeapTupleGetOid(tuple)); key = oidbuf; } else @@ -115,7 +129,7 @@ if (strcmp(newkey, key) == 0) newkey = NULL; else - deleted = 1; /* old key was deleted */ + deleted = 1; /* old key was deleted */ } if (strpbrk(key, "\\ \n'")) @@ -123,12 +137,12 @@ else okey = key; - sprintf(sql, "update _RSERV_LOG_ set logid = %d, logtime = now(), " - "deleted = %d where reloid = %u and key = '%s'", - GetCurrentTransactionId(), deleted, rel->rd_id, okey); + snprintf(sql, 8192, "update _RSERV_LOG_ set logid = %d, logtime = now(), " + "insert = %d, update = %d, delete = %d where reloid = %u and key = '%s'", + GetCurrentTransactionId(), inserted, updated, deleted, rel->rd_id, okey); if (debug) - elog(NOTICE, sql); + elog(DEBUG3, "sql: %s", sql); ret = SPI_exec(sql, 0); @@ -142,14 +156,14 @@ elog(ERROR, "_rserv_log_: duplicate tuples"); else if (SPI_processed == 0) { - sprintf(sql, "insert into _RSERV_LOG_ " - "(reloid, logid, logtime, deleted, key) " - "values (%u, %d, now(), %d, '%s')", - rel->rd_id, GetCurrentTransactionId(), - deleted, okey); + snprintf(sql, 8192, "insert into _RSERV_LOG_ " + "(reloid, logid, logtime, insert, update, delete, key, server) " + "values (%u, %d, now(), %d, %d, %d, '%s', %d)", + rel->rd_id, GetCurrentTransactionId(), + inserted, updated, deleted, okey, server); if (debug) - elog(NOTICE, sql); + elog(DEBUG3, "sql: %s", sql); ret = SPI_exec(sql, 0); @@ -167,13 +181,13 @@ else okey = newkey; - sprintf(sql, "insert into _RSERV_LOG_ " - "(reloid, logid, logtime, deleted, key) " - "values (%u, %d, now(), 0, '%s')", - rel->rd_id, GetCurrentTransactionId(), okey); + snprintf(sql, 8192, "insert into _RSERV_LOG_ " + "(reloid, logid, logtime, insert, update, deleted, key, server) " + "values (%u, %d, now(), %d, %d, 0, '%s', %d)", + rel->rd_id, GetCurrentTransactionId(), inserted, updated, okey, server); if (debug) - elog(NOTICE, sql); + elog(DEBUG3, "sql: %s", sql); ret = SPI_exec(sql, 0); @@ -202,13 +216,13 @@ #endif { #ifdef PG_FUNCTION_INFO_V1 - int32 server = PG_GETARG_INT32(0); + int32 server = PG_GETARG_INT32(0); #endif - char sql[8192]; - char buf[8192]; - char *active = buf; - uint32 xcnt; - int ret; + char sql[8192]; + char buf[8192]; + char *active = buf; + uint32 xcnt; + int ret; if (SerializableSnapshot == NULL) elog(ERROR, "_rserv_sync_: SerializableSnapshot is NULL"); @@ -216,17 +230,18 @@ buf[0] = 0; for (xcnt = 0; xcnt < SerializableSnapshot->xcnt; xcnt++) { - sprintf(buf + strlen(buf), "%s%u", (xcnt) ? ", " : "", - SerializableSnapshot->xip[xcnt]); + snprintf(buf + strlen(buf), 8192 - strlen(buf), + "%s%u", (xcnt) ? ", " : "", + SerializableSnapshot->xip[xcnt]); } if ((ret = SPI_connect()) < 0) elog(ERROR, "_rserv_sync_: SPI_connect returned %d", ret); - sprintf(sql, "insert into _RSERV_SYNC_ " - "(server, syncid, synctime, status, minid, maxid, active) " - "values (%u, currval('_rserv_sync_seq_'), now(), 0, %d, %d, '%s')", - server, SerializableSnapshot->xmin, SerializableSnapshot->xmax, active); + snprintf(sql, 8192, "insert into _RSERV_SYNC_ " + "(server, syncid, synctime, status, minid, maxid, active) " + "values (%u, currval('_rserv_sync_seq_'), now(), 0, %d, %d, '%s')", + server, SerializableSnapshot->xmin, SerializableSnapshot->xmax, active); ret = SPI_exec(sql, 0); @@ -247,18 +262,18 @@ #endif { #ifdef PG_FUNCTION_INFO_V1 - int32 newval = PG_GETARG_INT32(0); + int32 newval = PG_GETARG_INT32(0); #endif - int32 oldval = debug; + int32 oldval = debug; debug = newval; return (oldval); } -#define ExtendBy 1024 +#define ExtendBy 1024 -static char* +static char * OutputValue(char *key, char *buf, int size) { int i = 0; @@ -267,39 +282,45 @@ int slen = 0; size--; - for ( ; ; ) + for (;;) { switch (*key) { - case '\\': subst ="\\\\"; - slen = 2; - break; - case ' ': subst = "\\011"; - slen = 4; - break; - case '\n': subst = "\\012"; - slen = 4; - break; - case '\'': subst = "\\047"; - slen = 4; - break; - case '\0': out[i] = 0; - return(out); - default: slen = 1; - break; + case '\\': + subst = "\\\\"; + slen = 2; + break; + case ' ': + subst = "\\011"; + slen = 4; + break; + case '\n': + subst = "\\012"; + slen = 4; + break; + case '\'': + subst = "\\047"; + slen = 4; + break; + case '\0': + out[i] = 0; + return (out); + default: + slen = 1; + break; } if (i + slen >= size) { if (out == buf) { - out = (char*) palloc(size + ExtendBy); + out = (char *) palloc(size + ExtendBy); strncpy(out, buf, i); size += ExtendBy; } else { - out = (char*) repalloc(out, size + ExtendBy); + out = (char *) repalloc(out, size + ExtendBy); size += ExtendBy; } } @@ -314,6 +335,20 @@ key++; } - return(out); + return (out); } + +#ifdef PG_FUNCTION_INFO_V1 +Datum +_rserv_xid_(PG_FUNCTION_ARGS) +#else +int32 +_rserv_xid_(void) +#endif +{ + int32 curr_xid = GetCurrentTransactionId(); + + return (curr_xid); +} +