• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright (C) 2024 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License a
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from python.generators.diff_tests.testing import Path, DataPath, Metric
17from python.generators.diff_tests.testing import Csv, Json, TextProto
18from python.generators.diff_tests.testing import DiffTestBlueprint
19from python.generators.diff_tests.testing import TestSuite
20
21
22class IntervalsIntersect(TestSuite):
23
24  def test_simple_interval_intersect(self):
25    return DiffTestBlueprint(
26        trace=TextProto(""),
27        #      0 1 2 3 4 5 6 7
28        # A:   _ - - - - - - _
29        # B:   - - _ - - _ - -
30        # res: _ - _ - - _ - _
31        query="""
32        INCLUDE PERFETTO MODULE intervals.intersect;
33
34        CREATE PERFETTO TABLE A AS
35          WITH data(id, ts, dur) AS (
36            VALUES
37            (0, 1, 6)
38          )
39          SELECT * FROM data;
40
41        CREATE PERFETTO TABLE B AS
42          WITH data(id, ts, dur) AS (
43            VALUES
44            (0, 0, 2),
45            (1, 3, 2),
46            (2, 6, 2)
47          )
48          SELECT * FROM data;
49
50        SELECT ts, dur, id_0, id_1
51        FROM _interval_intersect!((A, B), ())
52        ORDER BY ts;
53        """,
54        out=Csv("""
55        "ts","dur","id_0","id_1"
56        1,1,0,0
57        3,2,0,1
58        6,1,0,2
59        """))
60
61  def test_simple_interval_intersect_two_tabs(self):
62    return DiffTestBlueprint(
63        trace=TextProto(""),
64        #      0 1 2 3 4 5 6 7
65        # A:   _ - - - - - - _
66        # B:   - - _ - - _ - -
67        # res: _ - _ - - _ - _
68        query="""
69        INCLUDE PERFETTO MODULE intervals.intersect;
70
71        CREATE PERFETTO TABLE A AS
72          WITH data(id, ts, dur) AS (
73            VALUES
74            (0, 1, 6)
75          )
76          SELECT * FROM data;
77
78        CREATE PERFETTO TABLE B AS
79          WITH data(id, ts, dur) AS (
80            VALUES
81            (0, 0, 2),
82            (1, 3, 2),
83            (2, 6, 2)
84          )
85          SELECT * FROM data;
86
87        SELECT ts, dur, id_0, id_1
88        FROM _interval_intersect!((B, A), ())
89        ORDER BY ts;
90        """,
91        out=Csv("""
92        "ts","dur","id_0","id_1"
93        1,1,0,0
94        3,2,1,0
95        6,1,2,0
96        """))
97
98  def test_simple_interval_intersect_three_tabs(self):
99    return DiffTestBlueprint(
100        trace=TextProto(""),
101        #      0 1 2 3 4 5 6 7
102        # A:   0 1 1 1 1 1 1 0
103        # B:   1 1 0 1 1 0 1 1
104        # C:   1 0 1 1 1 1 0 1
105        # res: 0 0 0 1 1 0 0 0
106        query="""
107        INCLUDE PERFETTO MODULE intervals.intersect;
108
109        CREATE PERFETTO TABLE A AS
110          WITH data(id, ts, dur) AS (
111            VALUES
112            (0, 1, 6)
113          )
114          SELECT * FROM data;
115
116        CREATE PERFETTO TABLE B AS
117          WITH data(id, ts, dur) AS (
118            VALUES
119            (0, 0, 2),
120            (1, 3, 2),
121            (2, 6, 2)
122          )
123          SELECT * FROM data;
124
125        CREATE PERFETTO TABLE C AS
126          WITH data(id, ts, dur) AS (
127            VALUES
128            (10, 0, 1),
129            (20, 2, 4),
130            (30, 7, 1)
131          )
132          SELECT * FROM data;
133
134        SELECT ts, dur, id_0, id_1, id_2
135        FROM _interval_intersect!((A, B, C), ())
136        ORDER BY ts;
137        """,
138        out=Csv("""
139        "ts","dur","id_0","id_1","id_2"
140        3,2,0,1,20
141        """))
142
143  def test_no_overlap(self):
144    return DiffTestBlueprint(
145        trace=TextProto(""),
146        # A:   __-
147        # B:   -__
148        # res: ___
149        query="""
150        INCLUDE PERFETTO MODULE intervals.intersect;
151
152        CREATE PERFETTO TABLE A AS
153          WITH data(id, ts, dur) AS (
154            VALUES
155            (0, 2, 1)
156          )
157          SELECT * FROM data;
158
159        CREATE PERFETTO TABLE B AS
160          WITH data(id, ts, dur) AS (
161            VALUES
162            (0, 0, 1)
163          )
164          SELECT * FROM data;
165
166        SELECT ts, dur, id_0, id_1
167        FROM _interval_intersect!((A, B), ())
168        ORDER BY ts;
169        """,
170        out=Csv("""
171        "ts","dur","id_0","id_1"
172        """))
173
174  def test_no_overlap_rev(self):
175    return DiffTestBlueprint(
176        trace=TextProto(""),
177        # A:   __-
178        # B:   -__
179        # res: ___
180        query="""
181        INCLUDE PERFETTO MODULE intervals.intersect;
182
183        CREATE PERFETTO TABLE A AS
184          WITH data(id, ts, dur) AS (
185            VALUES
186            (0, 2, 1)
187          )
188          SELECT * FROM data;
189
190        CREATE PERFETTO TABLE B AS
191          WITH data(id, ts, dur) AS (
192            VALUES
193            (0, 0, 1)
194          )
195          SELECT * FROM data;
196
197        SELECT ts, dur, id_0, id_1
198        FROM _interval_intersect!((B, A), ())
199        ORDER BY ts;
200        """,
201        out=Csv("""
202        "ts","dur","id_0","id_1"
203        """))
204
205  def test_no_empty(self):
206    return DiffTestBlueprint(
207        trace=TextProto(""),
208        # A:   __-
209        # B:   -__
210        # res: ___
211        query="""
212        INCLUDE PERFETTO MODULE intervals.intersect;
213
214        CREATE PERFETTO TABLE A AS
215          WITH data(id, ts, dur) AS (
216            VALUES
217            (0, 2, 1)
218          )
219          SELECT * FROM data;
220
221        CREATE PERFETTO TABLE B AS
222        SELECT * FROM A LIMIT 0;
223
224        SELECT ts, dur, id_0, id_1
225        FROM _interval_intersect!((A, B), ())
226        ORDER BY ts;
227        """,
228        out=Csv("""
229        "ts","dur","id_0","id_1"
230        """))
231
232  def test_no_empty_rev(self):
233    return DiffTestBlueprint(
234        trace=TextProto(""),
235        # A:   __-
236        # B:   -__
237        # res: ___
238        query="""
239        INCLUDE PERFETTO MODULE intervals.intersect;
240
241        CREATE PERFETTO TABLE A AS
242          WITH data(id, ts, dur) AS (
243            VALUES
244            (0, 2, 1)
245          )
246          SELECT * FROM data;
247
248        CREATE PERFETTO TABLE B AS
249        SELECT * FROM A LIMIT 0;
250
251        SELECT ts, dur, id_0, id_1
252        FROM _interval_intersect!((B, A), ())
253        ORDER BY ts;
254        """,
255        out=Csv("""
256        "ts","dur","id_0","id_1"
257        """))
258
259  def test_single_point_overlap(self):
260    return DiffTestBlueprint(
261        trace=TextProto(""),
262        # A:   _-
263        # B:   -_
264        # res: __
265        query="""
266        INCLUDE PERFETTO MODULE intervals.intersect;
267
268        CREATE PERFETTO TABLE A AS
269          WITH data(id, ts, dur) AS (
270            VALUES
271            (0, 1, 1)
272          )
273          SELECT * FROM data;
274
275        CREATE PERFETTO TABLE B AS
276          WITH data(id, ts, dur) AS (
277            VALUES
278            (0, 0, 1)
279          )
280          SELECT * FROM data;
281
282        SELECT ts, dur, id_0, id_1
283        FROM _interval_intersect!((A, B), ())
284        ORDER BY ts;
285        """,
286        out=Csv("""
287        "ts","dur","id_0","id_1"
288        """))
289
290  def test_single_point_overlap_rev(self):
291    return DiffTestBlueprint(
292        trace=TextProto(""),
293        # A:   _-
294        # B:   -_
295        # res: __
296        query="""
297        INCLUDE PERFETTO MODULE intervals.intersect;
298
299        CREATE PERFETTO TABLE A AS
300          WITH data(id, ts, dur) AS (
301            VALUES
302            (0, 1, 1)
303          )
304          SELECT * FROM data;
305
306        CREATE PERFETTO TABLE B AS
307          WITH data(id, ts, dur) AS (
308            VALUES
309            (0, 0, 1)
310          )
311          SELECT * FROM data;
312
313        SELECT ts, dur, id_0, id_1
314        FROM _interval_intersect!((B, A), ())
315        ORDER BY ts;
316        """,
317        out=Csv("""
318        "ts","dur","id_0","id_1"
319        """))
320
321  def test_single_interval(self):
322    return DiffTestBlueprint(
323        trace=TextProto(""),
324        #      0 1 2 3 4 5 6 7
325        # A:   _ - - - - - - _
326        # B:   - - _ - - _ - -
327        # res: _ - _ - - _ - _
328        query="""
329        INCLUDE PERFETTO MODULE intervals.intersect;
330
331        CREATE PERFETTO TABLE A AS
332          WITH data(id, ts, dur) AS (
333            VALUES
334            (0, 1, 6)
335          )
336          SELECT * FROM data;
337
338        CREATE PERFETTO TABLE B AS
339          WITH data(id, ts, dur) AS (
340            VALUES
341            (0, 0, 2),
342            (1, 3, 2),
343            (2, 6, 2)
344          )
345          SELECT * FROM data;
346
347        SELECT *
348        FROM _interval_intersect_single!(1, 6, B)
349        ORDER BY ts;
350        """,
351        out=Csv("""
352        "id","ts","dur"
353        0,1,1
354        1,3,2
355        2,6,1
356        """))
357
358  def test_ii_wrong_partition(self):
359    return DiffTestBlueprint(
360        trace=TextProto(''),
361        query="""
362        INCLUDE PERFETTO MODULE intervals.intersect;
363
364        CREATE PERFETTO TABLE A
365        AS
366        WITH x(id, ts, dur, c0) AS (VALUES(1, 1, 1, 1), (2, 3, 1, 2))
367        SELECT * FROM x;
368
369        CREATE PERFETTO TABLE B
370        AS
371        WITH x(id, ts, dur, c0) AS (VALUES(1, 5, 1, 3))
372        SELECT * FROM x;
373
374        SELECT ts FROM _interval_intersect!((A, B), (c0));
375        """,
376        out=Csv("""
377        "ts"
378        """))
379
380  def test_compare_with_span_join_partitioned(self):
381    return DiffTestBlueprint(
382        trace=DataPath('example_android_trace_30s.pb'),
383        query="""
384        INCLUDE PERFETTO MODULE intervals.intersect;
385
386        CREATE PERFETTO TABLE big_foo AS
387        SELECT
388          ts,
389          dur,
390          id,
391          cpu
392        FROM sched
393        WHERE dur > 0 AND utid != 0;
394
395        CREATE PERFETTO TABLE small_foo AS
396        SELECT
397          ts + 1000 AS ts,
398          dur + 1000 AS dur,
399          id * 10 AS id,
400          cpu
401        FROM sched
402        WHERE dur > 0 AND utid != 0;
403
404        CREATE PERFETTO TABLE small_foo_for_sj AS
405        SELECT
406          id AS small_id,
407          ts,
408          dur,
409          cpu
410        FROM small_foo;
411
412        CREATE PERFETTO TABLE big_foo_for_sj AS
413        SELECT
414          id AS big_id,
415          ts,
416          dur,
417          cpu
418        FROM big_foo;
419
420        CREATE VIRTUAL TABLE sj_res
421        USING SPAN_JOIN(
422          small_foo_for_sj PARTITIONED cpu,
423          big_foo_for_sj PARTITIONED cpu);
424
425        CREATE PERFETTO TABLE both AS
426        SELECT
427          id_0,
428          id_1,
429          cpu,
430          cat,
431          count() AS c
432        FROM (
433          SELECT id_0, id_1, ts, dur, cpu, "ii" AS cat
434          FROM _interval_intersect!((big_foo, small_foo), (cpu))
435          UNION
436          SELECT big_id AS id_0, small_id AS id_1, ts, dur, cpu, "sj" AS cat FROM sj_res
437        )
438          GROUP BY id_0, id_1, ts, dur, cpu ;
439
440        SELECT
441          SUM(c) FILTER (WHERE c == 2) AS good,
442          SUM(c) FILTER (WHERE c != 2) AS bad
443        FROM both;
444        """,
445        out=Csv("""
446          "good","bad"
447          880364,"[NULL]"
448        """))
449
450  def test_compare_ii_with_span_join(self):
451    return DiffTestBlueprint(
452        trace=DataPath('example_android_trace_30s.pb'),
453        query="""
454        INCLUDE PERFETTO MODULE intervals.intersect;
455
456        CREATE PERFETTO TABLE big_foo AS
457        SELECT
458          ts,
459          dur,
460          id
461        FROM sched
462        WHERE dur > 0 AND utid == 44;
463
464        CREATE PERFETTO TABLE small_foo AS
465        SELECT
466          ts,
467          dur,
468          id
469        FROM sched
470        WHERE dur > 0 AND utid == 103;
471
472        CREATE PERFETTO TABLE small_foo_for_sj AS
473        SELECT
474          id AS small_id,
475          ts,
476          dur
477        FROM small_foo;
478
479        CREATE PERFETTO TABLE big_foo_for_sj AS
480        SELECT
481          id AS big_id,
482          ts,
483          dur
484        FROM big_foo;
485
486        CREATE VIRTUAL TABLE sj_res
487        USING SPAN_JOIN(
488          small_foo_for_sj,
489          big_foo_for_sj);
490
491        CREATE PERFETTO TABLE both AS
492        SELECT
493          left_id,
494          right_id,
495          cat,
496          count() AS c
497        FROM (
498          SELECT id_0 AS left_id, id_1 AS right_id, ts, dur, "ii" AS cat
499          FROM _interval_intersect!((big_foo, small_foo), ())
500          UNION
501          SELECT big_id AS left_id, small_id AS right_id, ts, dur, "sj" AS cat FROM sj_res
502        )
503          GROUP BY left_id, right_id;
504
505        SELECT
506          SUM(c) FILTER (WHERE c == 2) AS good,
507          SUM(c) FILTER (WHERE c != 2) AS bad
508        FROM both;
509        """,
510        out=Csv("""
511          "good","bad"
512          28,"[NULL]"
513        """))
514
515  def test_sanity_check(self):
516    return DiffTestBlueprint(
517        trace=DataPath('example_android_trace_30s.pb'),
518        query="""
519        INCLUDE PERFETTO MODULE intervals.intersect;
520
521        CREATE PERFETTO TABLE trace_interval AS
522        SELECT
523          0 AS id,
524          TRACE_START() AS ts,
525          TRACE_DUR() AS dur;
526
527        CREATE PERFETTO TABLE non_overlapping AS
528        SELECT
529          id, ts, dur
530        FROM thread_state
531        WHERE utid = 1 AND dur != -1;
532
533        WITH ii AS (
534          SELECT *
535          FROM _interval_intersect!((trace_interval, non_overlapping), ())
536        )
537        SELECT
538          (SELECT count(*) FROM ii) AS ii_count,
539          (SELECT count(*) FROM non_overlapping) AS thread_count,
540          (SELECT sum(dur) FROM ii) AS ii_sum,
541          (SELECT sum(dur) FROM non_overlapping) AS thread_sum;
542        """,
543        out=Csv("""
544        "ii_count","thread_count","ii_sum","thread_sum"
545        313,313,27540674879,27540674879
546        """))
547
548  def test_sanity_check_single_interval(self):
549    return DiffTestBlueprint(
550        trace=DataPath('example_android_trace_30s.pb'),
551        query="""
552        INCLUDE PERFETTO MODULE intervals.intersect;
553
554        CREATE PERFETTO TABLE non_overlapping AS
555        SELECT
556          id, ts, dur
557        FROM thread_state
558        WHERE utid = 1 AND dur != -1;
559
560        WITH ii AS (
561          SELECT *
562          FROM _interval_intersect_single!(
563            TRACE_START(),
564            TRACE_DUR(),
565            non_overlapping)
566        )
567        SELECT
568          (SELECT count(*) FROM ii) AS ii_count,
569          (SELECT count(*) FROM non_overlapping) AS thread_count,
570          (SELECT sum(dur) FROM ii) AS ii_sum,
571          (SELECT sum(dur) FROM non_overlapping) AS thread_sum;
572        """,
573        out=Csv("""
574        "ii_count","thread_count","ii_sum","thread_sum"
575        313,313,27540674879,27540674879
576        """))
577
578  def test_sanity_multiple_partitions(self):
579    return DiffTestBlueprint(
580        trace=DataPath('example_android_trace_30s.pb'),
581        query="""
582        INCLUDE PERFETTO MODULE intervals.intersect;
583
584        SELECT * FROM _interval_intersect!(
585          ((SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10),
586          (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10)),
587          (utid, cpu)
588        );
589        """,
590        out=Csv("""
591        "ts","dur","id_0","id_1","utid","cpu"
592        70730062200,125364,0,0,1,0
593        70730187564,20297242,1,1,0,0
594        70731483398,24583,9,9,10,3
595        70731458606,24792,8,8,9,3
596        70731393294,42396,5,5,6,3
597        70731435690,22916,6,6,7,3
598        70731161731,35000,3,3,4,3
599        70731196731,196563,4,4,5,3
600        70731438502,55261,7,7,8,6
601        70731135898,25833,2,2,2,3
602        """))
603
604  def test_sanity_single_partitions(self):
605    return DiffTestBlueprint(
606        trace=DataPath('example_android_trace_30s.pb'),
607        query="""
608        INCLUDE PERFETTO MODULE intervals.intersect;
609
610        SELECT * FROM _interval_intersect!(
611          ((SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10),
612          (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10)),
613          (utid)
614        );
615        """,
616        out=Csv("""
617        "ts","dur","id_0","id_1","utid"
618        70731458606,24792,8,8,9
619        70731161731,35000,3,3,4
620        70731393294,42396,5,5,6
621        70730187564,20297242,1,1,0
622        70731135898,25833,2,2,2
623        70731438502,55261,7,7,8
624        70731483398,24583,9,9,10
625        70731196731,196563,4,4,5
626        70731435690,22916,6,6,7
627        70730062200,125364,0,0,1
628        """))
629
630  def test_sanity_multiple_tables_and_partitions(self):
631    return DiffTestBlueprint(
632        trace=DataPath('example_android_trace_30s.pb'),
633        query="""
634        INCLUDE PERFETTO MODULE intervals.intersect;
635
636        SELECT * FROM _interval_intersect!(
637          (
638            (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10),
639            (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10),
640            (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10)
641          ),
642          (utid, cpu)
643        );
644        """,
645        out=Csv("""
646        "ts","dur","id_0","id_1","id_2","utid","cpu"
647        70730062200,125364,0,0,0,1,0
648        70730187564,20297242,1,1,1,0,0
649        70731483398,24583,9,9,9,10,3
650        70731458606,24792,8,8,8,9,3
651        70731393294,42396,5,5,5,6,3
652        70731435690,22916,6,6,6,7,3
653        70731161731,35000,3,3,3,4,3
654        70731196731,196563,4,4,4,5,3
655        70731438502,55261,7,7,7,8,6
656        70731135898,25833,2,2,2,2,3
657        """))
658
659  def test_sanity_multiple_tables_and_partitions(self):
660    return DiffTestBlueprint(
661        trace=DataPath('example_android_trace_30s.pb'),
662        query="""
663        INCLUDE PERFETTO MODULE intervals.intersect;
664
665        SELECT * FROM _interval_intersect!(
666          (
667            (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10),
668            (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10),
669            (SELECT id, ts, dur, utid, cpu FROM sched WHERE dur > 0 LIMIT 10)
670          ),
671          (utid, cpu)
672        );
673        """,
674        out=Csv("""
675        "ts","dur","id_0","id_1","id_2","utid","cpu"
676        70730062200,125364,0,0,0,1,0
677        70730187564,20297242,1,1,1,0,0
678        70731483398,24583,9,9,9,10,3
679        70731458606,24792,8,8,8,9,3
680        70731393294,42396,5,5,5,6,3
681        70731435690,22916,6,6,6,7,3
682        70731161731,35000,3,3,3,4,3
683        70731196731,196563,4,4,4,5,3
684        70731438502,55261,7,7,7,8,6
685        70731135898,25833,2,2,2,2,3
686        """))
687
688  def test_multiple_tables_against_ii(self):
689    return DiffTestBlueprint(
690        trace=DataPath('example_android_trace_30s.pb'),
691        query="""
692        INCLUDE PERFETTO MODULE intervals.intersect;
693
694        CREATE PERFETTO TABLE foo AS
695        SELECT id, ts, dur FROM sched
696        WHERE dur > 0 AND cpu = 0
697        ORDER BY ts;
698
699        CREATE PERFETTO TABLE bar AS
700        SELECT id, ts, dur FROM sched
701        WHERE dur > 0 AND cpu = 1
702        ORDER BY ts;
703
704        CREATE PERFETTO TABLE baz AS
705        SELECT id, ts, dur FROM sched
706        WHERE dur > 0 AND cpu = 2
707        ORDER BY ts;
708
709        CREATE PERFETTO TABLE ii_foo_and_bar AS
710        SELECT
711          ROW_NUMBER() OVER (ORDER BY ts) AS id,
712          ts, dur, id_0 AS id_foo, id_1 AS id_bar
713        FROM _interval_intersect!((foo, bar), ())
714        ORDER BY ts;
715
716        CREATE PERFETTO TABLE ii_foo_bar_baz AS
717        SELECT id_foo, id_bar, id_1 AS id_baz, ii.ts, ii.dur
718        FROM _interval_intersect!((ii_foo_and_bar, baz), ()) ii
719        JOIN ii_foo_and_bar ON ii_foo_and_bar.id = ii.id_0;
720
721        WITH unioned AS (
722            SELECT id_foo, id_bar, id_baz, ts, dur, "std" AS cat
723            FROM ii_foo_bar_baz
724            UNION
725            SELECT id_0 AS id_foo, id_1 AS id_bar, id_2 AS id_baz, ts, dur, "triple" AS cat
726            FROM _interval_intersect!((foo, bar, baz), ())
727        ),
728        counted AS (
729          SELECT *, count() c FROM unioned GROUP BY ts, dur, id_foo, id_bar, id_baz
730        )
731        SELECT
732          SUM(c) FILTER (WHERE c == 2) AS good,
733          SUM(c) FILTER (WHERE c != 2) AS bad
734        FROM counted;
735        """,
736        out=Csv("""
737        "good","bad"
738        303178,"[NULL]"
739        """))
740
741  def test_multiple_tables_big(self):
742    return DiffTestBlueprint(
743        trace=DataPath('example_android_trace_30s.pb'),
744        query="""
745        INCLUDE PERFETTO MODULE intervals.intersect;
746
747        CREATE PERFETTO TABLE foo AS
748        SELECT id, ts, dur FROM sched
749        WHERE dur > 0 AND cpu = 0
750        ORDER BY ts;
751
752        CREATE PERFETTO TABLE bar AS
753        SELECT id, ts, dur FROM sched
754        WHERE dur > 0 AND cpu = 1
755        ORDER BY ts;
756
757        CREATE PERFETTO TABLE baz AS
758        SELECT id, ts, dur FROM sched
759        WHERE dur > 0 AND cpu = 2
760        ORDER BY ts;
761
762        SELECT * FROM _interval_intersect!((foo, bar, baz), ())
763        ORDER BY ts
764        LIMIT 10;
765        """,
766        out=Csv("""
767        "ts","dur","id_0","id_1","id_2"
768        70799077155,1187135,44,133,132
769        70800264290,473386,44,138,132
770        70800737676,352500,44,139,132
771        70801090176,643906,140,139,132
772        70801734082,121615,141,139,132
773        70801855697,68073,141,139,142
774        70801923770,61354,141,139,143
775        70801985124,5054323,141,139,144
776        70807039447,65261,141,139,145
777        70807104708,50572,141,139,146
778        """))
779