From: Sebastian Harl Date: Fri, 17 Oct 2014 22:42:43 +0000 (+0200) Subject: frontend/grammar: Use strings to access attribute value: attribute['name']. X-Git-Tag: sysdb-0.6.0~104 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=8d70fa00dd40edc9ecfc26d2d71994a392eea80b;p=sysdb.git frontend/grammar: Use strings to access attribute value: attribute['name']. --- diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index 24a1375..30414d2 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -450,7 +450,7 @@ compare_matcher: sdb_object_deref(SDB_OBJ($3)); } | - IDENTIFIER '[' IDENTIFIER ']' cmp expression + IDENTIFIER '[' STRING ']' cmp expression { $$ = sdb_store_matcher_parse_cmp($1, $3, $5, $6); free($1); $1 = NULL; @@ -458,7 +458,7 @@ compare_matcher: sdb_object_deref(SDB_OBJ($6)); } | - IDENTIFIER '[' IDENTIFIER ']' IS NULL_T + IDENTIFIER '[' STRING ']' IS NULL_T { sdb_store_expr_t *expr; @@ -479,7 +479,7 @@ compare_matcher: free($3); $3 = NULL; } | - IDENTIFIER '[' IDENTIFIER ']' IS NOT NULL_T + IDENTIFIER '[' STRING ']' IS NOT NULL_T { sdb_store_expr_t *expr; @@ -556,7 +556,7 @@ expression: $$ = sdb_store_expr_fieldvalue(field); } | - IDENTIFIER '[' IDENTIFIER ']' + IDENTIFIER '[' STRING ']' { $$ = sdb_store_expr_attrvalue($3); free($1); $1 = NULL; diff --git a/t/integration/matching.sh b/t/integration/matching.sh index d42044b..67b9721 100755 --- a/t/integration/matching.sh +++ b/t/integration/matching.sh @@ -67,7 +67,7 @@ echo "$output" | grep -F 'localhost' && exit 1 echo "$output" | grep -F 'other.host.name' && exit 1 output="$( run_sysdb -H "$SOCKET_FILE" \ - -c "LOOKUP hosts MATCHING attribute[architecture] = 'x42'" )" + -c "LOOKUP hosts MATCHING attribute['architecture'] = 'x42'" )" echo "$output" \ | grep -F '"host1.example.com"' \ | grep -F '"host2.example.com"' @@ -103,7 +103,7 @@ echo "$output" | grep -F 'localhost' && exit 1 # When querying hosts that don't exist, expect a zero exit code. output="$( run_sysdb -H "$SOCKET_FILE" \ - -c "LOOKUP hosts MATCHING attribute[invalid] = 'none'" )" + -c "LOOKUP hosts MATCHING attribute['invalid'] = 'none'" )" echo $output | grep -E '^\[\]$' stop_sysdbd diff --git a/t/unit/core/store_lookup_test.c b/t/unit/core/store_lookup_test.c index 2e1e6d8..1739296 100644 --- a/t/unit/core/store_lookup_test.c +++ b/t/unit/core/store_lookup_test.c @@ -783,80 +783,80 @@ START_TEST(test_scan) int expected; const char *tostring_re; } golden_data[] = { - { "host = 'a'", NULL, 1, + { "host = 'a'", NULL, 1, "OBJ\\[host\\]\\{ NAME\\{ 'a', \\(nil\\) \\} \\}" }, - { "host = 'a'", "host = 'x'", 0, /* filter never matches */ + { "host = 'a'", "host = 'x'", 0, /* filter never matches */ "OBJ\\[host\\]\\{ NAME\\{ 'a', \\(nil\\) \\} \\}" }, { "host = 'a'", - "NOT attribute[x] = ''", 1, /* filter always matches */ + "NOT attribute['x'] = ''", 1, /* filter always matches */ "OBJ\\[host\\]\\{ NAME\\{ 'a', \\(nil\\) \\} \\}" }, - { "host =~ 'a|b'", NULL, 2, + { "host =~ 'a|b'", NULL, 2, "OBJ\\[host\\]\\{ NAME\\{ NULL, "PTR_RE" \\} \\}" }, - { "host =~ 'host'", NULL, 0, + { "host =~ 'host'", NULL, 0, "OBJ\\[host\\]\\{ NAME\\{ NULL, "PTR_RE" \\} \\}" }, - { "host =~ '.'", NULL, 3, + { "host =~ '.'", NULL, 3, "OBJ\\[host\\]\\{ NAME\\{ NULL, "PTR_RE" \\} \\}" }, - { "metric = 'm1'", NULL, 2, + { "metric = 'm1'", NULL, 2, "OBJ\\[metric\\]\\{ NAME\\{ 'm1', \\(nil\\) } \\}" }, - { "metric= 'm1'", "host = 'x'", 0, /* filter never matches */ + { "metric= 'm1'", "host = 'x'", 0, /* filter never matches */ "OBJ\\[metric\\]\\{ NAME\\{ 'm1', \\(nil\\) } \\}" }, { "metric = 'm1'", - "NOT attribute[x] = ''", 2, /* filter always matches */ + "NOT attribute['x'] = ''", 2, /* filter always matches */ "OBJ\\[metric\\]\\{ NAME\\{ 'm1', \\(nil\\) } \\}" }, - { "metric =~ 'm'", NULL, 2, + { "metric =~ 'm'", NULL, 2, "OBJ\\[metric\\]\\{ NAME\\{ NULL, "PTR_RE" } \\}" }, - { "metric !~ 'm'", NULL, 1, + { "metric !~ 'm'", NULL, 1, "\\(NOT, OBJ\\[metric\\]\\{ NAME\\{ NULL, "PTR_RE" } \\}\\)" }, - { "metric =~ 'x'", NULL, 0, + { "metric =~ 'x'", NULL, 0, "OBJ\\[metric\\]\\{ NAME\\{ NULL, "PTR_RE" } \\}" }, - { "service = 's1'", NULL, 2, + { "service = 's1'", NULL, 2, "OBJ\\[service\\]\\{ NAME\\{ 's1', \\(nil\\) } \\}" }, - { "service = 's1'", "host = 'x'", 0, /* filter never matches */ + { "service = 's1'", "host = 'x'", 0, /* filter never matches */ "OBJ\\[service\\]\\{ NAME\\{ 's1', \\(nil\\) } \\}" }, { "service = 's1'", - "NOT attribute[x] = ''", 2, /* filter always matches */ + "NOT attribute['x'] = ''", 2, /* filter always matches */ "OBJ\\[service\\]\\{ NAME\\{ 's1', \\(nil\\) } \\}" }, - { "service =~ 's'", NULL, 2, + { "service =~ 's'", NULL, 2, "OBJ\\[service\\]\\{ NAME\\{ NULL, "PTR_RE" } \\}" }, - { "service !~ 's'", NULL, 1, + { "service !~ 's'", NULL, 1, "\\(NOT, OBJ\\[service\\]\\{ NAME\\{ NULL, "PTR_RE" } \\}\\)" }, - { "attribute = 'k1'", NULL, 1, + { "attribute = 'k1'", NULL, 1, "OBJ\\[attribute\\]\\{ NAME\\{ 'k1', \\(nil\\) \\} " }, - { "attribute = 'k1'", "host = 'x'", 0, /* filter never matches */ + { "attribute = 'k1'", "host = 'x'", 0, /* filter never matches */ "OBJ\\[attribute\\]\\{ NAME\\{ 'k1', \\(nil\\) \\} " }, { "attribute = 'k1'", - "NOT attribute[x] = ''", 1, /* filter always matches */ + "NOT attribute['x'] = ''", 1, /* filter always matches */ "OBJ\\[attribute\\]\\{ NAME\\{ 'k1', \\(nil\\) \\} " }, - { "attribute = 'x'", NULL, 0, + { "attribute = 'x'", NULL, 0, "OBJ\\[attribute\\]\\{ NAME\\{ 'x', \\(nil\\) \\}" }, - { "attribute[k1] = 'v1'", NULL, 1, + { "attribute['k1'] = 'v1'", NULL, 1, "ATTR\\[k1\\]\\{ VALUE\\{ 'v1', \\(nil\\) \\} \\}" }, - { "attribute[k1] IS NULL", NULL, 2, + { "attribute['k1'] IS NULL", NULL, 2, "\\(IS NULL\\)" }, - { "attribute[x1] IS NULL", NULL, 3, + { "attribute['x1'] IS NULL", NULL, 3, "\\(IS NULL\\)" }, - { "attribute[k1] IS NOT NULL", NULL, 1, + { "attribute['k1'] IS NOT NULL", NULL, 1, "\\(IS NOT NULL\\)" }, - { "attribute[x1] IS NOT NULL", NULL, 0, + { "attribute['x1'] IS NOT NULL", NULL, 0, "\\(IS NOT NULL\\)" }, - { "attribute[k2] < 123", NULL, 0, + { "attribute['k2'] < 123", NULL, 0, "ATTR\\[k2\\]\\{ < 123 \\}" }, - { "attribute[k2] <= 123", NULL, 1, + { "attribute['k2'] <= 123", NULL, 1, "ATTR\\[k2\\]\\{ <= 123 \\}" }, - { "attribute[k2] >= 123", NULL, 1, + { "attribute['k2'] >= 123", NULL, 1, "ATTR\\[k2\\]\\{ >= 123 \\}" }, - { "attribute[k2] > 123", NULL, 0, + { "attribute['k2'] > 123", NULL, 0, "ATTR\\[k2\\]\\{ > 123 \\}" }, - { "attribute[k2] = 123", NULL, 1, + { "attribute['k2'] = 123", NULL, 1, "ATTR\\[k2\\]\\{ = 123 \\}" }, - { "attribute[k2] != 123", NULL, 2, + { "attribute['k2'] != 123", NULL, 2, "\\(NOT, ATTR\\[k2\\]\\{ = 123 \\}\\)" }, - { "attribute[k1] != 'v1'", NULL, 2, + { "attribute['k1'] != 'v1'", NULL, 2, "\\(NOT, ATTR\\[k1\\]\\{ VALUE\\{ 'v1', \\(nil\\) \\} \\}\\)" }, - { "attribute[k1] != 'v2'", NULL, 3, + { "attribute['k1'] != 'v2'", NULL, 3, "\\(NOT, ATTR\\[k1\\]\\{ VALUE\\{ 'v2', \\(nil\\) \\} \\}\\)" }, { "attribute != 'x' " - "AND attribute[y] !~ 'x'", NULL, 3, + "AND attribute['y'] !~ 'x'", NULL, 3, "\\(AND, " "\\(NOT, OBJ\\[attribute\\]\\{ NAME\\{ 'x', \\(nil\\) \\} \\}\\), " "\\(NOT, ATTR\\[y\\]\\{ VALUE\\{ NULL, "PTR_RE" \\} \\}\\)\\)" }, diff --git a/t/unit/frontend/parser_test.c b/t/unit/frontend/parser_test.c index 7839ee8..8898e8b 100644 --- a/t/unit/frontend/parser_test.c +++ b/t/unit/frontend/parser_test.c @@ -130,61 +130,61 @@ START_TEST(test_parse) /* numeric constants */ { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "1234", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] != " + "attribute['foo'] != " "+234", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] < " + "attribute['foo'] < " "-234", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] > " + "attribute['foo'] > " "12.4", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] <= " + "attribute['foo'] <= " "12. + .3", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] <= " + "attribute['foo'] <= " "'f' || 'oo'", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] >= " + "attribute['foo'] >= " ".4", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "+12e3", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "+12e-3", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "-12e+3", -1, 1, CONNECTION_LOOKUP }, /* date, time, interval constants */ { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "1 Y 42D", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "1s 42D", -1, 1, CONNECTION_LOOKUP }, /* * TODO: Something like 1Y42D should work as well but it doesn't since * the scanner will tokenize it into {digit}{identifier} :-/ * { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "1Y42D", -1, 1, CONNECTION_LOOKUP }, */ /* NULL */ { "LOOKUP hosts MATCHING " - "attribute[foo] " + "attribute['foo'] " "IS NULL", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "attribute[foo] " + "attribute['foo'] " "IS NOT NULL", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " - "NOT attribute[foo] " + "NOT attribute['foo'] " "IS NULL", -1, 1, CONNECTION_LOOKUP }, { "LOOKUP hosts MATCHING " "host IS NULL", -1, -1, 0 }, @@ -193,25 +193,25 @@ START_TEST(test_parse) /* invalid numeric constants */ { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "+-12e+3", -1, -1, 0 }, { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "-12e-+3", -1, -1, 0 }, { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "e+3", -1, -1, 0 }, { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "3e", -1, -1, 0 }, /* following SQL standard, we don't support hex numbers */ { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "0x12", -1, -1, 0 }, /* invalid expressions */ { "LOOKUP hosts MATCHING " - "attribute[foo] = " + "attribute['foo'] = " "1.23 + 'foo'", -1, -1, 0 }, /* comments */ @@ -246,10 +246,10 @@ START_TEST(test_parse) "host = 'host' FILTER " "host = 'host'", -1, -1, 0 }, { "LOOKUP hosts MATCHING " - "attribute[foo] <= " + "attribute['foo'] <= " "f || 'oo'", -1, -1, 0 }, { "LOOKUP hosts MATCHING " - "attribute[foo] <= " + "attribute['foo'] <= " "'f' || oo", -1, -1, 0 }, }; @@ -298,96 +298,96 @@ START_TEST(test_parse_matcher) int expected; } golden_data[] = { /* empty expressions */ - { NULL, -1, -1 }, - { "", -1, -1 }, + { NULL, -1, -1 }, + { "", -1, -1 }, /* valid expressions */ - { "host = 'localhost'", -1, MATCHER_NAME }, - { "host != 'localhost'", -1, MATCHER_NOT }, - { "host =~ 'host'", -1, MATCHER_NAME }, - { "host !~ 'host'", -1, MATCHER_NOT }, - { "host = 'localhost' -- foo", -1, MATCHER_NAME }, - { "host = 'host' ", 13, MATCHER_NAME }, + { "host = 'localhost'", -1, MATCHER_NAME }, + { "host != 'localhost'", -1, MATCHER_NOT }, + { "host =~ 'host'", -1, MATCHER_NAME }, + { "host !~ 'host'", -1, MATCHER_NOT }, + { "host = 'localhost' -- foo", -1, MATCHER_NAME }, + { "host = 'host' ", 13, MATCHER_NAME }, /* match hosts by service */ - { "service = 'name'", -1, MATCHER_NAME }, - { "service != 'name'", -1, MATCHER_NOT }, - { "service =~ 'pattern'", -1, MATCHER_NAME }, - { "service !~ 'pattern'", -1, MATCHER_NOT }, + { "service = 'name'", -1, MATCHER_NAME }, + { "service != 'name'", -1, MATCHER_NOT }, + { "service =~ 'pattern'", -1, MATCHER_NAME }, + { "service !~ 'pattern'", -1, MATCHER_NOT }, /* match hosts by attribute */ - { "attribute = 'name'", -1, MATCHER_NAME }, - { "attribute != 'name'", -1, MATCHER_NOT }, - { "attribute =~ 'pattern'", -1, MATCHER_NAME }, - { "attribute !~ 'pattern'", -1, MATCHER_NOT }, + { "attribute = 'name'", -1, MATCHER_NAME }, + { "attribute != 'name'", -1, MATCHER_NOT }, + { "attribute =~ 'pattern'", -1, MATCHER_NAME }, + { "attribute !~ 'pattern'", -1, MATCHER_NOT }, /* composite expressions */ { "host =~ 'pattern' AND " - "service =~ 'pattern'", -1, MATCHER_AND }, + "service =~ 'pattern'", -1, MATCHER_AND }, { "host =~ 'pattern' OR " - "service =~ 'pattern'", -1, MATCHER_OR }, - { "NOT host = 'host'", -1, MATCHER_NOT }, + "service =~ 'pattern'", -1, MATCHER_OR }, + { "NOT host = 'host'", -1, MATCHER_NOT }, /* numeric expressions */ - { "attribute[foo] < 123", -1, MATCHER_LT }, - { "attribute[foo] <= 123", -1, MATCHER_LE }, - { "attribute[foo] = 123", -1, MATCHER_EQ }, - { "attribute[foo] >= 123", -1, MATCHER_GE }, - { "attribute[foo] > 123", -1, MATCHER_GT }, + { "attribute['foo'] < 123", -1, MATCHER_LT }, + { "attribute['foo'] <= 123", -1, MATCHER_LE }, + { "attribute['foo'] = 123", -1, MATCHER_EQ }, + { "attribute['foo'] >= 123", -1, MATCHER_GE }, + { "attribute['foo'] > 123", -1, MATCHER_GT }, /* datetime expressions */ - { "attribute[foo] = " - "2014-08-16", -1, MATCHER_EQ }, - { "attribute[foo] = " - "17:23", -1, MATCHER_EQ }, - { "attribute[foo] = " - "17:23:53", -1, MATCHER_EQ }, - { "attribute[foo] = " - "17:23:53.123", -1, MATCHER_EQ }, - { "attribute[foo] = " - "17:23:53.123456789", -1, MATCHER_EQ }, - { "attribute[foo] = " - "2014-08-16 17:23", -1, MATCHER_EQ }, - { "attribute[foo] = " - "2014-08-16 17:23:53", -1, MATCHER_EQ }, + { "attribute['foo'] = " + "2014-08-16", -1, MATCHER_EQ }, + { "attribute['foo'] = " + "17:23", -1, MATCHER_EQ }, + { "attribute['foo'] = " + "17:23:53", -1, MATCHER_EQ }, + { "attribute['foo'] = " + "17:23:53.123", -1, MATCHER_EQ }, + { "attribute['foo'] = " + "17:23:53.123456789", -1, MATCHER_EQ }, + { "attribute['foo'] = " + "2014-08-16 17:23", -1, MATCHER_EQ }, + { "attribute['foo'] = " + "2014-08-16 17:23:53", -1, MATCHER_EQ }, /* NULL; while this is an implementation detail, * IS NULL currently maps to an equality matcher */ - { "attribute[foo] IS NULL", -1, MATCHER_ISNULL }, - { "attribute[foo] IS NOT NULL", -1, MATCHER_ISNNULL }, + { "attribute['foo'] IS NULL", -1, MATCHER_ISNULL }, + { "attribute['foo'] IS NOT NULL", -1, MATCHER_ISNNULL }, /* object field matchers */ - { ".last_update < 10s", -1, MATCHER_LT }, - { ".AGE <= 1m", -1, MATCHER_LE }, - { ".interval = 10h", -1, MATCHER_EQ }, - { ".Last_Update >= 24D", -1, MATCHER_GE }, - { ".age > 1M", -1, MATCHER_GT }, - { ".age != 20Y", -1, MATCHER_NOT }, - { ".backend != 'be'", -1, MATCHER_NOT }, - { ".age <= 2 * .interval", -1, MATCHER_LE }, + { ".last_update < 10s", -1, MATCHER_LT }, + { ".AGE <= 1m", -1, MATCHER_LE }, + { ".interval = 10h", -1, MATCHER_EQ }, + { ".Last_Update >= 24D", -1, MATCHER_GE }, + { ".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 " "service = 'name' AND " "attribute = 'name' OR " - "attribute[foo] = 'bar'", -1, MATCHER_OR }, + "attribute['foo'] = 'bar'", -1, MATCHER_OR }, { "host = 'name' AND " "service = 'name' AND " "attribute = 'name' OR " - "attribute[foo] = 'bar'", -1, MATCHER_OR }, + "attribute['foo'] = 'bar'", -1, MATCHER_OR }, { "host = 'name' AND " "service = 'name' OR " "attribute = 'name' AND " - "attribute[foo] = 'bar'", -1, MATCHER_OR }, + "attribute['foo'] = 'bar'", -1, MATCHER_OR }, { "(host = 'name' OR " "service = 'name') AND " "(attribute = 'name' OR " - "attribute[foo] = 'bar')", -1, MATCHER_AND }, + "attribute['foo'] = 'bar')", -1, MATCHER_AND }, { "NOT host = 'name' OR " - "service = 'name'", -1, MATCHER_OR }, + "service = 'name'", -1, MATCHER_OR }, { "NOT host = 'name' OR " - "NOT service = 'name'", -1, MATCHER_OR }, + "NOT service = 'name'", -1, MATCHER_OR }, { "NOT (host = 'name' OR " - "NOT service = 'name')", -1, MATCHER_NOT }, + "NOT service = 'name')", -1, MATCHER_NOT }, /* syntax errors */ - { "LIST", -1, -1 }, - { "foo &^ bar", -1, -1 }, - { ".invalid", -1, -1 }, + { "LIST", -1, -1 }, + { "foo &^ bar", -1, -1 }, + { ".invalid", -1, -1 }, }; size_t i; @@ -455,7 +455,7 @@ START_TEST(test_parse_expr) { ".backend", -1, FIELD_VALUE }, /* attributes */ - { "attribute[foo]", -1, ATTR_VALUE }, + { "attribute['foo']", -1, ATTR_VALUE }, /* arithmetic expressions */ { ".age + .age", -1, SDB_DATA_ADD },