github.com/dolthub/go-mysql-server@v0.18.0/sql/analyzer/index_analyzer_test.go (about)

     1  // Copyright 2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package analyzer
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/dolthub/go-mysql-server/sql"
    23  	"github.com/dolthub/go-mysql-server/sql/expression"
    24  	"github.com/dolthub/go-mysql-server/sql/types"
    25  )
    26  
    27  func TestMatchingIndexes(t *testing.T) {
    28  	ctx := sql.NewEmptyContext()
    29  	const testDb = "mydb"
    30  	const testTable = "test"
    31  
    32  	v1 := expression.NewLiteral(1, types.Int64)
    33  	v2 := expression.NewLiteral(2, types.Int64)
    34  	v3 := expression.NewLiteral(3, types.Int64)
    35  
    36  	dummy1 := &dummyIdx{
    37  		id:       "dummy1",
    38  		expr:     []sql.Expression{v1},
    39  		database: testDb,
    40  		table:    testTable,
    41  	}
    42  	dummy2 := &dummyIdx{
    43  		id:       "dummy2",
    44  		expr:     []sql.Expression{v1, v2, v3},
    45  		database: testDb,
    46  		table:    testTable,
    47  	}
    48  	dummy3 := &dummyIdx{
    49  		id:       "dummy3",
    50  		expr:     []sql.Expression{v1, v2},
    51  		database: testDb,
    52  		table:    testTable,
    53  	}
    54  	dummy4 := &dummyIdx{
    55  		id:       "dummy4",
    56  		expr:     []sql.Expression{v3, v2, v1},
    57  		database: testDb,
    58  		table:    testTable,
    59  	}
    60  
    61  	ia := &indexAnalyzer{
    62  		indexesByTable: map[string][]sql.Index{testTable: {dummy1, dummy2, dummy3, dummy4}},
    63  		indexRegistry:  nil,
    64  		registryIdxes:  nil,
    65  	}
    66  
    67  	require.Equal(t, []sql.Index{dummy1, dummy2, dummy3}, ia.MatchingIndexes(ctx, testTable, testDb, v1))
    68  	require.Equal(t, []sql.Index{dummy3, dummy2}, ia.MatchingIndexes(ctx, testTable, testDb, v2, v1))
    69  	require.Equal(t, []sql.Index{dummy2, dummy4}, ia.MatchingIndexes(ctx, testTable, testDb, v3, v1))
    70  	require.Equal(t, []sql.Index{dummy2, dummy4}, ia.MatchingIndexes(ctx, testTable, testDb, v2, v3, v1))
    71  	require.Equal(t, []sql.Index{dummy4}, ia.MatchingIndexes(ctx, testTable, testDb, v3))
    72  	require.Equal(t, []sql.Index{dummy4}, ia.MatchingIndexes(ctx, testTable, testDb, v2, v3))
    73  	require.Equal(t, dummy1, ia.MatchingIndex(ctx, testTable, testDb, v1))
    74  	require.Equal(t, dummy3, ia.MatchingIndex(ctx, testTable, testDb, v2, v1))
    75  	require.Equal(t, dummy2, ia.MatchingIndex(ctx, testTable, testDb, v3, v1))
    76  	require.Equal(t, dummy2, ia.MatchingIndex(ctx, testTable, testDb, v2, v3, v1))
    77  	require.Equal(t, dummy4, ia.MatchingIndex(ctx, testTable, testDb, v3))
    78  	require.Equal(t, dummy4, ia.MatchingIndex(ctx, testTable, testDb, v2, v3))
    79  }
    80  
    81  func TestExpressionsWithIndexesPartialMatching(t *testing.T) {
    82  	const testDb = "mydb"
    83  	const testTable = "test"
    84  
    85  	v1 := expression.NewLiteral(1, types.Int64)
    86  	v2 := expression.NewLiteral(2, types.Int64)
    87  	v3 := expression.NewLiteral(3, types.Int64)
    88  	v4 := expression.NewLiteral(4, types.Int64)
    89  
    90  	gf1 := expression.NewGetField(0, types.Int64, "1", false)
    91  	gf2 := expression.NewGetField(1, types.Int64, "2", false)
    92  	//gf3 := expression.NewGetField(2, sql.Int64, "3", false)
    93  	gf4 := expression.NewGetField(3, types.Int64, "4", false)
    94  
    95  	dummy1 := &dummyIdx{
    96  		id:       "dummy",
    97  		expr:     []sql.Expression{v1, v2, v3},
    98  		database: testDb,
    99  		table:    testTable,
   100  	}
   101  	dummy2 := &dummyIdx{
   102  		id:       "dummy",
   103  		expr:     []sql.Expression{v2, v4, v1, v3},
   104  		database: testDb,
   105  		table:    testTable,
   106  	}
   107  
   108  	ia := &indexAnalyzer{
   109  		indexesByTable: map[string][]sql.Index{testTable: {dummy1}},
   110  		indexRegistry:  nil,
   111  		registryIdxes:  nil,
   112  	}
   113  	exprList := ia.ExpressionsWithIndexes(testDb, gf1, gf2)
   114  	require.Equal(t, [][]sql.Expression{{gf1, gf2}}, exprList)
   115  
   116  	ia = &indexAnalyzer{
   117  		indexesByTable: map[string][]sql.Index{testTable: {dummy1, dummy2}},
   118  		indexRegistry:  nil,
   119  		registryIdxes:  nil,
   120  	}
   121  	exprList = ia.ExpressionsWithIndexes(testDb, gf2, gf4, gf1)
   122  	require.Equal(t, [][]sql.Expression{{gf2, gf4, gf1}, {gf1, gf2}}, exprList)
   123  }
   124  
   125  type dummyIdx struct {
   126  	id       string
   127  	expr     []sql.Expression
   128  	database string
   129  	table    string
   130  }
   131  
   132  var _ sql.Index = (*dummyIdx)(nil)
   133  
   134  func (i dummyIdx) CanSupport(r ...sql.Range) bool {
   135  	return true
   136  }
   137  
   138  func (i dummyIdx) Expressions() []string {
   139  	var exprs []string
   140  	for _, e := range i.expr {
   141  		exprs = append(exprs, e.String())
   142  	}
   143  	return exprs
   144  }
   145  func (i *dummyIdx) ID() string              { return i.id }
   146  func (i *dummyIdx) Database() string        { return i.database }
   147  func (i *dummyIdx) Table() string           { return i.table }
   148  func (i *dummyIdx) IsUnique() bool          { return false }
   149  func (i *dummyIdx) IsSpatial() bool         { return false }
   150  func (i *dummyIdx) IsFullText() bool        { return false }
   151  func (i *dummyIdx) Comment() string         { return "" }
   152  func (i *dummyIdx) IsGenerated() bool       { return false }
   153  func (i *dummyIdx) IndexType() string       { return "BTREE" }
   154  func (i *dummyIdx) PrefixLengths() []uint16 { return nil }
   155  
   156  func (i *dummyIdx) NewLookup(*sql.Context, ...sql.Range) (sql.IndexLookup, error) {
   157  	panic("not implemented")
   158  }
   159  func (i *dummyIdx) ColumnExpressionTypes() []sql.ColumnExpressionType {
   160  	panic("not implemented")
   161  }