xref: /plugin/strata/_test/query.test.php (revision 5153720fcc1dd2b6e63035d45f7c2bc32e429371)
1*5153720fSfkaag71<?php
2*5153720fSfkaag71require_once('strataquerytest.inc.php');
3*5153720fSfkaag71
4*5153720fSfkaag71/**
5*5153720fSfkaag71 * Tests queries.
6*5153720fSfkaag71 *
7*5153720fSfkaag71 * @group plugin_strata
8*5153720fSfkaag71 * @group plugins
9*5153720fSfkaag71 */
10*5153720fSfkaag71class query_test extends Strata_Query_UnitTestCase {
11*5153720fSfkaag71
12*5153720fSfkaag71    function setup() {
13*5153720fSfkaag71        parent::setup();
14*5153720fSfkaag71
15*5153720fSfkaag71        $this->_isPerson =  array (
16*5153720fSfkaag71            'type' => 'triple',
17*5153720fSfkaag71            'subject' => array (
18*5153720fSfkaag71                'type' => 'variable',
19*5153720fSfkaag71                'text' => 'p'
20*5153720fSfkaag71            ),
21*5153720fSfkaag71            'predicate' => array (
22*5153720fSfkaag71                'type' => 'literal',
23*5153720fSfkaag71                'text' => 'class'
24*5153720fSfkaag71            ),
25*5153720fSfkaag71            'object' => array (
26*5153720fSfkaag71                'type' => 'literal',
27*5153720fSfkaag71                'text' => 'person'
28*5153720fSfkaag71            )
29*5153720fSfkaag71        );
30*5153720fSfkaag71        $this->_personBob = array (
31*5153720fSfkaag71            'type' => 'triple',
32*5153720fSfkaag71            'subject' => array (
33*5153720fSfkaag71                'type' => 'variable',
34*5153720fSfkaag71                'text' => 'p'
35*5153720fSfkaag71            ),
36*5153720fSfkaag71            'predicate' => array (
37*5153720fSfkaag71                'type' => 'literal',
38*5153720fSfkaag71                'text' => 'name'
39*5153720fSfkaag71            ),
40*5153720fSfkaag71            'object' => array (
41*5153720fSfkaag71                'type' => 'literal',
42*5153720fSfkaag71                'text' => 'Bob'
43*5153720fSfkaag71            )
44*5153720fSfkaag71        );
45*5153720fSfkaag71        $this->_personAlice = array (
46*5153720fSfkaag71            'type' => 'triple',
47*5153720fSfkaag71            'subject' => array (
48*5153720fSfkaag71                'type' => 'variable',
49*5153720fSfkaag71                'text' => 'p'
50*5153720fSfkaag71            ),
51*5153720fSfkaag71            'predicate' => array (
52*5153720fSfkaag71                'type' => 'literal',
53*5153720fSfkaag71                'text' => 'name'
54*5153720fSfkaag71            ),
55*5153720fSfkaag71            'object' => array (
56*5153720fSfkaag71                'type' => 'literal',
57*5153720fSfkaag71                'text' => 'Alice'
58*5153720fSfkaag71            )
59*5153720fSfkaag71        );
60*5153720fSfkaag71        $this->_personCarol = array (
61*5153720fSfkaag71            'type' => 'triple',
62*5153720fSfkaag71            'subject' => array (
63*5153720fSfkaag71                'type' => 'variable',
64*5153720fSfkaag71                'text' => 'p'
65*5153720fSfkaag71            ),
66*5153720fSfkaag71            'predicate' => array (
67*5153720fSfkaag71                'type' => 'literal',
68*5153720fSfkaag71                'text' => 'name'
69*5153720fSfkaag71            ),
70*5153720fSfkaag71            'object' => array (
71*5153720fSfkaag71                'type' => 'literal',
72*5153720fSfkaag71                'text' => 'Carol'
73*5153720fSfkaag71            )
74*5153720fSfkaag71        );
75*5153720fSfkaag71        $this->_bobUnionAlice =  array (
76*5153720fSfkaag71            'type' => 'union',
77*5153720fSfkaag71            'lhs' => $this->_personBob,
78*5153720fSfkaag71            'rhs' => $this->_personAlice
79*5153720fSfkaag71        );
80*5153720fSfkaag71        $this->_personRating = array (
81*5153720fSfkaag71            'type' => 'triple',
82*5153720fSfkaag71            'subject' => array (
83*5153720fSfkaag71                'type' => 'variable',
84*5153720fSfkaag71                'text' => 'p'
85*5153720fSfkaag71            ),
86*5153720fSfkaag71            'predicate' => array (
87*5153720fSfkaag71                'type' => 'literal',
88*5153720fSfkaag71                'text' => 'is rated'
89*5153720fSfkaag71            ),
90*5153720fSfkaag71            'object' => array (
91*5153720fSfkaag71                'type' => 'variable',
92*5153720fSfkaag71                'text' => 'rating'
93*5153720fSfkaag71            )
94*5153720fSfkaag71        );
95*5153720fSfkaag71        $this->_personKnows = array (
96*5153720fSfkaag71            'type' => 'triple',
97*5153720fSfkaag71            'subject' => array (
98*5153720fSfkaag71                'type' => 'variable',
99*5153720fSfkaag71                'text' => 'p'
100*5153720fSfkaag71            ),
101*5153720fSfkaag71            'predicate' => array (
102*5153720fSfkaag71                'type' => 'literal',
103*5153720fSfkaag71                'text' => 'knows'
104*5153720fSfkaag71            ),
105*5153720fSfkaag71            'object' => array (
106*5153720fSfkaag71                'type' => 'variable',
107*5153720fSfkaag71                'text' => 'knows'
108*5153720fSfkaag71            )
109*5153720fSfkaag71        );
110*5153720fSfkaag71        $this->_personLikes = array (
111*5153720fSfkaag71            'type' => 'triple',
112*5153720fSfkaag71            'subject' => array (
113*5153720fSfkaag71                'type' => 'variable',
114*5153720fSfkaag71                'text' => 'p'
115*5153720fSfkaag71            ),
116*5153720fSfkaag71            'predicate' => array (
117*5153720fSfkaag71                'type' => 'literal',
118*5153720fSfkaag71                'text' => 'likes'
119*5153720fSfkaag71            ),
120*5153720fSfkaag71            'object' => array (
121*5153720fSfkaag71                'type' => 'variable',
122*5153720fSfkaag71                'text' => 'likes'
123*5153720fSfkaag71            )
124*5153720fSfkaag71        );
125*5153720fSfkaag71        $this->_ratingMinusCarol =  array (
126*5153720fSfkaag71            'type' => 'minus',
127*5153720fSfkaag71            'lhs' => $this->_personRating,
128*5153720fSfkaag71            'rhs' => $this->_personCarol
129*5153720fSfkaag71        );
130*5153720fSfkaag71        $this->_knowsOptionalLikes =  array (
131*5153720fSfkaag71            'type' => 'optional',
132*5153720fSfkaag71            'lhs' => $this->_personKnows,
133*5153720fSfkaag71            'rhs' => $this->_personLikes
134*5153720fSfkaag71        );
135*5153720fSfkaag71    }
136*5153720fSfkaag71
137*5153720fSfkaag71    function testAllPersonsOnce() {
138*5153720fSfkaag71        $query = array (
139*5153720fSfkaag71            'type' => 'select',
140*5153720fSfkaag71            'grouping'=>array(),
141*5153720fSfkaag71            'group' => array (
142*5153720fSfkaag71                'type' => 'and',
143*5153720fSfkaag71                'lhs' => array (
144*5153720fSfkaag71                    'type' => 'and',
145*5153720fSfkaag71                    'lhs' => array (
146*5153720fSfkaag71                        'type' => 'and',
147*5153720fSfkaag71                        'lhs' => array (
148*5153720fSfkaag71                            'type' => 'and',
149*5153720fSfkaag71                            'lhs' => $this->_isPerson,
150*5153720fSfkaag71                            'rhs' => array (
151*5153720fSfkaag71                                'type' => 'triple',
152*5153720fSfkaag71                                'subject' => array (
153*5153720fSfkaag71                                    'type' => 'variable',
154*5153720fSfkaag71                                    'text' => 'p'
155*5153720fSfkaag71                                ),
156*5153720fSfkaag71                                'predicate' => array (
157*5153720fSfkaag71                                    'type' => 'literal',
158*5153720fSfkaag71                                    'text' => 'looks like'
159*5153720fSfkaag71                                ),
160*5153720fSfkaag71                                'object' => array (
161*5153720fSfkaag71                                    'type' => 'variable',
162*5153720fSfkaag71                                    'text' => 'img'
163*5153720fSfkaag71                                )
164*5153720fSfkaag71                            )
165*5153720fSfkaag71                        ),
166*5153720fSfkaag71                        'rhs' => $this->_personRating
167*5153720fSfkaag71                    ),
168*5153720fSfkaag71                    'rhs' => array (
169*5153720fSfkaag71                        'type' => 'triple',
170*5153720fSfkaag71                        'subject' => array (
171*5153720fSfkaag71                            'type' => 'variable',
172*5153720fSfkaag71                            'text' => 'p'
173*5153720fSfkaag71                        ),
174*5153720fSfkaag71                        'predicate' => array (
175*5153720fSfkaag71                            'type' => 'literal',
176*5153720fSfkaag71                            'text' => 'has length'
177*5153720fSfkaag71                        ),
178*5153720fSfkaag71                        'object' => array (
179*5153720fSfkaag71                            'type' => 'variable',
180*5153720fSfkaag71                            'text' => 'length'
181*5153720fSfkaag71                        )
182*5153720fSfkaag71                    )
183*5153720fSfkaag71                ),
184*5153720fSfkaag71                'rhs' => array (
185*5153720fSfkaag71                    'type' => 'triple',
186*5153720fSfkaag71                    'subject' => array (
187*5153720fSfkaag71                        'type' => 'variable',
188*5153720fSfkaag71                        'text' => 'p'
189*5153720fSfkaag71                    ),
190*5153720fSfkaag71                    'predicate' => array (
191*5153720fSfkaag71                        'type' => 'literal',
192*5153720fSfkaag71                        'text' => 'tax rate'
193*5153720fSfkaag71                    ),
194*5153720fSfkaag71                    'object' => array (
195*5153720fSfkaag71                        'type' => 'variable',
196*5153720fSfkaag71                        'text' => 'tax'
197*5153720fSfkaag71                    )
198*5153720fSfkaag71                )
199*5153720fSfkaag71            ),
200*5153720fSfkaag71            'projection' => array (
201*5153720fSfkaag71                'p',
202*5153720fSfkaag71                'img',
203*5153720fSfkaag71                'rating',
204*5153720fSfkaag71                'length',
205*5153720fSfkaag71                'tax'
206*5153720fSfkaag71            ),
207*5153720fSfkaag71            'ordering' => array (
208*5153720fSfkaag71                array (
209*5153720fSfkaag71                    'variable' => 'p',
210*5153720fSfkaag71                    'direction' => 'asc'
211*5153720fSfkaag71                )
212*5153720fSfkaag71            )
213*5153720fSfkaag71        );
214*5153720fSfkaag71
215*5153720fSfkaag71        $expected = array (
216*5153720fSfkaag71            array (
217*5153720fSfkaag71                'p' => array('person:alice'),
218*5153720fSfkaag71                'img' => array('50:alice.svg'),
219*5153720fSfkaag71                'rating' => array('10'),
220*5153720fSfkaag71                'length' => array('5 ft 5 in'),
221*5153720fSfkaag71                'tax' => array('10%')
222*5153720fSfkaag71            ),
223*5153720fSfkaag71            array (
224*5153720fSfkaag71                'p' => array('person:bob'),
225*5153720fSfkaag71                'img' => array('50:bob.png'),
226*5153720fSfkaag71                'rating' => array('8'),
227*5153720fSfkaag71                'length' => array('5 ft 10 in'),
228*5153720fSfkaag71                'tax' => array('25%')
229*5153720fSfkaag71            ),
230*5153720fSfkaag71            array (
231*5153720fSfkaag71                'p' => array('person:carol'),
232*5153720fSfkaag71                'img' => array('50:carol.jpg'),
233*5153720fSfkaag71                'rating' => array('1'),
234*5153720fSfkaag71                'length' => array('4 ft 11 in'),
235*5153720fSfkaag71                'tax' => array('2%')
236*5153720fSfkaag71            )
237*5153720fSfkaag71        );
238*5153720fSfkaag71
239*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
240*5153720fSfkaag71    }
241*5153720fSfkaag71
242*5153720fSfkaag71    function testAllPersons() {
243*5153720fSfkaag71        $query = array (
244*5153720fSfkaag71            'type' => 'select',
245*5153720fSfkaag71            'grouping'=>array(),
246*5153720fSfkaag71            'group' => array (
247*5153720fSfkaag71                'type' => 'and',
248*5153720fSfkaag71                'lhs' => array (
249*5153720fSfkaag71                    'type' => 'and',
250*5153720fSfkaag71                    'lhs' => array (
251*5153720fSfkaag71                        'type' => 'and',
252*5153720fSfkaag71                        'lhs' => array (
253*5153720fSfkaag71                            'type' => 'and',
254*5153720fSfkaag71                            'lhs' => array (
255*5153720fSfkaag71                                'type' => 'and',
256*5153720fSfkaag71                                'lhs' => $this->_isPerson,
257*5153720fSfkaag71                                'rhs' => $this->_personKnows
258*5153720fSfkaag71                            ),
259*5153720fSfkaag71                            'rhs' => array (
260*5153720fSfkaag71                                'type' => 'triple',
261*5153720fSfkaag71                                'subject' => array (
262*5153720fSfkaag71                                    'type' => 'variable',
263*5153720fSfkaag71                                    'text' => 'p'
264*5153720fSfkaag71                                ),
265*5153720fSfkaag71                                'predicate' => array (
266*5153720fSfkaag71                                    'type' => 'literal',
267*5153720fSfkaag71                                    'text' => 'looks like'
268*5153720fSfkaag71                                ),
269*5153720fSfkaag71                                'object' => array (
270*5153720fSfkaag71                                    'type' => 'variable',
271*5153720fSfkaag71                                    'text' => 'img'
272*5153720fSfkaag71                                )
273*5153720fSfkaag71                            )
274*5153720fSfkaag71                        ),
275*5153720fSfkaag71                        'rhs' => $this->_personRating
276*5153720fSfkaag71                    ),
277*5153720fSfkaag71                    'rhs' => array (
278*5153720fSfkaag71                        'type' => 'triple',
279*5153720fSfkaag71                        'subject' => array (
280*5153720fSfkaag71                            'type' => 'variable',
281*5153720fSfkaag71                            'text' => 'p'
282*5153720fSfkaag71                        ),
283*5153720fSfkaag71                        'predicate' => array (
284*5153720fSfkaag71                            'type' => 'literal',
285*5153720fSfkaag71                            'text' => 'has length'
286*5153720fSfkaag71                        ),
287*5153720fSfkaag71                        'object' => array (
288*5153720fSfkaag71                            'type' => 'variable',
289*5153720fSfkaag71                            'text' => 'length'
290*5153720fSfkaag71                        )
291*5153720fSfkaag71                    )
292*5153720fSfkaag71                ),
293*5153720fSfkaag71                'rhs' => array (
294*5153720fSfkaag71                    'type' => 'triple',
295*5153720fSfkaag71                    'subject' => array (
296*5153720fSfkaag71                        'type' => 'variable',
297*5153720fSfkaag71                        'text' => 'p'
298*5153720fSfkaag71                    ),
299*5153720fSfkaag71                    'predicate' => array (
300*5153720fSfkaag71                        'type' => 'literal',
301*5153720fSfkaag71                        'text' => 'tax rate'
302*5153720fSfkaag71                    ),
303*5153720fSfkaag71                    'object' => array (
304*5153720fSfkaag71                        'type' => 'variable',
305*5153720fSfkaag71                        'text' => 'tax'
306*5153720fSfkaag71                    )
307*5153720fSfkaag71                )
308*5153720fSfkaag71            ),
309*5153720fSfkaag71            'projection' => array (
310*5153720fSfkaag71                'p',
311*5153720fSfkaag71                'knows',
312*5153720fSfkaag71                'img',
313*5153720fSfkaag71                'rating',
314*5153720fSfkaag71                'length',
315*5153720fSfkaag71                'tax'
316*5153720fSfkaag71            ),
317*5153720fSfkaag71            'ordering' => array (
318*5153720fSfkaag71                array (
319*5153720fSfkaag71                    'variable' => 'p',
320*5153720fSfkaag71                    'direction' => 'desc'
321*5153720fSfkaag71                ),
322*5153720fSfkaag71                array (
323*5153720fSfkaag71                    'variable' => 'knows',
324*5153720fSfkaag71                    'direction' => 'asc'
325*5153720fSfkaag71                )
326*5153720fSfkaag71            )
327*5153720fSfkaag71        );
328*5153720fSfkaag71
329*5153720fSfkaag71        $expected = array (
330*5153720fSfkaag71            array (
331*5153720fSfkaag71                'p' => array('person:carol'),
332*5153720fSfkaag71                'knows' => array('person:alice'),
333*5153720fSfkaag71                'img' => array('50:carol.jpg'),
334*5153720fSfkaag71                'rating' => array('1'),
335*5153720fSfkaag71                'length' => array('4 ft 11 in'),
336*5153720fSfkaag71                'tax' => array('2%')
337*5153720fSfkaag71            ),
338*5153720fSfkaag71            array (
339*5153720fSfkaag71                'p' => array('person:carol'),
340*5153720fSfkaag71                'knows' => array('person:bob'),
341*5153720fSfkaag71                'img' => array('50:carol.jpg'),
342*5153720fSfkaag71                'rating' => array('1'),
343*5153720fSfkaag71                'length' => array('4 ft 11 in'),
344*5153720fSfkaag71                'tax' => array('2%')
345*5153720fSfkaag71            ),
346*5153720fSfkaag71            array (
347*5153720fSfkaag71                'p' => array('person:bob'),
348*5153720fSfkaag71                'knows' => array('person:alice'),
349*5153720fSfkaag71                'img' => array('50:bob.png'),
350*5153720fSfkaag71                'rating' => array('8'),
351*5153720fSfkaag71                'length' => array('5 ft 10 in'),
352*5153720fSfkaag71                'tax' => array('25%')
353*5153720fSfkaag71            ),
354*5153720fSfkaag71            array (
355*5153720fSfkaag71                'p' => array('person:alice'),
356*5153720fSfkaag71                'knows' => array('person:carol'),
357*5153720fSfkaag71                'img' => array('50:alice.svg'),
358*5153720fSfkaag71                'rating' => array('10'),
359*5153720fSfkaag71                'length' => array('5 ft 5 in'),
360*5153720fSfkaag71                'tax' => array('10%')
361*5153720fSfkaag71            )
362*5153720fSfkaag71        );
363*5153720fSfkaag71
364*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
365*5153720fSfkaag71    }
366*5153720fSfkaag71
367*5153720fSfkaag71    function testAllPersonsExceptBob() {
368*5153720fSfkaag71        // All persons except Bob
369*5153720fSfkaag71        $query = array (
370*5153720fSfkaag71            'type' => 'select',
371*5153720fSfkaag71            'grouping'=>array(),
372*5153720fSfkaag71            'group' => array (
373*5153720fSfkaag71                'type' => 'minus',
374*5153720fSfkaag71                'lhs' => $this->_isPerson,
375*5153720fSfkaag71                'rhs' => $this->_personBob
376*5153720fSfkaag71            ),
377*5153720fSfkaag71            'projection' => array (
378*5153720fSfkaag71                'p'
379*5153720fSfkaag71            ),
380*5153720fSfkaag71            'ordering' => array (
381*5153720fSfkaag71                array (
382*5153720fSfkaag71                    'variable' => 'p',
383*5153720fSfkaag71                    'direction' => 'asc'
384*5153720fSfkaag71                )
385*5153720fSfkaag71            )
386*5153720fSfkaag71        );
387*5153720fSfkaag71
388*5153720fSfkaag71        $expected = array (
389*5153720fSfkaag71            array (
390*5153720fSfkaag71                'p' => array('person:alice')
391*5153720fSfkaag71            ),
392*5153720fSfkaag71            array (
393*5153720fSfkaag71                'p' => array('person:carol')
394*5153720fSfkaag71            )
395*5153720fSfkaag71        );
396*5153720fSfkaag71
397*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
398*5153720fSfkaag71    }
399*5153720fSfkaag71
400*5153720fSfkaag71    function testAllPersonsThatKnowAlice() {
401*5153720fSfkaag71        // All persons that know Alice
402*5153720fSfkaag71        $query = array (
403*5153720fSfkaag71            'type' => 'select',
404*5153720fSfkaag71            'grouping'=>array(),
405*5153720fSfkaag71            'group' => array (
406*5153720fSfkaag71                'type' => 'and',
407*5153720fSfkaag71                'lhs' => array (
408*5153720fSfkaag71                    'type' => 'and',
409*5153720fSfkaag71                    'lhs' => $this->_isPerson,
410*5153720fSfkaag71                    'rhs' => array (
411*5153720fSfkaag71                        'type' => 'triple',
412*5153720fSfkaag71                        'subject' => array (
413*5153720fSfkaag71                            'type' => 'variable',
414*5153720fSfkaag71                            'text' => 'p'
415*5153720fSfkaag71                        ),
416*5153720fSfkaag71                        'predicate' => array (
417*5153720fSfkaag71                            'type' => 'literal',
418*5153720fSfkaag71                            'text' => 'knows'
419*5153720fSfkaag71                        ),
420*5153720fSfkaag71                        'object' => array (
421*5153720fSfkaag71                            'type' => 'variable',
422*5153720fSfkaag71                            'text' => 'relation'
423*5153720fSfkaag71                        )
424*5153720fSfkaag71                    )
425*5153720fSfkaag71                ),
426*5153720fSfkaag71                'rhs' => array (
427*5153720fSfkaag71                    'type' => 'triple',
428*5153720fSfkaag71                    'subject' => array (
429*5153720fSfkaag71                        'type' => 'variable',
430*5153720fSfkaag71                        'text' => 'relation'
431*5153720fSfkaag71                    ),
432*5153720fSfkaag71                    'predicate' => array (
433*5153720fSfkaag71                        'type' => 'literal',
434*5153720fSfkaag71                        'text' => 'name'
435*5153720fSfkaag71                    ),
436*5153720fSfkaag71                    'object' => array (
437*5153720fSfkaag71                        'type' => 'literal',
438*5153720fSfkaag71                        'text' => 'Alice'
439*5153720fSfkaag71                    )
440*5153720fSfkaag71                )
441*5153720fSfkaag71            ),
442*5153720fSfkaag71            'projection' => array (
443*5153720fSfkaag71                'p'
444*5153720fSfkaag71            ),
445*5153720fSfkaag71            'ordering' => array (
446*5153720fSfkaag71                array (
447*5153720fSfkaag71                    'variable' => 'p',
448*5153720fSfkaag71                    'direction' => 'asc'
449*5153720fSfkaag71                )
450*5153720fSfkaag71            )
451*5153720fSfkaag71        );
452*5153720fSfkaag71
453*5153720fSfkaag71        $expected = array (
454*5153720fSfkaag71            array (
455*5153720fSfkaag71                'p' => array('person:bob')
456*5153720fSfkaag71            ),
457*5153720fSfkaag71            array (
458*5153720fSfkaag71                'p' => array('person:carol')
459*5153720fSfkaag71            )
460*5153720fSfkaag71        );
461*5153720fSfkaag71
462*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
463*5153720fSfkaag71    }
464*5153720fSfkaag71
465*5153720fSfkaag71    function testAllPersonsRelatedToAlice() {
466*5153720fSfkaag71        // All persons having some relation with Alice
467*5153720fSfkaag71        $query = array (
468*5153720fSfkaag71            'type' => 'select',
469*5153720fSfkaag71            'grouping'=>array(),
470*5153720fSfkaag71            'group' => array (
471*5153720fSfkaag71                'type' => 'and',
472*5153720fSfkaag71                'lhs' => array (
473*5153720fSfkaag71                    'type' => 'and',
474*5153720fSfkaag71                    'lhs' => $this->_isPerson,
475*5153720fSfkaag71                    'rhs' => array (
476*5153720fSfkaag71                        'type' => 'triple',
477*5153720fSfkaag71                        'subject' => array (
478*5153720fSfkaag71                            'type' => 'variable',
479*5153720fSfkaag71                            'text' => 'p'
480*5153720fSfkaag71                        ),
481*5153720fSfkaag71                        'predicate' => array (
482*5153720fSfkaag71                            'type' => 'variable',
483*5153720fSfkaag71                            'text' => 'relationWith'
484*5153720fSfkaag71                        ),
485*5153720fSfkaag71                        'object' => array (
486*5153720fSfkaag71                            'type' => 'variable',
487*5153720fSfkaag71                            'text' => 'relation'
488*5153720fSfkaag71                        )
489*5153720fSfkaag71                    )
490*5153720fSfkaag71                ),
491*5153720fSfkaag71                'rhs' => array (
492*5153720fSfkaag71                    'type' => 'triple',
493*5153720fSfkaag71                    'subject' => array (
494*5153720fSfkaag71                        'type' => 'variable',
495*5153720fSfkaag71                        'text' => 'relation'
496*5153720fSfkaag71                    ),
497*5153720fSfkaag71                    'predicate' => array (
498*5153720fSfkaag71                        'type' => 'literal',
499*5153720fSfkaag71                        'text' => 'name'
500*5153720fSfkaag71                    ),
501*5153720fSfkaag71                    'object' => array (
502*5153720fSfkaag71                        'type' => 'literal',
503*5153720fSfkaag71                        'text' => 'Alice'
504*5153720fSfkaag71                    )
505*5153720fSfkaag71                )
506*5153720fSfkaag71            ),
507*5153720fSfkaag71            'projection' => array (
508*5153720fSfkaag71                'p',
509*5153720fSfkaag71                'relationWith'
510*5153720fSfkaag71            ),
511*5153720fSfkaag71            'ordering' => array (
512*5153720fSfkaag71                array (
513*5153720fSfkaag71                    'variable' => 'p',
514*5153720fSfkaag71                    'direction' => 'asc'
515*5153720fSfkaag71                )
516*5153720fSfkaag71            )
517*5153720fSfkaag71        );
518*5153720fSfkaag71
519*5153720fSfkaag71        $expected = array (
520*5153720fSfkaag71            array (
521*5153720fSfkaag71                'p' => array('person:bob'),
522*5153720fSfkaag71                'relationWith' => array('knows')
523*5153720fSfkaag71            ),
524*5153720fSfkaag71            array (
525*5153720fSfkaag71                'p' => array('person:bob'),
526*5153720fSfkaag71                'relationWith' => array('likes')
527*5153720fSfkaag71            ),
528*5153720fSfkaag71            array (
529*5153720fSfkaag71                'p' => array('person:carol'),
530*5153720fSfkaag71                'relationWith' => array('knows')
531*5153720fSfkaag71            )
532*5153720fSfkaag71        );
533*5153720fSfkaag71
534*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
535*5153720fSfkaag71    }
536*5153720fSfkaag71
537*5153720fSfkaag71    function testAllPersonsAndRelationWithAlice() {
538*5153720fSfkaag71        // All persons, including their relation with Alice
539*5153720fSfkaag71        $query = array (
540*5153720fSfkaag71            'type' => 'select',
541*5153720fSfkaag71            'grouping'=>array(),
542*5153720fSfkaag71            'group' => array (
543*5153720fSfkaag71                'type' => 'optional',
544*5153720fSfkaag71                'lhs' => $this->_isPerson,
545*5153720fSfkaag71                'rhs' => array (
546*5153720fSfkaag71                    'type' => 'and',
547*5153720fSfkaag71                    'lhs' => array (
548*5153720fSfkaag71                        'type' => 'triple',
549*5153720fSfkaag71                        'subject' => array (
550*5153720fSfkaag71                            'type' => 'variable',
551*5153720fSfkaag71                            'text' => 'p'
552*5153720fSfkaag71                        ),
553*5153720fSfkaag71                        'predicate' => array (
554*5153720fSfkaag71                            'type' => 'variable',
555*5153720fSfkaag71                            'text' => 'relationWith'
556*5153720fSfkaag71                        ),
557*5153720fSfkaag71                        'object' => array (
558*5153720fSfkaag71                            'type' => 'variable',
559*5153720fSfkaag71                            'text' => 'relation'
560*5153720fSfkaag71                        )
561*5153720fSfkaag71                    ),
562*5153720fSfkaag71                    'rhs' => array (
563*5153720fSfkaag71                        'type' => 'triple',
564*5153720fSfkaag71                        'subject' => array (
565*5153720fSfkaag71                            'type' => 'variable',
566*5153720fSfkaag71                            'text' => 'relation'
567*5153720fSfkaag71                        ),
568*5153720fSfkaag71                        'predicate' => array (
569*5153720fSfkaag71                            'type' => 'literal',
570*5153720fSfkaag71                            'text' => 'name'
571*5153720fSfkaag71                        ),
572*5153720fSfkaag71                        'object' => array (
573*5153720fSfkaag71                            'type' => 'literal',
574*5153720fSfkaag71                            'text' => 'Alice'
575*5153720fSfkaag71                        )
576*5153720fSfkaag71                    )
577*5153720fSfkaag71                )
578*5153720fSfkaag71            ),
579*5153720fSfkaag71            'projection' => array (
580*5153720fSfkaag71                'p',
581*5153720fSfkaag71                'relationWith'
582*5153720fSfkaag71            ),
583*5153720fSfkaag71            'ordering' => array (
584*5153720fSfkaag71                array (
585*5153720fSfkaag71                    'variable' => 'p',
586*5153720fSfkaag71                    'direction' => 'asc'
587*5153720fSfkaag71                )
588*5153720fSfkaag71            )
589*5153720fSfkaag71        );
590*5153720fSfkaag71
591*5153720fSfkaag71        $expected = array (
592*5153720fSfkaag71            array (
593*5153720fSfkaag71                'p' => array('person:alice'),
594*5153720fSfkaag71                'relationWith' => array()
595*5153720fSfkaag71            ),
596*5153720fSfkaag71            array (
597*5153720fSfkaag71                'p' => array('person:bob'),
598*5153720fSfkaag71                'relationWith' => array('knows')
599*5153720fSfkaag71            ),
600*5153720fSfkaag71            array (
601*5153720fSfkaag71                'p' => array('person:bob'),
602*5153720fSfkaag71                'relationWith' => array('likes')
603*5153720fSfkaag71            ),
604*5153720fSfkaag71            array (
605*5153720fSfkaag71                'p' => array('person:carol'),
606*5153720fSfkaag71                'relationWith' => array('knows')
607*5153720fSfkaag71            )
608*5153720fSfkaag71        );
609*5153720fSfkaag71
610*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
611*5153720fSfkaag71    }
612*5153720fSfkaag71
613*5153720fSfkaag71    function testAllPersonsAndSpecialRelationWithAlice() {
614*5153720fSfkaag71        // All persons, including their relation with Alice (unless this relation is 'knows')
615*5153720fSfkaag71        $query = array (
616*5153720fSfkaag71            'type' => 'select',
617*5153720fSfkaag71            'grouping'=>array(),
618*5153720fSfkaag71            'group' => array (
619*5153720fSfkaag71                'type' => 'optional',
620*5153720fSfkaag71                'lhs' => $this->_isPerson,
621*5153720fSfkaag71                'rhs' => array (
622*5153720fSfkaag71                    'type' => 'filter',
623*5153720fSfkaag71                    'lhs' => array (
624*5153720fSfkaag71                        'type' => 'and',
625*5153720fSfkaag71                        'lhs' => array (
626*5153720fSfkaag71                            'type' => 'triple',
627*5153720fSfkaag71                            'subject' => array (
628*5153720fSfkaag71                                'type' => 'variable',
629*5153720fSfkaag71                                'text' => 'p'
630*5153720fSfkaag71                            ),
631*5153720fSfkaag71                            'predicate' => array (
632*5153720fSfkaag71                                'type' => 'variable',
633*5153720fSfkaag71                                'text' => 'relationWith'
634*5153720fSfkaag71                            ),
635*5153720fSfkaag71                            'object' => array (
636*5153720fSfkaag71                                'type' => 'variable',
637*5153720fSfkaag71                                'text' => 'relation'
638*5153720fSfkaag71                            )
639*5153720fSfkaag71                        ),
640*5153720fSfkaag71                        'rhs' => array (
641*5153720fSfkaag71                            'type' => 'triple',
642*5153720fSfkaag71                            'subject' => array (
643*5153720fSfkaag71                                'type' => 'variable',
644*5153720fSfkaag71                                'text' => 'relation'
645*5153720fSfkaag71                            ),
646*5153720fSfkaag71                            'predicate' => array (
647*5153720fSfkaag71                                'type' => 'literal',
648*5153720fSfkaag71                                'text' => 'name'
649*5153720fSfkaag71                            ),
650*5153720fSfkaag71                            'object' => array (
651*5153720fSfkaag71                                'type' => 'literal',
652*5153720fSfkaag71                                'text' => 'Alice'
653*5153720fSfkaag71                            )
654*5153720fSfkaag71                        )
655*5153720fSfkaag71                    ),
656*5153720fSfkaag71                    'rhs' => array (
657*5153720fSfkaag71                        array (
658*5153720fSfkaag71                            'type' => 'filter',
659*5153720fSfkaag71                            'lhs' => array (
660*5153720fSfkaag71                                'type' => 'variable',
661*5153720fSfkaag71                                'text' => 'relationWith'
662*5153720fSfkaag71                            ),
663*5153720fSfkaag71                            'operator' => '!=',
664*5153720fSfkaag71                            'rhs' => array (
665*5153720fSfkaag71                                'type' => 'literal',
666*5153720fSfkaag71                                'text' => 'knows'
667*5153720fSfkaag71                            )
668*5153720fSfkaag71                        )
669*5153720fSfkaag71                    )
670*5153720fSfkaag71                )
671*5153720fSfkaag71            ),
672*5153720fSfkaag71            'projection' => array (
673*5153720fSfkaag71                'p',
674*5153720fSfkaag71                'relationWith'
675*5153720fSfkaag71            ),
676*5153720fSfkaag71            'ordering' => array (
677*5153720fSfkaag71                array (
678*5153720fSfkaag71                    'variable' => 'p',
679*5153720fSfkaag71                    'direction' => 'asc'
680*5153720fSfkaag71                )
681*5153720fSfkaag71            )
682*5153720fSfkaag71        );
683*5153720fSfkaag71
684*5153720fSfkaag71        $expected = array (
685*5153720fSfkaag71            array (
686*5153720fSfkaag71                'p' => array('person:alice'),
687*5153720fSfkaag71                'relationWith' => array()
688*5153720fSfkaag71            ),
689*5153720fSfkaag71            array (
690*5153720fSfkaag71                'p' => array('person:bob'),
691*5153720fSfkaag71                'relationWith' => array('likes')
692*5153720fSfkaag71            ),
693*5153720fSfkaag71            array (
694*5153720fSfkaag71                'p' => array('person:carol'),
695*5153720fSfkaag71                'relationWith' => array()
696*5153720fSfkaag71            )
697*5153720fSfkaag71        );
698*5153720fSfkaag71
699*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
700*5153720fSfkaag71    }
701*5153720fSfkaag71
702*5153720fSfkaag71    function testAllPersonsSpecialRelationWithAlice() {
703*5153720fSfkaag71        // All persons having a relation with Alice that is not 'knows'
704*5153720fSfkaag71        $query = array (
705*5153720fSfkaag71            'type' => 'select',
706*5153720fSfkaag71            'grouping'=>array(),
707*5153720fSfkaag71            'group' => array (
708*5153720fSfkaag71                'type' => 'filter',
709*5153720fSfkaag71                'lhs' => array (
710*5153720fSfkaag71                    'type' => 'and',
711*5153720fSfkaag71                    'lhs' => array (
712*5153720fSfkaag71                        'type' => 'and',
713*5153720fSfkaag71                        'lhs' => $this->_isPerson,
714*5153720fSfkaag71                        'rhs' => array (
715*5153720fSfkaag71                            'type' => 'triple',
716*5153720fSfkaag71                            'subject' => array (
717*5153720fSfkaag71                                'type' => 'variable',
718*5153720fSfkaag71                                'text' => 'p'
719*5153720fSfkaag71                            ),
720*5153720fSfkaag71                            'predicate' => array (
721*5153720fSfkaag71                                'type' => 'variable',
722*5153720fSfkaag71                                'text' => 'relationWith'
723*5153720fSfkaag71                            ),
724*5153720fSfkaag71                            'object' => array (
725*5153720fSfkaag71                                'type' => 'variable',
726*5153720fSfkaag71                                'text' => 'relation'
727*5153720fSfkaag71                            )
728*5153720fSfkaag71                        )
729*5153720fSfkaag71                    ),
730*5153720fSfkaag71                    'rhs' => array (
731*5153720fSfkaag71                        'type' => 'triple',
732*5153720fSfkaag71                        'subject' => array (
733*5153720fSfkaag71                            'type' => 'variable',
734*5153720fSfkaag71                            'text' => 'relation'
735*5153720fSfkaag71                        ),
736*5153720fSfkaag71                        'predicate' => array (
737*5153720fSfkaag71                            'type' => 'literal',
738*5153720fSfkaag71                            'text' => 'name'
739*5153720fSfkaag71                        ),
740*5153720fSfkaag71                        'object' => array (
741*5153720fSfkaag71                            'type' => 'literal',
742*5153720fSfkaag71                            'text' => 'Alice'
743*5153720fSfkaag71                        )
744*5153720fSfkaag71                    )
745*5153720fSfkaag71                ),
746*5153720fSfkaag71                'rhs' => array (
747*5153720fSfkaag71                    array (
748*5153720fSfkaag71                        'type' => 'filter',
749*5153720fSfkaag71                        'lhs' => array (
750*5153720fSfkaag71                            'type' => 'variable',
751*5153720fSfkaag71                            'text' => 'relationWith'
752*5153720fSfkaag71                        ),
753*5153720fSfkaag71                        'operator' => '!=',
754*5153720fSfkaag71                        'rhs' => array (
755*5153720fSfkaag71                            'type' => 'literal',
756*5153720fSfkaag71                            'text' => 'knows'
757*5153720fSfkaag71                        )
758*5153720fSfkaag71                    )
759*5153720fSfkaag71                )
760*5153720fSfkaag71            ),
761*5153720fSfkaag71            'projection' => array (
762*5153720fSfkaag71                'p',
763*5153720fSfkaag71                'relationWith'
764*5153720fSfkaag71            ),
765*5153720fSfkaag71            'ordering' => array (
766*5153720fSfkaag71                array (
767*5153720fSfkaag71                    'variable' => 'p',
768*5153720fSfkaag71                    'direction' => 'asc'
769*5153720fSfkaag71                )
770*5153720fSfkaag71            )
771*5153720fSfkaag71        );
772*5153720fSfkaag71
773*5153720fSfkaag71        $expected = array (
774*5153720fSfkaag71            array (
775*5153720fSfkaag71                'p' => array('person:bob'),
776*5153720fSfkaag71                'relationWith' => array('likes')
777*5153720fSfkaag71            )
778*5153720fSfkaag71        );
779*5153720fSfkaag71
780*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
781*5153720fSfkaag71    }
782*5153720fSfkaag71
783*5153720fSfkaag71    function testBobUnionAlice() {
784*5153720fSfkaag71        $query = array (
785*5153720fSfkaag71            'type' => 'select',
786*5153720fSfkaag71            'grouping'=>array(),
787*5153720fSfkaag71            'group' => $this->_bobUnionAlice,
788*5153720fSfkaag71            'projection' => array (
789*5153720fSfkaag71                'p'
790*5153720fSfkaag71            ),
791*5153720fSfkaag71            'ordering' => array (
792*5153720fSfkaag71                array (
793*5153720fSfkaag71                    'variable' => 'p',
794*5153720fSfkaag71                    'direction' => 'asc'
795*5153720fSfkaag71                )
796*5153720fSfkaag71            )
797*5153720fSfkaag71        );
798*5153720fSfkaag71
799*5153720fSfkaag71        $expected = array (
800*5153720fSfkaag71            array (
801*5153720fSfkaag71                'p' => array('person:alice')
802*5153720fSfkaag71            ),
803*5153720fSfkaag71            array (
804*5153720fSfkaag71                'p' => array('person:bob')
805*5153720fSfkaag71            )
806*5153720fSfkaag71        );
807*5153720fSfkaag71
808*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
809*5153720fSfkaag71    }
810*5153720fSfkaag71
811*5153720fSfkaag71    function testBobUnionAliceWithRating() {
812*5153720fSfkaag71        $query = array (
813*5153720fSfkaag71            'type' => 'select',
814*5153720fSfkaag71            'grouping'=>array(),
815*5153720fSfkaag71            'group' => array (
816*5153720fSfkaag71                'type' => 'union',
817*5153720fSfkaag71                'lhs' => array (
818*5153720fSfkaag71                    'type' => 'and',
819*5153720fSfkaag71                    'lhs' => $this->_personBob,
820*5153720fSfkaag71                    'rhs' => $this->_personRating
821*5153720fSfkaag71                ),
822*5153720fSfkaag71                'rhs' => array (
823*5153720fSfkaag71                    'type' => 'and',
824*5153720fSfkaag71                    'lhs' => $this->_personAlice,
825*5153720fSfkaag71                    'rhs' => $this->_personRating
826*5153720fSfkaag71                ),
827*5153720fSfkaag71            ),
828*5153720fSfkaag71            'projection' => array (
829*5153720fSfkaag71                'p',
830*5153720fSfkaag71                'rating'
831*5153720fSfkaag71            ),
832*5153720fSfkaag71            'ordering' => array (
833*5153720fSfkaag71                array (
834*5153720fSfkaag71                    'variable' => 'p',
835*5153720fSfkaag71                    'direction' => 'asc'
836*5153720fSfkaag71                )
837*5153720fSfkaag71            )
838*5153720fSfkaag71        );
839*5153720fSfkaag71
840*5153720fSfkaag71        $expected = array (
841*5153720fSfkaag71            array (
842*5153720fSfkaag71                'p' => array('person:alice'),
843*5153720fSfkaag71                'rating' => array('10')
844*5153720fSfkaag71            ),
845*5153720fSfkaag71            array (
846*5153720fSfkaag71                'p' => array('person:bob'),
847*5153720fSfkaag71                'rating' => array('8')
848*5153720fSfkaag71            )
849*5153720fSfkaag71        );
850*5153720fSfkaag71
851*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
852*5153720fSfkaag71    }
853*5153720fSfkaag71
854*5153720fSfkaag71    function testCarolUnionBobUnionAlice() {
855*5153720fSfkaag71        $query = array (
856*5153720fSfkaag71            'type' => 'select',
857*5153720fSfkaag71            'grouping'=>array(),
858*5153720fSfkaag71            'group' => array (
859*5153720fSfkaag71                'type' => 'union',
860*5153720fSfkaag71                'lhs' => $this->_personCarol,
861*5153720fSfkaag71                'rhs' => $this->_bobUnionAlice
862*5153720fSfkaag71            ),
863*5153720fSfkaag71            'projection' => array (
864*5153720fSfkaag71                'p'
865*5153720fSfkaag71            ),
866*5153720fSfkaag71            'ordering' => array (
867*5153720fSfkaag71                array (
868*5153720fSfkaag71                    'variable' => 'p',
869*5153720fSfkaag71                    'direction' => 'asc'
870*5153720fSfkaag71                )
871*5153720fSfkaag71            )
872*5153720fSfkaag71        );
873*5153720fSfkaag71
874*5153720fSfkaag71        $expected = array (
875*5153720fSfkaag71            array (
876*5153720fSfkaag71                'p' => array('person:alice')
877*5153720fSfkaag71            ),
878*5153720fSfkaag71            array (
879*5153720fSfkaag71                'p' => array('person:bob')
880*5153720fSfkaag71            ),
881*5153720fSfkaag71            array (
882*5153720fSfkaag71                'p' => array('person:carol')
883*5153720fSfkaag71            )
884*5153720fSfkaag71        );
885*5153720fSfkaag71
886*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
887*5153720fSfkaag71    }
888*5153720fSfkaag71
889*5153720fSfkaag71    function testBobUnionBobUnionAlice() {
890*5153720fSfkaag71        $query = array (
891*5153720fSfkaag71            'type' => 'select',
892*5153720fSfkaag71            'grouping'=>array(),
893*5153720fSfkaag71            'group' => array (
894*5153720fSfkaag71                'type' => 'union',
895*5153720fSfkaag71                'lhs' => $this->_personBob,
896*5153720fSfkaag71                'rhs' => $this->_bobUnionAlice
897*5153720fSfkaag71            ),
898*5153720fSfkaag71            'projection' => array (
899*5153720fSfkaag71                'p'
900*5153720fSfkaag71            ),
901*5153720fSfkaag71            'ordering' => array (
902*5153720fSfkaag71                array (
903*5153720fSfkaag71                    'variable' => 'p',
904*5153720fSfkaag71                    'direction' => 'asc'
905*5153720fSfkaag71                )
906*5153720fSfkaag71            )
907*5153720fSfkaag71        );
908*5153720fSfkaag71
909*5153720fSfkaag71        $expected = array (
910*5153720fSfkaag71            array (
911*5153720fSfkaag71                'p' => array('person:alice')
912*5153720fSfkaag71            ),
913*5153720fSfkaag71            array (
914*5153720fSfkaag71                'p' => array('person:bob')
915*5153720fSfkaag71            )
916*5153720fSfkaag71        );
917*5153720fSfkaag71
918*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
919*5153720fSfkaag71    }
920*5153720fSfkaag71
921*5153720fSfkaag71    function testCarolUnionBobUnionAliceMinusBob() {
922*5153720fSfkaag71        $query = array (
923*5153720fSfkaag71            'type' => 'select',
924*5153720fSfkaag71            'grouping'=>array(),
925*5153720fSfkaag71            'group' => array (
926*5153720fSfkaag71                'type' => 'union',
927*5153720fSfkaag71                'lhs' => $this->_personCarol,
928*5153720fSfkaag71                'rhs' => array (
929*5153720fSfkaag71                    'type' => 'minus',
930*5153720fSfkaag71                    'lhs' => $this->_bobUnionAlice,
931*5153720fSfkaag71                    'rhs' => $this->_personBob
932*5153720fSfkaag71                )
933*5153720fSfkaag71            ),
934*5153720fSfkaag71            'projection' => array (
935*5153720fSfkaag71                'p'
936*5153720fSfkaag71            ),
937*5153720fSfkaag71            'ordering' => array (
938*5153720fSfkaag71                array (
939*5153720fSfkaag71                    'variable' => 'p',
940*5153720fSfkaag71                    'direction' => 'asc'
941*5153720fSfkaag71                )
942*5153720fSfkaag71            )
943*5153720fSfkaag71        );
944*5153720fSfkaag71
945*5153720fSfkaag71        $expected = array (
946*5153720fSfkaag71            array (
947*5153720fSfkaag71                'p' => array('person:alice')
948*5153720fSfkaag71            ),
949*5153720fSfkaag71            array (
950*5153720fSfkaag71                'p' => array('person:carol')
951*5153720fSfkaag71            )
952*5153720fSfkaag71        );
953*5153720fSfkaag71
954*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
955*5153720fSfkaag71    }
956*5153720fSfkaag71
957*5153720fSfkaag71    function testBobUnionAliceOptionalRating() {
958*5153720fSfkaag71        $query = array (
959*5153720fSfkaag71            'type' => 'select',
960*5153720fSfkaag71            'grouping'=>array(),
961*5153720fSfkaag71            'group' => array (
962*5153720fSfkaag71                'type' => 'union',
963*5153720fSfkaag71                'lhs' => $this->_personBob,
964*5153720fSfkaag71                'rhs' => array (
965*5153720fSfkaag71                    'type' => 'optional',
966*5153720fSfkaag71                    'lhs' => $this->_personAlice,
967*5153720fSfkaag71                    'rhs' => $this->_personRating
968*5153720fSfkaag71                )
969*5153720fSfkaag71            ),
970*5153720fSfkaag71            'projection' => array (
971*5153720fSfkaag71                'p',
972*5153720fSfkaag71                'rating'
973*5153720fSfkaag71            ),
974*5153720fSfkaag71            'ordering' => array (
975*5153720fSfkaag71                array (
976*5153720fSfkaag71                    'variable' => 'p',
977*5153720fSfkaag71                    'direction' => 'asc'
978*5153720fSfkaag71                )
979*5153720fSfkaag71            )
980*5153720fSfkaag71        );
981*5153720fSfkaag71
982*5153720fSfkaag71        $expected = array (
983*5153720fSfkaag71            array (
984*5153720fSfkaag71              'p' => array('person:alice'),
985*5153720fSfkaag71              'rating' => array('10')
986*5153720fSfkaag71            ),
987*5153720fSfkaag71            array (
988*5153720fSfkaag71              'p' => array('person:bob'),
989*5153720fSfkaag71              'rating' => array()
990*5153720fSfkaag71            )
991*5153720fSfkaag71        );
992*5153720fSfkaag71
993*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
994*5153720fSfkaag71    }
995*5153720fSfkaag71
996*5153720fSfkaag71    function testPersonOptionalKnowsAndLikes() {
997*5153720fSfkaag71        $query = array (
998*5153720fSfkaag71            'type' => 'select',
999*5153720fSfkaag71            'grouping'=>array(),
1000*5153720fSfkaag71            'group' => array (
1001*5153720fSfkaag71                'type' => 'optional',
1002*5153720fSfkaag71                'lhs' => $this->_isPerson,
1003*5153720fSfkaag71                'rhs' => array (
1004*5153720fSfkaag71                    'type' => 'and',
1005*5153720fSfkaag71                    'lhs' => $this->_personKnows,
1006*5153720fSfkaag71                    'rhs' => $this->_personLikes
1007*5153720fSfkaag71                )
1008*5153720fSfkaag71            ),
1009*5153720fSfkaag71            'projection' => array (
1010*5153720fSfkaag71                'p',
1011*5153720fSfkaag71                'knows',
1012*5153720fSfkaag71                'likes'
1013*5153720fSfkaag71            ),
1014*5153720fSfkaag71            'ordering' => array (
1015*5153720fSfkaag71                array (
1016*5153720fSfkaag71                    'variable' => 'p',
1017*5153720fSfkaag71                    'direction' => 'asc'
1018*5153720fSfkaag71                )
1019*5153720fSfkaag71            )
1020*5153720fSfkaag71        );
1021*5153720fSfkaag71
1022*5153720fSfkaag71        $expected = array (
1023*5153720fSfkaag71            array (
1024*5153720fSfkaag71                'p' => array('person:alice'),
1025*5153720fSfkaag71                'knows' => array(),
1026*5153720fSfkaag71                'likes' => array()
1027*5153720fSfkaag71            ),
1028*5153720fSfkaag71            array (
1029*5153720fSfkaag71                'p' => array('person:bob'),
1030*5153720fSfkaag71                'knows' => array('person:alice'),
1031*5153720fSfkaag71                'likes' => array('person:alice')
1032*5153720fSfkaag71            ),
1033*5153720fSfkaag71            array (
1034*5153720fSfkaag71                'p' => array('person:carol'),
1035*5153720fSfkaag71                'knows' => array(),
1036*5153720fSfkaag71                'likes' => array()
1037*5153720fSfkaag71            )
1038*5153720fSfkaag71        );
1039*5153720fSfkaag71
1040*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1041*5153720fSfkaag71    }
1042*5153720fSfkaag71
1043*5153720fSfkaag71    function testPersonOptionalKnowsOptionalLikes() {
1044*5153720fSfkaag71        $query = array (
1045*5153720fSfkaag71            'type' => 'select',
1046*5153720fSfkaag71            'grouping'=>array(),
1047*5153720fSfkaag71            'group' => array (
1048*5153720fSfkaag71                'type' => 'optional',
1049*5153720fSfkaag71                'lhs' => $this->_isPerson,
1050*5153720fSfkaag71                'rhs' => $this->_knowsOptionalLikes
1051*5153720fSfkaag71            ),
1052*5153720fSfkaag71            'projection' => array (
1053*5153720fSfkaag71                'p',
1054*5153720fSfkaag71                'knows',
1055*5153720fSfkaag71                'likes'
1056*5153720fSfkaag71            ),
1057*5153720fSfkaag71            'ordering' => array (
1058*5153720fSfkaag71                array (
1059*5153720fSfkaag71                    'variable' => 'p',
1060*5153720fSfkaag71                    'direction' => 'asc'
1061*5153720fSfkaag71                ),
1062*5153720fSfkaag71                array (
1063*5153720fSfkaag71                    'variable' => 'knows',
1064*5153720fSfkaag71                    'direction' => 'asc'
1065*5153720fSfkaag71                )
1066*5153720fSfkaag71            )
1067*5153720fSfkaag71        );
1068*5153720fSfkaag71
1069*5153720fSfkaag71        $expected = array (
1070*5153720fSfkaag71            array (
1071*5153720fSfkaag71                'p' => array('person:alice'),
1072*5153720fSfkaag71                'knows' => array('person:carol'),
1073*5153720fSfkaag71                'likes' => array()
1074*5153720fSfkaag71            ),
1075*5153720fSfkaag71            array (
1076*5153720fSfkaag71                'p' => array('person:bob'),
1077*5153720fSfkaag71                'knows' => array('person:alice'),
1078*5153720fSfkaag71                'likes' => array('person:alice')
1079*5153720fSfkaag71            ),
1080*5153720fSfkaag71            array (
1081*5153720fSfkaag71                'p' => array('person:carol'),
1082*5153720fSfkaag71                'knows' => array('person:alice'),
1083*5153720fSfkaag71                'likes' => array()
1084*5153720fSfkaag71            ),
1085*5153720fSfkaag71            array (
1086*5153720fSfkaag71                'p' => array('person:carol'),
1087*5153720fSfkaag71                'knows' => array('person:bob'),
1088*5153720fSfkaag71                'likes' => array()
1089*5153720fSfkaag71            )
1090*5153720fSfkaag71        );
1091*5153720fSfkaag71
1092*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1093*5153720fSfkaag71    }
1094*5153720fSfkaag71
1095*5153720fSfkaag71    function testPersonOptionalRatingUnionLikes() {
1096*5153720fSfkaag71        $query = array (
1097*5153720fSfkaag71            'type' => 'select',
1098*5153720fSfkaag71            'grouping'=>array(),
1099*5153720fSfkaag71            'group' => array (
1100*5153720fSfkaag71                'type' => 'optional',
1101*5153720fSfkaag71                'lhs' => $this->_isPerson,
1102*5153720fSfkaag71                'rhs' => array (
1103*5153720fSfkaag71                    'type' => 'union',
1104*5153720fSfkaag71                    'lhs' => $this->_personRating,
1105*5153720fSfkaag71                    'rhs' => array (
1106*5153720fSfkaag71                        'type' => 'and',
1107*5153720fSfkaag71                        'lhs' => array (
1108*5153720fSfkaag71                            'type' => 'triple',
1109*5153720fSfkaag71                            'subject' => array (
1110*5153720fSfkaag71                                'type' => 'variable',
1111*5153720fSfkaag71                                'text' => 'p'
1112*5153720fSfkaag71                            ),
1113*5153720fSfkaag71                            'predicate' => array (
1114*5153720fSfkaag71                                'type' => 'literal',
1115*5153720fSfkaag71                                'text' => 'likes'
1116*5153720fSfkaag71                            ),
1117*5153720fSfkaag71                            'object' => array (
1118*5153720fSfkaag71                                'type' => 'variable',
1119*5153720fSfkaag71                                'text' => 'rating'
1120*5153720fSfkaag71                            )
1121*5153720fSfkaag71                        ),
1122*5153720fSfkaag71                        'rhs' => array (
1123*5153720fSfkaag71                            'type' => 'triple',
1124*5153720fSfkaag71                            'subject' => array (
1125*5153720fSfkaag71                                'type' => 'variable',
1126*5153720fSfkaag71                                'text' => 'p'
1127*5153720fSfkaag71                            ),
1128*5153720fSfkaag71                            'predicate' => array (
1129*5153720fSfkaag71                                'type' => 'literal',
1130*5153720fSfkaag71                                'text' => 'likes'
1131*5153720fSfkaag71                            ),
1132*5153720fSfkaag71                            'object' => array (
1133*5153720fSfkaag71                                'type' => 'variable',
1134*5153720fSfkaag71                                'text' => 'likes'
1135*5153720fSfkaag71                            )
1136*5153720fSfkaag71                        )
1137*5153720fSfkaag71                    )
1138*5153720fSfkaag71                )
1139*5153720fSfkaag71            ),
1140*5153720fSfkaag71            'projection' => array (
1141*5153720fSfkaag71                'p',
1142*5153720fSfkaag71                'rating'
1143*5153720fSfkaag71            ),
1144*5153720fSfkaag71            'ordering' => array (
1145*5153720fSfkaag71                array (
1146*5153720fSfkaag71                    'variable' => 'p',
1147*5153720fSfkaag71                    'direction' => 'asc'
1148*5153720fSfkaag71                ),
1149*5153720fSfkaag71                array (
1150*5153720fSfkaag71                    'variable' => 'likes',
1151*5153720fSfkaag71                    'direction' => 'desc'
1152*5153720fSfkaag71                )
1153*5153720fSfkaag71            )
1154*5153720fSfkaag71        );
1155*5153720fSfkaag71
1156*5153720fSfkaag71        $expected = array (
1157*5153720fSfkaag71            array (
1158*5153720fSfkaag71                'p' => array('person:alice'),
1159*5153720fSfkaag71                'rating' => array('10')
1160*5153720fSfkaag71            ),
1161*5153720fSfkaag71            array (
1162*5153720fSfkaag71                'p' => array('person:bob'),
1163*5153720fSfkaag71                'rating' => array('person:alice')
1164*5153720fSfkaag71            ),
1165*5153720fSfkaag71            array (
1166*5153720fSfkaag71                'p' => array('person:bob'),
1167*5153720fSfkaag71                'rating' => array('8')
1168*5153720fSfkaag71            ),
1169*5153720fSfkaag71            array (
1170*5153720fSfkaag71                'p' => array('person:carol'),
1171*5153720fSfkaag71                'rating' => array('1')
1172*5153720fSfkaag71            )
1173*5153720fSfkaag71        );
1174*5153720fSfkaag71
1175*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1176*5153720fSfkaag71    }
1177*5153720fSfkaag71
1178*5153720fSfkaag71    function testPersonOptionalRatingMinusCarol() {
1179*5153720fSfkaag71        $query = array (
1180*5153720fSfkaag71            'type' => 'select',
1181*5153720fSfkaag71            'grouping'=>array(),
1182*5153720fSfkaag71            'group' => array (
1183*5153720fSfkaag71                'type' => 'optional',
1184*5153720fSfkaag71                'lhs' => $this->_isPerson,
1185*5153720fSfkaag71                'rhs' => $this->_ratingMinusCarol
1186*5153720fSfkaag71            ),
1187*5153720fSfkaag71            'projection' => array (
1188*5153720fSfkaag71                'p',
1189*5153720fSfkaag71                'rating'
1190*5153720fSfkaag71            ),
1191*5153720fSfkaag71            'ordering' => array (
1192*5153720fSfkaag71                array (
1193*5153720fSfkaag71                    'variable' => 'p',
1194*5153720fSfkaag71                    'direction' => 'asc'
1195*5153720fSfkaag71                )
1196*5153720fSfkaag71            )
1197*5153720fSfkaag71        );
1198*5153720fSfkaag71
1199*5153720fSfkaag71        $expected = array (
1200*5153720fSfkaag71            array (
1201*5153720fSfkaag71                'p' => array('person:alice'),
1202*5153720fSfkaag71                'rating' => array('10')
1203*5153720fSfkaag71            ),
1204*5153720fSfkaag71            array (
1205*5153720fSfkaag71                'p' => array('person:bob'),
1206*5153720fSfkaag71                'rating' => array('8')
1207*5153720fSfkaag71            ),
1208*5153720fSfkaag71            array (
1209*5153720fSfkaag71                'p' => array('person:carol'),
1210*5153720fSfkaag71                'rating' => array()
1211*5153720fSfkaag71            )
1212*5153720fSfkaag71        );
1213*5153720fSfkaag71
1214*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1215*5153720fSfkaag71    }
1216*5153720fSfkaag71
1217*5153720fSfkaag71    function testPersonMinusBobUnionAlice() {
1218*5153720fSfkaag71        $query = array (
1219*5153720fSfkaag71            'type' => 'select',
1220*5153720fSfkaag71            'grouping'=>array(),
1221*5153720fSfkaag71            'group' => array (
1222*5153720fSfkaag71                'type' => 'minus',
1223*5153720fSfkaag71                'lhs' => $this->_isPerson,
1224*5153720fSfkaag71                'rhs' => $this->_bobUnionAlice
1225*5153720fSfkaag71            ),
1226*5153720fSfkaag71            'projection' => array (
1227*5153720fSfkaag71                'p'
1228*5153720fSfkaag71            ),
1229*5153720fSfkaag71            'ordering' => array (
1230*5153720fSfkaag71                array (
1231*5153720fSfkaag71                    'variable' => 'p',
1232*5153720fSfkaag71                    'direction' => 'asc'
1233*5153720fSfkaag71                )
1234*5153720fSfkaag71            )
1235*5153720fSfkaag71        );
1236*5153720fSfkaag71
1237*5153720fSfkaag71        $expected = array (
1238*5153720fSfkaag71            array (
1239*5153720fSfkaag71                'p' => array('person:carol')
1240*5153720fSfkaag71            )
1241*5153720fSfkaag71        );
1242*5153720fSfkaag71
1243*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1244*5153720fSfkaag71    }
1245*5153720fSfkaag71
1246*5153720fSfkaag71    function testPersonMinusRatingMinusCarol() {
1247*5153720fSfkaag71        $query = array (
1248*5153720fSfkaag71            'type' => 'select',
1249*5153720fSfkaag71            'grouping'=>array(),
1250*5153720fSfkaag71            'group' => array (
1251*5153720fSfkaag71                'type' => 'minus',
1252*5153720fSfkaag71                'lhs' => $this->_isPerson,
1253*5153720fSfkaag71                'rhs' => $this->_ratingMinusCarol
1254*5153720fSfkaag71            ),
1255*5153720fSfkaag71            'projection' => array (
1256*5153720fSfkaag71                'p'
1257*5153720fSfkaag71            ),
1258*5153720fSfkaag71            'ordering' => array (
1259*5153720fSfkaag71                array (
1260*5153720fSfkaag71                    'variable' => 'p',
1261*5153720fSfkaag71                    'direction' => 'asc'
1262*5153720fSfkaag71                )
1263*5153720fSfkaag71            )
1264*5153720fSfkaag71        );
1265*5153720fSfkaag71
1266*5153720fSfkaag71        $expected = array (
1267*5153720fSfkaag71            array (
1268*5153720fSfkaag71                'p' => array('person:carol')
1269*5153720fSfkaag71            )
1270*5153720fSfkaag71        );
1271*5153720fSfkaag71
1272*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1273*5153720fSfkaag71    }
1274*5153720fSfkaag71
1275*5153720fSfkaag71    function testPersonAndRatingMinusCarol() {
1276*5153720fSfkaag71        $query = array (
1277*5153720fSfkaag71            'type' => 'select',
1278*5153720fSfkaag71            'grouping'=>array(),
1279*5153720fSfkaag71            'group' => array (
1280*5153720fSfkaag71                'type' => 'and',
1281*5153720fSfkaag71                'lhs' => $this->_isPerson,
1282*5153720fSfkaag71                'rhs' => $this->_ratingMinusCarol
1283*5153720fSfkaag71            ),
1284*5153720fSfkaag71            'projection' => array (
1285*5153720fSfkaag71                'p',
1286*5153720fSfkaag71                'rating'
1287*5153720fSfkaag71            ),
1288*5153720fSfkaag71            'ordering' => array (
1289*5153720fSfkaag71                array (
1290*5153720fSfkaag71                    'variable' => 'p',
1291*5153720fSfkaag71                    'direction' => 'asc'
1292*5153720fSfkaag71                )
1293*5153720fSfkaag71            )
1294*5153720fSfkaag71        );
1295*5153720fSfkaag71
1296*5153720fSfkaag71        $expected = array (
1297*5153720fSfkaag71            array (
1298*5153720fSfkaag71                'p' => array('person:alice'),
1299*5153720fSfkaag71                'rating' => array('10')
1300*5153720fSfkaag71            ),
1301*5153720fSfkaag71            array (
1302*5153720fSfkaag71                'p' => array('person:bob'),
1303*5153720fSfkaag71                'rating' => array('8')
1304*5153720fSfkaag71            )
1305*5153720fSfkaag71        );
1306*5153720fSfkaag71
1307*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1308*5153720fSfkaag71    }
1309*5153720fSfkaag71
1310*5153720fSfkaag71    function testPersonAndBobUnionAlice() {
1311*5153720fSfkaag71        $query = array (
1312*5153720fSfkaag71            'type' => 'select',
1313*5153720fSfkaag71            'grouping'=>array(),
1314*5153720fSfkaag71            'group' => array (
1315*5153720fSfkaag71                'type' => 'and',
1316*5153720fSfkaag71                'lhs' => $this->_isPerson,
1317*5153720fSfkaag71                'rhs' => $this->_bobUnionAlice
1318*5153720fSfkaag71            ),
1319*5153720fSfkaag71            'projection' => array (
1320*5153720fSfkaag71                'p'
1321*5153720fSfkaag71            ),
1322*5153720fSfkaag71            'ordering' => array (
1323*5153720fSfkaag71                array (
1324*5153720fSfkaag71                    'variable' => 'p',
1325*5153720fSfkaag71                    'direction' => 'asc'
1326*5153720fSfkaag71                )
1327*5153720fSfkaag71            )
1328*5153720fSfkaag71        );
1329*5153720fSfkaag71
1330*5153720fSfkaag71        $expected = array (
1331*5153720fSfkaag71            array (
1332*5153720fSfkaag71                'p' => array('person:alice')
1333*5153720fSfkaag71            ),
1334*5153720fSfkaag71            array (
1335*5153720fSfkaag71                'p' => array('person:bob')
1336*5153720fSfkaag71            )
1337*5153720fSfkaag71        );
1338*5153720fSfkaag71
1339*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1340*5153720fSfkaag71    }
1341*5153720fSfkaag71
1342*5153720fSfkaag71    function testPersonAndKnowsOptionalLikes() {
1343*5153720fSfkaag71        $query = array (
1344*5153720fSfkaag71            'type' => 'select',
1345*5153720fSfkaag71            'grouping'=>array(),
1346*5153720fSfkaag71            'group' => array (
1347*5153720fSfkaag71                'type' => 'and',
1348*5153720fSfkaag71                'lhs' => $this->_isPerson,
1349*5153720fSfkaag71                'rhs' => $this->_knowsOptionalLikes
1350*5153720fSfkaag71            ),
1351*5153720fSfkaag71            'projection' => array (
1352*5153720fSfkaag71                'p',
1353*5153720fSfkaag71                'knows',
1354*5153720fSfkaag71                'likes'
1355*5153720fSfkaag71            ),
1356*5153720fSfkaag71            'ordering' => array (
1357*5153720fSfkaag71                array (
1358*5153720fSfkaag71                    'variable' => 'p',
1359*5153720fSfkaag71                    'direction' => 'asc'
1360*5153720fSfkaag71                ),
1361*5153720fSfkaag71                array (
1362*5153720fSfkaag71                    'variable' => 'knows',
1363*5153720fSfkaag71                    'direction' => 'asc'
1364*5153720fSfkaag71                )
1365*5153720fSfkaag71            )
1366*5153720fSfkaag71        );
1367*5153720fSfkaag71
1368*5153720fSfkaag71        $expected = array (
1369*5153720fSfkaag71            array (
1370*5153720fSfkaag71                'p' => array('person:alice'),
1371*5153720fSfkaag71                'knows' => array('person:carol'),
1372*5153720fSfkaag71                'likes' => array()
1373*5153720fSfkaag71            ),
1374*5153720fSfkaag71            array (
1375*5153720fSfkaag71                'p' => array('person:bob'),
1376*5153720fSfkaag71                'knows' => array('person:alice'),
1377*5153720fSfkaag71                'likes' => array('person:alice')
1378*5153720fSfkaag71            ),
1379*5153720fSfkaag71            array (
1380*5153720fSfkaag71                'p' => array('person:carol'),
1381*5153720fSfkaag71                'knows' => array('person:alice'),
1382*5153720fSfkaag71                'likes' => array()
1383*5153720fSfkaag71            ),
1384*5153720fSfkaag71            array (
1385*5153720fSfkaag71                'p' => array('person:carol'),
1386*5153720fSfkaag71                'knows' => array('person:bob'),
1387*5153720fSfkaag71                'likes' => array()
1388*5153720fSfkaag71            )
1389*5153720fSfkaag71        );
1390*5153720fSfkaag71
1391*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1392*5153720fSfkaag71    }
1393*5153720fSfkaag71
1394*5153720fSfkaag71    function testVariableNames() {
1395*5153720fSfkaag71        // Strange strings as variable names
1396*5153720fSfkaag71        $query = array (
1397*5153720fSfkaag71            'type' => 'select',
1398*5153720fSfkaag71            'grouping'=>array(),
1399*5153720fSfkaag71            'group' => array (
1400*5153720fSfkaag71                'type' => 'and',
1401*5153720fSfkaag71                'lhs' => array (
1402*5153720fSfkaag71                    'type' => 'and',
1403*5153720fSfkaag71                    'lhs' => array (
1404*5153720fSfkaag71                        'type' => 'triple',
1405*5153720fSfkaag71                        'subject' => array (
1406*5153720fSfkaag71                            'type' => 'variable',
1407*5153720fSfkaag71                            'text' => '_'
1408*5153720fSfkaag71                        ),
1409*5153720fSfkaag71                        'predicate' => array (
1410*5153720fSfkaag71                            'type' => 'literal',
1411*5153720fSfkaag71                            'text' => 'class'
1412*5153720fSfkaag71                        ),
1413*5153720fSfkaag71                        'object' => array (
1414*5153720fSfkaag71                            'type' => 'variable',
1415*5153720fSfkaag71                            'text' => '?c'
1416*5153720fSfkaag71                        ),
1417*5153720fSfkaag71                    ),
1418*5153720fSfkaag71                    'rhs' => array (
1419*5153720fSfkaag71                        'type' => 'and',
1420*5153720fSfkaag71                        'lhs' => array (
1421*5153720fSfkaag71                            'type' => 'triple',
1422*5153720fSfkaag71                            'subject' => array (
1423*5153720fSfkaag71                                'type' => 'variable',
1424*5153720fSfkaag71                                'text' => '_'
1425*5153720fSfkaag71                            ),
1426*5153720fSfkaag71                            'predicate' => array (
1427*5153720fSfkaag71                                'type' => 'literal',
1428*5153720fSfkaag71                                'text' => 'name'
1429*5153720fSfkaag71                            ),
1430*5153720fSfkaag71                            'object' => array (
1431*5153720fSfkaag71                                'type' => 'variable',
1432*5153720fSfkaag71                                'text' => 'given name'
1433*5153720fSfkaag71                            ),
1434*5153720fSfkaag71                        ),
1435*5153720fSfkaag71                        'rhs' => array (
1436*5153720fSfkaag71                            'type' => 'triple',
1437*5153720fSfkaag71                            'subject' => array (
1438*5153720fSfkaag71                                'type' => 'variable',
1439*5153720fSfkaag71                                'text' => '_'
1440*5153720fSfkaag71                            ),
1441*5153720fSfkaag71                            'predicate' => array (
1442*5153720fSfkaag71                                'type' => 'literal',
1443*5153720fSfkaag71                                'text' => 'knows'
1444*5153720fSfkaag71                            ),
1445*5153720fSfkaag71                            'object' => array (
1446*5153720fSfkaag71                                'type' => 'variable',
1447*5153720fSfkaag71                                'text' => '2 knów \'`"'
1448*5153720fSfkaag71                            )
1449*5153720fSfkaag71                        )
1450*5153720fSfkaag71                    )
1451*5153720fSfkaag71                ),
1452*5153720fSfkaag71            'rhs' => array (
1453*5153720fSfkaag71                    'type' => 'and',
1454*5153720fSfkaag71                    'lhs' => array (
1455*5153720fSfkaag71                        'type' => 'and',
1456*5153720fSfkaag71                        'lhs' => array (
1457*5153720fSfkaag71                            'type' => 'triple',
1458*5153720fSfkaag71                            'subject' => array (
1459*5153720fSfkaag71                                'type' => 'variable',
1460*5153720fSfkaag71                                'text' => '_'
1461*5153720fSfkaag71                            ),
1462*5153720fSfkaag71                            'predicate' => array (
1463*5153720fSfkaag71                                'type' => 'literal',
1464*5153720fSfkaag71                                'text' => 'has length'
1465*5153720fSfkaag71                            ),
1466*5153720fSfkaag71                            'object' => array (
1467*5153720fSfkaag71                                'type' => 'variable',
1468*5153720fSfkaag71                                'text' => ':l'
1469*5153720fSfkaag71                            ),
1470*5153720fSfkaag71                        ),
1471*5153720fSfkaag71                        'rhs' => array (
1472*5153720fSfkaag71                            'type' => 'triple',
1473*5153720fSfkaag71                            'subject' => array (
1474*5153720fSfkaag71                                'type' => 'variable',
1475*5153720fSfkaag71                                'text' => '_'
1476*5153720fSfkaag71                            ),
1477*5153720fSfkaag71                            'predicate' => array (
1478*5153720fSfkaag71                                'type' => 'literal',
1479*5153720fSfkaag71                                'text' => 'tax rate'
1480*5153720fSfkaag71                            ),
1481*5153720fSfkaag71                            'object' => array (
1482*5153720fSfkaag71                                'type' => 'variable',
1483*5153720fSfkaag71                                'text' => '%t'
1484*5153720fSfkaag71                            )
1485*5153720fSfkaag71                        )
1486*5153720fSfkaag71                    ),
1487*5153720fSfkaag71                'rhs' => array (
1488*5153720fSfkaag71                        'type' => 'and',
1489*5153720fSfkaag71                        'lhs' => array (
1490*5153720fSfkaag71                            'type' => 'triple',
1491*5153720fSfkaag71                            'subject' => array (
1492*5153720fSfkaag71                                'type' => 'variable',
1493*5153720fSfkaag71                                'text' => '_'
1494*5153720fSfkaag71                            ),
1495*5153720fSfkaag71                            'predicate' => array (
1496*5153720fSfkaag71                                'type' => 'literal',
1497*5153720fSfkaag71                                'text' => 'is rated'
1498*5153720fSfkaag71                            ),
1499*5153720fSfkaag71                            'object' => array (
1500*5153720fSfkaag71                                'type' => 'variable',
1501*5153720fSfkaag71                                'text' => '1.10'
1502*5153720fSfkaag71                            ),
1503*5153720fSfkaag71                        ),
1504*5153720fSfkaag71                        'rhs' => array (
1505*5153720fSfkaag71                            'type' => 'triple',
1506*5153720fSfkaag71                            'subject' => array (
1507*5153720fSfkaag71                                'type' => 'variable',
1508*5153720fSfkaag71                                'text' => '_'
1509*5153720fSfkaag71                            ),
1510*5153720fSfkaag71                            'predicate' => array (
1511*5153720fSfkaag71                                'type' => 'literal',
1512*5153720fSfkaag71                                'text' => 'looks like'
1513*5153720fSfkaag71                            ),
1514*5153720fSfkaag71                            'object' => array (
1515*5153720fSfkaag71                                'type' => 'variable',
1516*5153720fSfkaag71                                'text' => '  \\  like ""! '
1517*5153720fSfkaag71                            )
1518*5153720fSfkaag71                        )
1519*5153720fSfkaag71                    )
1520*5153720fSfkaag71                )
1521*5153720fSfkaag71            ),
1522*5153720fSfkaag71            'projection' => array (
1523*5153720fSfkaag71                '_',
1524*5153720fSfkaag71                '?c',
1525*5153720fSfkaag71                'given name',
1526*5153720fSfkaag71                '2 knów \'`"',
1527*5153720fSfkaag71                ':l',
1528*5153720fSfkaag71                '%t',
1529*5153720fSfkaag71                '1.10',
1530*5153720fSfkaag71                '  \\  like ""! '
1531*5153720fSfkaag71            ),
1532*5153720fSfkaag71            'ordering' => array (
1533*5153720fSfkaag71                array (
1534*5153720fSfkaag71                    'variable' => '_',
1535*5153720fSfkaag71                    'direction' => 'asc'
1536*5153720fSfkaag71                ),
1537*5153720fSfkaag71                array (
1538*5153720fSfkaag71                    'variable' => '2 knów \'`"',
1539*5153720fSfkaag71                    'direction' => 'asc'
1540*5153720fSfkaag71                )
1541*5153720fSfkaag71            )
1542*5153720fSfkaag71        );
1543*5153720fSfkaag71
1544*5153720fSfkaag71        $expected = array (
1545*5153720fSfkaag71            array (
1546*5153720fSfkaag71                '_' => array('person:alice'),
1547*5153720fSfkaag71                '?c' => array('person'),
1548*5153720fSfkaag71                'given name' => array('Alice'),
1549*5153720fSfkaag71                '2 knów \'`"' => array('person:carol'),
1550*5153720fSfkaag71                ':l' => array('5 ft 5 in'),
1551*5153720fSfkaag71                '%t' => array('10%'),
1552*5153720fSfkaag71                '1.10' => array('10'),
1553*5153720fSfkaag71                '  \\  like ""! ' => array('50:alice.svg')
1554*5153720fSfkaag71            ),
1555*5153720fSfkaag71            array (
1556*5153720fSfkaag71                '_' => array('person:bob'),
1557*5153720fSfkaag71                '?c' => array('person'),
1558*5153720fSfkaag71                'given name' => array('Bob'),
1559*5153720fSfkaag71                '2 knów \'`"' => array('person:alice'),
1560*5153720fSfkaag71                ':l' => array('5 ft 10 in'),
1561*5153720fSfkaag71                '%t' => array('25%'),
1562*5153720fSfkaag71                '1.10' => array('8'),
1563*5153720fSfkaag71                '  \\  like ""! ' => array('50:bob.png')
1564*5153720fSfkaag71            ),
1565*5153720fSfkaag71            array (
1566*5153720fSfkaag71                '_' => array('person:carol'),
1567*5153720fSfkaag71                '?c' => array('person'),
1568*5153720fSfkaag71                'given name' => array('Carol'),
1569*5153720fSfkaag71                '2 knów \'`"' => array('person:alice'),
1570*5153720fSfkaag71                ':l' => array('4 ft 11 in'),
1571*5153720fSfkaag71                '%t' => array('2%'),
1572*5153720fSfkaag71                '1.10' => array('1'),
1573*5153720fSfkaag71                '  \\  like ""! ' => array('50:carol.jpg')
1574*5153720fSfkaag71            ),
1575*5153720fSfkaag71            array (
1576*5153720fSfkaag71                '_' => array('person:carol'),
1577*5153720fSfkaag71                '?c' => array('person'),
1578*5153720fSfkaag71                'given name' => array('Carol'),
1579*5153720fSfkaag71                '2 knów \'`"' => array('person:bob'),
1580*5153720fSfkaag71                ':l' => array('4 ft 11 in'),
1581*5153720fSfkaag71                '%t' => array('2%'),
1582*5153720fSfkaag71                '1.10' => array('1'),
1583*5153720fSfkaag71                '  \\  like ""! ' => array('50:carol.jpg')
1584*5153720fSfkaag71            )
1585*5153720fSfkaag71        );
1586*5153720fSfkaag71
1587*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1588*5153720fSfkaag71    }
1589*5153720fSfkaag71
1590*5153720fSfkaag71    function testGrouping() {
1591*5153720fSfkaag71        $query = array (
1592*5153720fSfkaag71            'type' => 'select',
1593*5153720fSfkaag71            'grouping' => array (
1594*5153720fSfkaag71                'knows',
1595*5153720fSfkaag71                'rating'
1596*5153720fSfkaag71            ),
1597*5153720fSfkaag71            'group' => array (
1598*5153720fSfkaag71                'type' => 'and',
1599*5153720fSfkaag71                'lhs' => array (
1600*5153720fSfkaag71                    'type' => 'and',
1601*5153720fSfkaag71                    'lhs' => array (
1602*5153720fSfkaag71                        'type' => 'and',
1603*5153720fSfkaag71                        'lhs' => array (
1604*5153720fSfkaag71                            'type' => 'and',
1605*5153720fSfkaag71                            'lhs' => $this->_isPerson,
1606*5153720fSfkaag71                            'rhs' => $this->_personKnows
1607*5153720fSfkaag71                        ),
1608*5153720fSfkaag71                        'rhs' => array (
1609*5153720fSfkaag71                            'type' => 'triple',
1610*5153720fSfkaag71                            'subject' => array (
1611*5153720fSfkaag71                                'type' => 'variable',
1612*5153720fSfkaag71                                'text' => 'knows'
1613*5153720fSfkaag71                            ),
1614*5153720fSfkaag71                            'predicate' => array (
1615*5153720fSfkaag71                                'type' => 'literal',
1616*5153720fSfkaag71                                'text' => 'knows'
1617*5153720fSfkaag71                            ),
1618*5153720fSfkaag71                            'object' => array (
1619*5153720fSfkaag71                                'type' => 'variable',
1620*5153720fSfkaag71                                'text' => 'who knows'
1621*5153720fSfkaag71                            )
1622*5153720fSfkaag71                        )
1623*5153720fSfkaag71                    ),
1624*5153720fSfkaag71                    'rhs' => $this->_personRating
1625*5153720fSfkaag71                ),
1626*5153720fSfkaag71                'rhs' => array (
1627*5153720fSfkaag71                    'type' => 'triple',
1628*5153720fSfkaag71                    'subject' => array (
1629*5153720fSfkaag71                        'type' => 'variable',
1630*5153720fSfkaag71                        'text' => 'knows'
1631*5153720fSfkaag71                    ),
1632*5153720fSfkaag71                    'predicate' => array (
1633*5153720fSfkaag71                        'type' => 'literal',
1634*5153720fSfkaag71                        'text' => 'identifier'
1635*5153720fSfkaag71                    ),
1636*5153720fSfkaag71                    'object' => array (
1637*5153720fSfkaag71                        'type' => 'variable',
1638*5153720fSfkaag71                        'text' => 'knows id'
1639*5153720fSfkaag71                    )
1640*5153720fSfkaag71                )
1641*5153720fSfkaag71            ),
1642*5153720fSfkaag71            'projection' => array (
1643*5153720fSfkaag71                'p',
1644*5153720fSfkaag71                'knows id',
1645*5153720fSfkaag71                'who knows',
1646*5153720fSfkaag71            ),
1647*5153720fSfkaag71            'ordering' => array (
1648*5153720fSfkaag71                array (
1649*5153720fSfkaag71                    'variable' => 'rating',
1650*5153720fSfkaag71                    'direction' => 'desc'
1651*5153720fSfkaag71                ),
1652*5153720fSfkaag71                array (
1653*5153720fSfkaag71                    'variable' => 'knows',
1654*5153720fSfkaag71                    'direction' => 'asc'
1655*5153720fSfkaag71                ),
1656*5153720fSfkaag71                array (
1657*5153720fSfkaag71                    'variable' => 'who knows',
1658*5153720fSfkaag71                    'direction' => 'asc'
1659*5153720fSfkaag71                )
1660*5153720fSfkaag71            )
1661*5153720fSfkaag71        );
1662*5153720fSfkaag71
1663*5153720fSfkaag71        $expected = array (
1664*5153720fSfkaag71            array (
1665*5153720fSfkaag71                'p' => array('person:alice', 'person:alice'),
1666*5153720fSfkaag71                'knows id' => array('γ', 'γ'),
1667*5153720fSfkaag71                'who knows' => array('person:alice', 'person:bob'),
1668*5153720fSfkaag71            ),
1669*5153720fSfkaag71            array (
1670*5153720fSfkaag71                'p' => array('person:bob'),
1671*5153720fSfkaag71                'knows id' => array('α'),
1672*5153720fSfkaag71                'who knows' => array('person:carol'),
1673*5153720fSfkaag71            ),
1674*5153720fSfkaag71            array (
1675*5153720fSfkaag71                'p' => array('person:carol'),
1676*5153720fSfkaag71                'knows id' => array('α'),
1677*5153720fSfkaag71                'who knows' => array('person:carol'),
1678*5153720fSfkaag71            ),
1679*5153720fSfkaag71            array (
1680*5153720fSfkaag71                'p' => array('person:carol'),
1681*5153720fSfkaag71                'knows id' => array('Β'),
1682*5153720fSfkaag71                'who knows' => array('person:alice'),
1683*5153720fSfkaag71            )
1684*5153720fSfkaag71        );
1685*5153720fSfkaag71
1686*5153720fSfkaag71        $this->assertQueryResult($query, $expected);
1687*5153720fSfkaag71    }
1688*5153720fSfkaag71}
1689*5153720fSfkaag71
1690