summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5a53fae)
raw | patch | inline | side by side (parent: 5a53fae)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 2 Sep 2015 21:49:20 +0000 (23:49 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 2 Sep 2015 21:49:20 +0000 (23:49 +0200) |
That is, iterators may now work with arithmetic expressions that evaluate to
an array.
an array.
diff --git a/src/core/store_expr.c b/src/core/store_expr.c
index 80c1f4ac25c756383d579a1a92042045f5df6cec..5e15f5350b9ca26d16564317e46957e8285fbcd3 100644 (file)
--- a/src/core/store_expr.c
+++ b/src/core/store_expr.c
#include "core/object.h"
#include <assert.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
sdb_data_t array;
size_t array_idx;
+ bool free_array;
sdb_store_matcher_t *filter;
};
sdb_store_expr_iter_t *iter;
sdb_avltree_iter_t *tree = NULL;
sdb_data_t array = SDB_DATA_INIT;
+ bool free_array = 0;
if (! expr)
return NULL;
if (expr->data.type & SDB_TYPE_ARRAY)
array = expr->data;
}
- else
- return NULL;
+ else {
+ sdb_data_t value = SDB_DATA_INIT;
+ if (sdb_store_expr_eval(expr, obj, &value, filter))
+ return NULL;
+ if (! (value.type & SDB_TYPE_ARRAY)) {
+ sdb_data_free_datum(&value);
+ return NULL;
+ }
+ array = value;
+ free_array = 1;
+ }
if ((! tree) && (array.type == SDB_TYPE_NULL))
return NULL;
iter = calloc(1, sizeof(*iter));
- if (! iter)
+ if (! iter) {
+ if (free_array)
+ sdb_data_free_datum(&array);
return NULL;
+ }
sdb_object_ref(SDB_OBJ(obj));
sdb_object_ref(SDB_OBJ(expr));
iter->expr = expr;
iter->tree = tree;
iter->array = array;
+ iter->free_array = free_array;
iter->filter = filter;
return iter;
} /* sdb_store_expr_iter */
sdb_avltree_iter_destroy(iter->tree);
iter->tree = NULL;
+ if (iter->free_array)
+ sdb_data_free_datum(&iter->array);
iter->array = null;
iter->array_idx = 0;
index b43b1ef6785930cf1550fdec7b917aa22e081eff..06151a81d4fdb04bb49143dd794ee60c30a00618 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
assert((! CMP_M(ITER_M(m)->m)->left) && CMP_M(ITER_M(m)->m)->right);
iter = sdb_store_expr_iter(ITER_M(m)->iter, obj, filter);
- if (! iter)
+ if (! iter) {
+ sdb_log(SDB_LOG_WARNING, "store: Invalid iterator");
return 0;
+ }
status = all;
while (sdb_store_expr_iter_has_next(iter)) {
diff --git a/src/parser/analyzer.c b/src/parser/analyzer.c
index f12dff2005a953d39910eec9ce8e026f67c4be95..ecae40f890c2842d82f92d701ab0a8e3137025f9 100644 (file)
--- a/src/parser/analyzer.c
+++ b/src/parser/analyzer.c
static int
analyze_arith(context_t ctx, sdb_ast_op_t *op, sdb_strbuf_t *errbuf)
{
- if (ctx.iter) {
- op_error(errbuf, op, "cannot evaluate in iterator context");
- return -1;
- }
-
if (analyze_node(ctx, op->left, errbuf))
return -1;
if (analyze_node(ctx, op->right, errbuf))
index e36c302422089adbe740b9ecd2cdd5710bcda03a..7640511b692f7bfaa68f5a627066d7b5afa0bf90 100644 (file)
"{\"name\": \"hostname\", \"value\": \"h1\", " \
"\"last_update\": \"1970-01-01 00:00:01 +0000\", " \
"\"update_interval\": \"0s\", \"backends\": []}]}]}"
+#define HOST_H2 \
+ "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": [], " \
+ "\"metrics\": [" \
+ "{\"name\": \"m1\", \"timeseries\": false, " \
+ "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": [], " \
+ "\"attributes\": [" \
+ "{\"name\": \"hostname\", \"value\": \"h2\", " \
+ "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": []}]}], " \
+ "\"services\": [" \
+ "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": [], " \
+ "\"attributes\": [" \
+ "{\"name\": \"hostname\", \"value\": \"h2\", " \
+ "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": []}]}," \
+ "{\"name\": \"s2\", \"last_update\": \"1970-01-01 00:00:02 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": [], " \
+ "\"attributes\": [" \
+ "{\"name\": \"hostname\", \"value\": \"h2\", " \
+ "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": []}," \
+ "{\"name\": \"k1\", \"value\": 123, " \
+ "\"last_update\": \"1970-01-01 00:00:02 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": []}," \
+ "{\"name\": \"k2\", \"value\": 4711, " \
+ "\"last_update\": \"1970-01-01 00:00:01 +0000\", " \
+ "\"update_interval\": \"0s\", \"backends\": []}]}]}"
#define HOST_H1_ARRAY "["HOST_H1"]"
+#define HOST_H12_ARRAY "["HOST_H1","HOST_H2"]"
#define HOST_H1_LISTING \
"{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", " \
"\"update_interval\": \"0s\", \"backends\": []}"
SDB_CONNECTION_QUERY, "LOOKUP hosts MATCHING name = 'h1' FILTER age >= 0s", -1, /* always matches */
0, SDB_CONNECTION_DATA, 1112, SDB_CONNECTION_LOOKUP, HOST_H1_ARRAY,
},
+ {
+ SDB_CONNECTION_QUERY, "LOOKUP hosts MATCHING ANY backend = 'b'", -1,
+ 0, SDB_CONNECTION_DATA, 6, SDB_CONNECTION_LOOKUP, "[]",
+ },
+ {
+ SDB_CONNECTION_QUERY, "LOOKUP hosts MATCHING ANY backend || 'b' = 'b'", -1,
+ 0, SDB_CONNECTION_DATA, 2205, SDB_CONNECTION_LOOKUP, HOST_H12_ARRAY,
+ },
{
SDB_CONNECTION_QUERY, "FETCH host 'h1' FILTER age < 0s", -1, /* never matches */
-1, UINT32_MAX, 0, 0, NULL, /* FETCH fails if the object doesn't exist */
index 89ee2e6d6bc63bcd7aa759e6e385a99953764408..8da4ef0cc722a639e178d9714c89fa0ee16b0395 100644 (file)
"ALL backend =~ 'b'", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST },
{ "LOOKUP hosts MATCHING "
"ALL backend !~ 'b'", -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST },
+ { "LOOKUP hosts MATCHING "
+ "ANY backend || 'a' = 'b'",
+ -1, 1, SDB_AST_TYPE_LOOKUP, SDB_HOST },
/* attribute type is unknown */
{ "LOOKUP hosts MATCHING "
"ANY backend = attribute['backend']",
"ALL 1 || '2' < '3'", -1, -1, 0, 0 },
{ "LOOKUP hosts MATCHING "
"ALL name =~ 'a'", -1, -1, 0, 0 },
- /* this could work in theory but is not supported atm */
- { "LOOKUP hosts MATCHING "
- "ANY backend || 'a' = 'b'",
- -1, -1, 0, 0 },
{ "LOOKUP hosts MATCHING ANY "
"host.name = 'h'", -1, -1, 0, 0 },
{ "LOOKUP services MATCHING ANY "
"host.name = 'h'", -1, -1, 0, 0 },
{ "LOOKUP metrics MATCHING ANY "
"host.name = 'h'", -1, -1, 0, 0 },
+ { "LOOKUP hosts MATCHING ANY "
+ "name || 'a' = 'b'", -1, -1, 0, 0 },
/* invalid LIST commands */
{ "LIST", -1, -1, 0, 0 },