func builtinNow(args []interface{}, ctx map[interface{}]interface{}) (interface{}, error) { // TODO: if NOW is used in stored function or trigger, NOW will return the beginning time // of the execution. fsp := 0 if len(args) == 1 { var err error if fsp, err = checkFsp(args[0]); err != nil { return nil, errors.Trace(err) } } t := mysql.Time{ Time: time.Now(), Type: mysql.TypeDatetime, // set unspecified for later round Fsp: mysql.UnspecifiedFsp, } return t.RoundFrac(int(fsp)) }
func builtinNow(args []interface{}, ctx map[interface{}]interface{}) (interface{}, error) { fsp := int64(0) if len(args) == 1 { var err error fsp, err = types.ToInt64(args[0]) if err != nil { return nil, errors.Trace(err) } if int(fsp) > mysql.MaxFsp { return nil, errors.Errorf("Too big precision %d specified. Maximum is 6.", fsp) } else if fsp < 0 { return nil, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp) } } t := mysql.Time{ Time: time.Now(), Type: mysql.TypeDatetime, // set unspecified for later round Fsp: mysql.UnspecifiedFsp, } return t.RoundFrac(int(fsp)) }
// Cast casts val to certain types and does not return error. func Cast(val interface{}, target *FieldType) (v interface{}) { //NTYPE tp := target.Tp switch tp { case mysql.TypeString: x, _ := ToString(val) // TODO: consider target.Charset/Collate x = truncateStr(x, target.Flen) if target.Charset == charset.CharsetBin { return []byte(x) } return x case mysql.TypeDuration: var dur mysql.Duration fsp := mysql.DefaultFsp if target.Decimal != UnspecifiedLength { fsp = target.Decimal } switch x := val.(type) { case mysql.Duration: dur, _ = x.RoundFrac(fsp) case mysql.Time: dur, _ = x.ConvertToDuration() dur, _ = dur.RoundFrac(fsp) case string: dur, _ = mysql.ParseDuration(x, fsp) } return dur case mysql.TypeDatetime, mysql.TypeDate: fsp := mysql.DefaultFsp if target.Decimal != UnspecifiedLength { fsp = target.Decimal } var t mysql.Time t.Type = tp switch x := val.(type) { case mysql.Time: t, _ = x.Convert(tp) t, _ = t.RoundFrac(fsp) case mysql.Duration: t, _ = x.ConvertToTime(tp) t, _ = t.RoundFrac(fsp) case string: t, _ = mysql.ParseTime(x, tp, fsp) case int64: t, _ = mysql.ParseTimeFromNum(x, tp, fsp) } return t case mysql.TypeLonglong: if mysql.HasUnsignedFlag(target.Flag) { v, _ = ToUint64(val) } else { v, _ = ToInt64(val) } return case mysql.TypeNewDecimal: x, _ := ToDecimal(val) if target.Decimal != UnspecifiedLength { x = x.Round(int32(target.Decimal)) } // TODO: check Flen return x default: panic("should never happen") } }
// CastValue casts a value based on column's type. func (c *Col) CastValue(ctx context.Context, val interface{}) (casted interface{}, err error) { if val == nil { return } switch c.Tp { case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong, mysql.TypeYear, mysql.TypeBit: intVal, errCode := c.normalizeIntegerValue(val) if errCode == errCodeType { casted = intVal err = c.TypeError(val) return } return c.castIntegerValue(intVal, errCode) case mysql.TypeFloat, mysql.TypeDouble: return c.castFloatValue(val) case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp: switch v := val.(type) { case int64: casted, err = mysql.ParseTimeFromNum(v, c.Tp, c.Decimal) if err != nil { err = newParseColError(err, c) } case string: casted, err = mysql.ParseTime(v, c.Tp, c.Decimal) if err != nil { err = newParseColError(err, c) } case mysql.Time: var t mysql.Time t, err = v.Convert(c.Tp) if err != nil { err = newParseColError(err, c) return } casted, err = t.RoundFrac(c.Decimal) if err != nil { err = newParseColError(err, c) } default: err = c.TypeError(val) } case mysql.TypeDuration: switch v := val.(type) { case string: casted, err = mysql.ParseDuration(v, c.Decimal) if err != nil { err = newParseColError(err, c) } case mysql.Time: var t mysql.Duration t, err = v.ConvertToDuration() if err != nil { err = newParseColError(err, c) return } casted, err = t.RoundFrac(c.Decimal) if err != nil { err = newParseColError(err, c) } case mysql.Duration: casted, err = v.RoundFrac(c.Decimal) default: err = c.TypeError(val) } case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString: strV := "" switch v := val.(type) { case mysql.Time: strV = v.String() case mysql.Duration: strV = v.String() case []byte: if c.Charset == charset.CharsetBin { casted = v return } strV = string(v) default: strV = fmt.Sprintf("%v", val) } if (c.Flen != types.UnspecifiedLength) && (len(strV) > c.Flen) { strV = strV[:c.Flen] } casted = strV case mysql.TypeDecimal, mysql.TypeNewDecimal: switch v := val.(type) { case string: casted, err = mysql.ParseDecimal(v) if err != nil { err = newParseColError(err, c) } case int8: casted = mysql.NewDecimalFromInt(int64(v), 0) case int16: casted = mysql.NewDecimalFromInt(int64(v), 0) case int32: casted = mysql.NewDecimalFromInt(int64(v), 0) case int64: casted = mysql.NewDecimalFromInt(int64(v), 0) case int: casted = mysql.NewDecimalFromInt(int64(v), 0) case uint8: casted = mysql.NewDecimalFromUint(uint64(v), 0) case uint16: casted = mysql.NewDecimalFromUint(uint64(v), 0) case uint32: casted = mysql.NewDecimalFromUint(uint64(v), 0) case uint64: casted = mysql.NewDecimalFromUint(uint64(v), 0) case uint: casted = mysql.NewDecimalFromUint(uint64(v), 0) case float32: casted = mysql.NewDecimalFromFloat(float64(v)) case float64: casted = mysql.NewDecimalFromFloat(float64(v)) case mysql.Decimal: casted = v } default: err = c.TypeError(val) } return }