aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-02-21 18:01:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-02-21 18:01:41 +0000
commit6f96c539ede267ab31802da264e5c2bc226784a5 (patch)
tree92f1f94fafb49937b6b292b859e78f1fd4a2b8cd /src
parenta386cd7806a90d5f45e5801f1d0ce717f529ffd2 (diff)
downloadpostgresql-6f96c539ede267ab31802da264e5c2bc226784a5.tar.gz
postgresql-6f96c539ede267ab31802da264e5c2bc226784a5.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dump.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 17541d0d57c..8297fdaac64 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.422.2.2 2006/01/09 21:16:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.422.2.3 2006/02/21 18:01:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -4629,10 +4629,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
Oid typsendoid;
Oid typanalyzeoid;
char *typdelim;
- char *typdefault;
char *typbyval;
char *typalign;
char *typstorage;
+ char *typdefault;
+ bool typdefault_is_literal = false;
/* Set proper schema search path so regproc references list correctly */
selectSourceSchema(tinfo->dobj.namespace->dobj.name);
@@ -4648,8 +4649,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
"typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, "
"typanalyze::pg_catalog.oid as typanalyzeoid, "
- "typdelim, typdefault, typbyval, typalign, "
- "typstorage "
+ "typdelim, typbyval, typalign, typstorage, "
+ "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid",
tinfo->dobj.catId.oid);
@@ -4664,8 +4665,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
"typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, "
"0 as typanalyzeoid, "
- "typdelim, typdefault, typbyval, typalign, "
- "typstorage "
+ "typdelim, typbyval, typalign, typstorage, "
+ "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid",
tinfo->dobj.catId.oid);
@@ -4680,13 +4681,13 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
"typoutput::pg_catalog.oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, "
"0 as typanalyzeoid, "
- "typdelim, typdefault, typbyval, typalign, "
- "typstorage "
+ "typdelim, typbyval, typalign, typstorage, "
+ "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid",
tinfo->dobj.catId.oid);
}
- else if (fout->remoteVersion >= 70100)
+ else if (fout->remoteVersion >= 70200)
{
/*
* Note: although pre-7.3 catalogs contain typreceive and typsend,
@@ -4700,8 +4701,28 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
"typoutput::oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, "
"0 as typanalyzeoid, "
- "typdelim, typdefault, typbyval, typalign, "
- "typstorage "
+ "typdelim, typbyval, typalign, typstorage, "
+ "NULL as typdefaultbin, typdefault "
+ "FROM pg_type "
+ "WHERE oid = '%u'::oid",
+ tinfo->dobj.catId.oid);
+ }
+ else if (fout->remoteVersion >= 70100)
+ {
+ /*
+ * Ignore pre-7.2 typdefault; the field exists but has an unusable
+ * representation.
+ */
+ appendPQExpBuffer(query, "SELECT typlen, "
+ "typinput, typoutput, "
+ "'-' as typreceive, '-' as typsend, "
+ "'-' as typanalyze, "
+ "typinput::oid as typinputoid, "
+ "typoutput::oid as typoutputoid, "
+ "0 as typreceiveoid, 0 as typsendoid, "
+ "0 as typanalyzeoid, "
+ "typdelim, typbyval, typalign, typstorage, "
+ "NULL as typdefaultbin, NULL as typdefault "
"FROM pg_type "
"WHERE oid = '%u'::oid",
tinfo->dobj.catId.oid);
@@ -4716,8 +4737,9 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
"typoutput::oid as typoutputoid, "
"0 as typreceiveoid, 0 as typsendoid, "
"0 as typanalyzeoid, "
- "typdelim, typdefault, typbyval, typalign, "
- "'p'::char as typstorage "
+ "typdelim, typbyval, typalign, "
+ "'p'::char as typstorage, "
+ "NULL as typdefaultbin, NULL as typdefault "
"FROM pg_type "
"WHERE oid = '%u'::oid",
tinfo->dobj.catId.oid);
@@ -4747,13 +4769,18 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
- if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
- typdefault = NULL;
- else
- typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
+ if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
+ typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
+ else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
+ {
+ typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
+ typdefault_is_literal = true; /* it needs quotes */
+ }
+ else
+ typdefault = NULL;
/*
* DROP must be fully qualified in case same name appears in pg_catalog
@@ -4793,7 +4820,10 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
if (typdefault != NULL)
{
appendPQExpBuffer(q, ",\n DEFAULT = ");
- appendStringLiteral(q, typdefault, true);
+ if (typdefault_is_literal)
+ appendStringLiteral(q, typdefault, true);
+ else
+ appendPQExpBufferStr(q, typdefault);
}
if (tinfo->isArray)
@@ -4875,6 +4905,7 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
char *typnotnull;
char *typdefn;
char *typdefault;
+ bool typdefault_is_literal = false;
/* Set proper schema search path so type references list correctly */
selectSourceSchema(tinfo->dobj.namespace->dobj.name);
@@ -4883,7 +4914,7 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
/* We assume here that remoteVersion must be at least 70300 */
appendPQExpBuffer(query, "SELECT typnotnull, "
"pg_catalog.format_type(typbasetype, typtypmod) as typdefn, "
- "typdefault "
+ "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
"FROM pg_catalog.pg_type "
"WHERE oid = '%u'::pg_catalog.oid",
tinfo->dobj.catId.oid);
@@ -4902,10 +4933,15 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
- if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
- typdefault = NULL;
- else
+ if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
+ typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
+ else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
+ {
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
+ typdefault_is_literal = true; /* it needs quotes */
+ }
+ else
+ typdefault = NULL;
appendPQExpBuffer(q,
"CREATE DOMAIN %s AS %s",
@@ -4915,8 +4951,14 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
if (typnotnull[0] == 't')
appendPQExpBuffer(q, " NOT NULL");
- if (typdefault)
- appendPQExpBuffer(q, " DEFAULT %s", typdefault);
+ if (typdefault != NULL)
+ {
+ appendPQExpBuffer(q, " DEFAULT ");
+ if (typdefault_is_literal)
+ appendStringLiteral(q, typdefault, true);
+ else
+ appendPQExpBufferStr(q, typdefault);
+ }
PQclear(res);