File: dev-sql-compiler.t

package info (click to toggle)
librdf-query-perl 2.919-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,580 kB
  • sloc: perl: 30,628; javascript: 131; sh: 13; makefile: 2
file content (648 lines) | stat: -rw-r--r-- 34,438 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
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
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
#!/usr/bin/env perl
use strict;
use Test::More;
use Test::Exception;

use RDF::Query;
use RDF::Query::Parser::SPARQL;

if ($ENV{RDFQUERY_DEV_MYSQL}) {
	plan 'no_plan';
} else {
	plan tests => 34;
}

use_ok( 'RDF::Query::Compiler::SQL' );

my $parser		= new RDF::Query::Parser::SPARQL ();


{
	my $uri	= 'http://xmlns.com/foaf/0.1/name';
	my $node	= RDF::Query::Node::Resource->new( $uri );
	my $hash	= RDF::Query::Compiler::SQL->_mysql_node_hash( $node );
	is( $hash, '14911999128994829034', 'URI hash' );
}

{
	my $node	= RDF::Query::Node::Literal->new( 'kasei' );
	my $hash	= RDF::Query::Compiler::SQL->_mysql_node_hash( $node );
	is( $hash, '12775641923308277283', 'literal hash' );
}

{
	my $hash	= RDF::Query::Compiler::SQL::_mysql_hash( 'LTom Croucher<en>' );
	is( $hash, '14336915341960534814', 'language-typed literal hash' );
}

{
	my $node	= RDF::Query::Node::Literal->new( 'Tom Croucher', 'en' );
	my $hash	= RDF::Query::Compiler::SQL->_mysql_node_hash( $node );
	is( $hash, '14336915341960534814', 'language-typed literal node hash 1' );
}

{
	my $node	= RDF::Query::Node::Literal->new( 'RDF', 'en' );
	my $hash	= RDF::Query::Compiler::SQL->_mysql_node_hash( $node );
	is( $hash, '16625494614570964497', 'language-typed literal node hash 2' );
}



