Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaa731ed

Browse files
committed
Change nextval and other sequence functions to specify their sequence
argument as a 'regclass' value instead of a text string. The frontendconversion of text string to pg_class OID is now encapsulated as animplicitly-invocable coercion from text to regclass. This providesbackwards compatibility to the old behavior when the sequence argumentis explicitly typed as 'text'. When the argument is just an unadornedliteral string, it will be taken as 'regclass', which means that thestored representation will be an OID. This solves longstanding problemswith renaming sequences that are referenced in default expressions, aswell as new-in-8.1 problems with renaming such sequences' schemas ormoving them to another schema. All per recent discussion.Along the way, fix some rather serious problems in dbmirror's supportfor mirroring sequence operations (int4 vs int8 confusion for instance).
1 parent1b61ee3 commitaa731ed

File tree

25 files changed

+512
-339
lines changed

25 files changed

+512
-339
lines changed

‎contrib/dbmirror/MirrorSetup.sql

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ BEGIN;
22

33

44
CREATEFUNCTION "recordchange" () RETURNS triggerAS
5-
'$libdir/pending.so','recordchange' LANGUAGE'C';
5+
'$libdir/pending','recordchange' LANGUAGE'C';
66

77

88

@@ -48,15 +48,15 @@ CASCADE ON DELETE CASCADE
4848

4949
UPDATE pg_procSET proname='nextval_pg'WHERE proname='nextval';
5050

51-
CREATEFUNCTIONpg_catalog.nextval(text) RETURNS int8AS
52-
'$libdir/pending.so','nextval' LANGUAGE'C' STRICT;
51+
CREATEFUNCTIONpg_catalog.nextval(regclass) RETURNS int8AS
52+
'$libdir/pending','nextval_mirror' LANGUAGE'C' STRICT;
5353

5454

5555
UPDATE pg_procset proname='setval_pg'WHERE proname='setval';
5656

57-
CREATEFUNCTIONpg_catalog.setval("unknown",integer,boolean) RETURNS int8AS
58-
'$libdir/pending.so','setval' LANGUAGE'C' STRICT;
59-
CREATEFUNCTIONpg_catalog.setval("unknown",integer) RETURNS int8AS
60-
'$libdir/pending.so','setval' LANGUAGE'C' STRICT;
57+
CREATEFUNCTIONpg_catalog.setval(regclass, int8,boolean) RETURNS int8AS
58+
'$libdir/pending','setval3_mirror' LANGUAGE'C' STRICT;
59+
CREATEFUNCTIONpg_catalog.setval(regclass, int8) RETURNS int8AS
60+
'$libdir/pending','setval_mirror' LANGUAGE'C' STRICT;
6161

6262
COMMIT;

‎contrib/dbmirror/README.dbmirror

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Pending tables.
5656

5757
Requirements:
5858
---------------------------------
59-
-PostgreSQL-7.4 (Older versions are no longer supported)
59+
-PostgreSQL-8.1 (Older versions are no longer supported)
6060
-Perl 5.6 or 5.8 (Other versions might work)
6161
-PgPerl (http://gborg.postgresql.org/project/pgperl/projdisplay.php)
6262

@@ -177,15 +177,15 @@ If you are starting with an empty master database then the slave should
177177
be empty as well. Otherwise use pg_dump to ensure that the slave database
178178
tables are initially identical to the master.
179179

180-
6) Add entries in theMirrorHost table.
180+
6) Add entries in thedbmirror_MirrorHost table.
181181

182-
Each slave database must have an entry in theMirrorHost table.
182+
Each slave database must have an entry in thedbmirror_MirrorHost table.
183183

184-
The name of the host in theMirrorHost table must exactly match the
184+
The name of the host in thedbmirror_MirrorHost table must exactly match the
185185
slaveHost variable for that slave in the configuration file.
186186

187187
For example
188-
INSERT INTO"MirrorHost" ("SlaveName") VALUES ('backup_system');
188+
INSERT INTOdbmirror_MirrorHost (SlaveName) VALUES ('backup_system');
189189

190190

191191
6) Start DBMirror.pl

‎contrib/dbmirror/pending.c

Lines changed: 85 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
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.
@@ -30,12 +30,13 @@
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

