1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * rasqal_expr_evaluate.c - Rasqal expression evaluation
4 *
5 * Copyright (C) 2003-2010, David Beckett http://www.dajobe.org/
6 * Copyright (C) 2003-2005, University of Bristol, UK http://www.bristol.ac.uk/
7 *
8 * This package is Free Software and part of Redland http://librdf.org/
9 *
10 * It is licensed under the following three licenses as alternatives:
11 * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12 * 2. GNU General Public License (GPL) V2 or any newer version
13 * 3. Apache License, V2.0 or any newer version
14 *
15 * You may not use this file except in compliance with at least one of
16 * the above three licenses.
17 *
18 * See LICENSE.html or LICENSE.txt at the top of this package for the
19 * complete terms and further detail along with the license texts for
20 * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
21 *
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <rasqal_config.h>
27 #endif
28
29 #ifdef WIN32
30 #include <win32_rasqal_config.h>
31 #endif
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39 #include <stdarg.h>
40
41 #include "rasqal.h"
42 #include "rasqal_internal.h"
43
44
45 #define DEBUG_FH stderr
46
47 /* Enable evaluation debugging by defining RASQAL_DEBUG_EVAL */
48 /* #define RASQAL_DEBUG_EVAL 1 */
49
50
51 /*
52 * rasqal_language_matches:
53 * @lang_tag: language tag such as "en" or "en-US" or "ab-cd-ef"
54 * @lang_range: language range such as "*" (SPARQL) or "en" or "ab-cd"
55 *
56 * INTERNAL - Match a language tag against a language range
57 *
58 * Returns true if @lang_range matches @lang_tag per
59 * Matching of Language Tags [RFC4647] section 2.1
60 * RFC4647 defines a case-insensitive, hierarchical matching
61 * algorithm which operates on ISO-defined subtags for language and
62 * country codes, and user defined subtags.
63 *
64 * (Note: RFC3066 section 2.5 matching is identical to
65 * RFC4647 section 3.3.1 Basic Filtering )
66 *
67 * In SPARQL, a language-range of "*" matches any non-empty @lang_tag string.
68 * See http://www.w3.org/TR/2007/WD-rdf-sparql-query-20070326/#func-langMatches
69 *
70 * Return value: non-0 if true
71 */
72 int
rasqal_language_matches(const unsigned char * lang_tag,const unsigned char * lang_range)73 rasqal_language_matches(const unsigned char* lang_tag,
74 const unsigned char* lang_range)
75 {
76 int b= 0;
77
78 if(!(lang_tag && lang_range && *lang_tag && *lang_range)) {
79 /* One of the arguments is NULL or the empty string */
80 return 0;
81 }
82
83 /* Now have two non-empty arguments */
84
85 /* Simple range string "*" matches anything excluding NULL/empty
86 * lang_tag (checked above)
87 */
88 if(lang_range[0] == '*') {
89 if(!lang_range[1])
90 b = 1;
91 return b;
92 }
93
94 while (1) {
95 char tag_c = RASQAL_GOOD_CAST(char, tolower(*lang_tag++));
96 char range_c = RASQAL_GOOD_CAST(char, tolower(*lang_range++));
97 if ((!tag_c && !range_c) || (!range_c && tag_c == '-')) {
98 /* EITHER
99 * The end of both strings (thus everything previous matched
100 * such as e.g. tag "fr-CA" matching range "fr-ca")
101 * OR
102 * The end of the range and end of the tag prefix (e.g. tag
103 * "en-US" matching range "en")
104 * means a match
105 */
106 b = 1;
107 break;
108 }
109 if (range_c != tag_c) {
110 /* If a difference was found - including one of the
111 * strings being shorter than the other, it means no match
112 * (b is set to 0 above)
113 */
114 break;
115 }
116 }
117
118 return b;
119 }
120
121
122 /*
123 * rasqal_expression_evaluate_strdt:
124 * @e: The expression to evaluate.
125 * @eval_context: Evaluation context
126 *
127 * INTERNAL - Evaluate RASQAL_EXPR_STRDT(expr) expression.
128 *
129 * Return value: A #rasqal_literal string value or NULL on failure.
130 */
131 static rasqal_literal*
rasqal_expression_evaluate_strdt(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)132 rasqal_expression_evaluate_strdt(rasqal_expression *e,
133 rasqal_evaluation_context *eval_context,
134 int *error_p)
135 {
136 rasqal_world* world = eval_context->world;
137 rasqal_literal *l1 = NULL;
138 rasqal_literal *l2 = NULL;
139 const unsigned char* s = NULL;
140 unsigned char* new_s = NULL;
141 size_t len;
142 raptor_uri* dt_uri = NULL;
143
144 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
145 if((error_p && *error_p) || !l1)
146 goto failed;
147
148 if(l1->language || l1->datatype) {
149 /* not a simple literal so return NULL success */
150 rasqal_free_literal(l1);
151 return NULL;
152 }
153
154 s = rasqal_literal_as_counted_string(l1, &len, eval_context->flags, error_p);
155 if(error_p && *error_p)
156 goto failed;
157
158 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
159 if((error_p && *error_p) || !l2)
160 goto failed;
161
162 dt_uri = rasqal_literal_as_uri(l2);
163 if(dt_uri) {
164 dt_uri = raptor_uri_copy(dt_uri);
165 } else {
166 const unsigned char *uri_string;
167
168 uri_string = rasqal_literal_as_string_flags(l2, eval_context->flags,
169 error_p);
170 if(error_p && *error_p)
171 goto failed;
172
173 dt_uri = raptor_new_uri(world->raptor_world_ptr, uri_string);
174 if(!dt_uri)
175 goto failed;
176 }
177
178 new_s =RASQAL_MALLOC(unsigned char*, len + 1);
179 if(!new_s)
180 goto failed;
181 memcpy(new_s, s, len + 1);
182
183 rasqal_free_literal(l1);
184 rasqal_free_literal(l2);
185
186 /* after this new_s and dt_uri become owned by result */
187 return rasqal_new_string_literal(world, new_s, /* language */ NULL,
188 dt_uri, /* qname */ NULL);
189
190
191 failed:
192 if(error_p)
193 *error_p = 1;
194
195 if(new_s)
196 RASQAL_FREE(char*, new_s);
197 if(l1)
198 rasqal_free_literal(l1);
199 if(l2)
200 rasqal_free_literal(l2);
201
202 return NULL;
203 }
204
205
206 /*
207 * rasqal_expression_evaluate_strlang:
208 * @e: The expression to evaluate.
209 * @eval_context: Evaluation context
210 *
211 * INTERNAL - Evaluate RASQAL_EXPR_STRLANG(expr) expression.
212 *
213 * Return value: A #rasqal_literal string value or NULL on failure.
214 */
215 static rasqal_literal*
rasqal_expression_evaluate_strlang(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)216 rasqal_expression_evaluate_strlang(rasqal_expression *e,
217 rasqal_evaluation_context *eval_context,
218 int *error_p)
219 {
220 rasqal_world* world = eval_context->world;
221 rasqal_literal *l1 = NULL;
222 rasqal_literal *l2 = NULL;
223 const unsigned char* s = NULL;
224 const unsigned char* lang = NULL;
225 unsigned char* new_s = NULL;
226 unsigned char* new_lang = NULL;
227 size_t len;
228 size_t lang_len;
229
230 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
231 if((error_p && *error_p) || !l1)
232 goto failed;
233
234 if(l1->language || l1->datatype) {
235 /* not a simple literal so return NULL success */
236 rasqal_free_literal(l1);
237 return NULL;
238 }
239
240 s = rasqal_literal_as_counted_string(l1, &len, eval_context->flags, error_p);
241 if(error_p && *error_p)
242 goto failed;
243
244 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
245 if((error_p && *error_p) || !l2)
246 goto failed;
247
248 lang = rasqal_literal_as_counted_string(l2, &lang_len, eval_context->flags,
249 error_p);
250 if(error_p && *error_p)
251 goto failed;
252
253 new_s = RASQAL_MALLOC(unsigned char*, len + 1);
254 if(!new_s)
255 goto failed;
256 memcpy(new_s, s, len + 1);
257
258 new_lang = RASQAL_MALLOC(unsigned char*, lang_len + 1);
259 if(!new_lang)
260 goto failed;
261 memcpy(new_lang, lang, lang_len + 1);
262
263 rasqal_free_literal(l1);
264 rasqal_free_literal(l2);
265
266 /* after this new_s and new_lang become owned by result */
267 return rasqal_new_string_literal(world, new_s,
268 RASQAL_GOOD_CAST(const char*, new_lang),
269 /*datatype */ NULL, /* qname */ NULL);
270
271
272 failed:
273 if(error_p)
274 *error_p = 1;
275
276 if(new_s)
277 RASQAL_FREE(char*, new_s);
278 if(l1)
279 rasqal_free_literal(l1);
280 if(l2)
281 rasqal_free_literal(l2);
282
283 return NULL;
284 }
285
286
287 /*
288 * rasqal_expression_evaluate_istype:
289 * @e: The expression to evaluate.
290 * @eval_context: Evaluation context
291 *
292 * INTERNAL - Evaluate RASQAL_EXPR_ISBLANK, RASQAL_EXPR_ISURI,
293 * RASQAL_EXPR_ISLITERAL and RASQAL_EXPR_ISNUMERIC (expr)
294 * expressions.
295 *
296 * Return value: A #rasqal_literal boolean value or NULL on failure.
297 */
298 static rasqal_literal*
rasqal_expression_evaluate_istype(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)299 rasqal_expression_evaluate_istype(rasqal_expression *e,
300 rasqal_evaluation_context *eval_context,
301 int *error_p)
302 {
303 rasqal_world* world = eval_context->world;
304 rasqal_literal* l1;
305 int free_literal = 1;
306 rasqal_variable *v;
307 int b;
308
309 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
310 if((error_p && *error_p) || !l1)
311 goto failed;
312
313 v = rasqal_literal_as_variable(l1);
314 if(v) {
315 rasqal_free_literal(l1);
316
317 l1 = v->value; /* don't need v after this */
318
319 free_literal = 0;
320 if(!l1)
321 goto failed;
322 }
323
324 if(e->op == RASQAL_EXPR_ISBLANK)
325 b = (l1->type == RASQAL_LITERAL_BLANK);
326 else if(e->op == RASQAL_EXPR_ISLITERAL)
327 b = (rasqal_literal_get_rdf_term_type(l1) == RASQAL_LITERAL_STRING);
328 else if(e->op == RASQAL_EXPR_ISURI)
329 b =(l1->type == RASQAL_LITERAL_URI);
330 else
331 b = (rasqal_literal_is_numeric(l1));
332
333 if(free_literal)
334 rasqal_free_literal(l1);
335
336 return rasqal_new_boolean_literal(world, b);
337
338 failed:
339 if(error_p)
340 *error_p = 1;
341
342 if(free_literal && l1)
343 rasqal_free_literal(l1);
344
345 return NULL;
346 }
347
348
349 /*
350 * rasqal_expression_evaluate_bound:
351 * @e: The expression to evaluate.
352 * @eval_context: Evaluation context
353 *
354 * INTERNAL - Evaluate RASQAL_EXPR_BOUND (variable) expressions.
355 *
356 * Return value: A #rasqal_literal boolean value or NULL on failure.
357 */
358 static rasqal_literal*
rasqal_expression_evaluate_bound(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)359 rasqal_expression_evaluate_bound(rasqal_expression *e,
360 rasqal_evaluation_context *eval_context,
361 int *error_p)
362 {
363 rasqal_world* world = eval_context->world;
364 rasqal_literal* l1;
365 rasqal_variable* v;
366
367 /* Do not use rasqal_expression_evaluate() here since
368 * we need to check the argument is a variable, and
369 * that function will flatten such thing to literals
370 * as early as possible. See (FLATTEN_LITERAL) below
371 */
372 if(!e->arg1 || e->arg1->op != RASQAL_EXPR_LITERAL)
373 goto failed;
374
375 l1 = e->arg1->literal;
376 if(!l1 || l1->type != RASQAL_LITERAL_VARIABLE)
377 goto failed;
378
379 v = rasqal_literal_as_variable(l1);
380 if(!v)
381 goto failed;
382
383 return rasqal_new_boolean_literal(world, (v->value != NULL));
384
385 failed:
386 if(error_p)
387 *error_p = 1;
388
389 return NULL;
390 }
391
392
393 /*
394 * rasqal_expression_evaluate_if:
395 * @e: The expression to evaluate.
396 * @eval_context: Evaluation context
397 *
398 * INTERNAL - Evaluate RASQAL_EXPR_IF (condition, true expr, false expr) expressions.
399 *
400 * Return value: A #rasqal_literal value or NULL on failure.
401 */
402 static rasqal_literal*
rasqal_expression_evaluate_if(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)403 rasqal_expression_evaluate_if(rasqal_expression *e,
404 rasqal_evaluation_context *eval_context,
405 int *error_p)
406 {
407 rasqal_literal* l1;
408 int b;
409
410 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
411 if((error_p && *error_p) || !l1)
412 goto failed;
413
414 /* IF condition */
415 b = rasqal_literal_as_boolean(l1, error_p);
416 rasqal_free_literal(l1);
417
418 if(error_p && *error_p)
419 goto failed;
420
421 /* condition is true: evaluate arg2 or false: evaluate arg3 */
422 return rasqal_expression_evaluate2(b ? e->arg2 : e->arg3, eval_context,
423 error_p);
424
425 failed:
426 if(error_p)
427 *error_p = 1;
428
429 return NULL;
430 }
431
432
433 /*
434 * rasqal_expression_evaluate_sameterm:
435 * @e: The expression to evaluate.
436 * @eval_context: Evaluation context
437 *
438 * INTERNAL - Evaluate RASQAL_EXPR_SAMETERM (expr1, expr2) expressions.
439 *
440 * Return value: A #rasqal_literal boolean value or NULL on failure.
441 */
442 static rasqal_literal*
rasqal_expression_evaluate_sameterm(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)443 rasqal_expression_evaluate_sameterm(rasqal_expression *e,
444 rasqal_evaluation_context *eval_context,
445 int *error_p)
446 {
447 rasqal_world* world = eval_context->world;
448 rasqal_literal* l1;
449 rasqal_literal* l2;
450 int b;
451
452 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
453 if((error_p && *error_p) || !l1)
454 goto failed;
455
456 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
457 if((error_p && *error_p) || !l2)
458 goto failed;
459
460 b = rasqal_literal_same_term(l1, l2);
461 #ifdef RASQAL_DEBUG_EVAL
462 RASQAL_DEBUG2("rasqal_literal_same_term() returned: %d\n", b);
463 #endif
464
465 rasqal_free_literal(l1);
466 rasqal_free_literal(l2);
467
468 return rasqal_new_boolean_literal(world, b);
469
470 failed:
471 if(error_p)
472 *error_p = 1;
473
474 if(l1)
475 rasqal_free_literal(l1);
476
477 return NULL;
478 }
479
480
481 /*
482 * rasqal_expression_evaluate_in_set:
483 * @e: The expression to evaluate.
484 * @eval_context: Evaluation context
485 *
486 * INTERNAL - Evaluate RASQAL_EXPR_IN and RASQAL_EXPR_NOT_IN (expr,
487 * expr list) expression.
488 *
489 * Return value: A #rasqal_literal boolean value or NULL on failure.
490 */
491 static rasqal_literal*
rasqal_expression_evaluate_in_set(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)492 rasqal_expression_evaluate_in_set(rasqal_expression *e,
493 rasqal_evaluation_context *eval_context,
494 int *error_p)
495 {
496 rasqal_world* world = eval_context->world;
497 int size = raptor_sequence_size(e->args);
498 int i;
499 rasqal_literal* l1;
500 int found = 0;
501
502 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
503 if((error_p && *error_p) || !l1)
504 goto failed;
505
506 for(i = 0; i < size; i++) {
507 rasqal_expression* arg_e;
508 rasqal_literal* arg_literal;
509
510 arg_e = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
511 arg_literal = rasqal_expression_evaluate2(arg_e, eval_context, error_p);
512 if(!arg_literal)
513 goto failed;
514
515 found = (rasqal_literal_equals_flags(l1, arg_literal,
516 eval_context->flags, error_p) != 0);
517 #ifdef RASQAL_DEBUG_EVAL
518 if(error_p && *error_p)
519 RASQAL_DEBUG1("rasqal_literal_equals_flags() returned: FAILURE\n");
520 else
521 RASQAL_DEBUG2("rasqal_literal_equals_flags() returned: %d\n", found);
522 #endif
523 rasqal_free_literal(arg_literal);
524
525 if(error_p && *error_p)
526 goto failed;
527
528 if(found)
529 /* found - terminate search */
530 break;
531 }
532 rasqal_free_literal(l1);
533
534 if(e->op == RASQAL_EXPR_NOT_IN)
535 found = !found;
536 return rasqal_new_boolean_literal(world, found);
537
538 failed:
539 if(error_p)
540 *error_p = 1;
541
542 if(l1)
543 rasqal_free_literal(l1);
544
545 return NULL;
546 }
547
548
549 /*
550 * rasqal_expression_evaluate_coalesce:
551 * @e: The expression to evaluate.
552 * @eval_context: Evaluation context
553 *
554 * INTERNAL - Evaluate RASQAL_EXPR_COALESCE (expr list) expressions.
555 *
556 * Return value: A #rasqal_literal value or NULL on failure.
557 */
558 static rasqal_literal*
rasqal_expression_evaluate_coalesce(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)559 rasqal_expression_evaluate_coalesce(rasqal_expression *e,
560 rasqal_evaluation_context *eval_context,
561 int *error_p)
562 {
563 int size = raptor_sequence_size(e->args);
564 int i;
565
566 for(i = 0; i < size; i++) {
567 rasqal_expression* arg_e;
568
569 arg_e = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
570 if(arg_e) {
571 int my_error = 0;
572 rasqal_literal* result;
573 result = rasqal_expression_evaluate2(arg_e, eval_context, &my_error);
574 if(!my_error && result)
575 return result;
576 }
577 }
578
579 /* No arguments evaluated to an RDF term, return an error (NULL) */
580 return NULL;
581 }
582
583
584 /*
585 * rasqal_expression_evaluate_str:
586 * @e: The expression to evaluate.
587 * @eval_context: Evaluation context
588 *
589 * INTERNAL - Evaluate RASQAL_EXPR_STR (literal expr) expression.
590 *
591 * Return value: A #rasqal_literal value or NULL on failure.
592 */
593 static rasqal_literal*
rasqal_expression_evaluate_str(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)594 rasqal_expression_evaluate_str(rasqal_expression *e,
595 rasqal_evaluation_context *eval_context,
596 int *error_p)
597 {
598 rasqal_world* world = eval_context->world;
599 rasqal_literal* l1 = NULL;
600 rasqal_literal* result = NULL;
601 const unsigned char *s;
602 size_t len;
603 unsigned char *new_s;
604
605 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
606 if((error_p && *error_p) || !l1)
607 goto failed;
608
609 /* Note: flags removes RASQAL_COMPARE_XQUERY as this is the
610 * explicit stringify operation and we want URIs as strings.
611 */
612 s = rasqal_literal_as_counted_string(l1, &len,
613 (eval_context->flags & ~RASQAL_COMPARE_XQUERY),
614 error_p);
615 if((error_p && *error_p) || !s)
616 goto failed;
617
618 new_s = RASQAL_MALLOC(unsigned char*, len + 1);
619 if(!new_s)
620 goto failed;
621
622 memcpy(RASQAL_GOOD_CAST(char*, new_s), RASQAL_GOOD_CAST(const char*, s), len + 1);
623
624 /* after this new_s is owned by result */
625 result = rasqal_new_string_literal(world, new_s, NULL, NULL, NULL);
626
627 if(l1)
628 rasqal_free_literal(l1);
629
630 return result;
631
632 failed:
633 if(error_p)
634 *error_p = 1;
635
636 if(l1)
637 rasqal_free_literal(l1);
638
639 return NULL;
640 }
641
642
643 /*
644 * rasqal_expression_evaluate_lang:
645 * @e: The expression to evaluate.
646 * @eval_context: Evaluation context
647 *
648 * INTERNAL - Evaluate RASQAL_EXPR_LANG (literal expr) expression.
649 *
650 * Return value: A #rasqal_literal value or NULL on failure.
651 */
652 static rasqal_literal*
rasqal_expression_evaluate_lang(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)653 rasqal_expression_evaluate_lang(rasqal_expression *e,
654 rasqal_evaluation_context *eval_context,
655 int *error_p)
656 {
657 rasqal_world* world = eval_context->world;
658 rasqal_literal* l1;
659 int free_literal = 1;
660 rasqal_variable* v = NULL;
661 unsigned char* new_s;
662
663 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
664 if((error_p && *error_p) || !l1)
665 goto failed;
666
667 v = rasqal_literal_as_variable(l1);
668 if(v) {
669 rasqal_free_literal(l1);
670
671 l1 = v->value; /* don't need v after this */
672
673 free_literal = 0;
674 if(!l1)
675 goto failed;
676 }
677
678 if(rasqal_literal_get_rdf_term_type(l1) != RASQAL_LITERAL_STRING)
679 goto failed;
680
681 if(l1->language) {
682 size_t len = strlen(l1->language);
683 new_s = RASQAL_MALLOC(unsigned char*, len + 1);
684 if(!new_s)
685 goto failed;
686
687 memcpy(RASQAL_GOOD_CAST(char*, new_s), l1->language, len + 1);
688 } else {
689 new_s = RASQAL_MALLOC(unsigned char*, 1);
690 if(!new_s)
691 goto failed;
692
693 *new_s = '\0';
694 }
695
696 if(free_literal)
697 rasqal_free_literal(l1);
698
699 /* after this new_s is owned by result */
700 return rasqal_new_string_literal(world, new_s, NULL, NULL, NULL);
701
702 failed:
703 if(error_p)
704 *error_p = 1;
705
706 if(free_literal)
707 rasqal_free_literal(l1);
708
709 return NULL;
710 }
711
712
713 /*
714 * rasqal_expression_evaluate_datatype:
715 * @e: The expression to evaluate.
716 * @eval_context: Evaluation context
717 *
718 * INTERNAL - Evaluate RASQAL_EXPR_DATATYPE (string literal) expression.
719 *
720 * Return value: A #rasqal_literal URI value or NULL on failure.
721 */
722 static rasqal_literal*
rasqal_expression_evaluate_datatype(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)723 rasqal_expression_evaluate_datatype(rasqal_expression *e,
724 rasqal_evaluation_context *eval_context,
725 int *error_p)
726 {
727 rasqal_world* world = eval_context->world;
728 rasqal_literal* l1;
729 int free_literal = 1;
730 rasqal_variable* v = NULL;
731 raptor_uri* dt_uri = NULL;
732
733 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
734 if((error_p && *error_p) || !l1)
735 goto failed;
736
737 v = rasqal_literal_as_variable(l1);
738 if(v) {
739 rasqal_free_literal(l1);
740
741 l1 = v->value; /* don't need v after this */
742
743 free_literal = 0;
744 if(!l1)
745 goto failed;
746 }
747
748 if(rasqal_literal_get_rdf_term_type(l1) != RASQAL_LITERAL_STRING)
749 goto failed;
750
751 if(l1->language)
752 goto failed;
753
754 /* The datatype of a plain literal is xsd:string */
755 dt_uri = l1->datatype;
756 if(!dt_uri && l1->type == RASQAL_LITERAL_STRING)
757 dt_uri = rasqal_xsd_datatype_type_to_uri(l1->world,
758 RASQAL_LITERAL_XSD_STRING);
759
760 if(!dt_uri)
761 goto failed;
762
763 dt_uri = raptor_uri_copy(dt_uri);
764
765 if(free_literal)
766 rasqal_free_literal(l1);
767
768 /* after this dt_uri is owned by result */
769 return rasqal_new_uri_literal(world, dt_uri);
770
771 failed:
772 if(error_p)
773 *error_p = 1;
774
775 if(free_literal)
776 rasqal_free_literal(l1);
777
778 return NULL;
779 }
780
781
782 /*
783 * rasqal_expression_evaluate_uri_constructor:
784 * @e: The expression to evaluate.
785 * @eval_context: Evaluation context
786 *
787 * INTERNAL - Evaluate RASQAL_EXPR_URI and RASQAL_EXPR_IRI (string)
788 * expressions.
789 *
790 * Return value: A #rasqal_literal URI value or NULL on failure.
791 */
792 static rasqal_literal*
rasqal_expression_evaluate_uri_constructor(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)793 rasqal_expression_evaluate_uri_constructor(rasqal_expression *e,
794 rasqal_evaluation_context *eval_context,
795 int *error_p)
796 {
797 rasqal_world* world = eval_context->world;
798 rasqal_literal* l1;
799 raptor_uri* dt_uri;
800 const unsigned char *s;
801
802 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
803 if((error_p && *error_p) || !l1)
804 goto failed;
805
806 s = rasqal_literal_as_string_flags(l1, eval_context->flags, error_p);
807 if(error_p && *error_p)
808 goto failed;
809
810 dt_uri = raptor_new_uri_relative_to_base(world->raptor_world_ptr,
811 eval_context->base_uri,
812 s);
813 rasqal_free_literal(l1); l1 = NULL;
814
815 if(!dt_uri)
816 goto failed;
817
818 /* after this dt_uri is owned by the result literal */
819 return rasqal_new_uri_literal(world, dt_uri);
820
821 failed:
822 if(error_p)
823 *error_p = 1;
824
825 if(l1)
826 rasqal_free_literal(l1);
827
828 return NULL;
829 }
830
831
832 /*
833 * rasqal_expression_evaluate_bnode_constructor:
834 * @e: The expression to evaluate.
835 * @eval_context: Evaluation context
836 *
837 * INTERNAL - Evaluate RASQAL_EXPR_BNODE (string) expression.
838 *
839 * Return value: A #rasqal_literal blank node value or NULL on failure.
840 */
841 static rasqal_literal*
rasqal_expression_evaluate_bnode_constructor(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)842 rasqal_expression_evaluate_bnode_constructor(rasqal_expression *e,
843 rasqal_evaluation_context *eval_context,
844 int *error_p)
845 {
846 rasqal_world* world = eval_context->world;
847 rasqal_literal *l1 = NULL;
848 unsigned char *new_s = NULL;
849
850 if(e->arg1) {
851 const unsigned char *s;
852 size_t len;
853
854 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
855 if((error_p && *error_p) || !l1)
856 goto failed;
857
858 s = rasqal_literal_as_counted_string(l1, &len, eval_context->flags,
859 error_p);
860 if(error_p && *error_p)
861 goto failed;
862
863 new_s = RASQAL_MALLOC(unsigned char*, len + 1);
864 if(!new_s)
865 goto failed;
866
867 memcpy(RASQAL_GOOD_CAST(char*, new_s), s, len + 1);
868
869 rasqal_free_literal(l1);
870 } else {
871 new_s = rasqal_world_generate_bnodeid(world, NULL);
872 if(!new_s)
873 goto failed;
874 }
875
876 /* after this new_s is owned by the result */
877 return rasqal_new_simple_literal(world, RASQAL_LITERAL_BLANK, new_s);
878
879 failed:
880 if(error_p)
881 *error_p = 1;
882
883 if(l1)
884 rasqal_free_literal(l1);
885
886 return NULL;
887 }
888
889
890 /**
891 * rasqal_expression_evaluate2:
892 * @e: The expression to evaluate.
893 * @eval_context: expression context
894 * @error_p: pointer to error return flag
895 *
896 * Evaluate a #rasqal_expression tree in the context of a
897 * #rasqal_evaluation_context to give a #rasqal_literal result or error.
898 *
899 * Return value: a #rasqal_literal value or NULL (a valid value). @error_p is set to non-0 on failure.
900 **/
901 rasqal_literal*
rasqal_expression_evaluate2(rasqal_expression * e,rasqal_evaluation_context * eval_context,int * error_p)902 rasqal_expression_evaluate2(rasqal_expression* e,
903 rasqal_evaluation_context* eval_context,
904 int *error_p)
905 {
906 rasqal_world *world;
907 int flags;
908 rasqal_literal* result = NULL;
909 rasqal_literal *l1;
910 rasqal_literal *l2;
911
912 /* pack vars from different switch cases in unions to save some stack space */
913 union {
914 struct { int e1; int e2; } errs;
915 struct { int dummy_do_not_mask_e; int free_literal; } flags;
916 int e;
917 } errs;
918 union {
919 struct { int b1; int b2; } bools;
920 int b;
921 int i;
922 raptor_uri *dt_uri;
923 const unsigned char *s;
924 unsigned char *new_s;
925 rasqal_variable *v;
926 rasqal_expression *e;
927 struct { void *dummy_do_not_mask; int found; } flags;
928 rasqal_xsd_datetime* dt;
929 struct timeval *tv;
930 raptor_stringbuffer* sb;
931 } vars;
932
933 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(e, rasqal_expression, NULL);
934 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(eval_context, rasqal_evaluation_context, NULL);
935 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(error_p, intp, NULL);
936
937 world = eval_context->world;
938 flags = eval_context->flags;
939
940 errs.e = 0;
941
942 #ifdef RASQAL_DEBUG_EVAL
943 RASQAL_DEBUG2("evaluating expression %p: ", e);
944 rasqal_expression_print(e, stderr);
945 fprintf(stderr, "\n");
946 #endif
947
948 switch(e->op) {
949 case RASQAL_EXPR_AND:
950 errs.errs.e1 = 0;
951 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, &errs.errs.e1);
952 if(errs.errs.e1) {
953 vars.bools.b1 = 0;
954 } else {
955 vars.bools.b1 = rasqal_literal_as_boolean(l1, &errs.errs.e1);
956 rasqal_free_literal(l1);
957 }
958
959 errs.errs.e2 = 0;
960 l1 = rasqal_expression_evaluate2(e->arg2, eval_context, &errs.errs.e2);
961 if(errs.errs.e2) {
962 vars.bools.b2 = 0;
963 } else {
964 vars.bools.b2 = rasqal_literal_as_boolean(l1, &errs.errs.e2);
965 rasqal_free_literal(l1);
966 }
967
968 /* See http://www.w3.org/TR/2005/WD-rdf-sparql-query-20051123/#truthTable */
969 if(!errs.errs.e1 && !errs.errs.e2) {
970 /* No type error, answer is A && B */
971 vars.b = vars.bools.b1 && vars.bools.b2; /* don't need b1,b2 anymore */
972 } else {
973 if((!vars.bools.b1 && errs.errs.e2) || (errs.errs.e1 && vars.bools.b2))
974 /* F && E => F. E && F => F. */
975 vars.b = 0;
976 else
977 /* Otherwise E */
978 goto failed;
979 }
980
981 result = rasqal_new_boolean_literal(world, vars.b);
982 break;
983
984 case RASQAL_EXPR_OR:
985 errs.errs.e1 = 0;
986 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, &errs.errs.e1);
987 if(errs.errs.e1) {
988 vars.bools.b1 = 0;
989 } else {
990 vars.bools.b1 = rasqal_literal_as_boolean(l1, &errs.errs.e1);
991 rasqal_free_literal(l1);
992 }
993
994 errs.errs.e2 = 0;
995 l1 = rasqal_expression_evaluate2(e->arg2, eval_context, &errs.errs.e2);
996 if(errs.errs.e2) {
997 vars.bools.b2 = 0;
998 } else {
999 vars.bools.b2 = rasqal_literal_as_boolean(l1, &errs.errs.e2);
1000 rasqal_free_literal(l1);
1001 }
1002
1003 /* See http://www.w3.org/TR/2005/WD-rdf-sparql-query-20051123/#truthTable */
1004 if(!errs.errs.e1 && !errs.errs.e2) {
1005 /* No type error, answer is A || B */
1006 vars.b = vars.bools.b1 || vars.bools.b2; /* don't need b1,b2 anymore */
1007 } else {
1008 if((vars.bools.b1 && errs.errs.e2) || (errs.errs.e1 && vars.bools.b2))
1009 /* T || E => T. E || T => T */
1010 vars.b = 1;
1011 else
1012 /* Otherwise E */
1013 goto failed;
1014 }
1015
1016 result = rasqal_new_boolean_literal(world, vars.b);
1017 break;
1018
1019 case RASQAL_EXPR_EQ:
1020 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1021 if((error_p && *error_p) || !l1)
1022 goto failed;
1023
1024 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1025 if((error_p && *error_p) || !l2) {
1026 rasqal_free_literal(l1);
1027 goto failed;
1028 }
1029
1030 /* FIXME - this should probably be checked at literal creation
1031 * time
1032 */
1033 if(!rasqal_xsd_datatype_check(l1->type, l1->string, flags) ||
1034 !rasqal_xsd_datatype_check(l2->type, l2->string, flags)) {
1035 #ifdef RASQAL_DEBUG_EVAL
1036 RASQAL_DEBUG1("One of the literals was invalid\n");
1037 #endif
1038 goto failed;
1039 }
1040
1041 vars.b = (rasqal_literal_equals_flags(l1, l2, flags, &errs.e) != 0);
1042 #ifdef RASQAL_DEBUG_EVAL
1043 if(errs.e)
1044 RASQAL_DEBUG1("rasqal_literal_equals_flags returned: FAILURE\n");
1045 else
1046 RASQAL_DEBUG2("rasqal_literal_equals_flags returned: %d\n", vars.b);
1047 #endif
1048 rasqal_free_literal(l1);
1049 rasqal_free_literal(l2);
1050 if(errs.e)
1051 goto failed;
1052
1053 result = rasqal_new_boolean_literal(world, vars.b);
1054 break;
1055
1056 case RASQAL_EXPR_NEQ:
1057 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1058 if((error_p && *error_p) || !l1)
1059 goto failed;
1060
1061 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1062 if((error_p && *error_p) || !l2) {
1063 rasqal_free_literal(l1);
1064 goto failed;
1065 }
1066
1067 vars.b = (rasqal_literal_not_equals_flags(l1, l2, flags, &errs.e) != 0);
1068 #ifdef RASQAL_DEBUG_EVAL
1069 if(errs.e)
1070 RASQAL_DEBUG1("rasqal_literal_not_equals_flags returned: FAILURE\n");
1071 else
1072 RASQAL_DEBUG2("rasqal_literal_not_equals_flags returned: %d\n", vars.b);
1073 #endif
1074 rasqal_free_literal(l1);
1075 rasqal_free_literal(l2);
1076 if(errs.e)
1077 goto failed;
1078
1079 result = rasqal_new_boolean_literal(world, vars.b);
1080 break;
1081
1082 case RASQAL_EXPR_LT:
1083 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1084 if((error_p && *error_p) || !l1)
1085 goto failed;
1086
1087 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1088 if((error_p && *error_p) || !l2) {
1089 rasqal_free_literal(l1);
1090 goto failed;
1091 }
1092
1093 vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) < 0);
1094 rasqal_free_literal(l1);
1095 rasqal_free_literal(l2);
1096 if(errs.e)
1097 goto failed;
1098
1099 result = rasqal_new_boolean_literal(world, vars.b);
1100 break;
1101
1102 case RASQAL_EXPR_GT:
1103 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1104 if((error_p && *error_p) || !l1)
1105 goto failed;
1106
1107 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1108 if((error_p && *error_p) || !l2) {
1109 rasqal_free_literal(l1);
1110 goto failed;
1111 }
1112
1113 vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) > 0);
1114 rasqal_free_literal(l1);
1115 rasqal_free_literal(l2);
1116 if(errs.e)
1117 goto failed;
1118
1119 result = rasqal_new_boolean_literal(world, vars.b);
1120 break;
1121
1122 case RASQAL_EXPR_LE:
1123 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1124 if((error_p && *error_p) || !l1)
1125 goto failed;
1126
1127 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1128 if((error_p && *error_p) || !l2) {
1129 rasqal_free_literal(l1);
1130 goto failed;
1131 }
1132
1133 vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) <= 0);
1134 rasqal_free_literal(l1);
1135 rasqal_free_literal(l2);
1136 if(errs.e)
1137 goto failed;
1138
1139 result = rasqal_new_boolean_literal(world, vars.b);
1140 break;
1141
1142 case RASQAL_EXPR_GE:
1143 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1144 if((error_p && *error_p) || !l1)
1145 goto failed;
1146
1147 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1148 if((error_p && *error_p) || !l2) {
1149 rasqal_free_literal(l1);
1150 goto failed;
1151 }
1152
1153 vars.b = (rasqal_literal_compare(l1, l2, flags, &errs.e) >= 0);
1154 rasqal_free_literal(l1);
1155 rasqal_free_literal(l2);
1156 if(errs.e)
1157 goto failed;
1158
1159 result = rasqal_new_boolean_literal(world, vars.b);
1160 break;
1161
1162 case RASQAL_EXPR_UMINUS:
1163 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1164 if((error_p && *error_p) || !l1)
1165 goto failed;
1166
1167 result = rasqal_literal_negate(l1, &errs.e);
1168 rasqal_free_literal(l1);
1169 if(errs.e)
1170 goto failed;
1171 break;
1172
1173 case RASQAL_EXPR_BOUND:
1174 result = rasqal_expression_evaluate_bound(e, eval_context, error_p);
1175 break;
1176
1177 case RASQAL_EXPR_STR:
1178 result = rasqal_expression_evaluate_str(e, eval_context, error_p);
1179 break;
1180
1181 case RASQAL_EXPR_LANG:
1182 result = rasqal_expression_evaluate_lang(e, eval_context, error_p);
1183 break;
1184
1185 case RASQAL_EXPR_LANGMATCHES:
1186 result = rasqal_expression_evaluate_langmatches(e, eval_context, error_p);
1187 break;
1188
1189 case RASQAL_EXPR_DATATYPE:
1190 result = rasqal_expression_evaluate_datatype(e, eval_context, error_p);
1191 break;
1192
1193 case RASQAL_EXPR_ISURI:
1194 case RASQAL_EXPR_ISBLANK:
1195 case RASQAL_EXPR_ISLITERAL:
1196 case RASQAL_EXPR_ISNUMERIC:
1197 result = rasqal_expression_evaluate_istype(e, eval_context, error_p);
1198 break;
1199
1200 case RASQAL_EXPR_PLUS:
1201 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1202 if((error_p && *error_p) || !l1)
1203 goto failed;
1204
1205 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1206 if((error_p && *error_p) || !l2) {
1207 rasqal_free_literal(l1);
1208 goto failed;
1209 }
1210
1211 result = rasqal_literal_add(l1, l2, &errs.e);
1212 rasqal_free_literal(l1);
1213 rasqal_free_literal(l2);
1214 if(errs.e)
1215 goto failed;
1216
1217 break;
1218
1219 case RASQAL_EXPR_MINUS:
1220 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1221 if((error_p && *error_p) || !l1)
1222 goto failed;
1223
1224 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1225 if((error_p && *error_p) || !l2) {
1226 rasqal_free_literal(l1);
1227 goto failed;
1228 }
1229
1230 result = rasqal_literal_subtract(l1, l2, &errs.e);
1231 rasqal_free_literal(l1);
1232 rasqal_free_literal(l2);
1233 if(errs.e)
1234 goto failed;
1235
1236 break;
1237
1238 case RASQAL_EXPR_STAR:
1239 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1240 if((error_p && *error_p) || !l1)
1241 goto failed;
1242
1243 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1244 if((error_p && *error_p) || !l2) {
1245 rasqal_free_literal(l1);
1246 goto failed;
1247 }
1248
1249 result = rasqal_literal_multiply(l1, l2, &errs.e);
1250 rasqal_free_literal(l1);
1251 rasqal_free_literal(l2);
1252 if(errs.e)
1253 goto failed;
1254
1255 break;
1256
1257 case RASQAL_EXPR_SLASH:
1258 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1259 if((error_p && *error_p) || !l1)
1260 goto failed;
1261
1262 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1263 if((error_p && *error_p) || !l2) {
1264 rasqal_free_literal(l1);
1265 goto failed;
1266 }
1267
1268 result = rasqal_literal_divide(l1, l2, &errs.e);
1269 rasqal_free_literal(l1);
1270 rasqal_free_literal(l2);
1271 if(errs.e)
1272 goto failed;
1273
1274 break;
1275
1276 case RASQAL_EXPR_REM:
1277 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1278 if((error_p && *error_p) || !l1)
1279 goto failed;
1280
1281 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1282 if((error_p && *error_p) || !l2) {
1283 rasqal_free_literal(l1);
1284 goto failed;
1285 }
1286
1287 vars.i = rasqal_literal_as_integer(l2, &errs.errs.e2);
1288 /* error if divisor is zero */
1289 if(!vars.i)
1290 errs.errs.e2 = 1;
1291 else
1292 vars.i = rasqal_literal_as_integer(l1, &errs.errs.e1) % vars.i;
1293
1294 rasqal_free_literal(l1);
1295 rasqal_free_literal(l2);
1296 if(errs.errs.e1 || errs.errs.e2)
1297 goto failed;
1298
1299 result = rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, vars.i);
1300 break;
1301
1302 case RASQAL_EXPR_STR_EQ:
1303 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1304 if((error_p && *error_p) || !l1)
1305 goto failed;
1306
1307 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1308 if((error_p && *error_p) || !l2) {
1309 rasqal_free_literal(l1);
1310 goto failed;
1311 }
1312
1313 vars.b = (rasqal_literal_compare(l1, l2, flags | RASQAL_COMPARE_NOCASE,
1314 &errs.e) == 0);
1315 rasqal_free_literal(l1);
1316 rasqal_free_literal(l2);
1317 if(errs.e)
1318 goto failed;
1319
1320 result = rasqal_new_boolean_literal(world, vars.b);
1321 break;
1322
1323 case RASQAL_EXPR_STR_NEQ:
1324 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1325 if((error_p && *error_p) || !l1)
1326 goto failed;
1327
1328 l2 = rasqal_expression_evaluate2(e->arg2, eval_context, error_p);
1329 if((error_p && *error_p) || !l2) {
1330 rasqal_free_literal(l1);
1331 goto failed;
1332 }
1333
1334 vars.b = (rasqal_literal_compare(l1, l2, flags | RASQAL_COMPARE_NOCASE,
1335 &errs.e) != 0);
1336 rasqal_free_literal(l1);
1337 rasqal_free_literal(l2);
1338 if(errs.e)
1339 goto failed;
1340
1341 result = rasqal_new_boolean_literal(world, vars.b);
1342 break;
1343
1344 case RASQAL_EXPR_TILDE:
1345 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1346 if((error_p && *error_p) || !l1)
1347 goto failed;
1348
1349 vars.i= ~ rasqal_literal_as_integer(l1, &errs.e);
1350 rasqal_free_literal(l1);
1351 if(errs.e)
1352 goto failed;
1353
1354 result = rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, vars.i);
1355 break;
1356
1357 case RASQAL_EXPR_BANG:
1358 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1359 if((error_p && *error_p) || !l1)
1360 goto failed;
1361
1362 vars.b = ! rasqal_literal_as_boolean(l1, &errs.e);
1363 rasqal_free_literal(l1);
1364 if(errs.e)
1365 goto failed;
1366
1367 result = rasqal_new_boolean_literal(world, vars.b);
1368 break;
1369
1370 case RASQAL_EXPR_STR_MATCH:
1371 case RASQAL_EXPR_STR_NMATCH:
1372 case RASQAL_EXPR_REGEX:
1373 result = rasqal_expression_evaluate_strmatch(e, eval_context, error_p);
1374 break;
1375
1376 case RASQAL_EXPR_LITERAL:
1377 /* flatten any literal to a value as soon as possible - this
1378 * removes variables from expressions the first time they are seen.
1379 * (FLATTEN_LITERAL)
1380 */
1381 result = rasqal_new_literal_from_literal(rasqal_literal_value(e->literal));
1382 break;
1383
1384 case RASQAL_EXPR_FUNCTION:
1385 rasqal_log_warning_simple(world, RASQAL_WARNING_LEVEL_NOT_IMPLEMENTED,
1386 eval_context->locator,
1387 "No function expressions support at present. Returning false.");
1388 result = rasqal_new_boolean_literal(world, 0);
1389 break;
1390
1391 case RASQAL_EXPR_CAST:
1392 l1 = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1393 if((error_p && *error_p) || !l1)
1394 goto failed;
1395
1396 result = rasqal_literal_cast(l1, e->name, flags, &errs.e);
1397
1398 rasqal_free_literal(l1);
1399 if(errs.e)
1400 goto failed;
1401
1402 break;
1403
1404 case RASQAL_EXPR_ORDER_COND_ASC:
1405 case RASQAL_EXPR_ORDER_COND_DESC:
1406 case RASQAL_EXPR_GROUP_COND_ASC:
1407 case RASQAL_EXPR_GROUP_COND_DESC:
1408 result = rasqal_expression_evaluate2(e->arg1, eval_context, error_p);
1409 break;
1410
1411 case RASQAL_EXPR_COUNT:
1412 case RASQAL_EXPR_SUM:
1413 case RASQAL_EXPR_AVG:
1414 case RASQAL_EXPR_MIN:
1415 case RASQAL_EXPR_MAX:
1416 case RASQAL_EXPR_SAMPLE:
1417 case RASQAL_EXPR_GROUP_CONCAT:
1418 rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR,
1419 eval_context->locator,
1420 "Aggregate expressions cannot be evaluated in a general scalar expression.");
1421 errs.e = 1;
1422 goto failed;
1423
1424 case RASQAL_EXPR_VARSTAR:
1425 /* constants */
1426 break;
1427
1428 case RASQAL_EXPR_SAMETERM:
1429 result = rasqal_expression_evaluate_sameterm(e, eval_context, error_p);
1430 break;
1431
1432 case RASQAL_EXPR_CONCAT:
1433 result = rasqal_expression_evaluate_concat(e, eval_context, error_p);
1434 break;
1435
1436 case RASQAL_EXPR_COALESCE:
1437 result = rasqal_expression_evaluate_coalesce(e, eval_context, error_p);
1438 break;
1439
1440 case RASQAL_EXPR_IF:
1441 result = rasqal_expression_evaluate_if(e, eval_context, error_p);
1442 break;
1443
1444 case RASQAL_EXPR_URI:
1445 case RASQAL_EXPR_IRI:
1446 result = rasqal_expression_evaluate_uri_constructor(e, eval_context, error_p);
1447 break;
1448
1449 case RASQAL_EXPR_STRLANG:
1450 result = rasqal_expression_evaluate_strlang(e, eval_context, error_p);
1451 break;
1452
1453 case RASQAL_EXPR_STRDT:
1454 result = rasqal_expression_evaluate_strdt(e, eval_context, error_p);
1455 break;
1456
1457 case RASQAL_EXPR_BNODE:
1458 result = rasqal_expression_evaluate_bnode_constructor(e, eval_context, error_p);
1459 break;
1460
1461 case RASQAL_EXPR_IN:
1462 result = rasqal_expression_evaluate_in_set(e, eval_context, error_p);
1463 break;
1464
1465 case RASQAL_EXPR_NOT_IN:
1466 result = rasqal_expression_evaluate_in_set(e, eval_context, error_p);
1467 break;
1468
1469 case RASQAL_EXPR_YEAR:
1470 case RASQAL_EXPR_MONTH:
1471 case RASQAL_EXPR_DAY:
1472 case RASQAL_EXPR_HOURS:
1473 case RASQAL_EXPR_MINUTES:
1474 case RASQAL_EXPR_SECONDS:
1475 result = rasqal_expression_evaluate_datetime_part(e, eval_context, error_p);
1476 break;
1477
1478 case RASQAL_EXPR_CURRENT_DATETIME:
1479 case RASQAL_EXPR_NOW:
1480 result = rasqal_expression_evaluate_now(e, eval_context, error_p);
1481 break;
1482
1483 case RASQAL_EXPR_TO_UNIXTIME:
1484 result = rasqal_expression_evaluate_to_unixtime(e, eval_context, error_p);
1485 break;
1486
1487 case RASQAL_EXPR_FROM_UNIXTIME:
1488 result = rasqal_expression_evaluate_from_unixtime(e, eval_context, error_p);
1489 break;
1490
1491 case RASQAL_EXPR_RAND:
1492 result = rasqal_expression_evaluate_rand(e, eval_context, error_p);
1493 break;
1494
1495 case RASQAL_EXPR_STRLEN:
1496 result = rasqal_expression_evaluate_strlen(e, eval_context, error_p);
1497 break;
1498
1499 case RASQAL_EXPR_UCASE:
1500 case RASQAL_EXPR_LCASE:
1501 result = rasqal_expression_evaluate_set_case(e, eval_context, error_p);
1502 break;
1503
1504 case RASQAL_EXPR_STRSTARTS:
1505 case RASQAL_EXPR_STRENDS:
1506 case RASQAL_EXPR_CONTAINS:
1507 result = rasqal_expression_evaluate_str_prefix_suffix(e, eval_context, error_p);
1508 break;
1509
1510 case RASQAL_EXPR_TIMEZONE:
1511 result = rasqal_expression_evaluate_datetime_timezone(e, eval_context, error_p);
1512 break;
1513
1514 case RASQAL_EXPR_TZ:
1515 result = rasqal_expression_evaluate_datetime_tz(e, eval_context, error_p);
1516 break;
1517
1518 case RASQAL_EXPR_ENCODE_FOR_URI:
1519 result = rasqal_expression_evaluate_encode_for_uri(e, eval_context, error_p);
1520 break;
1521
1522 case RASQAL_EXPR_SUBSTR:
1523 result = rasqal_expression_evaluate_substr(e, eval_context, error_p);
1524 break;
1525
1526 case RASQAL_EXPR_STRBEFORE:
1527 result = rasqal_expression_evaluate_strbefore(e, eval_context, error_p);
1528 break;
1529
1530 case RASQAL_EXPR_STRAFTER:
1531 result = rasqal_expression_evaluate_strafter(e, eval_context, error_p);
1532 break;
1533
1534 case RASQAL_EXPR_REPLACE:
1535 result = rasqal_expression_evaluate_replace(e, eval_context, error_p);
1536 break;
1537
1538 case RASQAL_EXPR_ABS:
1539 result = rasqal_expression_evaluate_abs(e, eval_context, error_p);
1540 break;
1541
1542 case RASQAL_EXPR_ROUND:
1543 result = rasqal_expression_evaluate_round(e, eval_context, error_p);
1544 break;
1545
1546 case RASQAL_EXPR_CEIL:
1547 result = rasqal_expression_evaluate_ceil(e, eval_context, error_p);
1548 break;
1549
1550 case RASQAL_EXPR_FLOOR:
1551 result = rasqal_expression_evaluate_floor(e, eval_context, error_p);
1552 break;
1553
1554 case RASQAL_EXPR_MD5:
1555 case RASQAL_EXPR_SHA1:
1556 case RASQAL_EXPR_SHA224:
1557 case RASQAL_EXPR_SHA256:
1558 case RASQAL_EXPR_SHA384:
1559 case RASQAL_EXPR_SHA512:
1560 result = rasqal_expression_evaluate_digest(e, eval_context, error_p);
1561 break;
1562
1563 case RASQAL_EXPR_UUID:
1564 result = rasqal_expression_evaluate_uriuuid(e, eval_context, error_p);
1565 break;
1566
1567 case RASQAL_EXPR_STRUUID:
1568 result = rasqal_expression_evaluate_struuid(e, eval_context, error_p);
1569 break;
1570
1571 case RASQAL_EXPR_UNKNOWN:
1572 default:
1573 RASQAL_FATAL3("Unknown operation %s (%u)",
1574 rasqal_expression_op_label(e->op), e->op);
1575 }
1576
1577 got_result:
1578
1579 #ifdef RASQAL_DEBUG_EVAL
1580 RASQAL_DEBUG2("result of %p: ", e);
1581 rasqal_expression_print(e, stderr);
1582 fputs( ": ", stderr);
1583 if(error_p && *error_p)
1584 fputs("FAILURE",stderr);
1585 else
1586 rasqal_literal_print(result, stderr);
1587 fputc('\n', stderr);
1588 #endif
1589
1590 return result;
1591
1592 failed:
1593 *error_p = 1;
1594
1595 if(result) {
1596 rasqal_free_literal(result);
1597 result = NULL;
1598 }
1599 goto got_result;
1600 }
1601
1602
1603 #ifndef RASQAL_DISABLE_DEPRECATED
1604 /**
1605 * rasqal_expression_evaluate:
1606 * @world: #rasqal_world
1607 * @locator: error locator (or NULL)
1608 * @e: The expression to evaluate.
1609 * @flags: Flags for rasqal_literal_compare() and RASQAL_COMPARE_NOCASE for string matches.
1610 *
1611 * Evaluate a #rasqal_expression tree to give a #rasqal_literal result
1612 * or error.
1613 *
1614 * @Deprecated: use rasqal_expression_evaluate2() using a #rasqal_evaluation_context
1615 *
1616 * Return value: a #rasqal_literal value or NULL on failure.
1617 **/
1618 rasqal_literal*
rasqal_expression_evaluate(rasqal_world * world,raptor_locator * locator,rasqal_expression * e,int flags)1619 rasqal_expression_evaluate(rasqal_world *world, raptor_locator *locator,
1620 rasqal_expression* e, int flags)
1621 {
1622 rasqal_evaluation_context context; /* static */
1623 int error = 0;
1624 rasqal_literal* l;
1625
1626 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
1627 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(e, rasqal_expression, NULL);
1628
1629 memset(&context, '\0', sizeof(context));
1630 context.world = world;
1631 context.locator = locator;
1632 context.flags = flags;
1633
1634 l = rasqal_expression_evaluate2(e, &context, &error);
1635 if(error)
1636 return NULL;
1637
1638 return l;
1639 }
1640 #endif
1641