{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name
		WHERE	{ ?person foaf:name ?name }
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed, 'model' );
	isa_ok( $compiler, 'RDF::Query::Compiler::SQL' );
	
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.subject AS person_Node,\n\tljr0.URI AS person_URI,\n\tljl0.Value AS person_Value,\n\tljl0.Language AS person_Language,\n\tljl0.Datatype AS person_Datatype,\n\tljb0.Name AS person_Name,\n\ts2.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name\nFROM\n\tStatements15799945864759145248 s2 LEFT JOIN Resources ljr0 ON (s2.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s2.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.object = ljb1.ID)\nWHERE\n\ts2.predicate = 14911999128994829034", "select people and names" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name
		WHERE	{
					?person foaf:name ?name .
				}
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	isa_ok( $compiler, 'RDF::Query::Compiler::SQL' );
	
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.subject AS person_Node,\n\tljr0.URI AS person_URI,\n\tljl0.Value AS person_Value,\n\tljl0.Language AS person_Language,\n\tljl0.Datatype AS person_Datatype,\n\tljb0.Name AS person_Name,\n\ts2.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s2.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.object = ljb1.ID)\nWHERE\n\ts2.predicate = 14911999128994829034", "select people and names" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name ?homepage
		WHERE	{
					?person foaf:name ?name ; foaf:homepage ?homepage
				}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.subject AS person_Node,\n\tljr0.URI AS person_URI,\n\tljl0.Value AS person_Value,\n\tljl0.Language AS person_Language,\n\tljl0.Datatype AS person_Datatype,\n\tljb0.Name AS person_Name,\n\ts2.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name,\n\ts3.object AS homepage_Node,\n\tljr2.URI AS homepage_URI,\n\tljl2.Value AS homepage_Value,\n\tljl2.Language AS homepage_Language,\n\tljl2.Datatype AS homepage_Datatype,\n\tljb2.Name AS homepage_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s2.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.object = ljb1.ID),\n\tStatements s3 LEFT JOIN Resources ljr2 ON (s3.object = ljr2.ID) LEFT JOIN Literals ljl2 ON (s3.object = ljl2.ID) LEFT JOIN Bnodes ljb2 ON (s3.object = ljb2.ID)\nWHERE\n\ts2.predicate = 14911999128994829034 AND\n\ts3.subject = s2.subject AND\n\ts3.predicate = 9768710922987392204", "select people, names, and homepages" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX foaf: <http://xmlns.com/foaf/0.1/>
		SELECT ?x ?name
		FROM NAMED <file://data/named_graphs/alice.rdf>
		FROM NAMED <file://data/named_graphs/bob.rdf>
		WHERE {
			GRAPH <foo:bar> { ?x foaf:name ?name }
		}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts3.subject AS x_Node,\n\tljr0.URI AS x_URI,\n\tljl0.Value AS x_Value,\n\tljl0.Language AS x_Language,\n\tljl0.Datatype AS x_Datatype,\n\tljb0.Name AS x_Name,\n\ts3.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name\nFROM\n\tStatements s3 LEFT JOIN Resources ljr0 ON (s3.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s3.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s3.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s3.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s3.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s3.object = ljb1.ID)\nWHERE\n\ts3.predicate = 14911999128994829034 AND\n\ts3.context = 2618056589919804847", "select people and names of context-specific graph" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX foaf: <http://xmlns.com/foaf/0.1/>
		SELECT ?src ?name
		FROM NAMED <file://data/named_graphs/alice.rdf>
		FROM NAMED <file://data/named_graphs/bob.rdf>
		WHERE {
			GRAPH ?src { ?x foaf:name ?name }
		}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts3.context AS src_Node,\n\tljr0.URI AS src_URI,\n\tljl0.Value AS src_Value,\n\tljl0.Language AS src_Language,\n\tljl0.Datatype AS src_Datatype,\n\tljb0.Name AS src_Name,\n\ts3.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name,\n\tljr2.URI AS x_URI,\n\tljl2.Value AS x_Value,\n\tljl2.Language AS x_Language,\n\tljl2.Datatype AS x_Datatype,\n\tljb2.Name AS x_Name\nFROM\n\tStatements s3 LEFT JOIN Resources ljr0 ON (s3.context = ljr0.ID) LEFT JOIN Literals ljl0 ON (s3.context = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s3.context = ljb0.ID) LEFT JOIN Resources ljr1 ON (s3.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s3.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s3.object = ljb1.ID) LEFT JOIN Resources ljr2 ON (s3.subject = ljr2.ID) LEFT JOIN Literals ljl2 ON (s3.subject = ljl2.ID) LEFT JOIN Bnodes ljb2 ON (s3.subject = ljb2.ID)\nWHERE\n\ts3.predicate = 14911999128994829034", "select context of people and names" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX rss: <http://purl.org/rss/1.0/>
		SELECT ?title
		WHERE {
			<http://kasei.us/> rss:title ?title .
		}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.object AS title_Node,\n\tljr0.URI AS title_URI,\n\tljl0.Value AS title_Value,\n\tljl0.Language AS title_Language,\n\tljl0.Datatype AS title_Datatype,\n\tljb0.Name AS title_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.object = ljb0.ID)\nWHERE\n\ts2.subject = 1083049239652454081 AND\n\ts2.predicate = 17858988500659793691", "select rss:title of uri" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		PREFIX	dcterms: <http://purl.org/dc/terms/>
		PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
		SELECT	?page
		WHERE	{
					?person foaf:name "Gregory Todd Williams" .
					?person foaf:homepage ?page .
				}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts3.object AS page_Node,\n\tljr0.URI AS page_URI,\n\tljl0.Value AS page_Value,\n\tljl0.Language AS page_Language,\n\tljl0.Datatype AS page_Datatype,\n\tljb0.Name AS page_Name,\n\tljr1.URI AS person_URI,\n\tljl1.Value AS person_Value,\n\tljl1.Language AS person_Language,\n\tljl1.Datatype AS person_Datatype,\n\tljb1.Name AS person_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr1 ON (s2.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.subject = ljb1.ID),\n\tStatements s3 LEFT JOIN Resources ljr0 ON (s3.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s3.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s3.object = ljb0.ID)\nWHERE\n\ts2.predicate = 14911999128994829034 AND\n\ts2.object = 2782977400239829321 AND\n\ts3.subject = s2.subject AND\n\ts3.predicate = 9768710922987392204", "select homepage of person by name" );
}

