sdb_ast_node_t * sdb_ast_const_create(sdb_data_t value) { sdb_ast_const_t *c; c = SDB_AST_CONST(sdb_object_create("CONST", const_type)); if (! c) return NULL; c->super.type = SDB_AST_TYPE_CONST; c->value = value; return SDB_AST_NODE(c); } /* sdb_ast_const_create */
static int analyze_iter(int context, sdb_ast_iter_t *iter, sdb_strbuf_t *errbuf) { sdb_ast_const_t c = SDB_AST_CONST_INIT; int iter_context = context; int status; if (iter->iter->type == SDB_AST_TYPE_TYPED) iter_context = SDB_AST_TYPED(iter->iter)->type; if (analyze_node(iter_context, iter->iter, errbuf)) return -1; /* TODO: support other setups as well */ assert((iter->expr->type == SDB_AST_TYPE_OPERATOR) && (! SDB_AST_OP(iter->expr)->left)); /* 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 */ } 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; 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" : SDB_FIELD_TO_NAME(iter_type), SDB_STORE_TYPE_TO_NAME(context)); return -1; } } 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 */
static void const_destroy(sdb_object_t *obj) { sdb_ast_const_t *c = SDB_AST_CONST(obj); sdb_data_free_datum(&c->value); } /* const_destroy */