summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2013-07-08 02:37:24 +0000
committerTom Lane2013-07-08 02:37:24 +0000
commit5372275b4b5fc183c6c6dd4517cfd74d5b641446 (patch)
tree4e4927c2dc340e6206364bfc62b71eab93d913f0 /src/test
parent9b2543a4018c7f746bdb8d379c4ebc89c7d5f831 (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.out34
-rw-r--r--src/test/regress/sql/union.sql21
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);