Skip to content

Commit

Permalink
session: del NO_BACKSLASH_ESCAPES sql mode for internal sql (#43966) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-chi-bot authored May 23, 2023
1 parent 65aabc9 commit 55a0a57
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
10 changes: 10 additions & 0 deletions parser/mysql/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,16 @@ func (m SQLMode) HasAllowInvalidDatesMode() bool {
return m&ModeAllowInvalidDates == ModeAllowInvalidDates
}

// DelSQLMode delete sql mode from ori
func DelSQLMode(ori SQLMode, del SQLMode) SQLMode {
return ori & (^del)
}

// SetSQLMode add sql mode to ori
func SetSQLMode(ori SQLMode, add SQLMode) SQLMode {
return ori | add
}

// consts for sql modes.
// see https://dev.mysql.com/doc/internals/en/query-event.html#q-sql-mode-code
const (
Expand Down
7 changes: 6 additions & 1 deletion session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,12 @@ func (s *session) ParseSQL(ctx context.Context, sql string, params ...parser.Par

p := parserPool.Get().(*parser.Parser)
defer parserPool.Put(p)
p.SetSQLMode(s.sessionVars.SQLMode)

sqlMode := s.sessionVars.SQLMode
if s.isInternal() {
sqlMode = mysql.DelSQLMode(sqlMode, mysql.ModeNoBackslashEscapes)
}
p.SetSQLMode(sqlMode)
p.SetParserConfig(s.sessionVars.BuildParserConfig())
tmp, warn, err := p.ParseSQL(sql, params...)
// The []ast.StmtNode is referenced by the parser, to reuse the parser, make a copy of the result.
Expand Down
48 changes: 48 additions & 0 deletions session/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5858,3 +5858,51 @@ func (s *testSessionSuite) TestSameNameObjectWithLocalTemporaryTable(c *C) {
" `cs1` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
}

func (s *testSessionSuite) TestRandomBinary(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")

ctx := context.Background()
allBytes := [][]byte{
{4, 0, 0, 0, 0, 0, 0, 4, '2'},
{4, 0, 0, 0, 0, 0, 0, 4, '.'},
{4, 0, 0, 0, 0, 0, 0, 4, '*'},
{4, 0, 0, 0, 0, 0, 0, 4, '('},
{4, 0, 0, 0, 0, 0, 0, 4, '\''},
{4, 0, 0, 0, 0, 0, 0, 4, '!'},
{4, 0, 0, 0, 0, 0, 0, 4, 29},
{4, 0, 0, 0, 0, 0, 0, 4, 28},
{4, 0, 0, 0, 0, 0, 0, 4, 23},
{4, 0, 0, 0, 0, 0, 0, 4, 16},
}
sql := "insert into mysql.stats_top_n (table_id, is_index, hist_id, value, count) values "
var val string
for i, bytes := range allBytes {
if i == 0 {
val += sqlexec.MustEscapeSQL("(874, 0, 1, %?, 3)", bytes)
} else {
val += sqlexec.MustEscapeSQL(",(874, 0, 1, %?, 3)", bytes)
}
}
sql += val
tk.MustExec("set sql_mode = 'NO_BACKSLASH_ESCAPES';")
_, err := tk.Se.ExecuteInternal(ctx, sql)
c.Assert(err, Equals, nil)
}

func (s *testSessionSuite) TestSQLModeOp(c *C) {
m := mysql.ModeNoBackslashEscapes | mysql.ModeOnlyFullGroupBy
d := mysql.DelSQLMode(m, mysql.ModeANSIQuotes)
c.Assert(m, Equals, d)

d = mysql.DelSQLMode(m, mysql.ModeNoBackslashEscapes)
c.Assert(mysql.ModeOnlyFullGroupBy, Equals, d)

m = mysql.ModeNoBackslashEscapes | mysql.ModeOnlyFullGroupBy
a := mysql.SetSQLMode(m, mysql.ModeOnlyFullGroupBy)
c.Assert(m, Equals, a)

a = mysql.SetSQLMode(m, mysql.ModeAllowInvalidDates)
c.Assert(mysql.ModeNoBackslashEscapes|mysql.ModeOnlyFullGroupBy|mysql.ModeAllowInvalidDates, Equals, a)
}

0 comments on commit 55a0a57

Please sign in to comment.