X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Fparser%2Fanalyzer.c;h=4adeafc66f02651bbc85c665059503647d792ffb;hp=273463d8ce3a2037d2e7211dbb9113c9eec30676;hb=07dada8e5c614f0ef90fed8e86183ba7acd0e6e8;hpb=bc864220dfdef478fc644dbf0bfe4af40f90e8b0 diff --git a/src/parser/analyzer.c b/src/parser/analyzer.c index 273463d..4adeafc 100644 --- a/src/parser/analyzer.c +++ b/src/parser/analyzer.c @@ -34,14 +34,21 @@ #include #include +#include +#include #define VALID_OBJ_TYPE(t) ((SDB_HOST <= (t)) && ((t) <= SDB_METRIC)) +typedef struct { + int type; + bool iter; +} context_t; + #define FILTER_CONTEXT -1 -#define UNSPEC_CONTEXT -2 +static const context_t FILTER_CTX = { FILTER_CONTEXT, 0 }; static int -analyze_node(int context, sdb_ast_node_t *node, sdb_strbuf_t *errbuf); +analyze_node(context_t ctx, sdb_ast_node_t *node, sdb_strbuf_t *errbuf); /* * error reporting @@ -78,13 +85,91 @@ iter_error(sdb_strbuf_t *errbuf, sdb_ast_iter_t *iter, const char *reason, ...) r); } /* iter_error */ +/* + * generic checks + */ + +typedef struct { + int obj_type; + const char *hostname; + int parent_type; + const char *parent; + const char *name; +} parent_child_t; + +static int +analyze_parent_child(const char *cmd, parent_child_t *pc, sdb_strbuf_t *errbuf) +{ + if ((pc->obj_type != SDB_ATTRIBUTE) + && (! VALID_OBJ_TYPE(pc->obj_type))) { + sdb_strbuf_sprintf(errbuf, "Invalid object type %#x " + "in %s command", pc->obj_type, cmd); + return -1; + } + if (! pc->name) { + sdb_strbuf_sprintf(errbuf, "Missing object name in " + "%s %s command", cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type)); + return -1; + } + + if ((pc->obj_type == SDB_HOST) && pc->hostname) { + sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' " + "in %s HOST command", pc->hostname, cmd); + return -1; + } + else if ((pc->obj_type != SDB_HOST) && (! pc->hostname)) { + sdb_strbuf_sprintf(errbuf, "Missing parent hostname for '%s' " + "in %s %s command", pc->name, + cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type)); + return -1; + } + + if (pc->obj_type == SDB_ATTRIBUTE) { + if ((pc->parent_type <= 0) && pc->parent) { + sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' " + "in %s %s command", pc->parent, + cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type)); + return -1; + } + else if (pc->parent_type > 0) { + if (! VALID_OBJ_TYPE(pc->parent_type)) { + sdb_strbuf_sprintf(errbuf, "Invalid parent type %#x " + "in %s %s command", pc->parent_type, + cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type)); + return -1; + } + if (! pc->parent) { + sdb_strbuf_sprintf(errbuf, "Missing %s parent name " + "in %s %s command", + SDB_STORE_TYPE_TO_NAME(pc->parent_type), + cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type)); + return -1; + } + } + } + else if ((pc->parent_type > 0) || pc->parent) { + sdb_strbuf_sprintf(errbuf, "Unexpected %s parent name '%s' " + "in %s %s command", + SDB_STORE_TYPE_TO_NAME(pc->parent_type), + pc->parent ? pc->parent : "", + cmd, SDB_STORE_TYPE_TO_NAME(pc->obj_type)); + return -1; + } + return 0; +} /* analyze_parent_child */ + /* * expression nodes */ static int -analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) +analyze_logical(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; + } + switch (op->kind) { case SDB_AST_OR: case SDB_AST_AND: @@ -94,7 +179,7 @@ analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) SDB_AST_OP_TO_STRING(op->kind)); return -1; } - if (analyze_node(context, op->left, errbuf)) + if (analyze_node(ctx, op->left, errbuf)) return -1; /* fallthrough */ case SDB_AST_NOT: @@ -104,7 +189,7 @@ analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) SDB_AST_OP_TO_STRING(op->kind)); return -1; } - if (analyze_node(context, op->right, errbuf)) + if (analyze_node(ctx, op->right, errbuf)) return -1; break; @@ -115,9 +200,9 @@ analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) case SDB_AST_GE: case SDB_AST_GT: { - if (analyze_node(context, op->left, errbuf)) + if (analyze_node(ctx, op->left, errbuf)) return -1; - if (analyze_node(context, op->right, errbuf)) + if (analyze_node(ctx, op->right, errbuf)) return -1; if ((op->left->data_type > 0) && (op->right->data_type > 0)) { @@ -139,9 +224,9 @@ analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) case SDB_AST_REGEX: case SDB_AST_NREGEX: - if (analyze_node(context, op->left, errbuf)) + if (analyze_node(ctx, op->left, errbuf)) return -1; - if (analyze_node(context, op->right, errbuf)) + if (analyze_node(ctx, op->right, errbuf)) return -1; /* all types are supported for the left operand @@ -155,14 +240,16 @@ analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) break; case SDB_AST_ISNULL: - if (analyze_node(context, op->right, errbuf)) + case SDB_AST_ISTRUE: + case SDB_AST_ISFALSE: + if (analyze_node(ctx, op->right, errbuf)) return -1; break; case SDB_AST_IN: - if (analyze_node(context, op->left, errbuf)) + if (analyze_node(ctx, op->left, errbuf)) return -1; - if (analyze_node(context, op->right, errbuf)) + if (analyze_node(ctx, op->right, errbuf)) return -1; if ((op->right->data_type > 0) && (! (op->right->data_type & SDB_TYPE_ARRAY))) { @@ -186,11 +273,11 @@ analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) } /* analyze_logical */ static int -analyze_arith(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) +analyze_arith(context_t ctx, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) { - if (analyze_node(context, op->left, errbuf)) + if (analyze_node(ctx, op->left, errbuf)) return -1; - if (analyze_node(context, op->right, errbuf)) + if (analyze_node(ctx, op->right, errbuf)) return -1; SDB_AST_NODE(op)->data_type = sdb_data_expr_type(SDB_AST_OP_TO_DATA_OP(op->kind), op->left->data_type, op->right->data_type); @@ -206,88 +293,44 @@ analyze_arith(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) } /* analyze_arith */ static int -analyze_iter(int context, sdb_ast_iter_t *iter, sdb_strbuf_t *errbuf) +analyze_iter(context_t ctx, sdb_ast_iter_t *iter, sdb_strbuf_t *errbuf) { sdb_ast_const_t c = SDB_AST_CONST_INIT; - int iter_context = context; + context_t iter_ctx = ctx; int status; - if (iter->iter->type == SDB_AST_TYPE_TYPED) - iter_context = SDB_AST_TYPED(iter->iter)->type; + if (ctx.iter) { + iter_error(errbuf, iter, "nested iterators are not supported"); + return -1; + } - if (analyze_node(iter_context, iter->iter, errbuf)) + iter_ctx.iter = 1; + if (analyze_node(iter_ctx, iter->iter, errbuf)) return -1; - if (iter->iter->data_type > 0) + + if (iter->iter->data_type > 0) { + if (! (iter->iter->data_type & SDB_TYPE_ARRAY)) { + iter_error(errbuf, iter, "cannot iterate values of type %s", + SDB_TYPE_TO_STRING(iter->iter->data_type)); + return -1; + } c.value.type = iter->iter->data_type & 0xff; - else - c.value.type = -1; + } /* TODO: support other setups as well */ assert((iter->expr->type == SDB_AST_TYPE_OPERATOR) && (! SDB_AST_OP(iter->expr)->left)); + SDB_AST_OP(iter->expr)->left = SDB_AST_NODE(&c); - status = analyze_node(context, iter->expr, errbuf); + status = analyze_node(ctx, iter->expr, errbuf); SDB_AST_OP(iter->expr)->left = NULL; if (status) return -1; - - if (iter->iter->type == SDB_AST_TYPE_TYPED) { - int iter_type = SDB_AST_TYPED(iter->iter)->type; - - if (iter_type == SDB_ATTRIBUTE) { - /* attributes are always iterable */ - } - else if ((context != SDB_HOST) && (context != SDB_SERVICE) - && (context != SDB_METRIC) && (context != UNSPEC_CONTEXT)) { - iter_error(errbuf, iter, "%s not iterable in %s context", - SDB_STORE_TYPE_TO_NAME(iter_type), - SDB_STORE_TYPE_TO_NAME(context)); - return -1; - } - - if ((context == iter_type) - || ((iter_type != SDB_SERVICE) - && (iter_type != SDB_METRIC) - && (iter_type != SDB_ATTRIBUTE)) - || ((context == SDB_SERVICE) - && (iter_type == SDB_METRIC)) - || ((context == SDB_METRIC) - && (iter_type == SDB_SERVICE))) { - iter_error(errbuf, iter, "%s not iterable in %s context", - SDB_STORE_TYPE_TO_NAME(iter_type), - SDB_STORE_TYPE_TO_NAME(context)); - return -1; - } - } - else if (iter->iter->type == SDB_AST_TYPE_VALUE) { - int iter_type = SDB_AST_VALUE(iter->iter)->type; - - if (iter_type == SDB_FIELD_BACKEND) { - /* backends are always iterable */ - } - else if ((context != SDB_HOST) && (context != SDB_SERVICE) - && (context != SDB_METRIC) && (context != SDB_ATTRIBUTE) - && (context != UNSPEC_CONTEXT)) { - iter_error(errbuf, iter, "%s not iterable in %s context", - (iter_type == SDB_ATTRIBUTE) - ? "attribute" - : SDB_FIELD_TO_NAME(iter_type), - SDB_STORE_TYPE_TO_NAME(context)); - return -1; - } - } - else if (iter->iter->type == SDB_AST_TYPE_CONST) { - if (! (SDB_AST_CONST(iter->iter)->value.type & SDB_TYPE_ARRAY)) { - iter_error(errbuf, iter, "%s not iterable", - SDB_TYPE_TO_STRING(SDB_AST_CONST(iter->iter)->value.type)); - return -1; - } - } return 0; } /* analyze_iter */ static int -analyze_const(int __attribute__((unused)) context, sdb_ast_const_t *c, +analyze_const(context_t __attribute__((unused)) ctx, sdb_ast_const_t *c, sdb_strbuf_t __attribute__((unused)) *errbuf) { SDB_AST_NODE(c)->data_type = c->value.type; @@ -295,7 +338,7 @@ analyze_const(int __attribute__((unused)) context, sdb_ast_const_t *c, } /* analyze_const */ static int -analyze_value(int context, sdb_ast_value_t *v, sdb_strbuf_t *errbuf) +analyze_value(context_t ctx, sdb_ast_value_t *v, sdb_strbuf_t *errbuf) { if (v->type != SDB_ATTRIBUTE) SDB_AST_NODE(v)->data_type = SDB_FIELD_TYPE(v->type); @@ -311,17 +354,39 @@ analyze_value(int context, sdb_ast_value_t *v, sdb_strbuf_t *errbuf) return -1; } - if ((context != SDB_ATTRIBUTE) && (v->type == SDB_FIELD_VALUE)) { + /* this would be caught by the type check in analyze_iter but we're able + * to provide a more specific error message here */ + if (ctx.iter && (v->type != SDB_FIELD_BACKEND)) { + /* only backend values are iterable */ + char value_str[64 + (v->name ? strlen(v->name) : 0)]; + if (v->type == SDB_ATTRIBUTE) + snprintf(value_str, sizeof(value_str), "attribute[%s]", v->name); + else + snprintf(value_str, sizeof(value_str), "'%s'", SDB_FIELD_TO_NAME(v->type)); + sdb_strbuf_sprintf(errbuf, "Cannot iterate %s (scalar value)", value_str); + return -1; + } + + if ((ctx.type != SDB_ATTRIBUTE) && (v->type == SDB_FIELD_VALUE)) { sdb_strbuf_sprintf(errbuf, "Invalid expression %s.value", - SDB_FIELD_TO_NAME(v->type)); + SDB_FIELD_TO_NAME(ctx.type)); + return -1; + } + if ((ctx.type != SDB_METRIC) && (v->type == SDB_FIELD_TIMESERIES)) { + sdb_strbuf_sprintf(errbuf, "Invalid expression %s.timeseries", + SDB_FIELD_TO_NAME(ctx.type)); return -1; } return 0; } /* analyze_value */ static int -analyze_typed(int context, sdb_ast_typed_t *t, sdb_strbuf_t *errbuf) +analyze_typed(context_t ctx, sdb_ast_typed_t *t, sdb_strbuf_t *errbuf) { + context_t child_ctx = ctx; + bool needs_iter = 0; + bool valid = 1; + if ((t->expr->type != SDB_AST_TYPE_VALUE) && (t->expr->type != SDB_AST_TYPE_TYPED)) { sdb_strbuf_sprintf(errbuf, "Invalid expression %s.%s", @@ -329,33 +394,75 @@ analyze_typed(int context, sdb_ast_typed_t *t, sdb_strbuf_t *errbuf) SDB_AST_TYPE_TO_STRING(t->expr)); return -1; } - if (analyze_node(t->type, t->expr, errbuf)) - return -1; - SDB_AST_NODE(t)->data_type = t->expr->data_type; - if ((t->type != SDB_ATTRIBUTE) && (! VALID_OBJ_TYPE(t->type))) { sdb_strbuf_sprintf(errbuf, "Invalid expression %#x.%s", t->type, SDB_AST_TYPE_TO_STRING(t->expr)); return -1; } - /* self-references are allowed and services and metrics may reference - * their parent host; everything may reference attributes */ - if ((context != t->type) && (context != UNSPEC_CONTEXT) - && (((context != SDB_SERVICE) && (context != SDB_METRIC)) - || (t->type != SDB_HOST)) - && (t->type != SDB_ATTRIBUTE)) { + if (ctx.type > 0) { + if ((ctx.type == t->type) + || ((t->type == SDB_HOST) && (ctx.type != SDB_ATTRIBUTE))) { + /* self-references and references to the parent host are always fine */ + } + else if (t->type == SDB_ATTRIBUTE) { + /* references to attributes are always fine */ + needs_iter = 1; + } + else if ((ctx.type == SDB_HOST) + && ((t->type == SDB_SERVICE) || (t->type == SDB_METRIC))) { + /* only hosts may reference services and metrics */ + needs_iter = 1; + } + else { + valid = 0; + } + } + else if (ctx.type == FILTER_CONTEXT) { + if (t->type == SDB_ATTRIBUTE) { + /* all objects have attributes */ + needs_iter = 1; + } + else if ((t->type == SDB_SERVICE) || (t->type == SDB_METRIC)) { + /* these will be iterators for *some* operations; + * better forbid this altogether */ + valid = 0; + } + } + + if (needs_iter) { + if (! ctx.iter) + valid = 0; + else + child_ctx.iter = 0; + } /* else: push ctx.iter down to the child node */ + + if (! valid) { sdb_strbuf_sprintf(errbuf, "Invalid expression %s.%s in %s context", SDB_STORE_TYPE_TO_NAME(t->type), SDB_AST_TYPE_TO_STRING(t->expr), - context == -1 ? "generic" : SDB_STORE_TYPE_TO_NAME(context)); + SDB_STORE_TYPE_TO_NAME(ctx.type)); + return -1; + } + + child_ctx.type = t->type; + if (analyze_node(child_ctx, t->expr, errbuf)) return -1; + SDB_AST_NODE(t)->data_type = t->expr->data_type; + + if (needs_iter && (SDB_AST_NODE(t)->data_type > 0)) { + if (SDB_AST_NODE(t)->data_type & SDB_TYPE_ARRAY) { + sdb_strbuf_sprintf(errbuf, "Cannot access array inside iterator"); + return -1; + } + /* Tell the caller that we're accessing an iterator. */ + SDB_AST_NODE(t)->data_type |= SDB_TYPE_ARRAY; } return 0; } /* analyze_typed */ static int -analyze_node(int context, sdb_ast_node_t *node, sdb_strbuf_t *errbuf) +analyze_node(context_t ctx, sdb_ast_node_t *node, sdb_strbuf_t *errbuf) { if (! node) { sdb_strbuf_sprintf(errbuf, "Empty AST node"); @@ -367,18 +474,18 @@ analyze_node(int context, sdb_ast_node_t *node, sdb_strbuf_t *errbuf) if ((node->type == SDB_AST_TYPE_OPERATOR) && (SDB_AST_IS_LOGICAL(node))) - return analyze_logical(context, SDB_AST_OP(node), errbuf); + return analyze_logical(ctx, SDB_AST_OP(node), errbuf); else if ((node->type == SDB_AST_TYPE_OPERATOR) && (SDB_AST_IS_ARITHMETIC(node))) - return analyze_arith(context, SDB_AST_OP(node), errbuf); + return analyze_arith(ctx, SDB_AST_OP(node), errbuf); else if (node->type == SDB_AST_TYPE_ITERATOR) - return analyze_iter(context, SDB_AST_ITER(node), errbuf); + return analyze_iter(ctx, SDB_AST_ITER(node), errbuf); else if (node->type == SDB_AST_TYPE_CONST) - return analyze_const(context, SDB_AST_CONST(node), errbuf); + return analyze_const(ctx, SDB_AST_CONST(node), errbuf); else if (node->type == SDB_AST_TYPE_VALUE) - return analyze_value(context, SDB_AST_VALUE(node), errbuf); + return analyze_value(ctx, SDB_AST_VALUE(node), errbuf); else if (node->type == SDB_AST_TYPE_TYPED) - return analyze_typed(context, SDB_AST_TYPED(node), errbuf); + return analyze_typed(ctx, SDB_AST_TYPED(node), errbuf); sdb_strbuf_sprintf(errbuf, "Invalid expression node " "of type %#x", node->type); @@ -392,31 +499,16 @@ analyze_node(int context, sdb_ast_node_t *node, sdb_strbuf_t *errbuf) static int analyze_fetch(sdb_ast_fetch_t *fetch, sdb_strbuf_t *errbuf) { - if (! VALID_OBJ_TYPE(fetch->obj_type)) { - sdb_strbuf_sprintf(errbuf, "Invalid object type %#x " - "in FETCH command", fetch->obj_type); - return -1; - } - if (! fetch->name) { - sdb_strbuf_sprintf(errbuf, "Missing object name in " - "FETCH %s command", SDB_STORE_TYPE_TO_NAME(fetch->obj_type)); - return -1; - } + parent_child_t pc = { + fetch->obj_type, fetch->hostname, + fetch->parent_type, fetch->parent, fetch->name, + }; - if ((fetch->obj_type == SDB_HOST) && fetch->hostname) { - sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' " - "in FETCH HOST command", fetch->hostname); - return -1; - } - else if ((fetch->obj_type != SDB_HOST) && (! fetch->hostname)) { - sdb_strbuf_sprintf(errbuf, "Missing parent hostname for '%s' " - "in FETCH %s command", fetch->name, - SDB_STORE_TYPE_TO_NAME(fetch->obj_type)); + if (analyze_parent_child("FETCH", &pc, errbuf)) return -1; - } if (fetch->filter) - return analyze_node(FILTER_CONTEXT, fetch->filter, errbuf); + return analyze_node(FILTER_CTX, fetch->filter, errbuf); return 0; } /* analyze_fetch */ @@ -429,7 +521,7 @@ analyze_list(sdb_ast_list_t *list, sdb_strbuf_t *errbuf) return -1; } if (list->filter) - return analyze_node(FILTER_CONTEXT, list->filter, errbuf); + return analyze_node(FILTER_CTX, list->filter, errbuf); return 0; } /* analyze_list */ @@ -441,72 +533,26 @@ analyze_lookup(sdb_ast_lookup_t *lookup, sdb_strbuf_t *errbuf) "in LOOKUP command", lookup->obj_type); return -1; } - if (lookup->matcher) - if (analyze_node(lookup->obj_type, lookup->matcher, errbuf)) + if (lookup->matcher) { + context_t ctx = { lookup->obj_type, 0 }; + if (analyze_node(ctx, lookup->matcher, errbuf)) return -1; + } if (lookup->filter) - return analyze_node(FILTER_CONTEXT, lookup->filter, errbuf); + return analyze_node(FILTER_CTX, lookup->filter, errbuf); return 0; } /* analyze_lookup */ static int analyze_store(sdb_ast_store_t *st, sdb_strbuf_t *errbuf) { - if ((st->obj_type != SDB_ATTRIBUTE) - && (! VALID_OBJ_TYPE(st->obj_type))) { - sdb_strbuf_sprintf(errbuf, "Invalid object type %#x " - "in STORE command", st->obj_type); - return -1; - } - if (! st->name) { - sdb_strbuf_sprintf(errbuf, "Missing object name in " - "STORE %s command", SDB_STORE_TYPE_TO_NAME(st->obj_type)); - return -1; - } + parent_child_t pc = { + st->obj_type, st->hostname, + st->parent_type, st->parent, st->name, + }; - if ((st->obj_type == SDB_HOST) && st->hostname) { - sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' " - "in STORE HOST command", st->hostname); + if (analyze_parent_child("STORE", &pc, errbuf)) return -1; - } - else if ((st->obj_type != SDB_HOST) && (! st->hostname)) { - sdb_strbuf_sprintf(errbuf, "Missing parent hostname for '%s' " - "in STORE %s command", st->name, - SDB_STORE_TYPE_TO_NAME(st->obj_type)); - return -1; - } - - if (st->obj_type == SDB_ATTRIBUTE) { - if ((st->parent_type <= 0) && st->parent) { - sdb_strbuf_sprintf(errbuf, "Unexpected parent hostname '%s' " - "in STORE %s command", st->parent, - SDB_STORE_TYPE_TO_NAME(st->obj_type)); - return -1; - } - else if (st->parent_type > 0) { - if (! VALID_OBJ_TYPE(st->parent_type)) { - sdb_strbuf_sprintf(errbuf, "Invalid parent type %#x " - "in STORE %s command", st->parent_type, - SDB_STORE_TYPE_TO_NAME(st->obj_type)); - return -1; - } - if (! st->parent) { - sdb_strbuf_sprintf(errbuf, "Missing %s parent name " - "in STORE %s command", - SDB_STORE_TYPE_TO_NAME(st->parent_type), - SDB_STORE_TYPE_TO_NAME(st->obj_type)); - return -1; - } - } - } - else if ((st->parent_type > 0) || st->parent) { - sdb_strbuf_sprintf(errbuf, "Unexpected %s parent name '%s' " - "in STORE %s command", - SDB_STORE_TYPE_TO_NAME(st->parent_type), - st->parent ? st->parent : "", - SDB_STORE_TYPE_TO_NAME(st->obj_type)); - return -1; - } if (st->obj_type == SDB_METRIC) { if ((! st->store_type) != (! st->store_id)) { @@ -541,19 +587,19 @@ static int analyze_timeseries(sdb_ast_timeseries_t *ts, sdb_strbuf_t *errbuf) { if (! ts->hostname) { - sdb_strbuf_sprintf(errbuf, "Missing hostname in STORE command"); + sdb_strbuf_sprintf(errbuf, "Missing hostname in TIMESERIES command"); return -1; } if (! ts->metric) { - sdb_strbuf_sprintf(errbuf, "Missing metric name in STORE command"); + sdb_strbuf_sprintf(errbuf, "Missing metric name in TIMESERIES command"); return -1; } if (ts->end <= ts->start) { char start_str[64], end_str[64]; - sdb_strftime(start_str, sizeof(start_str), "%F %T Tz", ts->start); - sdb_strftime(end_str, sizeof(end_str), "%F %T Tz", ts->end); + sdb_strftime(start_str, sizeof(start_str), ts->start); + sdb_strftime(end_str, sizeof(end_str), ts->end); sdb_strbuf_sprintf(errbuf, "Start time (%s) greater than " - "end time (%s) in STORE command", start_str, end_str); + "end time (%s) in TIMESERIES command", start_str, end_str); return -1; } return 0; @@ -591,8 +637,14 @@ sdb_parser_analyze(sdb_ast_node_t *node, sdb_strbuf_t *errbuf) } /* sdb_parser_analyze */ int -sdb_parser_analyze_conditional(sdb_ast_node_t *node, sdb_strbuf_t *errbuf) +sdb_parser_analyze_conditional(int context, + sdb_ast_node_t *node, sdb_strbuf_t *errbuf) { + context_t ctx = { context, 0 }; + if (! VALID_OBJ_TYPE(context)) { + sdb_strbuf_sprintf(errbuf, "Invalid object type %#x", context); + return -1; + } if (! node) { sdb_strbuf_sprintf(errbuf, "Empty conditional node"); return -1; @@ -602,12 +654,18 @@ sdb_parser_analyze_conditional(sdb_ast_node_t *node, sdb_strbuf_t *errbuf) SDB_AST_TYPE_TO_STRING(node)); return -1; } - return analyze_node(UNSPEC_CONTEXT, node, errbuf); + return analyze_node(ctx, node, errbuf); } /* sdb_parser_analyze_conditional */ int -sdb_parser_analyze_arith(sdb_ast_node_t *node, sdb_strbuf_t *errbuf) +sdb_parser_analyze_arith(int context, + sdb_ast_node_t *node, sdb_strbuf_t *errbuf) { + context_t ctx = { context, 0 }; + if (! VALID_OBJ_TYPE(context)) { + sdb_strbuf_sprintf(errbuf, "Invalid object type %#x", context); + return -1; + } if (! node) { sdb_strbuf_sprintf(errbuf, "Empty arithmetic node"); return -1; @@ -617,7 +675,7 @@ sdb_parser_analyze_arith(sdb_ast_node_t *node, sdb_strbuf_t *errbuf) SDB_AST_TYPE_TO_STRING(node)); return -1; } - return analyze_node(UNSPEC_CONTEXT, node, errbuf); + return analyze_node(ctx, node, errbuf); } /* sdb_parser_analyze_arith */ /* vim: set tw=78 sw=4 ts=4 noexpandtab : */