From 1689c669f608687c752ceefaffdb5954dfee05f8 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sun, 18 Dec 2016 19:15:23 +0100 Subject: [PATCH] parser: Let the TIMESERIES command accept optional data-source names. These may be specified as an array of strings after the time-series identifier. --- doc/sysdbql.7.txt | 8 +++++--- src/frontend/query.c | 2 ++ src/include/parser/ast.h | 7 +++++-- src/parser/ast.c | 10 ++++++++++ src/parser/grammar.y | 26 ++++++++++++++++++++++++-- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/doc/sysdbql.7.txt b/doc/sysdbql.7.txt index 587cd6c..9c8b305 100644 --- a/doc/sysdbql.7.txt +++ b/doc/sysdbql.7.txt @@ -68,12 +68,14 @@ objects matching that filter will be included in the reply. See the sections the search and filter conditions. *TIMESERIES* ''.'' [START ''] [END '']:: +*TIMESERIES* ''.''\['] [END '']:: Retrieve a time-series for the specified host's metric. The data is retrieved from a backend data-store based on information provided by the respective query plugin. The return value includes the actual start and end time of the -time-series and one or multiple sequences of time-stamp / value pairs. If the -metric does not exist or if the backend data-store is not supported, an error -is returned. +time-series and one or multiple sequences of time-stamp / value pairs. If any +data-source names have been specified, only those data-sources will be +returned. If the metric or a specified data-source does not exist or if the +backend data-store is not supported, an error is returned. MATCHING clause ~~~~~~~~~~~~~~~ diff --git a/src/frontend/query.c b/src/frontend/query.c index 5165821..2a1954a 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -247,6 +247,8 @@ exec_timeseries(sdb_ast_timeseries_t *ts, sdb_strbuf_t *buf, sdb_strbuf_t *errbu fetch.obj_type = SDB_METRIC; fetch.hostname = strdup(ts->hostname); fetch.name = strdup(ts->metric); + opts.data_names = (const char * const *)ts->data_names; + opts.data_names_len = ts->data_names_len; opts.start = ts->start; opts.end = ts->end; diff --git a/src/include/parser/ast.h b/src/include/parser/ast.h index 4272ec0..110ee08 100644 --- a/src/include/parser/ast.h +++ b/src/include/parser/ast.h @@ -326,12 +326,14 @@ typedef struct { sdb_ast_node_t super; char *hostname; char *metric; + char **data_names; + size_t data_names_len; sdb_time_t start; sdb_time_t end; } sdb_ast_timeseries_t; #define SDB_AST_TIMESERIES(obj) ((sdb_ast_timeseries_t *)(obj)) #define SDB_AST_TIMESERIES_INIT \ - { { SDB_OBJECT_INIT, SDB_AST_TYPE_TIMESERIES, -1 }, NULL, NULL, 0, 0 } + { { SDB_OBJECT_INIT, SDB_AST_TYPE_TIMESERIES, -1 }, NULL, NULL, NULL, 0, 0, 0 } /* * AST constructors: @@ -425,10 +427,11 @@ sdb_ast_store_create(int obj_type, char *hostname, /* * sdb_ast_timeseries_create: * Creates an AST node representing a TIMESERIES command. The newly created - * node takes ownership of the strings. + * node takes ownership of the strings and string vectors. */ sdb_ast_node_t * sdb_ast_timeseries_create(char *hostname, char *metric, + char **data_names, size_t data_names_len, sdb_time_t start, sdb_time_t end); #ifdef __cplusplus diff --git a/src/parser/ast.c b/src/parser/ast.c index 96c05ff..1db342c 100644 --- a/src/parser/ast.c +++ b/src/parser/ast.c @@ -141,6 +141,13 @@ timeseries_destroy(sdb_object_t *obj) free(timeseries->hostname); if (timeseries->metric) free(timeseries->metric); + if (timeseries->data_names) { + size_t i; + for (i = 0; i < timeseries->data_names_len; i++) + free(timeseries->data_names[i]); + free(timeseries->data_names); + timeseries->data_names = NULL; + } timeseries->hostname = timeseries->metric = NULL; } /* timeseries_destroy */ @@ -372,6 +379,7 @@ sdb_ast_store_create(int obj_type, char *hostname, sdb_ast_node_t * sdb_ast_timeseries_create(char *hostname, char *metric, + char **data_names, size_t data_names_len, sdb_time_t start, sdb_time_t end) { sdb_ast_timeseries_t *timeseries; @@ -383,6 +391,8 @@ sdb_ast_timeseries_create(char *hostname, char *metric, timeseries->hostname = hostname; timeseries->metric = metric; + timeseries->data_names = data_names; + timeseries->data_names_len = data_names_len; timeseries->start = start; timeseries->end = end; return SDB_AST_NODE(timeseries); diff --git a/src/parser/grammar.y b/src/parser/grammar.y index 6654780..6189188 100644 --- a/src/parser/grammar.y +++ b/src/parser/grammar.y @@ -392,14 +392,36 @@ metric_store_clause: /* empty */ { $$.type = $$.id = NULL; $$.last_update = 0; } /* - * TIMESERIES . [START ] [END ]; + * TIMESERIES .[...] [START ] [END ]; * * Returns a time-series for the specified host's metric. */ timeseries_statement: TIMESERIES STRING '.' STRING start_clause end_clause { - $$ = sdb_ast_timeseries_create($2, $4, $5, $6); + $$ = sdb_ast_timeseries_create($2, $4, NULL, 0, $5, $6); + CK_OOM($$); + } + | + TIMESERIES STRING '.' STRING array start_clause end_clause + { + char **ds; + size_t ds_num; + + if ($5.type != (SDB_TYPE_ARRAY | SDB_TYPE_STRING)) { + sdb_parser_yyerrorf(&yylloc, scanner, YY_("syntax error, " + "unexpected array of type %s; expected STRING"), + SDB_TYPE_TO_STRING($5.type)); + sdb_data_free_datum(&$5); + free($2); + free($4); + YYABORT; + } + + ds = $5.data.array.values; + ds_num = $5.data.array.length; + + $$ = sdb_ast_timeseries_create($2, $4, ds, ds_num, $6, $7); CK_OOM($$); } ; -- 2.30.2