6
6
#include " caliper/reader/Aggregator.h"
7
7
#include " caliper/reader/CalQLParser.h"
8
8
#include " caliper/reader/FormatProcessor.h"
9
+ #include " caliper/reader/Preprocessor.h"
9
10
#include " caliper/reader/RecordSelector.h"
10
11
11
12
#include " caliper/tools-util/Args.h"
12
13
13
14
#include " caliper/common/Log.h"
14
15
15
16
#include " ../../common/util/parse_util.h"
17
+ #include " ../../common/util/format_util.h"
16
18
#include " ../../common/util/split.hpp"
17
19
18
20
#include " ../../services/Services.h"
@@ -98,6 +100,113 @@ parse_functioncall(std::istream& is, const QuerySpec::FunctionSignature* defs)
98
100
return std::make_pair (retid, std::move (args));
99
101
}
100
102
103
+ const char * s_calql_helpstr = R"helpstr(
104
+ The Caliper Query Language (CalQL) is used to to filter, aggregate, and create
105
+ reports from Caliper .cali data with cali-query.
106
+
107
+ The general structure of a query is:
108
+
109
+ LET
110
+ <list of pre-processing operations>
111
+ SELECT
112
+ <list of output attributes and aggregations>
113
+ GROUP BY
114
+ <list of aggregation key attributes>
115
+ WHERE
116
+ <list of conditions>
117
+ FORMAT
118
+ <report/output formatter>
119
+ ORDER BY
120
+ <list of sort attributes>
121
+
122
+ All of the statements are optional; by default cali-query will pass the input
123
+ records through as-is, without any aggregations, and output .cali data.
124
+ statements are case-insensitive and can be provided in any order.
125
+
126
+ Run "--help [let, select, groupby, where, format]" for more information about
127
+ each CalQL statement.
128
+ )helpstr" ;
129
+
130
+ const char * s_calql_let_helpstr = R"helpstr(
131
+ The LET statement defines operations to be applied on input records before
132
+ further processing. The general structure of the LET statement is
133
+
134
+ LET result = op(arguments) [ IF condition ] [, ... ]
135
+
136
+ This adds a new attribute "result" with the result of operation "op" to
137
+ the record. Results are only added if the operation was successful
138
+ (e.g., all required input operands were present in the record). If an
139
+ optional IF condition is given, the operation is only applied if the
140
+ condition is true.
141
+
142
+ Available LET operators:
143
+
144
+ )helpstr" ;
145
+
146
+ const char * s_calql_select_helpstr = R"helpstr(
147
+ The SELECT statement selects the attributes and aggregations in the output.
148
+ The general structure is
149
+
150
+ SELECT attribute | op(arguments) [ AS alias ] [ UNIT unit ] [, ...]
151
+
152
+ The aggregations in the SELECT statement specify how attributes are
153
+ aggregated. Use the GROUP BY statement to specify the output set. Use AS
154
+ to specify an optional custom label/header.
155
+
156
+ Available aggregation operations:
157
+
158
+ )helpstr" ;
159
+
160
+ const char * s_calql_groupby_helpstr = R"helpstr(
161
+ The GROUP BY statement selects the attributes that define the output set. For
162
+ example, when grouping by "mpi.rank", the output set has one record for each
163
+ mpi.rank value encountered in the input. Input records with the same mpi.rank
164
+ value will be aggregated as specified by the SELECT statement. The general
165
+ structure is
166
+
167
+ GROUP BY path | attribute name [, ...]
168
+
169
+ The "path" value selects all region name attributes for grouping.
170
+ )helpstr" ;
171
+
172
+ const char * s_calql_where_helpstr = R"helpstr(
173
+ Use the WHERE statement to filter input records. The filter is applied after
174
+ pre-processing (see LET) and before aggregating. The general structure is
175
+
176
+ WHERE [NOT] condition [, ...]
177
+
178
+ NOT negates the condition. Available conditions are:
179
+
180
+ attribute (matches if any entry for "attribute" is in the record)
181
+ attribute = value
182
+ attribute > value
183
+ attribute < value
184
+ )helpstr" ;
185
+
186
+ const char * s_calql_format_helpstr = R"helpstr(
187
+ The FORMAT statement selects and configures the output formatter. The general
188
+ structure is
189
+
190
+ FORMAT formatter [(arguments)] [ORDER BY attribute [ASC | DESC] [,...]]
191
+
192
+ The ORDER BY statement specifies a list of attributes to sort the output
193
+ records by. It can be used with the "table" and "tree" formatters.
194
+
195
+ Available formatters:
196
+
197
+ )helpstr" ;
198
+
199
+ std::ostream& print_function_signature (std::ostream& os, const QuerySpec::FunctionSignature& s)
200
+ {
201
+ os << " " << s.name << " (" ;
202
+ for (int i = 0 ; i < s.min_args ; ++i)
203
+ os << (i > 0 ? " , " : " " ) << s.args [i];
204
+ for (int i = s.min_args ; i < s.max_args ; ++i)
205
+ os << (i > 0 ? " , " : " " ) << s.args [i] << " *" ;
206
+ os << " )" ;
207
+ return os;
208
+ }
209
+
101
210
}
102
211
103
212
namespace cali
@@ -262,17 +371,50 @@ void print_caliquery_help(const Args& args, const char* usage, const ConfigManag
262
371
{
263
372
std::string helpopt = args.get (" help" );
264
373
265
- if (helpopt == " configs" ) {
374
+ if (helpopt == " configs" || helpopt == " recipes" ) {
375
+ std::cout << " Available config recipes:\n " ;
266
376
auto list = mgr.available_config_specs ();
377
+ size_t len = 0 ;
267
378
for (const auto &s : list)
268
- std::cout << mgr.get_documentation_for_spec (s.c_str ()) << " \n " ;
379
+ len = std::max (len, s.size ());
380
+ for (const auto &s : list) {
381
+ std::string descr = mgr.get_description_for_spec (s.c_str ());
382
+ util::pad_right (std::cout << " " , s, len) << descr << " \n " ;
383
+ }
269
384
} else if (helpopt == " services" ) {
385
+ std::cout << " Available services:\n " ;
270
386
services::add_default_service_specs ();
271
-
272
- int i = 0 ;
273
- for (const auto & s : services::get_available_services ())
274
- std::cout << (i++ > 0 ? " ," : " " ) << s;
275
- std::cout << std::endl;
387
+ auto list = services::get_available_services ();
388
+ size_t len = 0 ;
389
+ for (const auto &s : list)
390
+ len = std::max (len, s.size ());
391
+ for (const auto &s : list) {
392
+ std::string descr = services::get_service_description (s);
393
+ util::pad_right (std::cout << " " , s, len) << descr << " \n " ;
394
+ }
395
+ } else if (helpopt == " calql" ) {
396
+ std::cout << s_calql_helpstr;
397
+ } else if (helpopt == " let" ) {
398
+ std::cout << s_calql_let_helpstr;
399
+ const QuerySpec::FunctionSignature* ops = Preprocessor::preprocess_defs ();
400
+ for (const auto * p = ops; p && p->name ; ++p)
401
+ print_function_signature (std::cout, *p) << " \n " ;
402
+ } else if (helpopt == " select" ) {
403
+ std::cout << s_calql_select_helpstr;
404
+ const QuerySpec::FunctionSignature* ops = Aggregator::aggregation_defs ();
405
+ for (const auto * p = ops; p && p->name ; ++p) {
406
+ print_function_signature (std::cout, *p) << " -> " ;
407
+ std::vector<std::string> args (p->args , p->args +p->max_args );
408
+ const QuerySpec::AggregationOp op (*p, args);
409
+ std::cout << Aggregator::get_aggregation_attribute_name (op) << " \n " ;
410
+ }
411
+ } else if (helpopt == " where" ) {
412
+ std::cout << s_calql_where_helpstr;
413
+ } else if (helpopt == " format" ) {
414
+ std::cout << s_calql_format_helpstr;
415
+ const QuerySpec::FunctionSignature* ops = FormatProcessor::formatter_defs ();
416
+ for (const auto * p = ops; p && p->name ; ++p)
417
+ print_function_signature (std::cout, *p) << " \n " ;
276
418
} else if (!helpopt.empty ()) {
277
419
{
278
420
auto cfgs = mgr.available_config_specs ();
@@ -288,7 +430,7 @@ void print_caliquery_help(const Args& args, const char* usage, const ConfigManag
288
430
auto srvs = services::get_available_services ();
289
431
auto it = std::find (srvs.begin (), srvs.end (), helpopt);
290
432
if (it != srvs.end ()) {
291
- services::print_service_description (std::cout << *it << " service:\n " , helpopt. c_str () );
433
+ services::print_service_documentation (std::cout << *it << " service:\n " , helpopt);
292
434
return ;
293
435
}
294
436
}
@@ -302,6 +444,13 @@ void print_caliquery_help(const Args& args, const char* usage, const ConfigManag
302
444
} else {
303
445
std::cout << usage << " \n\n " ;
304
446
args.print_available_options (std::cout);
447
+ std::cout <<
448
+ " \n Use \" --help configs\" to list all config recipes."
449
+ " \n Use \" --help services\" to list all available services."
450
+ " \n Use \" --help [recipe name]\" to get help for a config recipe."
451
+ " \n Use \" --help [service name]\" to get help for a service."
452
+ " \n Use \" --help calql\" to get help for the CalQL query language."
453
+ " \n Use \" --help [let,select,where,groupby,format]\" to get help for CalQL statements.\n " ;
305
454
}
306
455
}
307
456
0 commit comments