X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Ffrontend%2Fgrammar.y;h=31b71a0eba7665b94de03bd47c50a0cd989ff24e;hp=2872bcf447fdeacb561aae754b9c85420a3fddc7;hb=5ced2b9eb4d4def7d3ad5b1172004293e7a68e0e;hpb=4d93f084bf26672e322b82ce192c8beb5765e1d0 diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index 2872bcf..31b71a0 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -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") %} @@ -104,6 +104,8 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...); sdb_store_matcher_t *m; sdb_store_expr_t *expr; + + sdb_metric_store_t metric_store; } %start statements @@ -117,14 +119,16 @@ 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 %token START END /* NULL token */ %token NULL_T -%token FETCH LIST LOOKUP TIMESERIES +%token FETCH LIST LOOKUP STORE TIMESERIES %token IDENTIFIER STRING @@ -153,6 +157,7 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...); fetch_statement list_statement lookup_statement + store_statement timeseries_statement matching_clause filter_clause @@ -161,10 +166,9 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...); %type matcher compare_matcher -%type expression +%type expression arithmetic_expression object_expression %type object_type object_type_plural -%type iterable %type field %type cmp @@ -175,6 +179,9 @@ sdb_fe_yyerrorf(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *fmt, ...); %type datetime start_clause end_clause + last_update_clause + +%type metric_store_clause %destructor { free($$); } %destructor { sdb_object_deref(SDB_OBJ($$)); } @@ -237,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)); @@ -265,6 +272,8 @@ statement: | lookup_statement | + store_statement + | timeseries_statement | /* empty */ @@ -345,6 +354,95 @@ filter_clause: | /* empty */ { $$ = NULL; } +/* + * STORE |. [LAST UPDATE ]; + * STORE METRIC . STORE [LAST UPDATE ]; + * STORE ATTRIBUTE . [LAST UPDATE ]; + * + * Store or update an object in the database. + */ +store_statement: + STORE HOST_T STRING last_update_clause + { + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_store_host_t, conn_store_host_destroy)); + CONN_STORE_HOST($$)->name = $3; + CONN_STORE_HOST($$)->last_update = $4; + $$->cmd = SDB_CONNECTION_STORE_HOST; + } + | + STORE SERVICE_T STRING '.' STRING last_update_clause + { + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_store_svc_t, conn_store_svc_destroy)); + CONN_STORE_SVC($$)->hostname = $3; + CONN_STORE_SVC($$)->name = $5; + CONN_STORE_SVC($$)->last_update = $6; + $$->cmd = SDB_CONNECTION_STORE_SERVICE; + } + | + STORE METRIC_T STRING '.' STRING metric_store_clause last_update_clause + { + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_store_metric_t, conn_store_metric_destroy)); + CONN_STORE_METRIC($$)->hostname = $3; + CONN_STORE_METRIC($$)->name = $5; + CONN_STORE_METRIC($$)->store_type = $6.type; + CONN_STORE_METRIC($$)->store_id = $6.id; + CONN_STORE_METRIC($$)->last_update = $7; + $$->cmd = SDB_CONNECTION_STORE_METRIC; + } + | + STORE HOST_T ATTRIBUTE_T STRING '.' STRING data last_update_clause + { + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_store_attr_t, conn_store_attr_destroy)); + CONN_STORE_ATTR($$)->parent_type = SDB_HOST; + CONN_STORE_ATTR($$)->hostname = NULL; + CONN_STORE_ATTR($$)->parent = $4; + CONN_STORE_ATTR($$)->key = $6; + CONN_STORE_ATTR($$)->value = $7; + CONN_STORE_ATTR($$)->last_update = $8; + $$->cmd = SDB_CONNECTION_STORE_ATTRIBUTE; + } + | + STORE SERVICE_T ATTRIBUTE_T STRING '.' STRING '.' STRING data last_update_clause + { + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_store_attr_t, conn_store_attr_destroy)); + CONN_STORE_ATTR($$)->parent_type = SDB_SERVICE; + CONN_STORE_ATTR($$)->hostname = $4; + CONN_STORE_ATTR($$)->parent = $6; + CONN_STORE_ATTR($$)->key = $8; + CONN_STORE_ATTR($$)->value = $9; + CONN_STORE_ATTR($$)->last_update = $10; + $$->cmd = SDB_CONNECTION_STORE_ATTRIBUTE; + } + | + STORE METRIC_T ATTRIBUTE_T STRING '.' STRING '.' STRING data last_update_clause + { + $$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL, + conn_store_attr_t, conn_store_attr_destroy)); + CONN_STORE_ATTR($$)->parent_type = SDB_METRIC; + CONN_STORE_ATTR($$)->hostname = $4; + CONN_STORE_ATTR($$)->parent = $6; + CONN_STORE_ATTR($$)->key = $8; + CONN_STORE_ATTR($$)->value = $9; + CONN_STORE_ATTR($$)->last_update = $10; + $$->cmd = SDB_CONNECTION_STORE_ATTRIBUTE; + } + ; + +last_update_clause: + LAST UPDATE datetime { $$ = $3; } + | + /* empty */ { $$ = sdb_gettime(); } + +metric_store_clause: + STORE STRING STRING { $$.type = $2; $$.id = $3; } + | + /* empty */ { $$.type = $$.id = NULL; } + /* * TIMESERIES . [START ] [END ]; * @@ -436,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)); } | @@ -466,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; @@ -515,6 +647,20 @@ expression: sdb_object_deref(SDB_OBJ($1)); $1 = NULL; sdb_object_deref(SDB_OBJ($3)); $3 = NULL; } + ; + +object_expression: + object_type '.' object_expression + { + $$ = sdb_store_expr_typed($1, $3); + sdb_object_deref(SDB_OBJ($3)); + } + | + ATTRIBUTE_T '.' object_expression + { + $$ = sdb_store_expr_typed(SDB_ATTRIBUTE, $3); + sdb_object_deref(SDB_OBJ($3)); + } | field { @@ -526,12 +672,6 @@ expression: $$ = sdb_store_expr_attrvalue($3); free($3); $3 = NULL; } - | - data - { - $$ = sdb_store_expr_constvalue(&$1); - sdb_data_free_datum(&$1); - } ; object_type: @@ -550,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; } | @@ -570,6 +700,8 @@ field: INTERVAL_T { $$ = SDB_FIELD_INTERVAL; } | BACKEND_T { $$ = SDB_FIELD_BACKEND; } + | + VALUE_T { $$ = SDB_FIELD_VALUE; } ; cmp: @@ -725,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 */