Example #1
0
File: ddl.go Project: pingcap/tidb
func (d *ddl) setCharsetCollationFlenDecimal(tp *types.FieldType) {
	if len(tp.Charset) == 0 {
		switch tp.Tp {
		case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
			tp.Charset, tp.Collate = getDefaultCharsetAndCollate()
		default:
			tp.Charset = charset.CharsetBin
			tp.Collate = charset.CharsetBin
		}
	}
	// If flen is not assigned, assigned it by type.
	if tp.Flen == types.UnspecifiedLength {
		tp.Flen = mysql.GetDefaultFieldLength(tp.Tp)
	}
	if tp.Decimal == types.UnspecifiedLength {
		tp.Decimal = mysql.GetDefaultDecimal(tp.Tp)
	}
}
Example #2
0
File: ddl.go Project: yangtsoo/tidb
// columnDefToCol converts ColumnDef to Col and TableConstraints.
func columnDefToCol(ctx context.Context, offset int, colDef *ast.ColumnDef) (*table.Column, []*ast.Constraint, error) {
	constraints := []*ast.Constraint{}
	col := &table.Column{
		ColumnInfo: model.ColumnInfo{
			Offset:    offset,
			Name:      colDef.Name.Name,
			FieldType: *colDef.Tp,
		},
	}

	// Check and set TimestampFlag and OnUpdateNowFlag.
	if col.Tp == mysql.TypeTimestamp {
		col.Flag |= mysql.TimestampFlag
		col.Flag |= mysql.OnUpdateNowFlag
		col.Flag |= mysql.NotNullFlag
	}

	// If flen is not assigned, assigned it by type.
	if col.Flen == types.UnspecifiedLength {
		col.Flen = mysql.GetDefaultFieldLength(col.Tp)
	}
	if col.Decimal == types.UnspecifiedLength {
		col.Decimal = mysql.GetDefaultDecimal(col.Tp)
	}

	setOnUpdateNow := false
	hasDefaultValue := false
	if colDef.Options != nil {
		keys := []*ast.IndexColName{
			{
				Column: colDef.Name,
				Length: colDef.Tp.Flen,
			},
		}
		for _, v := range colDef.Options {
			switch v.Tp {
			case ast.ColumnOptionNotNull:
				col.Flag |= mysql.NotNullFlag
			case ast.ColumnOptionNull:
				col.Flag &= ^uint(mysql.NotNullFlag)
				removeOnUpdateNowFlag(col)
			case ast.ColumnOptionAutoIncrement:
				col.Flag |= mysql.AutoIncrementFlag
			case ast.ColumnOptionPrimaryKey:
				constraint := &ast.Constraint{Tp: ast.ConstraintPrimaryKey, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.PriKeyFlag
			case ast.ColumnOptionUniq:
				constraint := &ast.Constraint{Tp: ast.ConstraintUniq, Name: colDef.Name.Name.O, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.UniqueKeyFlag
			case ast.ColumnOptionIndex:
				constraint := &ast.Constraint{Tp: ast.ConstraintIndex, Name: colDef.Name.Name.O, Keys: keys}
				constraints = append(constraints, constraint)
			case ast.ColumnOptionUniqIndex:
				constraint := &ast.Constraint{Tp: ast.ConstraintUniqIndex, Name: colDef.Name.Name.O, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.UniqueKeyFlag
			case ast.ColumnOptionKey:
				constraint := &ast.Constraint{Tp: ast.ConstraintKey, Name: colDef.Name.Name.O, Keys: keys}
				constraints = append(constraints, constraint)
			case ast.ColumnOptionUniqKey:
				constraint := &ast.Constraint{Tp: ast.ConstraintUniqKey, Name: colDef.Name.Name.O, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.UniqueKeyFlag
			case ast.ColumnOptionDefaultValue:
				value, err := getDefaultValue(ctx, v, colDef.Tp.Tp, colDef.Tp.Decimal)
				if err != nil {
					return nil, nil, ErrColumnBadNull.Gen("invalid default value - %s", err)
				}
				col.DefaultValue = value
				hasDefaultValue = true
				removeOnUpdateNowFlag(col)
			case ast.ColumnOptionOnUpdate:
				if !evaluator.IsCurrentTimeExpr(v.Expr) {
					return nil, nil, ErrInvalidOnUpdate.Gen("invalid ON UPDATE for - %s", col.Name)
				}

				col.Flag |= mysql.OnUpdateNowFlag
				setOnUpdateNow = true
			case ast.ColumnOptionComment:
				value, err := evaluator.Eval(ctx, v.Expr)
				if err != nil {
					return nil, nil, errors.Trace(err)
				}
				col.Comment, err = value.ToString()
				if err != nil {
					return nil, nil, errors.Trace(err)
				}
			case ast.ColumnOptionFulltext:
				// Do nothing.
			}
		}
	}

	setTimestampDefaultValue(col, hasDefaultValue, setOnUpdateNow)

	// Set `NoDefaultValueFlag` if this field doesn't have a default value and
	// it is `not null` and not an `AUTO_INCREMENT` field or `TIMESTAMP` field.
	setNoDefaultValueFlag(col, hasDefaultValue)

	err := checkDefaultValue(col, hasDefaultValue)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	if col.Charset == charset.CharsetBin {
		col.Flag |= mysql.BinaryFlag
	}
	return col, constraints, nil
}
Example #3
0
// ColumnDefToCol converts ColumnDef to Col and TableConstraints.
func ColumnDefToCol(offset int, colDef *ColumnDef) (*column.Col, []*TableConstraint, error) {
	constraints := []*TableConstraint{}
	col := &column.Col{
		ColumnInfo: model.ColumnInfo{
			Offset:    offset,
			Name:      model.NewCIStr(colDef.Name),
			FieldType: *colDef.Tp,
		},
	}

	// Check and set TimestampFlag and OnUpdateNowFlag.
	if col.Tp == mysql.TypeTimestamp {
		col.Flag |= mysql.TimestampFlag
		col.Flag |= mysql.OnUpdateNowFlag
		col.Flag |= mysql.NotNullFlag
	}

	// If flen is not assigned, assigned it by type.
	if col.Flen == types.UnspecifiedLength {
		col.Flen = mysql.GetDefaultFieldLength(col.Tp)
	}
	if col.Decimal == types.UnspecifiedLength {
		col.Decimal = mysql.GetDefaultDecimal(col.Tp)
	}

	setOnUpdateNow := false
	hasDefaultValue := false
	if colDef.Constraints != nil {
		keys := []*IndexColName{
			{
				colDef.Name,
				colDef.Tp.Flen,
			},
		}
		for _, v := range colDef.Constraints {
			switch v.Tp {
			case ConstrNotNull:
				col.Flag |= mysql.NotNullFlag
			case ConstrNull:
				col.Flag &= ^uint(mysql.NotNullFlag)
				removeOnUpdateNowFlag(col)
			case ConstrAutoIncrement:
				col.Flag |= mysql.AutoIncrementFlag
			case ConstrPrimaryKey:
				constraint := &TableConstraint{Tp: ConstrPrimaryKey, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.PriKeyFlag
			case ConstrUniq:
				constraint := &TableConstraint{Tp: ConstrUniq, ConstrName: colDef.Name, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.UniqueKeyFlag
			case ConstrIndex:
				constraint := &TableConstraint{Tp: ConstrIndex, ConstrName: colDef.Name, Keys: keys}
				constraints = append(constraints, constraint)
			case ConstrUniqIndex:
				constraint := &TableConstraint{Tp: ConstrUniqIndex, ConstrName: colDef.Name, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.UniqueKeyFlag
			case ConstrKey:
				constraint := &TableConstraint{Tp: ConstrKey, ConstrName: colDef.Name, Keys: keys}
				constraints = append(constraints, constraint)
			case ConstrUniqKey:
				constraint := &TableConstraint{Tp: ConstrUniqKey, ConstrName: colDef.Name, Keys: keys}
				constraints = append(constraints, constraint)
				col.Flag |= mysql.UniqueKeyFlag
			case ConstrDefaultValue:
				value, err := getDefaultValue(v, colDef.Tp.Tp, colDef.Tp.Decimal)
				if err != nil {
					return nil, nil, errors.Errorf("invalid default value - %s", errors.Trace(err))
				}
				col.DefaultValue = value
				hasDefaultValue = true
				removeOnUpdateNowFlag(col)
			case ConstrOnUpdate:
				if !expression.IsCurrentTimeExpr(v.Evalue) {
					return nil, nil, errors.Errorf("invalid ON UPDATE for - %s", col.Name)
				}

				col.Flag |= mysql.OnUpdateNowFlag
				setOnUpdateNow = true
			case ConstrFulltext:
				// Do nothing.
			case ConstrComment:
				// Do nothing.
			}
		}
	}

	setTimestampDefaultValue(col, hasDefaultValue, setOnUpdateNow)

	// Set `NoDefaultValueFlag` if this field doesn't have a default value and
	// it is `not null` and not an `AUTO_INCREMENT` field or `TIMESTAMP` field.
	setNoDefaultValueFlag(col, hasDefaultValue)

	err := checkDefaultValue(col, hasDefaultValue)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	if col.Charset == charset.CharsetBin {
		col.Flag |= mysql.BinaryFlag
	}
	return col, constraints, nil
}