Example #1
0
File: util.go Project: pingcap/tidb
func dumpTextValue(mysqlType uint8, value types.Datum) ([]byte, error) {
	switch value.Kind() {
	case types.KindInt64:
		return strconv.AppendInt(nil, value.GetInt64(), 10), nil
	case types.KindUint64:
		return strconv.AppendUint(nil, value.GetUint64(), 10), nil
	case types.KindFloat32:
		return strconv.AppendFloat(nil, value.GetFloat64(), 'f', -1, 32), nil
	case types.KindFloat64:
		return strconv.AppendFloat(nil, value.GetFloat64(), 'f', -1, 64), nil
	case types.KindString, types.KindBytes:
		return value.GetBytes(), nil
	case types.KindMysqlTime:
		return hack.Slice(value.GetMysqlTime().String()), nil
	case types.KindMysqlDuration:
		return hack.Slice(value.GetMysqlDuration().String()), nil
	case types.KindMysqlDecimal:
		return hack.Slice(value.GetMysqlDecimal().String()), nil
	case types.KindMysqlEnum:
		return hack.Slice(value.GetMysqlEnum().String()), nil
	case types.KindMysqlSet:
		return hack.Slice(value.GetMysqlSet().String()), nil
	case types.KindMysqlBit:
		return hack.Slice(value.GetMysqlBit().ToString()), nil
	case types.KindMysqlHex:
		return hack.Slice(value.GetMysqlHex().ToString()), nil
	default:
		return nil, errInvalidType.Gen("invalid type %T", value)
	}
}
Example #2
0
func flatten(data types.Datum) (types.Datum, error) {
	switch data.Kind() {
	case types.KindMysqlTime:
		// for mysql datetime, timestamp and date type
		b, err := data.GetMysqlTime().Marshal()
		if err != nil {
			return types.NewDatum(nil), errors.Trace(err)
		}
		return types.NewDatum(b), nil
	case types.KindMysqlDuration:
		// for mysql time type
		data.SetInt64(int64(data.GetMysqlDuration().Duration))
		return data, nil
	case types.KindMysqlDecimal:
		data.SetString(data.GetMysqlDecimal().String())
		return data, nil
	case types.KindMysqlEnum:
		data.SetUint64(data.GetMysqlEnum().Value)
		return data, nil
	case types.KindMysqlSet:
		data.SetUint64(data.GetMysqlSet().Value)
		return data, nil
	case types.KindMysqlBit:
		data.SetUint64(data.GetMysqlBit().Value)
		return data, nil
	case types.KindMysqlHex:
		data.SetInt64(data.GetMysqlHex().Value)
		return data, nil
	default:
		return data, nil
	}
}
Example #3
0
func flatten(data types.Datum) (types.Datum, error) {
	switch data.Kind() {
	case types.KindMysqlTime:
		// for mysql datetime, timestamp and date type
		return types.NewUintDatum(data.GetMysqlTime().ToPackedUint()), nil
	case types.KindMysqlDuration:
		// for mysql time type
		data.SetInt64(int64(data.GetMysqlDuration().Duration))
		return data, nil
	case types.KindMysqlDecimal:
		data.SetString(data.GetMysqlDecimal().String())
		return data, nil
	case types.KindMysqlEnum:
		data.SetUint64(data.GetMysqlEnum().Value)
		return data, nil
	case types.KindMysqlSet:
		data.SetUint64(data.GetMysqlSet().Value)
		return data, nil
	case types.KindMysqlBit:
		data.SetUint64(data.GetMysqlBit().Value)
		return data, nil
	case types.KindMysqlHex:
		data.SetInt64(data.GetMysqlHex().Value)
		return data, nil
	default:
		return data, nil
	}
}
Example #4
0
func datumExpr(d types.Datum) *tipb.Expr {
	expr := new(tipb.Expr)
	switch d.Kind() {
	case types.KindInt64:
		expr.Tp = tipb.ExprType_Int64.Enum()
		expr.Val = codec.EncodeInt(nil, d.GetInt64())
	case types.KindUint64:
		expr.Tp = tipb.ExprType_Uint64.Enum()
		expr.Val = codec.EncodeUint(nil, d.GetUint64())
	case types.KindString:
		expr.Tp = tipb.ExprType_String.Enum()
		expr.Val = d.GetBytes()
	case types.KindBytes:
		expr.Tp = tipb.ExprType_Bytes.Enum()
		expr.Val = d.GetBytes()
	case types.KindFloat32:
		expr.Tp = tipb.ExprType_Float32.Enum()
		expr.Val = codec.EncodeFloat(nil, d.GetFloat64())
	case types.KindFloat64:
		expr.Tp = tipb.ExprType_Float64.Enum()
		expr.Val = codec.EncodeFloat(nil, d.GetFloat64())
	case types.KindMysqlDuration:
		expr.Tp = tipb.ExprType_MysqlDuration.Enum()
		expr.Val = codec.EncodeInt(nil, int64(d.GetMysqlDuration().Duration))
	case types.KindMysqlDecimal:
		expr.Tp = tipb.ExprType_MysqlDecimal.Enum()
		expr.Val = codec.EncodeDecimal(nil, d.GetMysqlDecimal())
	default:
		expr.Tp = tipb.ExprType_Null.Enum()
	}
	return expr
}
Example #5
0
func testFrac(c *C, v *mysql.MyDecimal) {
	var d1 types.Datum
	d1.SetMysqlDecimal(v)
	b := EncodeDecimal([]byte{}, d1)
	_, d2, err := DecodeDecimal(b)
	c.Assert(err, IsNil)
	cmp, err := d1.CompareDatum(d2)
	c.Assert(err, IsNil)
	c.Assert(cmp, Equals, 0)
	c.Assert(d1.GetMysqlDecimal().String(), Equals, d2.GetMysqlDecimal().String())
}
Example #6
0
func testFrac(c *C, v *types.MyDecimal) {
	var d1 types.Datum
	d1.SetMysqlDecimal(v)
	b := EncodeDecimal([]byte{}, d1)
	_, d2, err := DecodeDecimal(b)
	c.Assert(err, IsNil)
	sc := new(variable.StatementContext)
	cmp, err := d1.CompareDatum(sc, d2)
	c.Assert(err, IsNil)
	c.Assert(cmp, Equals, 0)
	c.Assert(d1.GetMysqlDecimal().String(), Equals, d2.GetMysqlDecimal().String())
}
Example #7
0
// EncodeDecimal encodes a decimal d into a byte slice which can be sorted lexicographically later.
func EncodeDecimal(b []byte, d types.Datum) []byte {
	dec := d.GetMysqlDecimal()
	precision := d.Length()
	frac := d.Frac()
	if precision == 0 {
		precision, frac = dec.PrecisionAndFrac()
	}
	b = append(b, byte(precision), byte(frac))
	bin, err := dec.ToBin(precision, frac)
	if err != nil {
		log.Errorf("should not happen, precision %d, frac %d %v", precision, frac, err)
		return b
	}
	b = append(b, bin...)
	return b
}
Example #8
0
func computeMul(a, b types.Datum) (d types.Datum, err error) {
	switch a.Kind() {
	case types.KindInt64:
		switch b.Kind() {
		case types.KindInt64:
			r, err1 := types.MulInt64(a.GetInt64(), b.GetInt64())
			d.SetInt64(r)
			return d, errors.Trace(err1)
		case types.KindUint64:
			r, err1 := types.MulInteger(b.GetUint64(), a.GetInt64())
			d.SetUint64(r)
			return d, errors.Trace(err1)
		}
	case types.KindUint64:
		switch b.Kind() {
		case types.KindInt64:
			r, err1 := types.MulInteger(a.GetUint64(), b.GetInt64())
			d.SetUint64(r)
			return d, errors.Trace(err1)
		case types.KindUint64:
			r, err1 := types.MulUint64(a.GetUint64(), b.GetUint64())
			d.SetUint64(r)
			return d, errors.Trace(err1)
		}
	case types.KindFloat64:
		switch b.Kind() {
		case types.KindFloat64:
			r := a.GetFloat64() * b.GetFloat64()
			d.SetFloat64(r)
			return d, nil
		}
	case types.KindMysqlDecimal:
		switch b.Kind() {
		case types.KindMysqlDecimal:
			r := a.GetMysqlDecimal().Mul(b.GetMysqlDecimal())
			d.SetMysqlDecimal(r)
			return d, nil
		}
	}

	_, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Mul)
	return d, errors.Trace(err)
}
Example #9
0
func computeMinus(a, b types.Datum) (d types.Datum, err error) {
	switch a.Kind() {
	case types.KindInt64:
		switch b.Kind() {
		case types.KindInt64:
			r, err1 := types.SubInt64(a.GetInt64(), b.GetInt64())
			d.SetInt64(r)
			return d, errors.Trace(err1)
		case types.KindUint64:
			r, err1 := types.SubIntWithUint(a.GetInt64(), b.GetUint64())
			d.SetUint64(r)
			return d, errors.Trace(err1)
		}
	case types.KindUint64:
		switch b.Kind() {
		case types.KindInt64:
			r, err1 := types.SubUintWithInt(a.GetUint64(), b.GetInt64())
			d.SetUint64(r)
			return d, errors.Trace(err1)
		case types.KindUint64:
			r, err1 := types.SubUint64(a.GetUint64(), b.GetUint64())
			d.SetUint64(r)
			return d, errors.Trace(err1)
		}
	case types.KindFloat64:
		switch b.Kind() {
		case types.KindFloat64:
			r := a.GetFloat64() - b.GetFloat64()
			d.SetFloat64(r)
			return d, nil
		}
	case types.KindMysqlDecimal:
		switch b.Kind() {
		case types.KindMysqlDecimal:
			r := a.GetMysqlDecimal().Sub(b.GetMysqlDecimal())
			d.SetMysqlDecimal(r)
			return d, nil
		}
	}
	_, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Minus)
	return d, errors.Trace(err)
}
Example #10
0
func (b *executorBuilder) datumToPBExpr(client kv.Client, d types.Datum) *tipb.Expr {
	var tp tipb.ExprType
	var val []byte
	switch d.Kind() {
	case types.KindNull:
		tp = tipb.ExprType_Null
	case types.KindInt64:
		tp = tipb.ExprType_Int64
		val = codec.EncodeInt(nil, d.GetInt64())
	case types.KindUint64:
		tp = tipb.ExprType_Uint64
		val = codec.EncodeUint(nil, d.GetUint64())
	case types.KindString:
		tp = tipb.ExprType_String
		val = d.GetBytes()
	case types.KindBytes:
		tp = tipb.ExprType_Bytes
		val = d.GetBytes()
	case types.KindFloat32:
		tp = tipb.ExprType_Float32
		val = codec.EncodeFloat(nil, d.GetFloat64())
	case types.KindFloat64:
		tp = tipb.ExprType_Float64
		val = codec.EncodeFloat(nil, d.GetFloat64())
	case types.KindMysqlDuration:
		tp = tipb.ExprType_MysqlDuration
		val = codec.EncodeInt(nil, int64(d.GetMysqlDuration().Duration))
	case types.KindMysqlDecimal:
		tp = tipb.ExprType_MysqlDecimal
		val = codec.EncodeDecimal(nil, d.GetMysqlDecimal())
	default:
		return nil
	}
	if !client.SupportRequestType(kv.ReqTypeSelect, int64(tp)) {
		return nil
	}
	return &tipb.Expr{Tp: tp.Enum(), Val: val}
}
Example #11
0
func computeMod(a, b types.Datum) (d types.Datum, err error) {
	switch a.Kind() {
	case types.KindInt64:
		x := a.GetInt64()
		switch b.Kind() {
		case types.KindInt64:
			y := b.GetInt64()
			if y == 0 {
				return d, nil
			}
			d.SetInt64(x % y)
			return d, nil
		case types.KindUint64:
			y := b.GetUint64()
			if y == 0 {
				return d, nil
			} else if x < 0 {
				d.SetInt64(-int64(uint64(-x) % y))
				// first is int64, return int64.
				return d, nil
			}
			d.SetInt64(int64(uint64(x) % y))
			return d, nil
		}
	case types.KindUint64:
		x := a.GetUint64()
		switch b.Kind() {
		case types.KindInt64:
			y := b.GetInt64()
			if y == 0 {
				return d, nil
			} else if y < 0 {
				// first is uint64, return uint64.
				d.SetUint64(uint64(x % uint64(-y)))
				return d, nil
			}
			d.SetUint64(x % uint64(y))
			return d, nil
		case types.KindUint64:
			y := b.GetUint64()
			if y == 0 {
				return d, nil
			}
			d.SetUint64(x % y)
			return d, nil
		}
	case types.KindFloat64:
		x := a.GetFloat64()
		switch b.Kind() {
		case types.KindFloat64:
			y := b.GetFloat64()
			if y == 0 {
				return d, nil
			}
			d.SetFloat64(math.Mod(x, y))
			return d, nil
		}
	case types.KindMysqlDecimal:
		x := a.GetMysqlDecimal()
		switch b.Kind() {
		case types.KindMysqlDecimal:
			y := b.GetMysqlDecimal()
			xf, _ := x.Float64()
			yf, _ := y.Float64()
			if yf == 0 {
				return d, nil
			}
			d.SetFloat64(math.Mod(xf, yf))
			return d, nil
		}
	}
	_, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Mod)
	return d, errors.Trace(err)
}
Example #12
0
// unflatten converts a raw datum to a column datum.
func unflatten(datum types.Datum, ft *types.FieldType) (types.Datum, error) {
	if datum.IsNull() {
		return datum, nil
	}
	switch ft.Tp {
	case mysql.TypeFloat:
		datum.SetFloat32(float32(datum.GetFloat64()))
		return datum, nil
	case mysql.TypeTiny, mysql.TypeShort, mysql.TypeYear, mysql.TypeInt24,
		mysql.TypeLong, mysql.TypeLonglong, mysql.TypeDouble, mysql.TypeTinyBlob,
		mysql.TypeMediumBlob, mysql.TypeBlob, mysql.TypeLongBlob, mysql.TypeVarchar,
		mysql.TypeString:
		return datum, nil
	case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp:
		var t mysql.Time
		t.Type = ft.Tp
		t.Fsp = ft.Decimal
		err := t.Unmarshal(datum.GetBytes())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetMysqlTime(t)
		return datum, nil
	case mysql.TypeDuration:
		dur := mysql.Duration{Duration: time.Duration(datum.GetInt64())}
		datum.SetValue(dur)
		return datum, nil
	case mysql.TypeNewDecimal:
		if datum.Kind() == types.KindMysqlDecimal {
			if ft.Decimal >= 0 {
				dec := datum.GetMysqlDecimal().Truncate(int32(ft.Decimal))
				datum.SetMysqlDecimal(dec)
			}
			return datum, nil
		}
		dec, err := mysql.ParseDecimal(datum.GetString())
		if err != nil {
			return datum, errors.Trace(err)
		}
		if ft.Decimal >= 0 {
			dec = dec.Truncate(int32(ft.Decimal))
		}
		datum.SetValue(dec)
		return datum, nil
	case mysql.TypeEnum:
		enum, err := mysql.ParseEnumValue(ft.Elems, datum.GetUint64())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetValue(enum)
		return datum, nil
	case mysql.TypeSet:
		set, err := mysql.ParseSetValue(ft.Elems, datum.GetUint64())
		if err != nil {
			return datum, errors.Trace(err)
		}
		datum.SetValue(set)
		return datum, nil
	case mysql.TypeBit:
		bit := mysql.Bit{Value: datum.GetUint64(), Width: ft.Flen}
		datum.SetValue(bit)
		return datum, nil
	}
	return datum, nil
}