]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/008.schema.query.sql
Remove an INSERT into config.upgrade_log, inadvertently
[working/Evergreen.git] / Open-ILS / src / sql / Pg / 008.schema.query.sql
1 -- Script to create the query schema and the tables therein
2
3 BEGIN;
4
5 DROP SCHEMA IF EXISTS query CASCADE;
6 CREATE SCHEMA query;
7 COMMENT ON SCHEMA actor IS $$
8 /*
9  * Copyright (C) 2009  Equinox Software, Inc. / Georgia Public Library Service
10  * Scott McKellar <scott@esilibrary.com>
11  *
12  * Schema: query
13  *
14  * Contains tables designed to represent user-defined queries for
15  * reports and the like.
16  *
17  * ****
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  */
29 $$;
30
31 CREATE TABLE  query.stored_query (
32         id            SERIAL         PRIMARY KEY,
33         type          TEXT           NOT NULL CONSTRAINT query_type CHECK
34                                      ( type IN ( 'SELECT', 'UNION', 'INTERSECT', 'EXCEPT' ) ),
35         use_all       BOOLEAN        NOT NULL DEFAULT FALSE,
36         use_distinct  BOOLEAN        NOT NULL DEFAULT FALSE,
37         from_clause   INT            NOT NULL , --REFERENCES query.from_clause
38         where_clause  INT            , --REFERENCES query.expression
39                                      --DEFERRABLE INITIALLY DEFERRED,
40         having_clause INT            --REFERENCES query.expression
41                                      --DEFERRABLE INITIALLY DEFERRED
42 );
43
44 -- (Foreign keys to be defined later after other tables are created)
45
46 CREATE TABLE query.query_sequence (
47         id              SERIAL            PRIMARY KEY,
48         parent_query    INT               NOT NULL
49                                           REFERENCES query.stored_query
50                                                                           ON DELETE CASCADE
51                                                                           DEFERRABLE INITIALLY DEFERRED,
52         seq_no          INT               NOT NULL,
53         child_query     INT               NOT NULL
54                                           REFERENCES query.stored_query
55                                                                           ON DELETE CASCADE
56                                                                           DEFERRABLE INITIALLY DEFERRED,
57         CONSTRAINT query_query_seq UNIQUE( parent_query, seq_no )
58 );
59
60 CREATE TABLE query.datatype (
61         id              SERIAL            PRIMARY KEY,
62         datatype_name   TEXT              NOT NULL UNIQUE,
63         is_numeric      BOOL              NOT NULL DEFAULT FALSE,
64         is_composite    BOOL              NOT NULL DEFAULT FALSE,
65         CONSTRAINT qdt_comp_not_num CHECK
66         ( is_numeric IS FALSE OR is_composite IS FALSE )
67 );
68
69 CREATE TABLE query.subfield (
70         id              SERIAL            PRIMARY KEY,
71         composite_type  INT               NOT NULL
72                                           REFERENCES query.datatype(id)
73                                           ON DELETE CASCADE
74                                           DEFERRABLE INITIALLY DEFERRED,
75         seq_no          INT               NOT NULL
76                                           CONSTRAINT qsf_pos_seq_no
77                                           CHECK( seq_no > 0 ),
78         subfield_type   INT               NOT NULL
79                                           REFERENCES query.datatype(id)
80                                           DEFERRABLE INITIALLY DEFERRED,
81         CONSTRAINT qsf_datatype_seq_no UNIQUE (composite_type, seq_no)
82 );
83
84 CREATE TABLE query.function_sig (
85         id              SERIAL            PRIMARY KEY,
86         function_name   TEXT              NOT NULL,
87         return_type     INT               REFERENCES query.datatype(id)
88                                           DEFERRABLE INITIALLY DEFERRED,
89         is_aggregate    BOOL              NOT NULL DEFAULT FALSE,
90         CONSTRAINT qfd_rtn_or_aggr CHECK
91         ( return_type IS NULL OR is_aggregate = FALSE )
92 );
93
94 CREATE INDEX query_function_sig_name_idx 
95         ON query.function_sig (function_name);
96
97 CREATE TABLE query.function_param_def (
98         id              SERIAL            PRIMARY KEY,
99         function_id     INT               NOT NULL
100                                           REFERENCES query.function_sig( id )
101                                           ON DELETE CASCADE
102                                           DEFERRABLE INITIALLY DEFERRED,
103         seq_no          INT               NOT NULL
104                                           CONSTRAINT qfpd_pos_seq_no CHECK
105                                           ( seq_no > 0 ),
106         datatype        INT               NOT NULL
107                                           REFERENCES query.datatype( id )
108                                           DEFERRABLE INITIALLY DEFERRED,
109         CONSTRAINT qfpd_function_param_seq UNIQUE (function_id, seq_no)
110 );
111
112 CREATE TABLE query.expression (
113         id            SERIAL        PRIMARY KEY,
114         type          TEXT          NOT NULL CONSTRAINT predicate_type CHECK
115                                     ( type IN (
116                                         'xbet',    -- between
117                                                                         'xbool',   -- boolean
118                                         'xcase',   -- case
119                                                                         'xcast',   -- cast
120                                                                         'xcol',    -- column
121                                                                         'xex',     -- exists
122                                                                         'xfld',    -- field
123                                                                         'xfunc',   -- function
124                                                                         'xin',     -- in
125                                                                         'xnbet',   -- not between
126                                         'xnex',    -- not exists
127                                                                         'xnin',    -- not in
128                                         'xnull',   -- null
129                                                                         'xnum',    -- number
130                                                                         'xop',     -- operator
131                                                                         'xstr',    -- string
132                                                 'xsubq'    -- subquery
133                                                                 ) ),
134         parenthesize  BOOL          NOT NULL DEFAULT FALSE,
135         parent_expr   INT           REFERENCES query.expression
136                                     ON DELETE CASCADE
137                                     DEFERRABLE INITIALLY DEFERRED,
138         seq_no        INT           NOT NULL DEFAULT 1,
139         literal       TEXT,
140         table_alias   TEXT,
141         column_name   TEXT,
142         left_operand  INT           REFERENCES query.expression
143                                     DEFERRABLE INITIALLY DEFERRED,
144         operator      TEXT,
145         right_operand INT           REFERENCES query.expression
146                                     DEFERRABLE INITIALLY DEFERRED,
147         function_id   INT           REFERENCES query.function_sig
148                                     DEFERRABLE INITIALLY DEFERRED,
149         subquery      INT           REFERENCES query.stored_query
150                                     DEFERRABLE INITIALLY DEFERRED,
151         cast_type     INT           REFERENCES query.datatype
152                                     DEFERRABLE INITIALLY DEFERRED
153 );
154
155 CREATE UNIQUE INDEX query_expr_parent_seq
156         ON query.expression( parent_expr, seq_no )
157         WHERE parent_expr IS NOT NULL;
158
159 -- Due to some circular references, the following foreign key definitions
160 -- had to be deferred until query.expression existed:
161
162 ALTER TABLE query.stored_query
163         ADD FOREIGN KEY ( where_clause )
164         REFERENCES query.expression( id )
165         DEFERRABLE INITIALLY DEFERRED;
166
167 ALTER TABLE query.stored_query
168         ADD FOREIGN KEY ( having_clause )
169         REFERENCES query.expression( id )
170         DEFERRABLE INITIALLY DEFERRED;
171
172 CREATE TABLE query.case_branch (
173         id            SERIAL        PRIMARY KEY,
174         parent_expr   INT           NOT NULL REFERENCES query.expression
175                                     ON DELETE CASCADE
176                                     DEFERRABLE INITIALLY DEFERRED,
177         seq_no        INT           NOT NULL,
178         condition     INT           REFERENCES query.expression
179                                     DEFERRABLE INITIALLY DEFERRED,
180         result        INT           NOT NULL REFERENCES query.expression
181                                     DEFERRABLE INITIALLY DEFERRED,
182         CONSTRAINT case_branch_parent_seq UNIQUE (parent_expr, seq_no)
183 );
184
185 CREATE TABLE query.from_relation (
186         id               SERIAL        PRIMARY KEY,
187         type             TEXT          NOT NULL CONSTRAINT relation_type CHECK (
188                                            type IN ( 'RELATION', 'SUBQUERY', 'FUNCTION' ) ),
189         table_name       TEXT,
190         class_name       TEXT,
191         subquery         INT           REFERENCES query.stored_query,
192         function_call    INT           REFERENCES query.expression,
193         table_alias      TEXT          NOT NULL,
194         parent_relation  INT           REFERENCES query.from_relation
195                                        ON DELETE CASCADE
196                                        DEFERRABLE INITIALLY DEFERRED,
197         seq_no           INT           NOT NULL DEFAULT 1,
198         join_type        TEXT          CONSTRAINT good_join_type CHECK (
199                                            join_type IS NULL OR join_type IN
200                                            ( 'INNER', 'LEFT', 'RIGHT', 'FULL' )
201                                        ),
202         on_clause        INT           REFERENCES query.expression
203                                        DEFERRABLE INITIALLY DEFERRED,
204         CONSTRAINT join_or_core CHECK (
205             ( parent_relation IS NULL AND join_type IS NULL 
206               AND on_clause IS NULL and table_alias IS NULL )
207             OR
208             ( parent_relation IS NOT NULL AND join_type IS NOT NULL
209               AND on_clause IS NOT NULL )
210         )
211 );
212
213 CREATE UNIQUE INDEX from_parent_seq
214         ON query.from_relation( parent_relation, seq_no )
215         WHERE parent_relation IS NOT NULL;
216
217 -- The following foreign key had to be deferred until
218 -- query.from_relation existed
219
220 ALTER TABLE query.stored_query
221         ADD FOREIGN KEY (from_clause)
222         REFERENCES query.from_relation
223         DEFERRABLE INITIALLY DEFERRED;
224
225 CREATE TABLE query.record_column (
226         id            SERIAL            PRIMARY KEY,
227         from_relation INT               NOT NULL REFERENCES query.from_relation
228                                         ON DELETE CASCADE
229                                         DEFERRABLE INITIALLY DEFERRED,
230         seq_no        INT               NOT NULL,
231         column_name   TEXT              NOT NULL,
232     column_type   INT               NOT NULL REFERENCES query.datatype
233                                     ON DELETE CASCADE
234                                     DEFERRABLE INITIALLY DEFERRED,
235         CONSTRAINT column_sequence UNIQUE (from_relation, seq_no)
236 );
237
238 CREATE TABLE query.select_item (
239         id               SERIAL         PRIMARY KEY,
240         stored_query     INT            NOT NULL REFERENCES query.stored_query
241                                         ON DELETE CASCADE
242                                         DEFERRABLE INITIALLY DEFERRED,
243         seq_no           INT            NOT NULL,
244         expression       INT            NOT NULL REFERENCES query.expression
245                                         DEFERRABLE INITIALLY DEFERRED,
246         column_alias     TEXT,
247         grouped_by       BOOL           NOT NULL DEFAULT FALSE,
248         CONSTRAINT select_sequence UNIQUE( stored_query, seq_no )
249 );
250
251 CREATE TABLE query.order_by_item (
252         id               SERIAL         PRIMARY KEY,
253         stored_query     INT            NOT NULL REFERENCES query.stored_query
254                                         ON DELETE CASCADE
255                                         DEFERRABLE INITIALLY DEFERRED,
256         seq_no           INT            NOT NULL,
257         expression       INT            NOT NULL REFERENCES query.expression
258                                         ON DELETE CASCADE
259                                         DEFERRABLE INITIALLY DEFERRED,
260         CONSTRAINT order_by_sequence UNIQUE( stored_query, seq_no )
261 );
262
263 -- Create updatable views -------------------------------------------
264
265 -- Create updatable view for BETWEEN expressions
266
267 CREATE OR REPLACE VIEW query.expr_xbet AS
268     SELECT
269                 id,
270                 parenthesize,
271                 parent_expr,
272                 seq_no
273     FROM
274         query.expression
275     WHERE
276         type = 'xbet';
277
278 CREATE OR REPLACE RULE query_expr_xbet_insert_rule AS
279     ON INSERT TO query.expr_xbet
280     DO INSTEAD
281     INSERT INTO query.expression (
282                 id,
283                 type,
284                 parenthesize,
285                 parent_expr,
286                 seq_no
287     ) VALUES (
288         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
289         'xbet',
290         COALESCE(NEW.parenthesize, FALSE),
291         NEW.parent_expr,
292         COALESCE(NEW.seq_no, 1)
293     );
294
295 CREATE OR REPLACE RULE query_expr_xbet_update_rule AS
296     ON UPDATE TO query.expr_xbet
297     DO INSTEAD
298     UPDATE query.expression SET
299         id = NEW.id,
300         parenthesize = NEW.parenthesize,
301         parent_expr = NEW.parent_expr,
302         seq_no = NEW.seq_no
303     WHERE
304         id = OLD.id;
305
306 CREATE OR REPLACE RULE query_expr_xbet_delete_rule AS
307     ON DELETE TO query.expr_xbet
308     DO INSTEAD
309     DELETE FROM query.expression WHERE id = OLD.id;
310
311 -- Create updatable view for boolean expressions
312
313 CREATE OR REPLACE VIEW query.expr_xbool AS
314     SELECT
315                 id,
316                 parenthesize,
317                 parent_expr,
318                 seq_no,
319                 literal
320     FROM
321         query.expression
322     WHERE
323         type = 'xbool';
324
325 CREATE OR REPLACE RULE query_expr_xbool_insert_rule AS
326     ON INSERT TO query.expr_xbool
327     DO INSTEAD
328     INSERT INTO query.expression (
329                 id,
330                 type,
331                 parenthesize,
332                 parent_expr,
333                 seq_no,
334                 literal
335     ) VALUES (
336         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
337         'xbool',
338         COALESCE(NEW.parenthesize, FALSE),
339         NEW.parent_expr,
340         COALESCE(NEW.seq_no, 1),
341         NEW.literal
342     );
343
344 CREATE OR REPLACE RULE query_expr_xbool_update_rule AS
345     ON UPDATE TO query.expr_xbool
346     DO INSTEAD
347     UPDATE query.expression SET
348         id = NEW.id,
349         parenthesize = NEW.parenthesize,
350         parent_expr = NEW.parent_expr,
351         seq_no = NEW.seq_no,
352         literal = NEW.literal
353     WHERE
354         id = OLD.id;
355
356 CREATE OR REPLACE RULE query_expr_xbool_delete_rule AS
357     ON DELETE TO query.expr_xbool
358     DO INSTEAD
359     DELETE FROM query.expression WHERE id = OLD.id;
360
361 -- Create updatable view for CASE expressions
362
363 CREATE OR REPLACE VIEW query.expr_xcase AS
364     SELECT
365                 id,
366                 parenthesize,
367                 parent_expr,
368                 seq_no
369     FROM
370         query.expression
371     WHERE
372         type = 'xcase';
373
374 CREATE OR REPLACE RULE query_expr_xcase_insert_rule AS
375     ON INSERT TO query.expr_xcase
376     DO INSTEAD
377     INSERT INTO query.expression (
378                 id,
379                 type,
380                 parenthesize,
381                 parent_expr,
382                 seq_no
383     ) VALUES (
384         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
385         'xcase',
386         COALESCE(NEW.parenthesize, FALSE),
387         NEW.parent_expr,
388         COALESCE(NEW.seq_no, 1)
389     );
390
391 CREATE OR REPLACE RULE query_expr_xcase_update_rule AS
392     ON UPDATE TO query.expr_xcase
393     DO INSTEAD
394     UPDATE query.expression SET
395         id = NEW.id,
396         parenthesize = NEW.parenthesize,
397         parent_expr = NEW.parent_expr,
398         seq_no = NEW.seq_no
399     WHERE
400         id = OLD.id;
401
402 CREATE OR REPLACE RULE query_expr_xcase_delete_rule AS
403     ON DELETE TO query.expr_xcase
404     DO INSTEAD
405     DELETE FROM query.expression WHERE id = OLD.id;
406
407 -- Create updatable view for cast expressions
408
409 CREATE OR REPLACE VIEW query.expr_xcast AS
410     SELECT
411                 id,
412                 parenthesize,
413                 parent_expr,
414                 seq_no,
415                 left_operand,
416                 cast_type
417     FROM
418         query.expression
419     WHERE
420         type = 'xcast';
421
422 CREATE OR REPLACE RULE query_expr_xcast_insert_rule AS
423     ON INSERT TO query.expr_xcast
424     DO INSTEAD
425     INSERT INTO query.expression (
426                 id,
427                 type,
428                 parenthesize,
429                 parent_expr,
430                 seq_no,
431                 left_operand,
432                 cast_type
433     ) VALUES (
434         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
435         'xcast',
436         COALESCE(NEW.parenthesize, FALSE),
437         NEW.parent_expr,
438         COALESCE(NEW.seq_no, 1),
439                 NEW.left_operand,
440                 NEW.cast_type
441     );
442
443 CREATE OR REPLACE RULE query_expr_xcast_update_rule AS
444     ON UPDATE TO query.expr_xcast
445     DO INSTEAD
446     UPDATE query.expression SET
447         id = NEW.id,
448         parenthesize = NEW.parenthesize,
449         parent_expr = NEW.parent_expr,
450         seq_no = NEW.seq_no,
451                 left_operand = NEW.left_operand,
452                 cast_type = NEW.cast_type
453     WHERE
454         id = OLD.id;
455
456 CREATE OR REPLACE RULE query_expr_xcast_delete_rule AS
457     ON DELETE TO query.expr_xcast
458     DO INSTEAD
459     DELETE FROM query.expression WHERE id = OLD.id;
460
461 -- Create updatable view for column expressions
462
463 CREATE OR REPLACE VIEW query.expr_xcol AS
464     SELECT
465                 id,
466                 parenthesize,
467                 parent_expr,
468                 seq_no,
469                 table_alias,
470                 column_name
471     FROM
472         query.expression
473     WHERE
474         type = 'xcol';
475
476 CREATE OR REPLACE RULE query_expr_xcol_insert_rule AS
477     ON INSERT TO query.expr_xcol
478     DO INSTEAD
479     INSERT INTO query.expression (
480                 id,
481                 type,
482                 parenthesize,
483                 parent_expr,
484                 seq_no,
485                 table_alias,
486                 column_name
487     ) VALUES (
488         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
489         'xcol',
490         COALESCE(NEW.parenthesize, FALSE),
491         NEW.parent_expr,
492         COALESCE(NEW.seq_no, 1),
493                 NEW.table_alias,
494                 NEW.column_name
495     );
496
497 CREATE OR REPLACE RULE query_expr_xcol_update_rule AS
498     ON UPDATE TO query.expr_xcol
499     DO INSTEAD
500     UPDATE query.expression SET
501         id = NEW.id,
502         parenthesize = NEW.parenthesize,
503         parent_expr = NEW.parent_expr,
504         seq_no = NEW.seq_no,
505                 table_alias = NEW.table_alias,
506                 column_name = NEW.column_name
507     WHERE
508         id = OLD.id;
509
510 CREATE OR REPLACE RULE query_expr_xcol_delete_rule AS
511     ON DELETE TO query.expr_xcol
512     DO INSTEAD
513     DELETE FROM query.expression WHERE id = OLD.id;
514
515 -- Create updatable view for EXISTS expressions
516
517 CREATE OR REPLACE VIEW query.expr_xex AS
518     SELECT
519                 id,
520                 parenthesize,
521                 parent_expr,
522                 seq_no,
523                 subquery
524     FROM
525         query.expression
526     WHERE
527         type = 'xex';
528
529 CREATE OR REPLACE RULE query_expr_xex_insert_rule AS
530     ON INSERT TO query.expr_xex
531     DO INSTEAD
532     INSERT INTO query.expression (
533                 id,
534                 type,
535                 parenthesize,
536                 parent_expr,
537                 seq_no,
538                 subquery
539     ) VALUES (
540         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
541         'xex',
542         COALESCE(NEW.parenthesize, FALSE),
543         NEW.parent_expr,
544         COALESCE(NEW.seq_no, 1),
545                 NEW.subquery
546     );
547
548 CREATE OR REPLACE RULE query_expr_xex_update_rule AS
549     ON UPDATE TO query.expr_xex
550     DO INSTEAD
551     UPDATE query.expression SET
552         id = NEW.id,
553         parenthesize = NEW.parenthesize,
554         parent_expr = NEW.parent_expr,
555         seq_no = NEW.seq_no,
556                 subquery = NEW.subquery
557     WHERE
558         id = OLD.id;
559
560 CREATE OR REPLACE RULE query_expr_xex_delete_rule AS
561     ON DELETE TO query.expr_xex
562     DO INSTEAD
563     DELETE FROM query.expression WHERE id = OLD.id;
564
565 -- Create updatable view for field expressions
566
567 CREATE OR REPLACE VIEW query.expr_xfld AS
568     SELECT
569                 id,
570                 parenthesize,
571                 parent_expr,
572                 seq_no,
573                 column_name,
574                 left_operand
575     FROM
576         query.expression
577     WHERE
578         type = 'xfld';
579
580 CREATE OR REPLACE RULE query_expr_xfld_insert_rule AS
581     ON INSERT TO query.expr_xfld
582     DO INSTEAD
583     INSERT INTO query.expression (
584                 id,
585                 type,
586                 parenthesize,
587                 parent_expr,
588                 seq_no,
589                 column_name,
590                 left_operand
591     ) VALUES (
592         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
593         'xfld',
594         COALESCE(NEW.parenthesize, FALSE),
595         NEW.parent_expr,
596         COALESCE(NEW.seq_no, 1),
597                 NEW.column_name,
598                 NEW.left_operand
599     );
600
601 CREATE OR REPLACE RULE query_expr_xfld_update_rule AS
602     ON UPDATE TO query.expr_xfld
603     DO INSTEAD
604     UPDATE query.expression SET
605         id = NEW.id,
606         parenthesize = NEW.parenthesize,
607         parent_expr = NEW.parent_expr,
608         seq_no = NEW.seq_no,
609                 column_name = NEW.column_name,
610                 left_operand = NEW.left_operand
611     WHERE
612         id = OLD.id;
613
614 CREATE OR REPLACE RULE query_expr_xfld_delete_rule AS
615     ON DELETE TO query.expr_xfld
616     DO INSTEAD
617     DELETE FROM query.expression WHERE id = OLD.id;
618
619 -- Create updatable view for function call expressions
620
621 CREATE OR REPLACE VIEW query.expr_xfunc AS
622     SELECT
623                 id,
624                 parenthesize,
625                 parent_expr,
626                 seq_no,
627                 function_id
628     FROM
629         query.expression
630     WHERE
631         type = 'xfunc';
632
633 CREATE OR REPLACE RULE query_expr_xfunc_insert_rule AS
634     ON INSERT TO query.expr_xfunc
635     DO INSTEAD
636     INSERT INTO query.expression (
637                 id,
638                 type,
639                 parenthesize,
640                 parent_expr,
641                 seq_no,
642                 function_id
643     ) VALUES (
644         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
645         'xfunc',
646         COALESCE(NEW.parenthesize, FALSE),
647         NEW.parent_expr,
648         COALESCE(NEW.seq_no, 1),
649                 NEW.function_id
650     );
651
652 CREATE OR REPLACE RULE query_expr_xfunc_update_rule AS
653     ON UPDATE TO query.expr_xfunc
654     DO INSTEAD
655     UPDATE query.expression SET
656         id = NEW.id,
657         parenthesize = NEW.parenthesize,
658         parent_expr = NEW.parent_expr,
659         seq_no = NEW.seq_no,
660                 function_id = NEW.function_id
661     WHERE
662         id = OLD.id;
663
664 CREATE OR REPLACE RULE query_expr_xfunc_delete_rule AS
665     ON DELETE TO query.expr_xfunc
666     DO INSTEAD
667     DELETE FROM query.expression WHERE id = OLD.id;
668
669 -- Create updatable view for IN expressions
670
671 CREATE OR REPLACE VIEW query.expr_xin AS
672     SELECT
673                 id,
674                 parenthesize,
675                 parent_expr,
676                 seq_no,
677                 subquery
678     FROM
679         query.expression
680     WHERE
681         type = 'xin';
682
683 CREATE OR REPLACE RULE query_expr_xin_insert_rule AS
684     ON INSERT TO query.expr_xin
685     DO INSTEAD
686     INSERT INTO query.expression (
687                 id,
688                 type,
689                 parenthesize,
690                 parent_expr,
691                 seq_no,
692                 subquery
693     ) VALUES (
694         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
695         'xin',
696         COALESCE(NEW.parenthesize, FALSE),
697         NEW.parent_expr,
698         COALESCE(NEW.seq_no, 1),
699                 NEW.subquery
700     );
701
702 CREATE OR REPLACE RULE query_expr_xin_update_rule AS
703     ON UPDATE TO query.expr_xin
704     DO INSTEAD
705     UPDATE query.expression SET
706         id = NEW.id,
707         parenthesize = NEW.parenthesize,
708         parent_expr = NEW.parent_expr,
709         seq_no = NEW.seq_no,
710                 subquery = NEW.subquery
711     WHERE
712         id = OLD.id;
713
714 CREATE OR REPLACE RULE query_expr_xin_delete_rule AS
715     ON DELETE TO query.expr_xin
716     DO INSTEAD
717     DELETE FROM query.expression WHERE id = OLD.id;
718
719 -- Create updatable view for NOT BETWEEN expressions
720
721 CREATE OR REPLACE VIEW query.expr_xnbet AS
722     SELECT
723                 id,
724                 parenthesize,
725                 parent_expr,
726                 seq_no
727     FROM
728         query.expression
729     WHERE
730         type = 'xnbet';
731
732 CREATE OR REPLACE RULE query_expr_xnbet_insert_rule AS
733     ON INSERT TO query.expr_xnbet
734     DO INSTEAD
735     INSERT INTO query.expression (
736                 id,
737                 type,
738                 parenthesize,
739                 parent_expr,
740                 seq_no
741     ) VALUES (
742         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
743         'xnbet',
744         COALESCE(NEW.parenthesize, FALSE),
745         NEW.parent_expr,
746         COALESCE(NEW.seq_no, 1)
747     );
748
749 CREATE OR REPLACE RULE query_expr_xnbet_update_rule AS
750     ON UPDATE TO query.expr_xnbet
751     DO INSTEAD
752     UPDATE query.expression SET
753         id = NEW.id,
754         parenthesize = NEW.parenthesize,
755         parent_expr = NEW.parent_expr,
756         seq_no = NEW.seq_no
757     WHERE
758         id = OLD.id;
759
760 CREATE OR REPLACE RULE query_expr_xnbet_delete_rule AS
761     ON DELETE TO query.expr_xnbet
762     DO INSTEAD
763     DELETE FROM query.expression WHERE id = OLD.id;
764
765 -- Create updatable view for NOT EXISTS expressions
766
767 CREATE OR REPLACE VIEW query.expr_xnex AS
768     SELECT
769                 id,
770                 parenthesize,
771                 parent_expr,
772                 seq_no,
773                 subquery
774     FROM
775         query.expression
776     WHERE
777         type = 'xnex';
778
779 CREATE OR REPLACE RULE query_expr_xnex_insert_rule AS
780     ON INSERT TO query.expr_xnex
781     DO INSTEAD
782     INSERT INTO query.expression (
783                 id,
784                 type,
785                 parenthesize,
786                 parent_expr,
787                 seq_no,
788                 subquery
789     ) VALUES (
790         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
791         'xnex',
792         COALESCE(NEW.parenthesize, FALSE),
793         NEW.parent_expr,
794         COALESCE(NEW.seq_no, 1),
795                 NEW.subquery
796     );
797
798 CREATE OR REPLACE RULE query_expr_xnex_update_rule AS
799     ON UPDATE TO query.expr_xnex
800     DO INSTEAD
801     UPDATE query.expression SET
802         id = NEW.id,
803         parenthesize = NEW.parenthesize,
804         parent_expr = NEW.parent_expr,
805         seq_no = NEW.seq_no,
806                 subquery = NEW.subquery
807     WHERE
808         id = OLD.id;
809
810 CREATE OR REPLACE RULE query_expr_xnex_delete_rule AS
811     ON DELETE TO query.expr_xnex
812     DO INSTEAD
813     DELETE FROM query.expression WHERE id = OLD.id;
814
815 -- Create updatable view for NOT IN expressions
816
817 CREATE OR REPLACE VIEW query.expr_xnin AS
818     SELECT
819                 id,
820                 parenthesize,
821                 parent_expr,
822                 seq_no,
823                 subquery
824     FROM
825         query.expression
826     WHERE
827         type = 'xnin';
828
829 CREATE OR REPLACE RULE query_expr_xnin_insert_rule AS
830     ON INSERT TO query.expr_xnin
831     DO INSTEAD
832     INSERT INTO query.expression (
833                 id,
834                 type,
835                 parenthesize,
836                 parent_expr,
837                 seq_no,
838                 subquery
839     ) VALUES (
840         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
841         'xnin',
842         COALESCE(NEW.parenthesize, FALSE),
843         NEW.parent_expr,
844         COALESCE(NEW.seq_no, 1),
845                 NEW.subquery
846     );
847
848 CREATE OR REPLACE RULE query_expr_xnin_update_rule AS
849     ON UPDATE TO query.expr_xnin
850     DO INSTEAD
851     UPDATE query.expression SET
852         id = NEW.id,
853         parenthesize = NEW.parenthesize,
854         parent_expr = NEW.parent_expr,
855         seq_no = NEW.seq_no,
856                 subquery = NEW.subquery
857     WHERE
858         id = OLD.id;
859
860 CREATE OR REPLACE RULE query_expr_xnin_delete_rule AS
861     ON DELETE TO query.expr_xnin
862     DO INSTEAD
863     DELETE FROM query.expression WHERE id = OLD.id;
864
865 -- Create updatable view for NULL expressions
866
867 CREATE OR REPLACE VIEW query.expr_xnull AS
868     SELECT
869                 id,
870                 parenthesize,
871                 parent_expr,
872                 seq_no
873     FROM
874         query.expression
875     WHERE
876         type = 'xnull';
877
878 CREATE OR REPLACE RULE query_expr_xnull_insert_rule AS
879     ON INSERT TO query.expr_xnull
880     DO INSTEAD
881     INSERT INTO query.expression (
882                 id,
883                 type,
884                 parenthesize,
885                 parent_expr,
886                 seq_no
887     ) VALUES (
888         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
889         'xnull',
890         COALESCE(NEW.parenthesize, FALSE),
891         NEW.parent_expr,
892         COALESCE(NEW.seq_no, 1)
893     );
894
895 CREATE OR REPLACE RULE query_expr_xnull_update_rule AS
896     ON UPDATE TO query.expr_xnull
897     DO INSTEAD
898     UPDATE query.expression SET
899         id = NEW.id,
900         parenthesize = NEW.parenthesize,
901         parent_expr = NEW.parent_expr,
902         seq_no = NEW.seq_no
903     WHERE
904         id = OLD.id;
905
906 CREATE OR REPLACE RULE query_expr_xnull_delete_rule AS
907     ON DELETE TO query.expr_xnull
908     DO INSTEAD
909     DELETE FROM query.expression WHERE id = OLD.id;
910
911 -- Create updatable view for numeric literal expressions
912
913 CREATE OR REPLACE VIEW query.expr_xnum AS
914     SELECT
915                 id,
916                 parenthesize,
917                 parent_expr,
918                 seq_no,
919                 literal
920     FROM
921         query.expression
922     WHERE
923         type = 'xnum';
924
925 CREATE OR REPLACE RULE query_expr_xnum_insert_rule AS
926     ON INSERT TO query.expr_xnum
927     DO INSTEAD
928     INSERT INTO query.expression (
929                 id,
930                 type,
931                 parenthesize,
932                 parent_expr,
933                 seq_no,
934                 literal
935     ) VALUES (
936         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
937         'xnum',
938         COALESCE(NEW.parenthesize, FALSE),
939         NEW.parent_expr,
940         COALESCE(NEW.seq_no, 1),
941         NEW.literal
942     );
943
944 CREATE OR REPLACE RULE query_expr_xnum_update_rule AS
945     ON UPDATE TO query.expr_xnum
946     DO INSTEAD
947     UPDATE query.expression SET
948         id = NEW.id,
949         parenthesize = NEW.parenthesize,
950         parent_expr = NEW.parent_expr,
951         seq_no = NEW.seq_no,
952         literal = NEW.literal
953     WHERE
954         id = OLD.id;
955
956 CREATE OR REPLACE RULE query_expr_xnum_delete_rule AS
957     ON DELETE TO query.expr_xnum
958     DO INSTEAD
959     DELETE FROM query.expression WHERE id = OLD.id;
960
961 -- Create updatable view for operator expressions
962
963 CREATE OR REPLACE VIEW query.expr_xop AS
964     SELECT
965                 id,
966                 parenthesize,
967                 parent_expr,
968                 seq_no,
969                 left_operand,
970                 operator,
971                 right_operand
972     FROM
973         query.expression
974     WHERE
975         type = 'xop';
976
977 CREATE OR REPLACE RULE query_expr_xop_insert_rule AS
978     ON INSERT TO query.expr_xop
979     DO INSTEAD
980     INSERT INTO query.expression (
981                 id,
982                 type,
983                 parenthesize,
984                 parent_expr,
985                 seq_no,
986                 left_operand,
987                 operator,
988                 right_operand
989     ) VALUES (
990         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
991         'xop',
992         COALESCE(NEW.parenthesize, FALSE),
993         NEW.parent_expr,
994         COALESCE(NEW.seq_no, 1),
995                 NEW.left_operand,
996                 NEW.operator,
997                 NEW.right_operand
998     );
999
1000 CREATE OR REPLACE RULE query_expr_xop_update_rule AS
1001     ON UPDATE TO query.expr_xop
1002     DO INSTEAD
1003     UPDATE query.expression SET
1004         id = NEW.id,
1005         parenthesize = NEW.parenthesize,
1006         parent_expr = NEW.parent_expr,
1007         seq_no = NEW.seq_no,
1008                 left_operand = NEW.left_operand,
1009                 operator = NEW.operator,
1010                 right_operand = NEW.right_operand
1011     WHERE
1012         id = OLD.id;
1013
1014 CREATE OR REPLACE RULE query_expr_xop_delete_rule AS
1015     ON DELETE TO query.expr_xop
1016     DO INSTEAD
1017     DELETE FROM query.expression WHERE id = OLD.id;
1018
1019 -- Create updatable view for string literal expressions
1020
1021 CREATE OR REPLACE VIEW query.expr_string AS
1022     SELECT
1023         id,
1024         parenthesize,
1025         parent_expr,
1026         seq_no,
1027         literal
1028     FROM
1029         query.expression
1030     WHERE
1031         type = 'xstr';
1032
1033 CREATE OR REPLACE RULE query_expr_string_insert_rule AS
1034     ON INSERT TO query.expr_string
1035     DO INSTEAD
1036     INSERT INTO query.expression (
1037         id,
1038         type,
1039         parenthesize,
1040         parent_expr,
1041         seq_no,
1042         literal
1043     ) VALUES (
1044         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
1045         'xstr',
1046         COALESCE(NEW.parenthesize, FALSE),
1047         NEW.parent_expr,
1048         COALESCE(NEW.seq_no, 1),
1049         NEW.literal
1050     );
1051
1052 CREATE OR REPLACE RULE query_expr_string_update_rule AS
1053     ON UPDATE TO query.expr_string
1054     DO INSTEAD
1055     UPDATE query.expression SET
1056         id = NEW.id,
1057         parenthesize = NEW.parenthesize,
1058         parent_expr = NEW.parent_expr,
1059         seq_no = NEW.seq_no,
1060         literal = NEW.literal
1061     WHERE
1062         id = OLD.id;
1063
1064 CREATE OR REPLACE RULE query_expr_string_delete_rule AS
1065     ON DELETE TO query.expr_string
1066     DO INSTEAD
1067     DELETE FROM query.expression WHERE id = OLD.id;
1068
1069 -- Create updatable view for subquery expressions
1070
1071 CREATE OR REPLACE VIEW query.expr_xsubq AS
1072     SELECT
1073                 id,
1074                 parenthesize,
1075                 parent_expr,
1076                 seq_no,
1077                 subquery
1078     FROM
1079         query.expression
1080     WHERE
1081         type = 'xsubq';
1082
1083 CREATE OR REPLACE RULE query_expr_xsubq_insert_rule AS
1084     ON INSERT TO query.expr_xsubq
1085     DO INSTEAD
1086     INSERT INTO query.expression (
1087                 id,
1088                 type,
1089                 parenthesize,
1090                 parent_expr,
1091                 seq_no,
1092                 subquery
1093     ) VALUES (
1094         COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
1095         'xsubq',
1096         COALESCE(NEW.parenthesize, FALSE),
1097         NEW.parent_expr,
1098         COALESCE(NEW.seq_no, 1),
1099                 NEW.subquery
1100     );
1101
1102 CREATE OR REPLACE RULE query_expr_xsubq_update_rule AS
1103     ON UPDATE TO query.expr_xsubq
1104     DO INSTEAD
1105     UPDATE query.expression SET
1106         id = NEW.id,
1107         parenthesize = NEW.parenthesize,
1108         parent_expr = NEW.parent_expr,
1109         seq_no = NEW.seq_no,
1110                 subquery = NEW.subquery
1111     WHERE
1112         id = OLD.id;
1113
1114 CREATE OR REPLACE RULE query_expr_xsubq_delete_rule AS
1115     ON DELETE TO query.expr_xsubq
1116     DO INSTEAD
1117     DELETE FROM query.expression WHERE id = OLD.id;
1118
1119 COMMIT;