All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_exp.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2023 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 
19 /**
20  * @defgroup expression Expression Filters
21  *
22  * Expression filters are applied on each applicable server record.
23  * Expression filters require server version >= 5.2.0.4.
24  *
25  * If the filter exists and evaluates to false in a single record transaction,
26  * the transaction is ignored and AEROSPIKE_FILTERED_OUT is returned as an error code.
27  *
28  * If the filter exists and evaluates to false in a batch record row, AEROSPIKE_FILTERED_OUT
29  * is returned as a status for that record row in the batch.
30  *
31  * If the filter exists and evaluates to false on a scan/query record, that record is not
32  * returned.
33  *
34  * Expression filters can now be defined on all transactions through the transaction policy
35  * (as_policy_base contained in as_policy_read, as_policy_write, ...).
36  *
37  * Example:
38  * ~~~~~~~~~~{.c}
39  * as_exp_build(filter,
40  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(10)));
41  *
42  * as_policy_read p;
43  * as_policy_read_init(&p);
44  * p.filter_exp = filter;
45  * ...
46  * as_exp_destroy(filter);
47  * ~~~~~~~~~~
48  */
49 
55 #include <aerospike/as_nil.h>
56 #include <aerospike/as_std.h>
57 
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61 
62 /******************************************************************************
63  * TYPES
64  *****************************************************************************/
65 
66 typedef enum {
67  _AS_EXP_CODE_UNKNOWN = 0,
68 
69  _AS_EXP_CODE_CMP_EQ = 1,
70  _AS_EXP_CODE_CMP_NE = 2,
71  _AS_EXP_CODE_CMP_GT = 3,
72  _AS_EXP_CODE_CMP_GE = 4,
73  _AS_EXP_CODE_CMP_LT = 5,
74  _AS_EXP_CODE_CMP_LE = 6,
75 
76  _AS_EXP_CODE_CMP_REGEX = 7,
77  _AS_EXP_CODE_CMP_GEO = 8,
78 
79  _AS_EXP_CODE_AND = 16,
80  _AS_EXP_CODE_OR = 17,
81  _AS_EXP_CODE_NOT = 18,
82  _AS_EXP_CODE_EXCLUSIVE = 19,
83 
84  _AS_EXP_CODE_ADD = 20,
85  _AS_EXP_CODE_SUB = 21,
86  _AS_EXP_CODE_MUL = 22,
87  _AS_EXP_CODE_DIV = 23,
88  _AS_EXP_CODE_POW = 24,
89  _AS_EXP_CODE_LOG = 25,
90  _AS_EXP_CODE_MOD = 26,
91  _AS_EXP_CODE_ABS = 27,
92  _AS_EXP_CODE_FLOOR = 28,
93  _AS_EXP_CODE_CEIL = 29,
94 
95  _AS_EXP_CODE_TO_INT = 30,
96  _AS_EXP_CODE_TO_FLOAT = 31,
97 
98  _AS_EXP_CODE_INT_AND = 32,
99  _AS_EXP_CODE_INT_OR = 33,
100  _AS_EXP_CODE_INT_XOR = 34,
101  _AS_EXP_CODE_INT_NOT = 35,
102  _AS_EXP_CODE_INT_LSHIFT = 36,
103  _AS_EXP_CODE_INT_RSHIFT = 37,
104  _AS_EXP_CODE_INT_ARSHIFT = 38,
105  _AS_EXP_CODE_INT_COUNT = 39,
106  _AS_EXP_CODE_INT_LSCAN = 40,
107  _AS_EXP_CODE_INT_RSCAN = 41,
108 
109  _AS_EXP_CODE_MIN = 50,
110  _AS_EXP_CODE_MAX = 51,
111 
112  _AS_EXP_CODE_DIGEST_MODULO = 64,
113  _AS_EXP_CODE_DEVICE_SIZE = 65,
114  _AS_EXP_CODE_LAST_UPDATE = 66,
115  _AS_EXP_CODE_SINCE_UPDATE = 67,
116  _AS_EXP_CODE_VOID_TIME = 68,
117  _AS_EXP_CODE_TTL = 69,
118  _AS_EXP_CODE_SET_NAME = 70,
119  _AS_EXP_CODE_KEY_EXIST = 71,
120  _AS_EXP_CODE_IS_TOMBSTONE = 72,
121  _AS_EXP_CODE_MEMORY_SIZE = 73,
122  _AS_EXP_CODE_RECORD_SIZE = 74,
123 
124  _AS_EXP_CODE_KEY = 80,
125  _AS_EXP_CODE_BIN = 81,
126  _AS_EXP_CODE_BIN_TYPE = 82,
127 
128  _AS_EXP_CODE_COND = 123,
129  _AS_EXP_CODE_VAR = 124,
130  _AS_EXP_CODE_LET = 125,
131  _AS_EXP_CODE_QUOTE = 126,
132  _AS_EXP_CODE_CALL = 127,
133 
134  // Begin virtual ops, these do not go on the wire.
135  _AS_EXP_CODE_AS_VAL,
136  _AS_EXP_CODE_VAL_GEO,
137  _AS_EXP_CODE_VAL_PK,
138  _AS_EXP_CODE_VAL_INT,
139  _AS_EXP_CODE_VAL_UINT,
140  _AS_EXP_CODE_VAL_FLOAT,
141  _AS_EXP_CODE_VAL_BOOL,
142  _AS_EXP_CODE_VAL_STR,
143  _AS_EXP_CODE_VAL_BYTES,
144  _AS_EXP_CODE_VAL_RAWSTR,
145  _AS_EXP_CODE_VAL_RTYPE,
146 
147  _AS_EXP_CODE_CALL_VOP_START,
148  _AS_EXP_CODE_CDT_LIST_CRMOD,
149  _AS_EXP_CODE_CDT_LIST_MOD,
150  _AS_EXP_CODE_CDT_MAP_CRMOD,
151  _AS_EXP_CODE_CDT_MAP_CR,
152  _AS_EXP_CODE_CDT_MAP_MOD,
153  _AS_EXP_CODE_MERGE,
154 
155  _AS_EXP_CODE_END_OF_VA_ARGS
156 } as_exp_ops;
157 
158 typedef enum {
159  _AS_EXP_SYS_CALL_CDT = 0,
160  _AS_EXP_SYS_CALL_BITS = 1,
161  _AS_EXP_SYS_CALL_HLL = 2,
162 
163  _AS_EXP_SYS_FLAG_MODIFY_LOCAL = 0x40
165 
166 typedef enum {
177 
180 } as_exp_type;
181 
182 typedef struct as_exp {
183  uint32_t packed_sz;
184  uint8_t packed[];
185 } as_exp;
186 
187 typedef struct {
189  uint32_t count;
190  uint32_t sz;
191  int32_t prev_va_args;
192 
193  union {
195  const char* str_val;
196  uint8_t* bytes_val;
197  int64_t int_val;
198  uint64_t uint_val;
199  double float_val;
200  bool bool_val;
201 
202  as_cdt_ctx* ctx; // for CALL
203  as_list_policy* list_pol; // for LIST_POL_*
206  } v;
207 } as_exp_entry;
208 
209 /*********************************************************************************
210  * PRIVATE FUNCTIONS
211  *********************************************************************************/
212 
213 AS_EXTERN as_exp* as_exp_compile(as_exp_entry* table, uint32_t n);
215 AS_EXTERN void as_exp_destroy_b64(char* b64);
216 AS_EXTERN uint8_t* as_exp_write(as_exp* exp, uint8_t* ptr);
217 AS_EXTERN int64_t as_exp_get_ctx_type(const as_cdt_ctx* ctx, as_exp_type default_type);
218 AS_EXTERN int64_t as_exp_get_list_type(as_exp_type default_type, as_list_return_type rtype, bool is_multi);
219 AS_EXTERN int64_t as_exp_get_map_type(as_exp_type type, as_map_return_type rtype, bool is_multi);
220 
221 /*********************************************************************************
222  * PUBLIC FUNCTIONS
223  *********************************************************************************/
224 
225 /**
226  * Encode expression to null-terminated base64 string.
227  * Call as_exp_destroy_base64() when done with base64 string.
228  *
229  * @ingroup expression
230  */
231 static inline char*
233 {
234  return as_exp_compile_b64(exp);
235 }
236 
237 /**
238  * Decode null-terminated base64 string to expression.
239  * Call as_exp_destroy() when done with expression.
240  *
241  * @ingroup expression
242  */
243 AS_EXTERN as_exp* as_exp_from_base64(const char* base64);
244 
245 /**
246  * Free expression bytes.
247  *
248  * @ingroup expression
249  */
250 AS_EXTERN void as_exp_destroy(as_exp* exp);
251 
252 /**
253  * Free base64 string.
254  *
255  * @ingroup expression
256  */
257 static inline void
259 {
260  as_exp_destroy_b64(base64);
261 }
262 
263 /*********************************************************************************
264  * VALUE EXPRESSIONS
265  *********************************************************************************/
266 
267 /**
268  * Create an 'unknown' value. Used to intentionally fail an expression.
269  * The failure can be ignored with AS_EXP_WRITE_EVAL_NO_FAIL or
270  * AS_EXP_READ_NO_FAIL.
271  * Requires server version 5.6.0+.
272  *
273  * ~~~~~~~~~~{.c}
274  * // If var("v") (bin("balance") - 100.0) is greater that or equal to 0.0 then
275  * // return var("v") else fail operation.
276  * as_exp_build(expression,
277  * as_exp_let(
278  * as_exp_def("v", as_exp_sub(
279  * as_exp_bin_float("balance"), as_exp_float(100.0))),
280  * as_exp_cond(
281  * as_exp_ge(as_exp_var("v"), as_exp_float(0)), as_exp_var("v"),
282  * as_exp_unknown())));
283  * ~~~~~~~~~~
284  *
285  * @return (unknown value)
286  * @ingroup expression
287  */
288 #define as_exp_unknown() {.op=_AS_EXP_CODE_UNKNOWN, .count=1}
289 
290 /**
291  * Create boolean value.
292  *
293  * @param __val boolean value.
294  * @ingroup expression
295  */
296 #define as_exp_bool(__val) {.op=_AS_EXP_CODE_VAL_BOOL, .v.bool_val=__val}
297 
298 /**
299  * Create 64 bit signed integer value.
300  *
301  * @param __val integer value.
302  * @ingroup expression
303  */
304 #define as_exp_int(__val) {.op=_AS_EXP_CODE_VAL_INT, .v.int_val=__val}
305 
306 /**
307  * Create 64 bit unsigned integer value.
308  *
309  * @param __val unsigned integer value.
310  * @ingroup expression
311  */
312 #define as_exp_uint(__val) {.op=_AS_EXP_CODE_VAL_UINT, .v.uint_val=__val}
313 
314 /**
315  * Create 64 bit floating point value.
316  *
317  * @param __val floating point value.
318  * @ingroup expression
319  */
320 #define as_exp_float(__val) {.op=_AS_EXP_CODE_VAL_FLOAT, .v.float_val=__val}
321 
322 /**
323  * Create string value.
324  *
325  * @param __val string value.
326  * @ingroup expression
327  */
328 #define as_exp_str(__val) {.op=_AS_EXP_CODE_VAL_STR, .v.str_val=__val}
329 
330 /**
331  * Create byte array value.
332  *
333  * @param __val byte array value.
334  * @param __size number of bytes.
335  * @ingroup expression
336  */
337 #define as_exp_bytes(__val, __size) {.op=_AS_EXP_CODE_VAL_BYTES, .sz=__size, .v.bytes_val=__val}
338 
339 /**
340  * Create geojson value.
341  *
342  * @param __val geojson value.
343  * @ingroup expression
344  */
345 #define as_exp_geo(__val) {.op=_AS_EXP_CODE_VAL_GEO, .v.val=(as_val*)as_geojson_new(__val, false)}
346 
347 /**
348  * Create value from an as_val.
349  *
350  * @param __val as_val value.
351  * @ingroup expression
352  */
353 #define as_exp_val(__val) {.op=_AS_EXP_CODE_AS_VAL, .v.val=(as_val*)(__val)}
354 
355 /**
356  * Create 'nil' value.
357  * @ingroup expression
358  */
359 #define as_exp_nil() as_exp_val(&as_nil)
360 
361 /**
362  * Create infinity value.
363  * @ingroup expression
364  */
365 #define as_exp_inf() as_exp_val(&as_cmp_inf)
366 
367 /**
368  * Create wildcard value.
369  * @ingroup expression
370  */
371 #define as_exp_wildcard() as_exp_val(&as_cmp_wildcard)
372 
373 /*********************************************************************************
374  * KEY EXPRESSIONS
375  *********************************************************************************/
376 
377 /**
378  * Create expression that returns the key as an integer. Returns 'unknown' if
379  * the key is not an integer.
380  *
381  * ~~~~~~~~~~{.c}
382  * // Integer record key >= 10000
383  * as_exp_build(expression,
384  * as_exp_cmp_ge(as_exp_key_int(), as_exp_int(10000)));
385  * ~~~~~~~~~~
386  *
387  * @return (integer value) Integer value of the key if the key is an integer.
388  * @ingroup expression
389  */
390 #define as_exp_key_int() {.op=_AS_EXP_CODE_KEY, .count=2}, \
391  as_exp_int(AS_EXP_TYPE_INT)
392 
393 /**
394  * Create expression that returns the key as an string. Returns 'unknown' if
395  * the key is not a string.
396  *
397  * ~~~~~~~~~~{.c}
398  * // String record key == "aaa"
399  * as_exp_build(expression,
400  * as_exp_cmp_eq(as_exp_key_str(), as_exp_str("aaa")));
401  * ~~~~~~~~~~
402  *
403  * @return (string value) String value of the key if the key is a string.
404  * @ingroup expression
405  */
406 #define as_exp_key_str() {.op=_AS_EXP_CODE_KEY, .count=2}, \
407  as_exp_int(AS_EXP_TYPE_STR)
408 
409 /**
410  * Create expression that returns the key as an blob. Returns 'unknown' if
411  * the key is not an blob.
412  *
413  * ~~~~~~~~~~{.c}
414  * // Blob record key <= { 0x65, 0x65 }
415  * uint8_t val[] = {0x65, 0x65}
416  * as_exp_build(expression,
417  * as_exp_cmp_le(as_exp_key_blob(), as_exp_bytes(val, sizeof(val))));
418  * ~~~~~~~~~~
419  *
420  * @return (blob value) Blob value of the key if the key is a blob.
421  * @ingroup expression
422  */
423 #define as_exp_key_blob() {.op=_AS_EXP_CODE_KEY, .count=2}, \
424  as_exp_int(AS_EXP_TYPE_BLOB)
425 
426 /**
427  * Create expression that returns if the primary key is stored in the record meta
428  * data as a boolean expression. This would occur when "as_policy_write.key" is
429  * AS_POLICY_KEY_SEND on record write.
430  *
431  * ~~~~~~~~~~{.c}
432  * // Key exists in record meta data
433  * as_exp_build(expression, as_exp_key_exists());
434  * ~~~~~~~~~~
435  *
436  * @return (boolean value) True if the record has a stored key, false otherwise.
437  * @ingroup expression
438  */
439 #define as_exp_key_exist() {.op=_AS_EXP_CODE_KEY_EXIST, .count=1}
440 
441 /*********************************************************************************
442  * BIN EXPRESSIONS
443  *********************************************************************************/
444 
445 #define _AS_EXP_VAL_RAWSTR(__val) {.op=_AS_EXP_CODE_VAL_RAWSTR, .v.str_val=__val}
446 
447 /**
448  * Create expression that returns a bin as a boolean value. Returns 'unknown'
449  * if the bin is not a boolean.
450  *
451  * ~~~~~~~~~~{.c}
452  * // Check if the value in bin "a" is true.
453  * as_exp_build(expression, as_exp_bin_bool("a"));
454  * ~~~~~~~~~~
455  *
456  * @param __bin_name Bin name.
457  * @return (boolean bin)
458  * @ingroup expression
459  */
460 #define as_exp_bin_bool(__bin_name) \
461  {.op=_AS_EXP_CODE_BIN, .count=3}, \
462  as_exp_int(AS_EXP_TYPE_BOOL), \
463  _AS_EXP_VAL_RAWSTR(__bin_name)
464 
465 /**
466  * Create expression that returns a bin as a signed integer. Returns 'unknown'
467  * if the bin is not an integer.
468  *
469  * ~~~~~~~~~~{.c}
470  * // Integer bin "a" == 200
471  * as_exp_build(expression,
472  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(200)));
473  * ~~~~~~~~~~
474  *
475  * @param __bin_name Bin name.
476  * @return (integer bin)
477  * @ingroup expression
478  */
479 #define as_exp_bin_int(__bin_name) \
480  {.op=_AS_EXP_CODE_BIN, .count=3}, \
481  as_exp_int(AS_EXP_TYPE_INT), \
482  _AS_EXP_VAL_RAWSTR(__bin_name)
483 
484 /**
485  * Create expression that returns a bin as a float. Returns 'unknown' if the bin
486  * is not an float.
487  *
488  * ~~~~~~~~~~{.c}
489  * // Float bin "a" >= 2.71
490  * as_exp_build(expression,
491  * as_exp_cmp_ge(as_exp_bin_int("a"), as_exp_float(2.71)));
492  * ~~~~~~~~~~
493  *
494  * @param __bin_name Bin name.
495  * @return (float bin)
496  * @ingroup expression
497  */
498 #define as_exp_bin_float(__bin_name) \
499  {.op=_AS_EXP_CODE_BIN, .count=3}, \
500  as_exp_int(AS_EXP_TYPE_FLOAT), \
501  _AS_EXP_VAL_RAWSTR(__bin_name)
502 
503 /**
504  * Create expression that returns a bin as a string. Returns 'unknown' if the
505  * bin is not an string.
506  *
507  * ~~~~~~~~~~{.c}
508  * // String bin "a" == "b"
509  * as_exp_build(expression,
510  * as_exp_cmp_eq(as_exp_bin_str("a"), as_exp_str("b")));
511  * ~~~~~~~~~~
512  *
513  * @param __bin_name Bin name.
514  * @return (string bin)
515  * @ingroup expression
516  */
517 #define as_exp_bin_str(__bin_name) \
518  {.op=_AS_EXP_CODE_BIN, .count=3}, \
519  as_exp_int(AS_EXP_TYPE_STR), \
520  _AS_EXP_VAL_RAWSTR(__bin_name)
521 
522 /**
523  * Create expression that returns a bin as a blob. Returns 'unknown' if the bin
524  * is not an blob.
525  *
526  * ~~~~~~~~~~{.c}
527  * // Integer bin "a" == { 0x65, 0x65 }
528  * uint8_t val[] = {0x65, 0x65}
529  * as_exp_build(expression,
530  * as_exp_cmp_eq(as_exp_bin_blob("a"), as_exp_bytes(val, sizeof(val))));
531  * ~~~~~~~~~~
532  *
533  * @param __bin_name Bin name.
534  * @return (blob bin)
535  * @ingroup expression
536  */
537 #define as_exp_bin_blob(__bin_name) \
538  {.op=_AS_EXP_CODE_BIN, .count=3}, \
539  as_exp_int(AS_EXP_TYPE_BLOB), \
540  _AS_EXP_VAL_RAWSTR(__bin_name)
541 
542 /**
543  * Create expression that returns a bin as a geojson. Returns 'unknown' if the
544  * bin is not geojson.
545  *
546  * ~~~~~~~~~~{.c}
547  * // GeoJSON bin "a" contained by GeoJSON bin "b"
548  * as_exp_build(expression,
549  * as_exp_cmp_geo(as_exp_bin_geo("a"), as_exp_bin_geo("b")));
550  * ~~~~~~~~~~
551  *
552  * @param __bin_name Bin name.
553  * @return (geojson bin)
554  * @ingroup expression
555  */
556 #define as_exp_bin_geo(__bin_name) \
557  {.op=_AS_EXP_CODE_BIN, .count=3}, \
558  as_exp_int(AS_EXP_TYPE_GEOJSON), \
559  _AS_EXP_VAL_RAWSTR(__bin_name)
560 
561 /**
562  * Create expression that returns a bin as a list. Returns 'unknown' if the bin
563  * is not an list.
564  *
565  * ~~~~~~~~~~{.c}
566  * // List bin "a" contains at least one item == "abc"
567  * as_exp_build(filter,
568  * as_exp_cmp_gt(
569  * as_exp_list_get_by_value(NULL, AS_LIST_RETURN_COUNT,
570  * as_exp_str("abc"), as_exp_bin_list("a")),
571  * as_exp_int(0)));
572  * ~~~~~~~~~~
573  *
574  * @param __bin_name Bin name.
575  * @return (list bin)
576  * @ingroup expression
577  */
578 #define as_exp_bin_list(__bin_name) \
579  {.op=_AS_EXP_CODE_BIN, .count=3}, \
580  as_exp_int(AS_EXP_TYPE_LIST), \
581  _AS_EXP_VAL_RAWSTR(__bin_name)
582 
583 /**
584  * Create expression that returns a bin as a map. Returns 'unknown' if the bin
585  * is not an map.
586  *
587  * ~~~~~~~~~~{.c}
588  * // Map bin "a" size > 7.
589  * as_exp_build(expression,
590  * as_exp_cmp_gt(as_exp_map_size(NULL, as_exp_bin_map("a")),
591  * as_exp_int(7)));
592  * ~~~~~~~~~~
593  *
594  * @param __bin_name Bin name.
595  * @return (map bin)
596  * @ingroup expression
597  */
598 #define as_exp_bin_map(__bin_name) \
599  {.op=_AS_EXP_CODE_BIN, .count=3}, \
600  as_exp_int(AS_EXP_TYPE_MAP), \
601  _AS_EXP_VAL_RAWSTR(__bin_name)
602 
603 /**
604  * Create expression that returns a bin as a HyperLogLog (hll). Returns
605  * 'unknown' if the bin is not a HyperLogLog (hll).
606  *
607  * ~~~~~~~~~~{.c}
608  * // HLL bin "a" have an hll_count > 1000000
609  * as_exp_build(expression,
610  * as_exp_cmp_gt(as_exp_hll_get_count(AS_BIN_HLL("a")),
611  * as_exp_int(1000000)));
612  * ~~~~~~~~~~
613  *
614  * @param __bin_name Bin name.
615  * @return (hll bin)
616  * @ingroup expression
617  */
618 #define as_exp_bin_hll(__bin_name) \
619  {.op=_AS_EXP_CODE_BIN, .count=3}, \
620  as_exp_int(AS_EXP_TYPE_HLL), \
621  _AS_EXP_VAL_RAWSTR(__bin_name)
622 
623 /**
624  * Create expression that returns if bin of specified name exists.
625  *
626  * ~~~~~~~~~~{.c}
627  * // Bin "a" exists in record.
628  * as_exp_build(expression, as_exp_bin_exists("a"));
629  * ~~~~~~~~~~
630  *
631  * @param __bin_name Bin name.
632  * @return (boolean value) True if the bin exists, false otherwise.
633  * @ingroup expression
634  */
635 #define as_exp_bin_exists(__bin_name) \
636  as_exp_cmp_ne(as_exp_bin_type(__bin_name), as_exp_int(AS_BYTES_UNDEF))
637 
638 /**
639  * Create expression that returns the type of a bin as a integer.
640  *
641  * ~~~~~~~~~~{.c}
642  * // bin "a" == type.string
643  * as_exp_build(expression,
644  * as_exp_cmp_eq(as_exp_bin_type("a"), as_exp_int(AS_BYTES_STRING)));
645  * ~~~~~~~~~~
646  *
647  * @param __bin_name Bin name.
648  * @return (integer value) returns the bin_type as an as_bytes_type.
649  * @ingroup expression
650  */
651 #define as_exp_bin_type(__bin_name) \
652  {.op=_AS_EXP_CODE_BIN_TYPE, .count=2}, \
653  _AS_EXP_VAL_RAWSTR(__bin_name)
654 
655 /*********************************************************************************
656  * METADATA EXPRESSIONS
657  *********************************************************************************/
658 
659 /**
660  * Create expression that returns record set name string. This expression usually
661  * evaluates quickly because record meta data is cached in memory.
662  *
663  * ~~~~~~~~~~{.c}
664  * // Record set name == "myset"
665  * as_exp_build(expression,
666  * as_exp_cmp_eq(as_exp_set_name(), as_exp_str("myset")));
667  * ~~~~~~~~~~
668  *
669  * @return (string value) Name of the set this record belongs to.
670  * @ingroup expression
671  */
672 #define as_exp_set_name() {.op=_AS_EXP_CODE_SET_NAME, .count=1}
673 
674 /**
675  * Create expression that returns the record size. This expression usually evaluates
676  * quickly because record meta data is cached in memory.
677  *
678  * Requires server version 7.0+. This expression replaces as_exp_device_size() and
679  * as_exp_memory_size().
680  *
681  * ~~~~~~~~~~{.c}
682  * // Record size >= 100 KB
683  * as_exp_build(expression,
684  * as_exp_cmp_ge(as_exp_record_size(), as_exp_int(100 * 1024)));
685  * ~~~~~~~~~~
686  *
687  * @return (integer value) Uncompressed size of the record.
688  * @ingroup expression
689  */
690 #define as_exp_record_size() {.op=_AS_EXP_CODE_RECORD_SIZE, .count=1}
691 
692 /**
693  * Create expression that returns record size on disk. If server storage-engine is
694  * memory, then zero is returned. This expression usually evaluates quickly
695  * because record meta data is cached in memory.
696  *
697  * This expression should only be used for server versions less than 7.0. Use
698  * as_exp_record_size() for server version 7.0+.
699  *
700  * ~~~~~~~~~~{.c}
701  * // Record device size >= 100 KB
702  * as_exp_build(expression,
703  * as_exp_cmp_ge(as_exp_device_size(), as_exp_int(100 * 1024)));
704  * ~~~~~~~~~~
705  *
706  * @return (integer value) Uncompressed storage size of the record.
707  * @ingroup expression
708  */
709 #define as_exp_device_size() {.op=_AS_EXP_CODE_DEVICE_SIZE, .count=1}
710 
711 /**
712  * Create expression that returns record last update time expressed as 64 bit
713  * integer nanoseconds since 1970-01-01 epoch.
714  *
715  * ~~~~~~~~~~{.c}
716  * // Record last update time >= 2020-01-15
717  * as_exp_build(expression,
718  * as_exp_cmp_ge(as_exp_last_update(), as_exp_uint(1577836800)));
719  * ~~~~~~~~~~
720  *
721  * @return (integer value) When the record was last updated.
722  * @ingroup expression
723  */
724 #define as_exp_last_update() {.op=_AS_EXP_CODE_LAST_UPDATE, .count=1}
725 
726 /**
727  * Create expression that returns milliseconds since the record was last updated.
728  * This expression usually evaluates quickly because record meta data is cached
729  * in memory.
730  *
731  * ~~~~~~~~~~{.c}
732  * // Record last updated more than 2 hours ago
733  * as_exp_build(expression,
734  * as_exp_cmp_gt(as_exp_since_update(),
735  * as_exp_int(2 * 60 * 60 * 1000)))
736  * ~~~~~~~~~~
737  *
738  * @return (integer value) Number of milliseconds since last updated.
739  * @ingroup expression
740  */
741 #define as_exp_since_update() {.op=_AS_EXP_CODE_SINCE_UPDATE, .count=1}
742 
743 /**
744  * Create expression that returns record expiration time expressed as 64 bit
745  * integer nanoseconds since 1970-01-01 epoch.
746  *
747  * ~~~~~~~~~~{.c}
748  * // Record expires on 2021-01-01
749  * as_exp_build(expression,
750  * as_exp_and(
751  * as_exp_cmp_ge(as_exp_void_time(), as_exp_int(1609459200)),
752  * as_exp_cmp_lt(as_exp_void_time(), as_exp_int(1609545600))));
753  * ~~~~~~~~~~
754  *
755  * @return (integer value) Expiration time in nanoseconds since 1970-01-01.
756  * @ingroup expression
757  */
758 #define as_exp_void_time() {.op=_AS_EXP_CODE_VOID_TIME, .count=1}
759 
760 /**
761  * Create expression that returns record expiration time (time to live) in integer
762  * seconds.
763  *
764  * ~~~~~~~~~~{.c}
765  * // Record expires in less than 1 hour
766  * as_exp_build(expression,
767  * as_exp_cmp_lt(as_exp_ttl(), as_exp_int(60 * 60)));
768  * ~~~~~~~~~~
769  *
770  * @return (integer value) Number of seconds till the record will expire,
771  * returns -1 if the record never expires.
772  * @ingroup expression
773  */
774 #define as_exp_ttl() {.op=_AS_EXP_CODE_TTL, .count=1}
775 
776 /**
777  * Create expression that returns if record has been deleted and is still in
778  * tombstone state. This expression usually evaluates quickly because record
779  * meta data is cached in memory.
780  *
781  * Note - this is only useful for XDR filters.
782  *
783  * ~~~~~~~~~~{.c}
784  * // Deleted records that are in tombstone state.
785  * as_exp_build(expression, as_exp_is_tombstone());
786  * ~~~~~~~~~~
787  *
788  * @return (boolean value) True if the record is a tombstone, false otherwise.
789  * @ingroup expression
790  */
791 #define as_exp_is_tombstone() {.op=_AS_EXP_CODE_IS_TOMBSTONE, .count=1}
792 
793 /**
794  * Create expression that returns record size in memory when either the
795  * storage-engine is memory or data-in-memory is true, otherwise returns 0.
796  * This expression usually evaluates quickly because record meta data is cached
797  * in memory.
798  *
799  * Requires server version between 5.3 inclusive and 7.0 exclusive.
800  * Use as_exp_record_size() for server version 7.0+.
801  *
802  * ~~~~~~~~~~{.c}
803  * // Record memory size >= 100 KB
804  * as_exp_build(expression,
805  * as_exp_cmp_ge(as_exp_memory_size(), as_exp_int(100 * 1024)));
806  * ~~~~~~~~~~
807  *
808  * @return (integer value) memory size of the record.
809  * @ingroup expression
810  */
811 #define as_exp_memory_size() {.op=_AS_EXP_CODE_MEMORY_SIZE, .count=1}
812 
813 /**
814  * Create expression that returns record digest modulo as integer.
815  *
816  * ~~~~~~~~~~{.c}
817  * // Records that have digest(key) % 3 == 1
818  * as_exp_build(expression,
819  * as_exp_cmp_eq(as_exp_digest_modulo(3), as_exp_int(1)));
820  * ~~~~~~~~~~
821  *
822  * @param __mod Divisor used to divide the digest to get a remainder.
823  * @return (integer value) Value in range 0 and mod (exclusive)..
824  * @ingroup expression
825  */
826 #define as_exp_digest_modulo(__mod) \
827  {.op=_AS_EXP_CODE_DIGEST_MODULO, .count=2}, \
828  as_exp_int(__mod)
829 
830 /*********************************************************************************
831  * COMPARISON EXPRESSIONS
832  *********************************************************************************/
833 
834 /**
835  * Create equals (==) expression.
836  *
837  * ~~~~~~~~~~{.c}
838  * // Integer bin "a" == 11.
839  * as_exp_build(expression, as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(11)));
840  * ~~~~~~~~~~
841  *
842  * @param __left left expression in comparison.
843  * @param __right right expression in comparison.
844  * @return (boolean value)
845  * @ingroup expression
846  */
847 #define as_exp_cmp_eq(__left, __right) \
848  {.op=_AS_EXP_CODE_CMP_EQ, .count=3}, __left, __right
849 
850 /**
851  * Create not equal (!=) expression.
852  *
853  * ~~~~~~~~~~{.c}
854  * // Integer bin "a" != 13.
855  * as_exp_build(expression, as_exp_cmp_ne(as_exp_bin_int("a"), as_exp_int(13)));
856 
857  * ~~~~~~~~~~
858  *
859  * @param __left left expression in comparison.
860  * @param __right right expression in comparison.
861  * @return (boolean value)
862  * @ingroup expression
863  */
864 #define as_exp_cmp_ne(__left, __right) \
865  {.op=_AS_EXP_CODE_CMP_NE, .count=3}, __left, __right
866 
867 /**
868  * Create a greater than (>) expression.
869  *
870  * ~~~~~~~~~~{.c}
871  * // Integer bin "a" > 8.
872  * as_exp_build(expression, as_exp_cmp_gt(as_exp_bin_int("a"), as_exp_int(8)));
873  * ~~~~~~~~~~
874  *
875  * @param __left left expression in comparison.
876  * @param __right right expression in comparison.
877  * @return (boolean value)
878  * @ingroup expression
879  */
880 #define as_exp_cmp_gt(__left, __right) \
881  {.op=_AS_EXP_CODE_CMP_GT, .count=3}, __left, __right
882 
883 /**
884  * Create a greater than or equals (>=) expression.
885  *
886  * ~~~~~~~~~~{.c}
887  * // Integer bin "a" >= 88.
888  * as_exp_build(expression, as_exp_cmp_ge(as_exp_bin_int("a"), as_exp_int(88)));
889  * ~~~~~~~~~~
890  *
891  * @param __left left expression in comparison.
892  * @param __right right expression in comparison.
893  * @return (boolean value)
894  * @ingroup expression
895  */
896 #define as_exp_cmp_ge(__left, __right) \
897  {.op=_AS_EXP_CODE_CMP_GE, .count=3}, __left, __right
898 
899 /**
900  * Create a less than (<) expression.
901  *
902  * ~~~~~~~~~~{.c}
903  * // Integer bin "a" < 1000.
904  * as_exp_build(expression, as_exp_cmp_lt(as_exp_bin_int("a"), as_exp_int(1000)));
905  * ~~~~~~~~~~
906  *
907  * @param __left left expression in comparison.
908  * @param __right right expression in comparison.
909  * @return (boolean value)
910  * @ingroup expression
911  */
912 #define as_exp_cmp_lt(__left, __right) \
913  {.op=_AS_EXP_CODE_CMP_LT, .count=3}, __left, __right
914 
915 /**
916  * Create a less than or equals (<=) expression.
917  *
918  * ~~~~~~~~~~{.c}
919  * // Integer bin "a" <= 1.
920  * as_exp_build(expression, as_exp_cmp_le(as_exp_bin_int("a"), as_exp_int(1)));
921  * ~~~~~~~~~~
922  *
923  * @param __left left expression in comparison.
924  * @param __right right expression in comparison.
925  * @return (boolean value)
926  * @ingroup expression
927  */
928 #define as_exp_cmp_le(__left, __right) \
929  {.op=_AS_EXP_CODE_CMP_LE, .count=3}, __left, __right
930 
931 /**
932  * Create expression that performs a regex match on a string bin or value
933  * expression.
934  *
935  * ~~~~~~~~~~{.c}
936  * // Select string bin "a" that starts with "prefix" and ends with "suffix".
937  * // Ignore case and do not match newline.
938  * as_exp_build(expression,
939  * as_exp_cmp_regex(REG_ICASE | REG_NEWLINE, as_exp_str("prefix.*suffix"), as_exp_bin_str("a")));
940  * ~~~~~~~~~~
941  *
942  * @param __options POSIX regex flags defined in regex.h.
943  * @param __regex_str POSIX regex string.
944  * @param __cmp_str String expression to compare against.
945  * @return (boolean value)
946  * @ingroup expression
947  */
948 #define as_exp_cmp_regex(__options, __regex_str, __cmp_str) \
949  {.op=_AS_EXP_CODE_CMP_REGEX, .count=4}, \
950  as_exp_int(__options), _AS_EXP_VAL_RAWSTR(__regex_str), \
951  __cmp_str
952 
953 /**
954  * Create a point within region or region contains point expression.
955  *
956  * ~~~~~~~~~~{.c}
957  * // Geo bin "point" is within geo bin "region".
958  * as_exp_build(expression,
959  * as_exp_cmp_geo(as_exp_bin_geo("point"), as_exp_bin_geo("region")));
960  * ~~~~~~~~~~
961  *
962  * @param __left left expression in comparison.
963  * @param __right right expression in comparison.
964  * @return (boolean value)
965  * @ingroup expression
966  */
967 #define as_exp_cmp_geo(__left, __right) \
968  {.op=_AS_EXP_CODE_CMP_GEO, .count=3}, __left, __right
969 
970 /*********************************************************************************
971  * LOGICAL EXPRESSIONS
972  *********************************************************************************/
973 
974 /**
975  * Create "not" (!) operator expression.
976  *
977  * ~~~~~~~~~~{.c}
978  * // ! (a == 0 || a == 10)
979  * as_exp_build(expression,
980  * as_exp_not(as_exp_or(
981  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)),
982  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(10)))));
983  * ~~~~~~~~~~
984  *
985  * @param __expr Boolean expression to negate.
986  * @return (boolean value)
987  * @ingroup expression
988  */
989 #define as_exp_not(__expr) {.op=_AS_EXP_CODE_NOT, .count=2}, __expr
990 
991 /**
992  * Create "and" (&&) operator that applies to a variable number of expressions.
993  *
994  * ~~~~~~~~~~{.c}
995  * // (a > 5 || a == 0) && b < 3
996  * as_exp_build(expression,
997  * as_exp_and(
998  * as_exp_or(
999  * as_exp_cmp_gt(as_exp_bin_int("a"), as_exp_int(5)),
1000  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)))
1001  * as_exp_cmp_lt(as_exp_bin_int("b"), as_exp_int(3))));
1002  * ~~~~~~~~~~
1003  *
1004  * @param ... Variable number of boolean expressions.
1005  * @return (boolean value)
1006  * @ingroup expression
1007  */
1008 #define as_exp_and(...) {.op=_AS_EXP_CODE_AND}, __VA_ARGS__, \
1009  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1010 
1011 /**
1012  * Create "or" (||) operator that applies to a variable number of expressions.
1013  *
1014  * ~~~~~~~~~~{.c}
1015  * // a == 0 || b == 0
1016  * as_exp_build(expression,
1017  * as_exp_or(
1018  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)),
1019  * as_exp_cmp_eq(as_exp_bin_int("b"), as_exp_int(0))));
1020  * ~~~~~~~~~~
1021  *
1022  * @param ... Variable number of boolean expressions.
1023  * @return (boolean value)
1024  * @ingroup expression
1025  */
1026 #define as_exp_or(...) {.op=_AS_EXP_CODE_OR}, __VA_ARGS__, \
1027  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1028 
1029 /**
1030  * Create expression that returns true if only one of the expressions are true.
1031  * Requires server version 5.6.0+.
1032  *
1033  * ~~~~~~~~~~{.c}
1034  * // exclusive(a == 0, b == 0)
1035  * as_exp_build(expression,
1036  * as_exp_exclusive(
1037  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)),
1038  * as_exp_cmp_eq(as_exp_bin_int("b"), as_exp_int(0))));
1039  * ~~~~~~~~~~
1040  *
1041  * @param ... Variable number of boolean expressions.
1042  * @return (boolean value)
1043  * @ingroup expression
1044  */
1045 #define as_exp_exclusive(...) {.op=_AS_EXP_CODE_EXCLUSIVE}, __VA_ARGS__, \
1046  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1047 
1048 /*********************************************************************************
1049  * ARITHMETIC EXPRESSIONS
1050  *********************************************************************************/
1051 
1052 /**
1053  * Create "add" (+) operator that applies to a variable number of expressions.
1054  * Return the sum of all arguments.
1055  * All arguments must be the same type (integer or float).
1056  * Requires server version 5.6.0+.
1057  *
1058  * ~~~~~~~~~~{.c}
1059  * // a + b + c == 10
1060  * as_exp_build(expression,
1061  * as_exp_cmp_eq(
1062  * as_exp_add(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1063  * as_exp_int(10)));
1064  * ~~~~~~~~~~
1065  *
1066  * @param ... Variable number of integer or float expressions.
1067  * @return (integer or float value)
1068  * @ingroup expression
1069  */
1070 #define as_exp_add(...) {.op=_AS_EXP_CODE_ADD}, __VA_ARGS__, \
1071  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1072 
1073 /**
1074  * Create "subtract" (-) operator that applies to a variable number of expressions.
1075  * If only one argument is provided, return the negation of that argument.
1076  * Otherwise, return the sum of the 2nd to Nth argument subtracted from the 1st
1077  * argument. All arguments must resolve to the same type (integer or float).
1078  * Requires server version 5.6.0+.
1079  *
1080  * ~~~~~~~~~~{.c}
1081  * // a - b - c > 10
1082  * as_exp_build(expression,
1083  * as_exp_cmp_gt(
1084  * as_exp_sub(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1085  * as_exp_int(10)));
1086  * ~~~~~~~~~~
1087  *
1088  * @param ... Variable number of integer or float expressions.
1089  * @return (integer or float value)
1090  * @ingroup expression
1091  */
1092 #define as_exp_sub(...) {.op=_AS_EXP_CODE_SUB}, __VA_ARGS__, \
1093  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1094 
1095 /**
1096  * Create "multiply" (*) operator that applies to a variable number of expressions.
1097  * Return the product of all arguments. If only one argument is supplied, return
1098  * that argument. All arguments must resolve to the same type (integer or float).
1099  * Requires server version 5.6.0+.
1100  *
1101  * ~~~~~~~~~~{.c}
1102  * // a * b * c < 100
1103  * as_exp_build(expression,
1104  * as_exp_cmp_lt(
1105  * as_exp_mul(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1106  * as_exp_int(100)));
1107  * ~~~~~~~~~~
1108  *
1109  * @param ... Variable number of integer or float expressions.
1110  * @return (integer or float value)
1111  * @ingroup expression
1112  */
1113 #define as_exp_mul(...) {.op=_AS_EXP_CODE_MUL}, __VA_ARGS__, \
1114  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1115 
1116 /**
1117  * Create "divide" (/) operator that applies to a variable number of expressions.
1118  * If there is only one argument, returns the reciprocal for that argument.
1119  * Otherwise, return the first argument divided by the product of the rest.
1120  * All arguments must resolve to the same type (integer or float).
1121  * Requires server version 5.6.0+.
1122  *
1123  * ~~~~~~~~~~{.c}
1124  * // a / b / c == 1
1125  * as_exp_build(expression,
1126  * as_exp_cmp_gt(
1127  * as_exp_div(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1128  * as_exp_int(1)));
1129  * ~~~~~~~~~~
1130  *
1131  * @param ... Variable number of integer or float expressions.
1132  * @return (integer or float value)
1133  * @ingroup expression
1134  */
1135 #define as_exp_div(...) {.op=_AS_EXP_CODE_DIV}, __VA_ARGS__, \
1136  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1137 
1138 /**
1139  * Create "pow" operator that raises a "base" to the "exponent" power.
1140  * All arguments must resolve to floats.
1141  * Requires server version 5.6.0+.
1142  *
1143  * ~~~~~~~~~~{.c}
1144  * // pow(a, 2.0) == 4.0
1145  * as_exp_build(expression,
1146  * as_exp_cmp_eq(
1147  * as_exp_pow(as_exp_bin_float("a"), as_exp_float(2.0)),
1148  * as_exp_float(4.0)));
1149  * ~~~~~~~~~~
1150  *
1151  * @param __base Base value.
1152  * @param __exponent Exponent value.
1153  * @return (float value)
1154  * @ingroup expression
1155  */
1156 #define as_exp_pow(__base, __exponent) \
1157  {.op=_AS_EXP_CODE_POW, .count=3}, __base, __exponent
1158 
1159 /**
1160  * Create "log" operator for logarithm of "num" with base "base".
1161  * All arguments must resolve to floats.
1162  * Requires server version 5.6.0+.
1163  *
1164  * ~~~~~~~~~~{.c}
1165  * // log(a, 2) == 4.0
1166  * as_exp_build(expression,
1167  * as_exp_cmp_eq(
1168  * as_exp_log(as_exp_bin_float("a"), as_exp_float(2.0)),
1169  * as_exp_float(4.0)));
1170  * ~~~~~~~~~~
1171  *
1172  * @param __num Number.
1173  * @param __base Base value.
1174  * @return (float value)
1175  * @ingroup expression
1176  */
1177 #define as_exp_log(__num, __base) \
1178  {.op=_AS_EXP_CODE_LOG, .count=3}, __num, __base
1179 
1180 /**
1181  * Create "modulo" (%) operator that determines the remainder of "numerator"
1182  * divided by "denominator". All arguments must resolve to integers.
1183  * Requires server version 5.6.0+.
1184  *
1185  * ~~~~~~~~~~{.c}
1186  * // a % 10 == 0
1187  * as_exp_build(expression,
1188  * as_exp_cmp_eq(
1189  * as_exp_mod(as_exp_bin_int("a"), as_exp_int(10)),
1190  * as_exp_int(0)));
1191  * ~~~~~~~~~~
1192  *
1193  * @return (integer value)
1194  * @ingroup expression
1195  */
1196 #define as_exp_mod(__numerator, __denominator) \
1197  {.op=_AS_EXP_CODE_MOD, .count=3}, __numerator, __denominator
1198 
1199 /**
1200  * Create operator that returns absolute value of a number.
1201  * All arguments must resolve to integer or float.
1202  * Requires server version 5.6.0+.
1203  *
1204  * ~~~~~~~~~~{.c}
1205  * // abs(a) == 1
1206  * as_exp_build(expression,
1207  * as_exp_cmp_eq(
1208  * as_exp_abs(as_exp_bin_int("a")),
1209  * as_exp_int(1)));
1210  * ~~~~~~~~~~
1211  *
1212  * @return (number value)
1213  * @ingroup expression
1214  */
1215 #define as_exp_abs(__value) \
1216  {.op=_AS_EXP_CODE_ABS, .count=2}, __value
1217 
1218 /**
1219  * Create expression that rounds a floating point number down to the closest integer value.
1220  * Requires server version 5.6.0+.
1221  *
1222  * ~~~~~~~~~~{.c}
1223  * // floor(2.95) == 2.0
1224  * as_exp_build(expression,
1225  * as_exp_cmp_eq(
1226  * as_exp_floor(as_exp_float(2.95)),
1227  * as_exp_float(2.0)));
1228  * ~~~~~~~~~~
1229  *
1230  * @param __num Floating point value to round down.
1231  * @return (float-value)
1232  * @ingroup expression
1233  */
1234 #define as_exp_floor(__num) \
1235  {.op=_AS_EXP_CODE_FLOOR, .count=2}, __num
1236 
1237 /**
1238  * Create expression that rounds a floating point number up to the closest integer value.
1239  * Requires server version 5.6.0+.
1240  *
1241  * ~~~~~~~~~~{.c}
1242  * // ceil(2.15) == 3.0
1243  * as_exp_build(expression,
1244  * as_exp_cmp_eq(
1245  * as_exp_ceil(as_exp_float(2.15)),
1246  * as_exp_float(3.0)));
1247  * ~~~~~~~~~~
1248  *
1249  * @param __num Floating point value to round up.
1250  * @return (integer-value)
1251  * @ingroup expression
1252  */
1253 #define as_exp_ceil(__num) \
1254  {.op=_AS_EXP_CODE_CEIL, .count=2}, __num
1255 
1256 /**
1257  * Create expression that converts a float to an integer.
1258  * Requires server version 5.6.0+.
1259  *
1260  * ~~~~~~~~~~{.c}
1261  * // int(2.5) == 2
1262  * as_exp_build(expression,
1263  * as_exp_cmp_eq(
1264  * as_exp_to_int(as_exp_float(2.5)),
1265  * as_exp_int(2)));
1266  * ~~~~~~~~~~
1267  *
1268  * @param __num Integer to convert to a float
1269  * @return (float-value)
1270  * @ingroup expression
1271  */
1272 #define as_exp_to_int(__num) \
1273  {.op=_AS_EXP_CODE_TO_INT, .count=2}, __num
1274 
1275 /**
1276  * Create expression that converts an integer to a float.
1277  * Requires server version 5.6.0+.
1278  *
1279  * ~~~~~~~~~~{.c}
1280  * // float(2) == 2.0
1281  * as_exp_build(expression,
1282  * as_exp_cmp_eq(
1283  * as_exp_to_float(as_exp_int(2)),
1284  * as_exp_int(2.0)));
1285  * ~~~~~~~~~~
1286  *
1287  * @param __num Integer to convert to a float
1288  * @return (float-value)
1289  * @ingroup expression
1290  */
1291 #define as_exp_to_float(__num) \
1292  {.op=_AS_EXP_CODE_TO_FLOAT, .count=2}, __num
1293 
1294 /**
1295  * Create integer "and" (&) operator that is applied to two or more integers.
1296  * All arguments must resolve to integers.
1297  * Requires server version 5.6.0+.
1298  *
1299  * ~~~~~~~~~~{.c}
1300  * // a & 0xff == 0x11
1301  * as_exp_build(expression,
1302  * as_exp_cmp_eq(
1303  * as_exp_int_and(as_exp_bin_int("a"), as_exp_int(0xff)),
1304  * as_exp_int(0x11)));
1305  * ~~~~~~~~~~
1306  *
1307  * @param ... Variable number of integer expressions.
1308  * @return (integer value)
1309  * @ingroup expression
1310  */
1311 #define as_exp_int_and(...) {.op=_AS_EXP_CODE_INT_AND}, __VA_ARGS__, \
1312  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1313 
1314 /**
1315  * Create integer "or" (|) operator that is applied to two or more integers.
1316  * All arguments must resolve to integers.
1317  * Requires server version 5.6.0+.
1318  *
1319  * ~~~~~~~~~~{.c}
1320  * // a | 0x10 != 0
1321  * as_exp_build(expression,
1322  * as_exp_cmp_ne(
1323  * as_exp_int_or(as_exp_bin_int("a"), as_exp_int(0x10)),
1324  * as_exp_int(0)));
1325  * ~~~~~~~~~~
1326  *
1327  * @param ... Variable number of integer expressions.
1328  * @return (integer value)
1329  * @ingroup expression
1330  */
1331 #define as_exp_int_or(...) {.op=_AS_EXP_CODE_INT_OR}, __VA_ARGS__, \
1332  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1333 
1334 /**
1335  * Create integer "xor" (^) operator that is applied to two or more integers.
1336  * All arguments must resolve to integers.
1337  * Requires server version 5.6.0+.
1338  *
1339  * ~~~~~~~~~~{.c}
1340  * // a ^ b == 16
1341  * as_exp_build(expression,
1342  * as_exp_cmp_eq(
1343  * as_exp_int_xor(as_exp_bin_int("a"), as_exp_bin_int("b")),
1344  * as_exp_int(16)));
1345  * ~~~~~~~~~~
1346  *
1347  * @param ... Variable number of integer expressions.
1348  * @return (integer value)
1349  * @ingroup expression
1350  */
1351 #define as_exp_int_xor(...) {.op=_AS_EXP_CODE_INT_XOR}, __VA_ARGS__, \
1352  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1353 
1354 /**
1355  * Create integer "not" (~) operator.
1356  * Requires server version 5.6.0+.
1357  *
1358  * ~~~~~~~~~~{.c}
1359  * // ~a == 7
1360  * as_exp_build(expression,
1361  * as_exp_cmp_eq(
1362  * as_exp_int_not(as_exp_bin_int("a")),
1363  * as_exp_int(7)));
1364  * ~~~~~~~~~~
1365  *
1366  * @param __expr Integer expression.
1367  * @return (integer value)
1368  * @ingroup expression
1369  */
1370 #define as_exp_int_not(__expr) {.op=_AS_EXP_CODE_INT_NOT, .count=2}, \
1371  __expr
1372 
1373 /**
1374  * Create integer "left shift" (<<) operator.
1375  * Requires server version 5.6.0+.
1376  *
1377  * ~~~~~~~~~~{.c}
1378  * // a << 8 > 0xff
1379  * as_exp_build(expression,
1380  * as_exp_cmp_gt(
1381  * as_exp_int_lshift(as_exp_bin_int("a"), as_exp_int(8)),
1382  * as_exp_int(0xff)));
1383  * ~~~~~~~~~~
1384  *
1385  * @param __value Integer expression.
1386  * @param __shift Number of bits to shift by.
1387  * @return (integer value)
1388  * @ingroup expression
1389  */
1390 #define as_exp_int_lshift(__value, __shift) \
1391  {.op=_AS_EXP_CODE_INT_LSHIFT, .count=3}, __value, __shift
1392 
1393 /**
1394  * Create integer "logical right shift" (>>>) operator.
1395  * Requires server version 5.6.0+.
1396  *
1397  * ~~~~~~~~~~{.c}
1398  * // a >>> 8 > 0xff
1399  * as_exp_build(expression,
1400  * as_exp_cmp_gt(
1401  * as_exp_int_rshift(as_exp_bin_int("a"), as_exp_int(8)),
1402  * as_exp_int(0xff)));
1403  * ~~~~~~~~~~
1404  *
1405  * @param __value Integer expression.
1406  * @param __shift Number of bits to shift by.
1407  * @return (integer value)
1408  * @ingroup expression
1409  */
1410 #define as_exp_int_rshift(__value, __shift) \
1411  {.op=_AS_EXP_CODE_INT_RSHIFT, .count=3}, __value, __shift
1412 
1413 /**
1414  * Create integer "arithmetic right shift" (>>) operator.
1415  * Requires server version 5.6.0+.
1416  *
1417  * ~~~~~~~~~~{.c}
1418  * // a >> 8 > 0xff
1419  * as_exp_build(expression,
1420  * as_exp_cmp_eq(
1421  * as_exp_int_arshift(as_exp_bin_int("a"), as_exp_int(8)),
1422  * as_exp_int(0xff)));
1423  * ~~~~~~~~~~
1424  *
1425  * @param __value Integer expression.
1426  * @param __shift Number of bits to shift by.
1427  * @return (integer value)
1428  * @ingroup expression
1429  */
1430 #define as_exp_int_arshift(__value, __shift) \
1431  {.op=_AS_EXP_CODE_INT_ARSHIFT, .count=3}, __value, __shift
1432 
1433 /**
1434  * Create expression that returns count of integer bits that are set to 1.
1435  * Requires server version 5.6.0+.
1436  *
1437  * ~~~~~~~~~~{.c}
1438  * // count(a) == 4
1439  * as_exp_build(expression,
1440  * as_exp_cmp_eq(
1441  * as_exp_int_count(as_exp_bin_int("a")),
1442  * as_exp_int(4)));
1443  * ~~~~~~~~~~
1444  *
1445  * @return (integer value)
1446  * @ingroup expression
1447  */
1448 #define as_exp_int_count(__expr) \
1449  {.op=_AS_EXP_CODE_INT_COUNT, .count=2}, __expr
1450 
1451 /**
1452  * Create expression that scans integer bits from left (most significant bit) to
1453  * right (least significant bit), looking for a search bit value. When the
1454  * search value is found, the index of that bit (where the most significant bit is
1455  * index 0) is returned. If "search" is true, the scan will search for the bit
1456  * value 1. If "search" is false it will search for bit value 0.
1457  * Requires server version 5.6.0+.
1458  *
1459  * ~~~~~~~~~~{.c}
1460  * // lscan(a, true) == 4
1461  * as_exp_build(expression,
1462  * as_exp_cmp_eq(
1463  * as_exp_int_lscan(as_exp_bin_int("a"), as_exp_bool(true)),
1464  * as_exp_int(4)));
1465  * ~~~~~~~~~~
1466  *
1467  * @return (integer value)
1468  * @ingroup expression
1469  */
1470 #define as_exp_int_lscan(__value, __search) \
1471  {.op=_AS_EXP_CODE_INT_LSCAN, .count=3}, __value, __search
1472 
1473 /**
1474  * Create expression that scans integer bits from right (least significant bit) to
1475  * left (most significant bit), looking for a search bit value. When the
1476  * search value is found, the index of that bit (where the most significant bit is
1477  * index 0) is returned. If "search" is true, the scan will search for the bit
1478  * value 1. If "search" is false it will search for bit value 0.
1479  * Requires server version 5.6.0+.
1480  *
1481  * ~~~~~~~~~~{.c}
1482  * // rscan(a, true) == 4
1483  * as_exp_build(expression,
1484  * as_exp_cmp_eq(
1485  * as_exp_int_rscan(as_exp_bin_int("a"), as_exp_bool(true)),
1486  * as_exp_int(4)));
1487  * ~~~~~~~~~~
1488  *
1489  * @return (integer value)
1490  * @ingroup expression
1491  */
1492 #define as_exp_int_rscan(__value, __search) \
1493  {.op=_AS_EXP_CODE_INT_RSCAN, .count=3}, __value, __search
1494 
1495 /**
1496  * Create expression that returns the minimum value in a variable number of expressions.
1497  * All arguments must be the same type (integer or float).
1498  * Requires server version 5.6.0+.
1499  *
1500  * ~~~~~~~~~~{.c}
1501  * // min(a, b, c) > 0
1502  * as_exp_build(expression,
1503  * as_exp_cmp_gt(
1504  * as_exp_min(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1505  * as_exp_int(0)));
1506  * ~~~~~~~~~~
1507  *
1508  * @param ... Variable number of integer or float expressions.
1509  * @return (integer or float value)
1510  * @ingroup expression
1511  */
1512 #define as_exp_min(...) {.op=_AS_EXP_CODE_MIN}, __VA_ARGS__, \
1513  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1514 
1515 /**
1516  * Create expression that returns the maximum value in a variable number of expressions.
1517  * All arguments must be the same type (integer or float).
1518  * Requires server version 5.6.0+.
1519  *
1520  * ~~~~~~~~~~{.c}
1521  * // max(a, b, c) > 100
1522  * as_exp_build(expression,
1523  * as_exp_cmp_eq(
1524  * as_exp_max(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1525  * as_exp_int(100)));
1526  * ~~~~~~~~~~
1527  *
1528  * @param ... Variable number of integer or float expressions.
1529  * @return (integer or float value)
1530  * @ingroup expression
1531  */
1532 #define as_exp_max(...) {.op=_AS_EXP_CODE_MAX}, __VA_ARGS__, \
1533  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1534 
1535 /*********************************************************************************
1536  * FLOW CONTROL AND VARIABLE EXPRESSIONS
1537  *********************************************************************************/
1538 
1539 /**
1540  * Conditionally select an expression from a variable number of expression pairs
1541  * followed by default expression action. Requires server version 5.6.0+.
1542  *
1543  * ~~~~~~~~~~{.c}
1544  * Args Format: bool exp1, action exp1, bool exp2, action exp2, ..., action-default
1545  *
1546  * // Apply operator based on type and test if greater than 100
1547  * as_exp_build(expression,
1548  * as_exp_cmp_gt(
1549  * as_exp_cond(
1550  * as_exp_eq(as_exp_bin_int("type"), as_exp_int(0)),
1551  * as_exp_add(as_exp_bin_int("val1"), as_exp_bin_int("val2")),
1552  * as_exp_eq(as_exp_bin_int("type"), as_exp_int(1)),
1553  * as_exp_sub(as_exp_bin_int("val1"), as_exp_bin_int("val2")),
1554  * as_exp_eq(as_exp_bin_int("type"), as_exp_int(2)),
1555  * as_exp_mul(as_exp_bin_int("val1"), as_exp_bin_int("val2")),
1556  * as_exp_int(-1)),
1557  * as_exp_int(100)));
1558  * ~~~~~~~~~~
1559  *
1560  * @return first action expression where bool expression is true or action-default.
1561  * @ingroup expression
1562  */
1563 #define as_exp_cond(...) {.op=_AS_EXP_CODE_COND}, __VA_ARGS__, \
1564  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1565 
1566 /**
1567  * Define variables and expressions in scope.
1568  * Requires server version 5.6.0+.
1569  *
1570  * ~~~~~~~~~~{.c}
1571  * // 5 < a < 10
1572  * as_exp_build(expression,
1573  * as_exp_let(as_exp_def("x", as_exp_bin_int("a")),
1574  * as_exp_and(
1575  * as_exp_lt(as_exp_int(5), as_exp_var("x")),
1576  * as_exp_lt(as_exp_var("x"), as_exp_int(10)))));
1577  * ~~~~~~~~~~
1578  *
1579  * @param ... Variable number of as_exp_def followed by a scoped
1580  * expression.
1581  * @return result of scoped expression.
1582  * @ingroup expression
1583  */
1584 #define as_exp_let(...) \
1585  {.op=_AS_EXP_CODE_LET}, __VA_ARGS__, \
1586  {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1587 
1588 /**
1589  * Assign variable to an expression that can be accessed later.
1590  * Requires server version 5.6.0+.
1591  *
1592  * ~~~~~~~~~~{.c}
1593  * // 5 < a < 10
1594  * as_exp_build(expression,
1595  * as_exp_let(as_exp_def("x", as_exp_bin_int("a")),
1596  * as_exp_and(
1597  * as_exp_lt(as_exp_int(5), as_exp_var("x")),
1598  * as_exp_lt(as_exp_var("x"), as_exp_int(10)))));
1599  * ~~~~~~~~~~
1600  *
1601  * @param __var_name Variable name.
1602  * @param __expr The variable is set to the result of __expr.
1603  * @return A variable name expression pair.
1604  * @ingroup expression
1605  */
1606 #define as_exp_def(__var_name, __expr) \
1607  _AS_EXP_VAL_RAWSTR(__var_name), __expr
1608 
1609 /**
1610  * Retrieve expression value from a variable.
1611  * Requires server version 5.6.0+.
1612  *
1613  * ~~~~~~~~~~{.c}
1614  * // 5 < a < 10
1615  * as_exp_build(expression,
1616  * as_exp_let(as_exp_def("x", as_exp_bin_int("a")),
1617  * as_exp_and(
1618  * as_exp_lt(as_exp_int(5), as_exp_var("x")),
1619  * as_exp_lt(as_exp_var("x"), as_exp_int(10)))));
1620  * ~~~~~~~~~~
1621  *
1622  * @param __var_name Variable name.
1623  * @return value stored in variable.
1624  * @ingroup expression
1625  */
1626 #define as_exp_var(__var_name) \
1627  {.op=_AS_EXP_CODE_VAR, .count=2}, _AS_EXP_VAL_RAWSTR(__var_name)
1628 
1629 /*********************************************************************************
1630  * LIST MODIFY EXPRESSIONS
1631  *********************************************************************************/
1632 
1633 #define _AS_EXP_VAL_RTYPE(__val) {.op=_AS_EXP_CODE_VAL_RTYPE, .v.int_val=__val}
1634 
1635 #define _AS_EXP_LIST_MOD(__ctx, __pol, __op, __param, __extra_param) \
1636  {.op=_AS_EXP_CODE_CALL, .count=5}, \
1637  _AS_EXP_VAL_RTYPE(as_exp_get_ctx_type(__ctx, AS_EXP_TYPE_LIST)), \
1638  as_exp_int(_AS_EXP_SYS_CALL_CDT | _AS_EXP_SYS_FLAG_MODIFY_LOCAL), \
1639  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param + ((uintptr_t)(__pol) == (uintptr_t)NULL ? 0 : __extra_param), .v.ctx=__ctx}, \
1640  as_exp_int(__op)
1641 
1642 /**
1643  * Create expression that appends value to end of list.
1644  *
1645  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1646  * @param __pol Optional list write policy (as_list_policy).
1647  * @param __val Value expression.
1648  * @param __bin List bin or list value expression.
1649  * @return (list expression)
1650  * @ingroup expression
1651  */
1652 #define as_exp_list_append(__ctx, __pol, __val, __bin) \
1653  _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_APPEND, 1, 2), \
1654  __val, \
1655  {.op=_AS_EXP_CODE_CDT_LIST_CRMOD, .v.list_pol = __pol}, \
1656  __bin
1657 
1658 /**
1659  * Create expression that appends list items to end of list.
1660  *
1661  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1662  * @param __pol Optional list write policy (as_list_policy).
1663  * @param __val List items expression.
1664  * @param __bin List bin or list value expression.
1665  * @return (list expression)
1666  * @ingroup expression
1667  */
1668 #define as_exp_list_append_items(__ctx, __pol, __val, __bin) \
1669  _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_APPEND_ITEMS, 1, 2), \
1670  __val, \
1671  {.op=_AS_EXP_CODE_CDT_LIST_CRMOD, .v.list_pol = __pol}, \
1672  __bin
1673 
1674 /**
1675  * Create expression that inserts value to specified index of list.
1676  *
1677  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1678  * @param __pol Optional list write policy (as_list_policy).
1679  * @param __idx Index integer expression.
1680  * @param __val Value expression.
1681  * @param __bin List bin or list value expression.
1682  * @return (list expression)
1683  * @ingroup expression
1684  */
1685 #define as_exp_list_insert(__ctx, __pol, __idx, __val, __bin) \
1686  _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_INSERT, 2, 1), \
1687  __idx, __val, \
1688  {.op=_AS_EXP_CODE_CDT_LIST_MOD, .v.list_pol = __pol}, \
1689  __bin
1690 
1691 /**
1692  * Create expression that inserts each input list item starting at specified index of list.
1693  *
1694  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1695  * @param __pol Optional list write policy (as_list_policy).
1696  * @param __idx Index integer expression.
1697  * @param __val List items expression.
1698  * @param __bin List bin or list value expression.
1699  * @return (list expression)
1700  * @ingroup expression
1701  */
1702 #define as_exp_list_insert_items(__ctx, __pol, __idx, __val, __bin) \
1703  _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_INSERT_ITEMS, 2, 1), \
1704  __idx, __val, \
1705  {.op=_AS_EXP_CODE_CDT_LIST_MOD, .v.list_pol = __pol}, \
1706  __bin
1707 
1708 /**
1709  * Create expression that increments list[index] by value.
1710  *
1711  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1712  * @param __pol Optional list write policy (as_list_policy).
1713  * @param __idx Index integer expression.
1714  * @param __val Value expression.
1715  * @param __bin List bin or list value expression.
1716  * @return (list expression)
1717  * @ingroup expression
1718  */
1719 #define as_exp_list_increment(__ctx, __pol, __idx, __val, __bin) \
1720  _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_INCREMENT, 2, 2), \
1721  __idx, __val, \
1722  {.op=_AS_EXP_CODE_CDT_LIST_CRMOD, .v.list_pol = __pol}, \
1723  __bin
1724 
1725 /**
1726  * Create expression that sets item value at specified index in list.
1727  *
1728  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1729  * @param __pol Optional list write policy (as_list_policy).
1730  * @param __idx Index integer expression.
1731  * @param __val Value expression.
1732  * @param __bin List bin or list value expression.
1733  * @return (list expression)
1734  * @ingroup expression
1735  */
1736 #define as_exp_list_set(__ctx, __pol, __idx, __val, __bin) \
1737  _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_SET, 2, 1), \
1738  __idx, __val, \
1739  {.op=_AS_EXP_CODE_CDT_LIST_MOD, .v.list_pol = __pol}, \
1740  __bin
1741 
1742 /**
1743  * Create expression that removes all items in list.
1744  *
1745  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1746  * @param __bin List bin or list value expression.
1747  * @return (list expression)
1748  * @ingroup expression
1749  */
1750 #define as_exp_list_clear(__ctx, __bin) \
1751  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_CLEAR, 0, 0), \
1752  __bin
1753 
1754 /**
1755  * Create expression that sorts list.
1756  *
1757  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1758  * @param __order Sort order (as_list_sort_flags).
1759  * @param __bin List bin or list value expression.
1760  * @return (list expression)
1761  * @ingroup expression
1762  */
1763 #define as_exp_list_sort(__ctx, __order, __bin) \
1764  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_SORT, 1, 0), \
1765  as_exp_int(__order), \
1766  __bin
1767 
1768 /**
1769  * Create expression that removes list items identified by value.
1770  *
1771  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1772  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1773  * @param __val Value expression.
1774  * @param __bin List bin or list value expression.
1775  * @return (list expression)
1776  * @ingroup expression
1777  */
1778 #define as_exp_list_remove_by_value(__ctx, __rtype, __val, __bin) \
1779  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_ALL_BY_VALUE, 2, 0), \
1780  as_exp_int(__rtype), \
1781  __val, \
1782  __bin
1783 
1784 /**
1785  * Create expression that removes list items identified by values.
1786  *
1787  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1788  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1789  * @param __values Values list expression.
1790  * @param __bin List bin or list value expression.
1791  * @return (list expression)
1792  * @ingroup expression
1793  */
1794 #define as_exp_list_remove_by_value_list(__ctx, __rtype, __values, __bin) \
1795  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_LIST, 2, 0), \
1796  as_exp_int(__rtype), \
1797  __values, \
1798  __bin
1799 
1800 /**
1801  * Create expression that removes list items identified by value range
1802  * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
1803  * If end is infinity, the range is greater than equal to begin.
1804  *
1805  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1806  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1807  * @param __begin Begin value expression.
1808  * @param __end End value expression.
1809  * @param __bin List bin or list value expression.
1810  * @return (list expression)
1811  * @ingroup expression
1812  */
1813 #define as_exp_list_remove_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
1814  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_INTERVAL, 3, 0), \
1815  as_exp_int(__rtype), \
1816  __begin, __end, \
1817  __bin
1818 
1819 /**
1820  * Create expression that removes list items nearest to value and greater by relative rank.
1821  *
1822  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1823  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1824  * @param __val Value expression.
1825  * @param __rank Rank integer expression.
1826  * @param __bin List bin or list value expression.
1827  * @return (list expression)
1828  * @ingroup expression
1829  */
1830 #define as_exp_list_remove_by_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
1831  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_REL_RANK_RANGE, 3, 0), \
1832  as_exp_int(__rtype), \
1833  __val, __rank, \
1834  __bin
1835 
1836 /**
1837  * Create expression that removes list items nearest to value and greater by relative rank with a
1838  * count limit.
1839  *
1840  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1841  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1842  * @param __val Value expression.
1843  * @param __rank Rank integer expression.
1844  * @param __count Count integer expression.
1845  * @param __bin List bin or list value expression.
1846  * @return (list expression)
1847  * @ingroup expression
1848  */
1849 #define as_exp_list_remove_by_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
1850  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_REL_RANK_RANGE, 4, 0), \
1851  as_exp_int(__rtype), \
1852  __val, __rank, __count, \
1853  __bin
1854 
1855 /**
1856  * Create expression that removes list item identified by index.
1857  *
1858  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1859  * @param __idx Index integer expression.
1860  * @param __bin List bin or list value expression.
1861  * @return (list expression)
1862  * @ingroup expression
1863  */
1864 #define as_exp_list_remove_by_index(__ctx, __idx, __bin) \
1865  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_INDEX, 2, 0), \
1866  as_exp_int(AS_LIST_RETURN_NONE), \
1867  __idx, \
1868  __bin
1869 
1870 /**
1871  * Create expression that removes list items starting at specified index to the end of list.
1872  *
1873  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1874  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1875  * @param __idx Index integer expression.
1876  * @param __bin List bin or list value expression.
1877  * @return (list expression)
1878  * @ingroup expression
1879  */
1880 #define as_exp_list_remove_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
1881  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_INDEX_RANGE, 2, 0), \
1882  as_exp_int(__rtype), \
1883  __idx, \
1884  __bin
1885 
1886 /**
1887  * Create expression that removes "count" list items starting at specified index.
1888  *
1889  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1890  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1891  * @param __idx Index integer expression.
1892  * @param __count Count integer expression.
1893  * @param __bin List bin or list value expression.
1894  * @return (list expression)
1895  * @ingroup expression
1896  */
1897 #define as_exp_list_remove_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
1898  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_INDEX_RANGE, 3, 0), \
1899  as_exp_int(__rtype), \
1900  __idx, __count, \
1901  __bin
1902 
1903 /**
1904  * Create expression that removes list item identified by rank.
1905  *
1906  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1907  * @param __rank Rank integer expression.
1908  * @param __bin List bin or list value expression.
1909  * @return (list expression)
1910  * @ingroup expression
1911  */
1912 #define as_exp_list_remove_by_rank(__ctx, __rank, __bin) \
1913  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_RANK, 2, 0), \
1914  as_exp_int(AS_LIST_RETURN_NONE), \
1915  __rank, \
1916  __bin
1917 
1918 /**
1919  * Create expression that removes list items starting at specified rank to the last ranked item.
1920  *
1921  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1922  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1923  * @param __rank Rank integer expression.
1924  * @param __bin List bin or list value expression.
1925  * @return (list expression)
1926  * @ingroup expression
1927  */
1928 #define as_exp_list_remove_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
1929  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_RANK_RANGE, 2, 0), \
1930  as_exp_int(__rtype), \
1931  __rank, \
1932  __bin
1933 
1934 /**
1935  * Create expression that removes "count" list items starting at specified rank.
1936  *
1937  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1938  * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1939  * @param __rank Rank integer expression.
1940  * @param __count Count integer expression.
1941  * @param __bin List bin or list value expression.
1942  * @return (list expression)
1943  * @ingroup expression
1944  */
1945 #define as_exp_list_remove_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
1946  _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_RANK_RANGE, 3, 0), \
1947  as_exp_int(__rtype), \
1948  __rank, __count, \
1949  __bin
1950 
1951 /*********************************************************************************
1952  * LIST READ EXPRESSIONS
1953  *********************************************************************************/
1954 
1955 #define _AS_EXP_CDT_LIST_READ(__type, __rtype, __is_multi) \
1956  {.op=_AS_EXP_CODE_CALL, .count=5}, \
1957  _AS_EXP_VAL_RTYPE(as_exp_get_list_type(__type, __rtype, __is_multi)), \
1958  as_exp_int(_AS_EXP_SYS_CALL_CDT)
1959 
1960 #define _AS_EXP_LIST_START(__ctx, __op, __param) \
1961  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param, .v.ctx=__ctx}, \
1962  as_exp_int(__op)
1963 
1964 /**
1965  * Create expression that returns list size.
1966  *
1967  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1968  * @param __bin List bin or list value expression.
1969  * @return (integer expression)
1970  * @ingroup expression
1971  */
1972 #define as_exp_list_size(__ctx, __bin) \
1973  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, AS_LIST_RETURN_COUNT, false), \
1974  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_SIZE, 0), \
1975  __bin
1976 
1977 /**
1978  * Create expression that selects list items identified by value and returns selected
1979  * data specified by rtype.
1980  *
1981  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1982  * @param __rtype Return type (as_list_return_type).
1983  * @param __val Value expression.
1984  * @param __bin List bin or list value expression.
1985  * @return (expression)
1986  * @ingroup expression
1987  */
1988 #define as_exp_list_get_by_value(__ctx, __rtype, __val, __bin) \
1989  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
1990  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_ALL_BY_VALUE, 2), \
1991  as_exp_int(__rtype), \
1992  __val, \
1993  __bin
1994 
1995 /**
1996  * Create expression that selects list items identified by value range and returns selected
1997  * data specified by rtype.
1998  *
1999  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2000  * @param __rtype Return type (as_list_return_type).
2001  * @param __begin Begin value expression.
2002  * @param __end End value expression.
2003  * @param __bin List bin or list value expression.
2004  * @return (expression)
2005  * @ingroup expression
2006  */
2007 #define as_exp_list_get_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
2008  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2009  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_INTERVAL, 3), \
2010  as_exp_int(__rtype), \
2011  __begin, __end, \
2012  __bin
2013 
2014 /**
2015  * Create expression that selects list items identified by values and returns selected
2016  * data specified by rtype.
2017  *
2018  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2019  * @param __rtype Return type (as_list_return_type).
2020  * @param __val Values list expression.
2021  * @param __bin List bin or list value expression.
2022  * @return (expression)
2023  * @ingroup expression
2024  */
2025 #define as_exp_list_get_by_value_list(__ctx, __rtype, __val, __bin) \
2026  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2027  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_LIST, 2), \
2028  as_exp_int(__rtype), \
2029  __val, \
2030  __bin
2031 
2032 /**
2033  * Create expression that selects list items nearest to value and greater by relative rank
2034  * and returns selected data specified by rtype.
2035  *
2036  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2037  * @param __rtype Return type (as_list_return_type).
2038  * @param __val Values list expression.
2039  * @param __rank Rank integer expression.
2040  * @param __bin List bin or list value expression.
2041  * @return (expression)
2042  * @ingroup expression
2043  */
2044 #define as_exp_list_get_by_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
2045  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2046  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_REL_RANK_RANGE, 3), \
2047  as_exp_int(__rtype), \
2048  __val, __rank, \
2049  __bin
2050 
2051 /**
2052  * Create expression that selects list items nearest to value and greater by relative rank with a
2053  * count limit and returns selected data specified by rtype.
2054  *
2055  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2056  * @param __rtype Return type (as_list_return_type).
2057  * @param __val Values list expression.
2058  * @param __rank Rank integer expression.
2059  * @param __count Count integer expression.
2060  * @param __bin List bin or list value expression.
2061  * @return (expression)
2062  * @ingroup expression
2063  */
2064 #define as_exp_list_get_by_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
2065  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2066  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_REL_RANK_RANGE, 4), \
2067  as_exp_int(__rtype), \
2068  __val, __rank, __count, \
2069  __bin
2070 
2071 /**
2072  * Create expression that selects list item identified by index
2073  * and returns selected data specified by rtype.
2074  *
2075  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2076  * @param __rtype Return type (as_list_return_type).
2077  * @param __vtype Value type (as_exp_type).
2078  * @param __idx Index integer expression.
2079  * @param __bin List bin or list value expression.
2080  * @return (vtype expression)
2081  * @ingroup expression
2082  */
2083 #define as_exp_list_get_by_index(__ctx, __rtype, __vtype, __idx, __bin) \
2084  _AS_EXP_CDT_LIST_READ(__vtype, __rtype, false), \
2085  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_INDEX, 2), \
2086  as_exp_int(__rtype), \
2087  __idx, \
2088  __bin
2089 
2090 /**
2091  * Create expression that selects list items starting at specified index to the end of list
2092  * and returns selected data specified by rtype.
2093  *
2094  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2095  * @param __rtype Return type (as_list_return_type).
2096  * @param __idx Index integer expression.
2097  * @param __bin List bin or list value expression.
2098  * @return (expression)
2099  * @ingroup expression
2100  */
2101 #define as_exp_list_get_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
2102  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2103  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_INDEX_RANGE, 2), \
2104  as_exp_int(__rtype), \
2105  __idx, \
2106  __bin
2107 
2108 /**
2109  * Create expression that selects "count" list items starting at specified index
2110  * and returns selected data specified by rtype.
2111  *
2112  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2113  * @param __rtype Return type (as_list_return_type).
2114  * @param __idx Index integer expression.
2115  * @param __count Count integer expression.
2116  * @param __bin List bin or list value expression.
2117  * @return (expression)
2118  * @ingroup expression
2119  */
2120 #define as_exp_list_get_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
2121  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2122  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_INDEX_RANGE, 3), \
2123  as_exp_int(__rtype), \
2124  __idx, __count, \
2125  __bin
2126 
2127 /**
2128  * Create expression that selects list item identified by rank
2129  * and returns selected data specified by rtype.
2130  *
2131  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2132  * @param __rtype Return type (as_list_return_type).
2133  * @param __vtype Value type (as_exp_type).
2134  * @param __rank Rank integer expression.
2135  * @param __bin List bin or list value expression.
2136  * @return (vtype expression)
2137  * @ingroup expression
2138  */
2139 #define as_exp_list_get_by_rank(__ctx, __rtype, __vtype, __rank, __bin) \
2140  _AS_EXP_CDT_LIST_READ(__vtype, __rtype, false), \
2141  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_RANK, 2), \
2142  as_exp_int(__rtype), \
2143  __rank, \
2144  __bin
2145 
2146 /**
2147  * Create expression that selects list items starting at specified rank to the last ranked item
2148  * and returns selected data specified by rtype.
2149  *
2150  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2151  * @param __rtype Return type (as_list_return_type).
2152  * @param __rank Rank integer expression.
2153  * @param __bin List bin or list value expression.
2154  * @return (expression)
2155  * @ingroup expression
2156  */
2157 #define as_exp_list_get_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
2158  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2159  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_RANK_RANGE, 2), \
2160  as_exp_int(__rtype), \
2161  __rank, \
2162  __bin
2163 
2164 /**
2165  * Create expression that selects "count" list items starting at specified rank
2166  * and returns selected data specified by rtype.
2167  *
2168  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2169  * @param __rtype Return type (as_list_return_type).
2170  * @param __rank Rank integer expression.
2171  * @param __count Count integer expression.
2172  * @param __bin List bin or list value expression.
2173  * @return (expression)
2174  * @ingroup expression
2175  */
2176 #define as_exp_list_get_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
2177  _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2178  _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_RANK_RANGE, 3), \
2179  as_exp_int(__rtype), \
2180  __rank, __count, \
2181  __bin
2182 
2183 /*********************************************************************************
2184  * MAP MODIFY EXPRESSIONS
2185  *********************************************************************************/
2186 
2187 #define _AS_EXP_MAP_MOD(__ctx, __pol, __op, __param, __extra_param) \
2188  {.op=_AS_EXP_CODE_CALL, .count=5}, \
2189  _AS_EXP_VAL_RTYPE(as_exp_get_ctx_type(__ctx, AS_EXP_TYPE_MAP)), \
2190  as_exp_int(_AS_EXP_SYS_CALL_CDT | _AS_EXP_SYS_FLAG_MODIFY_LOCAL), \
2191  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param + ((uintptr_t)(__pol) == (uintptr_t)NULL ? 0 : __extra_param), .v.ctx=__ctx}, \
2192  as_exp_int(__op)
2193 
2194 /**
2195  * Create expression that writes key/val item to map bin.
2196  *
2197  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2198  * @param __pol Optional map write policy (as_map_policy).
2199  * @param __key Key expression.
2200  * @param __val Value expression.
2201  * @param __bin Map bin or map value expression.
2202  * @return (map expression)
2203  * @ingroup expression
2204  */
2205 #define as_exp_map_put(__ctx, __pol, __key, __val, __bin) \
2206  _AS_EXP_MAP_MOD(__ctx, __pol, AS_CDT_OP_MAP_PUT, 2, 2), \
2207  __key, __val, \
2208  {.op=_AS_EXP_CODE_CDT_MAP_CRMOD, .v.map_pol = __pol}, \
2209  __bin
2210 
2211 /**
2212  * Create expression that writes each map item to map bin.
2213  *
2214  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2215  * @param __pol Optional map write policy (as_map_policy).
2216  * @param __map Source map expression.
2217  * @param __bin Target map bin or map value expression.
2218  * @return (map expression)
2219  * @ingroup expression
2220  */
2221 #define as_exp_map_put_items(__ctx, __pol, __map, __bin) \
2222  _AS_EXP_MAP_MOD(__ctx, __pol, AS_CDT_OP_MAP_PUT_ITEMS, 1, 2), \
2223  __map, \
2224  {.op=_AS_EXP_CODE_CDT_MAP_CRMOD, .v.map_pol = __pol}, \
2225  __bin
2226 
2227 /**
2228  * Create expression that increments values by incr for all items identified by key.
2229  * Valid only for numbers.
2230  *
2231  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2232  * @param __pol Optional map write policy (as_map_policy).
2233  * @param __key Key expression.
2234  * @param __val Increment value number expression.
2235  * @param __bin Map bin or map value expression.
2236  * @return (map expression)
2237  * @ingroup expression
2238  */
2239 #define as_exp_map_increment(__ctx, __pol, __key, __val, __bin) \
2240  _AS_EXP_MAP_MOD(__ctx, __pol, AS_CDT_OP_MAP_INCREMENT, 2, 1), \
2241  __key, __val, \
2242  {.op=_AS_EXP_CODE_CDT_MAP_MOD, .v.map_pol = __pol}, \
2243  __bin
2244 
2245 /**
2246  * Create expression that removes all items in map.
2247  *
2248  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2249  * @param __bin Map bin or map value expression.
2250  * @return (map expression)
2251  * @ingroup expression
2252  */
2253 #define as_exp_map_clear(__ctx, __bin) \
2254  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_CLEAR, 0, 0), \
2255  __bin
2256 
2257 /**
2258  * Create expression that removes map item identified by key.
2259  *
2260  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2261  * @param __key Key expression.
2262  * @param __bin Map bin or map value expression.
2263  * @return (map expression)
2264  * @ingroup expression
2265  */
2266 #define as_exp_map_remove_by_key(__ctx, __key, __bin) \
2267  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY, 2, 0), \
2268  as_exp_int(AS_MAP_RETURN_NONE), \
2269  __key, \
2270  __bin
2271 
2272 /**
2273  * Create expression that removes map items identified by keys.
2274  *
2275  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2276  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2277  * @param __keys List expression of keys to remove.
2278  * @param __bin Map bin or map value expression.
2279  * @return (map expression)
2280  * @ingroup expression
2281  */
2282 #define as_exp_map_remove_by_key_list(__ctx, __rtype, __keys, __bin) \
2283  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_LIST, 2, 0), \
2284  as_exp_int(__rtype), \
2285  __keys, \
2286  __bin
2287 
2288 /**
2289  * Create expression that removes map items identified by key range
2290  * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2291  * If end is infinity, the range is greater than equal to begin.
2292  *
2293  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2294  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2295  * @param __begin Begin value expression.
2296  * @param __end End value expression.
2297  * @param __bin Map bin or map value expression.
2298  * @return (map expression)
2299  * @ingroup expression
2300  */
2301 #define as_exp_map_remove_by_key_range(__ctx, __rtype, __begin, __end, __bin) \
2302  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_INTERVAL, 3, 0), \
2303  as_exp_int(__rtype), \
2304  __begin, __end, \
2305  __bin
2306 
2307 /**
2308  * Create expression that removes map items nearest to key and greater by index.
2309  *
2310  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2311  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2312  * @param __key Key expression.
2313  * @param __idx Index integer expression.
2314  * @param __bin Map bin or map value expression.
2315  * @return (map expression)
2316  * @ingroup expression
2317  */
2318 #define as_exp_map_remove_by_key_rel_index_range_to_end(__ctx, __rtype, __key, __idx, __bin) \
2319  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_REL_INDEX_RANGE, 3, 0), \
2320  as_exp_int(__rtype), \
2321  __key, __idx, \
2322  __bin
2323 
2324 /**
2325  * Create expression that removes map items nearest to key and greater by index with a count limit.
2326  *
2327  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2328  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2329  * @param __key Key expression.
2330  * @param __idx Index integer expression.
2331  * @param __count Count integer expression.
2332  * @param __bin Map bin or map value expression.
2333  * @return (map expression)
2334  * @ingroup expression
2335  */
2336 #define as_exp_map_remove_by_key_rel_index_range(__ctx, __rtype, __key, __idx, __count, __bin) \
2337  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_REL_INDEX_RANGE, 4, 0), \
2338  as_exp_int(__rtype), \
2339  __key, __idx, __count, \
2340  __bin
2341 
2342 /**
2343  * Create expression that removes map items identified by value.
2344  *
2345  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2346  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2347  * @param __val Value expression.
2348  * @param __bin Map bin or map value expression.
2349  * @return (map expression)
2350  * @ingroup expression
2351  */
2352 #define as_exp_map_remove_by_value(__ctx, __rtype, __val, __bin) \
2353  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_ALL_BY_VALUE, 2, 0), \
2354  as_exp_int(__rtype), \
2355  __val, \
2356  __bin
2357 
2358 /**
2359  * Create expression that removes map items identified by values.
2360  *
2361  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2362  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2363  * @param __values Values list expression.
2364  * @param __bin Map bin or map value expression.
2365  * @return (map expression)
2366  * @ingroup expression
2367  */
2368 #define as_exp_map_remove_by_value_list(__ctx, __rtype, __values, __bin) \
2369  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_LIST, 2, 0), \
2370  as_exp_int(__rtype), \
2371  __values, \
2372  __bin
2373 
2374 /**
2375  * Create expression that removes map items identified by value range
2376  * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2377  * If end is infinity, the range is greater than equal to begin.
2378  *
2379  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2380  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2381  * @param __begin Begin value expression.
2382  * @param __end End value expression.
2383  * @param __bin Map bin or map value expression.
2384  * @return (map expression)
2385  * @ingroup expression
2386  */
2387 #define as_exp_map_remove_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
2388  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_INTERVAL, 3, 0), \
2389  as_exp_int(__rtype), \
2390  __begin, __end, \
2391  __bin
2392 
2393 /**
2394  * Create expression that removes map items nearest to value and greater by relative rank.
2395  *
2396  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2397  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2398  * @param __val Value expression.
2399  * @param __rank Rank integer expression.
2400  * @param __bin Map bin or map value expression.
2401  * @return (map expression)
2402  * @ingroup expression
2403  */
2404 #define as_exp_map_remove_by_value_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
2405  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_REL_RANK_RANGE, 3, 0), \
2406  as_exp_int(__rtype), \
2407  __val, __rank, \
2408  __bin
2409 
2410 /**
2411  * Create expression that removes map items nearest to value and greater by relative rank with a
2412  * count limit.
2413  *
2414  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2415  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2416  * @param __val Value expression.
2417  * @param __rank Rank integer expression.
2418  * @param __count Count integer expression.
2419  * @param __bin Map bin or map value expression.
2420  * @return (map expression)
2421  * @ingroup expression
2422  */
2423 #define as_exp_map_remove_by_value_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
2424  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_REL_RANK_RANGE, 4, 0), \
2425  as_exp_int(__rtype), \
2426  __val, __rank, __count, \
2427  __bin
2428 
2429 /**
2430  * Create expression that removes map item identified by index.
2431  *
2432  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2433  * @param __idx Index integer expression.
2434  * @param __bin Map bin or map value expression.
2435  * @return (map expression)
2436  * @ingroup expression
2437  */
2438 #define as_exp_map_remove_by_index(__ctx, __idx, __bin) \
2439  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_INDEX, 2, 0), \
2440  as_exp_int(AS_MAP_RETURN_NONE), \
2441  __idx, \
2442  __bin
2443 
2444 /**
2445  * Create expression that removes map items starting at specified index to the end of map.
2446  *
2447  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2448  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2449  * @param __idx Index integer expression.
2450  * @param __bin Map bin or map value expression.
2451  * @return (map expression)
2452  * @ingroup expression
2453  */
2454 #define as_exp_map_remove_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
2455  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_INDEX_RANGE, 2, 0), \
2456  as_exp_int(__rtype), \
2457  __idx, \
2458  __bin
2459 
2460 /**
2461  * Create expression that removes "count" map items starting at specified index.
2462  *
2463  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2464  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2465  * @param __idx Index integer expression.
2466  * @param __count Count integer expression.
2467  * @param __bin Map bin or map value expression.
2468  * @return (map expression)
2469  * @ingroup expression
2470  */
2471 #define as_exp_map_remove_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
2472  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_INDEX_RANGE, 3, 0), \
2473  as_exp_int(__rtype), \
2474  __idx, __count, \
2475  __bin
2476 
2477 /**
2478  * Create expression that removes map item identified by rank.
2479  *
2480  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2481  * @param __rank Rank integer expression.
2482  * @param __bin Map bin or map value expression.
2483  * @return (map expression)
2484  * @ingroup expression
2485  */
2486 #define as_exp_map_remove_by_rank(__ctx, __rank, __bin) \
2487  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_RANK, 2, 0), \
2488  as_exp_int(AS_MAP_RETURN_NONE), \
2489  __rank, \
2490  __bin
2491 
2492 /**
2493  * Create expression that removes map items starting at specified rank to the last ranked item.
2494  *
2495  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2496  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2497  * @param __rank Rank integer expression.
2498  * @param __bin Map bin or map value expression.
2499  * @return (map expression)
2500  * @ingroup expression
2501  */
2502 #define as_exp_map_remove_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
2503  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_RANK_RANGE, 2, 0), \
2504  as_exp_int(__rtype), \
2505  __rank, \
2506  __bin
2507 
2508 /**
2509  * Create expression that removes "count" map items starting at specified rank.
2510  *
2511  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2512  * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2513  * @param __rank Rank integer expression.
2514  * @param __count Count integer expression.
2515  * @param __bin Map bin or map value expression.
2516  * @return (map expression)
2517  * @ingroup expression
2518  */
2519 #define as_exp_map_remove_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
2520  _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_RANK_RANGE, 3, 0), \
2521  as_exp_int(__rtype), \
2522  __rank, __count, \
2523  __bin
2524 
2525 /*********************************************************************************
2526  * MAP READ EXPRESSIONS
2527  *********************************************************************************/
2528 
2529 #define _AS_EXP_MAP_READ(__type__, __rtype, __is_multi) \
2530  {.op=_AS_EXP_CODE_CALL, .count=5}, \
2531  _AS_EXP_VAL_RTYPE(as_exp_get_map_type(__type__, __rtype, __is_multi)), \
2532  as_exp_int(_AS_EXP_SYS_CALL_CDT)
2533 
2534 #define _AS_EXP_MAP_START(__ctx, __op, __param) \
2535  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param, .v.ctx=__ctx}, \
2536  as_exp_int(__op)
2537 
2538 /**
2539  * Create expression that returns map size.
2540  *
2541  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2542  * @param __bin Map bin or map value expression.
2543  * @return (integer expression)
2544  * @ingroup expression
2545  */
2546 #define as_exp_map_size(__ctx, __bin) \
2547  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, AS_MAP_RETURN_COUNT, false), \
2548  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_SIZE, 0), \
2549  __bin
2550 
2551 /**
2552  * Create expression that selects map item identified by key
2553  * and returns selected data specified by rtype.
2554  *
2555  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2556  * @param __rtype Return type (as_map_return_type).
2557  * @param __vtype Value type (as_exp_type).
2558  * @param __key Key expression.
2559  * @param __bin Map bin or map value expression.
2560  * @return (expression)
2561  * @ingroup expression
2562  */
2563 #define as_exp_map_get_by_key(__ctx, __rtype, __vtype, __key, __bin) \
2564  _AS_EXP_MAP_READ(__vtype, __rtype, false), \
2565  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY, 2), \
2566  as_exp_int(__rtype), \
2567  __key, \
2568  __bin
2569 
2570 /**
2571  * Create expression that selects map items identified by key range
2572  * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2573  * If end is infinity, the range is greater than equal to begin.
2574  * Expression returns selected data specified by rtype.
2575  *
2576  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2577  * @param __rtype Return type (as_map_return_type).
2578  * @param __begin Begin key expression.
2579  * @param __end End key expression.
2580  * @param __bin Map bin or map value expression.
2581  * @return (expression)
2582  * @ingroup expression
2583  */
2584 #define as_exp_map_get_by_key_range(__ctx, __rtype, __begin, __end, __bin) \
2585  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2586  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_INTERVAL, 3), \
2587  as_exp_int(__rtype), \
2588  __begin, __end, \
2589  __bin
2590 
2591 /**
2592  * Create expression that selects map items identified by keys
2593  * and returns selected data specified by rtype.
2594  *
2595  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2596  * @param __rtype Return type (as_map_return_type).
2597  * @param __keys Keys list expression.
2598  * @param __bin Map bin or map value expression.
2599  * @return (expression)
2600  * @ingroup expression
2601  */
2602 #define as_exp_map_get_by_key_list(__ctx, __rtype, __keys, __bin) \
2603  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2604  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_LIST, 2), \
2605  as_exp_int(__rtype), \
2606  __keys, \
2607  __bin
2608 
2609 /**
2610  * Create expression that selects map items nearest to key and greater by index
2611  * and returns selected data specified by rtype.
2612  *
2613  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2614  * @param __rtype Return type (as_map_return_type).
2615  * @param __key Key expression.
2616  * @param __idx Index integer expression.
2617  * @param __bin Map bin or map value expression.
2618  * @return (expression)
2619  * @ingroup expression
2620  */
2621 #define as_exp_map_get_by_key_rel_index_range_to_end(__ctx, __rtype, __key, __idx, __bin) \
2622  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2623  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_REL_INDEX_RANGE, 3), \
2624  as_exp_int(__rtype), \
2625  __key, __idx, \
2626  __bin
2627 
2628 /**
2629  * Create expression that selects map items nearest to key and greater by index with a count limit.
2630  * Expression returns selected data specified by rtype.
2631  *
2632  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2633  * @param __rtype Return type (as_map_return_type).
2634  * @param __key Key expression.
2635  * @param __idx Index integer expression.
2636  * @param __count Count integer expression.
2637  * @param __bin Map bin or map value expression.
2638  * @return (expression)
2639  * @ingroup expression
2640  */
2641 #define as_exp_map_get_by_key_rel_index_range(__ctx, __rtype, __key, __idx, __count, __bin) \
2642  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2643  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_REL_INDEX_RANGE, 4), \
2644  as_exp_int(__rtype), \
2645  __key, __idx, __count, \
2646  __bin
2647 
2648 /**
2649  * Create expression that selects map items identified by value
2650  * and returns selected data specified by rtype.
2651  *
2652  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2653  * @param __rtype Return type (as_map_return_type).
2654  * @param __val Value expression.
2655  * @param __bin Map bin or map value expression.
2656  * @return (expression)
2657  * @ingroup expression
2658  */
2659 #define as_exp_map_get_by_value(__ctx, __rtype, __val, __bin) \
2660  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2661  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_ALL_BY_VALUE, 2), \
2662  as_exp_int(__rtype), \
2663  __val, \
2664  __bin
2665 
2666 /**
2667  * Create expression that selects map items identified by value range
2668  * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2669  * If end is infinity, the range is greater than equal to begin.
2670  * Expression returns selected data specified by rtype.
2671  *
2672  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2673  * @param __rtype Return type (as_map_return_type).
2674  * @param __begin Begin value expression.
2675  * @param __end End value expression.
2676  * @param __bin Map bin or map value expression.
2677  * @return (expression)
2678  * @ingroup expression
2679  */
2680 #define as_exp_map_get_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
2681  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2682  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_INTERVAL, 3), \
2683  as_exp_int(__rtype), \
2684  __begin, __end, \
2685  __bin
2686 
2687 /**
2688  * Create expression that selects map items identified by values
2689  * and returns selected data specified by rtype.
2690  *
2691  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2692  * @param __rtype Return type (as_map_return_type).
2693  * @param __values Values list expression.
2694  * @param __bin Map bin or map value expression.
2695  * @return (expression)
2696  * @ingroup expression
2697  */
2698 #define as_exp_map_get_by_value_list(__ctx, __rtype, __values, __bin) \
2699  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2700  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_LIST, 2), \
2701  as_exp_int(__rtype), \
2702  __values, \
2703  __bin
2704 
2705 /**
2706  * Create expression that selects map items nearest to value and greater by relative rank.
2707  * Expression returns selected data specified by rtype.
2708  *
2709  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2710  * @param __rtype Return type (as_map_return_type).
2711  * @param __val Value expression.
2712  * @param __rank Rank integer expression.
2713  * @param __bin Map bin or map value expression.
2714  * @return (expression)
2715  * @ingroup expression
2716  */
2717 #define as_exp_map_get_by_value_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
2718  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2719  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_REL_RANK_RANGE, 3), \
2720  as_exp_int(__rtype), \
2721  __val, __rank, \
2722  __bin
2723 
2724 /**
2725  * Create expression that selects map items nearest to value and greater by relative rank with a
2726  * count limit. Expression returns selected data specified by rtype.
2727  *
2728  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2729  * @param __rtype Return type (as_map_return_type).
2730  * @param __val Value expression.
2731  * @param __rank Rank integer expression.
2732  * @param __count Count integer expression.
2733  * @param __bin Map bin or map value expression.
2734  * @return (expression)
2735  * @ingroup expression
2736  */
2737 #define as_exp_map_get_by_value_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
2738  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2739  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_REL_RANK_RANGE, 4), \
2740  as_exp_int(__rtype), \
2741  __val, __rank, __count, \
2742  __bin
2743 
2744 /**
2745  * Create expression that selects map item identified by index
2746  * and returns selected data specified by rtype.
2747  *
2748  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2749  * @param __rtype Return type (as_map_return_type).
2750  * @param __vtype Value type (as_exp_type).
2751  * @param __idx Index integer expression.
2752  * @param __bin Map bin or map value expression.
2753  * @return (expression)
2754  * @ingroup expression
2755  */
2756 #define as_exp_map_get_by_index(__ctx, __rtype, __vtype, __idx, __bin) \
2757  _AS_EXP_MAP_READ(__vtype, __rtype, false), \
2758  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_INDEX, 2), \
2759  as_exp_int(__rtype), \
2760  __idx, \
2761  __bin
2762 
2763 /**
2764  * Create expression that selects map items starting at specified index to the end of map
2765  * and returns selected data specified by rtype.
2766  *
2767  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2768  * @param __rtype Return type (as_map_return_type).
2769  * @param __idx Index integer expression.
2770  * @param __bin Map bin or map value expression.
2771  * @return (expression)
2772  * @ingroup expression
2773  */
2774 #define as_exp_map_get_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
2775  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2776  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_INDEX_RANGE, 2), \
2777  as_exp_int(__rtype), \
2778  __idx, \
2779  __bin
2780 
2781 /**
2782  * Create expression that selects "count" map items starting at specified index
2783  * and returns selected data specified by rtype.
2784  *
2785  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2786  * @param __rtype Return type (as_map_return_type).
2787  * @param __idx Index integer expression.
2788  * @param __count Count integer expression.
2789  * @param __bin Map bin or map value expression.
2790  * @return (expression)
2791  * @ingroup expression
2792  */
2793 #define as_exp_map_get_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
2794  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2795  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_INDEX_RANGE, 3), \
2796  as_exp_int(__rtype), \
2797  __idx, __count, \
2798  __bin
2799 
2800 /**
2801  * Create expression that selects map item identified by rank
2802  * and returns selected data specified by rtype.
2803  *
2804  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2805  * @param __rtype Return type (as_map_return_type).
2806  * @param __vtype Value type (as_exp_type).
2807  * @param __rank Rank integer expression.
2808  * @param __bin Map bin or map value expression.
2809  * @return (expression)
2810  * @ingroup expression
2811  */
2812 #define as_exp_map_get_by_rank(__ctx, __rtype, __vtype, __rank, __bin) \
2813  _AS_EXP_MAP_READ(__vtype, __rtype, false), \
2814  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_RANK, 2), \
2815  as_exp_int(__rtype), \
2816  __rank, \
2817  __bin
2818 
2819 /**
2820  * Create expression that selects map items starting at specified rank to the last ranked item
2821  * and returns selected data specified by rtype.
2822  *
2823  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2824  * @param __rtype Return type (as_map_return_type).
2825  * @param __rank Rank integer expression.
2826  * @param __bin Map bin or map value expression.
2827  * @return (expression)
2828  * @ingroup expression
2829  */
2830 #define as_exp_map_get_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
2831  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2832  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_RANK_RANGE, 2), \
2833  as_exp_int(__rtype), \
2834  __rank, \
2835  __bin
2836 
2837 /**
2838  * Create expression that selects "count" map items starting at specified rank
2839  * and returns selected data specified by rtype.
2840  *
2841  * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2842  * @param __rtype Return type (as_map_return_type).
2843  * @param __rank Rank integer expression.
2844  * @param __count Count integer expression.
2845  * @param __bin Map bin or map value expression.
2846  * @return (expression)
2847  * @ingroup expression
2848  */
2849 #define as_exp_map_get_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
2850  _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2851  _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_RANK_RANGE, 3), \
2852  as_exp_int(__rtype), \
2853  __rank, __count, \
2854  __bin
2855 
2856 /*********************************************************************************
2857  * BIT MODIFY EXPRESSIONS
2858  *********************************************************************************/
2859 
2860 #define _AS_EXP_BIT_MOD() \
2861  {.op=_AS_EXP_CODE_CALL, .count=5}, \
2862  _AS_EXP_VAL_RTYPE(AS_EXP_TYPE_BLOB), \
2863  as_exp_int(_AS_EXP_SYS_CALL_BITS | _AS_EXP_SYS_FLAG_MODIFY_LOCAL)
2864 
2865 #define _AS_EXP_BIT_MOD_START(__op, __n_params) \
2866  _AS_EXP_BIT_MOD(), \
2867  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
2868  as_exp_int(__op)
2869 
2870 /**
2871  * Create an expression that performs an as_operations_bit_resize operation.
2872  *
2873  * @param __policy An as_bit_policy value.
2874  * @param __byte_size Number of bytes the resulting blob should occupy.
2875  * @param __flags as_bit_resize_flags value.
2876  * @param __bin A blob bin expression to apply this function to.
2877  * @return (blob bin) __byte_size bytes.
2878  * @ingroup expression
2879  */
2880 #define as_exp_bit_resize(__policy, __byte_size, __flags, __bin) \
2881  _AS_EXP_BIT_MOD_START(AS_BIT_OP_RESIZE, 3), \
2882  __byte_size, \
2883  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2884  as_exp_uint(__flags), \
2885  __bin
2886 
2887 /**
2888  * Create an expression that performs an as_operations_bit_insert operation.
2889  *
2890  * @param __policy An as_bit_policy value.
2891  * @param __byte_offset Byte index of where to insert the value.
2892  * @param __value Blob expression containing the bytes to insert.
2893  * @param __bin A blob bin expression to apply this function to.
2894  * @return (blob bin) resulting blob containing the inserted bytes.
2895  * @ingroup expression
2896  */
2897 #define as_exp_bit_insert(__policy, __byte_offset, __value, __bin) \
2898  _AS_EXP_BIT_MOD_START(AS_BIT_OP_INSERT, 3), \
2899  __byte_offset, \
2900  __value, \
2901  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2902  __bin
2903 
2904 /**
2905  * Create an expression that performs an as_operations_bit_remove operation.
2906  *
2907  * @param __policy An as_bit_policy value.
2908  * @param __byte_offset Byte index of where to remove from.
2909  * @param __byte_size Number of bytes to remove.
2910  * @param __bin A blob bin expression to apply this function to.
2911  * @return (blob bin) resulting blob with the bytes removed.
2912  * @ingroup expression
2913  */
2914 #define as_exp_bit_remove(__policy, __byte_offset, __byte_size, __bin) \
2915  _AS_EXP_BIT_MOD_START(AS_BIT_OP_REMOVE, 3), \
2916  __byte_offset, \
2917  __byte_size, \
2918  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2919  __bin
2920 
2921 /**
2922  * Create an expression that performs an as_operations_bit_set operation.
2923  *
2924  * @param __policy An as_bit_policy value.
2925  * @param __bit_offset Bit index of where to start writing.
2926  * @param __bit_size Number of bytes to overwrite.
2927  * @param __value Blob expression containing bytes to write.
2928  * @param __bin A blob bin expression to apply this function to.
2929  * @return (blob bin) resulting blob with the bytes overwritten.
2930  * @ingroup expression
2931  */
2932 #define as_exp_bit_set(__policy, __bit_offset, __bit_size, __value, __bin) \
2933  _AS_EXP_BIT_MOD_START(AS_BIT_OP_SET, 4), \
2934  __bit_offset, \
2935  __bit_size, \
2936  __value, \
2937  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2938  __bin
2939 
2940 /**
2941  * Create an expression that performs an as_operations_bit_or operation.
2942  *
2943  * @param __policy An as_bit_policy value.
2944  * @param __bit_offset Bit index of where to start operation.
2945  * @param __bit_size Number of bytes to be operated on.
2946  * @param __value Blob expression containing bytes to write.
2947  * @param __bin A blob bin expression to apply this function to.
2948  * @return (blob bin) resulting blob with the bytes operated on.
2949  * @ingroup expression
2950  */
2951 #define as_exp_bit_or(__policy, __bit_offset, __bit_size, __value, __bin) \
2952  _AS_EXP_BIT_MOD_START(AS_BIT_OP_OR, 4), \
2953  __bit_offset, \
2954  __bit_size, \
2955  __value, \
2956  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2957  __bin
2958 
2959 /**
2960  * Create an expression that performs an as_operations_bit_xor operation.
2961  *
2962  * @param __policy An as_bit_policy value.
2963  * @param __bit_offset Bit index of where to start operation.
2964  * @param __bit_size Number of bits to be operated on.
2965  * @param __value Blob expression containing bytes to write.
2966  * @param __bin A blob bin expression to apply this function to.
2967  * @return (blob bin) resulting blob with the bytes operated on.
2968  * @ingroup expression
2969  */
2970 #define as_exp_bit_xor(__policy, __bit_offset, __bit_size, __value, __bin) \
2971  _AS_EXP_BIT_MOD_START(AS_BIT_OP_XOR, 4), \
2972  __bit_offset, \
2973  __bit_size, \
2974  __value, \
2975  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2976  __bin
2977 
2978 /**
2979  * Create an expression that performs an as_operations_bit_and operation.
2980  *
2981  * @param __policy An as_bit_policy value.
2982  * @param __bit_offset Bit index of where to start operation.
2983  * @param __bit_size Number of bits to be operated on.
2984  * @param __value Blob expression containing bytes to write.
2985  * @param __bin A blob bin expression to apply this function to.
2986  * @return (blob bin) resulting blob with the bytes operated on.
2987  * @ingroup expression
2988  */
2989 #define as_exp_bit_and(__policy, __bit_offset, __bit_size, __value, __bin) \
2990  _AS_EXP_BIT_MOD_START(AS_BIT_OP_AND, 4), \
2991  __bit_offset, \
2992  __bit_size, \
2993  __value, \
2994  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2995  __bin
2996 
2997 /**
2998  * Create an expression that performs an as_operations_bit_not operation.
2999  *
3000  * @param __policy An as_bit_policy value.
3001  * @param __bit_offset Bit index of where to start operation.
3002  * @param __bit_size Number of bits to be operated on.
3003  * @param __bin A blob bin expression to apply this function to.
3004  * @return (blob bin) resulting blob with the bytes operated on.
3005  * @ingroup expression
3006  */
3007 #define as_exp_bit_not(__policy, __bit_offset, __bit_size, __bin) \
3008  _AS_EXP_BIT_MOD_START(AS_BIT_OP_NOT, 3), \
3009  __bit_offset, \
3010  __bit_size, \
3011  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3012  __bin
3013 
3014 /**
3015  * Create an expression that performs an as_operations_bit_lshift operation.
3016  *
3017  * @param __policy An as_bit_policy value.
3018  * @param __bit_offset Bit index of where to start operation.
3019  * @param __bit_size Number of bits to be operated on.
3020  * @param __shift Number of bits to shift by.
3021  * @param __bin A blob bin expression to apply this function to.
3022  * @return (blob bin) resulting blob with the bytes operated on.
3023  * @ingroup expression
3024  */
3025 #define as_exp_bit_lshift(__policy, __bit_offset, __bit_size, __shift, __bin) \
3026  _AS_EXP_BIT_MOD_START(AS_BIT_OP_LSHIFT, 4), \
3027  __bit_offset, \
3028  __bit_size, \
3029  __shift, \
3030  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3031  __bin
3032 
3033 /**
3034  * Create an expression that performs an as_operations_bit_rshift operation.
3035  *
3036  * @param __policy An as_bit_policy value.
3037  * @param __bit_offset Bit index of where to start operation.
3038  * @param __bit_size Number of bits to be operated on.
3039  * @param __shift Number of bits to shift by.
3040  * @param __bin A blob bin expression to apply this function to.
3041  * @return (blob bin) resulting blob with the bytes operated on.
3042  * @ingroup expression
3043  */
3044 #define as_exp_bit_rshift(__policy, __bit_offset, __bit_size, __shift, __bin) \
3045  _AS_EXP_BIT_MOD_START(AS_BIT_OP_RSHIFT, 4), \
3046  __bit_offset, \
3047  __bit_size, \
3048  __shift, \
3049  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3050  __bin
3051 
3052 /**
3053  * Create an expression that performs an as_operations_bit_add operation.
3054  * Note: integers are stored big-endian.
3055  *
3056  * @param __policy An as_bit_policy value.
3057  * @param __bit_offset Bit index of where to start operation.
3058  * @param __bit_size Number of bits to be operated on.
3059  * @param __value Integer expression for value to add.
3060  * @param __action as_bit_overflow_action value.
3061  * @param __bin A blob bin expression to apply this function to.
3062  * @return (blob bin) resulting blob with the bytes operated on.
3063  * @ingroup expression
3064  */
3065 #define as_exp_bit_add(__policy, __bit_offset, __bit_size, __value, __action, __bin) \
3066  _AS_EXP_BIT_MOD_START(AS_BIT_OP_ADD, 5), \
3067  __bit_offset, \
3068  __bit_size, \
3069  __value, \
3070  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3071  as_exp_uint(__action), \
3072  __bin
3073 
3074 /**
3075  * Create an expression that performs an as_operations_bit_add operation.
3076  * Note: integers are stored big-endian.
3077  *
3078  * @param __policy An as_bit_policy value.
3079  * @param __bit_offset Bit index of where to start operation.
3080  * @param __bit_size Number of bits to be operated on.
3081  * @param __value Integer expression for value to subtract.
3082  * @param __action as_bit_overflow_action value.
3083  * @param __bin A blob bin expression to apply this function to.
3084  * @return (blob bin) resulting blob with the bytes operated on.
3085  * @ingroup expression
3086  */
3087 #define as_exp_bit_subtract(__policy, __bit_offset, __bit_size, __value, __action, __bin) \
3088  _AS_EXP_BIT_MOD_START(AS_BIT_OP_SUBTRACT, 5), \
3089  __bit_offset, \
3090  __bit_size, \
3091  __value, \
3092  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3093  as_exp_uint(__action), \
3094  __bin
3095 
3096 /**
3097  * Create an expression that performs an as_operations_bit_add operation.
3098  * Note: integers are stored big-endian.
3099  *
3100  * @param __policy An as_bit_policy value.
3101  * @param __bit_offset Bit index of where to start operation.
3102  * @param __bit_size Number of bits to be operated on.
3103  * @param __value Integer expression for value to set.
3104  * @param __bin A blob bin expression to apply this function to.
3105  * @return (blob bin) resulting blob with the bytes operated on.
3106  * @ingroup expression
3107  */
3108 #define as_exp_bit_set_int(__policy, __bit_offset, __bit_size, __value, __bin) \
3109  _AS_EXP_BIT_MOD_START(AS_BIT_OP_SET_INT, 4), \
3110  __bit_offset, \
3111  __bit_size, \
3112  __value, \
3113  as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3114  __bin
3115 
3116 /*********************************************************************************
3117  * BIT READ EXPRESSIONS
3118  *********************************************************************************/
3119 
3120 #define _AS_EXP_BIT_READ(__rtype) \
3121  {.op=_AS_EXP_CODE_CALL, .count=5}, \
3122  _AS_EXP_VAL_RTYPE(__rtype), \
3123  as_exp_int(_AS_EXP_SYS_CALL_BITS)
3124 
3125 #define _AS_EXP_BIT_READ_START(__rtype, __op, __n_params) \
3126  _AS_EXP_BIT_READ(__rtype), \
3127  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
3128  as_exp_int(__op)
3129 
3130 /**
3131  * Create an expression that performs an as_operations_bit_get operation.
3132  *
3133  * @param __bit_offset The bit index of where to start reading from.
3134  * @param __bit_size Number of bits to read from the blob bin.
3135  * @param __bin A blob bin expression to apply this function to.
3136  * @return (blob bin) bit_size bits rounded up to the nearest byte size.
3137  * @ingroup expression
3138  */
3139 #define as_exp_bit_get(__bit_offset, __bit_size, __bin) \
3140  _AS_EXP_BIT_READ_START(AS_EXP_TYPE_BLOB, AS_BIT_OP_GET, 2), \
3141  __bit_offset, \
3142  __bit_size, \
3143  __bin
3144 
3145 /**
3146  * Create an expression that performs an as_operations_bit_count operation.
3147  *
3148  * @param __bit_offset The bit index of where to start reading from.
3149  * @param __bit_size Number of bits to read from the blob bin.
3150  * @param __bin A blob bin expression to apply this function to.
3151  * @return (integer value) number of bits set to 1 in the bit_size region.
3152  * @ingroup expression
3153  */
3154 #define as_exp_bit_count(__bit_offset, __bit_size, __bin) \
3155  _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_COUNT, 2), \
3156  __bit_offset, \
3157  __bit_size, \
3158  __bin
3159 
3160 /**
3161  * Create an expression that performs an as_operations_bit_lscan operation.
3162  *
3163  * @param __bit_offset The bit index of where to start reading from.
3164  * @param __bit_size Number of bits to read from the blob bin.
3165  * @param __value Boolean expression, true searches for 1, false for 0.
3166  * @param __bin A blob bin expression to apply this function to.
3167  * @return (integer value) Index of the left most bit starting from __offset set to __value.
3168  * @ingroup expression
3169  */
3170 #define as_exp_bit_lscan(__bit_offset, __bit_size, __value, __bin) \
3171  _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_LSCAN, 3), \
3172  __bit_offset, \
3173  __bit_size, \
3174  __value, \
3175  __bin
3176 
3177 /**
3178  * Create an expression that performs an as_operations_bit_rscan operation.
3179  *
3180  * @param __bit_offset The bit index of where to start reading from.
3181  * @param __bit_size Number of bits to read from the blob bin.
3182  * @param __value Boolean expression, true searches for 1, false for 0.
3183  * @param __bin A blob bin expression to apply this function to.
3184  * @return (integer value) Index of the right most bit starting from __offset set to __value.
3185  * @ingroup expression
3186  */
3187 #define as_exp_bit_rscan(__bit_offset, __bit_size, __value, __bin) \
3188  _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_RSCAN, 3), \
3189  __bit_offset, \
3190  __bit_size, \
3191  __value, \
3192  __bin
3193 
3194 /**
3195  * Create an expression that performs an as_operations_bit_get_int operation.
3196  *
3197  * @param __bit_offset The bit index of where to start reading from.
3198  * @param __bit_size Number of bits to read from the blob bin.
3199  * @param __sign Boolean value, true for signed, false for unsigned.
3200  * @param __bin A blob bin expression to apply this function to.
3201  * @return (integer value) Index of the left most bit starting from __offset set to __value.
3202  * @ingroup expression
3203  */
3204 #define as_exp_bit_get_int(__bit_offset, __bit_size, __sign, __bin) \
3205  _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_GET_INT, 3), \
3206  __bit_offset, \
3207  __bit_size, \
3208  as_exp_int(__sign ? 1 : 0), \
3209  __bin
3210 
3211 /*********************************************************************************
3212  * HLL MODIFY EXPRESSIONS
3213  *********************************************************************************/
3214 
3215 #define _AS_EXP_HLL_MOD() \
3216  {.op=_AS_EXP_CODE_CALL, .count=5}, \
3217  _AS_EXP_VAL_RTYPE(AS_EXP_TYPE_HLL), \
3218  as_exp_int(_AS_EXP_SYS_CALL_HLL | _AS_EXP_SYS_FLAG_MODIFY_LOCAL)
3219 
3220 #define _AS_EXP_HLL_MOD_START(__op, __n_params) \
3221  _AS_EXP_HLL_MOD(), \
3222  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
3223  as_exp_int(__op)
3224 
3225 /**
3226  * Create expression that creates a new HLL or resets an existing HLL with minhash bits.
3227  *
3228  * @param __policy An as_hll_policy value.
3229  * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3230  * @param __mh_bit_count Number of min hash bits. Must be between 4 and 51 inclusive.
3231  * Also, __index_bit_count + __mh_bit_count must be <= 64.
3232  * @param __bin A bin expression to apply this function to.
3233  * @return (hll bin) Returns the resulting hll bin.
3234  * @ingroup expression
3235  */
3236 #define as_exp_hll_init_mh(__policy, __index_bit_count, __mh_bit_count, __bin) \
3237  _AS_EXP_HLL_MOD_START(AS_HLL_OP_INIT, 3), \
3238  as_exp_int(__index_bit_count), \
3239  as_exp_int(__mh_bit_count), \
3240  as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3241  __bin
3242 
3243 /**
3244  * Create expression that creates a new HLL or resets an existing HLL.
3245  *
3246  * @param __policy An as_hll_policy value.
3247  * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3248  * @param __bin A bin expression to apply this function to.
3249  * @return (hll bin) Returns the resulting hll bin.
3250  * @ingroup expression
3251  */
3252 #define as_exp_hll_init(__policy, __index_bit_count, __bin) \
3253  _AS_EXP_HLL_MOD_START(AS_HLL_OP_INIT, 2), \
3254  as_exp_int(__index_bit_count), \
3255  as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3256  __bin
3257 
3258 /**
3259  * Create an expression that performs an as_operations_hll_add_mh.
3260  *
3261  * @param __policy An as_hll_policy value.
3262  * @param __list A list expression of elements to add to the HLL.
3263  * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3264  * @param __mh_bit_count Number of min hash bits. Must be between 4 and 51 inclusive.
3265  * Also, __index_bit_count + __mh_bit_count must be <= 64.
3266  * @param __bin A bin expression to apply this function to.
3267  * @return (hll bin) Returns the resulting hll bin after adding elements from __list.
3268  * @ingroup expression
3269  */
3270 #define as_exp_hll_add_mh(__policy, __list, __index_bit_count, __mh_bit_count, __bin) \
3271  _AS_EXP_HLL_MOD_START(AS_HLL_OP_ADD, 4), \
3272  __list, \
3273  as_exp_int(__index_bit_count), \
3274  as_exp_int(__mh_bit_count), \
3275  as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3276  __bin
3277 
3278 /**
3279  * Create an expression that performs an as_operations_hll_add.
3280  *
3281  * @param __policy An as_hll_policy value.
3282  * @param __list A list expression of elements to add to the HLL.
3283  * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3284  * @param __bin A bin expression to apply this function to.
3285  * @return (hll bin) Returns the resulting hll bin after adding elements from __list.
3286  * @ingroup expression
3287  */
3288 #define as_exp_hll_add(__policy, __list, __index_bit_count, __bin) \
3289  _AS_EXP_HLL_MOD_START(AS_HLL_OP_ADD, 4), \
3290  __list, \
3291  as_exp_int(__index_bit_count), \
3292  as_exp_int(-1), \
3293  as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3294  __bin
3295 
3296 /**
3297  * Create an expression that performs an as_operations_hll_update.
3298  *
3299  * @param __policy An as_hll_policy value.
3300  * @param __list A list expression of elements to add to the HLL.
3301  * @param __bin A bin expression to apply this function to.
3302  * @return (hll bin) Returns the resulting hll bin after adding elements from __list.
3303  * @ingroup expression
3304  */
3305 #define as_exp_hll_update(__policy, __list, __bin) \
3306  _AS_EXP_HLL_MOD_START(AS_HLL_OP_ADD, 4), \
3307  __list, \
3308  as_exp_int(-1), \
3309  as_exp_int(-1), \
3310  as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3311  __bin
3312 
3313 /*********************************************************************************
3314  * HLL READ EXPRESSIONS
3315  *********************************************************************************/
3316 
3317 #define _AS_EXP_HLL_READ(__rtype) \
3318  {.op=_AS_EXP_CODE_CALL, .count=5}, \
3319  _AS_EXP_VAL_RTYPE(__rtype), \
3320  as_exp_int(_AS_EXP_SYS_CALL_HLL)
3321 
3322 #define _AS_EXP_HLL_READ_START(__rtype, __op, __n_params) \
3323  _AS_EXP_HLL_READ(__rtype), \
3324  {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
3325  as_exp_int(__op)
3326 
3327 /**
3328  * Create an expression that performs an as_operations_hll_get_count.
3329  *
3330  * @param __bin A bin expression to apply this function to.
3331  * @return (integer bin) The estimated number of unique elements in an HLL.
3332  * @ingroup expression
3333  */
3334 #define as_exp_hll_get_count(__bin) \
3335  _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_COUNT, 0), \
3336  __bin
3337 
3338 /**
3339  * Create an expression that performs an as_operations_hll_get_union.
3340  *
3341  * @param __list A list expression of HLLs to union with.
3342  * @param __bin A bin expression to apply this function to.
3343  * @return (hll bin) HLL bin representing the set union.
3344  * @ingroup expression
3345  */
3346 #define as_exp_hll_get_union(__list, __bin) \
3347  _AS_EXP_HLL_READ_START(AS_EXP_TYPE_HLL, AS_HLL_OP_GET_UNION, 1), \
3348  __list, \
3349  __bin
3350 
3351 /**
3352  * Create an expression that performs an as_operations_hll_get_union_count.
3353  *
3354  * @param __list A list expression of HLLs to union with.
3355  * @param __bin A bin expression to apply this function to.
3356  * @return (integer bin) Estimated number of elements in the set union.
3357  * @ingroup expression
3358  */
3359 #define as_exp_hll_get_union_count(__list, __bin) \
3360  _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_UNION_COUNT, 1), \
3361  __list, \
3362  __bin
3363 
3364 /**
3365  * Create an expression that performs an as_operations_hll_get_inersect_count.
3366  *
3367  * @param __list A list expression of HLLs to intersect with.
3368  * @param __bin A bin expression to apply this function to.
3369  * @return (integer bin) Estimated number of elements in the set intersection.
3370  * @ingroup expression
3371  */
3372 #define as_exp_hll_get_intersect_count(__list, __bin) \
3373  _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_INTERSECT_COUNT, 1), \
3374  __list, \
3375  __bin
3376 
3377 /**
3378  * Create an expression that performs an as_operations_hll_get_similarity.
3379  *
3380  * @param __list A list expression of HLLs to calculate similarity with..
3381  * @param __bin A bin expression to apply this function to.
3382  * @return (float bin) Estimated similarity between 0.0 and 1.0.
3383  * @ingroup expression
3384  */
3385 #define as_exp_hll_get_similarity(__list, __bin) \
3386  _AS_EXP_HLL_READ_START(AS_EXP_TYPE_FLOAT, AS_HLL_OP_SIMILARITY, 1), \
3387  __list, \
3388  __bin
3389 
3390 /**
3391  * Create an expression that performs an as_operations_hll_describe.
3392  *
3393  * @param __bin A bin expression to apply this function to.
3394  * @return (list bin) A list containing the index_bit_count and minhash_bit_count.
3395  * @ingroup expression
3396  */
3397 #define as_exp_hll_describe(__bin) \
3398  _AS_EXP_HLL_READ_START(AS_EXP_TYPE_LIST, AS_HLL_OP_DESCRIBE, 0), \
3399  __bin
3400 
3401 /**
3402  * Create an expression that checks if the HLL __bin may contain all keys in
3403  * __list..
3404  *
3405  * @param __list A list expression of keys to check if the HLL may contain them.
3406  * @param __bin A bin expression to apply this function to.
3407  * @return (integer bin) 1 __bin may contain all of __list, 0 otherwise.
3408  * @ingroup expression
3409  */
3410 #define as_exp_hll_may_contain(__list, __bin) \
3411  _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_MAY_CONTAIN, 1), \
3412  __list, \
3413  __bin
3414 
3415 /*********************************************************************************
3416  * EXPRESSION MERGE
3417  *********************************************************************************/
3418 
3419 /**
3420  * Merge precompiled expression into a new expression tree.
3421  * Useful for storing common precompiled expressions and then reusing
3422  * these expressions as part of a greater expression.
3423  *
3424  * ~~~~~~~~~~{.c}
3425  * // Merge precompiled expression into new expression.
3426  * as_exp_build(expr, as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(200)));
3427  * as_exp_build(merged,
3428  * as_exp_and(
3429  * as_exp_expr(expr),
3430  * as_exp_cmp_eq(as_exp_bin_int("b"), as_exp_int(100))));
3431  * ~~~~~~~~~~
3432  *
3433  * @param __e Pre-compiled expression.
3434  * @ingroup expression
3435  */
3436 #define as_exp_expr(__e) \
3437  {.op=_AS_EXP_CODE_MERGE, .v.expr=__e}
3438 
3439 /*********************************************************************************
3440  * EXPRESSION BUILDERS
3441  *********************************************************************************/
3442 
3443 /**
3444  * Declare and build an expression variable.
3445  *
3446  * ~~~~~~~~~~{.c}
3447  * // a == 10
3448  * as_exp_build(expression,
3449  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(10)));
3450  * ...
3451  * as_exp_destroy(expression);
3452  * ~~~~~~~~~~
3453  *
3454  * @param __name Name of the variable to hold the expression
3455  * @ingroup expression
3456  */
3457 #define as_exp_build(__name, ...) \
3458  as_exp* __name; \
3459  do { \
3460  as_exp_entry __table__[] = { __VA_ARGS__ }; \
3461  __name = as_exp_compile(__table__, sizeof(__table__) / sizeof(as_exp_entry)); \
3462  } while (false)
3463 
3464 /**
3465  * Declare and build an base64 packed expression variable.
3466  *
3467  * ~~~~~~~~~~{.c}
3468  * // a == 10
3469  * as_exp_build_b64(expression,
3470  * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(10)));
3471  * ...
3472  * as_exp_destroy_b64(expression);
3473  * ~~~~~~~~~~
3474  *
3475  * @param __name Name of the variable to hold the expression
3476  * @ingroup expression
3477  */
3478 #define as_exp_build_b64(__name, ...) \
3479  char* __name; \
3480  do { \
3481  as_exp_entry __table__[] = { __VA_ARGS__ }; \
3482  as_exp* temp = as_exp_compile(__table__, sizeof(__table__) / sizeof(as_exp_entry)); \
3483  __name = as_exp_compile_b64(temp); \
3484  as_exp_destroy(temp); \
3485  } while (false)
3486 
3487 #ifdef __cplusplus
3488 } // end extern "C"
3489 #endif
AS_EXTERN as_exp * as_exp_compile(as_exp_entry *table, uint32_t n)
double float_val
Definition: as_exp.h:199
uint8_t type
Definition: as_proto.h:36
static void as_exp_destroy_base64(char *base64)
Definition: as_exp.h:258
as_exp_call_system_type
Definition: as_exp.h:158
as_exp * expr
Definition: as_exp.h:205
const char * str_val
Definition: as_exp.h:195
AS_EXTERN int64_t as_exp_get_ctx_type(const as_cdt_ctx *ctx, as_exp_type default_type)
as_list_return_type
AS_EXTERN int64_t as_exp_get_list_type(as_exp_type default_type, as_list_return_type rtype, bool is_multi)
static char * as_exp_to_base64(as_exp *exp)
Definition: as_exp.h:232
as_exp_type
Definition: as_exp.h:166
as_map_policy * map_pol
Definition: as_exp.h:204
Definition: as_val.h:61
uint32_t count
Definition: as_exp.h:189
bool bool_val
Definition: as_exp.h:200
#define AS_EXTERN
Definition: as_std.h:25
AS_EXTERN int64_t as_exp_get_map_type(as_exp_type type, as_map_return_type rtype, bool is_multi)
AS_EXTERN uint8_t * as_exp_write(as_exp *exp, uint8_t *ptr)
Definition: as_exp.h:182
AS_EXTERN char * as_exp_compile_b64(as_exp *exp)
as_exp_ops
Definition: as_exp.h:66
uint32_t sz
Definition: as_exp.h:190
as_val * val
Definition: as_exp.h:194
int64_t int_val
Definition: as_exp.h:197
uint8_t * bytes_val
Definition: as_exp.h:196
as_cdt_ctx * ctx
Definition: as_exp.h:202
AS_EXTERN void as_exp_destroy(as_exp *exp)
uint64_t uint_val
Definition: as_exp.h:198
as_exp_ops op
Definition: as_exp.h:188
as_map_return_type
uint32_t packed_sz
Definition: as_exp.h:183
Definition: as_exp.h:187
AS_EXTERN void as_exp_destroy_b64(char *b64)
int32_t prev_va_args
Definition: as_exp.h:191
uint8_t packed[]
Definition: as_exp.h:184
AS_EXTERN as_exp * as_exp_from_base64(const char *base64)
as_list_policy * list_pol
Definition: as_exp.h:203