summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4ad0a66)
raw | patch | inline | side by side (parent: 4ad0a66)
author | Sebastian Harl <sh@tokkee.org> | |
Sun, 9 Nov 2014 13:49:20 +0000 (14:49 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sun, 9 Nov 2014 13:49:20 +0000 (14:49 +0100) |
That is, all operators are supported now.
src/core/store-private.h | patch | blob | history | |
src/core/store_lookup.c | patch | blob | history | |
src/frontend/analyzer.c | patch | blob | history |
index 953a8826c741abbb21e0b8b3e9871922da3e00d8..d2ea3f9a08c9f443584a4d021df97e02d1638111 100644 (file)
--- a/src/core/store-private.h
+++ b/src/core/store-private.h
MATCHER_NOT,
MATCHER_ANY,
MATCHER_ALL,
+ MATCHER_IN,
+
+ /* unary operators */
+ MATCHER_ISNULL,
+ MATCHER_ISNNULL,
+
+ /* ary operators */
MATCHER_LT,
MATCHER_LE,
MATCHER_EQ,
MATCHER_NE,
MATCHER_GE,
MATCHER_GT,
- MATCHER_IN,
MATCHER_REGEX,
MATCHER_NREGEX,
- MATCHER_ISNULL,
- MATCHER_ISNNULL,
};
#define MATCHER_SYM(t) \
: ((t) == MATCHER_NOT) ? "NOT" \
: ((t) == MATCHER_ANY) ? "ANY" \
: ((t) == MATCHER_ALL) ? "ALL" \
+ : ((t) == MATCHER_IN) ? "IN" \
+ : ((t) == MATCHER_ISNULL) ? "IS NULL" \
+ : ((t) == MATCHER_ISNNULL) ? "IS NOT NULL" \
: ((t) == MATCHER_LT) ? "<" \
: ((t) == MATCHER_LE) ? "<=" \
: ((t) == MATCHER_EQ) ? "=" \
: ((t) == MATCHER_NE) ? "!=" \
: ((t) == MATCHER_GE) ? ">=" \
: ((t) == MATCHER_GT) ? ">" \
- : ((t) == MATCHER_IN) ? "IN" \
: ((t) == MATCHER_REGEX) ? "=~" \
: ((t) == MATCHER_NREGEX) ? "!~" \
- : ((t) == MATCHER_ISNULL) ? "IS NULL" \
- : ((t) == MATCHER_ISNNULL) ? "IS NOT NULL" \
: "UNKNOWN")
/* matcher base type */
index eab37b4787bb2ba7e752ab6c06eb4b8bc019a7ea..e5dad19a960b2c18bebd8172452a58ac41bcb8fd 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
* is enabled, compare the string values in case of a type mismatch.
*/
static int
-cmp_value(int op, sdb_data_t *v1, sdb_data_t *v2, _Bool strcmp_fallback)
+match_cmp_value(int op, sdb_data_t *v1, sdb_data_t *v2, _Bool strcmp_fallback)
{
int status;
else if (op == MATCHER_GT)
return status > 0;
return 0;
-} /* cmp_value */
+} /* match_cmp_value */
+
+static int
+match_regex_value(int op, sdb_data_t *v, sdb_data_t *re)
+{
+ char value[sdb_data_strlen(v) + 1];
+ int status = 0;
+
+ assert((op == MATCHER_REGEX)
+ || (op == MATCHER_NREGEX));
+
+ if (sdb_data_isnull(v) || sdb_data_isnull(re))
+ return 0;
+
+ if (re->type == SDB_TYPE_STRING) {
+ sdb_data_t tmp = SDB_DATA_INIT;
+
+ if (sdb_data_parse(re->data.string, SDB_TYPE_REGEX, &tmp))
+ return 0;
+
+ sdb_data_free_datum(re);
+ *re = tmp;
+ }
+ else if (re->type != SDB_TYPE_REGEX)
+ return 0;
+
+ if (sdb_data_format(v, value, sizeof(value), SDB_UNQUOTED) < 0)
+ status = 0;
+ else if (! regexec(&re->data.re.regex, value, 0, NULL, 0))
+ status = 1;
+
+ if (op == MATCHER_NREGEX)
+ return !status;
+ return status;
+} /* match_regex_value */
+
+static int
+match_value(int op, sdb_data_t *v1, sdb_data_t *v2, _Bool strcmp_fallback)
+{
+ if ((op == MATCHER_REGEX) || (op == MATCHER_NREGEX))
+ return match_regex_value(op, v1, v2);
+ return match_cmp_value(op, v1, v2, strcmp_fallback);
+} /* match_value */
static int
match_logical(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
int status;
- /* TODO: fully support arbitrary operators (?) */
- if ((ITER_M(m)->m->type < MATCHER_LT) || (MATCHER_GT < ITER_M(m)->m->type))
+ if ((ITER_M(m)->m->type < MATCHER_LT)
+ || (MATCHER_NREGEX < ITER_M(m)->m->type))
return 0;
e1 = CMP_M(ITER_M(m)->m)->left;
break;
}
- if (cmp_value(ITER_M(m)->m->type, &v, &v2,
+ if (match_value(ITER_M(m)->m->type, &v, &v2,
(e1->data_type) < 0 || (e2->data_type < 0))) {
if (! all) {
status = 1;
return 0;
}
- status = cmp_value(m->type, &v1, &v2,
+ status = match_cmp_value(m->type, &v1, &v2,
(e1->data_type) < 0 || (e2->data_type < 0));
sdb_data_free_datum(&v1);
match_regex(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
{
- sdb_data_t v = SDB_DATA_INIT;
+ sdb_data_t regex = SDB_DATA_INIT, v = SDB_DATA_INIT;
int status = 0;
- regex_t regex;
- _Bool free_regex = 0;
-
assert((m->type == MATCHER_REGEX)
|| (m->type == MATCHER_NREGEX));
- if (! CMP_M(m)->right->type) {
- assert(CMP_M(m)->right->data.type == SDB_TYPE_REGEX);
- regex = CMP_M(m)->right->data.data.re.regex;
- }
- else {
- sdb_data_t tmp = SDB_DATA_INIT;
- char *raw;
-
- if (sdb_store_expr_eval(CMP_M(m)->right, obj, &tmp, filter))
- return 0;
-
- if (tmp.type != SDB_TYPE_STRING) {
- sdb_data_free_datum(&tmp);
- return 0;
- }
-
- raw = tmp.data.string;
- if (sdb_data_parse(raw, SDB_TYPE_REGEX, &tmp)) {
- free(raw);
- return 0;
- }
-
- regex = tmp.data.re.regex;
- free_regex = 1;
- free(tmp.data.re.raw);
- free(raw);
+ if (sdb_store_expr_eval(CMP_M(m)->left, obj, &v, filter))
+ return 0;
+ else if (! CMP_M(m)->right->type)
+ regex = CMP_M(m)->right->data;
+ else if (sdb_store_expr_eval(CMP_M(m)->right, obj, ®ex, filter)) {
+ sdb_data_free_datum(&v);
+ return 0;
}
- if ((sdb_store_expr_eval(CMP_M(m)->left, obj, &v, filter))
- || (sdb_data_isnull(&v)))
- status = INT_MAX;
- else {
- char value[sdb_data_strlen(&v) + 1];
- if (sdb_data_format(&v, value, sizeof(value), SDB_UNQUOTED) < 0)
- status = 0;
- else if (! regexec(®ex, value, 0, NULL, 0))
- status = 1;
- }
+ status = match_regex_value(m->type, &v, ®ex);
- if (free_regex)
- regfree(®ex);
sdb_data_free_datum(&v);
- if (status == INT_MAX)
- return 0;
- if (m->type == MATCHER_NREGEX)
- return !status;
+ if (CMP_M(m)->right->type)
+ sdb_data_free_datum(®ex);
return status;
} /* match_regex */
match_unary,
match_iter,
match_iter,
+ match_in,
+
+ /* unary operators */
+ match_isnull,
+ match_isnull,
+
+ /* ary operators */
match_cmp,
match_cmp,
match_cmp,
match_cmp,
match_cmp,
match_cmp,
- match_in,
match_regex,
match_regex,
- match_isnull,
- match_isnull,
};
/*
index 20864cae4d348ca2e3072e1e48945fd157cb6c66..c1b9d01ef19494188dddd2d3dd916601715e924a 100644 (file)
--- a/src/frontend/analyzer.c
+++ b/src/frontend/analyzer.c
&& (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_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,