Skip to content

Commit 92bec9a

Browse files
committed
Cause pg_dump to emit a 'SET client_encoding' command at the start of
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.
1 parent 55fb172 commit 92bec9a

File tree

3 files changed

+91
-16
lines changed

3 files changed

+91
-16
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.82 2004/01/04 04:02:15 tgl Exp $
18+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.83 2004/02/24 03:35:19 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -49,6 +49,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
4949
const int compression, ArchiveMode mode);
5050
static int _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData);
5151

52+
static void _doSetFixedOutputState(ArchiveHandle *AH);
5253
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
5354
static void _reconnectToDB(ArchiveHandle *AH, const char *dbname, const char *user);
5455
static void _becomeUser(ArchiveHandle *AH, const char *user);
@@ -200,6 +201,11 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
200201

201202
ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");
202203

204+
/*
205+
* Establish important parameter values right away.
206+
*/
207+
_doSetFixedOutputState(AH);
208+
203209
/*
204210
* Drop the items at the start, in reverse order
205211
*/
@@ -1568,7 +1574,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
15681574
AH->currUser = strdup(""); /* So it's valid, but we can free() it
15691575
* later if necessary */
15701576
AH->currSchema = strdup(""); /* ditto */
1571-
AH->chk_fn_bodies = true; /* assumed default state */
15721577

15731578
AH->toc = (TocEntry *) calloc(1, sizeof(TocEntry));
15741579
if (!AH->toc)
@@ -1826,6 +1831,10 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
18261831
{
18271832
teReqs res = 3; /* Schema = 1, Data = 2, Both = 3 */
18281833

1834+
/* ENCODING objects are dumped specially, so always reject here */
1835+
if (strcmp(te->desc, "ENCODING") == 0)
1836+
return 0;
1837+
18291838
/* If it's an ACL, maybe ignore it */
18301839
if (ropt->aclsSkip && strcmp(te->desc, "ACL") == 0)
18311840
return 0;
@@ -1910,6 +1919,33 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
19101919
return res;
19111920
}
19121921

1922+
/*
1923+
* Issue SET commands for parameters that we want to have set the same way
1924+
* at all times during execution of a restore script.
1925+
*/
1926+
static void
1927+
_doSetFixedOutputState(ArchiveHandle *AH)
1928+
{
1929+
TocEntry *te;
1930+
1931+
/* If we have an encoding setting, emit that */
1932+
te = AH->toc->next;
1933+
while (te != AH->toc)
1934+
{
1935+
if (strcmp(te->desc, "ENCODING") == 0)
1936+
{
1937+
ahprintf(AH, "%s", te->defn);
1938+
break;
1939+
}
1940+
te = te->next;
1941+
}
1942+
1943+
/* Make sure function checking is disabled */
1944+
ahprintf(AH, "SET check_function_bodies = false;\n");
1945+
1946+
ahprintf(AH, "\n");
1947+
}
1948+
19131949
/*
19141950
* Issue a SET SESSION AUTHORIZATION command. Caller is responsible
19151951
* for updating state if appropriate. If user is NULL or an empty string,
@@ -1991,7 +2027,8 @@ _reconnectToDB(ArchiveHandle *AH, const char *dbname, const char *user)
19912027
free(AH->currSchema);
19922028
AH->currSchema = strdup("");
19932029

1994-
AH->chk_fn_bodies = true; /* assumed default state */
2030+
/* re-establish fixed state */
2031+
_doSetFixedOutputState(AH);
19952032
}
19962033

19972034
/*
@@ -2087,13 +2124,6 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
20872124
_becomeOwner(AH, te);
20882125
_selectOutputSchema(AH, te->namespace);
20892126

2090-
/* If it's a function, make sure function checking is disabled */
2091-
if (AH->chk_fn_bodies && strcmp(te->desc, "FUNCTION") == 0)
2092-
{
2093-
ahprintf(AH, "SET check_function_bodies = false;\n\n");
2094-
AH->chk_fn_bodies = false;
2095-
}
2096-
20972127
if (isData)
20982128
pfx = "Data for ";
20992129
else

