Skip to content

Commit

Permalink
server: split code for serverutil (#45247)
Browse files Browse the repository at this point in the history
ref #44940
  • Loading branch information
hawkingrei authored Jul 10, 2023
1 parent aeda06e commit 0e83986
Show file tree
Hide file tree
Showing 11 changed files with 358 additions and 365 deletions.
5 changes: 5 additions & 0 deletions errors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2766,6 +2766,11 @@ error = '''
Resource control feature is disabled. Run `SET GLOBAL tidb_enable_resource_control='on'` to enable the feature
'''

["server:8057"]
error = '''
invalid type
'''

["session:8002"]
error = '''
[%d] can not retry select for update statement
Expand Down
3 changes: 0 additions & 3 deletions server/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ go_library(
"stat.go",
"statistics_handler.go",
"tokenlimiter.go",
"util.go",
],
importpath = "github.com/pingcap/tidb/server",
visibility = ["//visibility:public"],
Expand Down Expand Up @@ -158,7 +157,6 @@ go_test(
"tidb_library_test.go",
"tidb_serial_test.go",
"tidb_test.go",
"util_test.go",
],
data = glob(["testdata/**"]),
embed = [":server"],
Expand Down Expand Up @@ -213,7 +211,6 @@ go_test(
"//util/cpuprofile",
"//util/dbterror/exeerrors",
"//util/deadlockhistory",
"//util/mock",
"//util/plancodec",
"//util/replayer",
"//util/resourcegrouptag",
Expand Down
6 changes: 3 additions & 3 deletions server/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -2239,9 +2239,9 @@ func (cc *clientConn) writeChunks(ctx context.Context, rs ResultSet, binary bool
for i := 0; i < rowCount; i++ {
data = data[0:4]
if binary {
data, err = dumpBinaryRow(data, rs.Columns(), req.GetRow(i), cc.rsEncoder)
data, err = column.DumpBinaryRow(data, rs.Columns(), req.GetRow(i), cc.rsEncoder)
} else {
data, err = dumpTextRow(data, rs.Columns(), req.GetRow(i), cc.rsEncoder)
data, err = column.DumpTextRow(data, rs.Columns(), req.GetRow(i), cc.rsEncoder)
}
if err != nil {
reg.End()
Expand Down Expand Up @@ -2295,7 +2295,7 @@ func (cc *clientConn) writeChunksWithFetchSize(ctx context.Context, rs cursorRes
row := iter.Current()

data = data[0:4]
data, err = dumpBinaryRow(data, rs.Columns(), row, cc.rsEncoder)
data, err = column.DumpBinaryRow(data, rs.Columns(), row, cc.rsEncoder)
if err != nil {
return err
}
Expand Down
23 changes: 23 additions & 0 deletions server/err/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")

go_library(
name = "error",
srcs = ["error.go"],
importpath = "github.com/pingcap/tidb/server/error",
visibility = ["//visibility:public"],
deps = [
"//errno",
"//util/dbterror",
],
)

go_library(
name = "err",
srcs = ["error.go"],
importpath = "github.com/pingcap/tidb/server/err",
visibility = ["//visibility:public"],
deps = [
"//errno",
"//util/dbterror",
],
)
23 changes: 23 additions & 0 deletions server/err/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2023 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package err

import (
"github.com/pingcap/tidb/errno"
"github.com/pingcap/tidb/util/dbterror"
)

// ErrInvalidType is returned when the type of a value is not expected.
var ErrInvalidType = dbterror.ClassServer.NewStd(errno.ErrInvalidType)
12 changes: 11 additions & 1 deletion server/internal/column/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ go_library(
deps = [
"//parser/charset",
"//parser/mysql",
"//server/err",
"//server/internal/dump",
"//server/internal/util",
"//types",
"//util/chunk",
"//util/hack",
"//util/logutil",
"@org_uber_go_zap//:zap",
],
Expand All @@ -26,9 +31,14 @@ go_test(
],
embed = [":column"],
flaky = True,
shard_count = 4,
shard_count = 5,
deps = [
"//parser/charset",
"//parser/mysql",
"//server/internal/util",
"//types",
"//util/chunk",
"//util/mock",
"@com_github_stretchr_testify//require",
],
)
140 changes: 140 additions & 0 deletions server/internal/column/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@ package column

import (
"fmt"
"math"
"strconv"

"github.com/pingcap/tidb/parser/charset"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/server/err"
"github.com/pingcap/tidb/server/internal/dump"
"github.com/pingcap/tidb/server/internal/util"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/hack"
)

const maxColumnNameSize = 256
Expand Down Expand Up @@ -108,3 +115,136 @@ func dumpType(tp byte) byte {
return tp
}
}

// DumpTextRow dumps a row to bytes.
func DumpTextRow(buffer []byte, columns []*Info, row chunk.Row, d *ResultEncoder) ([]byte, error) {
if d == nil {
d = NewResultEncoder(charset.CharsetUTF8MB4)
}
tmp := make([]byte, 0, 20)
for i, col := range columns {
if row.IsNull(i) {
buffer = append(buffer, 0xfb)
continue
}
switch col.Type {
case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong:
tmp = strconv.AppendInt(tmp[:0], row.GetInt64(i), 10)
buffer = dump.LengthEncodedString(buffer, tmp)
case mysql.TypeYear:
year := row.GetInt64(i)
tmp = tmp[:0]
if year == 0 {
tmp = append(tmp, '0', '0', '0', '0')
} else {
tmp = strconv.AppendInt(tmp, year, 10)
}
buffer = dump.LengthEncodedString(buffer, tmp)
case mysql.TypeLonglong:
if mysql.HasUnsignedFlag(uint(columns[i].Flag)) {
tmp = strconv.AppendUint(tmp[:0], row.GetUint64(i), 10)
} else {
tmp = strconv.AppendInt(tmp[:0], row.GetInt64(i), 10)
}
buffer = dump.LengthEncodedString(buffer, tmp)
case mysql.TypeFloat:
prec := -1
if columns[i].Decimal > 0 && int(col.Decimal) != mysql.NotFixedDec && col.Table == "" {
prec = int(col.Decimal)
}
tmp = util.AppendFormatFloat(tmp[:0], float64(row.GetFloat32(i)), prec, 32)
buffer = dump.LengthEncodedString(buffer, tmp)
case mysql.TypeDouble:
prec := types.UnspecifiedLength
if col.Decimal > 0 && int(col.Decimal) != mysql.NotFixedDec && col.Table == "" {
prec = int(col.Decimal)
}
tmp = util.AppendFormatFloat(tmp[:0], row.GetFloat64(i), prec, 64)
buffer = dump.LengthEncodedString(buffer, tmp)
case mysql.TypeNewDecimal:
buffer = dump.LengthEncodedString(buffer, hack.Slice(row.GetMyDecimal(i).String()))
case mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar, mysql.TypeBit,
mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeBlob:
d.UpdateDataEncoding(col.Charset)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(row.GetBytes(i)))
case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp:
buffer = dump.LengthEncodedString(buffer, hack.Slice(row.GetTime(i).String()))
case mysql.TypeDuration:
dur := row.GetDuration(i, int(col.Decimal))
buffer = dump.LengthEncodedString(buffer, hack.Slice(dur.String()))
case mysql.TypeEnum:
d.UpdateDataEncoding(col.Charset)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(hack.Slice(row.GetEnum(i).String())))
case mysql.TypeSet:
d.UpdateDataEncoding(col.Charset)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(hack.Slice(row.GetSet(i).String())))
case mysql.TypeJSON:
// The collation of JSON type is always binary.
// To compatible with MySQL, here we treat it as utf-8.
d.UpdateDataEncoding(mysql.DefaultCollationID)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(hack.Slice(row.GetJSON(i).String())))
default:
return nil, err.ErrInvalidType.GenWithStack("invalid type %v", columns[i].Type)
}
}
return buffer, nil
}

// DumpBinaryRow dumps a row to bytes.
func DumpBinaryRow(buffer []byte, columns []*Info, row chunk.Row, d *ResultEncoder) ([]byte, error) {
if d == nil {
d = NewResultEncoder(charset.CharsetUTF8MB4)
}
buffer = append(buffer, mysql.OKHeader)
nullBitmapOff := len(buffer)
numBytes4Null := (len(columns) + 7 + 2) / 8
for i := 0; i < numBytes4Null; i++ {
buffer = append(buffer, 0)
}
for i := range columns {
if row.IsNull(i) {
bytePos := (i + 2) / 8
bitPos := byte((i + 2) % 8)
buffer[nullBitmapOff+bytePos] |= 1 << bitPos
continue
}
switch columns[i].Type {
case mysql.TypeTiny:
buffer = append(buffer, byte(row.GetInt64(i)))
case mysql.TypeShort, mysql.TypeYear:
buffer = dump.Uint16(buffer, uint16(row.GetInt64(i)))
case mysql.TypeInt24, mysql.TypeLong:
buffer = dump.Uint32(buffer, uint32(row.GetInt64(i)))
case mysql.TypeLonglong:
buffer = dump.Uint64(buffer, row.GetUint64(i))
case mysql.TypeFloat:
buffer = dump.Uint32(buffer, math.Float32bits(row.GetFloat32(i)))
case mysql.TypeDouble:
buffer = dump.Uint64(buffer, math.Float64bits(row.GetFloat64(i)))
case mysql.TypeNewDecimal:
buffer = dump.LengthEncodedString(buffer, hack.Slice(row.GetMyDecimal(i).String()))
case mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar, mysql.TypeBit,
mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeBlob:
d.UpdateDataEncoding(columns[i].Charset)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(row.GetBytes(i)))
case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp:
buffer = dump.BinaryDateTime(buffer, row.GetTime(i))
case mysql.TypeDuration:
buffer = append(buffer, dump.BinaryTime(row.GetDuration(i, 0).Duration)...)
case mysql.TypeEnum:
d.UpdateDataEncoding(columns[i].Charset)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(hack.Slice(row.GetEnum(i).String())))
case mysql.TypeSet:
d.UpdateDataEncoding(columns[i].Charset)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(hack.Slice(row.GetSet(i).String())))
case mysql.TypeJSON:
// The collation of JSON type is always binary.
// To compatible with MySQL, here we treat it as utf-8.
d.UpdateDataEncoding(mysql.DefaultCollationID)
buffer = dump.LengthEncodedString(buffer, d.EncodeData(hack.Slice(row.GetJSON(i).String())))
default:
return nil, err.ErrInvalidType.GenWithStack("invalid type %v", columns[i].Type)
}
}
return buffer, nil
}
Loading

0 comments on commit 0e83986

Please sign in to comment.