Add a bunch of updatable view to the query schema, for
authorscottmk <scottmk@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Fri, 4 Dec 2009 16:02:03 +0000 (16:02 +0000)
committerscottmk <scottmk@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Fri, 4 Dec 2009 16:02:03 +0000 (16:02 +0000)
representing various subsets of expressions.

M    Open-ILS/src/sql/Pg/002.schema.config.sql
M    Open-ILS/src/sql/Pg/008.schema.query.sql
A    Open-ILS/src/sql/Pg/upgrade/0107.schema.query-updatable_views.sql
M    Open-ILS/examples/fm_IDL.xml

git-svn-id: svn://svn.open-ils.org/ILS/trunk@15078 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/examples/fm_IDL.xml
Open-ILS/src/sql/Pg/002.schema.config.sql
Open-ILS/src/sql/Pg/008.schema.query.sql
Open-ILS/src/sql/Pg/upgrade/0107.schema.query-updatable_views.sql [new file with mode: 0644]

index 64e8eb5..3a121f3 100644 (file)
@@ -5596,6 +5596,242 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                </permacrud>
        </class>
 
+       <class id="xbet" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xbet" oils_persist:tablename="query.expr_xbet" reporter:label="Between Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xbool" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xbool" oils_persist:tablename="query.expr_xbool" reporter:label="Boolean Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Literal" name="literal" reporter:datatype="text"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xcase" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xcase" oils_persist:tablename="query.expr_xcase" reporter:label="Case Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xcast" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xcast" oils_persist:tablename="query.expr_xcast" reporter:label="Cast Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Left Operand" name="left_operand" reporter:datatype="link"/>
+                       <field reporter:label="Cast Type" name="cast_type" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="left_operand" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="cast_type" reltype="might_have" key="id" map="" class="qdt"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xcol" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xcol" oils_persist:tablename="query.expr_xcol" reporter:label="Column Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Table Alias" name="table_alias" reporter:datatype="text"/>
+                       <field reporter:label="Column Name" name="column_name" reporter:datatype="text"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xex" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xex" oils_persist:tablename="query.expr_xex" reporter:label="Exists Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Subquery" name="subquery" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="subquery" reltype="might_have" key="id" map="" class="qsq"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xfld" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xfld" oils_persist:tablename="query.expr_xfld" reporter:label="Field Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Column Name" name="column_name" reporter:datatype="text"/>
+                       <field reporter:label="Left Operand" name="left_operand" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="left_operand" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xfunc" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xfunc" oils_persist:tablename="query.expr_xfunc" reporter:label="Function Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Function ID" name="function_id" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="function_id" reltype="might_have" key="id" map="" class="qfs"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xin" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xin" oils_persist:tablename="query.expr_xin" reporter:label="In Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Subquery" name="subquery" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="subquery" reltype="might_have" key="id" map="" class="qsq"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xnbet" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xnbet" oils_persist:tablename="query.expr_xnbet" reporter:label="Not Between Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xnex" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xnex" oils_persist:tablename="query.expr_xnex" reporter:label="Not Exists Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Subquery" name="subquery" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="subquery" reltype="might_have" key="id" map="" class="qsq"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xnin" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xnin" oils_persist:tablename="query.expr_xnin" reporter:label="Not In Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Subquery" name="subquery" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="subquery" reltype="might_have" key="id" map="" class="qsq"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xnull" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xnull" oils_persist:tablename="query.expr_xnull" reporter:label="Null Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xnum" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xnum" oils_persist:tablename="query.expr_xnum" reporter:label="Number Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Literal" name="literal" reporter:datatype="text"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
+       <class id="xop" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xop" oils_persist:tablename="query.expr_xop" reporter:label="Operator Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Left Operand" name="left_operand" reporter:datatype="link"/>
+                       <field reporter:label="Operator" name="operator" reporter:datatype="text"/>
+                       <field reporter:label="Right Operand" name="right_operand" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="left_operand" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="right_operand" reltype="might_have" key="id" map="" class="qxp"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
        <class id="xstr" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_string" oils_persist:tablename="query.expr_string" reporter:label="String Expression">
                <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
                        <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
@@ -5611,6 +5847,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                </permacrud>
        </class>
 