{
	my $parsed	= $parser->parse(<<'END');
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?s ?p
		WHERE	{
					?s ?p "RDF"@en .
				}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.subject AS s_Node,\n\tljr0.URI AS s_URI,\n\tljl0.Value AS s_Value,\n\tljl0.Language AS s_Language,\n\tljl0.Datatype AS s_Datatype,\n\tljb0.Name AS s_Name,\n\ts2.predicate AS p_Node,\n\tljr1.URI AS p_URI,\n\tljl1.Value AS p_Value,\n\tljl1.Language AS p_Language,\n\tljl1.Datatype AS p_Datatype,\n\tljb1.Name AS p_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s2.predicate = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.predicate = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.predicate = ljb1.ID)\nWHERE\n\ts2.object = 16625494614570964497", "select s,p by language-tagged literal" );
}

{
	RDF::Query::Compiler::SQL->add_function( 'time:now', sub {
		my $self	= shift;
		my $parsed_vars	= shift;
		my $expr	= shift;
		my $level	= shift || \do{ my $a = 0 };
		my %queryvars	= map { $_->name => 1 } @$parsed_vars;
		return ({}, [], ['NOW()']);
	} );
	
	my $parsed	= $parser->parse(<<'END');
		PREFIX	rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		PREFIX	dcterms: <http://purl.org/dc/terms/>
		PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
		PREFIX	mygeo: <http://kasei.us/e/ns/geo#>
		PREFIX	xsd: <http://www.w3.org/2001/XMLSchema#>
		PREFIX	time: <time:>
		SELECT	?point
		WHERE	{
					?point a geo:Point .
					FILTER( time:now() > "2006-01-01" )
				}
END
	my $sql;
	lives_ok {
		my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
		$sql			= $compiler->compile();
	} 'compile: select with function filter';
	is( $sql, qq(SELECT\n\ts6.subject AS point_Node,\n\tljr0.URI AS point_URI,\n\tljl0.Value AS point_Value,\n\tljl0.Language AS point_Language,\n\tljl0.Datatype AS point_Datatype,\n\tljb0.Name AS point_Name\nFROM\n\tStatements s6 LEFT JOIN Resources ljr0 ON (s6.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s6.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s6.subject = ljb0.ID)\nWHERE\n\tNOW() > '2006-01-01' AND\n\ts6.predicate = 2982895206037061277 AND\n\ts6.object = 11045396790191387947), "sql: select with function filter" );
}

{
	RDF::Query::Compiler::SQL->add_function( 'http://kasei.us/e/ns/geo#distance', sub {
		my $self	= shift;
		my $parsed_vars	= shift;
		my $level	= shift || \do{ my $a = 0 };
		my @args	= @_;
		my $vars	= $self->{vars};
		my (@from, @where);
		
		my %queryvars	= map { $_->name => 1 } @$parsed_vars;
		
		++$$level; my $sql_a	= $self->expr2sql( $args[0], $level );
		++$$level; my $sql_b	= $self->expr2sql( $args[1], $level );
		++$$level; my $sql_c	= $self->expr2sql( $args[1], $level );
		push(@where, "distance($sql_a, $sql_b, $sql_c)");
		return ($vars, \@from, \@where);
	} );
	
	my $parsed	= $parser->parse(<<'END');
		PREFIX	rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		PREFIX	dcterms: <http://purl.org/dc/terms/>
		PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
		PREFIX	mygeo: <http://kasei.us/e/ns/geo#>
		PREFIX	xsd: <http://www.w3.org/2001/XMLSchema#>
		SELECT	?image ?point ?lat
		WHERE	{
					?point geo:lat ?lat .
					?image ?pred ?point .
					FILTER( mygeo:distance(?point, +41.849331, -71.392) < "10"^^xsd:integer )
				}
END

	my $sql;
	lives_ok {
		my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
		$sql			= $compiler->compile();
	} 'compile: select images filterd by distance function comparison';
	is( $sql, qq(SELECT\n\ts10.subject AS image_Node,\n\tljr0.URI AS image_URI,\n\tljl0.Value AS image_Value,\n\tljl0.Language AS image_Language,\n\tljl0.Datatype AS image_Datatype,\n\tljb0.Name AS image_Name,\n\ts9.subject AS point_Node,\n\tljr1.URI AS point_URI,\n\tljl1.Value AS point_Value,\n\tljl1.Language AS point_Language,\n\tljl1.Datatype AS point_Datatype,\n\tljb1.Name AS point_Name,\n\ts9.object AS lat_Node,\n\tljr2.URI AS lat_URI,\n\tljl2.Value AS lat_Value,\n\tljl2.Language AS lat_Language,\n\tljl2.Datatype AS lat_Datatype,\n\tljb2.Name AS lat_Name,\n\tljr3.URI AS pred_URI,\n\tljl3.Value AS pred_Value,\n\tljl3.Language AS pred_Language,\n\tljl3.Datatype AS pred_Datatype,\n\tljb3.Name AS pred_Name\nFROM\n\tStatements s9 LEFT JOIN Resources ljr1 ON (s9.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s9.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s9.subject = ljb1.ID) LEFT JOIN Resources ljr2 ON (s9.object = ljr2.ID) LEFT JOIN Literals ljl2 ON (s9.object = ljl2.ID) LEFT JOIN Bnodes ljb2 ON (s9.object = ljb2.ID),\n\tStatements s10 LEFT JOIN Resources ljr0 ON (s10.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s10.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s10.subject = ljb0.ID) LEFT JOIN Resources ljr3 ON (s10.predicate = ljr3.ID) LEFT JOIN Literals ljl3 ON (s10.predicate = ljl3.ID) LEFT JOIN Bnodes ljb3 ON (s10.predicate = ljb3.ID)\nWHERE\n\tdistance(, (0.0 + '+41.849331'), (0.0 + '+41.849331')) < (0 + '10') AND\n\ts9.predicate = 5391429383543785584 AND\n\ts10.object = s9.subject), "sql: select images filterd by distance function comparison" );
}

