diff options
| author | Tom Lane | 2013-07-08 02:37:24 +0000 |
|---|---|---|
| committer | Tom Lane | 2013-07-08 02:37:24 +0000 |
| commit | 5372275b4b5fc183c6c6dd4517cfd74d5b641446 (patch) | |
| tree | 4e4927c2dc340e6206364bfc62b71eab93d913f0 /src/test | |
| parent | 9b2543a4018c7f746bdb8d379c4ebc89c7d5f831 (diff) | |
Fix planning of parameterized appendrel paths with expensive join quals.
The code in set_append_rel_pathlist() for building parameterized paths
for append relations (inheritance and UNION ALL combinations) supposed
that the cheapest regular path for a child relation would still be cheapest
when reparameterized. Which might not be the case, particularly if the
added join conditions are expensive to compute, as in a recent example from
Jeff Janes. Fix it to compare child path costs *after* reparameterizing.
We can short-circuit that if the cheapest pre-existing path is already
parameterized correctly, which seems likely to be true often enough to be
worth checking for.
Back-patch to 9.2 where parameterized paths were introduced.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/union.out | 34 | ||||
| -rw-r--r-- | src/test/regress/sql/union.sql | 21 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/test/regress/expected/union.out b/src/test/regress/expected/union.out index 435f50d050d..bf8f1bcaf77 100644 --- a/src/test/regress/expected/union.out +++ b/src/test/regress/expected/union.out @@ -603,3 +603,37 @@ WHERE x > 3; 2 | 4 (1 row) +-- Test proper handling of parameterized appendrel paths when the +-- potential join qual is expensive +create function expensivefunc(int) returns int +language plpgsql immutable strict cost 10000 +as $$begin return $1; end$$; +create temp table t3 as select generate_series(-1000,1000) as x; +create index t3i on t3 (expensivefunc(x)); +analyze t3; +explain (costs off) +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x); + QUERY PLAN +------------------------------------------------------------ + Nested Loop + -> Seq Scan on int4_tbl + -> Append + -> Index Scan using t3i on t3 a + Index Cond: (expensivefunc(x) = int4_tbl.f1) + -> Index Scan using t3i on t3 b + Index Cond: (expensivefunc(x) = int4_tbl.f1) +(7 rows) + +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x); + x | f1 +---+---- + 0 | 0 + 0 | 0 +(2 rows) + +drop table t3; +drop function expensivefunc(int); diff --git a/src/test/regress/sql/union.sql b/src/test/regress/sql/union.sql index f3c9d113827..6194ce47511 100644 --- a/src/test/regress/sql/union.sql +++ b/src/test/regress/sql/union.sql @@ -249,3 +249,24 @@ SELECT * FROM UNION SELECT 2 AS t, 4 AS x) ss WHERE x > 3; + +-- Test proper handling of parameterized appendrel paths when the +-- potential join qual is expensive +create function expensivefunc(int) returns int +language plpgsql immutable strict cost 10000 +as $$begin return $1; end$$; + +create temp table t3 as select generate_series(-1000,1000) as x; +create index t3i on t3 (expensivefunc(x)); +analyze t3; + +explain (costs off) +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x); +select * from + (select * from t3 a union all select * from t3 b) ss + join int4_tbl on f1 = expensivefunc(x); + +drop table t3; +drop function expensivefunc(int); |
