Skip to content

Commit

Permalink
sql: add SET CLUSTER SETTING wrapper to alter system.settings
Browse files Browse the repository at this point in the history
Currently a very thin wrapper around just upserting strings, just to get the various boilerplate and plumbing in place.
  • Loading branch information
dt committed Apr 11, 2017
1 parent 4188096 commit 6d08b2c
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 4 deletions.
59 changes: 55 additions & 4 deletions pkg/sql/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
package sql

import (
"errors"
"fmt"
"strings"
"time"

"github.com/pkg/errors"
"golang.org/x/net/context"

"github.com/cockroachdb/apd"
Expand All @@ -40,6 +40,13 @@ func (p *planner) Set(ctx context.Context, n *parser.Set) (planNode, error) {
return nil, errors.New("invalid statement: SET ROW")
}

name := n.Name.String()
setMode := n.SetMode

if setMode == parser.SetModeClusterSetting {
return p.setClusterSetting(ctx, name, n.Values)
}

// By using VarName.String() here any variables that are keywords will
// be double quoted.
typedValues := make([]parser.TypedExpr, len(n.Values))
Expand All @@ -51,14 +58,11 @@ func (p *planner) Set(ctx context.Context, n *parser.Set) (planNode, error) {
typedValues[i] = typedValue
}

name := n.Name.String()

v, ok := varGen[strings.ToLower(name)]
if !ok {
return nil, fmt.Errorf("unknown variable: %q", name)
}

setMode := n.SetMode
if len(n.Values) == 0 {
setMode = parser.SetModeReset
}
Expand All @@ -83,6 +87,53 @@ func (p *planner) Set(ctx context.Context, n *parser.Set) (planNode, error) {
return &emptyNode{}, nil
}

func (p *planner) setClusterSetting(
ctx context.Context, name string, v []parser.Expr,
) (planNode, error) {
if err := p.RequireSuperUser("SET CLUSTER SETTING"); err != nil {
return nil, err
}
name = strings.ToLower(name)
ie := InternalExecutor{LeaseManager: p.LeaseMgr()}

switch len(v) {
case 0:
if _, err := ie.ExecuteStatementInTransaction(
ctx, "update-setting", p.txn, "DELETE FROM system.settings WHERE name = $1", name,
); err != nil {
return nil, err
}
case 1:
// TODO(dt): validate and properly encode str according to type.
encoded, err := p.toSettingString(v[0])
if err != nil {
return nil, err
}
upsertQ := "UPSERT INTO system.settings (name, value, lastUpdated, valueType) VALUES ($1, $2, NOW(), $3)"
if _, err := ie.ExecuteStatementInTransaction(
ctx, "update-setting", p.txn, upsertQ, name, encoded, "s",
); err != nil {
return nil, err
}
default:
return nil, errors.Errorf("SET %q requires a single value", name)
}
return &emptyNode{}, nil
}

func (p *planner) toSettingString(raw parser.Expr) (string, error) {
// TODO(dt): typecheck and handle according to setting's desired type.
typed, err := parser.TypeCheckAndRequire(raw, nil, parser.TypeString, "SET")
if err != nil {
return "", err
}
d, err := typed.Eval(&p.evalCtx)
if err != nil {
return "", err
}
return string(parser.MustBeDString(d)), nil
}

func (p *planner) getStringVal(name string, values []parser.TypedExpr) (string, error) {
if len(values) != 1 {
return "", fmt.Errorf("set %s: requires a single string value", name)
Expand Down
48 changes: 48 additions & 0 deletions pkg/sql/testdata/logic_test/set
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,51 @@ server_version
# Test read-only variables
statement error variable "max_index_keys" cannot be changed
SET max_index_keys = 32

query TT
SELECT name, value FROM system.settings WHERE name = 'foo'
----

user testuser
statement error only root is allowed to SET CLUSTER SETTING
SET CLUSTER SETTING foo = 'bar'

user root

query TT
SELECT name, value FROM system.settings WHERE name = 'foo'
----

statement ok
SET CLUSTER SETTING foo = 'bar'

query TT
SELECT name, value FROM system.settings WHERE name = 'foo'
----
foo bar

statement ok
SET CLUSTER SETTING foo = 'baz'

query TT
SELECT name, value FROM system.settings WHERE name = 'foo'
----
foo baz

user testuser
statement error only root is allowed to SET CLUSTER SETTING
SET CLUSTER SETTING foo = 'bar'

user root

query TT
SELECT name, value FROM system.settings WHERE name = 'foo'
----
foo baz

statement ok
SET CLUSTER SETTING foo TO DEFAULT

query TT
SELECT name, value FROM system.settings WHERE name = 'foo'
----

0 comments on commit 6d08b2c

Please sign in to comment.