Make pg_dump output more portable and more pleasing to look at.
The -n and -N options were removed. Quoting is now smart enough to supply quotes if and only if necessary. Numerical types are now printed without quotes, except in cases of special values such as NaN. Boolean values printed as true and false. Most string literals now do not escape whitespace characters (newlines, etc.) for portability. SET SESSION AUTHORIZATION argument is a string literal, to follow SQL. Made commands output by pg_dump use consistent spacing and indentation.
This commit is contained in:
parent
41298cf8a6
commit
c828ec8820
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.47 2002/08/10 16:57:31 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.48 2002/08/18 09:36:25 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ PostgreSQL documentation
|
|||||||
<arg>-f <replaceable>file</replaceable></arg>
|
<arg>-f <replaceable>file</replaceable></arg>
|
||||||
<arg>-F <replaceable>format</replaceable></arg>
|
<arg>-F <replaceable>format</replaceable></arg>
|
||||||
<arg>-i</arg>
|
<arg>-i</arg>
|
||||||
<group> <arg>-n</arg> <arg>-N</arg> </group>
|
|
||||||
<arg>-o</arg>
|
<arg>-o</arg>
|
||||||
<arg>-O</arg>
|
<arg>-O</arg>
|
||||||
<arg>-R</arg>
|
<arg>-R</arg>
|
||||||
@ -302,31 +301,6 @@ PostgreSQL documentation
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>-n</></term>
|
|
||||||
<term><option>--no-quotes</></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Suppress double quotes around identifiers unless absolutely necessary.
|
|
||||||
This may cause trouble loading this dumped data if there are reserved words
|
|
||||||
used for identifiers.
|
|
||||||
This was the default behavior for
|
|
||||||
<command>pg_dump</command> prior to version 6.4.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>-N</></term>
|
|
||||||
<term><option>--quotes</></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Include double quotes around identifiers.
|
|
||||||
This is the default.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-o</></term>
|
<term><option>-o</></term>
|
||||||
<term><option>--oids</></term>
|
<term><option>--oids</></term>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.146 2002/08/11 21:17:34 tgl Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.147 2002/08/18 09:36:25 petere Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<appendix id="release">
|
<appendix id="release">
|
||||||
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
|
|||||||
worries about funny characters.
|
worries about funny characters.
|
||||||
-->
|
-->
|
||||||
<literallayout><![CDATA[
|
<literallayout><![CDATA[
|
||||||
|
pg_dump -n and -N options have been removed. The new behavior is like -n but knows about key words.
|
||||||
CLUSTER is no longer hazardous to your schema
|
CLUSTER is no longer hazardous to your schema
|
||||||
COPY accepts a list of columns to copy
|
COPY accepts a list of columns to copy
|
||||||
ALTER TABLE DROP COLUMN
|
ALTER TABLE DROP COLUMN
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.124 2002/08/06 05:40:45 ishii Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.125 2002/08/18 09:36:25 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -20,6 +20,8 @@
|
|||||||
#include "parser/keywords.h"
|
#include "parser/keywords.h"
|
||||||
#include "parser/parse.h"
|
#include "parser/parse.h"
|
||||||
|
|
||||||
|
/* NB: This file is also used by pg_dump. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List of (keyword-name, keyword-token-value) pairs.
|
* List of (keyword-name, keyword-token-value) pairs.
|
||||||
*
|
*
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.116 2002/08/16 23:01:19 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.117 2002/08/18 09:36:25 petere Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -2529,14 +2529,42 @@ get_const_expr(Const *constval, deparse_context *context)
|
|||||||
{
|
{
|
||||||
case INT2OID:
|
case INT2OID:
|
||||||
case INT4OID:
|
case INT4OID:
|
||||||
case OIDOID: /* int types */
|
case INT8OID:
|
||||||
|
case OIDOID:
|
||||||
case FLOAT4OID:
|
case FLOAT4OID:
|
||||||
case FLOAT8OID: /* float types */
|
case FLOAT8OID:
|
||||||
/* These types are printed without quotes */
|
case NUMERICOID:
|
||||||
appendStringInfo(buf, extval);
|
{
|
||||||
break;
|
/*
|
||||||
default:
|
* These types are printed without quotes unless they
|
||||||
|
* contain values that aren't accepted by the scanner
|
||||||
|
* unquoted (e.g., 'NaN'). Note that strtod() and friends
|
||||||
|
* might accept NaN, so we can't use that to test.
|
||||||
|
*
|
||||||
|
* In reality we only need to defend against infinity and
|
||||||
|
* NaN, so we need not get too crazy about pattern
|
||||||
|
* matching here.
|
||||||
|
*/
|
||||||
|
if (strspn(extval, "0123456789 +-eE.") == strlen(extval))
|
||||||
|
appendStringInfo(buf, extval);
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "'%s'", extval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BITOID:
|
||||||
|
case VARBITOID:
|
||||||
|
appendStringInfo(buf, "B'%s'", extval);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BOOLOID:
|
||||||
|
if (strcmp(extval, "t")==0)
|
||||||
|
appendStringInfo(buf, "true");
|
||||||
|
else
|
||||||
|
appendStringInfo(buf, "false");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
/*
|
/*
|
||||||
* We must quote any funny characters in the constant's
|
* We must quote any funny characters in the constant's
|
||||||
* representation. XXX Any MULTIBYTE considerations here?
|
* representation. XXX Any MULTIBYTE considerations here?
|
||||||
@ -2564,6 +2592,7 @@ get_const_expr(Const *constval, deparse_context *context)
|
|||||||
|
|
||||||
switch (constval->consttype)
|
switch (constval->consttype)
|
||||||
{
|
{
|
||||||
|
case BOOLOID:
|
||||||
case INT4OID:
|
case INT4OID:
|
||||||
case FLOAT8OID:
|
case FLOAT8OID:
|
||||||
case UNKNOWNOID:
|
case UNKNOWNOID:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
# Portions Copyright (c) 1994, Regents of the University of California
|
# Portions Copyright (c) 1994, Regents of the University of California
|
||||||
#
|
#
|
||||||
# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.36 2002/07/27 20:10:05 petere Exp $
|
# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.37 2002/08/18 09:36:25 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -16,15 +16,18 @@ include $(top_builddir)/src/Makefile.global
|
|||||||
OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
|
OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
|
||||||
pg_backup_files.o pg_backup_null.o pg_backup_tar.o sprompt.o
|
pg_backup_files.o pg_backup_null.o pg_backup_tar.o sprompt.o
|
||||||
|
|
||||||
|
EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o
|
||||||
|
|
||||||
override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
|
override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
|
||||||
|
|
||||||
all: submake-libpq submake-libpgport pg_dump pg_restore pg_dumpall
|
|
||||||
|
all: submake-libpq submake-libpgport submake-backend pg_dump pg_restore pg_dumpall
|
||||||
|
|
||||||
pg_dump: pg_dump.o common.o $(OBJS) $(libpq_builddir)/libpq.a
|
pg_dump: pg_dump.o common.o $(OBJS) $(libpq_builddir)/libpq.a
|
||||||
$(CC) $(CFLAGS) pg_dump.o common.o $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@
|
$(CC) $(CFLAGS) pg_dump.o common.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@
|
||||||
|
|
||||||
pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a
|
pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a
|
||||||
$(CC) $(CFLAGS) pg_restore.o $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@
|
$(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@
|
||||||
|
|
||||||
pg_dumpall: pg_dumpall.sh
|
pg_dumpall: pg_dumpall.sh
|
||||||
sed -e 's,@VERSION@,$(VERSION),g' \
|
sed -e 's,@VERSION@,$(VERSION),g' \
|
||||||
@ -33,6 +36,11 @@ pg_dumpall: pg_dumpall.sh
|
|||||||
$< >$@
|
$< >$@
|
||||||
chmod a+x $@
|
chmod a+x $@
|
||||||
|
|
||||||
|
.PHONY: submake-backend
|
||||||
|
submake-backend:
|
||||||
|
$(MAKE) -C $(top_builddir)/src/backend/parser
|
||||||
|
|
||||||
|
|
||||||
install: all installdirs
|
install: all installdirs
|
||||||
$(INSTALL_PROGRAM) pg_dump$(X) $(DESTDIR)$(bindir)/pg_dump$(X)
|
$(INSTALL_PROGRAM) pg_dump$(X) $(DESTDIR)$(bindir)/pg_dump$(X)
|
||||||
$(INSTALL_PROGRAM) pg_restore$(X) $(DESTDIR)$(bindir)/pg_restore$(X)
|
$(INSTALL_PROGRAM) pg_restore$(X) $(DESTDIR)$(bindir)/pg_restore$(X)
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.20 2002/07/04 15:35:07 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.21 2002/08/18 09:36:25 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
#include "pqexpbuffer.h"
|
||||||
|
|
||||||
#define atooid(x) ((Oid) strtoul((x), NULL, 10))
|
#define atooid(x) ((Oid) strtoul((x), NULL, 10))
|
||||||
#define oidcmp(x,y) ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) )
|
#define oidcmp(x,y) ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) )
|
||||||
@ -119,7 +120,9 @@ __attribute__((format(printf, 3, 4)));
|
|||||||
|
|
||||||
extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
|
extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
|
||||||
|
|
||||||
extern const char *fmtId(const char *identifier, bool force_quotes);
|
extern const char *fmtId(const char *identifier);
|
||||||
|
extern void appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll);
|
||||||
|
|
||||||
|
|
||||||
/* Lets the archive know we have a DB connection to shutdown if it dies */
|
/* Lets the archive know we have a DB connection to shutdown if it dies */
|
||||||
|
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.53 2002/08/10 16:57:31 petere Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.54 2002/08/18 09:36:25 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pg_backup.h"
|
#include "pg_backup.h"
|
||||||
|
#include "pg_dump.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "pg_backup_db.h"
|
#include "pg_backup_db.h"
|
||||||
|
|
||||||
@ -30,6 +31,8 @@
|
|||||||
|
|
||||||
#include "pqexpbuffer.h"
|
#include "pqexpbuffer.h"
|
||||||
#include "libpq/libpq-fs.h"
|
#include "libpq/libpq-fs.h"
|
||||||
|
#include "parser/keywords.h"
|
||||||
|
|
||||||
|
|
||||||
typedef enum _teReqs_
|
typedef enum _teReqs_
|
||||||
{
|
{
|
||||||
@ -45,7 +48,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
|
|||||||
const int compression, ArchiveMode mode);
|
const int compression, ArchiveMode mode);
|
||||||
static int _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData);
|
static int _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData);
|
||||||
|
|
||||||
static void _doSetSessionAuth(ArchiveHandle *AH, const char *autharg);
|
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
|
||||||
static void _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te);
|
static void _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te);
|
||||||
static void _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user);
|
static void _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user);
|
||||||
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
|
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
|
||||||
@ -202,7 +205,7 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
|
|||||||
if (ropt->filename || ropt->compression)
|
if (ropt->filename || ropt->compression)
|
||||||
sav = SetOutput(AH, ropt->filename, ropt->compression);
|
sav = SetOutput(AH, ropt->filename, ropt->compression);
|
||||||
|
|
||||||
ahprintf(AH, "--\n-- Selected TOC Entries:\n--\n");
|
ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Drop the items at the start, in reverse order
|
* Drop the items at the start, in reverse order
|
||||||
@ -233,7 +236,6 @@ RestoreArchive(Archive *AHX, RestoreOptions *ropt)
|
|||||||
te = AH->toc->next;
|
te = AH->toc->next;
|
||||||
while (te != AH->toc)
|
while (te != AH->toc)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Work out what, if anything, we want from this entry */
|
/* Work out what, if anything, we want from this entry */
|
||||||
reqs = _tocEntryRequired(te, ropt);
|
reqs = _tocEntryRequired(te, ropt);
|
||||||
|
|
||||||
@ -464,7 +466,7 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop
|
|||||||
}
|
}
|
||||||
else if (AH->ropt->use_setsessauth)
|
else if (AH->ropt->use_setsessauth)
|
||||||
{
|
{
|
||||||
_doSetSessionAuth(AH, "DEFAULT");
|
_doSetSessionAuth(AH, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ahlog(AH, 1, "disabling triggers\n");
|
ahlog(AH, 1, "disabling triggers\n");
|
||||||
@ -482,7 +484,7 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop
|
|||||||
if (te && te->tag && strlen(te->tag) > 0)
|
if (te && te->tag && strlen(te->tag) > 0)
|
||||||
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = 0 "
|
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = 0 "
|
||||||
"WHERE oid = '%s'::pg_catalog.regclass;\n\n",
|
"WHERE oid = '%s'::pg_catalog.regclass;\n\n",
|
||||||
fmtId(te->tag, false));
|
fmtId(te->tag));
|
||||||
else
|
else
|
||||||
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = 0 FROM pg_catalog.pg_namespace "
|
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = 0 FROM pg_catalog.pg_namespace "
|
||||||
"WHERE relnamespace = pg_namespace.oid AND nspname !~ '^pg_';\n\n");
|
"WHERE relnamespace = pg_namespace.oid AND nspname !~ '^pg_';\n\n");
|
||||||
@ -498,7 +500,7 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *rop
|
|||||||
}
|
}
|
||||||
else if (AH->ropt->use_setsessauth)
|
else if (AH->ropt->use_setsessauth)
|
||||||
{
|
{
|
||||||
_doSetSessionAuth(AH, fmtId(oldUser, false));
|
_doSetSessionAuth(AH, oldUser);
|
||||||
}
|
}
|
||||||
free(oldUser);
|
free(oldUser);
|
||||||
free(oldSchema);
|
free(oldSchema);
|
||||||
@ -531,7 +533,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
|
|||||||
}
|
}
|
||||||
else if (AH->ropt->use_setsessauth)
|
else if (AH->ropt->use_setsessauth)
|
||||||
{
|
{
|
||||||
_doSetSessionAuth(AH, "DEFAULT");
|
_doSetSessionAuth(AH, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ahlog(AH, 1, "enabling triggers\n");
|
ahlog(AH, 1, "enabling triggers\n");
|
||||||
@ -550,7 +552,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
|
|||||||
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = "
|
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = "
|
||||||
"(SELECT pg_catalog.count(*) FROM pg_catalog.pg_trigger where pg_class.oid = tgrelid) "
|
"(SELECT pg_catalog.count(*) FROM pg_catalog.pg_trigger where pg_class.oid = tgrelid) "
|
||||||
"WHERE oid = '%s'::pg_catalog.regclass;\n\n",
|
"WHERE oid = '%s'::pg_catalog.regclass;\n\n",
|
||||||
fmtId(te->tag, false));
|
fmtId(te->tag));
|
||||||
else
|
else
|
||||||
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = "
|
ahprintf(AH, "UPDATE pg_catalog.pg_class SET reltriggers = "
|
||||||
"(SELECT pg_catalog.count(*) FROM pg_catalog.pg_trigger where pg_class.oid = tgrelid) "
|
"(SELECT pg_catalog.count(*) FROM pg_catalog.pg_trigger where pg_class.oid = tgrelid) "
|
||||||
@ -568,7 +570,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt
|
|||||||
}
|
}
|
||||||
else if (AH->ropt->use_setsessauth)
|
else if (AH->ropt->use_setsessauth)
|
||||||
{
|
{
|
||||||
_doSetSessionAuth(AH, fmtId(oldUser, false));
|
_doSetSessionAuth(AH, oldUser);
|
||||||
}
|
}
|
||||||
free(oldUser);
|
free(oldUser);
|
||||||
free(oldSchema);
|
free(oldSchema);
|
||||||
@ -1942,29 +1944,38 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Issue a SET SESSION AUTHORIZATION command. Caller is responsible
|
* Issue a SET SESSION AUTHORIZATION command. Caller is responsible
|
||||||
* for updating state if appropriate. Note that caller must also quote
|
* for updating state if appropriate. If user is NULL, the
|
||||||
* the argument if it's a username (it might be DEFAULT, too).
|
* specification DEFAULT will be used.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
_doSetSessionAuth(ArchiveHandle *AH, const char *autharg)
|
_doSetSessionAuth(ArchiveHandle *AH, const char *user)
|
||||||
{
|
{
|
||||||
|
PQExpBuffer cmd = createPQExpBuffer();
|
||||||
|
appendPQExpBuffer(cmd, "SET SESSION AUTHORIZATION ");
|
||||||
|
if (user)
|
||||||
|
/* SQL requires a string literal here. Might as well be
|
||||||
|
* correct. */
|
||||||
|
appendStringLiteral(cmd, user, false);
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(cmd, "DEFAULT");
|
||||||
|
appendPQExpBuffer(cmd, ";");
|
||||||
|
|
||||||
if (RestoringToDB(AH))
|
if (RestoringToDB(AH))
|
||||||
{
|
{
|
||||||
PQExpBuffer qry = createPQExpBuffer();
|
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
|
|
||||||
appendPQExpBuffer(qry, "SET SESSION AUTHORIZATION %s;", autharg);
|
res = PQexec(AH->connection, cmd->data);
|
||||||
res = PQexec(AH->connection, qry->data);
|
|
||||||
|
|
||||||
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
|
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
die_horribly(AH, modulename, "could not set session user to %s: %s",
|
die_horribly(AH, modulename, "could not set session user to %s: %s",
|
||||||
autharg, PQerrorMessage(AH->connection));
|
user, PQerrorMessage(AH->connection));
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
destroyPQExpBuffer(qry);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ahprintf(AH, "SET SESSION AUTHORIZATION %s;\n\n", autharg);
|
ahprintf(AH, "%s\n\n", cmd->data);
|
||||||
|
|
||||||
|
destroyPQExpBuffer(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1991,7 +2002,7 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
|
|||||||
*/
|
*/
|
||||||
if (!dbname && AH->ropt->use_setsessauth)
|
if (!dbname && AH->ropt->use_setsessauth)
|
||||||
{
|
{
|
||||||
_doSetSessionAuth(AH, fmtId(user, false));
|
_doSetSessionAuth(AH, user);
|
||||||
}
|
}
|
||||||
else if (AH->ropt && AH->ropt->noReconnect)
|
else if (AH->ropt && AH->ropt->noReconnect)
|
||||||
{
|
{
|
||||||
@ -2005,9 +2016,9 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
|
|||||||
PQExpBuffer qry = createPQExpBuffer();
|
PQExpBuffer qry = createPQExpBuffer();
|
||||||
|
|
||||||
appendPQExpBuffer(qry, "\\connect %s",
|
appendPQExpBuffer(qry, "\\connect %s",
|
||||||
dbname ? fmtId(dbname, false) : "-");
|
dbname ? fmtId(dbname) : "-");
|
||||||
appendPQExpBuffer(qry, " %s\n\n",
|
appendPQExpBuffer(qry, " %s\n\n",
|
||||||
fmtId(user, false));
|
fmtId(user));
|
||||||
|
|
||||||
ahprintf(AH, qry->data);
|
ahprintf(AH, qry->data);
|
||||||
|
|
||||||
@ -2061,7 +2072,7 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
|
|||||||
qry = createPQExpBuffer();
|
qry = createPQExpBuffer();
|
||||||
|
|
||||||
appendPQExpBuffer(qry, "SET search_path = %s",
|
appendPQExpBuffer(qry, "SET search_path = %s",
|
||||||
fmtId(schemaName, false));
|
fmtId(schemaName));
|
||||||
if (strcmp(schemaName, "pg_catalog") != 0)
|
if (strcmp(schemaName, "pg_catalog") != 0)
|
||||||
appendPQExpBuffer(qry, ", pg_catalog");
|
appendPQExpBuffer(qry, ", pg_catalog");
|
||||||
|
|
||||||
@ -2089,48 +2100,48 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fmtId
|
* Quotes input string if it's not a legitimate SQL identifier as-is.
|
||||||
*
|
|
||||||
* Quotes input string if it's not a legitimate SQL identifier as-is,
|
|
||||||
* or all the time if force_quotes is true.
|
|
||||||
*
|
*
|
||||||
* Note that the returned string must be used before calling fmtId again,
|
* Note that the returned string must be used before calling fmtId again,
|
||||||
* since we re-use the same return buffer each time. Non-reentrant but
|
* since we re-use the same return buffer each time. Non-reentrant but
|
||||||
* avoids memory leakage.
|
* avoids memory leakage.
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
fmtId(const char *rawid, bool force_quotes)
|
fmtId(const char *rawid)
|
||||||
{
|
{
|
||||||
static PQExpBuffer id_return = NULL;
|
static PQExpBuffer id_return = NULL;
|
||||||
const char *cp;
|
const char *cp;
|
||||||
|
bool need_quotes = false;
|
||||||
|
|
||||||
if (id_return) /* first time through? */
|
if (id_return) /* first time through? */
|
||||||
resetPQExpBuffer(id_return);
|
resetPQExpBuffer(id_return);
|
||||||
else
|
else
|
||||||
id_return = createPQExpBuffer();
|
id_return = createPQExpBuffer();
|
||||||
|
|
||||||
if (!force_quotes)
|
/* These checks need to match the identifier production in scan.l.
|
||||||
|
* Don't use islower() etc. */
|
||||||
|
|
||||||
|
if (ScanKeywordLookup(rawid))
|
||||||
|
need_quotes = true;
|
||||||
|
/* slightly different rules for first character */
|
||||||
|
else if (!((rawid[0] >= 'a' && rawid[0] <= 'z') || rawid[0] == '_'))
|
||||||
|
need_quotes = true;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* do a quick check on the first character... */
|
/* otherwise check the entire string */
|
||||||
if (!islower((unsigned char) *rawid) && *rawid != '_')
|
for (cp = rawid; *cp; cp++)
|
||||||
force_quotes = true;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* otherwise check the entire string */
|
if (!((*cp >= 'a' && *cp <= 'z')
|
||||||
for (cp = rawid; *cp; cp++)
|
|| (*cp >= '0' && *cp <= '9')
|
||||||
|
|| (*cp == '_')))
|
||||||
{
|
{
|
||||||
if (!(islower((unsigned char) *cp) ||
|
need_quotes = true;
|
||||||
isdigit((unsigned char) *cp) ||
|
break;
|
||||||
(*cp == '_')))
|
|
||||||
{
|
|
||||||
force_quotes = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!force_quotes)
|
if (!need_quotes)
|
||||||
{
|
{
|
||||||
/* no quoting needed */
|
/* no quoting needed */
|
||||||
appendPQExpBufferStr(id_return, rawid);
|
appendPQExpBufferStr(id_return, rawid);
|
||||||
@ -2156,6 +2167,50 @@ fmtId(const char *rawid, bool force_quotes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a string value to an SQL string literal and append it to
|
||||||
|
* the given buffer.
|
||||||
|
*
|
||||||
|
* Special characters are escaped. Quote mark ' goes to '' per SQL
|
||||||
|
* standard, other stuff goes to \ sequences. If escapeAll is false,
|
||||||
|
* whitespace characters are not escaped (tabs, newlines, etc.). This
|
||||||
|
* is appropriate for dump file output.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll)
|
||||||
|
{
|
||||||
|
appendPQExpBufferChar(buf, '\'');
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
char ch = *str++;
|
||||||
|
|
||||||
|
if (ch == '\\' || ch == '\'')
|
||||||
|
{
|
||||||
|
appendPQExpBufferChar(buf, ch); /* double these */
|
||||||
|
appendPQExpBufferChar(buf, ch);
|
||||||
|
}
|
||||||
|
else if ((unsigned char) ch < (unsigned char) ' ' &&
|
||||||
|
(escapeAll
|
||||||
|
|| (ch != '\t' && ch != '\n' && ch != '\v' && ch != '\f' && ch != '\r')
|
||||||
|
))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* generate octal escape for control chars other than
|
||||||
|
* whitespace
|
||||||
|
*/
|
||||||
|
appendPQExpBufferChar(buf, '\\');
|
||||||
|
appendPQExpBufferChar(buf, ((ch >> 6) & 3) + '0');
|
||||||
|
appendPQExpBufferChar(buf, ((ch >> 3) & 7) + '0');
|
||||||
|
appendPQExpBufferChar(buf, (ch & 7) + '0');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appendPQExpBufferChar(buf, ch);
|
||||||
|
}
|
||||||
|
appendPQExpBufferChar(buf, '\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData)
|
_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData)
|
||||||
{
|
{
|
||||||
@ -2170,7 +2225,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
|
|||||||
else
|
else
|
||||||
pfx = "";
|
pfx = "";
|
||||||
|
|
||||||
ahprintf(AH, "--\n-- %sTOC Entry ID %d (OID %s)\n--\n-- Name: %s Type: %s Schema: %s Owner: %s\n",
|
ahprintf(AH, "--\n-- %sTOC entry %d (OID %s)\n-- Name: %s; Type: %s; Schema: %s; Owner: %s\n",
|
||||||
pfx, te->id, te->oid, te->tag, te->desc,
|
pfx, te->id, te->oid, te->tag, te->desc,
|
||||||
te->namespace ? te->namespace : "-",
|
te->namespace ? te->namespace : "-",
|
||||||
te->owner);
|
te->owner);
|
||||||
@ -2178,7 +2233,8 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
|
|||||||
(*AH->PrintExtraTocPtr) (AH, te);
|
(*AH->PrintExtraTocPtr) (AH, te);
|
||||||
ahprintf(AH, "--\n\n");
|
ahprintf(AH, "--\n\n");
|
||||||
|
|
||||||
ahprintf(AH, "%s\n", te->defn);
|
if (strlen(te->defn) > 0)
|
||||||
|
ahprintf(AH, "%s\n\n", te->defn);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Implements the basic DB functions used by the archiver.
|
* Implements the basic DB functions used by the archiver.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.36 2002/08/10 16:57:31 petere Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.37 2002/08/18 09:36:25 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -590,9 +590,9 @@ FixupBlobRefs(ArchiveHandle *AH, TocEntry *te)
|
|||||||
|
|
||||||
if (te->namespace && strlen(te->namespace) > 0)
|
if (te->namespace && strlen(te->namespace) > 0)
|
||||||
appendPQExpBuffer(tblName, "%s.",
|
appendPQExpBuffer(tblName, "%s.",
|
||||||
fmtId(te->namespace, false));
|
fmtId(te->namespace));
|
||||||
appendPQExpBuffer(tblName, "%s",
|
appendPQExpBuffer(tblName, "%s",
|
||||||
fmtId(te->tag, false));
|
fmtId(te->tag));
|
||||||
|
|
||||||
appendPQExpBuffer(tblQry,
|
appendPQExpBuffer(tblQry,
|
||||||
"SELECT a.attname FROM "
|
"SELECT a.attname FROM "
|
||||||
@ -624,13 +624,13 @@ FixupBlobRefs(ArchiveHandle *AH, TocEntry *te)
|
|||||||
/* Can't use fmtId twice in one call... */
|
/* Can't use fmtId twice in one call... */
|
||||||
appendPQExpBuffer(tblQry,
|
appendPQExpBuffer(tblQry,
|
||||||
"UPDATE %s SET %s = %s.newOid",
|
"UPDATE %s SET %s = %s.newOid",
|
||||||
tblName->data, fmtId(attr, false),
|
tblName->data, fmtId(attr),
|
||||||
BLOB_XREF_TABLE);
|
BLOB_XREF_TABLE);
|
||||||
appendPQExpBuffer(tblQry,
|
appendPQExpBuffer(tblQry,
|
||||||
" FROM %s WHERE %s.oldOid = %s.%s",
|
" FROM %s WHERE %s.oldOid = %s.%s",
|
||||||
BLOB_XREF_TABLE,
|
BLOB_XREF_TABLE,
|
||||||
BLOB_XREF_TABLE,
|
BLOB_XREF_TABLE,
|
||||||
tblName->data, fmtId(attr, false));
|
tblName->data, fmtId(attr));
|
||||||
|
|
||||||
ahlog(AH, 10, "SQL: %s\n", tblQry->data);
|
ahlog(AH, 10, "SQL: %s\n", tblQry->data);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_dump.h,v 1.95 2002/08/15 16:36:06 momjian Exp $
|
* $Id: pg_dump.h,v 1.96 2002/08/18 09:36:26 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -15,7 +15,6 @@
|
|||||||
#define PG_DUMP_H
|
#define PG_DUMP_H
|
||||||
|
|
||||||
#include "pg_backup.h"
|
#include "pg_backup.h"
|
||||||
#include "pqexpbuffer.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The data structures used to store system catalog information
|
* The data structures used to store system catalog information
|
||||||
|
@ -1314,7 +1314,7 @@ SELECT tablename, rulename, definition FROM pg_rules
|
|||||||
tablename | rulename | definition
|
tablename | rulename | definition
|
||||||
---------------+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
---------------+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
pg_settings | pg_settings_n | CREATE RULE pg_settings_n AS ON UPDATE TO pg_settings DO INSTEAD NOTHING;
|
pg_settings | pg_settings_n | CREATE RULE pg_settings_n AS ON UPDATE TO pg_settings DO INSTEAD NOTHING;
|
||||||
pg_settings | pg_settings_u | CREATE RULE pg_settings_u AS ON UPDATE TO pg_settings WHERE (new.name = old.name) DO SELECT set_config(old.name, new.setting, 'f'::boolean) AS set_config;
|
pg_settings | pg_settings_u | CREATE RULE pg_settings_u AS ON UPDATE TO pg_settings WHERE (new.name = old.name) DO SELECT set_config(old.name, new.setting, false) AS set_config;
|
||||||
rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired '::bpchar, '$0.00'::money, old.salary);
|
rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired '::bpchar, '$0.00'::money, old.salary);
|
||||||
rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired '::bpchar, new.salary, '$0.00'::money);
|
rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired '::bpchar, new.salary, '$0.00'::money);
|
||||||
rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored '::bpchar, new.salary, old.salary);
|
rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored '::bpchar, new.salary, old.salary);
|
||||||
|
Loading…
Reference in New Issue
Block a user