4041
enumFieldUsage
4142
{
@@ -81,11 +82,11 @@ PG_FUNCTION_INFO_V1(recordchange);
8182

8283

8384

84-
externDatumnextval(PG_FUNCTION_ARGS);
85-
externDatumsetval(PG_FUNCTION_ARGS);
85+
externDatumsetval_mirror(PG_FUNCTION_ARGS);
86+
externDatumsetval3_mirror(PG_FUNCTION_ARGS);
87+
externDatumnextval_mirror(PG_FUNCTION_ARGS);
8688

87-
intsaveSequenceUpdate(consttext*sequenceName,
88-
intnextSequenceValue);
89+
staticvoidsaveSequenceUpdate(Oidrelid,int64nextValue,booliscalled);
8990

9091

9192
/*****************************************************************************
@@ -310,11 +311,9 @@ storeKeyInfo(char *cpTableName, HeapTuple tTupleData,
310311
SPI_pfree(cpKeyData);
311312

312313
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")));
318317

319318
debug_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

588591
Datum
589-
setval(PG_FUNCTION_ARGS)
592+
setval_mirror(PG_FUNCTION_ARGS)
590593
{
594+
Oidrelid=PG_GETARG_OID(0);
595+
int64next=PG_GETARG_INT64(1);
596+
int64result;
591597

598+
result=DatumGetInt64(DirectFunctionCall2(setval_oid,
599+
ObjectIdGetDatum(relid),
600+
Int64GetDatum(next)));
592601

593-
text*sequenceName;
594-
595-
OidsetvalArgTypes[3]= {TEXTOID,INT4OID,BOOLOID};
596-
intnextValue;
597-
void*setvalPlan=NULL;
598-
DatumsetvalData[3];
599-
constchar*setvalQuery="SELECT setval_pg($1,$2,$3)";
600-
intret;
601-
charis_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-
returnInt64GetDatum(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

654609
Datum
655-
nextval(PG_FUNCTION_ARGS)
610+
setval3_mirror(PG_FUNCTION_ARGS)
656611
{
657-
text*sequenceName;
658-
659-
constchar*nextvalQuery="SELECT nextval_pg($1)";
660-
OidnextvalArgTypes[1]= {TEXTOID};
661-
void*nextvalPlan=NULL;
662-
DatumnextvalData[1];
663-
664-
665-
intret;
666-
HeapTupleresTuple;
667-
charisNull;
668-
intnextSequenceValue;
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+
Oidrelid=PG_GETARG_OID(0);
613+
int64next=PG_GETARG_INT64(1);
614+
booliscalled=PG_GETARG_BOOL(2);
615+
int64result;
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+
Oidrelid=PG_GETARG_OID(0);
633+
int64result;
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-
returnInt64GetDatum(nextSequenceValue);
640+
PG_RETURN_INT64(result);
726641
}
727642

728643

729-
int
730-
saveSequenceUpdate(consttext*sequenceName,
731-
intnextSequenceVal)
644+
staticvoid
645+
saveSequenceUpdate(Oidrelid,int64nextValue,booliscalled)
732646
{
733-
734-
OidinsertArgTypes[2]= {TEXTOID,INT4OID};
647+
OidinsertArgTypes[2]= {NAMEOID,INT4OID};
735648
OidinsertDataArgTypes[1]= {NAMEOID};
736-
void*insertPlan=NULL;
737-
void*insertDataPlan=NULL;
649+
void*insertPlan;
650+
void*insertDataPlan;
738651
DatuminsertDatum[2];
739652
DatuminsertDataDatum[1];
740-
charnextSequenceText[32];
653+
charnextSequenceText[64];
741654

742655
constchar*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-
intret;
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

752667
insertPlan=SPI_prepare(insertQuery,2,insertArgTypes);
753668
insertDataPlan=SPI_prepare(insertDataQuery,1,insertDataArgTypes);
754669

755-
debug_msg("Prepared insert query");
756-
757-
758670
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")));
760674

675+
insertDatum[0]=PointerGetDatum(get_rel_name(relid));
761676
insertDatum[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+
*/
765686
insertDataDatum[0]=PointerGetDatum(nextSequenceText);
766-
debug_msg2("dbmirror:savesequenceupdate: Setting value %s",
687+
688+
debug_msg2("dbmirror:savesequenceupdate: Setting value as %s",
767689
nextSequenceText);
768690

769691
debug_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

775703
debug_msg("dbmirror:Insert query finished");
776704
SPI_pfree(insertPlan);
777705
SPI_pfree(insertDataPlan);
778706

779-
returnret;
780-
707+
SPI_finish();
781708
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp