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 { FuncStruct } from '../ui-worker/ProcedureWorkerFunc'; 17import { SearchFuncBean } from '../../bean/SearchFuncBean'; 18import { SelectionData } from '../../bean/BoxSelection'; 19import { HeapTraceFunctionInfo } from '../../../js-heap/model/DatabaseStruct'; 20import { FunctionItem } from '../../bean/BinderProcessThread'; 21import { StateGroup } from '../../bean/StateModle'; 22import { FuncNameCycle } from '../../bean/BinderProcessThread'; 23import { Utils } from '../../component/trace/base/Utils'; 24 25export const queryFuncNameCycle = ( 26 funcName: string, 27 tIds: string, 28 leftNS: number, 29 rightNS: number 30): Promise<Array<FunctionItem>> => 31 query( 32 'queryFuncNameCycle', 33 ` 34 SELECT 35 c.ts - r.start_ts AS cycleStartTime, 36 c.dur, 37 c.id, 38 t.tid, 39 p.pid 40 FROM 41 callstack c, trace_range r 42 LEFT JOIN 43 thread t 44 ON 45 c.callid = t.id 46 LEFT JOIN 47 process p 48 ON 49 t.ipid = p.id 50 WHERE 51 c.name like '${funcName}%' 52 AND 53 t.tid = ${tIds} 54 AND NOT 55 ((cycleStartTime < ${leftNS}) 56 OR 57 ((c.ts - r.start_ts + c.dur) > ${rightNS})) 58 `, 59 { 60 $funcName: funcName, 61 $tIds: tIds, 62 $leftNS: leftNS, 63 $rightNS: rightNS, 64 }, 65 { traceId: Utils.currentSelectTrace } 66 ); 67 68export const querySingleFuncNameCycle = ( 69 funcName: string, 70 tIds: string, 71 leftNS: number, 72 rightNS: number 73): Promise<Array<FunctionItem>> => 74 query( 75 'querySingleFuncNameCycle', 76 ` 77 SELECT 78 c.name AS funcName, 79 c.ts - r.start_ts AS cycleStartTime, 80 c.dur AS cycleDur, 81 c.id, 82 t.tid, 83 p.pid, 84 c.ts - r.start_ts + c.dur AS endTime 85 FROM 86 callstack c, trace_range r 87 LEFT JOIN 88 thread t 89 ON 90 c.callid = t.id 91 LEFT JOIN 92 process p 93 ON 94 t.ipid = p.id 95 WHERE 96 c.name = '${funcName}' 97 AND 98 t.tid = ${tIds} 99 AND NOT 100 ((cycleStartTime < ${leftNS}) 101 OR 102 (endTime > ${rightNS})) 103 `, 104 { 105 $funcName: funcName, 106 $tIds: tIds, 107 $leftNS: leftNS, 108 $rightNS: rightNS, 109 } 110 ); 111 112export const queryAllFuncNames = async (traceId?: string): Promise<Array<unknown>> => { 113 let list = await query( 114 'queryIsColorIndex', 115 `select 116 colorIndex 117 from 118 callstack 119 limit 1;`, 120 {}, 121 { traceId: traceId, action: 'exec-buf' } 122 ); 123 let isColorIndex = list.length !== 0 ? true : false; 124 let colorIndexStr = isColorIndex ? ',colorIndex' : ''; 125 let allFuncNamesBuffer = await query( 126 'queryAllFuncNames', 127 `select 128 id, 129 name 130 ${colorIndexStr} 131 from 132 callstack;`, 133 {}, 134 { traceId: traceId, action: 'exec-buf' } 135 ); 136 // @ts-ignore 137 return Utils.convertJSON(allFuncNamesBuffer); 138}; 139 140export const queryProcessAsyncFunc = ( 141 traceRange: { 142 startTs: number; 143 endTs: number; 144 }, 145 traceId?: string 146): //@ts-ignore 147 Promise<Array<unknown>> => 148 query( 149 'queryProcessAsyncFunc', 150 `SELECT 151 A.tid, 152 P.pid, 153 c.ts-${traceRange.startTs} as startTs, 154 c.dur, 155 c.custom_category as category, 156 c.id, 157 c.depth, 158 c.argsetid, 159 c.cookie, 160 c.trace_level, 161 c.trace_tag, 162 c.custom_args, 163 c.child_callid 164 FROM 165 (SELECT id, ts, parent_id, dur, depth, argsetid, cookie, custom_category, child_callid, trace_level, 166 trace_tag, custom_args from callstack where cookie NOT NULL) c 167 LEFT JOIN thread A ON A.id = c.child_callid 168 LEFT JOIN process P ON P.id = A.ipid 169 WHERE 170 startTs NOT NULL;`, 171 {}, 172 { traceId: traceId } 173 ); 174 175export const queryProcessAsyncFuncCat = ( 176 traceRange: { 177 startTs: number; 178 endTs: number; 179 } 180): Promise<Array<unknown>> => 181 query( 182 'queryProcessAsyncFuncCat', 183 ` 184 select 185 A.tid, 186 P.pid, 187 c.custom_category as threadName, 188 c.name as funName, 189 c.ts-${traceRange.startTs} as startTs, 190 c.dur, 191 c.depth, 192 c.cookie, 193 c.trace_level, 194 c.trace_tag, 195 c.custom_args, 196 c.child_callid 197 from 198 (select callid, name, ts, dur, custom_category, depth, cookie, parent_id,trace_level,trace_tag, 199 custom_args,child_callid from callstack where cookie not null and custom_category not null and child_callid is null) c 200 left join 201 thread A on A.id = c.callid 202 left join 203 process P on P.id = A.ipid 204 where 205 startTs not null 206 order by custom_category; 207 `, 208 {} 209 ); 210 211export const getMaxDepthByTid = (traceId?: string): //@ts-ignore 212 Promise<Array<unknown>> => 213 query( 214 'getMaxDepthByTid', 215 `SELECT 216 tid, 217 ipid, 218 maxDepth 219 FROM 220 thread T 221 LEFT JOIN ( 222 SELECT 223 callid, 224 MAX( c.depth + 1 ) AS maxDepth 225 FROM 226 callstack C 227 WHERE 228 c.ts IS NOT NULL 229 AND c.cookie IS NULL 230 GROUP BY 231 callid 232 ) C ON T.id = C.callid 233 WHERE 234 maxDepth NOT NULL`, 235 {}, 236 { traceId: traceId } 237 ); 238 239export const querySearchFuncData = ( 240 funcName: string, 241 tIds: number, 242 leftNS: number, 243 rightNS: number 244): Promise<Array<SearchFuncBean>> => 245 query( 246 'querySearchFuncData', 247 `select 248 c.ts - r.start_ts as startTime, 249 c.dur 250 from 251 callstack c 252 left join 253 thread t 254 on 255 c.callid = t.id 256 left join 257 process p 258 on 259 t.ipid = p.id 260 left join 261 trace_range r 262 where 263 c.name like '${funcName}%' 264 and 265 t.tid = ${tIds} 266 and 267 not ((startTime < ${leftNS}) or (startTime > ${rightNS})); 268 ` 269 ); 270 271export const queryFuncRowData = (funcName: string, tIds: number): Promise<Array<SearchFuncBean>> => 272 query( 273 'queryFuncRowData', 274 `select 275 c.name as funName, 276 c.ts - r.start_ts as startTime, 277 t.tid as tid 278 from 279 callstack c 280 left join 281 thread t 282 on 283 c.callid = t.id 284 left join 285 process p 286 on 287 t.ipid = p.id 288 left join 289 trace_range r 290 where 291 c.name like '${funcName}%' 292 and 293 t.tid = ${tIds} 294 `, 295 { $search: funcName } 296 ); 297 298export const fuzzyQueryFuncRowData = (funcName: string, tIds: number): 299 Promise<Array<SearchFuncBean>> => 300 query( 301 'fuzzyQueryFuncRowData', 302 `select 303 c.name as funName, 304 c.ts - r.start_ts as startTime, 305 c.ts - r.start_ts + c.dur as endTime, 306 t.tid as tid 307 from 308 callstack c 309 left join 310 thread t 311 on 312 c.callid = t.id 313 left join 314 process p 315 on 316 t.ipid = p.id 317 left join 318 trace_range r 319 where 320 c.name like '%${funcName}%' 321 and 322 t.tid = ${tIds} 323 `, 324 { $search: funcName } 325 ); 326 327export const getTabSlicesAsyncFunc = ( 328 asyncNames: string[], 329 asyncPid: number, 330 asyncTid: number | undefined, 331 leftNS: number, 332 rightNS: number 333): //@ts-ignore 334 Promise<Array<unknown>> => { 335 let condition = `${asyncTid !== null && asyncTid !== undefined ? `and A.tid = ${asyncTid}` : ''}`; 336 let sql = ` 337 SELECT 338 c.name AS name, 339 c.id, 340 sum( c.dur ) AS wallDuration, 341 count( c.name ) AS occurrences 342 FROM 343 (SELECT id, ts, parent_id, dur, name from callstack where cookie NOT NULL) C, 344 trace_range D 345 LEFT JOIN thread A ON A.id = C.parent_id 346 LEFT JOIN process P ON P.id = A.ipid 347 where 348 C.ts > 0 349 and 350 c.dur >= -1 351 and 352 P.pid = ${asyncPid} 353 and 354 c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')}) 355 and 356 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} 357 group by 358 c.name 359 order by 360 wallDuration desc;`; 361 return query<SelectionData>('getTabSlicesAsyncFunc', sql, {}); 362}; 363 364export const getTabDetails = ( 365 asyncNames: Array<string>, 366 asyncPid: Array<number>, 367 funTids: Array<number>, 368 leftNS: number, 369 rightNS: number 370): //@ts-ignore 371 Promise<Array<unknown>> => { 372 let condition = ` 373 and A.tid in (${funTids!.join(',')}) 374 and c.cookie is null 375 ${`and P.pid in (${asyncPid.join(',')})`} 376 ${`and c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')})`} 377 `; 378 let sql = ` 379 SELECT 380 c.name AS name, 381 c.dur AS duration, 382 c.id, 383 P.pid AS processId, 384 P.name AS process, 385 A.tid AS threadId, 386 A.name AS thread, 387 c.ts - D.start_ts as startNs 388 FROM 389 thread A,trace_range D 390 LEFT JOIN process P ON P.id = A.ipid 391 LEFT JOIN callstack C ON A.id = C.callid 392 where 393 C.ts > 0 394 and 395 c.dur >= -1 396 and 397 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} 398 `; 399 return query('getTabDetails', sql, {}); 400}; 401export const getSfDetails = ( 402 asyncNames: Array<string>, 403 asyncPid: number, 404 asyncTid: number | undefined, 405 leftNS: number, 406 rightNS: number 407): //@ts-ignore 408 Promise<Array<unknown>> => { 409 let condition = ` 410 and c.parent_id not null 411 ${asyncTid !== null && asyncTid !== undefined ? `and A.tid = ${asyncTid}` : ''} 412 ${`and P.pid = ${asyncPid}`} 413 ${`and c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')})`} 414 `; 415 let sql = ` 416 SELECT 417 c.name AS name, 418 c.dur AS duration, 419 P.pid AS processId, 420 P.name AS process, 421 A.tid AS threadId, 422 A.name AS thread, 423 c.id, 424 c.ts - D.start_ts as startNs 425 FROM 426 (SELECT id, ts, parent_id, dur, name from callstack where cookie NOT NULL) C, 427 trace_range D 428 LEFT JOIN thread A ON A.id = C.parent_id 429 LEFT JOIN process P ON P.id = A.ipid 430 where 431 C.ts > 0 432 and 433 c.dur >= -1 434 and 435 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} 436 `; 437 return query('getSfDetails', sql, {}); 438}; 439export const getParentDetail = ( 440 asyncPid: Array<number>, 441 funTids: Array<number>, 442 leftNS: number, 443 rightNS: number): 444 Promise<Array<unknown>> => 445 query( 446 'getParentTime', 447 ` SELECT 448 C.ts - D.start_ts AS startTS, 449 C.ts - D.start_ts + C.dur AS endTS, 450 C.depth, 451 c.id, 452 c.name 453 FROM 454 thread A 455 JOIN trace_range D 456 LEFT JOIN process P ON P.id = A.ipid 457 LEFT JOIN callstack C ON A.id = C.callid 458 WHERE 459 C.ts > 0 460 AND C.dur >= - 1 461 AND NOT ( 462 ( C.ts - D.start_ts + C.dur < ${leftNS} ) 463 OR ( C.ts - D.start_ts > ${rightNS} ) 464 ) 465 AND C.cookie IS NULL 466 AND A.tid IN (${funTids!.join(',')}) 467 AND P.pid IN (${asyncPid.join(',')}) 468 ` 469 ); 470export const getFuncChildren = ( 471 funcIds: Array<number>, 472 asyncPid: Array<number>, 473 funTids: Array<number>, 474 leftNS: number, 475 rightNS: number, 476 isChild: boolean 477): //@ts-ignore 478 Promise<Array<unknown>> => { 479 let durStr = isChild ? 'C.dur AS duration,' : 'SUM(COALESCE(C.dur, 0)) AS duration,'; 480 let condition = isChild ? '' : 'group by parentName'; 481 let sql = ` 482 SELECT 483 c.parent_id parentId, 484 ${durStr} 485 c.id, 486 c.name, 487 c1.name parentName 488 FROM 489 thread A,trace_range D 490 LEFT JOIN process P ON P.id = A.ipid 491 LEFT JOIN callstack C ON A.id = C.callid 492 LEFT JOIN callstack C1 ON c.parent_id = C1.id 493 where 494 C.ts > 0 495 and 496 c.dur >= -1 497 and 498 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) 499 and A.tid in (${funTids!.join(',')}) 500 and c.cookie is null 501 and P.pid in (${asyncPid.join(',')}) 502 and c.parent_id in (${funcIds.join(',')})${condition} 503 `; 504 return query('getTabDetails', sql, {}); 505}; 506export const getGhDetails = ( 507 asyncNames: Array<string>, 508 catName: string, 509 asyncPid: number, 510 leftNS: number, 511 rightNS: number 512): //@ts-ignore 513 Promise<Array<unknown>> => { 514 let sql = ` 515 SELECT 516 c.name AS name, 517 c.dur AS duration, 518 P.pid AS processId, 519 P.name AS process, 520 A.tid AS threadId, 521 A.name AS thread, 522 c.ts - D.start_ts as startNs 523 FROM 524 thread A,trace_range D 525 LEFT JOIN process P ON P.id = A.ipid 526 LEFT JOIN callstack C ON A.id = C.callid 527 where 528 C.ts > 0 529 and 530 c.dur >= -1 531 and 532 c.cookie not null 533 and 534 c.cat not null 535 and 536 c.parent_id is null 537 and 538 P.pid = ${asyncPid} 539 and 540 cat = '${catName}' 541 and 542 c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')}) 543 and 544 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) 545 `; 546 return query('getGhDetails', sql, {}); 547}; 548export const getTabSlicesAsyncCatFunc = ( 549 asyncCatNames: string, 550 asyncCatPid: number, 551 leftNS: number, 552 rightNS: number 553): Promise<Array<unknown>> => 554 query<SelectionData>( 555 'getTabSlicesAsyncCatFunc', 556 ` 557 select 558 c.name as name, 559 c.id, 560 sum(c.dur) as wallDuration, 561 count(c.name) as occurrences 562 from 563 thread A, trace_range D 564 left join process P on P.id = A.ipid 565 left join callstack C on A.id = C.callid 566 where 567 C.ts > 0 568 and 569 c.dur >= -1 570 and 571 c.cookie not null 572 and 573 c.cat not null 574 and 575 c.parent_id is null 576 and 577 P.pid = ${asyncCatPid} 578 and 579 c.cat = '${asyncCatNames}' 580 and 581 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) 582 group by 583 c.name 584 order by 585 wallDuration desc;`, 586 { $leftNS: leftNS, $rightNS: rightNS } 587 ); 588 589export const querySearchFunc = (search: string): Promise<Array<SearchFuncBean>> => 590 query( 591 'querySearchFunc', 592 ` 593 select c.cookie, 594 c.id, 595 c.name as funName, 596 c.ts - r.start_ts as startTime, 597 c.dur, 598 c.depth, 599 t.tid, 600 t.name as threadName, 601 p.pid, 602 c.argsetid, 603 c.trace_level, 604 c.trace_tag, 605 c.custom_args, 606 c.custom_category as category, 607 'func' as type 608 from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id 609 left join trace_range r 610 where c.name like '%${search}%' and startTime > 0 and cookie IS NULL; 611 `, 612 { $search: search }, 613 { traceId: Utils.currentSelectTrace } 614 ); 615 616 export const querySceneSearchFunc = (search: string, processList: Array<string>): 617 Promise<Array<SearchFuncBean>> => 618 query( 619 'querySceneSearchFunc', 620 `select c.cookie, 621 c.id, 622 c.name as funName, 623 c.ts - r.start_ts as startTime, 624 c.dur, 625 c.depth, 626 t.tid, 627 t.name as threadName, 628 p.pid, 629 c.argsetid, 630 c.trace_level, 631 c.trace_tag, 632 c.custom_args, 633 c.custom_category as category, 634 'func' as type 635 from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id 636 left join trace_range r 637 where c.name like "%${search}%" ESCAPE '\\' and startTime > 0 and p.pid in (${processList.join(',')}) 638 and cookie IS NULL; 639 `, 640 { $search: search }, 641 { traceId: Utils.currentSelectTrace } 642 ); 643 644export const queryHeapFunction = (fileId: number): Promise<Array<HeapTraceFunctionInfo>> => 645 query( 646 'queryHeapFunction', 647 `SELECT 648 function_index as index , 649 function_id as id , 650 name, 651 script_name as scriptName, 652 script_id as scriptId, 653 line, 654 column 655 FROM js_heap_trace_function_info WHERE file_id = ${fileId}` 656 ); 657 658export const queryHeapTraceNode = ( 659 fileId: number 660): //@ts-ignore 661 Promise<Array<unknown>> => 662 query( 663 'queryHeapTraceNode', 664 `SELECT F.name, 665 F.script_name as scriptName, 666 F.script_id as scriptId, 667 F.column, 668 F.line, 669 N.id, 670 N.function_info_index as functionInfoIndex, 671 N.parent_id as parentId, 672 N.count, 673 N.size, 674 IFNULL( S.live_count, 0 ) AS liveCount, 675 IFNULL( S.live_size, 0 ) AS liveSize 676 FROM 677 js_heap_trace_node N 678 LEFT JOIN ( 679 SELECT 680 trace_node_id as traceNodeId, 681 SUM( self_size ) AS liveSize, 682 count( * ) AS liveCount 683 FROM 684 js_heap_nodes 685 WHERE 686 file_id = ${fileId} 687 AND trace_node_id != 0 688 GROUP BY 689 trace_node_id 690 ) S ON N.id = S.trace_node_id 691 LEFT JOIN js_heap_trace_function_info F ON (F.file_id = N.file_id 692 AND F.function_index = N.function_info_index) 693 WHERE 694 N.file_id = ${fileId} 695 ORDER BY 696 N.id` 697 ); 698 699export const queryTaskPoolOtherRelationData = (ids: Array<number>, tid: number): 700 Promise<Array<FuncStruct>> => { 701 let sqlStr = `select 702 c.ts-D.start_ts as startTs, 703 c.dur, 704 c.name as funName, 705 c.argsetid, 706 c.depth, 707 c.id as id, 708 A.itid as itid, 709 A.ipid as ipid 710 from thread A,trace_range D 711 left join callstack C on A.id = C.callid 712 where startTs not null and c.cookie is null and tid = $tid and c.id in (${ids.join(',')})`; 713 return query('queryTaskPoolOtherRelationData', sqlStr, { $ids: ids, $tid: tid }); 714}; 715 716export const queryTaskPoolRelationData = (ids: Array<number>, tids: Array<number>): 717 Promise<Array<FuncStruct>> => { 718 let sqlStr = `select 719 c.ts-D.start_ts as startTs, 720 c.dur, 721 c.name as funName, 722 c.argsetid, 723 c.depth, 724 c.id as id, 725 A.itid as itid, 726 A.ipid as ipid 727 from thread A,trace_range D 728 left join callstack C on A.id = C.callid 729 where startTs not null and c.cookie is null and c.id in (${ids.join(',')}) and tid in (${tids.join( 730 ',' 731 )})`; 732 return query('queryTaskPoolRelationData', sqlStr, { $ids: ids, $tids: tids }); 733}; 734 735export const queryStatesCut = (tIds: Array<number>, leftNS: number, rightNS: number): 736 Promise<Array<StateGroup>> => 737 query<StateGroup>( 738 'queryBinderByThreadId', 739 ` 740 select 741 B.id, 742 B.pid, 743 B.tid, 744 B.dur, 745 B.cpu, 746 B.state, 747 B.ts - C.start_ts AS ts, 748 B.dur + B.ts as endTs 749 from 750 thread_state AS B,trace_range AS C 751 where 752 B.tid in (${tIds.join(',')}) 753 and 754 ((B.ts + ifnull(B.dur,0) > ($leftStartNs + C.start_ts)) 755 and (B.ts + B.dur < ($rightEndNs + C.start_ts)) 756 or 757 ( 758 B.ts > ($leftStartNs + C.start_ts) and B.ts < ($rightEndNs + C.start_ts) 759 )) 760 order by 761 B.pid; 762 `, 763 { 764 $tIds: tIds, 765 $leftStartNs: leftNS, 766 $rightEndNs: rightNS, 767 } 768 ); 769 770export const queryLoopFuncNameCycle = ( 771 funcName: string, 772 tIds: string, 773 leftNS: number, 774 rightNS: number 775): Promise<Array<FuncNameCycle>> => 776 query( 777 'queryLoopFuncNameCycle', 778 ` 779 SELECT 780 c.name AS funcName, 781 c.ts - r.start_ts AS cycleStartTime, 782 0 AS cycleDur, 783 c.id, 784 t.tid, 785 p.pid 786 FROM 787 callstack c, trace_range r 788 LEFT JOIN 789 thread t 790 ON 791 c.callid = t.id 792 LEFT JOIN 793 process p 794 ON 795 t.ipid = p.id 796 WHERE 797 c.name like '${funcName}%' 798 AND 799 t.tid = ${tIds} 800 AND NOT 801 ((cycleStartTime < ${leftNS}) 802 OR 803 (cycleStartTime > ${rightNS})) 804 `, 805 { 806 $funcName: funcName, 807 $tIds: tIds, 808 $leftNS: leftNS, 809 $rightNS: rightNS, 810 } 811 ); 812 813export const querySingleFuncNameCycleStates = ( 814 funcName: string, 815 tIds: string, 816 leftNS: number, 817 rightNS: number 818): Promise<Array<FuncNameCycle>> => 819 query( 820 'querySingleFuncNameCycle', 821 ` 822 SELECT 823 c.name AS funcName, 824 c.ts - r.start_ts AS cycleStartTime, 825 c.dur AS cycleDur, 826 c.id, 827 t.tid, 828 p.pid, 829 c.ts - r.start_ts + c.dur AS endTime 830 FROM 831 callstack c, trace_range r 832 LEFT JOIN 833 thread t 834 ON 835 c.callid = t.id 836 LEFT JOIN 837 process p 838 ON 839 t.ipid = p.id 840 WHERE 841 c.name like '${funcName}%' 842 AND 843 t.tid = ${tIds} 844 AND NOT 845 ((cycleStartTime < ${leftNS}) 846 OR 847 (endTime > ${rightNS})) 848 `, 849 { 850 $funcName: funcName, 851 $tIds: tIds, 852 $leftNS: leftNS, 853 $rightNS: rightNS, 854 } 855 ); 856