github.com/dolthub/go-mysql-server@v0.18.0/sql/rowexec/existssubquery_test.go (about) 1 // Copyright 2020-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 rowexec 16 17 import ( 18 "testing" 19 20 "github.com/stretchr/testify/require" 21 22 "github.com/dolthub/go-mysql-server/memory" 23 "github.com/dolthub/go-mysql-server/sql" 24 "github.com/dolthub/go-mysql-server/sql/expression" 25 "github.com/dolthub/go-mysql-server/sql/plan" 26 "github.com/dolthub/go-mysql-server/sql/types" 27 ) 28 29 func TestExistsSubquery(t *testing.T) { 30 db := memory.NewDatabase("test") 31 pro := memory.NewDBProvider(db) 32 ctx := newContext(pro) 33 34 table := memory.NewTable(db.BaseDatabase, "foo", sql.NewPrimaryKeySchema(sql.Schema{ 35 {Name: "t", Source: "foo", Type: types.Text}, 36 }), nil) 37 38 require.NoError(t, table.Insert(ctx, sql.Row{"one"})) 39 require.NoError(t, table.Insert(ctx, sql.Row{"two"})) 40 require.NoError(t, table.Insert(ctx, sql.Row{"three"})) 41 42 emptyTable := memory.NewTable(db.BaseDatabase, "empty", sql.NewPrimaryKeySchema(sql.Schema{ 43 {Name: "t", Source: "empty", Type: types.Int64}, 44 }), nil) 45 46 project := func(expr sql.Expression, tbl *memory.Table) sql.Node { 47 return plan.NewProject([]sql.Expression{ 48 expr, 49 }, plan.NewResolvedTable(tbl, nil, nil)) 50 } 51 52 testCases := []struct { 53 name string 54 subquery sql.Node 55 row sql.Row 56 result interface{} 57 }{ 58 { 59 "Null returns as true", 60 project( 61 expression.NewGetField(1, types.Text, "foo", false), table, 62 ), 63 sql.NewRow(nil), 64 true, 65 }, 66 { 67 "Non NULL evaluates as true", 68 project( 69 expression.NewGetField(1, types.Text, "foo", false), table, 70 ), 71 sql.NewRow("four"), 72 true, 73 }, 74 { 75 "Empty Set Passes", 76 project( 77 expression.NewGetField(1, types.Text, "foo", false), emptyTable, 78 ), 79 sql.NewRow(), 80 false, 81 }, 82 } 83 84 for _, tt := range testCases { 85 t.Run(tt.name, func(t *testing.T) { 86 require := require.New(t) 87 88 result, err := plan.NewExistsSubquery( 89 plan.NewSubquery(tt.subquery, "").WithExecBuilder(DefaultBuilder), 90 ).Eval(ctx, tt.row) 91 require.NoError(err) 92 require.Equal(tt.result, result) 93 94 // Test Not Exists 95 result, err = expression.NewNot(plan.NewExistsSubquery( 96 plan.NewSubquery(tt.subquery, "").WithExecBuilder(DefaultBuilder), 97 )).Eval(ctx, tt.row) 98 99 require.NoError(err) 100 require.Equal(tt.result, !result.(bool)) 101 }) 102 } 103 }