summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e3cf0b9)
raw | patch | inline | side by side (parent: e3cf0b9)
author | Sebastian Harl <sh@tokkee.org> | |
Mon, 23 Jun 2014 20:47:01 +0000 (22:47 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Mon, 23 Jun 2014 20:47:01 +0000 (22:47 +0200) |
This is supported only for comparing attribute values.
index 658f931ab30bc3fe64dd30b53e439416ad6a9ae6..3920b80127c5a228792b299e06bc5e6e51f1187b 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
sdb_store_matcher_t *(*matcher)(sdb_store_cond_t *) = NULL;
sdb_store_matcher_t *m;
sdb_store_cond_t *cond;
+ _Bool inv = 0;
/* TODO: this will reject any attributes called "name";
* use a different syntax for querying objects by name */
else if (! strcasecmp(op, "<="))
matcher = sdb_store_le_matcher;
else if (! strcasecmp(op, "="))
- /* XXX: this is still handled by sdb_store_matcher_parse_cmp */
matcher = sdb_store_eq_matcher;
else if (! strcasecmp(op, ">="))
matcher = sdb_store_ge_matcher;
else if (! strcasecmp(op, ">"))
matcher = sdb_store_gt_matcher;
+ else if (! strcasecmp(op, "!=")) {
+ matcher = sdb_store_eq_matcher;
+ inv = 1;
+ }
else
return NULL;
m = matcher(cond);
/* pass ownership to 'm' or destroy in case of an error */
sdb_object_deref(SDB_OBJ(cond));
+ if (! m)
+ return NULL;
+
+ if (inv) {
+ sdb_store_matcher_t *tmp;
+ tmp = sdb_store_inv_matcher(m);
+ /* pass ownership to the inverse matcher */
+ sdb_object_deref(SDB_OBJ(m));
+ m = tmp;
+ }
return m;
} /* parse_attr_cmp */
else
return NULL;
- if (value->type != SDB_TYPE_STRING)
+ if (value->type != SDB_TYPE_STRING) {
+ if (type == SDB_ATTRIBUTE)
+ return parse_attr_cmp(attr, op, value);
return NULL;
+ }
if (! strcasecmp(attr, "name"))
m = sdb_store_name_matcher(type, value->data.string, re);
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index c4c47755caa9b2c032ff0593b2a2134130a2c607..34a9c6b6474502d9fc059df45a6ed93a79890567 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
%token AND OR NOT WHERE
%token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX
+%token CMP_LT CMP_LE CMP_GE CMP_GT
%token FETCH LIST LOOKUP
%token <str> IDENTIFIER STRING
+%token <data> INTEGER FLOAT
+
/* Precedence (lowest first): */
%left OR
%left AND
-%left NOT
+%right NOT
%left CMP_EQUAL CMP_NEQUAL
+%left CMP_LT CMP_LE CMP_GE CMP_GT
%left CMP_REGEX CMP_NREGEX
%left '(' ')'
%left '.'
CMP_REGEX { $$ = "=~"; }
|
CMP_NREGEX { $$ = "!~"; }
+ |
+ CMP_LT { $$ = "<"; }
+ |
+ CMP_LE { $$ = "<="; }
+ |
+ CMP_GE { $$ = ">="; }
+ |
+ CMP_GT { $$ = ">"; }
;
data:
STRING { $$.type = SDB_TYPE_STRING; $$.data.string = $1; }
+ |
+ INTEGER { $$ = $1; }
+ |
+ FLOAT { $$ = $1; }
;
%%
diff --git a/src/frontend/scanner.l b/src/frontend/scanner.l
index dd2a86cf5273b4e5e3c450c02306820b282a1a46..0396db53e0d742f17ca12de0fcec788da4c24045 100644 (file)
--- a/src/frontend/scanner.l
+++ b/src/frontend/scanner.l
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include "core/data.h"
#include "frontend/connection.h"
#include "frontend/parser.h"
#include "frontend/grammar.h"
#include <errno.h>
#include <string.h>
+#include <stdlib.h>
#define YY_EXTRA_TYPE sdb_fe_yyextra_t *
/* TODO: fully support SQL strings */
string ('[^']*')
+dec ([\+\-]?[0-9]+)
+exp ([\+\-]?[0-9]+[Ee]\+?[0-9]+)
+integer ({dec}|{exp})
+float1 ([\+\-]?[0-9]+\.[0-9]*([Ee][\+\-]?[0-9]+)?)
+float2 ([\+\-]?[0-9]*\.[0-9]+([Ee][\+\-]?[0-9]+)?)
+float3 ([\+\-]?[0-9]+[Ee]\-[0-9]+)
+float4 ([\+\-]?[Ii][Nn][Ff]([Ii][Nn][Ii][Tt][Yy])?)
+float5 ([Nn][Aa][Nn])
+float ({float1}|{float2}|{float3}|{float4}|{float5})
+
%%
{whitespace} |
yylval->str = strdup(yytext + 1);
return STRING;
}
+{integer} {
+ yylval->data.data.integer = (int64_t)strtoll(yytext, NULL, 10);
+ yylval->data.type = SDB_TYPE_INTEGER;
+ return INTEGER;
+ }
+{float} {
+ yylval->data.data.decimal = strtod(yytext, NULL);
+ yylval->data.type = SDB_TYPE_DECIMAL;
+ return FLOAT;
+ }
= { return CMP_EQUAL; }
!= { return CMP_NEQUAL; }
=~ { return CMP_REGEX; }
!~ { return CMP_NREGEX; }
+\< { return CMP_LT; }
+\<= { return CMP_LE; }
+\>= { return CMP_GE; }
+\> { return CMP_GT; }
. { /* XXX: */ return yytext[0]; }
index 4a935429923bb4dd1118c092756387cf1393fc0e..6dd7bb3fa1916a2119cc1985f9c2dc7393a3db47 100644 (file)
"OBJ\\[attribute\\]\\{ NAME\\{ 'x', \\(nil\\) \\}" },
{ "attribute.k1 = 'v1'", 1,
"ATTR\\[k1\\]\\{ VALUE\\{ 'v1', \\(nil\\) \\} \\}" },
+ { "attribute.k2 < 123", 0,
+ "ATTR\\[k2\\]\\{ < 123 \\}" },
+ { "attribute.k2 <= 123", 1,
+ "ATTR\\[k2\\]\\{ <= 123 \\}" },
+ { "attribute.k2 >= 123", 1,
+ "ATTR\\[k2\\]\\{ >= 123 \\}" },
+ { "attribute.k2 > 123", 0,
+ "ATTR\\[k2\\]\\{ > 123 \\}" },
+ { "attribute.k2 = 123", 1,
+ "ATTR\\[k2\\]\\{ = 123 \\}" },
+ { "attribute.k2 != 123", 2,
+ "\\(NOT, ATTR\\[k2\\]\\{ = 123 \\}\\)" },
{ "attribute.k1 != 'v1'", 2,
"\\(NOT, ATTR\\[k1\\]\\{ VALUE\\{ 'v1', \\(nil\\) \\} \\}\\)" },
{ "attribute.k1 != 'v2'", 3,
index e245c29e56f1b89d279c5c7052c63208dae7b2a2..8c626606c3c2d1900aa580a6f721a180fd66c382 100644 (file)
"service.name =~ 'p' OR "
"service.name =~ 'r'", -1, 1, CONNECTION_LOOKUP },
+ /* numeric constants */
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "1234", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo != "
+ "+234", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo < "
+ "-234", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo > "
+ "12.4", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo <= "
+ "12.", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo >= "
+ ".4", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "+12e3", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "+12e-3", -1, 1, CONNECTION_LOOKUP },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "-12e+3", -1, 1, CONNECTION_LOOKUP },
+
+ /* invalid numeric constants */
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "+-12e+3", -1, -1, 0 },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "-12e-+3", -1, -1, 0 },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "e+3", -1, -1, 0 },
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "3e", -1, -1, 0 },
+ /* following SQL standard, we don't support hex numbers */
+ { "LOOKUP hosts WHERE "
+ "attribute.foo = "
+ "0x12", -1, -1, 0 },
+
/* comments */
{ "/* some comment */", -1, 0, 0 },
{ "-- another comment", -1, 0, 0 },