On 09/01/2013 12:53 AM, Stephen Frost wrote:
> * Stefan Kaltenbrunner ([email protected]) wrote:
>> On 08/18/2013 05:40 PM, Tom Lane wrote:
>>> Stefan Kaltenbrunner <[email protected]> writes:
>>>> While working on upgrading the database of the search system on
>>>> postgresql.org to 9.2 I noticed that the dumps that pg_dump generates on
>>>> that system are actually invalid and cannot be reloaded without being
>>>> hacked on manually...
>>>
>>>> CREATE TEXT SEARCH CONFIGURATION pg (
>>>> PARSER = pg_catalog."default" );
>>>
>>>> CREATE FUNCTION test() RETURNS INTEGER
>>>> LANGUAGE sql SET default_text_search_config TO 'public.pg' AS $$
>>>> SELECT 1;
>>>> $$;
>>>
>>>> once you dump that you will end up with an invalid dump because the
>>>> function will be dumped before the actual text search configuration is
>>>> (re)created.
>>>
>>> I don't think it will work to try to fix this by reordering the dump;
>>> it's too easy to imagine scenarios where that would lead to circular
>>> ordering constraints. What seems like a more workable answer is for
>>> CREATE FUNCTION to not attempt to validate SET clauses when
>>> check_function_bodies is off, or at least not throw a hard error when
>>> the validation fails. (I see for instance that if you try
>>> ALTER ROLE joe SET default_text_search_config TO nonesuch;
>>> you just get a notice and not an error.)
>>>
>>> However, I don't recall if there are any places where we assume the
>>> SET info was pre-validated by CREATE/ALTER FUNCTION.
>>
>> any further insights into that issue? - seems a bit silly to have an
>> open bug that actually prevents us from taking (restorable) backups of
>> the search system on our own website...
>
> It would seem that a simple solution would be to add an elevel argument
> to ProcessGUCArray and then call it with NOTICE in the case that
> check_function_bodies is true. None of the contrib modules call
> ProcessGUCArray, but should we worry that some external module does?
attached is a rough patch that does exactly that, if we are worried
about an api change we could simple do a ProcessGUCArrayNotice() in the
backbranches if that approach is actually sane.
>
> This doesn't address Tom's concern that we may trust in the SET to
> ensure that the value stored is valid. That seems like it'd be pretty
> odd given how we typically handle GUCs, but I've not done a
> comprehensive review to be sure.
well the whole per-database/per-user GUC handling is already pretty
weird/inconsistent, if you for example alter a database with an invalid
default_text_search_config you get a NOTICE about it, every time you
connect to that database later on you get a WARNING.
mastermind=# alter database mastermind set default_text_search_config to
'foo';
NOTICE: text search configuration "foo" does not exist
ALTER DATABASE
mastermind=# \q
mastermind@powerbrain:~$ psql
WARNING: invalid value for parameter "default_text_search_config": "foo"
psql (9.1.9)
Type "help" for help.
>
> Like Stefan, I'd really like to see this fixed, and sooner rather than
> later, so we can continue the process of upgrading our systems to 9.2..
well - we can certainly work around it but others might not...
Stefan
diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c
index 6e19736..7fda64c
*** a/src/backend/catalog/pg_db_role_setting.c
--- b/src/backend/catalog/pg_db_role_setting.c
*************** ApplySetting(Snapshot snapshot, Oid data
*** 262,268 ****
* right to insert an option into pg_db_role_setting was checked
* when it was inserted.
*/
! ProcessGUCArray(a, PGC_SUSET, source, GUC_ACTION_SET);
}
}
--- 262,268 ----
* right to insert an option into pg_db_role_setting was checked
* when it was inserted.
*/
! ProcessGUCArray(a, PGC_SUSET, source, GUC_ACTION_SET,0);
}
}
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 2a98ca9..5ecc630
*** a/src/backend/catalog/pg_proc.c
--- b/src/backend/catalog/pg_proc.c
*************** ProcedureCreate(const char *procedureNam
*** 679,688 ****
if (set_items) /* Need a new GUC nesting level */
{
save_nestlevel = NewGUCNestLevel();
ProcessGUCArray(set_items,
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
! GUC_ACTION_SAVE);
}
else
save_nestlevel = 0; /* keep compiler quiet */
--- 679,699 ----
if (set_items) /* Need a new GUC nesting level */
{
save_nestlevel = NewGUCNestLevel();
+ /* reduce elevel to NOTICE if check_function_bodies is disabled */
+ if (check_function_bodies) {
ProcessGUCArray(set_items,
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
! GUC_ACTION_SAVE,
! 0);
! }
! else {
! ProcessGUCArray(set_items,
! (superuser() ? PGC_SUSET : PGC_USERSET),
! PGC_S_SESSION,
! GUC_ACTION_SAVE,
! NOTICE);
! }
}
else
save_nestlevel = 0; /* keep compiler quiet */
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 42de04c..7d323eb
*** a/src/backend/utils/fmgr/fmgr.c
--- b/src/backend/utils/fmgr/fmgr.c
*************** fmgr_security_definer(PG_FUNCTION_ARGS)
*** 951,957 ****
ProcessGUCArray(fcache->proconfig,
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
! GUC_ACTION_SAVE);
}
/* function manager hook */
--- 951,958 ----
ProcessGUCArray(fcache->proconfig,
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
! GUC_ACTION_SAVE,
! 0);
}
/* function manager hook */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 0b23c38..15e4aab
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** ParseLongOption(const char *string, char
*** 7820,7832 ****
/*
* Handle options fetched from pg_db_role_setting.setconfig,
! * pg_proc.proconfig, etc. Caller must specify proper context/source/action.
*
* The array parameter must be an array of TEXT (it must not be NULL).
*/
void
ProcessGUCArray(ArrayType *array,
! GucContext context, GucSource source, GucAction action)
{
int i;
--- 7820,7832 ----
/*
* Handle options fetched from pg_db_role_setting.setconfig,
! * pg_proc.proconfig, etc. Caller must specify proper context/source/action/elevel.
*
* The array parameter must be an array of TEXT (it must not be NULL).
*/
void
ProcessGUCArray(ArrayType *array,
! GucContext context, GucSource source, GucAction action,int elevel)
{
int i;
*************** ProcessGUCArray(ArrayType *array,
*** 7868,7874 ****
(void) set_config_option(name, value,
context, source,
! action, true, 0);
free(name);
if (value)
--- 7868,7874 ----
(void) set_config_option(name, value,
context, source,
! action, true, elevel);
free(name);
if (value)
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index d497b1f..fb4b8f5
*** a/src/include/utils/guc.h
--- b/src/include/utils/guc.h
*************** extern void ExecSetVariableStmt(Variable
*** 334,340 ****
extern char *ExtractSetVariableArgs(VariableSetStmt *stmt);
extern void ProcessGUCArray(ArrayType *array,
! GucContext context, GucSource source, GucAction action);
extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value);
extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
extern ArrayType *GUCArrayReset(ArrayType *array);
--- 334,340 ----
extern char *ExtractSetVariableArgs(VariableSetStmt *stmt);
extern void ProcessGUCArray(ArrayType *array,
! GucContext context, GucSource source, GucAction action, int elevel);
extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value);
extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
extern ArrayType *GUCArrayReset(ArrayType *array);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers