]> granicus.if.org Git - postgresql/commitdiff
Accept a non-existent value in "ALTER USER/DATABASE SET ..." command.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 30 Jan 2012 08:32:46 +0000 (10:32 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 30 Jan 2012 09:19:38 +0000 (11:19 +0200)
When default_text_search_config, default_tablespace, or temp_tablespaces
setting is set per-user or per-database, with an "ALTER USER/DATABASE SET
..." statement, don't throw an error if the text search configuration or
tablespace does not exist. In case of text search configuration, even if
it doesn't exist in the current database, it might exist in another
database, where the setting is intended to have its effect. This behavior
is now the same as search_path's.

Tablespaces are cluster-wide, so the same argument doesn't hold for
tablespaces, but there's a problem with pg_dumpall: it dumps "ALTER USER
SET ..." statements before the "CREATE TABLESPACE" statements. Arguably
that's pg_dumpall's fault - it should dump the statements in such an order
that the tablespace is created first and then the "ALTER USER SET
default_tablespace ..." statements after that - but it seems better to be
consistent with search_path and default_text_search_config anyway. Besides,
you could still create a dump that throws an error, by creating the
tablespace, running "ALTER USER SET default_tablespace", then dropping the
tablespace and running pg_dumpall on that.

Backpatch to all supported versions.

src/backend/commands/tablespace.c
src/backend/utils/cache/ts_cache.c

index 3024dc4b6468ebf0c4b3eac1152f10550ab5bda7..3513fc7688050c71b9ba32c857877c18684b8e27 100644 (file)
@@ -1036,9 +1036,27 @@ check_default_tablespace(char **newval, void **extra, GucSource source)
                if (**newval != '\0' &&
                        !OidIsValid(get_tablespace_oid(*newval, true)))
                {
-                       GUC_check_errdetail("Tablespace \"%s\" does not exist.",
-                                                               *newval);
-                       return false;
+                       /*
+                        * When source == PGC_S_TEST, we are checking the argument of an
+                        * ALTER DATABASE SET or ALTER USER SET command.  pg_dumpall dumps
+                        * all roles before tablespaces, so if we're restoring a
+                        * pg_dumpall script the tablespace might not yet exist, but will
+                        * be created later.  Because of that, issue a NOTICE if source ==
+                        * PGC_S_TEST, but accept the value anyway.
+                        */
+                       if (source == PGC_S_TEST)
+                       {
+                               ereport(NOTICE,
+                                               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                                                errmsg("tablespace \"%s\" does not exist",
+                                                               *newval)));
+                       }
+                       else
+                       {
+                               GUC_check_errdetail("Tablespace \"%s\" does not exist.",
+                                                                       *newval);
+                               return false;
+                       }
                }
        }
 
@@ -1153,12 +1171,25 @@ check_temp_tablespaces(char **newval, void **extra, GucSource source)
                        }
 
                        /*
-                        * In an interactive SET command, we ereport for bad info.
-                        * Otherwise, silently ignore any bad list elements.
+                        * In an interactive SET command, we ereport for bad info.  When
+                        * source == PGC_S_TEST, we are checking the argument of an ALTER
+                        * DATABASE SET or ALTER USER SET command.  pg_dumpall dumps all
+                        * roles before tablespaces, so if we're restoring a pg_dumpall
+                        * script the tablespace might not yet exist, but will be created
+                        * later.  Because of that, issue a NOTICE if source == PGC_S_TEST,
+                        * but accept the value anyway.  Otherwise, silently ignore any
+                        * bad list elements.
                         */
-                       curoid = get_tablespace_oid(curname, source < PGC_S_INTERACTIVE);
+                       curoid = get_tablespace_oid(curname, source <= PGC_S_TEST);
                        if (curoid == InvalidOid)
+                       {
+                               if (source == PGC_S_TEST)
+                                       ereport(NOTICE,
+                                                       (errcode(ERRCODE_UNDEFINED_OBJECT),
+                                                        errmsg("tablespace \"%s\" does not exist",
+                                                                       curname)));
                                continue;
+                       }
 
                        /*
                         * Allow explicit specification of database's default tablespace
index a8c4d76565a375d888dc0cc28cefac23969d7daa..6a6cbbf90c1758ca37b5e67b0ce81b355940f62c 100644 (file)
@@ -604,8 +604,25 @@ check_TSCurrentConfig(char **newval, void **extra, GucSource source)
 
                cfgId = get_ts_config_oid(stringToQualifiedNameList(*newval), true);
 
+               /*
+                * When source == PGC_S_TEST, we are checking the argument of an
+                * ALTER DATABASE SET or ALTER USER SET command.  It could be that
+                * the intended use of the setting is for some other database, so
+                * we should not error out if the text search configuration is not
+                * present in the current database.  We issue a NOTICE instead.
+                */
                if (!OidIsValid(cfgId))
-                       return false;
+               {
+                       if (source == PGC_S_TEST)
+                       {
+                               ereport(NOTICE,
+                                               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                                                errmsg("text search configuration \"%s\" does not exist", *newval)));
+                               return true;
+                       }
+                       else
+                               return false;
+               }
 
                /*
                 * Modify the actually stored value to be fully qualified, to ensure