@@ -839,6 +839,18 @@ func (b *indexScanRangeBuilder) buildRangeCollection(f indexFilter) (sql.MySQLRa
839839 case * iScanOr :
840840 ranges , err = b .rangeBuildOr (f , inScan )
841841 case * iScanLeaf :
842+ // TODO: special case for in set. can skip overlapping ranges since it's a series of equality checks
843+ // TODO: sequential integers can be converted to a single partition, but i guess that's harder?
844+ if f .Op () == sql .IndexScanOpInSet {
845+ bb := sql .NewMySQLIndexBuilder (b .idx )
846+ b .rangeBuildDefaultLeaf (bb , f , inScan )
847+ if _ , err := bb .Build (b .ctx ); err != nil {
848+ return nil , err
849+ }
850+ ranges = bb .Ranges (b .ctx )
851+ return ranges , nil
852+ }
853+
842854 ranges , err = b .rangeBuildLeaf (f , inScan )
843855 default :
844856 return nil , fmt .Errorf ("unknown indexFilter type: %T" , f )
@@ -1429,14 +1441,18 @@ func newLeaf(ctx *sql.Context, id indexScanId, e sql.Expression, underlying stri
14291441
14301442 if op == sql .IndexScanOpInSet || op == sql .IndexScanOpNotInSet {
14311443 tup := right .(expression.Tuple )
1432- var litSet []interface {}
1444+ litSet := make (map [any ]struct {}, len (tup ))
1445+ setVals := make ([]any , 0 , len (tup ))
14331446 var litType sql.Type
14341447 for _ , lit := range tup {
14351448 value , err := lit .Eval (ctx , nil )
14361449 if err != nil {
14371450 return nil , false
14381451 }
1439- litSet = append (litSet , value )
1452+ if _ , ok = litSet [value ]; ! ok {
1453+ litSet [value ] = struct {}{}
1454+ setVals = append (setVals , value )
1455+ }
14401456 if litType == nil {
14411457 litType = lit .Type ()
14421458 }
@@ -1445,7 +1461,7 @@ func newLeaf(ctx *sql.Context, id indexScanId, e sql.Expression, underlying stri
14451461 id : id ,
14461462 gf : gf ,
14471463 op : op ,
1448- setValues : litSet ,
1464+ setValues : setVals ,
14491465 litType : litType ,
14501466 underlying : underlying ,
14511467 }, true
0 commit comments