1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * rasqal_query.c - Rasqal RDF Query
4 *
5 * Copyright (C) 2003-2009, 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 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38 #ifdef HAVE_STDINT_H
39 #include <stdint.h>
40 #endif
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #include <stdarg.h>
45
46 #include "rasqal.h"
47 #include "rasqal_internal.h"
48
49
50 /*
51 *
52 * Query Class Internals
53 *
54 * This is the main Rasqal class for constructing RDF graph queries
55 * from a syntax or by API, preparing them for execution with a query
56 * execution and executing them to return a result set.
57 *
58 * Queries are constructed from a syntax in some query language
59 * syntax and build an RDF query API structure based on triple
60 * patterns, filter expressions, graph patterns above them operating
61 * over a set of graphs.
62 *
63 * This class does not deal with manipulating result sets which are
64 * handled by the #rasqal_query_results and methods on it although
65 * rasqal_query_execute() does return a newly constructed result
66 * object.
67 *
68 * It also does not deal with executing a query which is handled by
69 * #rasqal_query_execution_factory instances that have their own
70 * simpler API.
71 *
72 */
73
74 #define DEBUG_FH stderr
75
76 static int rasqal_query_add_query_result(rasqal_query* query, rasqal_query_results* query_results);
77
78
79 /**
80 * rasqal_new_query:
81 * @world: rasqal_world object
82 * @name: the query language name (or NULL)
83 * @uri: #raptor_uri language uri (or NULL)
84 *
85 * Constructor - create a new rasqal_query object.
86 *
87 * A query language can be named or identified by a URI, either
88 * of which is optional. The default query language will be used
89 * if both are NULL. rasqal_world_get_query_language_description returns
90 * the description of the known names, labels, MIME types and URIs.
91 *
92 * Return value: a new #rasqal_query object or NULL on failure
93 */
94 rasqal_query*
rasqal_new_query(rasqal_world * world,const char * name,const unsigned char * uri)95 rasqal_new_query(rasqal_world *world, const char *name,
96 const unsigned char *uri)
97 {
98 rasqal_query_language_factory* factory;
99 rasqal_query* query;
100
101 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
102
103 /* for compatibility with older binaries that do not call it */
104 rasqal_world_open(world);
105
106 factory = rasqal_get_query_language_factory(world, name, uri);
107 if(!factory)
108 return NULL;
109
110 query = RASQAL_CALLOC(rasqal_query*, 1, sizeof(*query));
111 if(!query)
112 return NULL;
113
114 /* set usage first to 1 so we can clean up with rasqal_free_query() on error */
115 query->usage = 1;
116
117 query->world = world;
118
119 query->factory = factory;
120
121 query->context = RASQAL_CALLOC(void*, 1, factory->context_length);
122 if(!query->context)
123 goto tidy;
124
125 query->namespaces = raptor_new_namespaces(world->raptor_world_ptr, 0);
126 if(!query->namespaces)
127 goto tidy;
128
129 query->vars_table = rasqal_new_variables_table(query->world);
130 if(!query->vars_table)
131 goto tidy;
132
133 query->triples = raptor_new_sequence((raptor_data_free_handler)rasqal_free_triple, (raptor_data_print_handler)rasqal_triple_print);
134 if(!query->triples)
135 goto tidy;
136
137 query->prefixes = raptor_new_sequence((raptor_data_free_handler)rasqal_free_prefix, (raptor_data_print_handler)rasqal_prefix_print);
138 if(!query->prefixes)
139 goto tidy;
140
141 query->data_graphs = raptor_new_sequence((raptor_data_free_handler)rasqal_free_data_graph, (raptor_data_print_handler)rasqal_data_graph_print);
142 if(!query->data_graphs)
143 goto tidy;
144
145 query->results = raptor_new_sequence((raptor_data_free_handler)rasqal_query_results_remove_query_reference, NULL);
146 if(!query->results)
147 goto tidy;
148
149 query->eval_context = rasqal_new_evaluation_context(query->world,
150 &query->locator,
151 query->compare_flags);
152 if(!query->eval_context)
153 goto tidy;
154
155 if(factory->init(query, name))
156 goto tidy;
157
158 return query;
159
160 tidy:
161 rasqal_free_query(query);
162 return NULL;
163 }
164
165
166
167 /**
168 * rasqal_free_query:
169 * @query: #rasqal_query object
170 *
171 * Destructor - destroy a #rasqal_query object.
172 **/
173 void
rasqal_free_query(rasqal_query * query)174 rasqal_free_query(rasqal_query* query)
175 {
176 if(!query)
177 return;
178
179 if(--query->usage)
180 return;
181
182 if(query->factory)
183 query->factory->terminate(query);
184
185 if(query->eval_context)
186 rasqal_free_evaluation_context(query->eval_context);
187
188 if(query->context)
189 RASQAL_FREE(rasqal_query_context, query->context);
190
191 if(query->namespaces)
192 raptor_free_namespaces(query->namespaces);
193
194 if(query->base_uri)
195 raptor_free_uri(query->base_uri);
196
197 if(query->query_string)
198 RASQAL_FREE(char*, query->query_string);
199
200 if(query->data_graphs)
201 raptor_free_sequence(query->data_graphs);
202
203 if(query->describes)
204 raptor_free_sequence(query->describes);
205
206 if(query->triples)
207 raptor_free_sequence(query->triples);
208 if(query->optional_triples)
209 raptor_free_sequence(query->optional_triples);
210 if(query->constructs)
211 raptor_free_sequence(query->constructs);
212 if(query->prefixes)
213 raptor_free_sequence(query->prefixes);
214 if(query->results)
215 raptor_free_sequence(query->results);
216
217 if(query->triples_use_map)
218 RASQAL_FREE(shortarray, query->triples_use_map);
219
220 if(query->variables_use_map)
221 RASQAL_FREE(shortarray, query->variables_use_map);
222
223 if(query->query_graph_pattern)
224 rasqal_free_graph_pattern(query->query_graph_pattern);
225
226 if(query->graph_patterns_sequence)
227 raptor_free_sequence(query->graph_patterns_sequence);
228
229 if(query->query_results_formatter_name)
230 RASQAL_FREE(char*, query->query_results_formatter_name);
231
232 /* Do this last since most everything above could refer to a variable */
233 if(query->vars_table)
234 rasqal_free_variables_table(query->vars_table);
235
236 if(query->updates)
237 raptor_free_sequence(query->updates);
238
239 if(query->modifier)
240 rasqal_free_solution_modifier(query->modifier);
241
242 if(query->bindings)
243 rasqal_free_bindings(query->bindings);
244
245 if(query->projection)
246 rasqal_free_projection(query->projection);
247
248 RASQAL_FREE(rasqal_query, query);
249 }
250
251
252 /* Methods */
253
254 /**
255 * rasqal_query_get_name:
256 * @query: #rasqal_query query object
257 *
258 * Get a short name for the query language.
259 *
260 * Return value: shared string label value
261 **/
262 const char*
rasqal_query_get_name(rasqal_query * query)263 rasqal_query_get_name(rasqal_query* query)
264 {
265 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
266
267 return query->factory->desc.names[0];
268 }
269
270
271 /**
272 * rasqal_query_get_label:
273 * @query: #rasqal_query query object
274 *
275 * Get a readable label for the query language.
276 *
277 * Return value: shared string label value
278 **/
279 const char*
rasqal_query_get_label(rasqal_query * query)280 rasqal_query_get_label(rasqal_query* query)
281 {
282 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
283
284 return query->factory->desc.label;
285 }
286
287
288 /**
289 * rasqal_query_set_feature:
290 * @query: #rasqal_query query object
291 * @feature: feature to set from enumerated #rasqal_feature values
292 * @value: integer feature value
293 *
294 * Set various query features.
295 *
296 * The allowed features are available via rasqal_features_enumerate().
297 *
298 * Return value: non 0 on failure or if the feature is unknown
299 **/
300 int
rasqal_query_set_feature(rasqal_query * query,rasqal_feature feature,int value)301 rasqal_query_set_feature(rasqal_query* query, rasqal_feature feature, int value)
302 {
303 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
304
305 switch(feature) {
306 case RASQAL_FEATURE_NO_NET:
307 case RASQAL_FEATURE_RAND_SEED:
308
309 if(feature == RASQAL_FEATURE_RAND_SEED)
310 query->user_set_rand = 1;
311
312 query->features[RASQAL_GOOD_CAST(int, feature)] = value;
313 break;
314 }
315
316 return 0;
317 }
318
319
320 /**
321 * rasqal_query_set_feature_string:
322 * @query: #rasqal_query query object
323 * @feature: feature to set from enumerated #rasqal_feature values
324 * @value: feature value
325 *
326 * Set query features with string values.
327 *
328 * The allowed features are available via rasqal_features_enumerate().
329 * If the feature type is integer, the value is interpreted as an integer.
330 *
331 * Return value: non 0 on failure or if the feature is unknown
332 **/
333 int
rasqal_query_set_feature_string(rasqal_query * query,rasqal_feature feature,const unsigned char * value)334 rasqal_query_set_feature_string(rasqal_query *query,
335 rasqal_feature feature,
336 const unsigned char *value)
337 {
338 int value_is_string = (rasqal_feature_value_type(feature) == 1);
339
340 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
341
342 if(!value_is_string)
343 return rasqal_query_set_feature(query, feature,
344 atoi(RASQAL_GOOD_CAST(const char*, value)));
345
346 return -1;
347 }
348
349
350 /**
351 * rasqal_query_get_feature:
352 * @query: #rasqal_query query object
353 * @feature: feature to get value
354 *
355 * Get various query features.
356 *
357 * The allowed features are available via rasqal_features_enumerate().
358 *
359 * Note: no feature value is negative
360 *
361 * Return value: feature value or < 0 for an illegal feature
362 **/
363 int
rasqal_query_get_feature(rasqal_query * query,rasqal_feature feature)364 rasqal_query_get_feature(rasqal_query *query, rasqal_feature feature)
365 {
366 int result= -1;
367
368 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
369
370 switch(feature) {
371 case RASQAL_FEATURE_NO_NET:
372 case RASQAL_FEATURE_RAND_SEED:
373 result = (query->features[RASQAL_GOOD_CAST(int, feature)] != 0);
374 break;
375 }
376
377 return result;
378 }
379
380
381 /**
382 * rasqal_query_get_feature_string:
383 * @query: #rasqal_query query object
384 * @feature: feature to get value
385 *
386 * Get query features with string values.
387 *
388 * The allowed features are available via rasqal_features_enumerate().
389 * If a string is returned, it must be freed by the caller.
390 *
391 * Return value: feature value or NULL for an illegal feature or no value
392 **/
393 const unsigned char *
rasqal_query_get_feature_string(rasqal_query * query,rasqal_feature feature)394 rasqal_query_get_feature_string(rasqal_query *query,
395 rasqal_feature feature)
396 {
397 int value_is_string = (rasqal_feature_value_type(feature) == 1);
398
399 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
400
401 if(!value_is_string)
402 return NULL;
403
404 return NULL;
405 }
406
407
408 /**
409 * rasqal_query_get_distinct:
410 * @query: #rasqal_query query object
411 *
412 * Get the query distinct mode
413 *
414 * See rasqal_query_set_distinct() for the distinct modes.
415 *
416 * Return value: non-0 if the results should be distinct
417 **/
418 int
rasqal_query_get_distinct(rasqal_query * query)419 rasqal_query_get_distinct(rasqal_query* query)
420 {
421 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
422
423 if(!query->projection)
424 return 0;
425
426 return query->projection->distinct;
427 }
428
429
430 /**
431 * rasqal_query_set_distinct:
432 * @query: #rasqal_query query object
433 * @distinct_mode: distinct mode
434 *
435 * Set the query distinct results mode.
436 *
437 * The allowed @distinct_mode values are:
438 * 0 if not given
439 * 1 if DISTINCT: ensure solutions are unique
440 * 2 if SPARQL REDUCED: permit elimination of some non-unique solutions
441 *
442 **/
443 void
rasqal_query_set_distinct(rasqal_query * query,int distinct_mode)444 rasqal_query_set_distinct(rasqal_query* query, int distinct_mode)
445 {
446 RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
447
448 if(distinct_mode < 0 || distinct_mode > 2)
449 distinct_mode = 0;
450
451 if(!query->projection) {
452 query->projection = rasqal_new_projection(query,
453 /* variables */ NULL,
454 /* wildcard */ 0,
455 /* distinct */ 0);
456 if(!query->projection)
457 return;
458 }
459 query->projection->distinct = distinct_mode;
460 }
461
462
463 /**
464 * rasqal_query_get_explain:
465 * @query: #rasqal_query query object
466 *
467 * Get the query explain results flag.
468 *
469 * Return value: non-0 if the results should be explain
470 **/
471 int
rasqal_query_get_explain(rasqal_query * query)472 rasqal_query_get_explain(rasqal_query* query)
473 {
474 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
475
476 return query->explain;
477 }
478
479
480 /**
481 * rasqal_query_set_explain:
482 * @query: #rasqal_query query object
483 * @is_explain: non-0 if explain
484 *
485 * Set the query explain results flag.
486 *
487 **/
488 void
rasqal_query_set_explain(rasqal_query * query,int is_explain)489 rasqal_query_set_explain(rasqal_query* query, int is_explain)
490 {
491 RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
492
493 query->explain = (is_explain != 0) ? 1 : 0;
494 }
495
496
497 /**
498 * rasqal_query_get_limit:
499 * @query: #rasqal_query query object
500 *
501 * Get the query-specified limit on results.
502 *
503 * This is the limit given in the query on the number of results allowed.
504 *
505 * Return value: integer >=0 if a limit is given, otherwise <0
506 **/
507 int
rasqal_query_get_limit(rasqal_query * query)508 rasqal_query_get_limit(rasqal_query* query)
509 {
510 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
511
512 if(query->modifier)
513 return query->modifier->limit;
514 else
515 return -1;
516 }
517
518
519 /**
520 * rasqal_query_set_limit:
521 * @query: #rasqal_query query object
522 * @limit: the limit on results, >=0 to set a limit, <0 to have no limit
523 *
524 * Set the query-specified limit on results.
525 *
526 * This is the limit given in the query on the number of results
527 * allowed. It is only guaranteed to work after the query is
528 * prepared and before it is executed.
529 **/
530 void
rasqal_query_set_limit(rasqal_query * query,int limit)531 rasqal_query_set_limit(rasqal_query* query, int limit)
532 {
533 RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
534
535 if(query->modifier)
536 query->modifier->limit = limit;
537 }
538
539
540 /**
541 * rasqal_query_get_offset:
542 * @query: #rasqal_query query object
543 *
544 * Get the query-specified offset on results.
545 *
546 * This is the offset given in the query on the number of results
547 * allowed. It is only guaranteed to work after the query is
548 * prepared and before it is executed.
549 *
550 * Return value: integer >=0 if a offset is given, otherwise <0
551 **/
552 int
rasqal_query_get_offset(rasqal_query * query)553 rasqal_query_get_offset(rasqal_query* query)
554 {
555 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
556
557 if(query->modifier)
558 return query->modifier->offset;
559 else
560 return -1;
561 }
562
563
564 /**
565 * rasqal_query_set_offset:
566 * @query: #rasqal_query query object
567 * @offset: offset for results, >=0 to set an offset, <0 to have no offset
568 *
569 * Set the query-specified offset on results.
570 *
571 * This is the offset given in the query on the number of results allowed.
572 **/
573 void
rasqal_query_set_offset(rasqal_query * query,int offset)574 rasqal_query_set_offset(rasqal_query* query, int offset)
575 {
576 RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
577
578 if(query->modifier)
579 query->modifier->offset = offset;
580 }
581
582
583 /**
584 * rasqal_query_add_data_graph:
585 * @query: #rasqal_query query object
586 * @data_graph: data graph
587 *
588 * Add a data graph to the query.
589 *
590 * Return value: non-0 on failure
591 **/
592 int
rasqal_query_add_data_graph(rasqal_query * query,rasqal_data_graph * data_graph)593 rasqal_query_add_data_graph(rasqal_query* query, rasqal_data_graph* data_graph)
594 {
595 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
596 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(data_graph, rasqal_data_graph, 1);
597
598 if(raptor_sequence_push(query->data_graphs, (void*)data_graph))
599 return 1;
600 return 0;
601 }
602
603
604 /**
605 * rasqal_query_add_data_graphs:
606 * @query: #rasqal_query query object
607 * @data_graphs: sequence of #rasqal_data_graph
608 *
609 * Add a set of data graphs to the query.
610 *
611 * The objects in the passed-in @data_graphs sequence becomes owne by the query.
612 * The @data_graphs sequence itself is freed and must not be used after this call.
613 *
614 * Return value: non-0 on failure
615 **/
616 int
rasqal_query_add_data_graphs(rasqal_query * query,raptor_sequence * data_graphs)617 rasqal_query_add_data_graphs(rasqal_query* query,
618 raptor_sequence* data_graphs)
619 {
620 int rc;
621
622 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
623 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(data_graphs, raptor_sequence, 1);
624
625 rc = raptor_sequence_join(query->data_graphs, data_graphs);
626 raptor_free_sequence(data_graphs);
627
628 return rc;
629 }
630
631
632 /**
633 * rasqal_query_get_data_graph_sequence:
634 * @query: #rasqal_query query object
635 *
636 * Get the sequence of data_graph URIs.
637 *
638 * Return value: a #raptor_sequence of #raptor_uri pointers.
639 **/
640 raptor_sequence*
rasqal_query_get_data_graph_sequence(rasqal_query * query)641 rasqal_query_get_data_graph_sequence(rasqal_query* query)
642 {
643 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
644
645 return query->data_graphs;
646 }
647
648
649 /**
650 * rasqal_query_get_data_graph:
651 * @query: #rasqal_query query object
652 * @idx: index into the sequence (0 or larger)
653 *
654 * Get a rasqal_data_graph* in the sequence of data_graphs.
655 *
656 * Return value: a #rasqal_data_graph pointer or NULL if out of the sequence range
657 **/
658 rasqal_data_graph*
rasqal_query_get_data_graph(rasqal_query * query,int idx)659 rasqal_query_get_data_graph(rasqal_query* query, int idx)
660 {
661 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
662
663 if(!query->data_graphs)
664 return NULL;
665
666 return (rasqal_data_graph*)raptor_sequence_get_at(query->data_graphs, idx);
667 }
668
669
670 /**
671 * rasqal_query_dataset_contains_named_graph:
672 * @query: #rasqal_query query object
673 * @graph_uri: query URI
674 *
675 * Test if the query dataset contains a named graph
676 *
677 * Return value: non-0 if the dataset contains a named graph
678 */
679 int
rasqal_query_dataset_contains_named_graph(rasqal_query * query,raptor_uri * graph_uri)680 rasqal_query_dataset_contains_named_graph(rasqal_query* query,
681 raptor_uri *graph_uri)
682 {
683 rasqal_data_graph *dg;
684 int idx;
685 int found = 0;
686
687 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
688 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(graph_uri, raptor_uri, 1);
689
690 for(idx = 0; (dg = rasqal_query_get_data_graph(query, idx)); idx++) {
691 if(dg->name_uri && raptor_uri_equals(dg->name_uri, graph_uri)) {
692 /* graph_uri is a graph name in the dataset */
693 found = 1;
694 break;
695 }
696 }
697 return found;
698 }
699
700
701 /**
702 * rasqal_query_add_variable:
703 * @query: #rasqal_query query object
704 * @var: #rasqal_variable variable
705 *
706 * Add a projected (named) variable to the query.
707 *
708 * See also rasqal_query_set_variable() which assigns or removes a value to
709 * a previously added variable in the query.
710 *
711 * Return value: non-0 on failure
712 **/
713 int
rasqal_query_add_variable(rasqal_query * query,rasqal_variable * var)714 rasqal_query_add_variable(rasqal_query* query, rasqal_variable* var)
715 {
716 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
717 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(var, rasqal_variable, 1);
718
719 if(!rasqal_variables_table_contains(query->vars_table, var->type, var->name)) {
720 if(rasqal_variables_table_add_variable(query->vars_table, var))
721 return 1;
722 }
723
724 if(!query->projection) {
725 query->projection = rasqal_new_projection(query,
726 /* variables */ NULL,
727 /* wildcard */ 0,
728 /* distinct */ 0);
729 if(!query->projection)
730 return 1;
731 }
732 return rasqal_projection_add_variable(query->projection, var);
733 }
734
735
736 /**
737 * rasqal_query_get_bound_variable_sequence:
738 * @query: #rasqal_query query object
739 *
740 * Get the sequence of projected variables in the query.
741 *
742 * This returns the sequence of variables that are explicitly chosen
743 * via SELECT in SPARQL. Or all variables mentioned with SELECT *
744 *
745 * Return value: a #raptor_sequence of #rasqal_variable pointers.
746 **/
747 raptor_sequence*
rasqal_query_get_bound_variable_sequence(rasqal_query * query)748 rasqal_query_get_bound_variable_sequence(rasqal_query* query)
749 {
750 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
751
752 if(!query->projection)
753 return NULL;
754
755 return rasqal_projection_get_variables_sequence(query->projection);
756 }
757
758
759 /**
760 * rasqal_query_get_describe_sequence:
761 * @query: #rasqal_query query object
762 *
763 * Get the sequence of literals described in the query.
764 *
765 * This returns the sequence of literals (constants or variables) that are
766 * explicitly chosen via DESCRIBE in SPARQL.
767 *
768 * Return value: a #raptor_sequence of #rasqal_literal pointers.
769 **/
770 raptor_sequence*
rasqal_query_get_describe_sequence(rasqal_query * query)771 rasqal_query_get_describe_sequence(rasqal_query* query)
772 {
773 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
774
775 return query->describes;
776 }
777
778
779 /**
780 * rasqal_query_get_anonymous_variable_sequence:
781 * @query: #rasqal_query query object
782 *
783 * Get the sequence of anonymous variables mentioned in the query.
784 *
785 * Return value: a #raptor_sequence of #rasqal_variable pointers.
786 **/
787 raptor_sequence*
rasqal_query_get_anonymous_variable_sequence(rasqal_query * query)788 rasqal_query_get_anonymous_variable_sequence(rasqal_query* query)
789 {
790 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
791
792 return rasqal_variables_table_get_anonymous_variables_sequence(query->vars_table);
793 }
794
795
796 /**
797 * rasqal_query_get_all_variable_sequence:
798 * @query: #rasqal_query query object
799 *
800 * Get the sequence of all variables mentioned in the query.
801 *
802 * Return value: a #raptor_sequence of #rasqal_variable pointers.
803 **/
804 raptor_sequence*
rasqal_query_get_all_variable_sequence(rasqal_query * query)805 rasqal_query_get_all_variable_sequence(rasqal_query* query)
806 {
807 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
808
809 return rasqal_variables_table_get_named_variables_sequence(query->vars_table);
810 }
811
812
813 /**
814 * rasqal_query_get_variable:
815 * @query: #rasqal_query query object
816 * @idx: index into the sequence (0 or larger)
817 *
818 * Get a variable in the query
819 *
820 * Return value: pointer to shared #rasqal_variable or NULL if out of range
821 **/
822 rasqal_variable*
rasqal_query_get_variable(rasqal_query * query,int idx)823 rasqal_query_get_variable(rasqal_query* query, int idx)
824 {
825 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
826
827 return rasqal_variables_table_get(query->vars_table, idx);
828 }
829
830
831 /**
832 * rasqal_query_has_variable2:
833 * @query: #rasqal_query query object
834 * @type: the variable type to match or #RASQAL_VARIABLE_TYPE_UNKNOWN for any.
835 * @name: variable name
836 *
837 * Find if the named variable of the given type is in the query
838 *
839 * Note that looking up for any type #RASQAL_VARIABLE_TYPE_UNKNOWN
840 * may a name match but for any type so in cases where the query has
841 * both a named and anonymous (extensional) variable, an arbitrary one
842 * will be returned.
843 *
844 * Return value: non-0 if the variable name was found.
845 **/
846 int
rasqal_query_has_variable2(rasqal_query * query,rasqal_variable_type type,const unsigned char * name)847 rasqal_query_has_variable2(rasqal_query* query,
848 rasqal_variable_type type,
849 const unsigned char *name)
850 {
851 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
852 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 0);
853
854 return rasqal_variables_table_contains(query->vars_table, type, name);
855 }
856
857
858 #ifndef RASQAL_DISABLE_DEPRECATED
859 /**
860 * rasqal_query_has_variable:
861 * @query: #rasqal_query query object
862 * @name: variable name
863 *
864 * Find if the named variable is in the query (of any type)
865 *
866 * @Deprecated: Use rasqal_query_has_variable2() with the variable type arg
867 *
868 * Return value: non-0 if the variable name was found.
869 **/
870 int
rasqal_query_has_variable(rasqal_query * query,const unsigned char * name)871 rasqal_query_has_variable(rasqal_query* query, const unsigned char *name)
872 {
873 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
874 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 0);
875
876 return rasqal_query_has_variable2(query, RASQAL_VARIABLE_TYPE_UNKNOWN, name);
877 }
878 #endif
879
880 /**
881 * rasqal_query_set_variable2:
882 * @query: #rasqal_query query object
883 * @type: the variable type to match or #RASQAL_VARIABLE_TYPE_UNKNOWN for any.
884 * @name: #rasqal_variable variable
885 * @value: #rasqal_literal value to set or NULL
886 *
887 * Bind an existing typed variable to a value to the query.
888 *
889 * See also rasqal_query_add_variable() which adds a new binding variable
890 * and must be called before this method is invoked.
891 *
892 * Return value: non-0 on failure
893 **/
894 int
rasqal_query_set_variable2(rasqal_query * query,rasqal_variable_type type,const unsigned char * name,rasqal_literal * value)895 rasqal_query_set_variable2(rasqal_query* query,
896 rasqal_variable_type type,
897 const unsigned char *name,
898 rasqal_literal* value)
899 {
900 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
901 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 1);
902 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, rasqal_literal, 1);
903
904 return rasqal_variables_table_set(query->vars_table, type, name, value);
905 }
906
907
908 #ifndef RASQAL_DISABLE_DEPRECATED
909 /**
910 * rasqal_query_set_variable:
911 * @query: #rasqal_query query object
912 * @name: #rasqal_variable variable
913 * @value: #rasqal_literal value to set or NULL
914 *
915 * Bind an existing named (selected) variable to a value to the query.
916 *
917 * @Deprecated for rasqal_query_set_variable2() that includes a type
918 * arg. This function only sets named variables of type
919 * #RASQAL_VARIABLE_TYPE_NORMAL
920 *
921 * Return value: non-0 on failure
922 **/
923 int
rasqal_query_set_variable(rasqal_query * query,const unsigned char * name,rasqal_literal * value)924 rasqal_query_set_variable(rasqal_query* query, const unsigned char *name,
925 rasqal_literal* value)
926 {
927 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
928 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 1);
929 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, rasqal_literal, 1);
930
931 return rasqal_query_set_variable2(query, RASQAL_VARIABLE_TYPE_NORMAL,
932 name, value);
933 }
934 #endif
935
936 /**
937 * rasqal_query_get_triple_sequence:
938 * @query: #rasqal_query query object
939 *
940 * Get the sequence of matching triples in the query.
941 *
942 * Return value: a #raptor_sequence of #rasqal_triple pointers.
943 **/
944 raptor_sequence*
rasqal_query_get_triple_sequence(rasqal_query * query)945 rasqal_query_get_triple_sequence(rasqal_query* query)
946 {
947 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
948
949 return query->triples;
950 }
951
952
953 /**
954 * rasqal_query_get_triple:
955 * @query: #rasqal_query query object
956 * @idx: index into the sequence (0 or larger)
957 *
958 * Get a triple in the sequence of matching triples in the query.
959 *
960 * Return value: a #rasqal_triple pointer or NULL if out of the sequence range
961 **/
962 rasqal_triple*
rasqal_query_get_triple(rasqal_query * query,int idx)963 rasqal_query_get_triple(rasqal_query* query, int idx)
964 {
965 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
966
967 if(!query->triples)
968 return NULL;
969
970 return (rasqal_triple*)raptor_sequence_get_at(query->triples, idx);
971 }
972
973
974 int
rasqal_query_declare_prefix(rasqal_query * rq,rasqal_prefix * p)975 rasqal_query_declare_prefix(rasqal_query *rq, rasqal_prefix *p)
976 {
977 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(rq, rasqal_query, 1);
978 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(p, rasqal_prefix, 1);
979
980 if(p->declared)
981 return 0;
982
983 if(raptor_namespaces_start_namespace_full(rq->namespaces,
984 p->prefix,
985 raptor_uri_as_string(p->uri),
986 rq->prefix_depth))
987 return 1;
988 p->declared = 1;
989 rq->prefix_depth++;
990 return 0;
991 }
992
993
994 static int
rasqal_query_undeclare_prefix(rasqal_query * rq,rasqal_prefix * prefix)995 rasqal_query_undeclare_prefix(rasqal_query *rq, rasqal_prefix *prefix)
996 {
997 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(rq, rasqal_query, 1);
998 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(prefix, rasqal_prefix, 1);
999
1000 if(!prefix->declared) {
1001 prefix->declared = 1;
1002 return 0;
1003 }
1004
1005 raptor_namespaces_end_for_depth(rq->namespaces, prefix->depth);
1006 return 0;
1007 }
1008
1009
1010 int
rasqal_query_declare_prefixes(rasqal_query * rq)1011 rasqal_query_declare_prefixes(rasqal_query *rq)
1012 {
1013 int i;
1014
1015 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(rq, rasqal_query, 1);
1016
1017 if(!rq->prefixes)
1018 return 0;
1019
1020 for(i = 0; i< raptor_sequence_size(rq->prefixes); i++) {
1021 rasqal_prefix* p = (rasqal_prefix*)raptor_sequence_get_at(rq->prefixes, i);
1022 if(rasqal_query_declare_prefix(rq, p))
1023 return 1;
1024 }
1025
1026 return 0;
1027 }
1028
1029
1030 /**
1031 * rasqal_query_add_prefix:
1032 * @query: #rasqal_query query object
1033 * @prefix: #rasqal_prefix namespace prefix, URI
1034 *
1035 * Add a namespace prefix to the query.
1036 *
1037 * If the prefix has already been used, the old URI will be overridden.
1038 *
1039 * Return value: non-0 on failure
1040 **/
1041 int
rasqal_query_add_prefix(rasqal_query * query,rasqal_prefix * prefix)1042 rasqal_query_add_prefix(rasqal_query* query, rasqal_prefix* prefix)
1043 {
1044 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1045 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(prefix, rasqal_prefix, 1);
1046
1047 if(!query->prefixes) {
1048 query->prefixes = raptor_new_sequence((raptor_data_free_handler)rasqal_free_prefix, (raptor_data_print_handler)rasqal_prefix_print);
1049 if(!query->prefixes)
1050 return 1;
1051 } else {
1052 int i;
1053 for(i = 0; i < raptor_sequence_size(query->prefixes); i++) {
1054 rasqal_prefix* p;
1055 p = (rasqal_prefix*)raptor_sequence_get_at(query->prefixes, i);
1056
1057 if((!p->prefix && !prefix->prefix) ||
1058 ((p->prefix && prefix->prefix &&
1059 !strcmp(RASQAL_GOOD_CAST(const char*, p->prefix),
1060 RASQAL_GOOD_CAST(const char*, prefix->prefix))))
1061 ) {
1062 rasqal_query_undeclare_prefix(query, p);
1063 break;
1064 }
1065 }
1066 }
1067
1068 return raptor_sequence_push(query->prefixes, (void*)prefix);
1069 }
1070
1071
1072 /**
1073 * rasqal_query_get_prefix_sequence:
1074 * @query: #rasqal_query query object
1075 *
1076 * Get the sequence of namespace prefixes in the query.
1077 *
1078 * Return value: a #raptor_sequence of #rasqal_prefix pointers.
1079 **/
1080 raptor_sequence*
rasqal_query_get_prefix_sequence(rasqal_query * query)1081 rasqal_query_get_prefix_sequence(rasqal_query* query)
1082 {
1083 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1084
1085 return query->prefixes;
1086 }
1087
1088
1089 /**
1090 * rasqal_query_get_prefix:
1091 * @query: #rasqal_query query object
1092 * @idx: index into the sequence (0 or larger)
1093 *
1094 * Get a prefix in the sequence of namespsace prefixes in the query.
1095 *
1096 * Return value: a #rasqal_prefix pointer or NULL if out of the sequence range
1097 **/
1098 rasqal_prefix*
rasqal_query_get_prefix(rasqal_query * query,int idx)1099 rasqal_query_get_prefix(rasqal_query* query, int idx)
1100 {
1101 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1102
1103 if(!query->prefixes)
1104 return NULL;
1105
1106 return (rasqal_prefix*)raptor_sequence_get_at(query->prefixes, idx);
1107 }
1108
1109
1110 /**
1111 * rasqal_query_get_query_graph_pattern:
1112 * @query: #rasqal_query query object
1113 *
1114 * Get the top query graph pattern.
1115 *
1116 * Return value: a #rasqal_graph_pattern of the top query graph pattern
1117 **/
1118 rasqal_graph_pattern*
rasqal_query_get_query_graph_pattern(rasqal_query * query)1119 rasqal_query_get_query_graph_pattern(rasqal_query* query)
1120 {
1121 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1122
1123 return query->query_graph_pattern;
1124 }
1125
1126
1127 /**
1128 * rasqal_query_get_graph_pattern_sequence:
1129 * @query: #rasqal_query query object
1130 *
1131 * Get the sequence of graph_patterns expressions inside the top query graph pattern.
1132 *
1133 * Return value: a #raptor_sequence of #rasqal_graph_pattern pointers.
1134 **/
1135 raptor_sequence*
rasqal_query_get_graph_pattern_sequence(rasqal_query * query)1136 rasqal_query_get_graph_pattern_sequence(rasqal_query* query)
1137 {
1138 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1139
1140 return rasqal_graph_pattern_get_sub_graph_pattern_sequence(query->query_graph_pattern);
1141 }
1142
1143
1144 /**
1145 * rasqal_query_get_graph_pattern:
1146 * @query: #rasqal_query query object
1147 * @idx: index into the sequence (0 or larger)
1148 *
1149 * Get a graph_pattern in the sequence of graph_pattern expressions in the top query graph pattern.
1150 *
1151 * Return value: a #rasqal_graph_pattern pointer or NULL if out of the sequence range
1152 **/
1153 rasqal_graph_pattern*
rasqal_query_get_graph_pattern(rasqal_query * query,int idx)1154 rasqal_query_get_graph_pattern(rasqal_query* query, int idx)
1155 {
1156 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1157
1158 return rasqal_graph_pattern_get_sub_graph_pattern(query->query_graph_pattern, idx);
1159 }
1160
1161
1162 /**
1163 * rasqal_query_get_construct_triples_sequence:
1164 * @query: #rasqal_query query object
1165 *
1166 * Get the sequence of triples for a construct.
1167 *
1168 * Return value: a #raptor_sequence of #rasqal_triple pointers.
1169 **/
1170 raptor_sequence*
rasqal_query_get_construct_triples_sequence(rasqal_query * query)1171 rasqal_query_get_construct_triples_sequence(rasqal_query* query)
1172 {
1173 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1174
1175 return query->constructs;
1176 }
1177
1178
1179 /**
1180 * rasqal_query_get_construct_triple:
1181 * @query: #rasqal_query query object
1182 * @idx: index into the sequence (0 or larger)
1183 *
1184 * Get a triple in the sequence of construct triples.
1185 *
1186 * Return value: a #rasqal_triple pointer or NULL if out of the sequence range
1187 **/
1188 rasqal_triple*
rasqal_query_get_construct_triple(rasqal_query * query,int idx)1189 rasqal_query_get_construct_triple(rasqal_query* query, int idx)
1190 {
1191 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1192
1193 if(!query->constructs)
1194 return NULL;
1195
1196 return (rasqal_triple*)raptor_sequence_get_at(query->constructs, idx);
1197 }
1198
1199
1200
1201 /**
1202 * rasqal_query_prepare:
1203 * @query: the #rasqal_query object
1204 * @query_string: the query string (or NULL)
1205 * @base_uri: base URI of query string (optional)
1206 *
1207 * Prepare a query - typically parse it.
1208 *
1209 * Some query languages may require a base URI to resolve any
1210 * relative URIs in the query string. If this is not given,
1211 * the current directory in the filesystem is used as the base URI.
1212 *
1213 * The query string may be NULL in which case it is not parsed
1214 * and the query parts may be created by API calls such as
1215 * rasqal_query_add_source etc.
1216 *
1217 * Return value: non-0 on failure.
1218 **/
1219 int
rasqal_query_prepare(rasqal_query * query,const unsigned char * query_string,raptor_uri * base_uri)1220 rasqal_query_prepare(rasqal_query* query,
1221 const unsigned char *query_string,
1222 raptor_uri *base_uri)
1223 {
1224 int rc = 0;
1225
1226 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1227
1228 if(query->failed)
1229 return 1;
1230
1231 if(query->prepared)
1232 return 0;
1233 query->prepared = 1;
1234
1235 query->store_results = 0;
1236
1237 if(query_string) {
1238 /* flex lexers require two NULs at the end of the lexed buffer.
1239 * Add them here instead of parser to allow resource cleanup on error.
1240 *
1241 * flex manual:
1242 *
1243 * Function: YY_BUFFER_STATE yy_scan_buffer (char *base, yy_size_t size)
1244 * which scans in place the buffer starting at `base', consisting of
1245 * `size' bytes, the last two bytes of which _must_ be
1246 * `YY_END_OF_BUFFER_CHAR' (ASCII NUL). These last two bytes are not
1247 * scanned; thus, scanning consists of `base[0]' through
1248 * `base[size-2]', inclusive.
1249 */
1250 size_t len = strlen(RASQAL_GOOD_CAST(const char*, query_string)) + 3; /* +3 for " \0\0" */
1251 unsigned char *query_string_copy = RASQAL_MALLOC(unsigned char*, len);
1252 if(!query_string_copy) {
1253 query->failed = 1;
1254 return 1;
1255 }
1256 memcpy(query_string_copy, query_string, len - 3);
1257 query_string_copy[len - 3] = ' ';
1258 query_string_copy[len - 2] = query_string_copy[len - 1] = '\0';
1259 query->query_string = query_string_copy;
1260 query->query_string_length = len;
1261 }
1262
1263 if(base_uri)
1264 base_uri = raptor_uri_copy(base_uri);
1265 else {
1266 unsigned char *uri_string = raptor_uri_filename_to_uri_string("");
1267 base_uri = raptor_new_uri(query->world->raptor_world_ptr, uri_string);
1268 if(uri_string)
1269 raptor_free_memory(uri_string);
1270 }
1271
1272 rasqal_query_set_base_uri(query, base_uri);
1273 query->locator.line = query->locator.column = query->locator.byte = -1;
1274
1275 /* set evaluaton context with latest copies of query fields */
1276 query->eval_context->flags = query->compare_flags;
1277 rasqal_evaluation_context_set_base_uri(query->eval_context, query->base_uri);
1278
1279 /* set random seed */
1280 if(1) {
1281 unsigned int seed;
1282
1283 /* get seed either from user or system sources */
1284 if(query->user_set_rand)
1285 /* it is ok to truncate here for the purposes of getting a seed */
1286 seed = RASQAL_GOOD_CAST(unsigned int, query->features[RASQAL_GOOD_CAST(int, RASQAL_FEATURE_RAND_SEED)]);
1287 else
1288 seed = rasqal_random_get_system_seed(query->world);
1289
1290 rasqal_evaluation_context_set_rand_seed(query->eval_context, seed);
1291 }
1292
1293
1294 rc = query->factory->prepare(query);
1295 if(rc) {
1296 query->failed = 1;
1297 rc = 1;
1298 } else if(rasqal_query_prepare_common(query)) {
1299 query->failed = 1;
1300 rc = 1;
1301 }
1302
1303 return rc;
1304 }
1305
1306
1307 /**
1308 * rasqal_query_get_engine_by_name:
1309 * @name: query engine name
1310 *
1311 * INTERNAL - Get a query engine by name
1312 *
1313 * If @name is NULL or the name is unknown, the default factory is returned
1314 *
1315 * return value: pointer to factory
1316 **/
1317 const rasqal_query_execution_factory*
rasqal_query_get_engine_by_name(const char * name)1318 rasqal_query_get_engine_by_name(const char* name)
1319 {
1320 const rasqal_query_execution_factory* engine;
1321
1322 /* default */
1323 engine = &rasqal_query_engine_algebra;
1324
1325 if(name) {
1326 if(!strcmp(name, "2") || !strcmp(name, "algebra"))
1327 engine = &rasqal_query_engine_algebra;
1328 else
1329 engine = NULL;
1330 }
1331
1332 return engine;
1333 }
1334
1335
1336 /**
1337 * rasqal_query_execute_with_engine:
1338 * @query: the #rasqal_query object
1339 * @engine: execution engine factory (or NULL)
1340 *
1341 * INTERNAL - Excecute a query with a given factory and return results.
1342 *
1343 * return value: a #rasqal_query_results structure or NULL on failure.
1344 **/
1345 rasqal_query_results*
rasqal_query_execute_with_engine(rasqal_query * query,const rasqal_query_execution_factory * engine)1346 rasqal_query_execute_with_engine(rasqal_query* query,
1347 const rasqal_query_execution_factory* engine)
1348 {
1349 rasqal_query_results *query_results = NULL;
1350 rasqal_query_results_type type;
1351
1352 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1353
1354 if(query->failed)
1355 return NULL;
1356
1357 type = rasqal_query_get_result_type(query);
1358 if(type == RASQAL_QUERY_RESULTS_UNKNOWN)
1359 return NULL;
1360
1361 query_results = rasqal_new_query_results2(query->world, query, type);
1362 if(!query_results)
1363 return NULL;
1364
1365 if(!engine)
1366 engine = rasqal_query_get_engine_by_name(NULL);
1367
1368 if(rasqal_query_results_execute_with_engine(query_results, engine,
1369 query->store_results)) {
1370 rasqal_free_query_results(query_results);
1371 query_results = NULL;
1372 }
1373
1374
1375 if(query_results && rasqal_query_add_query_result(query, query_results)) {
1376 rasqal_free_query_results(query_results);
1377 query_results = NULL;
1378 }
1379
1380 return query_results;
1381 }
1382
1383
1384 /**
1385 * rasqal_query_execute:
1386 * @query: the #rasqal_query object
1387 *
1388 * Excute a query - run and return results.
1389 *
1390 * return value: a #rasqal_query_results structure or NULL on failure.
1391 **/
1392 rasqal_query_results*
rasqal_query_execute(rasqal_query * query)1393 rasqal_query_execute(rasqal_query* query)
1394 {
1395 return rasqal_query_execute_with_engine(query, NULL);
1396 }
1397
1398
1399 static const char* const rasqal_query_verb_labels[RASQAL_QUERY_VERB_LAST+1] = {
1400 "Unknown",
1401 "SELECT",
1402 "CONSTRUCT",
1403 "DESCRIBE",
1404 "ASK",
1405 "DELETE",
1406 "INSERT",
1407 "UPDATE"
1408 };
1409
1410 /* Utility methods */
1411
1412 /**
1413 * rasqal_query_verb_as_string:
1414 * @verb: the #rasqal_query_verb verb of the query
1415 *
1416 * Get a string for the query verb.
1417 *
1418 * Return value: pointer to a shared string label for the query verb
1419 **/
1420 const char*
rasqal_query_verb_as_string(rasqal_query_verb verb)1421 rasqal_query_verb_as_string(rasqal_query_verb verb)
1422 {
1423 if(verb <= RASQAL_QUERY_VERB_UNKNOWN ||
1424 verb > RASQAL_QUERY_VERB_LAST)
1425 verb = RASQAL_QUERY_VERB_UNKNOWN;
1426
1427 return rasqal_query_verb_labels[RASQAL_GOOD_CAST(int, verb)];
1428 }
1429
1430
1431 /**
1432 * rasqal_query_print:
1433 * @query: the #rasqal_query object
1434 * @fh: the FILE* handle to print to.
1435 *
1436 * Print a query in a debug format.
1437 *
1438 * Return value: non-0 on failure
1439 **/
1440 int
rasqal_query_print(rasqal_query * query,FILE * fh)1441 rasqal_query_print(rasqal_query* query, FILE *fh)
1442 {
1443 rasqal_variables_table* vars_table = query->vars_table;
1444 raptor_sequence* seq;
1445 int distinct_mode;
1446
1447 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1448 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(fh, FILE*, 1);
1449
1450 fprintf(fh, "query verb: %s\n", rasqal_query_verb_as_string(query->verb));
1451
1452 distinct_mode = rasqal_query_get_distinct(query);
1453 if(distinct_mode)
1454 fprintf(fh, "query results distinct mode: %s\n",
1455 (distinct_mode == 1 ? "distinct" : "reduced"));
1456 if(query->explain)
1457 fputs("query results explain: yes\n", fh);
1458
1459 if(query->modifier) {
1460 if(query->modifier->limit > 0)
1461 fprintf(fh, "query results limit: %d\n", query->modifier->limit);
1462 if(query->modifier->offset > 0)
1463 fprintf(fh, "query results offset: %d\n", query->modifier->offset);
1464 }
1465
1466 fputs("data graphs: ", fh);
1467 if(query->data_graphs)
1468 raptor_sequence_print(query->data_graphs, fh);
1469 seq = rasqal_variables_table_get_named_variables_sequence(vars_table);
1470 if(seq) {
1471 fputs("\nnamed variables: ", fh);
1472 raptor_sequence_print(seq, fh);
1473 }
1474 seq = rasqal_variables_table_get_anonymous_variables_sequence(vars_table);
1475 if(seq) {
1476 fputs("\nanonymous variables: ", fh);
1477 raptor_sequence_print(seq, fh);
1478 }
1479 seq = rasqal_query_get_bound_variable_sequence(query);
1480 if(seq) {
1481 int i;
1482
1483 fputs("\nprojected variable names: ", fh);
1484 for(i = 0; 1; i++) {
1485 rasqal_variable* v = (rasqal_variable*)raptor_sequence_get_at(seq, i);
1486 if(!v)
1487 break;
1488 if(i > 0)
1489 fputs(", ", fh);
1490
1491 fputs((const char*)v->name, fh);
1492 }
1493 fputc('\n', fh);
1494
1495 fputs("\nbound variables: ", fh);
1496 raptor_sequence_print(seq, fh);
1497 }
1498 if(query->describes) {
1499 fputs("\ndescribes: ", fh);
1500 raptor_sequence_print(query->describes, fh);
1501 }
1502 if(query->triples) {
1503 fputs("\ntriples: ", fh);
1504 raptor_sequence_print(query->triples, fh);
1505 }
1506 if(query->optional_triples) {
1507 fputs("\noptional triples: ", fh);
1508 raptor_sequence_print(query->optional_triples, fh);
1509 }
1510 if(query->constructs) {
1511 fputs("\nconstructs: ", fh);
1512 raptor_sequence_print(query->constructs, fh);
1513 }
1514 if(query->prefixes) {
1515 fputs("\nprefixes: ", fh);
1516 raptor_sequence_print(query->prefixes, fh);
1517 }
1518 if(query->query_graph_pattern) {
1519 fputs("\nquery graph pattern: ", fh);
1520 rasqal_graph_pattern_print(query->query_graph_pattern, fh);
1521 }
1522
1523 if(query->modifier) {
1524 if(query->modifier->order_conditions) {
1525 fputs("\nquery order conditions: ", fh);
1526 raptor_sequence_print(query->modifier->order_conditions, fh);
1527 }
1528 if(query->modifier->group_conditions) {
1529 fputs("\nquery group conditions: ", fh);
1530 raptor_sequence_print(query->modifier->group_conditions, fh);
1531 }
1532 if(query->modifier->having_conditions) {
1533 fputs("\nquery having conditions: ", fh);
1534 raptor_sequence_print(query->modifier->having_conditions, fh);
1535 }
1536 }
1537
1538 if(query->updates) {
1539 fputs("\nupdate operations: ", fh);
1540 raptor_sequence_print(query->updates, fh);
1541 }
1542 if(query->bindings) {
1543 fputs("\nbindings: ", fh);
1544 rasqal_bindings_print(query->bindings, fh);
1545 }
1546 fputc('\n', fh);
1547
1548 return 0;
1549 }
1550
1551
1552 static int
rasqal_query_add_query_result(rasqal_query * query,rasqal_query_results * query_results)1553 rasqal_query_add_query_result(rasqal_query* query,
1554 rasqal_query_results* query_results)
1555 {
1556 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1557 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, 1);
1558
1559 /* add reference to ensure query lives as long as this runs */
1560
1561 /* query->results sequence has rasqal_query_results_remove_query_reference()
1562 as the free handler which calls rasqal_free_query() decrementing
1563 query->usage */
1564
1565 query->usage++;
1566
1567 return raptor_sequence_push(query->results, query_results);
1568 }
1569
1570
1571
1572 int
rasqal_query_remove_query_result(rasqal_query * query,rasqal_query_results * query_results)1573 rasqal_query_remove_query_result(rasqal_query* query,
1574 rasqal_query_results* query_results)
1575 {
1576 int i;
1577 int size;
1578
1579 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1580 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, 1);
1581
1582 size = raptor_sequence_size(query->results);
1583 for(i = 0 ; i < size; i++) {
1584 rasqal_query_results *result;
1585 result = (rasqal_query_results*)raptor_sequence_get_at(query->results, i);
1586
1587 if(result == query_results) {
1588 raptor_sequence_set_at(query->results, i, NULL);
1589 break;
1590 }
1591 }
1592
1593 return 0;
1594 }
1595
1596
1597
1598 /**
1599 * rasqal_query_get_user_data:
1600 * @query: #rasqal_query
1601 *
1602 * Get query user data.
1603 *
1604 * Return value: user data as set by rasqal_query_set_user_data()
1605 **/
1606 void*
rasqal_query_get_user_data(rasqal_query * query)1607 rasqal_query_get_user_data(rasqal_query* query)
1608 {
1609 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1610
1611 return query->user_data;
1612 }
1613
1614
1615 /**
1616 * rasqal_query_set_user_data:
1617 * @query: #rasqal_query
1618 * @user_data: some user data to associate with the query
1619 *
1620 * Set the query user data.
1621 *
1622 **/
1623 void
rasqal_query_set_user_data(rasqal_query * query,void * user_data)1624 rasqal_query_set_user_data(rasqal_query* query, void *user_data)
1625 {
1626 RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
1627
1628 query->user_data = user_data;
1629 }
1630
1631
1632 /**
1633 * rasqal_query_get_verb:
1634 * @query: #rasqal_query
1635 *
1636 * Get the query verb.
1637 *
1638 * Return value: the operating verb of the query of type rasqal_query_verb
1639 **/
1640 rasqal_query_verb
rasqal_query_get_verb(rasqal_query * query)1641 rasqal_query_get_verb(rasqal_query* query)
1642 {
1643 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, RASQAL_QUERY_VERB_UNKNOWN);
1644
1645 return query->verb;
1646 }
1647
1648
1649 /**
1650 * rasqal_query_get_wildcard:
1651 * @query: #rasqal_query
1652 *
1653 * Get the query verb is wildcard flag.
1654 *
1655 * Return value: non-0 if the query verb was a wildcard (such as SELECT *)
1656 **/
1657 int
rasqal_query_get_wildcard(rasqal_query * query)1658 rasqal_query_get_wildcard(rasqal_query* query)
1659 {
1660 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
1661
1662 if(!query->projection)
1663 return 0;
1664
1665 return query->projection->wildcard;
1666 }
1667
1668
1669 /**
1670 * rasqal_query_set_wildcard:
1671 * @query: #rasqal_query query object
1672 * @wildcard: wildcard
1673 *
1674 * Set the query projection wildcard flag
1675 *
1676 **/
1677 void
rasqal_query_set_wildcard(rasqal_query * query,int wildcard)1678 rasqal_query_set_wildcard(rasqal_query* query, int wildcard)
1679 {
1680 RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
1681
1682 if(!query->projection) {
1683 query->projection = rasqal_new_projection(query,
1684 /* variables */ NULL,
1685 /* wildcard */ 0,
1686 /* wildcard */ 0);
1687 if(!query->projection)
1688 return;
1689 }
1690 query->projection->wildcard = wildcard ? 1 : 0;
1691 }
1692
1693
1694 /**
1695 * rasqal_query_get_order_conditions_sequence:
1696 * @query: #rasqal_query query object
1697 *
1698 * Get the sequence of query ordering conditions.
1699 *
1700 * Return value: a #raptor_sequence of #rasqal_expression pointers.
1701 **/
1702 raptor_sequence*
rasqal_query_get_order_conditions_sequence(rasqal_query * query)1703 rasqal_query_get_order_conditions_sequence(rasqal_query* query)
1704 {
1705 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1706
1707 if(query->modifier)
1708 return query->modifier->order_conditions;
1709 else
1710 return NULL;
1711 }
1712
1713
1714 /**
1715 * rasqal_query_get_order_condition:
1716 * @query: #rasqal_query query object
1717 * @idx: index into the sequence (0 or larger)
1718 *
1719 * Get a query ordering expression in the sequence of query ordering conditions.
1720 *
1721 * Return value: a #rasqal_expression pointer or NULL if out of the sequence range
1722 **/
1723 rasqal_expression*
rasqal_query_get_order_condition(rasqal_query * query,int idx)1724 rasqal_query_get_order_condition(rasqal_query* query, int idx)
1725 {
1726 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1727
1728 if(!query->modifier || !query->modifier->order_conditions)
1729 return NULL;
1730
1731 return (rasqal_expression*)raptor_sequence_get_at(query->modifier->order_conditions, idx);
1732 }
1733
1734
1735 /**
1736 * rasqal_query_get_group_conditions_sequence:
1737 * @query: #rasqal_query query object
1738 *
1739 * Get the sequence of query grouping conditions.
1740 *
1741 * Return value: a #raptor_sequence of #rasqal_expression pointers.
1742 **/
1743 raptor_sequence*
rasqal_query_get_group_conditions_sequence(rasqal_query * query)1744 rasqal_query_get_group_conditions_sequence(rasqal_query* query)
1745 {
1746 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1747
1748 if(query->modifier)
1749 return query->modifier->group_conditions;
1750 else
1751 return NULL;
1752 }
1753
1754
1755 /**
1756 * rasqal_query_get_group_condition:
1757 * @query: #rasqal_query query object
1758 * @idx: index into the sequence (0 or larger)
1759 *
1760 * Get a query grouping expression in the sequence of query grouping conditions.
1761 *
1762 * Return value: a #rasqal_expression pointer or NULL if out of the sequence range
1763 **/
1764 rasqal_expression*
rasqal_query_get_group_condition(rasqal_query * query,int idx)1765 rasqal_query_get_group_condition(rasqal_query* query, int idx)
1766 {
1767 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1768
1769 if(!query->modifier || !query->modifier->group_conditions)
1770 return NULL;
1771
1772 return (rasqal_expression*)raptor_sequence_get_at(query->modifier->group_conditions, idx);
1773 }
1774
1775
1776 /**
1777 * rasqal_query_get_having_conditions_sequence:
1778 * @query: #rasqal_query query object
1779 *
1780 * Get the sequence of query having conditions.
1781 *
1782 * Return value: a #raptor_sequence of #rasqal_expression pointers.
1783 **/
1784 raptor_sequence*
rasqal_query_get_having_conditions_sequence(rasqal_query * query)1785 rasqal_query_get_having_conditions_sequence(rasqal_query* query)
1786 {
1787 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1788
1789 if(query->modifier)
1790 return query->modifier->having_conditions;
1791 else
1792 return NULL;
1793 }
1794
1795
1796 /**
1797 * rasqal_query_get_having_condition:
1798 * @query: #rasqal_query query object
1799 * @idx: index into the sequence (0 or larger)
1800 *
1801 * Get a query having expression in the sequence of query havinging conditions.
1802 *
1803 * Return value: a #rasqal_expression pointer or NULL if out of the sequence range
1804 **/
1805 rasqal_expression*
rasqal_query_get_having_condition(rasqal_query * query,int idx)1806 rasqal_query_get_having_condition(rasqal_query* query, int idx)
1807 {
1808 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1809
1810 if(!query->modifier || !query->modifier->having_conditions)
1811 return NULL;
1812
1813 return (rasqal_expression*)raptor_sequence_get_at(query->modifier->having_conditions, idx);
1814 }
1815
1816
1817 /**
1818 * rasqal_query_graph_pattern_visit2:
1819 * @query: query
1820 * @visit_fn: user function to operate on
1821 * @data: user data to pass to function
1822 *
1823 * Visit all graph patterns in a query with a user function @visit_fn.
1824 *
1825 * See also rasqal_graph_pattern_visit().
1826 *
1827 * Return value: result from visit function @visit_fn if it returns non-0
1828 **/
1829 int
rasqal_query_graph_pattern_visit2(rasqal_query * query,rasqal_graph_pattern_visit_fn visit_fn,void * data)1830 rasqal_query_graph_pattern_visit2(rasqal_query* query,
1831 rasqal_graph_pattern_visit_fn visit_fn,
1832 void* data)
1833 {
1834 rasqal_graph_pattern* gp;
1835
1836 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1837
1838 gp = rasqal_query_get_query_graph_pattern(query);
1839 if(!gp)
1840 return 1;
1841
1842 return rasqal_graph_pattern_visit(query, gp, visit_fn, data);
1843 }
1844
1845
1846 #ifndef RASQAL_DISABLE_DEPRECATED
1847 /**
1848 * rasqal_query_graph_pattern_visit:
1849 * @query: query
1850 * @visit_fn: user function to operate on
1851 * @data: user data to pass to function
1852 *
1853 * Visit all graph patterns in a query with a user function @visit_fn.
1854 *
1855 * @Deprecated: use rasqal_query_graph_pattern_visit2() that returns the @visit_fn status code.
1856 *
1857 * See also rasqal_graph_pattern_visit().
1858 **/
1859 void
rasqal_query_graph_pattern_visit(rasqal_query * query,rasqal_graph_pattern_visit_fn visit_fn,void * data)1860 rasqal_query_graph_pattern_visit(rasqal_query* query,
1861 rasqal_graph_pattern_visit_fn visit_fn,
1862 void* data)
1863 {
1864 (void)rasqal_query_graph_pattern_visit2(query, visit_fn, data);
1865 }
1866 #endif
1867
1868
1869 /**
1870 * rasqal_query_write:
1871 * @iostr: #raptor_iostream to write the query to
1872 * @query: #rasqal_query pointer.
1873 * @format_uri: #raptor_uri describing the format to write (or NULL for default)
1874 * @base_uri: #raptor_uri base URI of the output format
1875 *
1876 * Write a query to an iostream in a specified format.
1877 *
1878 * The supported URIs for the format_uri are:
1879 *
1880 * Default: SPARQL Query Language 2006-04-06
1881 * http://www.w3.org/TR/2006/CR-rdf-sparql-query-20060406/
1882 *
1883 * Return value: non-0 on failure
1884 **/
1885 int
rasqal_query_write(raptor_iostream * iostr,rasqal_query * query,raptor_uri * format_uri,raptor_uri * base_uri)1886 rasqal_query_write(raptor_iostream* iostr, rasqal_query* query,
1887 raptor_uri* format_uri, raptor_uri* base_uri)
1888 {
1889 const char *format_uri_str = NULL;
1890
1891 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(iostr, raptor_iostream, 1);
1892 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1893
1894 if(format_uri)
1895 format_uri_str = RASQAL_GOOD_CAST(const char*, raptor_uri_as_string(format_uri));
1896
1897 if(!format_uri ||
1898 !strcmp(format_uri_str,
1899 "http://www.w3.org/TR/rdf-sparql-query/") ||
1900 !strcmp(format_uri_str,
1901 "http://www.w3.org/TR/2006/WD-rdf-sparql-query-20060220/") ||
1902 !strcmp(format_uri_str,
1903 "http://www.w3.org/TR/2006/CR-rdf-sparql-query-20060406/"))
1904 return rasqal_query_write_sparql_20060406(iostr, query, base_uri);
1905
1906 return 1;
1907 }
1908
1909
1910 /**
1911 * rasqal_query_iostream_write_escaped_counted_string:
1912 * @query: #rasqal_query object
1913 * @iostr: #raptor_iostream to write the escaped string to
1914 * @string: string to escape
1915 * @len: Length of string to escape
1916 *
1917 * Write a string to an iostream in escaped form suitable for the query string.
1918 *
1919 * Return value: non-0 on failure
1920 **/
1921 int
rasqal_query_iostream_write_escaped_counted_string(rasqal_query * query,raptor_iostream * iostr,const unsigned char * string,size_t len)1922 rasqal_query_iostream_write_escaped_counted_string(rasqal_query* query,
1923 raptor_iostream* iostr,
1924 const unsigned char* string,
1925 size_t len)
1926 {
1927 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
1928 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(iostr, raptor_iostream, 1);
1929 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(string, char*, 1);
1930
1931 if(query->factory->iostream_write_escaped_counted_string)
1932 return query->factory->iostream_write_escaped_counted_string(query, iostr,
1933 string, len);
1934 else
1935 return 1;
1936 }
1937
1938
1939 /**
1940 * rasqal_query_escape_counted_string:
1941 * @query: #rasqal_query object
1942 * @string: string to escape
1943 * @len: Length of string to escape
1944 * @output_len_p: Pointer to store length of output string (or NULL)
1945 *
1946 * Convert a string into an escaped form suitable for the query string.
1947 *
1948 * The returned string must be freed by the caller with
1949 * rasqal_free_memory()
1950 *
1951 * Return value: the escaped string or NULL on failure.
1952 **/
1953 unsigned char*
rasqal_query_escape_counted_string(rasqal_query * query,const unsigned char * string,size_t len,size_t * output_len_p)1954 rasqal_query_escape_counted_string(rasqal_query* query,
1955 const unsigned char* string,
1956 size_t len,
1957 size_t* output_len_p)
1958 {
1959 raptor_iostream* iostr;
1960 void* output_string = NULL;
1961 int rc;
1962
1963 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
1964 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(string, char*, NULL);
1965
1966 iostr = raptor_new_iostream_to_string(query->world->raptor_world_ptr,
1967 &output_string, output_len_p,
1968 rasqal_alloc_memory);
1969 if(!iostr)
1970 return NULL;
1971 rc = rasqal_query_iostream_write_escaped_counted_string(query, iostr,
1972 string, len);
1973 raptor_free_iostream(iostr);
1974 if(rc && output_string) {
1975 rasqal_free_memory(output_string);
1976 output_string = NULL;
1977 }
1978
1979 return (unsigned char *)output_string;
1980 }
1981
1982
1983 void
rasqal_query_set_base_uri(rasqal_query * query,raptor_uri * base_uri)1984 rasqal_query_set_base_uri(rasqal_query* query, raptor_uri* base_uri)
1985 {
1986 RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
1987 RASQAL_ASSERT_OBJECT_POINTER_RETURN(base_uri, raptor_uri);
1988
1989 if(query->base_uri)
1990 raptor_free_uri(query->base_uri);
1991 query->base_uri = base_uri;
1992 query->locator.uri = base_uri;
1993 }
1994
1995
1996 /**
1997 * rasqal_query_set_store_results:
1998 * @query: the #rasqal_query object
1999 * @store_results: store results flag
2000 *
2001 * Request that query results are stored during execution
2002 *
2003 * When called after a rasqal_query_prepare(), this tells
2004 * rasqal_query_execute() to execute the entire query immediately
2005 * rather than generate them lazily, and store all the results in
2006 * memory. The results will then be available for reading multiple
2007 * times using rasqal_query_results_rewind() to move back to the
2008 * start of the result object. If called after preparation, returns
2009 * failure.
2010 *
2011 * Return value: non-0 on failure.
2012 **/
2013 int
rasqal_query_set_store_results(rasqal_query * query,int store_results)2014 rasqal_query_set_store_results(rasqal_query* query, int store_results)
2015 {
2016 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
2017
2018 if(!query->prepared)
2019 return 1;
2020
2021 query->store_results = store_results;
2022
2023 return 0;
2024 }
2025
2026
2027 rasqal_variable*
rasqal_query_get_variable_by_offset(rasqal_query * query,int idx)2028 rasqal_query_get_variable_by_offset(rasqal_query* query, int idx)
2029 {
2030 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2031
2032 return rasqal_variables_table_get(query->vars_table, idx);
2033 }
2034
2035
2036 /*
2037 * rasqal_query_add_update_operation:
2038 * @query: #rasqal_query query object
2039 * @update: #rasqal_update_operation to add
2040 *
2041 * Add a update operation to the query.
2042 *
2043 * INTERNAL - The @update object becomes owned by the query.
2044 *
2045 * Return value: non-0 on failure
2046 **/
2047 int
rasqal_query_add_update_operation(rasqal_query * query,rasqal_update_operation * update)2048 rasqal_query_add_update_operation(rasqal_query* query,
2049 rasqal_update_operation *update)
2050 {
2051 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
2052
2053 if(!update)
2054 return 1;
2055
2056 if(!query->updates) {
2057 query->updates = raptor_new_sequence((raptor_data_free_handler)rasqal_free_update_operation, (raptor_data_print_handler)rasqal_update_operation_print);
2058 if(!query->updates) {
2059 rasqal_free_update_operation(update);
2060 return 1;
2061 }
2062 }
2063
2064 if(raptor_sequence_push(query->updates, (void*)update))
2065 return 1;
2066 return 0;
2067 }
2068
2069
2070 /**
2071 * rasqal_query_get_update_operations_sequence:
2072 * @query: #rasqal_query query object
2073 *
2074 * Get the sequence of update operations
2075 *
2076 * Return value: a #raptor_sequence of #rasqal_update_operation pointers.
2077 **/
2078 raptor_sequence*
rasqal_query_get_update_operations_sequence(rasqal_query * query)2079 rasqal_query_get_update_operations_sequence(rasqal_query* query)
2080 {
2081 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2082
2083 return query->updates;
2084 }
2085
2086
2087 /**
2088 * rasqal_query_get_update_operation:
2089 * @query: #rasqal_query query object
2090 * @idx: index into the sequence (0 or larger)
2091 *
2092 * Get a query update operation in the sequence of update operations
2093 *
2094 * Return value: a #rasqal_update_operation pointer or NULL if out of the sequence range
2095 **/
2096 rasqal_update_operation*
rasqal_query_get_update_operation(rasqal_query * query,int idx)2097 rasqal_query_get_update_operation(rasqal_query* query, int idx)
2098 {
2099 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2100
2101 if(!query->updates)
2102 return NULL;
2103
2104 return (rasqal_update_operation*)raptor_sequence_get_at(query->updates, idx);
2105 }
2106
2107
2108 /*
2109 * rasqal_query_generate_bnodeid - Default generate id - internal
2110 */
2111 unsigned char*
rasqal_query_generate_bnodeid(rasqal_query * rdf_query,unsigned char * user_bnodeid)2112 rasqal_query_generate_bnodeid(rasqal_query* rdf_query,
2113 unsigned char *user_bnodeid)
2114 {
2115 /* prefer world generate handler/data */
2116 if(rdf_query->world->generate_bnodeid_handler)
2117 return rasqal_world_generate_bnodeid(rdf_query->world, user_bnodeid);
2118
2119 return rasqal_world_default_generate_bnodeid_handler(rdf_query->world,
2120 user_bnodeid);
2121 }
2122
2123
2124 /**
2125 * rasqal_query_get_bindings_variables_sequence:
2126 * @query: #rasqal_query query object
2127 *
2128 * Get the sequence of BINDINGS block variables
2129 *
2130 * Return value: a #raptor_sequence of #raptor_variable pointers
2131 **/
2132 raptor_sequence*
rasqal_query_get_bindings_variables_sequence(rasqal_query * query)2133 rasqal_query_get_bindings_variables_sequence(rasqal_query* query)
2134 {
2135 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2136
2137 if(query->bindings)
2138 return query->bindings->variables;
2139 else
2140 return NULL;
2141
2142 }
2143
2144
2145 /**
2146 * rasqal_query_get_bindings_variable:
2147 * @query: #rasqal_query query object
2148 * @idx: index into the sequence (0 or larger)
2149 *
2150 * Get a rasqal_variable* in the sequence of BINDINGS block variables
2151 *
2152 * Return value: a #raptor_sequence of #raptor_variable pointers
2153 **/
2154 rasqal_variable*
rasqal_query_get_bindings_variable(rasqal_query * query,int idx)2155 rasqal_query_get_bindings_variable(rasqal_query* query, int idx)
2156 {
2157 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2158
2159 if(!query->bindings || !query->bindings->variables)
2160 return NULL;
2161
2162 return (rasqal_variable*)raptor_sequence_get_at(query->bindings->variables, idx);
2163 }
2164
2165
2166 /**
2167 * rasqal_query_get_bindings_rows_sequence:
2168 * @query: #rasqal_query query object
2169 *
2170 * Get the sequence of BINDINGS block result rows
2171 *
2172 * Return value: a #raptor_sequence of #raptor_row pointers
2173 **/
2174 raptor_sequence*
rasqal_query_get_bindings_rows_sequence(rasqal_query * query)2175 rasqal_query_get_bindings_rows_sequence(rasqal_query* query)
2176 {
2177 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2178
2179 if(query->bindings)
2180 return query->bindings->rows;
2181 else
2182 return NULL;
2183
2184 }
2185
2186
2187 /**
2188 * rasqal_query_get_bindings_row:
2189 * @query: #rasqal_query query object
2190 * @idx: index into the sequence (0 or larger)
2191 *
2192 * Get a rasqal_row* in the sequence of BINDINGS block result rows
2193 *
2194 * Return value: a #raptor_sequence of #raptor_row pointers
2195 **/
2196 rasqal_row*
rasqal_query_get_bindings_row(rasqal_query * query,int idx)2197 rasqal_query_get_bindings_row(rasqal_query* query, int idx)
2198 {
2199 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2200
2201 if(!query->bindings || !query->bindings->rows)
2202 return NULL;
2203
2204 return (rasqal_row*)raptor_sequence_get_at(query->bindings->rows, idx);
2205 }
2206
2207
2208 /*
2209 * rasqal_query_variable_bound_in_triple:
2210 * @query: #rasqal_query query object
2211 * @variable: variable
2212 * @column: triple column
2213 *
2214 * INTERNAL - Test if variable is bound in given triple
2215 *
2216 * Return value: part of triple the variable is bound in
2217 */
2218 rasqal_triple_parts
rasqal_query_variable_bound_in_triple(rasqal_query * query,rasqal_variable * v,int column)2219 rasqal_query_variable_bound_in_triple(rasqal_query* query,
2220 rasqal_variable* v,
2221 int column)
2222 {
2223 int width;
2224 unsigned short *triple_row;
2225
2226 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, (rasqal_triple_parts)0);
2227
2228 width = rasqal_variables_table_get_total_variables_count(query->vars_table);
2229 triple_row = &query->triples_use_map[column * width];
2230
2231 return (rasqal_triple_parts)((triple_row[v->offset] & RASQAL_TRIPLES_BOUND_MASK) >> 4);
2232 }
2233
2234
2235 /**
2236 * rasqal_query_get_result_type:
2237 * @query: #rasqal_query query object
2238 *
2239 * Get the result type expected from executing the query.
2240 *
2241 * This function is only valid after rasqal_query_prepare() has been
2242 * run on the query and will return #RASQAL_QUERY_RESULTS_UNKNOWN if
2243 * called before preparation.
2244 *
2245 * Return value: result type or #RASQAL_QUERY_RESULTS_UNKNOWN if not known or on error
2246 **/
2247 rasqal_query_results_type
rasqal_query_get_result_type(rasqal_query * query)2248 rasqal_query_get_result_type(rasqal_query* query)
2249 {
2250 rasqal_query_results_type type = RASQAL_QUERY_RESULTS_BINDINGS;
2251
2252 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, RASQAL_QUERY_RESULTS_UNKNOWN);
2253
2254 if(!query->prepared)
2255 return RASQAL_QUERY_RESULTS_UNKNOWN;
2256
2257 if(query->query_results_formatter_name)
2258 type = RASQAL_QUERY_RESULTS_SYNTAX;
2259 else
2260 switch(query->verb) {
2261 case RASQAL_QUERY_VERB_SELECT:
2262 type = RASQAL_QUERY_RESULTS_BINDINGS;
2263 break;
2264
2265 case RASQAL_QUERY_VERB_ASK:
2266 type = RASQAL_QUERY_RESULTS_BOOLEAN;
2267 break;
2268
2269 case RASQAL_QUERY_VERB_CONSTRUCT:
2270 case RASQAL_QUERY_VERB_DESCRIBE:
2271 type = RASQAL_QUERY_RESULTS_GRAPH;
2272 break;
2273
2274 case RASQAL_QUERY_VERB_UNKNOWN:
2275 case RASQAL_QUERY_VERB_DELETE:
2276 case RASQAL_QUERY_VERB_INSERT:
2277 case RASQAL_QUERY_VERB_UPDATE:
2278 default:
2279 type = RASQAL_QUERY_RESULTS_UNKNOWN;
2280 }
2281
2282 return type;
2283 }
2284
2285
2286 /*
2287 * rasqal_query_store_select_query:
2288 * @query: query
2289 * @gp: SELECT graph pattern
2290 *
2291 * INTERNAL - store a select query
2292 *
2293 * The query object owns the @projection, @data_graphs, @where_gp and
2294 * the @modifier after this call.
2295 *
2296 * Return value: non-0 on failure
2297 */
2298 int
rasqal_query_store_select_query(rasqal_query * query,rasqal_projection * projection,raptor_sequence * data_graphs,rasqal_graph_pattern * where_gp,rasqal_solution_modifier * modifier)2299 rasqal_query_store_select_query(rasqal_query* query,
2300 rasqal_projection* projection,
2301 raptor_sequence* data_graphs,
2302 rasqal_graph_pattern* where_gp,
2303 rasqal_solution_modifier* modifier)
2304 {
2305 if(!projection || !where_gp || !modifier)
2306 return 1;
2307
2308 query->verb = RASQAL_QUERY_VERB_SELECT;
2309
2310 rasqal_query_set_projection(query, projection);
2311
2312 query->query_graph_pattern = where_gp;
2313
2314 if(data_graphs)
2315 rasqal_query_add_data_graphs(query, data_graphs);
2316
2317 rasqal_query_set_modifier(query, modifier);
2318
2319 return 0;
2320 }
2321
2322
2323 int
rasqal_query_reset_select_query(rasqal_query * query)2324 rasqal_query_reset_select_query(rasqal_query* query)
2325 {
2326 rasqal_query_set_projection(query, NULL);
2327 rasqal_query_set_modifier(query, NULL);
2328
2329 if(query->data_graphs) {
2330 while(1) {
2331 rasqal_data_graph* dg;
2332 dg = (rasqal_data_graph*)raptor_sequence_pop(query->data_graphs);
2333 if(!dg)
2334 break;
2335 rasqal_free_data_graph(dg);
2336 }
2337 }
2338
2339 return 0;
2340 }
2341
2342
2343 /*
2344 * rasqal_query_get_projection:
2345 * @query: #rasqal_query
2346 *
2347 * INTERNAL - Get the query variable projection
2348 *
2349 * This may be NULL if the query does not project any variables such
2350 * as for CONSTRUCT or ASK queries.
2351 *
2352 * Return value: projection or NULL.
2353 **/
2354 rasqal_projection*
rasqal_query_get_projection(rasqal_query * query)2355 rasqal_query_get_projection(rasqal_query* query)
2356 {
2357 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
2358
2359 return query->projection;
2360 }
2361
2362
2363 /*
2364 * rasqal_query_set_projection:
2365 * @query: #rasqal_query
2366 * @projection: variable projection and flags
2367 *
2368 * INTERNAL - Set the query projection
2369 *
2370 * Return value: non-0 on failure
2371 **/
2372 int
rasqal_query_set_projection(rasqal_query * query,rasqal_projection * projection)2373 rasqal_query_set_projection(rasqal_query* query, rasqal_projection* projection)
2374 {
2375 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
2376
2377 if(query->projection)
2378 rasqal_free_projection(query->projection);
2379
2380 query->projection = projection;
2381
2382 return 0;
2383 }
2384
2385
2386 /*
2387 * rasqal_query_set_modifier:
2388 * @query: #rasqal_query
2389 * @modifier: variable modifier and flags
2390 *
2391 * INTERNAL - Set the query modifier
2392 *
2393 * Return value: non-0 on failure
2394 **/
2395 int
rasqal_query_set_modifier(rasqal_query * query,rasqal_solution_modifier * modifier)2396 rasqal_query_set_modifier(rasqal_query* query,
2397 rasqal_solution_modifier* modifier)
2398 {
2399 RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
2400
2401 if(query->modifier)
2402 rasqal_free_solution_modifier(query->modifier);
2403
2404 query->modifier = modifier;
2405
2406 return 0;
2407 }
2408