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 } as_query;
572 
573 /******************************************************************************
574  * INSTANCE FUNCTIONS
575  *****************************************************************************/
576 
577 /**
578  * Initialize a stack allocated as_query.
579  *
580  * ~~~~~~~~~~{.c}
581  * as_query query;
582  * as_query_init(&query, "test", "demo");
583  * ~~~~~~~~~~
584  *
585  * @param query The query to initialize.
586  * @param ns The namespace to query.
587  * @param set The set to query.
588  *
589  * @return On success, the initialized query. Otherwise NULL.
590  *
591  * @relates as_query
592  */
593 as_query * as_query_init(as_query * query, const as_namespace ns, const as_set set);
594 
595 /**
596  * Create and initialize a new heap allocated as_query.
597  *
598  * ~~~~~~~~~~{.c}
599  * as_query * query = as_query_new("test", "demo");
600  * ~~~~~~~~~~
601  *
602  * @param ns The namespace to query.
603  * @param set The set to query.
604  *
605  * @return On success, the new query. Otherwise NULL.
606  *
607  * @relates as_query
608  * @ingroup query_object
609  */
610 as_query * as_query_new(const as_namespace ns, const as_set set);
611 
612 /**
613  * Destroy the query and associated resources.
614  *
615  * ~~~~~~~~~~{.c}
616  * as_query_destroy(scan);
617  * ~~~~~~~~~~
618  *
619  * @param query The query to destroy.
620  *
621  * @relates as_query
622  */
623 void as_query_destroy(as_query * query);
624 
625 /******************************************************************************
626  * SELECT FUNCTIONS
627  *****************************************************************************/
628 
629 /**
630  * Initializes `as_query.select` with a capacity of `n` using `alloca`
631  *
632  * For heap allocation, use `as_query_select_init()`.
633  *
634  * ~~~~~~~~~~{.c}
635  * as_query_select_inita(&query, 2);
636  * as_query_select(&query, "bin1");
637  * as_query_select(&query, "bin2");
638  * ~~~~~~~~~~
639  *
640  * @param __query The query to initialize.
641  * @param __n The number of bins to allocate.
642  *
643  * @relates as_query
644  * @ingroup query_object
645  */
646 #define as_query_select_inita(__query, __n) \
647  do { \
648  if ( (__query) != NULL && (__query)->select.entries == NULL ) {\
649  (__query)->select.entries = (as_bin_name*) alloca(sizeof(as_bin_name) * (__n));\
650  if ( (__query)->select.entries ) { \
651  (__query)->select._free = false;\
652  (__query)->select.capacity = (__n);\
653  (__query)->select.size = 0;\
654  }\
655  } \
656  } while(0)
657 
658 /**
659  * Initializes `as_query.select` with a capacity of `n` using `malloc()`.
660  *
661  * For stack allocation, use `as_query_select_inita()`.
662  *
663  * ~~~~~~~~~~{.c}
664  * as_query_select_init(&query, 2);
665  * as_query_select(&query, "bin1");
666  * as_query_select(&query, "bin2");
667  * ~~~~~~~~~~
668  *
669  * @param query The query to initialize.
670  * @param n The number of bins to allocate.
671  *
672  * @return On success, the initialized. Otherwise an error occurred.
673  *
674  * @relates as_query
675  * @ingroup query_object
676  */
677 bool as_query_select_init(as_query * query, uint16_t n);
678 
679 /**
680  * Select bins to be projected from matching records.
681  *
682  * You have to ensure as_query.select has sufficient capacity, prior to
683  * adding a bin. If capacity is sufficient then false is returned.
684  *
685  * ~~~~~~~~~~{.c}
686  * as_query_select_init(&query, 2);
687  * as_query_select(&query, "bin1");
688  * as_query_select(&query, "bin2");
689  * ~~~~~~~~~~
690  *
691  * @param query The query to modify.
692  * @param bin The name of the bin to select.
693  *
694  * @return On success, true. Otherwise an error occurred.
695  *
696  * @relates as_query
697  * @ingroup query_object
698  */
699 bool as_query_select(as_query * query, const char * bin);
700 
701 /******************************************************************************
702  * WHERE FUNCTIONS
703  *****************************************************************************/
704 
705 /**
706  * Initializes `as_query.where` with a capacity of `n` using `alloca()`.
707  *
708  * For heap allocation, use `as_query_where_init()`.
709  *
710  * ~~~~~~~~~~{.c}
711  * as_query_where_inita(&query, 3);
712  * as_query_where(&query, "bin1", as_string_equals("abc"));
713  * as_query_where(&query, "bin2", as_integer_equals(123));
714  * as_query_where(&query, "bin3", as_integer_range(0,123));
715  * ~~~~~~~~~~
716  *
717  * @param __query The query to initialize.
718  * @param __n The number of as_predicate to allocate.
719  *
720  * @return On success, true. Otherwise an error occurred.
721  *
722  * @relates as_query
723  */
724 #define as_query_where_inita(__query, __n) \
725  do { \
726  if ( (__query) != NULL && (__query)->where.entries == NULL ) {\
727  (__query)->where.entries = (as_predicate*) alloca(sizeof(as_predicate) * (__n));\
728  if ( (__query)->where.entries ) { \
729  (__query)->where._free = false;\
730  (__query)->where.capacity = (__n);\
731  (__query)->where.size = 0;\
732  }\
733  } \
734  } while(0)
735 
736 /**
737  * Initializes `as_query.where` with a capacity of `n` using `malloc()`.
738  *
739  * For stack allocation, use `as_query_where_inita()`.
740  *
741  * ~~~~~~~~~~{.c}
742  * as_query_where_init(&query, 3);
743  * as_query_where(&query, "bin1", as_string_equals("abc"));
744  * as_query_where(&query, "bin1", as_integer_equals(123));
745  * as_query_where(&query, "bin1", as_integer_range(0,123));
746  * ~~~~~~~~~~
747  *
748  * @param query The query to initialize.
749  * @param n The number of as_predicate to allocate.
750  *
751  * @return On success, true. Otherwise an error occurred.
752  *
753  * @relates as_query
754  */
755 bool as_query_where_init(as_query * query, uint16_t n);
756 
757 /**
758  * Add a predicate to the query.
759  *
760  * You have to ensure as_query.where has sufficient capacity, prior to
761  * adding a predicate. If capacity is insufficient then false is returned.
762  *
763  * String predicates are not owned by as_query. If the string is allocated
764  * on the heap, the caller is responsible for freeing the string after the query
765  * has been executed. as_query_destroy() will not free this string predicate.
766  *
767  * ~~~~~~~~~~{.c}
768  * as_query_where_init(&query, 3);
769  * as_query_where(&query, "bin1", as_string_equals("abc"));
770  * as_query_where(&query, "bin1", as_integer_equals(123));
771  * as_query_where(&query, "bin1", as_integer_range(0,123));
772  * ~~~~~~~~~~
773  *
774  * @param query The query add the predicate to.
775  * @param bin The name of the bin the predicate will apply to.
776  * @param type The type of predicate.
777  * @param itype The type of index.
778  * @param dtype The underlying data type that the index is based on.
779  * @param ... The values for the predicate.
780  *
781  * @return On success, true. Otherwise an error occurred.
782  *
783  * @relates as_query
784  */
785 bool as_query_where(as_query * query, const char * bin, as_predicate_type type, as_index_type itype, as_index_datatype dtype, ... );
786 
787 /******************************************************************************
788  * PREDEXP FUNCTIONS
789  *****************************************************************************/
790 
791 /**
792  * Initializes `as_query.predexp` with a capacity of `n` using `alloca`
793  *
794  * For heap allocation, use `as_query_predexp_init()`.
795  *
796  * ~~~~~~~~~~{.c}
797  * as_query_predexp_inita(&query, 3);
798  * as_query_predexp_add(&query, as_predexp_string_value("apple"));
799  * as_query_predexp_add(&query, as_predexp_string_bin("fruit"));
800  * as_query_predexp_add(&query, as_predexp_string_equal());
801  * ~~~~~~~~~~
802  *
803  * @param __query The query to initialize.
804  * @param __n The number of predicate expression slots to allocate.
805  *
806  * @relates as_query
807  * @ingroup query_object
808  */
809 #define as_query_predexp_inita(__query, __n) \
810  if ( (__query) != NULL && (__query)->predexp.entries == NULL ) { \
811  (__query)->predexp.entries = \
812  (as_predexp_base **) \
813  alloca(__n * sizeof(as_predexp_base *)); \
814  if ( (__query)->predexp.entries ) { \
815  (__query)->predexp._free = false; \
816  (__query)->predexp.capacity = __n; \
817  (__query)->predexp.size = 0; \
818  } \
819  }
820 
821 /**
822  * Initializes `as_query.predexp` with a capacity of `n` using `malloc()`.
823  *
824  * For stack allocation, use `as_query_predexp_inita()`.
825  *
826  * ~~~~~~~~~~{.c}
827  * as_query_predexp_init(&query, 3);
828  * as_query_predexp_add(&query, as_predexp_string_value("apple"));
829  * as_query_predexp_add(&query, as_predexp_string_bin("fruit"));
830  * as_query_predexp_add(&query, as_predexp_string_equal());
831  * ~~~~~~~~~~
832  *
833  * @param query The query to initialize.
834  * @param n The number of predicate expression slots to allocate.
835  *
836  * @return On success, the initialized. Otherwise an error occurred.
837  *
838  * @relates as_query
839  * @ingroup query_object
840  */
841 bool as_query_predexp_init(as_query * query, uint16_t n);
842 
843 /**
844  * Adds predicate expressions to a query.
845  *
846  * You have to ensure as_query.predexp has sufficient capacity, prior to
847  * adding a predexp. If capacity is sufficient then false is returned.
848  *
849  * ~~~~~~~~~~{.c}
850  * as_query_predexp_inita(&query, 3);
851  * as_query_predexp_add(&query, as_predexp_string_value("apple"));
852  * as_query_predexp_add(&query, as_predexp_string_bin("fruit"));
853  * as_query_predexp_add(&query, as_predexp_string_equal());
854  * ~~~~~~~~~~
855  *
856  * @param query The query to modify.
857  * @param predexp Pointer to a constructed predicate expression.
858  *
859  * @return On success, true. Otherwise an error occurred.
860  *
861  * @relates as_query
862  * @ingroup query_object
863  */
864 bool as_query_predexp_add(as_query * query, as_predexp_base * predexp);
865 
866 /******************************************************************************
867  * QUERY MODIFIER FUNCTIONS
868  *****************************************************************************/
869 
870 /**
871  * Apply a function to the results of the query.
872  *
873  * ~~~~~~~~~~{.c}
874  * as_query_apply(&query, "my_module", "my_function", NULL);
875  * ~~~~~~~~~~
876  *
877  * @param query The query to apply the function to.
878  * @param module The module containing the function to invoke.
879  * @param function The function in the module to invoke.
880  * @param arglist The arguments to use when calling the function.
881  *
882  * @return On success, true. Otherwise an error occurred.
883  *
884  * @relates as_query
885  */
886 bool as_query_apply(as_query * query, const char * module, const char * function, const as_list * arglist);
887 
888 #ifdef __cplusplus
889 } // end extern "C"
890 #endif