aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2022-06-06 15:29:52 -0400
committerSteven Rostedt (Google) <rostedt@goodmis.org>2022-06-08 11:20:34 -0400
commit75545106144c42ddfad515244a23f023e0c42cf8 (patch)
treebf2b05e20f4f28c2e37541ec0a0f4f7051cc4a1f
parent00c6b5f6ba1747d09b5dff88a8ec26a331e4da28 (diff)
downloadlibtracefs-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.c25
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;