queries.xml 16.2 KB
Newer Older
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<page name="tutorial_queries">

<title>Queries</title>
<left>
<boxes-toc/>
<p>
You can cut and paste the code on this page and 
9
test it on the <a href="cgi-bin/cduce">incline interpreter</a>.
10
11
</p>
</left>
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

<box title="Select from where" link="sel">

<p>
CDuce is endowed with a <code>select_from_where</code> syntax to perform some SQL-like queries. The general form of select expressions is
</p>
<sample><![CDATA[
select %%e%% from
   %%p1%% in %%e1%%
   %%p2%% in %%e2%%
       :
   %%pn%% in %%en%%
where %%b%%
]]></sample>
<p>
where <code>%%e%%</code> is an expression <code>%%b%%</code> a boolean expression, the <code>%%pi%%</code>'s are patterns, and  the <code>%%ei%%</code>'s are sequence expressions.
</p>

<p>
32
The <code>select_from_where</code> construction is translated into:
33
34
</p>
<sample><![CDATA[
35
36
transform %%e1%% with %%p1%% -> 
   transform %%e2%% with %%p2%% -> 
37
         ...
38
39
       transform %%en%% with %%pn%% -> 
          if %%c%% then  [%%e%%] else []
40
41
42
43
44
45
46
47
48
49
50
51
52
]]>
</sample>


</box>

<box title="XPath-like expressions" link="xpath">
<p> XPath-like expressions are of two kind :
<code> %%e%%/%%t%% </code> and <code> %%e%%/@%%a%% </code>  where <code>%%e%%</code> is an expression, <code> %%t%% </code> a type, and <code> %%a%% </code> an attribute.

</p>

<p> 
53
54
55
56
57
58
They are syntactic sugar for :</p> 
<sample> <![CDATA[flatten(select x from <_>[(x::t | _ )*] in e)]]> </sample>
<p>  and </p>
<sample><![CDATA[
select x from <_ a=x>_ in  e]]>
</sample>
59

60
</box>
61

62
<box title="Examples" link="exsel">
63
64
<section title="Types and data for the examples">

65

66
<p> Let us consider the following types representing a Bibliography </p>
67
68
69
70
71
72
73
74
<sample><![CDATA[
type Biblio  = <bibliography>[Heading Paper*]
type Heading = <heading>[ PCDATA ]
type Paper   = <paper>[ Author+ Title Conference File ]
type Author  = <author>[ PCDATA ]
type Title   = <title>[ PCDATA ]
type Conference = <conference>[ PCDATA ]
type File    = <file>[ PCDATA ]
75
76
77
78
]]>
</sample>
<p> and some values </p>
<sample><![CDATA[
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
let bib : Biblio = 
  <bibliography>[
    <heading>"Alain Frisch's bibliography"
    <paper>[
      <author>"Alain Frisch"
      <author>"Giuseppe Castagna"
      <author>"Veronique Benzaken"
      <title>"Semantic subtyping"
      <conference>"LICS 02"
      <file>"semsub.ps.gz"
    ]
    <paper>[
      <author>"Mariangiola Dezani-Ciancaglini"
      <author>"Alain Frisch"
      <author>"Elio Giovannetti"
      <author>"Yoko Motohama"
      <title>"The Relevance of Semantic Subtyping"
      <conference>"ITRS'02"
      <file>"itrs02.ps.gz"
    ]
    <paper>[
      <author>"Veronique Benzaken"
      <author>"Giuseppe Castagna"
      <author>"Alain Frisch"
      <title>"CDuce: a white-paper"
      <conference>"PLANX-02"
      <file>"planx.ps.gz"
    ]
 ]
108
109
]]>
</sample>
110
111
112
113
</section>


