diff mbox series

[5/6] libtracefs: Differentiate WHERE clause when FROM and TO events are the same

Message ID 20220606192953.334315-6-rostedt@goodmis.org (mailing list archive)
State Accepted
Commit 75545106144c42ddfad515244a23f023e0c42cf8
Headers show
Series libtracefs: Fixes for sqlhist | expand

Commit Message

Steven Rostedt June 6, 2022, 7:29 p.m. UTC
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

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.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 src/tracefs-sqlhist.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/src/tracefs-sqlhist.c b/src/tracefs-sqlhist.c
index 22e4b652e48b..5205356356a5 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;