Skip to content

Commit

Permalink
handle the case the type is set for SEND_LONG_DATA param
Browse files Browse the repository at this point in the history
Signed-off-by: Yang Keao <yangkeao@chunibyo.icu>
  • Loading branch information
YangKeao committed Apr 18, 2024
1 parent ecb8a9e commit a2f9e0a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 2 deletions.
25 changes: 24 additions & 1 deletion pkg/server/conn_stmt_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,30 @@ func parseBinaryParams(params []param.BinaryParam, boundParams [][]byte, nullBit
if boundParams[i] != nil {
params[i] = param.BinaryParam{
Tp: mysql.TypeBlob,
Val: enc.DecodeInput(boundParams[i]),
Val: boundParams[i],
}

if (i<<1)+1 < len(paramTypes) {
// Set the type and unsigned flag for the parameter. It's still not clear whether every clients
// will pass the `paramTypes` of the param which has already been sent through `SEND_LONG_DATA`.
// Therefore, only set the type when it's given.
//
// Only `BLOB` or `STRING` type will be sent through `SEND_LONG_DATA`, because others are usually
// small.
tp := paramTypes[i<<1]
isUnsigned := (paramTypes[(i<<1)+1] & 0x80) > 0

switch tp {
case mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeString, mysql.TypeBit:
params[i].Tp = tp
params[i].IsUnsigned = isUnsigned
params[i].Val = enc.DecodeInput(boundParams[i])
case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
// TODO: check whether it needs to decode the data.
params[i].Tp = tp
params[i].IsUnsigned = isUnsigned
params[i].Val = boundParams[i]
}
}
continue
}
Expand Down
27 changes: 27 additions & 0 deletions pkg/server/internal/testserverclient/server_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2727,4 +2727,31 @@ func (cli *TestServerClient) RunTestConnectionCount(t *testing.T) {
})
}

func (cli *TestServerClient) RunTestTypeOfSendLongData(t *testing.T) {
cli.RunTests(t, func(config *mysql.Config) {
config.MaxAllowedPacket = 1024
}, func(dbt *testkit.DBTestKit) {
ctx := context.Background()

conn, err := dbt.GetDB().Conn(ctx)
require.NoError(t, err)
_, err = conn.ExecContext(ctx, "CREATE TABLE t (j JSON);")
require.NoError(t, err)

str := `"` + strings.Repeat("a", 1024) + `"`
stmt, err := conn.PrepareContext(ctx, "INSERT INTO t VALUES (cast(? as JSON));")
require.NoError(t, err)
_, err = stmt.ExecContext(ctx, str)
require.NoError(t, err)
result, err := conn.QueryContext(ctx, "SELECT j FROM t;")
require.NoError(t, err)

for result.Next() {
var j string
require.NoError(t, result.Scan(&j))
require.Equal(t, str, j)
}
})
}

//revive:enable:exported
2 changes: 1 addition & 1 deletion pkg/server/tests/commontest/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ go_test(
"tidb_test.go",
],
flaky = True,
shard_count = 49,
shard_count = 50,
deps = [
"//pkg/config",
"//pkg/ddl/util",
Expand Down
5 changes: 5 additions & 0 deletions pkg/server/tests/commontest/tidb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3082,3 +3082,8 @@ func TestConnectionCount(t *testing.T) {
ts := servertestkit.CreateTidbTestSuite(t)
ts.RunTestConnectionCount(t)
}

func TestTypeOfSendLongData(t *testing.T) {
ts := servertestkit.CreateTidbTestSuite(t)
ts.RunTestTypeOfSendLongData(t)
}

0 comments on commit a2f9e0a

Please sign in to comment.