Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3666260

Browse files
committed
Fix old pg_dump oversight: default values for domains really need to be dumped
by decompiling the typdefaultbin expression, not just printing the typdefault text which may be out-of-date or assume the wrong schema search path. (It's the same hazard as for adbin vs adsrc in column defaults.) The catalogs.sgml spec for pg_type implies that the correct procedure is to look to typdefaultbin first and consider typdefault only if typdefaultbin is NULL. I made dumping of both domains and base types do that, even though in the current backend code typdefaultbin is always correct for domains and typdefault for base types --- might as well try to future-proof it a little. Per bug report from Alexander Galler.
1 parent af49a16 commit 3666260

File tree

1 file changed

+66
-24
lines changed

1 file changed

+66
-24
lines changed

src/bin/pg_dump/pg_dump.c

+66-24
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* by PostgreSQL
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.429 2006/02/12 06:11:51 momjian Exp $
15+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.430 2006/02/21 18:01:32 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -4690,10 +4690,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
46904690
Oid typsendoid;
46914691
Oid typanalyzeoid;
46924692
char *typdelim;
4693-
char *typdefault;
46944693
char *typbyval;
46954694
char *typalign;
46964695
char *typstorage;
4696+
char *typdefault;
4697+
bool typdefault_is_literal = false;
46974698

46984699
/* Set proper schema search path so regproc references list correctly */
46994700
selectSourceSchema(tinfo->dobj.namespace->dobj.name);
@@ -4709,8 +4710,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
47094710
"typreceive::pg_catalog.oid as typreceiveoid, "
47104711
"typsend::pg_catalog.oid as typsendoid, "
47114712
"typanalyze::pg_catalog.oid as typanalyzeoid, "
4712-
"typdelim, typdefault, typbyval, typalign, "
4713-
"typstorage "
4713+
"typdelim, typbyval, typalign, typstorage, "
4714+
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
47144715
"FROM pg_catalog.pg_type "
47154716
"WHERE oid = '%u'::pg_catalog.oid",
47164717
tinfo->dobj.catId.oid);
@@ -4725,8 +4726,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
47254726
"typreceive::pg_catalog.oid as typreceiveoid, "
47264727
"typsend::pg_catalog.oid as typsendoid, "
47274728
"0 as typanalyzeoid, "
4728-
"typdelim, typdefault, typbyval, typalign, "
4729-
"typstorage "
4729+
"typdelim, typbyval, typalign, typstorage, "
4730+
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
47304731
"FROM pg_catalog.pg_type "
47314732
"WHERE oid = '%u'::pg_catalog.oid",
47324733
tinfo->dobj.catId.oid);
@@ -4741,13 +4742,13 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
47414742
"typoutput::pg_catalog.oid as typoutputoid, "
47424743
"0 as typreceiveoid, 0 as typsendoid, "
47434744
"0 as typanalyzeoid, "
4744-
"typdelim, typdefault, typbyval, typalign, "
4745-
"typstorage "
4745+
"typdelim, typbyval, typalign, typstorage, "
4746+
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
47464747
"FROM pg_catalog.pg_type "
47474748
"WHERE oid = '%u'::pg_catalog.oid",
47484749
tinfo->dobj.catId.oid);
47494750
}
4750-
else if (fout->remoteVersion >= 70100)
4751+
else if (fout->remoteVersion >= 70200)
47514752
{
47524753
/*
47534754
* Note: although pre-7.3 catalogs contain typreceive and typsend,
@@ -4761,8 +4762,28 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
47614762
"typoutput::oid as typoutputoid, "
47624763
"0 as typreceiveoid, 0 as typsendoid, "
47634764
"0 as typanalyzeoid, "
4764-
"typdelim, typdefault, typbyval, typalign, "
4765-
"typstorage "
4765+
"typdelim, typbyval, typalign, typstorage, "
4766+
"NULL as typdefaultbin, typdefault "
4767+
"FROM pg_type "
4768+
"WHERE oid = '%u'::oid",
4769+
tinfo->dobj.catId.oid);
4770+
}
4771+
else if (fout->remoteVersion >= 70100)
4772+
{
4773+
/*
4774+
* Ignore pre-7.2 typdefault; the field exists but has an unusable
4775+
* representation.
4776+
*/
4777+
appendPQExpBuffer(query, "SELECT typlen, "
4778+
"typinput, typoutput, "
4779+
"'-' as typreceive, '-' as typsend, "
4780+
"'-' as typanalyze, "
4781+
"typinput::oid as typinputoid, "
4782+
"typoutput::oid as typoutputoid, "
4783+
"0 as typreceiveoid, 0 as typsendoid, "
4784+
"0 as typanalyzeoid, "
4785+
"typdelim, typbyval, typalign, typstorage, "
4786+
"NULL as typdefaultbin, NULL as typdefault "
47664787
"FROM pg_type "
47674788
"WHERE oid = '%u'::oid",
47684789
tinfo->dobj.catId.oid);
@@ -4777,8 +4798,9 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
47774798
"typoutput::oid as typoutputoid, "
47784799
"0 as typreceiveoid, 0 as typsendoid, "
47794800
"0 as typanalyzeoid, "
4780-
"typdelim, typdefault, typbyval, typalign, "
4781-
"'p'::char as typstorage "
4801+
"typdelim, typbyval, typalign, "
4802+
"'p'::char as typstorage, "
4803+
"NULL as typdefaultbin, NULL as typdefault "
47824804
"FROM pg_type "
47834805
"WHERE oid = '%u'::oid",
47844806
tinfo->dobj.catId.oid);
@@ -4808,13 +4830,18 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
48084830
typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
48094831
typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
48104832
typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
4811-
if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
4812-
typdefault = NULL;
4813-
else
4814-
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
48154833
typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
48164834
typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
48174835
typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
4836+
if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
4837+
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
4838+
else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
4839+
{
4840+
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
4841+
typdefault_is_literal = true; /* it needs quotes */
4842+
}
4843+
else
4844+
typdefault = NULL;
48184845

