diff --git a/src/services/__tests__/from-text.spec.ts b/src/services/__tests__/from-text.spec.ts index dda02022..6442433d 100644 --- a/src/services/__tests__/from-text.spec.ts +++ b/src/services/__tests__/from-text.spec.ts @@ -21,7 +21,7 @@ tests.forEach((planTest: string) => { const planExpect = fs.readFileSync(planExpectFile, { encoding: "utf-8" }) const planService = new PlanService() - const r = planService.fromSource(planText) + const r = planService.fromSource(planService.cleanupSource(planText)) expect(r).toMatchObject(JSON.parse(planExpect)) }) }) diff --git a/src/services/__tests__/from-text/38-expect b/src/services/__tests__/from-text/38-expect new file mode 100644 index 00000000..e44e6144 --- /dev/null +++ b/src/services/__tests__/from-text/38-expect @@ -0,0 +1,11 @@ +{ + "Plan": { + "Node Type": "Nested Loop Join", + "Plans": [{ + "Node Type": "Bitmap Heap Scan", + "Plans": [{ + "Node Type": "Bitmap Index Scan" + }] + }] + } +} diff --git a/src/services/__tests__/from-text/38-plan b/src/services/__tests__/from-text/38-plan new file mode 100644 index 00000000..5cd49c66 --- /dev/null +++ b/src/services/__tests__/from-text/38-plan @@ -0,0 +1,8 @@ +Not a real plan. Showing how line breaks (with empty space at the begining) in an Output can break parsing. + QUERY PLAN +═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ + Nested Loop Left Join (cost=11.95..28.52 rows=5 width=157) + -> Bitmap Heap Scan on public.rel_users_exams (cost=11.80..20.27 rows=5 width=52) + Output: rel_users_exams.user_username, rel_users_exams.exam_id, + rel_users_exams.started_at, rel_users_exams.finished_at + -> Bitmap Index Scan on rel_users_exams_pkey (cost=0.00..11.80 rows=5 width=0) diff --git a/src/services/plan-service.ts b/src/services/plan-service.ts index 71a5a449..b67ce592 100644 --- a/src/services/plan-service.ts +++ b/src/services/plan-service.ts @@ -462,6 +462,10 @@ export class PlanService { return closingParIndex != -1 && closingParIndex < openingParIndex } + const sameIndent = (line1: string, line2: string) => { + return line1.search(/\S/) == line2.search(/\S/) + } + _.each(lines, (line: string) => { if (countChar(line, /\)/g) > countChar(line, /\(/g)) { // if there more closing parenthesis this means that it's the @@ -483,6 +487,14 @@ export class PlanService { } else { out.push(line) } + } else if ( + 0 < out.length && + out[out.length - 1].match(/^\s*Output/i) && + !sameIndent(out[out.length - 1], line) + ) { + // If previous line was Output and current line is not same indent + // (which would mean a new information line) + out[out.length - 1] += line } else { out.push(line) }