aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-03-21 20:03:28 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2018-03-21 20:03:28 -0400
commita35d7292316556a172f82796811f1ffb3400160b (patch)
treec7d207ae92a5c7554dedaab5d22dcdc7993dc8d8 /src/test
parent487a6e38de9048f29a1c23cb2c796cce3b1cdd62 (diff)
downloadpostgresql-a35d7292316556a172f82796811f1ffb3400160b.tar.gz
postgresql-a35d7292316556a172f82796811f1ffb3400160b.zip
Fix mishandling of quoted-list GUC values in pg_dump and ruleutils.c.
Code that prints out the contents of setconfig or proconfig arrays in SQL format needs to handle GUC_LIST_QUOTE variables differently from other ones, because for those variables, flatten_set_variable_args() already applied a layer of quoting. The value can therefore safely be printed as-is, and indeed must be, or flatten_set_variable_args() will muck it up completely on reload. For all other GUC variables, it's necessary and sufficient to quote the value as a SQL literal. We'd recognized the need for this long ago, but mis-analyzed the need slightly, thinking that all GUC_LIST_INPUT variables needed the special treatment. That's actually wrong, since a valid value of a LIST variable might include characters that need quoting, although no existing variables accept such values. More to the point, we hadn't made any particular effort to keep the various places that deal with this up-to-date with the set of variables that actually need special treatment, meaning that we'd do the wrong thing with, for example, temp_tablespaces values. This affects dumping of SET clauses attached to functions, as well as ALTER DATABASE/ROLE SET commands. In ruleutils.c we can fix it reasonably honestly by exporting a guc.c function that allows discovering the flags for a given GUC variable. But pg_dump doesn't have easy access to that, so continue the old method of having a hard-wired list of affected variable names. At least we can fix it to have just one list not two, and update the list to match current reality. A remaining problem with this is that it only works for built-in GUC variables. pg_dump's list obvious knows nothing of third-party extensions, and even the "ask guc.c" method isn't bulletproof since the relevant extension might not be loaded. There's no obvious solution to that, so for now, we'll just have to discourage extension authors from inventing custom GUCs that need GUC_LIST_QUOTE. This has been busted for a long time, so back-patch to all supported branches. Michael Paquier and Tom Lane, reviewed by Kyotaro Horiguchi and Pavel Stehule Discussion: https://postgr.es/m/20180111064900.GA51030@paquier.xyz
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/rules.out27
-rw-r--r--src/test/regress/sql/rules.sql13
2 files changed, 40 insertions, 0 deletions
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index bc400cb80c0..63094c03b99 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -3018,3 +3018,30 @@ SELECT * FROM hat_data WHERE hat_name IN ('h8', 'h9', 'h7') ORDER BY hat_name;
DROP RULE hat_upsert ON hats;
drop table hats;
drop table hat_data;
+-- test for pg_get_functiondef properly regurgitating SET parameters
+-- Note that the function is kept around to stress pg_dump.
+CREATE FUNCTION func_with_set_params() RETURNS integer
+ AS 'select 1;'
+ LANGUAGE SQL
+ SET search_path TO PG_CATALOG
+ SET extra_float_digits TO 2
+ SET work_mem TO '4MB'
+ SET datestyle to iso, mdy
+ SET local_preload_libraries TO "Mixed/Case", 'c:/"a"/path'
+ IMMUTABLE STRICT;
+SELECT pg_get_functiondef('func_with_set_params()'::regprocedure);
+ pg_get_functiondef
+---------------------------------------------------------------
+ CREATE OR REPLACE FUNCTION public.func_with_set_params() +
+ RETURNS integer +
+ LANGUAGE sql +
+ IMMUTABLE STRICT +
+ SET search_path TO pg_catalog +
+ SET extra_float_digits TO '2' +
+ SET work_mem TO '4MB' +
+ SET "DateStyle" TO 'iso, mdy' +
+ SET local_preload_libraries TO "Mixed/Case", "c:/""a""/path"+
+ AS $function$select 1;$function$ +
+
+(1 row)
+
diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql
index eb4176d1785..1d43c8b2058 100644
--- a/src/test/regress/sql/rules.sql
+++ b/src/test/regress/sql/rules.sql
@@ -1144,3 +1144,16 @@ DROP RULE hat_upsert ON hats;
drop table hats;
drop table hat_data;
+
+-- test for pg_get_functiondef properly regurgitating SET parameters
+-- Note that the function is kept around to stress pg_dump.
+CREATE FUNCTION func_with_set_params() RETURNS integer
+ AS 'select 1;'
+ LANGUAGE SQL
+ SET search_path TO PG_CATALOG
+ SET extra_float_digits TO 2
+ SET work_mem TO '4MB'
+ SET datestyle to iso, mdy
+ SET local_preload_libraries TO "Mixed/Case", 'c:/"a"/path'
+ IMMUTABLE STRICT;
+SELECT pg_get_functiondef('func_with_set_params()'::regprocedure);