@@ -876,6 +876,101 @@ static int build_filter(struct tracefs_synth *synth,
return ret;
}
+static int test_event_exists(struct tep_handle *tep, struct sqlhist_bison *sb,
+ struct expr *expr, struct tep_event **pevent)
+{
+ const char *system = expr->field.system;
+ const char *event_name = expr->field.event;
+ struct tep_event *event;
+
+ event = tep_find_event_by_name(tep, system, event_name);
+ if (pevent)
+ *pevent = event;
+ if (event)
+ return 0;
+
+ sb->line_no = expr->line;
+ sb->line_idx = expr->idx;
+
+ parse_error(sb, expr->field.raw, "event not found\n");
+ return -1;
+}
+
+static int test_field_exists(struct tep_handle *tep, struct sqlhist_bison *sb,
+ struct expr *expr)
+{
+ struct tep_event *event;
+
+ if (test_event_exists(tep, sb, expr, &event))
+ return -1;
+
+ if (trace_verify_event_field(event, expr->field.field, NULL))
+ return 0;
+
+ sb->line_no = expr->line;
+ sb->line_idx = expr->idx;
+
+ parse_error(sb, expr->field.raw, "Field '%s' not part of event %s\n",
+ expr->field.field, expr->field.event);
+ return -1;
+}
+
+static void *field_match_error(struct tep_handle *tep, struct sqlhist_bison *sb,
+ struct match *match)
+{
+ switch (errno) {
+ case ENODEV:
+ case EBADE:
+ break;
+ default:
+ /* System error */
+ return NULL;
+ }
+
+ /* ENODEV means that an event or field does not exist */
+ if (errno == ENODEV) {
+ if (test_field_exists(tep, sb, match->lval))
+ return NULL;
+ if (test_field_exists(tep, sb, match->rval))
+ return NULL;
+ return NULL;
+ }
+
+ /* fields exist, but values are not compatible */
+ sb->line_no = match->lval->line;
+ sb->line_idx = match->lval->idx;
+
+ parse_error(sb, match->lval->field.raw,
+ "Field '%s' is not compatible to match field '%s'\n",
+ match->lval->field.raw, match->rval->field.raw);
+ return NULL;
+}
+
+static void *synth_init_error(struct tep_handle *tep, struct sql_table *table)
+{
+ struct sqlhist_bison *sb = table->sb;
+ struct match *match = table->matches;
+
+ switch (errno) {
+ case ENODEV:
+ case EBADE:
+ break;
+ default:
+ /* System error */
+ return NULL;
+ }
+
+ /* ENODEV could mean that start or end events do not exist */
+ if (errno == ENODEV) {
+ if (test_event_exists(tep, sb, table->from, NULL))
+ return NULL;
+ if (test_event_exists(tep, sb, table->to, NULL))
+ return NULL;
+ }
+
+ return field_match_error(tep, sb, match);
+}
+
static struct tracefs_synth *build_synth(struct tep_handle *tep,
const char *name,
struct sql_table *table)
@@ -926,7 +1021,7 @@ static struct tracefs_synth *build_synth(struct tep_handle *tep,
start_event, end_system, end_event,
start_match, end_match, NULL);
if (!synth)
- return NULL;
+ return synth_init_error(tep, table);
for (match = match->next; match; match = match->next) {
ret = test_match(table, match);
@@ -939,8 +1034,10 @@ static struct tracefs_synth *build_synth(struct tep_handle *tep,
ret = tracefs_synth_add_match_field(synth,
start_match,
end_match, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ field_match_error(tep, table->sb, match);
goto free;
+ }
}
for (expr = table->selections; expr; expr = expr->next) {