Change tsearch2 to not use the unsafe practice of creating functions
authorTom Lane <[email protected]>
Tue, 3 May 2005 16:51:45 +0000 (16:51 +0000)
committerTom Lane <[email protected]>
Tue, 3 May 2005 16:51:45 +0000 (16:51 +0000)
that return INTERNAL without also having INTERNAL arguments.  Since the
functions in question aren't meant to be called by hand anyway, I just
redeclared them to take 'internal' instead of 'text'.  Also add code
to ProcedureCreate() to enforce the restriction, as I should have done
to start with :-(

contrib/tsearch2/gendict/sql.IN [new file with mode: 0644]
contrib/tsearch2/tsearch.sql.in
contrib/tsearch2/untsearch.sql.in [new file with mode: 0644]
src/backend/catalog/pg_proc.c

diff --git a/contrib/tsearch2/gendict/sql.IN b/contrib/tsearch2/gendict/sql.IN
new file mode 100644 (file)
index 0000000..044230b
--- /dev/null
@@ -0,0 +1,26 @@
+SET search_path = public;
+BEGIN;
+
+HASINIT create function dinit_CFG_MODNAME(internal)
+HASINIT         returns internal
+HASINIT         as 'MODULE_PATHNAME'
+HASINIT         language 'C';
+
+NOSNOWBALL create function dlexize_CFG_MODNAME(internal,internal,int4)
+NOSNOWBALL        returns internal
+NOSNOWBALL        as 'MODULE_PATHNAME'
+NOSNOWBALL        language 'C'
+NOSNOWBALL        with (isstrict);
+
+insert into pg_ts_dict select
+        'CFG_MODNAME',
+HASINIT        (select oid from pg_proc where proname='dinit_CFG_MODNAME'),
+NOINIT        null,
+        null,
+ISSNOWBALL        (select oid from pg_proc where proname='snb_lexize'),
+NOSNOWBALL        (select oid from pg_proc where proname='dlexize_CFG_MODNAME'),
+        CFG_COMMENT
+;
+
+
+END;
index bb5fc5a6a2cc72fb5e99a0b90faa0048da5b7fdf..5a621d6ebf43a5e724b29f506c35bbe1f5eb3f45 100644 (file)
@@ -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';
@@ -63,7 +63,7 @@ insert into pg_ts_dict select
        'Simple example of dictionary.'
 ;
         
-CREATE FUNCTION snb_en_init(text)
+CREATE FUNCTION snb_en_init(internal)
        returns internal
        as 'MODULE_PATHNAME' 
        language 'C';
@@ -82,7 +82,7 @@ insert into pg_ts_dict select
        'English Stemmer. Snowball.'
 ;
 
-CREATE FUNCTION snb_ru_init(text)
+CREATE FUNCTION snb_ru_init(internal)
        returns internal
        as 'MODULE_PATHNAME' 
        language 'C';
@@ -95,7 +95,7 @@ insert into pg_ts_dict select
        'Russian Stemmer. Snowball.'
 ;
         
-CREATE FUNCTION spell_init(text)
+CREATE FUNCTION spell_init(internal)
        returns internal
        as 'MODULE_PATHNAME' 
        language 'C';
@@ -114,7 +114,7 @@ insert into pg_ts_dict select
        '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';
diff --git a/contrib/tsearch2/untsearch.sql.in b/contrib/tsearch2/untsearch.sql.in
new file mode 100644 (file)
index 0000000..ed79b69
--- /dev/null
@@ -0,0 +1,65 @@
+BEGIN;
+
+--Be careful !!!
+--script drops all indices, triggers and columns with types defined
+--in tsearch2.sql
+
+
+DROP OPERATOR CLASS gist_tsvector_ops USING gist CASCADE;
+
+
+DROP OPERATOR || (tsvector, tsvector);
+DROP OPERATOR @@ (tsvector, tsquery);
+DROP OPERATOR @@ (tsquery, tsvector);
+
+DROP AGGREGATE stat(tsvector);
+
+DROP TABLE pg_ts_dict;
+DROP TABLE pg_ts_parser;
+DROP TABLE pg_ts_cfg;
+DROP TABLE pg_ts_cfgmap;
+
+DROP TYPE tokentype CASCADE;
+DROP TYPE tokenout CASCADE;
+DROP TYPE tsvector CASCADE;
+DROP TYPE tsquery CASCADE;
+DROP TYPE gtsvector CASCADE;
+DROP TYPE tsstat CASCADE;
+DROP TYPE statinfo CASCADE;
+DROP TYPE tsdebug CASCADE;
+
+
+DROP FUNCTION lexize(oid, text) ;
+DROP FUNCTION lexize(text, text);
+DROP FUNCTION lexize(text);
+DROP FUNCTION set_curdict(int);
+DROP FUNCTION set_curdict(text);
+DROP FUNCTION dex_init(internal);
+DROP FUNCTION dex_lexize(internal,internal,int4);
+DROP FUNCTION snb_en_init(internal);
+DROP FUNCTION snb_lexize(internal,internal,int4);
+DROP FUNCTION snb_ru_init(internal);
+DROP FUNCTION spell_init(internal);
+DROP FUNCTION spell_lexize(internal,internal,int4);
+DROP FUNCTION syn_init(internal);
+DROP FUNCTION syn_lexize(internal,internal,int4);
+DROP FUNCTION set_curprs(int);
+DROP FUNCTION set_curprs(text);
+DROP FUNCTION prsd_start(internal,int4);
+DROP FUNCTION prsd_getlexeme(internal,internal,internal);
+DROP FUNCTION prsd_end(internal);
+DROP FUNCTION prsd_lextype(internal);
+DROP FUNCTION prsd_headline(internal,internal,internal);
+DROP FUNCTION set_curcfg(int);
+DROP FUNCTION set_curcfg(text);
+DROP FUNCTION show_curcfg();
+DROP FUNCTION gtsvector_compress(internal);
+DROP FUNCTION gtsvector_decompress(internal);
+DROP FUNCTION gtsvector_penalty(internal,internal,internal);
+DROP FUNCTION gtsvector_picksplit(internal, internal);
+DROP FUNCTION gtsvector_union(bytea, internal);
+DROP FUNCTION reset_tsearch();
+DROP FUNCTION tsearch2() CASCADE;
+DROP FUNCTION _get_parser_from_curcfg();
+
+END;
index aa7f01d6303b0c81c4c61a657e83813121331ccb..cba798d289ce4fff60b484e05bd2393cdf98bed3 100644 (file)
@@ -65,6 +65,8 @@ ProcedureCreate(const char *procedureName,
                                const Oid *parameterTypes)
 {
        int                     i;
+       bool            genericParam = false;
+       bool            internalParam = false;
        Relation        rel;
        HeapTuple       tup;
        HeapTuple       oldtup;
@@ -94,29 +96,36 @@ ProcedureCreate(const char *procedureName,
 
        /*
         * Do not allow return type ANYARRAY or ANYELEMENT unless at least one
-        * 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.
         */
-       if (returnType == ANYARRAYOID || returnType == ANYELEMENTOID)
+       for (i = 0; i < parameterCount; i++)
        {
-               bool            genericParam = false;
-
-               for (i = 0; i < parameterCount; i++)
+               switch (parameterTypes[i])
                {
-                       if (parameterTypes[i] == ANYARRAYOID ||
-                               parameterTypes[i] == ANYELEMENTOID)
-                       {
+                       case ANYARRAYOID:
+                       case ANYELEMENTOID:
                                genericParam = true;
                                break;
-                       }
+                       case INTERNALOID:
+                               internalParam = true;
+                               break;
                }
-
-               if (!genericParam)
-                       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)
+               && !genericParam)
+               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 && !internalParam)
+               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.")));
+
        /* Make sure we have a zero-padded param type array */
        MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid));
        if (parameterCount > 0)