{
	my $parsed	= $parser->parse(<<'END');
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?name
		WHERE	{
					?p a foaf:Person ; foaf:name ?name .
					FILTER REGEX(?name, "Greg") .
				}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, qq(SELECT\n\ts5.object AS name_Node,\n\tljr0.URI AS name_URI,\n\tljl0.Value AS name_Value,\n\tljl0.Language AS name_Language,\n\tljl0.Datatype AS name_Datatype,\n\tljb0.Name AS name_Name,\n\tljr1.URI AS p_URI,\n\tljl1.Value AS p_Value,\n\tljl1.Language AS p_Language,\n\tljl1.Datatype AS p_Datatype,\n\tljb1.Name AS p_Name\nFROM\n\tStatements s4 LEFT JOIN Resources ljr1 ON (s4.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s4.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s4.subject = ljb1.ID),\n\tStatements s5 LEFT JOIN Resources ljr0 ON (s5.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s5.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s5.object = ljb0.ID)\nWHERE\n\t(ljl0.Value REGEXP 'Greg' OR ljr0.URI REGEXP 'Greg' OR ljb0.Name REGEXP 'Greg') AND\n\ts4.predicate = 2982895206037061277 AND\n\ts4.object = 3652866608875541952 AND\n\ts5.subject = s4.subject AND\n\ts5.predicate = 14911999128994829034), "select people by regex-filtered name" );
}

{
	my $parsed	= $parser->parse(<<'END');
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT DISTINCT	?name
		WHERE	{
					?p a foaf:Person ; foaf:name ?name .
					FILTER REGEX(?name, "Greg") .
				}
		LIMIT 1
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, qq(SELECT DISTINCT\n\ts5.object AS name_Node,\n\tljr0.URI AS name_URI,\n\tljl0.Value AS name_Value,\n\tljl0.Language AS name_Language,\n\tljl0.Datatype AS name_Datatype,\n\tljb0.Name AS name_Name,\n\tljr1.URI AS p_URI,\n\tljl1.Value AS p_Value,\n\tljl1.Language AS p_Language,\n\tljl1.Datatype AS p_Datatype,\n\tljb1.Name AS p_Name\nFROM\n\tStatements s4 LEFT JOIN Resources ljr1 ON (s4.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s4.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s4.subject = ljb1.ID),\n\tStatements s5 LEFT JOIN Resources ljr0 ON (s5.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s5.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s5.object = ljb0.ID)\nWHERE\n\t(ljl0.Value REGEXP 'Greg' OR ljr0.URI REGEXP 'Greg' OR ljb0.Name REGEXP 'Greg') AND\n\ts4.predicate = 2982895206037061277 AND\n\ts4.object = 3652866608875541952 AND\n\ts5.subject = s4.subject AND\n\ts5.predicate = 14911999128994829034\nLIMIT 1), "select people by regex-filtered name with DISTINCT and LIMIT" );
}

