X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Ffrontend%2Fanalyzer.c;h=4bd370222e8e11d4a41e9a3b297a1e35412155be;hp=c7a6ee0c6ff547c906a101f6b2509725b1c9dd60;hb=da760b7c730635befe5d3876641dd826f7abf9d3;hpb=1c6d22596a811f02f04980e4a07fee5b1e899525 diff --git a/src/frontend/analyzer.c b/src/frontend/analyzer.c index c7a6ee0..4bd3702 100644 --- a/src/frontend/analyzer.c +++ b/src/frontend/analyzer.c @@ -40,11 +40,12 @@ */ static void -iter_error(sdb_strbuf_t *errbuf, int op, int oper, int context) +iter_error(sdb_strbuf_t *errbuf, int op, sdb_store_expr_t *iter, int context) { - sdb_strbuf_sprintf(errbuf, "Cannot use %s %s in %s context", - MATCHER_SYM(op), SDB_STORE_TYPE_TO_NAME(oper), - SDB_STORE_TYPE_TO_NAME(context)); + sdb_strbuf_sprintf(errbuf, "Invalid %s iterator: %s %s " + "not iterable in %s context", MATCHER_SYM(op), + EXPR_TO_STRING(iter), SDB_STORE_TYPE_TO_NAME(iter->data_type), + context == -1 ? "generic" : SDB_STORE_TYPE_TO_NAME(context)); } /* iter_error */ static void @@ -99,14 +100,24 @@ analyze_expr(int context, sdb_store_expr_t *e, sdb_strbuf_t *errbuf) sdb_strbuf_sprintf(errbuf, "Invalid expression %s.%s " "in %s context", SDB_STORE_TYPE_TO_NAME(e->data.data.integer), - EXPR_TO_STRING(e->left), SDB_STORE_TYPE_TO_NAME(context)); + EXPR_TO_STRING(e->left), + context == -1 ? "generic" : SDB_STORE_TYPE_TO_NAME(context)); return -1; case ATTR_VALUE: - case FIELD_VALUE: case 0: break; + case FIELD_VALUE: + if ((e->data.data.integer == SDB_FIELD_VALUE) + && (context != SDB_ATTRIBUTE)) { + sdb_strbuf_sprintf(errbuf, "Invalid expression %s.value " + "(only attributes have a value)", + SDB_STORE_TYPE_TO_NAME(context)); + return -1; + } + break; + default: if (analyze_expr(context, e->left, errbuf)) return -1; @@ -127,7 +138,8 @@ analyze_expr(int context, sdb_store_expr_t *e, sdb_strbuf_t *errbuf) } /* analyze_expr */ static int -analyze_matcher(int context, sdb_store_matcher_t *m, sdb_strbuf_t *errbuf) +analyze_matcher(int context, int parent_type, + sdb_store_matcher_t *m, sdb_strbuf_t *errbuf) { if (! m) return 0; @@ -136,48 +148,69 @@ analyze_matcher(int context, sdb_store_matcher_t *m, sdb_strbuf_t *errbuf) case MATCHER_OR: case MATCHER_AND: assert(OP_M(m)->left && OP_M(m)->right); - if (analyze_matcher(context, OP_M(m)->left, errbuf)) + if (analyze_matcher(context, m->type, OP_M(m)->left, errbuf)) return -1; - if (analyze_matcher(context, OP_M(m)->right, errbuf)) + if (analyze_matcher(context, m->type, OP_M(m)->right, errbuf)) return -1; break; case MATCHER_NOT: assert(UOP_M(m)->op); - if (analyze_matcher(context, UOP_M(m)->op, errbuf)) + if (analyze_matcher(context, m->type, UOP_M(m)->op, errbuf)) return -1; break; case MATCHER_ANY: case MATCHER_ALL: + { + int child_context = -1; + int left_type = -1; + int type = -1; + assert(ITER_M(m)->m); - if ((context != SDB_HOST) - && (context != SDB_SERVICE) - && (context != SDB_METRIC)) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); - return -1; + + if ((ITER_M(m)->iter->type == TYPED_EXPR) + || (ITER_M(m)->iter->type == FIELD_VALUE)) + type = (int)ITER_M(m)->iter->data.data.integer; + + if (context == -1) { /* inside a filter */ + /* attributes are always iterable */ + if ((ITER_M(m)->iter->type == TYPED_EXPR) + && (type != SDB_ATTRIBUTE)) { + iter_error(errbuf, m->type, ITER_M(m)->iter, context); + return -1; + } + /* backends are always iterable */ + if ((ITER_M(m)->iter->type == FIELD_VALUE) + && (! (type != SDB_FIELD_BACKEND))) { + iter_error(errbuf, m->type, ITER_M(m)->iter, context); + return -1; + } } - if (ITER_M(m)->type == context) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); + else if (! sdb_store_expr_iterable(ITER_M(m)->iter, context)) { + iter_error(errbuf, m->type, ITER_M(m)->iter, context); return -1; } - if ((ITER_M(m)->type != SDB_SERVICE) - && (ITER_M(m)->type != SDB_METRIC) - && (ITER_M(m)->type != SDB_ATTRIBUTE) - && (ITER_M(m)->type != SDB_FIELD_BACKEND)) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); - return -1; + + if (ITER_M(m)->iter->type == TYPED_EXPR) { + child_context = type; + left_type = ITER_M(m)->iter->data_type; } - if ((context == SDB_SERVICE) - && (ITER_M(m)->type == SDB_METRIC)) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); - return -1; + else if (ITER_M(m)->iter->type == FIELD_VALUE) { + child_context = context; + /* element type of the field */ + left_type = ITER_M(m)->iter->data_type & 0xff; } - else if ((context == SDB_METRIC) - && (ITER_M(m)->type == SDB_SERVICE)) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); + else if (! ITER_M(m)->iter->type) { + child_context = context; + /* elements of the array constant */ + left_type = ITER_M(m)->iter->data.type & 0xff; + } + else { + iter_error(errbuf, m->type, ITER_M(m)->iter, context); return -1; } + /* any ary operator will do but these are the once * we currently support */ if ((ITER_M(m)->m->type != MATCHER_LT) @@ -189,33 +222,30 @@ analyze_matcher(int context, sdb_store_matcher_t *m, sdb_strbuf_t *errbuf) && (ITER_M(m)->m->type != MATCHER_REGEX) && (ITER_M(m)->m->type != MATCHER_NREGEX)) { iter_op_error(errbuf, m->type, - CMP_M(ITER_M(m)->m)->left->data_type, - ITER_M(m)->m->type, + left_type, ITER_M(m)->m->type, CMP_M(ITER_M(m)->m)->right->data_type); return -1; } - if (ITER_M(m)->type == SDB_FIELD_BACKEND) { - if (CMP_M(ITER_M(m)->m)->right->data_type < 0) - return 0; /* skip further type checks */ - if (CMP_M(ITER_M(m)->m)->right->data_type & SDB_TYPE_ARRAY) { + if ((left_type >= 0) + && (CMP_M(ITER_M(m)->m)->right->data_type >= 0)) { + if (left_type != CMP_M(ITER_M(m)->m)->right->data_type) { iter_op_error(errbuf, m->type, - CMP_M(ITER_M(m)->m)->left->data_type, - ITER_M(m)->m->type, - CMP_M(ITER_M(m)->m)->right->data_type); - return -1; - } - if ((CMP_M(ITER_M(m)->m)->left->data_type & 0xff) - != CMP_M(ITER_M(m)->m)->right->data_type) { - iter_op_error(errbuf, m->type, - CMP_M(ITER_M(m)->m)->left->data_type, - ITER_M(m)->m->type, + left_type, ITER_M(m)->m->type, CMP_M(ITER_M(m)->m)->right->data_type); return -1; } } - else if (analyze_matcher(ITER_M(m)->type, ITER_M(m)->m, errbuf)) + if (child_context <= 0) { + sdb_strbuf_sprintf(errbuf, "Unable to determine the context " + "(object type) of iterator %s %s %s %s", + MATCHER_SYM(m->type), SDB_TYPE_TO_STRING(left_type), + MATCHER_SYM(ITER_M(m)->m->type), + SDB_TYPE_TO_STRING(CMP_M(ITER_M(m)->m)->right->data_type)); + } + if (analyze_matcher(child_context, m->type, ITER_M(m)->m, errbuf)) return -1; break; + } case MATCHER_LT: case MATCHER_LE: @@ -223,33 +253,44 @@ analyze_matcher(int context, sdb_store_matcher_t *m, sdb_strbuf_t *errbuf) case MATCHER_NE: case MATCHER_GE: case MATCHER_GT: - assert(CMP_M(m)->left && CMP_M(m)->right); + { + int left_type = -1; + + assert(CMP_M(m)->right); + if ((parent_type == MATCHER_ALL) + || (parent_type == MATCHER_ANY)) { + assert(! CMP_M(m)->left); + } + else { + assert(CMP_M(m)->left); + left_type = CMP_M(m)->left->data_type; + } + if (analyze_expr(context, CMP_M(m)->left, errbuf)) return -1; if (analyze_expr(context, CMP_M(m)->right, errbuf)) return -1; - if ((CMP_M(m)->left->data_type > 0) - && (CMP_M(m)->right->data_type > 0)) { - if (CMP_M(m)->left->data_type == CMP_M(m)->right->data_type) + if ((left_type > 0) && (CMP_M(m)->right->data_type > 0)) { + if (left_type == CMP_M(m)->right->data_type) return 0; - cmp_error(errbuf, m->type, CMP_M(m)->left->data_type, + cmp_error(errbuf, m->type, left_type, CMP_M(m)->right->data_type); return -1; } - if ((CMP_M(m)->left->data_type > 0) - && (CMP_M(m)->left->data_type & SDB_TYPE_ARRAY)) { - cmp_error(errbuf, m->type, CMP_M(m)->left->data_type, + if ((left_type > 0) && (left_type & SDB_TYPE_ARRAY)) { + cmp_error(errbuf, m->type, left_type, CMP_M(m)->right->data_type); return -1; } if ((CMP_M(m)->right->data_type > 0) && (CMP_M(m)->right->data_type & SDB_TYPE_ARRAY)) { - cmp_error(errbuf, m->type, CMP_M(m)->left->data_type, + cmp_error(errbuf, m->type, left_type, CMP_M(m)->right->data_type); return -1; } break; + } case MATCHER_IN: case MATCHER_NIN: @@ -361,13 +402,20 @@ sdb_fe_analyze(sdb_conn_node_t *node, sdb_strbuf_t *errbuf) } else { sdb_strbuf_sprintf(errbuf, - "Don't know how to analyze command %#x", node->cmd); + "Don't know how to analyze %s command (id=%#x)", + SDB_CONN_MSGTYPE_TO_STRING(node->cmd), node->cmd); return -1; } - if (analyze_matcher(context, m, errbuf)) + if (context <= 0) { + sdb_strbuf_sprintf(errbuf, "Unable to determine the context " + "(object type) for %s command (id=%#x)", + SDB_CONN_MSGTYPE_TO_STRING(node->cmd), node->cmd); + return -1; + } + if (analyze_matcher(context, -1, m, errbuf)) status = -1; - if (analyze_matcher(-1, filter, errbuf)) + if (analyze_matcher(-1, -1, filter, errbuf)) status = -1; return status; } /* sdb_fe_analyze */