Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix dumping of casts and transforms using built-in functions
authorStephen Frost <sfrost@snowman.net>
Wed, 21 Dec 2016 18:47:18 +0000 (13:47 -0500)
committerStephen Frost <sfrost@snowman.net>
Wed, 21 Dec 2016 18:47:18 +0000 (13:47 -0500)
In pg_dump.c dumpCast() and dumpTransform(), we would happily ignore the
cast or transform if it happened to use a built-in function because we
weren't including the information about built-in functions when querying
pg_proc from getFuncs().

Modify the query in getFuncs() to also gather information about
functions which are used by user-defined casts and transforms (where
"user-defined" means "has an OID >= FirstNormalObjectId").  This also
adds to the TAP regression tests for 9.6 and master to cover these
types of objects.

Back-patch all the way for casts, back to 9.5 for transforms.

Discussion: https://www.postgresql.org/message-id/flat/20160504183952.GE10850%40tamriel.snowman.net

src/bin/pg_dump/pg_dump.c

index 5b9f5751e4730e0228252a423286efc3c6c23b2a..cd67082a8f4845428c0054688529fee843ff603a 100644 (file)
@@ -4506,7 +4506,9 @@ getFuncs(Archive *fout, int *numFuncs)
     * 3. Otherwise, we normally exclude functions in pg_catalog.  However, if
     * they're members of extensions and we are in binary-upgrade mode then
     * include them, since we want to dump extension members individually in
-    * that mode.
+    * that mode.  Also, if they are used by casts or transforms then we need
+    * to gather the information about them, though they won't be dumped if
+    * they are built-in.
     */
 
    if (fout->remoteVersion >= 70300)
@@ -4524,11 +4526,24 @@ getFuncs(Archive *fout, int *numFuncs)
                               "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                                 "WHERE classid = 'pg_proc'::regclass AND "
                                 "objid = p.oid AND deptype = 'i')");
-       appendPQExpBufferStr(query,
+       appendPQExpBuffer(query,
                             "\n  AND ("
                             "\n  pronamespace != "
                             "(SELECT oid FROM pg_namespace "
-                            "WHERE nspname = 'pg_catalog')");
+                            "WHERE nspname = 'pg_catalog')"
+                            "\n  OR EXISTS (SELECT 1 FROM pg_cast"
+                            "\n  WHERE pg_cast.oid > '%u'::oid"
+                            "\n  AND p.oid = pg_cast.castfunc)",
+                            g_last_builtin_oid);
+
+       if (fout->remoteVersion >= 90500)
+           appendPQExpBuffer(query,
+                                "\n  OR EXISTS (SELECT 1 FROM pg_transform"
+                                "\n  WHERE pg_transform.oid > %u::oid"
+                                "\n  AND (p.oid = pg_transform.trffromsql"
+                                "\n  OR p.oid = pg_transform.trftosql))",
+                                g_last_builtin_oid);
+
        if (dopt->binary_upgrade && fout->remoteVersion >= 90100)
            appendPQExpBufferStr(query,
                               "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
@@ -10835,7 +10850,8 @@ dumpCast(Archive *fout, CastInfo *cast)
    {
        funcInfo = findFuncByOid(cast->castfunc);
        if (funcInfo == NULL)
-           return;
+           exit_horribly(NULL, "unable to find function definition for OID %u",
+                         cast->castfunc);
    }
 
    /*
@@ -10939,13 +10955,15 @@ dumpTransform(Archive *fout, TransformInfo *transform)
    {
        fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
        if (fromsqlFuncInfo == NULL)
-           return;
+           exit_horribly(NULL, "unable to find function definition for OID %u",
+                         transform->trffromsql);
    }
    if (OidIsValid(transform->trftosql))
    {
        tosqlFuncInfo = findFuncByOid(transform->trftosql);
        if (tosqlFuncInfo == NULL)
-           return;
+           exit_horribly(NULL, "unable to find function definition for OID %u",
+                         transform->trftosql);
    }
 
    /* Make sure we are in proper schema (needed for getFormattedTypeName) */