<section title="Projections">
114
115
<p> All titles in the bibliography bib </p>
<sample><![CDATA[
116
117
118
let titles = [bib]/<paper>_/<title>_
]]>
</sample>
119
<p> Which yields to:</p>
120
121
122
123
124
<sample><![CDATA[
val titles : [ <title>[ Char* ]* ] = [ <title>[ 'Semantic subtyping' ]
  <title>[ 'The Relevance of Semantic Subtyping' ]
  <title>[ 'CDuce: a white-paper' ]
  ]
125
126
127
128
129
130
131
132
133
134
135
Ok.
]]>
</sample>

<p> All authors in the bibliography bib </p>
<sample><![CDATA[
let authors = [bib]/<paper>_/<author>_
]]>
</sample>
<p> Yielding the result: </p>
<sample><![CDATA[
136
137
138
139
140
141
142
143
144
145
146
val authors : [ <author>[ Char* ]* ] = [ <author>[ 'Alain Frisch' ]
  <author>[ 'Giuseppe Castagna' ]
  <author>[ 'Veronique Benzaken' ]
  <author>[ 'Mariangiola Dezani-Ciancaglini' ]
  <author>[ 'Alain Frisch' ]
  <author>[ 'Elio Giovannetti' ]
  <author>[ 'Yoko Motohama' ]
  <author>[ 'Veronique Benzaken' ]
  <author>[ 'Giuseppe Castagna' ]
  <author>[ 'Alain Frisch' ]
  ]
147
148
149
150
151
152
153
154
155
156
Ok.
]]>
</sample>
<p> All papers in the bibliography bib </p>
<sample><![CDATA[
let papers = [bib]/<paper>_
]]>
</sample>
<p> Yielding: </p>
<sample><![CDATA[
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
val papers : [ <paper>[ Author+ Title Conference File ]* ] = [ <paper>[
    <author>[ 'Alain Frisch' ]
    <author>[ 'Giuseppe Castagna' ]
    <author>[ 'Veronique Benzaken' ]
    <title>[ 'Semantic subtyping' ]
    <conference>[ 'LICS 02' ]
    <file>[ 'semsub.ps.gz' ]
    ]
  <paper>[
    <author>[ 'Mariangiola Dezani-Ciancaglini' ]
    <author>[ 'Alain Frisch' ]
    <author>[ 'Elio Giovannetti' ]
    <author>[ 'Yoko Motohama' ]
    <title>[ 'The Relevance of Semantic Subtyping' ]
    <conference>[ 'ITRS\'02' ]
    <file>[ 'itrs02.ps.gz' ]
    ]
  <paper>[
    <author>[ 'Veronique Benzaken' ]
    <author>[ 'Giuseppe Castagna' ]
    <author>[ 'Alain Frisch' ]
    <title>[ 'CDuce: a white-paper' ]
    <conference>[ 'PLANX-02' ]
    <file>[ 'planx.ps.gz' ]
    ]
  ]
183
184
185
Ok.
]]>
</sample>
186
187
188
189
190
</section>

<section title="Select_from_where">

<p>The same queries we wrote above can of course be programmed with the <code>select_from_where</code> construction </p>
191
192
193
194
195
196
197
198
199
<p> All the titles </p>
<sample><![CDATA[
let tquery = select y 
             from x in [bib]/<paper>_ ,
                  y in [x]/<title>_
]]>
</sample>
<p> This query is programmed in a XQuery-like style largely relying on the projections. Note that <code>x</code> and <code>y</code> are CDuce's patterns. The result is:</p>
<sample> <![CDATA[
200
201
202
203
val tquery : [ <title>[ Char* ]* ] = [ <title>[ 'Semantic subtyping' ]
  <title>[ 'The Relevance of Semantic Subtyping' ]
  <title>[ 'CDuce: a white-paper' ]
  ]
204
205
206
207
208
209
210
211
212
213
214
215
]]>
</sample>
<p> Now let's program the same query with the translation given previously thus eliminating the <code>y</code> variable </p>
<sample><![CDATA[
let withouty = flatten(select [x] from x in [bib]/<paper>_/<title>_)
]]>
</sample>

