diff options
author | Steven Rostedt (Google) <rostedt@goodmis.org> | 2022-06-06 15:29:52 -0400 |
---|---|---|
committer | Steven Rostedt (Google) <rostedt@goodmis.org> | 2022-06-08 11:20:34 -0400 |
commit | 75545106144c42ddfad515244a23f023e0c42cf8 (patch) | |
tree | bf2b05e20f4f28c2e37541ec0a0f4f7051cc4a1f | |
parent | 00c6b5f6ba1747d09b5dff88a8ec26a331e4da28 (diff) | |
download | libtracefs-75545106144c42ddfad515244a23f023e0c42cf8.tar.gz |
libtracefs: Differentiate WHERE clause when FROM and TO events are the same
With "FROM sched_switch as start JOIN sched_switch AS end" and then
filtering with "WHERE start.prev_state = 2 && end.next_prio < 100" the
parser gets confused and uses the "start.next_prio" instead of the
"end.next_prio", making the filter only on the start event and not on the
end event as expected.
Fix it by testing the field type (FIELD_TO/FIELD_FROM) as well as the
system and event of the field when selecting which event the field is a
part of.
Link: https://lore.kernel.org/linux-trace-devel/20220606192953.334315-6-rostedt@goodmis.org
Tested-by: Harald Seiler <hws@denx.de>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r-- | src/tracefs-sqlhist.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/tracefs-sqlhist.c b/src/tracefs-sqlhist.c index 22e4b65..5205356 100644 --- a/src/tracefs-sqlhist.c +++ b/src/tracefs-sqlhist.c @@ -904,20 +904,21 @@ static int verify_filter_error(struct sqlhist_bison *sb, struct expr *expr, } static int do_verify_filter(struct sqlhist_bison *sb, struct filter *filter, - const char **system, const char **event) + const char **system, const char **event, + enum field_type *ftype) { int ret; if (filter->type == FILTER_OR || filter->type == FILTER_AND) { - ret = do_verify_filter(sb, &filter->lval->filter, system, event); + ret = do_verify_filter(sb, &filter->lval->filter, system, event, ftype); if (ret) return ret; - return do_verify_filter(sb, &filter->rval->filter, system, event); + return do_verify_filter(sb, &filter->rval->filter, system, event, ftype); } if (filter->type == FILTER_GROUP || filter->type == FILTER_NOT_GROUP) { - return do_verify_filter(sb, &filter->lval->filter, system, event); + return do_verify_filter(sb, &filter->lval->filter, system, event, ftype); } /* @@ -927,6 +928,7 @@ static int do_verify_filter(struct sqlhist_bison *sb, struct filter *filter, if (!*system && !*event) { *system = filter->lval->field.system; *event = filter->lval->field.event_name; + *ftype = filter->lval->field.ftype; return 0; } @@ -938,7 +940,8 @@ static int do_verify_filter(struct sqlhist_bison *sb, struct filter *filter, } static int verify_filter(struct sqlhist_bison *sb, struct filter *filter, - const char **system, const char **event) + const char **system, const char **event, + enum field_type *ftype) { int ret; @@ -949,17 +952,17 @@ static int verify_filter(struct sqlhist_bison *sb, struct filter *filter, case FILTER_NOT_GROUP: break; default: - return do_verify_filter(sb, filter, system, event); + return do_verify_filter(sb, filter, system, event, ftype); } - ret = do_verify_filter(sb, &filter->lval->filter, system, event); + ret = do_verify_filter(sb, &filter->lval->filter, system, event, ftype); if (ret) return ret; switch (filter->type) { case FILTER_OR: case FILTER_AND: - return do_verify_filter(sb, &filter->rval->filter, system, event); + return do_verify_filter(sb, &filter->rval->filter, system, event, ftype); default: return 0; } @@ -1516,16 +1519,18 @@ static struct tracefs_synth *build_synth(struct tep_handle *tep, for (expr = table->where; expr; expr = expr->next) { const char *filter_system = NULL; const char *filter_event = NULL; + enum field_type ftype = FIELD_NONE; bool *started; bool start; ret = verify_filter(table->sb, &expr->filter, &filter_system, - &filter_event); + &filter_event, &ftype); if (ret < 0) goto free; start = filter_system == start_system && - filter_event == start_event; + filter_event == start_event && + ftype != FIELD_TO; if (start) started = &started_start; |