]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Cause pg_dump to emit a 'SET client_encoding' command at the start of
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 24 Feb 2004 03:35:45 +0000 (03:35 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 24 Feb 2004 03:35:45 +0000 (03:35 +0000)
any restore operation, thereby ensuring that dumped data is interpreted
the same way it was dumped even if the target database has a different
encoding.  Per suggestions from Pavel Stehule and others.  Also,
simplify scheme for handling check_function_bodies ... we may as well
just set that at the head of the script.

src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_backup_archiver.h
src/bin/pg_dump/pg_dump.c

index 08b2486f8aba32b205286e70dba5bd230e7929d7..32615d9f71a3988ecd7b77ffe3d875c35b700867 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.79.2.1 2004/01/04 04:02:22 tgl Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.79.2.2 2004/02/24 03:35:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,6 +48,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
                 const int compression, ArchiveMode mode);
 static int     _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData);
 
+static void _doSetFixedOutputState(ArchiveHandle *AH);
 static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
 static void _reconnectToDB(ArchiveHandle *AH, const char *dbname, const char *user);
 static void _becomeUser(ArchiveHandle *AH, const char *user);
@@ -204,6 +205,11 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
 
        ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");
 
+       /*
+        * Establish important parameter values right away.
+        */
+       _doSetFixedOutputState(AH);
+
        /*
         * Drop the items at the start, in reverse order
         */
@@ -1703,7 +1709,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
        AH->currUser = strdup("");      /* So it's valid, but we can free() it
                                                                 * later if necessary */
        AH->currSchema = strdup("");    /* ditto */
-       AH->chk_fn_bodies = true;       /* assumed default state */
 
        AH->toc = (TocEntry *) calloc(1, sizeof(TocEntry));
        if (!AH->toc)
@@ -1935,6 +1940,10 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
 {
        teReqs          res = 3;                /* Schema = 1, Data = 2, Both = 3 */
 
+       /* ENCODING objects are dumped specially, so always reject here */
+       if (strcmp(te->desc, "ENCODING") == 0)
+               return 0;
+
        /* If it's an ACL, maybe ignore it */
        if (ropt->aclsSkip && strcmp(te->desc, "ACL") == 0)
                return 0;
@@ -2019,6 +2028,33 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
        return res;
 }
 
+/*
+ * Issue SET commands for parameters that we want to have set the same way
+ * at all times during execution of a restore script.
+ */
+static void
+_doSetFixedOutputState(ArchiveHandle *AH)
+{
+       TocEntry   *te;
+
+       /* If we have an encoding setting, emit that */
+       te = AH->toc->next;
+       while (te != AH->toc)
+       {
+               if (strcmp(te->desc, "ENCODING") == 0)
+               {
+                       ahprintf(AH, "%s", te->defn);
+                       break;
+               }
+               te = te->next;
+       }
+
+       /* Make sure function checking is disabled */
+       ahprintf(AH, "SET check_function_bodies = false;\n");
+
+       ahprintf(AH, "\n");
+}
+
 /*
  * Issue a SET SESSION AUTHORIZATION command.  Caller is responsible
  * for updating state if appropriate.  If user is NULL or an empty string,
@@ -2100,7 +2136,8 @@ _reconnectToDB(ArchiveHandle *AH, const char *dbname, const char *user)
                free(AH->currSchema);
        AH->currSchema = strdup("");
 
-       AH->chk_fn_bodies = true;       /* assumed default state */
+       /* re-establish fixed state */
+       _doSetFixedOutputState(AH);
 }
 
 /*
@@ -2196,13 +2233,6 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
        _becomeOwner(AH, te);
        _selectOutputSchema(AH, te->namespace);
 
-       /* If it's a function, make sure function checking is disabled */
-       if (AH->chk_fn_bodies && strcmp(te->desc, "FUNCTION") == 0)
-       {
-               ahprintf(AH, "SET check_function_bodies = false;\n\n");
-               AH->chk_fn_bodies = false;
-       }
-
        if (isData)
                pfx = "Data for ";
        else
index fbfbba988e74e9a1688c662ffd67ff5b26555a07..0a4bc62e9d81c6498adaf4ff63e4dcc559b05665 100644 (file)
@@ -17,7 +17,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.52 2003/10/03 20:10:59 tgl Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.52.2.1 2004/02/24 03:35:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -241,7 +241,6 @@ typedef struct _archiveHandle
        /* these vars track state to avoid sending redundant SET commands */
        char       *currUser;           /* current username */
        char       *currSchema;         /* current schema */
-       bool            chk_fn_bodies;  /* current state of check_function_bodies */
 
        void       *lo_buf;
        size_t          lo_buf_used;
index 3b9133ed6ad0fd11f4b729a70c3bdee899946644..80d566d14544383b0b92603dfe44c40b6fc0197d 100644 (file)
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.355.2.2 2004/01/22 19:09:48 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.355.2.3 2004/02/24 03:35:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -115,6 +115,7 @@ static char *myFormatType(const char *typname, int32 typmod);
 static const char *fmtQualifiedId(const char *schema, const char *id);
 static int     dumpBlobs(Archive *AH, char *, void *);
 static int     dumpDatabase(Archive *AH);
+static void dumpEncoding(Archive *AH);
 static const char *getAttrName(int attrnum, TableInfo *tblInfo);
 static const char *fmtCopyColumnList(const TableInfo *ti);
 
@@ -547,6 +548,9 @@ main(int argc, char **argv)
                        write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid);
        }
 
+       /* First the special encoding entry. */
+       dumpEncoding(g_fout);
+
        /* Dump the database definition */
        if (!dataOnly)
                dumpDatabase(g_fout);
@@ -1244,6 +1248,61 @@ dumpDatabase(Archive *AH)
 }
 
 
+/*
+ * dumpEncoding: put the correct encoding into the archive
+ */
+static void
+dumpEncoding(Archive *AH)
+{
+       PQExpBuffer qry;
+       PGresult   *res;
+
+       /* Can't read the encoding from pre-7.3 servers (SHOW isn't a query) */
+       if (AH->remoteVersion < 70300)
+               return;
+
+       if (g_verbose)
+               write_msg(NULL, "saving encoding\n");
+
+       qry = createPQExpBuffer();
+
+       appendPQExpBuffer(qry, "SHOW client_encoding");
+
+       res = PQexec(g_conn, qry->data);
+       if (!res ||
+               PQresultStatus(res) != PGRES_TUPLES_OK ||
+               PQntuples(res) != 1)
+       {
+               write_msg(NULL, "SQL command failed\n");
+               write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
+               write_msg(NULL, "The command was: %s\n", qry->data);
+               exit_nicely();
+       }
+
+       resetPQExpBuffer(qry);
+
+       appendPQExpBuffer(qry, "SET client_encoding = ");
+       appendStringLiteral(qry, PQgetvalue(res, 0, 0), true);
+       appendPQExpBuffer(qry, ";\n");
+
+       ArchiveEntry(AH, "0",           /* OID */
+                                "ENCODING",    /* Name */
+                                NULL,                  /* Namespace */
+                                "",                    /* Owner */
+                                "ENCODING",    /* Desc */
+                                NULL,                  /* Deps */
+                                qry->data,             /* Create */
+                                "",                    /* Del */
+                                NULL,                  /* Copy */
+                                NULL,                  /* Dumper */
+                                NULL);                 /* Dumper Arg */
+
+       PQclear(res);
+
+       destroyPQExpBuffer(qry);
+}
+
+
 /*
  * dumpBlobs:
  *     dump all blobs