<p> Yielding: </p>
<sample><![CDATA[

val withouty : [ <title>[ Char* ]* ] = [ <title>[ 'Semantic subtyping' ]
216
217
218
219
220
221
222
223
224
  <title>[ 'The Relevance of Semantic Subtyping' ]
  <title>[ 'CDuce: a white-paper' ]
  ]
- : [ <title>[ Char* ]* ] = [ <title>[ 'The Relevance of Semantic Subtyping' ] ]
- : [ <title>[ Char* ]* ] = [ <title>[ 'The Relevance of Semantic Subtyping' ] ]

Ok.
]]>
</sample>
225
226
227
228
229
230
231
232



<p>
But the <code>select_from_where</code> expressions are likely to be used for
more complex queries such as the one that selects all titles whose at least one
author is "Alain Frisch" or "Veronique Benzaken"
</p>
233
234
235
236
237
238
239
240
241
<sample><![CDATA[
let sel = select y 
          from x in [bib]/<paper>_ ,
               y in [x]/<title>_,
               z in [x]/<author>_
where z = <author>"Alain Frisch" or z = <author>"Veronique Benzaken"
]]>
</sample>
<p> Which yields: </p>
242
243

<sample><![CDATA[
244
245
246
247
248
249
250
251
252
val sel : [ <title>[ Char* ]* ] = [ <title>[ 'Semantic subtyping' ]
  <title>[ 'Semantic subtyping' ]
  <title>[ 'The Relevance of Semantic Subtyping' ]
  <title>[ 'CDuce: a white-paper' ]
  <title>[ 'CDuce: a white-paper' ]
  ]

Ok.
]]>
253
254
255
256
</sample>



257
258
<p>Note that the corresponding semantics, as in SQL, is a multiset one.
Thus duplicates are not eliminated. To discard them, one has to use the <code>distinct_values</code> operator.
259
</p>
260
</section>
261

262
<section title="A pure pattern example">
263
<p>
264
265
266
This example computes the same result as the previous query except that
duplicates are eliminated. It is written in a pure pattern form (i.e., without
any XPath-like projections)
267
268
269
270
271
</p>

<sample><![CDATA[
let sel = select t
from <_>[(x::<paper>_ | _ )*] in [bib],
272
     <_>[ _* (<author>"Alain Frisch" | <author>"Veronique Benzaken")  _*  (t&<title>_ ); _]  in x  
273

274
275
276
]]>
</sample>
<p>
277
278
279
Note the pattern on the second line in the <code> from </code> clause. As the type of an element in <code>x</code> is <code><![CDATA[<paper>[ Author+ Title Conference File]]]></code>, we skip the tag : <code><![CDATA[<_>]]></code>, then we skip authors <code><![CDATA[_*]]> </code> until we find either Alain Frisch or Veronique Benzaken <code><![CDATA[ (<author>"Alain Frisch" | <author>"Veronique Benzaken")]]></code>, then we skip the remaining authors <code>_*</code>, we then capture the corresponding title <code><![CDATA[(t &<title>_)]]></code> and then ignore the tail of the sequence by writing <code>; _</code>
</p>
<p>
280
Result:
281
282
</p>
<sample><![CDATA[
283
284
285
val sel : [ <title>[ Char* ]* ] = [ <title>[ 'Semantic subtyping' ]
  <title>[ 'The Relevance of Semantic Subtyping' ]
  <title>[ 'CDuce: a white-paper' ]
286
  ]
287

288
289
290
291
Ok.
]]>
</sample>
<p>
292
293
294
This pure pattern form of the query yields (in general) better performance than
the same one written in an XQuery-like programming style. However, the query
optimiser automatically translates the latter into a pure pattern one
295
</p>
296
297
</section>
<section title="Joins">
298
299


300
<p>
301
302
This example is the exact transcription of query Q5 of XQuery use cases.
We first give the corresponding CDuce types. We leave the user in charge of  creating the corresponding relevant values.
303
</p>
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

