From e1325ac8e15fb9a9cf64f6375c14073100b7f6a6 Mon Sep 17 00:00:00 2001 From: John Shahid Date: Mon, 11 Nov 2013 18:52:19 -0500 Subject: [PATCH] fix #37. Support the negation of the regex matcher !~ --- CHANGELOG.md | 2 ++ src/datastore/boolean_operators.go | 1 + src/datastore/filtering_test.go | 24 ++++++++++++++++++++++++ src/parser/query.lex | 1 + src/parser/query.yacc | 13 ++++++++++++- 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10da812785..624e78db8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,8 @@ ### Features +- [Issue #37](https://github.com/influxdb/influxdb/issues/37). Support the negation of the regex matcher !~ + ### Bugfixes - [Issue #36](https://github.com/influxdb/influxdb/issues/36). The regex operator should be =~ not ~= diff --git a/src/datastore/boolean_operators.go b/src/datastore/boolean_operators.go index aaed3067fd..0dd4896e3d 100644 --- a/src/datastore/boolean_operators.go +++ b/src/datastore/boolean_operators.go @@ -19,6 +19,7 @@ func init() { registeredOperators["<"] = not(GreaterThanOrEqualOperator) registeredOperators["<="] = not(GreaterThanOperator) registeredOperators["=~"] = RegexMatcherOperator + registeredOperators["!~"] = not(RegexMatcherOperator) } func not(op BooleanOperation) BooleanOperation { diff --git a/src/datastore/filtering_test.go b/src/datastore/filtering_test.go index 865083fd67..9b4223805a 100644 --- a/src/datastore/filtering_test.go +++ b/src/datastore/filtering_test.go @@ -113,6 +113,30 @@ func (self *FilteringSuite) TestRegexFiltering(c *C) { c.Assert(*result.Points[0].Values[0].StringValue, Equals, "foobar") } +func (self *FilteringSuite) TestNotRegexFiltering(c *C) { + queryStr := "select * from t where column_one !~ /.*foo.*/ and time > now() - 1d;" + query, err := parser.ParseQuery(queryStr) + c.Assert(err, IsNil) + series, err := common.StringToSeriesArray(` +[ + { + "points": [ + {"values": [{"string_value": "100"}], "timestamp": 1381346631, "sequence_number": 1}, + {"values": [{"string_value": "foobar"}], "timestamp": 1381346631, "sequence_number": 1} + ], + "name": "t", + "fields": ["column_one"] + } +] +`) + c.Assert(err, IsNil) + result, err := Filter(query, series[0]) + c.Assert(err, IsNil) + c.Assert(result, NotNil) + c.Assert(result.Points, HasLen, 1) + c.Assert(*result.Points[0].Values[0].StringValue, Equals, "100") +} + func (self *FilteringSuite) TestInequalityFiltering(c *C) { queryStr := "select * from t where column_one >= 100 and column_two > 6 and time > now() - 1d;" query, err := parser.ParseQuery(queryStr) diff --git a/src/parser/query.lex b/src/parser/query.lex index e2a7ad905d..a4778b354d 100644 --- a/src/parser/query.lex +++ b/src/parser/query.lex @@ -46,6 +46,7 @@ static int yycolumn = 1; "or" { return OR; } "==" { yylval->string = strdup(yytext); return OPERATION_EQUAL; } "=~" { yylval->string = strdup(yytext); return REGEX_OP; } +"!~" { yylval->string = strdup(yytext); return NEGATION_REGEX_OP; } "!=" { yylval->string = strdup(yytext); return OPERATION_NE; } "<" { yylval->string = strdup(yytext); return OPERATION_LT; } ">" { yylval->string = strdup(yytext); return OPERATION_GT; } diff --git a/src/parser/query.yacc b/src/parser/query.yacc index 0ccd920959..9c1366d00c 100644 --- a/src/parser/query.yacc +++ b/src/parser/query.yacc @@ -61,7 +61,7 @@ value *create_value(char *name, int type, char is_case_insensitive, value_array // define types of tokens (terminals) %token SELECT FROM WHERE EQUAL GROUP BY FIRST LAST LIMIT ORDER ASC DESC MERGE INNER JOIN -%token STRING_VALUE INT_VALUE FLOAT_VALUE TABLE_NAME SIMPLE_NAME REGEX_OP REGEX_STRING INSENSITIVE_REGEX_STRING DURATION +%token STRING_VALUE INT_VALUE FLOAT_VALUE TABLE_NAME SIMPLE_NAME REGEX_OP NEGATION_REGEX_OP REGEX_STRING INSENSITIVE_REGEX_STRING DURATION // define the precedence of these operators %left OR @@ -385,6 +385,17 @@ BOOL_EXPRESSION: $$->right->op = '\0'; $$->right->right = NULL; } + | + EXPRESSION NEGATION_REGEX_OP REGEX_VALUE + { + $$ = malloc(sizeof(bool_expression)); + $$->left = $1; + $$->op = $2; + $$->right = malloc(sizeof(expression)); + $$->right->left = $3; + $$->right->op = '\0'; + $$->right->right = NULL; + } CONDITION: BOOL_EXPRESSION