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