<sample><![CDATA[
type Bib = <bib>[Book*] 
type Book = <book year=String>[Title (Author+ | Editor+ ) Publisher Price]
type Author = <author>[Last First]
type Editor = <editor>[Last First Affiliation]
type Title  = <title>[PCDATA]
type Last  = <last>[PCDATA]
type First  = <first>[PCDATA]
type Affiliation = <affiliation>[PCDATA]
type Publisher  = <publisher>[PCDATA]
type Price  = <price>[PCDATA]
]]>
</sample>
<p>
The queries are expressed first in an XQuery-like style, then in a pure pattern style: the first pattern-based query is the one produced by the automatic translation from the first one. The last query correponds to a pattern aware programmer's version.
</p>

<p>
XQuery style
</p>
<sample><![CDATA[
<books-with-prices>
select <book-with-price>[t1 
              <price-amazon>([p2]/_) <price-bn>([p1]/_)]
from b in [biblio]/Book ,
     t1 in [b]/Title,
     e in [amazon]/Entry,
     t2 in [e]/Title,
     p2 in [e]/Price,
     p1 in [b]/Price
 where t1=t2 
]]>
</sample>

<p> Automatic translation of the previous query into a pure pattern (thus more efficient) one </p>
<sample><![CDATA[
<books-with-prices>
select <book-with-price>[t1 <price-amazon>x11 <price-bn>x10 ]
from <_>[(x3::Book|_)*] in [biblio],
     <_>[(x9::Price|x5::Title|_)*] in x3,
     t1 in x5,
     <_>[(x6::Entry|_)*] in [amazon],
     <_>[(x7::Title|x8::Price|_)*] in x6,
     t2 in x7,
     <_>[(x10::_)*] in x9,
     <_>[(x11::_)*] in x8
 where t1=t2
]]>
</sample>

<p>  
Pattern aware programmer's version of the same query (hence hand optimised).
This version of the query is very efficient. Be aware of patterns.
</p>

<sample><![CDATA[
<books-with-prices>
select <book-with-price>[t2 <price-amazon>p2 <price-bn>p1]
from <bib>[b::Book*] in [biblio],
     <book>[t1&Title _* <price>p1] in b,
     <reviews>[e::Entry*] in [amazon],
     <entry>[t2&Title <price>p2 ;_] in e
where t1=t2
]]>
</sample>
370
</section>
371

372
373

<section title="An unorthodox query: Formatted table generation">
374

375
376
377
<p>
The following program generates a 10x10 multiplication table:
</p>
378

379
380
381
382
383
384
385
386
387
388
389
390
391
<sample><![CDATA[
let bg ((Int , Int) -> String) 
  (y, x) -> if (x mod 2 + y mod 2 <= 0) then "lightgreen" 
            else if (y mod 2 <= 0) then "yellow"
	    else if (x mod 2 <= 0) then "lightblue"
	    else "white";;

<table border="1">
  select <tr> select <td align="right" style=("background:"@bg(x,y)) >[ (x*y) ]
              from y in [1 2 3 4 5 6 7 8 9 10] 
  from x in [1 2 3 4 5 6 7 8 9 10];;
 ]]></sample>
