Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: support customized session options #70033

Closed
nvanbenschoten opened this issue Sep 10, 2021 · 0 comments · Fixed by #71915
Closed

sql: support customized session options #70033

nvanbenschoten opened this issue Sep 10, 2021 · 0 comments · Fixed by #71915
Labels
A-sql-pgcompat Semantic compatibility with PostgreSQL A-tools-postgrest C-enhancement Solution expected to add code/behavior + preserve backward-compat (pg compat issues are exception) T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions)

Comments

@nvanbenschoten
Copy link
Member

nvanbenschoten commented Sep 10, 2021

Needed for #69010.

Postgres allows arbitrary session parameters to be set for a session, as long as they have a two-part name (i.e. contain a period). Tools can use this to store and retrieve arbitrary local session state.

We should ensure the arbitrary state has memory accounting.

> SELECT set_config('mytool.state', 'some val', false);
 set_config
------------
 some val
(1 row)

> SELECT current_setting('mytool.state');
 current_setting
-----------------
 some val
(1 row)

PG docs: https://www.postgresql.org/docs/current/runtime-config-custom.html

Prototype:

diff --git a/pkg/sql/exec_util.go b/pkg/sql/exec_util.go
index 42dded41fb..de40f98631 100644
--- a/pkg/sql/exec_util.go
+++ b/pkg/sql/exec_util.go
@@ -2788,6 +2788,13 @@ func (m *sessionDataMutator) SetLocation(loc *time.Location) {
 	m.bufferParamStatusUpdate("TimeZone", sessionDataTimeZoneFormat(loc))
 }
 
+func (m *sessionDataMutator) SetCustomOption(name, val string) {
+	if m.data.CustomOptions == nil {
+		m.data.CustomOptions = make(map[string]string)
+	}
+	m.data.CustomOptions[name] = val
+}
+
 func (m *sessionDataMutator) SetReadOnly(val bool) {
 	// The read-only state is special; it's set as a session variable (SET
 	// transaction_read_only=<>), but it represents per-txn state, not
diff --git a/pkg/sql/sessiondata/session_data.go b/pkg/sql/sessiondata/session_data.go
index a86e467b5f..67964914af 100644
--- a/pkg/sql/sessiondata/session_data.go
+++ b/pkg/sql/sessiondata/session_data.go
@@ -48,6 +48,9 @@ type SessionData struct {
 	// SequenceState gives access to the SQL sequences that have been
 	// manipulated by the session.
 	SequenceState *SequenceState
+	CustomOptions map[string]string
 }
 
 // Clone returns a clone of SessionData.
diff --git a/pkg/sql/vars.go b/pkg/sql/vars.go
index 16de1f2361..b38b0863d0 100644
--- a/pkg/sql/vars.go
+++ b/pkg/sql/vars.go
@@ -1956,6 +1956,14 @@ func (p *planner) GetSessionVar(
 	_ context.Context, varName string, missingOk bool,
 ) (bool, string, error) {
 	name := strings.ToLower(varName)
+	if isCustomOption(name) {
+		v, ok := p.SessionData().CustomOptions[name]
+		if !ok && !missingOk {
+			return false, "", pgerror.Newf(pgcode.UndefinedObject,
+				"unrecognized configuration parameter %q", name)
+		}
+		return true, v, nil
+	}
 	ok, v, err := getSessionVar(name, missingOk)
 	if err != nil || !ok {
 		return ok, "", err
@@ -1966,6 +1974,18 @@ func (p *planner) GetSessionVar(
 // SetSessionVar implements the EvalSessionAccessor interface.
 func (p *planner) SetSessionVar(ctx context.Context, varName, newVal string, isLocal bool) error {
 	name := strings.ToLower(varName)
+	if isCustomOption(name) {
+		// Ignore isLocal.
+		_ = isLocal
+		return p.applyOnSessionDataMutators(
+			ctx,
+			isLocal,
+			func(m sessionDataMutator) error {
+				m.SetCustomOption(name, newVal)
+				return nil
+			},
+		)
+	}
 	_, v, err := getSessionVar(name, false /* missingOk */)
 	if err != nil {
 		return err
@@ -1995,3 +2015,7 @@ func (p *planner) SetSessionVar(ctx context.Context, varName, newVal string, isL
 		},
 	)
 }
+
+func isCustomOption(varName string) bool {
+	return strings.Contains(varName, ".")
+}

Epic CRDB-10300

@nvanbenschoten nvanbenschoten added C-enhancement Solution expected to add code/behavior + preserve backward-compat (pg compat issues are exception) A-sql-pgcompat Semantic compatibility with PostgreSQL labels Sep 10, 2021
@blathers-crl blathers-crl bot added the T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions) label Sep 10, 2021
@craig craig bot closed this as completed in 3f56647 Nov 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-sql-pgcompat Semantic compatibility with PostgreSQL A-tools-postgrest C-enhancement Solution expected to add code/behavior + preserve backward-compat (pg compat issues are exception) T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants