Skip to content

Commit

Permalink
[#21266] YSQL: Make BNL hashtable have its own Expression Context
Browse files Browse the repository at this point in the history
Summary:
Before this change, the BNL hashtable used the per-tuple expression context in the execution state to compute its equality expressions. This would yield issues like in queries like the one in the added test case. In such queries where the hashtable's equality expression is a subplan that might also use the same execution state's expression context, the expression execution would overwrite any data that the hashtable code had written into its expression context. This problem would most obviously happen in cases where the underlying subplan expression also ended up using a BNL hashtable that used the same inherited expression context.
This diff makes the hashtable BNL have its own expression context that's created using `CreateExprContext` just like `nodeHash.c` or `nodeMergejoin.c` might.

Needs backports to 2024.1, 2.20, 2.18
Jira: DB-10184

Test Plan: ./yb_build.sh --java-test 'org.yb.pgsql.TestPgRegressJoin'

Reviewers: mtakahara

Reviewed By: mtakahara

Subscribers: yql

Differential Revision: https://phorge.dev.yugabyte.com/D34889
  • Loading branch information
tanujnay112 committed May 10, 2024
1 parent cfab020 commit dae8cd5
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/postgres/src/backend/executor/nodeYbBatchedNestloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ InitHash(YbBatchedNestLoopState *bnlstate)
{
EState *estate = bnlstate->js.ps.state;
YbBatchedNestLoop *plan = (YbBatchedNestLoop*) bnlstate->js.ps.plan;
ExprContext *econtext = GetPerTupleExprContext(estate);
ExprContext *econtext = CreateExprContext(estate);
TupleDesc outer_tdesc = outerPlanState(bnlstate)->ps_ResultTupleDesc;

Assert(UseHash(plan, bnlstate));
Expand Down
61 changes: 61 additions & 0 deletions src/postgres/src/test/regress/expected/yb_join_batching.out
Original file line number Diff line number Diff line change
Expand Up @@ -2266,6 +2266,67 @@ WHERE ss1.a = ss3.a and ss3.c <= (SELECT a FROM ss3 where a < ss2.a + ss1.a limi
DROP TABLE ss1;
DROP TABLE ss2;
DROP TABLE ss3;
CREATE TABLE other(a int);
CREATE INDEX ON other(a asc);
CREATE TABLE ss1(a int);
CREATE TABLE ss2(a int, b int);
CREATE INDEX ON ss2(a asc, b asc);
INSERT INTO ss1 VALUES (0), (0);
INSERT INTO ss2 VALUES (0, 0), (0, 0);
INSERT INTO other VALUES (1), (1);
/*+Set(enable_hashjoin OFF) Set(enable_mergejoin OFF) Set(enable_material OFF) */EXPLAIN (COSTS OFF)
SELECT *
FROM (
SELECT ss1.a as a, other.a as othera
FROM ss1
CROSS JOIN other
) AS cross_join
LEFT OUTER JOIN ss2 ON ss2.a = (
SELECT other.a
FROM other, ss1
WHERE other.a = ss1.a + cross_join.a limit 1
);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Nested Loop
-> YB Batched Nested Loop Left Join
Join Filter: (ss2.a = (SubPlan 1))
-> Seq Scan on ss1
-> Index Only Scan using ss2_a_b_idx on ss2
Index Cond: (a = ANY (ARRAY[(SubPlan 1), (SubPlan 1), (SubPlan 1)]))
SubPlan 1
-> Limit
-> YB Batched Nested Loop Join
Join Filter: (other_1.a = (ss1_1.a + ss1.a))
-> Seq Scan on ss1 ss1_1
-> Index Only Scan using other_a_idx on other other_1
Index Cond: (a = ANY (ARRAY[(ss1_1.a + ss1.a), ($2 + ss1.a), ($3 + ss1.a)]))
-> Index Only Scan using other_a_idx on other
(14 rows)

/*+Set(enable_hashjoin OFF) Set(enable_mergejoin OFF) Set(enable_material OFF) */
SELECT *
FROM (
SELECT ss1.a as a, other.a as othera
FROM ss1
CROSS JOIN other
) AS cross_join
LEFT OUTER JOIN ss2 ON ss2.a = (
SELECT other.a
FROM other, ss1
WHERE other.a = ss1.a + cross_join.a limit 1
);
a | othera | a | b
---+--------+---+---
0 | 1 | |
0 | 1 | |
0 | 1 | |
0 | 1 | |
(4 rows)

DROP TABLE other;
DROP TABLE ss1;
DROP TABLE ss2;
--
--
-- Inner joins (equi-joins)
Expand Down
40 changes: 40 additions & 0 deletions src/postgres/src/test/regress/sql/yb_join_batching.sql
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,46 @@ DROP TABLE ss1;
DROP TABLE ss2;
DROP TABLE ss3;

CREATE TABLE other(a int);
CREATE INDEX ON other(a asc);
CREATE TABLE ss1(a int);
CREATE TABLE ss2(a int, b int);
CREATE INDEX ON ss2(a asc, b asc);

INSERT INTO ss1 VALUES (0), (0);
INSERT INTO ss2 VALUES (0, 0), (0, 0);
INSERT INTO other VALUES (1), (1);

/*+Set(enable_hashjoin OFF) Set(enable_mergejoin OFF) Set(enable_material OFF) */EXPLAIN (COSTS OFF)
SELECT *
FROM (
SELECT ss1.a as a, other.a as othera
FROM ss1
CROSS JOIN other
) AS cross_join
LEFT OUTER JOIN ss2 ON ss2.a = (
SELECT other.a
FROM other, ss1
WHERE other.a = ss1.a + cross_join.a limit 1
);

/*+Set(enable_hashjoin OFF) Set(enable_mergejoin OFF) Set(enable_material OFF) */
SELECT *
FROM (
SELECT ss1.a as a, other.a as othera
FROM ss1
CROSS JOIN other
) AS cross_join
LEFT OUTER JOIN ss2 ON ss2.a = (
SELECT other.a
FROM other, ss1
WHERE other.a = ss1.a + cross_join.a limit 1
);

DROP TABLE other;
DROP TABLE ss1;
DROP TABLE ss2;

--
--
-- Inner joins (equi-joins)
Expand Down

0 comments on commit dae8cd5

Please sign in to comment.