{
	my $parsed	= $parser->parse(<<'END');
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT DISTINCT	?name
		WHERE	{
					?p a foaf:Person ; foaf:name ?name .
					FILTER( ?name = "Gregory Todd Williams" )
				}
		LIMIT 1
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, qq(SELECT DISTINCT\n\ts7.object AS name_Node,\n\tljr0.URI AS name_URI,\n\tljl0.Value AS name_Value,\n\tljl0.Language AS name_Language,\n\tljl0.Datatype AS name_Datatype,\n\tljb0.Name AS name_Name,\n\tljr1.URI AS p_URI,\n\tljl1.Value AS p_Value,\n\tljl1.Language AS p_Language,\n\tljl1.Datatype AS p_Datatype,\n\tljb1.Name AS p_Name\nFROM\n\tStatements s6 LEFT JOIN Resources ljr1 ON (s6.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s6.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s6.subject = ljb1.ID),\n\tStatements s7 LEFT JOIN Resources ljr0 ON (s7.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s7.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s7.object = ljb0.ID)\nWHERE\n\t(SELECT value FROM Literals WHERE  = ID LIMIT 1) = 'Gregory Todd Williams' AND\n\ts6.predicate = 2982895206037061277 AND\n\ts6.object = 3652866608875541952 AND\n\ts7.subject = s6.subject AND\n\ts7.predicate = 14911999128994829034\nLIMIT 1), "select people by Literal name with DISTINCT and LIMIT" );
}

{
	my $parsed	= $parser->parse(<<'END');
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT DISTINCT	?name
		WHERE	{
					?p a foaf:Person ; foaf:name ?name .
					FILTER( ?p = <http://kasei.us/about/foaf.xrdf#greg> )
				}
		LIMIT 1
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, qq(SELECT DISTINCT\n\ts5.object AS name_Node,\n\tljr0.URI AS name_URI,\n\tljl0.Value AS name_Value,\n\tljl0.Language AS name_Language,\n\tljl0.Datatype AS name_Datatype,\n\tljb0.Name AS name_Name,\n\tljr1.URI AS p_URI,\n\tljl1.Value AS p_Value,\n\tljl1.Language AS p_Language,\n\tljl1.Datatype AS p_Datatype,\n\tljb1.Name AS p_Name\nFROM\n\tStatements s4 LEFT JOIN Resources ljr1 ON (s4.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s4.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s4.subject = ljb1.ID),\n\tStatements s5 LEFT JOIN Resources ljr0 ON (s5.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s5.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s5.object = ljb0.ID)\nWHERE\n\t = 2954181085641959508 AND\n\ts4.predicate = 2982895206037061277 AND\n\ts4.object = 3652866608875541952 AND\n\ts5.subject = s4.subject AND\n\ts5.predicate = 14911999128994829034\nLIMIT 1), "select people by URI with DISTINCT and LIMIT" );
	
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name
		WHERE	{
					?person foaf:name ?name .
					FILTER BOUND(?name) .
				}
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	isa_ok( $compiler, 'RDF::Query::Compiler::SQL' );
	
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts4.subject AS person_Node,\n\tljr0.URI AS person_URI,\n\tljl0.Value AS person_Value,\n\tljl0.Language AS person_Language,\n\tljl0.Datatype AS person_Datatype,\n\tljb0.Name AS person_Name,\n\ts4.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name\nFROM\n\tStatements s4 LEFT JOIN Resources ljr0 ON (s4.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s4.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s4.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s4.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s4.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s4.object = ljb1.ID)\nWHERE\n\t IS NOT NULL AND\n\ts4.predicate = 14911999128994829034", "select people and names with filter BOUND()" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name
		WHERE	{ ?person foaf:name ?name }
		ORDER BY ?name
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	isa_ok( $compiler, 'RDF::Query::Compiler::SQL' );
	
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.subject AS person_Node,\n\tljr0.URI AS person_URI,\n\tljl0.Value AS person_Value,\n\tljl0.Language AS person_Language,\n\tljl0.Datatype AS person_Datatype,\n\tljb0.Name AS person_Name,\n\ts2.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s2.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.object = ljb1.ID)\nWHERE\n\ts2.predicate = 14911999128994829034\nORDER BY\n\tname_Value ASC, name_URI ASC, name_Name ASC", "order by names" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name
		WHERE	{ ?person foaf:name ?name }
		ORDER BY ?name, ?person
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	throws_ok {
		my $sql		= $compiler->compile();
	} 'RDF::Query::Error::CompilationError', 'order by multiple columns throws error';
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		CONSTRUCT { ?person foaf:name ?name }
		WHERE	{ ?person foaf:name ?name }
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed, 'model' );
	throws_ok {
		my $sql		= $compiler->compile();
	} 'RDF::Query::Error::CompilationError', 'non-select throws error';
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX time: <time:>
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name
		WHERE	{ ?person foaf:name ?name }
		ORDER BY time:now()
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	$compiler->add_function( 'time:now', sub {
		my $self	= shift;
		my $parsed_vars	= shift;
		my $level	= shift || \do{ my $a = 0 };
		return ({}, [], ['NOW()']);
	} );
	isa_ok( $compiler, 'RDF::Query::Compiler::SQL' );
	
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.subject AS person_Node,\n\tljr0.URI AS person_URI,\n\tljl0.Value AS person_Value,\n\tljl0.Language AS person_Language,\n\tljl0.Datatype AS person_Datatype,\n\tljb0.Name AS person_Name,\n\ts2.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s2.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.object = ljb1.ID)\nWHERE\n\ts2.predicate = 14911999128994829034\nORDER BY\n\tNOW() ASC", "order by function (NOW())" );
}

