diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index c343bee9d09c35ff74618b0806261b5de282ae76..0f20e75fbced49120661742e0225b9c2dcb7da8b 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.298 2010/07/20 00:47:52 rhaas Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.299 2010/07/22 01:22:32 rhaas Exp $ -->
 
 <chapter Id="runtime-config">
   <title>Server Configuration</title>
@@ -5209,6 +5209,23 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
+    <varlistentry id="guc-quote-all-identifiers" xreflabel="quote-all-identifiers">
+      <term><varname>quote_all_identifiers</varname> (<type>boolean</type>)</term>
+      <indexterm>
+       <primary><varname>quote_all_identifiers</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        When the database generates SQL, force all identifiers to be quoted,
+        even if they are not (currently) keywords.  This will affect the
+        output of <command>EXPLAIN</> as well as the results of functions
+        like <function>pg_get_viewdef</>.  See also the
+	    <option>--quote-all-identifiers</option> to
+        <xref linkend="app-pgdump"> and <xref linkend="app-pg-dumpall">.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-sql-inheritance" xreflabel="sql_inheritance">
       <term><varname>sql_inheritance</varname> (<type>boolean</type>)</term>
       <indexterm>
diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
index 0f254d45ad73aa70266b2d441d7d68d0d49d14f6..f0498df50ce597d133f09e38d542f4ac477b8d0a 100644
--- a/doc/src/sgml/ref/pg_dump.sgml
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.117 2010/02/23 17:28:09 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.118 2010/07/22 01:22:33 rhaas Exp $
 PostgreSQL documentation
 -->
 
@@ -660,6 +660,17 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--quote-all-identifiers</></term>
+      <listitem>
+       <para>
+        Force quoting of all identifiers.  This may be useful when dumping a
+        database for migration to a future version that may have introduced
+        additional keywords.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
        <term><option>-?</></term>
        <term><option>--help</></term>
diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml
index 95a37512ee1d4df28b39a798b464876926de176e..7509730885195228adb5273059b7d3b625bbb9dd 100644
--- a/doc/src/sgml/ref/pg_dumpall.sgml
+++ b/doc/src/sgml/ref/pg_dumpall.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.82 2010/04/03 07:23:01 petere Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.83 2010/07/22 01:22:33 rhaas Exp $
 PostgreSQL documentation
 -->
 
@@ -356,6 +356,17 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--quote-all-identifiers</></term>
+      <listitem>
+       <para>
+        Force quoting of all identifiers.  This may be useful when dumping a
+        database for migration to a future version that may have introduced
+        additional keywords.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
        <term><option>-?</></term>
        <term><option>--help</></term>
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 7f1ec8766c61c11174a8d3f9e3019125011414b2..e06ac5697b7344788f1d65c6773fcdda3c54ee8c 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.328 2010/07/13 20:57:19 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.329 2010/07/22 01:22:33 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -132,6 +132,7 @@ static SPIPlanPtr plan_getrulebyoid = NULL;
 static const char *query_getrulebyoid = "SELECT * FROM pg_catalog.pg_rewrite WHERE oid = $1";
 static SPIPlanPtr plan_getviewrule = NULL;
 static const char *query_getviewrule = "SELECT * FROM pg_catalog.pg_rewrite WHERE ev_class = $1 AND rulename = $2";
+bool quote_all_identifiers;
 
 
 /* ----------
@@ -6727,6 +6728,9 @@ quote_identifier(const char *ident)
 		}
 	}
 
+	if (quote_all_identifiers)
+		safe = false;
+
 	if (safe)
 	{
 		/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9cc24237f8c0418a4aafeeca01397411b94eb702..463b563b4b878d4cba51f9a1dc1c277955e6dfdb 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.564 2010/07/20 00:47:53 rhaas Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.565 2010/07/22 01:22:33 rhaas Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -1282,6 +1282,15 @@ static struct config_bool ConfigureNamesBool[] =
 		false, NULL, NULL
 	},
 
+	{
+		{"quote_all_identifiers", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
+			gettext_noop("When generating SQL fragments, quote all identifiers."),
+			NULL,
+		},
+		&quote_all_identifiers,
+		false, NULL, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 21469d3f4a8d681d19e761d3426a247b8ee8543d..d3c07bd502ca434bdb10a233e3db42e80edab1b1 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -510,6 +510,7 @@
 #default_with_oids = off
 #escape_string_warning = on
 #lo_compat_privileges = off
+#quote_all_identifiers = off
 #sql_inheritance = on
 #standard_conforming_strings = on
 #synchronize_seqscans = on
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 124a4586661e50f4bab48a477efabea377fe4414..64e5b1df104e323c49cf4ff92ca8dabcbcc4bf49 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.56 2010/03/03 20:10:48 heikki Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.57 2010/07/22 01:22:34 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,6 +36,8 @@ static bool parallel_init_done = false;
 static DWORD tls_index;
 #endif
 
+int quote_all_identifiers;
+
 void
 init_parallel_dump_utils(void)
 {
@@ -102,8 +104,10 @@ fmtId(const char *rawid)
 	 * These checks need to match the identifier production in scan.l. Don't
 	 * use islower() etc.
 	 */
