Initial support for fixing of line-wrapped plans

Ever since I released explain.depesz.com over 11 years ago there have been cases were people would upload a plan and it didn't parse.

There were many reasons, but the most common was – plan was line-wrapped by injecting new-line characters where there shouldn't be one.

For example:

  1.                                                                   QUERY PLAN
  2. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  3.  Sort  (cost=32.88..32.96 ROWS=32 width=224) (actual TIME=0.532..0.532 
  4. ROWS=0 loops=1)
  5.    Sort KEY: n.nspname, c.relname
  6.    Sort Method: quicksort  Memory: 25kB
  7.    ->  Hash JOIN  (cost=1.09..32.08 ROWS=32 width=224) (actual TIME=0.5
  8. 24..0.525 ROWS=0 loops=1)
  9.          Hash Cond: (c.relnamespace = n.oid)
  10.          ->  Seq Scan ON pg_class c  (cost=0.00..29.84 ROWS=64 width=73
  11. ) (actual TIME=0.026..0.397 ROWS=128 loops=1)
  12.                FILTER: ((relkind = ANY ('{r,p,v,m,S,f,""}'::"char"[])) AND pg_table_is_visible(oid))
  13.                ROWS Removed BY FILTER: 261
  14.          ->  Hash  (cost=1.07..1.07 ROWS=2 width=68) (actual TIME=0.062..0.062 ROWS=2 loops=1)
  15.                Buckets: 1024  Batches: 1  Memory Usage: 9kB
  16.                ->  Seq Scan ON pg_namespace n  (cost=0.00..1.07 ROWS=2 width=68) (actual TIME=0.032..0.038 ROWS=2 loops=1)
  17.                      FILTER: ((nspname <> 'pg_catalog'::name) AND (nspname <> 'information_schema'::name) AND (nspname !~ '^pg_toast'::text))
  18.                      ROWS Removed BY FILTER: 3
  19.  Planning TIME: 0.636 ms
  20.  Execution TIME: 0.616 ms
  21. (15 ROWS)

This is artificial example, but it shows what is the problem. In case you don't see it – lines 4, 8, and 11 should be as continuation in previous lines.

Older Pg::Explain library when parsing such plans sometimes failed altogether, and sometimes produced incorrect results.

But today, I released new version that contains some support for unbreaking such plans. It doesn't work in all cases, and quite likely in most cases, but in some – it works.

Hope it will help you, and hope it doesn't break some pre-existing plans.