Code

frontend/grammar: Added support for field names in expressions.
authorSebastian Harl <sh@tokkee.org>
Thu, 31 Jul 2014 21:38:51 +0000 (23:38 +0200)
committerSebastian Harl <sh@tokkee.org>
Thu, 31 Jul 2014 21:38:51 +0000 (23:38 +0200)
src/core/store_lookup.c
src/frontend/grammar.y
src/include/core/store.h
t/unit/frontend/parser_test.c

index 0ef5f462a4ea4e759b99a5807de4507d45d4046e..98417830f19a52bbf985905d4acfaa2464ca6b7c 100644 (file)
@@ -854,6 +854,20 @@ sdb_store_isnull_matcher(const char *attr_name)
                                MATCHER_ISNULL, attr_name));
 } /* sdb_store_isnull_matcher */
 
+int
+sdb_store_parse_field_name(const char *name)
+{
+       if (! strcasecmp(name, "last_update"))
+               return SDB_FIELD_LAST_UPDATE;
+       else if (! strcasecmp(name, "age"))
+               return SDB_FIELD_AGE;
+       else if (! strcasecmp(name, "interval"))
+               return SDB_FIELD_INTERVAL;
+       else if (! strcasecmp(name, "backend"))
+               return SDB_FIELD_BACKEND;
+       return -1;
+} /* sdb_store_parse_field_name */
+
 static sdb_store_matcher_t *
 maybe_inv_matcher(sdb_store_matcher_t *m, _Bool inv)
 {
@@ -996,20 +1010,12 @@ sdb_store_matcher_parse_field_cmp(const char *name, const char *op,
        if (! expr)
                return NULL;
 
-       if (! strcasecmp(name, "last_update"))
-               field = SDB_FIELD_LAST_UPDATE;
-       else if (! strcasecmp(name, "age"))
-               field = SDB_FIELD_AGE;
-       else if (! strcasecmp(name, "interval"))
-               field = SDB_FIELD_INTERVAL;
-       else if (! strcasecmp(name, "backend"))
-               field = SDB_FIELD_BACKEND;
-       else
+       field = sdb_store_parse_field_name(name);
+       if (field < 0)
                return NULL;
 
        if (parse_cond_op(op, &matcher, &inv))
                return NULL;
-
        cond = sdb_store_obj_cond(field, expr);
        if (! cond)
                return NULL;
index 92bfd1f5c60d2ab24d5e0b6f82b90e7e4ce73c71..08d194deeac438290b55dd570356e31d6099a449 100644 (file)
@@ -414,6 +414,13 @@ expression:
                        sdb_object_deref(SDB_OBJ($3)); $3 = NULL;
                }
        |
+       ':' IDENTIFIER
+               {
+                       int field = sdb_store_parse_field_name($2);
+                       free($2); $2 = NULL;
+                       $$ = sdb_store_expr_fieldvalue(field);
+               }
+       |
        data
                {
                        $$ = sdb_store_expr_constvalue(&$1);
index 760c23d9fa89f7151b0e33267ebcaff0e37936c1..cb7f3e4bbe545e95bf9cd4b8108dbdee52ccfceb 100644 (file)
@@ -335,6 +335,17 @@ sdb_store_ge_matcher(sdb_store_cond_t *cond);
 sdb_store_matcher_t *
 sdb_store_gt_matcher(sdb_store_cond_t *cond);
 
+/*
+ * sdb_store_parse_field_name:
+ * Parse the name of a stored object's queryable field.
+ *
+ * Returns:
+ *  - the field id on success
+ *  - a negative value else
+ */
+int
+sdb_store_parse_field_name(const char *name);
+
 /*
  * sdb_store_matcher_parse_cmp:
  * Parse a simple compare expression (<obj_type>.<attr> <op> <expression>).
index a10185469f2397accd253425025dbf9fe097c62c..dade011bd31cd2b505382df27fe57903b8f94b6f 100644 (file)
@@ -86,6 +86,10 @@ START_TEST(test_parse)
                { "LOOKUP hosts MATCHING "
                  "host =~ 'p' "
                  "FILTER NOT :age>1D",  -1,  1, CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "host =~ 'p' "
+                 "FILTER :age>"
+                 ":interval",           -1,  1, CONNECTION_LOOKUP },
 
                /* numeric constants */
                { "LOOKUP hosts MATCHING "
@@ -275,6 +279,7 @@ START_TEST(test_parse_matcher)
                { ":age > 1M",                 -1,  MATCHER_GT },
                { ":age != 20Y",               -1,  MATCHER_NOT },
                { ":backend != 'be'",          -1,  MATCHER_NOT },
+               { ":age <= 2 * :interval",     -1,  MATCHER_LE },
 
                /* check operator precedence */
                { "host = 'name' OR "