Skip to content

Commit 7784677

Browse files
authored
Merge pull request #2868 from dolthub/nicktobey/max1row
Don't use non-unique indexes as functional dependencies in AND expressions.
2 parents a98abd7 + 42da97e commit 7784677

File tree

3 files changed

+85
-25
lines changed

3 files changed

+85
-25
lines changed

enginetest/queries/query_plans.go

Lines changed: 31 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enginetest/server_engine_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,51 @@ func TestServerPreparedStatements(t *testing.T) {
267267
},
268268
},
269269
},
270+
{
271+
name: "regression test for incorrectly setting QFlagMax1Row flag",
272+
setup: []string{
273+
"create table test(c0 int not null, c1 int not null, pk int primary key, key (c0, c1));",
274+
"insert into test values (2, 3, 1), (5, 6, 4), (2, 3, 7);",
275+
},
276+
assertions: []serverScriptTestAssertion{
277+
{
278+
query: "select * from test where c0 = 2 and c1 = 3;",
279+
expectedRows: []any{
280+
[]uint64{uint64(2), uint64(3), uint64(1)},
281+
[]uint64{uint64(2), uint64(3), uint64(7)},
282+
},
283+
checkRows: func(rows *gosql.Rows, expectedRows []any) (bool, error) {
284+
var c0, c1, pk uint64
285+
var rowNum int
286+
for rows.Next() {
287+
err := rows.Scan(&c0, &c1, &pk)
288+
require.NoError(t, err)
289+
if err != nil {
290+
return false, err
291+
}
292+
require.Less(t, rowNum, len(expectedRows))
293+
if rowNum >= len(expectedRows) {
294+
return false, nil
295+
}
296+
require.Equal(t, c0, expectedRows[rowNum].([]uint64)[0])
297+
if c0 != expectedRows[rowNum].([]uint64)[0] {
298+
return false, nil
299+
}
300+
require.Equal(t, c1, expectedRows[rowNum].([]uint64)[1])
301+
if c1 != expectedRows[rowNum].([]uint64)[1] {
302+
return false, nil
303+
}
304+
require.Equal(t, pk, expectedRows[rowNum].([]uint64)[2])
305+
if pk != expectedRows[rowNum].([]uint64)[2] {
306+
return false, nil
307+
}
308+
rowNum++
309+
}
310+
return true, nil
311+
},
312+
},
313+
},
314+
},
270315
}
271316

272317
port, perr := findEmptyPort()
@@ -315,6 +360,8 @@ func TestServerPreparedStatements(t *testing.T) {
315360
if assertion.expectErr {
316361
require.Error(t, err)
317362
return
363+
} else {
364+
require.NoError(t, err)
318365
}
319366
ok, err := assertion.checkRows(rows, assertion.expectedRows)
320367
require.NoError(t, err)

sql/analyzer/costed_index_scan.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,12 +1227,17 @@ func (c *indexCoster) costIndexScanAnd(filter *iScanAnd, s sql.Statistic, bucket
12271227
}
12281228
}
12291229

1230+
var conjFDs *sql.FuncDepSet
1231+
if idx.IsUnique() {
1232+
conjFDs = conj.getFds()
1233+
}
1234+
12301235
if exact.Len()+conj.applied.Len() == filter.childCnt() {
12311236
// matched all filters
1232-
return conj.hist, conj.getFds(), sql.NewFastIntSet(int(filter.id)), conj.missingPrefix, nil
1237+
return conj.hist, conjFDs, sql.NewFastIntSet(int(filter.id)), conj.missingPrefix, nil
12331238
}
12341239

1235-
return conj.hist, conj.getFds(), exact.Union(conj.applied), conj.missingPrefix, nil
1240+
return conj.hist, conjFDs, exact.Union(conj.applied), conj.missingPrefix, nil
12361241
}
12371242

12381243
func (c *indexCoster) costIndexScanOr(filter *iScanOr, s sql.Statistic, buckets []sql.HistogramBucket, ordinals map[string]int, idx sql.Index) ([]sql.HistogramBucket, *sql.FuncDepSet, bool, error) {

0 commit comments

Comments
 (0)