X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Fparser%2Fanalyzer.c;h=dea83d7e0c828d8966fbffe9e91a2895c466fdf7;hp=273463d8ce3a2037d2e7211dbb9113c9eec30676;hb=1ef0d00327e4b5f56b438f44053f48fd8b198baa;hpb=bc864220dfdef478fc644dbf0bfe4af40f90e8b0 diff --git a/src/parser/analyzer.c b/src/parser/analyzer.c index 273463d..dea83d7 100644 --- a/src/parser/analyzer.c +++ b/src/parser/analyzer.c @@ -155,6 +155,8 @@ analyze_logical(int context, sdb_ast_op_t *op, sdb_strbuf_t *errbuf) break; case SDB_AST_ISNULL: + case SDB_AST_ISTRUE: + case SDB_AST_ISFALSE: if (analyze_node(context, op->right, errbuf)) return -1; break; @@ -217,23 +219,17 @@ analyze_iter(int context, sdb_ast_iter_t *iter, sdb_strbuf_t *errbuf) if (analyze_node(iter_context, iter->iter, errbuf)) return -1; - if (iter->iter->data_type > 0) - 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); - SDB_AST_OP(iter->expr)->left = NULL; - if (status) - return -1; + /* determine the data-type for better error messages */ + analyze_node(iter_context, SDB_AST_OP(iter->expr)->right, NULL); if (iter->iter->type == SDB_AST_TYPE_TYPED) { int iter_type = SDB_AST_TYPED(iter->iter)->type; + c.value.type = iter->iter->data_type; + if (iter_type == SDB_ATTRIBUTE) { /* attributes are always iterable */ } @@ -262,12 +258,9 @@ analyze_iter(int context, sdb_ast_iter_t *iter, sdb_strbuf_t *errbuf) 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)) { + c.value.type = iter->iter->data_type & 0xff; + + if (iter_type != SDB_FIELD_BACKEND) { iter_error(errbuf, iter, "%s not iterable in %s context", (iter_type == SDB_ATTRIBUTE) ? "attribute" @@ -277,12 +270,27 @@ analyze_iter(int context, sdb_ast_iter_t *iter, sdb_strbuf_t *errbuf) } } else if (iter->iter->type == SDB_AST_TYPE_CONST) { + c.value.type = iter->iter->data_type & 0xff; + 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; } } + else { + /* TODO: if we know the data-type of iter->iter and it's an array, + * we should support an iterator for it as well */ + iter_error(errbuf, iter, "%s expression not iterable", + SDB_AST_TYPE_TO_STRING(iter->iter)); + return -1; + } + + SDB_AST_OP(iter->expr)->left = SDB_AST_NODE(&c); + status = analyze_node(context, iter->expr, errbuf); + SDB_AST_OP(iter->expr)->left = NULL; + if (status) + return -1; return 0; } /* analyze_iter */ @@ -311,10 +319,20 @@ analyze_value(int context, sdb_ast_value_t *v, sdb_strbuf_t *errbuf) return -1; } - if ((context != SDB_ATTRIBUTE) && (v->type == SDB_FIELD_VALUE)) { - sdb_strbuf_sprintf(errbuf, "Invalid expression %s.value", - SDB_FIELD_TO_NAME(v->type)); - return -1; + if (context != UNSPEC_CONTEXT) { + /* skip these checks if we don't know the context; it's up to the + * caller to check again once the right context information is + * available */ + if ((context != SDB_ATTRIBUTE) && (v->type == SDB_FIELD_VALUE)) { + sdb_strbuf_sprintf(errbuf, "Invalid expression %s.value", + SDB_FIELD_TO_NAME(context)); + return -1; + } + if ((context != SDB_METRIC) && (v->type == SDB_FIELD_TIMESERIES)) { + sdb_strbuf_sprintf(errbuf, "Invalid expression %s.timeseries", + SDB_FIELD_TO_NAME(context)); + return -1; + } } return 0; } /* analyze_value */ @@ -341,7 +359,7 @@ analyze_typed(int context, sdb_ast_typed_t *t, sdb_strbuf_t *errbuf) /* self-references are allowed and services and metrics may reference * their parent host; everything may reference attributes */ - if ((context != t->type) && (context != UNSPEC_CONTEXT) + if ((context != t->type) && (context > 0) && (((context != SDB_SERVICE) && (context != SDB_METRIC)) || (t->type != SDB_HOST)) && (t->type != SDB_ATTRIBUTE)) {