{
	my $parsed	= $parser->parse(<<"END");
		PREFIX func: <func:>
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?person ?name
		WHERE	{ ?person foaf:name ?name }
		ORDER BY func:ascii(?name)
END
	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	$compiler->add_function( 'func:ascii', sub {
		my $self	= shift;
		my $parsed_vars	= shift;
		my $level	= shift || \do{ my $a = 0 };
		my $expr	= shift;
		
		my $col		= $self->expr2sql( $expr, $level );
		return ({}, [], ["ASCII($col)"]);
	} );
	isa_ok( $compiler, 'RDF::Query::Compiler::SQL' );
	
	my $sql		= $compiler->compile();
	is( $sql, "SELECT\n\ts2.subject AS person_Node,\n\tljr0.URI AS person_URI,\n\tljl0.Value AS person_Value,\n\tljl0.Language AS person_Language,\n\tljl0.Datatype AS person_Datatype,\n\tljb0.Name AS person_Name,\n\ts2.object AS name_Node,\n\tljr1.URI AS name_URI,\n\tljl1.Value AS name_Value,\n\tljl1.Language AS name_Language,\n\tljl1.Datatype AS name_Datatype,\n\tljb1.Name AS name_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.subject = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.subject = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.subject = ljb0.ID) LEFT JOIN Resources ljr1 ON (s2.object = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.object = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.object = ljb1.ID)\nWHERE\n\ts2.predicate = 14911999128994829034\nORDER BY\n\tASCII(ljr1.URI) ASC, ASCII(ljl1.Value) ASC, ASCII(ljl1.Language) ASC", "order by function (ASCII(name))" );
}

	














