1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import { query } from '../SqlLite';
16import { SelectionData } from '../../bean/BoxSelection';
17import { ThreadStruct } from '../ui-worker/ProcedureWorkerThread';
18import { WakeupBean } from '../../bean/WakeupBean';
19import { SPTChild } from '../../bean/StateProcessThread';
20import { BinderArgBean } from '../../bean/BinderArgBean';
21import { ProcessMemStruct } from '../ui-worker/ProcedureWorkerMem';
22import { AppStartupStruct } from '../ui-worker/ProcedureWorkerAppStartup';
23import { SoStruct } from '../ui-worker/ProcedureWorkerSoInit';
24import { LiveProcess, ProcessHistory } from '../../bean/AbilityMonitor';
25import { EnergyAnomalyStruct } from '../ui-worker/ProcedureWorkerEnergyAnomaly';
26import { BinderItem } from '../../bean/BinderProcessThread';
27import { Utils } from '../../component/trace/base/Utils';
28import { FuncStruct } from '../ui-worker/ProcedureWorkerFunc';
29
30export const queryBinderByThreadId = (
31  pIds: number[],
32  tIds: Array<number>,
33  leftNS: number,
34  rightNS: number
35): Promise<Array<BinderItem>> =>
36  query<BinderItem>(
37    'queryBinderByThreadId',
38    `
39      SELECT 
40            c.name, 
41            c.ts - r.start_ts AS ts, 
42            c.dur, 
43            t.tid,
44            p.pid
45          FROM 
46              callstack c, trace_range r 
47          LEFT JOIN 
48              thread t 
49          ON 
50              c.callid = t.id 
51          LEFT JOIN
52              process p 
53          ON
54              t.ipid = p.id  
55          WHERE 
56              c.name in ('binder transaction', 'binder async rcv', 'binder reply', 'binder transaction async') 
57          AND 
58              t.tid in (${tIds.join(',')})
59          AND 
60              p.pid in (${pIds.join(',')})
61          AND NOT 
62              (((c.ts - r.start_ts) < ${leftNS}) 
63          OR 
64              ((c.ts - r.start_ts) > ${rightNS}))
65        `,
66    {
67      $pIds: pIds,
68      $tIds: tIds,
69      $leftNS: leftNS,
70      $rightNS: rightNS,
71    },
72    { traceId: Utils.currentSelectTrace }
73  );
74
75export const getTabBindersCount = (
76  pIds: number[],
77  tIds: number[],
78  leftNS: number,
79  rightNS: number
80): Promise<Array<BinderItem>> =>
81  query<BinderItem>(
82    'getTabBindersCount',
83    `
84      SELECT 
85          c.name,
86          c.dur,
87          1 AS count,
88          c.ts,
89          c.ts - r.start_ts AS startTime, 
90          c.ts -r.start_ts + c.dur AS endTime,
91          t.tid, 
92          p.pid
93        FROM 
94            callstack c, trace_range r 
95          LEFT JOIN
96            thread t 
97          ON 
98            c.callid = t.id 
99          LEFT JOIN
100            process p 
101          ON
102            t.ipid = p.id 
103        WHERE 
104            c.name in ('binder transaction', 'binder async rcv', 'binder reply', 'binder transaction async') 
105          AND 
106            t.tid in (${tIds.join(',')})
107          AND 
108            p.pid in (${pIds.join(',')})
109          AND NOT 
110            ((startTime < ${leftNS}) 
111          OR 
112            (endTime > ${rightNS}));
113      `,
114    {
115      $pIds: pIds,
116      $tIds: tIds,
117      $leftNS: leftNS,
118      $rightNS: rightNS,
119    }
120  );
121
122export const querySchedThreadStates = (
123  pIds: Array<number>,
124  tIds: Array<number>,
125  leftStartNs: number,
126  rightEndNs: number
127): //@ts-ignore
128  Promise<Array<unknown>> =>
129  query(
130    'getTabThreadStates',
131    `
132    select
133      B.pid,
134      B.tid,
135      B.state,
136      ifnull(B.dur,0) as dur,
137      B.ts,
138      ifnull(B.dur,0) + B.ts as endTs
139    from
140      thread_state AS B
141    where
142      B.tid in (${tIds.join(',')})
143    and 
144      B.pid in (${pIds.join(',')})
145    and
146      B.state='Running'
147    and
148      not ((B.ts + ifnull(B.dur,0) < $leftStartNs) or (B.ts > $rightEndNs))
149    order by
150      B.pid;
151    `,
152    { $leftStartNs: leftStartNs, $rightEndNs: rightEndNs }
153  );
154
155export const querySingleCutData = (
156  funcName: string,
157  tIds: string,
158  leftStartNs: number,
159  rightEndNs: number
160): //@ts-ignore
161  Promise<Array<unknown>> =>
162  query(
163    'querySingleCutData',
164    `
165    select 
166      c.ts as cycleStartTime,
167      c.ts + ifnull(c.dur, 0) as cycleEndTime,
168      t.tid,
169      p.pid
170      from
171      callstack c 
172    left join
173      thread t on c.callid = t.id 
174    left join
175      process p on t.ipid = p.id
176    left join
177      trace_range r
178    where
179      c.name like '${funcName}%'
180    and 
181      t.tid = '${tIds}'
182    and
183      not ((c.ts < $leftStartNs) or (c.ts + ifnull(c.dur, 0) > $rightEndNs))
184    order by
185      c.ts
186    `,
187    { $leftStartNs: leftStartNs, $rightEndNs: rightEndNs }
188  );
189
190export const queryLoopCutData = (
191  funcName: string,
192  tIds: string,
193  leftStartNs: number,
194  rightEndNs: number
195): //@ts-ignore
196  Promise<Array<unknown>> =>
197  query(
198    'queryLoopCutData',
199    `
200    select 
201      c.ts as cycleStartTime,
202      t.tid,
203      p.pid
204    from callstack c 
205    left join
206      thread t on c.callid = t.id 
207    left join
208      process p on t.ipid = p.id
209    where 
210      c.name like '${funcName}%' 
211    and
212      t.tid = '${tIds}' 
213    and
214      not ((c.ts < $leftStartNs) or (c.ts > $rightEndNs))
215    order by
216      c.ts
217    `,
218    { $leftStartNs: leftStartNs, $rightEndNs: rightEndNs }
219  );
220// 框选区域内sleeping的时间
221export const getTabSleepingTime = (
222  tIds: Array<number>,
223  leftNS: number,
224  rightNS: number
225): //@ts-ignore
226  Promise<Array<unknown>> =>
227  query<SelectionData>(
228    'getTabRunningPersent',
229    `
230 select
231   B.pid,
232   B.tid,
233   B.state,
234   B.cpu,
235   B.dur,
236   B.ts
237 from
238   thread_state AS  B
239 left join
240   trace_range AS TR
241 where
242   B.tid in (${tIds.join(',')})
243 and
244   B.state='Sleeping'
245 and
246   not ((B.ts - TR.start_ts + ifnull(B.dur,0) < ${leftNS}) or (B.ts - TR.start_ts > ${rightNS}))
247 order by
248   ts;`,
249    { $leftNS: leftNS, $rightNS: rightNS }
250  );
251export const getTabThreadStatesCpu = (
252  tIds: Array<number>,
253  leftNS: number,
254  rightNS: number
255): //@ts-ignore
256  Promise<Array<unknown>> => {
257  let sql = `
258select
259       B.pid,
260       B.tid,
261       B.cpu,
262       sum( min(${rightNS},(B.ts - TR.start_ts + iif(B.dur = -1 or B.dur is null, 0, B.dur))) - 
263       max(${leftNS},B.ts - TR.start_ts)) wallDuration
264from thread_state as B
265left join trace_range as TR
266where cpu notnull
267    and B.tid in (${tIds.join(',')})
268    and not ((B.ts - TR.start_ts + iif(B.dur = -1 or B.dur is null, 0, B.dur) < ${leftNS}) 
269    or (B.ts - TR.start_ts > ${rightNS}))
270group by B.tid, B.pid, B.cpu;`;
271  return query<SelectionData>('getTabThreadStatesCpu', sql, {
272    $leftNS: leftNS,
273    $rightNS: rightNS,
274  }, {
275    traceId: Utils.currentSelectTrace
276  });
277};
278
279// 框选区域内running的时间
280export const getTabRunningPersent = (
281  tIds: Array<number>,
282  leftNS: number,
283  rightNS: number
284): //@ts-ignore
285  Promise<Array<unknown>> =>
286  query<SelectionData>(
287    'getTabRunningPersent',
288    `
289   select
290     B.pid,
291     B.tid,
292     B.state,
293     B.cpu,
294     iif(B.dur = -1 or B.dur is null, 0, B.dur) as dur,
295     B.ts
296   from
297     thread_state AS  B
298   left join
299     trace_range AS TR
300   where
301     B.tid in (${tIds.join(',')})
302   and
303     B.state='Running'
304   and
305     not ((B.ts - TR.start_ts + iif(B.dur = -1 or B.dur is null, 0, B.dur) < ${leftNS}) 
306     or (B.ts - TR.start_ts > ${rightNS}))
307   order by
308     ts;`,
309    { $leftNS: leftNS, $rightNS: rightNS },
310    { traceId: Utils.currentSelectTrace }
311  );
312
313export const queryThreadData = (tid: number, pid: number): Promise<Array<ThreadStruct>> =>
314  query(
315    'queryThreadData',
316    `
317    select 
318      B.itid as id
319     , B.tid
320     , B.cpu
321     , B.ts - TR.start_ts AS startTime
322     , B.dur
323     , B.state
324     , B.pid
325     , B.arg_setid as argSetID
326from thread_state AS B
327    left join trace_range AS TR
328where B.tid = $tid and B.pid = $pid;`,
329    { $tid: tid, $pid: pid }
330  );
331
332export const queryThreadWakeUpFrom = async (itid: number, startTime: number): Promise<unknown> => {
333  let sql1 = `select wakeup_from from instant where ts = ${startTime} and ref = ${itid} limit 1`;
334  const result = await query('queryThreadWakeUpFrom', sql1, {}, { traceId: Utils.currentSelectTrace });
335  let res: unknown = [];
336  if (result && result.length > 0) { //@ts-ignore
337    let wakeupFromItid = result[0].wakeup_from; // 获取wakeup_from的值  
338    let sql2 = `  
339            select (A.ts - B.start_ts) as ts,  
340                   A.tid,  
341                   A.itid,  
342                   A.pid,  
343                   A.cpu,  
344                   A.dur,  
345                   A.arg_setid as argSetID  
346            from thread_state A, trace_range B  
347            where A.state = 'Running'  
348            and A.itid = ${wakeupFromItid}  
349            and (A.ts - B.start_ts) < (${startTime} - B.start_ts)  
350            order by ts desc limit 1  
351          `;
352    res = query('queryThreadWakeUpFrom', sql2, {}, { traceId: Utils.currentSelectTrace });
353  }
354  return res;
355};
356
357export const queryRWakeUpFrom = async (itid: number, startTime: number): Promise<unknown> => {
358  let sql1 = `select wakeup_from from instant where ts = ${startTime} and ref = ${itid} limit 1`;
359  const res = await query('queryRWakeUpFrom', sql1, {}, { traceId: Utils.currentSelectTrace });
360  let result: unknown = [];
361  if (res && res.length) {
362    //@ts-ignore
363    let wakeupFromItid = res[0].wakeup_from;
364    let sql2 = `
365      select 
366        (A.ts - B.start_ts) as ts,
367        A.tid,
368        A.itid,
369        A.arg_setid as argSetID
370      from 
371        thread_state A,
372        trace_range B
373      where 
374        A.state = 'Running'
375        and A.itid = ${wakeupFromItid}
376        and A.ts < ${startTime}
377      order by 
378        ts desc 
379        limit 1
380    `;
381    result = query('queryRWakeUpFrom', sql2, {}, { traceId: Utils.currentSelectTrace });
382  }
383  return result;
384};
385export const queryRunnableTimeByRunning = (tid: number, startTime: number): Promise<Array<WakeupBean>> => {
386  let sql = `
387select ts from thread_state,trace_range where ts + dur -start_ts = ${startTime} and state = 'R' and tid=${tid} limit 1
388    `;
389  return query('queryRunnableTimeByRunning', sql, {}, { traceId: Utils.currentSelectTrace });
390};
391
392export const queryProcessByTable = (traceId?: string): Promise<
393  Array<{
394    pid: number | null;
395    processName: string | null;
396  }>
397> =>
398  query(
399    'queryProcessByTable',
400    `
401    SELECT
402      pid, name as processName
403    FROM
404      process where pid != 0`,
405    {},
406    { traceId: traceId }
407  );
408
409export const getTabStartups = (
410  ids: Array<number>,
411  leftNS: number,
412  rightNS: number
413): //@ts-ignore
414  Promise<Array<unknown>> => {
415  let sql = `
416select
417    P.pid,
418    P.name as process,
419    (A.start_time - B.start_ts) as startTs,
420    (case when A.end_time = -1 then 0 else (A.end_time - A.start_time) end) as dur,
421    A.start_name as startName
422from app_startup A,trace_range B
423left join process P on A.ipid = P.ipid
424where P.pid in (${ids.join(',')}) 
425and not ((startTs + dur < ${leftNS}) or (startTs > ${rightNS}))
426order by start_name;`;
427  return query('getTabStartups', sql, {});
428};
429
430export const getTabStaticInit = (
431  ids: Array<number>,
432  leftNS: number,
433  rightNS: number
434): //@ts-ignore
435  Promise<Array<unknown>> => {
436  let sql = `
437select
438    P.pid,
439    P.name as process,
440    (A.start_time - B.start_ts) as startTs,
441    (case when A.end_time = -1 then 0 else (A.end_time - A.start_time) end) as dur,
442    A.so_name as soName
443from static_initalize A,trace_range B
444left join process P on A.ipid = P.ipid
445where P.pid in (${ids.join(',')}) 
446and not ((startTs + dur < ${leftNS}) or (startTs > ${rightNS}))
447order by dur desc;`;
448  return query('getTabStaticInit', sql, {});
449};
450
451export const queryBinderArgsByArgset = (argset: number): Promise<Array<BinderArgBean>> =>
452  query(
453    'queryBinderArgsByArgset',
454    `
455    select
456      *
457    from
458      args_view
459    where
460      argset = $argset;`,
461    { $argset: argset },
462    { traceId: Utils.currentSelectTrace }
463  );
464
465export const queryProcessData = (
466  pid: number,
467  startNS: number,
468  endNS: number
469): //@ts-ignore
470  Promise<Array<unknown>> =>
471  query(
472    'queryProcessData',
473    `
474    select  ta.cpu,
475        dur, 
476        ts-${window.recordStartNS} as startTime
477from thread_state ta
478where ta.cpu is not null and pid=$pid and startTime between $startNS and $endNS;`,
479    {
480      $pid: pid,
481      $startNS: startNS,
482      $endNS: endNS,
483    }
484  );
485
486export const queryProcessMem = (): //@ts-ignore
487  Promise<Array<unknown>> =>
488  query(
489    'queryProcessMem',
490    `
491    select
492      process_measure_filter.id as trackId,
493      process_measure_filter.name as trackName,
494      ipid as upid,
495      process.pid,
496      process.name as processName
497    from
498      process_measure_filter
499    join
500      process using (ipid)
501    order by trackName;`
502  );
503
504export const queryProcessThreadDataCount = (): //@ts-ignore
505  Promise<Array<unknown>> =>
506  query(
507    'queryProcessThreadDataCount',
508    `select pid,count(id) as count 
509    from thread_state 
510    where ts between ${window.recordStartNS} and ${window.recordEndNS} group by pid;`,
511    {}
512  );
513
514export const queryProcessFuncDataCount = (): //@ts-ignore
515  Promise<Array<unknown>> =>
516  query(
517    'queryProcessFuncDataCount',
518    `select
519        P.pid,
520        count(tid) as count
521    from callstack C
522    left join thread A on A.id = C.callid
523    left join process AS P on P.id = A.ipid
524    where  C.ts between ${window.recordStartNS} and ${window.recordEndNS} 
525    group by pid;`,
526    {}
527  );
528
529export const queryProcessMemDataCount = (): //@ts-ignore
530  Promise<Array<unknown>> =>
531  query(
532    'queryProcessMemDataCount',
533    `select
534      p.pid as pid, count(value) count
535    from process_measure c
536    left join process_measure_filter f on f.id = c.filter_id
537    left join process p on p.ipid = f.ipid
538where f.id not NULL and value>0 
539 and c.ts between ${window.recordStartNS} and ${window.recordEndNS}
540group by p.pid`,
541    {}
542  );
543
544export const queryProcessMemData = (trackId: number): Promise<Array<ProcessMemStruct>> =>
545  query(
546    'queryProcessMemData',
547    `
548    select
549      c.type,
550      ts,
551      value,
552      filter_id as track_id,
553      c.ts-tb.start_ts startTime
554    from
555      process_measure c,
556      trace_range tb
557    where
558      filter_id = $id;`,
559    { $id: trackId }
560  );
561
562export const queryThreads = (): //@ts-ignore
563  Promise<Array<unknown>> =>
564  query('queryThreads', `select id,tid,(ifnull(name,'Thread') || '(' || tid || ')') name from thread where id != 0;`);
565
566export const queryDataDICT = async (): Promise<Array<unknown>> => {
567  let dataDictBuffer = await query(
568    'queryDataDICT',
569    'select * from data_dict;',
570    {},
571    { action: 'exec-buf' }
572  );
573  // @ts-ignore
574  return Utils.convertJSON(dataDictBuffer);
575};
576
577export const queryAppStartupProcessIds = (): Promise<Array<{ pid: number }>> =>
578  query(
579    'queryAppStartupProcessIds',
580    `
581  SELECT pid FROM process 
582  WHERE ipid IN (
583    SELECT ipid FROM app_startup 
584    UNION
585    SELECT t.ipid FROM app_startup a LEFT JOIN thread t ON a.call_id = t.itid 
586);`
587  );
588
589export const queryTaskPoolProcessIds = (): Promise<Array<{ pid: number }>> =>
590  query(
591    'queryAppStartupProcessIds',
592    `SELECT pid 
593FROM
594    process 
595WHERE
596    ipid IN (
597    SELECT DISTINCT
598    ( ipid ) 
599    FROM
600    thread 
601    WHERE
602    itid IN ( SELECT DISTINCT ( callid ) FROM callstack WHERE name LIKE 'H:Task%' ) 
603    AND name = 'TaskWorkThread' 
604    )`
605  );
606
607export const queryProcessContentCount = (traceId?: string): Promise<Array<unknown>> =>
608  query(
609    `queryProcessContentCount`,
610    `select 
611    pid,
612    switch_count,
613    thread_count,
614    slice_count,
615    mem_count 
616    from process;`,
617    {},
618    { traceId: traceId }
619  );
620
621export const queryProcessThreadsByTable = (traceId?: string): Promise<Array<ThreadStruct>> =>
622  query(
623    'queryProcessThreadsByTable',
624    `
625        select 
626        p.pid as pid,
627        p.ipid as upid,
628        t.tid as tid,
629        p.name as processName,
630        t.name as threadName,
631        t.switch_count as switchCount, 
632        t.itid as utid 
633        from 
634        thread t left join process  p on t.ipid = p.id where t.tid != 0`,
635    {},
636    { traceId: traceId }
637  );
638
639export const queryStartupPidArray = (): Promise<Array<{ pid: number }>> =>
640  query(
641    'queryStartupPidArray',
642    `
643    select distinct pid 
644from app_startup A,trace_range B left join process P on A.ipid = p.ipid
645where A.start_time between B.start_ts and B.end_ts;`,
646    {}
647  );
648
649export const queryProcessStartup = (pid: number): Promise<Array<AppStartupStruct>> =>
650  query(
651    'queryProcessStartup',
652    `
653    select
654    P.pid,
655    A.tid,
656    A.call_id as itid,
657    (case when A.start_time < B.start_ts then 0 else (A.start_time - B.start_ts) end) as startTs,
658    (case 
659        when A.start_time < B.start_ts then (A.end_time - B.start_ts) 
660        when A.end_time = -1 then 0
661        else (A.end_time - A.start_time) end) as dur,
662    A.start_name as startName
663from app_startup A,trace_range B
664left join process P on A.ipid = P.ipid
665where P.pid = $pid
666order by start_name;`,
667    { $pid: pid }
668  );
669
670export const queryProcessAllAppStartup = (pids: Array<number>): Promise<Array<AppStartupStruct>> =>
671  query(
672    'queryProcessStartup',
673    `
674    select
675    P.pid,
676    A.tid,
677    A.call_id as itid,
678    (case when A.start_time < B.start_ts then 0 else (A.start_time - B.start_ts) end) as startTs,
679    (case 
680        when A.start_time < B.start_ts then (A.end_time - B.start_ts) 
681        when A.end_time = -1 then 0
682        else (A.end_time - A.start_time) end) as dur,
683    A.start_name as startName
684from app_startup A,trace_range B
685left join process P on A.ipid = P.ipid
686where P.pid in(${pids.join(',')}) 
687order by start_name;`,
688    { $pid: pids }
689  );
690
691export const querySingleAppStartupsName = (
692  pid: number
693): //@ts-ignore
694  Promise<Array<unknown>> =>
695  query(
696    'queryAllAppStartupsName',
697    `select name from process
698    where pid=$pid`,
699    { $pid: pid }
700  );
701
702export const queryProcessSoMaxDepth = (): Promise<Array<{ pid: number; maxDepth: number }>> =>
703  query(
704    'queryProcessSoMaxDepth',
705    `select p.pid,max(depth) maxDepth 
706from static_initalize S,trace_range B left join process p on S.ipid = p.ipid 
707where S.start_time between B.start_ts and B.end_ts
708group by p.pid;`,
709    {}
710  );
711export const queryAllThreadName = (): //@ts-ignore
712  Promise<Array<unknown>> => {
713  return query(
714    'queryAllThreadName',
715    `
716          select name,tid from thread;`
717  );
718};
719
720export const queryAllProcessNames = (): //@ts-ignore
721  Promise<Array<unknown>> => {
722  return query(
723    'queryAllProcessNames',
724    `
725        select id, name, pid from process;`
726  );
727};
728
729export const queryRsProcess = (): //@ts-ignore
730  Promise<Array<unknown>> => {
731  return query(
732    'queryRsProcess',
733    `
734        SELECT p.pid FROM process p WHERE p.ipid = (SELECT t.ipid FROM thread t WHERE t.itid IN 
735        ( SELECT c.callid FROM callstack c WHERE name LIKE '%H:RSMainThread::DoComposition%' LIMIT 1 ) 
736      LIMIT 1 
737      )`
738  );
739};
740
741export const queryProcessSoInitData = (pid: number): Promise<Array<SoStruct>> =>
742  query(
743    'queryProcessSoInitData',
744    `
745    select
746    P.pid,
747    T.tid,
748    A.call_id as itid,
749    (A.start_time - B.start_ts) as startTs,
750    (A.end_time - A.start_time) as dur,
751    A.so_name as soName,
752    A.depth
753from static_initalize A,trace_range B
754left join process P on A.ipid = P.ipid
755left join thread T on A.call_id = T.itid
756where P.pid = $pid;`,
757    { $pid: pid }
758  );
759
760export const queryThreadAndProcessName = (traceId?: string): //@ts-ignore
761  Promise<Array<unknown>> =>
762  query(
763    'queryThreadAndProcessName',
764    `
765    select tid id,name,'t' type from thread
766union all
767select pid id,name,'p' type from process;`,
768    {},
769    { traceId: traceId }
770  );
771
772export const queryThreadStateArgs = (argset: number): Promise<Array<BinderArgBean>> =>
773  query('queryThreadStateArgs',
774    `select args_view.* from args_view where argset = ${argset}`, {}, {
775    traceId: Utils.currentSelectTrace
776  });
777
778export const queryThreadStateArgsByName = (key: string, traceId?: string):
779  Promise<Array<{ argset: number; strValue: string }>> =>
780  query(
781    'queryThreadStateArgsByName',
782    `select 
783    strValue, 
784    argset 
785    from args_view where keyName = $key`,
786    { $key: key },
787    { traceId: traceId }
788  );
789
790export const queryArgsById = (key: string, traceId?: string):
791  Promise<Array<{ id: number }>> =>
792  query(
793    'queryArgsById',
794    `select
795    id 
796    from data_dict 
797    WHERE data = $key`,
798    { $key: key },
799    { traceId: traceId }
800  );
801
802export const queryThreadStateArgsById = (id: number, traceId?: string):
803  Promise<Array<{ argset: number; strValue: string }>> =>
804  query(
805    'queryThreadStateArgsById',
806    `select
807    A.argset,
808    DD.data as strValue
809    from 
810    (select argset,value 
811    from args where key = $id) as A left join data_dict as DD
812    on DD.id = A.value
813    `,
814    { $id: id },
815    { traceId: traceId }
816  );
817
818export const queryThreadWakeUp = (itid: number, startTime: number, dur: number):
819  Promise<Array<WakeupBean>> =>
820  query(
821    'queryThreadWakeUp',
822    `
823select TA.tid,min(TA.ts - TR.start_ts) as ts,TA.pid,TA.dur,TA.state,TA.cpu,TA.itid,TA.arg_setid as argSetID
824from
825  (select min(ts) as wakeTs,ref as itid from instant,trace_range
826       where name = 'sched_wakeup'
827       and wakeup_from = $itid
828       and ts > start_ts + $startTime
829       and ts < start_ts + $startTime + $dur
830      group by ref
831       ) TW
832left join thread_state TA on TW.itid = TA.itid
833left join trace_range TR
834where TA.ts > TW.wakeTs
835group by TA.tid,TA.pid;
836    `,
837    { $itid: itid, $startTime: startTime, $dur: dur },
838    { traceId: Utils.currentSelectTrace }
839  );
840
841export const getTabRunningPercent = (
842  tIds: Array<number>,
843  pIds: Array<number>,
844  leftNS: number,
845  rightNS: number
846): Promise<
847  Array<{
848    pid: number;
849    tid: number;
850    cpu: number;
851    dur: number;
852    ts: number;
853    process: string;
854    thread: string;
855  }>
856> =>
857  query(
858    'getTabRunningPercent',
859    `
860          select
861            B.pid,
862            B.tid,
863            B.cpu,
864            B.dur,
865            B.ts
866          from
867            thread_state AS B
868          left join 
869            trace_range AS TR
870          where
871            B.tid in (${tIds.join(',')})
872          and
873            B.state='Running'
874          and
875            B.pid in (${pIds.join(',')})
876          and
877            not ((B.ts - TR.start_ts + ifnull(B.dur,0) < ${leftNS}) or (B.ts - TR.start_ts > ${rightNS}))
878          order by ts
879       `,
880    {},
881    { traceId: Utils.currentSelectTrace }
882  );
883
884//VM  Purgeable 点选 tab页
885export const queryProcessPurgeableSelectionTab = (
886  startNs: number,
887  ipid: number,
888  isPin?: boolean
889): //@ts-ignore
890  Promise<Array<unknown>> => {
891  const condition = isPin ? "'mem.purg_pin'" : "'mem.purg_sum'";
892  const pinSql = isPin ? ' AND ref_count > 0' : '';
893  return query(
894    'queryProcessPurgeableSelectionTab',
895    `SELECT
896        ( CASE WHEN f.name = 'mem.purg_pin' THEN 'PinedPurg' ELSE 'TotalPurg' END ) AS name,
897        SUM( m.value )  AS value 
898    FROM
899        process_measure m,
900        trace_range tr
901        left join process_measure_filter f on f.id = m.filter_id 
902    WHERE
903        f.name = ${condition} 
904        AND m.ts - tr.start_ts = ${startNs}
905    AND f.ipid = ${ipid}
906    GROUP BY m.ts
907    UNION
908    SELECT
909        'ShmPurg' AS name,
910        SUM( pss ) AS size
911    FROM
912        memory_ashmem,
913        trace_range tr
914    WHERE
915        ipid = ${ipid}
916        AND ts - tr.start_ts = ${startNs}
917        AND flag = 0
918        ${pinSql}
919    GROUP BY ts`
920  );
921};
922///////////////////////////////////////////////
923//VM  Purgeable 框选 tab页
924export const queryProcessPurgeableTab = (
925  leftNs: number,
926  rightNs: number,
927  dur: number,
928  ipid: number,
929  isPin?: boolean
930): //@ts-ignore
931  Promise<Array<unknown>> => {
932  const pinSql = isPin ? ' AND ref_count > 0' : '';
933  let filterSql = isPin ? "'mem.purg_pin'" : "'mem.purg_sum'";
934  return query(
935    'queryProcessPurgeableTab',
936    `SELECT name, MAX(size) AS maxSize, MIN(size) AS minSize, AVG(size) AS avgSize
937    FROM
938      (SELECT
939        'ShmPurg' AS name, ts - tr.start_ts AS startTs, SUM( pss ) AS size
940      FROM
941        memory_ashmem,
942        trace_range tr
943      WHERE
944        ipid = ${ipid}
945        AND flag = 0
946        ${pinSql}
947      GROUP BY ts
948      UNION
949      SELECT
950      CASE
951          WHEN f.name = 'mem.purg_pin' THEN
952          'PinedPurg' ELSE 'TotalPurg'
953        END AS name,
954        m.ts - tr.start_ts AS startTs,
955        sum( m.value ) AS size
956      FROM
957        process_measure m,
958        trace_range tr
959        LEFT JOIN process_measure_filter f ON f.id = m.filter_id 
960      WHERE f.name = ${filterSql}
961        AND f.ipid = ${ipid}
962      GROUP BY m.ts
963    ) combined_data, trace_range tr
964    WHERE ${leftNs} <= startTs + ${dur} AND ${rightNs} >= startTs
965    GROUP BY name`
966  );
967};
968export const getTabPowerDetailsData = (
969  leftNs: number,
970  rightNs: number
971): Promise<
972  Array<{
973    startNS: number;
974    eventName: string;
975    appKey: string;
976    eventValue: string;
977  }>
978> =>
979  query(
980    'getTabPowerDetailsData',
981    `SELECT
982        ( S.ts - TR.start_ts ) AS startNS,
983        D.data AS eventName,
984        D2.data AS appKey,
985        group_concat( ( CASE WHEN S.type = 1 THEN S.string_value ELSE S.int_value END ), ',' ) AS eventValue
986        FROM
987        trace_range AS TR,
988        hisys_event_measure AS S
989        LEFT JOIN data_dict AS D ON D.id = S.name_id
990        LEFT JOIN app_name AS APP ON APP.id = S.key_id
991        LEFT JOIN data_dict AS D2 ON D2.id = APP.app_key
992        where
993        D.data in ('POWER_IDE_CPU','POWER_IDE_LOCATION','POWER_IDE_GPU','POWER_IDE_DISPLAY',
994        'POWER_IDE_CAMERA','POWER_IDE_BLUETOOTH','POWER_IDE_FLASHLIGHT','POWER_IDE_AUDIO',
995        'POWER_IDE_WIFISCAN')
996        and
997        D2.data in ('APPNAME')
998        GROUP BY
999        S.serial,
1000        APP.app_key,
1001        D.data,
1002        D2.data
1003        UNION
1004        SELECT
1005        ( S.ts - TR.start_ts ) AS startNS,
1006        D1.data AS eventName,
1007        D2.data AS appKey,
1008        group_concat( ( CASE WHEN S.type = 1 THEN S.string_value ELSE S.int_value END ), ',' ) AS eventValue
1009        FROM
1010        trace_range AS TR,
1011        hisys_event_measure AS S
1012        LEFT JOIN data_dict AS D1 ON D1.id = S.name_id
1013        LEFT JOIN app_name AS APP ON APP.id = S.key_id
1014        LEFT JOIN data_dict AS D2 ON D2.id = APP.app_key
1015        where
1016        D1.data in ('POWER_IDE_CPU','POWER_IDE_LOCATION','POWER_IDE_GPU','POWER_IDE_DISPLAY',
1017        'POWER_IDE_CAMERA','POWER_IDE_BLUETOOTH','POWER_IDE_FLASHLIGHT','POWER_IDE_AUDIO',
1018        'POWER_IDE_WIFISCAN')
1019        and
1020        D2.data in ('CHARGE','BACKGROUND_TIME','SCREEN_ON_TIME','SCREEN_OFF_TIME','LOAD','USAGE',
1021        'DURATION','CAMERA_ID','FOREGROUND_COUNT','BACKGROUND_COUNT','SCREEN_ON_COUNT',
1022        'SCREEN_OFF_COUNT','COUNT','UID','FOREGROUND_DURATION','FOREGROUND_ENERGY',
1023        'BACKGROUND_DURATION','BACKGROUND_ENERGY','SCREEN_ON_DURATION','SCREEN_ON_ENERGY',
1024        'SCREEN_OFF_DURATION','SCREEN_OFF_ENERGY','ENERGY')
1025        and
1026        (S.ts - TR.start_ts) >= $leftNS
1027        and (S.ts - TR.start_ts) <= $rightNS
1028        GROUP BY
1029        S.serial,
1030        APP.app_key,
1031        D1.data,
1032        D2.data
1033        ORDER BY
1034        eventName;`,
1035    { $leftNS: leftNs, $rightNS: rightNs }
1036  );
1037
1038export const getTabPowerBatteryData = (
1039  rightNs: number
1040): Promise<
1041  Array<{
1042    ts: number;
1043    eventName: string;
1044    appKey: string;
1045    eventValue: string;
1046  }>
1047> =>
1048  query(
1049    'getTabPowerBatteryData',
1050    `select
1051      MAX(S.ts) as ts,
1052      D.data as eventName,
1053      D2.data as appKey, 
1054      group_concat((case when S.type==1 then S.string_value else S.int_value end), ',') as eventValue 
1055      from 
1056      trace_range AS TR,
1057      hisys_event_measure as S 
1058      left join 
1059      data_dict as D 
1060      on 
1061      D.id=S.name_id 
1062      left join 
1063      app_name as APP 
1064      on 
1065      APP.id=S.key_id 
1066      left join 
1067      data_dict as D2 
1068      on 
1069      D2.id=APP.app_key
1070      where 
1071      D.data = 'POWER_IDE_BATTERY'
1072      and D2.data in ('GAS_GAUGE','CHARGE','SCREEN','LEVEL','CURRENT','CAPACITY','UID')
1073      and (S.ts - TR.start_ts) >= 0
1074      and (S.ts - TR.start_ts) <= $rightNS 
1075      group by APP.app_key,D.data,D2.data;`,
1076    { $rightNS: rightNs }
1077  );
1078export const queryPowerData = (): Promise<
1079  Array<{
1080    id: number;
1081    startNS: number;
1082    eventName: string;
1083    appKey: string;
1084    eventValue: string;
1085  }>
1086> =>
1087  query(
1088    'queryPowerData',
1089    `SELECT
1090         S.id,
1091        ( S.ts - TR.start_ts ) AS startNS,
1092        D.data AS eventName,
1093        D2.data AS appKey,
1094        group_concat( ( CASE WHEN S.type = 1 THEN S.string_value ELSE S.int_value END ), ',' ) AS eventValue
1095        FROM
1096        trace_range AS TR,
1097        hisys_event_measure AS S
1098        LEFT JOIN data_dict AS D
1099        ON D.id = S.name_id
1100        LEFT JOIN app_name AS APP
1101        ON APP.id = S.key_id
1102        LEFT JOIN data_dict AS D2
1103        ON D2.id = APP.app_key
1104        where
1105        D.data in ('POWER_IDE_CPU','POWER_IDE_LOCATION','POWER_IDE_GPU','POWER_IDE_DISPLAY',
1106        'POWER_IDE_CAMERA','POWER_IDE_BLUETOOTH','POWER_IDE_FLASHLIGHT','POWER_IDE_AUDIO',
1107        'POWER_IDE_WIFISCAN')
1108        and
1109        D2.data in ('BACKGROUND_ENERGY','FOREGROUND_ENERGY','SCREEN_ON_ENERGY','SCREEN_OFF_ENERGY',
1110        'ENERGY','APPNAME')
1111        GROUP BY
1112        S.serial,
1113        APP.app_key,
1114        D.data,
1115        D2.data
1116        ORDER BY
1117        eventName;`,
1118    {}
1119  );
1120export const getTabLiveProcessData = (leftNs: number, rightNs: number): Promise<Array<LiveProcess>> =>
1121  query<LiveProcess>(
1122    'getTabLiveProcessData',
1123    `SELECT
1124        process.id as processId,
1125        process.name as processName,
1126        process.ppid as responsibleProcess,
1127        process.uud as userName,
1128        process.usag as cpu,
1129        process.threadN as threads,
1130        process.pss as memory,
1131        process.cpu_time as cpuTime,
1132        process.disk_reads as diskReads,
1133        process.disk_writes as diskWrite
1134        FROM
1135        (
1136        SELECT
1137        tt.process_id AS id,
1138        tt.process_name AS name,
1139        tt.parent_process_id AS ppid,
1140        tt.uid as uud,
1141        tt.cpu_usage as usag,
1142        tt.thread_num AS threadN,
1143        mt.maxTT - TR.start_ts as endTs,
1144        tt.pss_info as pss,
1145        tt.cpu_time,
1146        tt.disk_reads,
1147        tt.disk_writes
1148        FROM
1149        live_process tt
1150        LEFT JOIN trace_range AS TR 
1151        LEFT JOIN (select re.process_id as idd, max(re.ts) as maxTT, min(re.ts) as minTT 
1152        from live_process re GROUP BY re.process_name, re.process_id ) mt
1153        on mt.idd = tt.process_id where endTs >= $rightNS
1154        GROUP BY
1155        tt.process_name,
1156        tt.process_id 
1157        ) process ;`,
1158    { $leftNS: leftNs, $rightNS: rightNs }
1159  );
1160
1161export const getTabProcessHistoryData = (
1162  leftNs: number,
1163  rightNs: number,
1164  processId: number | undefined,
1165  threadId: number | undefined
1166): Promise<Array<ProcessHistory>> =>
1167  query<ProcessHistory>(
1168    'getTabProcessHistoryData',
1169    `SELECT
1170        process.id as processId,
1171        process.isD as alive,
1172        process.startTS as firstSeen,
1173        process.endTs as lastSeen,
1174        process.name as processName,
1175        process.ppid as responsibleProcess,
1176        process.uuid as userName,
1177        process.cpu_time as cpuTime,
1178        0 as pss
1179        FROM
1180        (
1181        SELECT
1182        tt.process_id AS id,
1183        tt.process_name AS name,
1184        tt.parent_process_id AS ppid,
1185        tt.uid AS uuid,
1186        tt.cpu_time,
1187        (mt.minTT - TR.start_ts ) AS startTS,
1188        mt.maxTT - TR.start_ts as endTs,
1189        (mt.maxTT - TR.start_ts - $rightNS) > 0 as isD
1190        FROM
1191        live_process tt
1192        LEFT JOIN trace_range AS TR 
1193        LEFT JOIN (select re.process_id as idd, max(re.ts) as maxTT, min(re.ts) as minTT 
1194        from live_process re GROUP BY re.process_name, re.process_id ) mt
1195        on mt.idd = tt.process_id 
1196        GROUP BY
1197        tt.process_name,
1198        tt.process_id 
1199        ) process;`,
1200    {
1201      $leftNS: leftNs,
1202      $rightNS: rightNs,
1203      $processID: processId,
1204      $threadID: threadId,
1205    }
1206  );
1207export const getTabSlices = (
1208  funTids: Array<number>,
1209  pids: Array<number>,
1210  leftNS: number,
1211  rightNS: number
1212): Promise<Array<unknown>> =>
1213  query<SelectionData>(
1214    'getTabSlices',
1215    `
1216    select
1217      c.name as name,
1218      sum(c.dur) as wallDuration,
1219      count(c.name) as occurrences
1220    from
1221      thread T, trace_range TR
1222      left join process P on T.ipid = P.id
1223    left join
1224      callstack C
1225    on
1226      T.id = C.callid
1227    where
1228      C.ts > 0
1229      and
1230      c.dur >= 0
1231    and
1232      T.tid in (${funTids.join(',')})
1233    and
1234      P.pid in (${pids.join(',')})
1235    and
1236      c.cookie is null
1237    and
1238      not ((C.ts - TR.start_ts + C.dur < $leftNS) or (C.ts - TR.start_ts > $rightNS))
1239    group by
1240      c.name
1241    order by
1242      wallDuration desc;`,
1243    { $leftNS: leftNS, $rightNS: rightNS },
1244    { traceId: Utils.currentSelectTrace }
1245  );
1246
1247export const getTabThreadStates = (
1248  tIds: Array<number>,
1249  leftNS: number,
1250  rightNS: number
1251): //@ts-ignore
1252  Promise<Array<unknown>> =>
1253  query<SelectionData>(
1254    'getTabThreadStates',
1255    `
1256    select
1257      B.pid,
1258      B.tid,
1259      B.state,
1260      sum(B.dur) as wallDuration,
1261      avg(ifnull(B.dur,0)) as avgDuration,
1262      count(B.tid) as occurrences
1263    from
1264      thread_state AS B
1265    left join
1266      trace_range AS TR
1267    where
1268      B.tid in (${tIds.join(',')})
1269    and
1270      not ((B.ts - TR.start_ts + ifnull(B.dur,0) < $leftNS) or (B.ts - TR.start_ts > $rightNS))
1271    group by
1272      B.pid, B.tid, B.state
1273    order by
1274      wallDuration desc;`,
1275    { $leftNS: leftNS, $rightNS: rightNS }
1276  );
1277
1278export const queryAnomalyDetailedData = (leftNs: number, rightNs: number): Promise<Array<EnergyAnomalyStruct>> =>
1279  query<EnergyAnomalyStruct>(
1280    'queryAnomalyDetailedData',
1281    `select
1282  S.ts,
1283  D.data as eventName,
1284  D2.data as appKey,
1285  group_concat((case when S.type==1 then S.string_value else S.int_value end), ',') as Value
1286  from trace_range AS TR,hisys_event_measure as S
1287  left join data_dict as D on D.id=S.name_id
1288  left join app_name as APP on APP.id=S.key_id
1289  left join data_dict as D2 on D2.id=APP.app_key
1290  where D.data in ('ANOMALY_SCREEN_OFF_ENERGY','ANOMALY_ALARM_WAKEUP','ANOMALY_KERNEL_WAKELOCK',
1291  'ANOMALY_RUNNINGLOCK','ANORMALY_APP_ENERGY','ANOMALY_GNSS_ENERGY','ANOMALY_CPU_HIGH_FREQUENCY',
1292  'ANOMALY_CPU_ENERGY','ANOMALY_WAKEUP')
1293  and D2.data in ('APPNAME')
1294  and (S.ts - TR.start_ts) >= $leftNS
1295   and (S.ts - TR.start_ts) <= $rightNS
1296  group by S.serial,APP.app_key,D.data,D2.data
1297  union
1298  select
1299  S.ts,
1300  D.data as eventName,
1301  D2.data as appKey,
1302  group_concat((case when S.type = 1 then S.string_value else S.int_value end), ',') as Value
1303  from trace_range AS TR,hisys_event_measure as S
1304  left join data_dict as D on D.id = S.name_id
1305  left join app_name as APP on APP.id = S.key_id
1306  left join data_dict as D2 on D2.id = APP.app_key
1307  where D.data in ('ANOMALY_SCREEN_OFF_ENERGY', 'ANOMALY_ALARM_WAKEUP', 'ANOMALY_KERNEL_WAKELOCK',
1308  'ANOMALY_RUNNINGLOCK', 'ANORMALY_APP_ENERGY', 'ANOMALY_GNSS_ENERGY', 'ANOMALY_CPU_HIGH_FREQUENCY', 
1309  'ANOMALY_CPU_ENERGY', 'ANOMALY_WAKEUP')
1310  and D2.data not in ('pid_', 'tid_', 'type_', 'tz_', 'uid_', 'domain_', 'id_', 'level_', 'info_', 'tag_', 'APPNAME')
1311  and (S.ts - TR.start_ts) >= $leftNS
1312  and (S.ts - TR.start_ts) <= $rightNS
1313  group by S.serial, APP.app_key, D.data, D2.data;`,
1314    { $leftNS: leftNs, $rightNS: rightNs }
1315  );
1316
1317export const queryBySelectExecute = (
1318  executeId: string,
1319  itid: number
1320): Promise<
1321  Array<{
1322    tid: number;
1323    allocation_task_row: number;
1324    execute_task_row: number;
1325    return_task_row: number;
1326    priority: number;
1327  }>
1328> => {
1329  let sqlStr = `SELECT thread.tid,
1330                       task_pool.allocation_task_row,
1331                       task_pool.execute_task_row,
1332                       task_pool.return_task_row,
1333                       task_pool.priority
1334                FROM task_pool
1335                  LEFT JOIN callstack ON callstack.id = task_pool.allocation_task_row
1336                  LEFT JOIN thread ON thread.id = callstack.callid
1337                WHERE task_pool.task_id = $executeId AND task_pool.execute_itid = $itid;
1338    `;
1339  return query('queryBySelectExecute', sqlStr, { $executeId: executeId, $itid: itid });
1340};
1341
1342export const queryDistributedRelationData = (traceId?: string): Promise<
1343  Array<{
1344    id: number;
1345    chainId: string;
1346    spanId: string;
1347    parentSpanId: string;
1348    chainFlag: string;
1349  }>
1350> => {
1351  let sqlStr = `SELECT 
1352                      c.id, 
1353                      c.chainId, 
1354                      c.spanId, 
1355                      c.parentSpanId, 
1356                      c.flag as chainFlag
1357                      FROM
1358                      callstack c
1359                      WHERE
1360                      c.chainId IS NOT NULL
1361                      AND c.spanId IS NOT NULL
1362                      AND c.parentSpanId IS NOT NULL;`;
1363  return query('queryDistributedRelationData', sqlStr, {}, { traceId: traceId });
1364};
1365
1366export const queryDistributedRelationAllData = (
1367  chainId: string,
1368  traceId: string = ''
1369): Promise<
1370  Array<FuncStruct>
1371> => {
1372  let sqlStr = `SELECT
1373                      P.pid,
1374                      A.tid,
1375                      C.name as chainName,
1376                      C.chainId,
1377                      C.spanId,
1378                      C.parentSpanId,
1379                      C.flag as chainFlag,
1380                      C.depth,
1381                      (C.ts - r.start_ts) as ts,
1382                      c.dur,
1383                      $traceId as traceId
1384                  from callstack C, trace_range r
1385                      left join thread A on A.id = C.callid
1386                      left join process AS P on P.id = A.ipid
1387                      where C.chainId = $chainId;`;
1388  if (traceId === '') {
1389    return query('queryDistributedRelationAllData', sqlStr, { $chainId: chainId, $traceId: traceId });
1390  }
1391  return query('queryDistributedRelationAllData', sqlStr, { $chainId: chainId, $traceId: traceId }, { traceId: traceId });
1392};
1393
1394export const sqlPrioCount = (args: unknown): Promise<unknown> =>
1395  query(
1396    'prioCount',
1397    `select 
1398      S.priority AS prio,
1399      COUNT(S.priority) as count
1400      from 
1401      sched_slice AS S
1402      left join
1403      process P on S.ipid = P.ipid
1404      left join
1405      thread T on S.itid = T.itid
1406      where T.tid = ${//@ts-ignore
1407    args.tid}
1408      and P.pid = ${//@ts-ignore
1409    args.pid}
1410      GROUP BY S.priority;`
1411  );
1412
1413export const queryRunningThread = (
1414  pIds: Array<number>,
1415  tIds: Array<number>,
1416  leftStartNs: number,
1417  rightEndNs: number
1418): Promise<Array<unknown>> =>
1419  query(
1420    'getTabThread',
1421    `
1422        select
1423          P.pid,
1424          T.tid,
1425          S.itid,
1426          S.ts,
1427          P.name AS pName,
1428          S.dur + S.ts as endTs
1429        from
1430          sched_slice AS S
1431        left join
1432          process P on S.ipid = P.ipid
1433        left join
1434          thread T on S.itid = T.itid
1435        where
1436          T.tid in (${tIds.join(',')})
1437        and 
1438          P.pid in (${pIds.join(',')})
1439        and
1440          not ((S.ts + ifnull(S.dur,0) < $leftStartNs) or (S.ts > $rightEndNs))
1441        order by
1442          S.ts;
1443        `,
1444    { $leftStartNs: leftStartNs, $rightEndNs: rightEndNs }
1445  );
1446
1447export const queryCoreRunningThread = (
1448  pIds: Array<number>,
1449  tIds: Array<number>,
1450  cpu: Array<number>,
1451  leftStartNs: number,
1452  rightEndNs: number
1453): Promise<Array<unknown>> =>
1454  query(
1455    'getTabThread',
1456    `
1457          select
1458            P.pid,
1459            T.tid,
1460            S.cpu,
1461            S.itid,
1462            S.ts,
1463            P.name AS pName,
1464            S.dur + S.ts as endTs
1465          from
1466            sched_slice AS S
1467          left join
1468            process P on S.ipid = P.ipid
1469          left join
1470            thread T on S.itid = T.itid
1471          where
1472            T.tid in (${tIds.join(',')})
1473          and 
1474            P.pid in (${pIds.join(',')})
1475          and
1476            S.cpu in (${cpu.join(',')})
1477          and
1478            not ((S.ts + ifnull(S.dur,0) < $leftStartNs) or (S.ts > $rightEndNs))
1479          order by
1480            S.ts;
1481          `,
1482    { $leftStartNs: leftStartNs, $rightEndNs: rightEndNs }
1483  );
1484