diff --git a/contrib/tsearch2/gendict/sql.IN b/contrib/tsearch2/gendict/sql.IN index ff0d8423999f4810d69816baa9225daee7345fb2..044230b4173f8689953450454512cee85d3a251d 100644 --- a/contrib/tsearch2/gendict/sql.IN +++ b/contrib/tsearch2/gendict/sql.IN @@ -1,7 +1,7 @@ SET search_path = public; BEGIN; -HASINIT create function dinit_CFG_MODNAME(text) +HASINIT create function dinit_CFG_MODNAME(internal) HASINIT returns internal HASINIT as 'MODULE_PATHNAME' HASINIT language 'C'; diff --git a/contrib/tsearch2/tsearch.sql.in b/contrib/tsearch2/tsearch.sql.in index 35f96cd5cdb625243c3172c018772bf4b3538f3e..b51b049b9a865457311926431f3ff316ceef507f 100644 --- a/contrib/tsearch2/tsearch.sql.in +++ b/contrib/tsearch2/tsearch.sql.in @@ -44,7 +44,7 @@ CREATE FUNCTION set_curdict(text) with (isstrict); --built-in dictionaries -CREATE FUNCTION dex_init(text) +CREATE FUNCTION dex_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -57,13 +57,13 @@ CREATE FUNCTION dex_lexize(internal,internal,int4) insert into pg_ts_dict select 'simple', - 'dex_init(text)', + 'dex_init(internal)', null, 'dex_lexize(internal,internal,int4)', 'Simple example of dictionary.' ; -CREATE FUNCTION snb_en_init(text) +CREATE FUNCTION snb_en_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -76,26 +76,26 @@ CREATE FUNCTION snb_lexize(internal,internal,int4) insert into pg_ts_dict select 'en_stem', - 'snb_en_init(text)', + 'snb_en_init(internal)', 'contrib/english.stop', 'snb_lexize(internal,internal,int4)', 'English Stemmer. Snowball.' ; -CREATE FUNCTION snb_ru_init(text) +CREATE FUNCTION snb_ru_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; insert into pg_ts_dict select 'ru_stem', - 'snb_ru_init(text)', + 'snb_ru_init(internal)', 'contrib/russian.stop', 'snb_lexize(internal,internal,int4)', 'Russian Stemmer. Snowball.' ; -CREATE FUNCTION spell_init(text) +CREATE FUNCTION spell_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -108,13 +108,13 @@ CREATE FUNCTION spell_lexize(internal,internal,int4) insert into pg_ts_dict select 'ispell_template', - 'spell_init(text)', + 'spell_init(internal)', null, 'spell_lexize(internal,internal,int4)', 'ISpell interface. Must have .dict and .aff files' ; -CREATE FUNCTION syn_init(text) +CREATE FUNCTION syn_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -127,7 +127,7 @@ CREATE FUNCTION syn_lexize(internal,internal,int4) insert into pg_ts_dict select 'synonym', - 'syn_init(text)', + 'syn_init(internal)', null, 'syn_lexize(internal,internal,int4)', 'Example of synonym dictionary' diff --git a/contrib/tsearch2/untsearch.sql.in b/contrib/tsearch2/untsearch.sql.in index b1883d5fbdf083ced54b93bab60659d7c0b95890..2a658dfd933caac5e5d74f0329918c9db8d7fea1 100644 --- a/contrib/tsearch2/untsearch.sql.in +++ b/contrib/tsearch2/untsearch.sql.in @@ -34,14 +34,14 @@ DROP FUNCTION lexize(text, text); DROP FUNCTION lexize(text); DROP FUNCTION set_curdict(int); DROP FUNCTION set_curdict(text); -DROP FUNCTION dex_init(text); +DROP FUNCTION dex_init(internal); DROP FUNCTION dex_lexize(internal,internal,int4); -DROP FUNCTION snb_en_init(text); +DROP FUNCTION snb_en_init(internal); DROP FUNCTION snb_lexize(internal,internal,int4); -DROP FUNCTION snb_ru_init(text); -DROP FUNCTION spell_init(text); +DROP FUNCTION snb_ru_init(internal); +DROP FUNCTION spell_init(internal); DROP FUNCTION spell_lexize(internal,internal,int4); -DROP FUNCTION syn_init(text); +DROP FUNCTION syn_init(internal); DROP FUNCTION syn_lexize(internal,internal,int4); DROP FUNCTION set_curprs(int); DROP FUNCTION set_curprs(text); diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 1f8b3388db21f8f3fdf47a7aeccd08d0bcb41f69..12f6c64634f0e874a00e3d17f34939c99e146a6e 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.128 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.129 2005/05/03 16:51:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -81,6 +81,9 @@ ProcedureCreate(const char *procedureName, int allParamCount; Oid *allParams; bool genericInParam = false; + bool genericOutParam = false; + bool internalInParam = false; + bool internalOutParam = false; Relation rel; HeapTuple tup; HeapTuple oldtup; @@ -133,43 +136,59 @@ ProcedureCreate(const char *procedureName, /* * Do not allow return type ANYARRAY or ANYELEMENT unless at least one - * input argument is also ANYARRAY or ANYELEMENT + * input argument is ANYARRAY or ANYELEMENT. Also, do not allow + * return type INTERNAL unless at least one input argument is INTERNAL. */ for (i = 0; i < parameterCount; i++) { - if (parameterTypes->values[i] == ANYARRAYOID || - parameterTypes->values[i] == ANYELEMENTOID) + switch (parameterTypes->values[i]) { - genericInParam = true; - break; + case ANYARRAYOID: + case ANYELEMENTOID: + genericInParam = true; + break; + case INTERNALOID: + internalInParam = true; + break; } } - if (!genericInParam) + if (allParameterTypes != PointerGetDatum(NULL)) { - bool genericOutParam = false; - - if (allParameterTypes != PointerGetDatum(NULL)) + for (i = 0; i < allParamCount; i++) { - for (i = 0; i < allParamCount; i++) + /* + * We don't bother to distinguish input and output params here, + * so if there is, say, just an input INTERNAL param then we will + * still set internalOutParam. This is OK since we don't really + * care. + */ + switch (allParams[i]) { - if (allParams[i] == ANYARRAYOID || - allParams[i] == ANYELEMENTOID) - { + case ANYARRAYOID: + case ANYELEMENTOID: genericOutParam = true; break; - } + case INTERNALOID: + internalOutParam = true; + break; } } - - if (returnType == ANYARRAYOID || returnType == ANYELEMENTOID || - genericOutParam) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("cannot determine result data type"), - errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type."))); } + if ((returnType == ANYARRAYOID || returnType == ANYELEMENTOID || + genericOutParam) && !genericInParam) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("cannot determine result data type"), + errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type."))); + + if ((returnType == INTERNALOID || internalOutParam) && !internalInParam) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("unsafe use of INTERNAL pseudo-type"), + errdetail("A function returning \"internal\" must have at least one \"internal\" argument."))); + /* * don't allow functions of complex types that have the same name as * existing attributes of the type