# if ($ENV{RDFQUERY_DEV_MYSQL}) {
# 	my $model_name	= 'model';
# 	SKIP: {
# 		eval "require Kasei::RDF::Common;";
# 		if ($@) {
# 			warn $@;
# 			exit;
# #			skip "Failed to load Kasei::RDF::Common", 1;
# 		}
# 		
# 		my $dsn		= [ Kasei::Common::mysql_dbi_args() ];
# 		
# 		{
# 			my $model	= DBI->connect( @$dsn );
# 			my $sparql	= <<'END';
# 			SELECT	?s ?p ?o
# 			WHERE	{ ?s ?p ?o }
# 			LIMIT 1
# END
# 			lives_ok {
# 				my $query	= new RDF::Query ( $sparql, undef, undef, 'sparql' );
# 				$query->execute( $model, model => $model_name, require_sql => 1 );
# 			} 's-p-o without pre-bound vars';
# 		}
# 		
# 		{
# 			Kasei::RDF::Common->import('mysql_model');
# 			my @myargs	= Kasei::Common::mysql_upd();
# 			my $model	= mysql_model( $model_name, @myargs[ 2, 0, 1 ] );
# 			
# 			{
# 				my $sparql	= <<'END';
# 				SELECT	?s ?p ?o
# 				WHERE	{ ?s ?p ?o }
# 				LIMIT 1
# END
# 				lives_ok {
# 					my $query	= new RDF::Query ( $sparql, undef, undef, 'sparql' );
# 					$query->execute( $model, dsn => $dsn, model => $model_name, require_sql => 1 );
# 				} 's-p-o without pre-bound vars';
# 				
# 				throws_ok {
# 					my $query	= new RDF::Query ( $sparql, undef, undef, 'sparql' );
# 					$query->execute( $model, dsn => $dsn, model => $model_name, require_sql => 1, bind => { p => 1 } );
# 				} 'RDF::Query::Error::CompilationError', 's-p-o without pre-bound vars: forced sql compilation (expected) failure';
# 			}
# 			
# 			{
# 				my $query	= new RDF::Query ( <<"END", undef, undef, 'sparql' );
# 				PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
# 				SELECT	?image ?point ?lat
# 				WHERE	{
# 							?point geo:lat ?lat .
# 							?image ?pred ?point .
# 							FILTER(	geo:distance(?point) ) .
# 						}
# END
# 				throws_ok {
# 					$query->execute( $model, dsn => $dsn, model => $model_name, require_sql => 1 );
# 				} 'RDF::Query::Error::CompilationError', 'forced sql compilation (expected) failure';
# 			}
# 			
# 			{
# 				print "# FILTER rage test\n";
# 				my $query	= new RDF::Query ( <<"END", undef, undef, 'sparql' );
# 				PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
# 				PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
# 				SELECT	?image ?point ?lat
# 				WHERE	{
# 							?image a foaf:Image ; ?pred ?point .
# 							?point geo:lat ?lat .
# 							FILTER(
# 								(?pred = <http://purl.org/dc/terms/spatial> || ?pred = <http://xmlns.com/foaf/0.1/based_near>)
# 								&&	?lat > 52
# 								&&	?lat < 53
# 							) .
# 						}
# END
# 				my $stream	= $query->execute( $model, dsn => $dsn, model => $model_name );
# 	
# 				my $count;
# 				while (my $row = $stream->()) {
# 					my ($image, $point, $lat)	= @{ $row };
# 					ok( $image->isa('RDF::Trine::Node::Resource'), 'image is resource');
# 					my $latv	= ($lat) ? $lat->literal_value : undef;
# 					cmp_ok( $latv, '>', 52, 'lat: ' . $latv );
# 					cmp_ok( $latv, '<', 53, 'lat: ' . $latv );
# 					$count++;
# 				}
# 			}
# 			
# 			{
# 				print "# lots of points!\n";
# 				my $query	= new RDF::Query ( <<"END", undef, undef, 'sparql' );
# 					PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
# 					PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
# 					SELECT	?name
# 					WHERE	{
# 								?point a geo:Point; foaf:name ?name .
# 							}
# END
# 				my $stream	= $query->execute( $model, dsn => $dsn, model => $model_name );
# 				isa_ok( $stream, 'CODE', 'stream' );
# 				my $count;
# 				while (my $row = $stream->()) {
# 					my ($node)	= @{ $row };
# 					my $name	= $node->as_string;
# 					ok( $name, $name );
# 				} continue { last if ++$count >= 100 };
# 			}
# 			
# 			{
# 				print "# foaf:Person ORDER BY name\n";
# 				my $query	= new RDF::Query ( <<"END", undef, undef, 'sparql' );
# 					PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
# 					PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
# 					SELECT	DISTINCT ?p ?name
# 					WHERE	{
# 								?p a foaf:Person; foaf:name ?name
# 							}
# 					ORDER BY ?name
# END
# 				my $stream	= $query->execute( $model, dsn => $dsn, model => $model_name );
# 				isa_ok( $stream, 'CODE', 'stream' );
# 				my ($count, $last);
# 				while (my $row = $stream->()) {
# 					my ($p, $node)	= @{ $row };
# 					my $name	= $node->as_string;
# 					if (defined($last)) {
# 						cmp_ok( $name, 'ge', $last, "In order: $name (" . $p->as_string . ")" );
# 					} else {
# 						ok( $name, "$name (" . $p->as_string . ")" );
# 					}
# 					$last	= $name;
# 				} continue { last if ++$count >= 200 };
# 			}
# 			
# 			{
# 				print "# geo:Point ORDER BY longitude\n";
# 				my $query	= new RDF::Query ( <<"END", undef, undef, 'sparql' );
# 					PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
# 					PREFIX	geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
# 					PREFIX	xsd: <http://www.w3.org/2001/XMLSchema#>
# 					SELECT	DISTINCT ?name ?lat ?lon
# 					WHERE	{
# 								?point a geo:Point; foaf:name ?name; geo:lat ?lat; geo:long ?lon
# 							}
# 					ORDER BY DESC( xsd:decimal(?lon) )
# END
# 				my $stream	= $query->execute( $model, dsn => $dsn, model => $model_name );
# 				isa_ok( $stream, 'CODE', 'stream' );
# 				my ($count, $last);
# 				while (my $row = $stream->()) {
# 					my ($node, $lat, $long)	= @{ $row };
# 					my $name	= $node->as_string;
# 					if (defined($last)) {
# 						cmp_ok( $long->as_string, '<=', $last, "In order: $name (" . $long->as_string . ")" );
# 					} else {
# 						ok( $name, "$name (" . $long->as_string . ")" );
# 					}
# 					$last	= $long->as_string;
# 				} continue { last if ++$count >= 200 };
# 			}
# 		}
# 	}
# }



