]> git.openstreetmap.org Git - osqa.git/blob - forum_modules/pgfulltext/pg_fts_install.sql
Several improvements in full text search operations.
[osqa.git] / forum_modules / pgfulltext / pg_fts_install.sql
1 CREATE OR REPLACE FUNCTION public.create_plpgsql_language ()
2     RETURNS TEXT
3     AS $$
4         CREATE LANGUAGE plpgsql;
5         SELECT 'language plpgsql created'::TEXT;
6     $$
7 LANGUAGE 'sql';
8
9 SELECT CASE WHEN
10       (SELECT true::BOOLEAN
11          FROM pg_language
12         WHERE lanname='plpgsql')
13     THEN
14       (SELECT 'language already installed'::TEXT)
15     ELSE
16       (SELECT public.create_plpgsql_language())
17     END;
18
19 DROP FUNCTION public.create_plpgsql_language ();
20
21 CREATE OR REPLACE FUNCTION public.drop_tsv_noderevision_column () RETURNS VOID AS $$
22 begin
23         ALTER TABLE forum_noderevision DROP COLUMN tsv;
24         DROP TRIGGER IF EXISTS tsvectorupdate ON forum_noderevision;
25 end
26 $$ LANGUAGE plpgsql;
27
28 CREATE OR REPLACE FUNCTION public.tsv_noderevision_column_exists() RETURNS int AS $$
29  SELECT COUNT(attname)::int FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'forum_noderevision') AND attname = 'tsv';
30 $$ LANGUAGE 'sql';
31
32 select case when public.tsv_noderevision_column_exists()>0 then public.drop_tsv_noderevision_column()end;
33
34 drop function drop_tsv_noderevision_column();
35 drop function tsv_noderevision_column_exists();
36
37 CREATE OR REPLACE FUNCTION set_doctable_tsv() RETURNS TRIGGER AS $$
38 declare
39   root_id int;
40   doc tsvector;
41   rcount int;
42   cv tsvector;
43 begin
44     SELECT abs_parent_id INTO root_id FROM forum_node WHERE id = new.node_id;
45
46     IF root_id IS NULL THEN
47           root_id := new.node_id;
48     END IF;
49
50     SELECT count(*)::int INTO rcount FROM forum_node WHERE id = root_id;
51
52     IF rcount = 0 THEN
53         return new;
54     END IF;
55
56     SELECT
57       setweight(to_tsvector('english', coalesce(tagnames,'')), 'A') ||
58       setweight(to_tsvector('english', coalesce(title,'')), 'B') ||
59       setweight(to_tsvector('english', coalesce(body,'')), 'C') INTO doc
60       FROM forum_node WHERE id = root_id;
61
62     SELECT count(*)::int INTO rcount FROM forum_node WHERE abs_parent_id = root_id AND (NOT state_string LIKE '%%deleted%%');
63
64     IF rcount > 0 THEN
65        FOR cv in SELECT setweight(to_tsvector('english', coalesce(body,'')), 'C') FROM forum_node WHERE abs_parent_id = root_id  AND (NOT state_string LIKE '%%deleted%%') LOOP
66            doc :=(doc || cv);
67        END LOOP;
68      END IF;
69
70     SELECT count(*)::int INTO rcount FROM forum_rootnode_doc WHERE node_id = root_id;
71
72     IF rcount > 0 THEN
73        UPDATE forum_rootnode_doc SET document = doc WHERE node_id = root_id;
74     ELSE
75        INSERT INTO forum_rootnode_doc (node_id, document) VALUES (root_id, doc);
76     END IF;
77
78   RETURN new;
79 end
80 $$ LANGUAGE plpgsql;
81
82 CREATE OR REPLACE FUNCTION public.build_doc_table() RETURNS VOID as $$
83   CREATE TABLE forum_rootnode_doc
84   (
85      node_id integer,
86      "document" tsvector,
87       PRIMARY KEY (node_id),
88       FOREIGN KEY (node_id) REFERENCES forum_node (id)    ON UPDATE NO ACTION ON DELETE NO ACTION
89   ) WITH (OIDS=FALSE);
90
91   DROP TRIGGER IF EXISTS tsvectorupdate ON forum_noderevision;
92
93   CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
94     ON forum_noderevision FOR EACH ROW EXECUTE PROCEDURE set_doctable_tsv();
95
96   CREATE INDEX doctable_tsv ON forum_rootnode_doc USING gin(document);
97 $$ LANGUAGE 'sql';
98
99 CREATE OR REPLACE FUNCTION public.doc_table_exists() RETURNS int AS $$
100  SELECT COUNT(table_name)::int FROM information_schema.tables WHERE table_name = 'forum_rootnode_doc';
101 $$ LANGUAGE 'sql';
102
103 select case when public.doc_table_exists()=0 then public.build_doc_table()end;
104
105 drop function build_doc_table();
106 drop function doc_table_exists();
107
108 CREATE OR REPLACE FUNCTION rank_exact_matches(rank float) RETURNS float AS $$
109 begin
110         IF rank = 0 THEN
111                 return 1;
112         ELSE
113                 return rank;
114         END IF;
115
116 end
117 $$ LANGUAGE plpgsql;
118
119 CREATE OR REPLACE FUNCTION public.rebuild_index() RETURNS VOID as $$
120         DECLARE
121                 r integer;
122         BEGIN
123                 FOR r IN SELECT active_revision_id FROM forum_node WHERE node_type = 'question' LOOP
124                         UPDATE forum_noderevision SET id = id WHERE id = r;
125                 END LOOP;
126         END
127 $$ LANGUAGE 'plpgsql';
128
129 SELECT rebuild_index();