diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 21089df6794..443cd40387f 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ @@ -2085,6 +2085,17 @@ SET ENABLE_SEQSCAN TO OFF; + + check_function_bodies (boolean) + + + This parameter is normally true. When set false, it disables + validation of the function body string in CREATE FUNCTION. + Disabling validation is occasionally useful to avoid problems such as + forward references when restoring function definitions from a dump. + + + diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 99f07549bd2..fde65fd109e 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.108 2003/09/29 00:05:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.109 2003/10/03 19:26:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,6 +34,10 @@ #include "utils/syscache.h" +/* GUC parameter */ +bool check_function_bodies = true; + + Datum fmgr_internal_validator(PG_FUNCTION_ARGS); Datum fmgr_c_validator(PG_FUNCTION_ARGS); Datum fmgr_sql_validator(PG_FUNCTION_ARGS); @@ -560,6 +564,11 @@ fmgr_internal_validator(PG_FUNCTION_ARGS) Datum tmp; char *prosrc; + /* + * We do not honor check_function_bodies since it's unlikely the + * function name will be found later if it isn't there now. + */ + tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(funcoid), 0, 0, 0); @@ -604,6 +613,12 @@ fmgr_c_validator(PG_FUNCTION_ARGS) char *prosrc; char *probin; + /* + * It'd be most consistent to skip the check if !check_function_bodies, + * but the purpose of that switch is to be helpful for pg_dump loading, + * and for pg_dump loading it's much better if we *do* check. + */ + tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(funcoid), 0, 0, 0); @@ -633,8 +648,7 @@ fmgr_c_validator(PG_FUNCTION_ARGS) /* * Validator for SQL language functions * - * Parse it here in order to be sure that it contains no syntax - * errors. + * Parse it here in order to be sure that it contains no syntax errors. */ Datum fmgr_sql_validator(PG_FUNCTION_ARGS) @@ -689,30 +703,34 @@ fmgr_sql_validator(PG_FUNCTION_ARGS) } } - tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull); - if (isnull) - elog(ERROR, "null prosrc"); - - prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp)); - - /* - * We can't do full prechecking of the function definition if there - * are any polymorphic input types, because actual datatypes of - * expression results will be unresolvable. The check will be done at - * runtime instead. - * - * We can run the text through the raw parser though; this will at least - * catch silly syntactic errors. - */ - if (!haspolyarg) + /* Postpone body checks if !check_function_bodies */ + if (check_function_bodies) { - querytree_list = pg_parse_and_rewrite(prosrc, - proc->proargtypes, - proc->pronargs); - check_sql_fn_retval(proc->prorettype, functyptype, querytree_list); + tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull); + if (isnull) + elog(ERROR, "null prosrc"); + + prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp)); + + /* + * We can't do full prechecking of the function definition if there + * are any polymorphic input types, because actual datatypes of + * expression results will be unresolvable. The check will be done + * at runtime instead. + * + * We can run the text through the raw parser though; this will at + * least catch silly syntactic errors. + */ + if (!haspolyarg) + { + querytree_list = pg_parse_and_rewrite(prosrc, + proc->proargtypes, + proc->pronargs); + check_sql_fn_retval(proc->prorettype, functyptype, querytree_list); + } + else + querytree_list = pg_parse_query(prosrc); } - else - querytree_list = pg_parse_query(prosrc); ReleaseSysCache(tuple); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 1b085104927..377993a3742 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut . * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.161 2003/09/29 00:05:25 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.162 2003/10/03 19:26:49 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -66,6 +66,7 @@ /* XXX these should appear in other modules' header files */ extern bool Log_connections; +extern bool check_function_bodies; extern int PreAuthDelay; extern int AuthenticationTimeout; extern int CheckPointTimeout; @@ -821,6 +822,14 @@ static struct config_bool ConfigureNamesBool[] = &add_missing_from, true, NULL, NULL }, + { + {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("check function bodies during CREATE FUNCTION"), + NULL + }, + &check_function_bodies, + true, NULL, NULL + }, /* End-of-list marker */ { diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index c04aaab39bb..c880dc40318 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -205,6 +205,7 @@ # - Statement Behavior - #search_path = '$user,public' # schema names +#check_function_bodies = true #default_transaction_isolation = 'read committed' #default_transaction_read_only = false #statement_timeout = 0 # 0 is disabled, in milliseconds