Skip to content

Commit 9bacd9b

Browse files
committed
add fix dup row
1 parent e787e8e commit 9bacd9b

File tree

8 files changed

+32
-6
lines changed

8 files changed

+32
-6
lines changed

enginetest/queries/script_queries.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,26 @@ type ScriptTestAssertion struct {
120120
// Unlike other engine tests, ScriptTests must be self-contained. No other tables are created outside the definition of
121121
// the tests.
122122
var ScriptTests = []ScriptTest{
123+
{
124+
// https://github.com/dolthub/dolt/issues/9797
125+
Name: "EXISTS subquery returns duplicate rows with PRIMARY KEY",
126+
SetUpScript: []string{
127+
"CREATE TABLE t(c0 INT, c1 INT, PRIMARY KEY(c0, c1));",
128+
"INSERT INTO t VALUES (1, 1);",
129+
"INSERT INTO t VALUES (2, 2);",
130+
"INSERT INTO t VALUES (2, 3);",
131+
},
132+
Assertions: []ScriptTestAssertion{
133+
{
134+
Query: "SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t AS x WHERE x.c0 = t.c0);",
135+
Expected: []sql.Row{
136+
{1, 1},
137+
{2, 2},
138+
{2, 3},
139+
},
140+
},
141+
},
142+
},
123143
{
124144
// https://github.com/dolthub/dolt/issues/9794
125145
Name: "UPDATE with TRIM function on TEXT column",

sql/analyzer/indexed_joins.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,9 @@ func convertSemiToInnerJoin(m *memo.Memo) error {
472472
}
473473

474474
// join and its commute are a new group
475-
joinGrp := m.MemoizeInnerJoin(nil, semi.Left, rightGrp, plan.JoinTypeInner, semi.Filter)
475+
joinGrp := m.MemoizeInnerJoin(nil, semi.Left, rightGrp, plan.JoinTypeSemi, semi.Filter)
476476
// TODO: can't commute if right SubqueryAlias references outside scope (OuterScopeVisibility/IsLateral)
477-
m.MemoizeInnerJoin(joinGrp, rightGrp, semi.Left, plan.JoinTypeInner, semi.Filter)
477+
m.MemoizeInnerJoin(joinGrp, rightGrp, semi.Left, plan.JoinTypeSemi, semi.Filter)
478478

479479
// project belongs to the original group
480480
leftCols := semi.Left.RelProps.OutputCols()
@@ -1105,7 +1105,7 @@ func addMergeJoins(ctx *sql.Context, m *memo.Memo) error {
11051105
}
11061106
if rightIndexMatchesFilters(rIndex, join.Left.RelProps.FuncDeps().Constants(), matchedEqFilters) {
11071107
jb := join.Copy()
1108-
if d, ok := jb.Left.First.(*memo.Distinct); ok && lIndex.SqlIdx().IsUnique() {
1108+
if d, ok := jb.Left.First.(*memo.Distinct); ok && lIndex.SqlIdx().IsUnique() {
11091109
jb.Left = d.Child
11101110
}
11111111
if d, ok := jb.Right.First.(*memo.Distinct); ok && rIndex.SqlIdx().IsUnique() {

sql/analyzer/unnest_exists_subqueries.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ func unnestExistSubqueries(ctx *sql.Context, scope *plan.Scope, a *Analyzer, fil
151151
retFilters = append(retFilters, f)
152152
continue
153153
}
154+
154155

155156
// recurse
156157
if s.inner != nil {

sql/plan/join.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (i JoinType) IsPartial() bool {
177177
switch i {
178178
case JoinTypeSemi, JoinTypeAnti, JoinTypeAntiIncludeNulls, JoinTypeSemiHash,
179179
JoinTypeAntiHash, JoinTypeAntiHashIncludeNulls, JoinTypeAntiLookup, JoinTypeAntiLookupIncludeNulls,
180-
JoinTypeSemiLookup:
180+
JoinTypeSemiLookup, JoinTypeSemiMerge, JoinTypeAntiMerge, JoinTypeAntiMergeIncludeNulls:
181181
return true
182182
default:
183183
return false

sql/plan/subquery.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"fmt"
1919
"io"
2020
"sync"
21-
2221
"github.com/dolthub/go-mysql-server/sql"
2322
"github.com/dolthub/go-mysql-server/sql/hash"
2423
"github.com/dolthub/go-mysql-server/sql/transform"
@@ -431,6 +430,7 @@ func (s *Subquery) HashMultiple(ctx *sql.Context, row sql.Row) (sql.KeyValueCach
431430

432431
// HasResultRow returns whether the subquery has a result set > 0.
433432
func (s *Subquery) HasResultRow(ctx *sql.Context, row sql.Row) (bool, error) {
433+
434434
// First check if the query was cached.
435435
s.cacheMu.Lock()
436436
cached := s.resultsCached

sql/rowexec/join_iters.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ func (i *existsIter) Next(ctx *sql.Context) (sql.Row, error) {
367367
nextState = esIncRight
368368
}
369369
case esRet:
370+
if i.typ.IsSemi() {
371+
// For semi-joins, after returning a match, move to next left row
372+
nextState = esIncLeft
373+
}
370374
return i.removeParentRow(i.primaryRow.Copy()), nil
371375
default:
372376
return nil, fmt.Errorf("invalid exists join state")

sql/rowexec/merge_join.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,4 @@ func (i *mergeJoinIter) Close(ctx *sql.Context) (err error) {
588588

589589
return err
590590
}
591+

sql/rowexec/rel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ func (b *BaseBuilder) buildJoinNode(ctx *sql.Context, n *plan.JoinNode, row sql.
282282
case n.Op.IsRange():
283283
return newRangeHeapJoinIter(ctx, b, n, row)
284284
default:
285-
return newJoinIter(ctx, b, n, row)
285+
return newJoinIter(ctx, b, n, row)
286286
}
287287
}
288288

0 commit comments

Comments
 (0)