Code

store: Add sdb_store_query_prepare_matcher().
[sysdb.git] / src / frontend / grammar.y
index 87184a4e15ef3effafe1810c11e368b529b14ea8..31b71a0eba7665b94de03bd47c50a0cd989ff24e 100644 (file)
@@ -48,7 +48,7 @@
  */
 
 static sdb_store_matcher_t *
-name_iter_matcher(int m_type, int type, const char *cmp,
+name_iter_matcher(int m_type, sdb_store_expr_t *iter, const char *cmp,
                sdb_store_expr_t *expr);
 
 /*
@@ -78,7 +78,7 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...);
 #define MODE_TO_STRING(m) \
        (((m) == SDB_PARSE_DEFAULT) ? "statement" \
                : ((m) == SDB_PARSE_COND) ? "condition" \
-               : ((m) == SDB_PARSE_EXPR) ? "expression" \
+               : ((m) == SDB_PARSE_ARITH) ? "arithmetic expression" \
                : "UNKNOWN")
 
 %}
@@ -119,7 +119,7 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...);
 
 %token HOST_T HOSTS_T SERVICE_T SERVICES_T METRIC_T METRICS_T
 %token ATTRIBUTE_T ATTRIBUTES_T
-%token NAME_T LAST_UPDATE_T AGE_T INTERVAL_T BACKEND_T
+%token NAME_T LAST_UPDATE_T AGE_T INTERVAL_T BACKEND_T VALUE_T
 
 %token LAST UPDATE
 
@@ -166,10 +166,9 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...);
 %type <m> matcher
        compare_matcher
 
-%type <expr> expression object_expression
+%type <expr> expression arithmetic_expression object_expression
 
 %type <integer> object_type object_type_plural
-%type <integer> iterable
 %type <integer> field
 
 %type <sstr> cmp
@@ -245,7 +244,7 @@ statements:
        expression
                {
                        /* only accepted in expression parse mode */
-                       if (! (parser_mode & SDB_PARSE_EXPR)) {
+                       if (! (parser_mode & SDB_PARSE_ARITH)) {
                                sdb_fe_yyerrorf(&yylloc, scanner,
                                                YY_("syntax error, unexpected expression, "
                                                        "expecting %s"), MODE_TO_STRING(parser_mode));
@@ -535,15 +534,17 @@ compare_matcher:
                        sdb_object_deref(SDB_OBJ($3));
                }
        |
-       ANY iterable cmp expression
+       ANY expression cmp expression
                {
                        $$ = name_iter_matcher(MATCHER_ANY, $2, $3, $4);
+                       sdb_object_deref(SDB_OBJ($2));
                        sdb_object_deref(SDB_OBJ($4));
                }
        |
-       ALL iterable cmp expression
+       ALL expression cmp expression
                {
                        $$ = name_iter_matcher(MATCHER_ALL, $2, $3, $4);
+                       sdb_object_deref(SDB_OBJ($2));
                        sdb_object_deref(SDB_OBJ($4));
                }
        |
@@ -565,9 +566,41 @@ compare_matcher:
                        sdb_object_deref(SDB_OBJ($1));
                        sdb_object_deref(SDB_OBJ($3));
                }
+       |
+       expression NOT IN expression
+               {
+                       $$ = sdb_store_nin_matcher($1, $4);
+                       sdb_object_deref(SDB_OBJ($1));
+                       sdb_object_deref(SDB_OBJ($4));
+               }
        ;
 
 expression:
+       arithmetic_expression
+               {
+                       if (! $1) {
+                               /* we should have better error messages here
+                                * TODO: maybe let the analyzer handle this instead */
+                               sdb_fe_yyerror(&yylloc, scanner,
+                                               YY_("syntax error, invalid arithmetic expression"));
+                               YYABORT;
+                       }
+                       $$ = $1;
+               }
+       |
+       object_expression
+               {
+                       $$ = $1;
+               }
+       |
+       data
+               {
+                       $$ = sdb_store_expr_constvalue(&$1);
+                       sdb_data_free_datum(&$1);
+               }
+       ;
+
+arithmetic_expression:
        '(' expression ')'
                {
                        $$ = $2;
@@ -614,17 +647,6 @@ expression:
                        sdb_object_deref(SDB_OBJ($1)); $1 = NULL;
                        sdb_object_deref(SDB_OBJ($3)); $3 = NULL;
                }
-       |
-       object_expression
-               {
-                       $$ = $1;
-               }
-       |
-       data
-               {
-                       $$ = sdb_store_expr_constvalue(&$1);
-                       sdb_data_free_datum(&$1);
-               }
        ;
 
 object_expression:
@@ -634,6 +656,12 @@ object_expression:
                        sdb_object_deref(SDB_OBJ($3));
                }
        |
