OSDN Git Service

Cleaner solution to the problem of loading pre-7.3 dumps containing
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Feb 2003 22:06:59 +0000 (22:06 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Feb 2003 22:06:59 +0000 (22:06 +0000)
columns of type lo (see contrib/lo).  Rather than hacking the function
definitions on-the-fly, just modify the queries issued by FixupBlobRefs
so that they work even if CREATE CAST hasn't been issued.

src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_backup_db.c

index 52202c7..9c8eaaf 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.66 2003/01/27 00:23:38 tgl Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.67 2003/02/01 22:06:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,102 +122,6 @@ CloseArchive(Archive *AHX)
                die_horribly(AH, modulename, "could not close the output file in CloseArchive\n");
 }
 
-/*
- *     This function repairs a slip when upgrading PG cast
- *     mechanism from 7.2 or earlier to 7.3 or later.
- *     The casts between lo and oid are needed when retrieving
- *     lo type data in FixupBlobRefs and so adjust lo type in
- *     contrib before processing FixupBlobRefs.
- */
-static void
-Adjust_lo_type(ArchiveHandle *AH)
-{
-       PGresult   *res;
-       int     nTuples;
-
-       /*
-        *      First check the existence of the cast oid as lo.
-        */
-       res = PQexec(AH->blobConnection, "select 1 from pg_cast where"
-               " castsource in (select oid from pg_type where typname = 'oid')"
-               " and casttarget in (select oid from pg_type where typname = 'lo')");
-
-       if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
-               die_horribly(AH, modulename, "error while checking the cast oid as lo\n");
-       nTuples = PQntuples(res);
-       PQclear(res);
-       if (nTuples == 0)
-       {
-               /*
-                *      Check the existence of the cast function lo(oid)
-                *      and change it to be IMMUTABLE.
-                */
-               res = PQexec(AH->blobConnection, "update pg_proc set provolatile = 'i'"
-                       " where proname = 'lo'"
-                       " and pronargs = 1"
-                       " and prorettype in (select oid from pg_type where typname = 'lo')"
-                       " and proargtypes[0] in (select oid from pg_type where typname = 'oid')");
-
-               if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
-                       die_horribly(AH, modulename, "could not adjust lo(oid) function\n");
-               nTuples = atoi(PQcmdTuples(res));
-               PQclear(res);
-               if (nTuples == 1)
-               {
-                       /*
-                        *      The cast function lo(oid) exists and
-                        *      then create the correspoding cast.
-                        */
-                       res = PQexec(AH->blobConnection, "create cast"
-                               " (oid as lo) with function lo(oid) as implicit");
-                       if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
-                               die_horribly(AH, modulename, "couldn't create cast (oid as lo)\n");
-                       PQclear(res);
-               }
-       }
-
-       /*
-        *      Also check the existence of the cast lo as oid.
-        */
-       res = PQexec(AH->blobConnection, "select 1 from pg_cast where"
-               " castsource in (select oid from pg_type where typname = 'lo')"
-               " and casttarget in (select oid from pg_type where typname = 'oid')");
-
-       if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
-               die_horribly(AH, modulename, "error while checking the cast lo as oid\n");
-       nTuples = PQntuples(res);
-       PQclear(res);
-       if (nTuples == 0)
-       {
-               /*
-                *      Check the existence of the cast function oid(lo)
-                *      and change it to be IMMUTABLE.
-                */
-               res = PQexec(AH->blobConnection, "update pg_proc set provolatile = 'i'"
-                       " where proname = 'oid'"
-                       " and pronargs = 1"
-                       " and prorettype in (select oid from pg_type where typname = 'oid')"
-                       " and proargtypes[0] in (select oid from pg_type where typname = 'lo')");
-
-               if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
-                       die_horribly(AH, modulename, "could not adjust oid(lo) function\n");
-               nTuples = atoi(PQcmdTuples(res));
-               PQclear(res);
-               if (nTuples == 1)
-               {
-                       /*
-                        *      The cast function oid(lo) exists and
-                        *      then create the correspoding cast.
-                        */
-                       res = PQexec(AH->blobConnection, "create cast"
-                               " (lo as oid) with function oid(lo) as implicit");
-                       if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
-                               die_horribly(AH, modulename, "couldn't create cast (lo as oid)\n");
-                       PQclear(res);
-               }
-       }
-}
-
 /* Public */
 void
 RestoreArchive(Archive *AHX, RestoreOptions *ropt)
