diff --git a/src/core/store_expr.c b/src/core/store_expr.c
index 6e39305a89ecd18718ad7984a4e7cc85f407728d..6405002cfda3187177dc9b49dae9ce2bc8e82322 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_data_t value = { SDB_TYPE_INTEGER, { .integer = field } };
sdb_store_expr_t *e;
- if ((field < SDB_FIELD_NAME) || (SDB_FIELD_VALUE < field))
+ if ((field < SDB_FIELD_NAME) || (SDB_FIELD_TIMESERIES < field))
return NULL;
e = SDB_STORE_EXPR(sdb_object_create("store-fieldvalue", expr_type,
FIELD_VALUE, NULL, NULL, &value));
return status;
} /* sdb_store_expr_eval */
-bool
-sdb_store_expr_iterable(sdb_store_expr_t *expr, int context)
-{
- if (expr->type == TYPED_EXPR) {
- if ((context != SDB_HOST) && (context != SDB_SERVICE)
- && (context != SDB_METRIC))
- return 0;
- if (context == expr->data.data.integer)
- return 0;
- if ((expr->data.data.integer != SDB_SERVICE)
- && (expr->data.data.integer != SDB_METRIC)
- && (expr->data.data.integer != SDB_ATTRIBUTE))
- return 0;
- if ((context == SDB_SERVICE)
- && (expr->data.data.integer == SDB_METRIC))
- return 0;
- else if ((context == SDB_METRIC)
- && (expr->data.data.integer == SDB_SERVICE))
- return 0;
- return 1;
- }
- else if (expr->type == FIELD_VALUE) {
- if ((context != SDB_HOST) && (context != SDB_SERVICE)
- && (context != SDB_METRIC) && (context != SDB_ATTRIBUTE))
- return 0;
- if (expr->data.data.integer == SDB_FIELD_BACKEND)
- return 1;
- else if (expr->data.data.integer == SDB_FIELD_VALUE)
- /* we don't current support this just like when using
- * the attribute[<name>] syntax */
- return 0;
- }
- else if (! expr->type) {
- return !!(expr->data.type & SDB_TYPE_ARRAY);
- }
- return 0;
-} /* sdb_store_expr_iterable */
-
sdb_store_expr_iter_t *
sdb_store_expr_iter(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
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;
+ while (expr->type == TYPED_EXPR) {
+ int type = (int)expr->data.data.integer;
+
+ if (obj->type == type) {
+ /* self reference */
+ }
+ else if ((type == SDB_HOST)
+ && ((obj->type == SDB_SERVICE)
+ || (obj->type == SDB_METRIC))) {
+ /* reference to parent host */
+ obj = obj->parent;
+ }
+ else
+ break;
+ expr = expr->left;
+ }
+
if (expr->type == TYPED_EXPR) {
if (! obj)
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;