Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions enginetest/queries/script_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,26 @@ type ScriptTestAssertion struct {
// Unlike other engine tests, ScriptTests must be self-contained. No other tables are created outside the definition of
// the tests.
var ScriptTests = []ScriptTest{
{
// https://github.com/dolthub/dolt/issues/9797
Name: "EXISTS subquery returns duplicate rows with PRIMARY KEY",
SetUpScript: []string{
"CREATE TABLE t(c0 INT, c1 INT, PRIMARY KEY(c0, c1));",
"INSERT INTO t VALUES (1, 1);",
"INSERT INTO t VALUES (2, 2);",
"INSERT INTO t VALUES (2, 3);",
},
Assertions: []ScriptTestAssertion{
{
Query: "SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t AS x WHERE x.c0 = t.c0);",
Expected: []sql.Row{
{1, 1},
{2, 2},
{2, 3},
},
},
},
},
{
// https://github.com/dolthub/dolt/issues/9794
Name: "UPDATE with TRIM function on TEXT column",
Expand Down
4 changes: 2 additions & 2 deletions sql/analyzer/indexed_joins.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,9 @@ func convertSemiToInnerJoin(m *memo.Memo) error {
}

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

// project belongs to the original group
leftCols := semi.Left.RelProps.OutputCols()
Expand Down
2 changes: 1 addition & 1 deletion sql/plan/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (i JoinType) IsPartial() bool {
switch i {
case JoinTypeSemi, JoinTypeAnti, JoinTypeAntiIncludeNulls, JoinTypeSemiHash,
JoinTypeAntiHash, JoinTypeAntiHashIncludeNulls, JoinTypeAntiLookup, JoinTypeAntiLookupIncludeNulls,
JoinTypeSemiLookup:
JoinTypeSemiLookup, JoinTypeSemiMerge, JoinTypeAntiMerge, JoinTypeAntiMergeIncludeNulls:
return true
default:
return false
Expand Down
1 change: 1 addition & 0 deletions sql/plan/subquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ func (s *Subquery) HashMultiple(ctx *sql.Context, row sql.Row) (sql.KeyValueCach

// HasResultRow returns whether the subquery has a result set > 0.
func (s *Subquery) HasResultRow(ctx *sql.Context, row sql.Row) (bool, error) {

// First check if the query was cached.
s.cacheMu.Lock()
cached := s.resultsCached
Expand Down
4 changes: 4 additions & 0 deletions sql/rowexec/join_iters.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ func (i *existsIter) Next(ctx *sql.Context) (sql.Row, error) {
nextState = esIncRight
}
case esRet:
if i.typ.IsSemi() {
// For semi-joins, after returning a match, move to next left row
nextState = esIncLeft
}
return i.removeParentRow(i.primaryRow.Copy()), nil
default:
return nil, fmt.Errorf("invalid exists join state")
Expand Down
Loading