From e947693150a01adc08da971a74570bcd4917944d Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Mon, 22 Aug 2022 14:14:15 +0800 Subject: [PATCH] fix: render table_not_found error correctly (#372) --- pkg/mysql/conn.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pkg/mysql/conn.go b/pkg/mysql/conn.go index 0ae1cfe5..ab6fe9d2 100644 --- a/pkg/mysql/conn.go +++ b/pkg/mysql/conn.go @@ -25,12 +25,15 @@ import ( "fmt" "io" "net" + "regexp" "strings" "sync" "time" ) import ( + pmysql "github.com/arana-db/parser/mysql" + gxnet "github.com/dubbogo/gost/net" "github.com/pkg/errors" @@ -692,11 +695,33 @@ func (c *Conn) writeOKPacketWithEOFHeader(affectedRows, lastInsertID uint64, fla return c.writeEphemeralPacket() } +func (c *Conn) fixErrNoSuchTable(errorMessage string) string { + // FIXME: workaround, need refinement in the future. + // Table 'employees_0000.teacher' doesn't exist + if matches := getFixErrNoSuchTableRegexp().FindStringSubmatch(errorMessage); len(matches) == 3 { + var sb strings.Builder + sb.Grow(len(errorMessage)) + sb.WriteString("Table '") + sb.WriteString(c.Schema) + sb.WriteByte('.') + sb.WriteString(matches[2]) + sb.WriteString("' doesn't exist") + return sb.String() + } + + return errorMessage +} + // writeErrorPacket writes an error packet. // Server -> Client. // This method returns a generic error, not a SQLError. func (c *Conn) writeErrorPacket(errorCode uint16, sqlState string, format string, args ...interface{}) error { errorMessage := fmt.Sprintf(format, args...) + switch errorCode { + case pmysql.ErrNoSuchTable: + errorMessage = c.fixErrNoSuchTable(errorMessage) + } + length := 1 + 2 + 1 + 5 + len(errorMessage) data := c.startEphemeralPacket(length) pos := 0 @@ -865,3 +890,15 @@ func (c *Conn) GetTLSClientCerts() []*x509.Certificate { func (c *Conn) GetNetConn() net.Conn { return c.conn } + +var ( + _fixErrNoSuchTableRegexp *regexp.Regexp + _fixErrNoSuchTableRegexpOnce sync.Once +) + +func getFixErrNoSuchTableRegexp() *regexp.Regexp { + _fixErrNoSuchTableRegexpOnce.Do(func() { + _fixErrNoSuchTableRegexp = regexp.MustCompile(`^Table '([^.']+)\.([^.']+)' doesn't exist$`) + }) + return _fixErrNoSuchTableRegexp +}