github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/envtestutils/super_schema_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 envtestutils 16 17 import ( 18 "context" 19 "fmt" 20 "testing" 21 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 25 "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils" 26 tc "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils/testcommands" 27 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 28 "github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo" 29 ) 30 31 const ( 32 pkTag = 16191 33 c0Tag = 8734 34 c1Tag = 15903 35 c11Tag = 15001 36 ) 37 38 type SuperSchemaTest struct { 39 // The name of this test. Names should be unique and descriptive. 40 Name string 41 // Name of the table to be verified 42 TableName string 43 // The modifying queries to run 44 Commands []tc.Command 45 // Expected branch 46 ExpectedBranch string 47 // The schema of the result of the query, nil if an error is expected 48 ExpectedSchema schema.Schema 49 // The rows the select query should return, nil if an error is expected 50 ExpectedSuperSchema *schema.SuperSchema 51 // An expected error string 52 ExpectedErrStr string 53 } 54 55 var testableDef = fmt.Sprintf("create table testable (pk int not null primary key);") 56 57 var SuperSchemaTests = []SuperSchemaTest{ 58 { 59 Name: "can create super schema", 60 TableName: "testable", 61 Commands: []tc.Command{ 62 tc.Query{Query: testableDef}, 63 tc.CommitAll{Message: "created table testable"}, 64 }, 65 ExpectedBranch: "master", 66 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 67 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 68 )), 69 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 70 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 71 )), 72 }, 73 { 74 Name: "get super schema without commit", 75 TableName: "testable", 76 Commands: []tc.Command{ 77 tc.Query{Query: testableDef}, 78 }, 79 ExpectedBranch: "master", 80 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 81 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 82 )), 83 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 84 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 85 )), 86 }, 87 { 88 Name: "add column", 89 TableName: "testable", 90 Commands: []tc.Command{ 91 tc.Query{Query: testableDef}, 92 tc.CommitAll{Message: "created table testable"}, 93 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 94 }, 95 ExpectedBranch: "master", 96 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 97 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 98 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 99 )), 100 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 101 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 102 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 103 )), 104 }, 105 { 106 Name: "drop column", 107 TableName: "testable", 108 Commands: []tc.Command{ 109 tc.Query{Query: testableDef}, 110 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int")}, 111 tc.CommitAll{Message: "created table testable"}, 112 tc.Query{Query: "alter table testable drop column c0"}, 113 tc.CommitAll{Message: "dropped column c0"}, 114 }, 115 ExpectedBranch: "master", 116 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 117 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 118 )), 119 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 120 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 121 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 122 )), 123 }, 124 { 125 Name: "modify column", 126 TableName: "testable", 127 Commands: []tc.Command{ 128 tc.Query{Query: testableDef}, 129 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 130 tc.CommitAll{Message: "created table testable"}, 131 tc.Query{Query: "alter table testable drop column c0"}, 132 }, 133 ExpectedBranch: "master", 134 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 135 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 136 )), 137 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 138 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 139 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 140 )), 141 }, 142 { 143 Name: "drop column from working set", 144 TableName: "testable", 145 Commands: []tc.Command{ 146 tc.Query{Query: testableDef}, 147 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 148 tc.Query{Query: "alter table testable drop column c0"}, 149 }, 150 ExpectedBranch: "master", 151 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 152 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 153 )), 154 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 155 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 156 )), 157 }, 158 { 159 Name: "staged column persisted on commit, not working column", 160 TableName: "testable", 161 Commands: []tc.Command{ 162 tc.Query{Query: testableDef}, 163 tc.CommitAll{Message: "created table testable"}, 164 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 165 tc.StageAll{}, 166 tc.Query{Query: fmt.Sprintf("alter table testable add column c1 int;")}, 167 tc.CommitStaged{Message: "adding staged column c0"}, 168 tc.ResetHard{}, 169 }, 170 ExpectedBranch: "master", 171 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 172 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 173 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 174 )), 175 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 176 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 177 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 178 )), 179 }, 180 { 181 Name: "super schema on branch master", 182 TableName: "testable", 183 Commands: []tc.Command{ 184 tc.Query{Query: testableDef}, 185 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 186 tc.CommitAll{Message: "created table testable"}, 187 tc.Branch{BranchName: "other"}, 188 tc.Checkout{BranchName: "other"}, 189 tc.Query{Query: fmt.Sprintf("alter table testable add column c11 int;")}, 190 tc.CommitAll{Message: "added column c11 on branch other"}, 191 tc.Checkout{BranchName: "master"}, 192 tc.Query{Query: fmt.Sprintf("alter table testable add column c1 int;")}, 193 }, 194 ExpectedBranch: "master", 195 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 196 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 197 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 198 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 199 )), 200 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 201 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 202 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 203 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 204 )), 205 }, 206 { 207 Name: "super schema on branch other", 208 TableName: "testable", 209 Commands: []tc.Command{ 210 tc.Query{Query: testableDef}, 211 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 212 tc.CommitAll{Message: "created table testable"}, 213 tc.Branch{BranchName: "other"}, 214 tc.Checkout{BranchName: "other"}, 215 tc.Query{Query: fmt.Sprintf("alter table testable add column c11 int;")}, 216 tc.CommitAll{Message: "added column c11 on branch other"}, 217 tc.Checkout{BranchName: "master"}, 218 tc.Query{Query: fmt.Sprintf("alter table testable add column c1 int;")}, 219 tc.CommitAll{Message: "added column c1 on branch master"}, 220 tc.Checkout{BranchName: "other"}, 221 }, 222 ExpectedBranch: "other", 223 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 224 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 225 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 226 newColTypeInfo("c11", c11Tag, typeinfo.Int32Type, false), 227 )), 228 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 229 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 230 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 231 newColTypeInfo("c11", c11Tag, typeinfo.Int32Type, false), 232 )), 233 }, 234 // https://github.com/dolthub/dolt/issues/773 235 /*{ 236 Name: "super schema merge", 237 TableName: "testable", 238 Commands: []tc.Command{ 239 tc.Query{Query: testableDef}, 240 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 241 tc.CommitAll{Message: "created table testable"}, 242 tc.Branch{BranchName: "other"}, 243 tc.Checkout{BranchName: "other"}, 244 tc.Query{Query: fmt.Sprintf("alter table testable add column c11 int;")}, 245 tc.CommitAll{Message: "added column c11 on branch other"}, 246 tc.Checkout{BranchName: "master"}, 247 tc.Query{Query: fmt.Sprintf("alter table testable add column c1 int;")}, 248 tc.CommitAll{Message: "added column c1 on branch master"}, 249 tc.Merge{BranchName: "other"}, 250 }, 251 ExpectedBranch: "master", 252 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 253 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 254 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 255 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 256 newColTypeInfo("c11", c11Tag, typeinfo.Int32Type, false), 257 )), 258 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 259 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 260 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 261 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 262 newColTypeInfo("c11", c11Tag, typeinfo.Int32Type, false), 263 )), 264 }, 265 { 266 Name: "super schema merge with drops", 267 TableName: "testable", 268 Commands: []tc.Command{ 269 tc.Query{Query: testableDef}, 270 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 271 tc.CommitAll{Message: "created table testable"}, 272 tc.Branch{BranchName: "other"}, 273 tc.Checkout{BranchName: "other"}, 274 tc.Query{Query: fmt.Sprintf("alter table testable add column c11 int;")}, 275 tc.Query{Query: fmt.Sprintf("alter table testable add column c12 int;")}, 276 tc.CommitAll{Message: "added columns c11 and c12 on branch other"}, 277 tc.Query{Query: "alter table testable drop column c12;"}, 278 tc.CommitAll{Message: "dropped column c12 on branch other"}, 279 tc.Checkout{BranchName: "master"}, 280 tc.Query{Query: fmt.Sprintf("alter table testable add column c1 int;")}, 281 tc.CommitAll{Message: "added column c1 on branch master"}, 282 tc.Merge{BranchName: "other"}, 283 tc.CommitAll{Message: "Merged other into master"}, 284 }, 285 ExpectedBranch: "master", 286 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 287 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 288 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 289 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 290 newColTypeInfo("c11", c11Tag, typeinfo.Int32Type, false), 291 )), 292 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 293 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 294 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 295 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 296 newColTypeInfo("c11", c11Tag, typeinfo.Int32Type, false), 297 newColTypeInfo("c12", c12Tag, typeinfo.Int32Type, false), 298 )), 299 },*/ 300 { 301 Name: "super schema with table add/drops", 302 TableName: "testable", 303 Commands: []tc.Command{ 304 tc.Query{Query: testableDef}, 305 tc.Query{Query: fmt.Sprintf("alter table testable add column c0 int;")}, 306 tc.Query{Query: "create table foo (pk int not null primary key);"}, 307 tc.CommitAll{Message: "created tables testable and foo"}, 308 tc.Query{Query: fmt.Sprintf("alter table testable add column c1 int;")}, 309 tc.Query{Query: "create table qux (pk int not null primary key);"}, 310 tc.Query{Query: "drop table foo;"}, 311 tc.CommitAll{Message: "added column c1 on branch master, created table qux, dropped table foo"}, 312 }, 313 ExpectedBranch: "master", 314 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 315 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 316 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 317 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 318 )), 319 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 320 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 321 newColTypeInfo("c0", c0Tag, typeinfo.Int32Type, false), 322 newColTypeInfo("c1", c1Tag, typeinfo.Int32Type, false), 323 )), 324 }, 325 { 326 // This test corresponds to @test "diff sql reconciles DROP TABLE" in sql_diff.bats 327 Name: "sql diff bats test", 328 TableName: "testable", 329 Commands: []tc.Command{ 330 tc.Branch{BranchName: "first"}, 331 tc.Checkout{BranchName: "first"}, 332 tc.Query{Query: testableDef}, 333 tc.Query{Query: "insert into testable values (1);"}, 334 tc.CommitAll{Message: "setup table"}, 335 tc.Branch{BranchName: "other"}, 336 tc.Checkout{BranchName: "other"}, 337 tc.Query{Query: "drop table testable;"}, 338 tc.CommitAll{Message: "removed table"}, 339 tc.Checkout{BranchName: "first"}, 340 }, 341 ExpectedBranch: "first", 342 ExpectedSchema: schema.MustSchemaFromCols(columnCollection( 343 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 344 )), 345 ExpectedSuperSchema: superSchemaFromCols(columnCollection( 346 newColTypeInfo("pk", pkTag, typeinfo.Int32Type, true, schema.NotNullConstraint{}), 347 )), 348 }, 349 } 350 351 func TestSuperSchema(t *testing.T) { 352 for _, test := range SuperSchemaTests { 353 t.Run(test.Name, func(t *testing.T) { 354 testSuperSchema(t, test) 355 }) 356 } 357 } 358 359 func testSuperSchema(t *testing.T, test SuperSchemaTest) { 360 dEnv := dtestutils.CreateTestEnv() 361 362 var ee error 363 for idx, cmd := range test.Commands { 364 require.NoError(t, ee) 365 fmt.Println(fmt.Sprintf("%d: %s: %s", idx, cmd.CommandString(), cmd)) 366 ee = cmd.Exec(t, dEnv) 367 } 368 369 if test.ExpectedErrStr != "" { 370 require.Error(t, ee, test.ExpectedErrStr) 371 } else { 372 spec := dEnv.RepoState.CWBHeadRef() 373 require.Equal(t, "refs/heads/"+test.ExpectedBranch, spec.String()) 374 375 r, err := dEnv.WorkingRoot(context.Background()) 376 require.NoError(t, err) 377 378 tbl, ok, err := r.GetTable(context.Background(), test.TableName) 379 require.NoError(t, err) 380 require.True(t, ok) 381 382 ss, found, err := r.GetSuperSchema(context.Background(), test.TableName) 383 require.True(t, found) 384 require.NoError(t, err) 385 assert.Equal(t, test.ExpectedSuperSchema, ss) 386 387 sch, err := tbl.GetSchema(context.Background()) 388 require.NoError(t, err) 389 assert.Equal(t, test.ExpectedSchema, sch) 390 } 391 } 392 393 func superSchemaFromCols(cols *schema.ColCollection) *schema.SuperSchema { 394 sch := schema.MustSchemaFromCols(cols) 395 ss, _ := schema.NewSuperSchema(sch) 396 return ss 397 }