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

Commit4ad658c

Browse files
committed
Teach pg_dump to dump user-defined operator classes. For the moment,
this only works against 7.3 or later databases; the pushups requiredto do it without regprocedure/regtype/etc seem more trouble than they'reworth, considering that existing users aren't expecting pg_dump supportfor this.
1 parent2c2c43d commit4ad658c

File tree

3 files changed

+342
-3
lines changed

3 files changed

+342
-3
lines changed

‎src/bin/pg_dump/common.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.66 2002/07/18 23:11:29 petere Exp $
14+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.67 2002/07/30 21:56:04 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -60,13 +60,15 @@ dumpSchema(Archive *fout,
6060
intnumInherits;
6161
intnumAggregates;
6262
intnumOperators;
63+
intnumOpclasses;
6364
NamespaceInfo*nsinfo;
6465
TypeInfo*tinfo;
6566
FuncInfo*finfo;
6667
AggInfo*agginfo;
6768
TableInfo*tblinfo;
6869
InhInfo*inhinfo;
6970
OprInfo*oprinfo;
71+
OpclassInfo*opcinfo;
7072

7173
if (g_verbose)
7274
write_msg(NULL,"reading namespaces\n");
@@ -88,6 +90,10 @@ dumpSchema(Archive *fout,
8890
write_msg(NULL,"reading user-defined operators\n");
8991
oprinfo=getOperators(&numOperators);
9092

93+
if (g_verbose)
94+
write_msg(NULL,"reading user-defined operator classes\n");
95+
opcinfo=getOpclasses(&numOpclasses);
96+
9197
if (g_verbose)
9298
write_msg(NULL,"reading user-defined tables\n");
9399
tblinfo=getTables(&numTables);
@@ -170,6 +176,13 @@ dumpSchema(Archive *fout,
170176
dumpOprs(fout,oprinfo,numOperators);
171177
}
172178

179+
if (!dataOnly)
180+
{
181+
if (g_verbose)
182+
write_msg(NULL,"dumping out user-defined operator classes\n");
183+
dumpOpclasses(fout,opcinfo,numOpclasses);
184+
}
185+
173186
if (!dataOnly)
174187
{
175188
if (g_verbose)

‎src/bin/pg_dump/pg_dump.c

Lines changed: 316 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* IDENTIFICATION
25-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.276 2002/07/25 20:52:59 petere Exp $
25+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.277 2002/07/30 21:56:04 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -118,6 +118,7 @@ static void dumpOneOpr(Archive *fout, OprInfo *oprinfo,
118118
staticconstchar*convertRegProcReference(constchar*proc);
119119
staticconstchar*convertOperatorReference(constchar*opr,
120120
OprInfo*g_oprinfo,intnumOperators);
121+
staticvoiddumpOneOpclass(Archive*fout,OpclassInfo*opcinfo);
121122
staticvoiddumpOneAgg(Archive*fout,AggInfo*agginfo);
122123
staticOidfindLastBuiltinOid_V71(constchar*);
123124
staticOidfindLastBuiltinOid_V70(void);
@@ -1754,6 +1755,90 @@ getOperators(int *numOprs)
17541755
returnoprinfo;
17551756
}
17561757

1758+
/*
1759+
* getOpclasses:
1760+
* read all opclasses in the system catalogs and return them in the
1761+
* OpclassInfo* structure
1762+
*
1763+
*numOpclasses is set to the number of opclasses read in
1764+
*/
1765+
OpclassInfo*
1766+
getOpclasses(int*numOpclasses)
1767+
{
1768+
PGresult*res;
1769+
intntups;
1770+
inti;
1771+
PQExpBufferquery=createPQExpBuffer();
1772+
OpclassInfo*opcinfo;
1773+
inti_oid;
1774+
inti_opcname;
1775+
inti_opcnamespace;
1776+
inti_usename;
1777+
1778+
/*
1779+
* find all opclasses, including builtin opclasses;
1780+
* we filter out system-defined opclasses at dump-out time.
1781+
*/
1782+
1783+
/* Make sure we are in proper schema */
1784+
selectSourceSchema("pg_catalog");
1785+
1786+
if (g_fout->remoteVersion >=70300)
1787+
{
1788+
appendPQExpBuffer(query,"SELECT pg_opclass.oid, opcname, "
1789+
"opcnamespace, "
1790+
"(select usename from pg_user where opcowner = usesysid) as usename "
1791+
"from pg_opclass");
1792+
}
1793+
else
1794+
{
1795+
appendPQExpBuffer(query,"SELECT pg_opclass.oid, opcname, "
1796+
"0::oid as opcnamespace, "
1797+
"''::name as usename "
1798+
"from pg_opclass");
1799+
}
1800+
1801+
res=PQexec(g_conn,query->data);
1802+
if (!res||
1803+
PQresultStatus(res)!=PGRES_TUPLES_OK)
1804+
{
1805+
write_msg(NULL,"query to obtain list of opclasses failed: %s",PQerrorMessage(g_conn));
1806+
exit_nicely();
1807+
}
1808+
1809+
ntups=PQntuples(res);
1810+
*numOpclasses=ntups;
1811+
1812+
opcinfo= (OpclassInfo*)malloc(ntups*sizeof(OpclassInfo));
1813+
1814+
i_oid=PQfnumber(res,"oid");
1815+
i_opcname=PQfnumber(res,"opcname");
1816+
i_opcnamespace=PQfnumber(res,"opcnamespace");
1817+
i_usename=PQfnumber(res,"usename");
1818+
1819+
for (i=0;i<ntups;i++)
1820+
{
1821+
opcinfo[i].oid=strdup(PQgetvalue(res,i,i_oid));
1822+
opcinfo[i].opcname=strdup(PQgetvalue(res,i,i_opcname));
1823+
opcinfo[i].opcnamespace=findNamespace(PQgetvalue(res,i,i_opcnamespace),
1824+
opcinfo[i].oid);
1825+
opcinfo[i].usename=strdup(PQgetvalue(res,i,i_usename));
1826+
1827+
if (g_fout->remoteVersion >=70300)
1828+
{
1829+
if (strlen(opcinfo[i].usename)==0)
1830+
write_msg(NULL,"WARNING: owner of opclass \"%s\" appears to be invalid\n",
1831+
opcinfo[i].opcname);
1832+
}
1833+
}
1834+
1835+
PQclear(res);
1836+
1837+
destroyPQExpBuffer(query);
1838+
1839+
returnopcinfo;
1840+
}
1841+
17571842
/*
17581843
* getAggregates:
17591844
* read all the user-defined aggregates in the system catalogs and
@@ -3981,6 +4066,236 @@ convertOperatorReference(const char *opr,
39814066
returnname;
39824067
}
39834068

4069+
4070+
/*
4071+
* dumpOpclasses
4072+
* writes out to fout the queries to recreate all the user-defined
4073+
* operator classes
4074+
*/
4075+
void
4076+
dumpOpclasses(Archive*fout,OpclassInfo*opcinfo,intnumOpclasses)
4077+
{
4078+
inti;
4079+
4080+
for (i=0;i<numOpclasses;i++)
4081+
{
4082+
/* Dump only opclasses in dumpable namespaces */
4083+
if (!opcinfo[i].opcnamespace->dump)
4084+
continue;
4085+
4086+
/* OK, dump it */
4087+
dumpOneOpclass(fout,&opcinfo[i]);
4088+
}
4089+
}
4090+
4091+
/*
4092+
* dumpOneOpclass
4093+
* write out a single operator class definition
4094+
*/
4095+
staticvoid
4096+
dumpOneOpclass(Archive*fout,OpclassInfo*opcinfo)
4097+
{
4098+
PQExpBufferquery=createPQExpBuffer();
4099+
PQExpBufferq=createPQExpBuffer();
4100+
PQExpBufferdelq=createPQExpBuffer();
4101+
PGresult*res;
4102+
intntups;
4103+
inti_opcintype;
4104+
inti_opckeytype;
4105+
inti_opcdefault;
4106+
inti_amname;
4107+
inti_amopstrategy;
4108+
inti_amopreqcheck;
4109+
inti_amopopr;
4110+
inti_amprocnum;
4111+
inti_amproc;
4112+
char*opcintype;
4113+
char*opckeytype;
4114+
char*opcdefault;
4115+
char*amname;
4116+
char*amopstrategy;
4117+
char*amopreqcheck;
4118+
char*amopopr;
4119+
char*amprocnum;
4120+
char*amproc;
4121+
boolneedComma;
4122+
inti;
4123+
4124+
/*
4125+
* XXX currently we do not implement dumping of operator classes from
4126+
* pre-7.3 databases. This could be done but it seems not worth the
4127+
* trouble.
4128+
*/
4129+
if (g_fout->remoteVersion<70300)
4130+
return;
4131+
4132+
/* Make sure we are in proper schema so regoperator works correctly */
4133+
selectSourceSchema(opcinfo->opcnamespace->nspname);
4134+
4135+
/* Get additional fields from the pg_opclass row */
4136+
appendPQExpBuffer(query,"SELECT opcintype::pg_catalog.regtype, "
4137+
"opckeytype::pg_catalog.regtype, "
4138+
"opcdefault, "
4139+
"(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname "
4140+
"FROM pg_catalog.pg_opclass "
4141+
"WHERE oid = '%s'::pg_catalog.oid",
4142+
opcinfo->oid);
4143+
4144+
res=PQexec(g_conn,query->data);
4145+
if (!res||
4146+
PQresultStatus(res)!=PGRES_TUPLES_OK)
4147+
{
4148+
write_msg(NULL,"query to obtain opclass details failed: %s",PQerrorMessage(g_conn));
4149+
exit_nicely();
4150+
}
4151+
4152+
/* Expecting a single result only */
4153+
ntups=PQntuples(res);
4154+
if (ntups!=1)
4155+
{
4156+
write_msg(NULL,"Got %d rows instead of one from: %s",
4157+
ntups,query->data);
4158+
exit_nicely();
4159+
}
4160+
4161+
i_opcintype=PQfnumber(res,"opcintype");
4162+
i_opckeytype=PQfnumber(res,"opckeytype");
4163+
i_opcdefault=PQfnumber(res,"opcdefault");
4164+
i_amname=PQfnumber(res,"amname");
4165+
4166+
opcintype=PQgetvalue(res,0,i_opcintype);
4167+
opckeytype=PQgetvalue(res,0,i_opckeytype);
4168+
opcdefault=PQgetvalue(res,0,i_opcdefault);
4169+
amname=PQgetvalue(res,0,i_amname);
4170+
4171+
/* DROP must be fully qualified in case same name appears in pg_catalog */
4172+
appendPQExpBuffer(delq,"DROP OPERATOR CLASS %s",
4173+
fmtId(opcinfo->opcnamespace->nspname,force_quotes));
4174+
appendPQExpBuffer(delq,".%s",
4175+
fmtId(opcinfo->opcname,force_quotes));
4176+
appendPQExpBuffer(delq," USING %s;\n",
4177+
fmtId(amname,force_quotes));
4178+
4179+
/* Build the fixed portion of the CREATE command */
4180+
appendPQExpBuffer(q,"CREATE OPERATOR CLASS %s\n\t",
4181+
fmtId(opcinfo->opcname,force_quotes));
4182+
if (strcmp(opcdefault,"t")==0)
4183+
appendPQExpBuffer(q,"DEFAULT ");
4184+
appendPQExpBuffer(q,"FOR TYPE %s USING %s AS\n\t",
4185+
opcintype,
4186+
fmtId(amname,force_quotes));
4187+
4188+
needComma= false;
4189+
4190+
if (strcmp(opckeytype,"-")!=0)
4191+
{
4192+
appendPQExpBuffer(q,"STORAGE\t%s",
4193+
opckeytype);
4194+
needComma= true;
4195+
}
4196+
4197+
PQclear(res);
4198+
4199+
/*
4200+
* Now fetch and print the OPERATOR entries (pg_amop rows).
4201+
*/
4202+
resetPQExpBuffer(query);
4203+
4204+
appendPQExpBuffer(query,"SELECT amopstrategy, amopreqcheck, "
4205+
"amopopr::pg_catalog.regoperator "
4206+
"FROM pg_catalog.pg_amop "
4207+
"WHERE amopclaid = '%s'::pg_catalog.oid "
4208+
"ORDER BY amopstrategy",
4209+
opcinfo->oid);
4210+
4211+
res=PQexec(g_conn,query->data);
4212+
if (!res||
4213+
PQresultStatus(res)!=PGRES_TUPLES_OK)
4214+
{
4215+
write_msg(NULL,"query to obtain opclass operators failed: %s",PQerrorMessage(g_conn));
4216+
exit_nicely();
4217+
}
4218+
4219+
ntups=PQntuples(res);
4220+
4221+
i_amopstrategy=PQfnumber(res,"amopstrategy");
4222+
i_amopreqcheck=PQfnumber(res,"amopreqcheck");
4223+
i_amopopr=PQfnumber(res,"amopopr");
4224+
4225+
for (i=0;i<ntups;i++)
4226+
{
4227+
amopstrategy=PQgetvalue(res,i,i_amopstrategy);
4228+
amopreqcheck=PQgetvalue(res,i,i_amopreqcheck);
4229+
amopopr=PQgetvalue(res,i,i_amopopr);
4230+
4231+
if (needComma)
4232+
appendPQExpBuffer(q," ,\n\t");
4233+
4234+
appendPQExpBuffer(q,"OPERATOR\t%s\t%s",
4235+
amopstrategy,amopopr);
4236+
if (strcmp(amopreqcheck,"t")==0)
4237+
appendPQExpBuffer(q,"\tRECHECK");
4238+
4239+
needComma= true;
4240+
}
4241+
4242+
PQclear(res);
4243+
4244+
/*
4245+
* Now fetch and print the FUNCTION entries (pg_amproc rows).
4246+
*/
4247+
resetPQExpBuffer(query);
4248+
4249+
appendPQExpBuffer(query,"SELECT amprocnum, "
4250+
"amproc::pg_catalog.regprocedure "
4251+
"FROM pg_catalog.pg_amproc "
4252+
"WHERE amopclaid = '%s'::pg_catalog.oid "
4253+
"ORDER BY amprocnum",
4254+
opcinfo->oid);
4255+
4256+
res=PQexec(g_conn,query->data);
4257+
if (!res||
4258+
PQresultStatus(res)!=PGRES_TUPLES_OK)
4259+
{
4260+
write_msg(NULL,"query to obtain opclass functions failed: %s",PQerrorMessage(g_conn));
4261+
exit_nicely();
4262+
}
4263+
4264+
ntups=PQntuples(res);
4265+
4266+
i_amprocnum=PQfnumber(res,"amprocnum");
4267+
i_amproc=PQfnumber(res,"amproc");
4268+
4269+
for (i=0;i<ntups;i++)
4270+
{
4271+
amprocnum=PQgetvalue(res,i,i_amprocnum);
4272+
amproc=PQgetvalue(res,i,i_amproc);
4273+
4274+
if (needComma)
4275+
appendPQExpBuffer(q," ,\n\t");
4276+
4277+
appendPQExpBuffer(q,"FUNCTION\t%s\t%s",
4278+
amprocnum,amproc);
4279+
4280+
needComma= true;
4281+
}
4282+
4283+
PQclear(res);
4284+
4285+
appendPQExpBuffer(q," ;\n");
4286+
4287+
ArchiveEntry(fout,opcinfo->oid,opcinfo->opcname,
4288+
opcinfo->opcnamespace->nspname,opcinfo->usename,
4289+
"OPERATOR CLASS",NULL,
4290+
q->data,delq->data,
4291+
NULL,NULL,NULL);
4292+
4293+
destroyPQExpBuffer(query);
4294+
destroyPQExpBuffer(q);
4295+
destroyPQExpBuffer(delq);
4296+
}
4297+
4298+
39844299
/*
39854300
* dumpAggs
39864301
* writes out to fout the queries to create all the user-defined aggregates

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp