--- lib/rserv.c 2003/08/05 09:52:39 1.2 +++ lib/rserv.c 2003/08/06 16:14:53 1.3 @@ -31,227 +31,174 @@ static char *OutputValue(char *key, char *buf, int size); #ifdef PG_FUNCTION_INFO_V1 -Datum _rserv_log_(PG_FUNCTION_ARGS) +Datum +_rserv_log_(PG_FUNCTION_ARGS) #else -HeapTuple _rserv_log_() +HeapTuple +_rserv_log_() #endif { - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of args specified in CREATE TRIGGER */ - char **args; /* argument: argnum */ - Relation rel; /* triggered relation */ - HeapTuple tuple; /* tuple to return */ - HeapTuple newtuple = NULL; /* tuple to return */ - TupleDesc tupdesc; /* tuple description */ - int keynum; - char *key; - char *okey; - char *newkey = NULL; - int deleted, inserted, updated; - char sql[8192]; - char outbuf[8192]; - char oidbuf[64]; - int ret; - - /* Called by trigger manager ? */ - if (!CurrentTriggerData) - elog(ERROR, "_rserv_log_: triggers are not initialized"); - - /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) - elog(ERROR, "_rserv_log_: can't process STATEMENT events"); - - tuple = CurrentTriggerData->tg_trigtuple; - - trigger = CurrentTriggerData->tg_trigger; - nargs = trigger->tgnargs; - args = trigger->tgargs; - - if (nargs != 1) /* odd number of arguments! */ - elog(ERROR, "_rserv_log_: need in *one* argument"); - - keynum = atoi(args[0]); - - if (keynum < 0 && keynum != ObjectIdAttributeNumber) - elog(ERROR, "_rserv_log_: invalid keynum %d", keynum); - - rel = CurrentTriggerData->tg_relation; - tupdesc = rel->rd_att; - - deleted = (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) ? 1 : 0; - inserted = (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) ? 1 : 0; - // updated = (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) ? 1 : 0; - - updated = 0; - if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) { - updated = 1; - newtuple = CurrentTriggerData->tg_newtuple; - } + Trigger *trigger; /* to get trigger name */ + int nargs; /* # of args specified in CREATE TRIGGER */ + char **args; /* argument: argnum */ + Relation rel; /* triggered relation */ + HeapTuple tuple; /* tuple to return */ + HeapTuple newtuple = NULL; /* tuple to return */ + TupleDesc tupdesc; /* tuple description */ + int keynum; + char *key; + char *okey; + char *newkey = NULL; + int deleted, inserted, updated; + char sql[8192]; + char outbuf[8192]; + char oidbuf[64]; + int ret; + + /* Called by trigger manager ? */ + if (!CurrentTriggerData) + elog(ERROR, "_rserv_log_: triggers are not initialized"); + + /* Should be called for ROW trigger */ + if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + elog(ERROR, "_rserv_log_: can't process STATEMENT events"); + + tuple = CurrentTriggerData->tg_trigtuple; + + trigger = CurrentTriggerData->tg_trigger; + nargs = trigger->tgnargs; + args = trigger->tgargs; + + if (nargs != 1) /* odd number of arguments! */ + elog(ERROR, "_rserv_log_: need in *one* argument"); + + keynum = atoi(args[0]); + + if (keynum < 0 && keynum != ObjectIdAttributeNumber) + elog(ERROR, "_rserv_log_: invalid keynum %d", keynum); + + rel = CurrentTriggerData->tg_relation; + tupdesc = rel->rd_att; + + deleted = (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) ? + 1 : 0; + + 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 - * functions in queries. Normally, trigger functions have to be called - * by trigger manager code only. - */ - CurrentTriggerData = NULL; + + /* + * Setting CurrentTriggerData to NULL prevents direct calls to trigger + * functions in queries. Normally, trigger functions have to be called + * by trigger manager code only. + */ + CurrentTriggerData = NULL; #endif - - /* Connect to SPI manager */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "_rserv_log_: SPI_connect returned %d", ret); - - if (keynum == ObjectIdAttributeNumber) { - sprintf(oidbuf, "%u", tuple->t_data->t_oid); - key = oidbuf; - } else { - key = SPI_getvalue(tuple, tupdesc, keynum); - } - - if (key == NULL) - elog(ERROR, "_rserv_log_: key must be not null"); - - if (newtuple && keynum != ObjectIdAttributeNumber) { - newkey = SPI_getvalue(newtuple, tupdesc, keynum); - if (newkey == NULL) - elog(ERROR, "_rserv_log_: key must be not null"); - if (strcmp(newkey, key) == 0) - newkey = NULL; - else - deleted = 1; /* old key was deleted */ - } - - if (strpbrk(key, "\\ \n'")) - okey = OutputValue(key, outbuf, sizeof(outbuf)); - else - okey = key; - - - /** - versao onde verifica-se primeiro se o registro existe - para decidir se faz insert ou update em _RSERV_LOG_ - **********************/ - -#ifdef ASKFORUPDATE - sprintf(sql, "SELECT true WHERE EXISTS (SELECT logid from _RSERV_LOG_ " - "WHERE reloid = %u AND key = '%s')", - rel->rd_id, okey); - - if (debug) - elog(NOTICE, sql); - - if ((ret = SPI_exec(sql, 1)) < 0) { - elog(ERROR, "_rserv_log_: SPI_exec(update) returned %d", ret); - } - - if (SPI_processed > 0) { - sprintf(sql, "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); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec(update) returned %d", ret); - - if (SPI_processed > 1) - elog(ERROR, "_rserv_log_: duplicate tuples"); - } else { - sprintf(sql, "insert into _RSERV_LOG_ " - "(reloid, logid, logtime, insert, update, delete, key) " - "values (%u, %d, now(), %d, %d, %d, '%s')", - rel->rd_id, GetCurrentTransactionId(), - inserted, updated, deleted, okey); - - if (debug) - elog(NOTICE, sql); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec(insert) returned %d", ret); - } -#else - - sprintf(sql, "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); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec(update) returned %d", ret); - - - /* - * If no tuple was UPDATEd then do INSERT... - */ - - - if (SPI_processed > 1) - elog(ERROR, "_rserv_log_: duplicate tuples"); - else if (SPI_processed == 0) { - sprintf(sql, "insert into _RSERV_LOG_ " - "(reloid, logid, logtime, insert, update, delete, key) " - "values (%u, %d, now(), %d, %d, %d, '%s')", - rel->rd_id, GetCurrentTransactionId(), - inserted, updated, deleted, okey); - - if (debug) - elog(NOTICE, sql); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec(insert) returned %d", ret); - } - -#endif - - if (okey != key && okey != outbuf) - pfree(okey); - - if (newkey) { - if (strpbrk(newkey, "\\ \n'")) - okey = OutputValue(newkey, outbuf, sizeof(outbuf)); - else - okey = newkey; - - sprintf(sql, "insert into _RSERV_LOG_ " - "(reloid, logid, logtime, insert, update, delete, key) " - "values (%u, %d, now(), %d, %d, 0, '%s')", - rel->rd_id, GetCurrentTransactionId(), inserted, updated, okey); - - if (debug) - elog(NOTICE, sql); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec returned %d", ret); - - if (okey != newkey && okey != outbuf) - pfree(okey); - } - - SPI_finish(); - + /* Connect to SPI manager */ + if ((ret = SPI_connect()) < 0) + elog(ERROR, "_rserv_log_: SPI_connect returned %d", ret); + + if (keynum == ObjectIdAttributeNumber) + { + snprintf(oidbuf, sizeof(oidbuf), "%u", HeapTupleGetOid(tuple)); + key = oidbuf; + } + else + key = SPI_getvalue(tuple, tupdesc, keynum); + + if (key == NULL) + elog(ERROR, "_rserv_log_: key must be not null"); + + if (newtuple && keynum != ObjectIdAttributeNumber) + { + newkey = SPI_getvalue(newtuple, tupdesc, keynum); + if (newkey == NULL) + elog(ERROR, "_rserv_log_: key must be not null"); + if (strcmp(newkey, key) == 0) + newkey = NULL; + else + deleted = 1; /* old key was deleted */ + } + + if (strpbrk(key, "\\ \n'")) + okey = OutputValue(key, outbuf, sizeof(outbuf)); + else + okey = key; + + 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(DEBUG3, "sql: %s", sql); + + ret = SPI_exec(sql, 0); + + if (ret < 0) + elog(ERROR, "_rserv_log_: SPI_exec(update) returned %d", ret); + + /* + * If no tuple was UPDATEd then do INSERT... + */ + if (SPI_processed > 1) + elog(ERROR, "_rserv_log_: duplicate tuples"); + else if (SPI_processed == 0) + { + snprintf(sql, 8192, "insert into _RSERV_LOG_ " + "(reloid, logid, logtime, insert, update, delete, key) " + "values (%u, %d, now(), %d, %d, %d, '%s')", + rel->rd_id, GetCurrentTransactionId(), + inserted, updated, deleted, okey); + + if (debug) + elog(DEBUG3, "sql: %s", sql); + + ret = SPI_exec(sql, 0); + + if (ret < 0) + elog(ERROR, "_rserv_log_: SPI_exec(insert) returned %d", ret); + } + + if (okey != key && okey != outbuf) + pfree(okey); + + if (newkey) + { + if (strpbrk(newkey, "\\ \n'")) + okey = OutputValue(newkey, outbuf, sizeof(outbuf)); + else + okey = newkey; + + snprintf(sql, 8192, "insert into _RSERV_LOG_ " + "(reloid, logid, logtime, insert, update, deleted, key) " + "values (%u, %d, now(), %d, %d, 0, '%s')", + rel->rd_id, GetCurrentTransactionId(), inserted, updated, okey); + + if (debug) + elog(DEBUG3, "sql: %s", sql); + + ret = SPI_exec(sql, 0); + + if (ret < 0) + elog(ERROR, "_rserv_log_: SPI_exec returned %d", ret); + + if (okey != newkey && okey != outbuf) + pfree(okey); + } + + SPI_finish(); + #ifdef PG_FUNCTION_INFO_V1 - return (PointerGetDatum(tuple)); + return (PointerGetDatum(tuple)); #else - return (tuple); + return (tuple); #endif } @@ -278,17 +225,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) " + 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); + server, SerializableSnapshot->xmin, SerializableSnapshot->xmax, active); ret = SPI_exec(sql, 0);