X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fanalyzer.c;h=c96f81b61fa6cc121f19e9d48ff98f9cffda57c5;hb=c856cc7bc33c847f851cd1972cf0ddea9a0d9550;hp=e9e1d138c80c9bd5177caa7f4d38b02f30a173b3;hpb=26717c04224fb613f8dfe28f484b8a6f28f3739b;p=sysdb.git diff --git a/src/frontend/analyzer.c b/src/frontend/analyzer.c index e9e1d13..c96f81b 100644 --- a/src/frontend/analyzer.c +++ b/src/frontend/analyzer.c @@ -40,25 +40,26 @@ */ 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_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), SDB_STORE_TYPE_TO_NAME(context)); } /* iter_error */ static void -iter_array_error(sdb_strbuf_t *errbuf, int op, - int array_type, int cmp, int value_type) +iter_op_error(sdb_strbuf_t *errbuf, int op, + int iter_type, int cmp, int value_type) { - sdb_strbuf_sprintf(errbuf, "Invalid array iterator %s %s %s %s", - MATCHER_SYM(op), SDB_TYPE_TO_STRING(array_type), + sdb_strbuf_sprintf(errbuf, "Invalid iterator %s %s %s %s", + MATCHER_SYM(op), SDB_TYPE_TO_STRING(iter_type), MATCHER_SYM(cmp), SDB_TYPE_TO_STRING(value_type)); - if ((array_type & 0xff) != value_type) + if ((iter_type & 0xff) != value_type) sdb_strbuf_append(errbuf, " (type mismatch)"); else sdb_strbuf_append(errbuf, " (invalid operator)"); -} /* iter_array_error */ +} /* iter_op_error */ static void cmp_error(sdb_strbuf_t *errbuf, int op, int left, int right) @@ -127,7 +128,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,85 +138,78 @@ 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; + 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); + + 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 == context) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); - return -1; + + if (ITER_M(m)->iter->type == TYPED_EXPR) { + child_context = (int)ITER_M(m)->iter->data.data.integer; + left_type = ITER_M(m)->iter->data_type; } - 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; + 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 (! ITER_M(m)->iter->type) { + child_context = context; + /* elements of the array constant */ + left_type = ITER_M(m)->iter->data.type & 0xff; } - if ((context == SDB_SERVICE) - && (ITER_M(m)->type == SDB_METRIC)) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); + else { + iter_error(errbuf, m->type, ITER_M(m)->iter, context); return -1; } - else if ((context == SDB_METRIC) - && (ITER_M(m)->type == SDB_SERVICE)) { - iter_error(errbuf, m->type, ITER_M(m)->type, context); + + /* any ary operator will do but these are the once + * we currently support */ + if ((ITER_M(m)->m->type != MATCHER_LT) + && (ITER_M(m)->m->type != MATCHER_LE) + && (ITER_M(m)->m->type != MATCHER_EQ) + && (ITER_M(m)->m->type != MATCHER_NE) + && (ITER_M(m)->m->type != MATCHER_GE) + && (ITER_M(m)->m->type != MATCHER_GT) + && (ITER_M(m)->m->type != MATCHER_REGEX) + && (ITER_M(m)->m->type != MATCHER_NREGEX)) { + iter_op_error(errbuf, 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) { - /* array iterators only support simple comparison atm */ - if ((ITER_M(m)->m->type != MATCHER_LT) - && (ITER_M(m)->m->type != MATCHER_LE) - && (ITER_M(m)->m->type != MATCHER_EQ) - && (ITER_M(m)->m->type != MATCHER_NE) - && (ITER_M(m)->m->type != MATCHER_GE) - && (ITER_M(m)->m->type != MATCHER_GT) - && (ITER_M(m)->m->type != MATCHER_REGEX) - && (ITER_M(m)->m->type != MATCHER_NREGEX)) { - iter_array_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)->right->data_type < 0) - return 0; /* skip further type checks */ - if (CMP_M(ITER_M(m)->m)->right->data_type & SDB_TYPE_ARRAY) { - iter_array_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_array_error(errbuf, m->type, - CMP_M(ITER_M(m)->m)->left->data_type, - ITER_M(m)->m->type, + 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, + 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 (analyze_matcher(child_context, m->type, ITER_M(m)->m, errbuf)) return -1; break; + } case MATCHER_LT: case MATCHER_LE: @@ -222,53 +217,60 @@ 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: 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)->left->data_type & SDB_TYPE_ARRAY)) { - cmp_error(errbuf, m->type, CMP_M(m)->left->data_type, - CMP_M(m)->right->data_type); - return -1; - } + /* the left operand may be a scalar or an array but the element + * type has to match */ 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_M(m)->right->data_type); return -1; } - if ((CMP_M(m)->left->data_type > 0) && (CMP_M(m)->right->data_type > 0)) { if ((CMP_M(m)->left->data_type & 0xff) @@ -368,9 +370,9 @@ sdb_fe_analyze(sdb_conn_node_t *node, sdb_strbuf_t *errbuf) return -1; } - if (analyze_matcher(context, m, errbuf)) + 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 */