diff --git a/distsql/distsql.go b/distsql/distsql.go index 5a4be1a97d154..80d4960a3328e 100644 --- a/distsql/distsql.go +++ b/distsql/distsql.go @@ -16,6 +16,7 @@ package distsql import ( "context" "fmt" + "unsafe" "github.com/opentracing/opentracing-go" "github.com/pingcap/errors" @@ -146,6 +147,7 @@ func Checksum(ctx context.Context, client kv.Client, kvReq *kv.Request, vars *kv func SetEncodeType(ctx sessionctx.Context, dagReq *tipb.DAGRequest) { if canUseChunkRPC(ctx) { dagReq.EncodeType = tipb.EncodeType_TypeChunk + setChunkMemoryLayout(dagReq) } else { dagReq.EncodeType = tipb.EncodeType_TypeDefault } @@ -158,5 +160,41 @@ func canUseChunkRPC(ctx sessionctx.Context) bool { if ctx.GetSessionVars().EnableStreaming { return false } + if !checkAlignment() { + return false + } return true } + +var supportedAlignment = !(unsafe.Sizeof(types.MysqlTime{}) != 16 || + unsafe.Sizeof(types.Time{}) != 20 || + unsafe.Sizeof(types.MyDecimal{}) != 40) + +// checkAlignment checks the alignment in current system environment. +// The alignment is influenced by system, machine and Golang version. +// Using this function can guarantee the alignment is we want. +func checkAlignment() bool { + return supportedAlignment +} + +var systemEndian tipb.Endian + +// setChunkMemoryLayout sets the chunk memory layout for the DAGRequest. +func setChunkMemoryLayout(dagReq *tipb.DAGRequest) { + dagReq.ChunkMemoryLayout = &tipb.ChunkMemoryLayout{Endian: GetSystemEndian()} +} + +// GetSystemEndian gets the system endian. +func GetSystemEndian() tipb.Endian { + return systemEndian +} + +func init() { + var i int = 0x0100 + ptr := unsafe.Pointer(&i) + if 0x01 == *(*byte)(ptr) { + systemEndian = tipb.Endian_BigEndian + } else { + systemEndian = tipb.Endian_LittleEndian + } +} diff --git a/go.mod b/go.mod index d57f7b4acc3c1..58ab75dc12000 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/pingcap/pd v1.1.0-beta.0.20190923032047-5c648dc365e0 github.com/pingcap/sysutil v0.0.0-20191126040022-986c5b3ed9a3 github.com/pingcap/tidb-tools v3.0.6-0.20191106033616-90632dda3863+incompatible - github.com/pingcap/tipb v0.0.0-20191120020146-6161b015e21e + github.com/pingcap/tipb v0.0.0-20191127084114-0820b784842f github.com/prometheus/client_golang v1.0.0 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 github.com/remyoudompheng/bigfft v0.0.0-20190512091148-babf20351dd7 // indirect diff --git a/go.sum b/go.sum index f6ee2b835ec7d..0cb5c7a16dba9 100644 --- a/go.sum +++ b/go.sum @@ -194,8 +194,8 @@ github.com/pingcap/sysutil v0.0.0-20191126040022-986c5b3ed9a3 h1:HCNif3lukL83gNC github.com/pingcap/sysutil v0.0.0-20191126040022-986c5b3ed9a3/go.mod h1:Futrrmuw98pEsbEmoPsjw8aKLCmixwHEmT2rF+AsXGw= github.com/pingcap/tidb-tools v3.0.6-0.20191106033616-90632dda3863+incompatible h1:H1jg0aDWz2SLRh3hNBo2HFtnuHtudIUvBumU7syRkic= github.com/pingcap/tidb-tools v3.0.6-0.20191106033616-90632dda3863+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM= -github.com/pingcap/tipb v0.0.0-20191120020146-6161b015e21e h1:OWgXsJ2Zwa+q+sqi87fGuNda+ChJrclVd7wiGP5Epps= -github.com/pingcap/tipb v0.0.0-20191120020146-6161b015e21e/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI= +github.com/pingcap/tipb v0.0.0-20191127084114-0820b784842f h1:ywyH6JKJIf+gEYg2kRlU8SaPMryHgu5SoXKtPdkeZPU= +github.com/pingcap/tipb v0.0.0-20191127084114-0820b784842f/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/store/mockstore/mocktikv/cop_handler_dag.go b/store/mockstore/mocktikv/cop_handler_dag.go index 4362f37dadef0..693d3a79bc7fc 100644 --- a/store/mockstore/mocktikv/cop_handler_dag.go +++ b/store/mockstore/mocktikv/cop_handler_dag.go @@ -28,6 +28,7 @@ import ( "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" + "github.com/pingcap/tidb/distsql" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/expression/aggregation" "github.com/pingcap/tidb/kv" @@ -574,6 +575,9 @@ func (h *rpcHandler) fillUpData4SelectResponse(selResp *tipb.SelectResponse, dag case tipb.EncodeType_TypeDefault: h.encodeDefault(selResp, rows, dagReq.OutputOffsets) case tipb.EncodeType_TypeChunk: + if dagReq.GetChunkMemoryLayout().GetEndian() != distsql.GetSystemEndian() { + return errors.Errorf("Mocktikv endian must be the same as TiDB system endian.") + } colTypes := h.constructRespSchema(dagCtx) loc := dagCtx.evalCtx.sc.TimeZone err := h.encodeChunk(selResp, rows, colTypes, dagReq.OutputOffsets, loc)