1
1
/****************************************************************************
2
2
* 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 $
5
5
*
6
6
* This file contains a trigger for Postgresql-7.x to record changes to tables
7
7
* to a pending table for mirroring.
30
30
*
31
31
*
32
32
***************************************************************************/
33
- #include < postgres.h>
33
+ #include " postgres.h"
34
34
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"
39
40
40
41
enum FieldUsage
41
42
{
@@ -81,11 +82,11 @@ PG_FUNCTION_INFO_V1(recordchange);
81
82
82
83
83
84
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 );
86
88
87
- int saveSequenceUpdate (const text * sequenceName ,
88
- int nextSequenceValue );
89
+ static void saveSequenceUpdate (Oid relid , int64 nextValue , bool iscalled );
89
90
90
91
91
92
/*****************************************************************************
@@ -310,11 +311,9 @@ storeKeyInfo(char *cpTableName, HeapTuple tTupleData,
310
311
SPI_pfree (cpKeyData );
311
312
312
313
if (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" )));
318
317
319
318
debug_msg ("insert successful" );
320
319
@@ -583,161 +582,75 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc, Oid tableOid,
583
582
}
584
583
585
584
586
- PG_FUNCTION_INFO_V1 (setval );
585
+ /*
586
+ * Support for mirroring sequence objects.
587
+ */
588
+
589
+ PG_FUNCTION_INFO_V1 (setval_mirror );
587
590
588
591
Datum
589
- setval (PG_FUNCTION_ARGS )
592
+ setval_mirror (PG_FUNCTION_ARGS )
590
593
{
594
+ Oid relid = PG_GETARG_OID (0 );
595
+ int64 next = PG_GETARG_INT64 (1 );
596
+ int64 result ;
591
597
598
+ result = DatumGetInt64 (DirectFunctionCall2 (setval_oid ,
599
+ ObjectIdGetDatum (relid ),
600
+ Int64GetDatum (next )));
592
601
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);
647
603
604
+ PG_RETURN_INT64 (result );
648
605
}
649
606
650
-
651
-
652
- PG_FUNCTION_INFO_V1 (nextval );
607
+ PG_FUNCTION_INFO_V1 (setval3_mirror );
653
608
654
609
Datum
655
- nextval (PG_FUNCTION_ARGS )
610
+ setval3_mirror (PG_FUNCTION_ARGS )
656
611
{
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 ;
707
616
708
- debug_msg ("dbmirror:nextval Set resTuple" );
709
-
710
- nextSequenceValue = * (unsigned int * ) (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 )));
713
621
622
+ saveSequenceUpdate (relid , result , iscalled );
714
623
624
+ PG_RETURN_INT64 (result );
625
+ }
715
626
716
- debug_msg2 ( "dbmirror:nextval Set SPI_getbinval:%d" , nextSequenceValue );
627
+ PG_FUNCTION_INFO_V1 ( nextval_mirror );
717
628
629
+ Datum
630
+ nextval_mirror (PG_FUNCTION_ARGS )
631
+ {
632
+ Oid relid = PG_GETARG_OID (0 );
633
+ int64 result ;
718
634
719
- saveSequenceUpdate (sequenceName , nextSequenceValue );
720
- SPI_pfree (resTuple );
721
- SPI_pfree (nextvalPlan );
635
+ result = DatumGetInt64 (DirectFunctionCall1 (nextval_oid ,
636
+ ObjectIdGetDatum (relid )));
722
637
723
- SPI_finish ( );
638
+ saveSequenceUpdate ( relid , result , true );
724
639
725
- return Int64GetDatum ( nextSequenceValue );
640
+ PG_RETURN_INT64 ( result );
726
641
}
727
642
728
643
729
- int
730
- saveSequenceUpdate (const text * sequenceName ,
731
- int nextSequenceVal )
644
+ static void
645
+ saveSequenceUpdate (Oid relid , int64 nextValue , bool iscalled )
732
646
{
733
-
734
- Oid insertArgTypes [2 ] = {TEXTOID , INT4OID };
647
+ Oid insertArgTypes [2 ] = {NAMEOID , INT4OID };
735
648
Oid insertDataArgTypes [1 ] = {NAMEOID };
736
- void * insertPlan = NULL ;
737
- void * insertDataPlan = NULL ;
649
+ void * insertPlan ;
650
+ void * insertDataPlan ;
738
651
Datum insertDatum [2 ];
739
652
Datum insertDataDatum [1 ];
740
- char nextSequenceText [32 ];
653
+ char nextSequenceText [64 ];
741
654
742
655
const char * insertQuery =
743
656
"INSERT INTO dbmirror_Pending (TableName,Op,XID) VALUES" \
@@ -746,36 +659,50 @@ saveSequenceUpdate(const text *sequenceName,
746
659
"INSERT INTO dbmirror_PendingData(SeqId,IsKey,Data) VALUES " \
747
660
"(currval('dbmirror_pending_seqid_seq'),'t',$1)" ;
748
661
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" )));
751
666
752
667
insertPlan = SPI_prepare (insertQuery , 2 , insertArgTypes );
753
668
insertDataPlan = SPI_prepare (insertDataQuery , 1 , insertDataArgTypes );
754
669
755
- debug_msg ("Prepared insert query" );
756
-
757
-
758
670
if (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" )));
760
674
675
+ insertDatum [0 ] = PointerGetDatum (get_rel_name (relid ));
761
676
insertDatum [1 ] = Int32GetDatum (GetCurrentTransactionId ());
762
- insertDatum [0 ] = PointerGetDatum (sequenceName );
763
677
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
+ */
765
686
insertDataDatum [0 ] = PointerGetDatum (nextSequenceText );
766
- debug_msg2 ("dbmirror:savesequenceupdate: Setting value %s" ,
687
+
688
+ debug_msg2 ("dbmirror:savesequenceupdate: Setting value as %s" ,
767
689
nextSequenceText );
768
690
769
691
debug_msg ("dbmirror:About to execute insert query" );
770
692
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" )));
772
697
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" )));
774
702
775
703
debug_msg ("dbmirror:Insert query finished" );
776
704
SPI_pfree (insertPlan );
777
705
SPI_pfree (insertDataPlan );
778
706
779
- return ret ;
780
-
707
+ SPI_finish ();
781
708
}
0 commit comments