github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/schema/integration_test.go (about) 1 // Copyright 2020 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 schema_test 16 17 import ( 18 "context" 19 "sort" 20 "testing" 21 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 25 "github.com/dolthub/dolt/go/cmd/dolt/commands" 26 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 27 "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils" 28 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 29 ) 30 31 func TestSqlIntegration(t *testing.T) { 32 const tblName = "test" 33 tests := []struct { 34 name string 35 setup []string 36 isKeyless bool 37 }{ 38 { 39 name: "primary key", 40 setup: []string{"CREATE TABLE test (pk int PRIMARY KEY);"}, 41 isKeyless: false, 42 }, 43 { 44 name: "keyless", 45 setup: []string{"CREATE TABLE test (pk int);"}, 46 isKeyless: true, 47 }, 48 } 49 50 for _, test := range tests { 51 t.Run(test.name, func(t *testing.T) { 52 ctx := context.Background() 53 ddb, root := runTestSql(t, ctx, test.setup) 54 defer ddb.Close() 55 56 tbl, ok, err := root.GetTable(ctx, doltdb.TableName{Name: tblName}) 57 require.NoError(t, err) 58 require.True(t, ok) 59 sch, err := tbl.GetSchema(ctx) 60 require.NoError(t, err) 61 62 ok = schema.IsKeyless(sch) 63 assert.Equal(t, test.isKeyless, ok) 64 }) 65 } 66 } 67 68 func TestSchemaOrdering(t *testing.T) { 69 tests := []struct { 70 name string 71 query string 72 pkCols []string 73 otherCols []string 74 allCols []string 75 ordinals []int 76 }{ 77 { 78 name: "primary key", 79 query: "CREATE TABLE t (a int, b int, pk2 int, c int, pk1 int, PRIMARY KEY (pk1, pk2));", 80 pkCols: []string{"pk1", "pk2"}, 81 otherCols: []string{"a", "b", "c"}, 82 allCols: []string{"a", "b", "pk2", "c", "pk1"}, 83 ordinals: []int{4, 2}, 84 }, 85 } 86 87 for _, test := range tests { 88 t.Run(test.name, func(t *testing.T) { 89 ctx := context.Background() 90 ddb, root := runTestSql(t, ctx, []string{test.query}) 91 defer ddb.Close() 92 93 tbl, ok, err := root.GetTable(ctx, doltdb.TableName{Name: "t"}) 94 require.NoError(t, err) 95 require.True(t, ok) 96 sch, err := tbl.GetSchema(ctx) 97 require.NoError(t, err) 98 99 for i, col := range sch.GetPKCols().GetColumns() { 100 assert.Equal(t, test.pkCols[i], col.Name) 101 } 102 for i, col := range sch.GetNonPKCols().GetColumns() { 103 assert.Equal(t, test.otherCols[i], col.Name) 104 } 105 for i, col := range sch.GetAllCols().GetColumns() { 106 assert.Equal(t, test.allCols[i], col.Name) 107 } 108 for i, ord := range sch.GetPkOrdinals() { 109 assert.Equal(t, test.ordinals[i], ord) 110 } 111 }) 112 } 113 } 114 115 func TestGetKeyTags(t *testing.T) { 116 const tblName = "test" 117 tests := []struct { 118 name string 119 setup []string 120 keyCols []string 121 }{ 122 { 123 name: "primary key", 124 setup: []string{"CREATE TABLE test (pk int PRIMARY KEY, c0 int);"}, 125 keyCols: []string{"pk"}, 126 }, 127 { 128 name: "keyless", 129 setup: []string{"CREATE TABLE test (c0 int, c1 int);"}, 130 keyCols: nil, 131 }, 132 { 133 name: "secondary index", 134 setup: []string{"CREATE TABLE test (pk int PRIMARY KEY, c0 int, c1 int, INDEX(c0));"}, 135 keyCols: []string{"pk", "c0"}, 136 }, 137 { 138 name: "compound index", 139 setup: []string{"CREATE TABLE test (pk int PRIMARY KEY, c0 int, c1 int, INDEX(c1, c0));"}, 140 keyCols: []string{"pk", "c0", "c1"}, 141 }, 142 { 143 name: "keyless secondary index", 144 setup: []string{"CREATE TABLE test (c0 int, c1 int, INDEX(c1));"}, 145 keyCols: []string{"c1"}, 146 }, 147 } 148 149 for _, test := range tests { 150 t.Run(test.name, func(t *testing.T) { 151 ctx := context.Background() 152 ddb, root := runTestSql(t, ctx, test.setup) 153 defer ddb.Close() 154 155 tbl, ok, err := root.GetTable(ctx, doltdb.TableName{Name: tblName}) 156 require.NoError(t, err) 157 require.True(t, ok) 158 sch, err := tbl.GetSchema(ctx) 159 require.NoError(t, err) 160 161 all := sch.GetAllCols() 162 expected := make([]uint64, len(test.keyCols)) 163 for i, name := range test.keyCols { 164 expected[i] = all.LowerNameToCol[name].Tag 165 } 166 sort.Slice(expected, func(i, j int) bool { 167 return expected[i] < expected[j] 168 }) 169 170 actual := schema.GetKeyColumnTags(sch) 171 assert.Equal(t, expected, actual.AsSlice()) 172 }) 173 } 174 } 175 176 func runTestSql(t *testing.T, ctx context.Context, setup []string) (*doltdb.DoltDB, doltdb.RootValue) { 177 dEnv := dtestutils.CreateTestEnv() 178 cmd := commands.SqlCmd{} 179 cliCtx, verr := commands.NewArgFreeCliContext(ctx, dEnv) 180 require.NoError(t, verr) 181 182 for _, query := range setup { 183 code := cmd.Exec(ctx, cmd.Name(), []string{"-q", query}, dEnv, cliCtx) 184 require.Equal(t, 0, code) 185 } 186 root, err := dEnv.WorkingRoot(ctx) 187 require.NoError(t, err) 188 return dEnv.DoltDB, root 189 }