11/****************************************************************************
22 * pending.c
3- * $Id: pending.c,v 1.21 2005/03/29 00:16:48 tgl Exp $
4- * $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.21 2005/03/29 00:16:48 tgl Exp $
3+ * $Id: pending.c,v 1.22 2005/10/02 23:50:05 tgl Exp $
4+ * $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.22 2005/10/02 23:50:05 tgl Exp $
55 *
66 * This file contains a trigger for Postgresql-7.x to record changes to tables
77 * to a pending table for mirroring.
3030 *
3131 *
3232 ***************************************************************************/
33- #include < postgres.h>
33+ #include " postgres.h"
3434
35- #include <executor/spi.h>
36- #include <commands/trigger.h>
37- #include <utils/lsyscache.h>
38- #include <utils/array.h>
35+ #include "executor/spi.h"
36+ #include "commands/sequence.h"
37+ #include "commands/trigger.h"
38+ #include "utils/lsyscache.h"
39+ #include "utils/array.h"
3940
4041enum FieldUsage
4142{
@@ -81,11 +82,11 @@ PG_FUNCTION_INFO_V1(recordchange);
8182
8283
8384
84- extern Datum nextval (PG_FUNCTION_ARGS );
85- extern Datum setval (PG_FUNCTION_ARGS );
85+ extern Datum setval_mirror (PG_FUNCTION_ARGS );
86+ extern Datum setval3_mirror (PG_FUNCTION_ARGS );
87+ extern Datum nextval_mirror (PG_FUNCTION_ARGS );
8688
87- int saveSequenceUpdate (const text * sequenceName ,
88- int nextSequenceValue );
89+ static void saveSequenceUpdate (Oid relid ,int64 nextValue ,bool iscalled );
8990
9091
9192/*****************************************************************************
@@ -310,11 +311,9 @@ storeKeyInfo(char *cpTableName, HeapTuple tTupleData,
310311SPI_pfree (cpKeyData );
311312
312313if (iRetCode != SPI_OK_INSERT )
313- {
314- ereport (ERROR , (errcode (ERRCODE_TRIGGERED_ACTION_EXCEPTION )
315- ,errmsg ("error inserting row in pendingDelete" )));
316- return -1 ;
317- }
314+ ereport (ERROR ,
315+ (errcode (ERRCODE_TRIGGERED_ACTION_EXCEPTION ),
316+ errmsg ("error inserting row in pendingDelete" )));
318317
319318debug_msg ("insert successful" );
320319
@@ -583,161 +582,75 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc, Oid tableOid,
583582}
584583
585584
586- PG_FUNCTION_INFO_V1 (setval );
585+ /*
586+ * Support for mirroring sequence objects.
587+ */
588+
589+ PG_FUNCTION_INFO_V1 (setval_mirror );
587590
588591Datum
589- setval (PG_FUNCTION_ARGS )
592+ setval_mirror (PG_FUNCTION_ARGS )
590593{
594+ Oid relid = PG_GETARG_OID (0 );
595+ int64 next = PG_GETARG_INT64 (1 );
596+ int64 result ;
591597
598+ result = DatumGetInt64 (DirectFunctionCall2 (setval_oid ,
599+ ObjectIdGetDatum (relid ),
600+ Int64GetDatum (next )));
592601
593- text * sequenceName ;
594-
595- Oid setvalArgTypes [3 ]= {TEXTOID ,INT4OID ,BOOLOID };
596- int nextValue ;
597- void * setvalPlan = NULL ;
598- Datum setvalData [3 ];
599- const char * setvalQuery = "SELECT setval_pg($1,$2,$3)" ;
600- int ret ;
601- char is_called ;
602-
603- sequenceName = PG_GETARG_TEXT_P (0 );
604- nextValue = PG_GETARG_INT32 (1 );
605- is_called = PG_GETARG_BOOL (2 );
606-
607- setvalData [0 ]= PointerGetDatum (sequenceName );
608- setvalData [1 ]= Int32GetDatum (nextValue );
609- if (PG_NARGS ()> 2 )
610- {
611- setvalData [2 ]= BoolGetDatum (is_called );
612- }
613- else
614- {
615- setvalData [2 ]= 1 ;
616- }
617-
618- if (SPI_connect ()< 0 )
619- {
620- ereport (ERROR , (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
621- errmsg ("dbmirror:setval could not connect to SPI" )));
622- return -1 ;
623- }
624-
625- setvalPlan = SPI_prepare (setvalQuery ,3 ,setvalArgTypes );
626- if (setvalPlan == NULL )
627- {
628- ereport (ERROR , (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
629- errmsg ("dbmirror:setval could not prepare plan" )));
630- return -1 ;
631- }
632-
633- ret = SPI_execp (setvalPlan ,setvalData ,NULL ,1 );
634-
635- if (ret != SPI_OK_SELECT || SPI_processed != 1 )
636- return -1 ;
637-
638- debug_msg2 ("dbmirror:setval: setval_pg returned ok:%d" ,nextValue );
639-
640- ret = saveSequenceUpdate (sequenceName ,nextValue );
641-
642- SPI_pfree (setvalPlan );
643-
644- SPI_finish ();
645- debug_msg ("dbmirror:setval about to return" );
646- return Int64GetDatum (nextValue );
602+ saveSequenceUpdate (relid ,result , true);
647603
604+ PG_RETURN_INT64 (result );
648605}
649606
650-
651-
652- PG_FUNCTION_INFO_V1 (nextval );
607+ PG_FUNCTION_INFO_V1 (setval3_mirror );
653608
654609Datum
655- nextval (PG_FUNCTION_ARGS )
610+ setval3_mirror (PG_FUNCTION_ARGS )
656611{
657- text * sequenceName ;
658-
659- const char * nextvalQuery = "SELECT nextval_pg($1)" ;
660- Oid nextvalArgTypes [1 ]= {TEXTOID };
661- void * nextvalPlan = NULL ;
662- Datum nextvalData [1 ];
663-
664-
665- int ret ;
666- HeapTuple resTuple ;
667- char isNull ;
668- int nextSequenceValue ;
669-
670-
671-
672- debug_msg ("dbmirror:nextval Starting pending.so:nextval" );
673-
674-
675- sequenceName = PG_GETARG_TEXT_P (0 );
676-
677- if (SPI_connect ()< 0 )
678- {
679- ereport (ERROR , (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
680- errmsg ("dbmirror:nextval could not connect to SPI" )));
681- return -1 ;
682- }
683-
684- nextvalPlan = SPI_prepare (nextvalQuery ,1 ,nextvalArgTypes );
685-
686-
687- debug_msg ("prepared plan to call nextval_pg" );
688-
689-
690- if (nextvalPlan == NULL )
691- {
692- ereport (ERROR , (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
693- errmsg ("dbmirror:nextval error creating plan" )));
694- return -1 ;
695- }
696- nextvalData [0 ]= PointerGetDatum (sequenceName );
697-
698- ret = SPI_execp (nextvalPlan ,nextvalData ,NULL ,1 );
699-
700- debug_msg ("dbmirror:Executed call to nextval_pg" );
701-
702-
703- if (ret != SPI_OK_SELECT || SPI_processed != 1 )
704- return -1 ;
705-
706- resTuple = SPI_tuptable -> vals [0 ];
612+ Oid relid = PG_GETARG_OID (0 );
613+ int64 next = PG_GETARG_INT64 (1 );
614+ bool iscalled = PG_GETARG_BOOL (2 );
615+ int64 result ;
707616
708- debug_msg ("dbmirror:nextval Set resTuple" );
709-
710- nextSequenceValue = * (unsignedint * ) (DatumGetPointer (SPI_getbinval (resTuple ,
711- SPI_tuptable -> tupdesc ,
712- 1 ,& isNull )));
617+ result = DatumGetInt64 (DirectFunctionCall3 (setval3_oid ,
618+ ObjectIdGetDatum (relid ),
619+ Int64GetDatum (next ),
620+ BoolGetDatum (iscalled )));
713621
622+ saveSequenceUpdate (relid ,result ,iscalled );
714623
624+ PG_RETURN_INT64 (result );
625+ }
715626
716- debug_msg2 ( "dbmirror:nextval Set SPI_getbinval:%d" , nextSequenceValue );
627+ PG_FUNCTION_INFO_V1 ( nextval_mirror );
717628
629+ Datum
630+ nextval_mirror (PG_FUNCTION_ARGS )
631+ {
632+ Oid relid = PG_GETARG_OID (0 );
633+ int64 result ;
718634
719- saveSequenceUpdate (sequenceName ,nextSequenceValue );
720- SPI_pfree (resTuple );
721- SPI_pfree (nextvalPlan );
635+ result = DatumGetInt64 (DirectFunctionCall1 (nextval_oid ,
636+ ObjectIdGetDatum (relid )));
722637
723- SPI_finish ( );
638+ saveSequenceUpdate ( relid , result , true );
724639
725- return Int64GetDatum ( nextSequenceValue );
640+ PG_RETURN_INT64 ( result );
726641}
727642
728643
729- int
730- saveSequenceUpdate (const text * sequenceName ,
731- int nextSequenceVal )
644+ static void
645+ saveSequenceUpdate (Oid relid ,int64 nextValue ,bool iscalled )
732646{
733-
734- Oid insertArgTypes [2 ]= {TEXTOID ,INT4OID };
647+ Oid insertArgTypes [2 ]= {NAMEOID ,INT4OID };
735648Oid insertDataArgTypes [1 ]= {NAMEOID };
736- void * insertPlan = NULL ;
737- void * insertDataPlan = NULL ;
649+ void * insertPlan ;
650+ void * insertDataPlan ;
738651Datum insertDatum [2 ];
739652Datum insertDataDatum [1 ];
740- char nextSequenceText [32 ];
653+ char nextSequenceText [64 ];
741654
742655const char * insertQuery =
743656"INSERT INTO dbmirror_Pending (TableName,Op,XID) VALUES" \
@@ -746,36 +659,50 @@ saveSequenceUpdate(const text *sequenceName,
746659"INSERT INTO dbmirror_PendingData(SeqId,IsKey,Data) VALUES " \
747660"(currval('dbmirror_pending_seqid_seq'),'t',$1)" ;
748661
749- int ret ;
750-
662+ if (SPI_connect ()< 0 )
663+ ereport (ERROR ,
664+ (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
665+ errmsg ("dbmirror:savesequenceupdate could not connect to SPI" )));
751666
752667insertPlan = SPI_prepare (insertQuery ,2 ,insertArgTypes );
753668insertDataPlan = SPI_prepare (insertDataQuery ,1 ,insertDataArgTypes );
754669
755- debug_msg ("Prepared insert query" );
756-
757-
758670if (insertPlan == NULL || insertDataPlan == NULL )
759- ereport (ERROR , (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),errmsg ("dbmirror:nextval error creating plan" )));
671+ ereport (ERROR ,
672+ (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
673+ errmsg ("dbmirror:savesequenceupdate error creating plan" )));
760674
675+ insertDatum [0 ]= PointerGetDatum (get_rel_name (relid ));
761676insertDatum [1 ]= Int32GetDatum (GetCurrentTransactionId ());
762- insertDatum [0 ]= PointerGetDatum (sequenceName );
763677
764- sprintf (nextSequenceText ,"%d" ,nextSequenceVal );
678+ snprintf (nextSequenceText ,sizeof (nextSequenceText ),
679+ INT64_FORMAT ",'%c'" ,
680+ nextValue ,iscalled ?'t' :'f' );
681+
682+ /*
683+ * note type cheat here: we prepare a C string and then claim it is a
684+ * NAME, which the system will coerce to varchar for us.
685+ */
765686insertDataDatum [0 ]= PointerGetDatum (nextSequenceText );
766- debug_msg2 ("dbmirror:savesequenceupdate: Setting value %s" ,
687+
688+ debug_msg2 ("dbmirror:savesequenceupdate: Setting value as %s" ,
767689nextSequenceText );
768690
769691debug_msg ("dbmirror:About to execute insert query" );
770692
771- ret = SPI_execp (insertPlan ,insertDatum ,NULL ,1 );
693+ if (SPI_execp (insertPlan ,insertDatum ,NULL ,1 )!= SPI_OK_INSERT )
694+ ereport (ERROR ,
695+ (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
696+ errmsg ("error inserting row in dbmirror_Pending" )));
772697
773- ret = SPI_execp (insertDataPlan ,insertDataDatum ,NULL ,1 );
698+ if (SPI_execp (insertDataPlan ,insertDataDatum ,NULL ,1 )!= SPI_OK_INSERT )
699+ ereport (ERROR ,
700+ (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
701+ errmsg ("error inserting row in dbmirror_PendingData" )));
774702
775703debug_msg ("dbmirror:Insert query finished" );
776704SPI_pfree (insertPlan );
777705SPI_pfree (insertDataPlan );
778706
779- return ret ;
780-
707+ SPI_finish ();
781708}