+       <class id="xsubq" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="query::expr_xsubq" oils_persist:tablename="query.expr_xsubq" reporter:label="Subquery Expression">
+               <fields oils_persist:primary="id" oils_persist:sequence="expression_id_seq">
+                       <field reporter:label="Expression ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Is Parenthesized" name="parenthesize" reporter:datatype="bool"/>
+                       <field reporter:label="Parent Expression" name="parent_expr" reporter:datatype="link"/>
+                       <field reporter:label="Sequence Number" name="seq_no" reporter:datatype="int"/>
+                       <field reporter:label="Subquery" name="subquery" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="parent_expr" reltype="might_have" key="id" map="" class="qxp"/>
+                       <link field="subquery" reltype="might_have" key="id" map="" class="qsq"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+               </permacrud>
+       </class>
+
        <!-- ********************************************************************************************************************* -->
        <!-- What follows is a set of example extensions that are useful for PINES.  Comment out or remove if you don't want them. -->
        <!-- ********************************************************************************************************************* -->
index 61ff1a5..c4e614f 100644 (file)
@@ -51,7 +51,7 @@ CREATE TABLE config.upgrade_log (
     install_date    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
 );
 
-INSERT INTO config.upgrade_log (version) VALUES ('0106'); -- senator
+INSERT INTO config.upgrade_log (version) VALUES ('0107'); -- Scott McKellar
 
 CREATE TABLE config.bib_source (
        id              SERIAL  PRIMARY KEY,
index 0389479..3eaf97b 100644 (file)
@@ -260,7 +260,765 @@ CREATE TABLE query.order_by_item (
        CONSTRAINT order_by_sequence UNIQUE( stored_query, seq_no )
 );
 
--- Create updatable views
+-- Create updatable views -------------------------------------------
+
+-- Create updatable view for BETWEEN expressions
+
+INSERT INTO config.upgrade_log (version) VALUES ('0107'); -- Scott McKellar
+
+CREATE OR REPLACE VIEW query.expr_xbet AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xbet';
+
+CREATE OR REPLACE RULE query_expr_xbet_insert_rule AS
+    ON INSERT TO query.expr_xbet
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xbet',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xbet_update_rule AS
+    ON UPDATE TO query.expr_xbet
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xbet_delete_rule AS
+    ON DELETE TO query.expr_xbet
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for boolean expressions
+
+CREATE OR REPLACE VIEW query.expr_xbool AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    FROM
+        query.expression
+    WHERE
+        type = 'xbool';
+
+CREATE OR REPLACE RULE query_expr_xbool_insert_rule AS
+    ON INSERT TO query.expr_xbool
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xbool',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+        NEW.literal
+    );
+
+CREATE OR REPLACE RULE query_expr_xbool_update_rule AS
+    ON UPDATE TO query.expr_xbool
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+        literal = NEW.literal
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xbool_delete_rule AS
+    ON DELETE TO query.expr_xbool
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for CASE expressions
+
+CREATE OR REPLACE VIEW query.expr_xcase AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xcase';
+
+CREATE OR REPLACE RULE query_expr_xcase_insert_rule AS
+    ON INSERT TO query.expr_xcase
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xcase',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xcase_update_rule AS
+    ON UPDATE TO query.expr_xcase
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xcase_delete_rule AS
+    ON DELETE TO query.expr_xcase
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for cast expressions
+
+CREATE OR REPLACE VIEW query.expr_xcast AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               cast_type
+    FROM
+        query.expression
+    WHERE
+        type = 'xcast';
+
+CREATE OR REPLACE RULE query_expr_xcast_insert_rule AS
+    ON INSERT TO query.expr_xcast
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               cast_type
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xcast',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.left_operand,
+               NEW.cast_type
+    );
+
+CREATE OR REPLACE RULE query_expr_xcast_update_rule AS
+    ON UPDATE TO query.expr_xcast
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               left_operand = NEW.left_operand,
+               cast_type = NEW.cast_type
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xcast_delete_rule AS
+    ON DELETE TO query.expr_xcast
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for column expressions
+
+CREATE OR REPLACE VIEW query.expr_xcol AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               table_alias,
+               column_name
+    FROM
+        query.expression
+    WHERE
+        type = 'xcol';
+
+CREATE OR REPLACE RULE query_expr_xcol_insert_rule AS
+    ON INSERT TO query.expr_xcol
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               table_alias,
+               column_name
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xcol',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.table_alias,
+               NEW.column_name
+    );
+
+CREATE OR REPLACE RULE query_expr_xcol_update_rule AS
+    ON UPDATE TO query.expr_xcol
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               table_alias = NEW.table_alias,
+               column_name = NEW.column_name
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xcol_delete_rule AS
+    ON DELETE TO query.expr_xcol
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for EXISTS expressions
+
+CREATE OR REPLACE VIEW query.expr_xex AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xex';
+
+CREATE OR REPLACE RULE query_expr_xex_insert_rule AS
+    ON INSERT TO query.expr_xex
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xex',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xex_update_rule AS
+    ON UPDATE TO query.expr_xex
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xex_delete_rule AS
+    ON DELETE TO query.expr_xex
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for field expressions
+
+CREATE OR REPLACE VIEW query.expr_xfld AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               column_name,
+               left_operand
+    FROM
+        query.expression
+    WHERE
+        type = 'xfld';
+
+CREATE OR REPLACE RULE query_expr_xfld_insert_rule AS
+    ON INSERT TO query.expr_xfld
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               column_name,
+               left_operand
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xfld',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.column_name,
+               NEW.left_operand
+    );
+
+CREATE OR REPLACE RULE query_expr_xfld_update_rule AS
+    ON UPDATE TO query.expr_xfld
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               column_name = NEW.column_name,
+               left_operand = NEW.left_operand
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xfld_delete_rule AS
+    ON DELETE TO query.expr_xfld
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for function call expressions
+
+CREATE OR REPLACE VIEW query.expr_xfunc AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               function_id
+    FROM
+        query.expression
+    WHERE
+        type = 'xfunc';
+
+CREATE OR REPLACE RULE query_expr_xfunc_insert_rule AS
+    ON INSERT TO query.expr_xfunc
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               function_id
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xfunc',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.function_id
+    );
+
+CREATE OR REPLACE RULE query_expr_xfunc_update_rule AS
+    ON UPDATE TO query.expr_xfunc
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               function_id = NEW.function_id
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xfunc_delete_rule AS
+    ON DELETE TO query.expr_xfunc
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for IN expressions
+
+CREATE OR REPLACE VIEW query.expr_xin AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xin';
+
+CREATE OR REPLACE RULE query_expr_xin_insert_rule AS
+    ON INSERT TO query.expr_xin
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xin',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xin_update_rule AS
+    ON UPDATE TO query.expr_xin
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xin_delete_rule AS
+    ON DELETE TO query.expr_xin
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NOT BETWEEN expressions
+
+CREATE OR REPLACE VIEW query.expr_xnbet AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xnbet';
+
+CREATE OR REPLACE RULE query_expr_xnbet_insert_rule AS
+    ON INSERT TO query.expr_xnbet
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnbet',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xnbet_update_rule AS
+    ON UPDATE TO query.expr_xnbet
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnbet_delete_rule AS
+    ON DELETE TO query.expr_xnbet
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NOT EXISTS expressions
+
+CREATE OR REPLACE VIEW query.expr_xnex AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xnex';
+
+CREATE OR REPLACE RULE query_expr_xnex_insert_rule AS
+    ON INSERT TO query.expr_xnex
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnex',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xnex_update_rule AS
+    ON UPDATE TO query.expr_xnex
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnex_delete_rule AS
+    ON DELETE TO query.expr_xnex
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NOT IN expressions
+
+CREATE OR REPLACE VIEW query.expr_xnin AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xnin';
+
+CREATE OR REPLACE RULE query_expr_xnin_insert_rule AS
+    ON INSERT TO query.expr_xnin
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnin',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xnin_update_rule AS
+    ON UPDATE TO query.expr_xnin
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnin_delete_rule AS
+    ON DELETE TO query.expr_xnin
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NULL expressions
+
+CREATE OR REPLACE VIEW query.expr_xnull AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xnull';
+
+CREATE OR REPLACE RULE query_expr_xnull_insert_rule AS
+    ON INSERT TO query.expr_xnull
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnull',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xnull_update_rule AS
+    ON UPDATE TO query.expr_xnull
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnull_delete_rule AS
+    ON DELETE TO query.expr_xnull
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for numeric literal expressions
+
+CREATE OR REPLACE VIEW query.expr_xnum AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    FROM
+        query.expression
+    WHERE
+        type = 'xnum';
+
+CREATE OR REPLACE RULE query_expr_xnum_insert_rule AS
+    ON INSERT TO query.expr_xnum
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnum',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+        NEW.literal
+    );
+
+CREATE OR REPLACE RULE query_expr_xnum_update_rule AS
+    ON UPDATE TO query.expr_xnum
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+        literal = NEW.literal
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnum_delete_rule AS
+    ON DELETE TO query.expr_xnum
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for operator expressions
+
+CREATE OR REPLACE VIEW query.expr_xop AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               operator,
+               right_operand
+    FROM
+        query.expression
+    WHERE
+        type = 'xop';
+
+CREATE OR REPLACE RULE query_expr_xop_insert_rule AS
+    ON INSERT TO query.expr_xop
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               operator,
+               right_operand
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xop',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.left_operand,
+               NEW.operator,
+               NEW.right_operand
+    );
+
+CREATE OR REPLACE RULE query_expr_xop_update_rule AS
+    ON UPDATE TO query.expr_xop
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               left_operand = NEW.left_operand,
+               operator = NEW.operator,
+               right_operand = NEW.right_operand
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xop_delete_rule AS
+    ON DELETE TO query.expr_xop
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for string literal expressions
 
 CREATE OR REPLACE VIEW query.expr_string AS
     SELECT