@@ -453,7 +357,6 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
                /* NULL parameter means disable ALL user triggers */
                _disableTriggersIfNecessary(AH, NULL, ropt);
 
-               Adjust_lo_type(AH);
                te = AH->toc->next;
                while (te != AH->toc)
                {
index 93a8137..d5ed76d 100644 (file)
@@ -5,7 +5,7 @@
  *     Implements the basic DB functions used by the archiver.
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.43 2002/10/22 19:15:23 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.44 2003/02/01 22:06:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -589,7 +589,6 @@ FixupBlobRefs(ArchiveHandle *AH, TocEntry *te)
                           *uRes;
        int                     i,
                                n;
-       char       *attr;
 
        if (strcmp(te->tag, BLOB_XREF_TABLE) == 0)
                return;
@@ -604,7 +603,7 @@ FixupBlobRefs(ArchiveHandle *AH, TocEntry *te)
                                          fmtId(te->tag));
 
        appendPQExpBuffer(tblQry,
-                                         "SELECT a.attname FROM "
+                                         "SELECT a.attname, t.typname FROM "
                                          "pg_catalog.pg_attribute a, pg_catalog.pg_type t "
                 "WHERE a.attnum > 0 AND a.attrelid = '%s'::pg_catalog.regclass "
                                 "AND a.atttypid = t.oid AND t.typname in ('oid', 'lo')",
@@ -623,23 +622,53 @@ FixupBlobRefs(ArchiveHandle *AH, TocEntry *te)
 
        for (i = 0; i < n; i++)
        {
+               char       *attr;
+               char       *typname;
+               bool            typeisoid;
+
                attr = PQgetvalue(res, i, 0);
+               typname = PQgetvalue(res, i, 1);
+
+               typeisoid = (strcmp(typname, "oid") == 0);
 
                ahlog(AH, 1, "fixing large object cross-references for %s.%s\n",
                          te->tag, attr);
 
                resetPQExpBuffer(tblQry);
 
-               /* Can't use fmtId twice in one call... */
+               /*
+                * Note: we use explicit typename() cast style here because if we
+                * are dealing with a dump from a pre-7.3 database containing LO
+                * columns, the dump probably will not have CREATE CAST commands
+                * for lo<->oid conversions.  What it will have is functions,
+                * which we will invoke as functions.
+                */
+
+               /* Can't use fmtId more than once per call... */
                appendPQExpBuffer(tblQry,
-                                                 "UPDATE %s SET %s = %s.newOid",
-                                                 tblName->data, fmtId(attr),
-                                                 BLOB_XREF_TABLE);
+                                                 "UPDATE %s SET %s = ",
+                                                 tblName->data, fmtId(attr));
+               if (typeisoid)
+                       appendPQExpBuffer(tblQry,
+                                                         "%s.newOid",
+                                                         BLOB_XREF_TABLE);
+               else
+                       appendPQExpBuffer(tblQry,
+                                                         "%s(%s.newOid)",
+                                                         fmtId(typname),
+                                                         BLOB_XREF_TABLE);
                appendPQExpBuffer(tblQry,
-                                                 " FROM %s WHERE %s.oldOid = %s.%s",
-                                                 BLOB_XREF_TABLE,
+                                                 " FROM %s WHERE %s.oldOid = ",
                                                  BLOB_XREF_TABLE,
-                                                 tblName->data, fmtId(attr));
+                                                 BLOB_XREF_TABLE);
+               if (typeisoid)
+                       appendPQExpBuffer(tblQry,
+                                                         "%s.%s",
+                                                         tblName->data, fmtId(attr));
+               else
+                       appendPQExpBuffer(tblQry,
+                                                         "oid(%s.%s)",
+                                                         tblName->data, fmtId(attr));
 
                ahlog(AH, 10, "SQL: %s\n", tblQry->data);