github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/compile/ddl.go (about) 1 // Copyright 2021 Matrix Origin 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 compile 16 17 import ( 18 "context" 19 "fmt" 20 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 "github.com/matrixorigin/matrixone/pkg/compress" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/defines" 25 "github.com/matrixorigin/matrixone/pkg/pb/plan" 26 "github.com/matrixorigin/matrixone/pkg/sql/colexec" 27 "github.com/matrixorigin/matrixone/pkg/sql/util" 28 "github.com/matrixorigin/matrixone/pkg/util/trace" 29 "github.com/matrixorigin/matrixone/pkg/vm/engine" 30 ) 31 32 func (s *Scope) CreateDatabase(c *Compile) error { 33 var span trace.Span 34 c.ctx, span = trace.Start(c.ctx, "CreateDatabase") 35 defer span.End() 36 dbName := s.Plan.GetDdl().GetCreateDatabase().GetDatabase() 37 if _, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator); err == nil { 38 if s.Plan.GetDdl().GetCreateDatabase().GetIfNotExists() { 39 return nil 40 } 41 return moerr.NewDBAlreadyExists(c.ctx, dbName) 42 } 43 err := c.e.Create(context.WithValue(c.ctx, defines.SqlKey{}, c.sql), 44 dbName, c.proc.TxnOperator) 45 if err != nil { 46 return err 47 } 48 return colexec.CreateAutoIncrTable(c.e, c.ctx, c.proc, dbName) 49 } 50 51 func (s *Scope) DropDatabase(c *Compile) error { 52 dbName := s.Plan.GetDdl().GetDropDatabase().GetDatabase() 53 if _, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator); err != nil { 54 if s.Plan.GetDdl().GetDropDatabase().GetIfExists() { 55 return nil 56 } 57 return moerr.NewErrDropNonExistsDB(c.ctx, dbName) 58 } 59 return c.e.Delete(c.ctx, dbName, c.proc.TxnOperator) 60 } 61 62 // Drop the old view, and create the new view. 63 func (s *Scope) AlterView(c *Compile) error { 64 qry := s.Plan.GetDdl().GetAlterView() 65 66 dbName := c.db 67 dbSource, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator) 68 if err != nil { 69 if qry.GetIfExists() { 70 return nil 71 } 72 return err 73 } 74 tblName := qry.GetTableDef().GetName() 75 if _, err = dbSource.Relation(c.ctx, tblName); err != nil { 76 if qry.GetIfExists() { 77 return nil 78 } 79 return err 80 } 81 82 // Drop view table. 83 if err := dbSource.Delete(c.ctx, tblName); err != nil { 84 return err 85 } 86 87 // Create view table. 88 // convert the plan's cols to the execution's cols 89 planCols := qry.GetTableDef().GetCols() 90 exeCols := planColsToExeCols(planCols) 91 92 // convert the plan's defs to the execution's defs 93 exeDefs, err := planDefsToExeDefs(qry.GetTableDef()) 94 if err != nil { 95 return err 96 } 97 98 // if _, err := dbSource.Relation(c.ctx, tblName); err == nil { 99 // return moerr.NewTableAlreadyExists(c.ctx, tblName) 100 // } 101 102 return dbSource.Create(context.WithValue(c.ctx, defines.SqlKey{}, c.sql), tblName, append(exeCols, exeDefs...)) 103 } 104 105 func (s *Scope) CreateTable(c *Compile) error { 106 qry := s.Plan.GetDdl().GetCreateTable() 107 // convert the plan's cols to the execution's cols 108 planCols := qry.GetTableDef().GetCols() 109 tableCols := planCols 110 exeCols := planColsToExeCols(planCols) 111 112 // convert the plan's defs to the execution's defs 113 exeDefs, err := planDefsToExeDefs(qry.GetTableDef()) 114 if err != nil { 115 return err 116 } 117 118 dbName := c.db 119 if qry.GetDatabase() != "" { 120 dbName = qry.GetDatabase() 121 } 122 dbSource, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator) 123 if err != nil { 124 if dbName == "" { 125 return moerr.NewNoDB(c.ctx) 126 } 127 return err 128 } 129 tblName := qry.GetTableDef().GetName() 130 if _, err := dbSource.Relation(c.ctx, tblName); err == nil { 131 if qry.GetIfNotExists() { 132 return nil 133 } 134 return moerr.NewTableAlreadyExists(c.ctx, tblName) 135 } 136 137 // check in EntireEngine.TempEngine, notice that TempEngine may not init 138 tmpDBSource, err := c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator) 139 if err == nil { 140 if _, err := tmpDBSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName)); err == nil { 141 if qry.GetIfNotExists() { 142 return nil 143 } 144 return moerr.NewTableAlreadyExists(c.ctx, fmt.Sprintf("temporary '%s'", tblName)) 145 } 146 } 147 148 if err := dbSource.Create(context.WithValue(c.ctx, defines.SqlKey{}, c.sql), tblName, append(exeCols, exeDefs...)); err != nil { 149 return err 150 } 151 152 fkDbs := qry.GetFkDbs() 153 if len(fkDbs) > 0 { 154 fkTables := qry.GetFkTables() 155 newRelation, err := dbSource.Relation(c.ctx, tblName) 156 if err != nil { 157 return err 158 } 159 tblId := newRelation.GetTableID(c.ctx) 160 161 newTableDef, err := newRelation.TableDefs(c.ctx) 162 if err != nil { 163 return err 164 } 165 var colNameToId = make(map[string]uint64) 166 var oldCt *engine.ConstraintDef 167 for _, def := range newTableDef { 168 if attr, ok := def.(*engine.AttributeDef); ok { 169 colNameToId[attr.Attr.Name] = attr.Attr.ID 170 } 171 if ct, ok := def.(*engine.ConstraintDef); ok { 172 oldCt = ct 173 } 174 } 175 newFkeys := make([]*plan.ForeignKeyDef, len(qry.GetTableDef().Fkeys)) 176 for i, fkey := range qry.GetTableDef().Fkeys { 177 newDef := &plan.ForeignKeyDef{ 178 Name: fkey.Name, 179 Cols: make([]uint64, len(fkey.Cols)), 180 ForeignTbl: fkey.ForeignTbl, 181 ForeignCols: make([]uint64, len(fkey.ForeignCols)), 182 OnDelete: fkey.OnDelete, 183 OnUpdate: fkey.OnUpdate, 184 } 185 copy(newDef.ForeignCols, fkey.ForeignCols) 186 for idx, colName := range qry.GetFkCols()[i].Cols { 187 newDef.Cols[idx] = colNameToId[colName] 188 } 189 newFkeys[i] = newDef 190 } 191 // remove old fk settings 192 newCt, err := makeNewCreateConstraint(oldCt, &engine.ForeignKeyDef{ 193 Fkeys: newFkeys, 194 }) 195 if err != nil { 196 return err 197 } 198 err = newRelation.UpdateConstraint(c.ctx, newCt) 199 if err != nil { 200 return err 201 } 202 203 // need to append TableId to parent's TableDef.RefChildTbls 204 for i, fkTableName := range fkTables { 205 fkDbName := fkDbs[i] 206 fkDbSource, err := c.e.Database(c.ctx, fkDbName, c.proc.TxnOperator) 207 if err != nil { 208 return err 209 } 210 fkRelation, err := fkDbSource.Relation(c.ctx, fkTableName) 211 if err != nil { 212 return err 213 } 214 fkTableDef, err := fkRelation.TableDefs(c.ctx) 215 if err != nil { 216 return err 217 } 218 var oldCt *engine.ConstraintDef 219 var oldRefChildDef *engine.RefChildTableDef 220 for _, def := range fkTableDef { 221 if ct, ok := def.(*engine.ConstraintDef); ok { 222 oldCt = ct 223 for _, ct := range oldCt.Cts { 224 if old, ok := ct.(*engine.RefChildTableDef); ok { 225 oldRefChildDef = old 226 } 227 } 228 break 229 } 230 } 231 if oldRefChildDef == nil { 232 oldRefChildDef = &engine.RefChildTableDef{} 233 } 234 oldRefChildDef.Tables = append(oldRefChildDef.Tables, tblId) 235 newCt, err := makeNewCreateConstraint(oldCt, oldRefChildDef) 236 if err != nil { 237 return err 238 } 239 err = fkRelation.UpdateConstraint(c.ctx, newCt) 240 if err != nil { 241 return err 242 } 243 } 244 } 245 246 // build index table 247 for _, def := range qry.IndexTables { 248 planCols = def.GetCols() 249 exeCols = planColsToExeCols(planCols) 250 exeDefs, err = planDefsToExeDefs(def) 251 if err != nil { 252 return err 253 } 254 if _, err := dbSource.Relation(c.ctx, def.Name); err == nil { 255 return moerr.NewTableAlreadyExists(c.ctx, def.Name) 256 } 257 if err := dbSource.Create(c.ctx, def.Name, append(exeCols, exeDefs...)); err != nil { 258 return err 259 } 260 } 261 return colexec.CreateAutoIncrCol(c.e, c.ctx, dbSource, c.proc, tableCols, dbName, tblName) 262 } 263 264 func (s *Scope) CreateTempTable(c *Compile) error { 265 qry := s.Plan.GetDdl().GetCreateTable() 266 // convert the plan's cols to the execution's cols 267 planCols := qry.GetTableDef().GetCols() 268 tableCols := planCols 269 exeCols := planColsToExeCols(planCols) 270 271 // convert the plan's defs to the execution's defs 272 exeDefs, err := planDefsToExeDefs(qry.GetTableDef()) 273 if err != nil { 274 return err 275 } 276 277 // Temporary table names and persistent table names are not allowed to be duplicated 278 // So before create temporary table, need to check if it exists a table has same name 279 dbName := c.db 280 if qry.GetDatabase() != "" { 281 dbName = qry.GetDatabase() 282 } 283 284 // check in EntireEngine.TempEngine 285 tmpDBSource, err := c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator) 286 if err != nil { 287 return err 288 } 289 tblName := qry.GetTableDef().GetName() 290 if _, err := tmpDBSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName)); err == nil { 291 if qry.GetIfNotExists() { 292 return nil 293 } 294 return moerr.NewTableAlreadyExists(c.ctx, fmt.Sprintf("temporary '%s'", tblName)) 295 } 296 297 // check in EntireEngine.Engine 298 dbSource, err := c.e.Database(c.ctx, dbName, c.proc.TxnOperator) 299 if err != nil { 300 return err 301 } 302 if _, err := dbSource.Relation(c.ctx, tblName); err == nil { 303 if qry.GetIfNotExists() { 304 return nil 305 } 306 return moerr.NewTableAlreadyExists(c.ctx, tblName) 307 } 308 309 // create temporary table 310 if err := tmpDBSource.Create(c.ctx, engine.GetTempTableName(dbName, tblName), append(exeCols, exeDefs...)); err != nil { 311 return err 312 } 313 314 // build index table 315 for _, def := range qry.IndexTables { 316 planCols = def.GetCols() 317 exeCols = planColsToExeCols(planCols) 318 exeDefs, err = planDefsToExeDefs(def) 319 if err != nil { 320 return err 321 } 322 if _, err := tmpDBSource.Relation(c.ctx, def.Name); err == nil { 323 return moerr.NewTableAlreadyExists(c.ctx, def.Name) 324 } 325 326 if err := tmpDBSource.Create(c.ctx, engine.GetTempTableName(dbName, def.Name), append(exeCols, exeDefs...)); err != nil { 327 return err 328 } 329 } 330 331 return colexec.CreateAutoIncrCol(c.e, c.ctx, tmpDBSource, c.proc, tableCols, defines.TEMPORARY_DBNAME, engine.GetTempTableName(dbName, tblName)) 332 } 333 334 func (s *Scope) CreateIndex(c *Compile) error { 335 qry := s.Plan.GetDdl().GetCreateIndex() 336 d, err := c.e.Database(c.ctx, qry.Database, c.proc.TxnOperator) 337 if err != nil { 338 return err 339 } 340 r, err := d.Relation(c.ctx, qry.Table) 341 if err != nil { 342 return err 343 } 344 345 // build and create index table 346 if qry.TableExist { 347 def := qry.GetIndex().GetIndexTables()[0] 348 planCols := def.GetCols() 349 exeCols := planColsToExeCols(planCols) 350 exeDefs, err := planDefsToExeDefs(def) 351 if err != nil { 352 return err 353 } 354 if _, err := d.Relation(c.ctx, def.Name); err == nil { 355 return moerr.NewTableAlreadyExists(c.ctx, def.Name) 356 } 357 if err := d.Create(c.ctx, def.Name, append(exeCols, exeDefs...)); err != nil { 358 return err 359 } 360 361 } 362 // build and update constraint def 363 defs, err := planDefsToExeDefs(qry.GetIndex().GetTableDef()) 364 if err != nil { 365 return err 366 } 367 ct := defs[0].(*engine.ConstraintDef) 368 369 tblDefs, err := r.TableDefs(c.ctx) 370 if err != nil { 371 return err 372 } 373 var oldCt *engine.ConstraintDef 374 for _, def := range tblDefs { 375 if ct, ok := def.(*engine.ConstraintDef); ok { 376 oldCt = ct 377 break 378 } 379 } 380 newCt, err := makeNewCreateConstraint(oldCt, ct.Cts[0]) 381 if err != nil { 382 return err 383 } 384 err = r.UpdateConstraint(c.ctx, newCt) 385 if err != nil { 386 return err 387 } 388 389 // TODO: implement by insert ... select ... 390 // insert data into index table 391 indexDef := qry.GetIndex().GetTableDef().Indexes[0] 392 if indexDef.Unique { 393 targetAttrs := getIndexColsFromOriginTable(tblDefs, indexDef.Parts) 394 ret, err := r.Ranges(c.ctx, nil) 395 if err != nil { 396 return err 397 } 398 rds, err := r.NewReader(c.ctx, 1, nil, ret) 399 if err != nil { 400 return err 401 } 402 bat, err := rds[0].Read(c.ctx, targetAttrs, nil, c.proc.Mp()) 403 if err != nil { 404 return err 405 } 406 err = rds[0].Close() 407 if err != nil { 408 return err 409 } 410 411 if bat != nil { 412 indexBat, cnt := util.BuildUniqueKeyBatch(bat.Vecs, targetAttrs, indexDef.Parts, qry.OriginTablePrimaryKey, c.proc) 413 indexR, err := d.Relation(c.ctx, indexDef.IndexTableName) 414 if err != nil { 415 return err 416 } 417 if cnt != 0 { 418 if err := indexR.Write(c.ctx, indexBat); err != nil { 419 return err 420 } 421 } 422 indexBat.Clean(c.proc.Mp()) 423 } 424 // other situation is not supported now and check in plan 425 } 426 427 return nil 428 } 429 430 func (s *Scope) DropIndex(c *Compile) error { 431 qry := s.Plan.GetDdl().GetDropIndex() 432 d, err := c.e.Database(c.ctx, qry.Database, c.proc.TxnOperator) 433 if err != nil { 434 return err 435 } 436 r, err := d.Relation(c.ctx, qry.Table) 437 if err != nil { 438 return err 439 } 440 441 // build and update constraint def 442 tblDefs, err := r.TableDefs(c.ctx) 443 if err != nil { 444 return err 445 } 446 var oldCt *engine.ConstraintDef 447 for _, def := range tblDefs { 448 if ct, ok := def.(*engine.ConstraintDef); ok { 449 oldCt = ct 450 break 451 } 452 } 453 newCt, err := makeNewDropConstraint(oldCt, qry.GetIndexName()) 454 if err != nil { 455 return err 456 } 457 err = r.UpdateConstraint(c.ctx, newCt) 458 if err != nil { 459 return err 460 } 461 462 // drop index table 463 if qry.IndexTableName != "" { 464 if _, err = d.Relation(c.ctx, qry.IndexTableName); err != nil { 465 return err 466 } 467 if err = d.Delete(c.ctx, qry.IndexTableName); err != nil { 468 return err 469 } 470 } 471 return nil 472 } 473 474 func makeNewDropConstraint(oldCt *engine.ConstraintDef, dropName string) (*engine.ConstraintDef, error) { 475 // must fount dropName because of being checked in plan 476 for i, ct := range oldCt.Cts { 477 switch def := ct.(type) { 478 case *engine.ForeignKeyDef: 479 for idx, fkDef := range def.Fkeys { 480 if fkDef.Name == dropName { 481 def.Fkeys = append(def.Fkeys[:idx], def.Fkeys[idx+1:]...) 482 oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...) 483 oldCt.Cts = append(oldCt.Cts, def) 484 break 485 } 486 } 487 case *engine.IndexDef: 488 for idx, index := range def.Indexes { 489 if index.IndexName == dropName { 490 def.Indexes = append(def.Indexes[:idx], def.Indexes[idx+1:]...) 491 oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...) 492 oldCt.Cts = append(oldCt.Cts, def) 493 break 494 } 495 } 496 } 497 } 498 return oldCt, nil 499 } 500 501 func makeNewCreateConstraint(oldCt *engine.ConstraintDef, c engine.Constraint) (*engine.ConstraintDef, error) { 502 // duplication has checked in plan 503 if oldCt == nil { 504 return &engine.ConstraintDef{ 505 Cts: []engine.Constraint{c}, 506 }, nil 507 } 508 switch t := c.(type) { 509 case *engine.ForeignKeyDef: 510 ok := false 511 for i, ct := range oldCt.Cts { 512 if _, ok = ct.(*engine.ForeignKeyDef); ok { 513 oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...) 514 oldCt.Cts = append(oldCt.Cts, t) 515 break 516 } 517 } 518 if !ok { 519 oldCt.Cts = append(oldCt.Cts, c) 520 } 521 522 case *engine.RefChildTableDef: 523 ok := false 524 for i, ct := range oldCt.Cts { 525 if _, ok = ct.(*engine.RefChildTableDef); ok { 526 oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...) 527 oldCt.Cts = append(oldCt.Cts, t) 528 break 529 } 530 } 531 if !ok { 532 oldCt.Cts = append(oldCt.Cts, c) 533 } 534 case *engine.IndexDef: 535 ok := false 536 var indexdef *engine.IndexDef 537 for i, ct := range oldCt.Cts { 538 if indexdef, ok = ct.(*engine.IndexDef); ok { 539 indexdef.Indexes = append(indexdef.Indexes, t.Indexes[0]) 540 oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...) 541 oldCt.Cts = append(oldCt.Cts, indexdef) 542 break 543 } 544 } 545 if !ok { 546 oldCt.Cts = append(oldCt.Cts, c) 547 } 548 549 //case *engine.UniqueIndexDef: 550 // d := &plan.UniqueIndexDef{} 551 // err := d.UnMarshalUniqueIndexDef([]byte(t.UniqueIndex)) 552 // if err != nil { 553 // return nil, err 554 // } 555 // 556 // ok := false 557 // var idx *engine.UniqueIndexDef 558 // for i, ct := range oldCt.Cts { 559 // if idx, ok = ct.(*engine.UniqueIndexDef); ok { 560 // u := &plan.UniqueIndexDef{} 561 // err := u.UnMarshalUniqueIndexDef([]byte(idx.UniqueIndex)) 562 // if err != nil { 563 // return nil, err 564 // } 565 // u.IndexNames = append(u.IndexNames, d.IndexNames[0]) 566 // u.TableNames = append(u.TableNames, d.TableNames[0]) 567 // u.TableExists = append(u.TableExists, d.TableExists[0]) 568 // u.Fields = append(u.Fields, d.Fields[0]) 569 // u.Comments = append(u.Comments, d.Comments[0]) 570 // 571 // oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...) 572 // 573 // bytes, err := u.MarshalUniqueIndexDef() 574 // if err != nil { 575 // return nil, err 576 // } 577 // oldCt.Cts = append(oldCt.Cts, &engine.UniqueIndexDef{ 578 // UniqueIndex: string(bytes), 579 // }) 580 // break 581 // } 582 // } 583 // if !ok { 584 // oldCt.Cts = append(oldCt.Cts, c) 585 // } 586 //case *engine.SecondaryIndexDef: 587 // d := &plan.SecondaryIndexDef{} 588 // err := d.UnMarshalSecondaryIndexDef([]byte(t.SecondaryIndex)) 589 // if err != nil { 590 // return nil, err 591 // } 592 // 593 // ok := false 594 // var idx *engine.SecondaryIndexDef 595 // for i, ct := range oldCt.Cts { 596 // if idx, ok = ct.(*engine.SecondaryIndexDef); ok { 597 // u := &plan.SecondaryIndexDef{} 598 // err := u.UnMarshalSecondaryIndexDef([]byte(idx.SecondaryIndex)) 599 // if err != nil { 600 // return nil, err 601 // } 602 // u.IndexNames = append(u.IndexNames, d.IndexNames[0]) 603 // u.TableNames = append(u.TableNames, d.TableNames[0]) 604 // u.TableExists = append(u.TableExists, d.TableExists[0]) 605 // u.Fields = append(u.Fields, d.Fields[0]) 606 // u.Comments = append(u.Comments, d.Comments[0]) 607 // 608 // oldCt.Cts = append(oldCt.Cts[:i], oldCt.Cts[i+1:]...) 609 // 610 // bytes, err := u.MarshalSecondaryIndexDef() 611 // if err != nil { 612 // return nil, err 613 // } 614 // oldCt.Cts = append(oldCt.Cts, &engine.SecondaryIndexDef{ 615 // SecondaryIndex: string(bytes), 616 // }) 617 // break 618 // } 619 // } 620 // if !ok { 621 // oldCt.Cts = append(oldCt.Cts, c) 622 // } 623 } 624 return oldCt, nil 625 } 626 627 // Truncation operations cannot be performed if the session holds an active table lock. 628 func (s *Scope) TruncateTable(c *Compile) error { 629 var dbSource engine.Database 630 var rel engine.Relation 631 var err error 632 var isTemp bool 633 var newId uint64 634 635 tqry := s.Plan.GetDdl().GetTruncateTable() 636 dbName := tqry.GetDatabase() 637 tblName := tqry.GetTable() 638 oldId := tqry.GetTableId() 639 640 dbSource, err = c.e.Database(c.ctx, dbName, c.proc.TxnOperator) 641 if err != nil { 642 return err 643 } 644 645 if rel, err = dbSource.Relation(c.ctx, tblName); err != nil { 646 var e error // avoid contamination of error messages 647 dbSource, e = c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator) 648 if e != nil { 649 return err 650 } 651 rel, e = dbSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName)) 652 if e != nil { 653 return err 654 } 655 isTemp = true 656 } 657 658 if isTemp { 659 // memoryengine truncate always return 0, so for temporary table, just use origin tableId as newId 660 _, err = dbSource.Truncate(c.ctx, engine.GetTempTableName(dbName, tblName)) 661 newId = rel.GetTableID(c.ctx) 662 } else { 663 newId, err = dbSource.Truncate(c.ctx, tblName) 664 } 665 666 if err != nil { 667 return err 668 } 669 670 // Truncate Index Tables if needed 671 for _, name := range tqry.IndexTableNames { 672 var err error 673 if isTemp { 674 _, err = dbSource.Truncate(c.ctx, engine.GetTempTableName(dbName, name)) 675 } else { 676 _, err = dbSource.Truncate(c.ctx, name) 677 } 678 if err != nil { 679 return err 680 } 681 } 682 683 // update tableDef of foreign key's table with new table id 684 for _, ftblId := range tqry.ForeignTbl { 685 _, _, fkRelation, err := c.e.GetRelationById(c.ctx, c.proc.TxnOperator, ftblId) 686 if err != nil { 687 return err 688 } 689 fkTableDef, err := fkRelation.TableDefs(c.ctx) 690 if err != nil { 691 return err 692 } 693 var oldCt *engine.ConstraintDef 694 for _, def := range fkTableDef { 695 if ct, ok := def.(*engine.ConstraintDef); ok { 696 oldCt = ct 697 break 698 } 699 } 700 for _, ct := range oldCt.Cts { 701 if def, ok := ct.(*engine.RefChildTableDef); ok { 702 for idx, refTable := range def.Tables { 703 if refTable == oldId { 704 def.Tables[idx] = newId 705 break 706 } 707 } 708 break 709 } 710 } 711 if err != nil { 712 return err 713 } 714 err = fkRelation.UpdateConstraint(c.ctx, oldCt) 715 if err != nil { 716 return err 717 } 718 719 } 720 721 id := rel.GetTableID(c.ctx) 722 723 if isTemp { 724 err = colexec.ResetAutoInsrCol(c.e, c.ctx, engine.GetTempTableName(dbName, tblName), dbSource, c.proc, id, newId, defines.TEMPORARY_DBNAME) 725 } else { 726 err = colexec.ResetAutoInsrCol(c.e, c.ctx, tblName, dbSource, c.proc, id, newId, dbName) 727 } 728 if err != nil { 729 return err 730 } 731 732 return nil 733 } 734 735 func (s *Scope) DropTable(c *Compile) error { 736 qry := s.Plan.GetDdl().GetDropTable() 737 738 dbName := qry.GetDatabase() 739 var dbSource engine.Database 740 var rel engine.Relation 741 var err error 742 var isTemp bool 743 744 tblName := qry.GetTable() 745 tblId := qry.GetTableId() 746 747 dbSource, err = c.e.Database(c.ctx, dbName, c.proc.TxnOperator) 748 if err != nil { 749 if qry.GetIfExists() { 750 return nil 751 } 752 return err 753 } 754 755 if rel, err = dbSource.Relation(c.ctx, tblName); err != nil { 756 var e error // avoid contamination of error messages 757 dbSource, e = c.e.Database(c.ctx, defines.TEMPORARY_DBNAME, c.proc.TxnOperator) 758 if dbSource == nil && qry.GetIfExists() { 759 return nil 760 } else if e != nil { 761 return err 762 } 763 rel, e = dbSource.Relation(c.ctx, engine.GetTempTableName(dbName, tblName)) 764 if e != nil { 765 if qry.GetIfExists() { 766 return nil 767 } else { 768 return err 769 } 770 } 771 isTemp = true 772 } 773 774 // update tableDef of foreign key's table 775 for _, ftblId := range qry.ForeignTbl { 776 _, _, fkRelation, err := c.e.GetRelationById(c.ctx, c.proc.TxnOperator, ftblId) 777 if err != nil { 778 return err 779 } 780 fkTableDef, err := fkRelation.TableDefs(c.ctx) 781 if err != nil { 782 return err 783 } 784 var oldCt *engine.ConstraintDef 785 for _, def := range fkTableDef { 786 if ct, ok := def.(*engine.ConstraintDef); ok { 787 oldCt = ct 788 break 789 } 790 } 791 for _, ct := range oldCt.Cts { 792 if def, ok := ct.(*engine.RefChildTableDef); ok { 793 for idx, refTable := range def.Tables { 794 if refTable == tblId { 795 def.Tables = append(def.Tables[:idx], def.Tables[idx+1:]...) 796 break 797 } 798 } 799 break 800 } 801 } 802 if err != nil { 803 return err 804 } 805 err = fkRelation.UpdateConstraint(c.ctx, oldCt) 806 if err != nil { 807 return err 808 } 809 } 810 811 if isTemp { 812 if err := dbSource.Delete(c.ctx, engine.GetTempTableName(dbName, tblName)); err != nil { 813 return err 814 } 815 for _, name := range qry.IndexTableNames { 816 if err := dbSource.Delete(c.ctx, name); err != nil { 817 return err 818 } 819 } 820 return colexec.DeleteAutoIncrCol(c.e, c.ctx, dbSource, rel, c.proc, defines.TEMPORARY_DBNAME, rel.GetTableID(c.ctx)) 821 } else { 822 if err := dbSource.Delete(c.ctx, tblName); err != nil { 823 return err 824 } 825 for _, name := range qry.IndexTableNames { 826 if err := dbSource.Delete(c.ctx, name); err != nil { 827 return err 828 } 829 } 830 return colexec.DeleteAutoIncrCol(c.e, c.ctx, dbSource, rel, c.proc, dbName, rel.GetTableID(c.ctx)) 831 } 832 } 833 834 func planDefsToExeDefs(tableDef *plan.TableDef) ([]engine.TableDef, error) { 835 planDefs := tableDef.GetDefs() 836 var exeDefs []engine.TableDef 837 c := new(engine.ConstraintDef) 838 for _, def := range planDefs { 839 switch defVal := def.GetDef().(type) { 840 case *plan.TableDef_DefType_Properties: 841 properties := make([]engine.Property, len(defVal.Properties.GetProperties())) 842 for i, p := range defVal.Properties.GetProperties() { 843 properties[i] = engine.Property{ 844 Key: p.GetKey(), 845 Value: p.GetValue(), 846 } 847 } 848 exeDefs = append(exeDefs, &engine.PropertiesDef{ 849 Properties: properties, 850 }) 851 //case *plan.TableDef_DefType_UIdx: 852 // bytes, err := defVal.UIdx.MarshalUniqueIndexDef() 853 // if err != nil { 854 // return nil, err 855 // } 856 // c.Cts = append(c.Cts, &engine.UniqueIndexDef{ 857 // UniqueIndex: string(bytes), 858 // }) 859 //case *plan.TableDef_DefType_SIdx: 860 // bytes, err := defVal.SIdx.MarshalSecondaryIndexDef() 861 // if err != nil { 862 // return nil, err 863 // } 864 // c.Cts = append(c.Cts, &engine.SecondaryIndexDef{ 865 // SecondaryIndex: string(bytes), 866 // }) 867 } 868 } 869 870 if tableDef.Indexes != nil { 871 c.Cts = append(c.Cts, &engine.IndexDef{ 872 Indexes: tableDef.Indexes, 873 }) 874 875 //bytes, err := tableDef.Index.Marshal() 876 //if err != nil { 877 // return nil, err 878 //} 879 // 880 //c.Cts = append(c.Cts, &engine.IndexesDef{ 881 // Indexes: string(bytes), 882 //}) 883 } 884 885 if tableDef.Partition != nil { 886 bytes, err := tableDef.Partition.MarshalPartitionInfo() 887 if err != nil { 888 return nil, err 889 } 890 exeDefs = append(exeDefs, &engine.PartitionDef{ 891 Partition: string(bytes), 892 }) 893 } 894 895 if tableDef.ViewSql != nil { 896 exeDefs = append(exeDefs, &engine.ViewDef{ 897 View: tableDef.ViewSql.View, 898 }) 899 } 900 901 if len(tableDef.Fkeys) > 0 { 902 c.Cts = append(c.Cts, &engine.ForeignKeyDef{ 903 Fkeys: tableDef.Fkeys, 904 }) 905 } 906 907 if tableDef.Pkey != nil { 908 c.Cts = append(c.Cts, &engine.PrimaryKeyDef{ 909 Pkey: tableDef.Pkey, 910 }) 911 } 912 913 if len(tableDef.RefChildTbls) > 0 { 914 c.Cts = append(c.Cts, &engine.RefChildTableDef{ 915 Tables: tableDef.RefChildTbls, 916 }) 917 } 918 919 if len(c.Cts) > 0 { 920 exeDefs = append(exeDefs, c) 921 } 922 923 if tableDef.ClusterBy != nil { 924 exeDefs = append(exeDefs, &engine.ClusterByDef{ 925 Name: tableDef.ClusterBy.Name, 926 }) 927 } 928 return exeDefs, nil 929 } 930 931 func planColsToExeCols(planCols []*plan.ColDef) []engine.TableDef { 932 exeCols := make([]engine.TableDef, len(planCols)) 933 for i, col := range planCols { 934 var alg compress.T 935 switch col.Alg { 936 case plan.CompressType_None: 937 alg = compress.None 938 case plan.CompressType_Lz4: 939 alg = compress.Lz4 940 } 941 colTyp := col.GetTyp() 942 exeCols[i] = &engine.AttributeDef{ 943 Attr: engine.Attribute{ 944 Name: col.Name, 945 Alg: alg, 946 Type: types.Type{ 947 Oid: types.T(colTyp.GetId()), 948 Width: colTyp.GetWidth(), 949 Precision: colTyp.GetPrecision(), 950 Scale: colTyp.GetScale(), 951 Size: colTyp.GetSize(), 952 }, 953 Default: planCols[i].GetDefault(), 954 OnUpdate: planCols[i].GetOnUpdate(), 955 Primary: col.GetPrimary(), 956 Comment: col.GetComment(), 957 ClusterBy: col.ClusterBy, 958 AutoIncrement: col.Typ.GetAutoIncr(), 959 }, 960 } 961 } 962 return exeCols 963 } 964 965 // Get the required columns of the index table from the original table 966 func getIndexColsFromOriginTable(tblDefs []engine.TableDef, indexColumns []string) []string { 967 colNameMap := make(map[string]int) 968 for _, tbldef := range tblDefs { 969 if constraintDef, ok := tbldef.(*engine.ConstraintDef); ok { 970 for _, ct := range constraintDef.Cts { 971 if pk, ok2 := ct.(*engine.PrimaryKeyDef); ok2 { 972 for _, name := range pk.Pkey.Names { 973 colNameMap[name] = 1 974 } 975 break 976 } 977 } 978 } 979 } 980 981 for _, column := range indexColumns { 982 colNameMap[column] = 1 983 } 984 985 j := 0 986 keys := make([]string, len(colNameMap)) 987 for k := range colNameMap { 988 keys[j] = k 989 j++ 990 } 991 return keys 992 }