提交 f4d48358 编写于 作者: H Heikki Linnakangas

Make 'rows' estimate more accurate for plans that fetch only a few rows.

In commit c5f6dbbe, we changed the row and cost estimates on plan nodes
to represent per-segment costs. That made some estimates worse, because
the effects of the estimate "clamping" compounds. Per my comment on the
PR back then:

> One interesting effect of this change, that explains many of the
> plan changes: If you have a table with very few rows, or e.g. a qual
> like id = 123 that matches exactly one row, the Seq/Index Scan on it
> will be marked with rows=1. It now means that we estimate that every
> segment returns one row, although in reality, only one of them will
> return a row, and the rest will return nothing. That's because the
> row count estimates are "clamped" in the planner to at least
> 1. That's not a big deal on its own, but if you then have e.g. a
> Gather Motion on top of the Scan, the planner will estimate that the
> Gather Motion returns as many rows as there are segments. If you
> have e.g. 100 segments, that's relatively a big discrepancy, with
> 100 rows vs 1. I don't think that's a big problem in practice, I
> don't think most plans are very sensitive to that kind of a
> misestimate. What do you think?
>
> If we wanted to fix that, perhaps we should stop "clamping" the
> estimates to 1. I don't think there's any fundamental reason we need
> to do it. Perhaps clamp down to 1 / numsegments instead.

