home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre2.z / postgre2 / doc / papers / rules_procedur < prev    next >
Encoding:
Text File  |  1992-08-27  |  53.6 KB  |  1,445 lines

  1. .EQ
  2. delim ##
  3. gfont R
  4. .EN
  5.  
  6. .nr tp 12
  7. .nr sp 12
  8. .nr pp 10
  9. .nr fp 8
  10. .sz \n(pp
  11. .vs 12        \" set 1.5 spacing between lines
  12. .nr $r \n(.vu/\n(.su
  13. .nr $R \n($r
  14. .fo ''%''
  15. .(l C
  16. .sz \n(sp
  17. .b
  18. ON RULES, PROCEDURES, CACHING and VIEWS
  19.  
  20. .b
  21. IN DATA BASE SYSTEMS
  22. .sz \n(pp
  23. .sp 3
  24. .i
  25. Michael Stonebraker, Anant Jhingran, Jeffrey Goh and Spyros Potamianos
  26. EECS Dept.
  27. University of California, Berkeley
  28. .sp
  29. .r
  30. .)l
  31. .sp 3
  32. .(f
  33. This research was sponsored
  34. by the Army Research Organization
  35. Grant DAAL03-87-0083 and by the Defense Advanced Research
  36. Projects Agency through NASA Grant NAG2-530.
  37. .)f
  38. .ls 1
  39. .uh Abstract
  40. .pp
  41. This paper demonstrates that a simple rule system can be constructed that
  42. supports a more powerful view system than
  43. available in current commercial systems.  Not only can views be specified
  44. by using rules but also special semantics
  45. for resolving ambiguous view updates are simply additional rules.
  46. Moreover, procedural
  47. data types as proposed in POSTGRES are also efficiently simulated by
  48. the same rules system.  Lastly, caching of the action part
  49. of certain rules is
  50. a possible performance enhancement and can be applied to materialize
  51. views as well as to cache procedural data items.   Hence, we conclude
  52. that a rule system is a fundamental concept in a next generation
  53. DBMS, and it subsumes both views and procedures as special
  54. cases.
  55.  
  56. .sh 1  "INTRODUCTION"
  57. .pp
  58. Most commercial relational systems support the concept of relational
  59. views [STON75].  Hence, a virtual relation can be defined to
  60. the data manager, e.g:
  61. .(l
  62. define view TOY_EMP as
  63. retrieve (EMP.name, EMP.age, EMP.salary)
  64. where EMP.dept = ``toy''
  65. .)l
  66. Then, all queries and many updates
  67. to TOY_EMP can be mapped to commands on the underlying base
  68. relation, EMP.  
  69. Unfortunately, there are abundant
  70. examples of views for which certain updates 
  71. are impossible to successfully
  72. map [CODD74].  Commercial systems simply issue error 
  73. messages for such commands,
  74. and this shortcoming limits the utility of views.
  75. Clearly, the ability to specify update semantics for ambiguous updates
  76. to views would be a desirable enhancement.
  77. .pp
  78. Recently, several authors have proposed materializing views for 
  79. augmented performance.  In this case, the DBMS would keep a 
  80. physical instantiation of a view such as TOY_EMP.  Hence, queries to
  81. TOY_EMP can usually be processed much faster than without a materialization.
  82. However, updates to TOY_EMP will require more expensive
  83. processing because
  84. each update must be both mapped to underlying base relations and 
  85. processed on the materialization.  See [BLAK86, ROUS87] for
  86. details on this approach.
  87. .pp
  88. There are several extensions to the view mechanism that might
  89. be desirable.  First, it would be nice if a view could be specified by
  90. multiple query language commands, e.g:
  91. .(l
  92. define view SHOE_EMP as
  93. retrieve (EMP.name, EMP.salary, EMP.age) where EMP.dept = ``shoe''
  94. retrieve (NEWEMP.name, NEWEMP.salary, NEWEMP.age) where NEWEMP.dept = ``shoe''
  95. .)l
  96. Here, SHOE_EMP is defined to be the union of two commands. 
  97. Although it is possible to express this view 
  98. in 
  99. SQL using the union operator, 
  100. updates to union views are disallowed
  101. in commercial SQL implementations.
  102. Also, it is easy to propose collections of commands
  103. whose target lists are not union compatible, and therefore
  104. that are not expressible as SQL views.
  105. Lastly, it would also be nice if 
  106. .b partial
  107. views were supported, i.e. a view that is defined by a collection
  108. of stored tuples as well as by one or more view definitions
  109. to materialize the remainder of the tuples.
  110. .pp
  111. Some researchers have proposed that procedural data types be supported in 
  112. a data base system [STON87].  In this case, a column of a relation
  113. would contain data items, each of which is an unrestricted collection
  114. of query language commands.  An example of this capability is storing 
  115. information about hobbies of employees, e.g:
  116. .(l
  117. EMP (name, hobbies)
  118. .)l
  119. In the hobbies field we record all information about 
  120. each hobby that
  121. an employee engages in.
  122. One way to model this situation is to construct
  123. one relation in 
  124. the data base for each possible hobby indicating
  125. the names of the employees who practice the hobby and relevant data about
  126. their passtime.  Example relations might include:
  127. .(l
  128. SOFTBALL (name, position, average)
  129. JOGGING (name, miles, best-time)
  130. .)l
  131. Then each value in the hobbies field is a procedure consisting of
  132. a collection of
  133. query language commands retrieving relevant hobby data.
  134. Consequently, the appropriate procedure for an
  135. employee Joe who practices both
  136. softball and racing
  137. might be called foobar and would be:
  138. .(l
  139. retrieve (SOFTBALL.all) where SOFTBALL.name = "Joe"
  140. retrieve (JOGGING.all) where JOGGING.name = "Joe"
  141. .)l
  142. Hence, the appropriate insert to EMP would be:
  143. .(l
  144. append to EMP (name = "Joe", hobbies = foobar) 
  145. .)l
  146. .pp
  147. A special case of a procedural field is
  148. the situation where each tuple contains a procedure of the form:
  149. .(l
  150. retrieve (relation.all)
  151. .)l
  152. In this case, the value of the field is the indicated relation
  153. and the procedure efficiently simulates a
  154. nested 
  155. relational data structure [DADA86].
  156. .pp
  157. In [STON86], it was also suggested that a DBMS optimize procedural
  158. fields by precomputing the value of the procedure, rather than waiting
  159. for the user to request evaluation.
  160. .pp
  161. Lastly, [ROWE87] proposed a special case of procedural
  162. fields, namely that a column of a relation 
  163. contain the
  164. same procedure in each tuple, differing only in the value of one
  165. or more parameters.  
  166. For example, consider the following DEPT relation:
  167. .(l
  168. DEPT (dname, floor, composition)
  169. .)l
  170. Here, dname and floor are conventional fields while composition
  171. is intended to be the collection of EMP records for 
  172. employees in the given department.
  173. In this case, composition can be declared to be the following
  174. procedure:
  175. .(l
  176. retrieve (EMP.all) where EMP.dept = $.dname
  177. .)l
  178. Hence, each row of DEPT has the same procedure, namely the above
  179. query, differing only in the value of the
  180. parameter, $.dname, which is available in the dname field in each tuple.  
  181. As can be noted, parameterized (or special) procedures are an efficient
  182. means to support the type "collection of tuples in another
  183. relation".
  184. .pp
  185. In this paper we indicate that all the following concepts:
  186. .(l
  187. views
  188. special semantics for updating views 
  189. materialized views
  190. partial views
  191. procedures
  192. special procedures
  193. caching of procedures
  194. .)l
  195. can be subsumed by one general purpose rules system.  Hence, we 
  196. recommend that
  197. implementors concentrate on a single powerful rules system
  198. and then simulate all of these concepts using the rules system.  This is
  199. exactly what we are doing in
  200. Version 2 of POSTGRES.
  201. .pp
  202. Consequently, in Section 2 we present the rules 
  203. system that we are building for Version 2.  Section 3 continues with the
  204. two alternate implementations that we are constructing for activating rules.
  205. Then, in Section 4 we consider 
  206. caching the action portion of certain rules.  Section 5 indicates
  207. how view processing can be effectively
  208. layered on this rules system.  Lastly, Section 6 concludes with
  209. the implementation of procedures and special procedures as 
  210. particular rules.
  211. .sh 1  "THE NEW POSTGRES RULES SYSTEM"
  212. .pp
  213. Although the first version of POSTGRES proposed using a paradigm for
  214. rules in which a command was logically 
  215. .b always
  216. in execution or
  217. .b never
  218. in execution, the second POSTGRES rules system (PRS2) takes a more traditional
  219. production system approach 
  220. to rules [ESWA76, STON82, DELC88, HANS89, MCCA89, WIDO89].  PRS2 has
  221. points in common with these other proposals; in fact the syntax is
  222. quite close to that of [HANS89, WIDO89].  However, the main 
  223. contribution of this paper is to show how views and procedures can
  224. be subsumed under a rule paradigm. 
  225. This section
  226. briefly discusses the syntax of rules in PRS2.
  227. .pp
  228. A rule has the form:
  229. .(l
  230. DEFINE RULE rule-name [AS EXCEPTION TO rule-name]
  231. ON event TO object [[FROM clause] WHERE clause]
  232. THEN DO [instead] action
  233. .)l
  234. Here, event is one of:
  235. .(l
  236. retrieve 
  237. replace 
  238. delete
  239. append
  240. new (i. e. replace or append)
  241. old (i.e. delete or replace)
  242. .)l
  243. Moreover, object is either:
  244. .(l
  245. a relation name
  246. or
  247. relation.column, ...., relation.column
  248. .)l
  249. The FROM clause and WHERE clause
  250. are normal POSTQUEL clauses 
  251. with no additions or
  252. changes.  Lastly, the action portion of the DO clause 
  253. is a collection of POSTQUEL commands
  254. with the following change:
  255. .in+6
  256. .ll-6
  257. NEW or CURRENT can appear instead of 
  258. a tuple variable whenever a tuple
  259. variable is permissible in POSTQUEL.
  260.  
  261. .in-6
  262. .ll+6
  263. .pp
  264. The semantics of a PRS2 rule is that at the time an individual tuple is
  265. accessed, updated, inserted or deleted, there is a CURRENT tuple (for
  266. retrieves, replaces and deletes) and a NEW tuple (for replaces and appends).
  267. If the event and the condition specified in the ON clause are true 
  268. for the CURRENT tuple,
  269. then the action part of the rule is executed.  First, however, values
  270. from fields in the CURRENT tuple and/or the NEW tuple are substituted 
  271. for:
  272. .(l
  273. CURRENT.column-name
  274. NEW.column-name
  275. .)l
  276. The action part of the rule executes with same command and
  277. transaction identifier
  278. as the user command that caused activation.  
  279. .pp
  280. For example, consider the following rule:
  281. .(l
  282. define rule example_1
  283. on replace to EMP.salary where EMP.name = ``Joe''
  284. then replace EMP (salary = NEW.salary) where EMP.name = ``Sam''
  285. .)l
  286. At the time Joe receives a salary adjustment, the event will become
  287. true and Joe's current tuple and proposed new tuple are available
  288. to the execution routines.  Hence, his new salary is substituted into the 
  289. action part of the rule which is subsequently executed.  This 
  290. propagates Joe's salary on to Sam.
  291. .pp
  292. There is no requirement that the event and action
  293. be the same kind of command.  Hence, 
  294. consider a second rule:
  295. .(l
  296. define rule example_2
  297. on retrieve to EMP.salary where EMP.name = ``Joe''
  298. then replace EMP (salary = CURRENT.salary) where EMP.name = ``Bill''
  299. .)l
  300. This rule ensures that Bill has a salary equal to Joe's whenever
  301. Joe's salary is accessed.
  302. .pp
  303. Each rule can have the optional tag "instead".  Without this tag the
  304. action will be performed in addition to the user command 
  305. when the event 
  306. in the condition part of the rule occurs. 
  307. Alternately, the action part will be done instead of the user command.
  308. .pp
  309. For example, if Joe is not allowed to see the salary of employees in the
  310. shoe department, then the
  311. following rule is the appropriate specification:
  312. .(l
  313. define rule example_3
  314. on retrieve to EMP.salary where EMP.dept = ``shoe'' and user() = ``Joe''
  315. then do instead retrieve (salary = null)
  316. .)l
  317. At the time the event is true, there will be a current tuple for
  318. some member of the shoe department.  The action part 
  319. of the rule specifies that this person's salary
  320. is not to be returned; instead a null value should be inserted before
  321. the tuple is returned to higher level software for
  322. further processing.
  323. Notice, that insertion of a real value in the action
  324. part of the rule would allows 
  325. POSTGRES to 
  326. .b lie
  327. to Joe about the salaries of members of the shoe
  328. department by returning an incorrect value. 
  329. .pp
  330. It is also possible to update the CURRENT tuple or the NEW tuple
  331. using a rule.  Hence, 
  332. a somewhat more obscure way to express the above rule is:
  333. .(l
  334. define rule example_4
  335. on retrieve to EMP.salary where EMP.dept = ``shoe'' and user() = ``Joe''
  336. then do replace CURRENT (salary = null)
  337. .)l
  338. This rule has the same condition as the previous one; however it
  339. specifies that the current tuple is to be modified by changing the salary
  340. field to null.  This will return a null value to the requesting user.
  341. .pp
  342. Each rule is given a rule-name, which is used to remove the rule by name when
  343. it is no longer needed. 
  344. Lastly, each rule can be optionally designated to be an 
  345. .b exception 
  346. to another rule.  
  347. Consider, for example,
  348. the following rule:
  349. .(l
  350. define rule example_5 as exception to example_4 
  351. on retrieve to EMP.salary where EMP.name = ``Sam'' and user() = ``Joe''
  352. then do replace CURRENT (salary = 1000)
  353. .)l
  354. Suppose Sam is a member of the shoe department.  
  355. In this case, example_4 would return null for his salary
  356. while example_5 would return 1000.  Clearly, returning both null
  357. and 1000 is inappropriate, so the exception clause in example_5 
  358. indicates that
  359. 1000 should be returned.  
  360. .pp
  361. Exceptions are supported by converting the parent rule, in this case
  362. example_4, to have an event qualification of
  363. .(l
  364. event_qualification and not event_qualification_of_offspring
  365. .)l
  366. Then the parent rule is removed and reinstalled, while the offspring rule
  367. is inserted in the normal manner.  It is an error for 
  368. the offspring rule to have a different event-type and event-object
  369. from its parent.  
  370. If an exception hierarchy is present, then the above procedure must
  371. be repeated up the hierarchy until no further exceptions are encountered.
  372. .pp
  373. We now indicate three final examples of PRS2.  Consider the 
  374. rule that Sam should
  375. be given any raise that Joe receives as noted in example_1.  Suppose further
  376. that we want a rule to ensure that example_1 is the 
  377. .b only
  378. way that Sam's
  379. salary should be adjusted. This is specified in example_6.
  380. .(l
  381. define rule example_6
  382. on replace to EMP.salary where EMP.name = ``Sam'' and query() != example_1
  383. then do instead
  384. .)l
  385. This rule will disallow any command except the rule example_1 from
  386. changing the salary of Sam.  Example_1 and example_6 together ensure that
  387. Sam has the same salary as Joe.
  388. .pp
  389. Consider the desire to construct a security audit whenever any salary
  390. is accessed.  This is easily expressed by the following rule:
  391. .(l
  392. define rule example_7
  393. on retrieve to EMP.salary
  394. then do append to AUDIT (accessor = user(), object = CURRENT.name, value = CURRENT.salary)
  395. .)l
  396. .pp
  397. Lastly, consider the rule in example_8:
  398. .(l
  399. define rule example_8
  400. on retrieve to TOY_EMP
  401. then do instead retrieve (EMP-OID = EMP.OID, EMP.name, EMP.age, EMP.salary) 
  402. where EMP.dept = ``toy''
  403. .)l
  404. This specifies that when a user performs a retrieve to TOY_EMP
  405. that instead he should be given the result of the query in the action
  406. part of the rule, namely the employees in the toy department.
  407. Clearly, example_8 corresponds to a view definition.
  408. .sh 1  "IMPLEMENTATION"
  409. .pp
  410. There are two implementations for rules in PRS2.  The first is through
  411. .b tuple 
  412. .b level 
  413. processing deep in the executor.  This rules system is
  414. called when individual tuples are accessed, deleted, inserted or modified.
  415. The second implementation is through a 
  416. .b query 
  417. .b rewrite 
  418. implementation.
  419. This module exists between the parser and the query optimizer and 
  420. converts a user command to an alternate form prior to optimization.
  421. The tuple level implementation can process all PRS2 rules while
  422. the query rewrite implementation is used to more efficiently process
  423. a subset of PRS2.
  424. In the rest of this section we discuss each implementation.
  425. .sh 2  "Tuple Level Rule System"
  426. .pp
  427. This rules system can be invoked for any PRS2 rule, and
  428. activation of rules occurs in one of two ways.  First, 
  429. the execution engine 
  430. may be positioned on a specific tuple and a rule awakened.  In this
  431. case NEW and CURRENT take on values from the new and current tuple, and
  432. the rule manager executes the appropriate action. This 
  433. may include running other POSTQUEL commands and modifying values
  434. in NEW or CURRENT.  
  435. The second way the rule manager is called is when a relation
  436. is opened by the executor.  
  437. This will occur in example_8 above when a scan of TOY_EMP is
  438. initiated and the rule manager must be called to materialize
  439. specific tuples from another relation.
  440. This corresponds to materializing the tuples in a
  441. view one-by-one for any user query on the view.  A more efficient
  442. scheme will be discussed in the next subsection. 
  443. .pp
  444. Moreover, when the executor calls the rule manager to activate a retrieval
  445. rule, it knows
  446. how many tuples it wants returned. 
  447. For example, consider the following rule:
  448. .(l
  449. define rule example_9 
  450. on retrieve to EMP.salary where EMP.name = "Joe"
  451. then do instead retrieve (EMP.salary) where EMP.name = "John"
  452. .)l
  453. Even if there are multiple John's in the data base, the executor only
  454. wants one salary returned.  On the other hand, the executor sometimes
  455. wants multiple tuples returned as in example_8 above.  Hence, the executor
  456. will alert the rule manager 
  457. which situation exists and coordinate the protocol for a multiple tuple return.
  458. .pp
  459. Execution of an activated rule can occur either before any further tuples
  460. are processed from the user's query plan, or alternatively, information
  461. about the activated rule is put in a \fIrule agenda\fR, and rule execution
  462. takes place at the conclusion of  the user's query.
  463. In the latter case, the rule is run with the same command identifier as
  464. the user's query, and therefore cannot see any changes made by the
  465. the user command, apart from the new values of the tuple that triggered the
  466. rule. Alternately, it would be possible to run the rule with a separate command identifier
  467. and thereby allow each rule to see all changes of the user command and preceding rules.  
  468. It would also be reasonable to defer execution of rules until the end of the
  469. transaction.  We are not actively exploring either of these latter options.
  470. .pp
  471. When the executor processes a define rule command which will be
  472. implemented by the tuple level implementation, 
  473. information about the rule must be inserted in the system catalogs and 
  474. \fIrule locks\fR must be placed at either the relation level or 
  475. the tuple level.
  476. There are three types of rule locks, namely \fIEvent\fR, \fIImport\fR 
  477. and \fIExport\fR locks.
  478. .pp
  479. \fIEvent\fR locks are placed on appropriate fields in at least
  480. all tuples of the relation that appears in the event specification of
  481. a rule and satisfy the event
  482. qualification. For example consider the rule:
  483. .(l
  484. define rule example_10
  485. on retrieve to EMP.salary
  486. where EMP.age > 50 and EMP.dept = DEPT.dname and DEPT.floor = 1
  487. then do instead retrieve (salary =10000)
  488. .)l
  489. Here, \fIEvent\fR locks should be placed on the salary
  490. field of all
  491. employees who are more than 50
  492. years old and work in a first floor department.
  493. \fIEvent\fR locks are tagged with the type of
  494. event which will activate the action, in this
  495. case a retrieve along with the identifier of the rule.
  496. When an appropriate event occurs
  497. on a field marked by an appropriate \fIEvent\fR lock, 
  498. the qualification in the rule is checked and if true, the
  499. action is executed.
  500. .pp
  501. Apart from putting \fIEvent\fR locks in the right tuples at
  502. rule definition time,
  503. we must make sure that these locks remain on the right tuples even when
  504. updates change the database state.
  505. For instance, in the case of the rule in example_10, if a new employee is added,
  506. we must check whether it satisfies the rule qualification, and if yes put the
  507. appropriate \fIEvent\fR locks in his tuple.
  508. Alternately, if a department is transferred from the second floor to the first one,
  509. then we have to add locks to all the employees working there.
  510. .pp
  511. To achieve this effect, we use \fIstub\fR records.
  512. These can be either \fIindex stub\fR records or \fIrelation stub\fR
  513. records.
  514. The first ones are inserted at
  515. at each end of the scan of any
  516. index, and each intervening index record between these \fIstub\fR records
  517. must also be marked with the appropriate lock.
  518. If all index records on a page are locked, then the corresponding
  519. rule lock can be
  520. escalated to the parent page to save space. Details of this scheme appear
  521. in [KOLO89].
  522. Whenever a new tuple is added to the relation,
  523. or the value of the indexed field is updated,
  524. a record will be
  525. added to the index. By looking at the locks in the index records adjacent
  526. to the one just inserted, the locks that should be put on the
  527. new tuple and index record can be deduced.  This mechanism is 
  528. more fully discussed in
  529. [STON88].
  530. The \fIrelation stub\fR records are put at the relation level, and
  531. every time a new tuple is inserted into a relation, we check all its
  532. \fIstub\fR records to deduce the locks that must be added to the new
  533. tuple.
  534. .pp
  535. The locks are usually put at each individual tuple.
  536. However, in order to save space,
  537. if more than a cutoff number, CUTOFF-1, of locks are set, then the lock can be
  538. escalated to a whole column of a relation and placed in the appropriate record
  539. of the system catalogs.
  540. .pp
  541. \fIEvent\fR locks identify the rule that 
  542. must be awakened when a particular event
  543. occurs.  However, to keep the \fIEvent\fR locks correct as updates occur, we
  544. require two additional kinds of locks.  For example, in example_10
  545. corrective action must be taken if the name of a department or its
  546. floor changes.
  547. To support such actions, we require 
  548. \fIImport\fR and \fIExport\fR locks.
  549. In general, lets assume that the rule qualification has the following
  550. form:
  551. .(l
  552. on event to #R sub n .y#
  553. where
  554.     #R sub n#.x <op> #R sub n-1#.y and
  555.     #R sub n-1#.x <op> #R sub n-2#.y and 
  556.     .....
  557.     #R sub 2#.x <op> #R sub 1#.y and
  558.     #R sub 1#.x <op> C
  559. .)l
  560. where "<op>" is any binary operator, and "C" a constant.
  561. If the rule qualification is more complex, we can always ignore some of
  562. its clauses to construct a qualification of the above form.
  563. Of course that means that we might install more locks than
  564. necessary, because more tuples will satisfy the new qualification than the
  565. original one,
  566. but we believe that this is a reasonable
  567. tradeoff between efficiency and simplicity
  568. of implementation.
  569. .pp
  570. On every relation #R sub i# (i = 1,2, ...n)
  571. we must place an \fIImport\fR lock on the "x" field and
  572. an \fIExport\fR lock on
  573. the "y" field of all tuples that satisfy the qualification:
  574. .(l
  575. #Q sub i# : #R sub i#.x <op> #R sub i-1#.y and ... and #R sub 1#.x = C
  576. .)l
  577. and ensure that these locks will be placed on all modified or
  578. inserted tuples that satisfy #Q sub i#
  579. This can be done in the same ways as for the \fIEvent\fR locks
  580. by using \fIstub\fR records.
  581. .pp
  582. Specifically, when a tuple is inserted in #R sub i#,
  583. or we modify the "x" field of a tuple so
  584. that qualification #Q sub i# is now satisfied,
  585. we must 
  586. add an \fIImport\fR lock to the "x" field
  587. and an \fIExport\fR lock to the "y" field of this tuple.
  588. Moreover,
  589. if \fIY\fR is the value of the "y" field of the tuple, 
  590. then it is necessary to add \fIImport\fR and \fIExport\fR locks
  591. to all the tuples of relation #R sub i+1# which
  592. satisfy the qualification : #R sub i+1#.x = \fIY\fR.
  593. This process will be continued iteratively on
  594. #R sub i+2# ...
  595. .pp
  596. When a tuple is deleted from #R sub i# which had a lock on it, or the
  597. "x" field is modified so that the value no longer 
  598. satisfies #Q sub i#, 
  599. then it is necessary to
  600. delete the \fIImport\fR and \fIExport\fR locks from the tuple.
  601. Moreover,
  602. if there exists no other tuple in #R sub i# which
  603. satisfies the qualification : #R sub i#.y = \fIY\fR and #Q sub i#q.
  604. we must propagate the lock deletion to all
  605. the tuples of #R sub i+1#
  606. where #R sub i+1#.x = \fIY\fR, and iteratively on #R sub i+2#, ...
  607. .pp
  608. Finally if we modify the "y" field of a locked tuple of #R sub i#, we have to
  609. delete locks using the old value of "y" and then add locks
  610. using the new value of "y".
  611. .sh 2  "Query Rewrite Implementation"
  612. .pp
  613. The tuple level implementation will be extremely efficient when there are
  614. a large number of rules, each of whose events covers a small number of tuples.
  615. On the other hand, consider example_8
  616. .(l
  617. define rule example_8
  618. on retrieve to TOY_EMP
  619. then do instead retrieve (EMP-OID = EMP.OID, EMP.name, EMP.age, EMP.salary) 
  620. where EMP.dept = ``toy''
  621. .)l
  622. and an incoming query:
  623. .(l
  624. retrieve (TOY_EMP.salary) where TOY_EMP.name = "Sam"
  625. .)l
  626. Clearly, utilizing the tuple-level rules system will entail materializing
  627. all the tuples in TOY_EMP in order to find Sam's salary.  It would be much
  628. more efficient to 
  629. .b rewrite
  630. the query to:
  631. .(l
  632. retrieve (EMP.salary) where EMP.name = "Sam" and EMP.dept = "toy"
  633. .)l
  634. This section presents a general purpose rewrite algorithm for 
  635. PRS2.
  636. .pp
  637. This second implementation is a module between the parser and the
  638. query optimizer and processes an incoming POSTGRES command, Q
  639. to which a rule, R applies
  640. by converting Q into an alternate form, Q' prior to
  641. optimization and execution.
  642. This implementation can process any PRS2 rule which has a single
  643. command as its action, and we sketch the algorithm that is performed in this
  644. section.  First, we present the algorithm for rules which 
  645. have no event qualification
  646. and perform
  647. a concurrent example. Then we generalize the algorithm to rules
  648. with event qualifications.
  649. .pp
  650. Consider the rule:
  651. .(l
  652. define rule example_11
  653. on replace to TOY_EMP.salary
  654. then do instead replace EMP (salary = NEW.salary)
  655. where EMP.name = CURRENT.name 
  656. .)l
  657. and
  658. the incoming command:
  659. .(l
  660. replace TOY_EMP( salary = 1000) where TOY_EMP.name = "Joe"
  661. .)l
  662. Intuitively, we must remove any references to CURRENT.attribute and
  663. NEW.attribute in order to implement rules at a higher level
  664. than at individual tuple access.  The first two steps of the
  665. algorithm remove these constructs.  The third step deals with 
  666. the semantics of POSTQUEL qualifications, while the final step
  667. perform semantic simplification if possible.
  668. The four steps to the algorithm now follow.  
  669. .pp
  670. The first step is
  671. to note that CURRENT in the rule definition is really a
  672. .b tuple 
  673. .b variable 
  674. which ranges over the qualification in the user command. 
  675. Hence, in R we must replace any reference to CURRENT.attribute 
  676. with t-variable.attribute found as follows.  If Q is a retrieve 
  677. command, then t-variable.attribute is
  678. found in the target list.  On the other hand, if Q is 
  679. a replace or delete, then t-variable is
  680. the tuple variable being updated or deleted.
  681. In addition, the entire qualification from the user command 
  682. must be added to the action part of the rule.
  683. .pp
  684. For the current example CURRENT will range over: 
  685. .(l
  686. TOY_EMP where TOY_EMP.name = "Joe"
  687. .)l
  688. Hence, the rule can be converted in step 1 to:
  689. .(l
  690. on replace to TOY_EMP.salary 
  691. then do instead replace EMP (salary = NEW.salary)
  692. where EMP.name = TOY_EMP.name and TOY_EMP.name = "Joe"
  693. .)l
  694. .pp
  695. In step 2 of the algorithm we replace any reference to NEW.field-name
  696. with the right hand side of the target-list entry for the appropriate
  697. field name in the user's append or replace command.
  698. .pp
  699. In our example, we 
  700. note that NEW.salary can be replaced by the constant "1000" and
  701. the rule is thereby further rewritten to:
  702. .(l
  703. on replace to TOY_EMP.salary 
  704. then do instead replace EMP (salary = 1000)
  705. where EMP.name = TOY_EMP.name and TOY_EMP.name = "Joe"
  706. .)l
  707. .pp
  708. The resulting action
  709. part of the rule now contains one or more tuple variables, in the above example
  710. TOY_EMP and EMP.  Any update in POSTQUEL is actually a retrieve to isolate
  711. the tuples to be added, changed or deleted followed by lower level processing.
  712. Retrieves, of course, only perform a retrieval.  As a result,
  713. step 3 of the algorithm must be executed for a tuple
  714. variable, t-variable if there exists a rule of
  715. the form:
  716. .(l
  717. on retrieve to t-variable.attribute
  718. then do instead retrieve (attribute = \fIexpression\fR) where QUAL
  719. .)l
  720. In this case, replace all occurrences of t-variable.attribute
  721. in R with \fIexpression\fR and then add QUAL to the action part of the rule.
  722. .pp
  723. Such a rule exists as example_8, i.e:
  724. .(l
  725. define rule example_8
  726. on retrieve to TOY_EMP
  727. then do instead retrieve (EMP-OID = EMP.OID, EMP.name, EMP.age, EMP.salary) 
  728. where EMP.dept = ``toy''
  729. .)l
  730. Applying the rule in
  731. example_8 to further rewrite R we get:
  732. .(l
  733. on replace to TOY_EMP.salary
  734. then do instead replace EMP (salary = 1000) from E1 in EMP
  735. where EMP.name = E1.name and E1.name = "Joe" and E1.dept = "toy"
  736. .)l
  737. In the above example, we were required to rename the tuple variable 
  738. to avoid a name conflict.
  739. .pp
  740. The last step of the algorithm is to notice that 
  741. a semantic simplification can be
  742. performed to simplify the above rule to:
  743. .(l
  744. on replace to TOY_EMP.salary
  745. then do instead replace EMP (salary = 1000)
  746. where EMP.name = "Joe" and EMP.dept = "toy"
  747. .)l
  748. The resulting rule
  749. is now executed, i.e. the action part 
  750. of the rule is passed to the
  751. query optimizer and executor.
  752. First, however, the query rewrite module must ensure that 
  753. no new rules apply to the query which is about to be run.  If so,
  754. steps 1-4 must be repeated for the new rule.     
  755. .pp
  756. Intuitively, the user command has been substituted into the
  757. rule to accomplish the rewriting task in the four steps above.
  758. If the tag "instead" is present in R, then PRS will simply 
  759. do the action part of the rewritten rule
  760. in place of Q.
  761. On the other hand, if "instead"
  762. is absent, then the action will be executed in addition to Q. 
  763. .pp
  764. The above algorithm works if R has no event qualification.  On the other hand,
  765. suppose R contains a
  766. qualification, QUAL.  In this case
  767. before the above query modification phase we must transform
  768. the user command Q with qualification USER-QUAL into two user
  769. commands with the following
  770. qualifications: 
  771. .(l
  772. USER-QUAL and \fBnot\fR QUAL
  773.  
  774. USER-QUAL and QUAL
  775. .)l
  776. The first command is processed normally with no modifications while
  777. the second part has the algorithm above performed for it.  Hence, two
  778. commands will be actually be run.
  779. .pp
  780. For example, consider the following rule:
  781. .(l
  782. define rule example_12 
  783. on retrieve to TOY_EMP where TOY_EMP.age < 40
  784. then do instead retrieve (EMP-OID = EMP.OID, EMP.name, EMP.age, EMP.salary) 
  785. where EMP.dept = ``toy''
  786. .)l
  787. and the user query
  788. .(l
  789. retrieve (TOY_EMP.salary) where TOY_EMP.name = "Joe"
  790. .)l
  791. In this case, the following two queries will be run:
  792. .(l
  793. retrieve (TOY_EMP.salary) where TOY_EMP.name "Joe" and not TOY_EMP.age < 40
  794.  
  795. retrieve (TOY_EMP.salary) where TOY_EMP.name = "Joe" and TOY_EMP.age < 40
  796. .)l
  797. The first query is run normally while the second is converted by
  798. the algorithm to:
  799. .(l 
  800. retrieve (EMP.salary) where EMP.name = "Joe" and EMP.dept = "Toy" and EMP.age < 40
  801. .)l
  802. As will be seen in Section 5, this corresponds to a relation that is
  803. partly materialized and partly specified as a view definition.
  804. .pp
  805. Rules for the query rewrite system must be supported by \fIEvent\fR
  806. locks which
  807. are
  808. set at the relation level in the 
  809. system catalogs.  Locks set at the tuple level are not seen until 
  810. until the command is in execution, and therefore the query rewrite module
  811. cannot use them.
  812. .sh 1  "CACHING AND CHOICE OF IMPLEMENTATION"
  813. .pp
  814. For each rule, PRS2 must decide whether to use the query rewrite or
  815. tuple level implementation.  Intuitively, if the event covers most
  816. of a relation, then the rewrite implementation will probably be more efficient
  817. while if only a small number of tuple are involved, then the tuple level 
  818. system may be preferred.  
  819. Specifically, if there is no
  820. where clause in the rule event, then query rewrite will always be the
  821. preferred option.  The single rewritten query will be more efficient than 
  822. the original users query with one or more 
  823. separately evaluated action statements. 
  824. On the other hand, if a where clause is present, then query rewrite will
  825. construct two queries as noted in the previous section.  If a small
  826. number of tuples are covered by the event where clause, then
  827. these two queries
  828. will generally be less efficient than the single original query plus
  829. a separately activated action. 
  830. .pp
  831. Hence, the choice of implementation should be based on the
  832. expected number of tuples that are covered by the event where clause.  
  833. If this number, readily available from the query optimizer, is less
  834. than a cutoff value, CUTOFF-2, then the tuple level implementation should be
  835. chosen; otherwise the rewrite system should be used.
  836. Notice that CUTOFF-2 must be greater than or equal to CUTOFF-1 
  837. noted in the previous
  838. section.  Further investigation may determine that
  839. the two numbers are the same.
  840. .pp
  841. However, the above discussion must be modified when caching of rules
  842. is considered, and we now turn to this subject.
  843. For any rule of the form:
  844. .(l
  845. on retrieve to object ...
  846. then do instead retrieve ...
  847. .)l
  848. the action statement(s) can be evaluated in advance of rule activation
  849. by some user as long as
  850. the retrieve command(s) in the action part of
  851. the rule do not contain a function (such as user or time) which cannot be
  852. evaluated before activation.  We call this advance activation 
  853. .b caching 
  854. the rule and  
  855. there are 3 cases
  856. of interest:
  857.  
  858. 1) The object noted in the rule event is a relation name and there is no where clause in the event.
  859.  
  860. In this case, the rule defines a complete relation and
  861. the query rewrite implementation would normally process
  862. the rule.  If the rule is cached, then the query rewrite system should
  863. not convert the form of the query; rather it should simply
  864. execute the original user's
  865. command on the cached data.
  866.  
  867. 2) The object is of the form relation-name.field 
  868. and there is no where clause in the event.
  869.  
  870. In this case, the rule defines a complete column of a 
  871. relation. 
  872. There is no query processing advantage to caching the 
  873. complete column as a separate relation because
  874. the executor will have to perform a join between the relation of
  875. interest and the cached values to assemble the complete 
  876. relation. 
  877. .pp
  878. Rather, caching should be done on a tuple-by-tuple basis.  Hence, the value of
  879. the action portion of the rule should be constructed for each tuple
  880. in the relation individually.  This value can either be stored directly
  881. in the tuple or it can be stored in a convenient separate place.  If
  882. it is stored in the tuple, then the same value may be materialized 
  883. several times for various tuples.  On the 
  884. other hand, if it is stored separately, then the
  885. executor must maintain a pointer from the tuple to the cached value and
  886. pay a disk seek to obtain the value.
  887. The tradeoffs between these two implementations have been studied in [JHIN88],
  888. and we expect to implement both tactics.
  889. .pp
  890. If the rule is cached on a tuple-by-tuple basis,
  891. then query rewrite must not be performed.  Rather, execution should proceed in
  892. the normal fashion, and the 
  893. executor will simply access the cache to obtain the value needed.  On the
  894. other hand, if a particular value is not cached for 
  895. some reason, the executor must 
  896. evaluate the rule for the tuple of interest to get the needed value.
  897. .pp
  898. Consequently, if a rule which defines a whole column is
  899. cached, then the query rewrite implementation, which would normally
  900. process the rule, should do nothing and let the executor fetch values
  901. from the cache assisted by the tuple level 
  902. implementation if needed values are not present in the
  903. cache.
  904.  
  905. 3) There is a where qualification.
  906.  
  907. In this case, the action part applies to (perhaps) many tuples,  
  908. and we must cache the action part for each tuple to which it applies.  This
  909. cache can be either in the tuple itself or in some separate place.  Hence, it
  910. behaves exactly like case 2) above.
  911.  
  912. .pp
  913. Whenever the action part of the rule is cached, "invalidation" locks
  914. must be set on each accessed field in each tuple.
  915. If any other user command updates a field on which there is an 
  916. invalidation lock, then the cached value must be invalidated before
  917. proceeding; however, invalidation locks are left in place.  Thus, any
  918. object that has been cached once has its locks in place permanently.
  919. .pp
  920. POSTGRES will decide what rules to cache, and expects to use the
  921. following algorithm.  The general idea is to keep the "most worthy"
  922. objects in the cache, i.e. those which benefit the
  923. most from a cached representation.  The benefit computation uses
  924. the following parameters for the ith object:
  925. .(l
  926. #S sub i#: the size of the cached object
  927. #M sub i#: the cost to materialize the object
  928. #A sub i#: the cost to access the object if cached
  929. #D sub i#: the cost to invalidate the object if cached
  930. #a sub i#: the frequency of accesses to this object
  931. #u sub i#: the frequency of updates (invalidations) to this object
  932. .)l
  933. In this case, the expected cost per unit time, #C sub i#, for object #i# is:
  934. .EQ
  935. C sub i~=~left { lpile {{a sub i A sub i~+~u sub i D sub i} above {a sub i M sub i}}
  936. ~~lpile {{if~i~is~cached} above {if~i~is~not~cached}}
  937. .EN
  938. Using an indicator variable #I sub i# to indicate whether #i# is cached, the above can be
  939. expressed as:
  940. .EQ
  941. C sub i~=~a sub i M sub i ~-~ [a sub i (M sub i~-~A sub i )~-~u sub i D sub i ] I sub i
  942. .EN
  943. Thus, the total expected cost per unit time is minimized when
  944. .EQ
  945. F~=~sum from {i=1} to N [a sub i (M sub i~-~A sub i )~-~u sub i D sub i ] I sub i
  946. .EN
  947. is maximized. The constraints on this optimization problem are:
  948. .EQ
  949. sum from {i=1} to N S sub i I sub i~<=~S
  950. .EN
  951. where #S# is the size of the cache.
  952. It can be shown that the solution of the above 0-1 Knapsack problem 
  953. can be approximated by the following 
  954. algorithm if #Max (S sub i )~<<~S#:
  955. .pp
  956. Define the benefit function #f sub i# as
  957. .EQ
  958. f sub i~=~{a sub i (M sub i~-~A sub i )~-~u sub i D sub i} over S sub i
  959. .EN
  960. Intuitively, the benefit function is the benefit per unit size of 
  961. caching the ith object.
  962. Now sort the objects in the descending order of their benefit functions. Let the
  963. #j sup th# entry in this order be the object #pi sub j#. Now define:
  964. .EQ
  965. B sub min~=~f sub pi sub k~~~~~~where~sum from {j=1} to k S sub pi sub j~<=~S~and~sum from {j=1} to k+1 S sub pi sub j~>~S
  966. .EN
  967. Then,
  968. .EQ
  969. I sub i~=~left { lpile {1 above 0}
  970. ~~lpile { {if~f sub i~>=~B sub min} above otherwise}
  971. .EN
  972. Thus at any stage we keep only those 
  973. objects in cache whose benefit function exceeds
  974. the current #B sub min#.
  975. .pp
  976. The only issues that remain are to choose 
  977. #B sub min# and to efficiently estimate  
  978. #a sub i# and #u sub i#.
  979. We describe below a unique approach to each of these problems.
  980. .pp
  981. Consider the access pattern for an object #i#.
  982. Let #L sub a# be the expected length of the interval #I sub a# defined to be the
  983. time between the first access following 
  984. an update to #i# and the first update to the object following
  985. this access.  It can be shown that #L sub a~=~1 over u sub i#. Thus,
  986. if we measure
  987. the average length of all the #I sub a# intervals seen, we have a good
  988. statistical estimate for #u sub i#. 
  989. It can be seen that the average length of a 
  990. similar interval determines #a sub i#.
  991. .pp
  992. These average length statistics are very 
  993. cheap to maintain for cached objects because
  994. POSTGRES must invalidate the cached object on update and then rebuild the
  995. cache on the first subsequent access.  Both actions require writing the
  996. cached object.  Hence, if the statistics are kept with the cached object,
  997. there is no extra I/O cost to maintain them. 
  998. .pp
  999. For each object whose current benefit exceeds #B sub min# we maintain 
  1000. these statistics. 
  1001. Periodically, a caching
  1002. demon recomputes the current benefit of all objects whose statistics
  1003. are being maintained and deletes those objects from the cache (and stops
  1004. maintaining their statistics) whose benefit is below the current #B sub min#.
  1005. .pp
  1006. In between runs of the daemon, a cached object is marked "invalid" on each
  1007. update. On an access, an object is materialized and cached if
  1008. .ip 1)
  1009. Its statistics are being maintained and it is currently "invalid", or
  1010. .ip 2)
  1011. Its statistics are not being maintained, but its \fBexpected\fR benefit
  1012. exceeds #B sub min#.
  1013. In this case, we also start keeping its statistics.
  1014. The expected benefit of an object i is defined to be:
  1015. .EQ
  1016. f bar sub i~=~{a bar (M sub i~-~A sub i )~-~u bar D sub i} over S sub i
  1017. .EN
  1018. where #a bar# is the average frequency of access to the objects in the
  1019. database, and #u bar# is the average update frequency in the
  1020. database.
  1021. Ideally we would like to keep only those objects
  1022. whose \fBactual\fR benefit exceeds #B sub min#. Since 
  1023. the past access patterns of these objects are not being kept, the best
  1024. we can do is to make the decision on the basis of expected benefit.
  1025. .pp
  1026. When the cache demon runs, it checks for the space utilization. If the cache
  1027. space is not entirely utilized, it increases the value of #B sub min#. It
  1028. thus deletes fewer objects, and also permits the caching of more new objects
  1029. in between runs. 
  1030. On the other hand, if the cache space is used up in between runs, then the
  1031. next time the daemon runs, it will use a lower value of #B sub min#.
  1032. This feedback mechanism ensures that 
  1033. #B sub min# 
  1034. will converge to the correct value, provided the database access
  1035. patterns are fairly stable.
  1036. Furthermore, if access patterns change dramatically, this feedback mechanism
  1037. will ensure a reconvergence to a new #B sub min#.
  1038. .sh 1  "SUPPORT FOR VIEWS"
  1039. .sh 2  "Normal Views"
  1040. .pp
  1041. In POSTGRES named procedures can be defined to the system as
  1042. follows:
  1043. .(l
  1044. define [updated] procedure proc-name (type-1, ..., type-n) as postquel-commands
  1045. .)l
  1046. If the procedure has no parameters, then it is a 
  1047. .b view
  1048. definition, and
  1049. a syntactic alternative to the above definition would be:
  1050. .(l
  1051. define [updated] view view-name as postquel-commands
  1052. .)l
  1053. For example, consider the following view definition:
  1054. .(l
  1055. define view SHOE_EMP as 
  1056. retrieve (EMP.all) where EMP.dept = ``shoe''
  1057. .)l
  1058. This definition would be turned automatically by POSTGRES
  1059. into the following rule:
  1060. .(l
  1061. define rule SHOE_EMP_ret
  1062. on retrieve to SHOE_EMP
  1063. then instead do retrieve (EMP-OID = EMP.OID, EMP.all) where EMP.dept = ``shoe''
  1064. .)l
  1065. This rule will be processed by the query rewrite implementation
  1066. and will perform the correct query modification to any user
  1067. query that appears. 
  1068. .pp
  1069. On the other hand, consider the following view definition:
  1070. .(l
  1071. define updated view TOY_EMP as 
  1072. retrieve (EMP.name, EMP.age, EMP.salary) where EMP.dept = ``toy''
  1073. .)l
  1074. In this case, the user wishes standard view update semantics 
  1075. to be applied to
  1076. user updates to TOY_EMP.  Hence the system would automatically construct the
  1077. retrieve rule in example_8 in addition to the following update rules:
  1078. .(l
  1079. define rule TOY_EMP_d
  1080. on delete to TOY_EMP
  1081. then do instead delete EMP where EMP.OID = CURRENT.EMP-OID
  1082.  
  1083. define rule TOY_EMP_a
  1084. on append to TOY_EMP
  1085. then do instead append to EMP (name = NEW.name, 
  1086.                                age = NEW.age, 
  1087.                                salary = NEW.salary,
  1088.                                dept = ``toy'')
  1089.  
  1090. define rule TOY_EMP_r
  1091. on replace to TOY_EMP
  1092. then do instead replace EMP (name = NEW.name, age = NEW.age, salary = NEW.salary)
  1093.                           where EMP.OID = CURRENT.EMP-OID
  1094. .)l
  1095. .pp
  1096. A view will automatically have an OID field 
  1097. for each tuple variable
  1098. in its definition. When multiple identifiers are present,
  1099. the name of each identifier is tvar-OID, where tvar is the tuple
  1100. variable involved. This identifier keeps the OID of a tuple
  1101. in the relation tvar which was used to construct this particular
  1102. tuple in the view.
  1103. .pp
  1104. If a view is not specified as
  1105. updated, then it is the responsibility of the user to
  1106. specify his own update rules as discussed in the next subsection.
  1107. .sh 2  "More General Views"
  1108. .pp
  1109. Consider a rule defining 
  1110. a conventional join view, e.g:
  1111. .(l
  1112. define rule example_13 
  1113. on retrieve to E-D
  1114. then do instead 
  1115. retrieve (EMP-OID = EMP.OID, EMP.name, EMP.salary, EMP.dept, 
  1116. DEPT-OID = DEPT.OID, DEPT.floor)
  1117. where EMP.dept = DEPT.dname
  1118. .)l
  1119. In current commercial systems all deletes and appends fail for the E-D 
  1120. view and some updates fail.  However, in PRS2 we can specify the
  1121. following collection of update rules:
  1122. .(l
  1123. define rule E-D-1
  1124. on replace to E-D.name, E-D.salary
  1125. then do instead replace EMP (name = NEW.name, salary = NEW.salary)
  1126. where EMP.OID = CURRENT.EMP-OID
  1127.  
  1128. define rule E-D-2
  1129. on replace to E-D.floor
  1130. then do instead replace DEPT (floor = NEW.floor) 
  1131. where DEPT.OID = CURRENT.DEPT-OID
  1132.  
  1133. define rule E-D-3
  1134. on replace to E-D.dept
  1135. then do instead 
  1136.     replace EMP (dept = NEW.dept)
  1137.     where EMP.OID = CURRENT.EMP-OID
  1138.  
  1139.     append to DEPT (dname = NEW.dept, floor = CURRENT.floor)
  1140.     where NEW.dept not-in {DEPT.dname}
  1141. .)l
  1142. This will map all updates to underlying base relations.  Moreover,
  1143. when an employee in the E-D view changes departments, then 
  1144. his new department is created if it doesn't exist.
  1145. All other reasonable rules for updating EMP and DEPT when updates
  1146. to E-D occur appear expressible as PRS2 rules.
  1147. Hence, a sophisticated user can specify any particular mapping
  1148. rules for updates that he wishes to.  In this way, 
  1149. .b all
  1150. views can
  1151. be made updatable, a big advance over current implementations.
  1152. .sh 2  "Materialized, Partial and Composite Views"
  1153. .pp
  1154. In this section we discuss three other
  1155. more general kinds of views that are possible with PRS2.
  1156. First, consider a materialized view, e.g. one whose
  1157. tuples are maintained automatically by the system.  Such views
  1158. are discussed in [BLAK86, ROUS89].  In PRS2, all
  1159. views may be materialized by caching the action part of the
  1160. rule that defines the view.  This will be 
  1161. done automatically by the caching demon if the view is "worthy"
  1162. as noted earlier.
  1163. The only inefficiency in PRS2 is that materialized views are invalidated
  1164. if an update to an underlying base relation occurs.  In the future
  1165. we propose to study how to incorporate algorithms to directly update
  1166. materialized views.
  1167. .pp
  1168. Next consider a 
  1169. .b partial
  1170. view, i.e a relation that is partly instantiated with tuples
  1171. and partly expressed by a view.  Hence, a relation is considered
  1172. to be the union of a stored relation and a view.  This is naturally
  1173. supported by the following retrieve rule:
  1174. .(l
  1175. define rule example_14
  1176. on retrieve to PARTIAL
  1177. then do retrieve (EMP-OID = EMP.OID, EMP.all) where EMP.dept = ``toy''
  1178. .)l
  1179. Here, notice that the keyword "instead" has been omitted; consequently
  1180. a retrieve to the stored relation PARTIAL will occur along with 
  1181. query rewrite to access the employees in the toy department.  It
  1182. is
  1183. easy to specify updating rules for partial views, and example_15
  1184. expresses the appropriate insert rule:
  1185. .(l
  1186. define rule example_15
  1187. on append to PARTIAL 
  1188. then do instead
  1189.    append to EMP (NEW.all) where NEW.dept = ``toy''
  1190.    append to PARTIAL (NEW.all) where NEW.dept != ``toy''
  1191. .)l
  1192. .pp
  1193. Lastly, consider a view which is a composite of two relations, e.g:
  1194. .(l
  1195. define view TOY_EMP as
  1196. retrieve (EMP.name, EMP.salary, EMP.age) where EMP.dept = ``toy''
  1197. retrieve (NEWEMP.name, NEWEMP.status, NEMEMP.age) 
  1198. where NEWEMP.dept = ``toy''
  1199. .)l
  1200. This can easily be expressed as:
  1201. .(l
  1202. define rule example_16 
  1203. on retrieve to TOY_EMP 
  1204. then do instead
  1205. retrieve (EMP-OID = EMP.OID, EMP.name, EMP.salary, EMP.age) where EMP.dept = ``toy''
  1206. retrieve (NEWEMP-OID = NEWEMP.OID, NEWEMP.name, NEWEMP.status, NEMEMP.age) 
  1207. where NEWEMP.dept = ``toy''
  1208. .)l
  1209. Clearly various composite views can be defined, with automatic or
  1210. user defined updating rules.
  1211. .sh 1  "PROCEDURAL FIELDS"
  1212. .pp
  1213. There are four ways that procedures exist in the POSTGRES
  1214. system. Procedures without parameters are effectively view definitions
  1215. and were discussed in the previous section.  In this section
  1216. we discuss procedures with parameters, general procedural fields
  1217. and special procedural fields.
  1218. .sh 2  "Procedures with Parameters"
  1219. .pp
  1220. Procedures can be defined which contain
  1221. parameters, e.g:
  1222. .(l
  1223. define procedure TP1 (char16, int4) as
  1224. replace ACCOUNT (balance = ACCOUNT.balance - $2) where ACCOUNT.name = $1
  1225. .)l
  1226. This procedure is not a view definition and is simply
  1227. .b registered
  1228. in the system catalogs.  In this case, the only functionality
  1229. supported by POSTGRES is executing the procedure, e.g: 
  1230. .(l
  1231. execute TP1 ("Sam", 100)
  1232. .)l
  1233. .sh 2 "General Procedural Fields"
  1234. .pp
  1235. General procedures have been proposed for POSTGRES as 
  1236. a powerful modelling construct.
  1237. In this section we demonstrate the general procedures
  1238. are efficiently simulated by PRS2.
  1239. Consider the
  1240. standard example from [STON87]:
  1241. .(l
  1242. EMP (name, hobbies)
  1243. .)l
  1244. Each tuple of EMP contains a procedure in the hobbies field.  Since there
  1245. is a command to define procedures, each row of EMP has a value which
  1246. is a registered procedure of the form:
  1247. .(l
  1248. proc-name(param-list)
  1249. .)l
  1250. where proc-name is a previously registered procedure.
  1251. In this case an insert would look like:
  1252. .(l
  1253. append to EMP (name= "Sam", hobbies = foobar(param-1, ..., param-n))
  1254. .)l
  1255. The parameter list will be present only if the registered procedure
  1256. has parameters.
  1257. .pp
  1258. This data type can be effectively supported by 
  1259. defining one rule per
  1260. procedural data element of the form:
  1261. .(l
  1262. on retrieve to rel-name.column-name where rel-name.OID = value 
  1263. then do instead execute proc-name(param-list)
  1264. .)l
  1265. Hence, the insertion of Sam can be done as follows:
  1266. .(l
  1267. append to EMP (name = "Sam")
  1268.  
  1269. define rule example_17
  1270. on retrieve to EMP.hobbies where EMP.OID = value
  1271. then do instead execute foobar(param-1, ..., param-n)
  1272. .)l
  1273. If the action part of the rule is cached, then this will correspond
  1274. to the caching of procedures discussed in [STON87].
  1275. .pp
  1276. Moreover, POSTGRES has syntax to update the data base through a procedural
  1277. field.  Consider for example the following update:
  1278. .(l
  1279. replace EMP.hobbies (position = ``catcher'') where EMP.name = ``Sam''
  1280. .)l
  1281. There are two situations of interest.  First, if the procedure
  1282. corresponding the Sam's hobbies has no parameters, then it
  1283. could have been specified as a view definition with automatic update.
  1284. In this case, the automatic
  1285. update rules can be applied to map the above update.  Otherwise, 
  1286. the user is free to add his own updating rules
  1287. for Sam's hobby field, e.g:
  1288. .(l
  1289. define rule example_18
  1290. on replace to EMP.hobbies where EMP.name = "Sam"
  1291. then do instead ....
  1292. .)l
  1293. .sh 2  "Special Procedures"
  1294. .pp
  1295. A relation in POSTGRES can have a field of type special procedure.  Consider
  1296. the DEPT relation from Section 1:
  1297. .(l
  1298. create DEPT (dname = char16, floor = i4, composition = EMPS)
  1299. .)l
  1300. Here, composition is intended to have a value found by executing the
  1301. procedure EMPS.  This procedure would be defined as:
  1302. .(l
  1303. define procedure EMPS (char16) as 
  1304. retrieve (EMP-OID = EMP.OID, EMP.all) where EMP.dept = $.dname
  1305. .)l
  1306. Like TP1, this procedure contains a parameter, $.dname, and therefore is not a
  1307. view definition.
  1308. Like TP1 it is merely registered at the time it is defined.
  1309. .pp
  1310. At the time the DEPT relation is created, the following rule can be
  1311. defined:
  1312. .(l
  1313. on retrieve to DEPT.composition
  1314. then do instead retrieve (EMP-OID = EMP.OID, EMP.all) 
  1315. where EMP.dept = CURRENT.dname
  1316. .)l
  1317. This rule defines the column, DEPT.composition, and query rewriting rules
  1318. will map any query containing a reference to composition correctly.  Moreover,
  1319. caching can be applied to this rule and the tuples for each 
  1320. given department name will be
  1321. optionally cached by the algorithms in Section 4.  
  1322. .sh 1  "CONCLUSIONS"
  1323. .pp
  1324. In this paper we have demonstrated a rule system that will take appropriate 
  1325. actions when specific events become true.  This rules system can have
  1326. CURRENT.attribute and NEW.attribute in the action part, and its semantics
  1327. are naturally defined when individual tuples are retrieved or modified.
  1328. We described the corresponding tuple level implementation which enforces these
  1329. semantics.  However, we also presented an algorithm through which we
  1330. can remove CURRENT and NEW from a rule and perform query rewrite 
  1331. to enforce the rule, and described this second implementation of the
  1332. rules system.  
  1333. .pp
  1334. Moreover, any rule whose event and action parts are
  1335. retrieves can be evaluated before it is activated by a user.  We
  1336. described how this caching takes place and what algorithm should be
  1337. used to manage the cache.  
  1338. .pp
  1339. Then, we demonstrated that support for relational views is merely
  1340. an application of our query rewrite implementation on a
  1341. rule which specifies the view definition.  Moreover, non standard
  1342. update semantics can be specified as additional updating rules, thereby
  1343. substantially enchancing the power of views.  Various more general views
  1344. can also be readily supported.  
  1345. .pp
  1346. We then showed that POSTGRES procedures are merely an additional application
  1347. of the rules system.  In addition, caching of rules
  1348. naturally supports materialized views and cached procedures, thereby
  1349. no extra mechanisms are required to obtain this functionality. 
  1350. .pp
  1351. In the future we are going to explore additional applications of PRS2.
  1352. These include the possibility of writing a physical data base design tool
  1353. and the POSTGRES version system in PRS2.  Moreover, we plan to search
  1354. for algorithms which could convert an early implementation of
  1355. a rule, e.g:
  1356. .(l
  1357. on replace ...
  1358. then do replace ...
  1359. .)l
  1360. to an equivalent late rule, e.g:
  1361. .(l
  1362. on retrieve ...
  1363. then do instead retrieve ...
  1364. .)l
  1365. This would allow PRS2 to cache the action part of the rule and
  1366. decide automatically between early and late evaluation.
  1367. .pp
  1368. Lastly, we will continue to support our earlier 
  1369. .b always
  1370. and
  1371. .b never
  1372. syntax, because it can be easily compiled into multiple PRS2 commands.
  1373. We also plan to explore other higher level interfaces, for which rule
  1374. compilers can be constructed.
  1375.  
  1376. .ce
  1377. \fBREFERENCES\fP
  1378. .nr ii 10m
  1379. .ip [BLAK86]
  1380. Blakeley, J. et. al., ``Efficiently Updating Materialized Views,''
  1381. Proc. 1986 ACM-SIGMOD Conference on 
  1382. Management of Data, Washington, D.C., June 1986.
  1383. .ip [CODD74]
  1384. Codd, E., ``Recent Investigations in Relational Data Base Systems,''
  1385. IBM Research, Technical Report RJ1385, San Jose, Ca., April 1974. 
  1386. .ip [DADA86]
  1387. Dadam, P et. al., ``A DBMS Prototype to Support Extended NF2 Relations: An
  1388. Integrated View on Flat Tables and Hierarchies,'' Proc. 1986 ACM-SIGMOD
  1389. Conference on Management of Data, Washington, D.C., June 1986.
  1390. .ip [DELC88]
  1391. Delcambre, L. and Etheredge, J., 
  1392. .q "The Relational Production Language,"
  1393. Proc. 2nd International Conference on Expert Database Systems, Washington,
  1394. D.C., February 1988.
  1395. .ip [ESWA76]
  1396. Eswaren, K., ``Specification, Implementation and Interactions of a 
  1397. Rule Subsystem in an Integrated Database System,'' IBM Research,
  1398. San Jose, Ca., Research Report RJ1820, August 1976.
  1399. .ip [HANS89]
  1400. Hanson, E., ``An Initial Report on the Design of Ariel, '' 
  1401. ACM SIGMOD Record, Sept. 1989.
  1402. .ip [JHIN88]
  1403. Jhingran, A., ``A Performance Study of Query Optimization
  1404. Algorithms on a Data Base System Supporting Procedural Objects,''
  1405. Proc. 1988 VLDB Conference, Los Angeles, Ca., Sept. 1988.
  1406. .ip [KOLO89]
  1407. Kolovson, C. and Stonebraker, M., ``Segmented Search Trees and
  1408. their Application to Data Bases,'' (in preparation).
  1409. .ip [MCCA89]
  1410. McCarthy, D. and Dayal, U., ``The Architecture of an Active Data Base 
  1411. Management System,'' Proc 1989 ACM-SIGMOD Conference on Management
  1412. of Data, Portland, Ore., June 1989. 
  1413. .ip [ROUS87]
  1414. Rousoupoulis, N., ``The Incremental Access Method of View Cache: Concepts,
  1415. Algorithms, and Cost Analysis,'' Computer Science Technical Report CS-TR-2193,
  1416. University of Maryland, February 1989.
  1417. .ip [ROWE87]
  1418. Rowe, L. and Stonebraker, M.,
  1419. .q "The POSTGRES Data Model,"
  1420. Proc. 1987 VLDB Conference, Brighton, England, Sept 1987.
  1421. .ip [STON75]
  1422. Stonebraker, M., ``Implementation of Integrity Constraints and
  1423. Views by Query Modification,'' Proc. 1975 ACM-SIGMOD Conference,
  1424. San Jose, Ca., May 1975.
  1425. .ip [STON82]
  1426. Stonebraker, M. et. al., ``A Rules System for a Relational Data Base Management
  1427. System,'' Proc. 2nd International Conference on Databases,'' Jerusalem,
  1428. Israel, June 1982 (available from Academic press).
  1429. .ip [STON86]
  1430. Stonebraker, M. and Rowe, L., 
  1431. .q "The Design of POSTGRES,"
  1432. Proc. 
  1433. 1986 ACM-SIGMOD Conference, Washington, D.C., June 1986.
  1434. .ip [STON87]
  1435. Stonebraker, M., et. al., ``Extending a Data Base System With Procedures,''
  1436. ACM TODS, September, 1987.
  1437. .ip [STON88]
  1438. Stonebraker, M. et. al.,
  1439. .q "The POSTGRES Rules System,"
  1440. IEEE Transactions on Software Engineering, July 1988.
  1441. .ip [WIDO89]
  1442. Widom, J. and Finkelstein, S., ``A Syntax and Semantics for Set-oriented
  1443. Production Rules in Relational Data Bases, IBM Research, San Jose, Ca.,
  1444. June 1989.
  1445.