From 6415b886182144f10629659fd463aafcace39f48 Mon Sep 17 00:00:00 2001 From: Rafi Shamim Date: Tue, 1 Feb 2022 02:09:47 -0500 Subject: [PATCH] sql: support RESET ALL statement Release note (sql change): Support for the RESET ALL statement was added. This statement resets the values of all session variables to their default values. --- docs/generated/sql/bnf/reset_session_stmt.bnf | 1 + docs/generated/sql/bnf/stmt_block.bnf | 1 + pkg/sql/logictest/testdata/logic_test/set | 16 ++++++++ pkg/sql/parser/sql.y | 4 ++ pkg/sql/pgwire/conn_test.go | 13 ++++++ pkg/sql/set_var.go | 41 +++++++++++++++++++ pkg/sql/walk.go | 2 + 7 files changed, 78 insertions(+) diff --git a/docs/generated/sql/bnf/reset_session_stmt.bnf b/docs/generated/sql/bnf/reset_session_stmt.bnf index b2cbe4a2e468..5695f63dc938 100644 --- a/docs/generated/sql/bnf/reset_session_stmt.bnf +++ b/docs/generated/sql/bnf/reset_session_stmt.bnf @@ -1,3 +1,4 @@ reset_session_stmt ::= 'RESET' session_var | 'RESET' 'SESSION' session_var + | 'RESET_ALL' 'ALL' diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index d5df68b66665..62adf4a68a13 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -579,6 +579,7 @@ pause_all_jobs_stmt ::= reset_session_stmt ::= 'RESET' session_var | 'RESET' 'SESSION' session_var + | 'RESET_ALL' 'ALL' reset_csetting_stmt ::= 'RESET' 'CLUSTER' 'SETTING' var_name diff --git a/pkg/sql/logictest/testdata/logic_test/set b/pkg/sql/logictest/testdata/logic_test/set index 76a0c04c8ea8..bf37806fdf33 100644 --- a/pkg/sql/logictest/testdata/logic_test/set +++ b/pkg/sql/logictest/testdata/logic_test/set @@ -743,6 +743,22 @@ SHOW tracing.custom ---- ijk +# Test that RESET ALL changes custom options to empty strings. +statement ok +RESET ALL + +query T + +query T +SHOW tracing.custom +---- +. + +query T +SHOW custom_option.set_sql +---- +. + statement error unrecognized configuration parameter "custom_option.does_not_yet_exist" SHOW custom_option.does_not_yet_exist diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index eaca4853068f..7e1ad65960d9 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -4600,6 +4600,10 @@ reset_session_stmt: { $$.val = &tree.SetVar{Name: $3, Values:tree.Exprs{tree.DefaultVal{}}, Reset: true} } +| RESET_ALL ALL + { + $$.val = &tree.SetVar{ResetAll: true, Reset: true} + } | RESET error // SHOW HELP: RESET // %Help: RESET CLUSTER SETTING - reset a cluster setting to its default value diff --git a/pkg/sql/pgwire/conn_test.go b/pkg/sql/pgwire/conn_test.go index 1178059bdeb4..9b30a1a28635 100644 --- a/pkg/sql/pgwire/conn_test.go +++ b/pkg/sql/pgwire/conn_test.go @@ -1754,6 +1754,19 @@ func TestRoleDefaultSettings(t *testing.T) { setupStmt: "ALTER ROLE testuser IN DATABASE defaultdb SET search_path = 'f'", expectedSearchPath: "f", }, + { + // RESET after connecting should go back to the per-role default setting. + setupStmt: "", + postConnectStmt: "SET search_path = 'new'; RESET search_path;", + expectedSearchPath: "f", + }, + { + // RESET should use the query param as the default if it was provided. + setupStmt: "", + searchPathOptOverride: "g", + postConnectStmt: "SET search_path = 'new'; RESET ALL;", + expectedSearchPath: "g", + }, { setupStmt: "ALTER ROLE testuser IN DATABASE defaultdb SET search_path = DEFAULT", expectedSearchPath: "c", diff --git a/pkg/sql/set_var.go b/pkg/sql/set_var.go index c355849a02a0..ac98c5573bdd 100644 --- a/pkg/sql/set_var.go +++ b/pkg/sql/set_var.go @@ -39,10 +39,16 @@ type setVarNode struct { typedValues []tree.TypedExpr } +// resetAllNode represents a RESET ALL statement. +type resetAllNode struct{} + // SetVar sets session variables. // Privileges: None. // Notes: postgres/mysql do not require privileges for session variables (some exceptions). func (p *planner) SetVar(ctx context.Context, n *tree.SetVar) (planNode, error) { + if n.ResetAll { + return &resetAllNode{}, nil + } if n.Name == "" { // A client has sent the reserved internal syntax SET ROW ..., // or the user entered `SET "" = foo`. Reject it. @@ -182,6 +188,41 @@ func (n *setVarNode) Next(_ runParams) (bool, error) { return false, nil } func (n *setVarNode) Values() tree.Datums { return nil } func (n *setVarNode) Close(_ context.Context) {} +func (n *resetAllNode) startExec(params runParams) error { + for varName, v := range varGen { + if v.Set == nil && v.RuntimeSet == nil && v.SetWithPlanner == nil { + continue + } + _, defVal := getSessionVarDefaultString( + varName, + v, + params.p.sessionDataMutatorIterator.sessionDataMutatorBase, + ) + if err := params.p.SetSessionVar(params.ctx, varName, defVal, false /* isLocal */); err != nil { + return err + } + } + for varName := range params.SessionData().CustomOptions { + _, v, err := getSessionVar(varName, false /* missingOK */) + if err != nil { + return err + } + _, defVal := getSessionVarDefaultString( + varName, + v, + params.p.sessionDataMutatorIterator.sessionDataMutatorBase, + ) + if err := params.p.SetSessionVar(params.ctx, varName, defVal, false /* isLocal */); err != nil { + return err + } + } + return nil +} + +func (n *resetAllNode) Next(_ runParams) (bool, error) { return false, nil } +func (n *resetAllNode) Values() tree.Datums { return nil } +func (n *resetAllNode) Close(_ context.Context) {} + func getStringVal(evalCtx *tree.EvalContext, name string, values []tree.TypedExpr) (string, error) { if len(values) != 1 { return "", newSingleArgVarError(name) diff --git a/pkg/sql/walk.go b/pkg/sql/walk.go index 76d54cdd4721..041b7aa1e4d8 100644 --- a/pkg/sql/walk.go +++ b/pkg/sql/walk.go @@ -218,6 +218,7 @@ func (v *planVisitor) visitInternal(plan planNode, name string) { case *createViewNode: case *setVarNode: case *setClusterSettingNode: + case *resetAllNode: case *delayedNode: if n.plan != nil { @@ -416,6 +417,7 @@ var planNodeNames = map[reflect.Type]string{ reflect.TypeOf(&renameTableNode{}): "rename table", reflect.TypeOf(&reparentDatabaseNode{}): "reparent database", reflect.TypeOf(&renderNode{}): "render", + reflect.TypeOf(&resetAllNode{}): "reset all", reflect.TypeOf(&RevokeRoleNode{}): "revoke role", reflect.TypeOf(&rowCountNode{}): "count", reflect.TypeOf(&rowSourceToPlanNode{}): "row source to plan node",