src/bin/pg_dump/pg_backup_archiver.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*
1818
*
1919
* IDENTIFICATION
20-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.55 2003/12/08 16:39:05 tgl Exp $
20+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.56 2004/02/24 03:35:19 tgl Exp $
2121
*
2222
*-------------------------------------------------------------------------
2323
*/
@@ -245,7 +245,6 @@ typedef struct _archiveHandle
245245
/* these vars track state to avoid sending redundant SET commands */
246246
char *currUser; /* current username */
247247
char *currSchema; /* current schema */
248-
bool chk_fn_bodies; /* current state of check_function_bodies */
249248

250249
void *lo_buf;
251250
size_t lo_buf_used;

src/bin/pg_dump/pg_dump.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* by PostgreSQL
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.364 2004/02/12 23:41:03 tgl Exp $
15+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.365 2004/02/24 03:35:19 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -148,6 +148,7 @@ static char *myFormatType(const char *typname, int32 typmod);
148148
static const char *fmtQualifiedId(const char *schema, const char *id);
149149
static int dumpBlobs(Archive *AH, void *arg);
150150
static void dumpDatabase(Archive *AH);
151+
static void dumpEncoding(Archive *AH);
151152
static const char *getAttrName(int attrnum, TableInfo *tblInfo);
152153
static const char *fmtCopyColumnList(const TableInfo *ti);
153154
static void do_sql_command(PGconn *conn, const char *query);
@@ -561,11 +562,14 @@ main(int argc, char **argv)
561562
* in a safe order.
562563
*/
563564

564-
/* The database item is always first. */
565+
/* First the special encoding entry. */
566+
dumpEncoding(g_fout);
567+
568+
/* The database item is always second. */
565569
if (!dataOnly)
566570
dumpDatabase(g_fout);
567571

568-
/* Max OID is second. */
572+
/* Max OID is next. */
569573
if (oids == true)
570574
setMaxOid(g_fout);
571575

@@ -575,7 +579,7 @@ main(int argc, char **argv)
575579
dumpDumpableObject(g_fout, dobjs[i]);
576580
}
577581

578-
/* BLOBs are always last. */
582+
/* BLOBs are always last (XXX is this right?) */
579583
if (outputBlobs)
580584
ArchiveEntry(g_fout, nilCatalogId, createDumpId(),
581585
"BLOBS", NULL, "",
@@ -1246,6 +1250,48 @@ dumpDatabase(Archive *AH)
12461250
}
12471251

12481252

1253+
/*
1254+
* dumpEncoding: put the correct encoding into the archive
1255+
*/
1256+
static void
1257+
dumpEncoding(Archive *AH)
1258+
{
1259+
PQExpBuffer qry;
1260+
PGresult *res;
1261+
1262+
/* Can't read the encoding from pre-7.3 servers (SHOW isn't a query) */
1263+
if (AH->remoteVersion < 70300)
1264+
return;
1265+
1266+
if (g_verbose)
1267+
write_msg(NULL, "saving encoding\n");
1268+
1269+
qry = createPQExpBuffer();
1270+
1271+
appendPQExpBuffer(qry, "SHOW client_encoding");
1272+
1273+
res = PQexec(g_conn, qry->data);
1274+
1275+
check_sql_result(res, g_conn, qry->data, PGRES_TUPLES_OK);
1276+
1277+
resetPQExpBuffer(qry);
1278+
1279+
appendPQExpBuffer(qry, "SET client_encoding = ");
1280+
appendStringLiteral(qry, PQgetvalue(res, 0, 0), true);
1281+
appendPQExpBuffer(qry, ";\n");
1282+
1283+
ArchiveEntry(AH, nilCatalogId, createDumpId(),
1284+
"ENCODING", NULL, "",
1285+
"ENCODING", qry->data, "", NULL,
1286+
NULL, 0,
1287+
NULL, NULL);
1288+
1289+
PQclear(res);
1290+
1291+
destroyPQExpBuffer(qry);
1292+
}
1293+
1294+
12491295
/*
12501296
* dumpBlobs:
12511297
* dump all blobs

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