Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opt: fix incorrect results from zigzag join with different index directions #97151

Merged
merged 1 commit into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/zigzag_join
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,21 @@ CREATE TABLE t71271(a INT, b INT, c INT, d INT, INDEX (c), INDEX (d))

statement ok
SELECT d FROM t71271 WHERE c = 3 AND d = 4

# Regression test for #97090. We should not plan a zigzag join when the
# direction of the equality columns doesn't match.
statement ok
CREATE TABLE t97090 (
c INT NOT NULL,
l INT NOT NULL,
r INT NOT NULL,
INDEX (l ASC, c DESC),
INDEX (r ASC, c ASC)
);
INSERT INTO t97090 VALUES (1, 1, -1), (2, 1, -2)

# This query should return one row.
query III
SELECT * FROM t97090 WHERE l = 1 AND r = -1
----
1 1 -1
14 changes: 14 additions & 0 deletions pkg/sql/opt/exec/execbuilder/testdata/zigzag_join
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,17 @@ vectorized: true
right table: t71271@t71271_d_idx
right columns: (d, rowid)
right fixed values: 1 column

# Regression test for #97090. We should not plan a zigzag join when the
# direction of the equality columns doesn't match.
statement ok
CREATE TABLE t97090 (
c INT NOT NULL,
l INT NOT NULL,
r INT NOT NULL,
INDEX (l ASC, c DESC),
INDEX (r ASC, c ASC)
)

statement error could not produce a query plan conforming to the FORCE_ZIGZAG hint
EXPLAIN SELECT * FROM t97090@{FORCE_ZIGZAG} WHERE l = 1 AND r = -1
6 changes: 6 additions & 0 deletions pkg/sql/opt/xform/select_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,12 @@ func eqColsForZigzag(
}

for i < leftCnt && j < rightCnt {
// The zigzag joiner cannot handle equality columns that are not in the
// same direction. See #97090.
if leftIndex.Column(i).Descending != rightIndex.Column(j).Descending {
break
}

leftColID := tabID.IndexColumnID(leftIndex, i)
rightColID := tabID.IndexColumnID(rightIndex, j)
i++
Expand Down
29 changes: 29 additions & 0 deletions pkg/sql/opt/xform/testdata/rules/select
Original file line number Diff line number Diff line change
Expand Up @@ -6223,6 +6223,35 @@ inner-join (zigzag pqr@q pqr@s)
├── r:3 = 1 [outer=(3), constraints=(/3: [/1 - /1]; tight), fd=()-->(3)]
└── s:4 = 'foo' [outer=(4), constraints=(/4: [/'foo' - /'foo']; tight), fd=()-->(4)]

# Regression test for #97090. We should not plan a zigzag join when the
# direction of the equality columns doesn't match.
exec-ddl
CREATE TABLE t97090 (
c INT NOT NULL,
l INT NOT NULL,
r INT NOT NULL,
INDEX (l ASC, c DESC),
INDEX (r ASC, c ASC)
)
----

opt expect-not=GenerateZigzagJoins
SELECT * FROM t97090 WHERE l = 1 AND r = -1
----
select
├── columns: c:1!null l:2!null r:3!null
├── fd: ()-->(2,3)
├── index-join t97090
│ ├── columns: c:1!null l:2!null r:3!null
│ ├── fd: ()-->(2)
│ └── scan t97090@t97090_l_c_idx
│ ├── columns: c:1!null l:2!null rowid:4!null
│ ├── constraint: /2/-1/4: [/1 - /1]
│ ├── key: (4)
│ └── fd: ()-->(2), (4)-->(1)
└── filters
└── r:3 = -1 [outer=(3), constraints=(/3: [/-1 - /-1]; tight), fd=()-->(3)]

# Zigzag join should not be produced when there is a NO_ZIGZAG_JOIN hint.
opt expect-not=GenerateZigzagJoins
SELECT q,r FROM pqr@{NO_ZIGZAG_JOIN} WHERE q = 1 AND r = 2
Expand Down