48194846
/*
48204847
* DROP must be fully qualified in case same name appears in pg_catalog
@@ -4854,7 +4881,10 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
48544881
if (typdefault != NULL)
48554882
{
48564883
appendPQExpBuffer(q, ",\n DEFAULT = ");
4857-
appendStringLiteral(q, typdefault, true);
4884+
if (typdefault_is_literal)
4885+
appendStringLiteral(q, typdefault, true);
4886+
else
4887+
appendPQExpBufferStr(q, typdefault);
48584888
}
48594889

48604890
if (tinfo->isArray)
@@ -4936,6 +4966,7 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
49364966
char *typnotnull;
49374967
char *typdefn;
49384968
char *typdefault;
4969+
bool typdefault_is_literal = false;
49394970

49404971
/* Set proper schema search path so type references list correctly */
49414972
selectSourceSchema(tinfo->dobj.namespace->dobj.name);
@@ -4944,7 +4975,7 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
49444975
/* We assume here that remoteVersion must be at least 70300 */
49454976
appendPQExpBuffer(query, "SELECT typnotnull, "
49464977
"pg_catalog.format_type(typbasetype, typtypmod) as typdefn, "
4947-
"typdefault "
4978+
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
49484979
"FROM pg_catalog.pg_type "
49494980
"WHERE oid = '%u'::pg_catalog.oid",
49504981
tinfo->dobj.catId.oid);
@@ -4963,10 +4994,15 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
49634994

49644995
typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
49654996
typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
4966-
if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
4967-
typdefault = NULL;
4968-
else
4997+
if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
4998+
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
4999+
else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
5000+
{
49695001
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
5002+
typdefault_is_literal = true; /* it needs quotes */
5003+
}
5004+
else
5005+
typdefault = NULL;
49705006

49715007
appendPQExpBuffer(q,
49725008
"CREATE DOMAIN %s AS %s",
@@ -4976,8 +5012,14 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
49765012
if (typnotnull[0] == 't')
49775013
appendPQExpBuffer(q, " NOT NULL");
49785014

4979-
if (typdefault)
4980-
appendPQExpBuffer(q, " DEFAULT %s", typdefault);
5015+
if (typdefault != NULL)
5016+
{
5017+
appendPQExpBuffer(q, " DEFAULT ");
5018+
if (typdefault_is_literal)
5019+
appendStringLiteral(q, typdefault, true);
5020+
else
5021+
appendPQExpBufferStr(q, typdefault);
5022+
}
49815023

49825024
PQclear(res);
49835025

0 commit comments

Comments
 (0)