summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d500078)
raw | patch | inline | side by side (parent: d500078)
author | Sebastian Harl <sh@tokkee.org> | |
Mon, 28 Jul 2014 19:16:14 +0000 (21:16 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Mon, 28 Jul 2014 19:21:03 +0000 (21:21 +0200) |
… rather than simple values.
When comparing object names, the expression has to evaluate to a (constant)
string but conditional attribute comparison supports arbitrary expressions.
Expressions are only evaluated when using them during a comparison even though
we only support constant expressions so far. This will be optimized in the
future.
When comparing object names, the expression has to evaluate to a (constant)
string but conditional attribute comparison supports arbitrary expressions.
Expressions are only evaluated when using them during a comparison even though
we only support constant expressions so far. This will be optimized in the
future.
index 7479bc69ad25082c26ecbc542bbc4f7563b40809..30091a75a466e28351383be46a3e61883999f70a 100644 (file)
--- a/src/core/store-private.h
+++ b/src/core/store-private.h
typedef struct {
sdb_store_cond_t super;
char *name;
- sdb_data_t value;
+ sdb_store_expr_t *expr;
} attr_cond_t;
#define ATTR_C(obj) ((attr_cond_t *)(obj))
index 8aa8ab085e4dd1fc40eb2586e95ea62cb506ba2c..758ddd053c7a742e61ac85fbf15e9f51819c86df 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
attr_cmp(sdb_host_t *host, sdb_store_cond_t *cond)
{
sdb_attribute_t *attr;
+ sdb_data_t value = SDB_DATA_INIT;
+ int status;
+
+ if (sdb_store_expr_eval(ATTR_C(cond)->expr, &value))
+ return INT_MAX;
attr = attr_get(host, ATTR_C(cond)->name);
if (! attr)
- return INT_MAX;
- if (attr->value.type != ATTR_C(cond)->value.type)
- return INT_MAX;
- return sdb_data_cmp(&attr->value, &ATTR_C(cond)->value);
+ status = INT_MAX;
+ else if (attr->value.type != value.type)
+ status = INT_MAX;
+ else
+ status = sdb_data_cmp(&attr->value, &value);
+ sdb_data_free_datum(&value);
+ return status;
} /* attr_cmp */
/*
attr_cond_init(sdb_object_t *obj, va_list ap)
{
const char *name = va_arg(ap, const char *);
- const sdb_data_t *value = va_arg(ap, const sdb_data_t *);
+ sdb_store_expr_t *expr = va_arg(ap, sdb_store_expr_t *);
if (! name)
return -1;
ATTR_C(obj)->name = strdup(name);
if (! ATTR_C(obj)->name)
return -1;
- if (sdb_data_copy(&ATTR_C(obj)->value, value))
- return -1;
+ ATTR_C(obj)->expr = expr;
+ sdb_object_ref(SDB_OBJ(expr));
return 0;
} /* attr_cond_init */
{
if (ATTR_C(obj)->name)
free(ATTR_C(obj)->name);
- sdb_data_free_datum(&ATTR_C(obj)->value);
+ sdb_object_deref(SDB_OBJ(ATTR_C(obj)->expr));
} /* attr_cond_destroy */
static sdb_type_t attr_cond_type = {
cond_tostring(sdb_store_matcher_t *m, char *buf, size_t buflen)
{
if (COND_M(m)->cond->cmp == attr_cmp) {
- char value[buflen];
- if (sdb_data_format(&ATTR_C(COND_M(m)->cond)->value,
- value, sizeof(value), SDB_SINGLE_QUOTED) < 0)
- snprintf(value, sizeof(value), "ERR");
+ sdb_data_t value = SDB_DATA_INIT;
+ char value_str[buflen];
+ if (sdb_store_expr_eval(ATTR_C(COND_M(m)->cond)->expr, &value))
+ snprintf(value_str, sizeof(value_str), "ERR");
+ else if (sdb_data_format(&value, value_str, sizeof(value_str),
+ SDB_SINGLE_QUOTED) < 0)
+ snprintf(value_str, sizeof(value_str), "ERR");
snprintf(buf, buflen, "ATTR[%s]{ %s %s }",
- ATTR_C(COND_M(m)->cond)->name, MATCHER_SYM(m->type), value);
+ ATTR_C(COND_M(m)->cond)->name, MATCHER_SYM(m->type),
+ value_str);
+ sdb_data_free_datum(&value);
}
return buf;
} /* cond_tostring */
*/
sdb_store_cond_t *
-sdb_store_attr_cond(const char *name, const sdb_data_t *value)
+sdb_store_attr_cond(const char *name, sdb_store_expr_t *expr)
{
return SDB_STORE_COND(sdb_object_create("attr-cond", attr_cond_type,
- name, value));
+ name, expr));
} /* sdb_store_attr_cond */
sdb_store_matcher_t *
sdb_store_matcher_t *m;
if (re)
- m = M(sdb_object_create("name-matcher", name_type,
- NULL, name));
+ m = M(sdb_object_create("name-matcher", name_type, NULL, name));
else
- m = M(sdb_object_create("name-matcher", name_type,
- name, NULL));
+ m = M(sdb_object_create("name-matcher", name_type, name, NULL));
if (! m)
return NULL;
sdb_store_matcher_t *
sdb_store_attr_matcher(const char *name, const char *value, _Bool re)
{
+ sdb_store_matcher_t *m;
+
if (! name)
return NULL;
if (re)
- return M(sdb_object_create("attr-matcher", attr_type,
+ m = M(sdb_object_create("attr-matcher", attr_type,
name, NULL, value));
- return M(sdb_object_create("attr-matcher", attr_type,
- name, value, NULL));
+ else
+ m = M(sdb_object_create("attr-matcher", attr_type,
+ name, value, NULL));
+ return m;
} /* sdb_store_attr_matcher */
sdb_store_matcher_t *
} /* sdb_store_isnull_matcher */
static sdb_store_matcher_t *
-parse_attr_cmp(const char *attr, const char *op, const sdb_data_t *value)
+parse_attr_cmp(const char *attr, const char *op, sdb_store_expr_t *expr)
{
sdb_store_matcher_t *(*matcher)(sdb_store_cond_t *) = NULL;
sdb_store_matcher_t *m;
return NULL;
if (! strcasecmp(op, "IS")) {
- if (! value)
+ if (! expr)
return sdb_store_isnull_matcher(attr);
else
return NULL;
}
- else if (! value)
+ else if (! expr)
return NULL;
else if (! strcasecmp(op, "<"))
matcher = sdb_store_lt_matcher;
else
return NULL;
- cond = sdb_store_attr_cond(attr, value);
+ cond = sdb_store_attr_cond(attr, expr);
if (! cond)
return NULL;
sdb_store_matcher_t *
sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr,
- const char *op, const sdb_data_t *value)
+ const char *op, sdb_store_expr_t *expr)
{
int type = -1;
_Bool inv = 0;
_Bool re = 0;
+ sdb_data_t value = SDB_DATA_INIT;
sdb_store_matcher_t *m = NULL;
if (! strcasecmp(obj_type, "host"))
re = 1;
}
else if (type == SDB_ATTRIBUTE)
- return parse_attr_cmp(attr, op, value);
+ return parse_attr_cmp(attr, op, expr);
else
return NULL;
- if (! value)
+ if (! expr)
return NULL;
- if (value->type != SDB_TYPE_STRING) {
- if (type == SDB_ATTRIBUTE)
- return parse_attr_cmp(attr, op, value);
+ if (sdb_store_expr_eval(expr, &value))
return NULL;
+ if (value.type != SDB_TYPE_STRING) {
+ sdb_data_free_datum(&value);
+ return parse_attr_cmp(attr, op, expr);
}
if (! attr)
- m = sdb_store_name_matcher(type, value->data.string, re);
+ m = sdb_store_name_matcher(type, value.data.string, re);
else if (type == SDB_ATTRIBUTE)
- m = sdb_store_attr_matcher(attr, value->data.string, re);
+ m = sdb_store_attr_matcher(attr, value.data.string, re);
+
+ sdb_data_free_datum(&value);
if (! m)
return NULL;
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 0afbd9edb32461c00eb36f2248d0259204b1d930..ed4de830fc64cc0f091a52c43624fd325ee96e17 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
compare_matcher:
IDENTIFIER op expression
{
- sdb_data_t value = SDB_DATA_INIT;
- if (sdb_store_expr_eval($3, &value)) {
- sdb_object_deref(SDB_OBJ($3));
- free($1); $1 = NULL;
- sdb_fe_yyerror(&yylloc, scanner,
- YY_("syntax error, failed to evaluate expression"));
- YYABORT;
- }
- sdb_object_deref(SDB_OBJ($3));
- $$ = sdb_store_matcher_parse_cmp($1, NULL, $2, &value);
+ $$ = sdb_store_matcher_parse_cmp($1, NULL, $2, $3);
free($1); $1 = NULL;
- sdb_data_free_datum(&value);
+ sdb_object_deref(SDB_OBJ($3));
}
|
IDENTIFIER '.' IDENTIFIER op expression
{
- sdb_data_t value = SDB_DATA_INIT;
- if (sdb_store_expr_eval($5, &value)) {
- sdb_object_deref(SDB_OBJ($5));
- free($1); $1 = NULL;
- free($3); $3 = NULL;
- sdb_fe_yyerror(&yylloc, scanner,
- YY_("syntax error, failed to evaluate expression"));
- YYABORT;
- }
- sdb_object_deref(SDB_OBJ($5));
- $$ = sdb_store_matcher_parse_cmp($1, $3, $4, &value);
+ $$ = sdb_store_matcher_parse_cmp($1, $3, $4, $5);
free($1); $1 = NULL;
free($3); $3 = NULL;
- sdb_data_free_datum(&value);
+ sdb_object_deref(SDB_OBJ($5));
}
|
IDENTIFIER '.' IDENTIFIER IS NULL_T
index 1b4e7383bda1b77de607fea9e9d400e05e5ec578..574b01ed262adcfd88d2a6be63afdff7285300a9 100644 (file)
--- a/src/include/core/store.h
+++ b/src/include/core/store.h
/*
* sdb_store_attr_cond:
* Creates a conditional based on attribute values. The value of stored
- * attributes is compared against the specified value. See sdb_data_cmp for
- * details about the comparison.
+ * attributes is compared against the value the expression evaluates to. See
+ * sdb_data_cmp for details about the comparison.
*/
sdb_store_cond_t *
-sdb_store_attr_cond(const char *name, const sdb_data_t *value);
+sdb_store_attr_cond(const char *name, sdb_store_expr_t *expr);
/*
* Store matchers may be used to lookup hosts from the store based on their
/*
* sdb_store_matcher_parse_cmp:
- * Parse a simple compare expression (<obj_type>.<attr> <op> <value>).
+ * Parse a simple compare expression (<obj_type>.<attr> <op> <expression>).
*
* Returns:
* - a matcher object on success
*/
sdb_store_matcher_t *
sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr,
- const char *op, const sdb_data_t *value);
+ const char *op, sdb_store_expr_t *expr);
/*
* sdb_store_dis_matcher:
index 43bb1e53d7746bcc4689895be686f5eeacd04aff..27c03d7b71dcffd6ee3afe1249985de3893bf348 100644 (file)
"sdb_store_get_host(a) = NULL; expected: <host>");
for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
+ sdb_store_expr_t *expr;
sdb_store_cond_t *c;
char buf[1024];
size_t j;
sdb_data_format(&golden_data[i].value,
buf, sizeof(buf), SDB_UNQUOTED);
- c = sdb_store_attr_cond(golden_data[i].attr,
- &golden_data[i].value);
+ expr = sdb_store_expr_constvalue(&golden_data[i].value);
+ fail_unless(expr != NULL,
+ "sdb_store_expr_constvalue(%s) = NULL; expected: <expr>",
+ buf);
+
+ c = sdb_store_attr_cond(golden_data[i].attr, expr);
+ sdb_object_deref(SDB_OBJ(expr));
fail_unless(c != NULL,
- "sdb_store_attr_cond(%s, %s) = NULL; expected: <cond>",
+ "sdb_store_attr_cond(%s, expr{%s}) = NULL; expected: <cond>",
golden_data[i].attr, buf);
for (j = 0; j < SDB_STATIC_ARRAY_LEN(tests); ++j) {
};
for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
+ sdb_store_expr_t *expr;
char buf[1024];
- check = sdb_store_matcher_parse_cmp(golden_data[i].obj_type,
- golden_data[i].attr, golden_data[i].op,
- golden_data[i].value);
-
if (sdb_data_format(golden_data[i].value,
buf, sizeof(buf), SDB_UNQUOTED) < 0)
snprintf(buf, sizeof(buf), "ERR");
+ expr = sdb_store_expr_constvalue(golden_data[i].value);
+ fail_unless(expr != NULL || golden_data[i].value == NULL,
+ "sdb_store_expr_constvalue(%s) = NULL; expected: <expr>",
+ buf);
+
+ check = sdb_store_matcher_parse_cmp(golden_data[i].obj_type,
+ golden_data[i].attr, golden_data[i].op, expr);
+ sdb_object_deref(SDB_OBJ(expr));
+
if (golden_data[i].expected == -1) {
fail_unless(check == NULL,
- "sdb_store_matcher_parse_cmp(%s, %s, %s, %s) = %p; "
+ "sdb_store_matcher_parse_cmp(%s, %s, %s, expr{%s}) = %p; "
"expected: NULL", golden_data[i].obj_type,
golden_data[i].attr, golden_data[i].op, buf, check);
continue;