github.com/dolthub/go-mysql-server@v0.18.0/sql/rowexec/ddl_iters.go (about) 1 // Copyright 2023 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 "bufio" 19 "fmt" 20 "io" 21 "strings" 22 "sync" 23 "time" 24 25 "github.com/dolthub/vitess/go/mysql" 26 "github.com/dolthub/vitess/go/sqltypes" 27 "github.com/sirupsen/logrus" 28 "go.opentelemetry.io/otel/attribute" 29 "go.opentelemetry.io/otel/trace" 30 31 "github.com/dolthub/go-mysql-server/sql" 32 "github.com/dolthub/go-mysql-server/sql/expression" 33 "github.com/dolthub/go-mysql-server/sql/fulltext" 34 "github.com/dolthub/go-mysql-server/sql/mysql_db" 35 "github.com/dolthub/go-mysql-server/sql/plan" 36 "github.com/dolthub/go-mysql-server/sql/transform" 37 "github.com/dolthub/go-mysql-server/sql/types" 38 ) 39 40 type loadDataIter struct { 41 scanner *bufio.Scanner 42 destSch sql.Schema 43 reader io.ReadCloser 44 columnCount int 45 fieldToColumnMap []int 46 47 fieldsTerminatedBy string 48 fieldsEnclosedBy string 49 fieldsEnclosedByOpt bool 50 fieldsEscapedBy string 51 52 linesStartingBy string 53 linesTerminatedBy string 54 } 55 56 func (l loadDataIter) Next(ctx *sql.Context) (returnRow sql.Row, returnErr error) { 57 var exprs []sql.Expression 58 var err error 59 // If exprs is nil then this is a skipped line (see test cases). Keep skipping 60 // until exprs != nil 61 for exprs == nil { 62 keepGoing := l.scanner.Scan() 63 if !keepGoing { 64 if l.scanner.Err() != nil { 65 return nil, l.scanner.Err() 66 } 67 return nil, io.EOF 68 } 69 70 line := l.scanner.Text() 71 exprs, err = l.parseFields(ctx, line) 72 73 if err != nil { 74 return nil, err 75 } 76 } 77 78 row := make(sql.Row, len(exprs)) 79 var secondPass []int 80 for i, expr := range exprs { 81 if expr != nil { 82 if defaultVal, ok := expr.(*sql.ColumnDefaultValue); ok && !defaultVal.IsLiteral() { 83 secondPass = append(secondPass, i) 84 continue 85 } 86 row[i], err = expr.Eval(ctx, row) 87 if err != nil { 88 return nil, err 89 } 90 } 91 } 92 for _, index := range secondPass { 93 row[index], err = exprs[index].Eval(ctx, row) 94 if err != nil { 95 return nil, err 96 } 97 } 98 99 return sql.NewRow(row...), nil 100 } 101 102 func (l loadDataIter) Close(ctx *sql.Context) error { 103 return l.reader.Close() 104 } 105 106 // parseLinePrefix searches for the delim defined by linesStartingByDelim. 107 func (l loadDataIter) parseLinePrefix(line string) string { 108 if l.linesStartingBy == "" { 109 return line 110 } 111 112 prefixIndex := strings.Index(line, l.linesStartingBy) 113 114 // The prefix wasn't found so we need to skip this line. 115 if prefixIndex < 0 { 116 return "" 117 } else { 118 return line[prefixIndex+len(l.linesStartingBy):] 119 } 120 } 121 122 func (l loadDataIter) parseFields(ctx *sql.Context, line string) ([]sql.Expression, error) { 123 // Step 1. Start by Searching for prefix if there is one 124 line = l.parseLinePrefix(line) 125 if line == "" { 126 return nil, nil 127 } 128 129 // Step 2: Split the lines into fields given the delim 130 fields := strings.Split(line, l.fieldsTerminatedBy) 131 132 // Step 3: Go through each field and see if it was enclosed by something 133 // TODO: Support the OPTIONALLY parameter. 134 if l.fieldsEnclosedBy != "" { 135 for i, field := range fields { 136 if string(field[0]) == l.fieldsEnclosedBy && string(field[len(field)-1]) == l.fieldsEnclosedBy { 137 fields[i] = field[1 : len(field)-1] 138 } else { 139 return nil, fmt.Errorf("error: field not properly enclosed") 140 } 141 } 142 } 143 144 //Step 4: Handle the ESCAPED BY parameter. 145 if l.fieldsEscapedBy != "" { 146 for i, field := range fields { 147 if field == "\\N" { 148 fields[i] = "NULL" 149 } else if field == "\\Z" { 150 fields[i] = fmt.Sprintf("%c", 26) // ASCII 26 151 } else if field == "\\0" { 152 fields[i] = fmt.Sprintf("%c", 0) // ASCII 0 153 } else { 154 fields[i] = strings.ReplaceAll(field, l.fieldsEscapedBy, "") 155 } 156 } 157 } 158 159 exprs := make([]sql.Expression, len(l.destSch)) 160 161 limit := len(exprs) 162 if len(fields) < limit { 163 limit = len(fields) 164 } 165 166 destSch := l.destSch 167 for i := 0; i < limit; i++ { 168 field := fields[i] 169 destCol := destSch[l.fieldToColumnMap[i]] 170 // Replace the empty string with defaults 171 if field == "" { 172 _, ok := destCol.Type.(sql.StringType) 173 if !ok { 174 if destCol.Default != nil { 175 exprs[i] = destCol.Default 176 } else { 177 exprs[i] = expression.NewLiteral(nil, types.Null) 178 } 179 } else { 180 exprs[i] = expression.NewLiteral(field, types.LongText) 181 } 182 } else if field == "NULL" { 183 exprs[i] = expression.NewLiteral(nil, types.Null) 184 } else { 185 exprs[i] = expression.NewLiteral(field, types.LongText) 186 } 187 } 188 189 // Due to how projections work, if no columns are provided (each row may have a variable number of values), the 190 // projection will not insert default values, so we must do it here. 191 if l.columnCount == 0 { 192 for i, expr := range exprs { 193 if expr == nil && destSch[i].Default != nil { 194 f := destSch[i] 195 if !f.Nullable && f.Default == nil && !f.AutoIncrement { 196 return nil, sql.ErrInsertIntoNonNullableDefaultNullColumn.New(f.Name) 197 } 198 var def sql.Expression = f.Default 199 var err error 200 colIdx := make(map[string]int) 201 for i, c := range l.destSch { 202 colIdx[fmt.Sprintf("%s.%s", strings.ToLower(c.Source), strings.ToLower(c.Name))] = i 203 } 204 def, _, err = transform.Expr(f.Default, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) { 205 switch e := e.(type) { 206 case *expression.GetField: 207 idx, ok := colIdx[strings.ToLower(e.String())] 208 if !ok { 209 return nil, transform.SameTree, fmt.Errorf("field not found: %s", e.String()) 210 } 211 return e.WithIndex(idx), transform.NewTree, nil 212 default: 213 return e, transform.SameTree, nil 214 } 215 }) 216 if err != nil { 217 return nil, err 218 } 219 exprs[i] = def 220 } 221 } 222 } 223 224 return exprs, nil 225 } 226 227 type modifyColumnIter struct { 228 m *plan.ModifyColumn 229 alterable sql.AlterableTable 230 runOnce bool 231 } 232 233 func (i *modifyColumnIter) Next(ctx *sql.Context) (sql.Row, error) { 234 if i.runOnce { 235 return nil, io.EOF 236 } 237 i.runOnce = true 238 239 idx := i.m.TargetSchema().IndexOf(i.m.Column(), i.alterable.Name()) 240 if idx < 0 { 241 return nil, sql.ErrTableColumnNotFound.New(i.alterable.Name(), i.m.Column()) 242 } 243 244 if i.m.Order() != nil && !i.m.Order().First { 245 idx = i.m.TargetSchema().IndexOf(i.m.Order().AfterColumn, i.alterable.Name()) 246 if idx < 0 { 247 return nil, sql.ErrTableColumnNotFound.New(i.alterable.Name(), i.m.Order().AfterColumn) 248 } 249 } 250 251 lowerColName := strings.ToLower(i.m.Column()) 252 253 // Update the foreign key columns as well 254 if fkTable, ok := i.alterable.(sql.ForeignKeyTable); ok { 255 // We only care if the column is used in a foreign key 256 usedInFk := false 257 fks, err := fkTable.GetDeclaredForeignKeys(ctx) 258 if err != nil { 259 return nil, err 260 } 261 parentFks, err := fkTable.GetReferencedForeignKeys(ctx) 262 if err != nil { 263 return nil, err 264 } 265 OuterChildFk: 266 for _, foreignKey := range fks { 267 for _, colName := range foreignKey.Columns { 268 if strings.ToLower(colName) == lowerColName { 269 usedInFk = true 270 break OuterChildFk 271 } 272 } 273 } 274 if !usedInFk { 275 OuterParentFk: 276 for _, foreignKey := range parentFks { 277 for _, colName := range foreignKey.ParentColumns { 278 if strings.ToLower(colName) == lowerColName { 279 usedInFk = true 280 break OuterParentFk 281 } 282 } 283 } 284 } 285 286 tblSch := i.m.TargetSchema() 287 if usedInFk { 288 if !i.m.TargetSchema()[idx].Type.Equals(i.m.NewColumn().Type) { 289 // There seems to be a special case where you can lengthen a CHAR/VARCHAR/BINARY/VARBINARY. 290 // Have not tested every type nor combination, but this seems specific to those 4 types. 291 if tblSch[idx].Type.Type() == i.m.NewColumn().Type.Type() { 292 switch i.m.NewColumn().Type.Type() { 293 case sqltypes.Char, sqltypes.VarChar, sqltypes.Binary, sqltypes.VarBinary: 294 oldType := tblSch[idx].Type.(sql.StringType) 295 newType := i.m.NewColumn().Type.(sql.StringType) 296 if oldType.Collation() != newType.Collation() || oldType.MaxCharacterLength() > newType.MaxCharacterLength() { 297 return nil, sql.ErrForeignKeyTypeChange.New(i.m.Column()) 298 } 299 default: 300 return nil, sql.ErrForeignKeyTypeChange.New(i.m.Column()) 301 } 302 } else { 303 return nil, sql.ErrForeignKeyTypeChange.New(i.m.Column()) 304 } 305 } 306 if !i.m.NewColumn().Nullable { 307 lowerColName := strings.ToLower(i.m.Column()) 308 for _, fk := range fks { 309 if fk.OnUpdate == sql.ForeignKeyReferentialAction_SetNull || fk.OnDelete == sql.ForeignKeyReferentialAction_SetNull { 310 for _, col := range fk.Columns { 311 if lowerColName == strings.ToLower(col) { 312 return nil, sql.ErrForeignKeyTypeChangeSetNull.New(i.m.Column(), fk.Name) 313 } 314 } 315 } 316 } 317 } 318 err = handleFkColumnRename(ctx, fkTable, i.m.Db, i.m.Column(), i.m.NewColumn().Name) 319 if err != nil { 320 return nil, err 321 } 322 } 323 } 324 325 // Full-Text indexes will need to be rebuilt 326 hasFullText := hasFullText(ctx, i.alterable) 327 328 // TODO: replace with different node in analyzer 329 if rwt, ok := i.alterable.(sql.RewritableTable); ok { 330 rewritten, err := i.rewriteTable(ctx, rwt) 331 if err != nil { 332 return nil, err 333 } 334 if rewritten { 335 return sql.NewRow(types.NewOkResult(0)), nil 336 } 337 } 338 339 // TODO: fix me 340 if err := updateDefaultsOnColumnRename(ctx, i.alterable, i.m.TargetSchema(), i.m.Column(), i.m.NewColumn().Name); err != nil { 341 return nil, err 342 } 343 344 err := i.alterable.ModifyColumn(ctx, i.m.Column(), i.m.NewColumn(), i.m.Order()) 345 if err != nil { 346 return nil, err 347 } 348 349 if hasFullText { 350 if err = rebuildFullText(ctx, i.alterable.Name(), i.m.Db); err != nil { 351 return nil, err 352 } 353 } 354 return sql.NewRow(types.NewOkResult(0)), nil 355 } 356 357 func handleFkColumnRename(ctx *sql.Context, fkTable sql.ForeignKeyTable, db sql.Database, oldName string, newName string) error { 358 lowerOldName := strings.ToLower(oldName) 359 if lowerOldName == strings.ToLower(newName) { 360 return nil 361 } 362 363 parentFks, err := fkTable.GetReferencedForeignKeys(ctx) 364 if err != nil { 365 return err 366 } 367 if len(parentFks) > 0 { 368 dbName := strings.ToLower(db.Name()) 369 for _, parentFk := range parentFks { 370 //TODO: add support for multi db foreign keys 371 if dbName != strings.ToLower(parentFk.ParentDatabase) { 372 return fmt.Errorf("renaming columns involved in foreign keys referencing a different database" + 373 " is not yet supported") 374 } 375 shouldUpdate := false 376 for i, col := range parentFk.ParentColumns { 377 if strings.ToLower(col) == lowerOldName { 378 parentFk.ParentColumns[i] = newName 379 shouldUpdate = true 380 } 381 } 382 if shouldUpdate { 383 childTable, ok, err := db.GetTableInsensitive(ctx, parentFk.Table) 384 if err != nil { 385 return err 386 } 387 if !ok { 388 return sql.ErrTableNotFound.New(parentFk.Table) 389 } 390 err = childTable.(sql.ForeignKeyTable).UpdateForeignKey(ctx, parentFk.Name, parentFk) 391 if err != nil { 392 return err 393 } 394 } 395 } 396 } 397 398 fks, err := fkTable.GetDeclaredForeignKeys(ctx) 399 if err != nil { 400 return err 401 } 402 for _, fk := range fks { 403 shouldUpdate := false 404 for i, col := range fk.Columns { 405 if strings.ToLower(col) == lowerOldName { 406 fk.Columns[i] = newName 407 shouldUpdate = true 408 } 409 } 410 if shouldUpdate { 411 err = fkTable.UpdateForeignKey(ctx, fk.Name, fk) 412 if err != nil { 413 return err 414 } 415 } 416 } 417 return nil 418 } 419 420 // updateDefaultsOnColumnRename updates each column that references the old column name within its default value. 421 func updateDefaultsOnColumnRename(ctx *sql.Context, tbl sql.AlterableTable, schema sql.Schema, oldName, newName string) error { 422 if oldName == newName { 423 return nil 424 } 425 var err error 426 colsToModify := make(map[*sql.Column]struct{}) 427 for _, col := range schema { 428 if col.Default == nil { 429 continue 430 } 431 newCol := *col 432 newCol.Default.Expr, _, err = transform.Expr(col.Default.Expr, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) { 433 if expr, ok := e.(*expression.GetField); ok { 434 if strings.ToLower(expr.Name()) == oldName { 435 colsToModify[&newCol] = struct{}{} 436 return expr.WithName(newName), transform.NewTree, nil 437 } 438 } 439 return e, transform.SameTree, nil 440 }) 441 if err != nil { 442 return err 443 } 444 } 445 for col := range colsToModify { 446 err := tbl.ModifyColumn(ctx, col.Name, col, nil) 447 if err != nil { 448 return err 449 } 450 } 451 return nil 452 } 453 454 func (i *modifyColumnIter) Close(context *sql.Context) error { 455 return nil 456 } 457 458 // rewriteTable rewrites the table given if required or requested, and returns whether it was rewritten 459 func (i *modifyColumnIter) rewriteTable(ctx *sql.Context, rwt sql.RewritableTable) (bool, error) { 460 oldColIdx := i.m.TargetSchema().IndexOfColName(i.m.Column()) 461 if oldColIdx == -1 { 462 // Should be impossible, checked in analyzer 463 return false, sql.ErrTableColumnNotFound.New(rwt.Name(), i.m.Column()) 464 } 465 466 newSch, projections, err := modifyColumnInSchema(i.m.TargetSchema(), i.m.Column(), i.m.NewColumn(), i.m.Order()) 467 if err != nil { 468 return false, err 469 } 470 471 // Wrap any auto increment columns in auto increment expressions. This mirrors what happens to row sources for normal 472 // INSERT statements during analysis. 473 for i, col := range newSch { 474 if col.AutoIncrement { 475 projections[i], err = expression.NewAutoIncrementForColumn(ctx, rwt, col, projections[i]) 476 if err != nil { 477 return false, err 478 } 479 } 480 } 481 482 var renames []sql.ColumnRename 483 if i.m.Column() != i.m.NewColumn().Name { 484 renames = []sql.ColumnRename{{ 485 Before: i.m.Column(), After: i.m.NewColumn().Name, 486 }} 487 } 488 489 oldPkSchema := sql.SchemaToPrimaryKeySchema(rwt, rwt.Schema()) 490 newPkSchema := sql.SchemaToPrimaryKeySchema(rwt, newSch, renames...) 491 492 rewriteRequired := false 493 if i.m.TargetSchema()[oldColIdx].Nullable && !i.m.NewColumn().Nullable { 494 rewriteRequired = true 495 } 496 497 // TODO: codify rewrite requirements 498 rewriteRequested := rwt.ShouldRewriteTable(ctx, oldPkSchema, newPkSchema, i.m.TargetSchema()[oldColIdx], i.m.NewColumn()) 499 if !rewriteRequired && !rewriteRequested { 500 return false, nil 501 } 502 503 inserter, err := rwt.RewriteInserter(ctx, oldPkSchema, newPkSchema, i.m.TargetSchema()[oldColIdx], i.m.NewColumn(), nil) 504 if err != nil { 505 return false, err 506 } 507 508 partitions, err := rwt.Partitions(ctx) 509 if err != nil { 510 return false, err 511 } 512 513 rowIter := sql.NewTableRowIter(ctx, rwt, partitions) 514 515 for { 516 r, err := rowIter.Next(ctx) 517 if err == io.EOF { 518 break 519 } else if err != nil { 520 _ = inserter.DiscardChanges(ctx, err) 521 _ = inserter.Close(ctx) 522 return false, err 523 } 524 525 newRow, err := projectRowWithTypes(ctx, newSch, projections, r) 526 if err != nil { 527 _ = inserter.DiscardChanges(ctx, err) 528 _ = inserter.Close(ctx) 529 return false, err 530 } 531 532 err = i.validateNullability(ctx, newSch, newRow) 533 if err != nil { 534 _ = inserter.DiscardChanges(ctx, err) 535 _ = inserter.Close(ctx) 536 return false, err 537 } 538 539 err = inserter.Insert(ctx, newRow) 540 if err != nil { 541 _ = inserter.DiscardChanges(ctx, err) 542 _ = inserter.Close(ctx) 543 return false, err 544 } 545 } 546 547 // TODO: move this into iter.close, probably 548 err = inserter.Close(ctx) 549 if err != nil { 550 return false, err 551 } 552 553 return true, nil 554 } 555 556 // modifyColumnInSchema modifies the given column in given schema and returns the new schema, along with a set of 557 // projections to adapt the old schema to the new one. 558 func modifyColumnInSchema(schema sql.Schema, name string, column *sql.Column, order *sql.ColumnOrder) (sql.Schema, []sql.Expression, error) { 559 schema = schema.Copy() 560 currIdx := schema.IndexOf(name, column.Source) 561 if currIdx < 0 { 562 // Should be checked in the analyzer already 563 return nil, nil, sql.ErrTableColumnNotFound.New(column.Source, name) 564 } 565 566 // Primary key-ness isn't included in the column description as part of the ALTER statement, preserve it 567 if schema[currIdx].PrimaryKey { 568 column.PrimaryKey = true 569 } 570 571 newIdx := currIdx 572 if order != nil && len(order.AfterColumn) > 0 { 573 newIdx = schema.IndexOf(order.AfterColumn, column.Source) 574 if newIdx == -1 { 575 // Should be checked in the analyzer already 576 return nil, nil, sql.ErrTableColumnNotFound.New(column.Source, order.AfterColumn) 577 } 578 // if we're moving left in the schema, shift everything over one 579 if newIdx < currIdx { 580 newIdx++ 581 } 582 } else if order != nil && order.First { 583 newIdx = 0 584 } 585 586 // establish a map from old column index to new column index 587 oldToNewIdxMapping := make(map[int]int) 588 var i, j int 589 for j < len(schema) || i < len(schema) { 590 if i == currIdx { 591 oldToNewIdxMapping[i] = newIdx 592 i++ 593 } else if j == newIdx { 594 j++ 595 } else { 596 oldToNewIdxMapping[i] = j 597 i, j = i+1, j+1 598 } 599 } 600 601 // Now build the new schema, keeping track of: 602 // 1) The new result schema 603 // 2) A set of projections to translate rows in the old schema to rows in the new schema 604 newSch := make(sql.Schema, len(schema)) 605 projections := make([]sql.Expression, len(schema)) 606 607 for i := range schema { 608 j := oldToNewIdxMapping[i] 609 oldCol := schema[i] 610 c := oldCol 611 if j == newIdx { 612 c = column 613 } 614 newSch[j] = c 615 projections[j] = expression.NewGetField(i, oldCol.Type, oldCol.Name, oldCol.Nullable) 616 } 617 618 // If a column was renamed or moved, we need to update any column defaults that refer to it 619 for i := range newSch { 620 newCol := newSch[oldToNewIdxMapping[i]] 621 622 if newCol.Default != nil { 623 newDefault, _, err := transform.Expr(newCol.Default.Expr, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) { 624 gf, ok := e.(*expression.GetField) 625 if !ok { 626 return e, transform.SameTree, nil 627 } 628 629 colName := gf.Name() 630 // handle column renames 631 if strings.ToLower(colName) == strings.ToLower(name) { 632 colName = column.Name 633 } 634 635 newSchemaIdx := newSch.IndexOfColName(colName) 636 if newSchemaIdx == -1 { 637 return nil, transform.SameTree, sql.ErrColumnNotFound.New(colName) 638 } 639 return expression.NewGetFieldWithTable(newSchemaIdx, int(gf.TableId()), gf.Type(), gf.Database(), gf.Table(), colName, gf.IsNullable()), transform.NewTree, nil 640 }) 641 if err != nil { 642 return nil, nil, err 643 } 644 645 newDefault, err = newCol.Default.WithChildren(newDefault) 646 if err != nil { 647 return nil, nil, err 648 } 649 650 newCol.Default = newDefault.(*sql.ColumnDefaultValue) 651 } 652 } 653 654 // TODO: do we need col defaults here? probably when changing a column to be non-null? 655 return newSch, projections, nil 656 } 657 658 // TODO: this shares logic with insert 659 func (i *modifyColumnIter) validateNullability(ctx *sql.Context, dstSchema sql.Schema, row sql.Row) error { 660 for count, col := range dstSchema { 661 if !col.Nullable && row[count] == nil { 662 return sql.ErrInsertIntoNonNullableProvidedNull.New(col.Name) 663 } 664 } 665 return nil 666 } 667 668 func createIndex( 669 ctx *sql.Context, 670 log *logrus.Entry, 671 driver sql.IndexDriver, 672 index sql.DriverIndex, 673 iter sql.PartitionIndexKeyValueIter, 674 done chan<- struct{}, 675 ready <-chan struct{}, 676 ) { 677 span, ctx := ctx.Span("plan.createIndex", 678 trace.WithAttributes( 679 attribute.String("index", index.ID()), 680 attribute.String("table", index.Table()), 681 attribute.String("driver", index.Driver()), 682 ), 683 ) 684 defer span.End() 685 686 l := log.WithField("id", index.ID()) 687 688 err := driver.Save(ctx, index, newLoggingPartitionKeyValueIter(l, iter)) 689 close(done) 690 691 if err != nil { 692 span.RecordError(err) 693 694 ctx.Error(0, "unable to save the index: %s", err) 695 logrus.WithField("err", err).Error("unable to save the index") 696 697 deleted, err := ctx.GetIndexRegistry().DeleteIndex(index.Database(), index.ID(), true) 698 if err != nil { 699 ctx.Error(0, "unable to delete index: %s", err) 700 logrus.WithField("err", err).Error("unable to delete the index") 701 } else { 702 <-deleted 703 } 704 } else { 705 <-ready 706 log.Info("index successfully created") 707 } 708 } 709 710 type EvalPartitionKeyValueIter struct { 711 iter sql.PartitionIndexKeyValueIter 712 columns []string 713 exprs []sql.Expression 714 } 715 716 func NewEvalPartitionKeyValueIter(iter sql.PartitionIndexKeyValueIter, columns []string, exprs []sql.Expression) *EvalPartitionKeyValueIter { 717 return &EvalPartitionKeyValueIter{ 718 iter: iter, 719 columns: columns, 720 exprs: exprs, 721 } 722 } 723 724 func (i *EvalPartitionKeyValueIter) Next(ctx *sql.Context) (sql.Partition, sql.IndexKeyValueIter, error) { 725 p, iter, err := i.iter.Next(ctx) 726 if err != nil { 727 return nil, nil, err 728 } 729 730 return p, &evalKeyValueIter{ 731 columns: i.columns, 732 exprs: i.exprs, 733 iter: iter, 734 }, nil 735 } 736 737 func (i *EvalPartitionKeyValueIter) Close(ctx *sql.Context) error { 738 return i.iter.Close(ctx) 739 } 740 741 type evalKeyValueIter struct { 742 iter sql.IndexKeyValueIter 743 columns []string 744 exprs []sql.Expression 745 } 746 747 func (i *evalKeyValueIter) Next(ctx *sql.Context) ([]interface{}, []byte, error) { 748 vals, loc, err := i.iter.Next(ctx) 749 if err != nil { 750 return nil, nil, err 751 } 752 753 row := sql.NewRow(vals...) 754 evals := make([]interface{}, len(i.exprs)) 755 for j, ex := range i.exprs { 756 eval, err := ex.Eval(ctx, row) 757 if err != nil { 758 return nil, nil, err 759 } 760 761 evals[j] = eval 762 } 763 764 return evals, loc, nil 765 } 766 767 func (i *evalKeyValueIter) Close(ctx *sql.Context) error { 768 return i.iter.Close(ctx) 769 } 770 771 type loggingPartitionKeyValueIter struct { 772 log *logrus.Entry 773 iter sql.PartitionIndexKeyValueIter 774 rows uint64 775 } 776 777 func newLoggingPartitionKeyValueIter( 778 log *logrus.Entry, 779 iter sql.PartitionIndexKeyValueIter, 780 ) *loggingPartitionKeyValueIter { 781 return &loggingPartitionKeyValueIter{ 782 log: log, 783 iter: iter, 784 } 785 } 786 787 func (i *loggingPartitionKeyValueIter) Next(ctx *sql.Context) (sql.Partition, sql.IndexKeyValueIter, error) { 788 p, iter, err := i.iter.Next(ctx) 789 if err != nil { 790 return nil, nil, err 791 } 792 793 return p, newLoggingKeyValueIter(i.log, iter, &i.rows), nil 794 } 795 796 func (i *loggingPartitionKeyValueIter) Close(ctx *sql.Context) error { 797 return i.iter.Close(ctx) 798 } 799 800 type loggingKeyValueIter struct { 801 span trace.Span 802 log *logrus.Entry 803 iter sql.IndexKeyValueIter 804 rows *uint64 805 start time.Time 806 } 807 808 func newLoggingKeyValueIter( 809 log *logrus.Entry, 810 iter sql.IndexKeyValueIter, 811 rows *uint64, 812 ) *loggingKeyValueIter { 813 return &loggingKeyValueIter{ 814 log: log, 815 iter: iter, 816 start: time.Now(), 817 rows: rows, 818 } 819 } 820 821 func (i *loggingKeyValueIter) Next(ctx *sql.Context) ([]interface{}, []byte, error) { 822 if i.span == nil { 823 i.span, ctx = ctx.Span("plan.createIndex.iterator", trace.WithAttributes(attribute.Int64("start", int64(*i.rows)))) 824 } 825 826 (*i.rows)++ 827 if *i.rows%sql.IndexBatchSize == 0 { 828 duration := time.Since(i.start) 829 830 i.log.WithFields(logrus.Fields{ 831 "duration": duration, 832 "rows": *i.rows, 833 }).Debugf("still creating index") 834 835 if i.span != nil { 836 i.span.SetAttributes(attribute.Stringer("duration", duration)) 837 i.span.End() 838 i.span = nil 839 } 840 841 i.start = time.Now() 842 } 843 844 val, loc, err := i.iter.Next(ctx) 845 if err != nil { 846 i.span.RecordError(err) 847 i.span.End() 848 i.span = nil 849 } 850 851 return val, loc, err 852 } 853 854 func (i *loggingKeyValueIter) Close(ctx *sql.Context) error { 855 return i.iter.Close(ctx) 856 } 857 858 // projectRowWithTypes projects the row given with the projections given and additionally converts them to the 859 // corresponding types found in the schema given, using the standard type conversion logic. 860 func projectRowWithTypes(ctx *sql.Context, sch sql.Schema, projections []sql.Expression, r sql.Row) (sql.Row, error) { 861 newRow, err := ProjectRow(ctx, projections, r) 862 if err != nil { 863 return nil, err 864 } 865 866 for i := range newRow { 867 converted, inRange, err := sch[i].Type.Convert(newRow[i]) 868 if err != nil { 869 if sql.ErrNotMatchingSRID.Is(err) { 870 err = sql.ErrNotMatchingSRIDWithColName.New(sch[i].Name, err) 871 } 872 return nil, err 873 } else if !inRange { 874 return nil, sql.ErrValueOutOfRange.New(newRow[i], sch[i].Type) 875 } 876 newRow[i] = converted 877 } 878 879 return newRow, nil 880 } 881 882 // getTableFromDatabase returns table named from the database provided 883 func getTableFromDatabase(ctx *sql.Context, db sql.Database, tableNode sql.Node) (sql.Table, error) { 884 // Grab the table fresh from the database. 885 tableName := getTableName(tableNode) 886 887 table, ok, err := db.GetTableInsensitive(ctx, tableName) 888 if err != nil { 889 return nil, err 890 } 891 if !ok { 892 return nil, sql.ErrTableNotFound.New(tableName) 893 } 894 895 return table, nil 896 } 897 898 // getTableName attempts to fetch the table name from the node. If not found directly on the node, searches the 899 // children. Returns the first table name found, regardless of whether there are more, therefore this is only intended 900 // to be used in situations where only a single table is expected to be found. 901 func getTableName(nodeToSearch sql.Node) string { 902 nodeStack := []sql.Node{nodeToSearch} 903 for len(nodeStack) > 0 { 904 node := nodeStack[len(nodeStack)-1] 905 nodeStack = nodeStack[:len(nodeStack)-1] 906 switch n := node.(type) { 907 case *plan.TableAlias: 908 if n.UnaryNode != nil { 909 nodeStack = append(nodeStack, n.UnaryNode.Child) 910 continue 911 } 912 case *plan.ResolvedTable: 913 return n.Table.Name() 914 case *plan.UnresolvedTable: 915 return n.Name() 916 case *plan.IndexedTableAccess: 917 return n.Name() 918 case sql.TableWrapper: 919 return n.Underlying().Name() 920 } 921 nodeStack = append(nodeStack, node.Children()...) 922 } 923 return "" 924 } 925 926 func getIndexableTable(t sql.Table) (sql.DriverIndexableTable, error) { 927 switch t := t.(type) { 928 case sql.DriverIndexableTable: 929 return t, nil 930 case sql.TableWrapper: 931 return getIndexableTable(t.Underlying()) 932 default: 933 return nil, plan.ErrNotIndexable.New() 934 } 935 } 936 937 func getChecksumable(t sql.Table) sql.Checksumable { 938 switch t := t.(type) { 939 case sql.Checksumable: 940 return t 941 case sql.TableWrapper: 942 return getChecksumable(t.Underlying()) 943 default: 944 return nil 945 } 946 } 947 948 // GetColumnsAndPrepareExpressions extracts the unique columns required by all 949 // those expressions and fixes the indexes of the GetFields in the expressions 950 // to match a row with only the returned columns in that same order. 951 func GetColumnsAndPrepareExpressions( 952 exprs []sql.Expression, 953 ) ([]string, []sql.Expression, error) { 954 var columns []string 955 var seen = make(map[string]int) 956 var expressions = make([]sql.Expression, len(exprs)) 957 958 for i, e := range exprs { 959 ex, _, err := transform.Expr(e, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) { 960 gf, ok := e.(*expression.GetField) 961 if !ok { 962 return e, transform.SameTree, nil 963 } 964 965 var idx int 966 if j, ok := seen[gf.Name()]; ok { 967 idx = j 968 } else { 969 idx = len(columns) 970 columns = append(columns, gf.Name()) 971 seen[gf.Name()] = idx 972 } 973 974 return expression.NewGetFieldWithTable(idx, int(gf.TableId()), gf.Type(), gf.Database(), gf.Table(), gf.Name(), gf.IsNullable()), transform.NewTree, nil 975 }) 976 977 if err != nil { 978 return nil, nil, err 979 } 980 981 expressions[i] = ex 982 } 983 984 return columns, expressions, nil 985 } 986 987 type createPkIter struct { 988 targetSchema sql.Schema 989 columns []sql.IndexColumn 990 pkAlterable sql.PrimaryKeyAlterableTable 991 db sql.Database 992 runOnce bool 993 } 994 995 func (c *createPkIter) Next(ctx *sql.Context) (sql.Row, error) { 996 if c.runOnce { 997 return nil, io.EOF 998 } 999 c.runOnce = true 1000 1001 // Full-Text indexes will need to be rebuilt 1002 hasFullText := hasFullText(ctx, c.pkAlterable) 1003 1004 if rwt, ok := c.pkAlterable.(sql.RewritableTable); ok { 1005 err := c.rewriteTable(ctx, rwt) 1006 if err != nil { 1007 return nil, err 1008 } 1009 return sql.NewRow(types.NewOkResult(0)), nil 1010 } 1011 1012 err := c.pkAlterable.CreatePrimaryKey(ctx, c.columns) 1013 if err != nil { 1014 return nil, err 1015 } 1016 1017 if hasFullText { 1018 if err = rebuildFullText(ctx, c.pkAlterable.Name(), c.db); err != nil { 1019 return nil, err 1020 } 1021 } 1022 return sql.NewRow(types.NewOkResult(0)), nil 1023 } 1024 1025 func (c createPkIter) Close(context *sql.Context) error { 1026 return nil 1027 } 1028 1029 func (c *createPkIter) rewriteTable(ctx *sql.Context, rwt sql.RewritableTable) error { 1030 newSchema := addKeyToSchema(rwt.Name(), c.targetSchema, c.columns) 1031 1032 oldPkSchema, newPkSchema := sql.SchemaToPrimaryKeySchema(rwt, rwt.Schema()), newSchema 1033 1034 inserter, err := rwt.RewriteInserter(ctx, oldPkSchema, newPkSchema, nil, nil, c.columns) 1035 if err != nil { 1036 return err 1037 } 1038 1039 partitions, err := rwt.Partitions(ctx) 1040 if err != nil { 1041 return err 1042 } 1043 1044 rowIter := sql.NewTableRowIter(ctx, rwt, partitions) 1045 1046 for { 1047 r, err := rowIter.Next(ctx) 1048 if err == io.EOF { 1049 break 1050 } else if err != nil { 1051 _ = inserter.DiscardChanges(ctx, err) 1052 _ = inserter.Close(ctx) 1053 return err 1054 } 1055 1056 // check for null values in the primary key insert 1057 for _, i := range newSchema.PkOrdinals { 1058 if r[i] == nil { 1059 return sql.ErrInsertIntoNonNullableProvidedNull.New(newSchema.Schema[i].Name) 1060 } 1061 } 1062 1063 err = inserter.Insert(ctx, r) 1064 if err != nil { 1065 _ = inserter.DiscardChanges(ctx, err) 1066 _ = inserter.Close(ctx) 1067 return err 1068 } 1069 } 1070 1071 // TODO: move this into iter.close, probably 1072 err = inserter.Close(ctx) 1073 if err != nil { 1074 return err 1075 } 1076 1077 return nil 1078 } 1079 1080 func addKeyToSchema(tableName string, schema sql.Schema, columns []sql.IndexColumn) sql.PrimaryKeySchema { 1081 newSch := schema.Copy() 1082 ordinals := make([]int, len(columns)) 1083 for i := range columns { 1084 idx := schema.IndexOf(columns[i].Name, tableName) 1085 ordinals[i] = idx 1086 newSch[idx].PrimaryKey = true 1087 newSch[idx].Nullable = false 1088 } 1089 return sql.NewPrimaryKeySchema(newSch, ordinals...) 1090 } 1091 1092 type dropPkIter struct { 1093 targetSchema sql.Schema 1094 pkAlterable sql.PrimaryKeyAlterableTable 1095 db sql.Database 1096 runOnce bool 1097 } 1098 1099 func (d *dropPkIter) Next(ctx *sql.Context) (sql.Row, error) { 1100 if d.runOnce { 1101 return nil, io.EOF 1102 } 1103 d.runOnce = true 1104 1105 // Full-Text indexes will need to be rebuilt 1106 hasFullText := hasFullText(ctx, d.pkAlterable) 1107 1108 if rwt, ok := d.pkAlterable.(sql.RewritableTable); ok { 1109 err := d.rewriteTable(ctx, rwt) 1110 if err != nil { 1111 return nil, err 1112 } 1113 return sql.NewRow(types.NewOkResult(0)), nil 1114 } 1115 1116 err := d.pkAlterable.DropPrimaryKey(ctx) 1117 if err != nil { 1118 return nil, err 1119 } 1120 1121 if hasFullText { 1122 if err = rebuildFullText(ctx, d.pkAlterable.Name(), d.db); err != nil { 1123 return nil, err 1124 } 1125 } 1126 return sql.NewRow(types.NewOkResult(0)), nil 1127 } 1128 1129 func (d *dropPkIter) Close(context *sql.Context) error { 1130 return nil 1131 } 1132 1133 func (d *dropPkIter) rewriteTable(ctx *sql.Context, rwt sql.RewritableTable) error { 1134 newSchema := dropKeyFromSchema(d.targetSchema) 1135 1136 oldPkSchema, newPkSchema := sql.SchemaToPrimaryKeySchema(rwt, rwt.Schema()), newSchema 1137 1138 inserter, err := rwt.RewriteInserter(ctx, oldPkSchema, newPkSchema, nil, nil, nil) 1139 if err != nil { 1140 return err 1141 } 1142 1143 partitions, err := rwt.Partitions(ctx) 1144 if err != nil { 1145 return err 1146 } 1147 1148 rowIter := sql.NewTableRowIter(ctx, rwt, partitions) 1149 1150 for { 1151 r, err := rowIter.Next(ctx) 1152 if err == io.EOF { 1153 break 1154 } else if err != nil { 1155 _ = inserter.DiscardChanges(ctx, err) 1156 _ = inserter.Close(ctx) 1157 return err 1158 } 1159 1160 err = inserter.Insert(ctx, r) 1161 if err != nil { 1162 _ = inserter.DiscardChanges(ctx, err) 1163 _ = inserter.Close(ctx) 1164 return err 1165 } 1166 } 1167 1168 // TODO: move this into iter.close, probably 1169 err = inserter.Close(ctx) 1170 if err != nil { 1171 return err 1172 } 1173 1174 hasFullText := hasFullText(ctx, d.pkAlterable) 1175 if hasFullText { 1176 if err = rebuildFullText(ctx, d.pkAlterable.Name(), d.db); err != nil { 1177 return err 1178 } 1179 } 1180 1181 return nil 1182 } 1183 1184 func dropKeyFromSchema(schema sql.Schema) sql.PrimaryKeySchema { 1185 newSch := schema.Copy() 1186 for i := range newSch { 1187 newSch[i].PrimaryKey = false 1188 } 1189 1190 return sql.NewPrimaryKeySchema(newSch) 1191 } 1192 1193 type addColumnIter struct { 1194 a *plan.AddColumn 1195 alterable sql.AlterableTable 1196 runOnce bool 1197 b *BaseBuilder 1198 } 1199 1200 func (i *addColumnIter) Next(ctx *sql.Context) (sql.Row, error) { 1201 if i.runOnce { 1202 return nil, io.EOF 1203 } 1204 i.runOnce = true 1205 1206 // Full-Text indexes will need to be rebuilt 1207 hasFullText := hasFullText(ctx, i.alterable) 1208 1209 rwt, ok := i.alterable.(sql.RewritableTable) 1210 if ok { 1211 rewritten, err := i.rewriteTable(ctx, rwt) 1212 if err != nil { 1213 return nil, err 1214 } 1215 if rewritten { 1216 return sql.NewRow(types.NewOkResult(0)), nil 1217 } 1218 } 1219 1220 err := i.alterable.AddColumn(ctx, i.a.Column(), i.a.Order()) 1221 if err != nil { 1222 return nil, err 1223 } 1224 1225 if hasFullText { 1226 if err = rebuildFullText(ctx, i.alterable.Name(), i.a.Db); err != nil { 1227 return nil, err 1228 } 1229 } 1230 1231 // We only need to update all table rows if the new column is non-nil 1232 if i.a.Column().Nullable && i.a.Column().Default == nil { 1233 return sql.NewRow(types.NewOkResult(0)), nil 1234 } 1235 1236 err = i.UpdateRowsWithDefaults(ctx, i.alterable) 1237 if err != nil { 1238 return nil, err 1239 } 1240 1241 return sql.NewRow(types.NewOkResult(0)), nil 1242 } 1243 1244 // UpdateRowsWithDefaults iterates through an updatable table and applies an update to each row. 1245 func (i *addColumnIter) UpdateRowsWithDefaults(ctx *sql.Context, table sql.Table) error { 1246 rt := plan.NewResolvedTable(table, i.a.Db, nil) 1247 updatable, ok := table.(sql.UpdatableTable) 1248 if !ok { 1249 return plan.ErrUpdateNotSupported.New(rt.Name()) 1250 } 1251 1252 tableIter, err := i.b.buildNodeExec(ctx, rt, nil) 1253 if err != nil { 1254 return err 1255 } 1256 1257 schema := updatable.Schema() 1258 idx := -1 1259 for j, col := range schema { 1260 if col.Name == i.a.Column().Name { 1261 idx = j 1262 } 1263 } 1264 1265 updater := updatable.Updater(ctx) 1266 1267 for { 1268 r, err := tableIter.Next(ctx) 1269 if err == io.EOF { 1270 return updater.Close(ctx) 1271 } 1272 1273 if err != nil { 1274 _ = updater.Close(ctx) 1275 return err 1276 } 1277 1278 updatedRow, err := applyDefaults(ctx, schema, idx, r, i.a.Column().Default) 1279 if err != nil { 1280 return err 1281 } 1282 1283 err = updater.Update(ctx, r, updatedRow) 1284 if err != nil { 1285 return err 1286 } 1287 } 1288 } 1289 1290 // applyDefaults applies the default value of the given column index to the given row, and returns a new row with the updated values. 1291 // This assumes that the given row has placeholder `nil` values for the default entries, and also that each column in a table is 1292 // present and in the order as represented by the schema. 1293 func applyDefaults(ctx *sql.Context, tblSch sql.Schema, col int, row sql.Row, cd *sql.ColumnDefaultValue) (sql.Row, error) { 1294 newRow := row.Copy() 1295 if len(tblSch) != len(row) { 1296 return nil, fmt.Errorf("any row given to ApplyDefaults must be of the same length as the table it represents") 1297 } 1298 1299 if col < 0 || col > len(tblSch) { 1300 return nil, fmt.Errorf("column index `%d` is out of bounds, table schema has `%d` number of columns", col, len(tblSch)) 1301 } 1302 1303 columnDefaultExpr := cd 1304 if columnDefaultExpr == nil && !tblSch[col].Nullable { 1305 val := tblSch[col].Type.Zero() 1306 var err error 1307 newRow[col], _, err = tblSch[col].Type.Convert(val) 1308 if err != nil { 1309 return nil, err 1310 } 1311 } else { 1312 val, err := columnDefaultExpr.Eval(ctx, newRow) 1313 if err != nil { 1314 return nil, err 1315 } 1316 newRow[col], _, err = tblSch[col].Type.Convert(val) 1317 if err != nil { 1318 return nil, err 1319 } 1320 } 1321 1322 return newRow, nil 1323 } 1324 1325 func (i addColumnIter) Close(context *sql.Context) error { 1326 return nil 1327 } 1328 1329 // rewriteTable rewrites the table given if required or requested, and returns the whether it was rewritten 1330 func (i *addColumnIter) rewriteTable(ctx *sql.Context, rwt sql.RewritableTable) (bool, error) { 1331 newSch, projections, err := addColumnToSchema(i.a.TargetSchema(), i.a.Column(), i.a.Order()) 1332 if err != nil { 1333 return false, err 1334 } 1335 1336 oldPkSchema, newPkSchema := sql.SchemaToPrimaryKeySchema(rwt, rwt.Schema()), sql.SchemaToPrimaryKeySchema(rwt, newSch) 1337 1338 rewriteRequired := false 1339 if i.a.Column().Default != nil || i.a.Column().Generated != nil || !i.a.Column().Nullable || i.a.Column().AutoIncrement { 1340 rewriteRequired = true 1341 } 1342 1343 if !rewriteRequired && !rwt.ShouldRewriteTable(ctx, oldPkSchema, newPkSchema, nil, i.a.Column()) { 1344 return false, nil 1345 } 1346 1347 inserter, err := rwt.RewriteInserter(ctx, oldPkSchema, newPkSchema, nil, i.a.Column(), nil) 1348 if err != nil { 1349 return false, err 1350 } 1351 1352 partitions, err := rwt.Partitions(ctx) 1353 if err != nil { 1354 return false, err 1355 } 1356 1357 rowIter := sql.NewTableRowIter(ctx, rwt, partitions) 1358 1359 var val uint64 1360 autoIncColIdx := -1 1361 if newSch.HasAutoIncrement() && !i.a.TargetSchema().HasAutoIncrement() { 1362 t, ok := rwt.(sql.AutoIncrementTable) 1363 if !ok { 1364 return false, plan.ErrAutoIncrementNotSupported.New() 1365 } 1366 1367 autoIncColIdx = newSch.IndexOf(i.a.Column().Name, i.a.Column().Source) 1368 val, err = t.GetNextAutoIncrementValue(ctx, 1) 1369 if err != nil { 1370 return false, err 1371 } 1372 } 1373 1374 for { 1375 r, err := rowIter.Next(ctx) 1376 if err == io.EOF { 1377 break 1378 } else if err != nil { 1379 _ = inserter.DiscardChanges(ctx, err) 1380 _ = inserter.Close(ctx) 1381 return false, err 1382 } 1383 1384 newRow, err := ProjectRow(ctx, projections, r) 1385 if err != nil { 1386 _ = inserter.DiscardChanges(ctx, err) 1387 _ = inserter.Close(ctx) 1388 return false, err 1389 } 1390 1391 if autoIncColIdx != -1 { 1392 v, _, err := i.a.Column().Type.Convert(val) 1393 if err != nil { 1394 return false, err 1395 } 1396 newRow[autoIncColIdx] = v 1397 val++ 1398 } 1399 1400 err = inserter.Insert(ctx, newRow) 1401 if err != nil { 1402 _ = inserter.DiscardChanges(ctx, err) 1403 _ = inserter.Close(ctx) 1404 return false, err 1405 } 1406 } 1407 1408 // TODO: move this into iter.close, probably 1409 err = inserter.Close(ctx) 1410 if err != nil { 1411 return false, err 1412 } 1413 1414 return true, nil 1415 } 1416 1417 // addColumnToSchema returns a new schema and a set of projection expressions that when applied to rows from the old 1418 // schema will result in rows in the new schema. 1419 func addColumnToSchema(schema sql.Schema, column *sql.Column, order *sql.ColumnOrder) (sql.Schema, []sql.Expression, error) { 1420 idx := -1 1421 if order != nil && len(order.AfterColumn) > 0 { 1422 idx = schema.IndexOf(order.AfterColumn, column.Source) 1423 if idx == -1 { 1424 // Should be checked in the analyzer already 1425 return nil, nil, sql.ErrTableColumnNotFound.New(column.Source, order.AfterColumn) 1426 } 1427 idx++ 1428 } else if order != nil && order.First { 1429 idx = 0 1430 } 1431 1432 // Now build the new schema, keeping track of: 1433 // 1) the new result schema 1434 // 2) A set of projections to translate rows in the old schema to rows in the new schema 1435 newSch := make(sql.Schema, 0, len(schema)+1) 1436 projections := make([]sql.Expression, len(schema)+1) 1437 1438 if idx >= 0 { 1439 newSch = append(newSch, schema[:idx]...) 1440 newSch = append(newSch, column) 1441 newSch = append(newSch, schema[idx:]...) 1442 1443 for i := range schema[:idx] { 1444 projections[i] = expression.NewGetField(i, schema[i].Type, schema[i].Name, schema[i].Nullable) 1445 } 1446 projections[idx] = plan.ColDefaultExpression{column} 1447 for i := range schema[idx:] { 1448 schIdx := i + idx 1449 projections[schIdx+1] = expression.NewGetField(schIdx, schema[schIdx].Type, schema[schIdx].Name, schema[schIdx].Nullable) 1450 } 1451 } else { // new column at end 1452 newSch = append(newSch, schema...) 1453 newSch = append(newSch, column) 1454 for i := range schema { 1455 projections[i] = expression.NewGetField(i, schema[i].Type, schema[i].Name, schema[i].Nullable) 1456 } 1457 projections[len(schema)] = plan.ColDefaultExpression{column} 1458 } 1459 1460 // Alter the new default if it refers to other columns. The column indexes computed during analysis refer to the 1461 // column indexes in the new result schema, which is not what we want here: we want the positions in the old 1462 // (current) schema, since that is what we'll be evaluating when we rewrite the table. 1463 for i := range projections { 1464 switch p := projections[i].(type) { 1465 case plan.ColDefaultExpression: 1466 if p.Column.Default != nil { 1467 newExpr, _, err := transform.Expr(p.Column.Default.Expr, func(s sql.Expression) (sql.Expression, transform.TreeIdentity, error) { 1468 switch s := s.(type) { 1469 case *expression.GetField: 1470 idx := schema.IndexOf(s.Name(), schema[0].Source) 1471 if idx < 0 { 1472 return nil, transform.SameTree, sql.ErrTableColumnNotFound.New(schema[0].Source, s.Name()) 1473 } 1474 return expression.NewGetFieldWithTable(idx, 0, s.Type(), s.Database(), s.Table(), s.Name(), s.IsNullable()), transform.NewTree, nil 1475 default: 1476 return s, transform.SameTree, nil 1477 } 1478 return s, transform.SameTree, nil 1479 }) 1480 if err != nil { 1481 return nil, nil, err 1482 } 1483 p.Column.Default.Expr = newExpr 1484 projections[i] = p 1485 } 1486 break 1487 } 1488 } 1489 1490 return newSch, projections, nil 1491 } 1492 1493 // createProcedureIter is the row iterator for *CreateProcedure. 1494 type createProcedureIter struct { 1495 once sync.Once 1496 spd sql.StoredProcedureDetails 1497 db sql.Database 1498 } 1499 1500 // Next implements the sql.RowIter interface. 1501 func (c *createProcedureIter) Next(ctx *sql.Context) (sql.Row, error) { 1502 run := false 1503 c.once.Do(func() { 1504 run = true 1505 }) 1506 if !run { 1507 return nil, io.EOF 1508 } 1509 //TODO: if "automatic_sp_privileges" is true then the creator automatically gets EXECUTE and ALTER ROUTINE on this procedure 1510 pdb, ok := c.db.(sql.StoredProcedureDatabase) 1511 if !ok { 1512 return nil, sql.ErrStoredProceduresNotSupported.New(c.db.Name()) 1513 } 1514 1515 err := pdb.SaveStoredProcedure(ctx, c.spd) 1516 if err != nil { 1517 return nil, err 1518 } 1519 1520 return sql.Row{types.NewOkResult(0)}, nil 1521 } 1522 1523 // Close implements the sql.RowIter interface. 1524 func (c *createProcedureIter) Close(ctx *sql.Context) error { 1525 return nil 1526 } 1527 1528 type createTriggerIter struct { 1529 once sync.Once 1530 definition sql.TriggerDefinition 1531 db sql.Database 1532 ctx *sql.Context 1533 } 1534 1535 func (c *createTriggerIter) Next(ctx *sql.Context) (sql.Row, error) { 1536 run := false 1537 c.once.Do(func() { 1538 run = true 1539 }) 1540 1541 if !run { 1542 return nil, io.EOF 1543 } 1544 1545 tdb, ok := c.db.(sql.TriggerDatabase) 1546 if !ok { 1547 return nil, sql.ErrTriggersNotSupported.New(c.db.Name()) 1548 } 1549 1550 err := tdb.CreateTrigger(ctx, c.definition) 1551 if err != nil { 1552 return nil, err 1553 } 1554 1555 return sql.Row{types.NewOkResult(0)}, nil 1556 } 1557 1558 func (c *createTriggerIter) Close(*sql.Context) error { 1559 return nil 1560 } 1561 1562 type dropColumnIter struct { 1563 d *plan.DropColumn 1564 alterable sql.AlterableTable 1565 runOnce bool 1566 } 1567 1568 func (i *dropColumnIter) Next(ctx *sql.Context) (sql.Row, error) { 1569 if i.runOnce { 1570 return nil, io.EOF 1571 } 1572 i.runOnce = true 1573 1574 // drop constraints that reference the dropped column 1575 cat, ok := i.alterable.(sql.CheckAlterableTable) 1576 if ok { 1577 // note: validations done earlier ensure safety of dropping any constraint referencing the column 1578 err := dropConstraints(ctx, cat, i.d.Checks(), i.d.Column) 1579 if err != nil { 1580 return nil, err 1581 } 1582 } 1583 1584 rwt, ok := i.alterable.(sql.RewritableTable) 1585 if ok { 1586 rewritten, err := i.rewriteTable(ctx, rwt) 1587 if err != nil { 1588 return nil, err 1589 } 1590 if rewritten { 1591 return sql.NewRow(types.NewOkResult(0)), nil 1592 } 1593 } 1594 1595 // Full-Text indexes will need to be rebuilt 1596 hasFullText := hasFullText(ctx, i.alterable) 1597 if hasFullText { 1598 if err := fulltext.DropColumnFromTables(ctx, i.alterable.(sql.IndexAddressableTable), i.d.Db.(fulltext.Database), i.d.Column); err != nil { 1599 return nil, err 1600 } 1601 } 1602 1603 err := i.alterable.DropColumn(ctx, i.d.Column) 1604 if err != nil { 1605 return nil, err 1606 } 1607 1608 if hasFullText { 1609 if err = rebuildFullText(ctx, i.alterable.Name(), i.d.Db); err != nil { 1610 return nil, err 1611 } 1612 } 1613 return sql.NewRow(types.NewOkResult(0)), nil 1614 } 1615 1616 // rewriteTable rewrites the table given if required or requested, and returns whether it was rewritten 1617 func (i *dropColumnIter) rewriteTable(ctx *sql.Context, rwt sql.RewritableTable) (bool, error) { 1618 newSch, projections, err := dropColumnFromSchema(i.d.TargetSchema(), i.d.Column, i.alterable.Name()) 1619 if err != nil { 1620 return false, err 1621 } 1622 1623 oldPkSchema, newPkSchema := sql.SchemaToPrimaryKeySchema(rwt, rwt.Schema()), sql.SchemaToPrimaryKeySchema(rwt, newSch) 1624 droppedColIdx := oldPkSchema.IndexOf(i.d.Column, i.alterable.Name()) 1625 1626 rewriteRequested := rwt.ShouldRewriteTable(ctx, oldPkSchema, newPkSchema, oldPkSchema.Schema[droppedColIdx], nil) 1627 if !rewriteRequested { 1628 return false, nil 1629 } 1630 1631 inserter, err := rwt.RewriteInserter(ctx, oldPkSchema, newPkSchema, oldPkSchema.Schema[droppedColIdx], nil, nil) 1632 if err != nil { 1633 return false, err 1634 } 1635 1636 partitions, err := rwt.Partitions(ctx) 1637 if err != nil { 1638 return false, err 1639 } 1640 1641 rowIter := sql.NewTableRowIter(ctx, rwt, partitions) 1642 1643 for { 1644 r, err := rowIter.Next(ctx) 1645 if err == io.EOF { 1646 break 1647 } else if err != nil { 1648 _ = inserter.DiscardChanges(ctx, err) 1649 _ = inserter.Close(ctx) 1650 return false, err 1651 } 1652 1653 newRow, err := ProjectRow(ctx, projections, r) 1654 if err != nil { 1655 _ = inserter.DiscardChanges(ctx, err) 1656 _ = inserter.Close(ctx) 1657 return false, err 1658 } 1659 1660 err = inserter.Insert(ctx, newRow) 1661 if err != nil { 1662 _ = inserter.DiscardChanges(ctx, err) 1663 _ = inserter.Close(ctx) 1664 return false, err 1665 } 1666 } 1667 1668 // TODO: move this into iter.close, probably 1669 err = inserter.Close(ctx) 1670 if err != nil { 1671 return false, err 1672 } 1673 1674 return true, nil 1675 } 1676 1677 func dropColumnFromSchema(schema sql.Schema, column string, tableName string) (sql.Schema, []sql.Expression, error) { 1678 idx := schema.IndexOf(column, tableName) 1679 if idx < 0 { 1680 return nil, nil, sql.ErrTableColumnNotFound.New(tableName, column) 1681 } 1682 1683 newSch := make(sql.Schema, len(schema)-1) 1684 projections := make([]sql.Expression, len(schema)-1) 1685 1686 i := 0 1687 for j := range schema[:idx] { 1688 newSch[i] = schema[j] 1689 projections[i] = expression.NewGetField(j, schema[j].Type, schema[j].Name, schema[j].Nullable) 1690 i++ 1691 } 1692 1693 for j := range schema[idx+1:] { 1694 schIdx := j + i + 1 1695 newSch[j+i] = schema[schIdx] 1696 projections[j+i] = expression.NewGetField(schIdx, schema[schIdx].Type, schema[schIdx].Name, schema[schIdx].Nullable) 1697 } 1698 1699 return newSch, projections, nil 1700 } 1701 1702 // dropConstraints drop constraints that reference the column to be dropped. 1703 func dropConstraints(ctx *sql.Context, cat sql.CheckAlterableTable, checks sql.CheckConstraints, column string) error { 1704 var err error 1705 for _, check := range checks { 1706 _ = transform.InspectExpr(check.Expr, func(e sql.Expression) bool { 1707 var name string 1708 switch e := e.(type) { 1709 case *expression.UnresolvedColumn: 1710 name = e.Name() 1711 case *expression.GetField: 1712 name = e.Name() 1713 } 1714 if strings.EqualFold(column, name) { 1715 err = cat.DropCheck(ctx, check.Name) 1716 return true 1717 } 1718 return false 1719 }) 1720 1721 if err != nil { 1722 return err 1723 } 1724 } 1725 return nil 1726 } 1727 1728 func (i *dropColumnIter) Close(context *sql.Context) error { 1729 return nil 1730 } 1731 1732 // Execute inserts the rows in the database. 1733 func (b *BaseBuilder) executeCreateCheck(ctx *sql.Context, c *plan.CreateCheck) error { 1734 table, err := getTableFromDatabase(ctx, c.Database(), c.Table) 1735 if err != nil { 1736 return err 1737 } 1738 1739 chAlterable, err := getCheckAlterableTable(table) 1740 if err != nil { 1741 return err 1742 } 1743 1744 // check existing rows in table 1745 var res interface{} 1746 rowIter, err := b.buildNodeExec(ctx, c.Table, nil) 1747 if err != nil { 1748 return err 1749 } 1750 1751 for { 1752 row, err := rowIter.Next(ctx) 1753 if err == io.EOF { 1754 break 1755 } 1756 1757 if err != nil { 1758 return err 1759 } 1760 1761 res, err = sql.EvaluateCondition(ctx, c.Check.Expr, row) 1762 if err != nil { 1763 return err 1764 } 1765 1766 if sql.IsFalse(res) { 1767 return plan.ErrCheckViolated.New(c.Check.Name) 1768 } 1769 } 1770 1771 check, err := plan.NewCheckDefinition(ctx, c.Check) 1772 if err != nil { 1773 return err 1774 } 1775 1776 return chAlterable.CreateCheck(ctx, check) 1777 } 1778 1779 func (b *BaseBuilder) executeDropCheck(ctx *sql.Context, n *plan.DropCheck) error { 1780 table, err := getTableFromDatabase(ctx, n.Database(), n.Table) 1781 if err != nil { 1782 return err 1783 } 1784 1785 chAlterable, err := getCheckAlterableTable(table) 1786 if err != nil { 1787 return err 1788 } 1789 1790 return chAlterable.DropCheck(ctx, n.Name) 1791 } 1792 1793 func getCheckAlterableTable(t sql.Table) (sql.CheckAlterableTable, error) { 1794 switch t := t.(type) { 1795 case sql.CheckAlterableTable: 1796 return t, nil 1797 case sql.TableWrapper: 1798 return getCheckAlterableTable(t.Underlying()) 1799 case *plan.ResolvedTable: 1800 return getCheckAlterableTable(t.Table) 1801 default: 1802 return nil, plan.ErrNoCheckConstraintSupport.New(t.Name()) 1803 } 1804 } 1805 1806 // Execute inserts the rows in the database. 1807 func (b *BaseBuilder) executeAlterIndex(ctx *sql.Context, n *plan.AlterIndex) error { 1808 // We should refresh the state of the table in case this alter was in a multi alter statement. 1809 table, err := getTableFromDatabase(ctx, n.Database(), n.Table) 1810 if err != nil { 1811 return err 1812 } 1813 1814 indexable, ok := table.(sql.IndexAlterableTable) 1815 if !ok { 1816 return plan.ErrNotIndexable.New() 1817 } 1818 1819 if err != nil { 1820 return err 1821 } 1822 1823 switch n.Action { 1824 case plan.IndexAction_Create: 1825 if len(n.Columns) == 0 { 1826 return plan.ErrCreateIndexMissingColumns.New() 1827 } 1828 1829 // Make sure that all columns are valid, in the table, and there are no duplicates 1830 seenCols := make(map[string]bool) 1831 for _, col := range indexable.Schema() { 1832 seenCols[strings.ToLower(col.Name)] = false 1833 } 1834 for _, indexCol := range n.Columns { 1835 if seen, ok := seenCols[strings.ToLower(indexCol.Name)]; ok { 1836 if !seen { 1837 seenCols[strings.ToLower(indexCol.Name)] = true 1838 } else { 1839 return plan.ErrCreateIndexDuplicateColumn.New(indexCol.Name) 1840 } 1841 } else { 1842 return plan.ErrCreateIndexNonExistentColumn.New(indexCol.Name) 1843 } 1844 } 1845 1846 indexName := n.IndexName 1847 if indexName == "" { 1848 indexMap := make(map[string]struct{}) 1849 // If we can get the other indexes declared on this table then we can ensure that we're creating a unique 1850 // index name. In either case, we retain the map search to simplify the logic (it will either be populated 1851 // or empty). 1852 if indexedTable, ok := indexable.(sql.IndexAddressable); ok { 1853 indexes, err := indexedTable.GetIndexes(ctx) 1854 if err != nil { 1855 return err 1856 } 1857 for _, index := range indexes { 1858 indexMap[strings.ToLower(index.ID())] = struct{}{} 1859 } 1860 } 1861 indexName = strings.Join(n.ColumnNames(), "") 1862 if _, ok := indexMap[strings.ToLower(indexName)]; ok { 1863 for i := 0; true; i++ { 1864 newIndexName := fmt.Sprintf("%s_%d", indexName, i) 1865 if _, ok = indexMap[strings.ToLower(newIndexName)]; !ok { 1866 indexName = newIndexName 1867 break 1868 } 1869 } 1870 } 1871 } 1872 1873 indexDef := sql.IndexDef{ 1874 Name: indexName, 1875 Columns: n.Columns, 1876 Constraint: n.Constraint, 1877 Storage: n.Using, 1878 Comment: n.Comment, 1879 } 1880 1881 if n.Constraint == sql.IndexConstraint_Fulltext { 1882 database, ok := n.Database().(fulltext.Database) 1883 if !ok { 1884 if privDb, ok := n.Database().(mysql_db.PrivilegedDatabase); ok { 1885 if database, ok = privDb.Unwrap().(fulltext.Database); !ok { 1886 return sql.ErrIncompleteFullTextIntegration.New() 1887 } 1888 } else { 1889 return sql.ErrIncompleteFullTextIntegration.New() 1890 } 1891 } 1892 return fulltext.CreateFulltextIndexes(ctx, database, indexable, nil, indexDef) 1893 } 1894 1895 err = indexable.CreateIndex(ctx, indexDef) 1896 if err != nil { 1897 return err 1898 } 1899 1900 // Two ways to build an index for an integrator, implemented by two different interfaces. 1901 // The first way is building just an index with a special Inserter, only if the integrator requests it 1902 ibt, isIndexBuilding := indexable.(sql.IndexBuildingTable) 1903 if isIndexBuilding { 1904 shouldRebuild, err := ibt.ShouldBuildIndex(ctx, indexDef) 1905 if err != nil { 1906 return err 1907 } 1908 1909 if shouldRebuild || indexCreateRequiresBuild(n) { 1910 return buildIndex(ctx, n, ibt, indexDef) 1911 } 1912 } 1913 1914 // The second way to rebuild an index is with a full table rewrite 1915 rwt, isRewritable := indexable.(sql.RewritableTable) 1916 if isRewritable && indexCreateRequiresBuild(n) { 1917 return rewriteTableForIndexCreate(ctx, n, table, rwt) 1918 } 1919 1920 return nil 1921 case plan.IndexAction_Drop: 1922 if fkTable, ok := indexable.(sql.ForeignKeyTable); ok { 1923 fks, err := fkTable.GetDeclaredForeignKeys(ctx) 1924 if err != nil { 1925 return err 1926 } 1927 for _, fk := range fks { 1928 _, ok, err := plan.FindFKIndexWithPrefix(ctx, fkTable, fk.Columns, false, n.IndexName) 1929 if err != nil { 1930 return err 1931 } 1932 if !ok { 1933 return sql.ErrForeignKeyDropIndex.New(n.IndexName, fk.Name) 1934 } 1935 } 1936 1937 parentFks, err := fkTable.GetReferencedForeignKeys(ctx) 1938 if err != nil { 1939 return err 1940 } 1941 for _, parentFk := range parentFks { 1942 _, ok, err := plan.FindFKIndexWithPrefix(ctx, fkTable, parentFk.ParentColumns, true, n.IndexName) 1943 if err != nil { 1944 return err 1945 } 1946 if !ok { 1947 return sql.ErrForeignKeyDropIndex.New(n.IndexName, parentFk.Name) 1948 } 1949 } 1950 } 1951 1952 // If we're dropping a Full-Text, then we also need to delete its tables 1953 database := n.Database() 1954 if addressable, ok := indexable.(sql.IndexAddressableTable); !ok { 1955 // If they don't support their creation, then it's safe to assume that they won't have any to delete 1956 if _, ok = database.(fulltext.Database); ok { 1957 return sql.ErrIncompleteFullTextIntegration.New() 1958 } 1959 } else { 1960 indexes, err := addressable.GetIndexes(ctx) 1961 if err != nil { 1962 return err 1963 } 1964 // We need to keep a count of how many Full-Text indexes there are, so that we only delete the config table 1965 // once the last index has been deleted. 1966 ftCount := 0 1967 var ftIndex fulltext.Index 1968 lowercaseIndexName := strings.ToLower(n.IndexName) 1969 for _, index := range indexes { 1970 if strings.ToLower(index.ID()) == lowercaseIndexName { 1971 if index.IsFullText() { 1972 ftIndex, ok = index.(fulltext.Index) 1973 if !ok { 1974 return sql.ErrIncompleteFullTextIntegration.New() 1975 } 1976 ftCount++ 1977 } 1978 break 1979 } else if index.IsFullText() { 1980 ftCount++ 1981 } 1982 } 1983 // We found the index and it is Full-Text, so we need to delete the other tables 1984 if ftIndex != nil { 1985 dropper, ok := database.(sql.TableDropper) 1986 if !ok { 1987 return sql.ErrIncompleteFullTextIntegration.New() 1988 } 1989 tableNames, err := ftIndex.FullTextTableNames(ctx) 1990 if err != nil { 1991 return err 1992 } 1993 // We only delete the config table when there are no more Full-Text indexes on the table since its shared 1994 if ftCount == 1 { 1995 if err = dropper.DropTable(ctx, tableNames.Config); err != nil { 1996 return err 1997 } 1998 } 1999 if err = dropper.DropTable(ctx, tableNames.Position); err != nil { 2000 return err 2001 } 2002 if err = dropper.DropTable(ctx, tableNames.DocCount); err != nil { 2003 return err 2004 } 2005 if err = dropper.DropTable(ctx, tableNames.GlobalCount); err != nil { 2006 return err 2007 } 2008 if err = dropper.DropTable(ctx, tableNames.RowCount); err != nil { 2009 return err 2010 } 2011 } 2012 } 2013 return indexable.DropIndex(ctx, n.IndexName) 2014 case plan.IndexAction_Rename: 2015 return indexable.RenameIndex(ctx, n.PreviousIndexName, n.IndexName) 2016 case plan.IndexAction_DisableEnableKeys: 2017 if ctx != nil && ctx.Session != nil { 2018 ctx.Session.Warn(&sql.Warning{ 2019 Level: "Warning", 2020 Code: mysql.ERNotSupportedYet, 2021 Message: "'disable/enable keys' feature is not supported yet", 2022 }) 2023 } 2024 return nil 2025 default: 2026 return plan.ErrIndexActionNotImplemented.New(n.Action) 2027 } 2028 } 2029 2030 // buildIndex builds an index on a table, as a less expensive alternative to doing a complete table rewrite. 2031 func buildIndex(ctx *sql.Context, n *plan.AlterIndex, ibt sql.IndexBuildingTable, indexDef sql.IndexDef) error { 2032 inserter, err := ibt.BuildIndex(ctx, indexDef) 2033 if err != nil { 2034 return err 2035 } 2036 2037 partitions, err := ibt.Partitions(ctx) 2038 if err != nil { 2039 return err 2040 } 2041 2042 rowIter := sql.NewTableRowIter(ctx, ibt, partitions) 2043 2044 // Our table scan needs to include projections for virtual columns if there are any 2045 isVirtual := ibt.Schema().HasVirtualColumns() 2046 var projections []sql.Expression 2047 if isVirtual { 2048 projections = virtualTableProjections(n.TargetSchema(), ibt.Name()) 2049 } 2050 2051 for { 2052 r, err := rowIter.Next(ctx) 2053 if err == io.EOF { 2054 break 2055 } else if err != nil { 2056 _ = inserter.DiscardChanges(ctx, err) 2057 _ = inserter.Close(ctx) 2058 return err 2059 } 2060 2061 if isVirtual { 2062 r, err = ProjectRow(ctx, projections, r) 2063 if err != nil { 2064 return err 2065 } 2066 } 2067 2068 err = inserter.Insert(ctx, r) 2069 if err != nil { 2070 _ = inserter.DiscardChanges(ctx, err) 2071 _ = inserter.Close(ctx) 2072 return err 2073 } 2074 } 2075 2076 // TODO: move this into iter.close, probably 2077 err = inserter.Close(ctx) 2078 if err != nil { 2079 return err 2080 } 2081 return nil 2082 } 2083 2084 // virtualTableProjections returns the projections for a virtual table with the schema and name provided. 2085 // Typically virtual tables have their projections applied by the analyzer and row executor process, but this is 2086 // equivalent when we need it at runtime. 2087 func virtualTableProjections(schema sql.Schema, tableName string) []sql.Expression { 2088 projections := make([]sql.Expression, len(schema)) 2089 for i, c := range schema { 2090 if !c.Virtual { 2091 // todo: if we really need colId/tableId we can get from scope 2092 projections[i] = expression.NewGetFieldWithTable(i, 1, c.Type, c.DatabaseSource, tableName, c.Name, c.Nullable) 2093 } else { 2094 projections[i] = c.Generated 2095 } 2096 } 2097 2098 for i, p := range projections { 2099 projections[i] = assignColumnIndexes(p, schema) 2100 } 2101 2102 return projections 2103 } 2104 2105 // assignColumnIndexes fixes the column indexes in the expression to match the schema given 2106 func assignColumnIndexes(e sql.Expression, schema sql.Schema) sql.Expression { 2107 e, _, _ = transform.Expr(e, func(e sql.Expression) (sql.Expression, transform.TreeIdentity, error) { 2108 if gf, ok := e.(*expression.GetField); ok { 2109 idx := schema.IndexOfColName(gf.Name()) 2110 return gf.WithIndex(idx), transform.NewTree, nil 2111 } 2112 return e, transform.SameTree, nil 2113 }) 2114 return e 2115 } 2116 2117 func rewriteTableForIndexCreate(ctx *sql.Context, n *plan.AlterIndex, table sql.Table, rwt sql.RewritableTable) error { 2118 sch := sql.SchemaToPrimaryKeySchema(table, n.TargetSchema()) 2119 inserter, err := rwt.RewriteInserter(ctx, sch, sch, nil, nil, n.Columns) 2120 if err != nil { 2121 return err 2122 } 2123 2124 partitions, err := rwt.Partitions(ctx) 2125 if err != nil { 2126 return err 2127 } 2128 2129 rowIter := sql.NewTableRowIter(ctx, rwt, partitions) 2130 2131 for { 2132 r, err := rowIter.Next(ctx) 2133 if err == io.EOF { 2134 break 2135 } else if err != nil { 2136 _ = inserter.DiscardChanges(ctx, err) 2137 _ = inserter.Close(ctx) 2138 return err 2139 } 2140 2141 err = inserter.Insert(ctx, r) 2142 if err != nil { 2143 _ = inserter.DiscardChanges(ctx, err) 2144 _ = inserter.Close(ctx) 2145 return err 2146 } 2147 } 2148 2149 // TODO: move this into iter.close, probably 2150 err = inserter.Close(ctx) 2151 if err != nil { 2152 return err 2153 } 2154 return nil 2155 } 2156 2157 // indexRequiresBuild returns whether the given index requires a build operation to be performed as part of its creation 2158 func indexCreateRequiresBuild(n *plan.AlterIndex) bool { 2159 return n.Constraint == sql.IndexConstraint_Unique || indexOnVirtualColumn(n.Columns, n.TargetSchema()) 2160 } 2161 2162 func indexOnVirtualColumn(columns []sql.IndexColumn, schema sql.Schema) bool { 2163 for _, col := range columns { 2164 idx := schema.IndexOfColName(col.Name) 2165 if idx < 0 { 2166 return false // should be impossible 2167 } 2168 if schema[idx].Virtual { 2169 return true 2170 } 2171 } 2172 return false 2173 } 2174 2175 // Execute inserts the rows in the database. 2176 func (b *BaseBuilder) executeAlterAutoInc(ctx *sql.Context, n *plan.AlterAutoIncrement) error { 2177 // Grab the table fresh from the database. 2178 table, err := getTableFromDatabase(ctx, n.Database(), n.Table) 2179 if err != nil { 2180 return err 2181 } 2182 2183 insertable, ok := table.(sql.InsertableTable) 2184 if !ok { 2185 return plan.ErrInsertIntoNotSupported.New() 2186 } 2187 if err != nil { 2188 return err 2189 } 2190 2191 autoTbl, ok := insertable.(sql.AutoIncrementTable) 2192 if !ok { 2193 return plan.ErrAutoIncrementNotSupported.New(insertable.Name()) 2194 } 2195 2196 // No-op if the table doesn't already have an auto increment column. 2197 if !autoTbl.Schema().HasAutoIncrement() { 2198 return nil 2199 } 2200 2201 setter := autoTbl.AutoIncrementSetter(ctx) 2202 err = setter.SetAutoIncrementValue(ctx, n.AutoVal) 2203 if err != nil { 2204 return err 2205 } 2206 2207 return setter.Close(ctx) 2208 } 2209 2210 // hasFullText returns whether the given table has any Full-Text indexes. 2211 func hasFullText(ctx *sql.Context, tbl sql.Table) bool { 2212 hasFT := false 2213 indexAddressable, ok := tbl.(sql.IndexAddressableTable) 2214 if ok { 2215 indexes, err := indexAddressable.GetIndexes(ctx) 2216 if err != nil { 2217 panic(err) // really, why would this ever happen 2218 } 2219 for _, index := range indexes { 2220 if index.IsFullText() { 2221 hasFT = true 2222 break 2223 } 2224 } 2225 } 2226 return hasFT 2227 } 2228 2229 // rebuildFullText rebuilds all Full-Text indexes on the given table. 2230 func rebuildFullText(ctx *sql.Context, tblName string, db sql.Database) error { 2231 updatedTable, ok, err := db.GetTableInsensitive(ctx, tblName) 2232 if err != nil { 2233 return err 2234 } 2235 if !ok { 2236 return fmt.Errorf("cannot find newly updated table `%s`", tblName) 2237 } 2238 return fulltext.RebuildTables(ctx, updatedTable.(sql.IndexAddressableTable), db.(fulltext.Database)) 2239 }