PageRenderTime 64ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/rasqal-0.9.29/src/rasqal_query.c

#
C | 2440 lines | 1165 code | 422 blank | 853 comment | 177 complexity | f39bee3bcf21d3a6314ac9b91193b1c8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  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. #ifdef HAVE_CONFIG_H
  25. #include <rasqal_config.h>
  26. #endif
  27. #ifdef WIN32
  28. #include <win32_rasqal_config.h>
  29. #endif
  30. #include <stdio.h>
  31. #include <string.h>
  32. #ifdef HAVE_STDLIB_H
  33. #include <stdlib.h>
  34. #endif
  35. #ifdef HAVE_STDINT_H
  36. #include <stdint.h>
  37. #endif
  38. #ifdef HAVE_UNISTD_H
  39. #include <unistd.h>
  40. #endif
  41. #include <stdarg.h>
  42. #include "rasqal.h"
  43. #include "rasqal_internal.h"
  44. /*
  45. *
  46. * Query Class Internals
  47. *
  48. * This is the main Rasqal class for constructing RDF graph queries
  49. * from a syntax or by API, preparing them for execution with a query
  50. * execution and executing them to return a result set.
  51. *
  52. * Queries are constructed from a syntax in some query language
  53. * syntax and build an RDF query API structure based on triple
  54. * patterns, filter expressions, graph patterns above them operating
  55. * over a set of graphs.
  56. *
  57. * This class does not deal with manipulating result sets which are
  58. * handled by the #rasqal_query_results and methods on it although
  59. * rasqal_query_execute() does return a newly constructed result
  60. * object.
  61. *
  62. * It also does not deal with executing a query which is handled by
  63. * #rasqal_query_execution_factory instances that have their own
  64. * simpler API.
  65. *
  66. */
  67. #define DEBUG_FH stderr
  68. static int rasqal_query_add_query_result(rasqal_query* query, rasqal_query_results* query_results);
  69. /**
  70. * rasqal_new_query:
  71. * @world: rasqal_world object
  72. * @name: the query language name (or NULL)
  73. * @uri: #raptor_uri language uri (or NULL)
  74. *
  75. * Constructor - create a new rasqal_query object.
  76. *
  77. * A query language can be named or identified by a URI, either
  78. * of which is optional. The default query language will be used
  79. * if both are NULL. rasqal_world_get_query_language_description returns
  80. * the description of the known names, labels, MIME types and URIs.
  81. *
  82. * Return value: a new #rasqal_query object or NULL on failure
  83. */
  84. rasqal_query*
  85. rasqal_new_query(rasqal_world *world, const char *name,
  86. const unsigned char *uri)
  87. {
  88. rasqal_query_language_factory* factory;
  89. rasqal_query* query;
  90. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, rasqal_world, NULL);
  91. /* for compatibility with older binaries that do not call it */
  92. rasqal_world_open(world);
  93. factory = rasqal_get_query_language_factory(world, name, uri);
  94. if(!factory)
  95. return NULL;
  96. query = RASQAL_CALLOC(rasqal_query*, 1, sizeof(*query));
  97. if(!query)
  98. return NULL;
  99. /* set usage first to 1 so we can clean up with rasqal_free_query() on error */
  100. query->usage = 1;
  101. query->world = world;
  102. query->factory = factory;
  103. query->genid_counter = 1;
  104. query->context = RASQAL_CALLOC(void*, 1, factory->context_length);
  105. if(!query->context)
  106. goto tidy;
  107. query->namespaces = raptor_new_namespaces(world->raptor_world_ptr, 0);
  108. if(!query->namespaces)
  109. goto tidy;
  110. query->vars_table = rasqal_new_variables_table(query->world);
  111. if(!query->vars_table)
  112. goto tidy;
  113. query->triples = raptor_new_sequence((raptor_data_free_handler)rasqal_free_triple, (raptor_data_print_handler)rasqal_triple_print);
  114. if(!query->triples)
  115. goto tidy;
  116. query->prefixes = raptor_new_sequence((raptor_data_free_handler)rasqal_free_prefix, (raptor_data_print_handler)rasqal_prefix_print);
  117. if(!query->prefixes)
  118. goto tidy;
  119. query->data_graphs = raptor_new_sequence((raptor_data_free_handler)rasqal_free_data_graph, (raptor_data_print_handler)rasqal_data_graph_print);
  120. if(!query->data_graphs)
  121. goto tidy;
  122. query->results = raptor_new_sequence((raptor_data_free_handler)rasqal_query_results_remove_query_reference, NULL);
  123. if(!query->results)
  124. goto tidy;
  125. query->eval_context = rasqal_new_evaluation_context(query->world,
  126. &query->locator,
  127. query->compare_flags);
  128. if(!query->eval_context)
  129. goto tidy;
  130. if(factory->init(query, name))
  131. goto tidy;
  132. return query;
  133. tidy:
  134. rasqal_free_query(query);
  135. return NULL;
  136. }
  137. /**
  138. * rasqal_free_query:
  139. * @query: #rasqal_query object
  140. *
  141. * Destructor - destroy a #rasqal_query object.
  142. **/
  143. void
  144. rasqal_free_query(rasqal_query* query)
  145. {
  146. if(!query)
  147. return;
  148. if(--query->usage)
  149. return;
  150. if(query->factory)
  151. query->factory->terminate(query);
  152. if(query->eval_context)
  153. rasqal_free_evaluation_context(query->eval_context);
  154. if(query->context)
  155. RASQAL_FREE(rasqal_query_context, query->context);
  156. if(query->namespaces)
  157. raptor_free_namespaces(query->namespaces);
  158. if(query->base_uri)
  159. raptor_free_uri(query->base_uri);
  160. if(query->query_string)
  161. RASQAL_FREE(char*, query->query_string);
  162. if(query->data_graphs)
  163. raptor_free_sequence(query->data_graphs);
  164. if(query->describes)
  165. raptor_free_sequence(query->describes);
  166. if(query->triples)
  167. raptor_free_sequence(query->triples);
  168. if(query->optional_triples)
  169. raptor_free_sequence(query->optional_triples);
  170. if(query->constructs)
  171. raptor_free_sequence(query->constructs);
  172. if(query->prefixes)
  173. raptor_free_sequence(query->prefixes);
  174. if(query->results)
  175. raptor_free_sequence(query->results);
  176. if(query->triples_use_map)
  177. RASQAL_FREE(shortarray, query->triples_use_map);
  178. if(query->variables_use_map)
  179. RASQAL_FREE(shortarray, query->variables_use_map);
  180. if(query->query_graph_pattern)
  181. rasqal_free_graph_pattern(query->query_graph_pattern);
  182. if(query->graph_patterns_sequence)
  183. raptor_free_sequence(query->graph_patterns_sequence);
  184. if(query->query_results_formatter_name)
  185. RASQAL_FREE(char*, query->query_results_formatter_name);
  186. /* Do this last since most everything above could refer to a variable */
  187. if(query->vars_table)
  188. rasqal_free_variables_table(query->vars_table);
  189. if(query->updates)
  190. raptor_free_sequence(query->updates);
  191. if(query->modifier)
  192. rasqal_free_solution_modifier(query->modifier);
  193. if(query->bindings)
  194. rasqal_free_bindings(query->bindings);
  195. if(query->projection)
  196. rasqal_free_projection(query->projection);
  197. RASQAL_FREE(rasqal_query, query);
  198. }
  199. /* Methods */
  200. /**
  201. * rasqal_query_get_name:
  202. * @query: #rasqal_query query object
  203. *
  204. * Get a short name for the query language.
  205. *
  206. * Return value: shared string label value
  207. **/
  208. const char*
  209. rasqal_query_get_name(rasqal_query* query)
  210. {
  211. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  212. return query->factory->desc.names[0];
  213. }
  214. /**
  215. * rasqal_query_get_label:
  216. * @query: #rasqal_query query object
  217. *
  218. * Get a readable label for the query language.
  219. *
  220. * Return value: shared string label value
  221. **/
  222. const char*
  223. rasqal_query_get_label(rasqal_query* query)
  224. {
  225. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  226. return query->factory->desc.label;
  227. }
  228. /**
  229. * rasqal_query_set_feature:
  230. * @query: #rasqal_query query object
  231. * @feature: feature to set from enumerated #rasqal_feature values
  232. * @value: integer feature value
  233. *
  234. * Set various query features.
  235. *
  236. * The allowed features are available via rasqal_features_enumerate().
  237. *
  238. * Return value: non 0 on failure or if the feature is unknown
  239. **/
  240. int
  241. rasqal_query_set_feature(rasqal_query* query, rasqal_feature feature, int value)
  242. {
  243. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  244. switch(feature) {
  245. case RASQAL_FEATURE_NO_NET:
  246. case RASQAL_FEATURE_RAND_SEED:
  247. if(feature == RASQAL_FEATURE_RAND_SEED)
  248. query->user_set_rand = 1;
  249. query->features[RASQAL_GOOD_CAST(int, feature)] = value;
  250. break;
  251. default:
  252. break;
  253. }
  254. return 0;
  255. }
  256. /**
  257. * rasqal_query_set_feature_string:
  258. * @query: #rasqal_query query object
  259. * @feature: feature to set from enumerated #rasqal_feature values
  260. * @value: feature value
  261. *
  262. * Set query features with string values.
  263. *
  264. * The allowed features are available via rasqal_features_enumerate().
  265. * If the feature type is integer, the value is interpreted as an integer.
  266. *
  267. * Return value: non 0 on failure or if the feature is unknown
  268. **/
  269. int
  270. rasqal_query_set_feature_string(rasqal_query *query,
  271. rasqal_feature feature,
  272. const unsigned char *value)
  273. {
  274. int value_is_string = (rasqal_feature_value_type(feature) == 1);
  275. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  276. if(!value_is_string)
  277. return rasqal_query_set_feature(query, feature,
  278. atoi(RASQAL_GOOD_CAST(const char*, value)));
  279. return -1;
  280. }
  281. /**
  282. * rasqal_query_get_feature:
  283. * @query: #rasqal_query query object
  284. * @feature: feature to get value
  285. *
  286. * Get various query features.
  287. *
  288. * The allowed features are available via rasqal_features_enumerate().
  289. *
  290. * Note: no feature value is negative
  291. *
  292. * Return value: feature value or < 0 for an illegal feature
  293. **/
  294. int
  295. rasqal_query_get_feature(rasqal_query *query, rasqal_feature feature)
  296. {
  297. int result= -1;
  298. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  299. switch(feature) {
  300. case RASQAL_FEATURE_NO_NET:
  301. case RASQAL_FEATURE_RAND_SEED:
  302. result = (query->features[RASQAL_GOOD_CAST(int, feature)] != 0);
  303. break;
  304. default:
  305. break;
  306. }
  307. return result;
  308. }
  309. /**
  310. * rasqal_query_get_feature_string:
  311. * @query: #rasqal_query query object
  312. * @feature: feature to get value
  313. *
  314. * Get query features with string values.
  315. *
  316. * The allowed features are available via rasqal_features_enumerate().
  317. * If a string is returned, it must be freed by the caller.
  318. *
  319. * Return value: feature value or NULL for an illegal feature or no value
  320. **/
  321. const unsigned char *
  322. rasqal_query_get_feature_string(rasqal_query *query,
  323. rasqal_feature feature)
  324. {
  325. int value_is_string = (rasqal_feature_value_type(feature) == 1);
  326. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  327. if(!value_is_string)
  328. return NULL;
  329. return NULL;
  330. }
  331. /**
  332. * rasqal_query_get_distinct:
  333. * @query: #rasqal_query query object
  334. *
  335. * Get the query distinct mode
  336. *
  337. * See rasqal_query_set_distinct() for the distinct modes.
  338. *
  339. * Return value: non-0 if the results should be distinct
  340. **/
  341. int
  342. rasqal_query_get_distinct(rasqal_query* query)
  343. {
  344. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
  345. if(!query->projection)
  346. return 0;
  347. return query->projection->distinct;
  348. }
  349. /**
  350. * rasqal_query_set_distinct:
  351. * @query: #rasqal_query query object
  352. * @distinct_mode: distinct mode
  353. *
  354. * Set the query distinct results mode.
  355. *
  356. * The allowed @distinct_mode values are:
  357. * 0 if not given
  358. * 1 if DISTINCT: ensure solutions are unique
  359. * 2 if SPARQL REDUCED: permit elimination of some non-unique solutions
  360. *
  361. **/
  362. void
  363. rasqal_query_set_distinct(rasqal_query* query, int distinct_mode)
  364. {
  365. RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
  366. if(distinct_mode < 0 || distinct_mode > 2)
  367. distinct_mode = 0;
  368. if(!query->projection) {
  369. query->projection = rasqal_new_projection(query,
  370. /* variables */ NULL,
  371. /* wildcard */ 0,
  372. /* distinct */ 0);
  373. if(!query->projection)
  374. return;
  375. }
  376. query->projection->distinct = distinct_mode;
  377. }
  378. /**
  379. * rasqal_query_get_explain:
  380. * @query: #rasqal_query query object
  381. *
  382. * Get the query explain results flag.
  383. *
  384. * Return value: non-0 if the results should be explain
  385. **/
  386. int
  387. rasqal_query_get_explain(rasqal_query* query)
  388. {
  389. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
  390. return query->explain;
  391. }
  392. /**
  393. * rasqal_query_set_explain:
  394. * @query: #rasqal_query query object
  395. * @is_explain: non-0 if explain
  396. *
  397. * Set the query explain results flag.
  398. *
  399. **/
  400. void
  401. rasqal_query_set_explain(rasqal_query* query, int is_explain)
  402. {
  403. RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
  404. query->explain = (is_explain != 0) ? 1 : 0;
  405. }
  406. /**
  407. * rasqal_query_get_limit:
  408. * @query: #rasqal_query query object
  409. *
  410. * Get the query-specified limit on results.
  411. *
  412. * This is the limit given in the query on the number of results allowed.
  413. *
  414. * Return value: integer >=0 if a limit is given, otherwise <0
  415. **/
  416. int
  417. rasqal_query_get_limit(rasqal_query* query)
  418. {
  419. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
  420. if(query->modifier)
  421. return query->modifier->limit;
  422. else
  423. return -1;
  424. }
  425. /**
  426. * rasqal_query_set_limit:
  427. * @query: #rasqal_query query object
  428. * @limit: the limit on results, >=0 to set a limit, <0 to have no limit
  429. *
  430. * Set the query-specified limit on results.
  431. *
  432. * This is the limit given in the query on the number of results
  433. * allowed. It is only guaranteed to work after the query is
  434. * prepared and before it is executed.
  435. **/
  436. void
  437. rasqal_query_set_limit(rasqal_query* query, int limit)
  438. {
  439. RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
  440. if(query->modifier)
  441. query->modifier->limit = limit;
  442. }
  443. /**
  444. * rasqal_query_get_offset:
  445. * @query: #rasqal_query query object
  446. *
  447. * Get the query-specified offset on results.
  448. *
  449. * This is the offset given in the query on the number of results
  450. * allowed. It is only guaranteed to work after the query is
  451. * prepared and before it is executed.
  452. *
  453. * Return value: integer >=0 if a offset is given, otherwise <0
  454. **/
  455. int
  456. rasqal_query_get_offset(rasqal_query* query)
  457. {
  458. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
  459. if(query->modifier)
  460. return query->modifier->offset;
  461. else
  462. return -1;
  463. }
  464. /**
  465. * rasqal_query_set_offset:
  466. * @query: #rasqal_query query object
  467. * @offset: offset for results, >=0 to set an offset, <0 to have no offset
  468. *
  469. * Set the query-specified offset on results.
  470. *
  471. * This is the offset given in the query on the number of results allowed.
  472. **/
  473. void
  474. rasqal_query_set_offset(rasqal_query* query, int offset)
  475. {
  476. RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
  477. if(query->modifier)
  478. query->modifier->offset = offset;
  479. }
  480. /**
  481. * rasqal_query_add_data_graph:
  482. * @query: #rasqal_query query object
  483. * @data_graph: data graph
  484. *
  485. * Add a data graph to the query.
  486. *
  487. * Return value: non-0 on failure
  488. **/
  489. int
  490. rasqal_query_add_data_graph(rasqal_query* query, rasqal_data_graph* data_graph)
  491. {
  492. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  493. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(data_graph, rasqal_data_graph, 1);
  494. if(raptor_sequence_push(query->data_graphs, (void*)data_graph))
  495. return 1;
  496. return 0;
  497. }
  498. /**
  499. * rasqal_query_add_data_graphs:
  500. * @query: #rasqal_query query object
  501. * @data_graphs: sequence of #rasqal_data_graph
  502. *
  503. * Add a set of data graphs to the query.
  504. *
  505. * The objects in the passed-in @data_graphs sequence becomes owne by the query.
  506. * The @data_graphs sequence itself is freed and must not be used after this call.
  507. *
  508. * Return value: non-0 on failure
  509. **/
  510. int
  511. rasqal_query_add_data_graphs(rasqal_query* query,
  512. raptor_sequence* data_graphs)
  513. {
  514. int rc;
  515. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  516. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(data_graphs, raptor_sequence, 1);
  517. rc = raptor_sequence_join(query->data_graphs, data_graphs);
  518. raptor_free_sequence(data_graphs);
  519. return rc;
  520. }
  521. /**
  522. * rasqal_query_get_data_graph_sequence:
  523. * @query: #rasqal_query query object
  524. *
  525. * Get the sequence of data_graph URIs.
  526. *
  527. * Return value: a #raptor_sequence of #raptor_uri pointers.
  528. **/
  529. raptor_sequence*
  530. rasqal_query_get_data_graph_sequence(rasqal_query* query)
  531. {
  532. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  533. return query->data_graphs;
  534. }
  535. /**
  536. * rasqal_query_get_data_graph:
  537. * @query: #rasqal_query query object
  538. * @idx: index into the sequence (0 or larger)
  539. *
  540. * Get a rasqal_data_graph* in the sequence of data_graphs.
  541. *
  542. * Return value: a #rasqal_data_graph pointer or NULL if out of the sequence range
  543. **/
  544. rasqal_data_graph*
  545. rasqal_query_get_data_graph(rasqal_query* query, int idx)
  546. {
  547. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  548. if(!query->data_graphs)
  549. return NULL;
  550. return (rasqal_data_graph*)raptor_sequence_get_at(query->data_graphs, idx);
  551. }
  552. /**
  553. * rasqal_query_dataset_contains_named_graph:
  554. * @query: #rasqal_query query object
  555. * @graph_uri: query URI
  556. *
  557. * Test if the query dataset contains a named graph
  558. *
  559. * Return value: non-0 if the dataset contains a named graph
  560. */
  561. int
  562. rasqal_query_dataset_contains_named_graph(rasqal_query* query,
  563. raptor_uri *graph_uri)
  564. {
  565. rasqal_data_graph *dg;
  566. int idx;
  567. int found = 0;
  568. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  569. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(graph_uri, raptor_uri, 1);
  570. for(idx = 0; (dg = rasqal_query_get_data_graph(query, idx)); idx++) {
  571. if(dg->name_uri && raptor_uri_equals(dg->name_uri, graph_uri)) {
  572. /* graph_uri is a graph name in the dataset */
  573. found = 1;
  574. break;
  575. }
  576. }
  577. return found;
  578. }
  579. /**
  580. * rasqal_query_add_variable:
  581. * @query: #rasqal_query query object
  582. * @var: #rasqal_variable variable
  583. *
  584. * Add a projected (named) variable to the query.
  585. *
  586. * See also rasqal_query_set_variable() which assigns or removes a value to
  587. * a previously added variable in the query.
  588. *
  589. * Return value: non-0 on failure
  590. **/
  591. int
  592. rasqal_query_add_variable(rasqal_query* query, rasqal_variable* var)
  593. {
  594. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  595. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(var, rasqal_variable, 1);
  596. if(!rasqal_variables_table_contains(query->vars_table, var->type, var->name)) {
  597. if(rasqal_variables_table_add_variable(query->vars_table, var))
  598. return 1;
  599. }
  600. if(!query->projection) {
  601. query->projection = rasqal_new_projection(query,
  602. /* variables */ NULL,
  603. /* wildcard */ 0,
  604. /* distinct */ 0);
  605. if(!query->projection)
  606. return 1;
  607. }
  608. return rasqal_projection_add_variable(query->projection, var);
  609. }
  610. /**
  611. * rasqal_query_get_bound_variable_sequence:
  612. * @query: #rasqal_query query object
  613. *
  614. * Get the sequence of projected variables in the query.
  615. *
  616. * This returns the sequence of variables that are explicitly chosen
  617. * via SELECT in RDQL, SPARQL. Or all variables mentioned with SELECT *
  618. *
  619. * Return value: a #raptor_sequence of #rasqal_variable pointers.
  620. **/
  621. raptor_sequence*
  622. rasqal_query_get_bound_variable_sequence(rasqal_query* query)
  623. {
  624. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  625. if(!query->projection)
  626. return NULL;
  627. return rasqal_projection_get_variables_sequence(query->projection);
  628. }
  629. /**
  630. * rasqal_query_get_describe_sequence:
  631. * @query: #rasqal_query query object
  632. *
  633. * Get the sequence of literals described in the query.
  634. *
  635. * This returns the sequence of literals (constants or variables) that are
  636. * explicitly chosen via DESCRIBE in SPARQL.
  637. *
  638. * Return value: a #raptor_sequence of #rasqal_literal pointers.
  639. **/
  640. raptor_sequence*
  641. rasqal_query_get_describe_sequence(rasqal_query* query)
  642. {
  643. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  644. return query->describes;
  645. }
  646. /**
  647. * rasqal_query_get_anonymous_variable_sequence:
  648. * @query: #rasqal_query query object
  649. *
  650. * Get the sequence of anonymous variables mentioned in the query.
  651. *
  652. * Return value: a #raptor_sequence of #rasqal_variable pointers.
  653. **/
  654. raptor_sequence*
  655. rasqal_query_get_anonymous_variable_sequence(rasqal_query* query)
  656. {
  657. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  658. return rasqal_variables_table_get_anonymous_variables_sequence(query->vars_table);
  659. }
  660. /**
  661. * rasqal_query_get_all_variable_sequence:
  662. * @query: #rasqal_query query object
  663. *
  664. * Get the sequence of all variables mentioned in the query.
  665. *
  666. * Return value: a #raptor_sequence of #rasqal_variable pointers.
  667. **/
  668. raptor_sequence*
  669. rasqal_query_get_all_variable_sequence(rasqal_query* query)
  670. {
  671. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  672. return rasqal_variables_table_get_named_variables_sequence(query->vars_table);
  673. }
  674. /**
  675. * rasqal_query_get_variable:
  676. * @query: #rasqal_query query object
  677. * @idx: index into the sequence (0 or larger)
  678. *
  679. * Get a variable in the query
  680. *
  681. * Return value: a #rasqal_variable pointer or NULL if out of range
  682. **/
  683. rasqal_variable*
  684. rasqal_query_get_variable(rasqal_query* query, int idx)
  685. {
  686. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  687. return rasqal_variables_table_get(query->vars_table, idx);
  688. }
  689. /**
  690. * rasqal_query_has_variable2:
  691. * @query: #rasqal_query query object
  692. * @type: the variable type to match or #RASQAL_VARIABLE_TYPE_UNKNOWN for any.
  693. * @name: variable name
  694. *
  695. * Find if the named variable of the given type is in the query
  696. *
  697. * Note that looking up for any type #RASQAL_VARIABLE_TYPE_UNKNOWN
  698. * may a name match but for any type so in cases where the query has
  699. * both a named and anonymous (extensional) variable, an arbitrary one
  700. * will be returned.
  701. *
  702. * Return value: non-0 if the variable name was found.
  703. **/
  704. int
  705. rasqal_query_has_variable2(rasqal_query* query,
  706. rasqal_variable_type type,
  707. const unsigned char *name)
  708. {
  709. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
  710. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 0);
  711. return rasqal_variables_table_contains(query->vars_table, type, name);
  712. }
  713. /**
  714. * rasqal_query_has_variable:
  715. * @query: #rasqal_query query object
  716. * @name: variable name
  717. *
  718. * Find if the named variable is in the query (of any type)
  719. *
  720. * @Deprecated: Use rasqal_query_has_variable2() with the variable type arg
  721. *
  722. * Return value: non-0 if the variable name was found.
  723. **/
  724. int
  725. rasqal_query_has_variable(rasqal_query* query, const unsigned char *name)
  726. {
  727. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
  728. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 0);
  729. return rasqal_query_has_variable2(query, RASQAL_VARIABLE_TYPE_UNKNOWN, name);
  730. }
  731. /**
  732. * rasqal_query_set_variable2:
  733. * @query: #rasqal_query query object
  734. * @type: the variable type to match or #RASQAL_VARIABLE_TYPE_UNKNOWN for any.
  735. * @name: #rasqal_variable variable
  736. * @value: #rasqal_literal value to set or NULL
  737. *
  738. * Bind an existing typed variable to a value to the query.
  739. *
  740. * See also rasqal_query_add_variable() which adds a new binding variable
  741. * and must be called before this method is invoked.
  742. *
  743. * Return value: non-0 on failure
  744. **/
  745. int
  746. rasqal_query_set_variable2(rasqal_query* query,
  747. rasqal_variable_type type,
  748. const unsigned char *name,
  749. rasqal_literal* value)
  750. {
  751. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  752. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 1);
  753. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, rasqal_literal, 1);
  754. return rasqal_variables_table_set(query->vars_table, type, name, value);
  755. }
  756. /**
  757. * rasqal_query_set_variable:
  758. * @query: #rasqal_query query object
  759. * @name: #rasqal_variable variable
  760. * @value: #rasqal_literal value to set or NULL
  761. *
  762. * Bind an existing named (selected) variable to a value to the query.
  763. *
  764. * @Deprecated for rasqal_query_set_variable2() that includes a type
  765. * arg. This function only sets named variables of type
  766. * #RASQAL_VARIABLE_TYPE_NORMAL
  767. *
  768. * Return value: non-0 on failure
  769. **/
  770. int
  771. rasqal_query_set_variable(rasqal_query* query, const unsigned char *name,
  772. rasqal_literal* value)
  773. {
  774. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  775. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(name, char*, 1);
  776. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, rasqal_literal, 1);
  777. return rasqal_query_set_variable2(query, RASQAL_VARIABLE_TYPE_NORMAL,
  778. name, value);
  779. }
  780. /**
  781. * rasqal_query_get_triple_sequence:
  782. * @query: #rasqal_query query object
  783. *
  784. * Get the sequence of matching triples in the query.
  785. *
  786. * Return value: a #raptor_sequence of #rasqal_triple pointers.
  787. **/
  788. raptor_sequence*
  789. rasqal_query_get_triple_sequence(rasqal_query* query)
  790. {
  791. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  792. return query->triples;
  793. }
  794. /**
  795. * rasqal_query_get_triple:
  796. * @query: #rasqal_query query object
  797. * @idx: index into the sequence (0 or larger)
  798. *
  799. * Get a triple in the sequence of matching triples in the query.
  800. *
  801. * Return value: a #rasqal_triple pointer or NULL if out of the sequence range
  802. **/
  803. rasqal_triple*
  804. rasqal_query_get_triple(rasqal_query* query, int idx)
  805. {
  806. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  807. if(!query->triples)
  808. return NULL;
  809. return (rasqal_triple*)raptor_sequence_get_at(query->triples, idx);
  810. }
  811. int
  812. rasqal_query_declare_prefix(rasqal_query *rq, rasqal_prefix *p)
  813. {
  814. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(rq, rasqal_query, 1);
  815. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(p, rasqal_prefix, 1);
  816. if(p->declared)
  817. return 0;
  818. if(raptor_namespaces_start_namespace_full(rq->namespaces,
  819. p->prefix,
  820. raptor_uri_as_string(p->uri),
  821. rq->prefix_depth))
  822. return 1;
  823. p->declared = 1;
  824. rq->prefix_depth++;
  825. return 0;
  826. }
  827. static int
  828. rasqal_query_undeclare_prefix(rasqal_query *rq, rasqal_prefix *prefix)
  829. {
  830. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(rq, rasqal_query, 1);
  831. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(prefix, rasqal_prefix, 1);
  832. if(!prefix->declared) {
  833. prefix->declared = 1;
  834. return 0;
  835. }
  836. raptor_namespaces_end_for_depth(rq->namespaces, prefix->depth);
  837. return 0;
  838. }
  839. int
  840. rasqal_query_declare_prefixes(rasqal_query *rq)
  841. {
  842. int i;
  843. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(rq, rasqal_query, 1);
  844. if(!rq->prefixes)
  845. return 0;
  846. for(i = 0; i< raptor_sequence_size(rq->prefixes); i++) {
  847. rasqal_prefix* p = (rasqal_prefix*)raptor_sequence_get_at(rq->prefixes, i);
  848. if(rasqal_query_declare_prefix(rq, p))
  849. return 1;
  850. }
  851. return 0;
  852. }
  853. /**
  854. * rasqal_query_add_prefix:
  855. * @query: #rasqal_query query object
  856. * @prefix: #rasqal_prefix namespace prefix, URI
  857. *
  858. * Add a namespace prefix to the query.
  859. *
  860. * If the prefix has already been used, the old URI will be overridden.
  861. *
  862. * Return value: non-0 on failure
  863. **/
  864. int
  865. rasqal_query_add_prefix(rasqal_query* query, rasqal_prefix* prefix)
  866. {
  867. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  868. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(prefix, rasqal_prefix, 1);
  869. if(!query->prefixes) {
  870. query->prefixes = raptor_new_sequence((raptor_data_free_handler)rasqal_free_prefix, (raptor_data_print_handler)rasqal_prefix_print);
  871. if(!query->prefixes)
  872. return 1;
  873. } else {
  874. int i;
  875. for(i = 0; i < raptor_sequence_size(query->prefixes); i++) {
  876. rasqal_prefix* p;
  877. p = (rasqal_prefix*)raptor_sequence_get_at(query->prefixes, i);
  878. if((!p->prefix && !prefix->prefix) ||
  879. ((p->prefix && prefix->prefix &&
  880. !strcmp(RASQAL_GOOD_CAST(const char*, p->prefix),
  881. RASQAL_GOOD_CAST(const char*, prefix->prefix))))
  882. ) {
  883. rasqal_query_undeclare_prefix(query, p);
  884. break;
  885. }
  886. }
  887. }
  888. return raptor_sequence_push(query->prefixes, (void*)prefix);
  889. }
  890. /**
  891. * rasqal_query_get_prefix_sequence:
  892. * @query: #rasqal_query query object
  893. *
  894. * Get the sequence of namespace prefixes in the query.
  895. *
  896. * Return value: a #raptor_sequence of #rasqal_prefix pointers.
  897. **/
  898. raptor_sequence*
  899. rasqal_query_get_prefix_sequence(rasqal_query* query)
  900. {
  901. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  902. return query->prefixes;
  903. }
  904. /**
  905. * rasqal_query_get_prefix:
  906. * @query: #rasqal_query query object
  907. * @idx: index into the sequence (0 or larger)
  908. *
  909. * Get a prefix in the sequence of namespsace prefixes in the query.
  910. *
  911. * Return value: a #rasqal_prefix pointer or NULL if out of the sequence range
  912. **/
  913. rasqal_prefix*
  914. rasqal_query_get_prefix(rasqal_query* query, int idx)
  915. {
  916. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  917. if(!query->prefixes)
  918. return NULL;
  919. return (rasqal_prefix*)raptor_sequence_get_at(query->prefixes, idx);
  920. }
  921. /**
  922. * rasqal_query_get_query_graph_pattern:
  923. * @query: #rasqal_query query object
  924. *
  925. * Get the top query graph pattern.
  926. *
  927. * Return value: a #rasqal_graph_pattern of the top query graph pattern
  928. **/
  929. rasqal_graph_pattern*
  930. rasqal_query_get_query_graph_pattern(rasqal_query* query)
  931. {
  932. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  933. return query->query_graph_pattern;
  934. }
  935. /**
  936. * rasqal_query_get_graph_pattern_sequence:
  937. * @query: #rasqal_query query object
  938. *
  939. * Get the sequence of graph_patterns expressions inside the top query graph pattern.
  940. *
  941. * Return value: a #raptor_sequence of #rasqal_graph_pattern pointers.
  942. **/
  943. raptor_sequence*
  944. rasqal_query_get_graph_pattern_sequence(rasqal_query* query)
  945. {
  946. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  947. return rasqal_graph_pattern_get_sub_graph_pattern_sequence(query->query_graph_pattern);
  948. }
  949. /**
  950. * rasqal_query_get_graph_pattern:
  951. * @query: #rasqal_query query object
  952. * @idx: index into the sequence (0 or larger)
  953. *
  954. * Get a graph_pattern in the sequence of graph_pattern expressions in the top query graph pattern.
  955. *
  956. * Return value: a #rasqal_graph_pattern pointer or NULL if out of the sequence range
  957. **/
  958. rasqal_graph_pattern*
  959. rasqal_query_get_graph_pattern(rasqal_query* query, int idx)
  960. {
  961. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  962. return rasqal_graph_pattern_get_sub_graph_pattern(query->query_graph_pattern, idx);
  963. }
  964. /**
  965. * rasqal_query_get_construct_triples_sequence:
  966. * @query: #rasqal_query query object
  967. *
  968. * Get the sequence of triples for a construct.
  969. *
  970. * Return value: a #raptor_sequence of #rasqal_triple pointers.
  971. **/
  972. raptor_sequence*
  973. rasqal_query_get_construct_triples_sequence(rasqal_query* query)
  974. {
  975. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  976. return query->constructs;
  977. }
  978. /**
  979. * rasqal_query_get_construct_triple:
  980. * @query: #rasqal_query query object
  981. * @idx: index into the sequence (0 or larger)
  982. *
  983. * Get a triple in the sequence of construct triples.
  984. *
  985. * Return value: a #rasqal_triple pointer or NULL if out of the sequence range
  986. **/
  987. rasqal_triple*
  988. rasqal_query_get_construct_triple(rasqal_query* query, int idx)
  989. {
  990. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  991. if(!query->constructs)
  992. return NULL;
  993. return (rasqal_triple*)raptor_sequence_get_at(query->constructs, idx);
  994. }
  995. /**
  996. * rasqal_query_prepare:
  997. * @query: the #rasqal_query object
  998. * @query_string: the query string (or NULL)
  999. * @base_uri: base URI of query string (optional)
  1000. *
  1001. * Prepare a query - typically parse it.
  1002. *
  1003. * Some query languages may require a base URI to resolve any
  1004. * relative URIs in the query string. If this is not given,
  1005. * the current directory in the filesystem is used as the base URI.
  1006. *
  1007. * The query string may be NULL in which case it is not parsed
  1008. * and the query parts may be created by API calls such as
  1009. * rasqal_query_add_source etc.
  1010. *
  1011. * Return value: non-0 on failure.
  1012. **/
  1013. int
  1014. rasqal_query_prepare(rasqal_query* query,
  1015. const unsigned char *query_string,
  1016. raptor_uri *base_uri)
  1017. {
  1018. int rc = 0;
  1019. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  1020. if(query->failed)
  1021. return 1;
  1022. if(query->prepared)
  1023. return 0;
  1024. query->prepared = 1;
  1025. query->store_results = 0;
  1026. if(query_string) {
  1027. /* flex lexers require two NULs at the end of the lexed buffer.
  1028. * Add them here instead of parser to allow resource cleanup on error.
  1029. *
  1030. * flex manual:
  1031. *
  1032. * Function: YY_BUFFER_STATE yy_scan_buffer (char *base, yy_size_t size)
  1033. * which scans in place the buffer starting at `base', consisting of
  1034. * `size' bytes, the last two bytes of which _must_ be
  1035. * `YY_END_OF_BUFFER_CHAR' (ASCII NUL). These last two bytes are not
  1036. * scanned; thus, scanning consists of `base[0]' through
  1037. * `base[size-2]', inclusive.
  1038. */
  1039. size_t len = strlen(RASQAL_GOOD_CAST(const char*, query_string)) + 3; /* +3 for " \0\0" */
  1040. unsigned char *query_string_copy = RASQAL_MALLOC(unsigned char*, len);
  1041. if(!query_string_copy) {
  1042. query->failed = 1;
  1043. return 1;
  1044. }
  1045. memcpy(query_string_copy, query_string, len - 3);
  1046. query_string_copy[len - 3] = ' ';
  1047. query_string_copy[len - 2] = query_string_copy[len - 1] = '\0';
  1048. query->query_string = query_string_copy;
  1049. query->query_string_length = len;
  1050. }
  1051. if(base_uri)
  1052. base_uri = raptor_uri_copy(base_uri);
  1053. else {
  1054. unsigned char *uri_string = raptor_uri_filename_to_uri_string("");
  1055. base_uri = raptor_new_uri(query->world->raptor_world_ptr, uri_string);
  1056. if(uri_string)
  1057. raptor_free_memory(uri_string);
  1058. }
  1059. rasqal_query_set_base_uri(query, base_uri);
  1060. query->locator.line = query->locator.column = query->locator.byte = -1;
  1061. /* set evaluaton context with latest copies of query fields */
  1062. query->eval_context->flags = query->compare_flags;
  1063. rasqal_evaluation_context_set_base_uri(query->eval_context, query->base_uri);
  1064. /* set random seed */
  1065. if(1) {
  1066. unsigned int seed;
  1067. /* get seed either from user or system sources */
  1068. if(query->user_set_rand)
  1069. /* it is ok to truncate here for the purposes of getting a seed */
  1070. seed = RASQAL_GOOD_CAST(unsigned int, query->features[RASQAL_GOOD_CAST(int, RASQAL_FEATURE_RAND_SEED)]);
  1071. else
  1072. seed = rasqal_random_get_system_seed(query->world);
  1073. rasqal_evaluation_context_set_rand_seed(query->eval_context, seed);
  1074. }
  1075. rc = query->factory->prepare(query);
  1076. if(rc) {
  1077. query->failed = 1;
  1078. rc = 1;
  1079. } else if(rasqal_query_prepare_common(query)) {
  1080. query->failed = 1;
  1081. rc = 1;
  1082. }
  1083. return rc;
  1084. }
  1085. /**
  1086. * rasqal_query_get_engine_by_name:
  1087. * @name: query engine name
  1088. *
  1089. * INTERNAL - Get a query engine by name
  1090. *
  1091. * If @name is NULL or the name is unknown, the default factory is returned
  1092. *
  1093. * return value: pointer to factory
  1094. **/
  1095. const rasqal_query_execution_factory*
  1096. rasqal_query_get_engine_by_name(const char* name)
  1097. {
  1098. const rasqal_query_execution_factory* engine;
  1099. /* default */
  1100. engine = &rasqal_query_engine_algebra;
  1101. if(name) {
  1102. if(!strcmp(name, "2") || !strcmp(name, "algebra"))
  1103. engine = &rasqal_query_engine_algebra;
  1104. else
  1105. engine = NULL;
  1106. }
  1107. return engine;
  1108. }
  1109. /**
  1110. * rasqal_query_execute_with_engine:
  1111. * @query: the #rasqal_query object
  1112. * @engine: execution engine factory (or NULL)
  1113. *
  1114. * INTERNAL - Excecute a query with a given factory and return results.
  1115. *
  1116. * return value: a #rasqal_query_results structure or NULL on failure.
  1117. **/
  1118. rasqal_query_results*
  1119. rasqal_query_execute_with_engine(rasqal_query* query,
  1120. const rasqal_query_execution_factory* engine)
  1121. {
  1122. rasqal_query_results *query_results = NULL;
  1123. rasqal_query_results_type type;
  1124. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1125. if(query->failed)
  1126. return NULL;
  1127. type = rasqal_query_get_result_type(query);
  1128. if(type == RASQAL_QUERY_RESULTS_UNKNOWN)
  1129. return NULL;
  1130. query_results = rasqal_new_query_results(query->world, query, type,
  1131. query->vars_table);
  1132. if(!query_results)
  1133. return NULL;
  1134. if(!engine)
  1135. engine = rasqal_query_get_engine_by_name(NULL);
  1136. if(rasqal_query_results_execute_with_engine(query_results, engine,
  1137. query->store_results)) {
  1138. rasqal_free_query_results(query_results);
  1139. query_results = NULL;
  1140. }
  1141. if(query_results && rasqal_query_add_query_result(query, query_results)) {
  1142. rasqal_free_query_results(query_results);
  1143. query_results = NULL;
  1144. }
  1145. return query_results;
  1146. }
  1147. /**
  1148. * rasqal_query_execute:
  1149. * @query: the #rasqal_query object
  1150. *
  1151. * Excute a query - run and return results.
  1152. *
  1153. * return value: a #rasqal_query_results structure or NULL on failure.
  1154. **/
  1155. rasqal_query_results*
  1156. rasqal_query_execute(rasqal_query* query)
  1157. {
  1158. return rasqal_query_execute_with_engine(query, NULL);
  1159. }
  1160. static const char* const rasqal_query_verb_labels[RASQAL_QUERY_VERB_LAST+1] = {
  1161. "Unknown",
  1162. "SELECT",
  1163. "CONSTRUCT",
  1164. "DESCRIBE",
  1165. "ASK",
  1166. "DELETE",
  1167. "INSERT",
  1168. "UPDATE"
  1169. };
  1170. /* Utility methods */
  1171. /**
  1172. * rasqal_query_verb_as_string:
  1173. * @verb: the #rasqal_query_verb verb of the query
  1174. *
  1175. * Get a string for the query verb.
  1176. *
  1177. * Return value: pointer to a shared string label for the query verb
  1178. **/
  1179. const char*
  1180. rasqal_query_verb_as_string(rasqal_query_verb verb)
  1181. {
  1182. if(verb <= RASQAL_QUERY_VERB_UNKNOWN ||
  1183. verb > RASQAL_QUERY_VERB_LAST)
  1184. verb = RASQAL_QUERY_VERB_UNKNOWN;
  1185. return rasqal_query_verb_labels[RASQAL_GOOD_CAST(int, verb)];
  1186. }
  1187. /**
  1188. * rasqal_query_print:
  1189. * @query: the #rasqal_query object
  1190. * @fh: the FILE* handle to print to.
  1191. *
  1192. * Print a query in a debug format.
  1193. *
  1194. * Return value: non-0 on failure
  1195. **/
  1196. int
  1197. rasqal_query_print(rasqal_query* query, FILE *fh)
  1198. {
  1199. rasqal_variables_table* vars_table = query->vars_table;
  1200. raptor_sequence* seq;
  1201. unsigned int distinct_mode;
  1202. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  1203. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(fh, FILE*, 1);
  1204. fprintf(fh, "query verb: %s\n", rasqal_query_verb_as_string(query->verb));
  1205. distinct_mode = rasqal_query_get_distinct(query);
  1206. if(distinct_mode)
  1207. fprintf(fh, "query results distinct mode: %s\n",
  1208. (distinct_mode == 1 ? "distinct" : "reduced"));
  1209. if(query->explain)
  1210. fputs("query results explain: yes\n", fh);
  1211. if(query->modifier) {
  1212. if(query->modifier->limit >= 0)
  1213. fprintf(fh, "query results limit: %d\n", query->modifier->limit);
  1214. if(query->modifier->offset >= 0)
  1215. fprintf(fh, "query results offset: %d\n", query->modifier->offset);
  1216. }
  1217. fputs("data graphs: ", fh);
  1218. if(query->data_graphs)
  1219. raptor_sequence_print(query->data_graphs, fh);
  1220. seq = rasqal_variables_table_get_named_variables_sequence(vars_table);
  1221. if(seq) {
  1222. fputs("\nnamed variables: ", fh);
  1223. raptor_sequence_print(seq, fh);
  1224. }
  1225. seq = rasqal_variables_table_get_anonymous_variables_sequence(vars_table);
  1226. if(seq) {
  1227. fputs("\nanonymous variables: ", fh);
  1228. raptor_sequence_print(seq, fh);
  1229. }
  1230. seq = rasqal_query_get_bound_variable_sequence(query);
  1231. if(seq) {
  1232. int i;
  1233. fputs("\nprojected variable names: ", fh);
  1234. for(i = 0; 1; i++) {
  1235. rasqal_variable* v = (rasqal_variable*)raptor_sequence_get_at(seq, i);
  1236. if(!v)
  1237. break;
  1238. if(i > 0)
  1239. fputs(", ", fh);
  1240. fputs((const char*)v->name, fh);
  1241. }
  1242. fputc('\n', fh);
  1243. fputs("\nbound variables: ", fh);
  1244. raptor_sequence_print(seq, fh);
  1245. }
  1246. if(query->describes) {
  1247. fputs("\ndescribes: ", fh);
  1248. raptor_sequence_print(query->describes, fh);
  1249. }
  1250. if(query->triples) {
  1251. fputs("\ntriples: ", fh);
  1252. raptor_sequence_print(query->triples, fh);
  1253. }
  1254. if(query->optional_triples) {
  1255. fputs("\noptional triples: ", fh);
  1256. raptor_sequence_print(query->optional_triples, fh);
  1257. }
  1258. if(query->constructs) {
  1259. fputs("\nconstructs: ", fh);
  1260. raptor_sequence_print(query->constructs, fh);
  1261. }
  1262. if(query->prefixes) {
  1263. fputs("\nprefixes: ", fh);
  1264. raptor_sequence_print(query->prefixes, fh);
  1265. }
  1266. if(query->query_graph_pattern) {
  1267. fputs("\nquery graph pattern: ", fh);
  1268. rasqal_graph_pattern_print(query->query_graph_pattern, fh);
  1269. }
  1270. if(query->modifier) {
  1271. if(query->modifier->order_conditions) {
  1272. fputs("\nquery order conditions: ", fh);
  1273. raptor_sequence_print(query->modifier->order_conditions, fh);
  1274. }
  1275. if(query->modifier->group_conditions) {
  1276. fputs("\nquery group conditions: ", fh);
  1277. raptor_sequence_print(query->modifier->group_conditions, fh);
  1278. }
  1279. if(query->modifier->having_conditions) {
  1280. fputs("\nquery having conditions: ", fh);
  1281. raptor_sequence_print(query->modifier->having_conditions, fh);
  1282. }
  1283. }
  1284. if(query->updates) {
  1285. fputs("\nupdate operations: ", fh);
  1286. raptor_sequence_print(query->updates, fh);
  1287. }
  1288. if(query->bindings) {
  1289. fputs("\nbindings: ", fh);
  1290. rasqal_bindings_print(query->bindings, fh);
  1291. }
  1292. fputc('\n', fh);
  1293. return 0;
  1294. }
  1295. static int
  1296. rasqal_query_add_query_result(rasqal_query* query,
  1297. rasqal_query_results* query_results)
  1298. {
  1299. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  1300. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, 1);
  1301. /* add reference to ensure query lives as long as this runs */
  1302. /* query->results sequence has rasqal_query_results_remove_query_reference()
  1303. as the free handler which calls rasqal_free_query() decrementing
  1304. query->usage */
  1305. query->usage++;
  1306. return raptor_sequence_push(query->results, query_results);
  1307. }
  1308. int
  1309. rasqal_query_remove_query_result(rasqal_query* query,
  1310. rasqal_query_results* query_results)
  1311. {
  1312. int i;
  1313. int size;
  1314. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  1315. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query_results, rasqal_query_results, 1);
  1316. size = raptor_sequence_size(query->results);
  1317. for(i = 0 ; i < size; i++) {
  1318. rasqal_query_results *result;
  1319. result = (rasqal_query_results*)raptor_sequence_get_at(query->results, i);
  1320. if(result == query_results) {
  1321. raptor_sequence_set_at(query->results, i, NULL);
  1322. break;
  1323. }
  1324. }
  1325. return 0;
  1326. }
  1327. /**
  1328. * rasqal_query_get_user_data:
  1329. * @query: #rasqal_query
  1330. *
  1331. * Get query user data.
  1332. *
  1333. * Return value: user data as set by rasqal_query_set_user_data()
  1334. **/
  1335. void*
  1336. rasqal_query_get_user_data(rasqal_query* query)
  1337. {
  1338. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1339. return query->user_data;
  1340. }
  1341. /**
  1342. * rasqal_query_set_user_data:
  1343. * @query: #rasqal_query
  1344. * @user_data: some user data to associate with the query
  1345. *
  1346. * Set the query user data.
  1347. *
  1348. **/
  1349. void
  1350. rasqal_query_set_user_data(rasqal_query* query, void *user_data)
  1351. {
  1352. RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
  1353. query->user_data = user_data;
  1354. }
  1355. /**
  1356. * rasqal_query_get_verb:
  1357. * @query: #rasqal_query
  1358. *
  1359. * Get the query verb.
  1360. *
  1361. * Return value: the operating verb of the query of type rasqal_query_verb
  1362. **/
  1363. rasqal_query_verb
  1364. rasqal_query_get_verb(rasqal_query* query)
  1365. {
  1366. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, RASQAL_QUERY_VERB_UNKNOWN);
  1367. return query->verb;
  1368. }
  1369. /**
  1370. * rasqal_query_get_wildcard:
  1371. * @query: #rasqal_query
  1372. *
  1373. * Get the query verb is wildcard flag.
  1374. *
  1375. * Return value: non-0 if the query verb was a wildcard (such as SELECT *)
  1376. **/
  1377. int
  1378. rasqal_query_get_wildcard(rasqal_query* query)
  1379. {
  1380. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 0);
  1381. if(!query->projection)
  1382. return 0;
  1383. return query->projection->wildcard;
  1384. }
  1385. /**
  1386. * rasqal_query_set_wildcard:
  1387. * @query: #rasqal_query query object
  1388. * @wildcard: wildcard
  1389. *
  1390. * Set the query projection wildcard flag
  1391. *
  1392. **/
  1393. void
  1394. rasqal_query_set_wildcard(rasqal_query* query, int wildcard)
  1395. {
  1396. RASQAL_ASSERT_OBJECT_POINTER_RETURN(query, rasqal_query);
  1397. if(!query->projection) {
  1398. query->projection = rasqal_new_projection(query,
  1399. /* variables */ NULL,
  1400. /* wildcard */ 0,
  1401. /* wildcard */ 0);
  1402. if(!query->projection)
  1403. return;
  1404. }
  1405. query->projection->wildcard = wildcard;
  1406. }
  1407. /**
  1408. * rasqal_query_get_order_conditions_sequence:
  1409. * @query: #rasqal_query query object
  1410. *
  1411. * Get the sequence of query ordering conditions.
  1412. *
  1413. * Return value: a #raptor_sequence of #rasqal_expression pointers.
  1414. **/
  1415. raptor_sequence*
  1416. rasqal_query_get_order_conditions_sequence(rasqal_query* query)
  1417. {
  1418. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1419. if(query->modifier)
  1420. return query->modifier->order_conditions;
  1421. else
  1422. return NULL;
  1423. }
  1424. /**
  1425. * rasqal_query_get_order_condition:
  1426. * @query: #rasqal_query query object
  1427. * @idx: index into the sequence (0 or larger)
  1428. *
  1429. * Get a query ordering expression in the sequence of query ordering conditions.
  1430. *
  1431. * Return value: a #rasqal_expression pointer or NULL if out of the sequence range
  1432. **/
  1433. rasqal_expression*
  1434. rasqal_query_get_order_condition(rasqal_query* query, int idx)
  1435. {
  1436. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1437. if(!query->modifier || !query->modifier->order_conditions)
  1438. return NULL;
  1439. return (rasqal_expression*)raptor_sequence_get_at(query->modifier->order_conditions, idx);
  1440. }
  1441. /**
  1442. * rasqal_query_get_group_conditions_sequence:
  1443. * @query: #rasqal_query query object
  1444. *
  1445. * Get the sequence of query grouping conditions.
  1446. *
  1447. * Return value: a #raptor_sequence of #rasqal_expression pointers.
  1448. **/
  1449. raptor_sequence*
  1450. rasqal_query_get_group_conditions_sequence(rasqal_query* query)
  1451. {
  1452. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1453. if(query->modifier)
  1454. return query->modifier->group_conditions;
  1455. else
  1456. return NULL;
  1457. }
  1458. /**
  1459. * rasqal_query_get_group_condition:
  1460. * @query: #rasqal_query query object
  1461. * @idx: index into the sequence (0 or larger)
  1462. *
  1463. * Get a query grouping expression in the sequence of query grouping conditions.
  1464. *
  1465. * Return value: a #rasqal_expression pointer or NULL if out of the sequence range
  1466. **/
  1467. rasqal_expression*
  1468. rasqal_query_get_group_condition(rasqal_query* query, int idx)
  1469. {
  1470. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1471. if(!query->modifier || !query->modifier->group_conditions)
  1472. return NULL;
  1473. return (rasqal_expression*)raptor_sequence_get_at(query->modifier->group_conditions, idx);
  1474. }
  1475. /**
  1476. * rasqal_query_get_having_conditions_sequence:
  1477. * @query: #rasqal_query query object
  1478. *
  1479. * Get the sequence of query having conditions.
  1480. *
  1481. * Return value: a #raptor_sequence of #rasqal_expression pointers.
  1482. **/
  1483. raptor_sequence*
  1484. rasqal_query_get_having_conditions_sequence(rasqal_query* query)
  1485. {
  1486. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1487. if(query->modifier)
  1488. return query->modifier->having_conditions;
  1489. else
  1490. return NULL;
  1491. }
  1492. /**
  1493. * rasqal_query_get_having_condition:
  1494. * @query: #rasqal_query query object
  1495. * @idx: index into the sequence (0 or larger)
  1496. *
  1497. * Get a query having expression in the sequence of query havinging conditions.
  1498. *
  1499. * Return value: a #rasqal_expression pointer or NULL if out of the sequence range
  1500. **/
  1501. rasqal_expression*
  1502. rasqal_query_get_having_condition(rasqal_query* query, int idx)
  1503. {
  1504. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, NULL);
  1505. if(!query->modifier || !query->modifier->having_conditions)
  1506. return NULL;
  1507. return (rasqal_expression*)raptor_sequence_get_at(query->modifier->having_conditions, idx);
  1508. }
  1509. /**
  1510. * rasqal_query_graph_pattern_visit2:
  1511. * @query: query
  1512. * @visit_fn: user function to operate on
  1513. * @data: user data to pass to function
  1514. *
  1515. * Visit all graph patterns in a query with a user function @visit_fn.
  1516. *
  1517. * See also rasqal_graph_pattern_visit().
  1518. *
  1519. * Return value: result from visit function @visit_fn if it returns non-0
  1520. **/
  1521. int
  1522. rasqal_query_graph_pattern_visit2(rasqal_query* query,
  1523. rasqal_graph_pattern_visit_fn visit_fn,
  1524. void* data)
  1525. {
  1526. rasqal_graph_pattern* gp;
  1527. RASQAL_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, rasqal_query, 1);
  1528. gp = rasqal_query_get_query_graph_pattern(query);
  1529. if(!gp)
  1530. return 1;
  1531. return rasqal_graph_pattern_visit(query, gp, visit_fn, data);
  1532. }
  1533. /**
  1534. * rasqal_query_graph_pattern_visit:
  1535. * @query: query
  1536. * @visit_fn: user function to operate on
  1537. * @data: user data to pass to function
  1538. *
  1539. * Visit all graph patterns in a query with a user function @visit_fn.
  1540. *
  1541. * @Deprecated: use rasqal_query_graph_pattern_visit2() that returns the @visit_fn status code.
  1542. *
  1543. * See also rasqal_graph_pattern_visit().
  1544. **/
  1545. void
  1546. rasqal_query_graph_pattern_visit(rasqal_query* query,
  1547. rasqal_graph_pattern_visit_fn visit_fn,
  1548. void* data)
  1549. {
  1550. (void)rasqal_query_graph_pattern_visit2(query, visit_fn, data);
  1551. }
  1552. /**
  1553. * rasqal_query_write:
  1554. * @iostr: #raptor_iostream to write the query to
  1555. * @query: #rasqal_query pointer.
  1556. * @format_uri: #raptor_uri describing the format to write (or NULL for default)
  1557. * @base_uri: #raptor_uri base URI of the output format
  1558. *
  1559. * Write a query to an iostream in a specified format.
  1560. *
  1561. * The supported URIs for the format_uri are:
  1562. *
  1563. * Default: SPARQL Query Language 2006-04-06
  1564. * http://www.w3.org/TR/2006/CR-rdf-sparql-query-20060406/
  1565. *
  1566. * Return value: non-0 on failure
  1567. **/
  1568. int
  1569. ra

Large files files are truncated, but you can click here to view the full file