@@ -310,4 +1068,54 @@ CREATE OR REPLACE RULE query_expr_string_delete_rule AS
     DO INSTEAD
     DELETE FROM query.expression WHERE id = OLD.id;
 
+-- Create updatable view for subquery expressions
+
+CREATE OR REPLACE VIEW query.expr_xsubq AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xsubq';
+
+CREATE OR REPLACE RULE query_expr_xsubq_insert_rule AS
+    ON INSERT TO query.expr_xsubq
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xsubq',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xsubq_update_rule AS
+    ON UPDATE TO query.expr_xsubq
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xsubq_delete_rule AS
+    ON DELETE TO query.expr_xsubq
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
 COMMIT;
diff --git a/Open-ILS/src/sql/Pg/upgrade/0107.schema.query-updatable_views.sql b/Open-ILS/src/sql/Pg/upgrade/0107.schema.query-updatable_views.sql
new file mode 100644 (file)
index 0000000..b87a535
--- /dev/null
@@ -0,0 +1,809 @@
+BEGIN;
+
+-- Create updatable view for BETWEEN expressions
+
+INSERT INTO config.upgrade_log (version) VALUES ('0107'); -- Scott McKellar
+
+CREATE OR REPLACE VIEW query.expr_xbet AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xbet';
+
+CREATE OR REPLACE RULE query_expr_xbet_insert_rule AS
+    ON INSERT TO query.expr_xbet
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xbet',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xbet_update_rule AS
+    ON UPDATE TO query.expr_xbet
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xbet_delete_rule AS
+    ON DELETE TO query.expr_xbet
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for boolean expressions
+
+CREATE OR REPLACE VIEW query.expr_xbool AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    FROM
+        query.expression
+    WHERE
+        type = 'xbool';
+
+CREATE OR REPLACE RULE query_expr_xbool_insert_rule AS
+    ON INSERT TO query.expr_xbool
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xbool',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+        NEW.literal
+    );
+
+CREATE OR REPLACE RULE query_expr_xbool_update_rule AS
+    ON UPDATE TO query.expr_xbool
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+        literal = NEW.literal
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xbool_delete_rule AS
+    ON DELETE TO query.expr_xbool
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for CASE expressions
+
+CREATE OR REPLACE VIEW query.expr_xcase AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xcase';
+
+CREATE OR REPLACE RULE query_expr_xcase_insert_rule AS
+    ON INSERT TO query.expr_xcase
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xcase',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xcase_update_rule AS
+    ON UPDATE TO query.expr_xcase
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xcase_delete_rule AS
+    ON DELETE TO query.expr_xcase
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for cast expressions
+
+CREATE OR REPLACE VIEW query.expr_xcast AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               cast_type
+    FROM
+        query.expression
+    WHERE
+        type = 'xcast';
+
+CREATE OR REPLACE RULE query_expr_xcast_insert_rule AS
+    ON INSERT TO query.expr_xcast
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               cast_type
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xcast',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.left_operand,
+               NEW.cast_type
+    );
+
+CREATE OR REPLACE RULE query_expr_xcast_update_rule AS
+    ON UPDATE TO query.expr_xcast
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               left_operand = NEW.left_operand,
+               cast_type = NEW.cast_type
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xcast_delete_rule AS
+    ON DELETE TO query.expr_xcast
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for column expressions
+
+CREATE OR REPLACE VIEW query.expr_xcol AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               table_alias,
+               column_name
+    FROM
+        query.expression
+    WHERE
+        type = 'xcol';
+
+CREATE OR REPLACE RULE query_expr_xcol_insert_rule AS
+    ON INSERT TO query.expr_xcol
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               table_alias,
+               column_name
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xcol',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.table_alias,
+               NEW.column_name
+    );
+
+CREATE OR REPLACE RULE query_expr_xcol_update_rule AS
+    ON UPDATE TO query.expr_xcol
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               table_alias = NEW.table_alias,
+               column_name = NEW.column_name
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xcol_delete_rule AS
+    ON DELETE TO query.expr_xcol
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for EXISTS expressions
+
+CREATE OR REPLACE VIEW query.expr_xex AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xex';
+
+CREATE OR REPLACE RULE query_expr_xex_insert_rule AS
+    ON INSERT TO query.expr_xex
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xex',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xex_update_rule AS
+    ON UPDATE TO query.expr_xex
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xex_delete_rule AS
+    ON DELETE TO query.expr_xex
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for field expressions
+
+CREATE OR REPLACE VIEW query.expr_xfld AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               column_name,
+               left_operand
+    FROM
+        query.expression
+    WHERE
+        type = 'xfld';
+
+CREATE OR REPLACE RULE query_expr_xfld_insert_rule AS
+    ON INSERT TO query.expr_xfld
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               column_name,
+               left_operand
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xfld',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.column_name,
+               NEW.left_operand
+    );
+
+CREATE OR REPLACE RULE query_expr_xfld_update_rule AS
+    ON UPDATE TO query.expr_xfld
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               column_name = NEW.column_name,
+               left_operand = NEW.left_operand
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xfld_delete_rule AS
+    ON DELETE TO query.expr_xfld
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for function call expressions
+
+CREATE OR REPLACE VIEW query.expr_xfunc AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               function_id
+    FROM
+        query.expression
+    WHERE
+        type = 'xfunc';
+
+CREATE OR REPLACE RULE query_expr_xfunc_insert_rule AS
+    ON INSERT TO query.expr_xfunc
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               function_id
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xfunc',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.function_id
+    );
+
+CREATE OR REPLACE RULE query_expr_xfunc_update_rule AS
+    ON UPDATE TO query.expr_xfunc
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               function_id = NEW.function_id
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xfunc_delete_rule AS
+    ON DELETE TO query.expr_xfunc
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for IN expressions
+
+CREATE OR REPLACE VIEW query.expr_xin AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xin';
+
+CREATE OR REPLACE RULE query_expr_xin_insert_rule AS
+    ON INSERT TO query.expr_xin
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xin',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xin_update_rule AS
+    ON UPDATE TO query.expr_xin
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xin_delete_rule AS
+    ON DELETE TO query.expr_xin
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NOT BETWEEN expressions
+
+CREATE OR REPLACE VIEW query.expr_xnbet AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xnbet';
+
+CREATE OR REPLACE RULE query_expr_xnbet_insert_rule AS
+    ON INSERT TO query.expr_xnbet
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnbet',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xnbet_update_rule AS
+    ON UPDATE TO query.expr_xnbet
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnbet_delete_rule AS
+    ON DELETE TO query.expr_xnbet
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NOT EXISTS expressions
+
+CREATE OR REPLACE VIEW query.expr_xnex AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xnex';
+
+CREATE OR REPLACE RULE query_expr_xnex_insert_rule AS
+    ON INSERT TO query.expr_xnex
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnex',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xnex_update_rule AS
+    ON UPDATE TO query.expr_xnex
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnex_delete_rule AS
+    ON DELETE TO query.expr_xnex
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NOT IN expressions
+
+CREATE OR REPLACE VIEW query.expr_xnin AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xnin';
+
+CREATE OR REPLACE RULE query_expr_xnin_insert_rule AS
+    ON INSERT TO query.expr_xnin
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnin',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xnin_update_rule AS
+    ON UPDATE TO query.expr_xnin
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnin_delete_rule AS
+    ON DELETE TO query.expr_xnin
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for NULL expressions
+
+CREATE OR REPLACE VIEW query.expr_xnull AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no
+    FROM
+        query.expression
+    WHERE
+        type = 'xnull';
+
+CREATE OR REPLACE RULE query_expr_xnull_insert_rule AS
+    ON INSERT TO query.expr_xnull
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnull',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1)
+    );
+
+CREATE OR REPLACE RULE query_expr_xnull_update_rule AS
+    ON UPDATE TO query.expr_xnull
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnull_delete_rule AS
+    ON DELETE TO query.expr_xnull
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for numeric literal expressions
+
+CREATE OR REPLACE VIEW query.expr_xnum AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    FROM
+        query.expression
+    WHERE
+        type = 'xnum';
+
+CREATE OR REPLACE RULE query_expr_xnum_insert_rule AS
+    ON INSERT TO query.expr_xnum
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               literal
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xnum',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+        NEW.literal
+    );
+
+CREATE OR REPLACE RULE query_expr_xnum_update_rule AS
+    ON UPDATE TO query.expr_xnum
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+        literal = NEW.literal
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xnum_delete_rule AS
+    ON DELETE TO query.expr_xnum
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for operator expressions
+
+CREATE OR REPLACE VIEW query.expr_xop AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               operator,
+               right_operand
+    FROM
+        query.expression
+    WHERE
+        type = 'xop';
+
+CREATE OR REPLACE RULE query_expr_xop_insert_rule AS
+    ON INSERT TO query.expr_xop
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               left_operand,
+               operator,
+               right_operand
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xop',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.left_operand,
+               NEW.operator,
+               NEW.right_operand
+    );
+
+CREATE OR REPLACE RULE query_expr_xop_update_rule AS
+    ON UPDATE TO query.expr_xop
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               left_operand = NEW.left_operand,
+               operator = NEW.operator,
+               right_operand = NEW.right_operand
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xop_delete_rule AS
+    ON DELETE TO query.expr_xop
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+-- Create updatable view for subquery expressions
+
+CREATE OR REPLACE VIEW query.expr_xsubq AS
+    SELECT
+               id,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    FROM
+        query.expression
+    WHERE
+        type = 'xsubq';
+
+CREATE OR REPLACE RULE query_expr_xsubq_insert_rule AS
+    ON INSERT TO query.expr_xsubq
+    DO INSTEAD
+    INSERT INTO query.expression (
+               id,
+               type,
+               parenthesize,
+               parent_expr,
+               seq_no,
+               subquery
+    ) VALUES (
+        COALESCE(NEW.id, NEXTVAL('query.expression_id_seq'::REGCLASS)),
+        'xsubq',
+        COALESCE(NEW.parenthesize, FALSE),
+        NEW.parent_expr,
+        COALESCE(NEW.seq_no, 1),
+               NEW.subquery
+    );
+
+CREATE OR REPLACE RULE query_expr_xsubq_update_rule AS
+    ON UPDATE TO query.expr_xsubq
+    DO INSTEAD
+    UPDATE query.expression SET
+        id = NEW.id,
+        parenthesize = NEW.parenthesize,
+        parent_expr = NEW.parent_expr,
+        seq_no = NEW.seq_no,
+               subquery = NEW.subquery
+    WHERE
+        id = OLD.id;
+
+CREATE OR REPLACE RULE query_expr_xsubq_delete_rule AS
+    ON DELETE TO query.expr_xsubq
+    DO INSTEAD
+    DELETE FROM query.expression WHERE id = OLD.id;
+
+COMMIT;