Skip to content

Commit 8e70f3c

Browse files
committed
Fix pg_dump's heuristic for deciding which casts to dump.
Back in 2003 we had a discussion about how to decide which casts to dump. At the time pg_dump really only considered an object's containing schema to decide what to dump (ie, dump whatever's not in pg_catalog), and so we chose a complicated idea involving whether the underlying types were to be dumped (cf commit a6790ce). But users are allowed to create casts between built-in types, and we failed to dump such casts. Let's get rid of that heuristic, which has accreted even more ugliness since then, in favor of just looking at the cast's OID to decide if it's a built-in cast or not. In passing, also fix some really ancient code that supposed that it had to manufacture a dependency for the cast on its cast function; that's only true when dumping from a pre-7.3 server. This just resulted in some wasted cycles and duplicate dependency-list entries with newer servers, but we might as well improve it. Per gripes from a number of people, most recently Greg Sabino Mullane. Back-patch to all supported branches.
1 parent 72bbca2 commit 8e70f3c

File tree

1 file changed

+30
-47
lines changed

1 file changed

+30
-47
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 30 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
#include "access/attnum.h"
4747
#include "access/sysattr.h"
48+
#include "access/transam.h"
4849
#include "catalog/pg_cast.h"
4950
#include "catalog/pg_class.h"
5051
#include "catalog/pg_default_acl.h"
@@ -1081,6 +1082,24 @@ selectDumpableDefaultACL(DefaultACLInfo *dinfo)
10811082
dinfo->dobj.dump = include_everything;
10821083
}
10831084

1085+
/*
1086+
* selectDumpableCast: policy-setting subroutine
1087+
* Mark a cast as to be dumped or not
1088+
*
1089+
* Casts do not belong to any particular namespace (since they haven't got
1090+
* names), nor do they have identifiable owners. To distinguish user-defined
1091+
* casts from built-in ones, we must resort to checking whether the cast's
1092+
* OID is in the range reserved for initdb.
1093+
*/
1094+
static void
1095+
selectDumpableCast(CastInfo *cast)
1096+
{
1097+
if (cast->dobj.catId.oid < (Oid) FirstNormalObjectId)
1098+
cast->dobj.dump = false;
1099+
else
1100+
cast->dobj.dump = include_everything;
1101+
}
1102+
10841103
/*
10851104
* selectDumpableObject: policy-setting subroutine
10861105
* Mark a generic dumpable object as to be dumped or not
@@ -5071,12 +5090,13 @@ getCasts(int *numCasts)
50715090
sTypeInfo->dobj.name, tTypeInfo->dobj.name);
50725091
castinfo[i].dobj.name = namebuf.data;
50735092

5074-
if (OidIsValid(castinfo[i].castfunc))
5093+
if (g_fout->remoteVersion < 70300 &&
5094+
OidIsValid(castinfo[i].castfunc))
50755095
{
50765096
/*
50775097
* We need to make a dependency to ensure the function will be
50785098
* dumped first. (In 7.3 and later the regular dependency
5079-
* mechanism will handle this for us.)
5099+
* mechanism handles this for us.)
50805100
*/
50815101
FuncInfo *funcInfo;
50825102

@@ -5085,6 +5105,9 @@ getCasts(int *numCasts)
50855105
addObjectDependency(&castinfo[i].dobj,
50865106
funcInfo->dobj.dumpId);
50875107
}
5108+
5109+
/* Decide whether we want to dump it */
5110+
selectDumpableCast(&(castinfo[i]));
50885111
}
50895112

50905113
PQclear(res);
@@ -8308,12 +8331,12 @@ dumpCast(Archive *fout, CastInfo *cast)
83088331
PQExpBuffer delqry;
83098332
PQExpBuffer castsig;
83108333
FuncInfo *funcInfo = NULL;
8311-
TypeInfo *sourceInfo;
8312-
TypeInfo *targetInfo;
83138334

8314-
if (dataOnly)
8335+
/* Skip if not to be dumped */
8336+
if (!cast->dobj.dump || dataOnly)
83158337
return;
83168338

8339+
/* Cannot dump if we don't have the cast function's info */
83178340
if (OidIsValid(cast->castfunc))
83188341
{
83198342
funcInfo = findFuncByOid(cast->castfunc);
@@ -8322,49 +8345,9 @@ dumpCast(Archive *fout, CastInfo *cast)
83228345
}
83238346

83248347
/*
8325-
* As per discussion we dump casts if one or more of the underlying
8326-
* objects (the conversion function and the two data types) are not
8327-
* builtin AND if all of the non-builtin objects are included in the dump.
8328-
* Builtin meaning, the namespace name does not start with "pg_".
8329-
*/
8330-
sourceInfo = findTypeByOid(cast->castsource);
8331-
targetInfo = findTypeByOid(cast->casttarget);
8332-
8333-
if (sourceInfo == NULL || targetInfo == NULL)
8334-
return;
8335-
8336-
/*
8337-
* Skip this cast if all objects are from pg_
8338-
*/
8339-
if ((funcInfo == NULL ||
8340-
strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) &&
8341-
strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) == 0 &&
8342-
strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) == 0)
8343-
return;
8344-
8345-
/*
8346-
* Skip cast if function isn't from pg_ and is not to be dumped.
8347-
*/
8348-
if (funcInfo &&
8349-
strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
8350-
!funcInfo->dobj.dump)
8351-
return;
8352-
8353-
/*
8354-
* Same for the source type
8355-
*/
8356-
if (strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
8357-
!sourceInfo->dobj.dump)
8358-
return;
8359-
8360-
/*
8361-
* and the target type.
8348+
* Make sure we are in proper schema (needed for getFormattedTypeName).
8349+
* Casts don't have a schema of their own, so use pg_catalog.
83628350
*/
8363-
if (strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
8364-
!targetInfo->dobj.dump)
8365-
return;
8366-
8367-
/* Make sure we are in proper schema (needed for getFormattedTypeName) */
83688351
selectSourceSchema("pg_catalog");
83698352

83708353
defqry = createPQExpBuffer();

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