1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * rasqal_expr.c - Rasqal general expression support
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 
48 #ifndef STANDALONE
49 
50 
51 /**
52  * rasqal_new_0op_expression:
53  * @world: rasqal_world object
54  * @op: Expression operator
55  *
56  * Constructor - create a new 0-operand (constant) expression.
57  *
58  * The operators are:
59  * @RASQAL_EXPR_VARSTAR
60  *
61  * The only operator here is the '*' in COUNT(*) as used by LAQRS.
62  *
63  * Return value: a new #rasqal_expression object or NULL on failure
64  **/
65 rasqal_expression*
rasqal_new_0op_expression(rasqal_world * world,rasqal_op op)66 rasqal_new_0op_expression(rasqal_world* world, rasqal_op op)
67 {
68   rasqal_expression* e;
69 
70   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
71 
72   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
73   if(e) {
74     e->usage = 1;
75     e->world = world;
76     e->op = op;
77   }
78   return e;
79 }
80 
81 
82 /**
83  * rasqal_new_1op_expression:
84  * @world: rasqal_world object
85  * @op: Expression operator
86  * @arg: Operand 1
87  *
88  * Constructor - create a new 1-operand expression.
89  * Takes ownership of the operand expression.
90  *
91  * The operators are:
92  * @RASQAL_EXPR_TILDE @RASQAL_EXPR_BANG @RASQAL_EXPR_UMINUS
93  * @RASQAL_EXPR_BOUND @RASQAL_EXPR_STR @RASQAL_EXPR_LANG
94  * @RASQAL_EXPR_LANGMATCHES
95  * @RASQAL_EXPR_DATATYPE @RASQAL_EXPR_ISURI @RASQAL_EXPR_ISBLANK
96  * @RASQAL_EXPR_ISLITERAL @RASQAL_EXPR_ORDER_COND_ASC
97  * @RASQAL_EXPR_ORDER_COND_DESC @RASQAL_EXPR_COUNT @RASQAL_EXPR_SUM
98  * @RASQAL_EXPR_AVG @RASQAL_EXPR_MIN @RASQAL_EXPR_MAX
99  *
100  * The operator @RASQAL_EXPR_TILDE is not used by SPARQL (formerly RDQL).
101  *
102  * Return value: a new #rasqal_expression object or NULL on failure
103  **/
104 rasqal_expression*
rasqal_new_1op_expression(rasqal_world * world,rasqal_op op,rasqal_expression * arg)105 rasqal_new_1op_expression(rasqal_world* world, rasqal_op op,
106                           rasqal_expression* arg)
107 {
108   rasqal_expression* e = NULL;
109 
110   if(op == RASQAL_EXPR_BNODE) {
111     if(!world)
112       goto tidy;
113   } else {
114     if(!world || !arg)
115       goto tidy;
116   }
117 
118   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
119   if(e) {
120     e->usage = 1;
121     e->world = world;
122     e->op = op;
123     e->arg1 = arg; arg = NULL;
124   }
125 
126   tidy:
127   if(arg)
128     rasqal_free_expression(arg);
129 
130   return e;
131 }
132 
133 
134 /**
135  * rasqal_new_2op_expression:
136  * @world: rasqal_world object
137  * @op: Expression operator
138  * @arg1: Operand 1
139  * @arg2: Operand 2
140  *
141  * Constructor - create a new 2-operand expression.
142  * Takes ownership of the operand expressions.
143  *
144  * The operators are:
145  * @RASQAL_EXPR_AND @RASQAL_EXPR_OR @RASQAL_EXPR_EQ
146  * @RASQAL_EXPR_NEQ @RASQAL_EXPR_LT @RASQAL_EXPR_GT @RASQAL_EXPR_LE
147  * @RASQAL_EXPR_GE @RASQAL_EXPR_PLUS @RASQAL_EXPR_MINUS
148  * @RASQAL_EXPR_STAR @RASQAL_EXPR_SLASH @RASQAL_EXPR_REM
149  * @RASQAL_EXPR_STR_EQ @RASQAL_EXPR_STR_NEQ
150  *
151  * @RASQAL_EXPR_REM @RASQAL_EXPR_STR_EQ, @RASQAL_EXPR_STR_NEQ and
152  * @RASQAL_EXPR_REM are unused (formerly RDQL).
153  *
154  * Return value: a new #rasqal_expression object or NULL on failure
155  **/
156 rasqal_expression*
rasqal_new_2op_expression(rasqal_world * world,rasqal_op op,rasqal_expression * arg1,rasqal_expression * arg2)157 rasqal_new_2op_expression(rasqal_world* world,
158                           rasqal_op op,
159                           rasqal_expression* arg1,
160                           rasqal_expression* arg2)
161 {
162   rasqal_expression* e = NULL;
163 
164   if(!world || !arg1 || !arg2)
165     goto tidy;
166 
167   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
168   if(e) {
169     e->usage = 1;
170     e->world = world;
171     e->op = op;
172     e->arg1 = arg1; arg1 = NULL;
173     e->arg2 = arg2; arg2 = NULL;
174   }
175 
176 tidy:
177   if(arg1)
178     rasqal_free_expression(arg1);
179   if(arg2)
180     rasqal_free_expression(arg2);
181 
182   return e;
183 }
184 
185 
186 /**
187  * rasqal_new_3op_expression:
188  * @world: rasqal_world object
189  * @op: Expression operator
190  * @arg1: Operand 1
191  * @arg2: Operand 2
192  * @arg3: Operand 3 (may be NULL)
193  *
194  * Constructor - create a new 3-operand expression.
195  * Takes ownership of the operands.
196  *
197  * The operators are:
198  * #RASQAL_EXPR_REGEX #RASQAL_EXPR_IF #RASQAL_EXPR_SUBSTR
199  *
200  * Return value: a new #rasqal_expression object or NULL on failure
201  **/
202 rasqal_expression*
rasqal_new_3op_expression(rasqal_world * world,rasqal_op op,rasqal_expression * arg1,rasqal_expression * arg2,rasqal_expression * arg3)203 rasqal_new_3op_expression(rasqal_world* world,
204                           rasqal_op op,
205                           rasqal_expression* arg1,
206                           rasqal_expression* arg2,
207                           rasqal_expression* arg3)
208 {
209   rasqal_expression* e = NULL;
210 
211   if(!world || !arg1 || !arg2) /* arg3 may be NULL */
212     goto tidy;
213 
214   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
215   if(e) {
216     e->usage = 1;
217     e->world = world;
218     e->op = op;
219     e->arg1 = arg1; arg1 = NULL;
220     e->arg2 = arg2; arg2 = NULL;
221     e->arg3 = arg3; arg3 = NULL;
222   }
223 
224   tidy:
225   if(arg1)
226     rasqal_free_expression(arg1);
227   if(arg2)
228     rasqal_free_expression(arg2);
229   if(arg3)
230     rasqal_free_expression(arg3);
231 
232   return e;
233 }
234 
235 
236 /**
237  * rasqal_new_4op_expression:
238  * @world: rasqal_world object
239  * @op: Expression operator
240  * @arg1: Operand 1
241  * @arg2: Operand 2
242  * @arg3: Operand 3
243  * @arg4: Operand 4 (may be NULL)
244  *
245  * Constructor - create a new 4-operand expression.
246  * Takes ownership of the operands.
247  *
248  * The operators are:
249  * #RASQAL_EXPR_REPLACE
250  *
251  * Return value: a new #rasqal_expression object or NULL on failure
252  **/
253 rasqal_expression*
rasqal_new_4op_expression(rasqal_world * world,rasqal_op op,rasqal_expression * arg1,rasqal_expression * arg2,rasqal_expression * arg3,rasqal_expression * arg4)254 rasqal_new_4op_expression(rasqal_world* world,
255                           rasqal_op op,
256                           rasqal_expression* arg1,
257                           rasqal_expression* arg2,
258                           rasqal_expression* arg3,
259                           rasqal_expression* arg4)
260 {
261   rasqal_expression* e = NULL;
262 
263   if(!world || !arg1 || !arg2 || !arg3) /* arg4 may be NULL */
264     goto tidy;
265 
266   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
267   if(e) {
268     e->usage = 1;
269     e->world = world;
270     e->op = op;
271     e->arg1 = arg1; arg1 = NULL;
272     e->arg2 = arg2; arg2 = NULL;
273     e->arg3 = arg3; arg3 = NULL;
274     e->arg4 = arg4; arg4 = NULL;
275   }
276 
277   tidy:
278   if(arg1)
279     rasqal_free_expression(arg1);
280   if(arg2)
281     rasqal_free_expression(arg2);
282   if(arg3)
283     rasqal_free_expression(arg3);
284   if(arg4)
285     rasqal_free_expression(arg4);
286 
287   return e;
288 }
289 
290 
291 /**
292  * rasqal_new_string_op_expression:
293  * @world: rasqal_world object
294  * @op: Expression operator
295  * @arg1: Operand 1
296  * @literal: Literal operand 2
297  *
298  * Constructor - create a new expression with one expression and one string operand.
299  * Takes ownership of the operands.
300  *
301  * The operators are:
302  * @RASQAL_EXPR_STR_MATCH and
303  * @RASQAL_EXPR_STR_NMATCH (unused: formerly for RDQL)
304  *
305  * Return value: a new #rasqal_expression object or NULL on failure
306  **/
307 rasqal_expression*
rasqal_new_string_op_expression(rasqal_world * world,rasqal_op op,rasqal_expression * arg1,rasqal_literal * literal)308 rasqal_new_string_op_expression(rasqal_world* world,
309                                 rasqal_op op,
310                                 rasqal_expression* arg1,
311                                 rasqal_literal* literal)
312 {
313   rasqal_expression* e = NULL;
314 
315   if(!world || !arg1 || !literal)
316     goto tidy;
317 
318   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
319   if(e) {
320     e->usage = 1;
321     e->world = world;
322     e->op = op;
323     e->arg1 = arg1; arg1 = NULL;
324     e->literal = literal; literal = NULL;
325   }
326 
327   tidy:
328   if(arg1)
329     rasqal_free_expression(arg1);
330   if(literal)
331     rasqal_free_literal(literal);
332 
333   return e;
334 }
335 
336 
337 /**
338  * rasqal_new_literal_expression:
339  * @world: rasqal_world object
340  * @literal: Literal operand 1
341  *
342  * Constructor - create a new expression for a #rasqal_literal
343  * Takes ownership of the operand literal.
344  *
345  * Return value: a new #rasqal_expression object or NULL on failure
346  **/
347 rasqal_expression*
rasqal_new_literal_expression(rasqal_world * world,rasqal_literal * literal)348 rasqal_new_literal_expression(rasqal_world* world, rasqal_literal *literal)
349 {
350   rasqal_expression* e;
351 
352   if(!world || !literal)
353     return NULL;
354 
355   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
356   if(e) {
357     e->usage = 1;
358     e->world = world;
359     e->op = RASQAL_EXPR_LITERAL;
360     e->literal = literal;
361   } else {
362     rasqal_free_literal(literal);
363   }
364   return e;
365 }
366 
367 
368 static rasqal_expression*
rasqal_new_function_expression_common(rasqal_world * world,rasqal_op op,raptor_uri * name,rasqal_expression * arg1,raptor_sequence * args,raptor_sequence * params,unsigned int flags)369 rasqal_new_function_expression_common(rasqal_world* world,
370                                       rasqal_op op,
371                                       raptor_uri* name,
372                                       rasqal_expression* arg1,
373                                       raptor_sequence* args,
374                                       raptor_sequence* params,
375                                       unsigned int flags)
376 {
377   rasqal_expression* e = NULL;
378 
379   if(!world || (arg1 && args) || (name && !args)|| (!name && args))
380     goto tidy;
381 
382   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
383   if(e) {
384     e->usage = 1;
385     e->world = world;
386     e->op = op;
387     e->name = name; name = NULL;
388     e->arg1 = arg1; arg1 = NULL;
389     e->args = args; args = NULL;
390     e->params = params; params = NULL;
391     e->flags = flags;
392   }
393 
394   tidy:
395   if(name)
396     raptor_free_uri(name);
397   if(args)
398     raptor_free_sequence(args);
399   if(params)
400     raptor_free_sequence(params);
401 
402   return e;
403 }
404 
405 
406 /**
407  * rasqal_new_function_expression:
408  * @world: rasqal_world object
409  * @name: function name
410  * @args: sequence of #rasqal_expression function arguments
411  * @params: sequence of #rasqal_expression function parameters (or NULL)
412  * @flags: extension function bitflags
413  *
414  * Constructor - create a new expression for a URI-named function with arguments and optional parameters.
415  *
416  * Takes ownership of the @name, @args and @params arguments.
417  *
418  * Return value: a new #rasqal_expression object or NULL on failure
419  **/
420 rasqal_expression*
rasqal_new_function_expression(rasqal_world * world,raptor_uri * name,raptor_sequence * args,raptor_sequence * params,unsigned int flags)421 rasqal_new_function_expression(rasqal_world* world,
422                                raptor_uri* name,
423                                raptor_sequence* args,
424                                raptor_sequence* params,
425                                unsigned int flags)
426 {
427   return rasqal_new_function_expression_common(world, RASQAL_EXPR_FUNCTION,
428                                                name,
429                                                NULL /* expr */, args,
430                                                params,
431                                                flags);
432 }
433 
434 
435 /**
436  * rasqal_new_aggregate_function_expression:
437  * @world: rasqal_world object
438  * @op:  built-in aggregate function expression operator
439  * @arg1: #rasqal_expression argument to aggregate function
440  * @params: sequence of #rasqal_expression function parameters (or NULL)
441  * @flags: extension function bitflags
442  *
443  * Constructor - create a new 1-arg aggregate function expression for a builtin aggregate function
444  *
445  * Takes ownership of the @args and @params
446  *
447  * Return value: a new #rasqal_expression object or NULL on failure
448  **/
449 rasqal_expression*
rasqal_new_aggregate_function_expression(rasqal_world * world,rasqal_op op,rasqal_expression * arg1,raptor_sequence * params,unsigned int flags)450 rasqal_new_aggregate_function_expression(rasqal_world* world,
451                                          rasqal_op op,
452                                          rasqal_expression* arg1,
453                                          raptor_sequence* params,
454                                          unsigned int flags)
455 {
456   return rasqal_new_function_expression_common(world, op,
457                                                NULL /* name */,
458                                                arg1, NULL /* args */,
459                                                params,
460                                                flags | RASQAL_EXPR_FLAG_AGGREGATE);
461 }
462 
463 
464 /**
465  * rasqal_new_cast_expression:
466  * @world: rasqal_world object
467  * @name: cast datatype URI
468  * @value: expression value to cast to @datatype type
469  *
470  * Constructor - create a new expression for casting and expression to a datatype.
471  * Takes ownership of the datatype uri and expression value.
472  *
473  * Return value: a new #rasqal_expression object or NULL on failure
474  **/
475 rasqal_expression*
rasqal_new_cast_expression(rasqal_world * world,raptor_uri * name,rasqal_expression * value)476 rasqal_new_cast_expression(rasqal_world* world, raptor_uri* name,
477                            rasqal_expression *value)
478 {
479   rasqal_expression* e = NULL;
480 
481   if(!world || !name || !value)
482     goto tidy;
483 
484   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
485   if(e) {
486     e->usage = 1;
487     e->world = world;
488     e->op = RASQAL_EXPR_CAST;
489     e->name = name; name = NULL;
490     e->arg1 = value; value = NULL;
491   }
492 
493   tidy:
494   if(name)
495     raptor_free_uri(name);
496   if(value)
497     rasqal_free_expression(value);
498 
499   return e;
500 }
501 
502 
503 /**
504  * rasqal_new_expr_seq_expression:
505  * @world: rasqal_world object
506  * @op: expression operation
507  * @args: sequence of #rasqal_expression arguments
508  *
509  * Constructor - create a new expression with a sequence of expression arguments.
510  *
511  * Takes ownership of the @args
512  *
513  * Return value: a new #rasqal_expression object or NULL on failure
514  **/
515 rasqal_expression*
rasqal_new_expr_seq_expression(rasqal_world * world,rasqal_op op,raptor_sequence * args)516 rasqal_new_expr_seq_expression(rasqal_world* world,
517                                rasqal_op op,
518                                raptor_sequence* args)
519 {
520   rasqal_expression* e = NULL;
521 
522   if(!world || !args)
523     goto tidy;
524 
525   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
526   if(e) {
527     e->usage = 1;
528     e->world = world;
529     e->op = op;
530     e->args = args; args = NULL;
531   }
532 
533   tidy:
534   if(args)
535     raptor_free_sequence(args);
536 
537   return e;
538 }
539 
540 
541 /**
542  * rasqal_new_set_expression:
543  * @world: rasqal_world object
544  * @op: list operation
545  * @arg1: expression to look for in list
546  * @args: sequence of #rasqal_expression list arguments
547  *
548  * Constructor - create a new set IN/NOT IN operation with expression arguments.
549  *
550  * Takes ownership of the @arg1 and @args
551  *
552  * Return value: a new #rasqal_expression object or NULL on failure
553  **/
554 rasqal_expression*
rasqal_new_set_expression(rasqal_world * world,rasqal_op op,rasqal_expression * arg1,raptor_sequence * args)555 rasqal_new_set_expression(rasqal_world* world, rasqal_op op,
556                           rasqal_expression* arg1,
557                           raptor_sequence* args)
558 {
559   rasqal_expression* e = NULL;
560 
561   if(!world || !arg1 || !args)
562     goto tidy;
563 
564   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
565   if(e) {
566     e->usage = 1;
567     e->world = world;
568     e->op = op;
569     e->arg1 = arg1; arg1 = NULL;
570     e->args = args; args = NULL;
571   }
572 
573   tidy:
574   if(arg1)
575     rasqal_free_expression(arg1);
576   if(args)
577     raptor_free_sequence(args);
578 
579   return e;
580 }
581 
582 
583 /**
584  * rasqal_new_group_concat_expression:
585  * @world: rasqal_world object
586  * @flags: bitset of flags.  Only #RASQAL_EXPR_FLAG_DISTINCT is defined
587  * @args: sequence of #rasqal_expression list arguments
588  * @separator: SEPARATOR string literal or NULL
589  *
590  * Constructor - create a new SPARQL group concat expression
591  *
592  * Takes an optional distinct flag, a list of expressions and an optional separator string.
593  *
594  * Takes ownership of the @args and @separator
595  *
596  * Return value: a new #rasqal_expression object or NULL on failure
597  **/
598 rasqal_expression*
rasqal_new_group_concat_expression(rasqal_world * world,unsigned int flags,raptor_sequence * args,rasqal_literal * separator)599 rasqal_new_group_concat_expression(rasqal_world* world,
600                                    unsigned int flags,
601                                    raptor_sequence* args,
602                                    rasqal_literal* separator)
603 {
604   rasqal_expression* e = NULL;
605 
606   if(!world || !args)
607     goto tidy;
608 
609   e = RASQAL_CALLOC(rasqal_expression*, 1, sizeof(*e));
610   if(e) {
611     e->usage = 1;
612     e->world = world;
613     /* Discard any flags except RASQAL_EXPR_FLAG_DISTINCT */
614     e->flags = (flags & RASQAL_EXPR_FLAG_DISTINCT) | RASQAL_EXPR_FLAG_AGGREGATE;
615     e->op = RASQAL_EXPR_GROUP_CONCAT;
616     e->args = args; args = NULL;
617     e->literal = separator; separator = NULL;
618   }
619 
620   tidy:
621   if(args)
622     raptor_free_sequence(args);
623   if(separator)
624     rasqal_free_literal(separator);
625 
626   return e;
627 }
628 
629 
630 /**
631  * rasqal_expression_clear:
632  * @e: expression
633  *
634  * Empty an expression of contained content.
635  *
636  * Intended to be used to deallocate resources from a statically
637  * declared #rasqal_expression such as on a stack.
638  **/
639 void
rasqal_expression_clear(rasqal_expression * e)640 rasqal_expression_clear(rasqal_expression* e)
641 {
642   RASQAL_ASSERT_OBJECT_POINTER_RETURN(e, rasqal_expression);
643 
644   switch(e->op) {
645     case RASQAL_EXPR_CURRENT_DATETIME:
646     case RASQAL_EXPR_NOW:
647     case RASQAL_EXPR_RAND:
648       break;
649 
650     case RASQAL_EXPR_AND:
651     case RASQAL_EXPR_OR:
652     case RASQAL_EXPR_EQ:
653     case RASQAL_EXPR_NEQ:
654     case RASQAL_EXPR_LT:
655     case RASQAL_EXPR_GT:
656     case RASQAL_EXPR_LE:
657     case RASQAL_EXPR_GE:
658     case RASQAL_EXPR_PLUS:
659     case RASQAL_EXPR_MINUS:
660     case RASQAL_EXPR_STAR:
661     case RASQAL_EXPR_SLASH:
662     case RASQAL_EXPR_REM:
663     case RASQAL_EXPR_STR_EQ:
664     case RASQAL_EXPR_STR_NEQ:
665     case RASQAL_EXPR_LANGMATCHES:
666     case RASQAL_EXPR_SAMETERM:
667     case RASQAL_EXPR_STRLANG:
668     case RASQAL_EXPR_STRDT:
669     case RASQAL_EXPR_STRBEFORE:
670     case RASQAL_EXPR_STRAFTER:
671       rasqal_free_expression(e->arg1);
672       rasqal_free_expression(e->arg2);
673       break;
674 
675     case RASQAL_EXPR_REGEX:
676     case RASQAL_EXPR_IF:
677     case RASQAL_EXPR_STRSTARTS:
678     case RASQAL_EXPR_STRENDS:
679     case RASQAL_EXPR_CONTAINS:
680     case RASQAL_EXPR_SUBSTR:
681     case RASQAL_EXPR_REPLACE:
682       rasqal_free_expression(e->arg1);
683       rasqal_free_expression(e->arg2);
684       if(e->arg3)
685         rasqal_free_expression(e->arg3);
686       if(e->arg4)
687         rasqal_free_expression(e->arg4);
688       break;
689 
690     case RASQAL_EXPR_TILDE:
691     case RASQAL_EXPR_BANG:
692     case RASQAL_EXPR_UMINUS:
693     case RASQAL_EXPR_BOUND:
694     case RASQAL_EXPR_STR:
695     case RASQAL_EXPR_LANG:
696     case RASQAL_EXPR_DATATYPE:
697     case RASQAL_EXPR_ISURI:
698     case RASQAL_EXPR_ISBLANK:
699     case RASQAL_EXPR_ISLITERAL:
700     case RASQAL_EXPR_ORDER_COND_ASC:
701     case RASQAL_EXPR_ORDER_COND_DESC:
702     case RASQAL_EXPR_GROUP_COND_ASC:
703     case RASQAL_EXPR_GROUP_COND_DESC:
704     case RASQAL_EXPR_COUNT:
705     case RASQAL_EXPR_SUM:
706     case RASQAL_EXPR_AVG:
707     case RASQAL_EXPR_MIN:
708     case RASQAL_EXPR_MAX:
709     case RASQAL_EXPR_URI:
710     case RASQAL_EXPR_IRI:
711     case RASQAL_EXPR_BNODE:
712     case RASQAL_EXPR_SAMPLE:
713     case RASQAL_EXPR_ISNUMERIC:
714     case RASQAL_EXPR_YEAR:
715     case RASQAL_EXPR_MONTH:
716     case RASQAL_EXPR_DAY:
717     case RASQAL_EXPR_HOURS:
718     case RASQAL_EXPR_MINUTES:
719     case RASQAL_EXPR_SECONDS:
720     case RASQAL_EXPR_TIMEZONE:
721     case RASQAL_EXPR_FROM_UNIXTIME:
722     case RASQAL_EXPR_TO_UNIXTIME:
723     case RASQAL_EXPR_STRLEN:
724     case RASQAL_EXPR_UCASE:
725     case RASQAL_EXPR_LCASE:
726     case RASQAL_EXPR_ENCODE_FOR_URI:
727     case RASQAL_EXPR_TZ:
728     case RASQAL_EXPR_ABS:
729     case RASQAL_EXPR_ROUND:
730     case RASQAL_EXPR_CEIL:
731     case RASQAL_EXPR_FLOOR:
732     case RASQAL_EXPR_MD5:
733     case RASQAL_EXPR_SHA1:
734     case RASQAL_EXPR_SHA224:
735     case RASQAL_EXPR_SHA256:
736     case RASQAL_EXPR_SHA384:
737     case RASQAL_EXPR_SHA512:
738     case RASQAL_EXPR_UUID:
739     case RASQAL_EXPR_STRUUID:
740       /* arg1 is optional for RASQAL_EXPR_BNODE */
741       if(e->arg1)
742         rasqal_free_expression(e->arg1);
743       break;
744 
745     case RASQAL_EXPR_STR_MATCH:
746     case RASQAL_EXPR_STR_NMATCH:
747       rasqal_free_expression(e->arg1);
748       rasqal_free_literal(e->literal);
749       break;
750 
751     case RASQAL_EXPR_LITERAL:
752       rasqal_free_literal(e->literal);
753       break;
754 
755     case RASQAL_EXPR_FUNCTION:
756     case RASQAL_EXPR_GROUP_CONCAT:
757       /* FUNCTION name */
758       if(e->name)
759         raptor_free_uri(e->name);
760       raptor_free_sequence(e->args);
761       if(e->literal) /* GROUP_CONCAT() SEPARATOR */
762         rasqal_free_literal(e->literal);
763       break;
764 
765     case RASQAL_EXPR_CAST:
766       raptor_free_uri(e->name);
767       rasqal_free_expression(e->arg1);
768       break;
769 
770     case RASQAL_EXPR_VARSTAR:
771       /* constants */
772       break;
773 
774     case RASQAL_EXPR_COALESCE:
775     case RASQAL_EXPR_CONCAT:
776       raptor_free_sequence(e->args);
777       break;
778 
779     case RASQAL_EXPR_IN:
780     case RASQAL_EXPR_NOT_IN:
781       rasqal_free_expression(e->arg1);
782       raptor_free_sequence(e->args);
783       break;
784 
785     case RASQAL_EXPR_UNKNOWN:
786     default:
787       RASQAL_FATAL2("Unknown operation %u", e->op);
788   }
789 }
790 
791 
792 /**
793  * rasqal_new_expression_from_expression:
794  * @e: #rasqal_expression object to copy or NULL
795  *
796  * Copy Constructor - create a new #rasqal_expression object from an existing rasqal_expression object.
797  *
798  * Return value: a new #rasqal_expression object or NULL if @e is NULL
799  **/
800 rasqal_expression*
rasqal_new_expression_from_expression(rasqal_expression * e)801 rasqal_new_expression_from_expression(rasqal_expression* e)
802 {
803   if(!e)
804     return NULL;
805 
806   e->usage++;
807   return e;
808 }
809 
810 
811 /**
812  * rasqal_free_expression:
813  * @e: #rasqal_expression object
814  *
815  * Destructor - destroy a #rasqal_expression object.
816  *
817  **/
818 void
rasqal_free_expression(rasqal_expression * e)819 rasqal_free_expression(rasqal_expression* e)
820 {
821   if(!e)
822     return;
823 
824   if(--e->usage)
825     return;
826 
827   rasqal_expression_clear(e);
828   RASQAL_FREE(rasqal_expression, e);
829 }
830 
831 
832 /**
833  * rasqal_expression_visit:
834  * @e:  #rasqal_expression to visit
835  * @fn: visit function
836  * @user_data: user data to pass to visit function
837  *
838  * Visit a user function over a #rasqal_expression
839  *
840  * If the user function @fn returns non-0, the visit is truncated
841  * and the value is returned.
842  *
843  * Return value: non-0 if the visit was truncated.
844  **/
845 int
rasqal_expression_visit(rasqal_expression * e,rasqal_expression_visit_fn fn,void * user_data)846 rasqal_expression_visit(rasqal_expression* e,
847                         rasqal_expression_visit_fn fn,
848                         void *user_data)
849 {
850   int i;
851   int result = 0;
852 
853   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(e, rasqal_expression, 1);
854   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(fn, rasqal_expression_visit_fn, 1);
855 
856   /* This ordering allows fn to potentially edit 'e' in-place */
857   result = fn(user_data, e);
858   if(result)
859     return result;
860 
861   switch(e->op) {
862     case RASQAL_EXPR_CURRENT_DATETIME:
863     case RASQAL_EXPR_NOW:
864     case RASQAL_EXPR_RAND:
865       break;
866 
867     case RASQAL_EXPR_AND:
868     case RASQAL_EXPR_OR:
869     case RASQAL_EXPR_EQ:
870     case RASQAL_EXPR_NEQ:
871     case RASQAL_EXPR_LT:
872     case RASQAL_EXPR_GT:
873     case RASQAL_EXPR_LE:
874     case RASQAL_EXPR_GE:
875     case RASQAL_EXPR_PLUS:
876     case RASQAL_EXPR_MINUS:
877     case RASQAL_EXPR_STAR:
878     case RASQAL_EXPR_SLASH:
879     case RASQAL_EXPR_REM:
880     case RASQAL_EXPR_STR_EQ:
881     case RASQAL_EXPR_STR_NEQ:
882     case RASQAL_EXPR_LANGMATCHES:
883     case RASQAL_EXPR_SAMETERM:
884     case RASQAL_EXPR_STRLANG:
885     case RASQAL_EXPR_STRDT:
886     case RASQAL_EXPR_STRSTARTS:
887     case RASQAL_EXPR_STRENDS:
888     case RASQAL_EXPR_CONTAINS:
889     case RASQAL_EXPR_STRBEFORE:
890     case RASQAL_EXPR_STRAFTER:
891       result = rasqal_expression_visit(e->arg1, fn, user_data) ||
892                rasqal_expression_visit(e->arg2, fn, user_data);
893       break;
894 
895     case RASQAL_EXPR_REGEX:
896     case RASQAL_EXPR_IF:
897     case RASQAL_EXPR_SUBSTR:
898       result = rasqal_expression_visit(e->arg1, fn, user_data) ||
899                rasqal_expression_visit(e->arg2, fn, user_data) ||
900                (e->arg3 && rasqal_expression_visit(e->arg3, fn, user_data));
901       break;
902 
903     case RASQAL_EXPR_REPLACE:
904       result = rasqal_expression_visit(e->arg1, fn, user_data) ||
905                rasqal_expression_visit(e->arg2, fn, user_data) ||
906                rasqal_expression_visit(e->arg3, fn, user_data) ||
907                (e->arg4 && rasqal_expression_visit(e->arg4, fn, user_data));
908       break;
909 
910     case RASQAL_EXPR_TILDE:
911     case RASQAL_EXPR_BANG:
912     case RASQAL_EXPR_UMINUS:
913     case RASQAL_EXPR_BOUND:
914     case RASQAL_EXPR_STR:
915     case RASQAL_EXPR_LANG:
916     case RASQAL_EXPR_DATATYPE:
917     case RASQAL_EXPR_ISURI:
918     case RASQAL_EXPR_ISBLANK:
919     case RASQAL_EXPR_ISLITERAL:
920     case RASQAL_EXPR_CAST:
921     case RASQAL_EXPR_ORDER_COND_ASC:
922     case RASQAL_EXPR_ORDER_COND_DESC:
923     case RASQAL_EXPR_GROUP_COND_ASC:
924     case RASQAL_EXPR_GROUP_COND_DESC:
925     case RASQAL_EXPR_COUNT:
926     case RASQAL_EXPR_SUM:
927     case RASQAL_EXPR_AVG:
928     case RASQAL_EXPR_MIN:
929     case RASQAL_EXPR_MAX:
930     case RASQAL_EXPR_URI:
931     case RASQAL_EXPR_IRI:
932     case RASQAL_EXPR_BNODE:
933     case RASQAL_EXPR_SAMPLE:
934     case RASQAL_EXPR_ISNUMERIC:
935     case RASQAL_EXPR_YEAR:
936     case RASQAL_EXPR_MONTH:
937     case RASQAL_EXPR_DAY:
938     case RASQAL_EXPR_HOURS:
939     case RASQAL_EXPR_MINUTES:
940     case RASQAL_EXPR_SECONDS:
941     case RASQAL_EXPR_TIMEZONE:
942     case RASQAL_EXPR_FROM_UNIXTIME:
943     case RASQAL_EXPR_TO_UNIXTIME:
944     case RASQAL_EXPR_STRLEN:
945     case RASQAL_EXPR_UCASE:
946     case RASQAL_EXPR_LCASE:
947     case RASQAL_EXPR_ENCODE_FOR_URI:
948     case RASQAL_EXPR_TZ:
949     case RASQAL_EXPR_ABS:
950     case RASQAL_EXPR_ROUND:
951     case RASQAL_EXPR_CEIL:
952     case RASQAL_EXPR_FLOOR:
953     case RASQAL_EXPR_MD5:
954     case RASQAL_EXPR_SHA1:
955     case RASQAL_EXPR_SHA224:
956     case RASQAL_EXPR_SHA256:
957     case RASQAL_EXPR_SHA384:
958     case RASQAL_EXPR_SHA512:
959     case RASQAL_EXPR_UUID:
960     case RASQAL_EXPR_STRUUID:
961       /* arg1 is optional for RASQAL_EXPR_BNODE */
962       result = (e->arg1) ? rasqal_expression_visit(e->arg1, fn, user_data) : 0;
963       break;
964 
965     case RASQAL_EXPR_STR_MATCH:
966     case RASQAL_EXPR_STR_NMATCH:
967       result = fn(user_data, e->arg1);
968       break;
969 
970     case RASQAL_EXPR_LITERAL:
971       break;
972 
973     case RASQAL_EXPR_FUNCTION:
974     case RASQAL_EXPR_COALESCE:
975     case RASQAL_EXPR_GROUP_CONCAT:
976     case RASQAL_EXPR_CONCAT:
977       for(i = 0; i < raptor_sequence_size(e->args); i++) {
978         rasqal_expression* e2;
979         e2 = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
980         result = rasqal_expression_visit(e2, fn, user_data);
981         if(result)
982           break;
983       }
984       break;
985 
986     case RASQAL_EXPR_VARSTAR:
987       /* constants */
988       break;
989 
990     case RASQAL_EXPR_IN:
991     case RASQAL_EXPR_NOT_IN:
992       result = rasqal_expression_visit(e->arg1, fn, user_data);
993       if(!result) {
994         for(i = 0; i < raptor_sequence_size(e->args); i++) {
995           rasqal_expression* e2;
996           e2 = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
997           result = rasqal_expression_visit(e2, fn, user_data);
998           if(result)
999             break;
1000         }
1001       }
1002       break;
1003 
1004     case RASQAL_EXPR_UNKNOWN:
1005     default:
1006       RASQAL_FATAL2("Unknown operation %u", e->op);
1007       result= -1; /* keep some compilers happy */
1008       break;
1009   }
1010 
1011   return result;
1012 }
1013 
1014 
1015 static const char* const rasqal_op_labels[RASQAL_EXPR_LAST+1]={
1016   "UNKNOWN",
1017   "and",
1018   "or",
1019   "eq",
1020   "neq",
1021   "lt",
1022   "gt",
1023   "le",
1024   "ge",
1025   "uminus",
1026   "plus",
1027   "minus",
1028   "star",
1029   "slash",
1030   "rem",
1031   "str_eq",
1032   "str_ne",
1033   "str_match",
1034   "str_nmatch",
1035   "tilde",
1036   "bang",
1037   "literal",
1038   "function",
1039   "bound",
1040   "str",
1041   "lang",
1042   "datatype",
1043   "isUri",
1044   "isBlank",
1045   "isLiteral",
1046   "cast",
1047   "order asc",
1048   "order desc",
1049   "langMatches",
1050   "regex",
1051   "group asc",
1052   "group desc",
1053   "count",
1054   "varstar",
1055   "sameTerm",
1056   "sum",
1057   "avg",
1058   "min",
1059   "max",
1060   "coalesce",
1061   "if",
1062   "uri",
1063   "iri",
1064   "strlang",
1065   "strdt",
1066   "bnode",
1067   "group_concat",
1068   "sample",
1069   "in",
1070   "not in",
1071   "isnumeric",
1072   "year",
1073   "month",
1074   "day",
1075   "hours",
1076   "minutes",
1077   "seconds",
1078   "timezone",
1079   "current_datetime",
1080   "now",
1081   "from_unixtime",
1082   "to_unixtime",
1083   "concat",
1084   "strlen",
1085   "substr",
1086   "ucase",
1087   "lcase",
1088   "strstarts",
1089   "strends",
1090   "contains",
1091   "encode_for_uri",
1092   "tz",
1093   "rand",
1094   "abs",
1095   "round",
1096   "ceil",
1097   "floor",
1098   "md5",
1099   "sha1",
1100   "sha224",
1101   "sha256",
1102   "sha384",
1103   "sha512",
1104   "strbefore",
1105   "strafter",
1106   "replace",
1107   "uuid",
1108   "struuid"
1109 };
1110 
1111 
1112 /**
1113  * rasqal_expression_op_label:
1114  * @op: the #rasqal_expression_op object
1115  *
1116  * Get a label for the rasqal expression operator
1117  *
1118  * Return value: the label (shared string) or NULL if op is out of range or unknown
1119  **/
1120 const char*
rasqal_expression_op_label(rasqal_op op)1121 rasqal_expression_op_label(rasqal_op op)
1122 {
1123   if(op > RASQAL_EXPR_LAST)
1124     op = RASQAL_EXPR_UNKNOWN;
1125 
1126   return rasqal_op_labels[RASQAL_GOOD_CAST(int, op)];
1127 }
1128 
1129 
1130 /**
1131  * rasqal_expression_write_op:
1132  * @e: the #rasqal_expression object
1133  * @iostr: the #raptor_iostream to write to
1134  *
1135  * INTERNAL - Write a rasqal expression operator to an iostream in a debug format.
1136  *
1137  * The print debug format may change in any release.
1138  **/
1139 void
rasqal_expression_write_op(rasqal_expression * e,raptor_iostream * iostr)1140 rasqal_expression_write_op(rasqal_expression* e, raptor_iostream* iostr)
1141 {
1142   RASQAL_ASSERT_OBJECT_POINTER_RETURN(e, rasqal_expression);
1143 
1144   raptor_iostream_string_write(rasqal_expression_op_label(e->op), iostr);
1145 }
1146 
1147 
1148 /**
1149  * rasqal_expression_print_op:
1150  * @e: the #rasqal_expression object
1151  * @fh: the FILE* handle to print to
1152  *
1153  * Print a rasqal expression operator in a debug format.
1154  *
1155  * The print debug format may change in any release.
1156  **/
1157 void
rasqal_expression_print_op(rasqal_expression * e,FILE * fh)1158 rasqal_expression_print_op(rasqal_expression* e, FILE* fh)
1159 {
1160   RASQAL_ASSERT_OBJECT_POINTER_RETURN(e, rasqal_expression);
1161   RASQAL_ASSERT_OBJECT_POINTER_RETURN(fh, FILE*);
1162 
1163   fputs(rasqal_expression_op_label(e->op), fh);
1164 }
1165 
1166 
1167 /**
1168  * rasqal_expression_write:
1169  * @e: #rasqal_expression object.
1170  * @iostr: The #raptor_iostream to write to.
1171  *
1172  * Write a Rasqal expression to an iostream in a debug format.
1173  *
1174  * The print debug format may change in any release.
1175  **/
1176 void
rasqal_expression_write(rasqal_expression * e,raptor_iostream * iostr)1177 rasqal_expression_write(rasqal_expression* e, raptor_iostream* iostr)
1178 {
1179   int i;
1180 
1181   RASQAL_ASSERT_OBJECT_POINTER_RETURN(e, rasqal_expression);
1182   RASQAL_ASSERT_OBJECT_POINTER_RETURN(iostr, raptor_iostr);
1183 
1184   raptor_iostream_counted_string_write("expr(", 5, iostr);
1185   switch(e->op) {
1186     case RASQAL_EXPR_CURRENT_DATETIME:
1187     case RASQAL_EXPR_NOW:
1188     case RASQAL_EXPR_RAND:
1189       raptor_iostream_counted_string_write("op ", 3, iostr);
1190       rasqal_expression_write_op(e, iostr);
1191       raptor_iostream_counted_string_write("()", 2, iostr);
1192       break;
1193 
1194     case RASQAL_EXPR_AND:
1195     case RASQAL_EXPR_OR:
1196     case RASQAL_EXPR_EQ:
1197     case RASQAL_EXPR_NEQ:
1198     case RASQAL_EXPR_LT:
1199     case RASQAL_EXPR_GT:
1200     case RASQAL_EXPR_LE:
1201     case RASQAL_EXPR_GE:
1202     case RASQAL_EXPR_PLUS:
1203     case RASQAL_EXPR_MINUS:
1204     case RASQAL_EXPR_STAR:
1205     case RASQAL_EXPR_SLASH:
1206     case RASQAL_EXPR_REM:
1207     case RASQAL_EXPR_STR_EQ:
1208     case RASQAL_EXPR_STR_NEQ:
1209     case RASQAL_EXPR_LANGMATCHES:
1210     case RASQAL_EXPR_REGEX:
1211     case RASQAL_EXPR_SAMETERM:
1212     case RASQAL_EXPR_IF:
1213     case RASQAL_EXPR_STRLANG:
1214     case RASQAL_EXPR_STRDT:
1215     case RASQAL_EXPR_STRSTARTS:
1216     case RASQAL_EXPR_STRENDS:
1217     case RASQAL_EXPR_SUBSTR:
1218     case RASQAL_EXPR_CONTAINS:
1219     case RASQAL_EXPR_STRBEFORE:
1220     case RASQAL_EXPR_STRAFTER:
1221     case RASQAL_EXPR_REPLACE:
1222       raptor_iostream_counted_string_write("op ", 3, iostr);
1223       rasqal_expression_write_op(e, iostr);
1224       raptor_iostream_write_byte('(', iostr);
1225       rasqal_expression_write(e->arg1, iostr);
1226       raptor_iostream_counted_string_write(", ", 2, iostr);
1227       rasqal_expression_write(e->arg2, iostr);
1228 
1229       /* There are four 3+ arg expressions - all handled here */
1230       if((e->op == RASQAL_EXPR_REGEX || e->op == RASQAL_EXPR_IF ||
1231           e->op == RASQAL_EXPR_SUBSTR || e->op == RASQAL_EXPR_REPLACE)
1232          && e->arg3) {
1233         raptor_iostream_counted_string_write(", ", 2, iostr);
1234         rasqal_expression_write(e->arg3, iostr);
1235       }
1236       /* One 3 or 4 arg expression */
1237       if((e->op == RASQAL_EXPR_REPLACE) && e->arg4) {
1238         raptor_iostream_counted_string_write(", ", 2, iostr);
1239         rasqal_expression_write(e->arg4, iostr);
1240       }
1241       raptor_iostream_write_byte(')', iostr);
1242       break;
1243 
1244     case RASQAL_EXPR_STR_MATCH:
1245     case RASQAL_EXPR_STR_NMATCH:
1246       raptor_iostream_counted_string_write("op ", 3, iostr);
1247       rasqal_expression_write_op(e, iostr);
1248       raptor_iostream_write_byte('(', iostr);
1249       rasqal_expression_write(e->arg1, iostr);
1250       raptor_iostream_counted_string_write(", ", 2, iostr);
1251       rasqal_literal_write(e->literal, iostr);
1252       raptor_iostream_write_byte(')', iostr);
1253       break;
1254 
1255     case RASQAL_EXPR_TILDE:
1256     case RASQAL_EXPR_BANG:
1257     case RASQAL_EXPR_UMINUS:
1258     case RASQAL_EXPR_BOUND:
1259     case RASQAL_EXPR_STR:
1260     case RASQAL_EXPR_LANG:
1261     case RASQAL_EXPR_DATATYPE:
1262     case RASQAL_EXPR_ISURI:
1263     case RASQAL_EXPR_ISBLANK:
1264     case RASQAL_EXPR_ISLITERAL:
1265     case RASQAL_EXPR_ORDER_COND_ASC:
1266     case RASQAL_EXPR_ORDER_COND_DESC:
1267     case RASQAL_EXPR_GROUP_COND_ASC:
1268     case RASQAL_EXPR_GROUP_COND_DESC:
1269     case RASQAL_EXPR_COUNT:
1270     case RASQAL_EXPR_SUM:
1271     case RASQAL_EXPR_AVG:
1272     case RASQAL_EXPR_MIN:
1273     case RASQAL_EXPR_MAX:
1274     case RASQAL_EXPR_URI:
1275     case RASQAL_EXPR_IRI:
1276     case RASQAL_EXPR_BNODE:
1277     case RASQAL_EXPR_SAMPLE:
1278     case RASQAL_EXPR_ISNUMERIC:
1279     case RASQAL_EXPR_YEAR:
1280     case RASQAL_EXPR_MONTH:
1281     case RASQAL_EXPR_DAY:
1282     case RASQAL_EXPR_HOURS:
1283     case RASQAL_EXPR_MINUTES:
1284     case RASQAL_EXPR_SECONDS:
1285     case RASQAL_EXPR_TIMEZONE:
1286     case RASQAL_EXPR_FROM_UNIXTIME:
1287     case RASQAL_EXPR_TO_UNIXTIME:
1288     case RASQAL_EXPR_STRLEN:
1289     case RASQAL_EXPR_UCASE:
1290     case RASQAL_EXPR_LCASE:
1291     case RASQAL_EXPR_ENCODE_FOR_URI:
1292     case RASQAL_EXPR_TZ:
1293     case RASQAL_EXPR_ABS:
1294     case RASQAL_EXPR_ROUND:
1295     case RASQAL_EXPR_CEIL:
1296     case RASQAL_EXPR_FLOOR:
1297     case RASQAL_EXPR_MD5:
1298     case RASQAL_EXPR_SHA1:
1299     case RASQAL_EXPR_SHA224:
1300     case RASQAL_EXPR_SHA256:
1301     case RASQAL_EXPR_SHA384:
1302     case RASQAL_EXPR_SHA512:
1303     case RASQAL_EXPR_UUID:
1304     case RASQAL_EXPR_STRUUID:
1305       raptor_iostream_counted_string_write("op ", 3, iostr);
1306       rasqal_expression_write_op(e, iostr);
1307       raptor_iostream_write_byte('(', iostr);
1308       /* arg1 is optional for RASQAL_EXPR_BNODE */
1309       if(e->arg1)
1310         rasqal_expression_write(e->arg1, iostr);
1311       raptor_iostream_write_byte(')', iostr);
1312       break;
1313 
1314     case RASQAL_EXPR_LITERAL:
1315       rasqal_literal_write(e->literal, iostr);
1316       break;
1317 
1318     case RASQAL_EXPR_FUNCTION:
1319       raptor_iostream_counted_string_write("function(uri=", 13, iostr);
1320       raptor_uri_write(e->name, iostr);
1321       raptor_iostream_counted_string_write(", args=", 7, iostr);
1322       for(i=0; i<raptor_sequence_size(e->args); i++) {
1323         rasqal_expression* e2;
1324         if(i>0)
1325           raptor_iostream_counted_string_write(", ", 2, iostr);
1326         e2=(rasqal_expression*)raptor_sequence_get_at(e->args, i);
1327         rasqal_expression_write(e2, iostr);
1328       }
1329       raptor_iostream_write_byte(')', iostr);
1330       break;
1331 
1332     case RASQAL_EXPR_CAST:
1333       raptor_iostream_counted_string_write("cast(type=", 10, iostr);
1334       raptor_uri_write(e->name, iostr);
1335       raptor_iostream_counted_string_write(", value=", 8, iostr);
1336       rasqal_expression_write(e->arg1, iostr);
1337       raptor_iostream_write_byte(')', iostr);
1338       break;
1339 
1340     case RASQAL_EXPR_VARSTAR:
1341       raptor_iostream_counted_string_write("varstar", 7, iostr);
1342       break;
1343 
1344     case RASQAL_EXPR_COALESCE:
1345     case RASQAL_EXPR_CONCAT:
1346       rasqal_expression_write_op(e, iostr);
1347       raptor_iostream_write_byte('(', iostr);
1348       for(i = 0; i < raptor_sequence_size(e->args); i++) {
1349         rasqal_expression* e2;
1350         if(i > 0)
1351           raptor_iostream_counted_string_write(", ", 2, iostr);
1352         e2 = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
1353         rasqal_expression_write(e2, iostr);
1354       }
1355       raptor_iostream_write_byte(')', iostr);
1356       break;
1357 
1358     case RASQAL_EXPR_GROUP_CONCAT:
1359       raptor_iostream_counted_string_write("group_concat(", 13, iostr);
1360       if(e->flags & RASQAL_EXPR_FLAG_DISTINCT)
1361         raptor_iostream_counted_string_write("distinct,", 9, iostr);
1362       raptor_iostream_counted_string_write("args=", 5, iostr);
1363       for(i = 0; i < raptor_sequence_size(e->args); i++) {
1364         rasqal_expression* e2;
1365         if(i > 0)
1366           raptor_iostream_counted_string_write(", ", 2, iostr);
1367         e2 = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
1368         rasqal_expression_write(e2, iostr);
1369       }
1370       if(e->literal) {
1371         raptor_iostream_counted_string_write(",separator=", 11, iostr);
1372         rasqal_literal_write(e->literal, iostr);
1373       }
1374       raptor_iostream_write_byte(')', iostr);
1375       break;
1376 
1377     case RASQAL_EXPR_IN:
1378     case RASQAL_EXPR_NOT_IN:
1379       raptor_iostream_counted_string_write("op ", 3, iostr);
1380       rasqal_expression_write_op(e, iostr);
1381       raptor_iostream_counted_string_write("(expr=", 6, iostr);
1382       rasqal_expression_write(e->arg1, iostr);
1383       raptor_iostream_counted_string_write(", args=", 7, iostr);
1384       for(i = 0; i < raptor_sequence_size(e->args); i++) {
1385         rasqal_expression* e2;
1386         if(i > 0)
1387           raptor_iostream_counted_string_write(", ", 2, iostr);
1388         e2 = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
1389         rasqal_expression_write(e2, iostr);
1390       }
1391       raptor_iostream_write_byte(')', iostr);
1392       break;
1393 
1394     case RASQAL_EXPR_UNKNOWN:
1395     default:
1396       RASQAL_FATAL2("Unknown operation %u", e->op);
1397   }
1398   raptor_iostream_write_byte(')', iostr);
1399 }
1400 
1401 
1402 /**
1403  * rasqal_expression_print:
1404  * @e: #rasqal_expression object.
1405  * @fh: The FILE* handle to print to.
1406  *
1407  * Print a Rasqal expression in a debug format.
1408  *
1409  * The print debug format may change in any release.
1410  *
1411  * Return value: non-0 on failure
1412  **/
1413 int
rasqal_expression_print(rasqal_expression * e,FILE * fh)1414 rasqal_expression_print(rasqal_expression* e, FILE* fh)
1415 {
1416   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(e, rasqal_expression, 1);
1417   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(fh, FILE*, 1);
1418 
1419   fputs("expr(", fh);
1420   switch(e->op) {
1421     case RASQAL_EXPR_AND:
1422     case RASQAL_EXPR_OR:
1423     case RASQAL_EXPR_EQ:
1424     case RASQAL_EXPR_NEQ:
1425     case RASQAL_EXPR_LT:
1426     case RASQAL_EXPR_GT:
1427     case RASQAL_EXPR_LE:
1428     case RASQAL_EXPR_GE:
1429     case RASQAL_EXPR_PLUS:
1430     case RASQAL_EXPR_MINUS:
1431     case RASQAL_EXPR_STAR:
1432     case RASQAL_EXPR_SLASH:
1433     case RASQAL_EXPR_REM:
1434     case RASQAL_EXPR_STR_EQ:
1435     case RASQAL_EXPR_STR_NEQ:
1436     case RASQAL_EXPR_LANGMATCHES:
1437     case RASQAL_EXPR_REGEX:
1438     case RASQAL_EXPR_SAMETERM:
1439     case RASQAL_EXPR_IF:
1440     case RASQAL_EXPR_STRLANG:
1441     case RASQAL_EXPR_STRDT:
1442     case RASQAL_EXPR_STRSTARTS:
1443     case RASQAL_EXPR_STRENDS:
1444     case RASQAL_EXPR_CONTAINS:
1445     case RASQAL_EXPR_SUBSTR:
1446     case RASQAL_EXPR_STRBEFORE:
1447     case RASQAL_EXPR_STRAFTER:
1448     case RASQAL_EXPR_REPLACE:
1449       fputs("op ", fh);
1450       rasqal_expression_print_op(e, fh);
1451       fputc('(', fh);
1452       rasqal_expression_print(e->arg1, fh);
1453       fputs(", ", fh);
1454       rasqal_expression_print(e->arg2, fh);
1455 
1456       /* There are four 3+ arg expressions - all handled here */
1457       if((e->op == RASQAL_EXPR_REGEX || e->op == RASQAL_EXPR_IF ||
1458           e->op == RASQAL_EXPR_SUBSTR || e->op == RASQAL_EXPR_REPLACE)
1459          && e->arg3) {
1460         fputs(", ", fh);
1461         rasqal_expression_print(e->arg3, fh);
1462       }
1463       /* One 3 or 4 arg expression */
1464       if((e->op == RASQAL_EXPR_REPLACE) && e->arg4) {
1465         fputs(", ", fh);
1466         rasqal_expression_print(e->arg4, fh);
1467       }
1468       fputc(')', fh);
1469       break;
1470 
1471     case RASQAL_EXPR_STR_MATCH:
1472     case RASQAL_EXPR_STR_NMATCH:
1473       fputs("op ", fh);
1474       rasqal_expression_print_op(e, fh);
1475       fputc('(', fh);
1476       rasqal_expression_print(e->arg1, fh);
1477       fputs(", ", fh);
1478       rasqal_literal_print(e->literal, fh);
1479       fputc(')', fh);
1480       break;
1481 
1482     case RASQAL_EXPR_TILDE:
1483     case RASQAL_EXPR_BANG:
1484     case RASQAL_EXPR_UMINUS:
1485     case RASQAL_EXPR_BOUND:
1486     case RASQAL_EXPR_STR:
1487     case RASQAL_EXPR_LANG:
1488     case RASQAL_EXPR_DATATYPE:
1489     case RASQAL_EXPR_ISURI:
1490     case RASQAL_EXPR_ISBLANK:
1491     case RASQAL_EXPR_ISLITERAL:
1492     case RASQAL_EXPR_ORDER_COND_ASC:
1493     case RASQAL_EXPR_ORDER_COND_DESC:
1494     case RASQAL_EXPR_GROUP_COND_ASC:
1495     case RASQAL_EXPR_GROUP_COND_DESC:
1496     case RASQAL_EXPR_COUNT:
1497     case RASQAL_EXPR_SUM:
1498     case RASQAL_EXPR_AVG:
1499     case RASQAL_EXPR_MIN:
1500     case RASQAL_EXPR_MAX:
1501     case RASQAL_EXPR_URI:
1502     case RASQAL_EXPR_IRI:
1503     case RASQAL_EXPR_BNODE:
1504     case RASQAL_EXPR_SAMPLE:
1505     case RASQAL_EXPR_ISNUMERIC:
1506     case RASQAL_EXPR_YEAR:
1507     case RASQAL_EXPR_MONTH:
1508     case RASQAL_EXPR_DAY:
1509     case RASQAL_EXPR_HOURS:
1510     case RASQAL_EXPR_MINUTES:
1511     case RASQAL_EXPR_SECONDS:
1512     case RASQAL_EXPR_TIMEZONE:
1513     case RASQAL_EXPR_CURRENT_DATETIME:
1514     case RASQAL_EXPR_NOW:
1515     case RASQAL_EXPR_FROM_UNIXTIME:
1516     case RASQAL_EXPR_TO_UNIXTIME:
1517     case RASQAL_EXPR_STRLEN:
1518     case RASQAL_EXPR_UCASE:
1519     case RASQAL_EXPR_LCASE:
1520     case RASQAL_EXPR_ENCODE_FOR_URI:
1521     case RASQAL_EXPR_TZ:
1522     case RASQAL_EXPR_RAND:
1523     case RASQAL_EXPR_ABS:
1524     case RASQAL_EXPR_ROUND:
1525     case RASQAL_EXPR_CEIL:
1526     case RASQAL_EXPR_FLOOR:
1527     case RASQAL_EXPR_MD5:
1528     case RASQAL_EXPR_SHA1:
1529     case RASQAL_EXPR_SHA224:
1530     case RASQAL_EXPR_SHA256:
1531     case RASQAL_EXPR_SHA384:
1532     case RASQAL_EXPR_SHA512:
1533     case RASQAL_EXPR_UUID:
1534     case RASQAL_EXPR_STRUUID:
1535       fputs("op ", fh);
1536       rasqal_expression_print_op(e, fh);
1537       fputc('(', fh);
1538       /* arg1 is optional for RASQAL_EXPR_BNODE */
1539       if(e->arg1)
1540         rasqal_expression_print(e->arg1, fh);
1541       fputc(')', fh);
1542       break;
1543 
1544     case RASQAL_EXPR_LITERAL:
1545       rasqal_literal_print(e->literal, fh);
1546       break;
1547 
1548     case RASQAL_EXPR_FUNCTION:
1549       fputs("function(uri=", fh);
1550       raptor_uri_print(e->name, fh);
1551       fputs(", args=", fh);
1552       raptor_sequence_print(e->args, fh);
1553       fputc(')', fh);
1554       break;
1555 
1556     case RASQAL_EXPR_CAST:
1557       fputs("cast(type=", fh);
1558       raptor_uri_print(e->name, fh);
1559       fputs(", value=", fh);
1560       rasqal_expression_print(e->arg1, fh);
1561       fputc(')', fh);
1562       break;
1563 
1564     case RASQAL_EXPR_VARSTAR:
1565       fputs("varstar", fh);
1566       break;
1567 
1568     case RASQAL_EXPR_COALESCE:
1569     case RASQAL_EXPR_CONCAT:
1570       rasqal_expression_print_op(e, fh);
1571       fputc('(', fh);
1572       raptor_sequence_print(e->args, fh);
1573       fputc(')', fh);
1574       break;
1575 
1576     case RASQAL_EXPR_GROUP_CONCAT:
1577       fputs("group_concat(", fh);
1578       if(e->flags & RASQAL_EXPR_FLAG_DISTINCT)
1579         fputs("distinct,", fh);
1580       fputs("args=", fh);
1581       raptor_sequence_print(e->args, fh);
1582       if(e->literal) {
1583         fputs(",separator=", fh);
1584         rasqal_literal_print(e->literal, fh);
1585       }
1586       fputc(')', fh);
1587       break;
1588 
1589     case RASQAL_EXPR_IN:
1590     case RASQAL_EXPR_NOT_IN:
1591       fputs("op ", fh);
1592       rasqal_expression_print_op(e, fh);
1593       fputs("(expr=", fh);
1594       rasqal_expression_print(e->arg1, fh);
1595       fputs(", args=", fh);
1596       raptor_sequence_print(e->args, fh);
1597       fputc(')', fh);
1598       break;
1599 
1600     case RASQAL_EXPR_UNKNOWN:
1601     default:
1602       RASQAL_FATAL2("Unknown operation %u", e->op);
1603   }
1604   fputc(')', fh);
1605 
1606   return 0;
1607 }
1608 
1609 
1610 /* for use with rasqal_expression_visit and user_data=rasqal_query */
1611 int
rasqal_expression_has_qname(void * user_data,rasqal_expression * e)1612 rasqal_expression_has_qname(void *user_data, rasqal_expression *e)
1613 {
1614   if(e->op == RASQAL_EXPR_LITERAL)
1615     return rasqal_literal_has_qname(e->literal);
1616 
1617   return 0;
1618 }
1619 
1620 
1621 /* for use with rasqal_expression_visit and user_data=rasqal_query */
1622 int
rasqal_expression_expand_qname(void * user_data,rasqal_expression * e)1623 rasqal_expression_expand_qname(void *user_data, rasqal_expression *e)
1624 {
1625   if(e->op == RASQAL_EXPR_LITERAL)
1626     return rasqal_literal_expand_qname(user_data, e->literal);
1627 
1628   return 0;
1629 }
1630 
1631 
1632 int
rasqal_expression_is_constant(rasqal_expression * e)1633 rasqal_expression_is_constant(rasqal_expression* e)
1634 {
1635   int i;
1636   int result = 0;
1637 
1638   switch(e->op) {
1639     case RASQAL_EXPR_CURRENT_DATETIME:
1640     case RASQAL_EXPR_NOW:
1641       /* Constant - set once at the first execution of the expression in
1642        * a query execution after rasqal_world_reset_now() removes any
1643        * existing value.
1644        */
1645       result = 1;
1646       break;
1647 
1648     case RASQAL_EXPR_RAND:
1649       /* Never a constant */
1650       result = 0;
1651       break;
1652 
1653     case RASQAL_EXPR_AND:
1654     case RASQAL_EXPR_OR:
1655     case RASQAL_EXPR_EQ:
1656     case RASQAL_EXPR_NEQ:
1657     case RASQAL_EXPR_LT:
1658     case RASQAL_EXPR_GT:
1659     case RASQAL_EXPR_LE:
1660     case RASQAL_EXPR_GE:
1661     case RASQAL_EXPR_PLUS:
1662     case RASQAL_EXPR_MINUS:
1663     case RASQAL_EXPR_STAR:
1664     case RASQAL_EXPR_SLASH:
1665     case RASQAL_EXPR_REM:
1666     case RASQAL_EXPR_STR_EQ:
1667     case RASQAL_EXPR_STR_NEQ:
1668     case RASQAL_EXPR_LANGMATCHES:
1669     case RASQAL_EXPR_SAMETERM:
1670     case RASQAL_EXPR_STRLANG:
1671     case RASQAL_EXPR_STRDT:
1672     case RASQAL_EXPR_STRSTARTS:
1673     case RASQAL_EXPR_STRENDS:
1674     case RASQAL_EXPR_CONTAINS:
1675     case RASQAL_EXPR_STRBEFORE:
1676     case RASQAL_EXPR_STRAFTER:
1677       result = rasqal_expression_is_constant(e->arg1) &&
1678                rasqal_expression_is_constant(e->arg2);
1679       break;
1680 
1681     case RASQAL_EXPR_REGEX:
1682     case RASQAL_EXPR_IF:
1683     case RASQAL_EXPR_SUBSTR:
1684       result = rasqal_expression_is_constant(e->arg1) &&
1685                rasqal_expression_is_constant(e->arg2) &&
1686                (e->arg3 && rasqal_expression_is_constant(e->arg3));
1687       break;
1688 
1689     case RASQAL_EXPR_REPLACE:
1690       result = rasqal_expression_is_constant(e->arg1) &&
1691                rasqal_expression_is_constant(e->arg2) &&
1692                rasqal_expression_is_constant(e->arg3) &&
1693                (e->arg4 && rasqal_expression_is_constant(e->arg4));
1694       break;
1695 
1696     case RASQAL_EXPR_STR_MATCH:
1697     case RASQAL_EXPR_STR_NMATCH:
1698       result = rasqal_expression_is_constant(e->arg1) &&
1699                rasqal_literal_is_constant(e->literal);
1700       break;
1701 
1702     case RASQAL_EXPR_TILDE:
1703     case RASQAL_EXPR_BANG:
1704     case RASQAL_EXPR_UMINUS:
1705     case RASQAL_EXPR_BOUND:
1706     case RASQAL_EXPR_STR:
1707     case RASQAL_EXPR_LANG:
1708     case RASQAL_EXPR_DATATYPE:
1709     case RASQAL_EXPR_ISURI:
1710     case RASQAL_EXPR_ISBLANK:
1711     case RASQAL_EXPR_ISLITERAL:
1712     case RASQAL_EXPR_ORDER_COND_ASC:
1713     case RASQAL_EXPR_ORDER_COND_DESC:
1714     case RASQAL_EXPR_GROUP_COND_ASC:
1715     case RASQAL_EXPR_GROUP_COND_DESC:
1716     case RASQAL_EXPR_COUNT:
1717     case RASQAL_EXPR_SUM:
1718     case RASQAL_EXPR_AVG:
1719     case RASQAL_EXPR_MIN:
1720     case RASQAL_EXPR_MAX:
1721     case RASQAL_EXPR_URI:
1722     case RASQAL_EXPR_IRI:
1723     case RASQAL_EXPR_BNODE:
1724     case RASQAL_EXPR_SAMPLE:
1725     case RASQAL_EXPR_ISNUMERIC:
1726     case RASQAL_EXPR_YEAR:
1727     case RASQAL_EXPR_MONTH:
1728     case RASQAL_EXPR_DAY:
1729     case RASQAL_EXPR_HOURS:
1730     case RASQAL_EXPR_MINUTES:
1731     case RASQAL_EXPR_SECONDS:
1732     case RASQAL_EXPR_TIMEZONE:
1733     case RASQAL_EXPR_FROM_UNIXTIME:
1734     case RASQAL_EXPR_TO_UNIXTIME:
1735     case RASQAL_EXPR_STRLEN:
1736     case RASQAL_EXPR_UCASE:
1737     case RASQAL_EXPR_LCASE:
1738     case RASQAL_EXPR_ENCODE_FOR_URI:
1739     case RASQAL_EXPR_TZ:
1740     case RASQAL_EXPR_ABS:
1741     case RASQAL_EXPR_ROUND:
1742     case RASQAL_EXPR_CEIL:
1743     case RASQAL_EXPR_FLOOR:
1744     case RASQAL_EXPR_MD5:
1745     case RASQAL_EXPR_SHA1:
1746     case RASQAL_EXPR_SHA224:
1747     case RASQAL_EXPR_SHA256:
1748     case RASQAL_EXPR_SHA384:
1749     case RASQAL_EXPR_SHA512:
1750     case RASQAL_EXPR_UUID:
1751     case RASQAL_EXPR_STRUUID:
1752       /* arg1 is optional for RASQAL_EXPR_BNODE and result is always constant */
1753       result = (e->arg1) ? rasqal_expression_is_constant(e->arg1) : 1;
1754       break;
1755 
1756     case RASQAL_EXPR_LITERAL:
1757       result=rasqal_literal_is_constant(e->literal);
1758       break;
1759 
1760     case RASQAL_EXPR_FUNCTION:
1761     case RASQAL_EXPR_COALESCE:
1762     case RASQAL_EXPR_GROUP_CONCAT:
1763     case RASQAL_EXPR_CONCAT:
1764       result = 1;
1765       for(i = 0; i < raptor_sequence_size(e->args); i++) {
1766         rasqal_expression* e2;
1767         e2 = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
1768         if(!rasqal_expression_is_constant(e2)) {
1769           result = 0;
1770           break;
1771         }
1772       }
1773       /* e->literal is always a string constant - do not need to check */
1774       break;
1775 
1776     case RASQAL_EXPR_CAST:
1777       result=rasqal_expression_is_constant(e->arg1);
1778       break;
1779 
1780     case RASQAL_EXPR_VARSTAR:
1781       result=0;
1782       break;
1783 
1784     case RASQAL_EXPR_IN:
1785     case RASQAL_EXPR_NOT_IN:
1786       result = rasqal_expression_is_constant(e->arg1);
1787       if(!result)
1788         break;
1789 
1790       result = 1;
1791       for(i = 0; i < raptor_sequence_size(e->args); i++) {
1792         rasqal_expression* e2;
1793         e2 = (rasqal_expression*)raptor_sequence_get_at(e->args, i);
1794         if(!rasqal_expression_is_constant(e2)) {
1795           result = 0;
1796           break;
1797         }
1798       }
1799       break;
1800 
1801     case RASQAL_EXPR_UNKNOWN:
1802     default:
1803       RASQAL_FATAL2("Unknown operation %u", e->op);
1804   }
1805 
1806 #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1
1807   RASQAL_DEBUG2("expression %p: ", e);
1808   rasqal_expression_print(e, DEBUG_FH);
1809   fprintf(DEBUG_FH, " %s constant\n", (result ? "is" : "is not"));
1810 #endif
1811 
1812   return result;
1813 }
1814 
1815 
1816 void
rasqal_expression_convert_to_literal(rasqal_expression * e,rasqal_literal * l)1817 rasqal_expression_convert_to_literal(rasqal_expression* e, rasqal_literal* l)
1818 {
1819   int usage=e->usage;
1820 
1821   /* update expression 'e' in place */
1822   rasqal_expression_clear(e);
1823 
1824   memset(e, 0, sizeof(rasqal_expression));
1825   e->usage=usage;
1826   e->op=RASQAL_EXPR_LITERAL;
1827   e->literal=l;
1828 }
1829 
1830 
1831 
1832 
1833 /* for use with rasqal_expression_visit and user_data=rasqal_query */
1834 static int
rasqal_expression_has_variable(void * user_data,rasqal_expression * e)1835 rasqal_expression_has_variable(void *user_data, rasqal_expression *e)
1836 {
1837   rasqal_variable* v;
1838   const unsigned char* name=((rasqal_variable*)user_data)->name;
1839 
1840   if(e->op != RASQAL_EXPR_LITERAL)
1841     return 0;
1842 
1843   v=rasqal_literal_as_variable(e->literal);
1844   if(!v)
1845     return 0;
1846 
1847   if(!strcmp(RASQAL_GOOD_CAST(const char*, v->name), RASQAL_GOOD_CAST(const char*, name)))
1848     return 1;
1849 
1850   return 0;
1851 }
1852 
1853 
1854 int
rasqal_expression_mentions_variable(rasqal_expression * e,rasqal_variable * v)1855 rasqal_expression_mentions_variable(rasqal_expression* e, rasqal_variable* v)
1856 {
1857   return rasqal_expression_visit(e, rasqal_expression_has_variable, v);
1858 }
1859 
1860 
1861 /*
1862  * Deep copy a sequence of rasqal_expression to a new one.
1863  */
1864 raptor_sequence*
rasqal_expression_copy_expression_sequence(raptor_sequence * exprs_seq)1865 rasqal_expression_copy_expression_sequence(raptor_sequence* exprs_seq)
1866 {
1867   raptor_sequence* nexprs_seq = NULL;
1868   int size;
1869   int i;
1870 
1871   if(!exprs_seq)
1872     return NULL;
1873 
1874   nexprs_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_expression,
1875                                    (raptor_data_print_handler)rasqal_expression_print);
1876   if(!nexprs_seq)
1877     return NULL;
1878 
1879   size = raptor_sequence_size(exprs_seq);
1880   for(i = 0; i < size; i++) {
1881     rasqal_expression* e;
1882     e = (rasqal_expression*)raptor_sequence_get_at(exprs_seq, i);
1883     if(e) {
1884       e = rasqal_new_expression_from_expression(e);
1885       if(e)
1886         raptor_sequence_set_at(nexprs_seq, i, e);
1887     }
1888   }
1889 
1890   return nexprs_seq;
1891 }
1892 
1893 
1894 /**
1895  * rasqal_expression_sequence_evaluate:
1896  * @query: query
1897  * @exprs_seq: sequence of #rasqal_expression to evaluate
1898  * @ignore_errors: non-0 to ignore errors in evaluation
1899  * @error_p: OUT: pointer to error flag (or NULL)
1900  *
1901  * INTERNAL - evaluate a sequence of expressions into a sequence of literals
1902  *
1903  * Intended to implement SPARQL 1.1 Algebra ListEval defined:
1904  *   ListEval(ExprList, mu) returns a list E, where Ei = mu(ExprListi).
1905  *
1906  * The result is a new sequence with #rasqal_literal values evaluated
1907  * from the sequence of expressions @exprs_seq.  If @ignore_errors is
1908  * non-0, errors returned by a expressions are ignored (this
1909  * corresponds to SPARQL 1.1 Algebra ListEvalE )
1910  *
1911  * Return value: sequence of literals or NULL on failure
1912  */
1913 raptor_sequence*
rasqal_expression_sequence_evaluate(rasqal_query * query,raptor_sequence * exprs_seq,int ignore_errors,int * error_p)1914 rasqal_expression_sequence_evaluate(rasqal_query* query,
1915                                     raptor_sequence* exprs_seq,
1916                                     int ignore_errors,
1917                                     int* error_p)
1918 {
1919   int size;
1920   int i;
1921   raptor_sequence* literal_seq = NULL;
1922 
1923   if(!query || !exprs_seq) {
1924     if(error_p)
1925       *error_p = 1;
1926     return NULL;
1927   }
1928 
1929   size = raptor_sequence_size(exprs_seq);
1930   if(!size) {
1931     if(error_p)
1932       *error_p = 1;
1933     return NULL;
1934   }
1935 
1936   literal_seq = raptor_new_sequence((raptor_data_free_handler)rasqal_free_literal,
1937                                     (raptor_data_print_handler)rasqal_literal_print);
1938 
1939   for(i = 0; i < size; i++) {
1940     rasqal_expression* e;
1941     rasqal_literal *l;
1942     int error = 0;
1943 
1944     e = (rasqal_expression*)raptor_sequence_get_at(exprs_seq, i);
1945     l = rasqal_expression_evaluate2(e, query->eval_context, &error);
1946     if(error) {
1947       if(ignore_errors)
1948         continue;
1949 
1950       if(error_p)
1951         *error_p = error;
1952 
1953       return NULL;
1954     }
1955 
1956     /* l becomes owned by the sequence after this */
1957     raptor_sequence_set_at(literal_seq, i, l);
1958   }
1959 
1960   return literal_seq;
1961 }
1962 
1963 
1964 /**
1965  * rasqal_expression_compare:
1966  * @e1: #rasqal_expression first expression
1967  * @e2: #rasqal_expression second expression
1968  * @flags: comparison flags: see rasqal_literal_compare()
1969  * @error_p: pointer to error
1970  *
1971  * Compare two expressions
1972  *
1973  * The two literals are compared.  The comparison returned is as for
1974  * strcmp, first before second returns <0.  equal returns 0, and
1975  * first after second returns >0.  For URIs, the string value is used
1976  * for the comparsion.
1977  *
1978  * See rasqal_literal_compare() for comparison flags.
1979  *
1980  * If @error is not NULL, *error is set to non-0 on error
1981  *
1982  * Return value: <0, 0, or >0 as described above.
1983  **/
1984 int
rasqal_expression_compare(rasqal_expression * e1,rasqal_expression * e2,int flags,int * error_p)1985 rasqal_expression_compare(rasqal_expression* e1, rasqal_expression* e2,
1986                           int flags, int* error_p)
1987 {
1988   int rc = 0;
1989   int i;
1990   int diff;
1991 
1992   if(error_p)
1993     *error_p = 0;
1994 
1995   /* sort NULLs earlier */
1996   if(!e1 || !e2) {
1997     if(!e1 && !e2)
1998       return 0;
1999     if(!e1)
2000       return -1;
2001     else
2002       return 1;
2003   }
2004 
2005 
2006   if(e1->op != e2->op) {
2007     if(e1->op == RASQAL_EXPR_UNKNOWN || e2->op == RASQAL_EXPR_UNKNOWN)
2008       return 1;
2009 
2010     return RASQAL_GOOD_CAST(int, e2->op) - RASQAL_GOOD_CAST(int, e1->op);
2011   }
2012 
2013   switch(e1->op) {
2014     case RASQAL_EXPR_AND:
2015     case RASQAL_EXPR_OR:
2016     case RASQAL_EXPR_EQ:
2017     case RASQAL_EXPR_NEQ:
2018     case RASQAL_EXPR_LT:
2019     case RASQAL_EXPR_GT:
2020     case RASQAL_EXPR_LE:
2021     case RASQAL_EXPR_GE:
2022     case RASQAL_EXPR_PLUS:
2023     case RASQAL_EXPR_MINUS:
2024     case RASQAL_EXPR_STAR:
2025     case RASQAL_EXPR_SLASH:
2026     case RASQAL_EXPR_REM:
2027     case RASQAL_EXPR_STR_EQ:
2028     case RASQAL_EXPR_STR_NEQ:
2029     case RASQAL_EXPR_LANGMATCHES:
2030     case RASQAL_EXPR_REGEX:
2031     case RASQAL_EXPR_SAMETERM:
2032     case RASQAL_EXPR_IF:
2033     case RASQAL_EXPR_STRLANG:
2034     case RASQAL_EXPR_STRDT:
2035     case RASQAL_EXPR_STRSTARTS:
2036     case RASQAL_EXPR_STRENDS:
2037     case RASQAL_EXPR_CONTAINS:
2038     case RASQAL_EXPR_SUBSTR:
2039     case RASQAL_EXPR_STRBEFORE:
2040     case RASQAL_EXPR_STRAFTER:
2041       rc = rasqal_expression_compare(e1->arg1, e2->arg1, flags, error_p);
2042       if(rc)
2043         return rc;
2044 
2045       rc = rasqal_expression_compare(e1->arg2, e2->arg2, flags, error_p);
2046       if(rc)
2047         return rc;
2048 
2049       /* There are three 3-op expressions - both handled here */
2050       if(e1->op == RASQAL_EXPR_REGEX || e1->op == RASQAL_EXPR_IF ||
2051          e1->op == RASQAL_EXPR_SUBSTR)
2052         rc = rasqal_expression_compare(e1->arg3, e2->arg3, flags, error_p);
2053 
2054       break;
2055 
2056     case RASQAL_EXPR_REPLACE:
2057       /* 3 or 4 args */
2058       rc = rasqal_expression_compare(e1->arg1, e2->arg1, flags, error_p);
2059       if(rc)
2060         return rc;
2061 
2062       rc = rasqal_expression_compare(e1->arg2, e2->arg2, flags, error_p);
2063       if(rc)
2064         return rc;
2065 
2066       rc = rasqal_expression_compare(e1->arg3, e2->arg3, flags, error_p);
2067       if(rc)
2068         return rc;
2069 
2070       rc = rasqal_expression_compare(e1->arg4, e2->arg4, flags, error_p);
2071       break;
2072 
2073     case RASQAL_EXPR_STR_MATCH:
2074     case RASQAL_EXPR_STR_NMATCH:
2075       rc = rasqal_expression_compare(e1->arg1, e2->arg1, flags, error_p);
2076       if(rc)
2077         return rc;
2078 
2079       rc = rasqal_literal_compare(e1->literal, e2->literal, flags, error_p);
2080       break;
2081 
2082     case RASQAL_EXPR_TILDE:
2083     case RASQAL_EXPR_BANG:
2084     case RASQAL_EXPR_UMINUS:
2085     case RASQAL_EXPR_BOUND:
2086     case RASQAL_EXPR_STR:
2087     case RASQAL_EXPR_LANG:
2088     case RASQAL_EXPR_DATATYPE:
2089     case RASQAL_EXPR_ISURI:
2090     case RASQAL_EXPR_ISBLANK:
2091     case RASQAL_EXPR_ISLITERAL:
2092     case RASQAL_EXPR_ORDER_COND_ASC:
2093     case RASQAL_EXPR_ORDER_COND_DESC:
2094     case RASQAL_EXPR_GROUP_COND_ASC:
2095     case RASQAL_EXPR_GROUP_COND_DESC:
2096     case RASQAL_EXPR_COUNT:
2097     case RASQAL_EXPR_SUM:
2098     case RASQAL_EXPR_AVG:
2099     case RASQAL_EXPR_MIN:
2100     case RASQAL_EXPR_MAX:
2101     case RASQAL_EXPR_URI:
2102     case RASQAL_EXPR_IRI:
2103     case RASQAL_EXPR_BNODE:
2104     case RASQAL_EXPR_SAMPLE:
2105     case RASQAL_EXPR_ISNUMERIC:
2106     case RASQAL_EXPR_YEAR:
2107     case RASQAL_EXPR_MONTH:
2108     case RASQAL_EXPR_DAY:
2109     case RASQAL_EXPR_HOURS:
2110     case RASQAL_EXPR_MINUTES:
2111     case RASQAL_EXPR_SECONDS:
2112     case RASQAL_EXPR_TIMEZONE:
2113     case RASQAL_EXPR_FROM_UNIXTIME:
2114     case RASQAL_EXPR_TO_UNIXTIME:
2115     case RASQAL_EXPR_STRLEN:
2116     case RASQAL_EXPR_UCASE:
2117     case RASQAL_EXPR_LCASE:
2118     case RASQAL_EXPR_ENCODE_FOR_URI:
2119     case RASQAL_EXPR_TZ:
2120     case RASQAL_EXPR_ABS:
2121     case RASQAL_EXPR_ROUND:
2122     case RASQAL_EXPR_CEIL:
2123     case RASQAL_EXPR_FLOOR:
2124     case RASQAL_EXPR_MD5:
2125     case RASQAL_EXPR_SHA1:
2126     case RASQAL_EXPR_SHA224:
2127     case RASQAL_EXPR_SHA256:
2128     case RASQAL_EXPR_SHA384:
2129     case RASQAL_EXPR_SHA512:
2130     case RASQAL_EXPR_UUID:
2131     case RASQAL_EXPR_STRUUID:
2132       /* arg1 is optional for RASQAL_EXPR_BNODE */
2133       rc = rasqal_expression_compare(e1->arg1, e2->arg1, flags, error_p);
2134       break;
2135 
2136     case RASQAL_EXPR_LITERAL:
2137       rc = rasqal_literal_compare(e1->literal, e2->literal, flags, error_p);
2138       break;
2139 
2140     case RASQAL_EXPR_FUNCTION:
2141     case RASQAL_EXPR_COALESCE:
2142     case RASQAL_EXPR_CONCAT:
2143       diff = raptor_sequence_size(e2->args) - raptor_sequence_size(e1->args);
2144       if(diff)
2145         return diff;
2146 
2147       for(i = 0; i < raptor_sequence_size(e1->args); i++) {
2148         rasqal_expression* e1_f;
2149         rasqal_expression* e2_f;
2150 
2151         e1_f = (rasqal_expression*)raptor_sequence_get_at(e1->args, i);
2152         e2_f = (rasqal_expression*)raptor_sequence_get_at(e2->args, i);
2153 
2154         rc = rasqal_expression_compare(e1_f, e2_f, flags, error_p);
2155         if(rc)
2156           break;
2157       }
2158       break;
2159 
2160     case RASQAL_EXPR_CAST:
2161       rc = raptor_uri_compare(e1->name, e2->name);
2162       if(rc)
2163         break;
2164 
2165       rc = rasqal_expression_compare(e1->arg1, e2->arg1, flags, error_p);
2166       break;
2167 
2168     case RASQAL_EXPR_VARSTAR:
2169     case RASQAL_EXPR_CURRENT_DATETIME:
2170     case RASQAL_EXPR_NOW:
2171       /* 0-args: always equal */
2172       rc = 0;
2173       break;
2174 
2175     case RASQAL_EXPR_RAND:
2176       /* 0-args: always different */
2177       rc = 1;
2178       break;
2179 
2180     case RASQAL_EXPR_GROUP_CONCAT:
2181       rc = (RASQAL_GOOD_CAST(int, e2->flags) - RASQAL_GOOD_CAST(int, e1->flags));
2182       if(rc)
2183         break;
2184 
2185       diff = raptor_sequence_size(e2->args) - raptor_sequence_size(e1->args);
2186       if(diff)
2187         return diff;
2188 
2189       for(i = 0; i < raptor_sequence_size(e1->args); i++) {
2190         rasqal_expression* e1_f;
2191         rasqal_expression* e2_f;
2192 
2193         e1_f = (rasqal_expression*)raptor_sequence_get_at(e1->args, i);
2194         e2_f = (rasqal_expression*)raptor_sequence_get_at(e2->args, i);
2195 
2196         rc = rasqal_expression_compare(e1_f, e2_f, flags, error_p);
2197         if(rc)
2198           break;
2199       }
2200       if(rc)
2201         break;
2202 
2203       rc = rasqal_literal_compare(e1->literal, e2->literal, flags, error_p);
2204       break;
2205 
2206     case RASQAL_EXPR_IN:
2207     case RASQAL_EXPR_NOT_IN:
2208       rc = rasqal_expression_compare(e1->arg1, e2->arg1, flags, error_p);
2209       if(rc)
2210         return rc;
2211 
2212       diff = raptor_sequence_size(e2->args) - raptor_sequence_size(e1->args);
2213       if(diff)
2214         return diff;
2215 
2216       for(i = 0; i < raptor_sequence_size(e1->args); i++) {
2217         rasqal_expression* e1_f;
2218         rasqal_expression* e2_f;
2219 
2220         e1_f = (rasqal_expression*)raptor_sequence_get_at(e1->args, i);
2221         e2_f = (rasqal_expression*)raptor_sequence_get_at(e2->args, i);
2222 
2223         rc = rasqal_expression_compare(e1_f, e2_f, flags, error_p);
2224         if(rc)
2225           break;
2226       }
2227       break;
2228 
2229     case RASQAL_EXPR_UNKNOWN:
2230     default:
2231       RASQAL_FATAL2("Unknown operation %u", e1->op);
2232   }
2233 
2234   return rc;
2235 }
2236 
2237 
2238 /**
2239  * rasqal_expression_is_aggregate:
2240  * @e: expression
2241  *
2242  * INTERNAL - determine if expression is an aggregate expression (at the top; not recursively)
2243  *
2244  * Return value: non-0 if is aggreate
2245  */
2246 int
rasqal_expression_is_aggregate(rasqal_expression * e)2247 rasqal_expression_is_aggregate(rasqal_expression* e)
2248 {
2249   if(e->op == RASQAL_EXPR_COUNT ||
2250      e->op == RASQAL_EXPR_SUM ||
2251      e->op == RASQAL_EXPR_AVG ||
2252      e->op == RASQAL_EXPR_MIN ||
2253      e->op == RASQAL_EXPR_MAX ||
2254      e->op == RASQAL_EXPR_SAMPLE ||
2255      e->op == RASQAL_EXPR_GROUP_CONCAT)
2256     return 1;
2257 
2258   if(e->op != RASQAL_EXPR_FUNCTION)
2259     return 0;
2260 
2261   return (e->flags & RASQAL_EXPR_FLAG_AGGREGATE) != 0;
2262 }
2263 
2264 
2265 static int
rasqal_expression_mentions_aggregate_visitor(void * user_data,rasqal_expression * e)2266 rasqal_expression_mentions_aggregate_visitor(void *user_data,
2267                                              rasqal_expression *e)
2268 {
2269   return rasqal_expression_is_aggregate(e);
2270 }
2271 
2272 
2273 /*
2274  * Return non-0 if the expression tree mentions an aggregate expression
2275  */
2276 int
rasqal_expression_mentions_aggregate(rasqal_expression * e)2277 rasqal_expression_mentions_aggregate(rasqal_expression* e)
2278 {
2279   return rasqal_expression_visit(e,
2280                                  rasqal_expression_mentions_aggregate_visitor,
2281                                  NULL);
2282 }
2283 
2284 
2285 
2286 /*
2287  * rasqal_expression_convert_aggregate_to_variable:
2288  * @e_in: Input aggregate expression
2289  * @v: Input variable
2290  * @e_out: Output expression (or NULL)
2291  *
2292  * INTERNAL - Turn aggregate expression @e_in into a
2293  * #RASQAL_EXPR_LITERAL type one pointing at #rasqal_variable @v. If
2294  * field @e_out is not NULL, it returns in that variable a new
2295  * aggregate expression with the old expression fields.
2296  *
2297  * Takes ownership of @v
2298  *
2299  * Return value: non-0 on failure
2300  */
2301 int
rasqal_expression_convert_aggregate_to_variable(rasqal_expression * e_in,rasqal_variable * v,rasqal_expression ** e_out)2302 rasqal_expression_convert_aggregate_to_variable(rasqal_expression* e_in,
2303                                                 rasqal_variable* v,
2304                                                 rasqal_expression** e_out)
2305 {
2306   rasqal_world *world;
2307   rasqal_literal* l;
2308 
2309   if(!e_in || !v)
2310     goto tidy;
2311 
2312   world = e_in->world;
2313 
2314   if(e_out) {
2315     *e_out = RASQAL_MALLOC(rasqal_expression*, sizeof(**e_out));
2316     if(!*e_out)
2317       goto tidy;
2318   }
2319 
2320   l = rasqal_new_variable_literal(world, v);
2321   if(!l)
2322     goto tidy;
2323 
2324   if(e_out) {
2325     /* if e_out is not NULL, copy entire contents to new expression */
2326     memcpy(*e_out, e_in, sizeof(**e_out));
2327 
2328     /* ... and zero out old expression */
2329     memset(e_in, 0, sizeof(*e_in));
2330   } else {
2331     /* Otherwise just destroy the old aggregate fields */
2332     rasqal_expression_clear(e_in);
2333   }
2334 
2335 
2336   e_in->usage = 1;
2337   e_in->world = world;
2338   e_in->op = RASQAL_EXPR_LITERAL;
2339   e_in->literal = l;
2340 
2341   return 0;
2342 
2343   tidy:
2344   if(e_out) {
2345     RASQAL_FREE(rasqal_expression*, *e_out);
2346     *e_out = NULL;
2347   }
2348 
2349   return 1;
2350 }
2351 
2352 
2353 
2354 /**
2355  * rasqal_new_evaluation_context:
2356  * @world: rasqal world
2357  * @locator: locator or NULL
2358  * @flags: expression comparison flags
2359  *
2360  * Constructor - create a #rasqal_evaluation_context for use with
2361  * rasqal_expression_evaluate2()
2362  *
2363  * Return value: non-0 on failure
2364  */
2365 rasqal_evaluation_context*
rasqal_new_evaluation_context(rasqal_world * world,raptor_locator * locator,int flags)2366 rasqal_new_evaluation_context(rasqal_world* world,
2367                               raptor_locator* locator,
2368                               int flags)
2369 {
2370   rasqal_evaluation_context* eval_context;
2371 
2372   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
2373 
2374   eval_context = RASQAL_CALLOC(rasqal_evaluation_context*, 1, sizeof(*eval_context));
2375   if(!eval_context)
2376     return NULL;
2377 
2378   eval_context->world = world;
2379   eval_context->locator = locator;
2380   eval_context->flags = flags;
2381 
2382   eval_context->random = rasqal_new_random(world);
2383   if(!eval_context->random) {
2384     RASQAL_FREE(rasqal_evaluation_context*, eval_context);
2385     eval_context = NULL;
2386   }
2387 
2388   return eval_context;
2389 }
2390 
2391 
2392 /**
2393  * rasqal_free_evaluation_context:
2394  * @eval_context: #rasqal_evaluation_context object
2395  *
2396  * Destructor - destroy a #rasqal_evaluation_context object.
2397  *
2398  **/
2399 void
rasqal_free_evaluation_context(rasqal_evaluation_context * eval_context)2400 rasqal_free_evaluation_context(rasqal_evaluation_context* eval_context)
2401 {
2402   if(!eval_context)
2403     return;
2404 
2405   if(eval_context->base_uri)
2406     raptor_free_uri(eval_context->base_uri);
2407 
2408   if(eval_context->random)
2409     rasqal_free_random(eval_context->random);
2410 
2411   RASQAL_FREE(rasqal_evaluation_context*, eval_context);
2412 }
2413 
2414 
2415 /**
2416  * rasqal_evaluation_context_set_base_uri:
2417  * @eval_context: #rasqal_evaluation_context object
2418  * @base_uri: base URI
2419  *
2420  * Set the URI for a #rasqal_evaluation_context
2421  *
2422  * Return value: non-0 on failure
2423  */
2424 int
rasqal_evaluation_context_set_base_uri(rasqal_evaluation_context * eval_context,raptor_uri * base_uri)2425 rasqal_evaluation_context_set_base_uri(rasqal_evaluation_context* eval_context,
2426                                        raptor_uri *base_uri)
2427 {
2428 
2429   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(eval_context, rasqal_evaluation_context, 1);
2430 
2431   if(eval_context->base_uri)
2432     raptor_free_uri(eval_context->base_uri);
2433 
2434   eval_context->base_uri = raptor_uri_copy(base_uri);
2435 
2436   return 0;
2437 }
2438 
2439 
2440 /**
2441  * rasqal_evaluation_context_set_rand_seed:
2442  * @eval_context: #rasqal_evaluation_context object
2443  * @seed: random seed
2444  *
2445  * Set the random seed for a #rasqal_evaluation_context
2446  *
2447  * Return value: non-0 on failure
2448  */
2449 int
rasqal_evaluation_context_set_rand_seed(rasqal_evaluation_context * eval_context,unsigned int seed)2450 rasqal_evaluation_context_set_rand_seed(rasqal_evaluation_context* eval_context,
2451                                         unsigned int seed)
2452 {
2453 
2454   RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(eval_context, rasqal_evaluation_context, 1);
2455 
2456   return rasqal_random_seed(eval_context->random, seed);
2457 }
2458 
2459 
2460 #endif /* not STANDALONE */
2461 
2462 
2463 
2464 
2465 #ifdef STANDALONE
2466 #include <stdio.h>
2467 
2468 int main(int argc, char *argv[]);
2469 
2470 
2471 #define assert_match(function, result, string) do { if(strcmp(result, string)) { fprintf(stderr, #function " failed - returned %s, expected %s\n", result, string); exit(1); } } while(0)
2472 
2473 
2474 int
main(int argc,char * argv[])2475 main(int argc, char *argv[])
2476 {
2477   const char *program=rasqal_basename(argv[0]);
2478   rasqal_literal *lit1, *lit2;
2479   rasqal_expression *expr1, *expr2;
2480   rasqal_expression* expr;
2481   rasqal_literal* result;
2482   int error=0;
2483   rasqal_world *world;
2484   rasqal_evaluation_context *eval_context = NULL;
2485 
2486   raptor_world* raptor_world_ptr;
2487   raptor_world_ptr = raptor_new_world();
2488   if(!raptor_world_ptr || raptor_world_open(raptor_world_ptr))
2489     exit(1);
2490 
2491   world = rasqal_new_world();
2492   rasqal_world_set_raptor(world, raptor_world_ptr);
2493   /* no rasqal_world_open() */
2494 
2495   rasqal_uri_init(world);
2496 
2497   rasqal_xsd_init(world);
2498 
2499   eval_context = rasqal_new_evaluation_context(world, NULL /* locator */, 0);
2500 
2501   lit1=rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, 1);
2502   expr1=rasqal_new_literal_expression(world, lit1);
2503   lit2=rasqal_new_integer_literal(world, RASQAL_LITERAL_INTEGER, 1);
2504   expr2=rasqal_new_literal_expression(world, lit2);
2505   expr=rasqal_new_2op_expression(world, RASQAL_EXPR_PLUS, expr1, expr2);
2506 
2507   fprintf(stderr, "%s: expression: ", program);
2508   rasqal_expression_print(expr, stderr);
2509   fputc('\n', stderr);
2510 
2511   result = rasqal_expression_evaluate2(expr, eval_context, &error);
2512 
2513   if(error) {
2514     fprintf(stderr, "%s: expression evaluation FAILED with error\n", program);
2515   } else {
2516     int bresult;
2517 
2518     fprintf(stderr, "%s: expression result: \n", program);
2519     rasqal_literal_print(result, stderr);
2520     fputc('\n', stderr);
2521     bresult=rasqal_literal_as_boolean(result, &error);
2522     if(error) {
2523       fprintf(stderr, "%s: boolean expression FAILED\n", program);
2524     } else
2525       fprintf(stderr, "%s: boolean expression result: %d\n", program, bresult);
2526 
2527 
2528   }
2529 
2530   rasqal_free_expression(expr);
2531 
2532   if(result)
2533     rasqal_free_literal(result);
2534 
2535   rasqal_xsd_finish(world);
2536 
2537   rasqal_uri_finish(world);
2538 
2539   rasqal_free_evaluation_context(eval_context);
2540 
2541   RASQAL_FREE(rasqal_world, world);
2542 
2543   raptor_free_world(raptor_world_ptr);
2544 
2545   return error;
2546 }
2547 #endif /* STANDALONE */
2548