// FindOnUpdateCols finds columns which have OnUpdateNow flag. func FindOnUpdateCols(cols []*Column) []*Column { var rcols []*Column for _, col := range cols { if mysql.HasOnUpdateNowFlag(col.Flag) { rcols = append(rcols, col) } } return rcols }
// FindOnUpdateCols finds columns which have OnUpdateNow flag. func FindOnUpdateCols(cols []*Col) []*Col { var rcols []*Col for _, c := range cols { if mysql.HasOnUpdateNowFlag(c.Flag) { rcols = append(rcols, c) } } return rcols }
// NewColDesc returns a new ColDesc for a column. func NewColDesc(col *Column) *ColDesc { // TODO: if we have no primary key and a unique index which's columns are all not null // we will set these columns' flag as PriKeyFlag // see https://dev.mysql.com/doc/refman/5.7/en/show-columns.html // create table name := col.Name nullFlag := "YES" if mysql.HasNotNullFlag(col.Flag) { nullFlag = "NO" } keyFlag := "" if mysql.HasPriKeyFlag(col.Flag) { keyFlag = "PRI" } else if mysql.HasUniKeyFlag(col.Flag) { keyFlag = "UNI" } else if mysql.HasMultipleKeyFlag(col.Flag) { keyFlag = "MUL" } var defaultValue interface{} if !mysql.HasNoDefaultValueFlag(col.Flag) { defaultValue = col.DefaultValue } extra := "" if mysql.HasAutoIncrementFlag(col.Flag) { extra = "auto_increment" } else if mysql.HasOnUpdateNowFlag(col.Flag) { extra = "on update CURRENT_TIMESTAMP" } return &ColDesc{ Field: name.O, Type: col.GetTypeDesc(), Collation: col.Collate, Null: nullFlag, Key: keyFlag, DefaultValue: defaultValue, Extra: extra, Privileges: defaultPrivileges, Comment: "", } }
func (s *ShowPlan) fetchShowCreateTable(ctx context.Context) error { tb, err := s.getTable(ctx) if err != nil { return errors.Trace(err) } // TODO: let the result more like MySQL. var buf bytes.Buffer buf.WriteString(fmt.Sprintf("CREATE TABLE `%s` (\n", tb.TableName().O)) for i, col := range tb.Cols() { buf.WriteString(fmt.Sprintf(" `%s` %s", col.Name.O, col.GetTypeDesc())) if mysql.HasAutoIncrementFlag(col.Flag) { buf.WriteString(" NOT NULL AUTO_INCREMENT") } else { if mysql.HasNotNullFlag(col.Flag) { buf.WriteString(" NOT NULL") } switch col.DefaultValue { case nil: buf.WriteString(" DEFAULT NULL") case "CURRENT_TIMESTAMP": buf.WriteString(" DEFAULT CURRENT_TIMESTAMP") default: buf.WriteString(fmt.Sprintf(" DEFAULT '%v'", col.DefaultValue)) } if mysql.HasOnUpdateNowFlag(col.Flag) { buf.WriteString(" ON UPDATE CURRENT_TIMESTAMP") } } if i != len(tb.Cols())-1 { buf.WriteString(",\n") } } if len(tb.Indices()) > 0 { buf.WriteString(",\n") } for i, idx := range tb.Indices() { if idx.Primary { buf.WriteString(" PRIMARY KEY ") } else if idx.Unique { buf.WriteString(fmt.Sprintf(" UNIQUE KEY `%s` ", idx.Name.O)) } else { buf.WriteString(fmt.Sprintf(" KEY `%s` ", idx.Name.O)) } cols := make([]string, 0, len(idx.Columns)) for _, c := range idx.Columns { cols = append(cols, c.Name.O) } buf.WriteString(fmt.Sprintf("(`%s`)", strings.Join(cols, "`,`"))) if i != len(tb.Indices())-1 { buf.WriteString(",\n") } } buf.WriteString("\n") buf.WriteString(") ENGINE=InnoDB") if s := tb.Meta().Charset; len(s) > 0 { buf.WriteString(fmt.Sprintf(" DEFAULT CHARSET=%s", s)) } else { buf.WriteString(" DEFAULT CHARSET=latin1") } data := []interface{}{ tb.TableName().O, buf.String(), } s.rows = append(s.rows, &plan.Row{Data: data}) return nil }
func (e *ShowExec) fetchShowCreateTable() error { tb, err := e.getTable() if err != nil { return errors.Trace(err) } // TODO: let the result more like MySQL. var buf bytes.Buffer buf.WriteString(fmt.Sprintf("CREATE TABLE `%s` (\n", tb.Meta().Name.O)) var pkCol *table.Column for i, col := range tb.Cols() { buf.WriteString(fmt.Sprintf(" `%s` %s", col.Name.O, col.GetTypeDesc())) if mysql.HasAutoIncrementFlag(col.Flag) { buf.WriteString(" NOT NULL AUTO_INCREMENT") } else { if mysql.HasNotNullFlag(col.Flag) { buf.WriteString(" NOT NULL") } if !mysql.HasNoDefaultValueFlag(col.Flag) { switch col.DefaultValue { case nil: buf.WriteString(" DEFAULT NULL") case "CURRENT_TIMESTAMP": buf.WriteString(" DEFAULT CURRENT_TIMESTAMP") default: buf.WriteString(fmt.Sprintf(" DEFAULT '%v'", col.DefaultValue)) } } if mysql.HasOnUpdateNowFlag(col.Flag) { buf.WriteString(" ON UPDATE CURRENT_TIMESTAMP") } } if len(col.Comment) > 0 { buf.WriteString(fmt.Sprintf(" COMMENT '%s'", col.Comment)) } if i != len(tb.Cols())-1 { buf.WriteString(",\n") } if tb.Meta().PKIsHandle && mysql.HasPriKeyFlag(col.Flag) { pkCol = col } } if pkCol != nil { // If PKIsHanle, pk info is not in tb.Indices(). We should handle it here. buf.WriteString(",\n") buf.WriteString(fmt.Sprintf(" PRIMARY KEY (`%s`)", pkCol.Name.O)) } if len(tb.Indices()) > 0 || len(tb.Meta().ForeignKeys) > 0 { buf.WriteString(",\n") } for i, idx := range tb.Indices() { idxInfo := idx.Meta() if idxInfo.Primary { buf.WriteString(" PRIMARY KEY ") } else if idxInfo.Unique { buf.WriteString(fmt.Sprintf(" UNIQUE KEY `%s` ", idxInfo.Name.O)) } else { buf.WriteString(fmt.Sprintf(" KEY `%s` ", idxInfo.Name.O)) } cols := make([]string, 0, len(idxInfo.Columns)) for _, c := range idxInfo.Columns { cols = append(cols, c.Name.O) } buf.WriteString(fmt.Sprintf("(`%s`)", strings.Join(cols, "`,`"))) if i != len(tb.Indices())-1 { buf.WriteString(",\n") } } if len(tb.Indices()) > 0 && len(tb.Meta().ForeignKeys) > 0 { buf.WriteString(",\n") } for _, fk := range tb.Meta().ForeignKeys { if fk.State != model.StatePublic { continue } cols := make([]string, 0, len(fk.Cols)) for _, c := range fk.Cols { cols = append(cols, c.O) } refCols := make([]string, 0, len(fk.RefCols)) for _, c := range fk.Cols { refCols = append(refCols, c.O) } buf.WriteString(fmt.Sprintf(" CONSTRAINT `%s` FOREIGN KEY (`%s`)", fk.Name.O, strings.Join(cols, "`,`"))) buf.WriteString(fmt.Sprintf(" REFERENCES `%s` (`%s`)", fk.RefTable.O, strings.Join(refCols, "`,`"))) if ast.ReferOptionType(fk.OnDelete) != ast.ReferOptionNoOption { buf.WriteString(fmt.Sprintf(" ON DELETE %s", ast.ReferOptionType(fk.OnDelete))) } if ast.ReferOptionType(fk.OnUpdate) != ast.ReferOptionNoOption { buf.WriteString(fmt.Sprintf(" ON UPDATE %s", ast.ReferOptionType(fk.OnUpdate))) } } buf.WriteString("\n") buf.WriteString(") ENGINE=InnoDB") if s := tb.Meta().Charset; len(s) > 0 { buf.WriteString(fmt.Sprintf(" DEFAULT CHARSET=%s", s)) } if tb.Meta().AutoIncID > 0 { buf.WriteString(fmt.Sprintf(" AUTO_INCREMENT=%d", tb.Meta().AutoIncID)) } if len(tb.Meta().Comment) > 0 { buf.WriteString(fmt.Sprintf(" COMMENT='%s'", tb.Meta().Comment)) } data := types.MakeDatums(tb.Meta().Name.O, buf.String()) e.rows = append(e.rows, &Row{Data: data}) return nil }