Example #1
0
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_extract
func builtinExtract(args []types.Datum, _ context.Context) (d types.Datum, err error) {
	unit := args[0].GetString()
	vd := args[1]

	if vd.Kind() == types.KindNull {
		d.SetNull()
		return d, nil
	}

	f := types.NewFieldType(mysql.TypeDatetime)
	f.Decimal = mysql.MaxFsp
	val, err := vd.ConvertTo(f)
	if err != nil {
		d.SetNull()
		return d, errors.Trace(err)
	}
	if val.Kind() == types.KindNull {
		d.SetNull()
		return d, nil
	}

	if val.Kind() != types.KindMysqlTime {
		err = errors.Errorf("need time type, but got %T", val)
		d.SetNull()
		return d, err
	}
	t := val.GetMysqlTime()
	n, err1 := mysql.ExtractTimeNum(unit, t)
	if err1 != nil {
		d.SetNull()
		return d, errors.Trace(err1)
	}
	d.SetInt64(n)
	return d, nil
}
Example #2
0
func (e *Evaluator) funcExtract(v *ast.FuncExtractExpr) bool {
	val := v.Date.GetValue()
	if val == nil {
		v.SetValue(nil)
		return true
	}

	f := types.NewFieldType(mysql.TypeDatetime)
	f.Decimal = mysql.MaxFsp
	var err error
	val, err = types.Convert(val, f)
	if err != nil {
		e.err = errors.Trace(err)
		return false
	}
	if val == nil {
		v.SetValue(nil)
		return true
	}

	t, ok := val.(mysql.Time)
	if !ok {
		e.err = ErrInvalidOperation.Gen("need time type, but got %T", val)
		return false
	}
	n, err1 := mysql.ExtractTimeNum(v.Unit, t)
	if err1 != nil {
		e.err = errors.Trace(err1)
		return false
	}
	v.SetValue(n)
	return true
}
Example #3
0
// Eval implements the Expression Eval interface.
func (e *Extract) Eval(ctx context.Context, args map[interface{}]interface{}) (interface{}, error) {
	v, err := e.Date.Eval(ctx, args)
	if v == nil || err != nil {
		return nil, errors.Trace(err)
	}

	f := types.NewFieldType(mysql.TypeDatetime)
	f.Decimal = mysql.MaxFsp

	v, err = types.Convert(v, f)
	if v == nil || err != nil {
		return nil, errors.Trace(err)
	}

	t, ok := v.(mysql.Time)
	if !ok {
		return nil, errors.Errorf("need time type, but got %T", v)
	}

	n, err1 := mysql.ExtractTimeNum(e.Unit, t)
	if err1 != nil {
		return nil, errors.Trace(err1)
	}

	return n, nil
}