Skip to content

Commit

Permalink
session: del NO_BACKSLASH_ESCAPES sql mode for internal sql (pingcap#…
Browse files Browse the repository at this point in the history
  • Loading branch information
guo-shaoge authored May 19, 2023
1 parent 5ebad25 commit acc8f88
Show file tree
Hide file tree
Showing 3 changed files with 65 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 @@ -412,6 +412,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 @@ -1521,7 +1521,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
49 changes: 49 additions & 0 deletions session/sessiontest/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3553,3 +3553,52 @@ func TestHandleAssertionFailureForPartitionedTable(t *testing.T) {
require.ErrorContains(t, err, "assertion")
hook.CheckLogCount(t, 0)
}

func TestRandomBinary(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")

ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnStats)
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.Session().ExecuteInternal(ctx, sql)
require.NoError(t, err)
}

func TestSQLModeOp(t *testing.T) {
s := mysql.ModeNoBackslashEscapes | mysql.ModeOnlyFullGroupBy
d := mysql.DelSQLMode(s, mysql.ModeANSIQuotes)
require.Equal(t, s, d)

d = mysql.DelSQLMode(s, mysql.ModeNoBackslashEscapes)
require.Equal(t, mysql.ModeOnlyFullGroupBy, d)

s = mysql.ModeNoBackslashEscapes | mysql.ModeOnlyFullGroupBy
a := mysql.SetSQLMode(s, mysql.ModeOnlyFullGroupBy)
require.Equal(t, s, a)

a = mysql.SetSQLMode(s, mysql.ModeAllowInvalidDates)
require.Equal(t, mysql.ModeNoBackslashEscapes|mysql.ModeOnlyFullGroupBy|mysql.ModeAllowInvalidDates, a)
}

0 comments on commit acc8f88

Please sign in to comment.