mirror of
https://github.com/postgres/postgres.git
synced 2025-06-23 14:01:44 +03:00
Fix up pg_dump to do string escaping fully correctly for client encoding
and standard_conforming_strings; likewise for the other client programs that need it. As per previous discussion, a pg_dump dump now conforms to the standard_conforming_strings setting of the source database. We don't use E'' syntax in the dump, thereby improving portability of the SQL. I added a SET escape_strings_warning = off command to keep the dumps from getting a lot of back-chatter from that.
This commit is contained in:
@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.130 2006/05/26 23:48:54 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.131 2006/05/28 21:13:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -38,6 +38,7 @@
|
||||
|
||||
#include "pqexpbuffer.h"
|
||||
#include "libpq/libpq-fs.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
|
||||
|
||||
const char *progname;
|
||||
@ -60,7 +61,8 @@ static void _becomeUser(ArchiveHandle *AH, const char *user);
|
||||
static void _becomeOwner(ArchiveHandle *AH, TocEntry *te);
|
||||
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
|
||||
static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
|
||||
|
||||
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
|
||||
static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
|
||||
static teReqs _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls);
|
||||
static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
||||
static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt);
|
||||
@ -1589,6 +1591,14 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
|
||||
AH->vmin = K_VERS_MINOR;
|
||||
AH->vrev = K_VERS_REV;
|
||||
|
||||
/* initialize for backwards compatible string processing */
|
||||
AH->public.encoding = PG_SQL_ASCII;
|
||||
AH->public.std_strings = false;
|
||||
|
||||
/* sql error handling */
|
||||
AH->public.exit_on_error = true;
|
||||
AH->public.n_errors = 0;
|
||||
|
||||
AH->createDate = time(NULL);
|
||||
|
||||
AH->intSize = sizeof(int);
|
||||
@ -1676,10 +1686,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
|
||||
die_horribly(AH, modulename, "unrecognized file format \"%d\"\n", fmt);
|
||||
}
|
||||
|
||||
/* sql error handling */
|
||||
AH->public.exit_on_error = true;
|
||||
AH->public.n_errors = 0;
|
||||
|
||||
return AH;
|
||||
}
|
||||
|
||||
@ -1888,22 +1894,72 @@ ReadToc(ArchiveHandle *AH)
|
||||
ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n",
|
||||
i, te->dumpId, te->desc, te->tag);
|
||||
|
||||
/* link completed entry into TOC circular list */
|
||||
te->prev = AH->toc->prev;
|
||||
AH->toc->prev->next = te;
|
||||
AH->toc->prev = te;
|
||||
te->next = AH->toc;
|
||||
|
||||
/* special processing immediately upon read for some items */
|
||||
if (strcmp(te->desc, "ENCODING") == 0)
|
||||
processEncodingEntry(AH, te);
|
||||
else if (strcmp(te->desc, "STDSTRINGS") == 0)
|
||||
processStdStringsEntry(AH, te);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
|
||||
{
|
||||
/* te->defn should have the form SET client_encoding = 'foo'; */
|
||||
char *defn = strdup(te->defn);
|
||||
char *ptr1;
|
||||
char *ptr2 = NULL;
|
||||
int encoding;
|
||||
|
||||
ptr1 = strchr(defn, '\'');
|
||||
if (ptr1)
|
||||
ptr2 = strchr(++ptr1, '\'');
|
||||
if (ptr2)
|
||||
{
|
||||
*ptr2 = '\0';
|
||||
encoding = pg_char_to_encoding(ptr1);
|
||||
if (encoding < 0)
|
||||
die_horribly(AH, modulename, "unrecognized encoding \"%s\"\n",
|
||||
ptr1);
|
||||
AH->public.encoding = encoding;
|
||||
}
|
||||
else
|
||||
die_horribly(AH, modulename, "invalid ENCODING item: %s\n",
|
||||
te->defn);
|
||||
|
||||
free(defn);
|
||||
}
|
||||
|
||||
static void
|
||||
processStdStringsEntry(ArchiveHandle *AH, TocEntry *te)
|
||||
{
|
||||
/* te->defn should have the form SET standard_conforming_strings = 'x'; */
|
||||
char *ptr1;
|
||||
|
||||
ptr1 = strchr(te->defn, '\'');
|
||||
if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
|
||||
AH->public.std_strings = true;
|
||||
else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
|
||||
AH->public.std_strings = false;
|
||||
else
|
||||
die_horribly(AH, modulename, "invalid STDSTRINGS item: %s\n",
|
||||
te->defn);
|
||||
}
|
||||
|
||||
static teReqs
|
||||
_tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
|
||||
{
|
||||
teReqs res = REQ_ALL;
|
||||
|
||||
/* ENCODING and STDSTRINGS objects are dumped specially, so always reject */
|
||||
if (strcmp(te->desc, "ENCODING") == 0)
|
||||
return 0;
|
||||
if (strcmp(te->desc, "STDSTRINGS") == 0)
|
||||
/* ENCODING and STDSTRINGS items are dumped specially, so always reject */
|
||||
if (strcmp(te->desc, "ENCODING") == 0 ||
|
||||
strcmp(te->desc, "STDSTRINGS") == 0)
|
||||
return 0;
|
||||
|
||||
/* If it's an ACL, maybe ignore it */
|
||||
@ -2005,24 +2061,21 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
|
||||
static void
|
||||
_doSetFixedOutputState(ArchiveHandle *AH)
|
||||
{
|
||||
TocEntry *te;
|
||||
/* Select the correct character set encoding */
|
||||
ahprintf(AH, "SET client_encoding = '%s';\n",
|
||||
pg_encoding_to_char(AH->public.encoding));
|
||||
|
||||
/* If we have an encoding or std_strings setting, emit that */
|
||||
te = AH->toc->next;
|
||||
while (te != AH->toc)
|
||||
{
|
||||
if (strcmp(te->desc, "ENCODING") == 0)
|
||||
ahprintf(AH, "%s", te->defn);
|
||||
if (strcmp(te->desc, "STDSTRINGS") == 0)
|
||||
ahprintf(AH, "%s", te->defn);
|
||||
te = te->next;
|
||||
}
|
||||
/* Select the correct string literal syntax */
|
||||
ahprintf(AH, "SET standard_conforming_strings = %s;\n",
|
||||
AH->public.std_strings ? "on" : "off");
|
||||
|
||||
/* Make sure function checking is disabled */
|
||||
ahprintf(AH, "SET check_function_bodies = false;\n");
|
||||
|
||||
/* Avoid annoying notices etc */
|
||||
ahprintf(AH, "SET client_min_messages = warning;\n");
|
||||
if (!AH->public.std_strings)
|
||||
ahprintf(AH, "SET escape_string_warning = off;\n");
|
||||
|
||||
ahprintf(AH, "\n");
|
||||
}
|
||||
@ -2043,7 +2096,7 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user)
|
||||
* SQL requires a string literal here. Might as well be correct.
|
||||
*/
|
||||
if (user && *user)
|
||||
appendStringLiteral(cmd, user, false, true);
|
||||
appendStringLiteralAHX(cmd, user, AH);
|
||||
else
|
||||
appendPQExpBuffer(cmd, "DEFAULT");
|
||||
appendPQExpBuffer(cmd, ";");
|
||||
|
Reference in New Issue
Block a user