Commit 338c54cb authored by Marc G. Fournier's avatar Marc G. Fournier

From: Jan Wieck <jwieck@debis.com>

Hi,

    as  proposed here comes the first patch for the query rewrite
    system.

  <for details, see archive dated Mon, 17 Aug 1998>
parent fde65267
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.79 1998/07/20 20:48:51 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.80 1998/08/18 00:48:54 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -742,11 +742,33 @@ static Query * ...@@ -742,11 +742,33 @@ static Query *
transformRuleStmt(ParseState *pstate, RuleStmt *stmt) transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
{ {
Query *qry; Query *qry;
Query *action;
List *actions; List *actions;
qry = makeNode(Query); qry = makeNode(Query);
qry->commandType = CMD_UTILITY; qry->commandType = CMD_UTILITY;
/*
* 'instead nothing' rules with a qualification need a
* query a rangetable so the rewrite handler can add the
* negated rule qualification to the original query. We
* create a query with the new command type CMD_NOTHING
* here that is treated special by the rewrite system.
*/
if (stmt->actions == NIL) {
Query *nothing_qry = makeNode(Query);
nothing_qry->commandType = CMD_NOTHING;
addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
FALSE, FALSE);
addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
FALSE, FALSE);
nothing_qry->rtable = pstate->p_rtable;
stmt->actions = lappend(NIL, nothing_qry);
}
actions = stmt->actions; actions = stmt->actions;
/* /*
...@@ -768,6 +790,8 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt) ...@@ -768,6 +790,8 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
pstate->p_is_rule = true; /* for expand all */ pstate->p_is_rule = true; /* for expand all */
pstate->p_hasAggs = false; pstate->p_hasAggs = false;
action = (Query *)lfirst(actions);
if (action->commandType != CMD_NOTHING)
lfirst(actions) = transformStmt(pstate, lfirst(actions)); lfirst(actions) = transformStmt(pstate, lfirst(actions));
actions = lnext(actions); actions = lnext(actions);
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.22 1998/08/17 16:08:34 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.23 1998/08/18 00:48:55 scrappy Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -1955,6 +1955,7 @@ RuleStmt: CREATE RULE name AS ...@@ -1955,6 +1955,7 @@ RuleStmt: CREATE RULE name AS
OptStmtList: NOTHING { $$ = NIL; } OptStmtList: NOTHING { $$ = NIL; }
| OptimizableStmt { $$ = lcons($1, NIL); } | OptimizableStmt { $$ = lcons($1, NIL); }
| '[' OptStmtBlock ']' { $$ = $2; } | '[' OptStmtBlock ']' { $$ = $2; }
| '(' OptStmtBlock ')' { $$ = $2; }
; ;
OptStmtBlock: OptStmtMulti OptStmtBlock: OptStmtMulti
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.12 1998/07/08 14:04:11 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.13 1998/08/18 00:48:57 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -191,9 +191,14 @@ addRangeTableEntry(ParseState *pstate, ...@@ -191,9 +191,14 @@ addRangeTableEntry(ParseState *pstate,
if (pstate != NULL) if (pstate != NULL)
{ {
if (refnameRangeTablePosn(pstate, refname, &sublevels_up) != 0 && if (refnameRangeTablePosn(pstate, refname, &sublevels_up) != 0 &&
(!inFromCl || sublevels_up == 0)) (!inFromCl || sublevels_up == 0)) {
if (!strcmp(refname, "*CURRENT*") || !strcmp(refname, "*NEW*")) {
int rt_index = refnameRangeTablePosn(pstate, refname, &sublevels_up);
return (RangeTblEntry *)nth(rt_index - 1, pstate->p_rtable);
}
elog(ERROR, "Table name %s specified more than once", refname); elog(ERROR, "Table name %s specified more than once", refname);
} }
}
rte->relname = pstrdup(relname); rte->relname = pstrdup(relname);
rte->refname = pstrdup(refname); rte->refname = pstrdup(refname);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.16 1998/06/15 19:29:06 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.17 1998/08/18 00:48:58 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -155,12 +155,7 @@ ValidateRule(int event_type, ...@@ -155,12 +155,7 @@ ValidateRule(int event_type,
"rules not allowed for insert or delete events to an attribute"); "rules not allowed for insert or delete events to an attribute");
} }
if (event_qual && !*action && is_instead)
elog(ERROR,
"event_quals on 'instead nothing' rules not currently supported");
#if 0 #if 0
/* /*
* on retrieve to class.attribute do instead nothing is converted to * on retrieve to class.attribute do instead nothing is converted to
* 'on retrieve to class.attribute do instead retrieve (attribute = * 'on retrieve to class.attribute do instead retrieve (attribute =
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: nodes.h,v 1.26 1998/08/05 04:49:12 scrappy Exp $ * $Id: nodes.h,v 1.27 1998/08/18 00:49:01 scrappy Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -305,8 +305,12 @@ typedef enum CmdType ...@@ -305,8 +305,12 @@ typedef enum CmdType
CMD_INSERT, /* insert stmt (formerly append) */ CMD_INSERT, /* insert stmt (formerly append) */
CMD_DELETE, CMD_DELETE,
CMD_NOTIFY, CMD_NOTIFY,
CMD_UTILITY /* cmds like create, destroy, copy, CMD_UTILITY, /* cmds like create, destroy, copy,
* vacuum, etc. */ * vacuum, etc. */
CMD_NOTHING /* dummy command for
* instead nothing
* rules with qual
*/
} CmdType; } CmdType;
......
This diff is collapsed.
QUERY: create table rtest_t1 (a int4, b int4);
QUERY: create table rtest_t2 (a int4, b int4);
QUERY: create table rtest_t3 (a int4, b int4);
QUERY: create view rtest_v1 as select * from rtest_t1;
QUERY: create rule rtest_v1_ins as on insert to rtest_v1 do instead
insert into rtest_t1 values (new.a, new.b);
QUERY: create rule rtest_v1_upd as on update to rtest_v1 do instead
update rtest_t1 set a = new.a, b = new.b
where a = current.a;
QUERY: create rule rtest_v1_del as on delete to rtest_v1 do instead
delete from rtest_t1 where a = current.a;
QUERY: create table rtest_system (sysname text, sysdesc text);
QUERY: create table rtest_interface (sysname text, ifname text);
QUERY: create table rtest_person (pname text, pdesc text);
QUERY: create table rtest_admin (pname text, sysname text);
QUERY: create rule rtest_sys_upd1 as on update to rtest_system do
update rtest_interface set sysname = new.sysname
where sysname = current.sysname;
QUERY: create rule rtest_sys_upd2 as on update to rtest_system do
update rtest_admin set sysname = new.sysname
where sysname = current.sysname;
QUERY: create rule rtest_sys_del1 as on delete to rtest_system do
delete from rtest_interface where sysname = current.sysname;
QUERY: create rule rtest_sys_del2 as on delete to rtest_system do
delete from rtest_admin where sysname = current.sysname;
QUERY: create rule rtest_pers_upd as on update to rtest_person do
update rtest_admin set pname = new.pname where pname = current.pname;
QUERY: create rule rtest_pers_del as on delete to rtest_person do
delete from rtest_admin where pname = current.pname;
QUERY: create table rtest_emp (ename char(20), salary money);
QUERY: create table rtest_emplog (ename char(20), who name, action char(10), newsal money, oldsal money);
QUERY: create table rtest_empmass (ename char(20), salary money);
QUERY: create rule rtest_emp_ins as on insert to rtest_emp do
insert into rtest_emplog values (new.ename, getpgusername(),
'hired', new.salary, '0.00');
QUERY: create rule rtest_emp_upd as on update to rtest_emp where new.salary != current.salary do
insert into rtest_emplog values (new.ename, getpgusername(),
'honored', new.salary, current.salary);
QUERY: create rule rtest_emp_del as on delete to rtest_emp do
insert into rtest_emplog values (current.ename, getpgusername(),
'fired', '0.00', current.salary);
QUERY: create table rtest_t4 (a int4, b text);
QUERY: create table rtest_t5 (a int4, b text);
QUERY: create table rtest_t6 (a int4, b text);
QUERY: create table rtest_t7 (a int4, b text);
QUERY: create table rtest_t8 (a int4, b text);
QUERY: create table rtest_t9 (a int4, b text);
QUERY: create rule rtest_t4_ins1 as on insert to rtest_t4
where new.a >= 10 and new.a < 20 do instead
insert into rtest_t5 values (new.a, new.b);
QUERY: create rule rtest_t4_ins2 as on insert to rtest_t4
where new.a >= 20 and new.a < 30 do
insert into rtest_t6 values (new.a, new.b);
QUERY: create rule rtest_t5_ins as on insert to rtest_t5
where new.a > 15 do
insert into rtest_t7 values (new.a, new.b);
QUERY: create rule rtest_t6_ins as on insert to rtest_t6
where new.a > 25 do instead
insert into rtest_t8 values (new.a, new.b);
QUERY: create table rtest_order1 (a int4);
QUERY: create table rtest_order2 (a int4, b int4, c text);
QUERY: create sequence rtest_seq;
QUERY: create rule rtest_order_r3 as on insert to rtest_order1 do instead
insert into rtest_order2 values (new.a, nextval('rtest_seq'),
'rule 3 - this should run 3rd or 4th');
QUERY: create rule rtest_order_r4 as on insert to rtest_order1
where a < 100 do instead
insert into rtest_order2 values (new.a, nextval('rtest_seq'),
'rule 4 - this should run 2nd');
QUERY: create rule rtest_order_r2 as on insert to rtest_order1 do
insert into rtest_order2 values (new.a, nextval('rtest_seq'),
'rule 2 - this should run 1st');
QUERY: create rule rtest_order_r1 as on insert to rtest_order1 do instead
insert into rtest_order2 values (new.a, nextval('rtest_seq'),
'rule 1 - this should run 3rd or 4th');
QUERY: create table rtest_nothn1 (a int4, b text);
QUERY: create table rtest_nothn2 (a int4, b text);
QUERY: create table rtest_nothn3 (a int4, b text);
QUERY: create table rtest_nothn4 (a int4, b text);
QUERY: create rule rtest_nothn_r1 as on insert to rtest_nothn1
where new.a >= 10 and new.a < 20 do instead (select 1);
QUERY: create rule rtest_nothn_r2 as on insert to rtest_nothn1
where new.a >= 30 and new.a < 40 do instead nothing;
QUERY: create rule rtest_nothn_r3 as on insert to rtest_nothn2
where new.a >= 100 do instead
insert into rtest_nothn3 values (new.a, new.b);
QUERY: create rule rtest_nothn_r4 as on insert to rtest_nothn2
do instead nothing;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment