Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial implementation with XML parsing.

Properly generating a table of nodes for a plan, with all stuff filled in.
Includes the table spec generated by the `plan()` function. Probably some
typos and stuff; will have to add a bunch of tests to make sure they're right.

Also need to add some way to give each node a unique ID and to represent the
parent/child relationships. I'm not sure how I want to do that yet.
  • Loading branch information...
commit 908f0969cb1ac7e5983f72a56fbd3e38f70a9d7f 0 parents
@theory theory authored
2  .gitattributes
@@ -0,0 +1,2 @@
+.gitignore export-ignore
+.gitattributes export-ignore
1  .gitignore
@@ -0,0 +1 @@
+results/
15 Makefile
@@ -0,0 +1,15 @@
+DATA = $(wildcard sql/*.sql)
+DOCS = $(wildcard doc/*.txt)
+TESTS = $(wildcard test/sql/*.sql)
+REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS))
+REGRESS_OPTS = --inputdir=test
+
+ifdef NO_PGXS
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+else
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+endif
188 sql/explain-table.sql
@@ -0,0 +1,188 @@
+-- Adjust this setting to control where the objects get created.
+SET search_path = public;
+
+SET client_min_messages = warning;
+
+CREATE OR REPLACE FUNCTION parse_node(
+ node XML
+) RETURNS TABLE(
+ "Node Type" TEXT,
+ "Strategy" TEXT,
+ "Operation" TEXT,
+ "Startup Cost" FLOAT,
+ "Total Cost" FLOAT,
+ "Plan Rows" FLOAT,
+ "Plan Width" INTEGER,
+ "Actual Startup Time" FLOAT,
+ "Actual Total Time" FLOAT,
+ "Actual Rows" FLOAT,
+ "Actual Loops" FLOAT,
+ "Parent Relationship" TEXT,
+ "Sort Key" TEXT[],
+ "Sort Method" TEXT[],
+ "Sort Space Used" BIGINT,
+ "Sort Space Type" TEXT,
+ "Join Type" TEXT,
+ "Join Filter" TEXT,
+ "Hash Cond" TEXT,
+ "Relation Name" NAME,
+ "Alias" NAME,
+ "Scan Direction" TEXT,
+ "Index Name" TEXT,
+ "Index Cond" TEXT,
+ "Recheck Cond" TEXT,
+ "TID Cond" TEXT,
+ "Merge Cond" TEXT,
+ "Subplan Name" TEXT,
+ "Function Name" TEXT,
+ "Function Call" TEXT,
+ "Filter" TEXT,
+ "One-Time Filter" TEXT,
+ "Command" TEXT,
+ "Shared Hit Blocks" BIGINT,
+ "Shared Read Blocks" BIGINT,
+ "Shared Written Blocks" BIGINT,
+ "Local Hit Blocks" BIGINT,
+ "Local Read Blocks" BIGINT,
+ "Local Written Blocks" BIGINT,
+ "Temp Read Blocks" BIGINT,
+ "Temp Written Blocks" BIGINT,
+ "Output" TEXT[],
+ "Hash Buckets" BIGINT,
+ "Hash Batches" BIGINT,
+ "Original Hash Batches" BIGINT,
+ "Peak Memory Usage" BIGINT,
+ "Schema" TEXT,
+ "CTE Name" TEXT
+) LANGUAGE plpgsql AS $$
+DECLARE
+ plans xml[] := xpath('/Plan/Plans/Plan', node);
+BEGIN
+ RETURN QUERY SELECT (xpath('/Plan/Node-Type/text()', node))[1]::text,
+ (xpath('/Plan/Strategy/text()', node))[1]::text,
+ (xpath('/Plan/Operation/text()', node))[1]::text,
+ (xpath('/Plan/Startup-Cost/text()', node))[1]::text::FLOAT,
+ (xpath('/Plan/Total-Cost/text()', node))[1]::text::FLOAT,
+ (xpath('/Plan/Plan-Rows/text()', node))[1]::text::FLOAT,
+ (xpath('/Plan/Plan-Width/text()', node))[1]::text::INTEGER,
+ (xpath('/Plan/Actual-Startup-Time/text()', node))[1]::text::FLOAT,
+ (xpath('/Plan/Actual-Total-Time/text()', node))[1]::text::FLOAT,
+ (xpath('/Plan/Actual-Rows/text()', node))[1]::text::FLOAT,
+ (xpath('/Plan/Actual-Loops/text()', node))[1]::text::FLOAT,
+ (xpath('/Plan/Parent-Relationship/text()', node))[1]::text,
+ xpath('/Plan/Sort-Key/Item/text()', node)::text[],
+ xpath('/Plan/Sort-Method/text()', node)::text[],
+ (xpath('/Plan/Sort-Space-Used/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Sort-Space-Type/text()', node))[1]::text,
+ (xpath('/Plan/Join-Type/text()', node))[1]::text,
+ (xpath('/Plan/Join-Filter/text()', node))[1]::text,
+ (xpath('/Plan/Hash-Cond/text()', node))[1]::text,
+ (xpath('/Plan/Relation-Name/text()', node))[1]::text::name,
+ (xpath('/Plan/Alias/text()', node))[1]::text::name,
+ (xpath('/Plan/Scan-Direction/text()', node))[1]::text,
+ (xpath('/Plan/Index-Name/text()', node))[1]::text,
+ (xpath('/Plan/Index-Cond/text()', node))[1]::text,
+ (xpath('/Plan/Recheck-Cond/text()', node))[1]::text,
+ (xpath('/Plan/TID-Cond/text()', node))[1]::text,
+ (xpath('/Plan/Merge-Cond/text()', node))[1]::text,
+ (xpath('/Plan/Subplan-Name/text()', node))[1]::text,
+ (xpath('/Plan/Function-Name/text()', node))[1]::text,
+ (xpath('/Plan/Function-Call/text()', node))[1]::text,
+ (xpath('/Plan/Filter/text()', node))[1]::text,
+ (xpath('/Plan/One-Time-Filter/text()', node))[1]::text,
+ (xpath('/Plan/Command/text()', node))[1]::text,
+ (xpath('/Plan/Shared-Hit-Blocks/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Shared-Read-Blocks/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Shared-Written-Blocks/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Local-Hit-Blocks/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Local-Read-Blocks/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Local-Written-Blocks/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Temp-Read-Blocks/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Temp-Written-Blocks/text()', node))[1]::text::bigint,
+ xpath('/Plan/Output/text()', node)::text[],
+ (xpath('/Plan/Hash-Buckets/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Hash-Batches/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Original-Hash-Batches/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Peak-Memory-Usage/text()', node))[1]::text::bigint,
+ (xpath('/Plan/Schema/text()', node))[1]::text,
+ (xpath('/Plan/CTE-Name/text()', node))[1]::text
+ ;
+
+ -- Recurse.
+ IF plans IS NOT NULL THEN
+ FOR node IN SELECT unnest(plans) LOOP
+ RETURN QUERY SELECT * FROM parse_node(node);
+ END LOOP;
+ END IF;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION plan(
+ q TEXT,
+ a BOOLEAN DEFAULT FALSE
+) RETURNS TABLE(
+ "Node Type" TEXT,
+ "Strategy" TEXT,
+ "Operation" TEXT,
+ "Startup Cost" FLOAT,
+ "Total Cost" FLOAT,
+ "Plan Rows" FLOAT,
+ "Plan Width" INTEGER,
+ "Actual Startup Time" FLOAT,
+ "Actual Total Time" FLOAT,
+ "Actual Rows" FLOAT,
+ "Actual Loops" FLOAT,
+ "Parent Relationship" TEXT,
+ "Sort Key" TEXT[],
+ "Sort Method" TEXT[],
+ "Sort Space Used" BIGINT,
+ "Sort Space Type" TEXT,
+ "Join Type" TEXT,
+ "Join Filter" TEXT,
+ "Hash Cond" TEXT,
+ "Relation Name" NAME,
+ "Alias" NAME,
+ "Scan Direction" TEXT,
+ "Index Name" TEXT,
+ "Index Cond" TEXT,
+ "Recheck Cond" TEXT,
+ "TID Cond" TEXT,
+ "Merge Cond" TEXT,
+ "Subplan Name" TEXT,
+ "Function Name" TEXT,
+ "Function Call" TEXT,
+ "Filter" TEXT,
+ "One-Time Filter" TEXT,
+ "Command" TEXT,
+ "Shared Hit Blocks" BIGINT,
+ "Shared Read Blocks" BIGINT,
+ "Shared Written Blocks" BIGINT,
+ "Local Hit Blocks" BIGINT,
+ "Local Read Blocks" BIGINT,
+ "Local Written Blocks" BIGINT,
+ "Temp Read Blocks" BIGINT,
+ "Temp Written Blocks" BIGINT,
+ "Output" TEXT[],
+ "Hash Buckets" BIGINT,
+ "Hash Batches" BIGINT,
+ "Original Hash Batches" BIGINT,
+ "Peak Memory Usage" BIGINT,
+ "Schema" TEXT,
+ "CTE Name" TEXT
+) LANGUAGE plpgsql AS $$
+DECLARE
+ plan xml;
+ node xml;
+BEGIN
+ -- Get the plan.
+ EXECUTE 'EXPLAIN (format xml'
+ || CASE WHEN a THEN ', analyze true' ELSE '' END
+ || ') ' || q INTO plan;
+
+ RETURN QUERY SELECT * FROM parse_node((xpath(
+ '/e:explain/e:Query/e:Plan',
+ plan,
+ ARRAY[ARRAY['e', 'http://www.postgresql.org/2009/explain']]
+ ))[1]);
+END;
+$$;
26 test/expected/base.out
@@ -0,0 +1,26 @@
+\set ECHO 0
+CREATE TABLE
+ Node Type | Strategy | Operation | Startup Cost | Total Cost | Plan Rows | Plan Width | Actual Startup Time | Actual Total Time | Actual Rows | Actual Loops | Parent Relationship | Sort Key | Sort Method | Sort Space Used | Sort Space Type | Join Type | Join Filter | Hash Cond | Relation Name | Alias | Scan Direction | Index Name | Index Cond | Recheck Cond | TID Cond | Merge Cond | Subplan Name | Function Name | Function Call | Filter | One-Time Filter | Command | Shared Hit Blocks | Shared Read Blocks | Shared Written Blocks | Local Hit Blocks | Local Read Blocks | Local Written Blocks | Temp Read Blocks | Temp Written Blocks | Output | Hash Buckets | Hash Batches | Original Hash Batches | Peak Memory Usage | Schema | CTE Name
+-----------+----------+-----------+--------------+------------+-----------+------------+---------------------+-------------------+-------------+--------------+---------------------+----------+-------------+-----------------+-----------------+-----------+-------------+-----------+---------------+-------+----------------+------------+------------+--------------+----------+------------+--------------+---------------+---------------+--------+-----------------+---------+-------------------+--------------------+-----------------------+------------------+-------------------+----------------------+------------------+---------------------+--------+--------------+--------------+-----------------------+-------------------+--------+----------
+ Seq Scan | | | 0 | 34 | 2400 | 4 | | | | | | {} | {} | | | | | | foo | foo | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+(1 row)
+
+ Node Type | Strategy | Operation | Startup Cost | Total Cost | Plan Rows | Plan Width | Actual Startup Time | Actual Total Time | Actual Rows | Actual Loops | Parent Relationship | Sort Key | Sort Method | Sort Space Used | Sort Space Type | Join Type | Join Filter | Hash Cond | Relation Name | Alias | Scan Direction | Index Name | Index Cond | Recheck Cond | TID Cond | Merge Cond | Subplan Name | Function Name | Function Call | Filter | One-Time Filter | Command | Shared Hit Blocks | Shared Read Blocks | Shared Written Blocks | Local Hit Blocks | Local Read Blocks | Local Written Blocks | Temp Read Blocks | Temp Written Blocks | Output | Hash Buckets | Hash Batches | Original Hash Batches | Peak Memory Usage | Schema | CTE Name
+-----------+----------+-----------+--------------+------------+-----------+------------+---------------------+-------------------+-------------+--------------+---------------------+----------+-------------+-----------------+-----------------+-----------+-------------+-----------+---------------+-------+----------------+------------+------------+--------------+----------+------------+--------------+---------------+---------------+--------+-----------------+---------+-------------------+--------------------+-----------------------+------------------+-------------------+----------------------+------------------+---------------------+--------+--------------+--------------+-----------------------+-------------------+--------+----------
+ Seq Scan | | | 0 | 34 | 2400 | 4 | 0.001 | 0.001 | 0 | 1 | | {} | {} | | | | | | foo | foo | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+(1 row)
+
+ Node Type | Strategy | Operation | Startup Cost | Total Cost | Plan Rows | Plan Width | Actual Startup Time | Actual Total Time | Actual Rows | Actual Loops | Parent Relationship | Sort Key | Sort Method | Sort Space Used | Sort Space Type | Join Type | Join Filter | Hash Cond | Relation Name | Alias | Scan Direction | Index Name | Index Cond | Recheck Cond | TID Cond | Merge Cond | Subplan Name | Function Name | Function Call | Filter | One-Time Filter | Command | Shared Hit Blocks | Shared Read Blocks | Shared Written Blocks | Local Hit Blocks | Local Read Blocks | Local Written Blocks | Temp Read Blocks | Temp Written Blocks | Output | Hash Buckets | Hash Batches | Original Hash Batches | Peak Memory Usage | Schema | CTE Name
+---------------+----------+-----------+--------------+------------+-----------+------------+---------------------+-------------------+-------------+--------------+---------------------+-------------------------------------------------------------------------------+-------------+-----------------+-----------------+-----------+----------------------------------------------+----------------------------+-------------------------+-------+----------------+------------------------+----------------------------+--------------+----------+------------+--------------+---------------+---------------+-----------------+-----------------+---------+-------------------+--------------------+-----------------------+------------------+-------------------+----------------------+------------------+---------------------+--------+--------------+--------------+-----------------------+-------------------+--------+----------
+ Aggregate | Sorted | | 258.13 | 262.31 | 4 | 324 | 0.121 | 0.121 | 0 | 1 | | {} | {} | | | | | | | | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Sort | | | 258.13 | 258.14 | 4 | 324 | 0.117 | 0.117 | 0 | 1 | Outer | {d.name,d.version,d.abstract,d.description,d.relstatus,d.owner,d.sha1,d.meta} | {quicksort} | 25 | Memory | | | | | | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Nested Loop | | | 16.75 | 258.09 | 4 | 324 | 0.009 | 0.009 | 0 | 1 | Outer | {} | {} | | | Left | (semver_cmp(d.version, dt.version) = 0) | | | | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Hash Join | | | 16.75 | 253.06 | 4 | 292 | 0.009 | 0.009 | 0 | 1 | Outer | {} | {} | | | Inner | (semver_cmp(d.version, de.dist_version) = 0) | (de.distribution = d.name) | | | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Seq Scan | | | 0 | 15.1 | 510 | 128 | 0.008 | 0.008 | 0 | 1 | Outer | {} | {} | | | | | | distribution_extensions | de | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Hash | | | 13 | 13 | 300 | 228 | 0 | 0 | 0 | 0 | Inner | {} | {} | | | | | | | | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Seq Scan | | | 0 | 13 | 300 | 228 | 0 | 0 | 0 | 0 | Outer | {} | {} | | | | | | distributions | d | | | | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Index Scan | | | 0 | 0.46 | 3 | 96 | 0 | 0 | 0 | 0 | Inner | {} | {} | | | | | | distribution_tags | dt | NoMovement | distribution_tags_pkey | (d.name = dt.distribution) | | | | | | | | | | | | | | | | | | {} | | | | | |
+ Function Scan | | | 0 | 1 | 100 | 32 | 0 | 0 | 0 | 0 | SubPlan | {} | {} | | | | | | | g | | | | | | | SubPlan 1 | unnest | | (x IS NOT NULL) | | | | | | | | | | | {} | | | | | |
+(9 rows)
+
+ROLLBACK
162 test/sql/base.sql
@@ -0,0 +1,162 @@
+\set ECHO 0
+BEGIN;
+\set QUIET 1
+\i sql/explain-table.sql
+\set QUIET 0
+
+CREATE TABLE foo(id int);
+
+SELECT * FROM plan('select * from foo');
+SELECT * FROM plan('select * from foo', true);
+
+SELECT * FROM parse_node($$ <Plan>
+ <Node-Type>Aggregate</Node-Type>
+ <Strategy>Sorted</Strategy>
+ <Startup-Cost>258.13</Startup-Cost>
+ <Total-Cost>262.31</Total-Cost>
+ <Plan-Rows>4</Plan-Rows>
+ <Plan-Width>324</Plan-Width>
+ <Actual-Startup-Time>0.121</Actual-Startup-Time>
+ <Actual-Total-Time>0.121</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>1</Actual-Loops>
+ <Plans>
+ <Plan>
+ <Node-Type>Sort</Node-Type>
+ <Parent-Relationship>Outer</Parent-Relationship>
+ <Startup-Cost>258.13</Startup-Cost>
+ <Total-Cost>258.14</Total-Cost>
+ <Plan-Rows>4</Plan-Rows>
+ <Plan-Width>324</Plan-Width>
+ <Actual-Startup-Time>0.117</Actual-Startup-Time>
+ <Actual-Total-Time>0.117</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>1</Actual-Loops>
+ <Sort-Key>
+ <Item>d.name</Item>
+ <Item>d.version</Item>
+ <Item>d.abstract</Item>
+ <Item>d.description</Item>
+ <Item>d.relstatus</Item>
+ <Item>d.owner</Item>
+ <Item>d.sha1</Item>
+ <Item>d.meta</Item>
+ </Sort-Key>
+ <Sort-Method>quicksort</Sort-Method>
+ <Sort-Space-Used>25</Sort-Space-Used>
+ <Sort-Space-Type>Memory</Sort-Space-Type>
+ <Plans>
+ <Plan>
+ <Node-Type>Nested Loop</Node-Type>
+ <Parent-Relationship>Outer</Parent-Relationship>
+ <Join-Type>Left</Join-Type>
+ <Startup-Cost>16.75</Startup-Cost>
+ <Total-Cost>258.09</Total-Cost>
+ <Plan-Rows>4</Plan-Rows>
+ <Plan-Width>324</Plan-Width>
+ <Actual-Startup-Time>0.009</Actual-Startup-Time>
+ <Actual-Total-Time>0.009</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>1</Actual-Loops>
+ <Join-Filter>(semver_cmp(d.version, dt.version) = 0)</Join-Filter>
+ <Plans>
+ <Plan>
+ <Node-Type>Hash Join</Node-Type>
+ <Parent-Relationship>Outer</Parent-Relationship>
+ <Join-Type>Inner</Join-Type>
+ <Startup-Cost>16.75</Startup-Cost>
+ <Total-Cost>253.06</Total-Cost>
+ <Plan-Rows>4</Plan-Rows>
+ <Plan-Width>292</Plan-Width>
+ <Actual-Startup-Time>0.009</Actual-Startup-Time>
+ <Actual-Total-Time>0.009</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>1</Actual-Loops>
+ <Hash-Cond>(de.distribution = d.name)</Hash-Cond>
+ <Join-Filter>(semver_cmp(d.version, de.dist_version) = 0)</Join-Filter>
+ <Plans>
+ <Plan>
+ <Node-Type>Seq Scan</Node-Type>
+ <Parent-Relationship>Outer</Parent-Relationship>
+ <Relation-Name>distribution_extensions</Relation-Name>
+ <Alias>de</Alias>
+ <Startup-Cost>0.00</Startup-Cost>
+ <Total-Cost>15.10</Total-Cost>
+ <Plan-Rows>510</Plan-Rows>
+ <Plan-Width>128</Plan-Width>
+ <Actual-Startup-Time>0.008</Actual-Startup-Time>
+ <Actual-Total-Time>0.008</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>1</Actual-Loops>
+ </Plan>
+ <Plan>
+ <Node-Type>Hash</Node-Type>
+ <Parent-Relationship>Inner</Parent-Relationship>
+ <Startup-Cost>13.00</Startup-Cost>
+ <Total-Cost>13.00</Total-Cost>
+ <Plan-Rows>300</Plan-Rows>
+ <Plan-Width>228</Plan-Width>
+ <Actual-Startup-Time>0.000</Actual-Startup-Time>
+ <Actual-Total-Time>0.000</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>0</Actual-Loops>
+ <Plans>
+ <Plan>
+ <Node-Type>Seq Scan</Node-Type>
+ <Parent-Relationship>Outer</Parent-Relationship>
+ <Relation-Name>distributions</Relation-Name>
+ <Alias>d</Alias>
+ <Startup-Cost>0.00</Startup-Cost>
+ <Total-Cost>13.00</Total-Cost>
+ <Plan-Rows>300</Plan-Rows>
+ <Plan-Width>228</Plan-Width>
+ <Actual-Startup-Time>0.000</Actual-Startup-Time>
+ <Actual-Total-Time>0.000</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>0</Actual-Loops>
+ </Plan>
+ </Plans>
+ </Plan>
+ </Plans>
+ </Plan>
+ <Plan>
+ <Node-Type>Index Scan</Node-Type>
+ <Parent-Relationship>Inner</Parent-Relationship>
+ <Scan-Direction>NoMovement</Scan-Direction>
+ <Index-Name>distribution_tags_pkey</Index-Name>
+ <Relation-Name>distribution_tags</Relation-Name>
+ <Alias>dt</Alias>
+ <Startup-Cost>0.00</Startup-Cost>
+ <Total-Cost>0.46</Total-Cost>
+ <Plan-Rows>3</Plan-Rows>
+ <Plan-Width>96</Plan-Width>
+ <Actual-Startup-Time>0.000</Actual-Startup-Time>
+ <Actual-Total-Time>0.000</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>0</Actual-Loops>
+ <Index-Cond>(d.name = dt.distribution)</Index-Cond>
+ </Plan>
+ </Plans>
+ </Plan>
+ </Plans>
+ </Plan>
+ <Plan>
+ <Node-Type>Function Scan</Node-Type>
+ <Parent-Relationship>SubPlan</Parent-Relationship>
+ <Subplan-Name>SubPlan 1</Subplan-Name>
+ <Function-Name>unnest</Function-Name>
+ <Alias>g</Alias>
+ <Startup-Cost>0.00</Startup-Cost>
+ <Total-Cost>1.00</Total-Cost>
+ <Plan-Rows>100</Plan-Rows>
+ <Plan-Width>32</Plan-Width>
+ <Actual-Startup-Time>0.000</Actual-Startup-Time>
+ <Actual-Total-Time>0.000</Actual-Total-Time>
+ <Actual-Rows>0</Actual-Rows>
+ <Actual-Loops>0</Actual-Loops>
+ <Filter>(x IS NOT NULL)</Filter>
+ </Plan>
+ </Plans>
+ </Plan>
+$$);
+ROLLBACK;
Please sign in to comment.
Something went wrong with that request. Please try again.