Skip to content

Commit 09d646b

Browse files
authored
[rowexec] full outer join rightIter exhaust (#2814)
1 parent b01a7c6 commit 09d646b

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

enginetest/queries/script_queries.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,35 @@ type ScriptTestAssertion struct {
114114
// Unlike other engine tests, ScriptTests must be self-contained. No other tables are created outside the definition of
115115
// the tests.
116116
var ScriptTests = []ScriptTest{
117+
{
118+
Name: "outer join finish unmatched right side",
119+
SetUpScript: []string{
120+
`
121+
CREATE TABLE teams (
122+
team VARCHAR(100),
123+
namespace VARCHAR(100)
124+
);`,
125+
"INSERT INTO teams(team, namespace) VALUES ('sam', 'sam1');",
126+
"INSERT INTO teams(team, namespace) VALUES ('sam', 'sam2');",
127+
"INSERT INTO teams(team, namespace) VALUES ('janos', 'janos1');",
128+
`CREATE TABLE traces (
129+
namespace VARCHAR(100),
130+
value INT
131+
);`,
132+
"INSERT INTO traces(namespace, value) VALUES ('janos1', '400');",
133+
"INSERT INTO traces(namespace, value) VALUES ('0', '500');",
134+
},
135+
Assertions: []ScriptTestAssertion{
136+
{
137+
Query: "SELECT team, sum(value) FROM traces FULL OUTER JOIN teams ON teams.namespace = traces.namespace GROUP BY team;",
138+
Expected: []sql.Row{{"sam", nil}, {"janos", float64(400)}, {nil, float64(500)}},
139+
},
140+
{
141+
Query: "SELECT team, sum(value) FROM teams FULL OUTER JOIN traces ON teams.namespace = traces.namespace GROUP BY team;",
142+
Expected: []sql.Row{{"sam", nil}, {"janos", float64(400)}, {nil, float64(500)}},
143+
},
144+
},
145+
},
117146
{
118147
Name: "keyless reverse index",
119148
SetUpScript: []string{

sql/rowexec/join_iters.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ func newFullJoinIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode,
404404
rowSize: len(row) + len(j.Left().Schema()) + len(j.Right().Schema()),
405405
seenLeft: make(map[uint64]struct{}),
406406
seenRight: make(map[uint64]struct{}),
407+
leftLen: len(j.Left().Schema()),
408+
rightLen: len(j.Right().Schema()),
407409
b: b,
408410
}, nil
409411
}
@@ -422,6 +424,8 @@ type fullJoinIter struct {
422424
leftRow sql.Row
423425
scopeLen int
424426
rowSize int
427+
leftLen int
428+
rightLen int
425429

426430
leftDone bool
427431
seenLeft map[uint64]struct{}
@@ -439,6 +443,7 @@ func (i *fullJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
439443
i.leftDone = true
440444
i.l = nil
441445
i.r = nil
446+
continue
442447
}
443448
if err != nil {
444449
return nil, err
@@ -463,7 +468,7 @@ func (i *fullJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
463468
}
464469
if _, ok := i.seenLeft[key]; !ok {
465470
// (left, null) only if we haven't matched left
466-
ret := i.buildRow(i.leftRow, nil)
471+
ret := i.buildRow(i.leftRow, make(sql.Row, i.rightLen))
467472
i.r = nil
468473
i.leftRow = nil
469474
return i.removeParentRow(ret), nil
@@ -520,7 +525,7 @@ func (i *fullJoinIter) Next(ctx *sql.Context) (sql.Row, error) {
520525
continue
521526
}
522527
// (null, right) only if we haven't matched right
523-
ret := i.buildRow(nil, rightRow)
528+
ret := i.buildRow(make(sql.Row, i.leftLen), rightRow)
524529
return i.removeParentRow(ret), nil
525530
}
526531
}

0 commit comments

Comments
 (0)