[PATCH v2 10/21] libtracefs: Add error message when match fields are not FROM and JOIN events

From: Steven Rostedt
Date: Tue Aug 03 2021 - 00:24:46 EST


From: "Steven Rostedt (VMware)" <rostedt@xxxxxxxxxxx>

It is required that the "match" content (the ON portion of the SQL
sequence) has a field from the FROM event and a field from the JOIN event.

If they do not, then give a better message about what went wrong.

To simplify addition of future errors, also add a parse_error() that calls into
sql_parse_error() with the appropriate "ap" argument. That is, parse_error()
takes a normal printf() form and then translates it to the vprintf from of
sql_parse_error.

Signed-off-by: Steven Rostedt (VMware) <rostedt@xxxxxxxxxxx>
---
src/tracefs-sqlhist.c | 43 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/src/tracefs-sqlhist.c b/src/tracefs-sqlhist.c
index 887c2441a39e..0489657bea03 100644
--- a/src/tracefs-sqlhist.c
+++ b/src/tracefs-sqlhist.c
@@ -8,6 +8,7 @@
*/
#include <trace-seq.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <errno.h>

#include "tracefs.h"
@@ -153,6 +154,16 @@ __hidden void sql_parse_error(struct sqlhist_bison *sb, const char *text,
trace_seq_destroy(&s);
}

+static void parse_error(struct sqlhist_bison *sb, const char *text,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ sql_parse_error(sb, text, fmt, ap);
+ va_end(ap);
+}
+
static inline unsigned int quick_hash(const char *str)
{
unsigned int val = 0;
@@ -582,6 +593,34 @@ static int update_vars(struct sql_table *table, struct field *event)
return 0;
}

+static int match_error(struct sqlhist_bison *sb, struct match *match,
+ struct field *lmatch, struct field *rmatch)
+{
+ struct field *lval = &match->lval->field;
+ struct field *rval = &match->rval->field;
+ struct field *field;
+ struct expr *expr;
+
+ if (lval->system != lmatch->system ||
+ lval->event != lmatch->event) {
+ expr = match->lval;
+ field = lval;
+ } else {
+ expr = match->rval;
+ field = rval;
+ }
+
+ sb->line_no = expr->line;
+ sb->line_idx = expr->idx;
+
+ parse_error(sb, field->raw,
+ "'%s' and '%s' must be a field for each event: '%s' and '%s'\n",
+ lval->raw, rval->raw, sb->table->to->field.raw,
+ sb->table->from->field.raw);
+
+ return -1;
+}
+
static int test_match(struct sql_table *table, struct match *match)
{
struct field *lval, *rval;
@@ -613,13 +652,13 @@ static int test_match(struct sql_table *table, struct match *match)
(rval->event != to->event) ||
(lval->system != from->system) ||
(lval->event != from->event))
- return -1;
+ return match_error(table->sb, match, from, to);
} else {
if ((rval->system != from->system) ||
(rval->event != from->event) ||
(lval->system != to->system) ||
(lval->event != to->event))
- return -1;
+ return match_error(table->sb, match, to, from);
}
return 0;
}
--
2.30.2