All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_query.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2017 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 #pragma GCC diagnostic ignored "-Waddress"
19 
21 #include <aerospike/as_bin.h>
22 #include <aerospike/as_key.h>
23 #include <aerospike/as_list.h>
24 #include <aerospike/as_predexp.h>
25 #include <aerospike/as_udf.h>
26 
27 #include <stdarg.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /******************************************************************************
34  * MACROS
35  *****************************************************************************/
36 
37 /**
38  * Macro for setting setting the STRING_EQUAL predicate.
39  *
40  * ~~~~~~~~~~{.c}
41  * as_query_where(query, "bin1", as_string_equals("abc"));
42  * ~~~~~~~~~~
43  *
44  * @relates as_query
45  */
46 #define as_string_equals(__val) AS_PREDICATE_EQUAL, AS_INDEX_TYPE_DEFAULT, AS_INDEX_STRING, __val
47 
48 /**
49  * Macro for setting setting the INTEGER_EQUAL predicate.
50  *
51  * ~~~~~~~~~~{.c}
52  * as_query_where(query, "bin1", as_integer_equals(123));
53  * ~~~~~~~~~~
54  *
55  * @relates as_query
56  */
57 #define as_integer_equals(__val) AS_PREDICATE_EQUAL, AS_INDEX_TYPE_DEFAULT, AS_INDEX_NUMERIC, (int64_t)__val
58 
59 /**
60  * Macro for setting setting the INTEGER_RANGE predicate.
61  *
62  * ~~~~~~~~~~{.c}
63  * as_query_where(query, "bin1", as_integer_range(1,100));
64  * ~~~~~~~~~~
65  *
66  * @relates as_query
67  * @ingroup query_object
68  */
69 #define as_integer_range(__min, __max) AS_PREDICATE_RANGE, AS_INDEX_TYPE_DEFAULT, AS_INDEX_NUMERIC, (int64_t)__min, (int64_t)__max
70 
71 /**
72  * Macro for setting setting the RANGE predicate.
73  *
74  * ~~~~~~~~~~{.c}
75  * as_query_where(query, "bin1", as_range(LIST,NUMERIC,1,100));
76  * ~~~~~~~~~~
77  *
78  * @relates as_query
79  * @ingroup query_object
80  */
81 #define as_range(indextype, datatype, __min, __max) AS_PREDICATE_RANGE, AS_INDEX_TYPE_ ##indextype, AS_INDEX_ ##datatype, __min, __max
82 
83 /**
84  * Macro for setting setting the CONTAINS predicate.
85  *
86  * ~~~~~~~~~~{.c}
87  * as_query_where(query, "bin1", as_contains(LIST,STRING,"val"));
88  * ~~~~~~~~~~
89  *
90  * @relates as_query
91  * @ingroup query_object
92  */
93 #define as_contains(indextype, datatype, __val) AS_PREDICATE_EQUAL, AS_INDEX_TYPE_ ##indextype, AS_INDEX_ ##datatype, __val
94 
95 /**
96  * Macro for setting setting the EQUALS predicate.
97  *
98  * ~~~~~~~~~~{.c}
99  * as_query_where(query, "bin1", as_equals(NUMERIC,5));
100  * ~~~~~~~~~~
101  *
102  * @relates as_query
103  * @ingroup query_object
104  */
105 #define as_equals(datatype, __val) AS_PREDICATE_EQUAL, AS_INDEX_TYPE_DEFAULT, AS_INDEX_ ##datatype, __val
106 
107 #define as_geo_within(__val) AS_PREDICATE_RANGE, AS_INDEX_TYPE_DEFAULT, AS_INDEX_GEO2DSPHERE, __val
108 
109 #define as_geo_contains(__val) AS_PREDICATE_RANGE, AS_INDEX_TYPE_DEFAULT, AS_INDEX_GEO2DSPHERE, __val
110 
111 
112 /******************************************************************************
113  * TYPES
114  *****************************************************************************/
115 
116 /**
117  * Union of supported predicates
118  */
119 typedef union as_predicate_value_u {
120 
121  /**
122  * String Value
123  */
124  char * string;
125 
126  /**
127  * Integer Value
128  */
129  int64_t integer;
130 
131  /**
132  * Integer Range Value
133  */
134  struct {
135 
136  /**
137  * Minimum value
138  */
139  int64_t min;
140 
141  /**
142  * Maximum value
143  */
144  int64_t max;
145 
146  } integer_range;
147 
149 
150 /**
151  * The types of predicates supported.
152  */
153 typedef enum as_predicate_type_e {
154 
155  /**
156  * String Equality Predicate.
157  * Requires as_predicate_value.string to be set.
158  */
160 
163 
164 /**
165  * Defines a predicate, including the bin, type of predicate and the value
166  * for the predicate.
167  */
168 typedef struct as_predicate_s {
169 
170  /**
171  * Bin to apply the predicate to
172  */
174 
175  /**
176  * The predicate type, dictates which values to use from the union
177  */
179 
180  /**
181  * The value for the predicate.
182  */
184 
185  /*
186  * The type of data user wants to query
187  */
188 
190 
191  /*
192  * The type of index predicate is on
193  */
195 } as_predicate;
196 
197 /**
198  * Enumerations defining the direction of an ordering.
199  */
200 typedef enum as_order_e {
201 
202  /**
203  * Ascending order
204  */
206 
207  /**
208  * bin should be in ascending order
209  */
211 
212 } as_order;
213 
214 
215 /**
216  * Defines the direction a bin should be ordered by.
217  */
218 typedef struct as_ordering_s {
219 
220  /**
221  * Name of the bin to sort by
222  */
224 
225  /**
226  * Direction of the sort
227  */
229 
230 } as_ordering;
231 
232 /**
233  * Sequence of bins which should be selected during a query.
234  *
235  * Entries can either be initialized on the stack or on the heap.
236  *
237  * Initialization should be performed via a query object, using:
238  * - as_query_select_init()
239  * - as_query_select_inita()
240  */
241 typedef struct as_query_bins_s {
242 
243  /**
244  * @private
245  * If true, then as_query_destroy() will free this instance.
246  */
247  bool _free;
248 
249  /**
250  * Number of entries allocated
251  */
252  uint16_t capacity;
253 
254  /**
255  * Number of entries used
256  */
257  uint16_t size;
258 
259  /**
260  * Sequence of entries
261  */
263 
264 } as_query_bins;
265 
266 /**
267  * Sequence of predicates to be applied to a query.
268  *
269  * Entries can either be initialized on the stack or on the heap.
270  *
271  * Initialization should be performed via a query object, using:
272  * - as_query_where_init()
273  * - as_query_where_inita()
274  */
275 typedef struct as_query_predicates_s {
276 
277  /**
278  * @private
279  * If true, then as_query_destroy() will free this instance.
280  */
281  bool _free;
282 
283  /**
284  * Number of entries allocated
285  */
286  uint16_t capacity;
287 
288  /**
289  * Number of entries used
290  */
291  uint16_t size;
292 
293  /**
294  * Sequence of entries
295  */
297 
299 
300 /**
301  * Sequence of predicate expressions to be applied to a query.
302  *
303  * Entries can either be initialized on the stack or on the heap.
304  *
305  * Initialization should be performed via a query object, using:
306  * - as_query_predexp_init()
307  * - as_query_predexp_inita()
308  */
309 typedef struct as_query_predexp_s {
310 
311  /**
312  * @private
313  * If true, then as_query_destroy() will free this instance.
314  */
315  bool _free;
316 
317  /**
318  * Number of entries allocated
319  */
320  uint16_t capacity;
321 
322  /**
323  * Number of entries used
324  */
325  uint16_t size;
326 
327  /**
328  * Sequence of entries
329  */
331 
333 
334 /**
335  * Sequence of ordering to be applied to a query results.
336  *
337  * Entries can either be initialized on the stack or on the heap.
338  *
339  * Initialization should be performed via a query object, using:
340  * - as_query_orderby_init()
341  * - as_query_orderby_inita()
342  */
343 typedef struct as_query_sort_s {
344 
345  /**
346  * @private
347  * If true, then as_query_destroy() will free this instance.
348  */
349  bool _free;
350 
351  /**
352  * Number of entries allocated
353  */
354  uint16_t capacity;
355 
356  /**
357  * Number of entries used
358  */
359  uint16_t size;
360 
361  /**
362  * Sequence of entries
363  */
365 
367 
368 
369 /**
370  * The as_query object is used define a query to be executed in the datasbase.
371  *
372  * ## Initialization
373  *
374  * Before using an as_query, it must be initialized via either:
375  * - as_query_init()
376  * - as_query_new()
377  *
378  * as_query_init() should be used on a stack allocated as_query. It will
379  * initialize the as_query with the given namespace and set. On success,
380  * it will return a pointer to the initialized as_query. Otherwise, NULL
381  * is returned.
382  *
383  * ~~~~~~~~~~{.c}
384  * as_query query;
385  * as_query_init(&query, "namespace", "set");
386  * ~~~~~~~~~~
387  *
388  * as_query_new() should be used to allocate and initialize a heap allocated
389  * as_query. It will allocate the as_query, then initialized it with the
390  * given namespace and set. On success, it will return a pointer to the
391  * initialized as_query. Otherwise, NULL is returned.
392  *
393  * ~~~~~~~~~~{.c}
394  * as_query * query = as_query_new("namespace", "set");
395  * ~~~~~~~~~~
396  *
397  * ## Destruction
398  *
399  * When you are finished with the as_query, you can destroy it and associated
400  * resources:
401  *
402  * ~~~~~~~~~~{.c}
403  * as_query_destroy(query);
404  * ~~~~~~~~~~
405  *
406  * ## Usage
407  *
408  * The following explains how to use an as_query to build a query.
409  *
410  * ### Selecting Bins
411  *
412  * as_query_select() is used to specify the bins to be selected by the query.
413  *
414  * ~~~~~~~~~~{.c}
415  * as_query_select(query, "bin1");
416  * as_query_select(query, "bin2");
417  * ~~~~~~~~~~
418  *
419  * Before adding bins to select, the select structure must be initialized via
420  * either:
421  * - as_query_select_inita() - Initializes the structure on the stack.
422  * - as_query_select_init() - Initializes the structure on the heap.
423  *
424  * Both functions are given the number of bins to be selected.
425  *
426  * A complete example using as_query_select_inita()
427  *
428  * ~~~~~~~~~~{.c}
429  * as_query_select_inita(query, 2);
430  * as_query_select(query, "bin1");
431  * as_query_select(query, "bin2");
432  * ~~~~~~~~~~
433  *
434  *
435  * ### Predicates on Bins
436  *
437  * as_query_where() is used to specify predicates to be added to the the query.
438  *
439  * **Note:** Currently, a single where predicate is supported. To do more advanced filtering,
440  * you will want to use a UDF to process the result set on the server.
441  *
442  * ~~~~~~~~~~{.c}
443  * as_query_where(query, "bin1", as_string_equals("abc"));
444  * ~~~~~~~~~~
445  *
446  * The predicates that you can apply to a bin include:
447  * - as_string_equals() - Test for string equality.
448  * - as_integer_equals() - Test for integer equality.
449  * - as_integer_range() - Test for integer within a range.
450  *
451  * Before adding predicates, the where structure must be initialized. To
452  * initialize the where structure, you can choose to use one of the following:
453  * - as_query_where_inita() - Initializes the structure on the stack.
454  * - as_query_where_init() - Initializes the structure on the heap.
455  *
456  * Both functions are given the number of predicates to be added.
457  *
458  * A complete example using as_query_where_inita():
459  *
460  * ~~~~~~~~~~{.c}
461  * as_query_where_inita(query, 1);
462  * as_query_where(query, "bin1", as_string_equals("abc"));
463  * ~~~~~~~~~~
464  *
465  *
466  * ### Sorting Results
467  *
468  * as_query_orderby() is used to specify ordering of results of a query.
469  *
470  * ~~~~~~~~~~{.c}
471  * as_query_orderby(query, "bin1", AS_ORDER_ASCENDING);
472  * ~~~~~~~~~~
473  *
474  * The sort order can be:
475  * - `AS_ORDER_ASCENDING`
476  * - `AS_ORDER_DESCENDING`
477  *
478  * Before adding ordering, the orderby structure must be initialized via
479  * either:
480  * - as_query_orderby_inita() - Initializes the structure on the stack.
481  * - as_query_orderby_init() - Initializes the structure on the heap.
482  *
483  * Both functions are given the number of orderings to be added.
484  *
485  * A complete example using as_query_orderby_inita():
486  *
487  * ~~~~~~~~~~{.c}
488  * as_query_orderby_inita(query, 2);
489  * as_query_orderby(query, "bin1", AS_ORDER_ASCENDING);
490  * as_query_orderby(query, "bin2", AS_ORDER_ASCENDING);
491  * ~~~~~~~~~~
492  *
493  * ### Applying a UDF to Query Results
494  *
495  * A UDF can be applied to the results of a query.
496  *
497  * To define the UDF for the query, use as_query_apply().
498  *
499  * ~~~~~~~~~~{.c}
500  * as_query_apply(query, "udf_module", "udf_function", arglist);
501  * ~~~~~~~~~~
502  *
503  * @ingroup client_objects
504  */
505 typedef struct as_query_s {
506 
507  /**
508  * @private
509  * If true, then as_query_destroy() will free this instance.
510  */
511  bool _free;
512 
513  /**
514  * Namespace to be queried.
515  *
516  * Should be initialized via either:
517  * - as_query_init() - To initialize a stack allocated query.
518  * - as_query_new() - To heap allocate and initialize a query.
519  */
521 
522  /**
523  * Set to be queried.
524  *
525  * Should be initialized via either:
526  * - as_query_init() - To initialize a stack allocated query.
527  * - as_query_new() - To heap allocate and initialize a query.
528  */
530 
531  /**
532  * Name of bins to select.
533  *
534  * Use either of the following function to initialize:
535  * - as_query_select_init() - To initialize on the heap.
536  * - as_query_select_inita() - To initialize on the stack.
537  *
538  * Use as_query_select() to populate.
539  */
541 
542  /**
543  * Predicates for filtering.
544  *
545  * Use either of the following function to initialize:
546  * - as_query_where_init() - To initialize on the heap.
547  * - as_query_where_inita() - To initialize on the stack.
548  *
549  * Use as_query_where() to populate.
550  */
552 
553  /**
554  * Predicate Expressions for filtering.
555  *
556  * Use either of the following function to initialize:
557  * - as_query_predexp_init() - To initialize on the heap.
558  * - as_query_predexp_inita() - To initialize on the stack.
559  *
560  * Use as_query_predexp() to populate.
561  */
563 
564  /**
565  * UDF to apply to results of the query
566  *
567  * Should be set via `as_query_apply()`.
568  */
570 
571  /**
572  * Set to true if query should only return keys and no bin data.
573  *
574  * Default value is false.
575  */
576  bool no_bins;
577 
578 } as_query;
579 
580 /******************************************************************************
581  * INSTANCE FUNCTIONS
582  *****************************************************************************/
583 
584 /**
585  * Initialize a stack allocated as_query.
586  *
587  * ~~~~~~~~~~{.c}
588  * as_query query;
589  * as_query_init(&query, "test", "demo");
590  * ~~~~~~~~~~
591  *
592  * @param query The query to initialize.
593  * @param ns The namespace to query.
594  * @param set The set to query.
595  *
596  * @return On success, the initialized query. Otherwise NULL.
597  *
598  * @relates as_query
599  */
600 as_query * as_query_init(as_query * query, const as_namespace ns, const as_set set);
601 
602 /**
603  * Create and initialize a new heap allocated as_query.
604  *
605  * ~~~~~~~~~~{.c}
606  * as_query * query = as_query_new("test", "demo");
607  * ~~~~~~~~~~
608  *
609  * @param ns The namespace to query.
610  * @param set The set to query.
611  *
612  * @return On success, the new query. Otherwise NULL.
613  *
614  * @relates as_query
615  * @ingroup query_object
616  */
617 as_query * as_query_new(const as_namespace ns, const as_set set);
618 
619 /**
620  * Destroy the query and associated resources.
621  *
622  * ~~~~~~~~~~{.c}
623  * as_query_destroy(scan);
624  * ~~~~~~~~~~
625  *
626  * @param query The query to destroy.
627  *
628  * @relates as_query
629  */
630 void as_query_destroy(as_query * query);
631 
632 /******************************************************************************
633  * SELECT FUNCTIONS
634  *****************************************************************************/
635 
636 /**
637  * Initializes `as_query.select` with a capacity of `n` using `alloca`
638  *
639  * For heap allocation, use `as_query_select_init()`.
640  *
641  * ~~~~~~~~~~{.c}
642  * as_query_select_inita(&query, 2);
643  * as_query_select(&query, "bin1");
644  * as_query_select(&query, "bin2");
645  * ~~~~~~~~~~
646  *
647  * @param __query The query to initialize.
648  * @param __n The number of bins to allocate.
649  *
650  * @relates as_query
651  * @ingroup query_object
652  */
653 #define as_query_select_inita(__query, __n) \
654  do { \
655  if ( (__query) != NULL && (__query)->select.entries == NULL ) {\
656  (__query)->select.entries = (as_bin_name*) alloca(sizeof(as_bin_name) * (__n));\
657  if ( (__query)->select.entries ) { \
658  (__query)->select._free = false;\
659  (__query)->select.capacity = (__n);\
660  (__query)->select.size = 0;\
661  }\
662  } \
663  } while(0)
664 
665 /**
666  * Initializes `as_query.select` with a capacity of `n` using `malloc()`.
667  *
668  * For stack allocation, use `as_query_select_inita()`.
669  *
670  * ~~~~~~~~~~{.c}
671  * as_query_select_init(&query, 2);
672  * as_query_select(&query, "bin1");
673  * as_query_select(&query, "bin2");
674  * ~~~~~~~~~~
675  *
676  * @param query The query to initialize.
677  * @param n The number of bins to allocate.
678  *
679  * @return On success, the initialized. Otherwise an error occurred.
680  *
681  * @relates as_query
682  * @ingroup query_object
683  */
684 bool as_query_select_init(as_query * query, uint16_t n);
685 
686 /**
687  * Select bins to be projected from matching records.
688  *
689  * You have to ensure as_query.select has sufficient capacity, prior to
690  * adding a bin. If capacity is sufficient then false is returned.
691  *
692  * ~~~~~~~~~~{.c}
693  * as_query_select_init(&query, 2);
694  * as_query_select(&query, "bin1");
695  * as_query_select(&query, "bin2");
696  * ~~~~~~~~~~
697  *
698  * @param query The query to modify.
699  * @param bin The name of the bin to select.
700  *
701  * @return On success, true. Otherwise an error occurred.
702  *
703  * @relates as_query
704  * @ingroup query_object
705  */
706 bool as_query_select(as_query * query, const char * bin);
707 
708 /******************************************************************************
709  * WHERE FUNCTIONS
710  *****************************************************************************/
711 
712 /**
713  * Initializes `as_query.where` with a capacity of `n` using `alloca()`.
714  *
715  * For heap allocation, use `as_query_where_init()`.
716  *
717  * ~~~~~~~~~~{.c}
718  * as_query_where_inita(&query, 3);
719  * as_query_where(&query, "bin1", as_string_equals("abc"));
720  * as_query_where(&query, "bin2", as_integer_equals(123));
721  * as_query_where(&query, "bin3", as_integer_range(0,123));
722  * ~~~~~~~~~~
723  *
724  * @param __query The query to initialize.
725  * @param __n The number of as_predicate to allocate.
726  *
727  * @return On success, true. Otherwise an error occurred.
728  *
729  * @relates as_query
730  */
731 #define as_query_where_inita(__query, __n) \
732  do { \
733  if ( (__query) != NULL && (__query)->where.entries == NULL ) {\
734  (__query)->where.entries = (as_predicate*) alloca(sizeof(as_predicate) * (__n));\
735  if ( (__query)->where.entries ) { \
736  (__query)->where._free = false;\
737  (__query)->where.capacity = (__n);\
738  (__query)->where.size = 0;\
739  }\
740  } \
741  } while(0)
742 
743 /**
744  * Initializes `as_query.where` with a capacity of `n` using `malloc()`.
745  *
746  * For stack allocation, use `as_query_where_inita()`.
747  *
748  * ~~~~~~~~~~{.c}
749  * as_query_where_init(&query, 3);
750  * as_query_where(&query, "bin1", as_string_equals("abc"));
751  * as_query_where(&query, "bin1", as_integer_equals(123));
752  * as_query_where(&query, "bin1", as_integer_range(0,123));
753  * ~~~~~~~~~~
754  *
755  * @param query The query to initialize.
756  * @param n The number of as_predicate to allocate.
757  *
758  * @return On success, true. Otherwise an error occurred.
759  *
760  * @relates as_query
761  */
762 bool as_query_where_init(as_query * query, uint16_t n);
763 
764 /**
765  * Add a predicate to the query.
766  *
767  * You have to ensure as_query.where has sufficient capacity, prior to
768  * adding a predicate. If capacity is insufficient then false is returned.
769  *
770  * String predicates are not owned by as_query. If the string is allocated
771  * on the heap, the caller is responsible for freeing the string after the query
772  * has been executed. as_query_destroy() will not free this string predicate.
773  *
774  * ~~~~~~~~~~{.c}
775  * as_query_where_init(&query, 3);
776  * as_query_where(&query, "bin1", as_string_equals("abc"));
777  * as_query_where(&query, "bin1", as_integer_equals(123));
778  * as_query_where(&query, "bin1", as_integer_range(0,123));
779  * ~~~~~~~~~~
780  *
781  * @param query The query add the predicate to.
782  * @param bin The name of the bin the predicate will apply to.
783  * @param type The type of predicate.
784  * @param itype The type of index.
785  * @param dtype The underlying data type that the index is based on.
786  * @param ... The values for the predicate.
787  *
788  * @return On success, true. Otherwise an error occurred.
789  *
790  * @relates as_query
791  */
792 bool as_query_where(as_query * query, const char * bin, as_predicate_type type, as_index_type itype, as_index_datatype dtype, ... );
793 
794 /******************************************************************************
795  * PREDEXP FUNCTIONS
796  *****************************************************************************/
797 
798 /**
799  * Initializes `as_query.predexp` with a capacity of `n` using `alloca`
800  *
801  * For heap allocation, use `as_query_predexp_init()`.
802  *
803  * ~~~~~~~~~~{.c}
804  * as_query_predexp_inita(&query, 3);
805  * as_query_predexp_add(&query, as_predexp_string_value("apple"));
806  * as_query_predexp_add(&query, as_predexp_string_bin("fruit"));
807  * as_query_predexp_add(&query, as_predexp_string_equal());
808  * ~~~~~~~~~~
809  *
810  * @param __query The query to initialize.
811  * @param __n The number of predicate expression slots to allocate.
812  *
813  * @relates as_query
814  * @ingroup query_object
815  */
816 #define as_query_predexp_inita(__query, __n) \
817  if ( (__query) != NULL && (__query)->predexp.entries == NULL ) { \
818  (__query)->predexp.entries = \
819  (as_predexp_base **) \
820  alloca(__n * sizeof(as_predexp_base *)); \
821  if ( (__query)->predexp.entries ) { \
822  (__query)->predexp._free = false; \
823  (__query)->predexp.capacity = __n; \
824  (__query)->predexp.size = 0; \
825  } \
826  }
827 
828 /**
829  * Initializes `as_query.predexp` with a capacity of `n` using `malloc()`.
830  *
831  * For stack allocation, use `as_query_predexp_inita()`.
832  *
833  * ~~~~~~~~~~{.c}
834  * as_query_predexp_init(&query, 3);
835  * as_query_predexp_add(&query, as_predexp_string_value("apple"));
836  * as_query_predexp_add(&query, as_predexp_string_bin("fruit"));
837  * as_query_predexp_add(&query, as_predexp_string_equal());
838  * ~~~~~~~~~~
839  *
840  * @param query The query to initialize.
841  * @param n The number of predicate expression slots to allocate.
842  *
843  * @return On success, the initialized. Otherwise an error occurred.
844  *
845  * @relates as_query
846  * @ingroup query_object
847  */
848 bool as_query_predexp_init(as_query * query, uint16_t n);
849 
850 /**
851  * Adds predicate expressions to a query.
852  *
853  * You have to ensure as_query.predexp has sufficient capacity, prior to
854  * adding a predexp. If capacity is sufficient then false is returned.
855  *
856  * ~~~~~~~~~~{.c}
857  * as_query_predexp_inita(&query, 3);
858  * as_query_predexp_add(&query, as_predexp_string_value("apple"));
859  * as_query_predexp_add(&query, as_predexp_string_bin("fruit"));
860  * as_query_predexp_add(&query, as_predexp_string_equal());
861  * ~~~~~~~~~~
862  *
863  * @param query The query to modify.
864  * @param predexp Pointer to a constructed predicate expression.
865  *
866  * @return On success, true. Otherwise an error occurred.
867  *
868  * @relates as_query
869  * @ingroup query_object
870  */
871 bool as_query_predexp_add(as_query * query, as_predexp_base * predexp);
872 
873 /******************************************************************************
874  * QUERY MODIFIER FUNCTIONS
875  *****************************************************************************/
876 
877 /**
878  * Apply a function to the results of the query.
879  *
880  * ~~~~~~~~~~{.c}
881  * as_query_apply(&query, "my_module", "my_function", NULL);
882  * ~~~~~~~~~~
883  *
884  * @param query The query to apply the function to.
885  * @param module The module containing the function to invoke.
886  * @param function The function in the module to invoke.
887  * @param arglist The arguments to use when calling the function.
888  *
889  * @return On success, true. Otherwise an error occurred.
890  *
891  * @relates as_query
892  */
893 bool as_query_apply(as_query * query, const char * module, const char * function, const as_list * arglist);
894 
895 #ifdef __cplusplus
896 } // end extern "C"
897 #endif