Loading...
Searching...
No Matches
as_exp.h
Go to the documentation of this file.
1/*
2 * Copyright 2008-2024 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
59extern "C" {
60#endif
61
62/******************************************************************************
63 * TYPES
64 *****************************************************************************/
65
66typedef 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
158typedef 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
181
182typedef struct as_exp {
183 uint32_t packed_sz;
184 uint8_t packed[];
185} as_exp;
186
187typedef struct {
189 uint32_t count;
190 uint32_t sz;
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;
201
202 as_cdt_ctx* ctx; // for CALL
203 as_list_policy* list_pol; // for LIST_POL_*
206 } v;
208
209/*********************************************************************************
210 * PRIVATE FUNCTIONS
211 *********************************************************************************/
212
216AS_EXTERN uint8_t* as_exp_write(as_exp* exp, uint8_t* ptr);
217AS_EXTERN int64_t as_exp_get_ctx_type(const as_cdt_ctx* ctx, as_exp_type default_type);
218AS_EXTERN int64_t as_exp_get_list_type(as_exp_type default_type, as_list_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 */
231static 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 */
244
245/**
246 * Free expression bytes.
247 *
248 * @ingroup expression
249 */
251
252/**
253 * Free base64 string.
254 *
255 * @ingroup expression
256 */
257static 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 * This expression works for XDR filters and when used from a write request within
782 * as_operations_exp_write() or as_operations_exp_read(). This expression does not
783 * work with normal filtering of records because the tombstone record will be filtered
784 * out before this expression is evaluated.
785 *
786 * ~~~~~~~~~~{.c}
787 * // Deleted records that are in tombstone state.
788 * as_exp_build(expression, as_exp_is_tombstone());
789 * ~~~~~~~~~~
790 *
791 * @return (boolean value) True if the record is a tombstone, false otherwise.
792 * @ingroup expression
793 */
794#define as_exp_is_tombstone() {.op=_AS_EXP_CODE_IS_TOMBSTONE, .count=1}
795
796/**
797 * Create expression that returns record size in memory when either the
798 * storage-engine is memory or data-in-memory is true, otherwise returns 0.
799 * This expression usually evaluates quickly because record meta data is cached
800 * in memory.
801 *
802 * Requires server version between 5.3 inclusive and 7.0 exclusive.
803 * Use as_exp_record_size() for server version 7.0+.
804 *
805 * ~~~~~~~~~~{.c}
806 * // Record memory size >= 100 KB
807 * as_exp_build(expression,
808 * as_exp_cmp_ge(as_exp_memory_size(), as_exp_int(100 * 1024)));
809 * ~~~~~~~~~~
810 *
811 * @return (integer value) memory size of the record.
812 * @ingroup expression
813 */
814#define as_exp_memory_size() {.op=_AS_EXP_CODE_MEMORY_SIZE, .count=1}
815
816/**
817 * Create expression that returns record digest modulo as integer.
818 *
819 * ~~~~~~~~~~{.c}
820 * // Records that have digest(key) % 3 == 1
821 * as_exp_build(expression,
822 * as_exp_cmp_eq(as_exp_digest_modulo(3), as_exp_int(1)));
823 * ~~~~~~~~~~
824 *
825 * @param __mod Divisor used to divide the digest to get a remainder.
826 * @return (integer value) Value in range 0 and mod (exclusive)..
827 * @ingroup expression
828 */
829#define as_exp_digest_modulo(__mod) \
830 {.op=_AS_EXP_CODE_DIGEST_MODULO, .count=2}, \
831 as_exp_int(__mod)
832
833/*********************************************************************************
834 * COMPARISON EXPRESSIONS
835 *********************************************************************************/
836
837/**
838 * Create equals (==) expression.
839 *
840 * ~~~~~~~~~~{.c}
841 * // Integer bin "a" == 11.
842 * as_exp_build(expression, as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(11)));
843 * ~~~~~~~~~~
844 *
845 * @param __left left expression in comparison.
846 * @param __right right expression in comparison.
847 * @return (boolean value)
848 * @ingroup expression
849 */
850#define as_exp_cmp_eq(__left, __right) \
851 {.op=_AS_EXP_CODE_CMP_EQ, .count=3}, __left, __right
852
853/**
854 * Create not equal (!=) expression.
855 *
856 * ~~~~~~~~~~{.c}
857 * // Integer bin "a" != 13.
858 * as_exp_build(expression, as_exp_cmp_ne(as_exp_bin_int("a"), as_exp_int(13)));
859
860 * ~~~~~~~~~~
861 *
862 * @param __left left expression in comparison.
863 * @param __right right expression in comparison.
864 * @return (boolean value)
865 * @ingroup expression
866 */
867#define as_exp_cmp_ne(__left, __right) \
868 {.op=_AS_EXP_CODE_CMP_NE, .count=3}, __left, __right
869
870/**
871 * Create a greater than (>) expression.
872 *
873 * ~~~~~~~~~~{.c}
874 * // Integer bin "a" > 8.
875 * as_exp_build(expression, as_exp_cmp_gt(as_exp_bin_int("a"), as_exp_int(8)));
876 * ~~~~~~~~~~
877 *
878 * @param __left left expression in comparison.
879 * @param __right right expression in comparison.
880 * @return (boolean value)
881 * @ingroup expression
882 */
883#define as_exp_cmp_gt(__left, __right) \
884 {.op=_AS_EXP_CODE_CMP_GT, .count=3}, __left, __right
885
886/**
887 * Create a greater than or equals (>=) expression.
888 *
889 * ~~~~~~~~~~{.c}
890 * // Integer bin "a" >= 88.
891 * as_exp_build(expression, as_exp_cmp_ge(as_exp_bin_int("a"), as_exp_int(88)));
892 * ~~~~~~~~~~
893 *
894 * @param __left left expression in comparison.
895 * @param __right right expression in comparison.
896 * @return (boolean value)
897 * @ingroup expression
898 */
899#define as_exp_cmp_ge(__left, __right) \
900 {.op=_AS_EXP_CODE_CMP_GE, .count=3}, __left, __right
901
902/**
903 * Create a less than (<) expression.
904 *
905 * ~~~~~~~~~~{.c}
906 * // Integer bin "a" < 1000.
907 * as_exp_build(expression, as_exp_cmp_lt(as_exp_bin_int("a"), as_exp_int(1000)));
908 * ~~~~~~~~~~
909 *
910 * @param __left left expression in comparison.
911 * @param __right right expression in comparison.
912 * @return (boolean value)
913 * @ingroup expression
914 */
915#define as_exp_cmp_lt(__left, __right) \
916 {.op=_AS_EXP_CODE_CMP_LT, .count=3}, __left, __right
917
918/**
919 * Create a less than or equals (<=) expression.
920 *
921 * ~~~~~~~~~~{.c}
922 * // Integer bin "a" <= 1.
923 * as_exp_build(expression, as_exp_cmp_le(as_exp_bin_int("a"), as_exp_int(1)));
924 * ~~~~~~~~~~
925 *
926 * @param __left left expression in comparison.
927 * @param __right right expression in comparison.
928 * @return (boolean value)
929 * @ingroup expression
930 */
931#define as_exp_cmp_le(__left, __right) \
932 {.op=_AS_EXP_CODE_CMP_LE, .count=3}, __left, __right
933
934/**
935 * Create expression that performs a regex match on a string bin or value
936 * expression.
937 *
938 * ~~~~~~~~~~{.c}
939 * // Select string bin "a" that starts with "prefix" and ends with "suffix".
940 * // Ignore case and do not match newline.
941 * as_exp_build(expression,
942 * as_exp_cmp_regex(REG_ICASE | REG_NEWLINE, as_exp_str("prefix.*suffix"), as_exp_bin_str("a")));
943 * ~~~~~~~~~~
944 *
945 * @param __options POSIX regex flags defined in regex.h.
946 * @param __regex_str POSIX regex string.
947 * @param __cmp_str String expression to compare against.
948 * @return (boolean value)
949 * @ingroup expression
950 */
951#define as_exp_cmp_regex(__options, __regex_str, __cmp_str) \
952 {.op=_AS_EXP_CODE_CMP_REGEX, .count=4}, \
953 as_exp_int(__options), _AS_EXP_VAL_RAWSTR(__regex_str), \
954 __cmp_str
955
956/**
957 * Create a point within region or region contains point expression.
958 *
959 * ~~~~~~~~~~{.c}
960 * // Geo bin "point" is within geo bin "region".
961 * as_exp_build(expression,
962 * as_exp_cmp_geo(as_exp_bin_geo("point"), as_exp_bin_geo("region")));
963 * ~~~~~~~~~~
964 *
965 * @param __left left expression in comparison.
966 * @param __right right expression in comparison.
967 * @return (boolean value)
968 * @ingroup expression
969 */
970#define as_exp_cmp_geo(__left, __right) \
971 {.op=_AS_EXP_CODE_CMP_GEO, .count=3}, __left, __right
972
973/*********************************************************************************
974 * LOGICAL EXPRESSIONS
975 *********************************************************************************/
976
977/**
978 * Create "not" (!) operator expression.
979 *
980 * ~~~~~~~~~~{.c}
981 * // ! (a == 0 || a == 10)
982 * as_exp_build(expression,
983 * as_exp_not(as_exp_or(
984 * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)),
985 * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(10)))));
986 * ~~~~~~~~~~
987 *
988 * @param __expr Boolean expression to negate.
989 * @return (boolean value)
990 * @ingroup expression
991 */
992#define as_exp_not(__expr) {.op=_AS_EXP_CODE_NOT, .count=2}, __expr
993
994/**
995 * Create "and" (&&) operator that applies to a variable number of expressions.
996 *
997 * ~~~~~~~~~~{.c}
998 * // (a > 5 || a == 0) && b < 3
999 * as_exp_build(expression,
1000 * as_exp_and(
1001 * as_exp_or(
1002 * as_exp_cmp_gt(as_exp_bin_int("a"), as_exp_int(5)),
1003 * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)))
1004 * as_exp_cmp_lt(as_exp_bin_int("b"), as_exp_int(3))));
1005 * ~~~~~~~~~~
1006 *
1007 * @param ... Variable number of boolean expressions.
1008 * @return (boolean value)
1009 * @ingroup expression
1010 */
1011#define as_exp_and(...) {.op=_AS_EXP_CODE_AND}, __VA_ARGS__, \
1012 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1013
1014/**
1015 * Create "or" (||) operator that applies to a variable number of expressions.
1016 *
1017 * ~~~~~~~~~~{.c}
1018 * // a == 0 || b == 0
1019 * as_exp_build(expression,
1020 * as_exp_or(
1021 * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)),
1022 * as_exp_cmp_eq(as_exp_bin_int("b"), as_exp_int(0))));
1023 * ~~~~~~~~~~
1024 *
1025 * @param ... Variable number of boolean expressions.
1026 * @return (boolean value)
1027 * @ingroup expression
1028 */
1029#define as_exp_or(...) {.op=_AS_EXP_CODE_OR}, __VA_ARGS__, \
1030 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1031
1032/**
1033 * Create expression that returns true if only one of the expressions are true.
1034 * Requires server version 5.6.0+.
1035 *
1036 * ~~~~~~~~~~{.c}
1037 * // exclusive(a == 0, b == 0)
1038 * as_exp_build(expression,
1039 * as_exp_exclusive(
1040 * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(0)),
1041 * as_exp_cmp_eq(as_exp_bin_int("b"), as_exp_int(0))));
1042 * ~~~~~~~~~~
1043 *
1044 * @param ... Variable number of boolean expressions.
1045 * @return (boolean value)
1046 * @ingroup expression
1047 */
1048#define as_exp_exclusive(...) {.op=_AS_EXP_CODE_EXCLUSIVE}, __VA_ARGS__, \
1049 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1050
1051/*********************************************************************************
1052 * ARITHMETIC EXPRESSIONS
1053 *********************************************************************************/
1054
1055/**
1056 * Create "add" (+) operator that applies to a variable number of expressions.
1057 * Return the sum of all arguments.
1058 * All arguments must be the same type (integer or float).
1059 * Requires server version 5.6.0+.
1060 *
1061 * ~~~~~~~~~~{.c}
1062 * // a + b + c == 10
1063 * as_exp_build(expression,
1064 * as_exp_cmp_eq(
1065 * as_exp_add(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1066 * as_exp_int(10)));
1067 * ~~~~~~~~~~
1068 *
1069 * @param ... Variable number of integer or float expressions.
1070 * @return (integer or float value)
1071 * @ingroup expression
1072 */
1073#define as_exp_add(...) {.op=_AS_EXP_CODE_ADD}, __VA_ARGS__, \
1074 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1075
1076/**
1077 * Create "subtract" (-) operator that applies to a variable number of expressions.
1078 * If only one argument is provided, return the negation of that argument.
1079 * Otherwise, return the sum of the 2nd to Nth argument subtracted from the 1st
1080 * argument. All arguments must resolve to the same type (integer or float).
1081 * Requires server version 5.6.0+.
1082 *
1083 * ~~~~~~~~~~{.c}
1084 * // a - b - c > 10
1085 * as_exp_build(expression,
1086 * as_exp_cmp_gt(
1087 * as_exp_sub(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1088 * as_exp_int(10)));
1089 * ~~~~~~~~~~
1090 *
1091 * @param ... Variable number of integer or float expressions.
1092 * @return (integer or float value)
1093 * @ingroup expression
1094 */
1095#define as_exp_sub(...) {.op=_AS_EXP_CODE_SUB}, __VA_ARGS__, \
1096 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1097
1098/**
1099 * Create "multiply" (*) operator that applies to a variable number of expressions.
1100 * Return the product of all arguments. If only one argument is supplied, return
1101 * that argument. All arguments must resolve to the same type (integer or float).
1102 * Requires server version 5.6.0+.
1103 *
1104 * ~~~~~~~~~~{.c}
1105 * // a * b * c < 100
1106 * as_exp_build(expression,
1107 * as_exp_cmp_lt(
1108 * as_exp_mul(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1109 * as_exp_int(100)));
1110 * ~~~~~~~~~~
1111 *
1112 * @param ... Variable number of integer or float expressions.
1113 * @return (integer or float value)
1114 * @ingroup expression
1115 */
1116#define as_exp_mul(...) {.op=_AS_EXP_CODE_MUL}, __VA_ARGS__, \
1117 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1118
1119/**
1120 * Create "divide" (/) operator that applies to a variable number of expressions.
1121 * If there is only one argument, returns the reciprocal for that argument.
1122 * Otherwise, return the first argument divided by the product of the rest.
1123 * All arguments must resolve to the same type (integer or float).
1124 * Requires server version 5.6.0+.
1125 *
1126 * ~~~~~~~~~~{.c}
1127 * // a / b / c == 1
1128 * as_exp_build(expression,
1129 * as_exp_cmp_gt(
1130 * as_exp_div(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1131 * as_exp_int(1)));
1132 * ~~~~~~~~~~
1133 *
1134 * @param ... Variable number of integer or float expressions.
1135 * @return (integer or float value)
1136 * @ingroup expression
1137 */
1138#define as_exp_div(...) {.op=_AS_EXP_CODE_DIV}, __VA_ARGS__, \
1139 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1140
1141/**
1142 * Create "pow" operator that raises a "base" to the "exponent" power.
1143 * All arguments must resolve to floats.
1144 * Requires server version 5.6.0+.
1145 *
1146 * ~~~~~~~~~~{.c}
1147 * // pow(a, 2.0) == 4.0
1148 * as_exp_build(expression,
1149 * as_exp_cmp_eq(
1150 * as_exp_pow(as_exp_bin_float("a"), as_exp_float(2.0)),
1151 * as_exp_float(4.0)));
1152 * ~~~~~~~~~~
1153 *
1154 * @param __base Base value.
1155 * @param __exponent Exponent value.
1156 * @return (float value)
1157 * @ingroup expression
1158 */
1159#define as_exp_pow(__base, __exponent) \
1160 {.op=_AS_EXP_CODE_POW, .count=3}, __base, __exponent
1161
1162/**
1163 * Create "log" operator for logarithm of "num" with base "base".
1164 * All arguments must resolve to floats.
1165 * Requires server version 5.6.0+.
1166 *
1167 * ~~~~~~~~~~{.c}
1168 * // log(a, 2) == 4.0
1169 * as_exp_build(expression,
1170 * as_exp_cmp_eq(
1171 * as_exp_log(as_exp_bin_float("a"), as_exp_float(2.0)),
1172 * as_exp_float(4.0)));
1173 * ~~~~~~~~~~
1174 *
1175 * @param __num Number.
1176 * @param __base Base value.
1177 * @return (float value)
1178 * @ingroup expression
1179 */
1180#define as_exp_log(__num, __base) \
1181 {.op=_AS_EXP_CODE_LOG, .count=3}, __num, __base
1182
1183/**
1184 * Create "modulo" (%) operator that determines the remainder of "numerator"
1185 * divided by "denominator". All arguments must resolve to integers.
1186 * Requires server version 5.6.0+.
1187 *
1188 * ~~~~~~~~~~{.c}
1189 * // a % 10 == 0
1190 * as_exp_build(expression,
1191 * as_exp_cmp_eq(
1192 * as_exp_mod(as_exp_bin_int("a"), as_exp_int(10)),
1193 * as_exp_int(0)));
1194 * ~~~~~~~~~~
1195 *
1196 * @return (integer value)
1197 * @ingroup expression
1198 */
1199#define as_exp_mod(__numerator, __denominator) \
1200 {.op=_AS_EXP_CODE_MOD, .count=3}, __numerator, __denominator
1201
1202/**
1203 * Create operator that returns absolute value of a number.
1204 * All arguments must resolve to integer or float.
1205 * Requires server version 5.6.0+.
1206 *
1207 * ~~~~~~~~~~{.c}
1208 * // abs(a) == 1
1209 * as_exp_build(expression,
1210 * as_exp_cmp_eq(
1211 * as_exp_abs(as_exp_bin_int("a")),
1212 * as_exp_int(1)));
1213 * ~~~~~~~~~~
1214 *
1215 * @return (number value)
1216 * @ingroup expression
1217 */
1218#define as_exp_abs(__value) \
1219 {.op=_AS_EXP_CODE_ABS, .count=2}, __value
1220
1221/**
1222 * Create expression that rounds a floating point number down to the closest integer value.
1223 * Requires server version 5.6.0+.
1224 *
1225 * ~~~~~~~~~~{.c}
1226 * // floor(2.95) == 2.0
1227 * as_exp_build(expression,
1228 * as_exp_cmp_eq(
1229 * as_exp_floor(as_exp_float(2.95)),
1230 * as_exp_float(2.0)));
1231 * ~~~~~~~~~~
1232 *
1233 * @param __num Floating point value to round down.
1234 * @return (float-value)
1235 * @ingroup expression
1236 */
1237#define as_exp_floor(__num) \
1238 {.op=_AS_EXP_CODE_FLOOR, .count=2}, __num
1239
1240/**
1241 * Create expression that rounds a floating point number up to the closest integer value.
1242 * Requires server version 5.6.0+.
1243 *
1244 * ~~~~~~~~~~{.c}
1245 * // ceil(2.15) == 3.0
1246 * as_exp_build(expression,
1247 * as_exp_cmp_eq(
1248 * as_exp_ceil(as_exp_float(2.15)),
1249 * as_exp_float(3.0)));
1250 * ~~~~~~~~~~
1251 *
1252 * @param __num Floating point value to round up.
1253 * @return (integer-value)
1254 * @ingroup expression
1255 */
1256#define as_exp_ceil(__num) \
1257 {.op=_AS_EXP_CODE_CEIL, .count=2}, __num
1258
1259/**
1260 * Create expression that converts a float to an integer.
1261 * Requires server version 5.6.0+.
1262 *
1263 * ~~~~~~~~~~{.c}
1264 * // int(2.5) == 2
1265 * as_exp_build(expression,
1266 * as_exp_cmp_eq(
1267 * as_exp_to_int(as_exp_float(2.5)),
1268 * as_exp_int(2)));
1269 * ~~~~~~~~~~
1270 *
1271 * @param __num Integer to convert to a float
1272 * @return (float-value)
1273 * @ingroup expression
1274 */
1275#define as_exp_to_int(__num) \
1276 {.op=_AS_EXP_CODE_TO_INT, .count=2}, __num
1277
1278/**
1279 * Create expression that converts an integer to a float.
1280 * Requires server version 5.6.0+.
1281 *
1282 * ~~~~~~~~~~{.c}
1283 * // float(2) == 2.0
1284 * as_exp_build(expression,
1285 * as_exp_cmp_eq(
1286 * as_exp_to_float(as_exp_int(2)),
1287 * as_exp_int(2.0)));
1288 * ~~~~~~~~~~
1289 *
1290 * @param __num Integer to convert to a float
1291 * @return (float-value)
1292 * @ingroup expression
1293 */
1294#define as_exp_to_float(__num) \
1295 {.op=_AS_EXP_CODE_TO_FLOAT, .count=2}, __num
1296
1297/**
1298 * Create integer "and" (&) operator that is applied to two or more integers.
1299 * All arguments must resolve to integers.
1300 * Requires server version 5.6.0+.
1301 *
1302 * ~~~~~~~~~~{.c}
1303 * // a & 0xff == 0x11
1304 * as_exp_build(expression,
1305 * as_exp_cmp_eq(
1306 * as_exp_int_and(as_exp_bin_int("a"), as_exp_int(0xff)),
1307 * as_exp_int(0x11)));
1308 * ~~~~~~~~~~
1309 *
1310 * @param ... Variable number of integer expressions.
1311 * @return (integer value)
1312 * @ingroup expression
1313 */
1314#define as_exp_int_and(...) {.op=_AS_EXP_CODE_INT_AND}, __VA_ARGS__, \
1315 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1316
1317/**
1318 * Create integer "or" (|) operator that is applied to two or more integers.
1319 * All arguments must resolve to integers.
1320 * Requires server version 5.6.0+.
1321 *
1322 * ~~~~~~~~~~{.c}
1323 * // a | 0x10 != 0
1324 * as_exp_build(expression,
1325 * as_exp_cmp_ne(
1326 * as_exp_int_or(as_exp_bin_int("a"), as_exp_int(0x10)),
1327 * as_exp_int(0)));
1328 * ~~~~~~~~~~
1329 *
1330 * @param ... Variable number of integer expressions.
1331 * @return (integer value)
1332 * @ingroup expression
1333 */
1334#define as_exp_int_or(...) {.op=_AS_EXP_CODE_INT_OR}, __VA_ARGS__, \
1335 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1336
1337/**
1338 * Create integer "xor" (^) operator that is applied to two or more integers.
1339 * All arguments must resolve to integers.
1340 * Requires server version 5.6.0+.
1341 *
1342 * ~~~~~~~~~~{.c}
1343 * // a ^ b == 16
1344 * as_exp_build(expression,
1345 * as_exp_cmp_eq(
1346 * as_exp_int_xor(as_exp_bin_int("a"), as_exp_bin_int("b")),
1347 * as_exp_int(16)));
1348 * ~~~~~~~~~~
1349 *
1350 * @param ... Variable number of integer expressions.
1351 * @return (integer value)
1352 * @ingroup expression
1353 */
1354#define as_exp_int_xor(...) {.op=_AS_EXP_CODE_INT_XOR}, __VA_ARGS__, \
1355 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1356
1357/**
1358 * Create integer "not" (~) operator.
1359 * Requires server version 5.6.0+.
1360 *
1361 * ~~~~~~~~~~{.c}
1362 * // ~a == 7
1363 * as_exp_build(expression,
1364 * as_exp_cmp_eq(
1365 * as_exp_int_not(as_exp_bin_int("a")),
1366 * as_exp_int(7)));
1367 * ~~~~~~~~~~
1368 *
1369 * @param __expr Integer expression.
1370 * @return (integer value)
1371 * @ingroup expression
1372 */
1373#define as_exp_int_not(__expr) {.op=_AS_EXP_CODE_INT_NOT, .count=2}, \
1374 __expr
1375
1376/**
1377 * Create integer "left shift" (<<) operator.
1378 * Requires server version 5.6.0+.
1379 *
1380 * ~~~~~~~~~~{.c}
1381 * // a << 8 > 0xff
1382 * as_exp_build(expression,
1383 * as_exp_cmp_gt(
1384 * as_exp_int_lshift(as_exp_bin_int("a"), as_exp_int(8)),
1385 * as_exp_int(0xff)));
1386 * ~~~~~~~~~~
1387 *
1388 * @param __value Integer expression.
1389 * @param __shift Number of bits to shift by.
1390 * @return (integer value)
1391 * @ingroup expression
1392 */
1393#define as_exp_int_lshift(__value, __shift) \
1394 {.op=_AS_EXP_CODE_INT_LSHIFT, .count=3}, __value, __shift
1395
1396/**
1397 * Create integer "logical right shift" (>>>) operator.
1398 * Requires server version 5.6.0+.
1399 *
1400 * ~~~~~~~~~~{.c}
1401 * // a >>> 8 > 0xff
1402 * as_exp_build(expression,
1403 * as_exp_cmp_gt(
1404 * as_exp_int_rshift(as_exp_bin_int("a"), as_exp_int(8)),
1405 * as_exp_int(0xff)));
1406 * ~~~~~~~~~~
1407 *
1408 * @param __value Integer expression.
1409 * @param __shift Number of bits to shift by.
1410 * @return (integer value)
1411 * @ingroup expression
1412 */
1413#define as_exp_int_rshift(__value, __shift) \
1414 {.op=_AS_EXP_CODE_INT_RSHIFT, .count=3}, __value, __shift
1415
1416/**
1417 * Create integer "arithmetic right shift" (>>) operator.
1418 * Requires server version 5.6.0+.
1419 *
1420 * ~~~~~~~~~~{.c}
1421 * // a >> 8 > 0xff
1422 * as_exp_build(expression,
1423 * as_exp_cmp_eq(
1424 * as_exp_int_arshift(as_exp_bin_int("a"), as_exp_int(8)),
1425 * as_exp_int(0xff)));
1426 * ~~~~~~~~~~
1427 *
1428 * @param __value Integer expression.
1429 * @param __shift Number of bits to shift by.
1430 * @return (integer value)
1431 * @ingroup expression
1432 */
1433#define as_exp_int_arshift(__value, __shift) \
1434 {.op=_AS_EXP_CODE_INT_ARSHIFT, .count=3}, __value, __shift
1435
1436/**
1437 * Create expression that returns count of integer bits that are set to 1.
1438 * Requires server version 5.6.0+.
1439 *
1440 * ~~~~~~~~~~{.c}
1441 * // count(a) == 4
1442 * as_exp_build(expression,
1443 * as_exp_cmp_eq(
1444 * as_exp_int_count(as_exp_bin_int("a")),
1445 * as_exp_int(4)));
1446 * ~~~~~~~~~~
1447 *
1448 * @return (integer value)
1449 * @ingroup expression
1450 */
1451#define as_exp_int_count(__expr) \
1452 {.op=_AS_EXP_CODE_INT_COUNT, .count=2}, __expr
1453
1454/**
1455 * Create expression that scans integer bits from left (most significant bit) to
1456 * right (least significant bit), looking for a search bit value. When the
1457 * search value is found, the index of that bit (where the most significant bit is
1458 * index 0) is returned. If "search" is true, the scan will search for the bit
1459 * value 1. If "search" is false it will search for bit value 0.
1460 * Requires server version 5.6.0+.
1461 *
1462 * ~~~~~~~~~~{.c}
1463 * // lscan(a, true) == 4
1464 * as_exp_build(expression,
1465 * as_exp_cmp_eq(
1466 * as_exp_int_lscan(as_exp_bin_int("a"), as_exp_bool(true)),
1467 * as_exp_int(4)));
1468 * ~~~~~~~~~~
1469 *
1470 * @return (integer value)
1471 * @ingroup expression
1472 */
1473#define as_exp_int_lscan(__value, __search) \
1474 {.op=_AS_EXP_CODE_INT_LSCAN, .count=3}, __value, __search
1475
1476/**
1477 * Create expression that scans integer bits from right (least significant bit) to
1478 * left (most significant bit), looking for a search bit value. When the
1479 * search value is found, the index of that bit (where the most significant bit is
1480 * index 0) is returned. If "search" is true, the scan will search for the bit
1481 * value 1. If "search" is false it will search for bit value 0.
1482 * Requires server version 5.6.0+.
1483 *
1484 * ~~~~~~~~~~{.c}
1485 * // rscan(a, true) == 4
1486 * as_exp_build(expression,
1487 * as_exp_cmp_eq(
1488 * as_exp_int_rscan(as_exp_bin_int("a"), as_exp_bool(true)),
1489 * as_exp_int(4)));
1490 * ~~~~~~~~~~
1491 *
1492 * @return (integer value)
1493 * @ingroup expression
1494 */
1495#define as_exp_int_rscan(__value, __search) \
1496 {.op=_AS_EXP_CODE_INT_RSCAN, .count=3}, __value, __search
1497
1498/**
1499 * Create expression that returns the minimum value in a variable number of expressions.
1500 * All arguments must be the same type (integer or float).
1501 * Requires server version 5.6.0+.
1502 *
1503 * ~~~~~~~~~~{.c}
1504 * // min(a, b, c) > 0
1505 * as_exp_build(expression,
1506 * as_exp_cmp_gt(
1507 * as_exp_min(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1508 * as_exp_int(0)));
1509 * ~~~~~~~~~~
1510 *
1511 * @param ... Variable number of integer or float expressions.
1512 * @return (integer or float value)
1513 * @ingroup expression
1514 */
1515#define as_exp_min(...) {.op=_AS_EXP_CODE_MIN}, __VA_ARGS__, \
1516 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1517
1518/**
1519 * Create expression that returns the maximum value in a variable number of expressions.
1520 * All arguments must be the same type (integer or float).
1521 * Requires server version 5.6.0+.
1522 *
1523 * ~~~~~~~~~~{.c}
1524 * // max(a, b, c) > 100
1525 * as_exp_build(expression,
1526 * as_exp_cmp_eq(
1527 * as_exp_max(as_exp_bin_int("a"), as_exp_bin_int("b"), as_exp_bin_int("c")),
1528 * as_exp_int(100)));
1529 * ~~~~~~~~~~
1530 *
1531 * @param ... Variable number of integer or float expressions.
1532 * @return (integer or float value)
1533 * @ingroup expression
1534 */
1535#define as_exp_max(...) {.op=_AS_EXP_CODE_MAX}, __VA_ARGS__, \
1536 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1537
1538/*********************************************************************************
1539 * FLOW CONTROL AND VARIABLE EXPRESSIONS
1540 *********************************************************************************/
1541
1542/**
1543 * Conditionally select an action expression from a variable number of expression pairs
1544 * followed by a default action expression. Every action expression must return the same type.
1545 * The only exception is as_exp_unknown() which can be mixed with other types.
1546 *
1547 * Requires server version 5.6.0+.
1548 *
1549 * ~~~~~~~~~~{.c}
1550 * Args Format: bool exp1, action exp1, bool exp2, action exp2, ..., action-default
1551 *
1552 * // Apply operator based on type and test if greater than 100
1553 * as_exp_build(expression,
1554 * as_exp_cmp_gt(
1555 * as_exp_cond(
1556 * as_exp_eq(as_exp_bin_int("type"), as_exp_int(0)),
1557 * as_exp_add(as_exp_bin_int("val1"), as_exp_bin_int("val2")),
1558 * as_exp_eq(as_exp_bin_int("type"), as_exp_int(1)),
1559 * as_exp_sub(as_exp_bin_int("val1"), as_exp_bin_int("val2")),
1560 * as_exp_eq(as_exp_bin_int("type"), as_exp_int(2)),
1561 * as_exp_mul(as_exp_bin_int("val1"), as_exp_bin_int("val2")),
1562 * as_exp_int(-1)),
1563 * as_exp_int(100)));
1564 * ~~~~~~~~~~
1565 *
1566 * @return first action expression where bool expression is true or action-default.
1567 * @ingroup expression
1568 */
1569#define as_exp_cond(...) {.op=_AS_EXP_CODE_COND}, __VA_ARGS__, \
1570 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1571
1572/**
1573 * Define variables and expressions in scope.
1574 * Requires server version 5.6.0+.
1575 *
1576 * ~~~~~~~~~~{.c}
1577 * // 5 < a < 10
1578 * as_exp_build(expression,
1579 * as_exp_let(as_exp_def("x", as_exp_bin_int("a")),
1580 * as_exp_and(
1581 * as_exp_lt(as_exp_int(5), as_exp_var("x")),
1582 * as_exp_lt(as_exp_var("x"), as_exp_int(10)))));
1583 * ~~~~~~~~~~
1584 *
1585 * @param ... Variable number of as_exp_def followed by a scoped
1586 * expression.
1587 * @return result of scoped expression.
1588 * @ingroup expression
1589 */
1590#define as_exp_let(...) \
1591 {.op=_AS_EXP_CODE_LET}, __VA_ARGS__, \
1592 {.op=_AS_EXP_CODE_END_OF_VA_ARGS}
1593
1594/**
1595 * Assign variable to an expression that can be accessed later.
1596 * Requires server version 5.6.0+.
1597 *
1598 * ~~~~~~~~~~{.c}
1599 * // 5 < a < 10
1600 * as_exp_build(expression,
1601 * as_exp_let(as_exp_def("x", as_exp_bin_int("a")),
1602 * as_exp_and(
1603 * as_exp_lt(as_exp_int(5), as_exp_var("x")),
1604 * as_exp_lt(as_exp_var("x"), as_exp_int(10)))));
1605 * ~~~~~~~~~~
1606 *
1607 * @param __var_name Variable name.
1608 * @param __expr The variable is set to the result of __expr.
1609 * @return A variable name expression pair.
1610 * @ingroup expression
1611 */
1612#define as_exp_def(__var_name, __expr) \
1613 _AS_EXP_VAL_RAWSTR(__var_name), __expr
1614
1615/**
1616 * Retrieve expression value from a variable.
1617 * Requires server version 5.6.0+.
1618 *
1619 * ~~~~~~~~~~{.c}
1620 * // 5 < a < 10
1621 * as_exp_build(expression,
1622 * as_exp_let(as_exp_def("x", as_exp_bin_int("a")),
1623 * as_exp_and(
1624 * as_exp_lt(as_exp_int(5), as_exp_var("x")),
1625 * as_exp_lt(as_exp_var("x"), as_exp_int(10)))));
1626 * ~~~~~~~~~~
1627 *
1628 * @param __var_name Variable name.
1629 * @return value stored in variable.
1630 * @ingroup expression
1631 */
1632#define as_exp_var(__var_name) \
1633 {.op=_AS_EXP_CODE_VAR, .count=2}, _AS_EXP_VAL_RAWSTR(__var_name)
1634
1635/*********************************************************************************
1636 * LIST MODIFY EXPRESSIONS
1637 *********************************************************************************/
1638
1639#define _AS_EXP_VAL_RTYPE(__val) {.op=_AS_EXP_CODE_VAL_RTYPE, .v.int_val=__val}
1640
1641#define _AS_EXP_LIST_MOD(__ctx, __pol, __op, __param, __extra_param) \
1642 {.op=_AS_EXP_CODE_CALL, .count=5}, \
1643 _AS_EXP_VAL_RTYPE(as_exp_get_ctx_type(__ctx, AS_EXP_TYPE_LIST)), \
1644 as_exp_int(_AS_EXP_SYS_CALL_CDT | _AS_EXP_SYS_FLAG_MODIFY_LOCAL), \
1645 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param + ((uintptr_t)(__pol) == (uintptr_t)NULL ? 0 : __extra_param), .v.ctx=__ctx}, \
1646 as_exp_int(__op)
1647
1648/**
1649 * Create expression that appends value to end of list.
1650 *
1651 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1652 * @param __pol Optional list write policy (as_list_policy).
1653 * @param __val Value expression.
1654 * @param __bin List bin or list value expression.
1655 * @return (list expression)
1656 * @ingroup expression
1657 */
1658#define as_exp_list_append(__ctx, __pol, __val, __bin) \
1659 _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_APPEND, 1, 2), \
1660 __val, \
1661 {.op=_AS_EXP_CODE_CDT_LIST_CRMOD, .v.list_pol = __pol}, \
1662 __bin
1663
1664/**
1665 * Create expression that appends list items to end of list.
1666 *
1667 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1668 * @param __pol Optional list write policy (as_list_policy).
1669 * @param __val List items expression.
1670 * @param __bin List bin or list value expression.
1671 * @return (list expression)
1672 * @ingroup expression
1673 */
1674#define as_exp_list_append_items(__ctx, __pol, __val, __bin) \
1675 _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_APPEND_ITEMS, 1, 2), \
1676 __val, \
1677 {.op=_AS_EXP_CODE_CDT_LIST_CRMOD, .v.list_pol = __pol}, \
1678 __bin
1679
1680/**
1681 * Create expression that inserts value to specified index of list.
1682 *
1683 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1684 * @param __pol Optional list write policy (as_list_policy).
1685 * @param __idx Index integer expression.
1686 * @param __val Value expression.
1687 * @param __bin List bin or list value expression.
1688 * @return (list expression)
1689 * @ingroup expression
1690 */
1691#define as_exp_list_insert(__ctx, __pol, __idx, __val, __bin) \
1692 _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_INSERT, 2, 1), \
1693 __idx, __val, \
1694 {.op=_AS_EXP_CODE_CDT_LIST_MOD, .v.list_pol = __pol}, \
1695 __bin
1696
1697/**
1698 * Create expression that inserts each input list item starting at specified index of list.
1699 *
1700 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1701 * @param __pol Optional list write policy (as_list_policy).
1702 * @param __idx Index integer expression.
1703 * @param __val List items expression.
1704 * @param __bin List bin or list value expression.
1705 * @return (list expression)
1706 * @ingroup expression
1707 */
1708#define as_exp_list_insert_items(__ctx, __pol, __idx, __val, __bin) \
1709 _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_INSERT_ITEMS, 2, 1), \
1710 __idx, __val, \
1711 {.op=_AS_EXP_CODE_CDT_LIST_MOD, .v.list_pol = __pol}, \
1712 __bin
1713
1714/**
1715 * Create expression that increments list[index] by value.
1716 *
1717 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1718 * @param __pol Optional list write policy (as_list_policy).
1719 * @param __idx Index integer expression.
1720 * @param __val Value expression.
1721 * @param __bin List bin or list value expression.
1722 * @return (list expression)
1723 * @ingroup expression
1724 */
1725#define as_exp_list_increment(__ctx, __pol, __idx, __val, __bin) \
1726 _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_INCREMENT, 2, 2), \
1727 __idx, __val, \
1728 {.op=_AS_EXP_CODE_CDT_LIST_CRMOD, .v.list_pol = __pol}, \
1729 __bin
1730
1731/**
1732 * Create expression that sets item value at specified index in list.
1733 *
1734 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1735 * @param __pol Optional list write policy (as_list_policy).
1736 * @param __idx Index integer expression.
1737 * @param __val Value expression.
1738 * @param __bin List bin or list value expression.
1739 * @return (list expression)
1740 * @ingroup expression
1741 */
1742#define as_exp_list_set(__ctx, __pol, __idx, __val, __bin) \
1743 _AS_EXP_LIST_MOD(__ctx, __pol, AS_CDT_OP_LIST_SET, 2, 1), \
1744 __idx, __val, \
1745 {.op=_AS_EXP_CODE_CDT_LIST_MOD, .v.list_pol = __pol}, \
1746 __bin
1747
1748/**
1749 * Create expression that removes all items in list.
1750 *
1751 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1752 * @param __bin List bin or list value expression.
1753 * @return (list expression)
1754 * @ingroup expression
1755 */
1756#define as_exp_list_clear(__ctx, __bin) \
1757 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_CLEAR, 0, 0), \
1758 __bin
1759
1760/**
1761 * Create expression that sorts list.
1762 *
1763 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1764 * @param __order Sort order (as_list_sort_flags).
1765 * @param __bin List bin or list value expression.
1766 * @return (list expression)
1767 * @ingroup expression
1768 */
1769#define as_exp_list_sort(__ctx, __order, __bin) \
1770 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_SORT, 1, 0), \
1771 as_exp_int(__order), \
1772 __bin
1773
1774/**
1775 * Create expression that removes list items identified by value.
1776 *
1777 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1778 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1779 * @param __val Value expression.
1780 * @param __bin List bin or list value expression.
1781 * @return (list expression)
1782 * @ingroup expression
1783 */
1784#define as_exp_list_remove_by_value(__ctx, __rtype, __val, __bin) \
1785 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_ALL_BY_VALUE, 2, 0), \
1786 as_exp_int(__rtype), \
1787 __val, \
1788 __bin
1789
1790/**
1791 * Create expression that removes list items identified by values.
1792 *
1793 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1794 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1795 * @param __values Values list expression.
1796 * @param __bin List bin or list value expression.
1797 * @return (list expression)
1798 * @ingroup expression
1799 */
1800#define as_exp_list_remove_by_value_list(__ctx, __rtype, __values, __bin) \
1801 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_LIST, 2, 0), \
1802 as_exp_int(__rtype), \
1803 __values, \
1804 __bin
1805
1806/**
1807 * Create expression that removes list items identified by value range
1808 * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
1809 * If end is infinity, the range is greater than equal to begin.
1810 *
1811 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1812 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1813 * @param __begin Begin value expression.
1814 * @param __end End value expression.
1815 * @param __bin List bin or list value expression.
1816 * @return (list expression)
1817 * @ingroup expression
1818 */
1819#define as_exp_list_remove_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
1820 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_INTERVAL, 3, 0), \
1821 as_exp_int(__rtype), \
1822 __begin, __end, \
1823 __bin
1824
1825/**
1826 * Create expression that removes list items nearest to value and greater by relative rank.
1827 *
1828 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1829 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1830 * @param __val Value expression.
1831 * @param __rank Rank integer expression.
1832 * @param __bin List bin or list value expression.
1833 * @return (list expression)
1834 * @ingroup expression
1835 */
1836#define as_exp_list_remove_by_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
1837 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_REL_RANK_RANGE, 3, 0), \
1838 as_exp_int(__rtype), \
1839 __val, __rank, \
1840 __bin
1841
1842/**
1843 * Create expression that removes list items nearest to value and greater by relative rank with a
1844 * count limit.
1845 *
1846 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1847 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1848 * @param __val Value expression.
1849 * @param __rank Rank integer expression.
1850 * @param __count Count integer expression.
1851 * @param __bin List bin or list value expression.
1852 * @return (list expression)
1853 * @ingroup expression
1854 */
1855#define as_exp_list_remove_by_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
1856 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_VALUE_REL_RANK_RANGE, 4, 0), \
1857 as_exp_int(__rtype), \
1858 __val, __rank, __count, \
1859 __bin
1860
1861/**
1862 * Create expression that removes list item identified by index.
1863 *
1864 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1865 * @param __idx Index integer expression.
1866 * @param __bin List bin or list value expression.
1867 * @return (list expression)
1868 * @ingroup expression
1869 */
1870#define as_exp_list_remove_by_index(__ctx, __idx, __bin) \
1871 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_INDEX, 2, 0), \
1872 as_exp_int(AS_LIST_RETURN_NONE), \
1873 __idx, \
1874 __bin
1875
1876/**
1877 * Create expression that removes list items starting at specified index to the end of list.
1878 *
1879 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1880 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1881 * @param __idx Index integer expression.
1882 * @param __bin List bin or list value expression.
1883 * @return (list expression)
1884 * @ingroup expression
1885 */
1886#define as_exp_list_remove_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
1887 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_INDEX_RANGE, 2, 0), \
1888 as_exp_int(__rtype), \
1889 __idx, \
1890 __bin
1891
1892/**
1893 * Create expression that removes "count" list items starting at specified index.
1894 *
1895 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1896 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1897 * @param __idx Index integer expression.
1898 * @param __count Count integer expression.
1899 * @param __bin List bin or list value expression.
1900 * @return (list expression)
1901 * @ingroup expression
1902 */
1903#define as_exp_list_remove_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
1904 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_INDEX_RANGE, 3, 0), \
1905 as_exp_int(__rtype), \
1906 __idx, __count, \
1907 __bin
1908
1909/**
1910 * Create expression that removes list item identified by rank.
1911 *
1912 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1913 * @param __rank Rank integer expression.
1914 * @param __bin List bin or list value expression.
1915 * @return (list expression)
1916 * @ingroup expression
1917 */
1918#define as_exp_list_remove_by_rank(__ctx, __rank, __bin) \
1919 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_RANK, 2, 0), \
1920 as_exp_int(AS_LIST_RETURN_NONE), \
1921 __rank, \
1922 __bin
1923
1924/**
1925 * Create expression that removes list items starting at specified rank to the last ranked item.
1926 *
1927 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1928 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1929 * @param __rank Rank integer expression.
1930 * @param __bin List bin or list value expression.
1931 * @return (list expression)
1932 * @ingroup expression
1933 */
1934#define as_exp_list_remove_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
1935 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_RANK_RANGE, 2, 0), \
1936 as_exp_int(__rtype), \
1937 __rank, \
1938 __bin
1939
1940/**
1941 * Create expression that removes "count" list items starting at specified rank.
1942 *
1943 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1944 * @param __rtype Return type. Valid values are AS_LIST_RETURN_NONE or AS_LIST_RETURN_INVERTED.
1945 * @param __rank Rank integer expression.
1946 * @param __count Count integer expression.
1947 * @param __bin List bin or list value expression.
1948 * @return (list expression)
1949 * @ingroup expression
1950 */
1951#define as_exp_list_remove_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
1952 _AS_EXP_LIST_MOD(__ctx, NULL, AS_CDT_OP_LIST_REMOVE_BY_RANK_RANGE, 3, 0), \
1953 as_exp_int(__rtype), \
1954 __rank, __count, \
1955 __bin
1956
1957/*********************************************************************************
1958 * LIST READ EXPRESSIONS
1959 *********************************************************************************/
1960
1961#define _AS_EXP_CDT_LIST_READ(__type, __rtype, __is_multi) \
1962 {.op=_AS_EXP_CODE_CALL, .count=5}, \
1963 _AS_EXP_VAL_RTYPE(as_exp_get_list_type(__type, __rtype, __is_multi)), \
1964 as_exp_int(_AS_EXP_SYS_CALL_CDT)
1965
1966#define _AS_EXP_LIST_START(__ctx, __op, __param) \
1967 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param, .v.ctx=__ctx}, \
1968 as_exp_int(__op)
1969
1970/**
1971 * Create expression that returns list size.
1972 *
1973 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1974 * @param __bin List bin or list value expression.
1975 * @return (integer expression)
1976 * @ingroup expression
1977 */
1978#define as_exp_list_size(__ctx, __bin) \
1979 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, AS_LIST_RETURN_COUNT, false), \
1980 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_SIZE, 0), \
1981 __bin
1982
1983/**
1984 * Create expression that selects list items identified by value and returns selected
1985 * data specified by rtype.
1986 *
1987 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
1988 * @param __rtype Return type (as_list_return_type).
1989 * @param __val Value expression.
1990 * @param __bin List bin or list value expression.
1991 * @return (expression)
1992 * @ingroup expression
1993 */
1994#define as_exp_list_get_by_value(__ctx, __rtype, __val, __bin) \
1995 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
1996 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_ALL_BY_VALUE, 2), \
1997 as_exp_int(__rtype), \
1998 __val, \
1999 __bin
2000
2001/**
2002 * Create expression that selects list items identified by value range and returns selected
2003 * data specified by rtype.
2004 *
2005 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2006 * @param __rtype Return type (as_list_return_type).
2007 * @param __begin Begin value expression.
2008 * @param __end End value expression.
2009 * @param __bin List bin or list value expression.
2010 * @return (expression)
2011 * @ingroup expression
2012 */
2013#define as_exp_list_get_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
2014 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2015 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_INTERVAL, 3), \
2016 as_exp_int(__rtype), \
2017 __begin, __end, \
2018 __bin
2019
2020/**
2021 * Create expression that selects list items identified by values and returns selected
2022 * data specified by rtype.
2023 *
2024 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2025 * @param __rtype Return type (as_list_return_type).
2026 * @param __val Values list expression.
2027 * @param __bin List bin or list value expression.
2028 * @return (expression)
2029 * @ingroup expression
2030 */
2031#define as_exp_list_get_by_value_list(__ctx, __rtype, __val, __bin) \
2032 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2033 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_LIST, 2), \
2034 as_exp_int(__rtype), \
2035 __val, \
2036 __bin
2037
2038/**
2039 * Create expression that selects list items nearest to value and greater by relative rank
2040 * and returns selected data specified by rtype.
2041 *
2042 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2043 * @param __rtype Return type (as_list_return_type).
2044 * @param __val Values list expression.
2045 * @param __rank Rank integer expression.
2046 * @param __bin List bin or list value expression.
2047 * @return (expression)
2048 * @ingroup expression
2049 */
2050#define as_exp_list_get_by_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
2051 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2052 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_REL_RANK_RANGE, 3), \
2053 as_exp_int(__rtype), \
2054 __val, __rank, \
2055 __bin
2056
2057/**
2058 * Create expression that selects list items nearest to value and greater by relative rank with a
2059 * count limit and returns selected data specified by rtype.
2060 *
2061 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2062 * @param __rtype Return type (as_list_return_type).
2063 * @param __val Values list expression.
2064 * @param __rank Rank integer expression.
2065 * @param __count Count integer expression.
2066 * @param __bin List bin or list value expression.
2067 * @return (expression)
2068 * @ingroup expression
2069 */
2070#define as_exp_list_get_by_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
2071 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2072 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_VALUE_REL_RANK_RANGE, 4), \
2073 as_exp_int(__rtype), \
2074 __val, __rank, __count, \
2075 __bin
2076
2077/**
2078 * Create expression that selects list item identified by index
2079 * and returns selected data specified by rtype.
2080 *
2081 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2082 * @param __rtype Return type (as_list_return_type).
2083 * @param __vtype Value type (as_exp_type).
2084 * @param __idx Index integer expression.
2085 * @param __bin List bin or list value expression.
2086 * @return (vtype expression)
2087 * @ingroup expression
2088 */
2089#define as_exp_list_get_by_index(__ctx, __rtype, __vtype, __idx, __bin) \
2090 _AS_EXP_CDT_LIST_READ(__vtype, __rtype, false), \
2091 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_INDEX, 2), \
2092 as_exp_int(__rtype), \
2093 __idx, \
2094 __bin
2095
2096/**
2097 * Create expression that selects list items starting at specified index to the end of list
2098 * and returns selected data specified by rtype.
2099 *
2100 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2101 * @param __rtype Return type (as_list_return_type).
2102 * @param __idx Index integer expression.
2103 * @param __bin List bin or list value expression.
2104 * @return (expression)
2105 * @ingroup expression
2106 */
2107#define as_exp_list_get_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
2108 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2109 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_INDEX_RANGE, 2), \
2110 as_exp_int(__rtype), \
2111 __idx, \
2112 __bin
2113
2114/**
2115 * Create expression that selects "count" list items starting at specified index
2116 * and returns selected data specified by rtype.
2117 *
2118 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2119 * @param __rtype Return type (as_list_return_type).
2120 * @param __idx Index integer expression.
2121 * @param __count Count integer expression.
2122 * @param __bin List bin or list value expression.
2123 * @return (expression)
2124 * @ingroup expression
2125 */
2126#define as_exp_list_get_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
2127 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2128 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_INDEX_RANGE, 3), \
2129 as_exp_int(__rtype), \
2130 __idx, __count, \
2131 __bin
2132
2133/**
2134 * Create expression that selects list item identified by rank
2135 * and returns selected data specified by rtype.
2136 *
2137 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2138 * @param __rtype Return type (as_list_return_type).
2139 * @param __vtype Value type (as_exp_type).
2140 * @param __rank Rank integer expression.
2141 * @param __bin List bin or list value expression.
2142 * @return (vtype expression)
2143 * @ingroup expression
2144 */
2145#define as_exp_list_get_by_rank(__ctx, __rtype, __vtype, __rank, __bin) \
2146 _AS_EXP_CDT_LIST_READ(__vtype, __rtype, false), \
2147 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_RANK, 2), \
2148 as_exp_int(__rtype), \
2149 __rank, \
2150 __bin
2151
2152/**
2153 * Create expression that selects list items starting at specified rank to the last ranked item
2154 * and returns selected data specified by rtype.
2155 *
2156 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2157 * @param __rtype Return type (as_list_return_type).
2158 * @param __rank Rank integer expression.
2159 * @param __bin List bin or list value expression.
2160 * @return (expression)
2161 * @ingroup expression
2162 */
2163#define as_exp_list_get_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
2164 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2165 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_RANK_RANGE, 2), \
2166 as_exp_int(__rtype), \
2167 __rank, \
2168 __bin
2169
2170/**
2171 * Create expression that selects "count" list items starting at specified rank
2172 * and returns selected data specified by rtype.
2173 *
2174 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2175 * @param __rtype Return type (as_list_return_type).
2176 * @param __rank Rank integer expression.
2177 * @param __count Count integer expression.
2178 * @param __bin List bin or list value expression.
2179 * @return (expression)
2180 * @ingroup expression
2181 */
2182#define as_exp_list_get_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
2183 _AS_EXP_CDT_LIST_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2184 _AS_EXP_LIST_START(__ctx, AS_CDT_OP_LIST_GET_BY_RANK_RANGE, 3), \
2185 as_exp_int(__rtype), \
2186 __rank, __count, \
2187 __bin
2188
2189/*********************************************************************************
2190 * MAP MODIFY EXPRESSIONS
2191 *********************************************************************************/
2192
2193#define _AS_EXP_MAP_MOD(__ctx, __pol, __op, __param, __extra_param) \
2194 {.op=_AS_EXP_CODE_CALL, .count=5}, \
2195 _AS_EXP_VAL_RTYPE(as_exp_get_ctx_type(__ctx, AS_EXP_TYPE_MAP)), \
2196 as_exp_int(_AS_EXP_SYS_CALL_CDT | _AS_EXP_SYS_FLAG_MODIFY_LOCAL), \
2197 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param + ((uintptr_t)(__pol) == (uintptr_t)NULL ? 0 : __extra_param), .v.ctx=__ctx}, \
2198 as_exp_int(__op)
2199
2200/**
2201 * Create expression that writes key/val item to map bin.
2202 *
2203 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2204 * @param __pol Optional map write policy (as_map_policy).
2205 * @param __key Key expression.
2206 * @param __val Value expression.
2207 * @param __bin Map bin or map value expression.
2208 * @return (map expression)
2209 * @ingroup expression
2210 */
2211#define as_exp_map_put(__ctx, __pol, __key, __val, __bin) \
2212 _AS_EXP_MAP_MOD(__ctx, __pol, AS_CDT_OP_MAP_PUT, 2, 2), \
2213 __key, __val, \
2214 {.op=_AS_EXP_CODE_CDT_MAP_CRMOD, .v.map_pol = __pol}, \
2215 __bin
2216
2217/**
2218 * Create expression that writes each map item to map bin.
2219 *
2220 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2221 * @param __pol Optional map write policy (as_map_policy).
2222 * @param __map Source map expression.
2223 * @param __bin Target map bin or map value expression.
2224 * @return (map expression)
2225 * @ingroup expression
2226 */
2227#define as_exp_map_put_items(__ctx, __pol, __map, __bin) \
2228 _AS_EXP_MAP_MOD(__ctx, __pol, AS_CDT_OP_MAP_PUT_ITEMS, 1, 2), \
2229 __map, \
2230 {.op=_AS_EXP_CODE_CDT_MAP_CRMOD, .v.map_pol = __pol}, \
2231 __bin
2232
2233/**
2234 * Create expression that increments values by incr for all items identified by key.
2235 * Valid only for numbers.
2236 *
2237 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2238 * @param __pol Optional map write policy (as_map_policy).
2239 * @param __key Key expression.
2240 * @param __val Increment value number expression.
2241 * @param __bin Map bin or map value expression.
2242 * @return (map expression)
2243 * @ingroup expression
2244 */
2245#define as_exp_map_increment(__ctx, __pol, __key, __val, __bin) \
2246 _AS_EXP_MAP_MOD(__ctx, __pol, AS_CDT_OP_MAP_INCREMENT, 2, 1), \
2247 __key, __val, \
2248 {.op=_AS_EXP_CODE_CDT_MAP_MOD, .v.map_pol = __pol}, \
2249 __bin
2250
2251/**
2252 * Create expression that removes all items in map.
2253 *
2254 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2255 * @param __bin Map bin or map value expression.
2256 * @return (map expression)
2257 * @ingroup expression
2258 */
2259#define as_exp_map_clear(__ctx, __bin) \
2260 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_CLEAR, 0, 0), \
2261 __bin
2262
2263/**
2264 * Create expression that removes map item identified by key.
2265 *
2266 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2267 * @param __key Key expression.
2268 * @param __bin Map bin or map value expression.
2269 * @return (map expression)
2270 * @ingroup expression
2271 */
2272#define as_exp_map_remove_by_key(__ctx, __key, __bin) \
2273 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY, 2, 0), \
2274 as_exp_int(AS_MAP_RETURN_NONE), \
2275 __key, \
2276 __bin
2277
2278/**
2279 * Create expression that removes map items identified by keys.
2280 *
2281 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2282 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2283 * @param __keys List expression of keys to remove.
2284 * @param __bin Map bin or map value expression.
2285 * @return (map expression)
2286 * @ingroup expression
2287 */
2288#define as_exp_map_remove_by_key_list(__ctx, __rtype, __keys, __bin) \
2289 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_LIST, 2, 0), \
2290 as_exp_int(__rtype), \
2291 __keys, \
2292 __bin
2293
2294/**
2295 * Create expression that removes map items identified by key range
2296 * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2297 * If end is infinity, the range is greater than equal to begin.
2298 *
2299 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2300 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2301 * @param __begin Begin value expression.
2302 * @param __end End value expression.
2303 * @param __bin Map bin or map value expression.
2304 * @return (map expression)
2305 * @ingroup expression
2306 */
2307#define as_exp_map_remove_by_key_range(__ctx, __rtype, __begin, __end, __bin) \
2308 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_INTERVAL, 3, 0), \
2309 as_exp_int(__rtype), \
2310 __begin, __end, \
2311 __bin
2312
2313/**
2314 * Create expression that removes map items nearest to key and greater by index.
2315 *
2316 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2317 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2318 * @param __key Key expression.
2319 * @param __idx Index integer expression.
2320 * @param __bin Map bin or map value expression.
2321 * @return (map expression)
2322 * @ingroup expression
2323 */
2324#define as_exp_map_remove_by_key_rel_index_range_to_end(__ctx, __rtype, __key, __idx, __bin) \
2325 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_REL_INDEX_RANGE, 3, 0), \
2326 as_exp_int(__rtype), \
2327 __key, __idx, \
2328 __bin
2329
2330/**
2331 * Create expression that removes map items nearest to key and greater by index with a count limit.
2332 *
2333 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2334 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2335 * @param __key Key expression.
2336 * @param __idx Index integer expression.
2337 * @param __count Count integer expression.
2338 * @param __bin Map bin or map value expression.
2339 * @return (map expression)
2340 * @ingroup expression
2341 */
2342#define as_exp_map_remove_by_key_rel_index_range(__ctx, __rtype, __key, __idx, __count, __bin) \
2343 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_KEY_REL_INDEX_RANGE, 4, 0), \
2344 as_exp_int(__rtype), \
2345 __key, __idx, __count, \
2346 __bin
2347
2348/**
2349 * Create expression that removes map items identified by value.
2350 *
2351 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2352 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2353 * @param __val Value expression.
2354 * @param __bin Map bin or map value expression.
2355 * @return (map expression)
2356 * @ingroup expression
2357 */
2358#define as_exp_map_remove_by_value(__ctx, __rtype, __val, __bin) \
2359 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_ALL_BY_VALUE, 2, 0), \
2360 as_exp_int(__rtype), \
2361 __val, \
2362 __bin
2363
2364/**
2365 * Create expression that removes map items identified by values.
2366 *
2367 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2368 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2369 * @param __values Values list expression.
2370 * @param __bin Map bin or map value expression.
2371 * @return (map expression)
2372 * @ingroup expression
2373 */
2374#define as_exp_map_remove_by_value_list(__ctx, __rtype, __values, __bin) \
2375 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_LIST, 2, 0), \
2376 as_exp_int(__rtype), \
2377 __values, \
2378 __bin
2379
2380/**
2381 * Create expression that removes map items identified by value range
2382 * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2383 * If end is infinity, the range is greater than equal to begin.
2384 *
2385 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2386 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2387 * @param __begin Begin value expression.
2388 * @param __end End value expression.
2389 * @param __bin Map bin or map value expression.
2390 * @return (map expression)
2391 * @ingroup expression
2392 */
2393#define as_exp_map_remove_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
2394 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_INTERVAL, 3, 0), \
2395 as_exp_int(__rtype), \
2396 __begin, __end, \
2397 __bin
2398
2399/**
2400 * Create expression that removes map items nearest to value and greater by relative rank.
2401 *
2402 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2403 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2404 * @param __val Value expression.
2405 * @param __rank Rank integer expression.
2406 * @param __bin Map bin or map value expression.
2407 * @return (map expression)
2408 * @ingroup expression
2409 */
2410#define as_exp_map_remove_by_value_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
2411 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_REL_RANK_RANGE, 3, 0), \
2412 as_exp_int(__rtype), \
2413 __val, __rank, \
2414 __bin
2415
2416/**
2417 * Create expression that removes map items nearest to value and greater by relative rank with a
2418 * count limit.
2419 *
2420 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2421 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2422 * @param __val Value expression.
2423 * @param __rank Rank integer expression.
2424 * @param __count Count integer expression.
2425 * @param __bin Map bin or map value expression.
2426 * @return (map expression)
2427 * @ingroup expression
2428 */
2429#define as_exp_map_remove_by_value_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
2430 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_VALUE_REL_RANK_RANGE, 4, 0), \
2431 as_exp_int(__rtype), \
2432 __val, __rank, __count, \
2433 __bin
2434
2435/**
2436 * Create expression that removes map item identified by index.
2437 *
2438 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2439 * @param __idx Index integer expression.
2440 * @param __bin Map bin or map value expression.
2441 * @return (map expression)
2442 * @ingroup expression
2443 */
2444#define as_exp_map_remove_by_index(__ctx, __idx, __bin) \
2445 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_INDEX, 2, 0), \
2446 as_exp_int(AS_MAP_RETURN_NONE), \
2447 __idx, \
2448 __bin
2449
2450/**
2451 * Create expression that removes map items starting at specified index to the end of map.
2452 *
2453 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2454 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2455 * @param __idx Index integer expression.
2456 * @param __bin Map bin or map value expression.
2457 * @return (map expression)
2458 * @ingroup expression
2459 */
2460#define as_exp_map_remove_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
2461 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_INDEX_RANGE, 2, 0), \
2462 as_exp_int(__rtype), \
2463 __idx, \
2464 __bin
2465
2466/**
2467 * Create expression that removes "count" map items starting at specified index.
2468 *
2469 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2470 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2471 * @param __idx Index integer expression.
2472 * @param __count Count integer expression.
2473 * @param __bin Map bin or map value expression.
2474 * @return (map expression)
2475 * @ingroup expression
2476 */
2477#define as_exp_map_remove_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
2478 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_INDEX_RANGE, 3, 0), \
2479 as_exp_int(__rtype), \
2480 __idx, __count, \
2481 __bin
2482
2483/**
2484 * Create expression that removes map item identified by rank.
2485 *
2486 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2487 * @param __rank Rank integer expression.
2488 * @param __bin Map bin or map value expression.
2489 * @return (map expression)
2490 * @ingroup expression
2491 */
2492#define as_exp_map_remove_by_rank(__ctx, __rank, __bin) \
2493 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_RANK, 2, 0), \
2494 as_exp_int(AS_MAP_RETURN_NONE), \
2495 __rank, \
2496 __bin
2497
2498/**
2499 * Create expression that removes map items starting at specified rank to the last ranked item.
2500 *
2501 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2502 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2503 * @param __rank Rank integer expression.
2504 * @param __bin Map bin or map value expression.
2505 * @return (map expression)
2506 * @ingroup expression
2507 */
2508#define as_exp_map_remove_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
2509 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_RANK_RANGE, 2, 0), \
2510 as_exp_int(__rtype), \
2511 __rank, \
2512 __bin
2513
2514/**
2515 * Create expression that removes "count" map items starting at specified rank.
2516 *
2517 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2518 * @param __rtype Return type. Valid values are AS_MAP_RETURN_NONE or AS_MAP_RETURN_INVERTED.
2519 * @param __rank Rank integer expression.
2520 * @param __count Count integer expression.
2521 * @param __bin Map bin or map value expression.
2522 * @return (map expression)
2523 * @ingroup expression
2524 */
2525#define as_exp_map_remove_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
2526 _AS_EXP_MAP_MOD(__ctx, NULL, AS_CDT_OP_MAP_REMOVE_BY_RANK_RANGE, 3, 0), \
2527 as_exp_int(__rtype), \
2528 __rank, __count, \
2529 __bin
2530
2531/*********************************************************************************
2532 * MAP READ EXPRESSIONS
2533 *********************************************************************************/
2534
2535#define _AS_EXP_MAP_READ(__type__, __rtype, __is_multi) \
2536 {.op=_AS_EXP_CODE_CALL, .count=5}, \
2537 _AS_EXP_VAL_RTYPE(as_exp_get_map_type(__type__, __rtype, __is_multi)), \
2538 as_exp_int(_AS_EXP_SYS_CALL_CDT)
2539
2540#define _AS_EXP_MAP_START(__ctx, __op, __param) \
2541 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + __param, .v.ctx=__ctx}, \
2542 as_exp_int(__op)
2543
2544/**
2545 * Create expression that returns map size.
2546 *
2547 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2548 * @param __bin Map bin or map value expression.
2549 * @return (integer expression)
2550 * @ingroup expression
2551 */
2552#define as_exp_map_size(__ctx, __bin) \
2553 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, AS_MAP_RETURN_COUNT, false), \
2554 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_SIZE, 0), \
2555 __bin
2556
2557/**
2558 * Create expression that selects map item identified by key
2559 * and returns selected data specified by rtype.
2560 *
2561 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2562 * @param __rtype Return type (as_map_return_type).
2563 * @param __vtype Value type (as_exp_type).
2564 * @param __key Key expression.
2565 * @param __bin Map bin or map value expression.
2566 * @return (expression)
2567 * @ingroup expression
2568 */
2569#define as_exp_map_get_by_key(__ctx, __rtype, __vtype, __key, __bin) \
2570 _AS_EXP_MAP_READ(__vtype, __rtype, false), \
2571 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY, 2), \
2572 as_exp_int(__rtype), \
2573 __key, \
2574 __bin
2575
2576/**
2577 * Create expression that selects map items identified by key range
2578 * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2579 * If end is infinity, the range is greater than equal to begin.
2580 * Expression returns selected data specified by rtype.
2581 *
2582 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2583 * @param __rtype Return type (as_map_return_type).
2584 * @param __begin Begin key expression.
2585 * @param __end End key expression.
2586 * @param __bin Map bin or map value expression.
2587 * @return (expression)
2588 * @ingroup expression
2589 */
2590#define as_exp_map_get_by_key_range(__ctx, __rtype, __begin, __end, __bin) \
2591 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2592 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_INTERVAL, 3), \
2593 as_exp_int(__rtype), \
2594 __begin, __end, \
2595 __bin
2596
2597/**
2598 * Create expression that selects map items identified by keys
2599 * and returns selected data specified by rtype.
2600 *
2601 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2602 * @param __rtype Return type (as_map_return_type).
2603 * @param __keys Keys list expression.
2604 * @param __bin Map bin or map value expression.
2605 * @return (expression)
2606 * @ingroup expression
2607 */
2608#define as_exp_map_get_by_key_list(__ctx, __rtype, __keys, __bin) \
2609 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2610 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_LIST, 2), \
2611 as_exp_int(__rtype), \
2612 __keys, \
2613 __bin
2614
2615/**
2616 * Create expression that selects map items nearest to key and greater by index
2617 * and returns selected data specified by rtype.
2618 *
2619 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2620 * @param __rtype Return type (as_map_return_type).
2621 * @param __key Key expression.
2622 * @param __idx Index integer expression.
2623 * @param __bin Map bin or map value expression.
2624 * @return (expression)
2625 * @ingroup expression
2626 */
2627#define as_exp_map_get_by_key_rel_index_range_to_end(__ctx, __rtype, __key, __idx, __bin) \
2628 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2629 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_REL_INDEX_RANGE, 3), \
2630 as_exp_int(__rtype), \
2631 __key, __idx, \
2632 __bin
2633
2634/**
2635 * Create expression that selects map items nearest to key and greater by index with a count limit.
2636 * Expression returns selected data specified by rtype.
2637 *
2638 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2639 * @param __rtype Return type (as_map_return_type).
2640 * @param __key Key expression.
2641 * @param __idx Index integer expression.
2642 * @param __count Count integer expression.
2643 * @param __bin Map bin or map value expression.
2644 * @return (expression)
2645 * @ingroup expression
2646 */
2647#define as_exp_map_get_by_key_rel_index_range(__ctx, __rtype, __key, __idx, __count, __bin) \
2648 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2649 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_KEY_REL_INDEX_RANGE, 4), \
2650 as_exp_int(__rtype), \
2651 __key, __idx, __count, \
2652 __bin
2653
2654/**
2655 * Create expression that selects map items identified by value
2656 * and returns selected data specified by rtype.
2657 *
2658 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2659 * @param __rtype Return type (as_map_return_type).
2660 * @param __val Value expression.
2661 * @param __bin Map bin or map value expression.
2662 * @return (expression)
2663 * @ingroup expression
2664 */
2665#define as_exp_map_get_by_value(__ctx, __rtype, __val, __bin) \
2666 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2667 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_ALL_BY_VALUE, 2), \
2668 as_exp_int(__rtype), \
2669 __val, \
2670 __bin
2671
2672/**
2673 * Create expression that selects map items identified by value range
2674 * (begin inclusive, end exclusive). If begin is nil, the range is less than end.
2675 * If end is infinity, the range is greater than equal to begin.
2676 * Expression returns selected data specified by rtype.
2677 *
2678 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2679 * @param __rtype Return type (as_map_return_type).
2680 * @param __begin Begin value expression.
2681 * @param __end End value expression.
2682 * @param __bin Map bin or map value expression.
2683 * @return (expression)
2684 * @ingroup expression
2685 */
2686#define as_exp_map_get_by_value_range(__ctx, __rtype, __begin, __end, __bin) \
2687 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2688 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_INTERVAL, 3), \
2689 as_exp_int(__rtype), \
2690 __begin, __end, \
2691 __bin
2692
2693/**
2694 * Create expression that selects map items identified by values
2695 * and returns selected data specified by rtype.
2696 *
2697 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2698 * @param __rtype Return type (as_map_return_type).
2699 * @param __values Values list expression.
2700 * @param __bin Map bin or map value expression.
2701 * @return (expression)
2702 * @ingroup expression
2703 */
2704#define as_exp_map_get_by_value_list(__ctx, __rtype, __values, __bin) \
2705 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2706 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_LIST, 2), \
2707 as_exp_int(__rtype), \
2708 __values, \
2709 __bin
2710
2711/**
2712 * Create expression that selects map items nearest to value and greater by relative rank.
2713 * Expression returns selected data specified by rtype.
2714 *
2715 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2716 * @param __rtype Return type (as_map_return_type).
2717 * @param __val Value expression.
2718 * @param __rank Rank integer expression.
2719 * @param __bin Map bin or map value expression.
2720 * @return (expression)
2721 * @ingroup expression
2722 */
2723#define as_exp_map_get_by_value_rel_rank_range_to_end(__ctx, __rtype, __val, __rank, __bin) \
2724 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2725 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_REL_RANK_RANGE, 3), \
2726 as_exp_int(__rtype), \
2727 __val, __rank, \
2728 __bin
2729
2730/**
2731 * Create expression that selects map items nearest to value and greater by relative rank with a
2732 * count limit. Expression returns selected data specified by rtype.
2733 *
2734 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2735 * @param __rtype Return type (as_map_return_type).
2736 * @param __val Value expression.
2737 * @param __rank Rank integer expression.
2738 * @param __count Count integer expression.
2739 * @param __bin Map bin or map value expression.
2740 * @return (expression)
2741 * @ingroup expression
2742 */
2743#define as_exp_map_get_by_value_rel_rank_range(__ctx, __rtype, __val, __rank, __count, __bin) \
2744 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2745 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_VALUE_REL_RANK_RANGE, 4), \
2746 as_exp_int(__rtype), \
2747 __val, __rank, __count, \
2748 __bin
2749
2750/**
2751 * Create expression that selects map item identified by index
2752 * and returns selected data specified by rtype.
2753 *
2754 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2755 * @param __rtype Return type (as_map_return_type).
2756 * @param __vtype Value type (as_exp_type).
2757 * @param __idx Index integer expression.
2758 * @param __bin Map bin or map value expression.
2759 * @return (expression)
2760 * @ingroup expression
2761 */
2762#define as_exp_map_get_by_index(__ctx, __rtype, __vtype, __idx, __bin) \
2763 _AS_EXP_MAP_READ(__vtype, __rtype, false), \
2764 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_INDEX, 2), \
2765 as_exp_int(__rtype), \
2766 __idx, \
2767 __bin
2768
2769/**
2770 * Create expression that selects map items starting at specified index to the end of map
2771 * and returns selected data specified by rtype.
2772 *
2773 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2774 * @param __rtype Return type (as_map_return_type).
2775 * @param __idx Index integer expression.
2776 * @param __bin Map bin or map value expression.
2777 * @return (expression)
2778 * @ingroup expression
2779 */
2780#define as_exp_map_get_by_index_range_to_end(__ctx, __rtype, __idx, __bin) \
2781 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2782 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_INDEX_RANGE, 2), \
2783 as_exp_int(__rtype), \
2784 __idx, \
2785 __bin
2786
2787/**
2788 * Create expression that selects "count" map items starting at specified index
2789 * and returns selected data specified by rtype.
2790 *
2791 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2792 * @param __rtype Return type (as_map_return_type).
2793 * @param __idx Index integer expression.
2794 * @param __count Count integer expression.
2795 * @param __bin Map bin or map value expression.
2796 * @return (expression)
2797 * @ingroup expression
2798 */
2799#define as_exp_map_get_by_index_range(__ctx, __rtype, __idx, __count, __bin) \
2800 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2801 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_INDEX_RANGE, 3), \
2802 as_exp_int(__rtype), \
2803 __idx, __count, \
2804 __bin
2805
2806/**
2807 * Create expression that selects map item identified by rank
2808 * and returns selected data specified by rtype.
2809 *
2810 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2811 * @param __rtype Return type (as_map_return_type).
2812 * @param __vtype Value type (as_exp_type).
2813 * @param __rank Rank integer expression.
2814 * @param __bin Map bin or map value expression.
2815 * @return (expression)
2816 * @ingroup expression
2817 */
2818#define as_exp_map_get_by_rank(__ctx, __rtype, __vtype, __rank, __bin) \
2819 _AS_EXP_MAP_READ(__vtype, __rtype, false), \
2820 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_RANK, 2), \
2821 as_exp_int(__rtype), \
2822 __rank, \
2823 __bin
2824
2825/**
2826 * Create expression that selects map items starting at specified rank to the last ranked item
2827 * and returns selected data specified by rtype.
2828 *
2829 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2830 * @param __rtype Return type (as_map_return_type).
2831 * @param __rank Rank integer expression.
2832 * @param __bin Map bin or map value expression.
2833 * @return (expression)
2834 * @ingroup expression
2835 */
2836#define as_exp_map_get_by_rank_range_to_end(__ctx, __rtype, __rank, __bin) \
2837 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2838 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_RANK_RANGE, 2), \
2839 as_exp_int(__rtype), \
2840 __rank, \
2841 __bin
2842
2843/**
2844 * Create expression that selects "count" map items starting at specified rank
2845 * and returns selected data specified by rtype.
2846 *
2847 * @param __ctx Optional context path for nested CDT (as_cdt_ctx).
2848 * @param __rtype Return type (as_map_return_type).
2849 * @param __rank Rank integer expression.
2850 * @param __count Count integer expression.
2851 * @param __bin Map bin or map value expression.
2852 * @return (expression)
2853 * @ingroup expression
2854 */
2855#define as_exp_map_get_by_rank_range(__ctx, __rtype, __rank, __count, __bin) \
2856 _AS_EXP_MAP_READ(AS_EXP_TYPE_AUTO, __rtype, true), \
2857 _AS_EXP_MAP_START(__ctx, AS_CDT_OP_MAP_GET_BY_RANK_RANGE, 3), \
2858 as_exp_int(__rtype), \
2859 __rank, __count, \
2860 __bin
2861
2862/*********************************************************************************
2863 * BIT MODIFY EXPRESSIONS
2864 *********************************************************************************/
2865
2866#define _AS_EXP_BIT_MOD() \
2867 {.op=_AS_EXP_CODE_CALL, .count=5}, \
2868 _AS_EXP_VAL_RTYPE(AS_EXP_TYPE_BLOB), \
2869 as_exp_int(_AS_EXP_SYS_CALL_BITS | _AS_EXP_SYS_FLAG_MODIFY_LOCAL)
2870
2871#define _AS_EXP_BIT_MOD_START(__op, __n_params) \
2872 _AS_EXP_BIT_MOD(), \
2873 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
2874 as_exp_int(__op)
2875
2876/**
2877 * Create an expression that performs an as_operations_bit_resize operation.
2878 *
2879 * @param __policy An as_bit_policy value.
2880 * @param __byte_size Number of bytes the resulting blob should occupy.
2881 * @param __flags as_bit_resize_flags value.
2882 * @param __bin A blob bin expression to apply this function to.
2883 * @return (blob bin) __byte_size bytes.
2884 * @ingroup expression
2885 */
2886#define as_exp_bit_resize(__policy, __byte_size, __flags, __bin) \
2887 _AS_EXP_BIT_MOD_START(AS_BIT_OP_RESIZE, 3), \
2888 __byte_size, \
2889 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2890 as_exp_uint(__flags), \
2891 __bin
2892
2893/**
2894 * Create an expression that performs an as_operations_bit_insert operation.
2895 *
2896 * @param __policy An as_bit_policy value.
2897 * @param __byte_offset Byte index of where to insert the value.
2898 * @param __value Blob expression containing the bytes to insert.
2899 * @param __bin A blob bin expression to apply this function to.
2900 * @return (blob bin) resulting blob containing the inserted bytes.
2901 * @ingroup expression
2902 */
2903#define as_exp_bit_insert(__policy, __byte_offset, __value, __bin) \
2904 _AS_EXP_BIT_MOD_START(AS_BIT_OP_INSERT, 3), \
2905 __byte_offset, \
2906 __value, \
2907 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2908 __bin
2909
2910/**
2911 * Create an expression that performs an as_operations_bit_remove operation.
2912 *
2913 * @param __policy An as_bit_policy value.
2914 * @param __byte_offset Byte index of where to remove from.
2915 * @param __byte_size Number of bytes to remove.
2916 * @param __bin A blob bin expression to apply this function to.
2917 * @return (blob bin) resulting blob with the bytes removed.
2918 * @ingroup expression
2919 */
2920#define as_exp_bit_remove(__policy, __byte_offset, __byte_size, __bin) \
2921 _AS_EXP_BIT_MOD_START(AS_BIT_OP_REMOVE, 3), \
2922 __byte_offset, \
2923 __byte_size, \
2924 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2925 __bin
2926
2927/**
2928 * Create an expression that performs an as_operations_bit_set operation.
2929 *
2930 * @param __policy An as_bit_policy value.
2931 * @param __bit_offset Bit index of where to start writing.
2932 * @param __bit_size Number of bytes to overwrite.
2933 * @param __value Blob expression containing bytes to write.
2934 * @param __bin A blob bin expression to apply this function to.
2935 * @return (blob bin) resulting blob with the bytes overwritten.
2936 * @ingroup expression
2937 */
2938#define as_exp_bit_set(__policy, __bit_offset, __bit_size, __value, __bin) \
2939 _AS_EXP_BIT_MOD_START(AS_BIT_OP_SET, 4), \
2940 __bit_offset, \
2941 __bit_size, \
2942 __value, \
2943 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2944 __bin
2945
2946/**
2947 * Create an expression that performs an as_operations_bit_or operation.
2948 *
2949 * @param __policy An as_bit_policy value.
2950 * @param __bit_offset Bit index of where to start operation.
2951 * @param __bit_size Number of bytes to be operated on.
2952 * @param __value Blob expression containing bytes to write.
2953 * @param __bin A blob bin expression to apply this function to.
2954 * @return (blob bin) resulting blob with the bytes operated on.
2955 * @ingroup expression
2956 */
2957#define as_exp_bit_or(__policy, __bit_offset, __bit_size, __value, __bin) \
2958 _AS_EXP_BIT_MOD_START(AS_BIT_OP_OR, 4), \
2959 __bit_offset, \
2960 __bit_size, \
2961 __value, \
2962 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2963 __bin
2964
2965/**
2966 * Create an expression that performs an as_operations_bit_xor operation.
2967 *
2968 * @param __policy An as_bit_policy value.
2969 * @param __bit_offset Bit index of where to start operation.
2970 * @param __bit_size Number of bits to be operated on.
2971 * @param __value Blob expression containing bytes to write.
2972 * @param __bin A blob bin expression to apply this function to.
2973 * @return (blob bin) resulting blob with the bytes operated on.
2974 * @ingroup expression
2975 */
2976#define as_exp_bit_xor(__policy, __bit_offset, __bit_size, __value, __bin) \
2977 _AS_EXP_BIT_MOD_START(AS_BIT_OP_XOR, 4), \
2978 __bit_offset, \
2979 __bit_size, \
2980 __value, \
2981 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
2982 __bin
2983
2984/**
2985 * Create an expression that performs an as_operations_bit_and operation.
2986 *
2987 * @param __policy An as_bit_policy value.
2988 * @param __bit_offset Bit index of where to start operation.
2989 * @param __bit_size Number of bits to be operated on.
2990 * @param __value Blob expression containing bytes to write.
2991 * @param __bin A blob bin expression to apply this function to.
2992 * @return (blob bin) resulting blob with the bytes operated on.
2993 * @ingroup expression
2994 */
2995#define as_exp_bit_and(__policy, __bit_offset, __bit_size, __value, __bin) \
2996 _AS_EXP_BIT_MOD_START(AS_BIT_OP_AND, 4), \
2997 __bit_offset, \
2998 __bit_size, \
2999 __value, \
3000 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3001 __bin
3002
3003/**
3004 * Create an expression that performs an as_operations_bit_not operation.
3005 *
3006 * @param __policy An as_bit_policy value.
3007 * @param __bit_offset Bit index of where to start operation.
3008 * @param __bit_size Number of bits to be operated on.
3009 * @param __bin A blob bin expression to apply this function to.
3010 * @return (blob bin) resulting blob with the bytes operated on.
3011 * @ingroup expression
3012 */
3013#define as_exp_bit_not(__policy, __bit_offset, __bit_size, __bin) \
3014 _AS_EXP_BIT_MOD_START(AS_BIT_OP_NOT, 3), \
3015 __bit_offset, \
3016 __bit_size, \
3017 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3018 __bin
3019
3020/**
3021 * Create an expression that performs an as_operations_bit_lshift operation.
3022 *
3023 * @param __policy An as_bit_policy value.
3024 * @param __bit_offset Bit index of where to start operation.
3025 * @param __bit_size Number of bits to be operated on.
3026 * @param __shift Number of bits to shift by.
3027 * @param __bin A blob bin expression to apply this function to.
3028 * @return (blob bin) resulting blob with the bytes operated on.
3029 * @ingroup expression
3030 */
3031#define as_exp_bit_lshift(__policy, __bit_offset, __bit_size, __shift, __bin) \
3032 _AS_EXP_BIT_MOD_START(AS_BIT_OP_LSHIFT, 4), \
3033 __bit_offset, \
3034 __bit_size, \
3035 __shift, \
3036 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3037 __bin
3038
3039/**
3040 * Create an expression that performs an as_operations_bit_rshift operation.
3041 *
3042 * @param __policy An as_bit_policy value.
3043 * @param __bit_offset Bit index of where to start operation.
3044 * @param __bit_size Number of bits to be operated on.
3045 * @param __shift Number of bits to shift by.
3046 * @param __bin A blob bin expression to apply this function to.
3047 * @return (blob bin) resulting blob with the bytes operated on.
3048 * @ingroup expression
3049 */
3050#define as_exp_bit_rshift(__policy, __bit_offset, __bit_size, __shift, __bin) \
3051 _AS_EXP_BIT_MOD_START(AS_BIT_OP_RSHIFT, 4), \
3052 __bit_offset, \
3053 __bit_size, \
3054 __shift, \
3055 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3056 __bin
3057
3058/**
3059 * Create an expression that performs an as_operations_bit_add operation.
3060 * Note: integers are stored big-endian.
3061 *
3062 * @param __policy An as_bit_policy value.
3063 * @param __bit_offset Bit index of where to start operation.
3064 * @param __bit_size Number of bits to be operated on.
3065 * @param __value Integer expression for value to add.
3066 * @param __action as_bit_overflow_action value.
3067 * @param __bin A blob bin expression to apply this function to.
3068 * @return (blob bin) resulting blob with the bytes operated on.
3069 * @ingroup expression
3070 */
3071#define as_exp_bit_add(__policy, __bit_offset, __bit_size, __value, __action, __bin) \
3072 _AS_EXP_BIT_MOD_START(AS_BIT_OP_ADD, 5), \
3073 __bit_offset, \
3074 __bit_size, \
3075 __value, \
3076 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3077 as_exp_uint(__action), \
3078 __bin
3079
3080/**
3081 * Create an expression that performs an as_operations_bit_add operation.
3082 * Note: integers are stored big-endian.
3083 *
3084 * @param __policy An as_bit_policy value.
3085 * @param __bit_offset Bit index of where to start operation.
3086 * @param __bit_size Number of bits to be operated on.
3087 * @param __value Integer expression for value to add.
3088 * @param __signed Boolean indicating if bits should be treated as a signed number.
3089 * @param __action as_bit_overflow_action value.
3090 * @param __bin A blob bin expression to apply this function to.
3091 * @return (blob bin) resulting blob with the bytes operated on.
3092 * @ingroup expression
3093 */
3094#define as_exp_bit_add_signed(__policy, __bit_offset, __bit_size, __value, __signed, __action, __bin) \
3095 _AS_EXP_BIT_MOD_START(AS_BIT_OP_ADD, 5), \
3096 __bit_offset, \
3097 __bit_size, \
3098 __value, \
3099 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3100 as_exp_uint(__signed ? __action | 0x01 : __action), \
3101 __bin
3102
3103/**
3104 * Create an expression that performs an as_operations_bit_subtract operation.
3105 * Note: integers are stored big-endian.
3106 *
3107 * @param __policy An as_bit_policy value.
3108 * @param __bit_offset Bit index of where to start operation.
3109 * @param __bit_size Number of bits to be operated on.
3110 * @param __value Integer expression for value to subtract.
3111 * @param __action as_bit_overflow_action value.
3112 * @param __bin A blob bin expression to apply this function to.
3113 * @return (blob bin) resulting blob with the bytes operated on.
3114 * @ingroup expression
3115 */
3116#define as_exp_bit_subtract(__policy, __bit_offset, __bit_size, __value, __action, __bin) \
3117 _AS_EXP_BIT_MOD_START(AS_BIT_OP_SUBTRACT, 5), \
3118 __bit_offset, \
3119 __bit_size, \
3120 __value, \
3121 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3122 as_exp_uint(__action), \
3123 __bin
3124
3125/**
3126 * Create an expression that performs an as_operations_bit_subtract operation.
3127 * Note: integers are stored big-endian.
3128 *
3129 * @param __policy An as_bit_policy value.
3130 * @param __bit_offset Bit index of where to start operation.
3131 * @param __bit_size Number of bits to be operated on.
3132 * @param __value Integer expression for value to subtract.
3133 * @param __signed Boolean indicating if bits should be treated as a signed number.
3134 * @param __action as_bit_overflow_action value.
3135 * @param __bin A blob bin expression to apply this function to.
3136 * @return (blob bin) resulting blob with the bytes operated on.
3137 * @ingroup expression
3138 */
3139#define as_exp_bit_subtract_signed(__policy, __bit_offset, __bit_size, __value, __signed, __action, __bin) \
3140 _AS_EXP_BIT_MOD_START(AS_BIT_OP_SUBTRACT, 5), \
3141 __bit_offset, \
3142 __bit_size, \
3143 __value, \
3144 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3145 as_exp_uint(__signed ? __action | 0x01 : __action), \
3146 __bin
3147
3148/**
3149 * Create an expression that performs an as_operations_bit_set_int operation.
3150 * Note: integers are stored big-endian.
3151 *
3152 * @param __policy An as_bit_policy value.
3153 * @param __bit_offset Bit index of where to start operation.
3154 * @param __bit_size Number of bits to be operated on.
3155 * @param __value Integer expression for value to set.
3156 * @param __bin A blob bin expression to apply this function to.
3157 * @return (blob bin) resulting blob with the bytes operated on.
3158 * @ingroup expression
3159 */
3160#define as_exp_bit_set_int(__policy, __bit_offset, __bit_size, __value, __bin) \
3161 _AS_EXP_BIT_MOD_START(AS_BIT_OP_SET_INT, 4), \
3162 __bit_offset, \
3163 __bit_size, \
3164 __value, \
3165 as_exp_uint(__policy ? ((as_bit_policy*)(__policy))->flags : 0), \
3166 __bin
3167
3168/*********************************************************************************
3169 * BIT READ EXPRESSIONS
3170 *********************************************************************************/
3171
3172#define _AS_EXP_BIT_READ(__rtype) \
3173 {.op=_AS_EXP_CODE_CALL, .count=5}, \
3174 _AS_EXP_VAL_RTYPE(__rtype), \
3175 as_exp_int(_AS_EXP_SYS_CALL_BITS)
3176
3177#define _AS_EXP_BIT_READ_START(__rtype, __op, __n_params) \
3178 _AS_EXP_BIT_READ(__rtype), \
3179 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
3180 as_exp_int(__op)
3181
3182/**
3183 * Create an expression that performs an as_operations_bit_get operation.
3184 *
3185 * @param __bit_offset The bit index of where to start reading from.
3186 * @param __bit_size Number of bits to read from the blob bin.
3187 * @param __bin A blob bin expression to apply this function to.
3188 * @return (blob bin) bit_size bits rounded up to the nearest byte size.
3189 * @ingroup expression
3190 */
3191#define as_exp_bit_get(__bit_offset, __bit_size, __bin) \
3192 _AS_EXP_BIT_READ_START(AS_EXP_TYPE_BLOB, AS_BIT_OP_GET, 2), \
3193 __bit_offset, \
3194 __bit_size, \
3195 __bin
3196
3197/**
3198 * Create an expression that performs an as_operations_bit_count operation.
3199 *
3200 * @param __bit_offset The bit index of where to start reading from.
3201 * @param __bit_size Number of bits to read from the blob bin.
3202 * @param __bin A blob bin expression to apply this function to.
3203 * @return (integer value) number of bits set to 1 in the bit_size region.
3204 * @ingroup expression
3205 */
3206#define as_exp_bit_count(__bit_offset, __bit_size, __bin) \
3207 _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_COUNT, 2), \
3208 __bit_offset, \
3209 __bit_size, \
3210 __bin
3211
3212/**
3213 * Create an expression that performs an as_operations_bit_lscan operation.
3214 *
3215 * @param __bit_offset The bit index of where to start reading from.
3216 * @param __bit_size Number of bits to read from the blob bin.
3217 * @param __value Boolean expression, true searches for 1, false for 0.
3218 * @param __bin A blob bin expression to apply this function to.
3219 * @return (integer value) Index of the left most bit starting from __offset set to __value.
3220 * @ingroup expression
3221 */
3222#define as_exp_bit_lscan(__bit_offset, __bit_size, __value, __bin) \
3223 _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_LSCAN, 3), \
3224 __bit_offset, \
3225 __bit_size, \
3226 __value, \
3227 __bin
3228
3229/**
3230 * Create an expression that performs an as_operations_bit_rscan operation.
3231 *
3232 * @param __bit_offset The bit index of where to start reading from.
3233 * @param __bit_size Number of bits to read from the blob bin.
3234 * @param __value Boolean expression, true searches for 1, false for 0.
3235 * @param __bin A blob bin expression to apply this function to.
3236 * @return (integer value) Index of the right most bit starting from __offset set to __value.
3237 * @ingroup expression
3238 */
3239#define as_exp_bit_rscan(__bit_offset, __bit_size, __value, __bin) \
3240 _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_RSCAN, 3), \
3241 __bit_offset, \
3242 __bit_size, \
3243 __value, \
3244 __bin
3245
3246/**
3247 * Create an expression that performs an as_operations_bit_get_int operation.
3248 *
3249 * @param __bit_offset The bit index of where to start reading from.
3250 * @param __bit_size Number of bits to read from the blob bin.
3251 * @param __sign Boolean value, true for signed, false for unsigned.
3252 * @param __bin A blob bin expression to apply this function to.
3253 * @return (integer value) Index of the left most bit starting from __offset set to __value.
3254 * @ingroup expression
3255 */
3256#define as_exp_bit_get_int(__bit_offset, __bit_size, __sign, __bin) \
3257 _AS_EXP_BIT_READ_START(AS_EXP_TYPE_INT, AS_BIT_OP_GET_INT, 3), \
3258 __bit_offset, \
3259 __bit_size, \
3260 as_exp_int(__sign ? 1 : 0), \
3261 __bin
3262
3263/*********************************************************************************
3264 * HLL MODIFY EXPRESSIONS
3265 *********************************************************************************/
3266
3267#define _AS_EXP_HLL_MOD() \
3268 {.op=_AS_EXP_CODE_CALL, .count=5}, \
3269 _AS_EXP_VAL_RTYPE(AS_EXP_TYPE_HLL), \
3270 as_exp_int(_AS_EXP_SYS_CALL_HLL | _AS_EXP_SYS_FLAG_MODIFY_LOCAL)
3271
3272#define _AS_EXP_HLL_MOD_START(__op, __n_params) \
3273 _AS_EXP_HLL_MOD(), \
3274 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
3275 as_exp_int(__op)
3276
3277/**
3278 * Create expression that creates a new HLL or resets an existing HLL with minhash bits.
3279 *
3280 * @param __policy An as_hll_policy value.
3281 * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3282 * @param __mh_bit_count Number of min hash bits. Must be between 4 and 51 inclusive.
3283 * Also, __index_bit_count + __mh_bit_count must be <= 64.
3284 * @param __bin A bin expression to apply this function to.
3285 * @return (hll bin) Returns the resulting hll bin.
3286 * @ingroup expression
3287 */
3288#define as_exp_hll_init_mh(__policy, __index_bit_count, __mh_bit_count, __bin) \
3289 _AS_EXP_HLL_MOD_START(AS_HLL_OP_INIT, 3), \
3290 as_exp_int(__index_bit_count), \
3291 as_exp_int(__mh_bit_count), \
3292 as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3293 __bin
3294
3295/**
3296 * Create expression that creates a new HLL or resets an existing HLL.
3297 *
3298 * @param __policy An as_hll_policy value.
3299 * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3300 * @param __bin A bin expression to apply this function to.
3301 * @return (hll bin) Returns the resulting hll bin.
3302 * @ingroup expression
3303 */
3304#define as_exp_hll_init(__policy, __index_bit_count, __bin) \
3305 _AS_EXP_HLL_MOD_START(AS_HLL_OP_INIT, 2), \
3306 as_exp_int(__index_bit_count), \
3307 as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3308 __bin
3309
3310/**
3311 * Create an expression that performs an as_operations_hll_add_mh.
3312 *
3313 * @param __policy An as_hll_policy value.
3314 * @param __list A list expression of elements to add to the HLL.
3315 * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3316 * @param __mh_bit_count Number of min hash bits. Must be between 4 and 51 inclusive.
3317 * Also, __index_bit_count + __mh_bit_count must be <= 64.
3318 * @param __bin A bin expression to apply this function to.
3319 * @return (hll bin) Returns the resulting hll bin after adding elements from __list.
3320 * @ingroup expression
3321 */
3322#define as_exp_hll_add_mh(__policy, __list, __index_bit_count, __mh_bit_count, __bin) \
3323 _AS_EXP_HLL_MOD_START(AS_HLL_OP_ADD, 4), \
3324 __list, \
3325 as_exp_int(__index_bit_count), \
3326 as_exp_int(__mh_bit_count), \
3327 as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3328 __bin
3329
3330/**
3331 * Create an expression that performs an as_operations_hll_add.
3332 *
3333 * @param __policy An as_hll_policy value.
3334 * @param __list A list expression of elements to add to the HLL.
3335 * @param __index_bit_count Number of index bits. Must be between 4 and 16 inclusive.
3336 * @param __bin A bin expression to apply this function to.
3337 * @return (hll bin) Returns the resulting hll bin after adding elements from __list.
3338 * @ingroup expression
3339 */
3340#define as_exp_hll_add(__policy, __list, __index_bit_count, __bin) \
3341 _AS_EXP_HLL_MOD_START(AS_HLL_OP_ADD, 4), \
3342 __list, \
3343 as_exp_int(__index_bit_count), \
3344 as_exp_int(-1), \
3345 as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3346 __bin
3347
3348/**
3349 * Create an expression that performs an as_operations_hll_update.
3350 *
3351 * @param __policy An as_hll_policy value.
3352 * @param __list A list expression of elements to add to the HLL.
3353 * @param __bin A bin expression to apply this function to.
3354 * @return (hll bin) Returns the resulting hll bin after adding elements from __list.
3355 * @ingroup expression
3356 */
3357#define as_exp_hll_update(__policy, __list, __bin) \
3358 _AS_EXP_HLL_MOD_START(AS_HLL_OP_ADD, 4), \
3359 __list, \
3360 as_exp_int(-1), \
3361 as_exp_int(-1), \
3362 as_exp_int(__policy == NULL ? 0 : ((as_hll_policy*)__policy)->flags), \
3363 __bin
3364
3365/*********************************************************************************
3366 * HLL READ EXPRESSIONS
3367 *********************************************************************************/
3368
3369#define _AS_EXP_HLL_READ(__rtype) \
3370 {.op=_AS_EXP_CODE_CALL, .count=5}, \
3371 _AS_EXP_VAL_RTYPE(__rtype), \
3372 as_exp_int(_AS_EXP_SYS_CALL_HLL)
3373
3374#define _AS_EXP_HLL_READ_START(__rtype, __op, __n_params) \
3375 _AS_EXP_HLL_READ(__rtype), \
3376 {.op=_AS_EXP_CODE_CALL_VOP_START, .count=1 + (__n_params) }, \
3377 as_exp_int(__op)
3378
3379/**
3380 * Create an expression that performs an as_operations_hll_get_count.
3381 *
3382 * @param __bin A bin expression to apply this function to.
3383 * @return (integer bin) The estimated number of unique elements in an HLL.
3384 * @ingroup expression
3385 */
3386#define as_exp_hll_get_count(__bin) \
3387 _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_COUNT, 0), \
3388 __bin
3389
3390/**
3391 * Create an expression that performs an as_operations_hll_get_union.
3392 *
3393 * @param __list A list expression of HLLs to union with.
3394 * @param __bin A bin expression to apply this function to.
3395 * @return (hll bin) HLL bin representing the set union.
3396 * @ingroup expression
3397 */
3398#define as_exp_hll_get_union(__list, __bin) \
3399 _AS_EXP_HLL_READ_START(AS_EXP_TYPE_HLL, AS_HLL_OP_GET_UNION, 1), \
3400 __list, \
3401 __bin
3402
3403/**
3404 * Create an expression that performs an as_operations_hll_get_union_count.
3405 *
3406 * @param __list A list expression of HLLs to union with.
3407 * @param __bin A bin expression to apply this function to.
3408 * @return (integer bin) Estimated number of elements in the set union.
3409 * @ingroup expression
3410 */
3411#define as_exp_hll_get_union_count(__list, __bin) \
3412 _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_UNION_COUNT, 1), \
3413 __list, \
3414 __bin
3415
3416/**
3417 * Create an expression that performs an as_operations_hll_get_inersect_count.
3418 *
3419 * @param __list A list expression of HLLs to intersect with.
3420 * @param __bin A bin expression to apply this function to.
3421 * @return (integer bin) Estimated number of elements in the set intersection.
3422 * @ingroup expression
3423 */
3424#define as_exp_hll_get_intersect_count(__list, __bin) \
3425 _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_INTERSECT_COUNT, 1), \
3426 __list, \
3427 __bin
3428
3429/**
3430 * Create an expression that performs an as_operations_hll_get_similarity.
3431 *
3432 * @param __list A list expression of HLLs to calculate similarity with..
3433 * @param __bin A bin expression to apply this function to.
3434 * @return (float bin) Estimated similarity between 0.0 and 1.0.
3435 * @ingroup expression
3436 */
3437#define as_exp_hll_get_similarity(__list, __bin) \
3438 _AS_EXP_HLL_READ_START(AS_EXP_TYPE_FLOAT, AS_HLL_OP_SIMILARITY, 1), \
3439 __list, \
3440 __bin
3441
3442/**
3443 * Create an expression that performs an as_operations_hll_describe.
3444 *
3445 * @param __bin A bin expression to apply this function to.
3446 * @return (list bin) A list containing the index_bit_count and minhash_bit_count.
3447 * @ingroup expression
3448 */
3449#define as_exp_hll_describe(__bin) \
3450 _AS_EXP_HLL_READ_START(AS_EXP_TYPE_LIST, AS_HLL_OP_DESCRIBE, 0), \
3451 __bin
3452
3453/**
3454 * Create an expression that checks if the HLL __bin may contain all keys in
3455 * __list..
3456 *
3457 * @param __list A list expression of keys to check if the HLL may contain them.
3458 * @param __bin A bin expression to apply this function to.
3459 * @return (integer bin) 1 __bin may contain all of __list, 0 otherwise.
3460 * @ingroup expression
3461 */
3462#define as_exp_hll_may_contain(__list, __bin) \
3463 _AS_EXP_HLL_READ_START(AS_EXP_TYPE_INT, AS_HLL_OP_MAY_CONTAIN, 1), \
3464 __list, \
3465 __bin
3466
3467/*********************************************************************************
3468 * EXPRESSION MERGE
3469 *********************************************************************************/
3470
3471/**
3472 * Merge precompiled expression into a new expression tree.
3473 * Useful for storing common precompiled expressions and then reusing
3474 * these expressions as part of a greater expression.
3475 *
3476 * ~~~~~~~~~~{.c}
3477 * // Merge precompiled expression into new expression.
3478 * as_exp_build(expr, as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(200)));
3479 * as_exp_build(merged,
3480 * as_exp_and(
3481 * as_exp_expr(expr),
3482 * as_exp_cmp_eq(as_exp_bin_int("b"), as_exp_int(100))));
3483 * ~~~~~~~~~~
3484 *
3485 * @param __e Pre-compiled expression.
3486 * @ingroup expression
3487 */
3488#define as_exp_expr(__e) \
3489 {.op=_AS_EXP_CODE_MERGE, .v.expr=__e}
3490
3491/*********************************************************************************
3492 * EXPRESSION BUILDERS
3493 *********************************************************************************/
3494
3495/**
3496 * Declare and build an expression variable.
3497 *
3498 * ~~~~~~~~~~{.c}
3499 * // a == 10
3500 * as_exp_build(expression,
3501 * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(10)));
3502 * ...
3503 * as_exp_destroy(expression);
3504 * ~~~~~~~~~~
3505 *
3506 * @param __name Name of the variable to hold the expression
3507 * @ingroup expression
3508 */
3509#define as_exp_build(__name, ...) \
3510 as_exp* __name; \
3511 do { \
3512 as_exp_entry __table__[] = { __VA_ARGS__ }; \
3513 __name = as_exp_compile(__table__, sizeof(__table__) / sizeof(as_exp_entry)); \
3514 } while (false)
3515
3516/**
3517 * Declare and build an base64 packed expression variable.
3518 *
3519 * ~~~~~~~~~~{.c}
3520 * // a == 10
3521 * as_exp_build_b64(expression,
3522 * as_exp_cmp_eq(as_exp_bin_int("a"), as_exp_int(10)));
3523 * ...
3524 * as_exp_destroy_b64(expression);
3525 * ~~~~~~~~~~
3526 *
3527 * @param __name Name of the variable to hold the expression
3528 * @ingroup expression
3529 */
3530#define as_exp_build_b64(__name, ...) \
3531 char* __name; \
3532 do { \
3533 as_exp_entry __table__[] = { __VA_ARGS__ }; \
3534 as_exp* temp = as_exp_compile(__table__, sizeof(__table__) / sizeof(as_exp_entry)); \
3535 __name = as_exp_compile_b64(temp); \
3536 as_exp_destroy(temp); \
3537 } while (false)
3538
3539#ifdef __cplusplus
3540} // end extern "C"
3541#endif
as_exp_type
Definition as_exp.h:166
@ AS_EXP_TYPE_BLOB
Definition as_exp.h:173
@ AS_EXP_TYPE_ERROR
Definition as_exp.h:179
@ AS_EXP_TYPE_LIST
Definition as_exp.h:171
@ AS_EXP_TYPE_FLOAT
Definition as_exp.h:174
@ AS_EXP_TYPE_STR
Definition as_exp.h:170
@ AS_EXP_TYPE_BOOL
Definition as_exp.h:168
@ AS_EXP_TYPE_HLL
Definition as_exp.h:176
@ AS_EXP_TYPE_NIL
Definition as_exp.h:167
@ AS_EXP_TYPE_INT
Definition as_exp.h:169
@ AS_EXP_TYPE_AUTO
Definition as_exp.h:178
@ AS_EXP_TYPE_GEOJSON
Definition as_exp.h:175
@ AS_EXP_TYPE_MAP
Definition as_exp.h:172
AS_EXTERN as_exp * as_exp_compile(as_exp_entry *table, uint32_t n)
AS_EXTERN int64_t as_exp_get_map_type(as_exp_type type, as_map_return_type rtype, bool is_multi)
AS_EXTERN char * as_exp_compile_b64(as_exp *exp)
AS_EXTERN void as_exp_destroy_b64(char *b64)
as_exp_ops
Definition as_exp.h:66
AS_EXTERN int64_t as_exp_get_list_type(as_exp_type default_type, as_list_return_type rtype, bool is_multi)
as_exp_call_system_type
Definition as_exp.h:158
AS_EXTERN int64_t as_exp_get_ctx_type(const as_cdt_ctx *ctx, as_exp_type default_type)
AS_EXTERN uint8_t * as_exp_write(as_exp *exp, uint8_t *ptr)
uint8_t type
Definition as_proto.h:1
#define AS_EXTERN
Definition as_std.h:25
static void as_exp_destroy_base64(char *base64)
Definition as_exp.h:258
static char * as_exp_to_base64(as_exp *exp)
Definition as_exp.h:232
AS_EXTERN void as_exp_destroy(as_exp *exp)
AS_EXTERN as_exp * as_exp_from_base64(const char *base64)
as_list_return_type
as_map_return_type
Definition as_exp.h:187
int32_t prev_va_args
Definition as_exp.h:191
bool bool_val
Definition as_exp.h:200
as_exp * expr
Definition as_exp.h:205
uint32_t count
Definition as_exp.h:189
uint64_t uint_val
Definition as_exp.h:198
as_val * val
Definition as_exp.h:194
as_list_policy * list_pol
Definition as_exp.h:203
const char * str_val
Definition as_exp.h:195
int64_t int_val
Definition as_exp.h:197
uint32_t sz
Definition as_exp.h:190
as_map_policy * map_pol
Definition as_exp.h:204
uint8_t * bytes_val
Definition as_exp.h:196
double float_val
Definition as_exp.h:199
as_cdt_ctx * ctx
Definition as_exp.h:202
as_exp_ops op
Definition as_exp.h:188
uint32_t packed_sz
Definition as_exp.h:183
uint8_t packed[]
Definition as_exp.h:184