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

  1.  
  2.  
  3. .nr tp 12
  4. .nr sp 12
  5. .nr pp 11
  6. .nr fp 10
  7. .sz \n(pp
  8. .fo ''%''
  9. .(l C
  10. .sz \n(sp
  11. .b
  12. EXTENDING A DATA BASE SYSTEM WITH PROCEDURES
  13. .sz \n(pp
  14. .sp 3
  15. .i
  16. Michael Stonebraker, Jeff Anton and Eric Hanson
  17. .sp
  18. EECS Department
  19. University of California
  20. Berkeley, Ca., 94720
  21. .sp
  22. .r
  23. .)l
  24. .sp 3
  25. .(f
  26. This research was sponsored
  27. by the U.S. Air Force Office of Scientific 
  28. Research  Grant 83-0254
  29. and
  30. the Naval Electronics Systems 
  31. Command  Contract N39-82-C-0235
  32. .)f
  33. .uh Abstract
  34. .pp
  35. This paper suggests that more powerful data base systems (DBMS) can
  36. be built by supporting data base procedures as full fledged 
  37. data base objects.  In particular, allowing fields of a data base to
  38. be a collection of queries in the query language of the system
  39. is shown to allow complex data relationships to be 
  40. naturally expressed.  
  41. Moreover, many of the features present in object-oriented
  42. systems and semantic data models can be
  43. supported by this facility.
  44. .pp
  45. In order to implement this construct, extensions
  46. to a typical relational query language must be made and 
  47. considerable work on the execution engine of the underlying DBMS
  48. must be accomplished.  This paper reports on the extensions for
  49. one particular query language and data manager and then gives 
  50. performance figures for a prototype implementation.
  51. Even though the performance of the prototype is competitive with that of
  52. a
  53. conventional system, suggestions
  54. for improvement are presented.
  55. .sh 1 "INTRODUCTION"
  56. .pp
  57. Most current data base systems store information only as data. 
  58. However
  59. older data base systems (e.g. [DBTG71]) specifically allowed data base 
  60. procedures written in a general purpose 
  61. programming language to be called during command execution.  
  62. Moreover, Lisp [WILE84] supports objects which are interchangeably
  63. either
  64. procedures or data.  In this paper we suggest that supporting 
  65. a restricted form of data base procedures in a DBMS allows complex 
  66. data base problems to be easily and naturally addressed.  In 
  67. particular, we propose that a field in a data base be allowed to
  68. have a value which is a collection of commands
  69. in the query language supported by the DBMS (e.g. SQL [SORD84] or QUEL).
  70. .pp
  71. Our proposal should augment a field-oriented abstract data 
  72. type (ADT) facility (e.g. [ONG84]).  Such an ADT capability appears useful
  73. for supporting relatively simple objects which do not require
  74. shared subobjects (e.g. lines, points, complex numbers, etc.).  On
  75. the other hand, data base procedures are attractive for more complex
  76. objects, possibly with shared subobjects (e.g. forms, icons, reports, etc.).
  77. .pp
  78. We begin in Section 2 by presenting the data definition facilities for
  79. procedural data along with several examples of the
  80. use of this construct.
  81. Then, in Section 3 
  82. we review briefly how to extend one query language with 
  83. necessary facilities to use procedures.
  84. Our choice is QUEL [STON76], but the
  85. extensions are easy to map into most other relational query languages.
  86. The definition of this language, QUEL+, is indicated in Section
  87. 3 and is based on suggestions in [STON84]. 
  88. Substantial changes to the query execution code 
  89. of a data base system are required to process QUEL+.  In Section 4 we indicate 
  90. the changes that were necessary
  91. to support our constructs in the University of California version
  92. of INGRES [STON76].  Then, in Section 5 the performance of
  93. our prototype on several problems with complex data relationships
  94. is indicated.  Lastly, Section 6 discusses ways in which
  95. the performance
  96. of the prototype could be improved.
  97. .sh 1  "DATA BASE PROCEDURES"
  98. .pp
  99. The motivation behind using procedures as full-fledged
  100. data base objects was to retain the ``spartan simplicity''
  101. of the relational model, while allowing it to address situations
  102. where it has been found inadequate.  
  103. Such situations include
  104. generalization, aggregation, referential
  105. integrity, transitive closure, complex objects with shared subobjects, 
  106. stored queries, and objects with unpredictable composition.  
  107. The main advantage of our approach is that a single mechanism
  108. can address a large class of recognized deficiencies. 
  109. We discuss the data definition capabilities of our proposal along
  110. with examples of its application to some of the above problems 
  111. in the remainder of
  112. this section.
  113. .sh 2  "Objects with Unpredictable Composition"
  114. .pp
  115. The basic concept is that a field in a relation can 
  116. have a value consisting of a collection of 
  117. query language commands.  Consider, for example, a conventional
  118. EMP relation with the requirement of storing
  119. data on 
  120. the various hobbies of employees.
  121. Three relations containing hobby data might be:
  122. .(l
  123. SOFTBALL (emp-name, position, average)
  124. SAILING    (emp-name, rating, boat-type, marina)
  125. JOGGING  (emp-name, distance, best-time, shoe-type, number-of-races)
  126. .)l
  127. Each gives relevant data for a particular hobby.  For example, 
  128. Smith could be added as the catcher of the softball team by:
  129. .(l
  130. append to SOFTBALL (name = ``Smith'', position = ``catcher'', average = 0)
  131. .)l
  132. The desired form of the EMP relation would be:
  133. .(l
  134. create EMP (name = c10, age = i4, salary = f8, hobbies = procedure)
  135. .)l
  136. Then, for example, Smith could be added as an employee by:
  137. .(l
  138. append to EMP (
  139.                         name = ``Smith''
  140.                         age = 40
  141.                         salary = 10000,
  142.                         hobbies = ``retrieve (SOFTBALL.all) 
  143.                                        where SOFTBALL.name = ``Smith''''
  144.                      )
  145. .)l
  146. In this case, the first three values are conventional fields while
  147. the fourth is a field of data type ``collection of commands in the
  148. query language''.  The value of this last field is obtained by
  149. executing the command (s) in the field. 
  150. As such the ultimate value of each hobbies object is an arbitrary
  151. collection of records of arbitrary composition.  A procedural field has
  152. the flexibility to model environments where there is no predetermined 
  153. structure
  154. to objects.  A second example of the need for procedural
  155. fields is indicated in the next subsection.
  156. .sh 2  "Stored Queries"
  157. .pp
  158. Most data base systems which preprocess commands in advance
  159. of execution (e.g. System R [ASTR76] and the IDM [EPST80]) store 
  160. access plans or compiled
  161. code in the data base system.  Such systems already manage a data base
  162. of compiled queries.  Their implementations would become somewhat
  163. cleaner if data base commands became full-fledged data base objects.
  164. For example, the precompiler for a programming language
  165. could run a conventional APPEND command to insert
  166. a tuple into the following
  167. relation for each data base command found in a user program:
  168. .(l
  169. TODO (id, command)
  170. .)l
  171. Then, at run time the program would use the EXECUTE command to
  172. be introduced in Section 3:
  173. .(l
  174. execute (TODO.command) where TODO.id = value 
  175. .)l
  176. To substitute parameters into such a command, one 
  177. requires an additional operator ``with'' to specify:
  178. .(l
  179. execute (TODO.command with param-list) where TODO.id = value
  180. .)l
  181. In this way, the compile-time and run-time interfaces to the data base system
  182. are the same, resulting in a more compact implementation.(**)
  183. .(f
  184. ** Of course, authorization must be done for the above
  185. command to support access control.
  186. It would
  187. be beneficial to avoid reauthorizing a command each time it
  188. is executed from an application program.  A mechanism to
  189. accomplish this task is beyond the scope of this paper. 
  190. .)f 
  191. Moreover, in Section 6 we discuss how to asynchronously  
  192. build query processing plans
  193. for user commands between the time that the preprocessor inserts
  194. then in the TODO relation and the time that the user executes them.  Hence,
  195. there is no performance penalty to our approach compared to current technology.
  196. In fact, our approach may well run faster because in Section 6
  197. we also
  198. propose caching the
  199. answers to commands as well as their execution plan.
  200. .pp 
  201. A second use of stored queries is to support
  202. the definition of relational views.
  203. Each view can be stored as a row
  204. in a VIEW relation as follows:
  205. .(l
  206. VIEW (name, query)
  207. .)l
  208. Here, the retrieval command that defines the view can be stored in
  209. the ``query'' field while the name of the view is stored in
  210. the ``name'' field.
  211. The query modification facilities of [STON75] are needed to support
  212. the extensions that we propose to a query language in the next section;
  213. consequently, it will be seen that views require very little special case
  214. code if implemented as procedural fields.
  215. .pp
  216. Lastly, many applications require the ability to 
  217. store algorithms made up
  218. of data base commands in the data base. 
  219. An example of this kind
  220. of application is [KUNG84].
  221. Our proposal contains exactly the facilities
  222. needed in such environments.
  223. .sh 2  "Complex Objects with Shared Subobjects"
  224. .pp
  225. Another example where procedures are helpful is in
  226. modeling of complex objects.  
  227. Suppose an 
  228. object is composed of text, line segments, and polygons and
  229. is represented in the following relations:
  230. .(l
  231. OBJECT    (Oid, text, shape)
  232. LINE        (Lid, l-desc)
  233. TEXT        (Tid, t-desc)
  234. POLYGON (Pid, p-desc)
  235. .)l
  236. Subcomponents of objects would be inserted 
  237. into the LINE, TEXT or POLYGON relation, 
  238. and we assume that l-desc and p-desc are of
  239. type ``line'' and ``point'' respectively and utilize a field-oriented
  240. ADT facility (e.g. [ONG84]). 
  241. For example:
  242. .(l
  243. append to LINE (Lid = 22, 
  244.                  l-desc = ``(0,0) (14,28)'')
  245. append to POLYGON (Pid = 44,
  246.                                 p-desc = ``(1,10) (14,22) (6,19) (12,22)'')
  247. append to TEXT (Tid = 16,
  248.                            t-desc = ``the fox jumped over the log'')
  249. .)l
  250. Then, the ``text'' and ``shape'' fields of
  251. OBJECT would be of type procedure, and each tuple in OBJECT would
  252. contain queries to assemble a specific object from pieces stored in 
  253. the other relations. 
  254. For example,
  255. the following query would make object 6 be
  256. composed of all line segments with identifiers less
  257. than 20,
  258. polygon 44, and the first 9 text fragments.
  259. .(l
  260. append to OBJECT( Oid = 6,
  261.                              shape = ``retrieve (LINE.all) where LINE.Lid < 20
  262.                                           retrieve (POLYGON.all) where POLYGON.Pid = 44'',
  263.                              text = ``retrieve (TEXT.all) where TEXT.Tid < 10'')
  264. .)l
  265. Notice that sharing is easily accomplished by inserting
  266. queries into multiple ``shape'' or ``text'' fields which reference the same
  267. subobject. 
  268. .pp
  269. Additional examples of complex objects 
  270. include forms (such as found in a system like FADS [ROWE82]),
  271. icons, reports, and complex geographic objects (e.g. a plumbing
  272. fixture which makes a right angle bend).
  273. .pp
  274. When objects can have a variety
  275. of subobjects and those subobjects can be shared, most contemporary
  276. modelling ideas are flawed.  For example, the proposal of [HASK82, LORI83] does
  277. not easily allow shared subobjects.  Semantic 
  278. data models (e.g. [HAMM81, MYLO80,
  279. SHIP81, SMIT77, ZANI83]) lack
  280. the flexibility to deal with uncertain structure.  
  281. The proposal of [COPE84] allows sharing by storing subobjects 
  282. as separate records and connecting them with 
  283. pointer chains.  Our sharing is accomplished without
  284. requiring a specialized low level storage manager, and 
  285. we will show in Section 6 how caching can be 
  286. used to make performance competitive with pointer
  287. based proposals.
  288. .sh 2  "Generalizations to Arbitrary Procedures"
  289. .pp
  290. Our proposal should be easily generalizable to procedures
  291. written in a general purpose programming language.
  292. An example that can utilize more general procedures is a graphics 
  293. application that wishes to store icons in the data base (e.g. [KALA85]).
  294. Icons should be stored in human readable form, so their description
  295. can be browsed
  296. easily.  However, display software requires icons to be 
  297. converted into a display list
  298. for a particular graphics terminal.  An icon could be
  299. a complex object, and its components assembled
  300. by a query.  However, the components must then be turned
  301. into a display list by a procedure in a general
  302. purpose programming language which appears in an application
  303. program.  Efficiency can be gained by
  304. caching icons as noted in Section 6; however, further
  305. efficiency results from caching the actual display list.
  306. Such a capability requires general procedures rather than just
  307. data base procedures.
  308. .pp
  309. A second example of the need for general procedures
  310. is in the support for
  311. extended data type proposals (e.g. [ONG84])
  312. They require user-defined
  313. procedures to implement new operators.  Such procedures must
  314. be called by the DBMS as appropriate, and it 
  315. would be more natural if they
  316. were full fledged data base objects.
  317. .pp
  318. A last example of the use of general procedures would be in
  319. the system catalogs of a
  320. typical 
  321. relational data base system where the following two relations appear.
  322. .(l
  323. RELATION (relation-name, owner, ...)
  324. ATTRIBUTE (relation-name, attribute-name, position, data-type, ...)
  325. .)l
  326. Whenever a relation with N attributes is ``opened'', a ``descriptor'' must be
  327. built by accessing one
  328. tuple in RELATION 
  329. plus N tuples from the
  330. ATTRIBUTE relation.  
  331. In order to allow ``browsing'' of the system catalogs, it is desirable
  332. to store the catalogs in the above fashion; however the penalty
  333. is the lengthy time required to open a relation.  
  334. .pp
  335. An alternate solution is to 
  336. add a procedural field
  337. to RELATION, e.g:
  338. .(l
  339. RELATION (relation-name, owner, ... , descriptor)
  340. .)l
  341. The ``descriptor'' field contains queries
  342. to retrieve the appropriate
  343. tuples from the ATTRIBUTE relation and the current tuple from the 
  344. RELATION relation.  
  345. These queries are surrounded by code in a general purpose programming
  346. language to build the actual descriptor in the format desired by the run
  347. time system.
  348. .pp
  349. In Section 6 we will discuss a technique that allows the value
  350. for a procedural field to be cached in the field itself.  If this
  351. is accomplished, then the N accesses to the ATTRIBUTE relation
  352. are avoided, and the descriptor can be accessed directly from the
  353. RELATION relation.
  354. Writes to 
  355. tuples in the ATTRIBUTE relation
  356. which make up an object (an infrequent event) will cause
  357. the cached value to be invalidated as explained in Section 6.
  358. The next time a relation is opened, the contents of the cached
  359. value must be reassembled.
  360. .pp
  361. Alternate implementations of complex objects (e.g. [COPE84]) store
  362. subobjects as individual records.  Hence, pointers must 
  363. be followed to assemble
  364. a composite object.  Sophisticated clustering will be required to
  365. avoid extra disk reads in this environment.  Moreover, if subobjects
  366. are shared, 
  367. it
  368. will be impossible to guarantee clustering.  Our caching implementation
  369. should offer superior performance to one based on pointers
  370. when updates are infrequent.
  371. It should be noted, however, that our caching idea can be applied to
  372. any DBMS to improve performance.  Hence, a pointer based
  373. DBMS that also implemented
  374. caching might be an attractive alternative.
  375. .pp
  376. We now turn to a special case of procedural data types
  377. and indicate 
  378. its utility.
  379. .sh 2  "Referential Integrity"
  380. .pp
  381. Consider the standard EMP and DEPT example as follows:
  382. .(l
  383. EMP (name, age, salary, dept)
  384. DEPT (dname, floor, budget)
  385. .)l
  386. Here, one often wants to guarantee that the values that occur in the
  387. column ``dept'' of EMP are a subset of the values that occur in 
  388. the field ``dname'' in DEPT.  This concept has been 
  389. termed 
  390. .b referential 
  391. .b integrity 
  392. in
  393. [DATE81] and occurs because ``dept'' is, in effect, a pointer to a tuple
  394. in DEPT and is represented by a foreign key.  
  395. .pp
  396. Procedural data can alleviate the need for special case syntax
  397. and implementation code to support referential integrity
  398. in the following way.  Suppose
  399. the ``dept'' field for each employee in the EMP relation
  400. contains the following procedure:
  401. .(l
  402. retrieve (DEPT.all) where DEPT.dname = ``the-appropriate-dept''
  403. .)l
  404. In this case the following semantics are automatically enforced.
  405. Whenever, an
  406. employee is hired and assigned to a non-existent department, then the
  407. procedure in the ``dept'' field evaluates to null, and the employee
  408. is effectively placed in the
  409. null department.  Moreover, whenever a department is deleted from the
  410. DEPT relation, then all employees who were previously in that department
  411. now have a procedural field which evaluates to null and are thereby placed
  412. in the null department.  Although [DATE81] has
  413. several other options, procedural data captures the main thrust of that
  414. proposal.
  415. .pp
  416. Notice that all fields in the ``dept'' column have the same basic query 
  417. as their value, differing only in the constant used in the qualification.
  418. Consider an
  419. implementation of this special case whereby the parameterized
  420. command(s) is stored in the system catalogs and only the 
  421. parameter(s) stored in the field itself.  
  422. Hence, in the example above, only the
  423. department name of the employee's department would appear in the
  424. field ``dept'', while the remainder of the query:
  425. .(l
  426. retrieve (DEPT.all) where DEPT.dname = parameter-1
  427. .)l
  428. would appear in the system catalogs. 
  429. Moreover, an update to the ``dept'' field would only need to
  430. specify the parameter and not the entire query, e.g:
  431. .(l
  432. append to EMP (name = ``Joe'', age = 25, salary = 10000, dept = ``shoe'')
  433. .)l
  434. .pp
  435. To specify this special case syntactically, one 
  436. could proceed in two steps.  First,
  437. one could 
  438. .b register
  439. the procedure containing the parameter(s) with the data manager and give it
  440. some internal name, say DEPARTMENT, with the following command:
  441. .(l
  442. define DEPARTMENT as retrieve (DEPT.all) where DEPT.dname = parameter-1
  443. .)l
  444. Then, one
  445. could create the EMP relation as:
  446. .(l
  447. create EMP (name = c10, age = i4, salary = f8, dept = DEPARTMENT)
  448. .)l
  449. Alternatively, one could avoid the registration step for commonly
  450. used procedures such as the one above by accepting the following syntax:
  451. .(l
  452. create EMP (name = c10, age = i4, salary = f8, dept = DEPT[dname])
  453. .)l
  454. The syntactic token DEPT[dname] signifies that the  
  455. procedure
  456. .(l
  457. retrieve (DEPT.all) where DEPT.dname = parameter-1
  458. .)l
  459. should be automatically defined and associated with the ``dept'' field.
  460. .pp
  461. The data type ``pointer to a tuple'' suggested in [POWE83, ZANI83]
  462. can be effectively supported by another special case.  Suppose each
  463. relation automatically contains a unique identifier (UID), a feature
  464. commonly requested in some environments.  Moreover, suppose 
  465. in the syntax:
  466. .(l
  467. create EMP (name = c10, age = i4, salary = f8, dept = DEPT)
  468. .)l
  469. the DEPT token is automatically associated with the query:
  470. .(l
  471. retrieve (DEPT.all) where DEPT.UID = parameter-1
  472. .)l
  473. In this way procedures can be used to support the capability that a
  474. field in one relation can be a uniquely identified tuple in another
  475. relation. 
  476. .sh 2  "Aggregation and Generalization"
  477. .pp
  478. Procedural fields can support both generalization and
  479. aggregation as proposed in [SMIT77].  
  480. For example, consider:
  481. .(l
  482. PEOPLE (name, phone#)
  483. .)l
  484. where phone# is 
  485. of type procedure and is an aggregate for the more detailed
  486. values area-code, exchange and number. As such, the following parameterized
  487. procedure can be used for the phone# field:
  488. .(l
  489. retrieve (area-code = parameter-1, exchange = parameter-2, number = parameter-3)
  490. .)l
  491. A simple append to PEOPLE  might be:
  492. .(l
  493. append to PEOPLE (name = ``Fred'', phone# = ``415-841-3461'')
  494. .)l
  495. Here, ``-'' is the assumed separator between the values of the three parameters.
  496. .pp
  497. Generalization is also easy to support.  If all employees 
  498. have exactly one hobby, then the hobbies field in the example EMP 
  499. relation from Section 2.1 will specify a simple generalization hierarchy.  In fact,
  500. our example use of hobbies 
  501. supports a generalization hierarchy with members
  502. which can be in several of the subcategories at once.
  503. .sh 2  "Summary"
  504. .pp
  505. In summary, data base procedures are a high leverage construct.
  506. Not only can they be used to simulate a variety of semantic
  507. data modelling ideas such as generalization and aggregation, but also
  508. they can be used to support objects that have unpredictable composition 
  509. and shared subobjects.  In addition, they are useful in simplifying the
  510. design of current relational systems by allowing a more uniform treatment of
  511. compiled queries and views.  Lastly, support for procedures written in an arbitrary
  512. programming language is a natural and valuable extension, and a 
  513. preliminary proposal in this direction appears in [STON86].  Hence, a single
  514. construct is useful in a wide variety of circumstances.
  515. .sh 1 "THE QUERY LANGUAGE, QUEL+"
  516. .pp
  517. In order to make procedures a useful construct, several extensions 
  518. must be made to QUEL and these are indicated in the next several
  519. subsections.  This language, QUEL+, contains slight modifications to
  520. the facilities proposed in [STON84], and a concise summary of its 
  521. extensions to QUEL appears in Appendix 1. 
  522. .sh 2 "Execution of the Data"
  523. .pp
  524. A procedural field can be interpreted in two ways, namely it has
  525. .b definition
  526. which is the QUEL code in the field
  527. and a
  528. .b value
  529. which is obtained by executing the QUEL commands.
  530. Since a user needs to gain access to both representations, we use the
  531. convention that a normal retrieval returns the definition.  For example, the
  532. query:
  533. .(l
  534. retrieve (EMP.hobbies) where EMP.name = ``Smith''
  535. .)l
  536. will return a collection of QUEL commands.  Execution of a procedural
  537. field is accomplished by an additional 
  538. QUEL+
  539. command which allows one to execute data in the
  540. data base. 
  541. For example, one
  542. can find all the hobby data for Smith 
  543. by running the
  544. following command:
  545. .(l
  546. execute (EMP.hobbies) where EMP.name = ``Smith''
  547. .)l
  548. This command will search for qualifying tuples 
  549. and then execute the contents of
  550. the hobbies field.
  551. .pp
  552. Two points should be noted about the above command.  First,
  553. notice that a user program must be prepared to accept the
  554. tuples returned from the above query.  
  555. Since the composition of these tuples may vary
  556. from tuple to tuple,  
  557. the run time system must send output to an application
  558. program using a more complex format than often used currently.  In
  559. particular, each tuple must either be self-describing
  560. or a tuple descriptor must be sent to the application which 
  561. describes all subsequent tuples until a new descriptor is sent.
  562. Run time support code in the application program must be prepared
  563. to accept this more complex format and deal with the more complex
  564. buffering and communication with variables in an 
  565. application program that
  566. this entails.
  567. Second,
  568. a user must note which fields contain procedural data,
  569. since retrieving a procedural field does not yield the ultimate data value.
  570. We considered
  571. automatic evaluation of procedural fields, but this option requires
  572. a second operator to ``unevaluate'' the procedure and seemed no more
  573. user-friendly.
  574. Also, it would have required the application program to accept
  575. unnormalized relations.  For example, automatic evaluation
  576. of procedural fields for the query:
  577. .(l
  578. retrieve (EMP.name, EMP.hobbies) where EMP.age > 35
  579. .)l
  580. would yield an unnormalized relation as a result.
  581. .pp
  582. In some applications, it is desirable to execute only one 
  583. of a collection of qualifying tuples.  The following command
  584. will execute the hobby description for one
  585. employee over 70. 
  586. .(l
  587. execute-one (EMP.hobbies) where EMP.age > 70
  588. .)l
  589. The intent of this command is that query processing heuristics along the lines
  590. of [SELI79] would be run on each candidate hobby description.  The 
  591. one with the expected least cost would be selected for execution.
  592. The
  593. use of this construct in a particular expert system 
  594. application is discussed in [KUNG84].
  595. .sh 2  "Multiple-Dot Notation"
  596. .pp
  597. Our second extension to QUEL allows the 
  598. components of a complex object to be addressed directly.
  599. For example, one could retrieve the batting average of Smith as follows:
  600. .(l
  601. retrieve (EMP.hobbies.average) where EMP.name = ``Smith'' 
  602. .)l
  603. This 
  604. .b multiple-dot 
  605. notation has many points in common with the data manipulation
  606. language GEM [ZANI83],
  607. and allows one to conveniently access subsets of components
  608. of complex objects.
  609. More exactly, QUEL+ allows an indirectly referenced column name
  610. of the form: 
  611. .(l
  612. relation.column-name-1.column-name-2 ... column-name-n 
  613. .)l
  614. wherever 
  615. a normal column name:
  616. .(l
  617. relation.column-name
  618. .)l
  619. is allowed in QUEL.  The only restriction
  620. is that ``column-name-i'' must be a procedural data type
  621. for 1 <= i < n-1.  Moreover,
  622. column-name-(i+1) is a column
  623. in any relation specified by a RETRIEVE 
  624. command contained in the field specified by
  625. column-name-i.
  626. Of course, the same construct is allowed for relation surrogates 
  627. (tuple variables).
  628. .pp
  629. The above QUEL+ command returns the average of Smith for any hobby
  630. that has a field with name ``average''.  Since there may be
  631. several hobbies with this field defined, one requires a notation
  632. to restrict the average only to the SOFTBALL relation.  This is
  633. easily accomplished with another operator, i.e:
  634. .(l
  635. retrieve (EMP.hobbies.average)
  636. where EMP.name = ``Smith'' 
  637. and EMP.hobbies.average in SOFTBALL
  638. .)l
  639. Here ``in'' expects an indirectly referenced
  640. column name as the left operand and a relation name as
  641. the right operand and returns true only if the column is in the 
  642. indicated relation.
  643. Additional operators associated with procedural objects may be appropriate 
  644. and will be added to QUEL+ as a need arises.
  645. .sh 2  "Extended Scoping"
  646. .pp
  647. To change the position of Smith from catcher to outfield,
  648. one could make a direct
  649. update to the SOFTBALL relation.  However, it is sometimes 
  650. cleaner to allow the update to be made through the EMP
  651. relation as follows:
  652. .(l
  653. replace EMP.hobbies (position = ``outfield'') where EMP.name = ``Smith''
  654. .)l
  655. The desired construct is that a procedural field (in this
  656. case EMP.hobbies) can appear as the target of a 
  657. DELETE, REPLACE or APPEND command.
  658. In general, this procedural field is identified by an arbitrary multiple-dot
  659. expression of the form discussed in the previous section, and we term
  660. this expression the
  661. .b scope
  662. of the update.
  663. .pp
  664. The semantics of an 
  665. .b extended
  666. .b scope
  667. command
  668. are that the RETRIEVE commands in
  669. the procedural field used as the target of the update command
  670. define conventional
  671. relational views.  
  672. Once a specific instance of such a procedural field has been identified,
  673. for each view, Vi, associated with a RETRIEVE command, Ri, one need
  674. only replace the 
  675. the update scope by Vi 
  676. in every place it appears in the user command, and then  
  677. standard query modification [STON75] using Ri should
  678. be performed on the qualification and the target list of the
  679. resulting user's command.
  680. .pp
  681. For example, if Smith's ``EMP.hobbies'' field contains the single
  682. query:
  683. .(l
  684. retrieve (SOFTBALL.all) where SOFTBALL.name = ``Smith''
  685. .)l
  686. then the above command to move Smith to the outfield will have the form
  687. .(l
  688. replace EMP.hobbies (position = ``outfield'')
  689. .)l
  690. once the clause
  691. .(l
  692. where EMP.name = ``Smith''
  693. .)l
  694. has been evaluated to identify a specific ``EMP.hobbies'' value.
  695. Hence, this query is turned into:
  696. .(l
  697. replace V1 (position = ``outfield'')
  698. .)l
  699. and then query modification converts it to:
  700. .(l
  701. replace SOFTBALL (position = ``outfield'') where SOFTBALL.name = ``Smith''
  702. .)l
  703. .pp
  704. Notice that this construct allows a very simple means for supporting relational
  705. views.  If the definition of each view appears in the VIEW relation as suggested
  706. in the previous section, e.g:
  707. .(l
  708. VIEW (name, query)
  709. .)l
  710. then any command involving a view, V, need only be modified to replace every
  711. reference to V with VIEW.query and then the clause
  712. .(l
  713. VIEW.name = V
  714. .)l
  715. must be added to the qualification.  The resulting command will be one
  716. containing multiple-dot clauses and extended scoping statements and
  717. can be executed
  718. as a conventional QUEL+ command.
  719. .sh 2  "Extended Scoping with Tuple Variables"
  720. .pp
  721. In addition to allowing the above construct, QUEL+ also allows
  722. a tuple variable to be used whenever a relation name or a field
  723. of type QUEL is permissible.
  724. Hence, the example above can also be expressed as:
  725. .(l
  726. range of e is EMP.hobbies
  727. replace e (position = ``outfield'') where EMP.name = ``Smith''
  728. .)l
  729. .sh 2 "Relation Level Operators"
  730. .pp
  731. In addition, QUEL+ supports relation level operators, including
  732. union, intersection, outer join, natural join, containment and a test
  733. for emptiness.
  734. We illustrate the use of this construct with an example from the
  735. previous section where objects were made up of lines, polygons, and
  736. text fragments.
  737. In this situation, one might want to find
  738. all pairs of objects, one of which
  739. contains all 
  740. the shapes in the other.  This would be formulated as:
  741. .(l
  742. range of o is OBJECT
  743. range of o1 is OBJECT
  744. retrieve (o.Oid, o1.Oid) where o.shape >> o1.shape
  745. .)l
  746. Here, the containment operator >>, accepts two procedural operands
  747. and returns true if the relation specified by the
  748. procedure in the left operand includes the relation specified by the
  749. procedure in the right operand.
  750. The relation on the left is found by
  751. constructing the outer union defined by the
  752. RETRIEVE 
  753. commands in o.shape.  
  754. If all commands have identical target lists, then the outer union is
  755. the same as a normal union.  Otherwise, it is formed by constructing a
  756. relation with all columns appearing in any command, filling each
  757. target list with nulls to be the full width of the composite relation, and
  758. then performing a normal union.
  759. This resulting relation must be
  760. compared for set inclusion with the relation to which
  761. o1.shape
  762. evaluates.
  763. Our initial collection of operators is indicated in Table 1.
  764. .(z
  765. .(c
  766. .TS
  767. |c|c|
  768. |l|l|.
  769. Operator    Function
  770. _    _
  771. U    union
  772. !!    intersection
  773. >>    containment
  774. <<    containment
  775. ==    equality
  776. <>    inequality
  777. JJ    natural join on all common column names
  778. OJ    outer (natural) join
  779. empty    emptyness
  780. _    _
  781. .TE
  782. .)c
  783.  
  784. .ce 
  785. Relation Level Operators
  786.  
  787. .ce
  788. Table 1
  789. .)z
  790. .sh 1 "PROCESSING QUEL+"
  791. .pp
  792. The purpose of this section is to explain how our existing
  793. prototype executes QUEL+ commands.
  794. This prototype supports the complete language noted in the previous section
  795. with the exception of execute-one and extended scoping statements.
  796. Moreover, it only implements general QUEL procedural fields.  The 
  797. optimization routines to support the special case that all queries in a 
  798. given column differ only by a collection of parameters have not yet
  799. been implemented.
  800. .pp
  801. Although more sophisticated
  802. query processing algorithms have been constructed [SELI79, KOOI82],
  803. our implementation 
  804. builds on the original INGRES strategy [WONG76].  The implementation
  805. of QUEL+ has been accomplished using this code because it
  806. is readily available for experimentation.
  807. Integration of our constructs into more advanced optimizers
  808. appears straightforward, and we discuss this point again at
  809. the end of this section.
  810. .pp
  811. Figure 1 shows a diagram of the extended decomposition process.
  812. .(z
  813. .hl
  814. .nf
  815. |-----------------  
  816. |                      | 
  817. |                     V
  818. |        -------------------------------            
  819. |        | extract and process one  | 
  820. |        | variable clauses which    |
  821. |        | do not contain relation   |
  822. |        | level or multiple-dot      |
  823. |        | operators                     |
  824. |        -------------------------------        
  825. |                      |                                         
  826. |                     V                                         
  827. |        ----------------------- 
  828. |        | apply reduction |
  829. |        |  algorithm        |
  830. |        -----------------------            
  831. |                      |                                        
  832. |                     V                                         
  833. |        ---------------------------                 ---------------------------
  834. |        | is the qualification   |    yes         | are there relations   |
  835. |        | free of variables?      |----------->| to materialize?        |
  836. |        ---------------------------                 ---------------------------
  837. |                 no |                                       yes |           | no
  838. |                     |                            -------------|           |
  839. |                     |                            |                            |
  840. |                    V                          V                          V
  841. |        ---------------------         -----------------          ----------------------
  842. |        |  do tuple       |           | materialize a |           | pass to extended     |
  843. |        | substitution   |           | relation        |           | OVQP for relation  |
  844. |        ---------------------         -----------------          | level operator        |
  845. |                     |                           |                        | evaluation             |
  846. |                     |                           |                         --------------------
  847. |                     |                           |                                |
  848. |                    V                         V                              V
  849. ----------------------------------------------------------------------------------
  850.  
  851. .ce
  852. Extended Decomposition
  853.  
  854. .ce
  855. Figure 1
  856. .fi
  857. .hl
  858. .)z
  859. Detachment of one-variable queries that do not
  860. contain multiple-dot or relation level
  861. operators can proceed as in the original
  862. INGRES algorithms [WONG76].  Similarly, the reduction module of decomposition
  863. is unaffected by our extensions to QUEL. 
  864. In addition, tuple substitution is performed when all 
  865. other processing steps fail.
  866. A glance at the left hand column of Figure 1 indicates that a test
  867. for zero variables must be inserted into the original flow of control
  868. after the reduction module.  Then, new facilities must be included 
  869. to process the ``yes'' branch of the test.  These include a test 
  870. for whether there is a relation to materialize and
  871. the code to perform this step. 
  872. Lastly, 
  873. the one-variable query 
  874. processor must be extended to process relation level operators.  We
  875. explain these extensions with a detailed example.
  876. .pp
  877. The desired task is to find the polygon descriptions
  878. with identifiers less than 5 for all objects which have the 
  879. same collection of shapes as the 
  880. complex object with Oid equal to 10, 
  881. i.e:
  882. .(l
  883. range of o is OBJECT
  884. range of o1 is OBJECT
  885. retrieve (o.shape.p-desc) 
  886. where o.shape.Pid < 5
  887. and o.shape == o1.shape
  888. and o1.Oid = 10
  889. .)l
  890. In the initial step of the reduction process 
  891. the last clause in the query is found to have a single variable, so
  892. it can be executed as:
  893. .(l
  894. retrieve into TEMP-1 (o1.shape) where o1.Oid = 10
  895. .)l
  896. The original query is now:
  897. .(l
  898. retrieve (o.shape.p-desc) where o.shape.Pid < 5 and o.shape == TEMP-1.shape 
  899. .)l
  900. The first clause above contains a multiple-dot attribute and should
  901. not be processed until later.
  902. At this point reduction fails and the query still has two
  903. variables in it, so processing falls through to the tuple 
  904. substitution module.  If TEMP-1 is selected for substitution, the 
  905. resulting query is:
  906. .(l
  907. retrieve (o.shape.p-desc) 
  908. where o.shape.Pid < 5 
  909. and o.shape == ``QUEL-constant-1'' 
  910. .)l
  911. Notice that the variable ``TEMP-1.shape'' has been replaced by a
  912. constant ``QUEL-constant-1'' which is a collection of QUEL commands.
  913. Processing now returns to the top of the loop where the query
  914. still does not have any one-variable clauses.  Processing again returns
  915. to tuple substitution where the variable o might be chosen.  This
  916. results in the query:
  917. .(l
  918. retrieve (``QUEL-constant-2''.p-desc) 
  919. where ``QUEL-constant-2''.Pid < 5
  920. and ``QUEL-constant-3'' == ``QUEL-constant-1''
  921. .)l
  922. Notice that o.shape has been replaced by two constants ``QUEL-constant-2''
  923. and ``QUEL-constant-3'' which are identical.  When o.shape 
  924. is materialized, there will be a one-relation clause (o.shape.Pid < 5)
  925. that
  926. can be used to restrict and project the relation.
  927. Moreover, it is desirable to check this clause as early as possible
  928. because the current query will have no answer if this clause is false.
  929. On the other hand, o.shape must be retained as a complete object
  930. so that the 
  931. the relation level comparison with QUEL-constant-1 can be performed
  932. if necessary.  In order to avoid forcing the relation level operator
  933. to be executed first, we have duplicated the QUEL constant and 
  934. thereby retained the option of 
  935. performing the one-variable restriction first.
  936. Even though QUEL-constant-2 and QUEL-constant-3 define the same object,
  937. the caching discussed in Section 6
  938. should avoid materializing this object more than
  939. once.
  940. .pp
  941. Now the command has zero variables and is passed to the 
  942. materialize module.  This processing step chooses one of the 
  943. QUEL constants and materializes the outer-union of the RETRIEVE
  944. commands into a relation TEMP-2.  If ``QUEL-constant-2''
  945. is chosen, then the resulting query will be:
  946. .(l
  947. retrieve (TEMP-2.p-desc) where
  948. TEMP-2.Pid < 5
  949. and ``QUEL-constant-3'' == ``QUEL-constant-1''
  950. .)l
  951. This query now has a one-variable clause which can be
  952. detached and processed creating another temporary
  953. relation TEMP-3.
  954. If TEMP-3 is empty then
  955. the query is false and
  956. can be terminated.  Alternately, processing must
  957. continue on the following command:
  958. .(l
  959. retrieve (TEMP-3.p-desc) where ``QUEL-constant-3'' == ``QUEL-constant-1''
  960. .)l
  961. The qualification is again free from variables, so another relation
  962. must be materialized.  If ``QUEL-constant-1'' is chosen, we obtain:
  963. .(l
  964. retrieve (TEMP-3.p-desc) where ``QUEL-constant-3'' == TEMP-4
  965. .)l
  966. The qualification is still free from variables, so the final
  967. relation must be materialized as follows:
  968. .(l
  969. retrieve (TEMP-3.p-desc) where TEMP-5 == TEMP-4 
  970. .)l
  971. After another trip around the processing loop, no further materialization is
  972. possible.  Hence, the query must now be passed to the one-variable query
  973. processor.  This module will process the operator == for the two
  974. relations involved.
  975. .pp
  976. Several comments are appropriate at this time.  First, this algorithm delays
  977. materializing a relation until there is no conventional
  978. processing to do.  In addition, it delays evaluating relation
  979. level operators until there is nothing else to do.  This reflects
  980. our belief that expensive operations should never be done until
  981. absolutely necessary.  
  982. The current prototype only materializes a procedural 
  983. field if the desired columns
  984. actually appear in the result.  This tactic avoids 
  985. obviously unnecessary materializations.
  986. However, no attempt has been made to materialize only a subset of a procedural
  987. object by using qualification in the user command to advantage.  For
  988. example, only the tuples where Pid < 5 could have been materialized
  989. from the query in ``QUEL-constant-2'' by modifying the qualification. Such 
  990. restricted materializations would not allow the caching that we have in 
  991. mind, and we did not consider them.  A more sophisticated query planner
  992. would try to optimize the decision of
  993. whether to materialize the value of the whole procedural object
  994. or a qualified subset. 
  995. .pp
  996. Second, most current optimizers build a complete query plan in advance
  997. of executing the command.  Such optimizers (e.g. [SELI79, KOOI82]) can
  998. construct a plan for the portion of the query without nested dot constructs.
  999. However, run-time planning will be required on remaining portions
  1000. of commands.
  1001. For example,
  1002. the following query must be processed by tuple substitution
  1003. for o or o1.  
  1004. .(l
  1005. retrieve (o.shape.p-desc, o1.shape.p-desc) where o.shape.l-desc = o1.shape.l-desc
  1006. .)l
  1007. After substitution twice, the remaining query is:
  1008. .(l
  1009. retrieve (TEMP-1.p-desc, TEMP-2.p-desc) where TEMP-1.l-desc = TEMP-2.l-desc
  1010. .)l
  1011. The characteristics of TEMP-1 and TEMP-2 are not known until
  1012. run time, so further query planning must be deferred to 
  1013. this time.
  1014. .pp
  1015. The only exception to run time planning would occur if all values
  1016. in a procedural column contain the same query as discussed in Section 2.
  1017. In this situation, a view translation 
  1018. algorithm can be run on the initial user
  1019. command instead of applying the algorithm of this section.
  1020. The algorithm is similar to the one presented in [STON75]
  1021. and would translate a multiple-dot query 
  1022. into a conventional query which can be optimized in the
  1023. conventional fashion.
  1024. This ``flattening'' of a query
  1025. will allow a compile time plan to be built and additionally
  1026. will support a wide range of query processing alternatives to
  1027. be explored, rather than just the ``outside-to-inside'' strategy
  1028. discussed in this section.
  1029. The details of this algorithm
  1030. are straight-forward and are omitted for the sake of brevity.
  1031. .pp
  1032. Lastly, in our prototype
  1033. the module that materializes a relation passes the RETRIEVE commands
  1034. to another process which also runs the INGRES+ code.  This second
  1035. INGRES+ executes the command, stores the resulting
  1036. relation in the data base, and then passes control back to the
  1037. first INGRES+.  A second process is required because the INGRES
  1038. code will not allow a command to 
  1039. suspend in the middle of the decomposition process so that 
  1040. a new command can be executed.  The ability to ``stack'' the 
  1041. execution state of a query would be a very desirable addition
  1042. to the system.
  1043. .sh 1  "BENCHMARK RESULTS"
  1044. .pp
  1045. It would be clearly desirable to compare the performance of
  1046. INGRES+ against various other approaches to object management.  These
  1047. could include using a conventional relational system
  1048. as well as prototypes with other capabilities
  1049. (e.g. [COPE84, LORI83]).
  1050. Only a conventional relational system was easily available in
  1051. our environment as a test case.  Hence,
  1052. a more detailed performance study is left as a future exercise 
  1053. and would require the acquisition of appropriate hardware to run other
  1054. prototypes.
  1055. .pp
  1056. In this section we describe a collection of benchmarks
  1057. which we performed on our prototype.
  1058. We modeled three different tasks using QUEL+ and then compared
  1059. them to a conventional relational system, namely INGRES [STON76].
  1060. In all cases
  1061. we chose tasks which would result in different
  1062. queries in the two systems.
  1063. Running the same command in both systems would clearly result in equal
  1064. performance.
  1065. In all tests recovery and concurrency control 
  1066. has been turned off, and CPU time and total elapsed time
  1067. in a single user environment were tabulated.
  1068. For
  1069. convenience, INGRES numbers are normalized to 1 while INGRES+ 
  1070. numbers are given as a multiple of the corresponding 
  1071. INGRES result.  All 
  1072. tests are run on a single-user VAX 11/780.
  1073. .pp
  1074. Both systems contain substantial inefficiencies (e.g. run-time optimization,
  1075. generation of an excessive number of temporary relations).  However,
  1076. it appears that such problems penalize both systems about equally.
  1077. Only three issues excessively penalize INGRES+.  First, the 
  1078. unnecessary communication with a second INGRES+ task adds unnecessary
  1079. overhead that could be eliminated in a commercial implementation.
  1080. Second, in many cases INGRES will be seen to execute a single
  1081. two-variable query while INGRES+ runs a larger number of one-variable
  1082. commands.  Run time query planning of a larger number of commands
  1083. imposes an excessive penalty on INGRES+.  
  1084. Lastly, the flattening of parameterized procedural fields has not
  1085. yet been implemented in INGRES+.  Consequently, execution of muliple-dot
  1086. queries is constrained by the structure of the query, and
  1087. an inefficient plan may be executed as a result.
  1088. Hence, a compiled query implementation of QUEL+ which included parameterized
  1089. procedual fields 
  1090. should yield results similar to or more
  1091. favorable toward INGRES+ than those we present.
  1092. .pp
  1093. The three experiments are discussed in the following 
  1094. subsections.
  1095. .sh 2  "Simulation of Simple Complex Objects"
  1096. .pp
  1097. This experiment involves accessing simple variant records
  1098. corresponding to hobbies in the EMP relation of Section 2.  Each of 7000 
  1099. employees has 
  1100. a collection of hobbies.
  1101. From a total of 50 possible hobbies, each employee practices
  1102. between one and eight.
  1103. .pp
  1104. Both an INGRES and an INGRES+ data base must store records on
  1105. each of the 50 hobbies in relations:
  1106. .(l
  1107. SOFTBALL (emp-name, other data)
  1108. SAILING   (emp-name, other data)
  1109. JOGGING  (emp-name, other data)
  1110.  .
  1111.  .
  1112.  .
  1113. .)l
  1114. A normal DBMS would store in addition the relations:
  1115. .(l
  1116. EMP(name, age, salary)
  1117. HOBBIES(emp-name, hobby-name)
  1118. .)l
  1119. while an INGRES+ data base would only require a single relation:
  1120. .(l
  1121. EMP(name, age, salary, hobbies)
  1122. .)l
  1123. The field ``hobbies'' has a collection of queries, one per
  1124. hobby as noted in Section 2.
  1125. .pp
  1126. The task is to find the information
  1127. on all hobbies
  1128. for a given employee and is expressed in INGRES+ as follows:
  1129. .(l
  1130.        execute (EMP.hobbies) where EMP.name = ``unique-emp''
  1131. .)l
  1132. A normal DBMS query language cannot express
  1133. this task, and the most reasonable option is to execute the
  1134. following algorithm.
  1135. .(l
  1136.        retrieve (HOBBIES.hobby-name) where HOBBIES.emp-name = ``unique-emp''
  1137.        for each such hobby-name do
  1138.            retrieve (hobby-name.all) where hobby-name.emp-name = ``unique-emp''
  1139.        end-do
  1140. .)l
  1141. Table 2 indicates a performance comparison for
  1142. various numbers of hobbies per employee.  The INGRES+ numbers result from
  1143. running the above execute command while the INGRES number were obtained
  1144. using the terminal monitor to
  1145. retrieve the hobbies for a given employee and then
  1146. executing the appropriate number of retrieve commands to obtain
  1147. hobby data.  This would simulate a user who ran a query to
  1148. obtain the collection of hobbies and then ran the correct collection
  1149. of queries on the various hobbies relations.
  1150. Notice that the INGRES+ option is superior except when there
  1151. is a single hobby per employee.
  1152. This performance difference results from the fact that a large
  1153. number of queries are passed
  1154. through the INGRES terminal monitor,
  1155. which has noticeable 
  1156. overhead.  The INGRES+ solution runs the same collection of queries,
  1157. but the hobby queries are generated internally by the system and
  1158. do not go through a terminal monitor.
  1159. .(z
  1160. .hl
  1161. .(c
  1162. .TS
  1163. l|l|l|l|l
  1164. l|l|l|l|l
  1165. l|n|n|n|n.
  1166. Query    INGRES-CPU    INGRES+-CPU    INGRES-total    INGRES+-total    
  1167. _    _    _    _    _
  1168. one-hobby    1    1.23    1    1.28
  1169. four-hobby    1    .73    1    .61
  1170. eight-hobby    1    .59    1    .61
  1171. .TE
  1172. .)c
  1173.  
  1174. .ce
  1175. A Benchmark of Simple Complex Objects
  1176.  
  1177. .ce
  1178. Table 2
  1179. .hl
  1180. .)z
  1181. .sh 2  "Simulation of More Complex Objects With Shared Subobjects"
  1182. .pp
  1183. Consider the example from Section 2 where complex objects are
  1184. composed of 
  1185. lines, text and polygons.  Moreover, assume that these subobjects
  1186. must be shared among various complex objects.  
  1187. Consequently, both schemas have relations for the subobjects 
  1188. as follows:
  1189. .(l
  1190. LINE (Lid, l-desc)
  1191. TEXT (Tid, t-desc)
  1192. POLYGON (Pid, p-desc)
  1193. .)l
  1194. Then, a normal schema must have three additional relations
  1195. indicating which subobjects are in which complex objects:
  1196. .(l
  1197. T-obj  (Tid, Oid)
  1198. P-obj  (Pid, Oid)
  1199. L-obj  (Lid, Oid)
  1200. .)l
  1201. However, an INGRES+ schema needs only the single additional
  1202. relation from Section 2, namely:
  1203. .(l
  1204. OBJECT (Oid, trim, shape)
  1205. .)l
  1206. The trim field  in OBJECT is a collection of queries of the form:
  1207. .(l
  1208. retrieve (TEXT.all) where TEXT.Tid = value
  1209. .)l
  1210. while the shape field has a collection of queries of the form:
  1211. .(l
  1212. retrieve (LINE.all) where LINE.Lid = value
  1213. retrieve (POLYGON.all) where POLYGON.Pid = value
  1214. .)l
  1215. .pp
  1216. The benchmark query is to find 
  1217. the shapes of a particular complex object, e.g:
  1218. .(l
  1219. retrieve (POLYGON.all) 
  1220. where POLYGON.Pid = P-obj.Pid 
  1221. and P-obj.Oid = ``unique-value''
  1222.  
  1223. retrieve (LINE.all)
  1224. where LINE.Lid = L-obj.Lid
  1225. and L-obj.Oid = ``unique-value''
  1226. .)l
  1227. The QUEL+ query is simply:
  1228. .(l
  1229. execute (OBJECT.shapes) where OBJECT.Oid = ``unique-value''
  1230. .)l
  1231. .pp
  1232. The INGRES+ prototype limits the length of procedural fields to 255
  1233. bytes (about 9 queries); hence, multiple rows are required
  1234. to express an object with a larger number of subobjects.  This
  1235. limitation affects INGRES+ performance marginally.
  1236. The costs of the two systems for objects
  1237. having respectively
  1238. 1, 4, 8, 16 and 32 subobjects is shown in Table 3.
  1239. .(z
  1240. .hl
  1241. .(c
  1242. .TS
  1243. l|l|l|l|l
  1244. l|l|l|l|l
  1245. l|n|n|n|n.
  1246. Query    INGRES-CPU    INGRES+-CPU    INGRES-total    INGRES+-total    
  1247. _    _    _    _    _
  1248. Q1    1    .54    1    .67
  1249. Q4    1    .75    1    .78
  1250. Q8    1    .99    1    1.0
  1251. Q16    1    1.35    1    1.44
  1252. Q32    1    2.17    1    2.94
  1253. .TE
  1254. .)c
  1255.  
  1256. .ce
  1257. Benchmarks of Complex Objects
  1258.  
  1259. .ce
  1260. Table 3
  1261. .hl
  1262. .)z
  1263. INGRES must run 2 two-variable
  1264. queries while INGRES+ runs a single query on the OBJECT relation
  1265. followed by a one-relation query per subobject.   
  1266. If there is only one subobject, it is clear that INGRES+ will run 2 
  1267. one-variable queries and have better performance than INGRES.  This
  1268. performance advantage deteriorates until there are 16 subobjects
  1269. at which point
  1270. 17 one-variable queries take more time than 2 two-variable queries.
  1271. In a commercial implementation, two-variables queries would be better
  1272. optimized and the crossover point might occur at a lower number of
  1273. subobjects.  On the other hand, run-time optimization of 17 commands
  1274. in INGRES+ is a serious source of overhead which would not be 
  1275. present in a commercial system.  Hence, it is not clear how Table 3 
  1276. would look in a commercial environment.
  1277. .sh 2  "Simulation of Unnormalized Relations"
  1278. .pp
  1279. Although QUEL+ is most useful when applied to applications with 
  1280. complex structure, it is also possible to provide multiple-dot
  1281. addressing on conventional data.  This will allow
  1282. a more natural query formulation 
  1283. compared to conventional techniques; however,  
  1284. much of the same effect can be alternately achieved using relational views.
  1285. This section is included to demonstrate that QUEL+ provides
  1286. reasonable performance even in ordinary situations.
  1287. .pp
  1288. The normal way to store data for the standard 
  1289. EMP, DEPT and JOB data base is:
  1290. .(l
  1291. EMP (name, age, salary, dept, jid)
  1292. DEPT(dname, floor)
  1293. JOB (jid, jname, benefits)
  1294. .)l
  1295. Here, employees have a name, an age, a salary, are in a 
  1296. department, and have a job identifier.  The other two relations
  1297. are self-evident.  We assume that there are 7000 employees, 500
  1298. departments and 50 job descriptions.  Moreover, EMP tuples are
  1299. 32 bytes wide, DEPT tuples are 14, and JOB tuples are 24.
  1300. .pp
  1301. On the other hand, in INGRES+ one can use an alternate schema
  1302. as follows:
  1303. .(l
  1304. EMP (name, age, salary, dept, j-emp)
  1305. DEPT(dname, floor, d-emp)
  1306. JOB (jid, jname, benefits)
  1307. .)l
  1308. Here, j-emp is a procedural field of the form:
  1309. .(l
  1310. retrieve (JOB.all) where JOB.jid = ``value-for-this-employee''
  1311. .)l
  1312. In addition, d-emp is a procedural field of the form:
  1313. .(l
  1314. retrieve (EMP.all) where EMP.dept = ``this-dept''
  1315. .)l
  1316. Consequently, all the employees in a specific department are accessible
  1317. though the d-emp field while the job description of a particular
  1318. employee can be obtained through the j-emp field.
  1319. .pp
  1320. We ran the following three queries in both INGRES and INGRES+
  1321.  
  1322. Query 1:  a normal join returning a few tuples
  1323.  
  1324. The queries to run in the two systems are respectively:
  1325. .(l
  1326. retrieve (EMP.name, DEPT.floor) 
  1327. where EMP.dept = DEPT.dname
  1328. and DEPT.dname = ``unique-name''
  1329.  
  1330. retrieve (DEPT.d-emp.name, DEPT.floor) 
  1331. where DEPT.dname = ``unique-name''
  1332. .)l
  1333. In this case, we are comparing the processing speed of normal INGRES
  1334. running a two variable query with that of INGRES+ which must
  1335. execute a one-variable query and then a second one-variable subquery.
  1336.  
  1337. Query 2: the full join
  1338.  
  1339. The two queries are respectively:
  1340. .(l
  1341. retrieve (EMP.name, DEPT.floor) 
  1342. where EMP.dept = DEPT.dname
  1343.  
  1344. retrieve (DEPT.d-emp.name, DEPT.floor) 
  1345. .)l
  1346. In this case, we are computing the full join between EMP and DEPT.  The
  1347. comparison is between a single two variable query and a single one-variable
  1348. query to scan the DEPT relation along with 500 one-variable queries to
  1349. find appropriate information in EMP.  This should be a 
  1350. poor query for INGRES+ because of the run-time optimization of 500
  1351. queries.
  1352. Moreover, because of the structure of the query, INGRES+ will iterate 
  1353. over DEPT tuples and then access the EMP relation for each one.  
  1354. This may (or may not) correspond to the plan which would be
  1355. selected by a conventional optimizer using a flat representation
  1356. of the query.  If 
  1357. iterative substitution for DEPT tuples is not a wise plan, then INGRES+
  1358. will have poor performance because of the structure of the query.
  1359.  
  1360. Query 3:  a three way join to find the job of a particular employee in a particular department
  1361.  
  1362. The queries are:
  1363. .(l
  1364. retrieve (JOB.jname, EMP.name) 
  1365. where DEPT.dname = ``value-1''
  1366. and EMP.dept = dept.dname
  1367. and EMP.job  = JOB.jid
  1368. and EMP.name = ``value-2''
  1369.  
  1370. retrieve (DEPT.d-emp.j-emp.jname, DEPT.d-emp.name) 
  1371. where DEPT.dname = ``value-1''
  1372. and DEPT.d-emp.name = ``value-2''
  1373. .)l
  1374. Here, INGRES is running a single three variable query 
  1375. while INGRES+ will execute three one-variable queries.  The 
  1376. extended system should be especially attractive in this case, because
  1377. of the extra complexity required to process multivariable queries in
  1378. a conventional system.
  1379. .pp
  1380. Table 4 presents the results for these three queries.
  1381. .(l
  1382. .hl
  1383. .(c
  1384. .TS
  1385. l|l|l|l|l
  1386. l|l|l|l|l
  1387. l|n|n|n|n.
  1388. Query    INGRES-CPU    INGRES+-CPU    INGRES-total    INGRES+-total    
  1389. _    _    _    _    _
  1390. Query 1    1    1.37    1    1.15
  1391. Query 2    1    15.1    1    17.2
  1392. Query 3    1    .29    1    .36
  1393. .TE
  1394. .)c
  1395.  
  1396. .ce
  1397. Benchmarks of Unnormalized Relations
  1398.  
  1399. .ce
  1400. Table 4
  1401. .hl
  1402. .)l
  1403. As can be seen, Query 1 performs at about the same speed in both
  1404. systems.  In this case two one-variable queries are comparable to
  1405. a single two variable query.
  1406. The full join was a factor 15-17 worse in INGRES+
  1407. because the overhead of running 500 queries to retrieve EMP tuples is 
  1408. overwhelming. 
  1409. Finally, Query 3 shows that three one-variable commands are
  1410. faster by a factor of 3-4 than a single three-variable command.   
  1411. Although one would expect superior performance from INGRES+, the
  1412. magnitude is surprising and reflects the fact that the normal INGRES optimizer
  1413. is not especially good at three way joins.
  1414. .pp
  1415. The conclusion to be drawn is that INGRES+ is competitive except when
  1416. it utilizes a poor query plan or is forced to run a large number of commands.
  1417. Bad performance in the latter situation 
  1418. should be eliminated by compile time query planning.
  1419. Bad performance in the former case can be alleviated by
  1420. flattening out multiple-dot
  1421. commands when an entire column has the same query structure.
  1422. .pp
  1423. The next section turns to a suggestion to dramatically improve the performance
  1424. of procedural fields.
  1425. .sh 1 "CACHING PROCEDURAL FIELDS"
  1426. .pp
  1427. The performance of
  1428. INGRES+ may be dramatically improved by caching
  1429. frequently used objects so they will
  1430. not have to be repeatedly rematerialized.  
  1431. This section explores the use of this tactic.
  1432. .sh 2 "The Cache Model"
  1433. .pp
  1434. Caching QUEL procedures should be thought of as a two step process:
  1435. .(l
  1436. 1) compile a query plan for the command(s)  (plan caching)
  1437. 2) execute the plan   (result caching)
  1438. .)l
  1439. .pp
  1440. The first step (plan caching)
  1441. is often done at compile time in current
  1442. systems; however, in our model it should be thought of as
  1443. computing an intermediate representation of the object.  This
  1444. representation can be saved for later reuse.  Moreover, in current
  1445. systems a query plan is usually invalidated at execution time if
  1446. the schema has changed in a way that compromises the validity
  1447. of the plan.  
  1448. In our model
  1449. query plans are cached until a compromising update
  1450. forces invalidation.  One can optionally support a ``demon'' which
  1451. utilizes any idle CPU resources recompiling invalidated plans.
  1452. Alternatively, one can simply recompile when the plan is executed,
  1453. as in [ASTR76].
  1454. .pp
  1455. The size of a compiled plan depends on the target language 
  1456. of the compiler.  If access plans are generated, then the 
  1457. size will be modest (e.g. hundreds of bytes).  If machine code
  1458. is generated, then the size will be thousands of bytes.  
  1459. If plans are of moderate size, they can be cached directly
  1460. in the field that defines them.  Larger plan representations
  1461. can be cached in a separate relation, i.e:
  1462. .(l
  1463. CACHE (identifier, compiled-plan)
  1464. .)l
  1465. and only the identifier stored in the defining field.
  1466. .pp
  1467. The second step (result caching) involves materializing
  1468. the object from the compiled plan.
  1469. Again this step can be performed on demand and saved
  1470. for reuse or even computed in advance.
  1471. The
  1472. size of a materialized object depends, of course, 
  1473. on
  1474. the command(s) which is executed.
  1475. Small objects can be cached directly in the defining field. 
  1476. Larger objects should probably be cached as
  1477. individual relations, and 
  1478. the name of the relation(s) inserted in the defining field.
  1479. When objects are hierarchically composed of other objects, the 
  1480. above constructs can be applied recursively; hence, small objects
  1481. which are composed of small objects will be cached together
  1482. in the field describing the enclosing object.
  1483. .pp
  1484. It is straightforward for the data base system
  1485. to allow result caching for N1 ``big objects'' and execute a least
  1486. recently used (LRU) algorithm to select big objects to be discarded.
  1487. Of course this requires N1 relations to hold these objects and
  1488. the corresponding extra entries in the system catalogs.
  1489. Alternately, a data manager could reserve N2 blocks of storage
  1490. for objects and select a victim based on a function of
  1491. size and time-since-last-reference.  Of course, N1 and N2
  1492. would be carefully chosen system-specific parameters.  Objects 
  1493. must also be
  1494. discarded upon an update to one or more tuples from which they are
  1495. composed.  We discuss a mechanism to accomplish this task
  1496. presently.  Alternately, it should be possible to incrementally
  1497. update the cached object when a subobject is modified.  
  1498. Recent work on supporting materialized views (e.g. [BLAK86])
  1499. can be applied to this task.  Moreover, if the object is an
  1500. QUEL aggregate, it is straightforward to update the cached value.  
  1501. Additional effort in this direction is currently in progress.
  1502. .pp
  1503. For cached big objects, it is desirable to store their name
  1504. and the query(s) which compose them in a main memory data structure.
  1505. Then, if the same or another user materializes an object with the same 
  1506. description, the one already materialized can be used instead.
  1507. An example of this situation occurred in Section 4 where our
  1508. algorithm materialized the object represented by o.shape twice.
  1509. .pp
  1510. The prototype discussed in Section 4 caches
  1511. big objects as discussed above, but small object caching as well as
  1512. invalidation on update has
  1513. yet to be implemented.
  1514. We turn now to the efficient invalidation of objects.
  1515. .sh 2  "Object Invalidation"
  1516. .pp
  1517. Consider a new kind of lock mode called I mode. Hence,
  1518. objects can be locked in R, W or I mode.  A lock set in
  1519. I mode has an associated identifier indicating the object which
  1520. has been precomputed using the locked object.
  1521. The compatibility of the various modes is
  1522. indicated in Table 5.
  1523. .(z
  1524. .hl
  1525. .(c
  1526. .TS
  1527. c c c c
  1528. l l l l.
  1529.     R    W    I
  1530.  
  1531. R    ok    no    ok
  1532. W    no    no    *
  1533. I    ok    no    ok
  1534. .TE
  1535. .)c
  1536.  
  1537. .ce
  1538. Compatibility Modes for I Locks
  1539.  
  1540. .ce
  1541. Table 5
  1542. .hl
  1543. .)z
  1544. The * in that table indicates that a W requestor for an object
  1545. locked in I mode will be allowed to proceed and set
  1546. a W lock on the object.  First, however the object
  1547. with which the I lock is associated will be invalidated.
  1548. .pp
  1549. When INGRES+ materializes any object, it
  1550. simply sets I locks on all objects read by the query(s)
  1551. which materialize the object.  These I locks are held
  1552. until the object is deleted or invalidated through an
  1553. update to a subobject.
  1554. .sh 2  "Implementation of I Locks"
  1555. .pp
  1556. A straight-forward approach would be to place I locks in the
  1557. same lock table holding R and W locks.   In this case, one must cope
  1558. with a lock table of widely varying size since the number
  1559. of I locks can change dramatically.  Moreover, when a
  1560. failure occurs, either all precomputed objects must be invalidated 
  1561. (which may be a costly alternative if the facility is extensively
  1562. used) or I locks must
  1563. be made
  1564. recoverable.   Lastly, phantoms must be correctly
  1565. handled.  Hence, if a new tuple is added which
  1566. satisfies the qualification of some precomputed object, then this
  1567. object must be invalidated.  
  1568. .pp
  1569. The first objective can be satisfied by using
  1570. extendible hashing [FAGI79] for the lock table instead of conventional
  1571. hashing.  The second objective requires setting I locks
  1572. as part of a transaction and writing them into the log.
  1573. If a failure occurs during this transaction, then recovery
  1574. code must be extended slightly to back 
  1575. out the I locks which were set.  Moreover, I locks
  1576. must be periodically checkpointed to allow recovery from media
  1577. failures.  Hence, when recovery code is rolling forward from a
  1578. checkpoint, I locks can be suitable updated.
  1579. In summary, making I locks recoverable simply involves treating them
  1580. as ordinary data and presents only modest implementation difficulties.
  1581. .pp
  1582. The phantom problem poses more serious issues.   Systems 
  1583. which perform page level locking (e.g. [RTI86, CHEN84])
  1584. have few difficulties
  1585. supporting correct semantics in the presence of
  1586. phantoms.
  1587. Hence, one can include I locks in such systems without concern.
  1588. However, finer granularity locking is required to
  1589. avoid an excessive number of unnecessary invalidations. 
  1590. Systems which perform record
  1591. level locking (e.g. System R [ASTR76]) can allow detection of
  1592. phantoms by holding locks on index intervals in the leaf nodes of 
  1593. secondary indexes as well as on data records. 
  1594. Hence, a transaction which inserts a tuple will
  1595. hold a write lock on the tuple and on the appropriate index interval
  1596. for any field for which a secondary index
  1597. exists.
  1598. If I locks are also held on data records and index intervals, 
  1599. then all conflicts caused by phantoms will be detected by a
  1600. collision in some index.
  1601. .pp
  1602. When access paths other than B-trees are present, a slight
  1603. generalization to the above scheme will support phantom
  1604. detection.
  1605. Tuple level locks are held
  1606. on index and data records which use a hashed or B-tree organization.
  1607. Then, 
  1608. a precomputed object must be invalidated if an I lock which
  1609. is held on its behalf falls
  1610. adjacent to a tuple 
  1611. on which a W lock is held.
  1612. For B-tree data records and indexes,
  1613. adjacency means ``logically adjacent in tuple identifier order'';
  1614. for hashed records and indexes,
  1615. adjacency means ``in the same hash bucket.'' 
  1616. .pp
  1617. The only problem with the adjacency approach 
  1618. is that a B-tree page split will cause a write lock to be set
  1619. on the page to be split, and thereby will cause an invalidation
  1620. of all objects holding I locks
  1621. on that page.  Unless tuple identifiers
  1622. are constructed so that they do not change when a tuple moves to
  1623. a different page, this invalidation is required.  Otherwise
  1624. I locks will be held on the previous identifier for the moved tuple,
  1625. and incorrect operation will result.
  1626. .pp
  1627. The phantom problem and the logging problem 
  1628. appear easier to solve if an alternate strategy is employed.
  1629. Consider storing I locks in the data and index records
  1630. themselves.   Systems which support variable length records can simply
  1631. add as many I locks to each record as necessary.   Such locks are
  1632. recoverable using conventional techniques which
  1633. are automatically applied to data records.   
  1634. The phantom problem requires the above adjacency algorithm; however,
  1635. structure modifications (e.g. B-tree page splits) do not cause
  1636. unnecessary invalidations.
  1637. Moreover, since the extra locks are stored separately from
  1638. R and W locks, extendible hashing is not a prerequisite for the
  1639. lock table.   
  1640. Lastly, this approach is easily extended to field-level 
  1641. locks, which may offer superior performance to record level I locks.
  1642. .pp
  1643. The drawbacks of this second alternative is that a second implementation
  1644. of a lock manager must be coded for I locks.
  1645. Moreover, setting an I lock on an object requires rewriting the object instead
  1646. of just reading it.  Hence, setting I locks will be expensive.
  1647. .sh 2  "Performance of Cached Objects"
  1648. .pp
  1649. The purpose of this section is to present a model which can be
  1650. used to suggest when caching should be applied to a procedural object.
  1651. Consider a ``small'' object which can be constructed 
  1652. in N1 page accesses
  1653. and inspection of N2 records.  Assume that this object
  1654. occupies R1 = 1 page of space, 
  1655. consists of R2 tuples and is cached in the data record itself.
  1656. In addition, 
  1657. consider a query pattern in which P percent of the accesses are
  1658. reads of the complex object and 1-P are updates to subobjects from which
  1659. the complex object is composed.
  1660. Moreover, each update is applied to a randomly chosen subobject from the
  1661. N2 candidates.
  1662. Lastly, the record in which the description of the complex object is stored
  1663. must be read during retrieval whether or not caching is employed.  Hence, 
  1664. that access is not counted in the following analysis.
  1665. .pp
  1666. Consider the sequence of accesses to be a collection of
  1667. .b intervals,
  1668. each consisting of 
  1669. one or
  1670. more consecutive writes followed by one or more consecutive reads.
  1671. In a given interval, the expected length ER of the run of reads and
  1672. the length EW of the run of writes is:
  1673. .(l
  1674. ER = 1 / (1 - P)
  1675. EW = 1 / P
  1676. .)l
  1677. Consider first the no-cache alternative.
  1678. With the 
  1679. parameter K discussed in [SELI79] which weighs the CPU time used 
  1680. in evaluating a query plan relative to the number of I/O's, 
  1681. the cost, M to materialize the
  1682. object after its definition has been obtained is:
  1683. .(l
  1684. M = N1 + N2 * K
  1685. .)l
  1686. Without caching, this cost must be paid on each read access,  
  1687. and the
  1688. cost, C1 of these accesses is:
  1689. .(l
  1690. C1  = (ER) * (M)
  1691. .)l
  1692. .pp
  1693. We now turn to the corresponding costs for
  1694. cached objects.  The cost to invalidate the complex object
  1695. on the initial write is:
  1696. .(l
  1697. IN = 1
  1698. .)l 
  1699. This assumes that I locks are stored in the records of the subobjects
  1700. and that only the 
  1701. data record containing the object description
  1702. must be rewritten to perform invalidation.  All
  1703. I locks are simply left in place.  
  1704. Subsequent writes prior to the first read also require the same 
  1705. cost even though the complex object has already been invalidated.
  1706. .pp
  1707. The first read to the complex object
  1708. requires a materialization at cost, M.  In addition, the cost, C
  1709. to cache the object is:
  1710. .(l
  1711. C = 1 
  1712. .)l
  1713. The materialized object must be written into the field occupied by
  1714. the description of the complex object requiring a single record to be rewritten.
  1715. Since I locks were never reset from prior materializations,
  1716. no extra cost is required to ensure that they are set.  
  1717. Subsequent reads only require accessing the object in the
  1718. cache.  Since the access to the object description is not being
  1719. counted, there is no additional I/O because the cached object is stored
  1720. in this record.  Hence, only the CPU cost to access the R2 records in the 
  1721. cached object must be paid, i.e:
  1722. .(l
  1723. A = R2 * K
  1724. .)l
  1725. .pp
  1726. Therefore, the expected cost of an interval using
  1727. caching is:
  1728. .(l
  1729. C2  =  EW * IN                      /*cache invalidation on each write*/
  1730.  
  1731.       + M + C                       /*materialize plus cache on first read*/
  1732.  
  1733.       + (ER - 1) * (A)                 /*subsequent reads access the cache*/
  1734.  
  1735. .)l
  1736. Define Z = M - A to be the caching factor, i.e. the 
  1737. difference between the cost to materialize the object
  1738. and the cost to access the object from the cache. 
  1739. This cost is in weighted CPU and page costs and is typically 
  1740. in the range of 10 - 1000.
  1741. Algebraic manipulation now yields that caching will be preferred if:
  1742. .(l
  1743. Z > (1 / P ** 2) - 1
  1744. .)l
  1745. The consequence of this analysis is that caching will generally
  1746. win unless P is very small.  If P is 1/2, then Z must be 
  1747. greater than 3 for caching to be
  1748. beneficial.  If P is 1/10, then Z must exceed 99.
  1749. .sh 2  "Indexing Cached Fields"
  1750. .pp
  1751. An extension of this caching 
  1752. tactic may be attractive when the 
  1753. queries in a field have certain compositions.  Consider
  1754. a situation, such as salaries in an EMP relation for which
  1755. most of the fields are specified as constants while
  1756. a few are specified procedurally.  For example, Joe might make
  1757. $10,000 and Bill is specified as having the same wages as Joe.
  1758. In this case salary can be a procedural field and most
  1759. rows have a value of the form:
  1760. .(l
  1761. retrieve (wages = constant)
  1762. .)l
  1763. while Bill would have a value of:
  1764. .(l
  1765. retrieve (EMP.salary.wages) where EMP.name = ``Joe''
  1766. .)l
  1767. In this case, one would desire a salary index on salaries for
  1768. efficient processing
  1769. of queries of the form:
  1770. .(l
  1771. retrieve (EMP.name) where EMP.salary.wages = value
  1772. .)l
  1773. This section indicates how to construct such indexes on procedural fields.
  1774. .pp
  1775. Instead of caching values as they are
  1776. computed, consider caching all values
  1777. in advance.  If this is done, then
  1778. it is straightforward to
  1779. build an index on a field appearing in the cached objects using
  1780. the conventional indexing utility.  
  1781. One can use this index to answer queries of the above form
  1782. rapidly.
  1783. On updates to subobjects, one
  1784. must invalidate cached objects as discussed 
  1785. in the previous subsection.  However,
  1786. as part of the transaction which updates a subobject, the invalidated
  1787. object must be rebuilt and the index updated. 
  1788. Conventional locking must be employed to guarantee consistency,
  1789. and aborting a transaction must cause a backout of all
  1790. updates or an
  1791. invalidation of
  1792. the new cached value.
  1793. .pp
  1794. In the case that most values are simply constants, such indexes
  1795. should be beneficial, and be only marginally more expensive to
  1796. maintain than conventional ones.  
  1797. .sh 1  "CONCLUSIONS"
  1798. .pp
  1799. This paper has suggested that data base procedures are a natural
  1800. way to model complex objects and to allow data base oriented algorithms
  1801. and precompiled queries in the data base.  Moreover, they
  1802. appear to be easily generalizable to arbitrary programming language
  1803. procedures which may be useful in certain applications.
  1804. Lastly, they can be used to model aggregation, generalization and
  1805. most other environments addressed by semantic data models.  The
  1806. advantage of data base procedures is that a user does not need to learn
  1807. additional concepts to design his application.  Since he must 
  1808. know the query language anyway, there is little extra complexity.
  1809. Hence, this proposal is in the same spirit of the ``spartan simplicity''
  1810. stressed by the original advocates of the relational model.
  1811. .pp
  1812. A prototype implementation was described and initial performance
  1813. studies explored.  They indicated comparable
  1814. performance between the extended and the non-extended prototypes
  1815. except when many one-variable commands were processed
  1816. by INGRES+ or when a 
  1817. bad query plan was 
  1818. indicated by the structure of the query.
  1819. Bad plans can be avoided if procedural fields are restricted to
  1820. parameterized queries, and compile time optimization should
  1821. alleviate the overhead of one-relation commands.  Moreover,
  1822. a caching strategy was described which should 
  1823. accelerate performance of the prototype especially when objects
  1824. are of moderate size.  Our caching scheme should
  1825. offer superior performance to pointer oriented
  1826. implementations of complex objects when update frequency
  1827. is low or moderate.
  1828. .bp
  1829. .lp
  1830. .ce
  1831. REFERENCES
  1832. .ls 1
  1833. .nr ii 10m
  1834. .ip [ASTR76]
  1835. Astrahan, M., et. al., ``System R: A Relational Approach to Data,'' 
  1836. ACM-TODS, June 1976.
  1837. .ip [BLAK86]
  1838. Blakeley, J. et. al., ``Efficiently Updating Materialized Views,''
  1839. Proc. 1986 ACM-SIGMOD Conference on Management of Data, Washington, D.C.,
  1840. May 1986.
  1841. .ip [CHEN84]
  1842. Cheng, J., et. al., ``IBM Database 2 Performance: Design, Implementation,
  1843. and Tuning,'' IBM Systems Journal, February 1984.
  1844. .ip [COPE84]
  1845. Copeland, G. and Maier, D., ``Making Smalltalk a Data Base System,''
  1846. Proc. 1984 ACM-SIGMOD Conference on Management of Data, Boston, Mass.,
  1847. June 1984.
  1848. .ip [DATE81]
  1849. Date, C., ``Referential Integrity,'' Proc. 6th VLDB Conference, 
  1850. Cannes, France, September 1981.
  1851. .ip [DBTG71]
  1852. Data Base Task Group, ``Report to the CODASYL Programming Language
  1853. Committee,'' April 1971.
  1854. .ip [EPST80]
  1855. Epstein, R., and Hawthorn, P., ``Design Decisions for the Intelligent
  1856. Database Machine,'' Proc. 1980 National Computer Conference,
  1857. Anaheim, Ca., May 1980.
  1858. .ip [FAGI79]
  1859. Fagin, R. et. al., ``Extendible Hashing: A Fast Access Method for Dynamic
  1860. Files,'' ACM-TODS, Sept. 1979.
  1861. .ip [HAMM81]
  1862. Hammer, M. and McLeod, D., ``Database Description with SDM,'' ACM-TODS,
  1863. September 1981.
  1864. .ip [HASK82]
  1865. Haskins, R. and Lorie, R., 
  1866. ``On Extending the Functions of a Relational Database System,''
  1867. Proc. 1982
  1868. ACM-SIGMOD Conference on Management of Data, Orlando, Fl, June 1982.
  1869. .ip [HELD75]
  1870. Held, G. et. al., ``INGRES - A Relational Data Base System,'' Proc. 1975
  1871. National Computer Conference, Anaheim, Ca., May 1975.
  1872. .ip [KALA85]
  1873. Kalash, J., ``Implementation of a Data Base Browser,'' Electronics 
  1874. Research Laboratory, University of California, Berkeley, Ca.,
  1875. Memo No. M85/22, May 1985.
  1876. .ip [KOOI82]
  1877. Kooi, R. and Frankfurth, D., ``Query Optimization in INGRES,''
  1878. Database Engineering, Sept. 1982.
  1879. .ip [KUNG84]
  1880. Kung, R. et. al., ``Heuristic Search in Database Systems,'' Proc.
  1881. 1st International Conference on Expert Systems, Kiowah, S.C., 
  1882. Oct. 1984.
  1883. .ip [LORI83]
  1884. Lorie, R. and Plouffe, W., ``Complex Objects and Their Use in
  1885. Design Transactions,'' Proc. Engineering Design Applications Stream of
  1886. ACM-IEEE Data Base Week, San Jose, Ca., May 1983.
  1887. .ip [MYLO80]
  1888. Myloupoulis, J. et. al., ``A Language Facility for Designing Database
  1889. Intensive Applications,'' ACM-TODS, June 1980.
  1890. .ip [ONG84]
  1891. Ong, J., et. al., ``Implementation of Data Abstraction in the Relational
  1892. Database System INGRES,'' SIGMOD Record, March 1984.
  1893. .ip [POWE83]
  1894. Powell, M. and Linton, M., ``Database Support for Programming
  1895. Environments,'' Proc. Engineering Design Applications Stream of ACM-IEEE
  1896. Database Week, San Jose, Ca., May 1983.
  1897. .ip [ROWE82]
  1898. Rowe, L. and Shoens, K., ``A Form  Application Development System,''
  1899. Proc. 1982 ACM-SIGMOD Conference on Management of Data, Orlando, Fl,
  1900. June 1982.
  1901. .ip [RTI86]
  1902. Relational Technology, Inc., ``INGRES Version 5.0 Reference Manual,'' 
  1903. November 1986.
  1904. .ip [SELI79]
  1905. Selinger, P., ``Access Path Selection in a Relational Database System,''
  1906. Proc. 1979 ACM-SIGMOD Conference on Management of Data, Boston, Mass.,
  1907. June 1979.
  1908. .ip [SHIP81]
  1909. Shipman, D., ``The Functional Model and the Data Language Daplex,''
  1910. ACM-TODS, March, 1981.
  1911. .ip [SMIT77]
  1912. Smith, J and Smith, D., ``Database Abstractions: Aggregation and
  1913. Generalization,'' ACM TODS, June 1977.
  1914. .ip [SORD84]
  1915. Sordi, J., ``IBM Database 2: The Query Management Facility,'' IBM Systems 
  1916. Journal, February 1984.
  1917. .ip [STON75]
  1918. Stonebraker, M., ``Implementation of Views and Integrity Control by
  1919. Query Modification,'' Proc. 1975 ACM-SIGMOD Conference on Management
  1920. of Data, San Jose, Ca., June 1975.
  1921. .ip [STON76]
  1922. Stonebraker, M. et al., ``The Design and Implementation of INGRES,''
  1923. ACM-TODS,
  1924. September 1976.
  1925. .ip [STON84]
  1926. Stonebraker, M. et. al., ``QUEL as a Data Type,'' Proc. 1984 ACM-SIGMOD
  1927. Conference on Management of Data, Boston, Mass., June 1984.
  1928. .ip [STON86]
  1929. Stonebraker, M., ``Object Management in POSTGRES Using Procedures,''
  1930. Electronics Research Laboratory, University of California,
  1931. Memo M86/42, July 1986. 
  1932. .ip [WILE84]
  1933. Wilensky, R., ``The LISP PRIMER'' 
  1934. W. Norton, Co, New York, 1984.
  1935. .ip [WONG76]
  1936. Wong, E., ``Decomposition: A Strategy for Query Processing,'' ACM-TODS,
  1937. Sept. 1976.
  1938. .ip [ZANI83]
  1939. Zaniolo, C., ``The Database Language GEM,''
  1940. Proc. 1983 ACM-SIGMOD Conference on Management of Data,
  1941. San Jose, Ca., May 1983.
  1942.  
  1943. .bp
  1944. .ce
  1945. APPENDIX 1
  1946.  
  1947. The syntax of QUEL has been described elsewhere [HELD75].  Here,
  1948. we report only the extensions to the original language, QUEL, which
  1949. define QUEL+. Let F be the construct ``QUEL-col-1.,...,QUEL-col-n.field''. 
  1950.  
  1951. 1) F can appear
  1952. wherever a field of a relation can appear in QUEL. 
  1953.  
  1954. 2) The construct ``tuple-variable.F can appear
  1955. whenever a tuple variable or a relation name can appear in QUEL.
  1956.  
  1957. 3) Clauses of the form:
  1958. .(l
  1959. G1 newop G2
  1960. .)l
  1961. are allowable if G1 and G2 are tuple variables or the 
  1962. construct ``tuple-variable.F'' and newop is in the set:
  1963. .(l
  1964. { U , !! , >> , << , == , <> , JJ , OJ, empty }
  1965. .)l
  1966.  
  1967. 4) EXECUTE and EXECUTE-ONE are added as commands
  1968.  
  1969. 5) An operator ``in'' is added accepting an indirectly referenced column
  1970. as a left operand and a relation name as a right operand.
  1971.  
  1972. 6) A keyword ``with'' is added which is usable with the EXECUTE command
  1973. to indicate the presence of a parameter list.
  1974.