diff --git a/engine.go b/engine.go index 9b7faf4f7a..714a0adb48 100644 --- a/engine.go +++ b/engine.go @@ -268,6 +268,9 @@ func clearWarnings(ctx *sql.Context, node sql.Node) { case *plan.Offset, *plan.Limit: // `show warning limit x offset y` is valid, so we need to recurse clearWarnings(ctx, n.Children()[0]) + case *plan.Set: + // We want to maintain warnings when setting the warnings_lock variable. + // Set statements also can't produce warnings, so we don't care about clearing them. case plan.ShowWarnings: // ShowWarnings should not clear the warnings, but should still reset the warning count. ctx.ClearWarningCount() diff --git a/enginetest/queries/variable_queries.go b/enginetest/queries/variable_queries.go index 056771d00b..173be4222a 100644 --- a/enginetest/queries/variable_queries.go +++ b/enginetest/queries/variable_queries.go @@ -575,6 +575,64 @@ var VariableQueries = []ScriptTest{ }, }, }, + { + Name: "locked warnings stay after query", + SetUpScript: []string{ + "set @@lock_warnings = 1", + "select 1/0,1/0", + "select 1/1", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "show warnings", + Expected: []sql.Row{ + {"Warning", 1365, "Division by 0"}, + {"Warning", 1365, "Division by 0"}}, + }, + { + Query: "select 1/0", + SkipResultsCheck: true, + }, + { + Query: "show warnings", + Expected: []sql.Row{ + {"Warning", 1365, "Division by 0"}, + {"Warning", 1365, "Division by 0"}, + {"Warning", 1365, "Division by 0"}, + }, + }, + }, + }, + { + Name: "unlocked warnings clear after query", + SetUpScript: []string{ + "set @@lock_warnings = 0", + "select 1/0,1/0", + "select 1/1", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "show warnings", + Expected: []sql.Row{}, + }, + }, + }, + { + Name: "warnings persist after locking between queries", + SetUpScript: []string{ + "select 1/0", + "set @@lock_warnings = 1", + "select 1/1", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "show warnings", + Expected: []sql.Row{ + {"Warning", 1365, "Division by 0"}, + }, + }, + }, + }, //TODO: do not override tables with user-var-like names...but why would you do this?? //{ // Name: "user var table name no conflict", diff --git a/sql/variables/system_variables.go b/sql/variables/system_variables.go index e515ba6134..188d3bc5ec 100644 --- a/sql/variables/system_variables.go +++ b/sql/variables/system_variables.go @@ -1253,6 +1253,23 @@ var systemVars = map[string]sql.SystemVariable{ Type: types.NewSystemIntType("lock_wait_timeout", 1, 31536000, false), Default: int64(31536000), }, + "lock_warnings": &sql.MysqlSystemVariable{ + Name: "lock_warnings", + Scope: sql.GetMysqlScope(sql.SystemVariableScope_Session), + Dynamic: true, + SetVarHintApplies: false, + Type: types.NewSystemBoolType("lock_warnings"), + Default: int8(0), + NotifyChanged: func(ctx *sql.Context, _ sql.SystemVariableScope, value sql.SystemVarValue) error { + switch value.Val.(int8) { + case 0: + ctx.UnlockWarnings() + case 1: + ctx.LockWarnings() + } + return nil + }, + }, "log_bin": &sql.MysqlSystemVariable{ Name: "log_bin", Scope: sql.GetMysqlScope(sql.SystemVariableScope_Persist),