From 1ef0d00327e4b5f56b438f44053f48fd8b198baa Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 20 May 2015 10:35:29 +0200 Subject: [PATCH 1/1] parser: Add support for metric timeseries fields. --- src/parser/analyzer.c | 7 ++++++- src/parser/grammar.y | 2 ++ t/unit/core/store_lookup_test.c | 3 +++ t/unit/parser/parser_test.c | 34 ++++++++++++++++++++++++++++++--- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/parser/analyzer.c b/src/parser/analyzer.c index 28d3121..dea83d7 100644 --- a/src/parser/analyzer.c +++ b/src/parser/analyzer.c @@ -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 */ diff --git a/src/parser/grammar.y b/src/parser/grammar.y index 339f17a..1b6d208 100644 --- a/src/parser/grammar.y +++ b/src/parser/grammar.y @@ -634,6 +634,8 @@ field: BACKEND_T { $$ = SDB_FIELD_BACKEND; } | VALUE_T { $$ = SDB_FIELD_VALUE; } + | + TIMESERIES { $$ = SDB_FIELD_TIMESERIES; } ; cmp: diff --git a/t/unit/core/store_lookup_test.c b/t/unit/core/store_lookup_test.c index 33c9268..33fd1d2 100644 --- a/t/unit/core/store_lookup_test.c +++ b/t/unit/core/store_lookup_test.c @@ -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 }, diff --git a/t/unit/parser/parser_test.c b/t/unit/parser/parser_test.c index 4dcf684..3d2e40c 100644 --- a/t/unit/parser/parser_test.c +++ b/t/unit/parser/parser_test.c @@ -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 }, -- 2.30.2