Code

frontend: Added 'FILTER' support to the 'LOOKUP' command.
[sysdb.git] / src / frontend / grammar.y
index ed4de830fc64cc0f091a52c43624fd325ee96e17..92bfd1f5c60d2ab24d5e0b6f82b90e7e4ce73c71 100644 (file)
@@ -82,7 +82,7 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
 
 %token SCANNER_ERROR
 
-%token AND OR IS NOT MATCHING
+%token AND OR IS NOT MATCHING FILTER
 %token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX
 %token CMP_LT CMP_LE CMP_GE CMP_GT
 %token CONCAT
@@ -125,6 +125,7 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
 %type <sstr> op
 
 %type <data> data
+       interval interval_elem
 
 %destructor { free($$); } <str>
 %destructor { sdb_object_deref(SDB_OBJ($$)); } <node> <m> <expr>
@@ -228,7 +229,7 @@ list_statement:
        ;
 
 /*
- * LOOKUP <type> MATCHING <condition>;
+ * LOOKUP <type> MATCHING <condition> [FILTER <condition>];
  *
  * Returns detailed information about <type> matching condition.
  */
@@ -252,6 +253,27 @@ lookup_statement:
                        $$->cmd = CONNECTION_LOOKUP;
                        free($2); $2 = NULL;
                }
+       |
+       LOOKUP IDENTIFIER MATCHING condition FILTER condition
+               {
+                       /* TODO: support other types as well */
+                       if (strcasecmp($2, "hosts")) {
+                               char errmsg[strlen($2) + 32];
+                               snprintf(errmsg, sizeof(errmsg),
+                                               YY_("unknown table %s"), $2);
+                               sdb_fe_yyerror(&yylloc, scanner, errmsg);
+                               free($2); $2 = NULL;
+                               sdb_object_deref(SDB_OBJ($4));
+                               YYABORT;
+                       }
+
+                       $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
+                                               conn_lookup_t, conn_lookup_destroy));
+                       CONN_LOOKUP($$)->matcher = CONN_MATCHER($4);
+                       CONN_LOOKUP($$)->filter = CONN_MATCHER($6);
+                       $$->cmd = CONNECTION_LOOKUP;
+                       free($2); $2 = NULL;
+               }
        ;
 
 condition:
@@ -265,7 +287,7 @@ condition:
                        }
 
                        $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
-                                               conn_node_matcher_t, conn_matcher_destroy));
+                                               conn_matcher_t, conn_matcher_destroy));
                        $$->cmd = CONNECTION_EXPR;
                        CONN_MATCHER($$)->matcher = $1;
                }
@@ -309,6 +331,13 @@ matcher:
  * Parse matchers comparing object attributes with a value.
  */
 compare_matcher:
+       ':' IDENTIFIER op expression
+               {
+                       $$ = sdb_store_matcher_parse_field_cmp($2, $3, $4);
+                       free($2); $2 = NULL;
+                       sdb_object_deref(SDB_OBJ($4));
+               }
+       |
        IDENTIFIER op expression
                {
                        $$ = sdb_store_matcher_parse_cmp($1, NULL, $2, $3);
@@ -416,6 +445,44 @@ data:
        INTEGER { $$ = $1; }
        |
        FLOAT { $$ = $1; }
+       |
+       interval { $$ = $1; }
+       ;
+
+interval:
+       interval interval_elem
+               {
+                       $$.data.datetime = $1.data.datetime + $2.data.datetime;
+               }
+       |
+       interval_elem { $$ = $1; }
+       ;
+
+interval_elem:
+       INTEGER IDENTIFIER
+               {
+                       sdb_time_t unit = 1;
+
+                       unit = sdb_strpunit($2);
+                       if (! unit) {
+                               char errmsg[strlen($2) + 32];
+                               snprintf(errmsg, sizeof(errmsg),
+                                               YY_("invalid time unit %s"), $2);
+                               sdb_fe_yyerror(&yylloc, scanner, errmsg);
+                               free($2); $2 = NULL;
+                               YYABORT;
+                       }
+                       free($2); $2 = NULL;
+
+                       $$.type = SDB_TYPE_DATETIME;
+                       $$.data.datetime = (sdb_time_t)$1.data.integer * unit;
+
+                       if ($1.data.integer < 0) {
+                               sdb_fe_yyerror(&yylloc, scanner,
+                                               YY_("syntax error, negative intervals not supported"));
+                               YYABORT;
+                       }
+               }
        ;
 
 %%