Code

parser: Add support for metric timeseries fields.
authorSebastian Harl <sh@tokkee.org>
Wed, 20 May 2015 08:35:29 +0000 (10:35 +0200)
committerSebastian Harl <sh@tokkee.org>
Wed, 20 May 2015 08:35:29 +0000 (10:35 +0200)
src/parser/analyzer.c
src/parser/grammar.y
t/unit/core/store_lookup_test.c
t/unit/parser/parser_test.c

index 28d3121..dea83d7 100644 (file)
@@ -320,7 +320,7 @@ analyze_value(int context, sdb_ast_value_t *v, sdb_strbuf_t *errbuf)
        }
 
        if (context != UNSPEC_CONTEXT) {
-               /* skip this check if we don't know the context; it's up to the
+               /* skip these checks if we don't know the context; it's up to the
                 * caller to check again once the right context information is
                 * available */
                if ((context != SDB_ATTRIBUTE) && (v->type == SDB_FIELD_VALUE)) {
@@ -328,6 +328,11 @@ analyze_value(int context, sdb_ast_value_t *v, sdb_strbuf_t *errbuf)
                                        SDB_FIELD_TO_NAME(context));
                        return -1;
                }
+               if ((context != SDB_METRIC) && (v->type == SDB_FIELD_TIMESERIES)) {
+                       sdb_strbuf_sprintf(errbuf, "Invalid expression %s.timeseries",
+                                       SDB_FIELD_TO_NAME(context));
+                       return -1;
+               }
        }
        return 0;
 } /* analyze_value */
index 339f17a..1b6d208 100644 (file)
@@ -634,6 +634,8 @@ field:
        BACKEND_T { $$ = SDB_FIELD_BACKEND; }
        |
        VALUE_T { $$ = SDB_FIELD_VALUE; }
+       |
+       TIMESERIES { $$ = SDB_FIELD_TIMESERIES; }
        ;
 
 cmp:
index 33c9268..33fd1d2 100644 (file)
@@ -577,6 +577,9 @@ struct {
                NULL,                              1 },
        { "host.attribute['x1'] IS NULL",
                NULL,                              3 },
+       /* not a boolean so neither TRUE nor FALSE: */
+       { "attribute['k1'] IS TRUE", NULL,     0 },
+       { "attribute['k1'] IS FALSE", NULL,    0 },
        { "attribute['k1'] = 'v1'", NULL,      1 },
        { "attribute['k1'] = 'v1'",
                "name != 'k1'",                    0 },
index 4dcf684..3d2e40c 100644 (file)
@@ -402,6 +402,8 @@ struct {
        { "LOOKUP hosts MATCHING "
          "NOT attribute['foo'] "
          "IS FALSE",            -1,  1, SDB_AST_TYPE_LOOKUP, SDB_HOST },
+       { "LOOKUP metrics MATCHING "
+         "timeseries IS TRUE",  -1,  1, SDB_AST_TYPE_LOOKUP, SDB_METRIC },
 
        /* invalid numeric constants */
        { "LOOKUP hosts MATCHING "
@@ -457,6 +459,10 @@ struct {
          "value = 'a'",           -1, -1, 0, 0 },
        { "LIST metrics FILTER "
          "name.1 = 'a'",          -1, -1, 0, 0 },
+       { "LIST hosts FILTER "
+         "timeseries IS TRUE",    -1, -1, 0, 0 },
+       { "LIST services FILTER "
+         "timeseries IS TRUE",    -1, -1, 0, 0 },
 
        /* type mismatches */
        { "LOOKUP hosts MATCHING "
@@ -831,12 +837,13 @@ struct {
        { "ALL attribute.name !~ 'pattern'",   -1,  SDB_AST_ALL },
        { "ALL attribute.name &^ 'pattern'",   -1,  -1 },
        { "ANY attribute !~ 'pattern'",        -1,  -1 },
+
        /* composite expressions */
        { "name =~ 'pattern' AND "
-         "ANY service.name =~ 'pattern'",     -1,  SDB_AST_AND },
+         "ANY service.name =~ 'pattern'",  -1,  SDB_AST_AND },
        { "name =~ 'pattern' OR "
-         "ANY service.name =~ 'pattern'",     -1,  SDB_AST_OR },
-       { "NOT name = 'host'",                 -1,  SDB_AST_NOT },
+         "ANY service.name =~ 'pattern'",  -1,  SDB_AST_OR },
+       { "NOT name = 'host'",              -1,  SDB_AST_NOT },
        /* numeric expressions */
        { "attribute['foo'] < 123",         -1,  SDB_AST_LT },
        { "attribute['foo'] <= 123",        -1,  SDB_AST_LE },
@@ -908,6 +915,13 @@ struct {
        { "'be' NOT IN backend",            -1,  SDB_AST_NOT },
        { "['a','b'] IN backend",           -1,  SDB_AST_IN },
        { "['a','b'] NOT IN backend",       -1,  SDB_AST_NOT },
+       { "timeseries IS TRUE",             -1,  SDB_AST_ISTRUE },
+       { "timeseries IS FALSE",            -1,  SDB_AST_ISFALSE },
+       { "timeseries IS NOT TRUE",         -1,  SDB_AST_NOT },
+       { "timeseries IS NOT FALSE",        -1,  SDB_AST_NOT },
+       { "timeseries > 0",                 -1,  -1 },
+       { "timeseries = TRUE",              -1,  -1 },
+       { "timeseries != FALSE",            -1,  -1 },
 
        /* check operator precedence */
        { "name = 'name' OR "
@@ -1038,6 +1052,20 @@ struct {
        { "(age + age) * age",    -1, SDB_AST_MUL, SDB_TYPE_DATETIME },
        { "age + (age * age)",    -1, SDB_AST_ADD, SDB_TYPE_DATETIME },
 
+       /* boolean expressions */
+       { "timeseries + 1",               -1, -1, -1 },
+       { "timeseries - 1",               -1, -1, -1 },
+       { "timeseries * 1",               -1, -1, -1 },
+       { "timeseries / 1",               -1, -1, -1 },
+       { "timeseries \% 1",              -1, -1, -1 },
+       { "timeseries CONCAT 1",          -1, -1, -1 },
+       { "timeseries + timeseries",      -1, -1, -1 },
+       { "timeseries - timeseries",      -1, -1, -1 },
+       { "timeseries * timeseries",      -1, -1, -1 },
+       { "timeseries / timeseries",      -1, -1, -1 },
+       { "timeseries \% timeseries",     -1, -1, -1 },
+       { "timeseries CONCAT timeseries", -1, -1, -1 },
+
        /* syntax errors */
        { "LIST",                 -1, -1, -1 },
        { "foo &^ bar",           -1, -1, -1 },