• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  * Copyright (C) 2021 VMware Inc, Steven Rostedt <rostedt@goodmis.org>
4  *
5  * Updates:
6  * Copyright (C) 2021, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
7  *
8  */
9 #include <trace-seq.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <ctype.h>
13 #include <errno.h>
14 
15 #include "tracefs.h"
16 #include "tracefs-local.h"
17 #include "sqlhist-parse.h"
18 
19 extern int yylex_init(void* ptr_yy_globals);
20 extern int yylex_init_extra(struct sqlhist_bison *sb, void* ptr_yy_globals);
21 extern int yylex_destroy (void * yyscanner );
22 
23 struct str_hash {
24 	struct str_hash		*next;
25 	char			*str;
26 };
27 
28 enum alias_type {
29 	ALIAS_EVENT,
30 	ALIAS_FIELD,
31 };
32 
33 enum field_type {
34 	FIELD_NONE,
35 	FIELD_FROM,
36 	FIELD_TO,
37 };
38 
39 #define for_each_field(expr, field, table) \
40 	for (expr = (table)->fields; expr; expr = (field)->next)
41 
42 struct field {
43 	struct expr		*next;	/* private link list */
44 	const char		*system;
45 	const char		*event_name;
46 	struct tep_event	*event;
47 	const char		*raw;
48 	const char		*label;
49 	const char		*field;
50 	const char		*type;
51 	enum field_type		ftype;
52 };
53 
54 struct filter {
55 	enum filter_type	type;
56 	struct expr		*lval;
57 	struct expr		*rval;
58 };
59 
60 struct match {
61 	struct match		*next;
62 	struct expr		*lval;
63 	struct expr		*rval;
64 };
65 
66 struct compare {
67 	enum compare_type	type;
68 	struct expr		*lval;
69 	struct expr		*rval;
70 	const char		*name;
71 };
72 
73 enum expr_type
74 {
75 	EXPR_NUMBER,
76 	EXPR_STRING,
77 	EXPR_FIELD,
78 	EXPR_FILTER,
79 	EXPR_COMPARE,
80 };
81 
82 struct expr {
83 	struct expr		*free_list;
84 	struct expr		*next;
85 	enum expr_type		type;
86 	int			line;
87 	int			idx;
88 	union {
89 		struct field	field;
90 		struct filter	filter;
91 		struct compare	compare;
92 		const char	*string;
93 		long		number;
94 	};
95 };
96 
97 struct sql_table {
98 	struct sqlhist_bison	*sb;
99 	const char		*name;
100 	struct expr		*exprs;
101 	struct expr		*fields;
102 	struct expr		*from;
103 	struct expr		*to;
104 	struct expr		*where;
105 	struct expr		**next_where;
106 	struct match		*matches;
107 	struct match		**next_match;
108 	struct expr		*selections;
109 	struct expr		**next_selection;
110 };
111 
my_yyinput(void * extra,char * buf,int max)112 __hidden int my_yyinput(void *extra, char *buf, int max)
113 {
114 	struct sqlhist_bison *sb = extra;
115 
116 	if (!sb || !sb->buffer)
117 		return -1;
118 
119 	if (sb->buffer_idx + max > sb->buffer_size)
120 		max = sb->buffer_size - sb->buffer_idx;
121 
122 	if (max)
123 		memcpy(buf, sb->buffer + sb->buffer_idx, max);
124 
125 	sb->buffer_idx += max;
126 
127 	return max;
128 }
129 
sql_parse_error(struct sqlhist_bison * sb,const char * text,const char * fmt,va_list ap)130 __hidden void sql_parse_error(struct sqlhist_bison *sb, const char *text,
131 			      const char *fmt, va_list ap)
132 {
133 	const char *buffer = sb->buffer;
134 	struct trace_seq s;
135 	int line = sb->line_no;
136 	int idx = sb->line_idx - strlen(text);
137 	int i;
138 
139 	if (!buffer)
140 		return;
141 
142 	trace_seq_init(&s);
143 	if (!s.buffer) {
144 		tracefs_warning("Error allocating internal buffer\n");
145 		return;
146 	}
147 
148 	for (i = 0; line && buffer[i]; i++) {
149 		if (buffer[i] == '\n')
150 			line--;
151 	}
152 	for (; buffer[i] && buffer[i] != '\n'; i++)
153 		trace_seq_putc(&s, buffer[i]);
154 	trace_seq_putc(&s, '\n');
155 	for (i = idx; i > 0; i--)
156 		trace_seq_putc(&s, ' ');
157 	trace_seq_puts(&s, "^\n");
158 	trace_seq_printf(&s, "ERROR: '%s'\n", text);
159 	trace_seq_vprintf(&s, fmt, ap);
160 
161 	trace_seq_terminate(&s);
162 
163 	sb->parse_error_str = strdup(s.buffer);
164 	trace_seq_destroy(&s);
165 }
166 
parse_error(struct sqlhist_bison * sb,const char * text,const char * fmt,...)167 static void parse_error(struct sqlhist_bison *sb, const char *text,
168 			const char *fmt, ...)
169 {
170 	va_list ap;
171 
172 	va_start(ap, fmt);
173 	sql_parse_error(sb, text, fmt, ap);
174 	va_end(ap);
175 }
176 
quick_hash(const char * str)177 __hidden unsigned int quick_hash(const char *str)
178 {
179 	unsigned int val = 0;
180 	int len = strlen(str);
181 
182 	for (; len >= 4; str += 4, len -= 4) {
183 		val += str[0];
184 		val += str[1] << 8;
185 		val += str[2] << 16;
186 		val += str[3] << 24;
187 	}
188 	for (; len > 0; str++, len--)
189 		val += str[0] << (len * 8);
190 
191         val *= 2654435761;
192 
193         return val & ((1 << HASH_BITS) - 1);
194 }
195 
196 
find_string(struct sqlhist_bison * sb,const char * str)197 static struct str_hash *find_string(struct sqlhist_bison *sb, const char *str)
198 {
199 	unsigned int key = quick_hash(str);
200 	struct str_hash *hash = sb->str_hash[key];
201 
202 	for (; hash; hash = hash->next) {
203 		if (!strcmp(hash->str, str))
204 			return hash;
205 	}
206 	return NULL;
207 }
208 
209 /*
210  * If @str is found, then return the hash string.
211  * This lets store_str() know to free str.
212  */
add_hash(struct sqlhist_bison * sb,const char * str)213 static char **add_hash(struct sqlhist_bison *sb, const char *str)
214 {
215 	struct str_hash *hash;
216 	unsigned int key;
217 
218 	if ((hash = find_string(sb, str))) {
219 		return &hash->str;
220 	}
221 
222 	hash = malloc(sizeof(*hash));
223 	if (!hash)
224 		return NULL;
225 	key = quick_hash(str);
226 	hash->next = sb->str_hash[key];
227 	sb->str_hash[key] = hash;
228 	hash->str = NULL;
229 	return &hash->str;
230 }
231 
store_str(struct sqlhist_bison * sb,const char * str)232 __hidden char *store_str(struct sqlhist_bison *sb, const char *str)
233 {
234 	char **pstr = add_hash(sb, str);
235 
236 	if (!pstr)
237 		return NULL;
238 
239 	if (!(*pstr))
240 		*pstr = strdup(str);
241 
242 	return *pstr;
243 }
244 
add_cast(struct sqlhist_bison * sb,void * data,const char * type)245 __hidden void *add_cast(struct sqlhist_bison *sb,
246 			void *data, const char *type)
247 {
248 	struct expr *expr = data;
249 	struct field *field = &expr->field;
250 
251 	field->type = type;
252 	return expr;
253 }
254 
add_selection(struct sqlhist_bison * sb,void * select,const char * name)255 __hidden int add_selection(struct sqlhist_bison *sb, void *select,
256 			   const char *name)
257 {
258 	struct sql_table *table = sb->table;
259 	struct expr *expr = select;
260 
261 	switch (expr->type) {
262 	case EXPR_FIELD:
263 		expr->field.label = name;
264 		break;
265 	case EXPR_COMPARE:
266 		expr->compare.name = name;
267 		break;
268 	case EXPR_NUMBER:
269 	case EXPR_STRING:
270 	case EXPR_FILTER:
271 	default:
272 		return -1;
273 	}
274 
275 	if (expr->next)
276 		return -1;
277 
278 	*table->next_selection = expr;
279 	table->next_selection = &expr->next;
280 
281 	return 0;
282 }
283 
find_field(struct sqlhist_bison * sb,const char * raw,const char * label)284 static struct expr *find_field(struct sqlhist_bison *sb,
285 				const char *raw, const char *label)
286 {
287 	struct field *field;
288 	struct expr *expr;
289 
290 	for_each_field(expr, field, sb->table) {
291 		field = &expr->field;
292 
293 		if (!strcmp(field->raw, raw)) {
294 			if (label && !field->label)
295 				field->label = label;
296 			if (label && strcmp(label, field->label) != 0)
297 				continue;
298 			return expr;
299 		}
300 
301 		if (label && !strcmp(field->raw, label)) {
302 			if (!field->label) {
303 				field->label = label;
304 				field->raw = raw;
305 			}
306 			return expr;
307 		}
308 
309 		if (!field->label)
310 			continue;
311 
312 		if (!strcmp(field->label, raw))
313 			return expr;
314 
315 		if (label && !strcmp(field->label, label))
316 			return expr;
317 	}
318 	return NULL;
319 }
320 
create_expr(struct sqlhist_bison * sb,enum expr_type type,struct expr ** expr_p)321 static void *create_expr(struct sqlhist_bison *sb,
322 			 enum expr_type type, struct expr **expr_p)
323 {
324 	struct expr *expr;
325 
326 	expr = calloc(1, sizeof(*expr));
327 	if (!expr)
328 		return NULL;
329 
330 	if (expr_p)
331 		*expr_p = expr;
332 
333 	expr->free_list = sb->table->exprs;
334 	sb->table->exprs = expr;
335 
336 	expr->type = type;
337 	expr->line = sb->line_no;
338 	expr->idx = sb->line_idx;
339 
340 	switch (type) {
341 	case EXPR_FIELD:	return &expr->field;
342 	case EXPR_COMPARE:	return &expr->compare;
343 	case EXPR_NUMBER:	return &expr->number;
344 	case EXPR_STRING:	return &expr->string;
345 	case EXPR_FILTER:	return &expr->filter;
346 	}
347 
348 	return NULL;
349 }
350 
351 #define __create_expr(var, type, ENUM, expr)			\
352 	do {							\
353 		var = (type *)create_expr(sb, EXPR_##ENUM, expr);	\
354 	} while(0)
355 
356 #define create_field(var, expr)				\
357 	__create_expr(var, struct field, FIELD, expr)
358 
359 #define create_filter(var, expr)			\
360 	__create_expr(var, struct filter, FILTER, expr)
361 
362 #define create_compare(var, expr)				\
363 	__create_expr(var, struct compare, COMPARE, expr)
364 
365 #define create_string(var, expr)			\
366 	__create_expr(var, const char *, STRING, expr)
367 
368 #define create_number(var, expr)			\
369 	__create_expr(var, long, NUMBER, expr)
370 
add_field(struct sqlhist_bison * sb,const char * field_name,const char * label)371 __hidden void *add_field(struct sqlhist_bison *sb,
372 			 const char *field_name, const char *label)
373 {
374 	struct sql_table *table = sb->table;
375 	struct expr *expr;
376 	struct field *field;
377 
378 	expr = find_field(sb, field_name, label);
379 	if (expr)
380 		return expr;
381 
382 	create_field(field, &expr);
383 
384 	field->next = table->fields;
385 	table->fields = expr;
386 
387 	field->raw = field_name;
388 	field->label = label;
389 
390 	return expr;
391 }
392 
add_filter(struct sqlhist_bison * sb,void * A,void * B,enum filter_type op)393 __hidden void *add_filter(struct sqlhist_bison *sb,
394 			  void *A, void *B, enum filter_type op)
395 {
396 	struct filter *filter;
397 	struct expr *expr;
398 
399 	create_filter(filter, &expr);
400 
401 	filter->lval = A;
402 	filter->rval = B;
403 
404 	filter->type = op;
405 
406 	return expr;
407 }
408 
add_match(struct sqlhist_bison * sb,void * A,void * B)409 __hidden int add_match(struct sqlhist_bison *sb, void *A, void *B)
410 {
411 	struct sql_table *table = sb->table;
412 	struct match *match;
413 
414 	match = calloc(1, sizeof(*match));
415 	if (!match)
416 		return -1;
417 
418 	match->lval = A;
419 	match->rval = B;
420 
421 	*table->next_match = match;
422 	table->next_match = &match->next;
423 
424 	return 0;
425 }
add_compare(struct sqlhist_bison * sb,void * A,void * B,enum compare_type type)426 __hidden void *add_compare(struct sqlhist_bison *sb,
427 			   void *A, void *B, enum compare_type type)
428 {
429 	struct compare *compare;
430 	struct expr *expr;
431 
432 	create_compare(compare, &expr);
433 
434 	compare = &expr->compare;
435 	compare->lval = A;
436 	compare->rval = B;
437 	compare->type = type;
438 
439 	return expr;
440 }
441 
add_where(struct sqlhist_bison * sb,void * item)442 __hidden int add_where(struct sqlhist_bison *sb, void *item)
443 {
444 	struct expr *expr = item;
445 	struct sql_table *table = sb->table;
446 
447 	if (expr->type != EXPR_FILTER)
448 		return -1;
449 
450 	*table->next_where = expr;
451 	table->next_where = &expr->next;
452 
453 	if (expr->next)
454 		return -1;
455 
456 	return 0;
457 }
458 
add_from(struct sqlhist_bison * sb,void * item)459 __hidden int add_from(struct sqlhist_bison *sb, void *item)
460 {
461 	struct expr *expr = item;
462 
463 	if (expr->type != EXPR_FIELD)
464 		return -1;
465 
466 	sb->table->from = expr;
467 
468 	return 0;
469 }
470 
add_to(struct sqlhist_bison * sb,void * item)471 __hidden int add_to(struct sqlhist_bison *sb, void *item)
472 {
473 	struct expr *expr = item;
474 
475 	if (expr->type != EXPR_FIELD)
476 		return -1;
477 
478 	sb->table->to = expr;
479 
480 	return 0;
481 }
482 
add_string(struct sqlhist_bison * sb,const char * str)483 __hidden void *add_string(struct sqlhist_bison *sb, const char *str)
484 {
485 	struct expr *expr;
486 	const char **str_p;
487 
488 	create_string(str_p, &expr);
489 	*str_p = str;
490 	return expr;
491 }
492 
add_number(struct sqlhist_bison * sb,long val)493 __hidden void *add_number(struct sqlhist_bison *sb, long val)
494 {
495 	struct expr *expr;
496 	long *num;
497 
498 	create_number(num, &expr);
499 	*num = val;
500 	return expr;
501 }
502 
table_start(struct sqlhist_bison * sb)503 __hidden int table_start(struct sqlhist_bison *sb)
504 {
505 	struct sql_table *table;
506 
507 	table = calloc(1, sizeof(*table));
508 	if (!table)
509 		return -ENOMEM;
510 
511 	table->sb = sb;
512 	sb->table = table;
513 
514 	table->next_where = &table->where;
515 	table->next_match = &table->matches;
516 	table->next_selection = &table->selections;
517 
518 	return 0;
519 }
520 
test_event_exists(struct tep_handle * tep,struct sqlhist_bison * sb,struct expr * expr,struct tep_event ** pevent)521 static int test_event_exists(struct tep_handle *tep,
522 			     struct sqlhist_bison *sb,
523 			     struct expr *expr, struct tep_event **pevent)
524 {
525 	struct field *field = &expr->field;
526 	const char *system = field->system;
527 	const char *event = field->event_name;
528 
529 	if (!field->event)
530 		field->event = tep_find_event_by_name(tep, system, event);
531 	if (pevent)
532 		*pevent = field->event;
533 
534 	if (field->event)
535 		return 0;
536 
537 	sb->line_no = expr->line;
538 	sb->line_idx = expr->idx;
539 
540 	parse_error(sb, field->raw, "event not found\n");
541 	return -1;
542 }
543 
test_field_exists(struct tep_handle * tep,struct sqlhist_bison * sb,struct expr * expr)544 static int test_field_exists(struct tep_handle *tep,
545 			     struct sqlhist_bison *sb,
546 			     struct expr *expr)
547 {
548 	struct field *field = &expr->field;
549 	struct tep_format_field *tfield;
550 	char *field_name;
551 	const char *p;
552 
553 	if (!field->event) {
554 		if (test_event_exists(tep, sb, expr, NULL))
555 			return -1;
556 	}
557 
558 	/* The field could have a conversion */
559 	p = strchr(field->field, '.');
560 	if (p)
561 		field_name = strndup(field->field, p - field->field);
562 	else
563 		field_name = strdup(field->field);
564 
565 	if (!field_name)
566 		return -1;
567 
568 	if (!strcmp(field_name, TRACEFS_TIMESTAMP) ||
569 	    !strcmp(field->field, TRACEFS_TIMESTAMP_USECS))
570 		tfield = (void *)1L;
571 	else
572 		tfield = tep_find_any_field(field->event, field_name);
573 	free(field_name);
574 
575 	if (!tfield && (!strcmp(field->field, "COMM") || !strcmp(field->field, "comm")))
576 		tfield = (void *)1L;
577 
578 	if (tfield)
579 		return 0;
580 
581 	sb->line_no = expr->line;
582 	sb->line_idx = expr->idx;
583 
584 	parse_error(sb, field->raw,
585 		    "Field '%s' not part of event %s\n",
586 		    field->field, field->event_name);
587 	return -1;
588 }
589 
update_vars(struct tep_handle * tep,struct sql_table * table,struct expr * expr)590 static int update_vars(struct tep_handle *tep,
591 		       struct sql_table *table,
592 		       struct expr *expr)
593 {
594 	struct sqlhist_bison *sb = table->sb;
595 	struct field *event_field = &expr->field;
596 	enum field_type ftype = FIELD_NONE;
597 	struct tep_event *event;
598 	struct field *field;
599 	const char *label;
600 	const char *raw = event_field->raw;
601 	const char *event_name;
602 	const char *system;
603 	const char *p;
604 	int label_len = 0, event_len, system_len;
605 
606 	if (expr == table->to)
607 		ftype = FIELD_TO;
608 	else if (expr == table->from)
609 		ftype = FIELD_FROM;
610 
611 	p = strchr(raw, '.');
612 	if (p) {
613 		char *str;
614 
615 		str = strndup(raw, p - raw);
616 		if (!str)
617 			return -1;
618 		event_field->system = store_str(sb, str);
619 		free(str);
620 		if (!event_field->system)
621 			return -1;
622 		p++;
623 	} else {
624 		p = raw;
625 	}
626 
627 	event_field->event_name = store_str(sb, p);
628 	if (!event_field->event_name)
629 		return -1;
630 
631 	if (test_event_exists(tep, sb, expr, &event))
632 		return -1;
633 
634 	if (!event_field->system)
635 		event_field->system = store_str(sb, event->system);
636 
637 	if (!event_field->system)
638 		return -1;
639 
640 	label = event_field->label;
641 	if (label)
642 		label_len = strlen(label);
643 
644 	system = event_field->system;
645 	system_len = strlen(system);
646 
647 	event_name = event_field->event_name;
648 	event_len = strlen(event_name);
649 
650 	for_each_field(expr, field, table) {
651 		int len;
652 
653 		field = &expr->field;
654 
655 		if (field->event)
656 			continue;
657 
658 		raw = field->raw;
659 
660 		/*
661 		 * The field could be:
662 		 *     system.event.field...
663 		 *     event.field...
664 		 *     label.field...
665 		 * We check label first.
666 		 */
667 
668 		len = label_len;
669 		if (label && !strncmp(raw, label, len) &&
670 		    raw[len] == '.') {
671 			/* Label matches and takes precedence */
672 			goto found;
673 		}
674 
675 		if (!strncmp(raw, system, system_len) &&
676 		    raw[system_len] == '.') {
677 			raw += system_len + 1;
678 			/* Check the event portion next */
679 		}
680 
681 		len = event_len;
682 		if (strncmp(raw, event_name, len) ||
683 		    raw[len] != '.') {
684 			/* Does not match */
685 			continue;
686 		}
687  found:
688 		field->system = system;
689 		field->event_name = event_name;
690 		field->event = event;
691 		field->field = raw + len + 1;
692 		field->ftype = ftype;
693 
694 		if (!strcmp(field->field, "TIMESTAMP"))
695 			field->field = store_str(sb, TRACEFS_TIMESTAMP);
696 		if (!strcmp(field->field, "TIMESTAMP_USECS"))
697 			field->field = store_str(sb, TRACEFS_TIMESTAMP_USECS);
698 		if (test_field_exists(tep, sb, expr))
699 			return -1;
700 	}
701 
702 	return 0;
703 }
704 
705 /*
706  * Called when there's a FROM but no JOIN(to), which means that the
707  * selections can be fields and not mention the event itself.
708  */
update_fields(struct tep_handle * tep,struct sql_table * table,struct expr * expr)709 static int update_fields(struct tep_handle *tep,
710 			 struct sql_table *table,
711 			 struct expr *expr)
712 {
713 	struct field *event_field = &expr->field;
714 	struct sqlhist_bison *sb = table->sb;
715 	struct tep_format_field *tfield;
716 	struct tep_event *event;
717 	struct field *field;
718 	const char *p;
719 	int len;
720 
721 	/* First update fields with aliases an such and add event */
722 	update_vars(tep, table, expr);
723 
724 	/*
725 	 * If event is not found, the creation of the synth will
726 	 * add a proper error, so return "success".
727 	*/
728 	if (!event_field->event)
729 		return 0;
730 
731 	event = event_field->event;
732 
733 	for_each_field(expr, field, table) {
734 		const char *field_name;
735 
736 		field = &expr->field;
737 
738 		if (field->event)
739 			continue;
740 
741 		field_name = field->raw;
742 
743 		p = strchr(field_name, '.');
744 		if (p) {
745 			len = p - field_name;
746 			p = strndup(field_name, len);
747 			if (!p)
748 				return -1;
749 			field_name = store_str(sb, p);
750 			if (!field_name)
751 				return -1;
752 			free((char *)p);
753 		}
754 
755 		tfield = tep_find_any_field(event, field_name);
756 		/* Let it error properly later */
757 		if (!tfield)
758 			continue;
759 
760 		field->system = event_field->system;
761 		field->event_name = event_field->event_name;
762 		field->event = event;
763 		field->field = field_name;
764 	}
765 
766 	return 0;
767 }
768 
match_error(struct sqlhist_bison * sb,struct match * match,struct field * lmatch,struct field * rmatch)769 static int match_error(struct sqlhist_bison *sb, struct match *match,
770 		       struct field *lmatch, struct field *rmatch)
771 {
772 	struct field *lval = &match->lval->field;
773 	struct field *rval = &match->rval->field;
774 	struct field *field;
775 	struct expr *expr;
776 
777 	if (lval->system != lmatch->system ||
778 	    lval->event != lmatch->event) {
779 		expr = match->lval;
780 		field = lval;
781 	} else {
782 		expr = match->rval;
783 		field = rval;
784 	}
785 
786 	sb->line_no = expr->line;
787 	sb->line_idx = expr->idx;
788 
789 	parse_error(sb, field->raw,
790 		    "'%s' and '%s' must be a field for each event: '%s' and '%s'\n",
791 		    lval->raw, rval->raw, sb->table->to->field.raw,
792 		    sb->table->from->field.raw);
793 
794 	return -1;
795 }
796 
test_match(struct sql_table * table,struct match * match)797 static int test_match(struct sql_table *table, struct match *match)
798 {
799 	struct field *lval, *rval;
800 	struct field *to, *from;
801 
802 	if (!match->lval || !match->rval)
803 		return -1;
804 
805 	if (match->lval->type != EXPR_FIELD || match->rval->type != EXPR_FIELD)
806 		return -1;
807 
808 	to = &table->to->field;
809 	from = &table->from->field;
810 
811 	lval = &match->lval->field;
812 	rval = &match->rval->field;
813 
814 	/*
815 	 * Note, strings are stored in the string store, so all
816 	 * duplicate strings are the same value, and we can use
817 	 * normal "==" and "!=" instead of strcmp().
818 	 *
819 	 * Either lval == to and rval == from
820 	 * or lval == from and rval == to.
821 	 */
822 	if ((lval->system != to->system) ||
823 	    (lval->event != to->event)) {
824 		if ((rval->system != to->system) ||
825 		    (rval->event != to->event) ||
826 		    (lval->system != from->system) ||
827 		    (lval->event != from->event))
828 			return match_error(table->sb, match, from, to);
829 	} else {
830 		if ((rval->system != from->system) ||
831 		    (rval->event != from->event) ||
832 		    (lval->system != to->system) ||
833 		    (lval->event != to->event))
834 			return match_error(table->sb, match, to, from);
835 	}
836 	return 0;
837 }
838 
assign_match(const char * system,const char * event,struct match * match,const char ** start_match,const char ** end_match)839 static void assign_match(const char *system, const char *event,
840 			 struct match *match,
841 			 const char **start_match, const char **end_match)
842 {
843 	struct field *lval, *rval;
844 
845 	lval = &match->lval->field;
846 	rval = &match->rval->field;
847 
848 	if (lval->system == system &&
849 	    lval->event_name == event) {
850 		*start_match = lval->field;
851 		*end_match = rval->field;
852 	} else {
853 		*start_match = rval->field;
854 		*end_match = lval->field;
855 	}
856 }
857 
build_compare(struct tracefs_synth * synth,const char * system,const char * event,struct compare * compare)858 static int build_compare(struct tracefs_synth *synth,
859 			 const char *system, const char *event,
860 			 struct compare *compare)
861 {
862 	const char *start_field;
863 	const char *end_field;
864 	struct field *lval, *rval;
865 	enum tracefs_synth_calc calc;
866 	int ret;
867 
868 	if (!compare->name)
869 		return -1;
870 
871 	lval = &compare->lval->field;
872 	rval = &compare->rval->field;
873 
874 	if (lval->system == system &&
875 	    lval->event_name == event) {
876 		start_field = lval->field;
877 		end_field = rval->field;
878 		calc = TRACEFS_SYNTH_DELTA_START;
879 	} else {
880 		start_field = rval->field;
881 		end_field = lval->field;
882 		calc = TRACEFS_SYNTH_DELTA_END;
883 	}
884 
885 	if (compare->type == COMPARE_ADD)
886 		calc = TRACEFS_SYNTH_ADD;
887 
888 	ret = tracefs_synth_add_compare_field(synth, start_field,
889 					      end_field, calc,
890 					      compare->name);
891 	return ret;
892 }
893 
verify_filter_error(struct sqlhist_bison * sb,struct expr * expr,const char * event)894 static int verify_filter_error(struct sqlhist_bison *sb, struct expr *expr,
895 			       const char *event)
896 {
897 	struct field *field = &expr->field;
898 
899 	sb->line_no = expr->line;
900 	sb->line_idx = expr->idx;
901 
902 	parse_error(sb, field->raw,
903 		    "event '%s' can not be grouped or '||' together with '%s'\n"
904 		    "All filters between '&&' must be for the same event\n",
905 		    field->event, event);
906 	return -1;
907 }
908 
do_verify_filter(struct sqlhist_bison * sb,struct filter * filter,const char ** system,const char ** event,enum field_type * ftype)909 static int do_verify_filter(struct sqlhist_bison *sb, struct filter *filter,
910 			    const char **system, const char **event,
911 			    enum field_type *ftype)
912 {
913 	int ret;
914 
915 	if (filter->type == FILTER_OR ||
916 	    filter->type == FILTER_AND) {
917 		ret = do_verify_filter(sb, &filter->lval->filter, system, event, ftype);
918 		if (ret)
919 			return ret;
920 		return do_verify_filter(sb, &filter->rval->filter, system, event, ftype);
921 	}
922 	if (filter->type == FILTER_GROUP ||
923 	    filter->type == FILTER_NOT_GROUP) {
924 		return do_verify_filter(sb, &filter->lval->filter, system, event, ftype);
925 	}
926 
927 	/*
928 	 * system and event will be NULL until we find the left most
929 	 * node. Then assign it, and compare on the way back up.
930 	 */
931 	if (!*system && !*event) {
932 		*system = filter->lval->field.system;
933 		*event = filter->lval->field.event_name;
934 		*ftype = filter->lval->field.ftype;
935 		return 0;
936 	}
937 
938 	if (filter->lval->field.system != *system ||
939 	    filter->lval->field.event_name != *event)
940 		return verify_filter_error(sb, filter->lval, *event);
941 
942 	return 0;
943 }
944 
verify_filter(struct sqlhist_bison * sb,struct filter * filter,const char ** system,const char ** event,enum field_type * ftype)945 static int verify_filter(struct sqlhist_bison *sb, struct filter *filter,
946 			 const char **system, const char **event,
947 			 enum field_type *ftype)
948 {
949 	int ret;
950 
951 	switch (filter->type) {
952 	case FILTER_OR:
953 	case FILTER_AND:
954 	case FILTER_GROUP:
955 	case FILTER_NOT_GROUP:
956 		break;
957 	default:
958 		return do_verify_filter(sb, filter, system, event, ftype);
959 	}
960 
961 	ret = do_verify_filter(sb, &filter->lval->filter, system, event, ftype);
962 	if (ret)
963 		return ret;
964 
965 	switch (filter->type) {
966 	case FILTER_OR:
967 	case FILTER_AND:
968 		return do_verify_filter(sb, &filter->rval->filter, system, event, ftype);
969 	default:
970 		return 0;
971 	}
972 }
973 
974 static int test_field_exists(struct tep_handle *tep, struct sqlhist_bison *sb,
975 			     struct expr *expr);
976 
filter_compare_error(struct tep_handle * tep,struct sqlhist_bison * sb,struct expr * expr)977 static void filter_compare_error(struct tep_handle *tep,
978 				 struct sqlhist_bison *sb,
979 				 struct expr *expr)
980 {
981 	struct field *field = &expr->field;
982 
983 	switch (errno) {
984 	case ENODEV:
985 	case EBADE:
986 		break;
987 	case EINVAL:
988 		parse_error(sb, field->raw, "Invalid compare\n");
989 		break;
990 	default:
991 		parse_error(sb, field->raw, "System error?\n");
992 		return;
993 	}
994 
995 	/* ENODEV means that an event or field does not exist */
996 	if (errno == ENODEV) {
997 		if (test_field_exists(tep, sb, expr))
998 			return;
999 		if (test_field_exists(tep, sb, expr))
1000 			return;
1001 		return;
1002 	}
1003 
1004 	/* fields exist, but values are not compatible */
1005 	sb->line_no = expr->line;
1006 	sb->line_idx = expr->idx;
1007 
1008 	parse_error(sb, field->raw,
1009 		    "Field '%s' is not compatible to be compared with the given value\n",
1010 		    field->field);
1011 }
1012 
filter_error(struct tep_handle * tep,struct sqlhist_bison * sb,struct expr * expr)1013 static void filter_error(struct tep_handle *tep,
1014 			 struct sqlhist_bison *sb, struct expr *expr)
1015 {
1016 	struct filter *filter = &expr->filter;
1017 
1018 	sb->line_no = expr->line;
1019 	sb->line_idx = expr->idx;
1020 
1021 	switch (filter->type) {
1022 	case FILTER_NOT_GROUP:
1023 	case FILTER_GROUP:
1024 	case FILTER_OR:
1025 	case FILTER_AND:
1026 		break;
1027 	default:
1028 		filter_compare_error(tep, sb, filter->lval);
1029 		return;
1030 	}
1031 
1032 	sb->line_no = expr->line;
1033 	sb->line_idx = expr->idx;
1034 
1035 	parse_error(sb, "", "Problem with filter entry?\n");
1036 }
1037 
build_filter(struct tep_handle * tep,struct sqlhist_bison * sb,struct tracefs_synth * synth,bool start,struct expr * expr,bool * started)1038 static int build_filter(struct tep_handle *tep, struct sqlhist_bison *sb,
1039 			struct tracefs_synth *synth,
1040 			bool start, struct expr *expr, bool *started)
1041 {
1042 	int (*append_filter)(struct tracefs_synth *synth,
1043 			     enum tracefs_filter type,
1044 			     const char *field,
1045 			     enum tracefs_compare compare,
1046 			     const char *val);
1047 	struct filter *filter = &expr->filter;
1048 	enum tracefs_compare cmp;
1049 	const char *val;
1050 	int and_or = TRACEFS_FILTER_AND;
1051 	char num[64];
1052 	int ret;
1053 
1054 	if (start)
1055 		append_filter = tracefs_synth_append_start_filter;
1056 	else
1057 		append_filter = tracefs_synth_append_end_filter;
1058 
1059 	if (started && *started) {
1060 		ret = append_filter(synth, and_or, NULL, 0, NULL);
1061 		ret = append_filter(synth, TRACEFS_FILTER_OPEN_PAREN,
1062 				    NULL, 0, NULL);
1063 	}
1064 
1065 	switch (filter->type) {
1066 	case FILTER_NOT_GROUP:
1067 		ret = append_filter(synth, TRACEFS_FILTER_NOT,
1068 				    NULL, 0, NULL);
1069 		if (ret < 0)
1070 			goto out;
1071 		/* Fall through */
1072 	case FILTER_GROUP:
1073 		ret = append_filter(synth, TRACEFS_FILTER_OPEN_PAREN,
1074 				    NULL, 0, NULL);
1075 		if (ret < 0)
1076 			goto out;
1077 		ret = build_filter(tep, sb, synth, start, filter->lval, NULL);
1078 		if (ret < 0)
1079 			goto out;
1080 		ret = append_filter(synth, TRACEFS_FILTER_CLOSE_PAREN,
1081 				    NULL, 0, NULL);
1082 		goto out;
1083 
1084 	case FILTER_OR:
1085 		and_or = TRACEFS_FILTER_OR;
1086 		/* Fall through */
1087 	case FILTER_AND:
1088 		ret = build_filter(tep, sb, synth, start, filter->lval, NULL);
1089 		if (ret < 0)
1090 			goto out;
1091 		ret = append_filter(synth, and_or, NULL, 0, NULL);
1092 
1093 		if (ret)
1094 			goto out;
1095 		ret = build_filter(tep, sb, synth, start, filter->rval, NULL);
1096 		goto out;
1097 	default:
1098 		break;
1099 	}
1100 
1101 	switch (filter->rval->type) {
1102 	case EXPR_NUMBER:
1103 		sprintf(num, "%ld", filter->rval->number);
1104 		val = num;
1105 		break;
1106 	case EXPR_STRING:
1107 		val = filter->rval->string;
1108 		break;
1109 	default:
1110 		break;
1111 	}
1112 
1113 	switch (filter->type) {
1114 	case FILTER_EQ:		cmp = TRACEFS_COMPARE_EQ; break;
1115 	case FILTER_NE:		cmp = TRACEFS_COMPARE_NE; break;
1116 	case FILTER_LE:		cmp = TRACEFS_COMPARE_LE; break;
1117 	case FILTER_LT:		cmp = TRACEFS_COMPARE_LT; break;
1118 	case FILTER_GE:		cmp = TRACEFS_COMPARE_GE; break;
1119 	case FILTER_GT:		cmp = TRACEFS_COMPARE_GT; break;
1120 	case FILTER_BIN_AND:	cmp = TRACEFS_COMPARE_AND; break;
1121 	case FILTER_STR_CMP:	cmp = TRACEFS_COMPARE_RE; break;
1122 	default:
1123 		tracefs_warning("Error invalid filter type '%d'", filter->type);
1124 		return ERANGE;
1125 	}
1126 
1127 	ret = append_filter(synth, TRACEFS_FILTER_COMPARE,
1128 			    filter->lval->field.field, cmp, val);
1129 
1130 	if (ret)
1131 		filter_error(tep, sb, expr);
1132  out:
1133 	if (!ret && started) {
1134 		if (*started)
1135 			ret = append_filter(synth, TRACEFS_FILTER_CLOSE_PAREN,
1136 					    NULL, 0, NULL);
1137 		*started = true;
1138 	}
1139 	return ret;
1140 }
1141 
field_match_error(struct tep_handle * tep,struct sqlhist_bison * sb,struct match * match)1142 static void *field_match_error(struct tep_handle *tep, struct sqlhist_bison *sb,
1143 			       struct match *match)
1144 {
1145 	switch (errno) {
1146 	case ENODEV:
1147 	case EBADE:
1148 		break;
1149 	default:
1150 		/* System error */
1151 		return NULL;
1152 	}
1153 
1154 	/* ENODEV means that an event or field does not exist */
1155 	if (errno == ENODEV) {
1156 		if (test_field_exists(tep, sb, match->lval))
1157 			return NULL;
1158 		if (test_field_exists(tep, sb, match->rval))
1159 			return NULL;
1160 		return NULL;
1161 	}
1162 
1163 	/* fields exist, but values are not compatible */
1164 	sb->line_no = match->lval->line;
1165 	sb->line_idx = match->lval->idx;
1166 
1167 	parse_error(sb, match->lval->field.raw,
1168 		    "Field '%s' is not compatible to match field '%s'\n",
1169 		    match->lval->field.raw, match->rval->field.raw);
1170 	return NULL;
1171 }
1172 
synth_init_error(struct tep_handle * tep,struct sql_table * table)1173 static void *synth_init_error(struct tep_handle *tep, struct sql_table *table)
1174 {
1175 	struct sqlhist_bison *sb = table->sb;
1176 	struct match *match = table->matches;
1177 
1178 	switch (errno) {
1179 	case ENODEV:
1180 	case EBADE:
1181 		break;
1182 	default:
1183 		/* System error */
1184 		return NULL;
1185 	}
1186 
1187 	/* ENODEV could mean that start or end events do not exist */
1188 	if (errno == ENODEV) {
1189 		if (test_event_exists(tep, sb, table->from, NULL))
1190 			return NULL;
1191 		if (test_event_exists(tep, sb, table->to, NULL))
1192 			return NULL;
1193 	}
1194 
1195 	return field_match_error(tep, sb, match);
1196 }
1197 
selection_error(struct tep_handle * tep,struct sqlhist_bison * sb,struct expr * expr)1198 static void selection_error(struct tep_handle *tep,
1199 			    struct sqlhist_bison *sb, struct expr *expr)
1200 {
1201 	/* We just care about event not existing */
1202 	if (errno != ENODEV)
1203 		return;
1204 
1205 	test_field_exists(tep, sb, expr);
1206 }
1207 
compare_error(struct tep_handle * tep,struct sqlhist_bison * sb,struct expr * expr)1208 static void compare_error(struct tep_handle *tep,
1209 			    struct sqlhist_bison *sb, struct expr *expr)
1210 {
1211 	struct compare *compare = &expr->compare;
1212 
1213 	if (!compare->name) {
1214 		sb->line_no = expr->line;
1215 		sb->line_idx = expr->idx + strlen("no name");
1216 
1217 		parse_error(sb, "no name",
1218 		    "Field calculations must be labeled 'AS name'\n");
1219 	}
1220 
1221 	switch (errno) {
1222 	case ENODEV:
1223 	case EBADE:
1224 		break;
1225 	default:
1226 		/* System error */
1227 		return;
1228 	}
1229 
1230 	/* ENODEV means that an event or field does not exist */
1231 	if (errno == ENODEV) {
1232 		if (test_field_exists(tep, sb, compare->lval))
1233 			return;
1234 		if (test_field_exists(tep, sb, compare->rval))
1235 			return;
1236 		return;
1237 	}
1238 
1239 	/* fields exist, but values are not compatible */
1240 	sb->line_no = compare->lval->line;
1241 	sb->line_idx = compare->lval->idx;
1242 
1243 	parse_error(sb, compare->lval->field.raw,
1244 		    "'%s' is not compatible to compare with '%s'\n",
1245 		    compare->lval->field.raw, compare->rval->field.raw);
1246 }
1247 
compare_no_to_error(struct sqlhist_bison * sb,struct expr * expr)1248 static void compare_no_to_error(struct sqlhist_bison *sb, struct expr *expr)
1249 {
1250 	struct compare *compare = &expr->compare;
1251 
1252 	sb->line_no = compare->lval->line;
1253 	sb->line_idx = compare->lval->idx;
1254 
1255 	parse_error(sb, compare->lval->field.raw,
1256 		    "Simple SQL (without JOIN/ON) do not allow comparisons\n",
1257 		    compare->lval->field.raw, compare->rval->field.raw);
1258 }
1259 
where_no_to_error(struct sqlhist_bison * sb,struct expr * expr,const char * from_event,const char * event)1260 static void where_no_to_error(struct sqlhist_bison *sb, struct expr *expr,
1261 			      const char *from_event, const char *event)
1262 {
1263 	while (expr) {
1264 		switch (expr->filter.type) {
1265 		case FILTER_OR:
1266 		case FILTER_AND:
1267 		case FILTER_GROUP:
1268 		case FILTER_NOT_GROUP:
1269 			expr = expr->filter.lval;
1270 			continue;
1271 		default:
1272 			break;
1273 		}
1274 		break;
1275 	}
1276 	sb->line_no = expr->filter.lval->line;
1277 	sb->line_idx = expr->filter.lval->idx;
1278 
1279 	parse_error(sb, expr->filter.lval->field.raw,
1280 		    "Event '%s' does not match FROM event '%s'\n",
1281 		    event, from_event);
1282 }
1283 
verify_field_type(struct tep_handle * tep,struct sqlhist_bison * sb,struct expr * expr,int * cnt)1284 static int verify_field_type(struct tep_handle *tep,
1285 			     struct sqlhist_bison *sb,
1286 			     struct expr *expr, int *cnt)
1287 {
1288 	struct field *field = &expr->field;
1289 	struct tep_event *event;
1290 	struct tep_format_field *tfield;
1291 	char *type;
1292 	int ret;
1293 	int i;
1294 
1295 	if (!field->type)
1296 		return 0;
1297 
1298 	sb->line_no = expr->line;
1299 	sb->line_idx = expr->idx;
1300 
1301 	event = tep_find_event_by_name(tep, field->system, field->event_name);
1302 	if (!event) {
1303 		parse_error(sb, field->raw,
1304 			    "Event '%s' not found\n",
1305 			    field->event_name ? : "(null)");
1306 		return -1;
1307 	}
1308 
1309 	tfield = tep_find_any_field(event, field->field);
1310 	if (!tfield) {
1311 		parse_error(sb, field->raw,
1312 			    "Field '%s' not part of event '%s'\n",
1313 			    field->field ? : "(null)", field->event);
1314 		return -1;
1315 	}
1316 
1317 	type = strdup(field->type);
1318 	if (!type)
1319 		return -1;
1320 
1321 	if (!strcmp(type, TRACEFS_HIST_COUNTER) ||
1322 	    !strcmp(type, "_COUNTER_")) {
1323 		ret = HIST_COUNTER_TYPE;
1324 		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY)) {
1325 			parse_error(sb, field->raw,
1326 				    "'%s' is a string, and counters may only be used with numbers\n");
1327 			ret = -1;
1328 		}
1329 		goto out;
1330 	}
1331 
1332 	for (i = 0; type[i]; i++)
1333 		type[i] = tolower(type[i]);
1334 
1335 	if (!strcmp(type, "hex")) {
1336 		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY))
1337 			goto fail_type;
1338 		ret = TRACEFS_HIST_KEY_HEX;
1339 	} else if (!strcmp(type, "sym")) {
1340 		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY))
1341 			goto fail_type;
1342 		ret = TRACEFS_HIST_KEY_SYM;
1343 	} else if (!strcmp(type, "sym-offset")) {
1344 		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY))
1345 			goto fail_type;
1346 		ret = TRACEFS_HIST_KEY_SYM_OFFSET;
1347 	} else if (!strcmp(type, "syscall")) {
1348 		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY))
1349 			goto fail_type;
1350 		ret = TRACEFS_HIST_KEY_SYSCALL;
1351 	} else if (!strcmp(type, "execname") ||
1352 		   !strcmp(type, "comm")) {
1353 		ret = TRACEFS_HIST_KEY_EXECNAME;
1354 		if (strcmp(field->field, "common_pid")) {
1355 			parse_error(sb, field->raw,
1356 				    "'%s' is only allowed for common_pid\n",
1357 				    type);
1358 			ret = -1;
1359 		}
1360 	} else if (!strcmp(type, "log") ||
1361 		   !strcmp(type, "log2")) {
1362 		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY))
1363 			goto fail_type;
1364 		ret = TRACEFS_HIST_KEY_LOG;
1365 	} else if (!strncmp(type, "buckets", 7)) {
1366 		if (type[7] != '=' || !isdigit(type[8])) {
1367 			parse_error(sb, field->raw,
1368 				    "buckets type must have '=[number]' after it\n");
1369 			ret = -1;
1370 			goto out;
1371 		}
1372 		*cnt = atoi(&type[8]);
1373 		if (tfield->flags & (TEP_FIELD_IS_STRING | TEP_FIELD_IS_ARRAY))
1374 			goto fail_type;
1375 		ret = TRACEFS_HIST_KEY_BUCKETS;
1376 	} else {
1377 		parse_error(sb, field->raw,
1378 			    "Cast of '%s' to unknown type '%s'\n",
1379 			    field->raw, type);
1380 		ret = -1;
1381 	}
1382  out:
1383 	free(type);
1384 	return ret;
1385  fail_type:
1386 	parse_error(sb, field->raw,
1387 		    "Field '%s' cast to '%s' but is of type %s\n",
1388 		    field->field, type, tfield->flags & TEP_FIELD_IS_STRING ?
1389 		    "string" : "array");
1390 	free(type);
1391 	return -1;
1392 }
1393 
build_synth(struct tep_handle * tep,const char * name,struct sql_table * table)1394 static struct tracefs_synth *build_synth(struct tep_handle *tep,
1395 					 const char *name,
1396 					 struct sql_table *table)
1397 {
1398 	struct tracefs_synth *synth;
1399 	struct field *field;
1400 	struct match *match;
1401 	struct expr *expr;
1402 	const char *start_system;
1403 	const char *start_event;
1404 	const char *end_system;
1405 	const char *end_event;
1406 	const char *start_match;
1407 	const char *end_match;
1408 	bool started_start = false;
1409 	bool started_end = false;
1410 	bool non_val = false;
1411 	int ret;
1412 
1413 	if (!table->from)
1414 		return NULL;
1415 
1416 	/* This could be a simple SQL statement to only build a histogram */
1417 	if (!table->to) {
1418 		ret = update_fields(tep, table, table->from);
1419 		if (ret < 0)
1420 			return NULL;
1421 
1422 		start_system = table->from->field.system;
1423 		start_event = table->from->field.event_name;
1424 
1425 		synth = synth_init_from(tep, start_system, start_event);
1426 		if (!synth)
1427 			return synth_init_error(tep, table);
1428 		goto hist_only;
1429 	}
1430 
1431 	ret = update_vars(tep, table, table->from);
1432 	if (ret < 0)
1433 		return NULL;
1434 
1435 	ret = update_vars(tep, table, table->to);
1436 	if (ret < 0)
1437 		return NULL;
1438 
1439 	start_system = table->from->field.system;
1440 	start_event = table->from->field.event_name;
1441 
1442 	match = table->matches;
1443 	if (!match)
1444 		return NULL;
1445 
1446 	ret = test_match(table, match);
1447 	if (ret < 0)
1448 		return NULL;
1449 
1450 	end_system = table->to->field.system;
1451 	end_event = table->to->field.event_name;
1452 
1453 	assign_match(start_system, start_event, match,
1454 		     &start_match, &end_match);
1455 
1456 	synth = tracefs_synth_alloc(tep, name, start_system,
1457 				    start_event, end_system, end_event,
1458 				    start_match, end_match, NULL);
1459 	if (!synth)
1460 		return synth_init_error(tep, table);
1461 
1462 	for (match = match->next; match; match = match->next) {
1463 		ret = test_match(table, match);
1464 		if (ret < 0)
1465 			goto free;
1466 
1467 		assign_match(start_system, start_event, match,
1468 			     &start_match, &end_match);
1469 
1470 		ret = tracefs_synth_add_match_field(synth,
1471 						    start_match,
1472 						    end_match, NULL);
1473 		if (ret < 0) {
1474 			field_match_error(tep, table->sb, match);
1475 			goto free;
1476 		}
1477 	}
1478 
1479  hist_only:
1480 	/* table->to may be NULL here */
1481 
1482 	for (expr = table->selections; expr; expr = expr->next) {
1483 		if (expr->type == EXPR_FIELD) {
1484 			ret = -1;
1485 			field = &expr->field;
1486 			if (field->ftype != FIELD_TO &&
1487 			    field->system == start_system &&
1488 			    field->event_name == start_event) {
1489 				int type;
1490 				int cnt = 0;
1491 				type = verify_field_type(tep, table->sb, expr, &cnt);
1492 				if (type < 0)
1493 					goto free;
1494 				if (type != HIST_COUNTER_TYPE)
1495 					non_val = true;
1496 				ret = synth_add_start_field(synth,
1497 						field->field, field->label,
1498 						type, cnt);
1499 			} else if (table->to) {
1500 				ret = tracefs_synth_add_end_field(synth,
1501 						field->field, field->label);
1502 			}
1503 			if (ret < 0) {
1504 				selection_error(tep, table->sb, expr);
1505 				goto free;
1506 			}
1507 			continue;
1508 		}
1509 
1510 		if (!table->to) {
1511 			compare_no_to_error(table->sb, expr);
1512 			goto free;
1513 		}
1514 
1515 		if (expr->type != EXPR_COMPARE)
1516 			goto free;
1517 
1518 		ret = build_compare(synth, start_system, end_system,
1519 				    &expr->compare);
1520 		if (ret < 0) {
1521 			compare_error(tep, table->sb, expr);
1522 			goto free;
1523 		}
1524 	}
1525 
1526 	if (!non_val && !table->to) {
1527 		table->sb->line_no = 0;
1528 		table->sb->line_idx = 10;
1529 		parse_error(table->sb, "CAST",
1530 			    "Not all SELECT items can be of type _COUNTER_\n");
1531 		goto free;
1532 	}
1533 
1534 	for (expr = table->where; expr; expr = expr->next) {
1535 		const char *filter_system = NULL;
1536 		const char *filter_event = NULL;
1537 		enum field_type ftype = FIELD_NONE;
1538 		bool *started;
1539 		bool start;
1540 
1541 		ret = verify_filter(table->sb, &expr->filter, &filter_system,
1542 				    &filter_event, &ftype);
1543 		if (ret < 0)
1544 			goto free;
1545 
1546 		start = filter_system == start_system &&
1547 			filter_event == start_event &&
1548 			ftype != FIELD_TO;
1549 
1550 		if (start)
1551 			started = &started_start;
1552 		else if (!table->to) {
1553 			where_no_to_error(table->sb, expr, start_event,
1554 					  filter_event);
1555 			goto free;
1556 		} else
1557 			started = &started_end;
1558 
1559 		ret = build_filter(tep, table->sb, synth, start, expr, started);
1560 		if (ret < 0)
1561 			goto free;
1562 	}
1563 
1564 	return synth;
1565  free:
1566 	tracefs_synth_free(synth);
1567 	return NULL;
1568 }
1569 
free_sql_table(struct sql_table * table)1570 static void free_sql_table(struct sql_table *table)
1571 {
1572 	struct match *match;
1573 	struct expr *expr;
1574 
1575 	if (!table)
1576 		return;
1577 
1578 	while ((expr = table->exprs)) {
1579 		table->exprs = expr->free_list;
1580 		free(expr);
1581 	}
1582 
1583 	while ((match = table->matches)) {
1584 		table->matches = match->next;
1585 		free(match);
1586 	}
1587 
1588 	free(table);
1589 }
1590 
free_str_hash(struct str_hash ** hash)1591 static void free_str_hash(struct str_hash **hash)
1592 {
1593 	struct str_hash *item;
1594 	int i;
1595 
1596 	for (i = 0; i < 1 << HASH_BITS; i++) {
1597 		while ((item = hash[i])) {
1598 			hash[i] = item->next;
1599 			free(item->str);
1600 			free(item);
1601 		}
1602 	}
1603 }
1604 
free_sb(struct sqlhist_bison * sb)1605 static void free_sb(struct sqlhist_bison *sb)
1606 {
1607 	free_sql_table(sb->table);
1608 	free_str_hash(sb->str_hash);
1609 	free(sb->parse_error_str);
1610 }
1611 
tracefs_sql(struct tep_handle * tep,const char * name,const char * sql_buffer,char ** err)1612 struct tracefs_synth *tracefs_sql(struct tep_handle *tep, const char *name,
1613 				  const char *sql_buffer, char **err)
1614 {
1615 	struct tracefs_synth *synth = NULL;
1616 	struct sqlhist_bison sb;
1617 	int ret;
1618 
1619 	if (!tep || !sql_buffer) {
1620 		errno = EINVAL;
1621 		return NULL;
1622 	}
1623 
1624 	memset(&sb, 0, sizeof(sb));
1625 
1626 	sb.buffer = sql_buffer;
1627 	sb.buffer_size = strlen(sql_buffer);
1628 	sb.buffer_idx = 0;
1629 
1630 	ret = yylex_init_extra(&sb, &sb.scanner);
1631 	if (ret < 0) {
1632 		yylex_destroy(sb.scanner);
1633 		return NULL;
1634 	}
1635 
1636 	ret = tracefs_parse(&sb);
1637 	yylex_destroy(sb.scanner);
1638 
1639 	if (ret)
1640 		goto free;
1641 
1642 	synth = build_synth(tep, name, sb.table);
1643 
1644  free:
1645 	if (!synth) {
1646 		if (sb.parse_error_str && err) {
1647 			*err = sb.parse_error_str;
1648 			sb.parse_error_str = NULL;
1649 		}
1650 	}
1651 	free_sb(&sb);
1652 	return synth;
1653 }
1654