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

Lines changed: 66 additions & 24 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy