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