From 888bf2b9e8f538d4f034ae6c6b7a4d4fa002d3b2 Mon Sep 17 00:00:00 2001 From: Rafi Shamim Date: Mon, 19 Sep 2022 11:54:11 -0400 Subject: [PATCH] sql: fix current_setting(..., true) for custom options Release note (bug fix): The `current_setting` builtin function now properly does not result in an error when checking a custom session setting that does not exist and the `missing_ok` argument is true. --- .../logictest/testdata/logic_test/pg_builtins | 28 +++++++++++++++++++ pkg/sql/vars.go | 14 ++++++++++ 2 files changed, 42 insertions(+) diff --git a/pkg/sql/logictest/testdata/logic_test/pg_builtins b/pkg/sql/logictest/testdata/logic_test/pg_builtins index 04485b716310..6d42fb197e04 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_builtins +++ b/pkg/sql/logictest/testdata/logic_test/pg_builtins @@ -268,6 +268,34 @@ SELECT current_setting('statement_timeout'), current_setting('search_path') query error unrecognized configuration parameter SELECT pg_catalog.current_setting('woo', false) +# Check that current_setting handles custom settings correctly. +query T +SELECT current_setting('my.custom', true) +---- +NULL + +statement ok +PREPARE check_custom AS SELECT current_setting('my.custom', true) + +query T +EXECUTE check_custom +---- +NULL + +statement ok +BEGIN; +SET LOCAL my.custom = 'foo' + +# Check that the existence of my.custom is checked depending on the execution +# context, and not at PREPARE time. +query T +EXECUTE check_custom +---- +foo + +statement ok +COMMIT + # check error on unsupported session var. query error configuration setting.*not supported SELECT current_setting('vacuum_cost_delay', false) diff --git a/pkg/sql/vars.go b/pkg/sql/vars.go index d84abb75be86..5fb80969ee70 100644 --- a/pkg/sql/vars.go +++ b/pkg/sql/vars.go @@ -79,6 +79,11 @@ type sessionVar struct { // either by SHOW or in the pg_catalog table. Get func(evalCtx *extendedEvalContext, kv *kv.Txn) (string, error) + // Exists returns true if this custom session option exists in the current + // context. It's needed to support the current_setting builtin for custom + // options. It is only defined for custom options. + Exists func(evalCtx *extendedEvalContext, kv *kv.Txn) bool + // GetFromSessionData returns a string representation of a given variable to // be used by BufferParamStatus. This is only required if the variable // is expected to send updates through ParamStatusUpdate in pgwire. @@ -2607,6 +2612,10 @@ func getCustomOptionSessionVar(varName string) (sv sessionVar, isCustom bool) { } return v, nil }, + Exists: func(evalCtx *extendedEvalContext, _ *kv.Txn) bool { + _, ok := evalCtx.SessionData().CustomOptions[varName] + return ok + }, Set: func(ctx context.Context, m sessionDataMutator, val string) error { // TODO(#72026): do some memory accounting. m.SetCustomOption(varName, val) @@ -2629,6 +2638,11 @@ func (p *planner) GetSessionVar( if err != nil || !ok { return ok, "", err } + if existsFn := v.Exists; existsFn != nil { + if missingOk && !existsFn(&p.extendedEvalCtx, p.Txn()) { + return false, "", nil + } + } val, err := v.Get(&p.extendedEvalCtx, p.Txn()) return true, val, err }