0736876ae1b464d0100958ad04c73b41a08e31b6
1 /*
2 * SysDB - src/include/parser/ast.h
3 * Copyright (C) 2013-2015 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
28 /*
29 * The SysDB query language AST describes the parse-tree of an SysQL query.
30 */
32 #ifndef SDB_PARSER_AST_H
33 #define SDB_PARSER_AST_H 1
35 #include "core/data.h"
36 #include "core/time.h"
37 #include "core/object.h"
39 #include <assert.h>
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
45 /*
46 * sdb_ast_node_type_t describes the type of an AST node.
47 */
48 typedef enum {
49 /* command nodes */
50 SDB_AST_TYPE_FETCH = 1,
51 SDB_AST_TYPE_LIST = 2,
52 SDB_AST_TYPE_LOOKUP = 3,
53 SDB_AST_TYPE_STORE = 4,
54 SDB_AST_TYPE_TIMESERIES = 5,
56 /* generic expressions */
57 SDB_AST_TYPE_OPERATOR = 100,
58 SDB_AST_TYPE_ITERATOR = 101,
60 /* values */
61 SDB_AST_TYPE_CONST = 200,
62 SDB_AST_TYPE_VALUE = 201,
64 SDB_AST_TYPE_TYPED = 210,
65 } sdb_ast_node_type_t;
67 /*
68 * sdb_ast_operator_t describes the type of an operator.
69 */
70 typedef enum {
71 /* logical and comparison operators */
72 #define SDB_AST_IS_LOGICAL(n) \
73 ((((n)->type == SDB_AST_TYPE_OPERATOR) \
74 && ((SDB_AST_AND <= SDB_AST_OP(n)->kind) \
75 && (SDB_AST_OP(n)->kind <= SDB_AST_IN))) \
76 || (((n)->type == SDB_AST_TYPE_ITERATOR) \
77 && ((SDB_AST_ALL <= SDB_AST_ITER(n)->kind) \
78 && (SDB_AST_ITER(n)->kind <= SDB_AST_ANY))))
79 SDB_AST_AND = 1000,
80 SDB_AST_OR = 1001,
81 SDB_AST_NOT = 1002,
83 SDB_AST_LT = 1010,
84 SDB_AST_LE = 1011,
85 SDB_AST_EQ = 1012,
86 SDB_AST_NE = 1013,
87 SDB_AST_GE = 1014,
88 SDB_AST_GT = 1015,
89 SDB_AST_REGEX = 1016,
90 SDB_AST_NREGEX = 1017,
91 SDB_AST_ISNULL = 1018,
92 SDB_AST_ISTRUE = 1019,
93 SDB_AST_ISFALSE = 1020,
94 SDB_AST_IN = 1021,
96 /* arithmetic expressions */
97 #define SDB_AST_IS_ARITHMETIC(n) \
98 (((n)->type == SDB_AST_TYPE_CONST) \
99 || ((n)->type == SDB_AST_TYPE_VALUE) \
100 || ((n)->type == SDB_AST_TYPE_TYPED) \
101 || (((n)->type == SDB_AST_TYPE_OPERATOR) \
102 && ((SDB_AST_ADD <= SDB_AST_OP(n)->kind) \
103 && (SDB_AST_OP(n)->kind <= SDB_AST_CONCAT))))
104 SDB_AST_ADD = 2000,
105 SDB_AST_SUB = 2001,
106 SDB_AST_MUL = 2002,
107 SDB_AST_DIV = 2003,
108 SDB_AST_MOD = 2004,
109 SDB_AST_CONCAT = 2005,
111 /* iterators */
112 #define SDB_AST_IS_ITERATOR(n) \
113 (((n)->type == SDB_AST_TYPE_ITERATOR) \
114 && ((SDB_AST_ALL <= SDB_AST_ITER(n)->kind) \
115 && (SDB_AST_ITER(n)->kind <= SDB_AST_ANY)))
116 SDB_AST_ALL = 3000,
117 SDB_AST_ANY = 3001,
118 } sdb_ast_operator_t;
120 #define SDB_AST_OP_TO_STRING(op) \
121 (((op) == SDB_AST_AND) ? "AND" \
122 : ((op) == SDB_AST_OR) ? "OR" \
123 : ((op) == SDB_AST_NOT) ? "NOT" \
124 : ((op) == SDB_AST_LT) ? "LT" \
125 : ((op) == SDB_AST_LE) ? "LE" \
126 : ((op) == SDB_AST_EQ) ? "EQ" \
127 : ((op) == SDB_AST_NE) ? "NE" \
128 : ((op) == SDB_AST_GE) ? "GE" \
129 : ((op) == SDB_AST_GT) ? "GT" \
130 : ((op) == SDB_AST_REGEX) ? "REGEX" \
131 : ((op) == SDB_AST_NREGEX) ? "NREGEX" \
132 : ((op) == SDB_AST_ISNULL) ? "IS NULL" \
133 : ((op) == SDB_AST_ISTRUE) ? "IS TRUE" \
134 : ((op) == SDB_AST_ISFALSE) ? "IS FALSE" \
135 : ((op) == SDB_AST_IN) ? "IN" \
136 : ((op) == SDB_AST_ADD) ? "ADD" \
137 : ((op) == SDB_AST_SUB) ? "SUB" \
138 : ((op) == SDB_AST_MUL) ? "MUL" \
139 : ((op) == SDB_AST_DIV) ? "DIV" \
140 : ((op) == SDB_AST_MOD) ? "MOD" \
141 : ((op) == SDB_AST_CONCAT) ? "CONCAT" \
142 : ((op) == SDB_AST_ALL) ? "ALL" \
143 : ((op) == SDB_AST_ANY) ? "ANY" \
144 : "UNKNOWN")
146 #define SDB_AST_OP_TO_DATA_OP(op) \
147 (((op) == SDB_AST_ADD) ? SDB_DATA_ADD \
148 : ((op) == SDB_AST_SUB) ? SDB_DATA_SUB \
149 : ((op) == SDB_AST_MUL) ? SDB_DATA_MUL \
150 : ((op) == SDB_AST_DIV) ? SDB_DATA_DIV \
151 : ((op) == SDB_AST_MOD) ? SDB_DATA_MOD \
152 : ((op) == SDB_AST_CONCAT) ? SDB_DATA_CONCAT \
153 : -1)
155 #define SDB_AST_TYPE_TO_STRING(n) \
156 (((n)->type == SDB_AST_TYPE_FETCH) ? "FETCH" \
157 : ((n)->type == SDB_AST_TYPE_LIST) ? "LIST" \
158 : ((n)->type == SDB_AST_TYPE_LOOKUP) ? "LOOKUP" \
159 : ((n)->type == SDB_AST_TYPE_STORE) ? "STORE" \
160 : ((n)->type == SDB_AST_TYPE_TIMESERIES) ? "TIMESERIES" \
161 : ((n)->type == SDB_AST_TYPE_OPERATOR) \
162 ? SDB_AST_OP_TO_STRING(SDB_AST_OP(n)->kind) \
163 : ((n)->type == SDB_AST_TYPE_ITERATOR) ? "ITERATOR" \
164 : ((n)->type == SDB_AST_TYPE_CONST) ? "CONSTANT" \
165 : ((n)->type == SDB_AST_TYPE_VALUE) ? "VALUE" \
166 : ((n)->type == SDB_AST_TYPE_TYPED) ? "TYPED VALUE" \
167 : "UNKNOWN")
169 /*
170 * sdb_ast_node_t is the interface for AST nodes. The first field of any
171 * actual implementation of the interface is of type sdb_ast_node_t to
172 * fascilitate casting between the interface and implementation types.
173 *
174 * It inherits from sdb_object_t and instances may safely be cast to a generic
175 * object as well.
176 */
177 typedef struct {
178 sdb_object_t super;
180 /* type describes the type of the actual node */
181 int type;
183 /* data-type describes the type of the result value */
184 int data_type;
185 } sdb_ast_node_t;
186 #define SDB_AST_NODE(obj) ((sdb_ast_node_t *)(obj))
188 /*
189 * sdb_ast_op_t represents a simple operation.
190 */
191 typedef struct {
192 sdb_ast_node_t super;
193 int kind;
194 /* left operand is NULL for unary expressions */
195 sdb_ast_node_t *left;
196 sdb_ast_node_t *right;
197 } sdb_ast_op_t;
198 #define SDB_AST_OP(obj) ((sdb_ast_op_t *)(obj))
199 #define SDB_AST_OP_INIT \
200 { { SDB_OBJECT_INIT, SDB_AST_TYPE_OPERATOR, -1 }, -1, NULL, NULL }
202 /*
203 * sdb_ast_iter_t represents an iterator.
204 */
205 typedef struct {
206 sdb_ast_node_t super;
207 int kind;
208 sdb_ast_node_t *iter;
209 /* exactly one operand of the expression has to be unset and will be
210 * filled in by the iterator value */
211 sdb_ast_node_t *expr;
212 } sdb_ast_iter_t;
213 #define SDB_AST_ITER(obj) ((sdb_ast_iter_t *)(obj))
214 #define SDB_AST_ITER_INIT \
215 { { SDB_OBJECT_INIT, SDB_AST_TYPE_ITERATOR, -1 }, -1, NULL, NULL }
217 /*
218 * sdb_ast_typed_t represents a typed value.
219 */
220 typedef struct {
221 sdb_ast_node_t super;
222 int type;
223 sdb_ast_node_t *expr;
224 } sdb_ast_typed_t;
225 #define SDB_AST_TYPED(obj) ((sdb_ast_typed_t *)(obj))
226 #define SDB_AST_TYPED_INIT \
227 { { SDB_OBJECT_INIT, SDB_AST_TYPE_TYPED, -1 }, -1, NULL }
229 /*
230 * sdb_ast_const_t represents a constant value.
231 */
232 typedef struct {
233 sdb_ast_node_t super;
234 sdb_data_t value;
235 } sdb_ast_const_t;
236 #define SDB_AST_CONST(obj) ((sdb_ast_const_t *)(obj))
237 #define SDB_AST_CONST_INIT \
238 { { SDB_OBJECT_INIT, SDB_AST_TYPE_CONST, -1 }, SDB_DATA_INIT }
240 /*
241 * sdb_ast_value_t represents an object-specific value:
242 * attributes, or field values.
243 */
244 typedef struct {
245 sdb_ast_node_t super;
246 int type; /* attribute or field */
247 char *name; /* object name; optional */
248 } sdb_ast_value_t;
249 #define SDB_AST_VALUE(obj) ((sdb_ast_value_t *)(obj))
250 #define SDB_AST_VALUE_INIT \
251 { { SDB_OBJECT_INIT, SDB_AST_TYPE_VALUE, -1 }, -1, NULL }
253 /*
254 * sdb_ast_fetch_t represents a FETCH command.
255 */
256 typedef struct {
257 sdb_ast_node_t super;
258 int obj_type;
259 char *hostname; /* optional */
260 char *name;
261 /* whether to include the full object, that is,
262 * including all attributes and all children */
263 bool full;
264 sdb_ast_node_t *filter; /* optional */
265 } sdb_ast_fetch_t;
266 #define SDB_AST_FETCH(obj) ((sdb_ast_fetch_t *)(obj))
267 #define SDB_AST_FETCH_INIT \
268 { { SDB_OBJECT_INIT, SDB_AST_TYPE_FETCH, -1 }, -1, NULL, NULL, 0, NULL }
270 /*
271 * sdb_ast_list_t represents a LIST command.
272 */
273 typedef struct {
274 sdb_ast_node_t super;
275 int obj_type;
276 sdb_ast_node_t *filter; /* optional */
277 } sdb_ast_list_t;
278 #define SDB_AST_LIST(obj) ((sdb_ast_list_t *)(obj))
279 #define SDB_AST_LIST_INIT \
280 { { SDB_OBJECT_INIT, SDB_AST_TYPE_LIST, -1 }, -1, NULL }
282 /*
283 * sdb_ast_lookup_t represents a LOOKUP command.
284 */
285 typedef struct {
286 sdb_ast_node_t super;
287 int obj_type;
288 sdb_ast_node_t *matcher; /* optional */
289 sdb_ast_node_t *filter; /* optional */
290 } sdb_ast_lookup_t;
291 #define SDB_AST_LOOKUP(obj) ((sdb_ast_lookup_t *)(obj))
292 #define SDB_AST_LOOKUP_INIT \
293 { { SDB_OBJECT_INIT, SDB_AST_TYPE_LOOKUP, -1 }, -1, NULL, NULL }
295 /*
296 * sdb_ast_store_t represents a STORE command.
297 */
298 typedef struct {
299 sdb_ast_node_t super;
300 int obj_type;
301 char *hostname; /* optional */
302 int parent_type; /* optional */
303 char *parent; /* optional */
304 char *name;
305 sdb_time_t last_update;
307 /* metric specific */
308 char *store_type;
309 char *store_id;
311 /* attribute specific */
312 sdb_data_t value;
313 } sdb_ast_store_t;
314 #define SDB_AST_STORE(obj) ((sdb_ast_store_t *)(obj))
315 #define SDB_AST_STORE_INIT \
316 { { SDB_OBJECT_INIT, SDB_AST_TYPE_STORE, -1 }, \
317 -1, NULL, -1, NULL, NULL, 0, NULL, NULL, SDB_DATA_INIT }
319 /*
320 * sdb_ast_timeseries_t represents a TIMESERIES command.
321 */
322 typedef struct {
323 sdb_ast_node_t super;
324 char *hostname;
325 char *metric;
326 sdb_time_t start;
327 sdb_time_t end;
328 } sdb_ast_timeseries_t;
329 #define SDB_AST_TIMESERIES(obj) ((sdb_ast_timeseries_t *)(obj))
330 #define SDB_AST_TIMESERIES_INIT \
331 { { SDB_OBJECT_INIT, SDB_AST_TYPE_TIMESERIES, -1 }, NULL, NULL, 0, 0 }
333 /*
334 * AST constructors:
335 * Newly created nodes take ownership of any dynamically allocated objects
336 * (node objects, dynamically allocated constant values, strings). The memory
337 * will be freed when destroying the node using sdb_object_deref.
338 *
339 * The constructors do not verify any arguments. The analyzer has to be used
340 * for that purpose.
341 */
343 /*
344 * sdb_ast_op_create:
345 * Creates an AST node representing a simple (ary or unary) operation. The
346 * newly created node takes ownership of the left and right nodes.
347 */
348 sdb_ast_node_t *
349 sdb_ast_op_create(int kind, sdb_ast_node_t *left, sdb_ast_node_t *right);
351 /*
352 * sdb_ast_iter_create:
353 * Creates an AST node representing an iterator. The newly created node takes
354 * ownership of the iter and expr nodes.
355 */
356 sdb_ast_node_t *
357 sdb_ast_iter_create(int kind, sdb_ast_node_t *iter, sdb_ast_node_t *expr);
359 /*
360 * sdb_ast_typed_create:
361 * Creates an AST node representing a typed expression. Thew newly created
362 * node takes ownership of the expr node.
363 */
364 sdb_ast_node_t *
365 sdb_ast_typed_create(int type, sdb_ast_node_t *expr);
367 /*
368 * sdb_ast_const_create:
369 * Creates an AST node representing a constant value. The newly created node
370 * takes ownership of the value object.
371 */
372 sdb_ast_node_t *
373 sdb_ast_const_create(sdb_data_t value);
375 /*
376 * sdb_ast_value_create:
377 * Creates an AST node representing an object-specific value (sibling nodes,
378 * attributes, or field values). The newly created node takes ownership of the
379 * string value.
380 */
381 sdb_ast_node_t *
382 sdb_ast_value_create(int type, char *name);
384 /*
385 * sdb_ast_fetch_create:
386 * Creates an AST node representing a FETCH command. The newly created node
387 * takes ownership of the strings and the filter node.
388 */
389 sdb_ast_node_t *
390 sdb_ast_fetch_create(int obj_type, char *hostname, char *name, bool full,
391 sdb_ast_node_t *filter);
393 /*
394 * sdb_ast_list_create:
395 * Creates an AST node representing a LIST command. The newly created node
396 * takes ownership of the filter node.
397 */
398 sdb_ast_node_t *
399 sdb_ast_list_create(int obj_type, sdb_ast_node_t *filter);
401 /*
402 * sdb_ast_lookup_create:
403 * Creates an AST node representing a LOOKUP command. The newly created node
404 * takes ownership of the matcher and filter nodes.
405 */
406 sdb_ast_node_t *
407 sdb_ast_lookup_create(int obj_type, sdb_ast_node_t *matcher,
408 sdb_ast_node_t *filter);
410 /*
411 * sdb_ast_store_create:
412 * Creates an AST node representing a STORE command. Thew newly created node
413 * takes ownership of all strings and the value object.
414 */
415 sdb_ast_node_t *
416 sdb_ast_store_create(int obj_type, char *hostname,
417 int parent_type, char *parent, char *name, sdb_time_t last_update,
418 char *store_type, char *store_id, sdb_data_t value);
420 /*
421 * sdb_ast_timeseries_create:
422 * Creates an AST node representing a TIMESERIES command. The newly created
423 * node takes ownership of the strings.
424 */
425 sdb_ast_node_t *
426 sdb_ast_timeseries_create(char *hostname, char *metric,
427 sdb_time_t start, sdb_time_t end);
429 #ifdef __cplusplus
430 } /* extern "C" */
431 #endif
433 #endif /* ! SDB_PARSER_AST_H */
435 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */