// String implements fmt.Stringer interface. func (c *Col) String() string { ans := []string{c.Name.O, types.FieldTypeToStr(c.Tp, c.Charset)} if mysql.HasAutoIncrementFlag(c.Flag) { ans = append(ans, "AUTO_INCREMENT") } if mysql.HasNotNullFlag(c.Flag) { ans = append(ans, "NOT NULL") } return strings.Join(ans, " ") }
func (s *InsertIntoStmt) initDefaultValues(ctx context.Context, t table.Table, cols []*column.Col, row []interface{}, marked map[int]struct{}) error { var err error var defaultValueCols []*column.Col for i, c := range cols { if row[i] != nil { // Column value is not nil, continue. continue } // If the nil value is evaluated in insert list, we will use nil except auto increment column. if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) { continue } if mysql.HasAutoIncrementFlag(c.Flag) { var id int64 if id, err = t.AllocAutoID(); err != nil { return errors.Trace(err) } row[i] = id variable.GetSessionVars(ctx).SetLastInsertID(uint64(id)) } else { var value interface{} value, _, err = getDefaultValue(ctx, c) if err != nil { return errors.Trace(err) } row[i] = value } defaultValueCols = append(defaultValueCols, c) } if err = column.CastValues(ctx, row, defaultValueCols); err != nil { return errors.Trace(err) } return nil }
func setNoDefaultValueFlag(c *column.Col, hasDefaultValue bool) { if hasDefaultValue { return } if !mysql.HasNotNullFlag(c.Flag) { return } // Check if it is an `AUTO_INCREMENT` field or `TIMESTAMP` field. if !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) { c.Flag |= mysql.NoDefaultValueFlag } }
// NewColDesc returns a new ColDesc for a column. func NewColDesc(col *Col) *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 }