Repository: matrixorigin/matrixone
Pull request #3571 (2022-06-30 09:28:26)

logservice: use sync.Pool to avoid morpc allocations
**What type of PR is this?**

- [ ] API-change
- [ ] BUG
- [ ] Improvement
- [ ] Documentation
- [ ] Feature
- [ ] Test and CI
- [ ] Code Refactoring

**Which issue(s) this PR fixes:**

issue #

**What this PR does / why we need it:**

Use sync.Pool to avoid allocations in morpc.

**Special notes for your reviewer:**

Not Available

**Additional documentation (e.g. design docs, usage docs, etc.):**

Not Available



Patch:
diff --git a/pkg/logservice/client.go b/pkg/logservice/client.go
index c405a030d..2cb92970e 100644
--- a/pkg/logservice/client.go
+++ b/pkg/logservice/client.go
@@ -16,6 +16,7 @@ package logservice
 
 import (
 	"context"
+	"sync"
 	"time"
 
 	"github.com/matrixorigin/matrixone/pkg/common/moerr"
@@ -64,18 +65,26 @@ type client struct {
 	cfg    LogServiceClientConfig
 	client morpc.RPCClient
 	addr   string
+	req    *RPCRequest
+	pool   *sync.Pool
 }
 
 var _ Client = (*client)(nil)
 
 func CreateClient(ctx context.Context,
 	name string, cfg LogServiceClientConfig) (Client, error) {
+	pool := &sync.Pool{}
+	pool.New = func() interface{} {
+		return &RPCResponse{pool: pool}
+	}
 	c := &client{
-		cfg: cfg,
+		cfg:  cfg,
+		req:  &RPCRequest{},
+		pool: pool,
 	}
 	var e error
 	for _, addr := range cfg.ServiceAddresses {
-		cc, err := getRPCClient(ctx, addr)
+		cc, err := getRPCClient(ctx, addr, c.pool)
 		if err != nil {
 			e = err
 			continue
@@ -161,17 +170,14 @@ func (c *client) request(ctx context.Context,
 		Index:   index,
 		MaxSize: maxSize,
 	}
-	rr := &RPCRequest{
-		Request: req,
-		payload: payload,
-	}
-	// FIXME: fix SendOption
-	// FIXME: how to avoid allocation here?
+	c.req.Request = req
+	c.req.payload = payload
 	future, err := c.client.Send(ctx,
-		c.addr, rr, morpc.SendOptions{Timeout: time.Duration(timeout)})
+		c.addr, c.req, morpc.SendOptions{Timeout: time.Duration(timeout)})
 	if err != nil {
 		return pb.Response{}, nil, err
 	}
+	defer future.Close()
 	msg, err := future.Get()
 	if err != nil {
 		return pb.Response{}, nil, err
@@ -180,6 +186,8 @@ func (c *client) request(ctx context.Context,
 	if !ok {
 		panic("unexpected response type")
 	}
+	resp := response.Response
+	defer response.Release()
 	var recs pb.LogRecordResponse
 	if len(response.payload) > 0 {
 		MustUnmarshal(&recs, response.payload)
@@ -188,7 +196,7 @@ func (c *client) request(ctx context.Context,
 	if err != nil {
 		return pb.Response{}, nil, err
 	}
-	return response.Response, recs.Records, nil
+	return resp, recs.Records, nil
 }
 
 func (c *client) connect(ctx context.Context, mt pb.MethodType) error {
@@ -226,12 +234,11 @@ func (c *client) getTruncatedIndex(ctx context.Context) (Lsn, error) {
 	return resp.Index, nil
 }
 
-func getRPCClient(ctx context.Context, target string) (morpc.RPCClient, error) {
+func getRPCClient(ctx context.Context, target string, pool *sync.Pool) (morpc.RPCClient, error) {
 	mf := func() morpc.Message {
-		return &RPCResponse{}
+		return pool.Get().(*RPCResponse)
 	}
 	codec := morpc.NewMessageCodec(mf, defaultWriteSocketSize)
-	// FIXME: set options
 	bf := morpc.NewGoettyBasedBackendFactory(codec,
 		morpc.WithBackendConnectWhenCreate(),
 		morpc.WithBackendConnectTimeout(connectionTimeout))
diff --git a/pkg/logservice/service.go b/pkg/logservice/service.go
index d683c10a7..286a74fce 100644
--- a/pkg/logservice/service.go
+++ b/pkg/logservice/service.go
@@ -16,8 +16,10 @@ package logservice
 
 import (
 	"context"
+	"sync"
 	"time"
 
+	"github.com/fagongzi/goetty/v2"
 	"github.com/lni/dragonboat/v4/logger"
 
 	"github.com/matrixorigin/matrixone/pkg/common/morpc"
@@ -48,10 +50,18 @@ func firstError(err1 error, err2 error) error {
 type RPCRequest struct {
 	pb.Request
 	payload []byte
+	pool    *sync.Pool
 }
 
 var _ morpc.PayloadMessage = (*RPCRequest)(nil)
 
+func (r *RPCRequest) Release() {
+	if r.pool != nil {
+		r.payload = nil
+		r.pool.Put(r)
+	}
+}
+
 func (r *RPCRequest) SetID(id uint64) {
 	r.RequestID = id
 }
@@ -76,10 +86,18 @@ func (r *RPCRequest) SetPayloadField(data []byte) {
 type RPCResponse struct {
 	pb.Response
 	payload []byte
+	pool    *sync.Pool
 }
 
 var _ morpc.PayloadMessage = (*RPCResponse)(nil)
 
+func (r *RPCResponse) Release() {
+	if r.pool != nil {
+		r.payload = nil
+		r.pool.Put(r)
+	}
+}
+
 func (r *RPCResponse) SetID(id uint64) {
 	r.RequestID = id
 }
@@ -106,9 +124,11 @@ func (r *RPCResponse) SetPayloadField(data []byte) {
 // clients owned by DN nodes and the HAKeeper service via network, it can
 // be considered as the interface layer of the LogService.
 type Service struct {
-	cfg    Config
-	store  *store
-	server morpc.RPCServer
+	cfg      Config
+	store    *store
+	server   morpc.RPCServer
+	pool     *sync.Pool
+	respPool *sync.Pool
 }
 
 func NewService(cfg Config) (*Service, error) {
@@ -122,21 +142,34 @@ func NewService(cfg Config) (*Service, error) {
 		plog.Errorf("failed to create log store %v", err)
 		return nil, err
 	}
+	pool := &sync.Pool{}
+	pool.New = func() interface{} {
+		return &RPCRequest{pool: pool}
+	}
+	respPool := &sync.Pool{}
+	respPool.New = func() interface{} {
+		return &RPCResponse{pool: respPool}
+	}
 
 	mf := func() morpc.Message {
-		return &RPCRequest{}
+		return pool.Get().(*RPCRequest)
 	}
 	codec := morpc.NewMessageCodec(mf, 16*1024)
-	server, err := morpc.NewRPCServer(LogServiceRPCName, cfg.ServiceListenAddress, codec)
+	server, err := morpc.NewRPCServer(LogServiceRPCName, cfg.ServiceListenAddress, codec,
+		morpc.WithServerGoettyOptions(goetty.WithReleaseMsgFunc(func(i interface{}) {
+			respPool.Put(i)
+		})))
 	if err != nil {
 		return nil, err
 	}
 
 	plog.Infof("store created")
 	service := &Service{
-		cfg:    cfg,
-		store:  store,
-		server: server,
+		cfg:      cfg,
+		store:    store,
+		server:   server,
+		pool:     pool,
+		respPool: respPool,
 	}
 	server.RegisterRequestHandler(service.handleRPCRequest)
 
@@ -169,17 +202,19 @@ func (s *Service) handleRPCRequest(req morpc.Message,
 	if !ok {
 		panic("unexpected message type")
 	}
+	defer rr.Release()
 	resp, records := s.handle(rr.Request, rr.GetPayloadField())
 	var recs []byte
 	if len(records.Records) > 0 {
+		plog.Infof("total recs: %d", len(records.Records))
 		recs = MustMarshal(&records)
 	}
-	// FIXME: set timeout value
 	resp.RequestID = rr.RequestID
-	return cs.Write(&RPCResponse{
-		Response: resp,
-		payload:  recs,
-	}, morpc.SendOptions{})
+	response := s.respPool.Get().(*RPCResponse)
+	response.Response = resp
+	response.payload = recs
+	return cs.Write(response,
+		morpc.SendOptions{Timeout: time.Duration(rr.Request.Timeout)})
 }
 
 func (s *Service) handle(req pb.Request,
diff --git a/pkg/sql/parsers/dialect/mysql/mysql_sql.go b/pkg/sql/parsers/dialect/mysql/mysql_sql.go
index 202c86f72..17f65d614 100644
--- a/pkg/sql/parsers/dialect/mysql/mysql_sql.go
+++ b/pkg/sql/parsers/dialect/mysql/mysql_sql.go
@@ -914,7 +914,7 @@ const yyEofCode = 1
 const yyErrCode = 2
 const yyInitialStackSize = 16
 
-//line mysql_sql.y:6507
+//line mysql_sql.y:6511
 
 //line yacctab:1
 var yyExca = [...]int{
@@ -3529,7 +3529,7 @@ var yyPgo = [...]int{
 	1734, 1733, 1732, 1731, 1730, 128, 1729,
 }
 
-//line mysql_sql.y:6507
+//line mysql_sql.y:6511
 type yySymType struct {
 	union interface{}
 	id    int
@@ -11191,11 +11191,15 @@ yydefault:
 		var yyLOCAL *tree.T
 //line mysql_sql.y:4542
 		{
+			name := yyDollar[1].str
+			if yyDollar[2].str != "" {
+				name = yyDollar[2].str
+			}
 			locale := ""
 			yyLOCAL = &tree.T{
 				InternalType: tree.InternalType{
 					Family:       tree.IntFamily,
-					FamilyString: yyDollar[1].str,
+					FamilyString: name,
 					Width:        64,
 					Locale:       &locale,
 					Oid:          uint32(defines.MYSQL_TYPE_LONGLONG),
@@ -11206,13 +11210,13 @@ yydefault:
 	case 776:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:4555
+//line mysql_sql.y:4559
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
 				InternalType: tree.InternalType{
 					Family:       tree.IntFamily,
-					FamilyString: yyDollar[1].str,
+					FamilyString: yyDollar[2].str,
 					Width:        64,
 					Locale:       &locale,
 					Unsigned:     true,
@@ -11223,13 +11227,13 @@ yydefault:
 		yyVAL.union = yyLOCAL
 	case 777:
 		yyDollar = yyS[yypt-0 : yypt+1]
-//line mysql_sql.y:4570
+//line mysql_sql.y:4574
 		{
 		}
 	case 780:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4576
+//line mysql_sql.y:4580
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11242,7 +11246,7 @@ yydefault:
 	case 781:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4585
+//line mysql_sql.y:4589
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11254,7 +11258,7 @@ yydefault:
 	case 782:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4593
+//line mysql_sql.y:4597
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11266,7 +11270,7 @@ yydefault:
 	case 783:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4601
+//line mysql_sql.y:4605
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11279,7 +11283,7 @@ yydefault:
 	case 784:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4610
+//line mysql_sql.y:4614
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11292,7 +11296,7 @@ yydefault:
 	case 785:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4619
+//line mysql_sql.y:4623
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11305,7 +11309,7 @@ yydefault:
 	case 786:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4628
+//line mysql_sql.y:4632
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11318,7 +11322,7 @@ yydefault:
 	case 787:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4637
+//line mysql_sql.y:4641
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			es := tree.NewNumValWithType(constant.MakeString("*"), "*", false, tree.P_char)
@@ -11331,7 +11335,7 @@ yydefault:
 	case 788:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4646
+//line mysql_sql.y:4650
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11344,7 +11348,7 @@ yydefault:
 	case 789:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4655
+//line mysql_sql.y:4659
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11357,7 +11361,7 @@ yydefault:
 	case 790:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4664
+//line mysql_sql.y:4668
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11370,7 +11374,7 @@ yydefault:
 	case 791:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4673
+//line mysql_sql.y:4677
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11383,7 +11387,7 @@ yydefault:
 	case 792:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4682
+//line mysql_sql.y:4686
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11396,7 +11400,7 @@ yydefault:
 	case 793:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4691
+//line mysql_sql.y:4695
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11409,7 +11413,7 @@ yydefault:
 	case 794:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4700
+//line mysql_sql.y:4704
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11422,7 +11426,7 @@ yydefault:
 	case 798:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4716
+//line mysql_sql.y:4720
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11434,7 +11438,7 @@ yydefault:
 	case 799:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4724
+//line mysql_sql.y:4728
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11446,7 +11450,7 @@ yydefault:
 	case 800:
 		yyDollar = yyS[yypt-6 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4732
+//line mysql_sql.y:4736
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11458,7 +11462,7 @@ yydefault:
 	case 801:
 		yyDollar = yyS[yypt-8 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4740
+//line mysql_sql.y:4744
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11470,7 +11474,7 @@ yydefault:
 	case 802:
 		yyDollar = yyS[yypt-6 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4748
+//line mysql_sql.y:4752
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			timeUinit := tree.NewNumValWithType(constant.MakeString(yyDollar[3].str), yyDollar[3].str, false, tree.P_char)
@@ -11483,7 +11487,7 @@ yydefault:
 	case 803:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4757
+//line mysql_sql.y:4761
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11495,7 +11499,7 @@ yydefault:
 	case 804:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4765
+//line mysql_sql.y:4769
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11508,7 +11512,7 @@ yydefault:
 	case 805:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4774
+//line mysql_sql.y:4778
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11521,7 +11525,7 @@ yydefault:
 	case 806:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4783
+//line mysql_sql.y:4787
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11533,7 +11537,7 @@ yydefault:
 	case 807:
 		yyDollar = yyS[yypt-6 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4791
+//line mysql_sql.y:4795
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11545,7 +11549,7 @@ yydefault:
 	case 808:
 		yyDollar = yyS[yypt-6 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4799
+//line mysql_sql.y:4803
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			arg1 := tree.NewNumValWithType(constant.MakeString(yyDollar[3].str), yyDollar[3].str, false, tree.P_char)
@@ -11558,7 +11562,7 @@ yydefault:
 	case 809:
 		yyDollar = yyS[yypt-7 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4808
+//line mysql_sql.y:4812
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			arg1 := tree.NewNumValWithType(constant.MakeString(yyDollar[3].str), yyDollar[3].str, false, tree.P_char)
@@ -11570,14 +11574,14 @@ yydefault:
 		yyVAL.union = yyLOCAL
 	case 815:
 		yyDollar = yyS[yypt-1 : yypt+1]
-//line mysql_sql.y:4828
+//line mysql_sql.y:4832
 		{
 			yyVAL.str = yyDollar[1].str
 		}
 	case 844:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4864
+//line mysql_sql.y:4868
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			var es tree.Exprs = nil
@@ -11593,7 +11597,7 @@ yydefault:
 	case 845:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4876
+//line mysql_sql.y:4880
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			var es tree.Exprs = nil
@@ -11609,7 +11613,7 @@ yydefault:
 	case 846:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4890
+//line mysql_sql.y:4894
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11621,7 +11625,7 @@ yydefault:
 	case 847:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4898
+//line mysql_sql.y:4902
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11632,7 +11636,7 @@ yydefault:
 	case 848:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4905
+//line mysql_sql.y:4909
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			yyLOCAL = &tree.FuncExpr{
@@ -11643,7 +11647,7 @@ yydefault:
 	case 849:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4912
+//line mysql_sql.y:4916
 		{
 			name := tree.SetUnresolvedName(strings.ToLower(yyDollar[1].str))
 			var es tree.Exprs = nil
@@ -11659,7 +11663,7 @@ yydefault:
 	case 850:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4924
+//line mysql_sql.y:4928
 		{
 			name := tree.SetUnresolvedName("char")
 			yyLOCAL = &tree.FuncExpr{
@@ -11671,7 +11675,7 @@ yydefault:
 	case 851:
 		yyDollar = yyS[yypt-6 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4932
+//line mysql_sql.y:4936
 		{
 			cn := tree.NewNumValWithType(constant.MakeString(yyDollar[5].str), yyDollar[5].str, false, tree.P_char)
 			es := yyDollar[3].exprsUnion()
@@ -11686,7 +11690,7 @@ yydefault:
 	case 852:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4943
+//line mysql_sql.y:4947
 		{
 			val := tree.NewNumValWithType(constant.MakeString(yyDollar[2].str), yyDollar[2].str, false, tree.P_char)
 			name := tree.SetUnresolvedName("date")
@@ -11699,7 +11703,7 @@ yydefault:
 	case 853:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4952
+//line mysql_sql.y:4956
 		{
 			val := tree.NewNumValWithType(constant.MakeString(yyDollar[2].str), yyDollar[2].str, false, tree.P_char)
 			name := tree.SetUnresolvedName("time")
@@ -11712,7 +11716,7 @@ yydefault:
 	case 854:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4961
+//line mysql_sql.y:4965
 		{
 			name := tree.SetUnresolvedName("insert")
 			yyLOCAL = &tree.FuncExpr{
@@ -11724,7 +11728,7 @@ yydefault:
 	case 855:
 		yyDollar = yyS[yypt-6 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4969
+//line mysql_sql.y:4973
 		{
 			es := tree.Exprs{yyDollar[3].exprUnion()}
 			es = append(es, yyDollar[5].exprUnion())
@@ -11738,7 +11742,7 @@ yydefault:
 	case 856:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4979
+//line mysql_sql.y:4983
 		{
 			name := tree.SetUnresolvedName("password")
 			yyLOCAL = &tree.FuncExpr{
@@ -11750,7 +11754,7 @@ yydefault:
 	case 857:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4987
+//line mysql_sql.y:4991
 		{
 			name := tree.SetUnresolvedName("binary")
 			yyLOCAL = &tree.FuncExpr{
@@ -11762,7 +11766,7 @@ yydefault:
 	case 858:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.FuncExpr
-//line mysql_sql.y:4995
+//line mysql_sql.y:4999
 		{
 			val := tree.NewNumValWithType(constant.MakeString(yyDollar[2].str), yyDollar[2].str, false, tree.P_char)
 			name := tree.SetUnresolvedName("timestamp")
@@ -11775,7 +11779,7 @@ yydefault:
 	case 859:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5005
+//line mysql_sql.y:5009
 		{
 			yyLOCAL = nil
 		}
@@ -11783,7 +11787,7 @@ yydefault:
 	case 860:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5009
+//line mysql_sql.y:5013
 		{
 			yyLOCAL = yyDollar[1].exprUnion()
 		}
@@ -11791,7 +11795,7 @@ yydefault:
 	case 861:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5015
+//line mysql_sql.y:5019
 		{
 			yyLOCAL = nil
 		}
@@ -11799,7 +11803,7 @@ yydefault:
 	case 862:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5019
+//line mysql_sql.y:5023
 		{
 			ival, errStr := util.GetInt64(yyDollar[2].item)
 			if errStr != "" {
@@ -11812,18 +11816,18 @@ yydefault:
 		yyVAL.union = yyLOCAL
 	case 869:
 		yyDollar = yyS[yypt-0 : yypt+1]
-//line mysql_sql.y:5038
+//line mysql_sql.y:5042
 		{
 		}
 	case 870:
 		yyDollar = yyS[yypt-2 : yypt+1]
-//line mysql_sql.y:5040
+//line mysql_sql.y:5044
 		{
 		}
 	case 903:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5080
+//line mysql_sql.y:5084
 		{
 			name := tree.SetUnresolvedName("interval")
 			arg2 := tree.NewNumValWithType(constant.MakeString(yyDollar[3].str), yyDollar[3].str, false, tree.P_char)
@@ -11836,7 +11840,7 @@ yydefault:
 	case 904:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL tree.FuncType
-//line mysql_sql.y:5090
+//line mysql_sql.y:5094
 		{
 			yyLOCAL = tree.FUNC_TYPE_DEFAULT
 		}
@@ -11844,7 +11848,7 @@ yydefault:
 	case 905:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.FuncType
-//line mysql_sql.y:5094
+//line mysql_sql.y:5098
 		{
 			yyLOCAL = tree.FUNC_TYPE_DISTINCT
 		}
@@ -11852,7 +11856,7 @@ yydefault:
 	case 906:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.FuncType
-//line mysql_sql.y:5098
+//line mysql_sql.y:5102
 		{
 			yyLOCAL = tree.FUNC_TYPE_ALL
 		}
@@ -11860,7 +11864,7 @@ yydefault:
 	case 907:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL *tree.Tuple
-//line mysql_sql.y:5104
+//line mysql_sql.y:5108
 		{
 			yyLOCAL = tree.NewTuple(yyDollar[2].exprsUnion())
 		}
@@ -11868,7 +11872,7 @@ yydefault:
 	case 908:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL tree.Exprs
-//line mysql_sql.y:5109
+//line mysql_sql.y:5113
 		{
 			yyLOCAL = nil
 		}
@@ -11876,7 +11880,7 @@ yydefault:
 	case 909:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Exprs
-//line mysql_sql.y:5113
+//line mysql_sql.y:5117
 		{
 			yyLOCAL = yyDollar[1].exprsUnion()
 		}
@@ -11884,7 +11888,7 @@ yydefault:
 	case 910:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Exprs
-//line mysql_sql.y:5119
+//line mysql_sql.y:5123
 		{
 			yyLOCAL = tree.Exprs{yyDollar[1].exprUnion()}
 		}
@@ -11892,7 +11896,7 @@ yydefault:
 	case 911:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Exprs
-//line mysql_sql.y:5123
+//line mysql_sql.y:5127
 		{
 			yyLOCAL = append(yyDollar[1].exprsUnion(), yyDollar[3].exprUnion())
 		}
@@ -11900,7 +11904,7 @@ yydefault:
 	case 912:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5130
+//line mysql_sql.y:5134
 		{
 			yyLOCAL = tree.NewAndExpr(yyDollar[1].exprUnion(), yyDollar[3].exprUnion())
 		}
@@ -11908,7 +11912,7 @@ yydefault:
 	case 913:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5134
+//line mysql_sql.y:5138
 		{
 			yyLOCAL = tree.NewOrExpr(yyDollar[1].exprUnion(), yyDollar[3].exprUnion())
 		}
@@ -11916,7 +11920,7 @@ yydefault:
 	case 914:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5138
+//line mysql_sql.y:5142
 		{
 			yyLOCAL = tree.NewXorExpr(yyDollar[1].exprUnion(), yyDollar[3].exprUnion())
 		}
@@ -11924,7 +11928,7 @@ yydefault:
 	case 915:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5142
+//line mysql_sql.y:5146
 		{
 			yyLOCAL = tree.NewNotExpr(yyDollar[2].exprUnion())
 		}
@@ -11932,7 +11936,7 @@ yydefault:
 	case 916:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5146
+//line mysql_sql.y:5150
 		{
 			yyLOCAL = tree.NewComparisonExpr(tree.EQUAL, yyDollar[1].exprUnion(), yyDollar[3].exprUnion())
 		}
@@ -11940,7 +11944,7 @@ yydefault:
 	case 917:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5150
+//line mysql_sql.y:5154
 		{
 			yyLOCAL = tree.NewComparisonExpr(tree.NOT_EQUAL, yyDollar[1].exprUnion(), yyDollar[4].exprUnion())
 		}
@@ -11948,7 +11952,7 @@ yydefault:
 	case 918:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5154
+//line mysql_sql.y:5158
 		{
 			arg := tree.NewNumValWithType(constant.MakeString(yyDollar[3].str), "", false, tree.P_char)
 			yyLOCAL = tree.NewComparisonExpr(tree.EQUAL, yyDollar[1].exprUnion(), arg)
@@ -11957,7 +11961,7 @@ yydefault:
 	case 919:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5159
+//line mysql_sql.y:5163
 		{
 			arg := tree.NewNumValWithType(constant.MakeString(yyDollar[3].str), "", false, tree.P_char)
 			yyLOCAL = tree.NewComparisonExpr(tree.NOT_EQUAL, yyDollar[1].exprUnion(), arg)
@@ -11966,7 +11970,7 @@ yydefault:
 	case 920:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5164
+//line mysql_sql.y:5168
 		{
 			yyLOCAL = yyDollar[1].exprUnion()
 		}
@@ -11974,7 +11978,7 @@ yydefault:
 	case 921:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5170
+//line mysql_sql.y:5174
 		{
 			yyLOCAL = tree.NewIsNullExpr(yyDollar[1].exprUnion())
 		}
@@ -11982,7 +11986,7 @@ yydefault:
 	case 922:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5174
+//line mysql_sql.y:5178
 		{
 			yyLOCAL = tree.NewIsNotNullExpr(yyDollar[1].exprUnion())
 		}
@@ -11990,7 +11994,7 @@ yydefault:
 	case 923:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5178
+//line mysql_sql.y:5182
 		{
 			yyLOCAL = tree.NewComparisonExpr(yyDollar[2].comparisonOpUnion(), yyDollar[1].exprUnion(), yyDollar[3].exprUnion())
 		}
@@ -11998,7 +12002,7 @@ yydefault:
 	case 924:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5182
+//line mysql_sql.y:5186
 		{
 			yyLOCAL = tree.NewSubqueryComparisonExpr(yyDollar[2].comparisonOpUnion(), yyDollar[3].comparisonOpUnion(), yyDollar[1].exprUnion(), yyDollar[4].subqueryUnion())
 		}
@@ -12006,7 +12010,7 @@ yydefault:
 	case 926:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5189
+//line mysql_sql.y:5193
 		{
 			yyLOCAL = tree.NewNumValWithType(constant.MakeBool(true), "", false, tree.P_bool)
 		}
@@ -12014,7 +12018,7 @@ yydefault:
 	case 927:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5193
+//line mysql_sql.y:5197
 		{
 			yyLOCAL = tree.NewNumValWithType(constant.MakeBool(false), "", false, tree.P_bool)
 		}
@@ -12022,7 +12026,7 @@ yydefault:
 	case 928:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5199
+//line mysql_sql.y:5203
 		{
 			yyLOCAL = tree.NewComparisonExpr(tree.IN, yyDollar[1].exprUnion(), yyDollar[3].exprUnion())
 		}
@@ -12030,7 +12034,7 @@ yydefault:
 	case 929:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5203
+//line mysql_sql.y:5207
 		{
 			yyLOCAL = tree.NewComparisonExpr(tree.NOT_IN, yyDollar[1].exprUnion(), yyDollar[4].exprUnion())
 		}
@@ -12038,7 +12042,7 @@ yydefault:
 	case 930:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5207
+//line mysql_sql.y:5211
 		{
 			yyLOCAL = tree.NewComparisonExprWithEscape(tree.LIKE, yyDollar[1].exprUnion(), yyDollar[3].exprUnion(), yyDollar[4].exprUnion())
 		}
@@ -12046,7 +12050,7 @@ yydefault:
 	case 931:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5211
+//line mysql_sql.y:5215
 		{
 			yyLOCAL = tree.NewComparisonExprWithEscape(tree.NOT_LIKE, yyDollar[1].exprUnion(), yyDollar[4].exprUnion(), yyDollar[5].exprUnion())
 		}
@@ -12054,7 +12058,7 @@ yydefault:
 	case 932:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5215
+//line mysql_sql.y:5219
 		{
 			yyLOCAL = tree.NewComparisonExpr(tree.REG_MATCH, yyDollar[1].exprUnion(), yyDollar[3].exprUnion())
 		}
@@ -12062,7 +12066,7 @@ yydefault:
 	case 933:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5219
+//line mysql_sql.y:5223
 		{
 			yyLOCAL = tree.NewComparisonExpr(tree.NOT_REG_MATCH, yyDollar[1].exprUnion(), yyDollar[4].exprUnion())
 		}
@@ -12070,7 +12074,7 @@ yydefault:
 	case 934:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5223
+//line mysql_sql.y:5227
 		{
 			yyLOCAL = tree.NewRangeCond(false, yyDollar[1].exprUnion(), yyDollar[3].exprUnion(), yyDollar[5].exprUnion())
 		}
@@ -12078,7 +12082,7 @@ yydefault:
 	case 935:
 		yyDollar = yyS[yypt-6 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5227
+//line mysql_sql.y:5231
 		{
 			yyLOCAL = tree.NewRangeCond(true, yyDollar[1].exprUnion(), yyDollar[4].exprUnion(), yyDollar[6].exprUnion())
 		}
@@ -12086,7 +12090,7 @@ yydefault:
 	case 937:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5233
+//line mysql_sql.y:5237
 		{
 			yyLOCAL = nil
 		}
@@ -12094,7 +12098,7 @@ yydefault:
 	case 938:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5237
+//line mysql_sql.y:5241
 		{
 			yyLOCAL = yyDollar[2].exprUnion()
 		}
@@ -12102,7 +12106,7 @@ yydefault:
 	case 939:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5243
+//line mysql_sql.y:5247
 		{
 			yyLOCAL = yyDollar[1].tupleUnion()
 		}
@@ -12110,7 +12114,7 @@ yydefault:
 	case 940:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5247
+//line mysql_sql.y:5251
 		{
 			yyLOCAL = yyDollar[1].subqueryUnion()
 		}
@@ -12118,7 +12122,7 @@ yydefault:
 	case 941:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5254
+//line mysql_sql.y:5258
 		{
 			yyLOCAL = tree.ALL
 		}
@@ -12126,7 +12130,7 @@ yydefault:
 	case 942:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5258
+//line mysql_sql.y:5262
 		{
 			yyLOCAL = tree.ANY
 		}
@@ -12134,7 +12138,7 @@ yydefault:
 	case 943:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5262
+//line mysql_sql.y:5266
 		{
 			yyLOCAL = tree.SOME
 		}
@@ -12142,7 +12146,7 @@ yydefault:
 	case 944:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5268
+//line mysql_sql.y:5272
 		{
 			yyLOCAL = tree.EQUAL
 		}
@@ -12150,7 +12154,7 @@ yydefault:
 	case 945:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5272
+//line mysql_sql.y:5276
 		{
 			yyLOCAL = tree.LESS_THAN
 		}
@@ -12158,7 +12162,7 @@ yydefault:
 	case 946:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5276
+//line mysql_sql.y:5280
 		{
 			yyLOCAL = tree.GREAT_THAN
 		}
@@ -12166,7 +12170,7 @@ yydefault:
 	case 947:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5280
+//line mysql_sql.y:5284
 		{
 			yyLOCAL = tree.LESS_THAN_EQUAL
 		}
@@ -12174,7 +12178,7 @@ yydefault:
 	case 948:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5284
+//line mysql_sql.y:5288
 		{
 			yyLOCAL = tree.GREAT_THAN_EQUAL
 		}
@@ -12182,7 +12186,7 @@ yydefault:
 	case 949:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5288
+//line mysql_sql.y:5292
 		{
 			yyLOCAL = tree.NOT_EQUAL
 		}
@@ -12190,7 +12194,7 @@ yydefault:
 	case 950:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ComparisonOp
-//line mysql_sql.y:5292
+//line mysql_sql.y:5296
 		{
 			yyLOCAL = tree.NULL_SAFE_EQUAL
 		}
@@ -12198,7 +12202,7 @@ yydefault:
 	case 951:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL tree.ColumnAttribute
-//line mysql_sql.y:5298
+//line mysql_sql.y:5302
 		{
 			yyLOCAL = tree.NewAttributePrimaryKey()
 		}
@@ -12206,7 +12210,7 @@ yydefault:
 	case 952:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL tree.ColumnAttribute
-//line mysql_sql.y:5302
+//line mysql_sql.y:5306
 		{
 			yyLOCAL = tree.NewAttributeUniqueKey()
 		}
@@ -12214,7 +12218,7 @@ yydefault:
 	case 953:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ColumnAttribute
-//line mysql_sql.y:5306
+//line mysql_sql.y:5310
 		{
 			yyLOCAL = tree.NewAttributeUnique()
 		}
@@ -12222,7 +12226,7 @@ yydefault:
 	case 954:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.ColumnAttribute
-//line mysql_sql.y:5310
+//line mysql_sql.y:5314
 		{
 			yyLOCAL = tree.NewAttributeKey()
 		}
@@ -12230,7 +12234,7 @@ yydefault:
 	case 955:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5316
+//line mysql_sql.y:5320
 		{
 			yyLOCAL = tree.NewNumValWithType(constant.MakeString(yyDollar[1].str), yyDollar[1].str, false, tree.P_char)
 		}
@@ -12238,7 +12242,7 @@ yydefault:
 	case 956:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5320
+//line mysql_sql.y:5324
 		{
 			str := fmt.Sprintf("%v", yyDollar[1].item)
 			switch v := yyDollar[1].item.(type) {
@@ -12255,7 +12259,7 @@ yydefault:
 	case 957:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5333
+//line mysql_sql.y:5337
 		{
 			fval := yyDollar[1].item.(float64)
 			yyLOCAL = tree.NewNumValWithType(constant.MakeFloat64(fval), yylex.(*Lexer).scanner.LastToken, false, tree.P_float64)
@@ -12264,7 +12268,7 @@ yydefault:
 	case 958:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5338
+//line mysql_sql.y:5342
 		{
 			yyLOCAL = tree.NewNumValWithType(constant.MakeBool(true), "true", false, tree.P_bool)
 		}
@@ -12272,7 +12276,7 @@ yydefault:
 	case 959:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5342
+//line mysql_sql.y:5346
 		{
 			yyLOCAL = tree.NewNumValWithType(constant.MakeBool(false), "false", false, tree.P_bool)
 		}
@@ -12280,7 +12284,7 @@ yydefault:
 	case 960:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5346
+//line mysql_sql.y:5350
 		{
 			yyLOCAL = tree.NewNumValWithType(constant.MakeUnknown(), "null", false, tree.P_null)
 		}
@@ -12288,7 +12292,7 @@ yydefault:
 	case 961:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5350
+//line mysql_sql.y:5354
 		{
 			switch v := yyDollar[1].item.(type) {
 			case uint64:
@@ -12306,7 +12310,7 @@ yydefault:
 	case 962:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5364
+//line mysql_sql.y:5368
 		{
 			yyLOCAL = tree.NewNumValWithType(constant.MakeString(yyDollar[1].str), yyDollar[1].str, false, tree.P_decimal)
 		}
@@ -12314,7 +12318,7 @@ yydefault:
 	case 963:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL tree.Expr
-//line mysql_sql.y:5368
+//line mysql_sql.y:5372
 		{
 			switch v := yyDollar[1].item.(type) {
 			case uint64:
@@ -12332,7 +12336,7 @@ yydefault:
 	case 964:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5384
+//line mysql_sql.y:5388
 		{
 			yyLOCAL = yyDollar[1].columnTypeUnion()
 			yyLOCAL.InternalType.Unsigned = yyDollar[2].unsignedOptUnion()
@@ -12342,7 +12346,7 @@ yydefault:
 	case 968:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5395
+//line mysql_sql.y:5399
 		{
 			yyLOCAL = yyDollar[1].columnTypeUnion()
 			yyLOCAL.InternalType.DisplayWith = yyDollar[2].lengthOptUnion()
@@ -12351,7 +12355,7 @@ yydefault:
 	case 969:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5400
+//line mysql_sql.y:5404
 		{
 			yyLOCAL = yyDollar[1].columnTypeUnion()
 		}
@@ -12359,7 +12363,7 @@ yydefault:
 	case 970:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5406
+//line mysql_sql.y:5410
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12375,7 +12379,7 @@ yydefault:
 	case 971:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5418
+//line mysql_sql.y:5422
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12391,7 +12395,7 @@ yydefault:
 	case 972:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5430
+//line mysql_sql.y:5434
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12407,7 +12411,7 @@ yydefault:
 	case 973:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5442
+//line mysql_sql.y:5446
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12424,7 +12428,7 @@ yydefault:
 	case 974:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5455
+//line mysql_sql.y:5459
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12441,7 +12445,7 @@ yydefault:
 	case 975:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5468
+//line mysql_sql.y:5472
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12458,7 +12462,7 @@ yydefault:
 	case 976:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5481
+//line mysql_sql.y:5485
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12475,7 +12479,7 @@ yydefault:
 	case 977:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5494
+//line mysql_sql.y:5498
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12492,7 +12496,7 @@ yydefault:
 	case 978:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5507
+//line mysql_sql.y:5511
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12509,7 +12513,7 @@ yydefault:
 	case 979:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5520
+//line mysql_sql.y:5524
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12526,7 +12530,7 @@ yydefault:
 	case 980:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5533
+//line mysql_sql.y:5537
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12543,7 +12547,7 @@ yydefault:
 	case 981:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5546
+//line mysql_sql.y:5550
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12560,7 +12564,7 @@ yydefault:
 	case 982:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5559
+//line mysql_sql.y:5563
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12577,7 +12581,7 @@ yydefault:
 	case 983:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5572
+//line mysql_sql.y:5576
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12594,7 +12598,7 @@ yydefault:
 	case 984:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5587
+//line mysql_sql.y:5591
 		{
 			locale := ""
 			if yyDollar[2].lengthScaleOptUnion().DisplayWith > 255 {
@@ -12621,7 +12625,7 @@ yydefault:
 	case 985:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5610
+//line mysql_sql.y:5614
 		{
 			locale := ""
 			if yyDollar[2].lengthScaleOptUnion().Precision != tree.NotDefineDec && yyDollar[2].lengthScaleOptUnion().Precision > yyDollar[2].lengthScaleOptUnion().DisplayWith {
@@ -12661,7 +12665,7 @@ yydefault:
 	case 986:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5647
+//line mysql_sql.y:5651
 		{
 			locale := ""
 			if yyDollar[2].lengthScaleOptUnion().Precision != tree.NotDefineDec && yyDollar[2].lengthScaleOptUnion().Precision > yyDollar[2].lengthScaleOptUnion().DisplayWith {
@@ -12701,7 +12705,7 @@ yydefault:
 	case 987:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5695
+//line mysql_sql.y:5699
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12720,7 +12724,7 @@ yydefault:
 	case 988:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5712
+//line mysql_sql.y:5716
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12736,7 +12740,7 @@ yydefault:
 	case 989:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5724
+//line mysql_sql.y:5728
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12755,7 +12759,7 @@ yydefault:
 	case 990:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5739
+//line mysql_sql.y:5743
 		{
 			locale := ""
 			if yyDollar[2].lengthOptUnion() < 0 || yyDollar[2].lengthOptUnion() > 6 {
@@ -12779,7 +12783,7 @@ yydefault:
 	case 991:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5759
+//line mysql_sql.y:5763
 		{
 			locale := ""
 			if yyDollar[2].lengthOptUnion() < 0 || yyDollar[2].lengthOptUnion() > 6 {
@@ -12803,7 +12807,7 @@ yydefault:
 	case 992:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5779
+//line mysql_sql.y:5783
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12821,7 +12825,7 @@ yydefault:
 	case 993:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5795
+//line mysql_sql.y:5799
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12838,7 +12842,7 @@ yydefault:
 	case 994:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5808
+//line mysql_sql.y:5812
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12855,7 +12859,7 @@ yydefault:
 	case 995:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5821
+//line mysql_sql.y:5825
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12872,7 +12876,7 @@ yydefault:
 	case 996:
 		yyDollar = yyS[yypt-2 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5834
+//line mysql_sql.y:5838
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12889,7 +12893,7 @@ yydefault:
 	case 997:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5847
+//line mysql_sql.y:5851
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12905,7 +12909,7 @@ yydefault:
 	case 998:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5859
+//line mysql_sql.y:5863
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12921,7 +12925,7 @@ yydefault:
 	case 999:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5871
+//line mysql_sql.y:5875
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12937,7 +12941,7 @@ yydefault:
 	case 1000:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5883
+//line mysql_sql.y:5887
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12953,7 +12957,7 @@ yydefault:
 	case 1001:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5895
+//line mysql_sql.y:5899
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12969,7 +12973,7 @@ yydefault:
 	case 1002:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5907
+//line mysql_sql.y:5911
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -12985,7 +12989,7 @@ yydefault:
 	case 1003:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5919
+//line mysql_sql.y:5923
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -13001,7 +13005,7 @@ yydefault:
 	case 1004:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5931
+//line mysql_sql.y:5935
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -13017,7 +13021,7 @@ yydefault:
 	case 1005:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5943
+//line mysql_sql.y:5947
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -13033,7 +13037,7 @@ yydefault:
 	case 1006:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5955
+//line mysql_sql.y:5959
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -13050,7 +13054,7 @@ yydefault:
 	case 1007:
 		yyDollar = yyS[yypt-4 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5968
+//line mysql_sql.y:5972
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -13067,7 +13071,7 @@ yydefault:
 	case 1008:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL *tree.T
-//line mysql_sql.y:5983
+//line mysql_sql.y:5987
 		{
 			locale := ""
 			yyLOCAL = &tree.T{
@@ -13083,7 +13087,7 @@ yydefault:
 	case 1009:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL []string
-//line mysql_sql.y:6006
+//line mysql_sql.y:6010
 		{
 			yyLOCAL = make([]string, 0, 4)
 			yyLOCAL = append(yyLOCAL, yyDollar[1].str)
@@ -13092,7 +13096,7 @@ yydefault:
 	case 1010:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL []string
-//line mysql_sql.y:6011
+//line mysql_sql.y:6015
 		{
 			yyLOCAL = append(yyDollar[1].strsUnion(), yyDollar[3].str)
 		}
@@ -13100,7 +13104,7 @@ yydefault:
 	case 1011:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL int32
-//line mysql_sql.y:6017
+//line mysql_sql.y:6021
 		{
 			yyLOCAL = 0
 		}
@@ -13108,7 +13112,7 @@ yydefault:
 	case 1013:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL int32
-//line mysql_sql.y:6024
+//line mysql_sql.y:6028
 		{
 			yyLOCAL = 6
 		}
@@ -13116,7 +13120,7 @@ yydefault:
 	case 1014:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL int32
-//line mysql_sql.y:6028
+//line mysql_sql.y:6032
 		{
 			yyLOCAL = int32(yyDollar[2].item.(int64))
 		}
@@ -13124,7 +13128,7 @@ yydefault:
 	case 1015:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL int32
-//line mysql_sql.y:6033
+//line mysql_sql.y:6037
 		{
 			yyLOCAL = int32(-1)
 		}
@@ -13132,7 +13136,7 @@ yydefault:
 	case 1016:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL int32
-//line mysql_sql.y:6037
+//line mysql_sql.y:6041
 		{
 			yyLOCAL = int32(yyDollar[2].item.(int64))
 		}
@@ -13140,7 +13144,7 @@ yydefault:
 	case 1017:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL int32
-//line mysql_sql.y:6043
+//line mysql_sql.y:6047
 		{
 			yyLOCAL = tree.GetDisplayWith(int32(yyDollar[2].item.(int64)))
 		}
@@ -13148,7 +13152,7 @@ yydefault:
 	case 1018:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL tree.LengthScaleOpt
-//line mysql_sql.y:6049
+//line mysql_sql.y:6053
 		{
 			yyLOCAL = tree.LengthScaleOpt{
 				DisplayWith: tree.NotDefineDisplayWidth,
@@ -13159,7 +13163,7 @@ yydefault:
 	case 1019:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.LengthScaleOpt
-//line mysql_sql.y:6056
+//line mysql_sql.y:6060
 		{
 			yyLOCAL = tree.LengthScaleOpt{
 				DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))),
@@ -13170,7 +13174,7 @@ yydefault:
 	case 1020:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL tree.LengthScaleOpt
-//line mysql_sql.y:6063
+//line mysql_sql.y:6067
 		{
 			yyLOCAL = tree.LengthScaleOpt{
 				DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))),
@@ -13181,7 +13185,7 @@ yydefault:
 	case 1021:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL tree.LengthScaleOpt
-//line mysql_sql.y:6072
+//line mysql_sql.y:6076
 		{
 			yyLOCAL = tree.LengthScaleOpt{
 				DisplayWith: 10, // this is the default precision for decimal
@@ -13192,7 +13196,7 @@ yydefault:
 	case 1022:
 		yyDollar = yyS[yypt-3 : yypt+1]
 		var yyLOCAL tree.LengthScaleOpt
-//line mysql_sql.y:6079
+//line mysql_sql.y:6083
 		{
 			yyLOCAL = tree.LengthScaleOpt{
 				DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))),
@@ -13203,7 +13207,7 @@ yydefault:
 	case 1023:
 		yyDollar = yyS[yypt-5 : yypt+1]
 		var yyLOCAL tree.LengthScaleOpt
-//line mysql_sql.y:6086
+//line mysql_sql.y:6090
 		{
 			yyLOCAL = tree.LengthScaleOpt{
 				DisplayWith: tree.GetDisplayWith(int32(yyDollar[2].item.(int64))),
@@ -13214,7 +13218,7 @@ yydefault:
 	case 1024:
 		yyDollar = yyS[yypt-0 : yypt+1]
 		var yyLOCAL bool
-//line mysql_sql.y:6095
+//line mysql_sql.y:6099
 		{
 			yyLOCAL = false
 		}
@@ -13222,7 +13226,7 @@ yydefault:
 	case 1025:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL bool
-//line mysql_sql.y:6099
+//line mysql_sql.y:6103
 		{
 			yyLOCAL = true
 		}
@@ -13230,33 +13234,33 @@ yydefault:
 	case 1026:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL bool
-//line mysql_sql.y:6103
+//line mysql_sql.y:6107
 		{
 			yyLOCAL = false
 		}
 		yyVAL.union = yyLOCAL
 	case 1027:
 		yyDollar = yyS[yypt-0 : yypt+1]
-//line mysql_sql.y:6109
+//line mysql_sql.y:6113
 		{
 		}
 	case 1028:
 		yyDollar = yyS[yypt-1 : yypt+1]
 		var yyLOCAL bool
-//line mysql_sql.y:6111
+//line mysql_sql.y:6115
 		{
 			yyLOCAL = true
 		}
 		yyVAL.union = yyLOCAL
 	case 1032:
 		yyDollar = yyS[yypt-0 : yypt+1]
-//line mysql_sql.y:6121
+//line mysql_sql.y:6125
 		{
 			yyVAL.str = ""
 		}
 	case 1033:
 		yyDollar = yyS[yypt-1 : yypt+1]
-//line mysql_sql.y:6125
+//line mysql_sql.y:6129
 		{
 			yyVAL.str = string(yyDollar[1].str)
 		}
diff --git a/pkg/sql/parsers/dialect/mysql/mysql_sql.y b/pkg/sql/parsers/dialect/mysql/mysql_sql.y
index 51a670a8d..149ba201a 100644
--- a/pkg/sql/parsers/dialect/mysql/mysql_sql.y
+++ b/pkg/sql/parsers/dialect/mysql/mysql_sql.y
@@ -4540,11 +4540,15 @@ cast_type:
     }
 |   SIGNED integer_opt
     {
+    	name := $1
+    	if $2 != "" {
+    		name = $2
+    	}
         locale := ""
         $$ = &tree.T{
             InternalType: tree.InternalType{
 		        Family: tree.IntFamily,
-                FamilyString: $1,
+                FamilyString: name,
 		        Width:  64,
 		        Locale: &locale,
 		        Oid:    uint32(defines.MYSQL_TYPE_LONGLONG),
@@ -4557,7 +4561,7 @@ cast_type:
         $$ = &tree.T{
             InternalType: tree.InternalType{
 		        Family: tree.IntFamily,
-                FamilyString: $1,
+                FamilyString: $2,
 		        Width:  64,
 		        Locale: &locale,
                 Unsigned: true,
diff --git a/pkg/sql/parsers/tree/types.go b/pkg/sql/parsers/tree/types.go
index 5a574c9aa..037ef4d28 100644
--- a/pkg/sql/parsers/tree/types.go
+++ b/pkg/sql/parsers/tree/types.go
@@ -128,8 +128,11 @@ func (node *InternalType) Format(ctx *FmtCtx) {
 	fs := strings.ToLower(node.FamilyString)
 	ctx.WriteString(fs)
 
-	if node.Unsigned && fs != "unsigned" {
-		ctx.WriteString(" unsigned")
+	if node.Unsigned {
+		if fs != "" {
+			ctx.WriteByte(' ')
+		}
+		ctx.WriteString("unsigned")
 	}
 	if node.Zerofill {
 		ctx.WriteString(" zerofill")
diff --git a/pkg/sql/plan2/function/operator/cast.go b/pkg/sql/plan2/function/operator/cast.go
index 81310e7f3..78ba3866f 100644
--- a/pkg/sql/plan2/function/operator/cast.go
+++ b/pkg/sql/plan2/function/operator/cast.go
@@ -300,13 +300,13 @@ func Cast(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
 		case types.T_int64:
 			return CastSpecials1Int[int64](lv, rv, proc)
 		case types.T_uint8:
-			return CastSpecials1Int[uint8](lv, rv, proc)
+			return CastSpecials1Uint[uint8](lv, rv, proc)
 		case types.T_uint16:
-			return CastSpecials1Int[uint16](lv, rv, proc)
+			return CastSpecials1Uint[uint16](lv, rv, proc)
 		case types.T_uint32:
-			return CastSpecials1Int[uint32](lv, rv, proc)
+			return CastSpecials1Uint[uint32](lv, rv, proc)
 		case types.T_uint64:
-			return CastSpecials1Int[uint64](lv, rv, proc)
+			return CastSpecials1Uint[uint64](lv, rv, proc)
 		}
 	}
 
@@ -824,7 +824,7 @@ func CastInt64ToUint64(lv, rv *vector.Vector, proc *process.Process) (*vector.Ve
 
 // CastSpecials1Int : Cast converts string to integer,Contains the following:
 // (char / varhcar) -> (int8 / int16 / int32/ int64 / uint8 / uint16 / uint32 / uint64)
-func CastSpecials1Int[T constraints.Integer](lv, rv *vector.Vector, proc *process.Process) (*vector.Vector, error) {
+func CastSpecials1Int[T constraints.Signed](lv, rv *vector.Vector, proc *process.Process) (*vector.Vector, error) {
 	rtl := rv.Typ.Oid.TypeLen()
 	col := vector.MustBytesCols(lv)
 	var vec *vector.Vector
@@ -849,6 +849,31 @@ func CastSpecials1Int[T constraints.Integer](lv, rv *vector.Vector, proc *proces
 	return vec, nil
 }
 
+func CastSpecials1Uint[T constraints.Unsigned](lv, rv *vector.Vector, proc *process.Process) (*vector.Vector, error) {
+	rtl := rv.Typ.Oid.TypeLen()
+	col := vector.MustBytesCols(lv)
+	var vec *vector.Vector
+	var err error
+	var rs []T
+	if lv.IsScalar() {
+		vec = proc.AllocScalarVector(rv.Typ)
+		rs = make([]T, 1)
+	} else {
+		vec, err = proc.AllocVector(rv.Typ, int64(rtl)*int64(len(col.Offsets)))
+		if err != nil {
+			return nil, err
+		}
+		rs = encoding.DecodeFixedSlice[T](vec.Data, rtl)
+	}
+	if _, err = typecast.BytesToUint(col, rs); err != nil {
+		return nil, err
+	}
+
+	nulls.Set(vec.Nsp, lv.Nsp)
+	vector.SetCol(vec, rs)
+	return vec, nil
+}
+
 // CastSpecials1Float : Cast converts string to floating point number,Contains the following:
 // (char / varhcar) -> (float32 / float64)
 func CastSpecials1Float[T constraints.Float](lv, rv *vector.Vector, proc *process.Process) (*vector.Vector, error) {
diff --git a/pkg/vectorize/typecast/typecast.go b/pkg/vectorize/typecast/typecast.go
index 1dec1331a..41c7c6d18 100644
--- a/pkg/vectorize/typecast/typecast.go
+++ b/pkg/vectorize/typecast/typecast.go
@@ -15,10 +15,12 @@
 package typecast
 
 import (
+	"fmt"
 	"github.com/matrixorigin/matrixone/pkg/common/moerr"
 	"github.com/matrixorigin/matrixone/pkg/vectorize/div"
 	"math"
 	"strconv"
+	"strings"
 	"unsafe"
 
 	"github.com/matrixorigin/matrixone/pkg/container/types"
@@ -134,13 +136,13 @@ var (
 	Int32ToBytes   = IntToBytes[int32]
 	BytesToInt64   = BytesToInt[int64]
 	Int64ToBytes   = IntToBytes[int64]
-	BytesToUint8   = BytesToInt[uint8]
+	BytesToUint8   = BytesToUint[uint8]
 	Uint8ToBytes   = IntToBytes[uint8]
-	BytesToUint16  = BytesToInt[uint16]
+	BytesToUint16  = BytesToUint[uint16]
 	Uint16ToBytes  = IntToBytes[uint16]
-	BytesToUint32  = BytesToInt[uint32]
+	BytesToUint32  = BytesToUint[uint32]
 	Uint32ToBytes  = IntToBytes[uint32]
-	BytesToUint64  = BytesToInt[uint64]
+	BytesToUint64  = BytesToUint[uint64]
 	Uint64ToBytes  = IntToBytes[uint64]
 	BytesToFloat32 = BytesToFloat[float32]
 	Float32ToBytes = FloatToBytes[float32]
@@ -200,14 +202,34 @@ func int64ToUint64(xs []int64, rs []uint64) ([]uint64, error) {
 	return rs, nil
 }
 
-func BytesToInt[T constraints.Integer](xs *types.Bytes, rs []T) ([]T, error) {
+func BytesToInt[T constraints.Signed](xs *types.Bytes, rs []T) ([]T, error) {
 	var bitSize = int(unsafe.Sizeof(T(0))) * 8
 
 	for i, o := range xs.Offsets {
 		s := string(xs.Data[o : o+xs.Lengths[i]])
-		val, err := strconv.ParseInt(s, 10, bitSize)
+		val, err := strconv.ParseInt(strings.TrimSpace(s), 10, bitSize)
 		if err != nil {
-			return nil, err
+			if strings.Contains(err.Error(), "value out of range") {
+				return nil, fmt.Errorf("Overflow when cast '%s' as type of integer", s)
+			}
+			return nil, fmt.Errorf("Can't cast '%s' as type of integer", s)
+		}
+		rs[i] = T(val)
+	}
+	return rs, nil
+}
+
+func BytesToUint[T constraints.Unsigned](xs *types.Bytes, rs []T) ([]T, error) {
+	var bitSize = int(unsafe.Sizeof(T(0))) * 8
+
+	for i, o := range xs.Offsets {
+		s := string(xs.Data[o : o+xs.Lengths[i]])
+		val, err := strconv.ParseUint(strings.TrimSpace(s), 10, bitSize)
+		if err != nil {
+			if strings.Contains(err.Error(), "value out of range") {
+				return nil, fmt.Errorf("Overflow when cast '%s' as type of unsigned integer", s)
+			}
+			return nil, fmt.Errorf("Can't cast '%s' as type of unsigned integer", s)
 		}
 		rs[i] = T(val)
 	}


Test patch:
diff --git a/pkg/logservice/client_test.go b/pkg/logservice/client_test.go
index 8fc8e2465..0b8158a49 100644
--- a/pkg/logservice/client_test.go
+++ b/pkg/logservice/client_test.go
@@ -129,7 +129,7 @@ func TestClientRead(t *testing.T) {
 		recs, lsn, err := c.Read(ctx, 4, math.MaxUint64)
 		require.NoError(t, err)
 		assert.Equal(t, uint64(4), lsn)
-		assert.Equal(t, 2, len(recs))
+		require.Equal(t, 2, len(recs))
 		assert.Equal(t, cmd, recs[0].Data)
 		assert.Equal(t, cmd2, recs[1].Data)
 
diff --git a/pkg/sql/parsers/dialect/mysql/mysql_sql_test.go b/pkg/sql/parsers/dialect/mysql/mysql_sql_test.go
index 56d5b1e3f..7496549f5 100644
--- a/pkg/sql/parsers/dialect/mysql/mysql_sql_test.go
+++ b/pkg/sql/parsers/dialect/mysql/mysql_sql_test.go
@@ -26,8 +26,8 @@ var (
 		input  string
 		output string
 	}{
-		input:  "SELECT ((+0) IN ((0b111111111111111111111111111111111111111111111111111),(rpad(1.0,2048,1)), (32767.1)));",
-		output: "select ((+0) in ((0b111111111111111111111111111111111111111111111111111), (rpad(1.0, 2048, 1)), (32767.1)))",
+		input:  "select CAST('10 ' as unsigned);",
+		output: "select cast(10  as unsigned)",
 	}
 )
 
@@ -52,6 +52,12 @@ var (
 		input  string
 		output string
 	}{{
+		input:  "select CAST('10 ' as unsigned);",
+		output: "select cast(10  as unsigned)",
+	}, {
+		input:  "select CAST('10 ' as unsigned integer);",
+		output: "select cast(10  as integer unsigned)",
+	}, {
 		input:  "SELECT ((+0) IN ((0b111111111111111111111111111111111111111111111111111),(rpad(1.0,2048,1)), (32767.1)));",
 		output: "select ((+0) in ((0b111111111111111111111111111111111111111111111111111), (rpad(1.0, 2048, 1)), (32767.1)))",
 	}, {
diff --git a/test/cases/dtype/bigint.test b/test/cases/dtype/bigint.test
index 07abc583d..c9294f3ad 100644
--- a/test/cases/dtype/bigint.test
+++ b/test/cases/dtype/bigint.test
@@ -77,11 +77,9 @@ select * from t1 where bigint_col='17666000000000000000';
 
 #Test cases of cast
 drop table t1;
--- @bvt:issue#3249
 select cast(10000002383263201056 as unsigned) mod 50 as result;
 select cast(19999999999999999999 as signed);
 select cast(-19999999999999999999 as signed);
--- @bvt:issue
 CREATE TABLE t1 (id INT PRIMARY KEY,
 a BIGINT(20) UNSIGNED,
 b VARCHAR(20));
diff --git a/test/cases/function/func_cast.test b/test/cases/function/func_cast.test
index 5d4bdbac1..7558accb8 100644
--- a/test/cases/function/func_cast.test
+++ b/test/cases/function/func_cast.test
@@ -1,9 +1,7 @@
 select CAST(1-2 AS UNSIGNED);
 select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
--- @bvt:issue#3360
 select CAST('10 ' as unsigned integer);
 select CAST('10x' as unsigned integer);
--- @bvt:issue
 -- @bvt:issue#3294
 select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
 -- @bvt:issue
@@ -33,10 +31,8 @@ select CAST(0xb3 as signed);
 select CAST(0x8fffffffffffffff as signed);
 select CAST(0xffffffffffffffff as unsigned);
 select CAST(0xfffffffffffffffe as signed);
--- @bvt:issue#3360
 select cast('-10a' as signed integer);
 select cast('a10' as unsigned integer);
--- @bvt:issue
 -- @bvt:issue#3247
 select 10+'a';
 -- @bvt:issue
@@ -48,17 +44,13 @@ select 10E+0+'a';
 -- @bvt:issue
 
 # out-of-range cases
--- @bvt:issue#3360
 select cast('18446744073709551616' as unsigned);
 select cast('18446744073709551616' as signed);
 select cast('9223372036854775809' as signed);
--- @bvt:issue
 select cast('-1' as unsigned);
--- @bvt:issue#3360
 select cast('abc' as signed);
 select cast('1a' as signed);
 select cast('' as signed);
--- @bvt:issue
 #
 # Character set conversion
 #
@@ -199,10 +191,8 @@ select date_add(cast('2004-12-30 12:00:00' as date), interval 0 hour);
 #
 select cast(18446744073709551615 as unsigned);
 select cast(18446744073709551615 as signed);
--- @bvt:issue#3360
 select cast('18446744073709551615' as unsigned);
 select cast('18446744073709551615' as signed);
--- @bvt:issue
 select cast('9223372036854775807' as signed);
 
 select cast(concat_ws('184467440','73709551615') as unsigned);
diff --git a/test/result/dtype/bigint.result b/test/result/dtype/bigint.result
index d54aa3275..3d74b365a 100644
--- a/test/result/dtype/bigint.result
+++ b/test/result/dtype/bigint.result
@@ -133,14 +133,11 @@ bigint_col
 17666000000000000000
 drop table t1;
 select cast(10000002383263201056 as unsigned) mod 50 as result;
-result
-6
+overflow from bigint unsigned to bigint
 select cast(19999999999999999999 as signed);
-cast(19999999999999999999 as signed)
-9223372036854775807
+Operator 'cast' with parameters [DECIMAL128 BIGINT] will be implemented in future version.
 select cast(-19999999999999999999 as signed);
-cast(-19999999999999999999 as signed)
--9223372036854775808
+Operator 'cast' with parameters [DECIMAL128 BIGINT] will be implemented in future version.
 CREATE TABLE t1 (id INT PRIMARY KEY,
 a BIGINT(20) UNSIGNED,
 b VARCHAR(20));
diff --git a/test/result/function/func_cast.result b/test/result/function/func_cast.result
index 2f06206b5..c312e66d7 100644
--- a/test/result/function/func_cast.result
+++ b/test/result/function/func_cast.result
@@ -3,11 +3,10 @@ overflow from bigint to bigint unsigned
 select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
 overflow from bigint to bigint unsigned
 select CAST('10 ' as unsigned integer);
-CAST('10 ' as unsigned integer)
+cast(10  as integer unsigned)
 10
 select CAST('10x' as unsigned integer);
-CAST('10x' as unsigned integer)
-10
+Can't cast '10x' as type of unsigned integer
 select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
 cast(-5 as unsigned) | 1	cast(-5 as unsigned) & -1
 18446744073709551611	18446744073709551611
@@ -45,11 +44,9 @@ CAST(0xffffffffffffffff as unsigned)
 select CAST(0xfffffffffffffffe as signed);
 overflow from bigint unsigned to bigint
 select cast('-10a' as signed integer);
-cast('-10a' as signed integer)
--10
+Can't cast '-10a' as type of integer
 select cast('a10' as unsigned integer);
-cast('a10' as unsigned integer)
-0
+Can't cast 'a10' as type of unsigned integer
 select 10+'a';
 10+'a'
 10.0
@@ -60,26 +57,19 @@ select 10E+0+'a';
 10E+0+'a'
 10.0
 select cast('18446744073709551616' as unsigned);
-cast('18446744073709551616' as unsigned)
-18446744073709551615
+Overflow when cast '18446744073709551616' as type of unsigned integer
 select cast('18446744073709551616' as signed);
-cast('18446744073709551616' as signed)
--1
+Overflow when cast '18446744073709551616' as type of integer
 select cast('9223372036854775809' as signed);
-cast('9223372036854775809' as signed)
--9223372036854775807
+Overflow when cast '9223372036854775809' as type of integer
 select cast('-1' as unsigned);
-cast('-1' as unsigned)
-18446744073709551615
+Can't cast '-1' as type of unsigned integer
 select cast('abc' as signed);
-cast('abc' as signed)
-0
+Can't cast 'abc' as type of integer
 select cast('1a' as signed);
-cast('1a' as signed)
-1
+Can't cast '1a' as type of integer
 select cast('' as signed);
-cast('' as signed)
-0
+Can't cast '' as type of integer
 select cast("2001-1-1" as date) = "2001-01-01";
 cast("2001-1-1" as date) = "2001-01-01"
 1
@@ -101,8 +91,7 @@ select cast('18446744073709551615' as unsigned);
 cast('18446744073709551615' as unsigned)
 18446744073709551615
 select cast('18446744073709551615' as signed);
-cast('18446744073709551615' as signed)
--1
+Overflow when cast '18446744073709551615' as type of integer
 select cast('9223372036854775807' as signed);
 cast('9223372036854775807' as signed)
 9223372036854775807