Skip to content

Commit

Permalink
Merge pull request #877 from dolthub/fulghum/set_config
Browse files Browse the repository at this point in the history
Function: `set_config()`
  • Loading branch information
fulghum authored Oct 23, 2024
2 parents bcd2766 + a68aa0f commit c642a48
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions server/functions/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func Init() {
initRpad()
initRtrim()
initScale()
initSetConfig()
initSetVal()
initShobjDescription()
initSign()
Expand Down
67 changes: 67 additions & 0 deletions server/functions/set_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2024 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package functions

import (
"fmt"
"strings"

"github.com/dolthub/go-mysql-server/sql"

"github.com/dolthub/doltgresql/server/functions/framework"
pgtypes "github.com/dolthub/doltgresql/server/types"
)

func initSetConfig() {
framework.RegisterFunction(set_config_text_text_boolean)
}

// set_config_text_text_boolean implements the set_config() function
// https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-SET
var set_config_text_text_boolean = framework.Function3{
Name: "set_config",
Return: pgtypes.Text,
Parameters: [3]pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text, pgtypes.Bool},
Callable: func(ctx *sql.Context, _ [4]pgtypes.DoltgresType, settingName any, newValue any, isLocal any) (any, error) {
if settingName == nil {
return nil, fmt.Errorf("NULL value not allowed for configuration setting name")
}

// NULL is not supported for configuration values, and gets turned into the empty string
if newValue == nil {
newValue = ""
}

if isLocal == true {
// TODO: If isLocal is true, then the config setting should only persist for the current transaction
return nil, fmt.Errorf("setting configuration values for the current transaction is not supported yet")
}

// set_config can set system configuration or user configuration. System configuration settings are in top
// level settings, while user configuration settings are namespaced.
isUserConfig := strings.Contains(settingName.(string), ".")
if isUserConfig {
if err := ctx.SetUserVariable(ctx, settingName.(string), newValue.(string), pgtypes.Text); err != nil {
return nil, err
}
} else {
if err := ctx.SetSessionVariable(ctx, settingName.(string), newValue.(string)); err != nil {
return nil, err
}
}

return newValue.(string), nil
},
}
85 changes: 85 additions & 0 deletions testing/generation/function_coverage/output/set_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2024 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package output

import (
"testing"

"github.com/dolthub/go-mysql-server/sql"
)

func Test_SetConfig(t *testing.T) {
RunScripts(t, []ScriptTest{
{
Name: "set_config",
Assertions: []ScriptTestAssertion{
{
// non-namespaced, non-system settings result in an error: "unrecognized configuration parameter"
Query: "SELECT set_config('doesnotexist', '42', false);",
ExpectedErr: true,
},
{
Query: "SELECT set_config('', 'bar', false);",
ExpectedErr: true,
},
{
Query: "SELECT set_config(NULL, 'bar', false);",
ExpectedErr: true,
},
{
// Set a system config setting
Query: "SELECT set_config('search_path', '123', false);",
Expected: []sql.Row{{"123"}},
},
{
Query: "SELECT current_setting('search_path');",
Expected: []sql.Row{{"123"}},
},
{
// Set a user config setting in a custom namespace
Query: "SELECT set_config('mynamespace.var', 'bar', false);",
Expected: []sql.Row{{"bar"}},
},
{
Query: "SELECT current_setting('mynamespace.var');",
Expected: []sql.Row{{"bar"}},
},
{
// Only text values are supported
Query: "SELECT set_config('myvars.boo', 3.14159, false);",
ExpectedErr: true,
},
{
// All settings must be text
Query: "SELECT set_config('myvars.boo', 3.14159::text, false);",
Expected: []sql.Row{{"3.14159"}},
},
{
Query: "SELECT current_setting('myvars.boo');",
Expected: []sql.Row{{"3.14159"}},
},
{
// A NULL value is turned into the empty string
Query: "SELECT set_config('myvars.nullval', NULL, false);",
Expected: []sql.Row{{""}},
},
{
Query: "SELECT current_setting('myvars.nullval');",
Expected: []sql.Row{{""}},
},
},
},
})
}

0 comments on commit c642a48

Please sign in to comment.