Code

store_expr: iterator: Support constant arrays without a stored object.
[sysdb.git] / src / core / store_expr.c
index 11370bb438455f6fcf3b08a34a4bcfa5607a98af..60b0bea130a8c50f85c12b6c1b6d9cf91ebc6a25 100644 (file)
@@ -302,10 +302,12 @@ sdb_store_expr_iter(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
        sdb_avltree_iter_t *tree = NULL;
        sdb_data_t array = SDB_DATA_INIT;
 
-       if ((! expr) || (! obj))
+       if (! expr)
                return NULL;
 
        if (expr->type == TYPED_EXPR) {
+               if (! obj)
+                       return NULL;
                if (obj->type == SDB_HOST) {
                        if (expr->data.data.integer == SDB_SERVICE)
                                tree = sdb_avltree_get_iter(HOST(obj)->services);
@@ -324,6 +326,8 @@ sdb_store_expr_iter(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
                }
        }
        else if (expr->type == FIELD_VALUE) {
+               if (! obj)
+                       return NULL;
                if (expr->data.data.integer == SDB_FIELD_BACKEND) {
                        /* while scanning the store, we hold a read lock, so it's safe to
                         * access the data without copying */
@@ -385,8 +389,21 @@ sdb_store_expr_iter_has_next(sdb_store_expr_iter_t *iter)
        if (! iter)
                return 0;
 
-       if (iter->tree)
+       if (iter->tree) {
+               /* this function may be called before get_next,
+                * so we'll have to apply filters here as well */
+               if (iter->filter) {
+                       sdb_store_obj_t *child;
+                       while ((child = STORE_OBJ(sdb_avltree_iter_peek_next(iter->tree)))) {
+                               if (sdb_store_matcher_matches(iter->filter, child, NULL))
+                                       break;
+                               (void)sdb_avltree_iter_get_next(iter->tree);
+                       }
+               }
+
                return sdb_avltree_iter_has_next(iter->tree);
+       }
+
        return iter->array_idx < iter->array.data.array.length;
 } /* sdb_store_expr_iter_has_next */
 
@@ -411,16 +428,19 @@ sdb_store_expr_iter_get_next(sdb_store_expr_iter_t *iter)
                                        && (! sdb_store_matcher_matches(iter->filter, child, NULL)))
                                continue;
 
-                       if (sdb_store_expr_eval(iter->expr, iter->obj, &ret, iter->filter))
+                       if (sdb_store_expr_eval(iter->expr, child, &ret, iter->filter))
                                return null;
                        break;
                }
 
                /* Skip over any filtered objects */
-               if (iter->filter)
-                       while ((child = STORE_OBJ(sdb_avltree_iter_peek_next(iter->tree))))
+               if (iter->filter) {
+                       while ((child = STORE_OBJ(sdb_avltree_iter_peek_next(iter->tree)))) {
                                if (sdb_store_matcher_matches(iter->filter, child, NULL))
                                        break;
+                               (void)sdb_avltree_iter_get_next(iter->tree);
+                       }
+               }
 
                return ret;
        }