Clean up EXPLAIN's handling of per-worker details.
Previously, it was possible for EXPLAIN ANALYZE of a parallel query
to produce several different "Workers" fields for a single plan node,
because different portions of explain.c independently generated
per-worker data and wrapped that output in separate fields. This
is pretty bogus, especially for the structured output formats: even
if it's not technically illegal, most programs would have a hard time
dealing with such data.
To improve matters, add infrastructure that allows redirecting
per-worker values into a side data structure, and then collect that
data into a single "Workers" field after we've finished running all
the relevant code for a given plan node.
There are a few visible side-effects:
* In text format, instead of something like
Sort Method: external merge Disk: 4920kB
Worker 0: Sort Method: external merge Disk: 5880kB
Worker 1: Sort Method: external merge Disk: 5920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Buffers: shared hit=345 read=3507, temp read=505 written=744
you get
Sort Method: external merge Disk: 4920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Sort Method: external merge Disk: 5880kB
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Sort Method: external merge Disk: 5920kB
Buffers: shared hit=345 read=3507, temp read=505 written=744
* When JIT is enabled, any relevant per-worker JIT stats are attached
to the child node of the Gather or Gather Merge node, which is where
the other per-worker output has always been. Previously, that info
was attached directly to a Gather node, or missed entirely for Gather
Merge.
* A query's summary JIT data no longer includes a bogus
"Worker Number: -1" field.
A notable code-level change is that indenting for lines of text-format
output should now be handled by calling "ExplainIndentText(es)",
instead of hard-wiring how much space to emit. This seems a good deal
cleaner anyway.
This patch also adds a new "explain.sql" regression test script that's
dedicated to testing EXPLAIN. There is more that can be done in that
line, certainly, but for now it just adds some coverage of the XML and
YAML output formats, which had been completely untested.
Although this is surely a bug fix, it's not clear that people would
be happy with rearranging EXPLAIN output in a minor release, so apply
to HEAD only.
Maciek Sakrejda and Tom Lane, based on an idea of Andres Freund's;
reviewed by Georgios Kokolatos
Discussion: https://postgr.es/m/CAOtHd0AvAA8CLB9Xz0wnxu1U=zJCKrr1r4QwwXi_kcQsHDVU=Q@mail.gmail.com
2020-01-26 00:16:42 +01:00
|
|
|
--
|
|
|
|
-- EXPLAIN
|
|
|
|
--
|
|
|
|
-- There are many test cases elsewhere that use EXPLAIN as a vehicle for
|
|
|
|
-- checking something else (usually planner behavior). This file is
|
|
|
|
-- concerned with testing EXPLAIN in its own right.
|
|
|
|
--
|
|
|
|
|
|
|
|
-- To produce stable regression test output, it's usually necessary to
|
|
|
|
-- ignore details such as exact costs or row counts. These filter
|
|
|
|
-- functions replace changeable output details with fixed strings.
|
|
|
|
|
|
|
|
create function explain_filter(text) returns setof text
|
|
|
|
language plpgsql as
|
|
|
|
$$
|
|
|
|
declare
|
|
|
|
ln text;
|
|
|
|
begin
|
|
|
|
for ln in execute $1
|
|
|
|
loop
|
|
|
|
-- Replace any numeric word with just 'N'
|
Make use of in-core query id added by commit 5fd9dfa5f5
Use the in-core query id computation for pg_stat_activity,
log_line_prefix, and EXPLAIN VERBOSE.
Similar to other fields in pg_stat_activity, only the queryid from the
top level statements are exposed, and if the backends status isn't
active then the queryid from the last executed statements is displayed.
Add a %Q placeholder to include the queryid in log_line_prefix, which
will also only expose top level statements.
For EXPLAIN VERBOSE, if a query identifier has been computed, either by
enabling compute_query_id or using a third-party module, display it.
Bump catalog version.
Discussion: https://postgr.es/m/20210407125726.tkvjdbw76hxnpwfi@nol
Author: Julien Rouhaud
Reviewed-by: Alvaro Herrera, Nitin Jadhav, Zhihong Yu
2021-04-07 20:03:56 +02:00
|
|
|
ln := regexp_replace(ln, '-?\m\d+\M', 'N', 'g');
|
Clean up EXPLAIN's handling of per-worker details.
Previously, it was possible for EXPLAIN ANALYZE of a parallel query
to produce several different "Workers" fields for a single plan node,
because different portions of explain.c independently generated
per-worker data and wrapped that output in separate fields. This
is pretty bogus, especially for the structured output formats: even
if it's not technically illegal, most programs would have a hard time
dealing with such data.
To improve matters, add infrastructure that allows redirecting
per-worker values into a side data structure, and then collect that
data into a single "Workers" field after we've finished running all
the relevant code for a given plan node.
There are a few visible side-effects:
* In text format, instead of something like
Sort Method: external merge Disk: 4920kB
Worker 0: Sort Method: external merge Disk: 5880kB
Worker 1: Sort Method: external merge Disk: 5920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Buffers: shared hit=345 read=3507, temp read=505 written=744
you get
Sort Method: external merge Disk: 4920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Sort Method: external merge Disk: 5880kB
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Sort Method: external merge Disk: 5920kB
Buffers: shared hit=345 read=3507, temp read=505 written=744
* When JIT is enabled, any relevant per-worker JIT stats are attached
to the child node of the Gather or Gather Merge node, which is where
the other per-worker output has always been. Previously, that info
was attached directly to a Gather node, or missed entirely for Gather
Merge.
* A query's summary JIT data no longer includes a bogus
"Worker Number: -1" field.
A notable code-level change is that indenting for lines of text-format
output should now be handled by calling "ExplainIndentText(es)",
instead of hard-wiring how much space to emit. This seems a good deal
cleaner anyway.
This patch also adds a new "explain.sql" regression test script that's
dedicated to testing EXPLAIN. There is more that can be done in that
line, certainly, but for now it just adds some coverage of the XML and
YAML output formats, which had been completely untested.
Although this is surely a bug fix, it's not clear that people would
be happy with rearranging EXPLAIN output in a minor release, so apply
to HEAD only.
Maciek Sakrejda and Tom Lane, based on an idea of Andres Freund's;
reviewed by Georgios Kokolatos
Discussion: https://postgr.es/m/CAOtHd0AvAA8CLB9Xz0wnxu1U=zJCKrr1r4QwwXi_kcQsHDVU=Q@mail.gmail.com
2020-01-26 00:16:42 +01:00
|
|
|
-- In sort output, the above won't match units-suffixed numbers
|
|
|
|
ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g');
|
2020-04-03 18:25:44 +02:00
|
|
|
-- Ignore text-mode buffers output because it varies depending
|
|
|
|
-- on the system state
|
|
|
|
CONTINUE WHEN (ln ~ ' +Buffers: .*');
|
2020-08-21 18:22:55 +02:00
|
|
|
-- Ignore text-mode "Planning:" line because whether it's output
|
|
|
|
-- varies depending on the system state
|
|
|
|
CONTINUE WHEN (ln = 'Planning:');
|
Clean up EXPLAIN's handling of per-worker details.
Previously, it was possible for EXPLAIN ANALYZE of a parallel query
to produce several different "Workers" fields for a single plan node,
because different portions of explain.c independently generated
per-worker data and wrapped that output in separate fields. This
is pretty bogus, especially for the structured output formats: even
if it's not technically illegal, most programs would have a hard time
dealing with such data.
To improve matters, add infrastructure that allows redirecting
per-worker values into a side data structure, and then collect that
data into a single "Workers" field after we've finished running all
the relevant code for a given plan node.
There are a few visible side-effects:
* In text format, instead of something like
Sort Method: external merge Disk: 4920kB
Worker 0: Sort Method: external merge Disk: 5880kB
Worker 1: Sort Method: external merge Disk: 5920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Buffers: shared hit=345 read=3507, temp read=505 written=744
you get
Sort Method: external merge Disk: 4920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Sort Method: external merge Disk: 5880kB
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Sort Method: external merge Disk: 5920kB
Buffers: shared hit=345 read=3507, temp read=505 written=744
* When JIT is enabled, any relevant per-worker JIT stats are attached
to the child node of the Gather or Gather Merge node, which is where
the other per-worker output has always been. Previously, that info
was attached directly to a Gather node, or missed entirely for Gather
Merge.
* A query's summary JIT data no longer includes a bogus
"Worker Number: -1" field.
A notable code-level change is that indenting for lines of text-format
output should now be handled by calling "ExplainIndentText(es)",
instead of hard-wiring how much space to emit. This seems a good deal
cleaner anyway.
This patch also adds a new "explain.sql" regression test script that's
dedicated to testing EXPLAIN. There is more that can be done in that
line, certainly, but for now it just adds some coverage of the XML and
YAML output formats, which had been completely untested.
Although this is surely a bug fix, it's not clear that people would
be happy with rearranging EXPLAIN output in a minor release, so apply
to HEAD only.
Maciek Sakrejda and Tom Lane, based on an idea of Andres Freund's;
reviewed by Georgios Kokolatos
Discussion: https://postgr.es/m/CAOtHd0AvAA8CLB9Xz0wnxu1U=zJCKrr1r4QwwXi_kcQsHDVU=Q@mail.gmail.com
2020-01-26 00:16:42 +01:00
|
|
|
return next ln;
|
|
|
|
end loop;
|
|
|
|
end;
|
|
|
|
$$;
|
|
|
|
|
|
|
|
-- To produce valid JSON output, replace numbers with "0" or "0.0" not "N"
|
|
|
|
create function explain_filter_to_json(text) returns jsonb
|
|
|
|
language plpgsql as
|
|
|
|
$$
|
|
|
|
declare
|
|
|
|
data text := '';
|
|
|
|
ln text;
|
|
|
|
begin
|
|
|
|
for ln in execute $1
|
|
|
|
loop
|
|
|
|
-- Replace any numeric word with just '0'
|
|
|
|
ln := regexp_replace(ln, '\m\d+\M', '0', 'g');
|
|
|
|
data := data || ln;
|
|
|
|
end loop;
|
|
|
|
return data::jsonb;
|
|
|
|
end;
|
|
|
|
$$;
|
|
|
|
|
2022-03-12 23:21:40 +01:00
|
|
|
-- Disable JIT, or we'll get different output on machines where that's been
|
|
|
|
-- forced on
|
2021-07-27 18:49:40 +02:00
|
|
|
set jit = off;
|
|
|
|
|
2022-03-12 23:21:40 +01:00
|
|
|
-- Similarly, disable track_io_timing, to avoid output differences when
|
|
|
|
-- enabled.
|
|
|
|
set track_io_timing = off;
|
2021-07-27 18:49:40 +02:00
|
|
|
|
Clean up EXPLAIN's handling of per-worker details.
Previously, it was possible for EXPLAIN ANALYZE of a parallel query
to produce several different "Workers" fields for a single plan node,
because different portions of explain.c independently generated
per-worker data and wrapped that output in separate fields. This
is pretty bogus, especially for the structured output formats: even
if it's not technically illegal, most programs would have a hard time
dealing with such data.
To improve matters, add infrastructure that allows redirecting
per-worker values into a side data structure, and then collect that
data into a single "Workers" field after we've finished running all
the relevant code for a given plan node.
There are a few visible side-effects:
* In text format, instead of something like
Sort Method: external merge Disk: 4920kB
Worker 0: Sort Method: external merge Disk: 5880kB
Worker 1: Sort Method: external merge Disk: 5920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Buffers: shared hit=345 read=3507, temp read=505 written=744
you get
Sort Method: external merge Disk: 4920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Sort Method: external merge Disk: 5880kB
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Sort Method: external merge Disk: 5920kB
Buffers: shared hit=345 read=3507, temp read=505 written=744
* When JIT is enabled, any relevant per-worker JIT stats are attached
to the child node of the Gather or Gather Merge node, which is where
the other per-worker output has always been. Previously, that info
was attached directly to a Gather node, or missed entirely for Gather
Merge.
* A query's summary JIT data no longer includes a bogus
"Worker Number: -1" field.
A notable code-level change is that indenting for lines of text-format
output should now be handled by calling "ExplainIndentText(es)",
instead of hard-wiring how much space to emit. This seems a good deal
cleaner anyway.
This patch also adds a new "explain.sql" regression test script that's
dedicated to testing EXPLAIN. There is more that can be done in that
line, certainly, but for now it just adds some coverage of the XML and
YAML output formats, which had been completely untested.
Although this is surely a bug fix, it's not clear that people would
be happy with rearranging EXPLAIN output in a minor release, so apply
to HEAD only.
Maciek Sakrejda and Tom Lane, based on an idea of Andres Freund's;
reviewed by Georgios Kokolatos
Discussion: https://postgr.es/m/CAOtHd0AvAA8CLB9Xz0wnxu1U=zJCKrr1r4QwwXi_kcQsHDVU=Q@mail.gmail.com
2020-01-26 00:16:42 +01:00
|
|
|
-- Simple cases
|
|
|
|
|
|
|
|
select explain_filter('explain select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (analyze) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (analyze, verbose) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (analyze, buffers, format yaml) select * from int8_tbl i8');
|
2020-08-21 13:48:59 +02:00
|
|
|
select explain_filter('explain (buffers, format text) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (buffers, format json) select * from int8_tbl i8');
|
Clean up EXPLAIN's handling of per-worker details.
Previously, it was possible for EXPLAIN ANALYZE of a parallel query
to produce several different "Workers" fields for a single plan node,
because different portions of explain.c independently generated
per-worker data and wrapped that output in separate fields. This
is pretty bogus, especially for the structured output formats: even
if it's not technically illegal, most programs would have a hard time
dealing with such data.
To improve matters, add infrastructure that allows redirecting
per-worker values into a side data structure, and then collect that
data into a single "Workers" field after we've finished running all
the relevant code for a given plan node.
There are a few visible side-effects:
* In text format, instead of something like
Sort Method: external merge Disk: 4920kB
Worker 0: Sort Method: external merge Disk: 5880kB
Worker 1: Sort Method: external merge Disk: 5920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Buffers: shared hit=345 read=3507, temp read=505 written=744
you get
Sort Method: external merge Disk: 4920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Sort Method: external merge Disk: 5880kB
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Sort Method: external merge Disk: 5920kB
Buffers: shared hit=345 read=3507, temp read=505 written=744
* When JIT is enabled, any relevant per-worker JIT stats are attached
to the child node of the Gather or Gather Merge node, which is where
the other per-worker output has always been. Previously, that info
was attached directly to a Gather node, or missed entirely for Gather
Merge.
* A query's summary JIT data no longer includes a bogus
"Worker Number: -1" field.
A notable code-level change is that indenting for lines of text-format
output should now be handled by calling "ExplainIndentText(es)",
instead of hard-wiring how much space to emit. This seems a good deal
cleaner anyway.
This patch also adds a new "explain.sql" regression test script that's
dedicated to testing EXPLAIN. There is more that can be done in that
line, certainly, but for now it just adds some coverage of the XML and
YAML output formats, which had been completely untested.
Although this is surely a bug fix, it's not clear that people would
be happy with rearranging EXPLAIN output in a minor release, so apply
to HEAD only.
Maciek Sakrejda and Tom Lane, based on an idea of Andres Freund's;
reviewed by Georgios Kokolatos
Discussion: https://postgr.es/m/CAOtHd0AvAA8CLB9Xz0wnxu1U=zJCKrr1r4QwwXi_kcQsHDVU=Q@mail.gmail.com
2020-01-26 00:16:42 +01:00
|
|
|
|
2022-04-08 04:27:21 +02:00
|
|
|
-- Check output including I/O timings. These fields are conditional
|
|
|
|
-- but always set in JSON format, so check them only in this case.
|
|
|
|
set track_io_timing = on;
|
|
|
|
select explain_filter('explain (analyze, buffers, format json) select * from int8_tbl i8');
|
|
|
|
set track_io_timing = off;
|
|
|
|
|
2020-01-26 22:31:48 +01:00
|
|
|
-- SETTINGS option
|
|
|
|
-- We have to ignore other settings that might be imposed by the environment,
|
|
|
|
-- so printing the whole Settings field unfortunately won't do.
|
|
|
|
|
|
|
|
begin;
|
|
|
|
set local plan_cache_mode = force_generic_plan;
|
|
|
|
select true as "OK"
|
|
|
|
from explain_filter('explain (settings) select * from int8_tbl i8') ln
|
|
|
|
where ln ~ '^ *Settings: .*plan_cache_mode = ''force_generic_plan''';
|
|
|
|
select explain_filter_to_json('explain (settings, format json) select * from int8_tbl i8') #> '{0,Settings,plan_cache_mode}';
|
|
|
|
rollback;
|
|
|
|
|
2023-03-24 22:07:14 +01:00
|
|
|
-- GENERIC_PLAN option
|
|
|
|
|
|
|
|
select explain_filter('explain (generic_plan) select unique1 from tenk1 where thousand = $1');
|
|
|
|
-- should fail
|
|
|
|
select explain_filter('explain (analyze, generic_plan) select unique1 from tenk1 where thousand = $1');
|
|
|
|
|
2024-01-29 17:53:03 +01:00
|
|
|
-- MEMORY option
|
|
|
|
select explain_filter('explain (memory) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (memory, analyze) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (memory, summary, format yaml) select * from int8_tbl i8');
|
|
|
|
select explain_filter('explain (memory, analyze, format json) select * from int8_tbl i8');
|
|
|
|
prepare int8_query as select * from int8_tbl i8;
|
|
|
|
select explain_filter('explain (memory) execute int8_query');
|
|
|
|
|
2023-03-24 22:07:14 +01:00
|
|
|
-- Test EXPLAIN (GENERIC_PLAN) with partition pruning
|
|
|
|
-- partitions should be pruned at plan time, based on constants,
|
|
|
|
-- but there should be no pruning based on parameter placeholders
|
|
|
|
create table gen_part (
|
|
|
|
key1 integer not null,
|
|
|
|
key2 integer not null
|
|
|
|
) partition by list (key1);
|
|
|
|
create table gen_part_1
|
|
|
|
partition of gen_part for values in (1)
|
|
|
|
partition by range (key2);
|
|
|
|
create table gen_part_1_1
|
|
|
|
partition of gen_part_1 for values from (1) to (2);
|
|
|
|
create table gen_part_1_2
|
|
|
|
partition of gen_part_1 for values from (2) to (3);
|
|
|
|
create table gen_part_2
|
|
|
|
partition of gen_part for values in (2);
|
|
|
|
-- should scan gen_part_1_1 and gen_part_1_2, but not gen_part_2
|
|
|
|
select explain_filter('explain (generic_plan) select key1, key2 from gen_part where key1 = 1 and key2 = $1');
|
|
|
|
drop table gen_part;
|
|
|
|
|
Clean up EXPLAIN's handling of per-worker details.
Previously, it was possible for EXPLAIN ANALYZE of a parallel query
to produce several different "Workers" fields for a single plan node,
because different portions of explain.c independently generated
per-worker data and wrapped that output in separate fields. This
is pretty bogus, especially for the structured output formats: even
if it's not technically illegal, most programs would have a hard time
dealing with such data.
To improve matters, add infrastructure that allows redirecting
per-worker values into a side data structure, and then collect that
data into a single "Workers" field after we've finished running all
the relevant code for a given plan node.
There are a few visible side-effects:
* In text format, instead of something like
Sort Method: external merge Disk: 4920kB
Worker 0: Sort Method: external merge Disk: 5880kB
Worker 1: Sort Method: external merge Disk: 5920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Buffers: shared hit=345 read=3507, temp read=505 written=744
you get
Sort Method: external merge Disk: 4920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Sort Method: external merge Disk: 5880kB
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Sort Method: external merge Disk: 5920kB
Buffers: shared hit=345 read=3507, temp read=505 written=744
* When JIT is enabled, any relevant per-worker JIT stats are attached
to the child node of the Gather or Gather Merge node, which is where
the other per-worker output has always been. Previously, that info
was attached directly to a Gather node, or missed entirely for Gather
Merge.
* A query's summary JIT data no longer includes a bogus
"Worker Number: -1" field.
A notable code-level change is that indenting for lines of text-format
output should now be handled by calling "ExplainIndentText(es)",
instead of hard-wiring how much space to emit. This seems a good deal
cleaner anyway.
This patch also adds a new "explain.sql" regression test script that's
dedicated to testing EXPLAIN. There is more that can be done in that
line, certainly, but for now it just adds some coverage of the XML and
YAML output formats, which had been completely untested.
Although this is surely a bug fix, it's not clear that people would
be happy with rearranging EXPLAIN output in a minor release, so apply
to HEAD only.
Maciek Sakrejda and Tom Lane, based on an idea of Andres Freund's;
reviewed by Georgios Kokolatos
Discussion: https://postgr.es/m/CAOtHd0AvAA8CLB9Xz0wnxu1U=zJCKrr1r4QwwXi_kcQsHDVU=Q@mail.gmail.com
2020-01-26 00:16:42 +01:00
|
|
|
--
|
|
|
|
-- Test production of per-worker data
|
|
|
|
--
|
|
|
|
-- Unfortunately, because we don't know how many worker processes we'll
|
|
|
|
-- actually get (maybe none at all), we can't examine the "Workers" output
|
|
|
|
-- in any detail. We can check that it parses correctly as JSON, and then
|
|
|
|
-- remove it from the displayed results.
|
|
|
|
|
2021-03-15 11:27:08 +01:00
|
|
|
begin;
|
Clean up EXPLAIN's handling of per-worker details.
Previously, it was possible for EXPLAIN ANALYZE of a parallel query
to produce several different "Workers" fields for a single plan node,
because different portions of explain.c independently generated
per-worker data and wrapped that output in separate fields. This
is pretty bogus, especially for the structured output formats: even
if it's not technically illegal, most programs would have a hard time
dealing with such data.
To improve matters, add infrastructure that allows redirecting
per-worker values into a side data structure, and then collect that
data into a single "Workers" field after we've finished running all
the relevant code for a given plan node.
There are a few visible side-effects:
* In text format, instead of something like
Sort Method: external merge Disk: 4920kB
Worker 0: Sort Method: external merge Disk: 5880kB
Worker 1: Sort Method: external merge Disk: 5920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Buffers: shared hit=345 read=3507, temp read=505 written=744
you get
Sort Method: external merge Disk: 4920kB
Buffers: shared hit=682 read=10188, temp read=1415 written=2101
Worker 0: actual time=130.058..130.324 rows=1324 loops=1
Sort Method: external merge Disk: 5880kB
Buffers: shared hit=337 read=3489, temp read=505 written=739
Worker 1: actual time=130.273..130.512 rows=1297 loops=1
Sort Method: external merge Disk: 5920kB
Buffers: shared hit=345 read=3507, temp read=505 written=744
* When JIT is enabled, any relevant per-worker JIT stats are attached
to the child node of the Gather or Gather Merge node, which is where
the other per-worker output has always been. Previously, that info
was attached directly to a Gather node, or missed entirely for Gather
Merge.
* A query's summary JIT data no longer includes a bogus
"Worker Number: -1" field.
A notable code-level change is that indenting for lines of text-format
output should now be handled by calling "ExplainIndentText(es)",
instead of hard-wiring how much space to emit. This seems a good deal
cleaner anyway.
This patch also adds a new "explain.sql" regression test script that's
dedicated to testing EXPLAIN. There is more that can be done in that
line, certainly, but for now it just adds some coverage of the XML and
YAML output formats, which had been completely untested.
Although this is surely a bug fix, it's not clear that people would
be happy with rearranging EXPLAIN output in a minor release, so apply
to HEAD only.
Maciek Sakrejda and Tom Lane, based on an idea of Andres Freund's;
reviewed by Georgios Kokolatos
Discussion: https://postgr.es/m/CAOtHd0AvAA8CLB9Xz0wnxu1U=zJCKrr1r4QwwXi_kcQsHDVU=Q@mail.gmail.com
2020-01-26 00:16:42 +01:00
|
|
|
-- encourage use of parallel plans
|
|
|
|
set parallel_setup_cost=0;
|
|
|
|
set parallel_tuple_cost=0;
|
|
|
|
set min_parallel_table_scan_size=0;
|
|
|
|
set max_parallel_workers_per_gather=4;
|
|
|
|
|
|
|
|
select jsonb_pretty(
|
|
|
|
explain_filter_to_json('explain (analyze, verbose, buffers, format json)
|
|
|
|
select * from tenk1 order by tenthous')
|
|
|
|
-- remove "Workers" node of the Seq Scan plan node
|
|
|
|
#- '{0,Plan,Plans,0,Plans,0,Workers}'
|
|
|
|
-- remove "Workers" node of the Sort plan node
|
|
|
|
#- '{0,Plan,Plans,0,Workers}'
|
|
|
|
-- Also remove its sort-type fields, as those aren't 100% stable
|
|
|
|
#- '{0,Plan,Plans,0,Sort Method}'
|
|
|
|
#- '{0,Plan,Plans,0,Sort Space Type}'
|
|
|
|
);
|
|
|
|
|
|
|
|
rollback;
|
Make use of in-core query id added by commit 5fd9dfa5f5
Use the in-core query id computation for pg_stat_activity,
log_line_prefix, and EXPLAIN VERBOSE.
Similar to other fields in pg_stat_activity, only the queryid from the
top level statements are exposed, and if the backends status isn't
active then the queryid from the last executed statements is displayed.
Add a %Q placeholder to include the queryid in log_line_prefix, which
will also only expose top level statements.
For EXPLAIN VERBOSE, if a query identifier has been computed, either by
enabling compute_query_id or using a third-party module, display it.
Bump catalog version.
Discussion: https://postgr.es/m/20210407125726.tkvjdbw76hxnpwfi@nol
Author: Julien Rouhaud
Reviewed-by: Alvaro Herrera, Nitin Jadhav, Zhihong Yu
2021-04-07 20:03:56 +02:00
|
|
|
|
2021-07-27 18:03:16 +02:00
|
|
|
-- Test display of temporary objects
|
|
|
|
create temp table t1(f1 float8);
|
|
|
|
|
|
|
|
create function pg_temp.mysin(float8) returns float8 language plpgsql
|
|
|
|
as 'begin return sin($1); end';
|
|
|
|
|
|
|
|
select explain_filter('explain (verbose) select * from t1 where pg_temp.mysin(f1) < 0.5');
|
|
|
|
|
|
|
|
-- Test compute_query_id
|
Make use of in-core query id added by commit 5fd9dfa5f5
Use the in-core query id computation for pg_stat_activity,
log_line_prefix, and EXPLAIN VERBOSE.
Similar to other fields in pg_stat_activity, only the queryid from the
top level statements are exposed, and if the backends status isn't
active then the queryid from the last executed statements is displayed.
Add a %Q placeholder to include the queryid in log_line_prefix, which
will also only expose top level statements.
For EXPLAIN VERBOSE, if a query identifier has been computed, either by
enabling compute_query_id or using a third-party module, display it.
Bump catalog version.
Discussion: https://postgr.es/m/20210407125726.tkvjdbw76hxnpwfi@nol
Author: Julien Rouhaud
Reviewed-by: Alvaro Herrera, Nitin Jadhav, Zhihong Yu
2021-04-07 20:03:56 +02:00
|
|
|
set compute_query_id = on;
|
2021-04-08 00:14:36 +02:00
|
|
|
select explain_filter('explain (verbose) select * from int8_tbl i8');
|