+	if (quote_all_identifiers)
+		need_quotes = true;
 	/* slightly different rules for first character */
-	if (!((rawid[0] >= 'a' && rawid[0] <= 'z') || rawid[0] == '_'))
+	else if (!((rawid[0] >= 'a' && rawid[0] <= 'z') || rawid[0] == '_'))
 		need_quotes = true;
 	else
 	{
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index 298b687cd1da3970541d38337145513414d9907e..3d22a46323e76b5fb8a9b6483757b810c484a567 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.29 2010/02/26 02:01:16 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.h,v 1.30 2010/07/22 01:22:34 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,4 +46,6 @@ extern bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf,
 					  const char *schemavar, const char *namevar,
 					  const char *altnamevar, const char *visibilityrule);
 
+extern int quote_all_identifiers;
+
 #endif   /* DUMPUTILS_H */
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 63b1da09ab46220e216d0f2e1fa68729afacf450..666312fb56a3ca375650620b4c206866f9b0a115 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -25,7 +25,7 @@
  *	http://archives.postgresql.org/pgsql-bugs/2010-02/msg00187.php
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.582 2010/07/14 21:21:08 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.583 2010/07/22 01:22:34 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -297,6 +297,7 @@ main(int argc, char **argv)
 		{"inserts", no_argument, &dump_inserts, 1},
 		{"lock-wait-timeout", required_argument, NULL, 2},
 		{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
+		{"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
 		{"role", required_argument, NULL, 3},
 		{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
 
@@ -634,6 +635,12 @@ main(int argc, char **argv)
 	if (g_fout->remoteVersion >= 70300)
 		do_sql_command(g_conn, "SET statement_timeout = 0");
 
+	/*
+	 * Quote all identifiers, if requested.
+	 */
+	if (quote_all_identifiers && g_fout->remoteVersion >= 90100)
+		do_sql_command(g_conn, "SET quote_all_identifiers = true");
+
 	/*
 	 * Start serializable transaction to dump consistent data.
 	 */
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 275a22ab88d2a19726f81caa5930eea9a65d8b66..3f9b77739fab0614cb57addecb93a8db99c191b5 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.134 2010/02/26 02:01:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.135 2010/07/22 01:22:34 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -130,6 +130,7 @@ main(int argc, char *argv[])
 		{"inserts", no_argument, &inserts, 1},
 		{"lock-wait-timeout", required_argument, NULL, 2},
 		{"no-tablespaces", no_argument, &no_tablespaces, 1},
+		{"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
 		{"role", required_argument, NULL, 3},
 		{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
 
@@ -328,6 +329,8 @@ main(int argc, char *argv[])
 		appendPQExpBuffer(pgdumpopts, " --inserts");
 	if (no_tablespaces)
 		appendPQExpBuffer(pgdumpopts, " --no-tablespaces");
+	if (quote_all_identifiers)
+		appendPQExpBuffer(pgdumpopts, " --quote-all-identifiers");
 	if (use_setsessauth)
 		appendPQExpBuffer(pgdumpopts, " --use-set-session-authorization");
 
@@ -440,6 +443,10 @@ main(int argc, char *argv[])
 		destroyPQExpBuffer(query);
 	}
 
+	/* Force quoting of all identifiers if requested. */
+	if (quote_all_identifiers && server_version >= 90000)
+		executeCommand(conn, "SET quote_all_identifiers = true");
+
 	fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
 	if (verbose)
 		dumpTimestamp("Started on");
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 9f0586855c7ceb1a3767330958288884c8f8e532..92b3c64aaada7be35618c69fb4f1fcf721e6f50e 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.351 2010/07/13 20:57:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.352 2010/07/22 01:22:35 rhaas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -583,6 +583,7 @@ extern Datum record_ge(PG_FUNCTION_ARGS);
 extern Datum btrecordcmp(PG_FUNCTION_ARGS);
 
 /* ruleutils.c */
+extern bool quote_all_identifiers;
 extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
 extern Datum pg_get_ruledef_ext(PG_FUNCTION_ARGS);
 extern Datum pg_get_viewdef(PG_FUNCTION_ARGS);