<p>
392
The result is the xhtml code that generates the following table:
393
394
</p>
<table border="1"><tr><td align="right" style="background:white">1</td><td align="right" style="background:lightblue">2</td><td align="right" style="background:white">3</td><td align="right" style="background:lightblue">4</td><td align="right" style="background:white">5</td><td align="right" style="background:lightblue">6</td><td align="right" style="background:white">7</td><td align="right" style="background:lightblue">8</td><td align="right" style="background:white">9</td><td align="right" style="background:lightblue">10</td></tr><tr><td align="right" style="background:yellow">2</td><td align="right" style="background:lightgreen">4</td><td align="right" style="background:yellow">6</td><td align="right" style="background:lightgreen">8</td><td align="right" style="background:yellow">10</td><td align="right" style="background:lightgreen">12</td><td align="right" style="background:yellow">14</td><td align="right" style="background:lightgreen">16</td><td align="right" style="background:yellow">18</td><td align="right" style="background:lightgreen">20</td></tr><tr><td align="right" style="background:white">3</td><td align="right" style="background:lightblue">6</td><td align="right" style="background:white">9</td><td align="right" style="background:lightblue">12</td><td align="right" style="background:white">15</td><td align="right" style="background:lightblue">18</td><td align="right" style="background:white">21</td><td align="right" style="background:lightblue">24</td><td align="right" style="background:white">27</td><td align="right" style="background:lightblue">30</td></tr><tr><td align="right" style="background:yellow">4</td><td align="right" style="background:lightgreen">8</td><td align="right" style="background:yellow">12</td><td align="right" style="background:lightgreen">16</td><td align="right" style="background:yellow">20</td><td align="right" style="background:lightgreen">24</td><td align="right" style="background:yellow">28</td><td align="right" style="background:lightgreen">32</td><td align="right" style="background:yellow">36</td><td align="right" style="background:lightgreen">40</td></tr><tr><td align="right" style="background:white">5</td><td align="right" style="background:lightblue">10</td><td align="right" style="background:white">15</td><td align="right" style="background:lightblue">20</td><td align="right" style="background:white">25</td><td align="right" style="background:lightblue">30</td><td align="right" style="background:white">35</td><td align="right" style="background:lightblue">40</td><td align="right" style="background:white">45</td><td align="right" style="background:lightblue">50</td></tr><tr><td align="right" style="background:yellow">6</td><td align="right" style="background:lightgreen">12</td><td align="right" style="background:yellow">18</td><td align="right" style="background:lightgreen">24</td><td align="right" style="background:yellow">30</td><td align="right" style="background:lightgreen">36</td><td align="right" style="background:yellow">42</td><td align="right" style="background:lightgreen">48</td><td align="right" style="background:yellow">54</td><td align="right" style="background:lightgreen">60</td></tr><tr><td align="right" style="background:white">7</td><td align="right" style="background:lightblue">14</td><td align="right" style="background:white">21</td><td align="right" style="background:lightblue">28</td><td align="right" style="background:white">35</td><td align="right" style="background:lightblue">42</td><td align="right" style="background:white">49</td><td align="right" style="background:lightblue">56</td><td align="right" style="background:white">63</td><td align="right" style="background:lightblue">70</td></tr><tr><td align="right" style="background:yellow">8</td><td align="right" style="background:lightgreen">16</td><td align="right" style="background:yellow">24</td><td align="right" style="background:lightgreen">32</td><td align="right" style="background:yellow">40</td><td align="right" style="background:lightgreen">48</td><td align="right" style="background:yellow">56</td><td align="right" style="background:lightgreen">64</td><td align="right" style="background:yellow">72</td><td align="right" style="background:lightgreen">80</td></tr><tr><td align="right" style="background:white">9</td><td align="right" style="background:lightblue">18</td><td align="right" style="background:white">27</td><td align="right" style="background:lightblue">36</td><td align="right" style="background:white">45</td><td align="right" style="background:lightblue">54</td><td align="right" style="background:white">63</td><td align="right" style="background:lightblue">72</td><td align="right" style="background:white">81</td><td align="right" style="background:lightblue">90</td></tr><tr><td align="right" style="background:yellow">10</td><td align="right" style="background:lightgreen">20</td><td align="right" style="background:yellow">30</td><td align="right" style="background:lightgreen">40</td><td align="right" style="background:yellow">50</td><td align="right" style="background:lightgreen">60</td><td align="right" style="background:yellow">70</td><td align="right" style="background:lightgreen">80</td><td align="right" style="background:yellow">90</td><td align="right" style="background:lightgreen">100</td></tr></table>
395

396
</section>
397
</box>
398
399

</page>