summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorDavid Rowley2024-10-17 01:25:08 +0000
committerDavid Rowley2024-10-17 01:25:08 +0000
commit9ca67658d19e6c258eb4021a326ed7d38b3ab75f (patch)
tree8034b0b5bfb372ebdf68970faa90c052bfa050bc /src/test
parent089aac631b5ba53be0ecf8ea2e8d81388d69629c (diff)
Don't store intermediate hash values in ExprState->resvalue
adf97c156 made it so ExprStates could support hashing and changed Hash Join to use that instead of manually extracting Datums from tuples and hashing them one column at a time. When hashing multiple columns or expressions, the code added in that commit stored the intermediate hash value in the ExprState's resvalue field. That was a mistake as steps may be injected into the ExprState between each hashing step that look at or overwrite the stored intermediate hash value. EEOP_PARAM_SET is an example of such a step. Here we fix this by adding a new dedicated field for storing intermediate hash values and adjust the code so that all apart from the final hashing step store their result in the intermediate field. In passing, rename a variable so that it's more aligned to the surrounding code and also so a few lines stay within the 80 char margin. Reported-by: Andres Freund Reviewed-by: Alena Rybakina <a.rybakina@postgrespro.ru> Discussion: https://postgr.es/m/CAApHDvqo9eenEFXND5zZ9JxO_k4eTA4jKMGxSyjdTrsmYvnmZw@mail.gmail.com
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/join.out55
-rw-r--r--src/test/regress/sql/join.sql21
2 files changed, 76 insertions, 0 deletions
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 756c2e24965..5669ed929a7 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -2359,6 +2359,61 @@ where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous;
(0 rows)
--
+-- Test hash joins with multiple hash keys and subplans.
+--
+-- First ensure we get a hash join with multiple hash keys.
+explain (costs off)
+select t1.unique1,t2.unique1 from tenk1 t1
+inner join tenk1 t2 on t1.two = t2.two
+ and t1.unique1 = (select min(unique1) from tenk1
+ where t2.unique1=unique1)
+where t1.unique1 < 10 and t2.unique1 < 10
+order by t1.unique1;
+ QUERY PLAN
+----------------------------------------------------------------------------------------------------
+ Sort
+ Sort Key: t1.unique1
+ -> Hash Join
+ Hash Cond: ((t1.two = t2.two) AND (t1.unique1 = (SubPlan 2)))
+ -> Bitmap Heap Scan on tenk1 t1
+ Recheck Cond: (unique1 < 10)
+ -> Bitmap Index Scan on tenk1_unique1
+ Index Cond: (unique1 < 10)
+ -> Hash
+ -> Bitmap Heap Scan on tenk1 t2
+ Recheck Cond: (unique1 < 10)
+ -> Bitmap Index Scan on tenk1_unique1
+ Index Cond: (unique1 < 10)
+ SubPlan 2
+ -> Result
+ InitPlan 1
+ -> Limit
+ -> Index Only Scan using tenk1_unique1 on tenk1
+ Index Cond: ((unique1 IS NOT NULL) AND (unique1 = t2.unique1))
+(19 rows)
+
+-- Ensure we get the expected result
+select t1.unique1,t2.unique1 from tenk1 t1
+inner join tenk1 t2 on t1.two = t2.two
+ and t1.unique1 = (select min(unique1) from tenk1
+ where t2.unique1=unique1)
+where t1.unique1 < 10 and t2.unique1 < 10
+order by t1.unique1;
+ unique1 | unique1
+---------+---------
+ 0 | 0
+ 1 | 1
+ 2 | 2
+ 3 | 3
+ 4 | 4
+ 5 | 5
+ 6 | 6
+ 7 | 7
+ 8 | 8
+ 9 | 9
+(10 rows)
+
+--
-- checks for correct handling of quals in multiway outer joins
--
explain (costs off)
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index 0c65e5af4be..73474bb64f5 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -442,6 +442,27 @@ select a.f1, b.f1, t.thousand, t.tenthous from
where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous;
--
+-- Test hash joins with multiple hash keys and subplans.
+--
+
+-- First ensure we get a hash join with multiple hash keys.
+explain (costs off)
+select t1.unique1,t2.unique1 from tenk1 t1
+inner join tenk1 t2 on t1.two = t2.two
+ and t1.unique1 = (select min(unique1) from tenk1
+ where t2.unique1=unique1)
+where t1.unique1 < 10 and t2.unique1 < 10
+order by t1.unique1;
+
+-- Ensure we get the expected result
+select t1.unique1,t2.unique1 from tenk1 t1
+inner join tenk1 t2 on t1.two = t2.two
+ and t1.unique1 = (select min(unique1) from tenk1
+ where t2.unique1=unique1)
+where t1.unique1 < 10 and t2.unique1 < 10
+order by t1.unique1;
+
+--
-- checks for correct handling of quals in multiway outer joins
--
explain (costs off)