+       ATTRIBUTE_T '.' object_expression
+               {
+                       $$ = sdb_store_expr_typed(SDB_ATTRIBUTE, $3);
+                       sdb_object_deref(SDB_OBJ($3));
+               }
+       |
        field
                {
                        $$ = sdb_store_expr_fieldvalue($1);
@@ -662,16 +690,6 @@ object_type_plural:
        METRICS_T { $$ = SDB_METRIC; }
        ;
 
-iterable:
-       SERVICE_T { $$ = SDB_SERVICE; }
-       |
-       METRIC_T { $$ = SDB_METRIC; }
-       |
-       ATTRIBUTE_T { $$ = SDB_ATTRIBUTE; }
-       |
-       BACKEND_T { $$ = SDB_FIELD_BACKEND; }
-       ;
-
 field:
        NAME_T { $$ = SDB_FIELD_NAME; }
        |
@@ -682,6 +700,8 @@ field:
        INTERVAL_T { $$ = SDB_FIELD_INTERVAL; }
        |
        BACKEND_T { $$ = SDB_FIELD_BACKEND; }
+       |
+       VALUE_T { $$ = SDB_FIELD_VALUE; }
        ;
 
 cmp:
@@ -837,35 +857,24 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...)
        va_start(ap, fmt);
        va_copy(aq, ap);
        sdb_vlog(SDB_LOG_ERR, fmt, ap);
-       sdb_strbuf_vsprintf(errbuf, "%s", aq);
+       sdb_strbuf_vsprintf(errbuf, fmt, aq);
        va_end(ap);
 } /* sdb_fe_yyerrorf */
 
 static sdb_store_matcher_t *
-name_iter_matcher(int m_type, int type, const char *cmp,
+name_iter_matcher(int type, sdb_store_expr_t *iter, const char *cmp,
                sdb_store_expr_t *expr)
 {
        sdb_store_matcher_op_cb cb = sdb_store_parse_matcher_op(cmp);
-       sdb_store_expr_t *e;
        sdb_store_matcher_t *m, *tmp = NULL;
        assert(cb);
 
-       /* hosts are never iterable */
-       if (type == SDB_HOST) {
-               return NULL;
-       }
-
-       if (type == SDB_FIELD_BACKEND)
-               e = sdb_store_expr_fieldvalue(type);
-       else
-               e = sdb_store_expr_fieldvalue(SDB_FIELD_NAME);
-       m = cb(e, expr);
-       if (m_type == MATCHER_ANY)
-               tmp = sdb_store_any_matcher(type, m);
-       else if (m_type == MATCHER_ALL)
-               tmp = sdb_store_all_matcher(type, m);
+       m = cb(NULL, expr);
+       if (type == MATCHER_ANY)
+               tmp = sdb_store_any_matcher(iter, m);
+       else if (type == MATCHER_ALL)
+               tmp = sdb_store_all_matcher(iter, m);
        sdb_object_deref(SDB_OBJ(m));
-       sdb_object_deref(SDB_OBJ(e));
        return tmp;
 } /* name_iter_matcher */