# if ($ENV{RDFQUERY_DEV_POSTGRESQL}) {
# 	eval "require Kasei::RDF::Common;";
# 	$ENV{'POSTGRESQL_MODEL'}	= 'model';
# 	$ENV{'POSTGRESQL_DATABASE'}	= 'greg';
# 	$ENV{'POSTGRESQL_PASSWORD'}	= 'password';
# 	
# 	Kasei::RDF::Common->import('postgresql_model');
# 	my $dbh		= postgresql_model();
# 	warn $dbh;
# 	
# 	my @myargs	= Kasei::Common::postgresql_upd();
# 	my $model	= postgresql_model( 'db1', @myargs[ 2, 0, 1 ] );
# 	my $dsn		= [ Kasei::Common::postgresql_dbi_args() ];
# 	
# 	warn $model;
# 	warn Dumper($dsn);
# 
# 
# }



__END__
{
	my $parsed	= $parser->parse(<<'END');
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?name
		WHERE	{
					?p a foaf:Person .
					?p foaf:name ?name .
					FILTER( ?p = _:r1101876070r10 )
				}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	is( $sql, qq(SELECT\n\ts2.object AS name_Node,\n\tljr0.URI AS name_URI,\n\tljl0.Value AS name_Value,\n\tljl0.Language AS name_Language,\n\tljl0.Datatype AS name_Datatype,\n\tljb0.Name AS name_Name,\n\tljr1.URI AS p_URI,\n\tljl1.Value AS p_Value,\n\tljl1.Language AS p_Language,\n\tljl1.Datatype AS p_Datatype,\n\tljb1.Name AS p_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr1 ON (s2.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.subject = ljb1.ID),\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.object = ljb0.ID)\nWHERE\n\ts2.predicate = 2982895206037061277 AND\n\ts2.object = 3652866608875541952 AND\n\ts2.subject = s2.subject AND\n\ts2.predicate = 14911999128994829034 AND\n\ts2.subject = 4025741532186680712), "select people by BNode" );
}

{
	my $parsed	= $parser->parse(<<'END');
		PREFIX	foaf: <http://xmlns.com/foaf/0.1/>
		SELECT	?name
		WHERE	{
					?p a foaf:Person ; foaf:name ?name .
					FILTER( ?p = [] )
				}
END

	my $compiler	= RDF::Query::Compiler::SQL->new( $parsed );
	my $sql		= $compiler->compile();
	$sql		=~ s/(s2.subject\s*=\s*)\d+/$1XXX/;
	is( $sql, qq(SELECT\n\ts2.object AS name_Node,\n\tljr0.URI AS name_URI,\n\tljl0.Value AS name_Value,\n\tljl0.Language AS name_Language,\n\tljl0.Datatype AS name_Datatype,\n\tljb0.Name AS name_Name,\n\tljr1.URI AS p_URI,\n\tljl1.Value AS p_Value,\n\tljl1.Language AS p_Language,\n\tljl1.Datatype AS p_Datatype,\n\tljb1.Name AS p_Name\nFROM\n\tStatements s2 LEFT JOIN Resources ljr1 ON (s2.subject = ljr1.ID) LEFT JOIN Literals ljl1 ON (s2.subject = ljl1.ID) LEFT JOIN Bnodes ljb1 ON (s2.subject = ljb1.ID),\n\tStatements s2 LEFT JOIN Resources ljr0 ON (s2.object = ljr0.ID) LEFT JOIN Literals ljl0 ON (s2.object = ljl0.ID) LEFT JOIN Bnodes ljb0 ON (s2.object = ljb0.ID)\nWHERE\n\ts2.predicate = 2982895206037061277 AND\n\ts2.object = 3652866608875541952 AND\n\ts2.subject = s2.subject AND\n\ts2.predicate = 14911999128994829034 AND\n\ts2.subject = XXX), "select people by BNode" );
}