PostgreSQL7.0手册-程序员手册 -42. Postgres 规则系统
用.目前不可能做两个视图的联合查询 -- 每个都有一个聚集字段,并且与资格列里的两个聚集的结果进行比较.但我们可能把这些聚集表达式放到函数里,通过合适的参数在视图定义中使用它们.
联合(union)的视图当前不被支持.尽管我们很容易把一个简单的SELECT 重写成联合(union).但是如果该视图是一个正在做更新的联合的一部分时就会有麻烦.
视图里的 ORDER BY 子句不被支持.
视图里的 DISTINCT 不被支持.
为什么优化器不能处理那些分析器因 SQL 语法限制生成的"不应该生成"分析树?我们也没有充分的理由.作者希望这些问题在将来会消失.
如此实现的副作用
使用上面描述的规则系统来实现视图有着有趣的副作用.下面的(命令)看起来不会工作:
al_bundy=> INSERT INTO shoe (shoename, sh_avail, slcolor)
al_bundy-> VALUES ('sh5', 0, 'black');
INSERT 20128 1
al_bundy=> SELECT shoename, sh_avail, slcolor FROM shoe_data;
shoename |sh_avail|slcolor
----------+--------+----------
sh1 | 2|black
sh3 | 4|brown
sh2 | 0|black
sh4 | 3|brown
(4 rows)
有趣的事情是 INSERT 的返回码给我们一个对象标识(OID)并且告诉我们插入了一行.但该行没有在 shoe_data 里出现.往数据库目录里看时我们可以发现,用于视图关系 shoe 的数据库文件看来现在有了数据块.实际情况正是如此.
我们还可以使用一条 DELETE 命令,如果该命令没有(资格)条件,它会告诉我们有一行被删除了并且下一次清理时将把文件复位为零尺寸.
这种现象的原因是 INSERT 生成的分析树没有在任何变量里引用 shoe (鞋)关系.目标列表只包含常量值.所以不会附加任何规则,查询不加修改地进入执行插入该行. DELETE 时完全一样.
要改变这些问题,我们可以定义一些规则用以改变 非-SELECT 查询的特性.这是下一章的内容.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
INSERT,UPDATE 和 DELETE 的规则
与 View Rules 的区别
定义在 ON INSERT,UPDATE 和 DELETE 的规则与前一章描述的视图规则完全不同.首先,他们的 CREATE RULE 命令允许更多:
它们可以没有动作(action).
它们可以有多个动作(action).
关键字 INSTEAD 是可选的.
伪关系 NEW 和 OLD 变得可用.
它们可以有规则资格条件.
第二,它们不是实地修改分析树.它们是创建零个或多个新分析树并且可以把最先的那个仍掉.
这些规则是如何工作的
把下面语法
CREATE RULE rule_name AS ON event
TO object [WHERE rule_qualification]
DO [INSTEAD] [action | (actions) | NOTHING];
牢牢记住.下面,"update rules" 意思是定义在 ON INSERT,UPDATE 或 DELETE 上的规则.
当分析树的结果关系和命令类型与 CREATE RULE 命令里给出的对象和事件一样的话,规则系统就把更新规则(update rules)应用上去.对于更新规则(update rules),规则系统创建一个分析树列表.一开始分析树是空的.这里可以有零个(NOTHING 关键字),一个或多个动作.为简单起见,我们看一眼一个只有一个动作(action)的规则.这个规则可以有一个资格(条件)或没有并且它可以是 INSTEAD 或反之.
何为规则资格?它是一个限制条件,告诉规则动作(action)什么时候要做,什么时候不用做.这个资格(条件)可以只引用 NEW 和/或 OLD 伪关系--它们是作为对象给出的基本关系(但是有着特殊含义).
所以,对这个一个动作(action)的规则生成分析树,有下面四种情况.
没有资格(条件)和没有 INSTEAD:
从规则动作(action)来的分析树,已经在最初的分析树上追加了资格(条件).
没有资格(条件)但有 INSTEAD:
从规则动作(action)来的分析树,已经在最初的分析树上追加了资格(条件).
有资格(条件)但没有 INSTEAD:
从规则动作(action)来的分析树,追加了规则资格(条件)和在最初的分析树的资格(条件).
有资格(条件)也有 INSTEAD:
从规则动作(action)来的分析树,追加了规则资格(条件)和在最初的分析树的资格(条件).
最初的分析树,增加了相反的规则资格(条件).
最后,如果规则不是 INSTEAD,最初的未修改的分析树被加入到列表.因为只有资格(条件)规则已经在初始的分析树里面,所以我们最终得到最多有两个分析树的单动作(action)规则。
从规则动作生成的分析树被再次送到重写系统并且可能应用更多的规则,结果是更多的或更少的分析树.所以规则动作里的分析树必须是另一个命令类型或另一个结果关系.否则这样的递归过程就会没完没了.现在有一个编译级的递归限制是10个语句.如果10次递归之后还有需要应用的更新规则(update rules),规则系统就认为是一个多规则的循环而退出事务.
在 pg_rewrite 系统表里的分析树的动作(action)只是模板.因为他们可以引用 NEW 和 OLD 的可排列元素,在使用它们之前必须做一些调整.对于任何对 NEW 的引用,都要先在初始查询的目标列中搜索对应的条目.如果找到,把该条目表达式放到引用里.否则 NEW 和 OLD 的含义一样.任何用于 OLD 的引用都用结果关系的可排列元素的引用替换.
循序渐进的第一个规则
我们希望跟踪 shoelace_data 关系中的 sl_avail 字段.所以我们设置一个日志表和一条规则,这条规则每次在用 UPDATE 更新 shoelace_data 表时都要往数据库里写一条记录.
CREATE TABLE shoelace_log (
sl_name char(10), -- shoelace changed
sl_avail integer, -
联合(union)的视图当前不被支持.尽管我们很容易把一个简单的SELECT 重写成联合(union).但是如果该视图是一个正在做更新的联合的一部分时就会有麻烦.
视图里的 ORDER BY 子句不被支持.
视图里的 DISTINCT 不被支持.
为什么优化器不能处理那些分析器因 SQL 语法限制生成的"不应该生成"分析树?我们也没有充分的理由.作者希望这些问题在将来会消失.
如此实现的副作用
使用上面描述的规则系统来实现视图有着有趣的副作用.下面的(命令)看起来不会工作:
al_bundy=> INSERT INTO shoe (shoename, sh_avail, slcolor)
al_bundy-> VALUES ('sh5', 0, 'black');
INSERT 20128 1
al_bundy=> SELECT shoename, sh_avail, slcolor FROM shoe_data;
shoename |sh_avail|slcolor
----------+--------+----------
sh1 | 2|black
sh3 | 4|brown
sh2 | 0|black
sh4 | 3|brown
(4 rows)
有趣的事情是 INSERT 的返回码给我们一个对象标识(OID)并且告诉我们插入了一行.但该行没有在 shoe_data 里出现.往数据库目录里看时我们可以发现,用于视图关系 shoe 的数据库文件看来现在有了数据块.实际情况正是如此.
我们还可以使用一条 DELETE 命令,如果该命令没有(资格)条件,它会告诉我们有一行被删除了并且下一次清理时将把文件复位为零尺寸.
这种现象的原因是 INSERT 生成的分析树没有在任何变量里引用 shoe (鞋)关系.目标列表只包含常量值.所以不会附加任何规则,查询不加修改地进入执行插入该行. DELETE 时完全一样.
要改变这些问题,我们可以定义一些规则用以改变 非-SELECT 查询的特性.这是下一章的内容.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
INSERT,UPDATE 和 DELETE 的规则
与 View Rules 的区别
定义在 ON INSERT,UPDATE 和 DELETE 的规则与前一章描述的视图规则完全不同.首先,他们的 CREATE RULE 命令允许更多:
它们可以没有动作(action).
它们可以有多个动作(action).
关键字 INSTEAD 是可选的.
伪关系 NEW 和 OLD 变得可用.
它们可以有规则资格条件.
第二,它们不是实地修改分析树.它们是创建零个或多个新分析树并且可以把最先的那个仍掉.
这些规则是如何工作的
把下面语法
CREATE RULE rule_name AS ON event
TO object [WHERE rule_qualification]
DO [INSTEAD] [action | (actions) | NOTHING];
牢牢记住.下面,"update rules" 意思是定义在 ON INSERT,UPDATE 或 DELETE 上的规则.
当分析树的结果关系和命令类型与 CREATE RULE 命令里给出的对象和事件一样的话,规则系统就把更新规则(update rules)应用上去.对于更新规则(update rules),规则系统创建一个分析树列表.一开始分析树是空的.这里可以有零个(NOTHING 关键字),一个或多个动作.为简单起见,我们看一眼一个只有一个动作(action)的规则.这个规则可以有一个资格(条件)或没有并且它可以是 INSTEAD 或反之.
何为规则资格?它是一个限制条件,告诉规则动作(action)什么时候要做,什么时候不用做.这个资格(条件)可以只引用 NEW 和/或 OLD 伪关系--它们是作为对象给出的基本关系(但是有着特殊含义).
所以,对这个一个动作(action)的规则生成分析树,有下面四种情况.
没有资格(条件)和没有 INSTEAD:
从规则动作(action)来的分析树,已经在最初的分析树上追加了资格(条件).
没有资格(条件)但有 INSTEAD:
从规则动作(action)来的分析树,已经在最初的分析树上追加了资格(条件).
有资格(条件)但没有 INSTEAD:
从规则动作(action)来的分析树,追加了规则资格(条件)和在最初的分析树的资格(条件).
有资格(条件)也有 INSTEAD:
从规则动作(action)来的分析树,追加了规则资格(条件)和在最初的分析树的资格(条件).
最初的分析树,增加了相反的规则资格(条件).
最后,如果规则不是 INSTEAD,最初的未修改的分析树被加入到列表.因为只有资格(条件)规则已经在初始的分析树里面,所以我们最终得到最多有两个分析树的单动作(action)规则。
从规则动作生成的分析树被再次送到重写系统并且可能应用更多的规则,结果是更多的或更少的分析树.所以规则动作里的分析树必须是另一个命令类型或另一个结果关系.否则这样的递归过程就会没完没了.现在有一个编译级的递归限制是10个语句.如果10次递归之后还有需要应用的更新规则(update rules),规则系统就认为是一个多规则的循环而退出事务.
在 pg_rewrite 系统表里的分析树的动作(action)只是模板.因为他们可以引用 NEW 和 OLD 的可排列元素,在使用它们之前必须做一些调整.对于任何对 NEW 的引用,都要先在初始查询的目标列中搜索对应的条目.如果找到,把该条目表达式放到引用里.否则 NEW 和 OLD 的含义一样.任何用于 OLD 的引用都用结果关系的可排列元素的引用替换.
循序渐进的第一个规则
我们希望跟踪 shoelace_data 关系中的 sl_avail 字段.所以我们设置一个日志表和一条规则,这条规则每次在用 UPDATE 更新 shoelace_data 表时都要往数据库里写一条记录.
CREATE TABLE shoelace_log (
sl_name char(10), -- shoelace changed
sl_avail integer, -
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] 下一页

