Skip to content

Commit 0c4e082

Browse files
committed
Don't use non-unique indexes as functional dependencies in AND expressions.
1 parent a98abd7 commit 0c4e082

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

enginetest/server_engine_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,45 @@ 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+
if err := rows.Scan(&c0, &c1, &pk); err != nil {
288+
return false, err
289+
}
290+
if rowNum >= len(expectedRows) {
291+
return false, nil
292+
}
293+
if c0 != expectedRows[rowNum].([]uint64)[0] {
294+
return false, nil
295+
}
296+
if c1 != expectedRows[rowNum].([]uint64)[1] {
297+
return false, nil
298+
}
299+
if pk != expectedRows[rowNum].([]uint64)[2] {
300+
return false, nil
301+
}
302+
rowNum++
303+
}
304+
return true, nil
305+
},
306+
},
307+
},
308+
},
270309
}
271310

272311
port, perr := findEmptyPort()
@@ -315,6 +354,8 @@ func TestServerPreparedStatements(t *testing.T) {
315354
if assertion.expectErr {
316355
require.Error(t, err)
317356
return
357+
} else {
358+
require.NoError(t, err)
318359
}
319360
ok, err := assertion.checkRows(rows, assertion.expectedRows)
320361
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)