But I came up with a less intrusive idea, implemented in this commit:
Most Motion nodes have a "parent" RelOptInfo, and the RelOptInfo
contains an estimate of the total number of rows, before dividing it
with the number of segments or clamping. So if the row estimate we get
from the subpath seems clamped to 1.0, we look at the row estimate on
the underlying RelOptInfo instead, and use that if it's smaller. That
makes the row count estimates better for plans that fetch a single row
or a few rows, same as they were before commit c5f6dbbe. Not all
RelOptInfos have a row count estimate, and the subpaths estimate is
more accurate if the number of rows produced by the path differs from
the number of rows in the underlying relation, e.g.  because of a
ProjectSet node, so we still prefer the subpath's estimate if it
doesn't seem clamped.
Reviewed-by: NZhenghua Lyu <zlv@pivotal.io>
上级 81613a5c
...@@ -77,18 +77,50 @@ cdbpath_cost_motion(PlannerInfo *root, CdbMotionPath *motionpath) ...@@ -77,18 +77,50 @@ cdbpath_cost_motion(PlannerInfo *root, CdbMotionPath *motionpath)
double sendrows; double sendrows;
double send_segments; double send_segments;
double recv_segments; double recv_segments;
double total_rows;
if (CdbPathLocus_IsPartitioned(motionpath->path.locus))
recv_segments = CdbPathLocus_NumSegments(motionpath->path.locus);
else
recv_segments = 1;
if (CdbPathLocus_IsPartitioned(subpath->locus)) if (CdbPathLocus_IsPartitioned(subpath->locus))
send_segments = CdbPathLocus_NumSegments(subpath->locus); send_segments = CdbPathLocus_NumSegments(subpath->locus);
else else
send_segments = 1; send_segments = 1;
if (CdbPathLocus_IsPartitioned(motionpath->path.locus)) /*
recv_segments = CdbPathLocus_NumSegments(motionpath->path.locus); * Estimate the total number of rows being sent.
else *
recv_segments = 1; * The base estimate is computed by multiplying the subpath's rows with
* the number of sending segments. But in some cases, that leads to too
* large estimates, if the subpath's estimate was "clamped" to 1 row. The
* typical example is a single-row select like "SELECT * FROM table WHERE
* key = 123. The Scan on the table returns only one row, on one segment,
* and the estimate on the Scan node is 1 row. If you have e.g. 3
* segments, and we just multiplied the subpath's row estimate by 3, we
* would estimate that the Gather returns 3 rows, even though there is
* only one matching row in the table. Using the 'rows' estimate on the
* RelOptInfo is more accurate in such cases. To correct that, if the
* subpath's estimate is 1 row, but the underlying relation's estimate is
* smaller, use the underlying relation's estimate.
*
* We don't always use the relation's estimate, because there might be
* nodes like ProjectSet or Limit in the subpath, in which case the
* subpath's estimate is more accurate. Also, the relation might not have
* a valid 'rows' estimate; upper rels, for example, do not. So check for
* that too.
*/
total_rows = subpath->rows * send_segments;
if (subpath->rows == 1.0 &&
motionpath->path.parent->rows > 0 &&
motionpath->path.parent->rows < total_rows)
{
/* use the RelOptInfo's estimate */
total_rows = motionpath->path.parent->rows;
}
motionpath->path.rows = clamp_row_est(subpath->rows * (send_segments / recv_segments)); motionpath->path.rows = clamp_row_est(total_rows / recv_segments);
cost_per_row = (gp_motion_cost_per_row > 0.0) cost_per_row = (gp_motion_cost_per_row > 0.0)
? gp_motion_cost_per_row ? gp_motion_cost_per_row
......
...@@ -19,14 +19,20 @@ ...@@ -19,14 +19,20 @@
-- s/num times hit:\'[4-9]\'/num times hit:\'greater_than_two\'/ -- s/num times hit:\'[4-9]\'/num times hit:\'greater_than_two\'/
-- end_matchsubs -- end_matchsubs
begin; begin;
create function num_dirty(relid oid) returns bigint as create function num_dirty_on_qes(relid oid) returns setof bigint as
$$ $$
select count(*) from dirty_buffers() declare
rfnode oid;
result int4;
begin
select relfilenode into rfnode from pg_class where oid=$1;
select count(*) into result from dirty_buffers_on_qes()
as (tablespace oid, database oid, relfilenode oid, block int) as (tablespace oid, database oid, relfilenode oid, block int)
where relfilenode in where relfilenode = rfnode;
(select relfilenode from pg_class return next result;
where oid=$1); end
$$ language sql; $$ language plpgsql execute on all segments;
-- Wait until number of dirty buffers for the specified relfiles drops -- Wait until number of dirty buffers for the specified relfiles drops
-- to 0 or timeout occurs. Returns false if timeout occurred. -- to 0 or timeout occurs. Returns false if timeout occurred.
create function wait_for_bgwriter( create function wait_for_bgwriter(
...@@ -40,7 +46,7 @@ declare ...@@ -40,7 +46,7 @@ declare
begin begin
i := 0; i := 0;
loop loop
select sum(num_dirty($1)) into d from gp_dist_random('gp_id'); select sum(nd) into d from num_dirty_on_qes($1) nd;
if (d = 0) then if (d = 0) then
return true; return true;
end if; end if;
...@@ -103,16 +109,16 @@ from gp_segment_configuration where role = 'p' and content > -1; ...@@ -103,16 +109,16 @@ from gp_segment_configuration where role = 'p' and content > -1;
(3 rows) (3 rows)
-- Ensure no buffers are dirty before we start. -- Ensure no buffers are dirty before we start.
select * from dirty_buffers() select * from dirty_buffers_on_qd()
as (tablespace oid, database oid, relfilenode oid, block int); as (tablespace oid, database oid, relfilenode oid, block int);
tablespace | database | relfilenode | block tablespace | database | relfilenode | block
------------+----------+-------------+------- ------------+----------+-------------+-------
(0 rows) (0 rows)
select dirty_buffers() from gp_dist_random('gp_id') select * from dirty_buffers_on_qes()
as (tablespace oid, database oid, relfilenode oid, block int); as (tablespace oid, database oid, relfilenode oid, block int);
dirty_buffers tablespace | database | relfilenode | block
--------------- ------------+----------+-------------+-------
(0 rows) (0 rows)
-- Make buffers dirty. At least two relfiles must be sync'ed during -- Make buffers dirty. At least two relfiles must be sync'ed during
...@@ -120,15 +126,13 @@ select dirty_buffers() from gp_dist_random('gp_id') ...@@ -120,15 +126,13 @@ select dirty_buffers() from gp_dist_random('gp_id')
insert into fsync_test1 select i, i from generate_series(1,1000)i; insert into fsync_test1 select i, i from generate_series(1,1000)i;
delete from fsync_test2; delete from fsync_test2;
-- Should return at least one dirty buffer. -- Should return at least one dirty buffer.
select sum(num_dirty('fsync_test1'::regclass)) > 0 as passed select sum(nd) > 0 as passed from num_dirty_on_qes('fsync_test1'::regclass) nd;
from gp_dist_random('gp_id');
passed passed
-------- --------
t t
(1 row) (1 row)
select sum(num_dirty('fsync_test2'::regclass)) > 0 as passed select sum(nd) > 0 as passed from num_dirty_on_qes('fsync_test2'::regclass) nd;
from gp_dist_random('gp_id');
passed passed
-------- --------
t t
...@@ -192,10 +196,10 @@ from gp_segment_configuration where role = 'p' and content > -1; ...@@ -192,10 +196,10 @@ from gp_segment_configuration where role = 'p' and content > -1;
checkpoint; checkpoint;
-- There should be no dirty buffers after checkpoint. -- There should be no dirty buffers after checkpoint.
select dirty_buffers() from gp_dist_random('gp_id') select * from dirty_buffers_on_qes()
as (tablespace oid, database oid, relfilenode oid, block int); as (tablespace oid, database oid, relfilenode oid, block int);
dirty_buffers tablespace | database | relfilenode | block
--------------- ------------+----------+-------------+-------
(0 rows) (0 rows)
-- Validate that the number of files fsync'ed by checkpointer is at -- Validate that the number of files fsync'ed by checkpointer is at
......
create or replace function dirty_buffers() returns setof record as create or replace function dirty_buffers_on_qd() returns setof record as
'@abs_builddir@/fsync_helper@DLSUFFIX@', 'dirty_buffers' '@abs_builddir@/fsync_helper@DLSUFFIX@', 'dirty_buffers'
LANGUAGE C VOLATILE STRICT NO SQL; LANGUAGE C VOLATILE STRICT NO SQL EXECUTE ON MASTER;
create or replace function dirty_buffers_on_qes() returns setof record as
'@abs_builddir@/fsync_helper@DLSUFFIX@', 'dirty_buffers'
LANGUAGE C VOLATILE STRICT NO SQL EXECUTE ON ALL SEGMENTS;
create or replace function dirty_buffers() returns setof record as create or replace function dirty_buffers_on_qd() returns setof record as
'@abs_builddir@/fsync_helper@DLSUFFIX@', 'dirty_buffers' '@abs_builddir@/fsync_helper@DLSUFFIX@', 'dirty_buffers'
LANGUAGE C VOLATILE STRICT NO SQL; LANGUAGE C VOLATILE STRICT NO SQL EXECUTE ON MASTER;
create or replace function dirty_buffers_on_qes() returns setof record as
'@abs_builddir@/fsync_helper@DLSUFFIX@', 'dirty_buffers'
LANGUAGE C VOLATILE STRICT NO SQL EXECUTE ON ALL SEGMENTS;
...@@ -19,14 +19,20 @@ ...@@ -19,14 +19,20 @@
-- s/num times hit:\'[4-9]\'/num times hit:\'greater_than_two\'/ -- s/num times hit:\'[4-9]\'/num times hit:\'greater_than_two\'/
-- end_matchsubs -- end_matchsubs
begin; begin;
create function num_dirty(relid oid) returns bigint as create function num_dirty_on_qes(relid oid) returns setof bigint as
$$ $$
select count(*) from dirty_buffers() declare
rfnode oid;
result int4;
begin
select relfilenode into rfnode from pg_class where oid=$1;
select count(*) into result from dirty_buffers_on_qes()
as (tablespace oid, database oid, relfilenode oid, block int) as (tablespace oid, database oid, relfilenode oid, block int)
where relfilenode in where relfilenode = rfnode;
(select relfilenode from pg_class return next result;
where oid=$1); end
$$ language sql; $$ language plpgsql execute on all segments;
-- Wait until number of dirty buffers for the specified relfiles drops -- Wait until number of dirty buffers for the specified relfiles drops
-- to 0 or timeout occurs. Returns false if timeout occurred. -- to 0 or timeout occurs. Returns false if timeout occurred.
...@@ -41,7 +47,7 @@ declare ...@@ -41,7 +47,7 @@ declare
begin begin
i := 0; i := 0;
loop loop
select sum(num_dirty($1)) into d from gp_dist_random('gp_id'); select sum(nd) into d from num_dirty_on_qes($1) nd;
if (d = 0) then if (d = 0) then
return true; return true;
end if; end if;
...@@ -84,9 +90,9 @@ select gp_inject_fault_infinite('fault_in_background_writer_main', 'suspend', db ...@@ -84,9 +90,9 @@ select gp_inject_fault_infinite('fault_in_background_writer_main', 'suspend', db
from gp_segment_configuration where role = 'p' and content > -1; from gp_segment_configuration where role = 'p' and content > -1;
-- Ensure no buffers are dirty before we start. -- Ensure no buffers are dirty before we start.
select * from dirty_buffers() select * from dirty_buffers_on_qd()
as (tablespace oid, database oid, relfilenode oid, block int); as (tablespace oid, database oid, relfilenode oid, block int);
select dirty_buffers() from gp_dist_random('gp_id') select * from dirty_buffers_on_qes()
as (tablespace oid, database oid, relfilenode oid, block int); as (tablespace oid, database oid, relfilenode oid, block int);
-- Make buffers dirty. At least two relfiles must be sync'ed during -- Make buffers dirty. At least two relfiles must be sync'ed during
...@@ -95,10 +101,8 @@ insert into fsync_test1 select i, i from generate_series(1,1000)i; ...@@ -95,10 +101,8 @@ insert into fsync_test1 select i, i from generate_series(1,1000)i;
delete from fsync_test2; delete from fsync_test2;
-- Should return at least one dirty buffer. -- Should return at least one dirty buffer.
select sum(num_dirty('fsync_test1'::regclass)) > 0 as passed select sum(nd) > 0 as passed from num_dirty_on_qes('fsync_test1'::regclass) nd;
from gp_dist_random('gp_id'); select sum(nd) > 0 as passed from num_dirty_on_qes('fsync_test2'::regclass) nd;
select sum(num_dirty('fsync_test2'::regclass)) > 0 as passed
from gp_dist_random('gp_id');
-- Flush all dirty pages by BgBufferSync() -- Flush all dirty pages by BgBufferSync()
select gp_inject_fault_infinite('bg_buffer_sync_default_logic', 'skip', dbid) select gp_inject_fault_infinite('bg_buffer_sync_default_logic', 'skip', dbid)
...@@ -126,7 +130,7 @@ from gp_segment_configuration where role = 'p' and content > -1; ...@@ -126,7 +130,7 @@ from gp_segment_configuration where role = 'p' and content > -1;
checkpoint; checkpoint;
-- There should be no dirty buffers after checkpoint. -- There should be no dirty buffers after checkpoint.
select dirty_buffers() from gp_dist_random('gp_id') select * from dirty_buffers_on_qes()
as (tablespace oid, database oid, relfilenode oid, block int); as (tablespace oid, database oid, relfilenode oid, block int);
-- Validate that the number of files fsync'ed by checkpointer is at -- Validate that the number of files fsync'ed by checkpointer is at
......
...@@ -81,7 +81,7 @@ RETURNS integer as $$ ...@@ -81,7 +81,7 @@ RETURNS integer as $$
f.close() f.close()
return 0 return 0
$$ LANGUAGE plpython3u; $$ LANGUAGE plpython3u EXECUTE ON ALL SEGMENTS;
CREATE OR REPLACE FUNCTION invalidate_buffers_for_rel(tablename text) RETURNS BOOL AS CREATE OR REPLACE FUNCTION invalidate_buffers_for_rel(tablename text) RETURNS BOOL AS
$$ $$
DECLARE DECLARE
...@@ -136,7 +136,7 @@ select invalidate_buffers_for_rel('corrupt_table') from gp_dist_random('gp_id'); ...@@ -136,7 +136,7 @@ select invalidate_buffers_for_rel('corrupt_table') from gp_dist_random('gp_id');
(3 rows) (3 rows)
-- Verify corruption on heap table -- Verify corruption on heap table
select SUM(corrupt_file(get_relation_path('corrupt_table'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_relation_path('corrupt_table'), -50));
INFO: corrupting file base/81967/81931 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287) INFO: corrupting file base/81967/81931 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287)
INFO: corrupting file base/81967/81931 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288) INFO: corrupting file base/81967/81931 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288)
INFO: corrupting file base/81967/81931 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289) INFO: corrupting file base/81967/81931 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289)
...@@ -164,7 +164,7 @@ select invalidate_buffers_for_rel(get_toast_name('corrupt_toast_table')) from gp ...@@ -164,7 +164,7 @@ select invalidate_buffers_for_rel(get_toast_name('corrupt_toast_table')) from gp
(3 rows) (3 rows)
-- Verify corruption on toast table -- Verify corruption on toast table
select SUM(corrupt_file(get_toast_path('corrupt_toast_table'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_toast_path('corrupt_toast_table'), -50));
INFO: corrupting file base/81967/81933 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287) INFO: corrupting file base/81967/81933 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287)
INFO: corrupting file base/81967/81933 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288) INFO: corrupting file base/81967/81933 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288)
INFO: corrupting file base/81967/81933 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289) INFO: corrupting file base/81967/81933 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289)
...@@ -193,7 +193,7 @@ select invalidate_buffers_for_rel('btree_index') from gp_dist_random('gp_id'); ...@@ -193,7 +193,7 @@ select invalidate_buffers_for_rel('btree_index') from gp_dist_random('gp_id');
(3 rows) (3 rows)
-- Verify corruption on Btree index -- Verify corruption on Btree index
select SUM(corrupt_file(get_index_path('corrupt_btree_index'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_index_path('corrupt_btree_index'), -50));
INFO: corrupting file base/81967/81936 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287) INFO: corrupting file base/81967/81936 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287)
INFO: corrupting file base/81967/81936 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288) INFO: corrupting file base/81967/81936 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288)
INFO: corrupting file base/81967/81936 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289) INFO: corrupting file base/81967/81936 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289)
...@@ -222,7 +222,7 @@ select invalidate_buffers_for_rel('bitmap_index') from gp_dist_random('gp_id'); ...@@ -222,7 +222,7 @@ select invalidate_buffers_for_rel('bitmap_index') from gp_dist_random('gp_id');
(3 rows) (3 rows)
-- Verify corruption on Bitmap index -- Verify corruption on Bitmap index
select SUM(corrupt_file(get_index_path('corrupt_bitmap_index'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_index_path('corrupt_bitmap_index'), -50));
INFO: corrupting file base/81967/81938 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287) INFO: corrupting file base/81967/81938 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287)
INFO: corrupting file base/81967/81938 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288) INFO: corrupting file base/81967/81938 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288)
INFO: corrupting file base/81967/81938 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289) INFO: corrupting file base/81967/81938 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289)
...@@ -264,7 +264,7 @@ select count(*) from mark_buffer_dirty_hint; ...@@ -264,7 +264,7 @@ select count(*) from mark_buffer_dirty_hint;
create table flush_xlog_page_to_disk (c int); create table flush_xlog_page_to_disk (c int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Greenplum Database data distribution key for this table. NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Greenplum Database data distribution key for this table.
-- corrupt the page on disk -- corrupt the page on disk
select SUM(corrupt_file(get_relation_path('mark_buffer_dirty_hint'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_relation_path('mark_buffer_dirty_hint'), -50));
INFO: corrupting file base/81967/81939 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287) INFO: corrupting file base/81967/81939 at -50 (seg0 slice1 127.0.0.1:25432 pid=27287)
INFO: corrupting file base/81967/81939 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288) INFO: corrupting file base/81967/81939 at -50 (seg1 slice1 127.0.0.1:25433 pid=27288)
INFO: corrupting file base/81967/81939 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289) INFO: corrupting file base/81967/81939 at -50 (seg2 slice1 127.0.0.1:25434 pid=27289)
......
...@@ -91,7 +91,7 @@ RETURNS integer as $$ ...@@ -91,7 +91,7 @@ RETURNS integer as $$
f.close() f.close()
return 0 return 0
$$ LANGUAGE plpython3u; $$ LANGUAGE plpython3u EXECUTE ON ALL SEGMENTS;
CREATE OR REPLACE FUNCTION invalidate_buffers_for_rel(tablename text) RETURNS BOOL AS CREATE OR REPLACE FUNCTION invalidate_buffers_for_rel(tablename text) RETURNS BOOL AS
$$ $$
...@@ -122,7 +122,7 @@ insert into corrupt_table select i from generate_series(1, 10) i; ...@@ -122,7 +122,7 @@ insert into corrupt_table select i from generate_series(1, 10) i;
checkpoint; checkpoint;
select invalidate_buffers_for_rel('corrupt_table') from gp_dist_random('gp_id'); select invalidate_buffers_for_rel('corrupt_table') from gp_dist_random('gp_id');
-- Verify corruption on heap table -- Verify corruption on heap table
select SUM(corrupt_file(get_relation_path('corrupt_table'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_relation_path('corrupt_table'), -50));
SELECT COUNT(*) FROM corrupt_table; SELECT COUNT(*) FROM corrupt_table;
-- Corrupt a heap table, with toast table -- Corrupt a heap table, with toast table
...@@ -131,7 +131,7 @@ insert into corrupt_toast_table select i, ("decode"(repeat('a',3000000),'escape' ...@@ -131,7 +131,7 @@ insert into corrupt_toast_table select i, ("decode"(repeat('a',3000000),'escape'
checkpoint; checkpoint;
select invalidate_buffers_for_rel(get_toast_name('corrupt_toast_table')) from gp_dist_random('gp_id'); select invalidate_buffers_for_rel(get_toast_name('corrupt_toast_table')) from gp_dist_random('gp_id');
-- Verify corruption on toast table -- Verify corruption on toast table
select SUM(corrupt_file(get_toast_path('corrupt_toast_table'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_toast_path('corrupt_toast_table'), -50));
SELECT md5(comment::text) FROM corrupt_toast_table; SELECT md5(comment::text) FROM corrupt_toast_table;
-- Corrupt a Btree Index -- Corrupt a Btree Index
...@@ -141,7 +141,7 @@ insert into corrupt_btree_index select i, 'a' from generate_series(1, 10) i; ...@@ -141,7 +141,7 @@ insert into corrupt_btree_index select i, 'a' from generate_series(1, 10) i;
checkpoint; checkpoint;
select invalidate_buffers_for_rel('btree_index') from gp_dist_random('gp_id'); select invalidate_buffers_for_rel('btree_index') from gp_dist_random('gp_id');
-- Verify corruption on Btree index -- Verify corruption on Btree index
select SUM(corrupt_file(get_index_path('corrupt_btree_index'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_index_path('corrupt_btree_index'), -50));
insert into corrupt_btree_index select i, 'a' from generate_series(1, 10) i; -- insert will trigger scan of the index insert into corrupt_btree_index select i, 'a' from generate_series(1, 10) i; -- insert will trigger scan of the index
-- Corrupt a Bitmap Index -- Corrupt a Bitmap Index
...@@ -151,7 +151,7 @@ insert into corrupt_bitmap_index select i, 'a' from generate_series(1, 10) i; ...@@ -151,7 +151,7 @@ insert into corrupt_bitmap_index select i, 'a' from generate_series(1, 10) i;
checkpoint; checkpoint;
select invalidate_buffers_for_rel('bitmap_index') from gp_dist_random('gp_id'); select invalidate_buffers_for_rel('bitmap_index') from gp_dist_random('gp_id');
-- Verify corruption on Bitmap index -- Verify corruption on Bitmap index
select SUM(corrupt_file(get_index_path('corrupt_bitmap_index'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_index_path('corrupt_bitmap_index'), -50));
insert into corrupt_bitmap_index select i, 'a' from generate_series(1, 10) i; -- insert will trigger scan of the index insert into corrupt_bitmap_index select i, 'a' from generate_series(1, 10) i; -- insert will trigger scan of the index
-- Test make sure full page image is captured in XLOG if hint bit change is the first change after checkpoint -- Test make sure full page image is captured in XLOG if hint bit change is the first change after checkpoint
...@@ -168,7 +168,7 @@ select count(*) from mark_buffer_dirty_hint; ...@@ -168,7 +168,7 @@ select count(*) from mark_buffer_dirty_hint;
-- using a DML to trigger the XLogFlush() to have the backup block written -- using a DML to trigger the XLogFlush() to have the backup block written
create table flush_xlog_page_to_disk (c int); create table flush_xlog_page_to_disk (c int);
-- corrupt the page on disk -- corrupt the page on disk
select SUM(corrupt_file(get_relation_path('mark_buffer_dirty_hint'), -50)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_relation_path('mark_buffer_dirty_hint'), -50));
-- invalidate buffer and confirm data is corrupted -- invalidate buffer and confirm data is corrupted
select invalidate_buffers_for_rel('mark_buffer_dirty_hint') from gp_dist_random('gp_id'); select invalidate_buffers_for_rel('mark_buffer_dirty_hint') from gp_dist_random('gp_id');
select count(*) from mark_buffer_dirty_hint; select count(*) from mark_buffer_dirty_hint;
......
...@@ -63,7 +63,7 @@ RETURNS integer as $$ ...@@ -63,7 +63,7 @@ RETURNS integer as $$
f.close() f.close()
return 0 return 0
$$ LANGUAGE plpython3u; $$ LANGUAGE plpython3u EXECUTE ON ALL SEGMENTS;
-- Corrupt a file by replacing the last occurrence of 'str' within the file -- Corrupt a file by replacing the last occurrence of 'str' within the file
-- with 'replacement' -- with 'replacement'
CREATE FUNCTION corrupt_file(data_file text, target bytea, replacement bytea) CREATE FUNCTION corrupt_file(data_file text, target bytea, replacement bytea)
...@@ -90,11 +90,11 @@ RETURNS integer as $$ ...@@ -90,11 +90,11 @@ RETURNS integer as $$
f.close() f.close()
return 0 return 0
$$ LANGUAGE plpython3u; $$ LANGUAGE plpython3u EXECUTE ON ALL SEGMENTS;
-- Large content, corrupt block header -- Large content, corrupt block header
create table corrupt_header_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY; create table corrupt_header_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY;
insert into corrupt_header_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ; insert into corrupt_header_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ;
select SUM(corrupt_file(get_aoseg1_path('corrupt_header_large_co'), 8)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_header_large_co'), 8));
INFO: corrupting file base/107062/107070.1 at 8 (seg0 slice1 127.0.0.1:40000 pid=28137) INFO: corrupting file base/107062/107070.1 at 8 (seg0 slice1 127.0.0.1:40000 pid=28137)
INFO: corrupting file base/107062/107070.1 at 8 (seg1 slice1 127.0.0.1:40001 pid=28138) INFO: corrupting file base/107062/107070.1 at 8 (seg1 slice1 127.0.0.1:40001 pid=28138)
INFO: corrupting file base/107062/107070.1 at 8 (seg2 slice1 127.0.0.1:40002 pid=28139) INFO: corrupting file base/107062/107070.1 at 8 (seg2 slice1 127.0.0.1:40002 pid=28139)
...@@ -108,7 +108,7 @@ ERROR: header checksum does not match, expected 0xBA9CC649 and found 0x0C997AE7 ...@@ -108,7 +108,7 @@ ERROR: header checksum does not match, expected 0xBA9CC649 and found 0x0C997AE7
-- Large content, corrupt content -- Large content, corrupt content
create table corrupt_content_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY; create table corrupt_content_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY;
insert into corrupt_content_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ; insert into corrupt_content_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ;
select SUM(corrupt_file(get_aoseg1_path('corrupt_content_large_co'), -3)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_content_large_co'), -3));
INFO: corrupting file base/107062/107080.1 at -3 (seg0 slice1 127.0.0.1:40000 pid=28137) INFO: corrupting file base/107062/107080.1 at -3 (seg0 slice1 127.0.0.1:40000 pid=28137)
INFO: corrupting file base/107062/107080.1 at -3 (seg1 slice1 127.0.0.1:40001 pid=28138) INFO: corrupting file base/107062/107080.1 at -3 (seg1 slice1 127.0.0.1:40001 pid=28138)
INFO: corrupting file base/107062/107080.1 at -3 (seg2 slice1 127.0.0.1:40002 pid=28139) INFO: corrupting file base/107062/107080.1 at -3 (seg2 slice1 127.0.0.1:40002 pid=28139)
...@@ -123,7 +123,7 @@ ERROR: block checksum does not match, expected 0x9C02F450 and found 0x0A78638C ...@@ -123,7 +123,7 @@ ERROR: block checksum does not match, expected 0x9C02F450 and found 0x0A78638C
create table corrupt_header_small_co(a int) with (appendonly=true, orientation=column, checksum=true); create table corrupt_header_small_co(a int) with (appendonly=true, orientation=column, checksum=true);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table.
insert into corrupt_header_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_header_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_co'), 8)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_co'), 8));
INFO: corrupting file base/107062/107090.1 at 8 (seg0 slice1 127.0.0.1:40000 pid=28137) INFO: corrupting file base/107062/107090.1 at 8 (seg0 slice1 127.0.0.1:40000 pid=28137)
INFO: corrupting file base/107062/107090.1 at 8 (seg1 slice1 127.0.0.1:40001 pid=28138) INFO: corrupting file base/107062/107090.1 at 8 (seg1 slice1 127.0.0.1:40001 pid=28138)
INFO: corrupting file base/107062/107090.1 at 8 (seg2 slice1 127.0.0.1:40002 pid=28139) INFO: corrupting file base/107062/107090.1 at 8 (seg2 slice1 127.0.0.1:40002 pid=28139)
...@@ -138,7 +138,7 @@ ERROR: header checksum does not match, expected 0xAA39D941 and found 0xE8FB379B ...@@ -138,7 +138,7 @@ ERROR: header checksum does not match, expected 0xAA39D941 and found 0xE8FB379B
create table corrupt_content_small_co(a int) with (appendonly=true, orientation=column, checksum=true); create table corrupt_content_small_co(a int) with (appendonly=true, orientation=column, checksum=true);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table.
insert into corrupt_content_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_content_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_co'), -3)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_co'), -3));
INFO: corrupting file base/107062/107097.1 at -3 (seg0 slice1 127.0.0.1:40000 pid=28137) INFO: corrupting file base/107062/107097.1 at -3 (seg0 slice1 127.0.0.1:40000 pid=28137)
INFO: corrupting file base/107062/107097.1 at -3 (seg1 slice1 127.0.0.1:40001 pid=28138) INFO: corrupting file base/107062/107097.1 at -3 (seg1 slice1 127.0.0.1:40001 pid=28138)
INFO: corrupting file base/107062/107097.1 at -3 (seg2 slice1 127.0.0.1:40002 pid=28139) INFO: corrupting file base/107062/107097.1 at -3 (seg2 slice1 127.0.0.1:40002 pid=28139)
...@@ -153,7 +153,7 @@ ERROR: block checksum does not match, expected 0xA3CAEC7A and found 0x35B07BA6 ...@@ -153,7 +153,7 @@ ERROR: block checksum does not match, expected 0xA3CAEC7A and found 0x35B07BA6
create table corrupt_header_small_ao(a int) with (appendonly=true, orientation=row, checksum=true); create table corrupt_header_small_ao(a int) with (appendonly=true, orientation=row, checksum=true);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table.
insert into corrupt_header_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_header_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_ao'), 8)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_ao'), 8));
INFO: corrupting file base/107062/107104.1 at 8 (seg0 slice1 127.0.0.1:40000 pid=28137) INFO: corrupting file base/107062/107104.1 at 8 (seg0 slice1 127.0.0.1:40000 pid=28137)
INFO: corrupting file base/107062/107104.1 at 8 (seg1 slice1 127.0.0.1:40001 pid=28138) INFO: corrupting file base/107062/107104.1 at 8 (seg1 slice1 127.0.0.1:40001 pid=28138)
INFO: corrupting file base/107062/107104.1 at 8 (seg2 slice1 127.0.0.1:40002 pid=28139) INFO: corrupting file base/107062/107104.1 at 8 (seg2 slice1 127.0.0.1:40002 pid=28139)
...@@ -168,7 +168,7 @@ ERROR: header checksum does not match, expected 0x413AF15D and found 0x805DA822 ...@@ -168,7 +168,7 @@ ERROR: header checksum does not match, expected 0x413AF15D and found 0x805DA822
create table corrupt_content_small_ao(a int) with (appendonly=true, orientation=row, checksum=true); create table corrupt_content_small_ao(a int) with (appendonly=true, orientation=row, checksum=true);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table.
insert into corrupt_content_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_content_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_ao'), -3)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_ao'), -3));
INFO: corrupting file base/107062/107111.1 at -3 (seg0 slice1 127.0.0.1:40000 pid=28137) INFO: corrupting file base/107062/107111.1 at -3 (seg0 slice1 127.0.0.1:40000 pid=28137)
INFO: corrupting file base/107062/107111.1 at -3 (seg1 slice1 127.0.0.1:40001 pid=28138) INFO: corrupting file base/107062/107111.1 at -3 (seg1 slice1 127.0.0.1:40001 pid=28138)
INFO: corrupting file base/107062/107111.1 at -3 (seg2 slice1 127.0.0.1:40002 pid=28139) INFO: corrupting file base/107062/107111.1 at -3 (seg2 slice1 127.0.0.1:40002 pid=28139)
...@@ -185,7 +185,7 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as ...@@ -185,7 +185,7 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as
insert into appendonly_verify_block_checksums_co insert into appendonly_verify_block_checksums_co
select 'abcdefghijlmnopqrstuvxyz' from generate_series(1, 5); select 'abcdefghijlmnopqrstuvxyz' from generate_series(1, 5);
-- Corrupt the table by flip the 'xyz' on the last row with ### -- Corrupt the table by flip the 'xyz' on the last row with ###
select SUM(corrupt_file(get_aoseg1_path('appendonly_verify_block_checksums_co'), 'xyz', '###')) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('appendonly_verify_block_checksums_co'), 'xyz', '###'));
INFO: skipping non-existent file base/107062/107118.1 (seg0 slice1 127.0.0.1:40000 pid=28137) INFO: skipping non-existent file base/107062/107118.1 (seg0 slice1 127.0.0.1:40000 pid=28137)
INFO: skipping non-existent file base/107062/107118.1 (seg1 slice1 127.0.0.1:40001 pid=28138) INFO: skipping non-existent file base/107062/107118.1 (seg1 slice1 127.0.0.1:40001 pid=28138)
INFO: corrupting file base/107062/107118.1 by replacing <type 'str'> with ### (seg2 slice1 127.0.0.1:40002 pid=28139) INFO: corrupting file base/107062/107118.1 by replacing <type 'str'> with ### (seg2 slice1 127.0.0.1:40002 pid=28139)
......
...@@ -1179,24 +1179,23 @@ analyze r_part; ...@@ -1179,24 +1179,23 @@ analyze r_part;
explain select * from r_part r1, r_part r2 where r1.a=1; -- should eliminate partitions in the r1 copy of r_part explain select * from r_part r1, r_part r2 where r1.a=1; -- should eliminate partitions in the r1 copy of r_part
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000010.72 rows=9 width=16) Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000010.38 rows=9 width=16)
-> Nested Loop (cost=10000000000.00..10000000010.54 rows=3 width=16) -> Nested Loop (cost=10000000000.00..10000000010.26 rows=3 width=16)
-> Broadcast Motion 1:3 (slice2; segments: 1) (cost=0.00..1.05 rows=3 width=8) -> Broadcast Motion 1:3 (slice2; segments: 1) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on r_part_1_prt_1 r1 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_1 r1 (cost=0.00..1.01 rows=1 width=8)
Filter: (a = 1) Filter: (a = 1)
-> Materialize (cost=0.00..9.17 rows=3 width=8) -> Append (cost=0.00..9.13 rows=9 width=8)
-> Append (cost=0.00..9.12 rows=3 width=8) -> Seq Scan on r_part_1_prt_1 r2 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_1 r2 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_2 r2_1 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_2 r2_1 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_3 r2_2 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_3 r2_2 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_4 r2_3 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_4 r2_3 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_5 r2_4 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_5 r2_4 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_6 r2_5 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_6 r2_5 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_7 r2_6 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_7 r2_6 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_8 r2_7 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_8 r2_7 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_9 r2_8 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_9 r2_8 (cost=0.00..1.00 rows=1 width=8)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(17 rows) (16 rows)
-- the numbers in the filter should be both on segment 0 -- the numbers in the filter should be both on segment 0
explain select * from r_part where a in (7,8); -- should eliminate partitions explain select * from r_part where a in (7,8); -- should eliminate partitions
......
...@@ -1183,27 +1183,23 @@ analyze r_part; ...@@ -1183,27 +1183,23 @@ analyze r_part;
explain select * from r_part r1, r_part r2 where r1.a=1; -- should eliminate partitions in the r1 copy of r_part explain select * from r_part r1, r_part r2 where r1.a=1; -- should eliminate partitions in the r1 copy of r_part
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000010.72 rows=9 width=16) Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000010.38 rows=9 width=16)
-> Nested Loop (cost=10000000000.00..10000000010.54 rows=3 width=16) -> Nested Loop (cost=10000000000.00..10000000010.26 rows=3 width=16)
-> Broadcast Motion 1:3 (slice2; segments: 1) (cost=0.00..1.05 rows=3 width=8) -> Broadcast Motion 1:3 (slice2; segments: 1) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on r_part_1_prt_1 r1 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_1 r1 (cost=0.00..1.01 rows=1 width=8)
Filter: (a = 1) Filter: (a = 1)
-> Materialize (cost=0.00..9.17 rows=3 width=8) -> Append (cost=0.00..9.13 rows=9 width=8)
-> Append (cost=0.00..9.12 rows=3 width=8) -> Seq Scan on r_part_1_prt_1 r2 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_1 r2 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_2 r2_1 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_2 r2_1 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_3 r2_2 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_3 r2_2 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_4 r2_3 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_4 r2_3 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_5 r2_4 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_5 r2_4 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_6 r2_5 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_6 r2_5 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_7 r2_6 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_7 r2_6 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_8 r2_7 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_8 r2_7 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on r_part_1_prt_9 r2_8 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on r_part_1_prt_9 r2_8 (cost=0.00..1.00 rows=1 width=8)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
JIT: (16 rows)
Functions: 5
Options: Inlining true, Optimization true, Expressions true, Deforming true
(20 rows)
-- the numbers in the filter should be both on segment 0 -- the numbers in the filter should be both on segment 0
explain select * from r_part where a in (7,8); -- should eliminate partitions explain select * from r_part where a in (7,8); -- should eliminate partitions
......
...@@ -857,35 +857,32 @@ reset enable_nestloop; ...@@ -857,35 +857,32 @@ reset enable_nestloop;
-- --
-- one of the joined tables can be used for partition elimination, the other can not -- one of the joined tables can be used for partition elimination, the other can not
explain (costs off, timing off, summary off, analyze) select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; explain (costs off, timing off, summary off, analyze) select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------------------------ ---------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (actual rows=36 loops=1) Gather Motion 3:1 (slice1; segments: 3) (actual rows=36 loops=1)
-> Hash Join (actual rows=16 loops=1) -> Hash Join (actual rows=16 loops=1)
Hash Cond: (pt_1_prt_2.ptid = t1.tid) Hash Cond: (t1.t2 = t.t2)
-> Append (actual rows=8 loops=1) -> Hash Join (actual rows=8 loops=1)
Partition Selectors: $0 Hash Cond: (pt_1_prt_2.ptid = t1.tid)
-> Seq Scan on pt_1_prt_2 (never executed) -> Append (actual rows=8 loops=1)
-> Seq Scan on pt_1_prt_3 (actual rows=3 loops=1) Partition Selectors: $0
-> Seq Scan on pt_1_prt_4 (actual rows=5 loops=1) -> Seq Scan on pt_1_prt_2 (never executed)
-> Seq Scan on pt_1_prt_5 (never executed) -> Seq Scan on pt_1_prt_3 (actual rows=3 loops=1)
-> Seq Scan on pt_1_prt_6 (never executed) -> Seq Scan on pt_1_prt_4 (actual rows=5 loops=1)
-> Seq Scan on pt_1_prt_junk_data (never executed) -> Seq Scan on pt_1_prt_5 (never executed)
-> Hash (actual rows=4 loops=1) -> Seq Scan on pt_1_prt_6 (never executed)
-> Seq Scan on pt_1_prt_junk_data (never executed)
-> Hash (actual rows=2 loops=1)
Buckets: 131072 Batches: 1 Memory Usage: 1025kB
-> Partition Selector (selector id: $0) (actual rows=2 loops=1)
-> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1)
-> Seq Scan on t1 (actual rows=1 loops=1)
-> Hash (actual rows=2 loops=1)
Buckets: 131072 Batches: 1 Memory Usage: 1025kB Buckets: 131072 Batches: 1 Memory Usage: 1025kB
-> Partition Selector (selector id: $0) (actual rows=4 loops=1) -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=2 loops=1)
-> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=4 loops=1) -> Seq Scan on t (actual rows=2 loops=1)
-> Hash Join (actual rows=4 loops=1)
Hash Cond: (t.t2 = t1.t2)
-> Redistribute Motion 3:3 (slice3; segments: 3) (actual rows=2 loops=1)
Hash Key: t.t2
-> Seq Scan on t (actual rows=2 loops=1)
-> Hash (actual rows=2 loops=1)
Buckets: 131072 Batches: 1 Memory Usage: 1025kB
-> Redistribute Motion 3:3 (slice4; segments: 3) (actual rows=2 loops=1)
Hash Key: t1.t2
-> Seq Scan on t1 (actual rows=1 loops=1)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(26 rows) (23 rows)
select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid;
dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid
......
...@@ -857,35 +857,32 @@ reset enable_nestloop; ...@@ -857,35 +857,32 @@ reset enable_nestloop;
-- --
-- one of the joined tables can be used for partition elimination, the other can not -- one of the joined tables can be used for partition elimination, the other can not
explain (costs off, timing off, summary off, analyze) select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; explain (costs off, timing off, summary off, analyze) select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------------------------ ---------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (actual rows=36 loops=1) Gather Motion 3:1 (slice1; segments: 3) (actual rows=36 loops=1)
-> Hash Join (actual rows=16 loops=1) -> Hash Join (actual rows=16 loops=1)
Hash Cond: (pt_1_prt_2.ptid = t1.tid) Hash Cond: (t1.t2 = t.t2)
-> Append (actual rows=8 loops=1) -> Hash Join (actual rows=8 loops=1)
Partition Selectors: $0 Hash Cond: (pt_1_prt_2.ptid = t1.tid)
-> Seq Scan on pt_1_prt_2 (never executed) -> Append (actual rows=8 loops=1)
-> Seq Scan on pt_1_prt_3 (actual rows=3 loops=1) Partition Selectors: $0
-> Seq Scan on pt_1_prt_4 (actual rows=5 loops=1) -> Seq Scan on pt_1_prt_2 (never executed)
-> Seq Scan on pt_1_prt_5 (never executed) -> Seq Scan on pt_1_prt_3 (actual rows=3 loops=1)
-> Seq Scan on pt_1_prt_6 (never executed) -> Seq Scan on pt_1_prt_4 (actual rows=5 loops=1)
-> Seq Scan on pt_1_prt_junk_data (never executed) -> Seq Scan on pt_1_prt_5 (never executed)
-> Hash (actual rows=4 loops=1) -> Seq Scan on pt_1_prt_6 (never executed)
-> Seq Scan on pt_1_prt_junk_data (never executed)
-> Hash (actual rows=2 loops=1)
Buckets: 131072 Batches: 1 Memory Usage: 1025kB
-> Partition Selector (selector id: $0) (actual rows=2 loops=1)
-> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1)
-> Seq Scan on t1 (actual rows=1 loops=1)
-> Hash (actual rows=2 loops=1)
Buckets: 131072 Batches: 1 Memory Usage: 1025kB Buckets: 131072 Batches: 1 Memory Usage: 1025kB
-> Partition Selector (selector id: $0) (actual rows=4 loops=1) -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=2 loops=1)
-> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=4 loops=1) -> Seq Scan on t (actual rows=2 loops=1)
-> Hash Join (actual rows=4 loops=1)
Hash Cond: (t.t2 = t1.t2)
-> Redistribute Motion 3:3 (slice3; segments: 3) (actual rows=2 loops=1)
Hash Key: t.t2
-> Seq Scan on t (actual rows=2 loops=1)
-> Hash (actual rows=2 loops=1)
Buckets: 131072 Batches: 1 Memory Usage: 1025kB
-> Redistribute Motion 3:3 (slice4; segments: 3) (actual rows=2 loops=1)
Hash Key: t1.t2
-> Seq Scan on t1 (actual rows=1 loops=1)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(26 rows) (23 rows)
select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid;
dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid
......
...@@ -95,6 +95,7 @@ create table ec0 (ff int8 primary key, f1 int8, f2 int8); ...@@ -95,6 +95,7 @@ create table ec0 (ff int8 primary key, f1 int8, f2 int8);
create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2); create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2);
create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2); create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2);
-- for the moment we only want to look at nestloop plans -- for the moment we only want to look at nestloop plans
set enable_nestloop = on;
set enable_hashjoin = off; set enable_hashjoin = off;
set enable_mergejoin = off; set enable_mergejoin = off;
-- --
...@@ -147,18 +148,17 @@ explain (costs off) ...@@ -147,18 +148,17 @@ explain (costs off)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and ff = '42'::int8; select * from ec1, ec2 where ff = x1 and ff = '42'::int8;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop -> Nested Loop
Join Filter: (ec1.ff = ec2.x1) Join Filter: (ec1.ff = ec2.x1)
-> Broadcast Motion 1:3 (slice2; segments: 1)
-> Index Scan using ec1_pkey on ec1
Index Cond: ((ff = '42'::bigint) AND (ff = '42'::bigint))
-> Seq Scan on ec2 -> Seq Scan on ec2
-> Materialize
-> Broadcast Motion 1:3 (slice2; segments: 1)
-> Index Scan using ec1_pkey on ec1
Index Cond: ((ff = '42'::bigint) AND (ff = '42'::bigint))
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(9 rows) (8 rows)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and ff = '42'::int8alias1; select * from ec1, ec2 where ff = x1 and ff = '42'::int8alias1;
...@@ -169,11 +169,10 @@ explain (costs off) ...@@ -169,11 +169,10 @@ explain (costs off)
-> Broadcast Motion 3:3 (slice2; segments: 3) -> Broadcast Motion 3:3 (slice2; segments: 3)
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = '42'::int8alias1) Index Cond: (ff = '42'::int8alias1)
-> Materialize -> Seq Scan on ec2
-> Seq Scan on ec2 Filter: (x1 = '42'::int8alias1)
Filter: (x1 = '42'::int8alias1)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(9 rows) (8 rows)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and '42'::int8 = x1; select * from ec1, ec2 where ff = x1 and '42'::int8 = x1;
...@@ -185,11 +184,10 @@ explain (costs off) ...@@ -185,11 +184,10 @@ explain (costs off)
-> Broadcast Motion 1:3 (slice2; segments: 1) -> Broadcast Motion 1:3 (slice2; segments: 1)
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = '42'::bigint) Index Cond: (ff = '42'::bigint)
-> Materialize -> Seq Scan on ec2
-> Seq Scan on ec2 Filter: ('42'::bigint = x1)
Filter: ('42'::bigint = x1)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(10 rows) (9 rows)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias1; select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias1;
...@@ -200,11 +198,10 @@ explain (costs off) ...@@ -200,11 +198,10 @@ explain (costs off)
-> Broadcast Motion 3:3 (slice2; segments: 3) -> Broadcast Motion 3:3 (slice2; segments: 3)
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = '42'::int8alias1) Index Cond: (ff = '42'::int8alias1)
-> Materialize -> Seq Scan on ec2
-> Seq Scan on ec2 Filter: (x1 = '42'::int8alias1)
Filter: (x1 = '42'::int8alias1)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(9 rows) (8 rows)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias2; select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias2;
...@@ -298,22 +295,28 @@ explain (costs off) ...@@ -298,22 +295,28 @@ explain (costs off)
union all union all
select ff + 4 as x from ec1) as ss2 select ff + 4 as x from ec1) as ss2
where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8; where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8;
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------- -----------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop -> Nested Loop
-> Broadcast Motion 3:3 (slice2; segments: 3) -> Broadcast Motion 3:3 (slice2; segments: 3)
-> Nested Loop -> Nested Loop
Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1) -> Broadcast Motion 1:3 (slice3; segments: 1)
-> Merge Append -> Index Scan using ec1_pkey on ec1
Sort Key: (((ec1_1.ff + 2) + 1)) Index Cond: (ff = '42'::bigint)
-> Index Scan using ec1_expr2 on ec1 ec1_1 -> Append
-> Index Scan using ec1_expr3 on ec1 ec1_2 -> Bitmap Heap Scan on ec1 ec1_1
-> Index Scan using ec1_expr4 on ec1 ec1_3 Recheck Cond: (((ff + 2) + 1) = ec1.f1)
-> Materialize -> Bitmap Index Scan on ec1_expr2
-> Broadcast Motion 1:3 (slice3; segments: 1) Index Cond: (((ff + 2) + 1) = ec1.f1)
-> Index Scan using ec1_pkey on ec1 -> Bitmap Heap Scan on ec1 ec1_2
Index Cond: (ff = '42'::bigint) Recheck Cond: (((ff + 3) + 1) = ec1.f1)
-> Bitmap Index Scan on ec1_expr3
Index Cond: (((ff + 3) + 1) = ec1.f1)
-> Bitmap Heap Scan on ec1 ec1_3
Recheck Cond: ((ff + 4) = ec1.f1)
-> Bitmap Index Scan on ec1_expr4
Index Cond: ((ff + 4) = ec1.f1)
-> Append -> Append
-> Index Scan using ec1_expr2 on ec1 ec1_4 -> Index Scan using ec1_expr2 on ec1 ec1_4
Index Cond: (((ff + 2) + 1) = (((ec1_1.ff + 2) + 1))) Index Cond: (((ff + 2) + 1) = (((ec1_1.ff + 2) + 1)))
...@@ -322,7 +325,7 @@ explain (costs off) ...@@ -322,7 +325,7 @@ explain (costs off)
-> Index Scan using ec1_expr4 on ec1 ec1_6 -> Index Scan using ec1_expr4 on ec1 ec1_6
Index Cond: ((ff + 4) = (((ec1_1.ff + 2) + 1))) Index Cond: ((ff + 4) = (((ec1_1.ff + 2) + 1)))
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(22 rows) (28 rows)
-- let's try that as a mergejoin -- let's try that as a mergejoin
set enable_mergejoin = on; set enable_mergejoin = on;
......
...@@ -95,6 +95,7 @@ create table ec0 (ff int8 primary key, f1 int8, f2 int8); ...@@ -95,6 +95,7 @@ create table ec0 (ff int8 primary key, f1 int8, f2 int8);
create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2); create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2);
create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2); create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2);
-- for the moment we only want to look at nestloop plans -- for the moment we only want to look at nestloop plans
set enable_nestloop = on;
set enable_hashjoin = off; set enable_hashjoin = off;
set enable_mergejoin = off; set enable_mergejoin = off;
-- --
...@@ -168,11 +169,10 @@ explain (costs off) ...@@ -168,11 +169,10 @@ explain (costs off)
-> Broadcast Motion 3:3 (slice2; segments: 3) -> Broadcast Motion 3:3 (slice2; segments: 3)
-> Index Scan using ec1_pkey on ec1 -> Index Scan using ec1_pkey on ec1
Index Cond: (ff = '42'::int8alias1) Index Cond: (ff = '42'::int8alias1)
-> Materialize -> Seq Scan on ec2
-> Seq Scan on ec2 Filter: (x1 = '42'::int8alias1)
Filter: (x1 = '42'::int8alias1)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(9 rows) (8 rows)
explain (costs off) explain (costs off)
select * from ec1, ec2 where ff = x1 and '42'::int8 = x1; select * from ec1, ec2 where ff = x1 and '42'::int8 = x1;
......
...@@ -12225,20 +12225,20 @@ where out.b in (select coalesce(tcorr2.a, 99) ...@@ -12225,20 +12225,20 @@ where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a); from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
QUERY PLAN QUERY PLAN
---------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------
Nested Loop Semi Join (cost=10000000001.10..10000000003.36 rows=3 width=8) Nested Loop Semi Join (cost=10000000001.05..10000000003.21 rows=3 width=8)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.05 rows=3 width=8) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8)
-> Materialize (cost=1.10..2.28 rows=1 width=4) -> Materialize (cost=1.05..2.17 rows=1 width=4)
-> Subquery Scan on "ANY_subquery" (cost=1.10..2.27 rows=1 width=4) -> Subquery Scan on "ANY_subquery" (cost=1.05..2.16 rows=1 width=4)
Filter: ("out".b = "ANY_subquery"."coalesce") Filter: ("out".b = "ANY_subquery"."coalesce")
-> Hash Left Join (cost=1.10..2.23 rows=3 width=4) -> Hash Left Join (cost=1.05..2.12 rows=3 width=4)
Hash Cond: (tcorr1.a = (tcorr2.a + "out".a)) Hash Cond: (tcorr1.a = (tcorr2.a + "out".a))
-> Materialize (cost=0.00..1.06 rows=3 width=4) -> Materialize (cost=0.00..1.03 rows=1 width=4)
-> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4)
-> Seq Scan on tcorr1 (cost=0.00..1.01 rows=1 width=4) -> Seq Scan on tcorr1 (cost=0.00..1.01 rows=1 width=4)
-> Hash (cost=1.06..1.06 rows=3 width=4) -> Hash (cost=1.03..1.03 rows=1 width=4)
-> Materialize (cost=0.00..1.06 rows=3 width=4) -> Materialize (cost=0.00..1.03 rows=1 width=4)
-> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1.05 rows=3 width=4) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=4)
-> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=4) -> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=4)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(16 rows) (16 rows)
...@@ -12261,15 +12261,15 @@ where out.b in (select max(tcorr2.b + out.b - 1) ...@@ -12261,15 +12261,15 @@ where out.b in (select max(tcorr2.b + out.b - 1)
where tcorr2.a=out.a); where tcorr2.a=out.a);
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.05 rows=3 width=8) Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8)
Filter: (SubPlan 1) Filter: (SubPlan 1)
SubPlan 1 SubPlan 1
-> Aggregate (cost=1.12..1.13 rows=1 width=4) -> Aggregate (cost=1.05..1.06 rows=1 width=4)
-> Result (cost=0.00..1.09 rows=3 width=4) -> Result (cost=0.00..1.04 rows=1 width=4)
Filter: (tcorr2.a = "out".a) Filter: (tcorr2.a = "out".a)
-> Materialize (cost=0.00..1.06 rows=3 width=8) -> Materialize (cost=0.00..1.03 rows=1 width=8)
-> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=8)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(11 rows) (11 rows)
...@@ -12321,20 +12321,20 @@ where out.b in (select coalesce(tcorr2.a, 99) ...@@ -12321,20 +12321,20 @@ where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a); from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
QUERY PLAN QUERY PLAN
---------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------
Nested Loop Semi Join (cost=10000000001.10..10000000003.36 rows=3 width=8) Nested Loop Semi Join (cost=10000000001.05..10000000003.21 rows=3 width=8)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.05 rows=3 width=8) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8)
-> Materialize (cost=1.10..2.28 rows=1 width=4) -> Materialize (cost=1.05..2.17 rows=1 width=4)
-> Subquery Scan on "ANY_subquery" (cost=1.10..2.27 rows=1 width=4) -> Subquery Scan on "ANY_subquery" (cost=1.05..2.16 rows=1 width=4)
Filter: ("out".b = "ANY_subquery"."coalesce") Filter: ("out".b = "ANY_subquery"."coalesce")
-> Hash Left Join (cost=1.10..2.23 rows=3 width=4) -> Hash Left Join (cost=1.05..2.12 rows=3 width=4)
Hash Cond: (tcorr1.a = (tcorr2.a + "out".a)) Hash Cond: (tcorr1.a = (tcorr2.a + "out".a))
-> Materialize (cost=0.00..1.06 rows=3 width=4) -> Materialize (cost=0.00..1.03 rows=1 width=4)
-> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4)
-> Seq Scan on tcorr1 (cost=0.00..1.01 rows=1 width=4) -> Seq Scan on tcorr1 (cost=0.00..1.01 rows=1 width=4)
-> Hash (cost=1.06..1.06 rows=3 width=4) -> Hash (cost=1.03..1.03 rows=1 width=4)
-> Materialize (cost=0.00..1.06 rows=3 width=4) -> Materialize (cost=0.00..1.03 rows=1 width=4)
-> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1.05 rows=3 width=4) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=4)
-> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=4) -> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=4)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(16 rows) (16 rows)
...@@ -12357,15 +12357,15 @@ where out.b in (select max(tcorr2.b + out.b - 1) ...@@ -12357,15 +12357,15 @@ where out.b in (select max(tcorr2.b + out.b - 1)
where tcorr2.a=out.a); where tcorr2.a=out.a);
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.05 rows=3 width=8) Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on tcorr1 "out" (cost=0.00..1.01 rows=1 width=8)
Filter: (SubPlan 1) Filter: (SubPlan 1)
SubPlan 1 SubPlan 1
-> Aggregate (cost=1.12..1.13 rows=1 width=4) -> Aggregate (cost=1.05..1.06 rows=1 width=4)
-> Result (cost=0.00..1.09 rows=3 width=4) -> Result (cost=0.00..1.04 rows=1 width=4)
Filter: (tcorr2.a = "out".a) Filter: (tcorr2.a = "out".a)
-> Materialize (cost=0.00..1.06 rows=3 width=8) -> Materialize (cost=0.00..1.03 rows=1 width=8)
-> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8)
-> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..1.01 rows=1 width=8)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(11 rows) (11 rows)
......
...@@ -3216,25 +3216,23 @@ explain (costs off) ...@@ -3216,25 +3216,23 @@ explain (costs off)
select * from select * from
tenk1, int8_tbl a, int8_tbl b tenk1, int8_tbl a, int8_tbl b
where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2; where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------- ---------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop -> Nested Loop
Join Filter: (tenk1.tenthous = b.q1) -> Broadcast Motion 3:3 (slice2; segments: 3)
-> Nested Loop -> Seq Scan on int8_tbl b
-> Broadcast Motion 3:3 (slice2; segments: 3) Filter: (q2 = 2)
-> Seq Scan on int8_tbl a
Filter: (q2 = 1)
-> Bitmap Heap Scan on tenk1
Recheck Cond: (thousand = a.q1)
-> Bitmap Index Scan on tenk1_thous_tenthous
Index Cond: (thousand = a.q1)
-> Materialize -> Materialize
-> Broadcast Motion 3:3 (slice3; segments: 3) -> Nested Loop
-> Seq Scan on int8_tbl b -> Materialize
Filter: (q2 = 2) -> Broadcast Motion 3:3 (slice3; segments: 3)
-> Seq Scan on int8_tbl a
Filter: (q2 = 1)
-> Index Scan using tenk1_thous_tenthous on tenk1
Index Cond: ((thousand = a.q1) AND (tenthous = b.q1))
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(16 rows) (14 rows)
reset enable_nestloop; reset enable_nestloop;
-- --
...@@ -6502,38 +6500,38 @@ from onek t1, tenk1 t2 ...@@ -6502,38 +6500,38 @@ from onek t1, tenk1 t2
where exists (select 1 from tenk1 t3 where exists (select 1 from tenk1 t3
where t3.thousand = t1.unique1 and t3.tenthous = t2.hundred) where t3.thousand = t1.unique1 and t3.tenthous = t2.hundred)
and t1.unique1 < 1; and t1.unique1 < 1;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) Gather Motion 3:1 (slice1; segments: 3)
Output: t1.unique1, t2.hundred Output: t1.unique1, t2.hundred
-> Nested Loop -> Nested Loop
Output: t1.unique1, t2.hundred Output: t1.unique1, t2.hundred
-> Broadcast Motion 3:3 (slice2; segments: 3) -> Broadcast Motion 3:3 (slice2; segments: 3)
Output: t1.unique1, t3.tenthous Output: t1.unique1, t3.tenthous
-> Hash Join -> Nested Loop
Output: t1.unique1, t3.tenthous Output: t1.unique1, t3.tenthous
Hash Cond: (t1.unique1 = t3.thousand) Join Filter: (t1.unique1 = t3.thousand)
-> Broadcast Motion 3:3 (slice3; segments: 3) -> HashAggregate
Output: t1.unique1
-> Index Only Scan using onek_unique1 on public.onek t1
Output: t1.unique1
Index Cond: (t1.unique1 < 1)
-> Hash
Output: t3.thousand, t3.tenthous Output: t3.thousand, t3.tenthous
-> HashAggregate Group Key: t3.thousand, t3.tenthous
-> Redistribute Motion 3:3 (slice3; segments: 3)
Output: t3.thousand, t3.tenthous Output: t3.thousand, t3.tenthous
Group Key: t3.thousand, t3.tenthous Hash Key: t3.thousand, t3.tenthous
-> Redistribute Motion 3:3 (slice4; segments: 3) -> Index Only Scan using tenk1_thous_tenthous on public.tenk1 t3
Output: t3.thousand, t3.tenthous Output: t3.thousand, t3.tenthous
Hash Key: t3.thousand, t3.tenthous Index Cond: (t3.thousand < 1)
-> Index Only Scan using tenk1_thous_tenthous on public.tenk1 t3 -> Materialize
Output: t3.thousand, t3.tenthous Output: t1.unique1
Index Cond: (t3.thousand < 1) -> Broadcast Motion 3:3 (slice4; segments: 3)
Output: t1.unique1
-> Index Only Scan using onek_unique1 on public.onek t1
Output: t1.unique1
Index Cond: (t1.unique1 < 1)
-> Index Only Scan using tenk1_hundred on public.tenk1 t2 -> Index Only Scan using tenk1_hundred on public.tenk1 t2
Output: t2.hundred Output: t2.hundred
Index Cond: (t2.hundred = t3.tenthous) Index Cond: (t2.hundred = t3.tenthous)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
Settings: enable_bitmapscan=off, enable_mergejoin=on, enable_nestloop=on, enable_seqscan=off, optimizer=off Settings: enable_bitmapscan=off, enable_mergejoin=on, enable_nestloop=on, enable_seqscan=off, jit=off, optimizer=off
(30 rows) (30 rows)
-- ... unless it actually is unique -- ... unless it actually is unique
......
...@@ -377,38 +377,37 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i i ...@@ -377,38 +377,37 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i i
explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10;
QUERY PLAN QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=20000000100.29..20000000100.52 rows=10 width=12) Limit (cost=20000000003.86..20000000004.00 rows=10 width=12)
-> Gather Motion 3:1 (slice3; segments: 3) (cost=20000000100.29..20000000100.52 rows=10 width=12) -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000003.86..20000000004.28 rows=30 width=12)
Merge Key: a.i, b.i, c.j Merge Key: a.i, b.i, c.j
-> Limit (cost=20000000100.29..20000000100.32 rows=4 width=12) -> Limit (cost=20000000003.86..20000000003.88 rows=10 width=12)
-> Sort (cost=20000000100.29..20000000100.43 rows=18 width=12) -> Sort (cost=20000000003.85..20000000003.90 rows=18 width=12)
Sort Key: a.i, b.i, c.j Sort Key: a.i, b.i, c.j
-> Nested Loop (cost=20000000000.00..20000000099.13 rows=18 width=12) -> Nested Loop (cost=20000000000.00..20000000003.48 rows=18 width=12)
-> Nested Loop (cost=10000000000.00..10000000093.81 rows=2 width=8) -> Nested Loop (cost=10000000000.00..10000000002.08 rows=2 width=8)
-> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..90.51 rows=1 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=4)
-> Seq Scan on a (cost=0.00..90.47 rows=1 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4)
Filter: (j = (SubPlan 2)) Filter: (j = (SubPlan 2))
SubPlan 2 SubPlan 2
-> Result (cost=0.00..17.68 rows=5 width=4) -> Result (cost=0.00..1.16 rows=4 width=4)
Filter: (c_1.j = a.j) Filter: (c_1.j = a.j)
-> Materialize (cost=0.00..17.68 rows=5 width=4) -> Materialize (cost=0.00..1.11 rows=4 width=4)
-> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..17.66 rows=2 width=4) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.09 rows=4 width=4)
-> Seq Scan on c c_1 (cost=0.00..17.57 rows=2 width=4) -> Seq Scan on c c_1 (cost=0.00..1.03 rows=2 width=4)
Filter: (SubPlan 1) Filter: (SubPlan 1)
SubPlan 1 SubPlan 1
-> Result (cost=0.00..3.20 rows=5 width=4) -> Result (cost=0.00..1.17 rows=5 width=4)
Filter: (c_1.i = b_1.i) Filter: (c_1.i = b_1.i)
-> Materialize (cost=0.00..3.20 rows=5 width=4) -> Materialize (cost=0.00..1.12 rows=5 width=4)
-> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..3.17 rows=2 width=4) -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1.09 rows=5 width=4)
-> Seq Scan on b b_1 (cost=0.00..3.08 rows=2 width=4) -> Seq Scan on b b_1 (cost=0.00..1.02 rows=2 width=4)
Filter: (i <> 10) Filter: (i <> 10)
-> Materialize (cost=0.00..3.09 rows=2 width=4) -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4)
-> Seq Scan on b (cost=0.00..3.06 rows=2 width=4) -> Materialize (cost=0.00..1.19 rows=9 width=4)
-> Materialize (cost=0.00..3.58 rows=9 width=4) -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.15 rows=9 width=4)
-> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.45 rows=9 width=4) -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4)
-> Seq Scan on c (cost=0.00..3.09 rows=3 width=4)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(31 rows) (30 rows)
select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10;
i | i | j i | i | j
...@@ -597,37 +596,36 @@ ERROR: correlated subquery with skip-level correlations is not supported ...@@ -597,37 +596,36 @@ ERROR: correlated subquery with skip-level correlations is not supported
explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10;
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=20000000045.25..20000000045.47 rows=10 width=12) Limit (cost=20000000003.86..20000000004.00 rows=10 width=12)
-> Gather Motion 3:1 (slice3; segments: 3) (cost=20000000045.25..20000000045.47 rows=10 width=12) -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000003.86..20000000004.28 rows=30 width=12)
Merge Key: a.i, b.i, c.j Merge Key: a.i, b.i, c.j
-> Limit (cost=20000000045.25..20000000045.27 rows=4 width=12) -> Limit (cost=20000000003.86..20000000003.88 rows=10 width=12)
-> Sort (cost=20000000045.25..20000000045.38 rows=18 width=12) -> Sort (cost=20000000003.85..20000000003.90 rows=18 width=12)
Sort Key: a.i, b.i, c.j Sort Key: a.i, b.i, c.j
-> Nested Loop (cost=20000000000.00..20000000044.08 rows=18 width=12) -> Nested Loop (cost=20000000000.00..20000000003.48 rows=18 width=12)
-> Nested Loop (cost=10000000000.00..10000000038.76 rows=2 width=8) -> Nested Loop (cost=10000000000.00..10000000002.08 rows=2 width=8)
-> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..35.46 rows=1 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=4)
-> Seq Scan on a (cost=0.00..35.42 rows=1 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4)
Filter: (j = (SubPlan 1)) Filter: (j = (SubPlan 1))
SubPlan 1 SubPlan 1
-> Hash Semi Join (cost=3.26..6.67 rows=6 width=4) -> Hash Semi Join (cost=1.18..2.55 rows=5 width=4)
Hash Cond: (c_1.i = b_1.i) Hash Cond: (c_1.i = b_1.i)
-> Result (cost=0.00..3.31 rows=9 width=8) -> Result (cost=0.00..1.28 rows=9 width=8)
Filter: (c_1.j = a.j) Filter: (c_1.j = a.j)
-> Materialize (cost=0.00..3.31 rows=9 width=8) -> Materialize (cost=0.00..1.19 rows=9 width=8)
-> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..3.27 rows=3 width=8) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.15 rows=9 width=8)
-> Seq Scan on c c_1 (cost=0.00..3.09 rows=3 width=8) -> Seq Scan on c c_1 (cost=0.00..1.03 rows=3 width=8)
-> Hash (cost=3.20..3.20 rows=2 width=4) -> Hash (cost=1.12..1.12 rows=5 width=4)
-> Materialize (cost=0.00..3.20 rows=5 width=4) -> Materialize (cost=0.00..1.12 rows=5 width=4)
-> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..3.17 rows=2 width=4) -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1.09 rows=5 width=4)
-> Seq Scan on b b_1 (cost=0.00..3.08 rows=2 width=4) -> Seq Scan on b b_1 (cost=0.00..1.02 rows=2 width=4)
Filter: (i <> 10) Filter: (i <> 10)
-> Materialize (cost=0.00..3.09 rows=2 width=4) -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4)
-> Seq Scan on b (cost=0.00..3.06 rows=2 width=4) -> Materialize (cost=0.00..1.19 rows=9 width=4)
-> Materialize (cost=0.00..3.58 rows=9 width=4) -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.15 rows=9 width=4)
-> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.45 rows=9 width=4) -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4)
-> Seq Scan on c (cost=0.00..3.09 rows=3 width=4)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(30 rows) (29 rows)
select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10;
i | i | j i | i | j
......
...@@ -945,18 +945,17 @@ select t1.a, t2.b from t1 inner join t2 on (t1.a=t2.a) where ((t1.a,t2.b) not i ...@@ -945,18 +945,17 @@ select t1.a, t2.b from t1 inner join t2 on (t1.a=t2.a) where ((t1.a,t2.b) not i
explain select t1.a, t2.b from t1, t2 where t1.a=t2.a or ((t1.a,t2.b) not in (select i1.a,i1.b from i1)); explain select t1.a, t2.b from t1, t2 where t1.a=t2.a or ((t1.a,t2.b) not in (select i1.a,i1.b from i1));
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.15 rows=3 width=8) Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.10 rows=3 width=8)
-> Nested Loop (cost=10000000000.00..10000000002.10 rows=1 width=8) -> Nested Loop (cost=10000000000.00..10000000002.05 rows=1 width=8)
Join Filter: ((t1.a = t2.a) OR (NOT (hashed SubPlan 1))) Join Filter: ((t1.a = t2.a) OR (NOT (hashed SubPlan 1)))
-> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4)
-> Seq Scan on t1 (cost=0.00..1.01 rows=1 width=4) -> Seq Scan on t1 (cost=0.00..1.01 rows=1 width=4)
-> Materialize (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=8)
SubPlan 1 SubPlan 1
-> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.01 rows=1 width=8) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on i1 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on i1 (cost=0.00..1.01 rows=1 width=8)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(11 rows) (10 rows)
-- --
-- not in subquery involving vars from different rels with left join. -- not in subquery involving vars from different rels with left join.
......
...@@ -943,18 +943,17 @@ select t1.a, t2.b from t1 inner join t2 on (t1.a=t2.a) where ((t1.a,t2.b) not i ...@@ -943,18 +943,17 @@ select t1.a, t2.b from t1 inner join t2 on (t1.a=t2.a) where ((t1.a,t2.b) not i
explain select t1.a, t2.b from t1, t2 where t1.a=t2.a or ((t1.a,t2.b) not in (select i1.a,i1.b from i1)); explain select t1.a, t2.b from t1, t2 where t1.a=t2.a or ((t1.a,t2.b) not in (select i1.a,i1.b from i1));
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=10000000001.01..10000000003.14 rows=4 width=8) Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.10 rows=3 width=8)
-> Nested Loop (cost=10000000001.01..10000000003.14 rows=2 width=8) -> Nested Loop (cost=10000000000.00..10000000002.05 rows=1 width=8)
Join Filter: ((t1.a = t2.a) OR (NOT (hashed SubPlan 1))) Join Filter: ((t1.a = t2.a) OR (NOT (hashed SubPlan 1)))
-> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=1 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4)
-> Seq Scan on t1 (cost=0.00..1.01 rows=1 width=4) -> Seq Scan on t1 (cost=0.00..1.01 rows=1 width=4)
-> Materialize (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=8)
SubPlan 1 SubPlan 1
-> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.01 rows=1 width=8) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.01 rows=1 width=8)
-> Seq Scan on i1 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on i1 (cost=0.00..1.01 rows=1 width=8)
Optimizer: Postgres query optimizer Optimizer: Postgres query optimizer
(11 rows) (10 rows)
-- --
-- not in subquery involving vars from different rels with left join. -- not in subquery involving vars from different rels with left join.
......
...@@ -925,17 +925,17 @@ explain (costs off) insert into t_replicate_volatile select nextval('seq_for_ins ...@@ -925,17 +925,17 @@ explain (costs off) insert into t_replicate_volatile select nextval('seq_for_ins
-- update & delete -- update & delete
explain (costs off) update t_replicate_volatile set a = 1 where b > random(); explain (costs off) update t_replicate_volatile set a = 1 where b > random();
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) update t_replicate_volatile set a = 1 from t_replicate_volatile x where x.a + random() = t_replicate_volatile.b; explain (costs off) update t_replicate_volatile set a = 1 from t_replicate_volatile x where x.a + random() = t_replicate_volatile.b;
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) update t_replicate_volatile set a = 1 from t_hashdist x where x.a + random() = t_replicate_volatile.b; explain (costs off) update t_replicate_volatile set a = 1 from t_hashdist x where x.a + random() = t_replicate_volatile.b;
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) delete from t_replicate_volatile where a < random(); explain (costs off) delete from t_replicate_volatile where a < random();
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) delete from t_replicate_volatile using t_replicate_volatile x where t_replicate_volatile.a + x.b < random(); explain (costs off) delete from t_replicate_volatile using t_replicate_volatile x where t_replicate_volatile.a + x.b < random();
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) update t_replicate_volatile set a = random(); explain (costs off) update t_replicate_volatile set a = random();
ERROR: could not devise a plan. (cdbpath.c:2408) ERROR: could not devise a plan. (cdbpath.c:2440)
-- limit -- limit
explain (costs off) insert into t_replicate_volatile select * from t_replicate_volatile limit random(); explain (costs off) insert into t_replicate_volatile select * from t_replicate_volatile limit random();
QUERY PLAN QUERY PLAN
......
...@@ -905,20 +905,20 @@ explain (costs off) insert into t_replicate_volatile select nextval('seq_for_ins ...@@ -905,20 +905,20 @@ explain (costs off) insert into t_replicate_volatile select nextval('seq_for_ins
-- update & delete -- update & delete
explain (costs off) update t_replicate_volatile set a = 1 where b > random(); explain (costs off) update t_replicate_volatile set a = 1 where b > random();
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) update t_replicate_volatile set a = 1 from t_replicate_volatile x where x.a + random() = t_replicate_volatile.b; explain (costs off) update t_replicate_volatile set a = 1 from t_replicate_volatile x where x.a + random() = t_replicate_volatile.b;
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) update t_replicate_volatile set a = 1 from t_hashdist x where x.a + random() = t_replicate_volatile.b; explain (costs off) update t_replicate_volatile set a = 1 from t_hashdist x where x.a + random() = t_replicate_volatile.b;
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) delete from t_replicate_volatile where a < random(); explain (costs off) delete from t_replicate_volatile where a < random();
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) delete from t_replicate_volatile using t_replicate_volatile x where t_replicate_volatile.a + x.b < random(); explain (costs off) delete from t_replicate_volatile using t_replicate_volatile x where t_replicate_volatile.a + x.b < random();
ERROR: could not devise a plan (cdbpath.c:2545) ERROR: could not devise a plan (cdbpath.c:2577)
explain (costs off) update t_replicate_volatile set a = random(); explain (costs off) update t_replicate_volatile set a = random();
ERROR: could not devise a plan. (cdbpath.c:2408) ERROR: could not devise a plan. (cdbpath.c:2440)
-- limit -- limit
explain (costs off) insert into t_replicate_volatile select * from t_replicate_volatile limit random(); explain (costs off) insert into t_replicate_volatile select * from t_replicate_volatile limit random();
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
Insert on t_replicate_volatile Insert on t_replicate_volatile
-> Result -> Result
......
...@@ -362,7 +362,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ...@@ -362,7 +362,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE
SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 1 1 | 1
(1 row) (1 row)
-- create statistics -- create statistics
...@@ -377,7 +377,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ...@@ -377,7 +377,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE
SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 1 1 | 1
(1 row) (1 row)
-- a => b, a => c, b => c -- a => b, a => c, b => c
...@@ -389,13 +389,13 @@ ANALYZE functional_dependencies; ...@@ -389,13 +389,13 @@ ANALYZE functional_dependencies;
SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1''');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
-- create statistics -- create statistics
...@@ -451,7 +451,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ...@@ -451,7 +451,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b =
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 1 1 | 1
(1 row) (1 row)
-- create statistics -- create statistics
...@@ -466,7 +466,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ...@@ -466,7 +466,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b =
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 1 1 | 1
(1 row) (1 row)
-- 100 distinct combinations, all in the MCV list -- 100 distinct combinations, all in the MCV list
...@@ -478,37 +478,37 @@ ANALYZE mcv_lists; ...@@ -478,37 +478,37 @@ ANALYZE mcv_lists;
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1'''); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1''');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0'''); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0''');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
-- create statistics -- create statistics
...@@ -566,7 +566,7 @@ ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric; ...@@ -566,7 +566,7 @@ ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric;
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1''');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
ANALYZE mcv_lists; ANALYZE mcv_lists;
...@@ -590,13 +590,13 @@ ANALYZE mcv_lists; ...@@ -590,13 +590,13 @@ ANALYZE mcv_lists;
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 50 1 | 50
(1 row) (1 row)
-- create statistics -- create statistics
...@@ -690,19 +690,19 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b A ...@@ -690,19 +690,19 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b A
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 0 1 | 0
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 0 1 | 0
(1 row) (1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c'); SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c');
estimated | actual estimated | actual
-----------+-------- -----------+--------
3 | 0 1 | 0
(1 row) (1 row)
-- Permission tests. Users should not be able to see specific data values in -- Permission tests. Users should not be able to see specific data values in
......
...@@ -69,7 +69,7 @@ RETURNS integer as $$ ...@@ -69,7 +69,7 @@ RETURNS integer as $$
f.close() f.close()
return 0 return 0
$$ LANGUAGE plpython3u; $$ LANGUAGE plpython3u EXECUTE ON ALL SEGMENTS;
-- Corrupt a file by replacing the last occurrence of 'str' within the file -- Corrupt a file by replacing the last occurrence of 'str' within the file
-- with 'replacement' -- with 'replacement'
...@@ -97,48 +97,48 @@ RETURNS integer as $$ ...@@ -97,48 +97,48 @@ RETURNS integer as $$
f.close() f.close()
return 0 return 0
$$ LANGUAGE plpython3u; $$ LANGUAGE plpython3u EXECUTE ON ALL SEGMENTS;
-- Large content, corrupt block header -- Large content, corrupt block header
create table corrupt_header_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY; create table corrupt_header_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY;
insert into corrupt_header_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ; insert into corrupt_header_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ;
select SUM(corrupt_file(get_aoseg1_path('corrupt_header_large_co'), 8)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_header_large_co'), 8));
SELECT COUNT(*) FROM corrupt_header_large_co; SELECT COUNT(*) FROM corrupt_header_large_co;
-- Large content, corrupt content -- Large content, corrupt content
create table corrupt_content_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY; create table corrupt_content_large_co(comment bytea ) with (appendonly=true, orientation=column, checksum=true) DISTRIBUTED RANDOMLY;
insert into corrupt_content_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ; insert into corrupt_content_large_co select ("decode"(repeat('a',33554432),'escape')) from generate_series(1,8) ;
select SUM(corrupt_file(get_aoseg1_path('corrupt_content_large_co'), -3)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_content_large_co'), -3));
SELECT COUNT(*) FROM corrupt_content_large_co; SELECT COUNT(*) FROM corrupt_content_large_co;
-- Small content, corrupt block header -- Small content, corrupt block header
create table corrupt_header_small_co(a int) with (appendonly=true, orientation=column, checksum=true); create table corrupt_header_small_co(a int) with (appendonly=true, orientation=column, checksum=true);
insert into corrupt_header_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_header_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_co'), 8)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_co'), 8));
SELECT COUNT(*) FROM corrupt_header_small_co; SELECT COUNT(*) FROM corrupt_header_small_co;
-- Small content, corrupt content -- Small content, corrupt content
create table corrupt_content_small_co(a int) with (appendonly=true, orientation=column, checksum=true); create table corrupt_content_small_co(a int) with (appendonly=true, orientation=column, checksum=true);
insert into corrupt_content_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_content_small_co values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_co'), -3)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_co'), -3));
SELECT COUNT(*) FROM corrupt_content_small_co; SELECT COUNT(*) FROM corrupt_content_small_co;
-- Row-oriented, Small content, corrupt block header -- Row-oriented, Small content, corrupt block header
create table corrupt_header_small_ao(a int) with (appendonly=true, orientation=row, checksum=true); create table corrupt_header_small_ao(a int) with (appendonly=true, orientation=row, checksum=true);
insert into corrupt_header_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_header_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_ao'), 8)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_header_small_ao'), 8));
SELECT COUNT(*) FROM corrupt_header_small_ao; SELECT COUNT(*) FROM corrupt_header_small_ao;
-- Row-oriented, Small content, corrupt content -- Row-oriented, Small content, corrupt content
create table corrupt_content_small_ao(a int) with (appendonly=true, orientation=row, checksum=true); create table corrupt_content_small_ao(a int) with (appendonly=true, orientation=row, checksum=true);
insert into corrupt_content_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null); insert into corrupt_content_small_ao values (1),(1),(1),(-1),(1),(1),(1),(2),(2),(2),(2),(2),(2),(2),(33),(3),(3),(3),(1),(8),(19),(20),(31),(32),(33),(34),(5),(5),(5),(5),(5),(6),(6),(6),(6),(6),(6),(7),(7),(7),(7),(7),(7),(7),(7), (null),(7),(7),(7),(null),(8),(8),(8),(8),(8),(8),(4),(4),(null),(4),(17),(17),(17),(null),(null),(null);
select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_ao'), -3)) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('corrupt_content_small_ao'), -3));
SELECT COUNT(*) FROM corrupt_content_small_ao; SELECT COUNT(*) FROM corrupt_content_small_ao;
...@@ -149,7 +149,7 @@ insert into appendonly_verify_block_checksums_co ...@@ -149,7 +149,7 @@ insert into appendonly_verify_block_checksums_co
select 'abcdefghijlmnopqrstuvxyz' from generate_series(1, 5); select 'abcdefghijlmnopqrstuvxyz' from generate_series(1, 5);
-- Corrupt the table by flip the 'xyz' on the last row with ### -- Corrupt the table by flip the 'xyz' on the last row with ###
select SUM(corrupt_file(get_aoseg1_path('appendonly_verify_block_checksums_co'), 'xyz', '###')) from gp_dist_random('gp_id'); select SUM(corrupt_file(get_aoseg1_path('appendonly_verify_block_checksums_co'), 'xyz', '###'));
-- Fails, checksum is wrong. -- Fails, checksum is wrong.
SELECT * FROM appendonly_verify_block_checksums_co; SELECT * FROM appendonly_verify_block_checksums_co;
......
...@@ -103,6 +103,7 @@ create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2); ...@@ -103,6 +103,7 @@ create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2);
create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2); create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2);
-- for the moment we only want to look at nestloop plans -- for the moment we only want to look at nestloop plans
set enable_nestloop = on;
set enable_hashjoin = off; set enable_hashjoin = off;
set enable_mergejoin = off; set enable_mergejoin = off;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册