diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index a1e03c4..63aa673 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -192,6 +192,9 @@ PostgreSQL documentation
database itself and reconnect to the created database. (With a
script of this form, it doesn't matter which database in the
destination installation you connect to before running the script.)
+ It also sets all the database-level properties such as Ownership,
+ ACLs, ALTER DATABASE ... SET commands, and
+ ALTER ROLE IN DATABASE ... SET commands.
If is also specified, the script drops and
recreates the target database before reconnecting to it.
@@ -1203,10 +1206,6 @@ CREATE DATABASE foo WITH TEMPLATE template0;
ANALYZE after restoring from a dump file
to ensure optimal performance; see
and for more information.
- The dump file also does not
- contain any ALTER DATABASE ... SET> commands;
- these settings are dumped by ,
- along with database users and other installation-wide settings.
diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml
index afbadce..57aab47 100644
--- a/doc/src/sgml/ref/pg_dumpall.sgml
+++ b/doc/src/sgml/ref/pg_dumpall.sgml
@@ -116,6 +116,10 @@ PostgreSQL documentation
Dump only global objects (roles and tablespaces), no databases.
+ Any database role configuration settings are not dumped with
+ this option. User needs to use pg_dump
+ with --create option to dump ALTER ROLE IN DATABASE ... SET
+ commands.
diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index b58636e..9f559d8 100644
--- a/src/bin/pg_dump/Makefile
+++ b/src/bin/pg_dump/Makefile
@@ -31,8 +31,8 @@ pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) | submake-libpq submake-libpg
pg_restore: pg_restore.o $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
$(CC) $(CFLAGS) pg_restore.o $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
-pg_dumpall: pg_dumpall.o dumputils.o | submake-libpq submake-libpgport submake-libpgfeutils
- $(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(WIN32RES) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+pg_dumpall: pg_dumpall.o dumputils.o pg_backup_utils.o | submake-libpq submake-libpgport submake-libpgfeutils
+ $(CC) $(CFLAGS) pg_dumpall.o dumputils.o pg_backup_utils.o $(WIN32RES) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
install: all installdirs
$(INSTALL_PROGRAM) pg_dump$(X) '$(DESTDIR)$(bindir)'/pg_dump$(X)
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index b41f2b9..d41d306 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -776,3 +776,70 @@ buildACLQueries(PQExpBuffer acl_subquery, PQExpBuffer racl_subquery,
printfPQExpBuffer(init_racl_subquery, "NULL");
}
}
+
+/*
+ * Helper function for dumpXXXConfig().
+ *
+ * Frame the ALTER .. SET .. commands and fill it in buf.
+ */
+void
+makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
+ const char *type, const char *name,
+ const char *type2, const char *name2,
+ PQExpBuffer buf)
+{
+ char *pos;
+ char *mine;
+
+ mine = pg_strdup(arrayitem);
+ pos = strchr(mine, '=');
+ if (pos == NULL)
+ {
+ pg_free(mine);
+ return;
+ }
+
+ *pos = 0;
+ appendPQExpBuffer(buf, "ALTER %s %s ", type, fmtId(name));
+ if (type2 != NULL && name2 != NULL)
+ appendPQExpBuffer(buf, "IN %s %s ", type2, fmtId(name2));
+ appendPQExpBuffer(buf, "SET %s TO ", fmtId(mine));
+
+ /*
+ * Some GUC variable names are 'LIST' type and hence must not be quoted.
+ */
+ if (pg_strcasecmp(mine, "DateStyle") == 0
+ || pg_strcasecmp(mine, "search_path") == 0)
+ appendPQExpBufferStr(buf, pos + 1);
+ else
+ appendStringLiteralConn(buf, pos + 1, conn);
+ appendPQExpBufferStr(buf, ";\n");
+
+ pg_free(mine);
+}
+
+/*
+ * Run a query, return the results, exit program on failure.
+ */
+PGresult *
+executeQuery(PGconn *conn, const char *query)
+{
+ PGresult *res;
+
+ if (g_verbose)
+ fprintf(stderr, _("%s: executing %s\n"), progname, query);
+
+ res = PQexec(conn, query);
+ if (!res ||
+ PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, _("%s: query failed: %s"),
+ progname, PQerrorMessage(conn));
+ fprintf(stderr, _("%s: query was: %s\n"),
+ progname, query);
+ PQfinish(conn);
+ exit_nicely(1);
+ }
+
+ return res;
+}
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index d7eecdf..80d68f9 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -17,6 +17,7 @@
#include "libpq-fe.h"
#include "pqexpbuffer.h"
+#include "pg_backup_utils.h"
/*
* Preferred strftime(3) format specifier for printing timestamps in pg_dump
@@ -56,4 +57,10 @@ extern void buildACLQueries(PQExpBuffer acl_subquery, PQExpBuffer racl_subquery,
const char *acl_column, const char *acl_owner,
const char *obj_kind, bool binary_upgrade);
+extern void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
+ const char *type, const char *name, const char *type2,
+ const char *name2, PQExpBuffer buf);
+
+extern PGresult *executeQuery(PGconn *conn, const char *query);
+
#endif /* DUMPUTILS_H */
diff --git a/src/bin/pg_dump/pg_backup_utils.c b/src/bin/pg_dump/pg_backup_utils.c
index d7907fd..635ad2b 100644
--- a/src/bin/pg_dump/pg_backup_utils.c
+++ b/src/bin/pg_dump/pg_backup_utils.c
@@ -19,6 +19,9 @@
/* Globals exported by this file */
const char *progname = NULL;
+/* User wants verbose narration of our activities */
+bool g_verbose = false;
+
#define MAX_ON_EXIT_NICELY 20
static struct
diff --git a/src/bin/pg_dump/pg_backup_utils.h b/src/bin/pg_dump/pg_backup_utils.h
index 04b53f4..1481b48 100644
--- a/src/bin/pg_dump/pg_backup_utils.h
+++ b/src/bin/pg_dump/pg_backup_utils.h
@@ -26,7 +26,7 @@ typedef enum /* bits returned by set_dump_section */
typedef void (*on_exit_nicely_callback) (int code, void *arg);
extern const char *progname;
-
+extern bool g_verbose;
extern void set_dump_section(const char *arg, int *dumpSections);
extern void write_msg(const char *modulename, const char *fmt,...) pg_attribute_printf(2, 3);
extern void vwrite_msg(const char *modulename, const char *fmt, va_list ap) pg_attribute_printf(2, 0);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index e67171d..ccd7aea 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -86,9 +86,6 @@ typedef enum OidOptions
zeroAsNone = 8
} OidOptions;
-/* global decls */
-bool g_verbose; /* User wants verbose narration of our
- * activities. */
/* subquery used to convert user ID (eg, datdba) to user name */
static const char *username_subquery;
@@ -246,7 +243,7 @@ static void dumpPolicy(Archive *fout, PolicyInfo *polinfo);
static void dumpPublication(Archive *fout, PublicationInfo *pubinfo);
static void dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo);
static void dumpSubscription(Archive *fout, SubscriptionInfo *subinfo);
-static void dumpDatabase(Archive *AH);
+static void dumpDatabase(Archive *AH, bool aclsSkip);
static void dumpEncoding(Archive *AH);
static void dumpStdStrings(Archive *AH);
static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
@@ -266,7 +263,8 @@ static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
const char *prefix, Archive *fout);
static char *get_synchronized_snapshot(Archive *fout);
static void setupDumpWorker(Archive *AHX);
-
+static void dumpDatabaseConfig(Archive *fout, PQExpBuffer creaQry, const char *dbname);
+static void dumpDbRoleConfig(Archive *AH, PQExpBuffer creaQry);
int
main(int argc, char **argv)
@@ -826,7 +824,7 @@ main(int argc, char **argv)
/* The database item is always next, unless we don't want it at all */
if (dopt.include_everything && !dopt.dataOnly)
- dumpDatabase(fout);
+ dumpDatabase(fout, dopt.aclsSkip);
/* Now the rearrangeable objects. */
for (i = 0; i < numObjs; i++)
@@ -2418,7 +2416,7 @@ guessConstraintInheritance(TableInfo *tblinfo, int numTables)
* dump the database definition
*/
static void
-dumpDatabase(Archive *fout)
+dumpDatabase(Archive *fout, bool aclsSkip)
{
DumpOptions *dopt = fout->dopt;
PQExpBuffer dbQry = createPQExpBuffer();
@@ -2429,38 +2427,132 @@ dumpDatabase(Archive *fout)
int i_tableoid,
i_oid,
i_dba,
+ i_dbacl,
+ i_rdbacl,
i_encoding,
i_collate,
i_ctype,
i_frozenxid,
i_minmxid,
- i_tablespace;
+ i_tablespace,
+ i_dbistemplate,
+ i_dbconnlimit;
CatalogId dbCatId;
DumpId dbDumpId;
const char *datname,
*dba,
+ *dbacl,
+ *rdbacl,
*encoding,
*collate,
*ctype,
- *tablespace;
+ *tablespace,
+ *dbistemplate,
+ *dbconnlimit;
uint32 frozenxid,
minmxid;
+ char *default_encoding = NULL;
+ char *default_collate = NULL;
+ char *default_ctype = NULL;
datname = PQdb(conn);
if (g_verbose)
write_msg(NULL, "saving database definition\n");
+ /*
+ * First, get the installation's default encoding and locale information.
+ * We will dump encoding and locale specifications in the CREATE DATABASE
+ * commands for just those databases with values different from defaults.
+ *
+ * We consider template0's encoding and locale to define the installation
+ * default. Pre-8.4 installations do not have per-database locale
+ * settings; for them, every database must necessarily be using the
+ * installation default, so there's no need to do anything.
+ *
+ * TBD -- is it necessary to get the default encoding
+ */
+
+ if (fout->remoteVersion >= 80400)
+ {
+ appendPQExpBuffer(dbQry,
+ "SELECT pg_encoding_to_char(encoding), "
+ "datcollate, datctype "
+ "FROM pg_database "
+ "WHERE datname = 'template0'");
+
+ res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
+ }
+ else
+ {
+ appendPQExpBuffer(dbQry,
+ "SELECT pg_encoding_to_char(encoding), "
+ "null::text AS datcollate, null::text AS datctype "
+ "FROM pg_database "
+ "WHERE datname = 'template0'");
+
+ res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
+ }
+ /* If for some reason the template DB isn't there, treat as unknown */
+ if (PQntuples(res) > 0)
+ {
+ if (!PQgetisnull(res, 0, 0))
+ default_encoding = pg_strdup(PQgetvalue(res, 0, 0));
+ if (!PQgetisnull(res, 0, 1))
+ default_collate = pg_strdup(PQgetvalue(res, 0, 1));
+ if (!PQgetisnull(res, 0, 2))
+ default_ctype = pg_strdup(PQgetvalue(res, 0, 2));
+ }
+
+ PQclear(res);
+ resetPQExpBuffer(dbQry);
+
/* Make sure we are in proper schema */
selectSourceSchema(fout, "pg_catalog");
- /* Get the database owner and parameters from pg_database */
- if (fout->remoteVersion >= 90300)
+ /*
+ * Now collect all the information about databases to dump.
+ *
+ * For the database ACLs, as of 9.6, we extract both the positive (as
+ * datacl) and negative (as rdatacl) ACLs, relative to the default ACL for
+ * databases, which are then passed to buildACLCommands() below.
+ *
+ * See buildACLQueries() and buildACLCommands().
+ *
+ * Note that we do not support initial privileges (pg_init_privs) on
+ * databases.
+ */
+
+ if (fout->remoteVersion >= 90600)
+ {
+ appendPQExpBuffer(dbQry,
+ "SELECT tableoid, oid, "
+ "(%s datdba) AS dba, "
+ "pg_encoding_to_char(encoding) AS encoding, "
+ "datcollate, datctype, datfrozenxid, datminmxid, datistemplate, "
+ "(SELECT pg_catalog.array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
+ " SELECT pg_catalog.unnest(coalesce(datacl,pg_catalog.acldefault('d',datdba))) AS acl "
+ " EXCEPT SELECT pg_catalog.unnest(pg_catalog.acldefault('d',datdba))) as datacls)"
+ "AS datacl, "
+ "(SELECT pg_catalog.array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
+ " SELECT pg_catalog.unnest(pg_catalog.acldefault('d',datdba)) AS acl "
+ " EXCEPT SELECT pg_catalog.unnest(coalesce(datacl,pg_catalog.acldefault('d',datdba)))) as rdatacls)"
+ "AS rdatacl, "
+ "datconnlimit, "
+ "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
+ "shobj_description(oid, 'pg_database') AS description "
+
+ "FROM pg_database "
+ "WHERE datname = ",
+ username_subquery);
+ appendStringLiteralAH(dbQry, datname, fout);
+ }
+ else if (fout->remoteVersion >= 90300)
{
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
- "datcollate, datctype, datfrozenxid, datminmxid, "
+ "datcollate, datctype, datfrozenxid, datminmxid, datistemplate, datacl,'' as rdatacl, datconnlimit,"
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
"shobj_description(oid, 'pg_database') AS description "
@@ -2474,7 +2566,7 @@ dumpDatabase(Archive *fout)
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
- "datcollate, datctype, datfrozenxid, 0 AS datminmxid, "
+ "datcollate, datctype, datfrozenxid, 0 AS datminmxid, datistemplate, datacl, '' as rdatacl, datconnlimit,"
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
"shobj_description(oid, 'pg_database') AS description "
@@ -2488,7 +2580,7 @@ dumpDatabase(Archive *fout)
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
- "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, "
+ "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, datistemplate, datacl,'' as rdatacl, datconnlimit,"
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
"shobj_description(oid, 'pg_database') AS description "
@@ -2502,7 +2594,8 @@ dumpDatabase(Archive *fout)
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
"(%s datdba) AS dba, "
"pg_encoding_to_char(encoding) AS encoding, "
- "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, "
+ "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, datistemplate, datacl,'' as rdatacl,"
+ "-1 as datconnlimit,"
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace "
"FROM pg_database "
"WHERE datname = ",
@@ -2521,6 +2614,10 @@ dumpDatabase(Archive *fout)
i_frozenxid = PQfnumber(res, "datfrozenxid");
i_minmxid = PQfnumber(res, "datminmxid");
i_tablespace = PQfnumber(res, "tablespace");
+ i_dbacl = PQfnumber(res, "datacl");
+ i_rdbacl = PQfnumber(res, "rdatacl");
+ i_dbistemplate = PQfnumber(res, "datistemplate");
+ i_dbconnlimit = PQfnumber(res, "datconnlimit");
dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
@@ -2531,29 +2628,70 @@ dumpDatabase(Archive *fout)
frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
tablespace = PQgetvalue(res, 0, i_tablespace);
+ dbacl = PQgetvalue(res, 0, i_dbacl);
+ rdbacl = PQgetvalue(res, 0, i_rdbacl);
+ dbistemplate = PQgetvalue(res, 0, i_dbistemplate);
+ dbconnlimit = PQgetvalue(res, 0, i_dbconnlimit);
- appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
- fmtId(datname));
- if (strlen(encoding) > 0)
- {
- appendPQExpBufferStr(creaQry, " ENCODING = ");
- appendStringLiteralAH(creaQry, encoding, fout);
- }
- if (strlen(collate) > 0)
+ /*
+ * Skip the CREATE DATABASE commands for "template1" and "postgres", since
+ * they are presumably already there in the destination cluster. We do
+ * want to emit their ACLs and config options if any, however.
+ */
+ if (strcmp(datname, "template1") != 0 && strcmp(datname, "postgres") != 0)
{
- appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
- appendStringLiteralAH(creaQry, collate, fout);
+ appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
+ fmtId(datname));
+
+ if (strlen(dba) > 0)
+ {
+ appendPQExpBufferStr(creaQry, " OWNER = ");
+ appendStringLiteralAH(creaQry, dba, fout);
+ }
+ if (strlen(encoding) > 0 && default_encoding && strcmp(encoding, default_encoding) != 0)
+ {
+ appendPQExpBufferStr(creaQry, " ENCODING = ");
+ appendStringLiteralAH(creaQry, encoding, fout);
+ }
+ if (strlen(collate) > 0 && default_collate && strcmp(collate, default_collate) != 0)
+ {
+ appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
+ appendStringLiteralAH(creaQry, collate, fout);
+ }
+ if (strlen(ctype) > 0 && default_ctype && strcmp(ctype, default_ctype) != 0)
+ {
+ appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+ appendStringLiteralAH(creaQry, ctype, fout);
+ }
+ if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
+ !dopt->outputNoTablespaces)
+ {
+ appendPQExpBuffer(creaQry, " TABLESPACE = %s",
+ fmtId(tablespace));
+ }
+
+ if (strlen(dbistemplate) > 0 && strcmp(dbistemplate, "t") == 0)
+ appendPQExpBuffer(creaQry, " IS_TEMPLATE = true");
+
+ if (strlen(dbconnlimit) > 0 && strcmp(dbconnlimit, "-1") != 0)
+ appendPQExpBuffer(creaQry, " CONNECTION LIMIT = %s",
+ dbconnlimit);
+
+ appendPQExpBufferStr(creaQry, ";\n");
}
- if (strlen(ctype) > 0)
+ else if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 && !dopt->outputNoTablespaces)
{
- appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
- appendStringLiteralAH(creaQry, ctype, fout);
+ if (strcmp(datname, "postgres") == 0)
+ appendPQExpBuffer(creaQry, "\\ connect template1\n");
+ else if (strcmp(datname, "template1") == 0)
+ appendPQExpBuffer(creaQry, "\\ connect postgres\n");
+
+ appendPQExpBuffer(creaQry, "ALTER DATABASE %s SET TABLESPACE %s;\n",
+ datname, fmtId(tablespace));
+
+ /* connect to original database */
+ appendPsqlMetaConnect(creaQry, datname);
}
- if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
- !dopt->outputNoTablespaces)
- appendPQExpBuffer(creaQry, " TABLESPACE = %s",
- fmtId(tablespace));
- appendPQExpBufferStr(creaQry, ";\n");
if (dopt->binary_upgrade)
{
@@ -2567,6 +2705,20 @@ dumpDatabase(Archive *fout)
}
+ if (!aclsSkip &&
+ !buildACLCommands(datname, NULL, "DATABASE",
+ dbacl, rdbacl, dba,
+ "", fout->remoteVersion, creaQry))
+ {
+ exit_horribly(NULL, _("%s: could not parse ACL list (%s) for database \"%s\"\n"), progname, dbacl, datname);
+ }
+
+ /* Dump database specific configuration */
+ dumpDatabaseConfig(fout, creaQry, datname);
+
+ /* Dump user and database specific configuration */
+ dumpDbRoleConfig(fout, creaQry);
+
appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
fmtId(datname));
@@ -2738,6 +2890,13 @@ dumpDatabase(Archive *fout)
PQclear(shres);
}
+ if (default_encoding)
+ free(default_encoding);
+ if (default_collate)
+ free(default_collate);
+ if (default_ctype)
+ free(default_ctype);
+
PQclear(res);
destroyPQExpBuffer(dbQry);
@@ -17470,3 +17629,87 @@ appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
if (!res)
write_msg(NULL, "WARNING: could not parse reloptions array\n");
}
+
+/*
+ * Dump database-specific configuration
+ */
+static void
+dumpDatabaseConfig(Archive *AH, PQExpBuffer creaQry, const char *dbname)
+{
+ PGconn *conn = GetConnection(AH);
+ PQExpBuffer buf = createPQExpBuffer();
+ int count = 1;
+
+ for (;;)
+ {
+ PGresult *res;
+
+ if (AH->remoteVersion >= 90000)
+ printfPQExpBuffer(buf, "SELECT setconfig[%d] FROM pg_db_role_setting WHERE "
+ "setrole = 0 AND setdatabase = (SELECT oid FROM pg_database WHERE datname = ", count);
+ else
+ printfPQExpBuffer(buf, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count);
+
+ appendStringLiteralConn(buf, dbname, conn);
+
+ if (AH->remoteVersion >= 90000)
+ appendPQExpBuffer(buf, ")");
+
+ res = executeQuery(conn, buf->data);
+ resetPQExpBuffer(buf);
+
+ if (PQntuples(res) == 1 &&
+ !PQgetisnull(res, 0, 0))
+ {
+ makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
+ "DATABASE", dbname, NULL, NULL, buf);
+
+ appendPQExpBuffer(creaQry, "%s", buf->data);
+ PQclear(res);
+ count++;
+ }
+ else
+ {
+ PQclear(res);
+ break;
+ }
+ }
+
+ destroyPQExpBuffer(buf);
+}
+
+/*
+ * Dump user-and-database-specific configuration
+ */
+static void
+dumpDbRoleConfig(Archive *AH, PQExpBuffer creaQry)
+{
+ PGconn *conn = GetConnection(AH);
+ PQExpBuffer buf = createPQExpBuffer();
+ PGresult *res;
+ int i;
+
+ printfPQExpBuffer(buf, "SELECT rolname, datname, unnest(setconfig) "
+ "FROM pg_db_role_setting, pg_roles, pg_database "
+ "WHERE setrole = pg_roles.oid AND setdatabase = pg_database.oid");
+ res = executeQuery(conn, buf->data);
+
+ if (PQntuples(res) > 0)
+ {
+ appendPQExpBufferStr(creaQry, "\n\n--\n-- Per-Database Role Settings \n--\n\n");
+
+ resetPQExpBuffer(buf);
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ makeAlterConfigCommand(conn, PQgetvalue(res, i, 2),
+ "ROLE", PQgetvalue(res, i, 0),
+ "DATABASE", PQgetvalue(res, i, 1), buf);
+ }
+
+ appendPQExpBuffer(creaQry, "%s", buf->data);
+ appendPQExpBufferStr(creaQry, "\n\n");
+ }
+
+ PQclear(res);
+ destroyPQExpBuffer(buf);
+}
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 81ed924..f9410a4 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -37,16 +37,9 @@ static void dumpGroups(PGconn *conn);
static void dropTablespaces(PGconn *conn);
static void dumpTablespaces(PGconn *conn);
static void dropDBs(PGconn *conn);
-static void dumpCreateDB(PGconn *conn);
-static void dumpDatabaseConfig(PGconn *conn, const char *dbname);
static void dumpUserConfig(PGconn *conn, const char *username);
-static void dumpDbRoleConfig(PGconn *conn);
-static void makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
- const char *type, const char *name, const char *type2,
- const char *name2);
static void dumpDatabases(PGconn *conn);
static void dumpTimestamp(const char *msg);
-
static int runPgDump(const char *dbname);
static void buildShSecLabels(PGconn *conn, const char *catalog_name,
uint32 objectId, PQExpBuffer buffer,
@@ -54,15 +47,12 @@ static void buildShSecLabels(PGconn *conn, const char *catalog_name,
static PGconn *connectDatabase(const char *dbname, const char *connstr, const char *pghost, const char *pgport,
const char *pguser, trivalue prompt_password, bool fail_on_error);
static char *constructConnStr(const char **keywords, const char **values);
-static PGresult *executeQuery(PGconn *conn, const char *query);
static void executeCommand(PGconn *conn, const char *query);
static char pg_dump_bin[MAXPGPATH];
-static const char *progname;
static PQExpBuffer pgdumpopts;
static char *connstr = "";
static bool skip_acls = false;
-static bool verbose = false;
static int binary_upgrade = 0;
static int column_inserts = 0;
@@ -264,7 +254,7 @@ main(int argc, char *argv[])
break;
case 'v':
- verbose = true;
+ g_verbose = true;
appendPQExpBufferStr(pgdumpopts, " -v");
break;
@@ -466,7 +456,7 @@ main(int argc, char *argv[])
executeCommand(conn, "SET quote_all_identifiers = true");
fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
- if (verbose)
+ if (g_verbose)
dumpTimestamp("Started on");
/*
@@ -526,17 +516,6 @@ main(int argc, char *argv[])
/* Dump tablespaces */
if (!roles_only && !no_tablespaces)
dumpTablespaces(conn);
-
- /* Dump CREATE DATABASE commands */
- if (binary_upgrade || (!globals_only && !roles_only && !tablespaces_only))
- dumpCreateDB(conn);
-
- /* Dump role/database settings */
- if (!tablespaces_only && !roles_only)
- {
- if (server_version >= 90000)
- dumpDbRoleConfig(conn);
- }
}
if (!globals_only && !roles_only && !tablespaces_only)
@@ -544,7 +523,7 @@ main(int argc, char *argv[])
PQfinish(conn);
- if (verbose)
+ if (g_verbose)
dumpTimestamp("Completed on");
fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
@@ -1260,324 +1239,6 @@ dropDBs(PGconn *conn)
}
/*
- * Dump commands to create each database.
- *
- * To minimize the number of reconnections (and possibly ensuing
- * password prompts) required by the output script, we emit all CREATE
- * DATABASE commands during the initial phase of the script, and then
- * run pg_dump for each database to dump the contents of that
- * database. We skip databases marked not datallowconn, since we'd be
- * unable to connect to them anyway (and besides, we don't want to
- * dump template0).
- */
-static void
-dumpCreateDB(PGconn *conn)
-{
- PQExpBuffer buf = createPQExpBuffer();
- char *default_encoding = NULL;
- char *default_collate = NULL;
- char *default_ctype = NULL;
- PGresult *res;
- int i;
-
- fprintf(OPF, "--\n-- Database creation\n--\n\n");
-
- /*
- * First, get the installation's default encoding and locale information.
- * We will dump encoding and locale specifications in the CREATE DATABASE
- * commands for just those databases with values different from defaults.
- *
- * We consider template0's encoding and locale to define the installation
- * default. Pre-8.4 installations do not have per-database locale
- * settings; for them, every database must necessarily be using the
- * installation default, so there's no need to do anything.
- */
- if (server_version >= 80400)
- res = executeQuery(conn,
- "SELECT pg_encoding_to_char(encoding), "
- "datcollate, datctype "
- "FROM pg_database "
- "WHERE datname = 'template0'");
- else
- res = executeQuery(conn,
- "SELECT pg_encoding_to_char(encoding), "
- "null::text AS datcollate, null::text AS datctype "
- "FROM pg_database "
- "WHERE datname = 'template0'");
-
- /* If for some reason the template DB isn't there, treat as unknown */
- if (PQntuples(res) > 0)
- {
- if (!PQgetisnull(res, 0, 0))
- default_encoding = pg_strdup(PQgetvalue(res, 0, 0));
- if (!PQgetisnull(res, 0, 1))
- default_collate = pg_strdup(PQgetvalue(res, 0, 1));
- if (!PQgetisnull(res, 0, 2))
- default_ctype = pg_strdup(PQgetvalue(res, 0, 2));
- }
-
- PQclear(res);
-
-
- /*
- * Now collect all the information about databases to dump.
- *
- * For the database ACLs, as of 9.6, we extract both the positive (as
- * datacl) and negative (as rdatacl) ACLs, relative to the default ACL for
- * databases, which are then passed to buildACLCommands() below.
- *
- * See buildACLQueries() and buildACLCommands().
- *
- * Note that we do not support initial privileges (pg_init_privs) on
- * databases.
- */
- if (server_version >= 90600)
- printfPQExpBuffer(buf,
- "SELECT datname, "
- "coalesce(rolname, (select rolname from %s where oid=(select datdba from pg_database where datname='template0'))), "
- "pg_encoding_to_char(d.encoding), "
- "datcollate, datctype, datfrozenxid, datminmxid, "
- "datistemplate, "
- "(SELECT pg_catalog.array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
- " SELECT pg_catalog.unnest(coalesce(datacl,pg_catalog.acldefault('d',datdba))) AS acl "
- " EXCEPT SELECT pg_catalog.unnest(pg_catalog.acldefault('d',datdba))) as datacls)"
- "AS datacl, "
- "(SELECT pg_catalog.array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
- " SELECT pg_catalog.unnest(pg_catalog.acldefault('d',datdba)) AS acl "
- " EXCEPT SELECT pg_catalog.unnest(coalesce(datacl,pg_catalog.acldefault('d',datdba)))) as rdatacls)"
- "AS rdatacl, "
- "datconnlimit, "
- "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
- "FROM pg_database d LEFT JOIN %s u ON (datdba = u.oid) "
- "WHERE datallowconn ORDER BY 1", role_catalog, role_catalog);
- else if (server_version >= 90300)
- printfPQExpBuffer(buf,
- "SELECT datname, "
- "coalesce(rolname, (select rolname from %s where oid=(select datdba from pg_database where datname='template0'))), "
- "pg_encoding_to_char(d.encoding), "
- "datcollate, datctype, datfrozenxid, datminmxid, "
- "datistemplate, datacl, '' as rdatacl, "
- "datconnlimit, "
- "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
- "FROM pg_database d LEFT JOIN %s u ON (datdba = u.oid) "
- "WHERE datallowconn ORDER BY 1", role_catalog, role_catalog);
- else if (server_version >= 80400)
- printfPQExpBuffer(buf,
- "SELECT datname, "
- "coalesce(rolname, (select rolname from %s where oid=(select datdba from pg_database where datname='template0'))), "
- "pg_encoding_to_char(d.encoding), "
- "datcollate, datctype, datfrozenxid, 0 AS datminmxid, "
- "datistemplate, datacl, '' as rdatacl, "
- "datconnlimit, "
- "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
- "FROM pg_database d LEFT JOIN %s u ON (datdba = u.oid) "
- "WHERE datallowconn ORDER BY 1", role_catalog, role_catalog);
- else if (server_version >= 80100)
- printfPQExpBuffer(buf,
- "SELECT datname, "
- "coalesce(rolname, (select rolname from %s where oid=(select datdba from pg_database where datname='template0'))), "
- "pg_encoding_to_char(d.encoding), "
- "null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
- "datistemplate, datacl, '' as rdatacl, "
- "datconnlimit, "
- "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
- "FROM pg_database d LEFT JOIN %s u ON (datdba = u.oid) "
- "WHERE datallowconn ORDER BY 1", role_catalog, role_catalog);
- else
- printfPQExpBuffer(buf,
- "SELECT datname, "
- "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
- "pg_encoding_to_char(d.encoding), "
- "null::text AS datcollate, null::text AS datctype, datfrozenxid, 0 AS datminmxid, "
- "datistemplate, datacl, '' as rdatacl, "
- "-1 as datconnlimit, "
- "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
- "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
- "WHERE datallowconn ORDER BY 1");
-
- res = executeQuery(conn, buf->data);
-
- for (i = 0; i < PQntuples(res); i++)
- {
- char *dbname = PQgetvalue(res, i, 0);
- char *dbowner = PQgetvalue(res, i, 1);
- char *dbencoding = PQgetvalue(res, i, 2);
- char *dbcollate = PQgetvalue(res, i, 3);
- char *dbctype = PQgetvalue(res, i, 4);
- uint32 dbfrozenxid = atooid(PQgetvalue(res, i, 5));
- uint32 dbminmxid = atooid(PQgetvalue(res, i, 6));
- char *dbistemplate = PQgetvalue(res, i, 7);
- char *dbacl = PQgetvalue(res, i, 8);
- char *rdbacl = PQgetvalue(res, i, 9);
- char *dbconnlimit = PQgetvalue(res, i, 10);
- char *dbtablespace = PQgetvalue(res, i, 11);
- char *fdbname;
-
- fdbname = pg_strdup(fmtId(dbname));
-
- resetPQExpBuffer(buf);
-
- /*
- * Skip the CREATE DATABASE commands for "template1" and "postgres",
- * since they are presumably already there in the destination cluster.
- * We do want to emit their ACLs and config options if any, however.
- */
- if (strcmp(dbname, "template1") != 0 &&
- strcmp(dbname, "postgres") != 0)
- {
- appendPQExpBuffer(buf, "CREATE DATABASE %s", fdbname);
-
- appendPQExpBufferStr(buf, " WITH TEMPLATE = template0");
-
- if (strlen(dbowner) != 0)
- appendPQExpBuffer(buf, " OWNER = %s", fmtId(dbowner));
-
- if (default_encoding && strcmp(dbencoding, default_encoding) != 0)
- {
- appendPQExpBufferStr(buf, " ENCODING = ");
- appendStringLiteralConn(buf, dbencoding, conn);
- }
-
- if (default_collate && strcmp(dbcollate, default_collate) != 0)
- {
- appendPQExpBufferStr(buf, " LC_COLLATE = ");
- appendStringLiteralConn(buf, dbcollate, conn);
- }
-
- if (default_ctype && strcmp(dbctype, default_ctype) != 0)
- {
- appendPQExpBufferStr(buf, " LC_CTYPE = ");
- appendStringLiteralConn(buf, dbctype, conn);
- }
-
- /*
- * Output tablespace if it isn't the default. For default, it
- * uses the default from the template database. If tablespace is
- * specified and tablespace creation failed earlier, (e.g. no such
- * directory), the database creation will fail too. One solution
- * would be to use 'SET default_tablespace' like we do in pg_dump
- * for setting non-default database locations.
- */
- if (strcmp(dbtablespace, "pg_default") != 0 && !no_tablespaces)
- appendPQExpBuffer(buf, " TABLESPACE = %s",
- fmtId(dbtablespace));
-
- if (strcmp(dbistemplate, "t") == 0)
- appendPQExpBuffer(buf, " IS_TEMPLATE = true");
-
- if (strcmp(dbconnlimit, "-1") != 0)
- appendPQExpBuffer(buf, " CONNECTION LIMIT = %s",
- dbconnlimit);
-
- appendPQExpBufferStr(buf, ";\n");
- }
- else if (strcmp(dbtablespace, "pg_default") != 0 && !no_tablespaces)
- {
- /*
- * Cannot change tablespace of the database we're connected to, so
- * to move "postgres" to another tablespace, we connect to
- * "template1", and vice versa.
- */
- if (strcmp(dbname, "postgres") == 0)
- appendPQExpBuffer(buf, "\\connect template1\n");
- else
- appendPQExpBuffer(buf, "\\connect postgres\n");
-
- appendPQExpBuffer(buf, "ALTER DATABASE %s SET TABLESPACE %s;\n",
- fdbname, fmtId(dbtablespace));
-
- /* connect to original database */
- appendPsqlMetaConnect(buf, dbname);
- }
-
- if (binary_upgrade)
- {
- appendPQExpBufferStr(buf, "-- For binary upgrade, set datfrozenxid and datminmxid.\n");
- appendPQExpBuffer(buf, "UPDATE pg_catalog.pg_database "
- "SET datfrozenxid = '%u', datminmxid = '%u' "
- "WHERE datname = ",
- dbfrozenxid, dbminmxid);
- appendStringLiteralConn(buf, dbname, conn);
- appendPQExpBufferStr(buf, ";\n");
- }
-
- if (!skip_acls &&
- !buildACLCommands(fdbname, NULL, "DATABASE",
- dbacl, rdbacl, dbowner,
- "", server_version, buf))
- {
- fprintf(stderr, _("%s: could not parse ACL list (%s) for database \"%s\"\n"),
- progname, dbacl, fdbname);
- PQfinish(conn);
- exit_nicely(1);
- }
-
- fprintf(OPF, "%s", buf->data);
-
- dumpDatabaseConfig(conn, dbname);
-
- free(fdbname);
- }
-
- if (default_encoding)
- free(default_encoding);
- if (default_collate)
- free(default_collate);
- if (default_ctype)
- free(default_ctype);
-
- PQclear(res);
- destroyPQExpBuffer(buf);
-
- fprintf(OPF, "\n\n");
-}
-
-
-/*
- * Dump database-specific configuration
- */
-static void
-dumpDatabaseConfig(PGconn *conn, const char *dbname)
-{
- PQExpBuffer buf = createPQExpBuffer();
- int count = 1;
-
- for (;;)
- {
- PGresult *res;
-
- if (server_version >= 90000)
- printfPQExpBuffer(buf, "SELECT setconfig[%d] FROM pg_db_role_setting WHERE "
- "setrole = 0 AND setdatabase = (SELECT oid FROM pg_database WHERE datname = ", count);
- else
- printfPQExpBuffer(buf, "SELECT datconfig[%d] FROM pg_database WHERE datname = ", count);
- appendStringLiteralConn(buf, dbname, conn);
-
- if (server_version >= 90000)
- appendPQExpBuffer(buf, ")");
-
- res = executeQuery(conn, buf->data);
- if (PQntuples(res) == 1 &&
- !PQgetisnull(res, 0, 0))
- {
- makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
- "DATABASE", dbname, NULL, NULL);
- PQclear(res);
- count++;
- }
- else
- {
- PQclear(res);
- break;
- }
- }
-
- destroyPQExpBuffer(buf);
-}
-
-
-
-/*
* Dump user-specific configuration
*/
static void
@@ -1603,11 +1264,14 @@ dumpUserConfig(PGconn *conn, const char *username)
appendPQExpBufferChar(buf, ')');
res = executeQuery(conn, buf->data);
+ resetPQExpBuffer(buf);
+
if (PQntuples(res) == 1 &&
!PQgetisnull(res, 0, 0))
{
makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
- "ROLE", username, NULL, NULL);
+ "ROLE", username, NULL, NULL, buf);
+ fprintf(OPF, "%s", buf->data);
PQclear(res);
count++;
}
@@ -1621,86 +1285,6 @@ dumpUserConfig(PGconn *conn, const char *username)
destroyPQExpBuffer(buf);
}
-
-/*
- * Dump user-and-database-specific configuration
- */
-static void
-dumpDbRoleConfig(PGconn *conn)
-{
- PQExpBuffer buf = createPQExpBuffer();
- PGresult *res;
- int i;
-
- printfPQExpBuffer(buf, "SELECT rolname, datname, unnest(setconfig) "
- "FROM pg_db_role_setting, %s u, pg_database "
- "WHERE setrole = u.oid AND setdatabase = pg_database.oid", role_catalog);
- res = executeQuery(conn, buf->data);
-
- if (PQntuples(res) > 0)
- {
- fprintf(OPF, "--\n-- Per-Database Role Settings \n--\n\n");
-
- for (i = 0; i < PQntuples(res); i++)
- {
- makeAlterConfigCommand(conn, PQgetvalue(res, i, 2),
- "ROLE", PQgetvalue(res, i, 0),
- "DATABASE", PQgetvalue(res, i, 1));
- }
-
- fprintf(OPF, "\n\n");
- }
-
- PQclear(res);
- destroyPQExpBuffer(buf);
-}
-
-
-/*
- * Helper function for dumpXXXConfig().
- */
-static void
-makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
- const char *type, const char *name,
- const char *type2, const char *name2)
-{
- char *pos;
- char *mine;
- PQExpBuffer buf;
-
- mine = pg_strdup(arrayitem);
- pos = strchr(mine, '=');
- if (pos == NULL)
- {
- free(mine);
- return;
- }
-
- buf = createPQExpBuffer();
-
- *pos = 0;
- appendPQExpBuffer(buf, "ALTER %s %s ", type, fmtId(name));
- if (type2 != NULL && name2 != NULL)
- appendPQExpBuffer(buf, "IN %s %s ", type2, fmtId(name2));
- appendPQExpBuffer(buf, "SET %s TO ", fmtId(mine));
-
- /*
- * Some GUC variable names are 'LIST' type and hence must not be quoted.
- */
- if (pg_strcasecmp(mine, "DateStyle") == 0
- || pg_strcasecmp(mine, "search_path") == 0)
- appendPQExpBufferStr(buf, pos + 1);
- else
- appendStringLiteralConn(buf, pos + 1, conn);
- appendPQExpBufferStr(buf, ";\n");
-
- fprintf(OPF, "%s", buf->data);
- destroyPQExpBuffer(buf);
- free(mine);
-}
-
-
-
/*
* Dump contents of databases.
*/
@@ -1715,50 +1299,17 @@ dumpDatabases(PGconn *conn)
for (i = 0; i < PQntuples(res); i++)
{
int ret;
-
char *dbname = PQgetvalue(res, i, 0);
- PQExpBufferData connectbuf;
- if (verbose)
+ if (g_verbose)
fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
- initPQExpBuffer(&connectbuf);
- appendPsqlMetaConnect(&connectbuf, dbname);
- fprintf(OPF, "%s\n", connectbuf.data);
- termPQExpBuffer(&connectbuf);
-
- /*
- * Restore will need to write to the target cluster. This connection
- * setting is emitted for pg_dumpall rather than in the code also used
- * by pg_dump, so that a cluster with databases or users which have
- * this flag turned on can still be replicated through pg_dumpall
- * without editing the file or stream. With pg_dump there are many
- * other ways to allow the file to be used, and leaving it out allows
- * users to protect databases from being accidental restore targets.
- */
- fprintf(OPF, "SET default_transaction_read_only = off;\n\n");
-
- if (filename)
- fclose(OPF);
-
ret = runPgDump(dbname);
if (ret != 0)
{
fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
exit_nicely(1);
}
-
- if (filename)
- {
- OPF = fopen(filename, PG_BINARY_A);
- if (!OPF)
- {
- fprintf(stderr, _("%s: could not re-open the output file \"%s\": %s\n"),
- progname, filename, strerror(errno));
- exit_nicely(1);
- }
- }
-
}
PQclear(res);
@@ -1779,6 +1330,13 @@ runPgDump(const char *dbname)
appendPQExpBuffer(cmd, "\"%s\" %s", pg_dump_bin,
pgdumpopts->data);
+
+ /*
+ * The create individual database logic has been moved to pg_dump. invoke
+ * pg_dump with create database option.
+ */
+ appendPQExpBufferStr(cmd, " -C ");
+
/*
* If we have a filename, use the undocumented plain-append pg_dump
* format.
@@ -1797,7 +1355,7 @@ runPgDump(const char *dbname)
appendShellString(cmd, connstrbuf->data);
- if (verbose)
+ if (g_verbose)
fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data);
fflush(stdout);
@@ -2090,31 +1648,7 @@ constructConnStr(const char **keywords, const char **values)
return connstr;
}
-/*
- * Run a query, return the results, exit program on failure.
- */
-static PGresult *
-executeQuery(PGconn *conn, const char *query)
-{
- PGresult *res;
-
- if (verbose)
- fprintf(stderr, _("%s: executing %s\n"), progname, query);
-
- res = PQexec(conn, query);
- if (!res ||
- PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, _("%s: query failed: %s"),
- progname, PQerrorMessage(conn));
- fprintf(stderr, _("%s: query was: %s\n"),
- progname, query);
- PQfinish(conn);
- exit_nicely(1);
- }
- return res;
-}
/*
* As above for a SQL command (which returns nothing).
@@ -2124,7 +1658,7 @@ executeCommand(PGconn *conn, const char *query)
{
PGresult *res;
- if (verbose)
+ if (g_verbose)
fprintf(stderr, _("%s: executing %s\n"), progname, query);
res = PQexec(conn, query);