author | Sebastian Harl <sh@tokkee.org> | |
Wed, 12 Nov 2014 21:16:35 +0000 (22:16 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 12 Nov 2014 21:21:03 +0000 (22:21 +0100) |
1 | 2 | |||
---|---|---|---|---|
src/frontend/analyzer.c | patch | | diff1 | | diff2 | | blob | history |
src/frontend/grammar.y | patch | | diff1 | | diff2 | | blob | history |
t/unit/frontend/parser_test.c | patch | | diff1 | | diff2 | | blob | history |
diff --combined src/frontend/analyzer.c
index 2de9befa6eeb6605ca405fb07689f6672c86b169,6a50736be23752fe6ea96c2beaccda8815ea9c8d..701130e88d498335c13ccc133719bca5989cda4a
+++ b/src/frontend/analyzer.c
case MATCHER_GE:
case MATCHER_GT:
assert(CMP_M(m)->left && CMP_M(m)->right);
+ if ((CMP_M(m)->left->data_type > 0)
+ && (CMP_M(m)->right->data_type > 0)
+ && (CMP_M(m)->left->data_type == CMP_M(m)->right->data_type))
+ return 0;
if ((CMP_M(m)->left->data_type > 0)
&& (CMP_M(m)->left->data_type & SDB_TYPE_ARRAY)) {
cmp_error(errbuf, m->type, CMP_M(m)->left->data_type,
/* For now, this function checks basic matcher attributes only;
* later, this may be turned into one of multiple AST visitors. */
- if (node->cmd == CONNECTION_FETCH) {
+ if (node->cmd == SDB_CONNECTION_FETCH) {
conn_fetch_t *fetch = CONN_FETCH(node);
if ((fetch->type == SDB_HOST) && fetch->name) {
sdb_strbuf_sprintf(errbuf, "Unexpected STRING '%s'", fetch->name);
filter = fetch->filter->matcher;
context = fetch->type;
}
- else if (node->cmd == CONNECTION_LIST) {
+ else if (node->cmd == SDB_CONNECTION_LIST) {
if (CONN_LIST(node)->filter)
filter = CONN_LIST(node)->filter->matcher;
context = CONN_LIST(node)->type;
}
- else if (node->cmd == CONNECTION_LOOKUP) {
+ else if (node->cmd == SDB_CONNECTION_LOOKUP) {
if (CONN_LOOKUP(node)->matcher)
m = CONN_LOOKUP(node)->matcher->matcher;
if (CONN_LOOKUP(node)->filter)
filter = CONN_LOOKUP(node)->filter->matcher;
context = CONN_LOOKUP(node)->type;
}
- else if (node->cmd == CONNECTION_TIMESERIES)
+ else if (node->cmd == SDB_CONNECTION_TIMESERIES)
return 0;
else
return -1;
diff --combined src/frontend/grammar.y
index d4e54a9c4c8f3869946bfa151de5d764c1156e88,3180167fe2d98256637078338be98baf1e5368f8..2872bcf447fdeacb561aae754b9c85420a3fddc7
+++ b/src/frontend/grammar.y
%type <data> data
interval interval_elem
+ array array_elem_list
%type <datetime> datetime
start_clause end_clause
sdb_conn_node_t *n;
n = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
conn_expr_t, conn_expr_destroy));
- n->cmd = CONNECTION_EXPR;
+ n->cmd = SDB_CONNECTION_EXPR;
CONN_EXPR(n)->expr = $1;
sdb_llist_append(pt, SDB_OBJ(n));
CONN_FETCH($$)->host = $3;
CONN_FETCH($$)->name = NULL;
CONN_FETCH($$)->filter = CONN_MATCHER($4);
- $$->cmd = CONNECTION_FETCH;
+ $$->cmd = SDB_CONNECTION_FETCH;
}
|
FETCH object_type STRING '.' STRING filter_clause
CONN_FETCH($$)->host = $3;
CONN_FETCH($$)->name = $5;
CONN_FETCH($$)->filter = CONN_MATCHER($6);
- $$->cmd = CONNECTION_FETCH;
+ $$->cmd = SDB_CONNECTION_FETCH;
}
;
conn_list_t, conn_list_destroy));
CONN_LIST($$)->type = $2;
CONN_LIST($$)->filter = CONN_MATCHER($3);
- $$->cmd = CONNECTION_LIST;
+ $$->cmd = SDB_CONNECTION_LIST;
}
;
CONN_LOOKUP($$)->type = $2;
CONN_LOOKUP($$)->matcher = CONN_MATCHER($3);
CONN_LOOKUP($$)->filter = CONN_MATCHER($4);
- $$->cmd = CONNECTION_LOOKUP;
+ $$->cmd = SDB_CONNECTION_LOOKUP;
}
;
CONN_TS($$)->metric = $4;
CONN_TS($$)->opts.start = $5;
CONN_TS($$)->opts.end = $6;
- $$->cmd = CONNECTION_TIMESERIES;
+ $$->cmd = SDB_CONNECTION_TIMESERIES;
}
;
$$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
conn_matcher_t, conn_matcher_destroy));
- $$->cmd = CONNECTION_MATCHER;
+ $$->cmd = SDB_CONNECTION_MATCHER;
CONN_MATCHER($$)->matcher = $1;
}
;
datetime { $$.type = SDB_TYPE_DATETIME; $$.data.datetime = $1; }
|
interval { $$ = $1; }
+ |
+ array { $$ = $1; }
;
datetime:
unit = sdb_strpunit($2);
if (! unit) {
sdb_fe_yyerrorf(&yylloc, scanner,
- YY_("invalid time unit %s"), $2);
+ YY_("syntax error, invalid time unit %s"), $2);
free($2); $2 = NULL;
YYABORT;
}
}
;
+array:
+ '[' array_elem_list ']'
+ {
+ $$ = $2;
+ }
+ ;
+
+array_elem_list:
+ array_elem_list ',' data
+ {
+ size_t elem_size;
+
+ if (($3.type & SDB_TYPE_ARRAY) || (($1.type & 0xff) != $3.type)) {
+ sdb_fe_yyerrorf(&yylloc, scanner, YY_("syntax error, "
+ "cannot use element of type %s in array of type %s"),
+ SDB_TYPE_TO_STRING($3.type),
+ SDB_TYPE_TO_STRING($1.type));
+ sdb_data_free_datum(&$1);
+ sdb_data_free_datum(&$3);
+ YYABORT;
+ }
+
+ elem_size = sdb_data_sizeof($3.type);
+ $1.data.array.values = realloc($1.data.array.values,
+ ($1.data.array.length + 1) * elem_size);
+ if (! $1.data.array.values) {
+ sdb_fe_yyerror(&yylloc, scanner, YY_("out of memory"));
+ YYABORT;
+ }
+
+ memcpy((char *)$1.data.array.values
+ + $1.data.array.length * elem_size,
+ &$3.data, elem_size);
+ ++$1.data.array.length;
+
+ $$ = $1;
+ }
+ |
+ data
+ {
+ size_t elem_size;
+
+ if ($1.type & SDB_TYPE_ARRAY) {
+ sdb_fe_yyerrorf(&yylloc, scanner, YY_("syntax error, "
+ "cannot construct array of type %s"),
+ SDB_TYPE_TO_STRING($1.type));
+ sdb_data_free_datum(&$1);
+ YYABORT;
+ }
+
+ $$ = $1;
+ $$.type = $1.type | SDB_TYPE_ARRAY;
+ $$.data.array.length = 1;
+ elem_size = sdb_data_sizeof($1.type);
+ $$.data.array.values = malloc(elem_size);
+ if (! $$.data.array.values ) {
+ sdb_fe_yyerror(&yylloc, scanner, YY_("out of memory"));
+ YYABORT;
+ }
+ memcpy($$.data.array.values, &$1.data, elem_size);
+ }
+ ;
+
%%
void
diff --combined t/unit/frontend/parser_test.c
index c377f78fa59a9acd359de8fdeb560fce0013ce52,2368bcc4d3efe821a5342aa25ee07316ff69e7e1..c5b514fde5156fa43fafed5a714e6ffbd2e768cf
{ ";;", -1, 0, 0 },
/* valid commands */
- { "FETCH host 'host'", -1, 1, CONNECTION_FETCH },
+ { "FETCH host 'host'", -1, 1, SDB_CONNECTION_FETCH },
{ "FETCH host 'host' FILTER "
- "age > 60s", -1, 1, CONNECTION_FETCH },
+ "age > 60s", -1, 1, SDB_CONNECTION_FETCH },
{ "FETCH service "
- "'host'.'service'", -1, 1, CONNECTION_FETCH },
+ "'host'.'service'", -1, 1, SDB_CONNECTION_FETCH },
{ "FETCH metric "
- "'host'.'metric'", -1, 1, CONNECTION_FETCH },
+ "'host'.'metric'", -1, 1, SDB_CONNECTION_FETCH },
- { "LIST hosts", -1, 1, CONNECTION_LIST },
- { "LIST hosts -- foo", -1, 1, CONNECTION_LIST },
- { "LIST hosts;", -1, 1, CONNECTION_LIST },
- { "LIST hosts; INVALID", 11, 1, CONNECTION_LIST },
+ { "LIST hosts", -1, 1, SDB_CONNECTION_LIST },
+ { "LIST hosts -- foo", -1, 1, SDB_CONNECTION_LIST },
+ { "LIST hosts;", -1, 1, SDB_CONNECTION_LIST },
+ { "LIST hosts; INVALID", 11, 1, SDB_CONNECTION_LIST },
{ "LIST hosts FILTER "
- "age > 60s", -1, 1, CONNECTION_LIST },
- { "LIST services", -1, 1, CONNECTION_LIST },
+ "age > 60s", -1, 1, SDB_CONNECTION_LIST },
+ { "LIST services", -1, 1, SDB_CONNECTION_LIST },
{ "LIST services FILTER "
- "age > 60s", -1, 1, CONNECTION_LIST },
- { "LIST metrics", -1, 1, CONNECTION_LIST },
+ "age > 60s", -1, 1, SDB_CONNECTION_LIST },
+ { "LIST metrics", -1, 1, SDB_CONNECTION_LIST },
{ "LIST metrics FILTER "
- "age > 60s", -1, 1, CONNECTION_LIST },
+ "age > 60s", -1, 1, SDB_CONNECTION_LIST },
- { "LOOKUP hosts", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
- "name = 'host'", -1, 1, CONNECTION_LOOKUP },
+ "name = 'host'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING NOT "
- "name = 'host'", -1, 1, CONNECTION_LOOKUP },
+ "name = 'host'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"name =~ 'p' AND "
- "ANY service =~ 'p'", -1, 1, CONNECTION_LOOKUP },
+ "ANY service =~ 'p'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING NOT "
"name =~ 'p' AND "
- "ANY service =~ 'p'", -1, 1, CONNECTION_LOOKUP },
+ "ANY service =~ 'p'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"name =~ 'p' AND "
"ANY service =~ 'p' OR "
- "ANY service =~ 'r'", -1, 1, CONNECTION_LOOKUP },
+ "ANY service =~ 'r'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING NOT "
"name =~ 'p' AND "
"ANY service =~ 'p' OR "
- "ANY service =~ 'r'", -1, 1, CONNECTION_LOOKUP },
+ "ANY service =~ 'r'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"name =~ 'p' "
- "FILTER age > 1D", -1, 1, CONNECTION_LOOKUP },
+ "FILTER age > 1D", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"name =~ 'p' "
"FILTER age > 1D AND "
- "interval < 240s" , -1, 1, CONNECTION_LOOKUP },
+ "interval < 240s" , -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"name =~ 'p' "
- "FILTER NOT age>1D", -1, 1, CONNECTION_LOOKUP },
+ "FILTER NOT age>1D", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"name =~ 'p' "
"FILTER age>"
- "interval", -1, 1, CONNECTION_LOOKUP },
- { "LOOKUP services", -1, 1, CONNECTION_LOOKUP },
+ "interval", -1, 1, SDB_CONNECTION_LOOKUP },
+ { "LOOKUP services", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP services MATCHING ANY "
- "attribute =~ 'a'", -1, 1, CONNECTION_LOOKUP },
- { "LOOKUP metrics", -1, 1, CONNECTION_LOOKUP },
+ "attribute =~ 'a'", -1, 1, SDB_CONNECTION_LOOKUP },
+ { "LOOKUP metrics", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP metrics MATCHING ANY "
- "attribute =~ 'a'", -1, 1, CONNECTION_LOOKUP },
+ "attribute =~ 'a'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "TIMESERIES 'host'.'metric' "
"START 2014-01-01 "
"END 2014-12-31 "
- "23:59:59", -1, 1, CONNECTION_TIMESERIES },
+ "23:59:59", -1, 1, SDB_CONNECTION_TIMESERIES },
{ "TIMESERIES 'host'.'metric' "
"START 2014-02-02 "
- "14:02", -1, 1, CONNECTION_TIMESERIES },
+ "14:02", -1, 1, SDB_CONNECTION_TIMESERIES },
{ "TIMESERIES 'host'.'metric' "
- "END 2014-02-02", -1, 1, CONNECTION_TIMESERIES },
+ "END 2014-02-02", -1, 1, SDB_CONNECTION_TIMESERIES },
{ "TIMESERIES "
- "'host'.'metric'", -1, 1, CONNECTION_TIMESERIES },
+ "'host'.'metric'", -1, 1, SDB_CONNECTION_TIMESERIES },
/* string constants */
{ "LOOKUP hosts MATCHING "
- "name = ''''", -1, 1, CONNECTION_LOOKUP },
+ "name = ''''", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
- "name = '''foo'", -1, 1, CONNECTION_LOOKUP },
+ "name = '''foo'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
- "name = 'f''oo'", -1, 1, CONNECTION_LOOKUP },
+ "name = 'f''oo'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
- "name = 'foo'''", -1, 1, CONNECTION_LOOKUP },
+ "name = 'foo'''", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"name = '''", -1, -1, 0 },
/* numeric constants */
{ "LOOKUP hosts MATCHING "
"attribute['foo'] = "
- "1234", -1, 1, CONNECTION_LOOKUP },
+ "1234", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] != "
- "+234", -1, 1, CONNECTION_LOOKUP },
+ "+234", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] < "
- "-234", -1, 1, CONNECTION_LOOKUP },
+ "-234", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] > "
- "12.4", -1, 1, CONNECTION_LOOKUP },
+ "12.4", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] <= "
- "12. + .3", -1, 1, CONNECTION_LOOKUP },
+ "12. + .3", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] <= "
- "'f' || 'oo'", -1, 1, CONNECTION_LOOKUP },
+ "'f' || 'oo'", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] >= "
- ".4", -1, 1, CONNECTION_LOOKUP },
+ ".4", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] = "
- "+12e3", -1, 1, CONNECTION_LOOKUP },
+ "+12e3", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] = "
- "+12e-3", -1, 1, CONNECTION_LOOKUP },
+ "+12e-3", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] = "
- "-12e+3", -1, 1, CONNECTION_LOOKUP },
+ "-12e+3", -1, 1, SDB_CONNECTION_LOOKUP },
/* date, time, interval constants */
{ "LOOKUP hosts MATCHING "
"attribute['foo'] = "
- "1 Y 42D", -1, 1, CONNECTION_LOOKUP },
+ "1 Y 42D", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] = "
- "1s 42D", -1, 1, CONNECTION_LOOKUP },
+ "1s 42D", -1, 1, SDB_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'] = "
- "1Y42D", -1, 1, CONNECTION_LOOKUP },
+ "1Y42D", -1, 1, SDB_CONNECTION_LOOKUP },
*/
- "backend = ['foo']", -1, 1, CONNECTION_LOOKUP },
+ /* array constants */
+ { "LOOKUP hosts MATCHING "
- "backend = ['a','b']", -1, 1, CONNECTION_LOOKUP },
++ "backend = ['foo']", -1, 1, SDB_CONNECTION_LOOKUP },
+ { "LOOKUP hosts MATCHING "
++ "backend = ['a','b']", -1, 1, SDB_CONNECTION_LOOKUP },
+
/* NULL */
{ "LOOKUP hosts MATCHING "
"attribute['foo'] "
- "IS NULL", -1, 1, CONNECTION_LOOKUP },
+ "IS NULL", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"attribute['foo'] "
- "IS NOT NULL", -1, 1, CONNECTION_LOOKUP },
+ "IS NOT NULL", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"NOT attribute['foo'] "
- "IS NULL", -1, 1, CONNECTION_LOOKUP },
+ "IS NULL", -1, 1, SDB_CONNECTION_LOOKUP },
{ "LOOKUP hosts MATCHING "
"ANY service IS NULL", -1, -1, 0 },
* IS NULL currently maps to an equality matcher */
{ "attribute['foo'] IS NULL", -1, MATCHER_ISNULL },
{ "attribute['foo'] IS NOT NULL", -1, MATCHER_ISNNULL },
+ /* array expressions */
+ { "backend < ['a']", -1, MATCHER_LT },
+ { "backend <= ['a']", -1, MATCHER_LE },
+ { "backend = ['a']", -1, MATCHER_EQ },
+ { "backend != ['a']", -1, MATCHER_NE },
+ { "backend >= ['a']", -1, MATCHER_GE },
+ { "backend > ['a']", -1, MATCHER_GT },
+ { "backend &^ ['a']", -1, -1 },
/* object field matchers */
{ "name < 'a'", -1, MATCHER_LT },