summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 78afb86)
raw | patch | inline | side by side (parent: 78afb86)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 12 Nov 2014 21:10:47 +0000 (22:10 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 12 Nov 2014 21:10:47 +0000 (22:10 +0100) |
index c1b9d01ef19494188dddd2d3dd916601715e924a..2de9befa6eeb6605ca405fb07689f6672c86b169 100644 (file)
--- a/src/frontend/analyzer.c
+++ 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,
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 80fb249684e0120be85cd421905fec666d277bc4..d4e54a9c4c8f3869946bfa151de5d764c1156e88 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
%type <data> data
interval interval_elem
+ array array_elem_list
%type <datetime> datetime
start_clause end_clause
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
index 18d811f0201edac5fd3a3ebc75d4f5951b981c65..49f9125647dafbd17fa630278f749a1d630aa03b 100644 (file)
{ "name =~ '.'", NULL, 3 },
{ "ANY backend = 'backend'", NULL, 0 },
{ "ALL backend = ''", NULL, 3 }, /* backend is empty */
+ { "backend = ['backend']", NULL, 0 },
+ { "backend != ['backend']", NULL, 3 },
+ { "backend < ['backend']", NULL, 3 },
+ { "backend <= ['backend']", NULL, 3 },
+ { "backend >= ['backend']", NULL, 0 },
+ { "backend > ['backend']", NULL, 0 },
{ "ANY metric = 'm1'", NULL, 2 },
{ "ANY metric= 'm1'", "name = 'x'", 0 }, /* filter never matches */
{ "ANY metric = 'm1'",
index 17c1032bcd0168c94fb9a9ae5873d111c6eb3926..c377f78fa59a9acd359de8fdeb560fce0013ce52 100644 (file)
"1Y42D", -1, 1, CONNECTION_LOOKUP },
*/
+ /* array constants */
+ { "LOOKUP hosts MATCHING "
+ "backend = ['foo']", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts MATCHING "
+ "backend = ['a','b']", -1, 1, CONNECTION_LOOKUP },
+
/* NULL */
{ "LOOKUP hosts MATCHING "
"attribute['foo'] "
* 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 },