Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ require (
github.com/PuerkitoBio/goquery v1.8.1
github.com/cockroachdb/apd/v3 v3.2.3
github.com/cockroachdb/errors v1.7.5
github.com/dolthub/dolt/go v0.40.5-0.20260828173935-dc4e79209ce0
github.com/dolthub/dolt/go v0.40.5-0.20260901102237-645f6accd917
github.com/dolthub/eventsapi_schema v0.0.0-20260715220557-d9b4a1c6b4d4
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2
github.com/dolthub/go-mysql-server v0.20.1-0.20260831214236-aa1f8e45655b
github.com/dolthub/go-mysql-server v0.20.1-0.20260901192735-5d6be3976cd5
github.com/dolthub/pg_query_go/v6 v6.0.0-20251215122834-fb20be4254d1
github.com/dolthub/sqllogictest/go v0.0.0-20260624223518-788480b24166
github.com/dolthub/vitess v0.0.0-20260828193927-f9eb707fd659
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ github.com/dolthub/aws-sdk-go-ini-parser v0.0.0-20250305001723-2821c37f6c12 h1:I
github.com/dolthub/aws-sdk-go-ini-parser v0.0.0-20250305001723-2821c37f6c12/go.mod h1:rN7X8BHwkjPcfMQQ2QTAq/xM3leUSGLfb+1Js7Y6TVo=
github.com/dolthub/dolt-mcp v0.3.4 h1:AyG5cw+fNWXDHXujtQnqUPZrpWtPg6FN6yYtjv1pP44=
github.com/dolthub/dolt-mcp v0.3.4/go.mod h1:bCZ7KHvDYs+M0e+ySgmGiNvLhcwsN7bbf5YCyillLrk=
github.com/dolthub/dolt/go v0.40.5-0.20260828173935-dc4e79209ce0 h1:VrCgqBaqm3WT7olZRdYGScPGsZdzd4S67M/hD/R00f8=
github.com/dolthub/dolt/go v0.40.5-0.20260828173935-dc4e79209ce0/go.mod h1:vGmWnRXHjHe+BYLeaC2WCte5lpzEXdcKFt4mFiKD2yc=
github.com/dolthub/dolt/go v0.40.5-0.20260901102237-645f6accd917 h1:lx7XhihYV9y0H5N6US13VlN5JGjT7FB9eksXXA7sMCU=
github.com/dolthub/dolt/go v0.40.5-0.20260901102237-645f6accd917/go.mod h1:D1MXT5V70cZfYR8eKpijs/1vsOFgSGdmr9hk83gi73Y=
github.com/dolthub/eventsapi_schema v0.0.0-20260715220557-d9b4a1c6b4d4 h1:0mg9QEFdkkBwJMxvz1tCjHYmfG2iIC6aShj1InDq9/M=
github.com/dolthub/eventsapi_schema v0.0.0-20260715220557-d9b4a1c6b4d4/go.mod h1:SSLraQS/jGLYFgff3vuZ+JbVUct6vyEeMzjLBqWqoyM=
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 h1:u3PMzfF8RkKd3lB9pZ2bfn0qEG+1Gms9599cr0REMww=
Expand All @@ -256,8 +256,8 @@ github.com/dolthub/fslock v0.0.5 h1:QoXhBhgY1oumHE26qyE7tgmXUT8qjJwxsIzo54O/B/k=
github.com/dolthub/fslock v0.0.5/go.mod h1:sdofYYqE0D79zNZyB4/kmlnsQOVap1C2yByjGKSirEM=
github.com/dolthub/go-icu-regex v0.0.0-20260610153742-72563bc7ca83 h1:FEMjCGEroDnY/BXyAffVZxUpXhP2GpoUJyyq5KaLn8c=
github.com/dolthub/go-icu-regex v0.0.0-20260610153742-72563bc7ca83/go.mod h1:F3cnm+vMRK1HaU6+rNqQrOCyR03HHhR1GWG2gnPOqaE=
github.com/dolthub/go-mysql-server v0.20.1-0.20260831214236-aa1f8e45655b h1:O9lohpiOrRXsdogCmnxLT2P7ox4u+Ilat6pl6b8f2+w=
github.com/dolthub/go-mysql-server v0.20.1-0.20260831214236-aa1f8e45655b/go.mod h1:CtDdfkAma4klv+UQbEmV4AkVvkSyXf/V3iRpIDu6c2I=
github.com/dolthub/go-mysql-server v0.20.1-0.20260901192735-5d6be3976cd5 h1:OjIEbos9AZW660TkKANOzDjMnOZgFchyJkhcXXulCcE=
github.com/dolthub/go-mysql-server v0.20.1-0.20260901192735-5d6be3976cd5/go.mod h1:CtDdfkAma4klv+UQbEmV4AkVvkSyXf/V3iRpIDu6c2I=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 h1:OAsXLAPL4du6tfbBgK0xXHZkOlos63RdKYS3Sgw/dfI=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63/go.mod h1:lV7lUeuDhH5thVGDCKXbatwKy2KW80L4rMT46n+Y2/Q=
github.com/dolthub/ishell v0.0.0-20260414231531-5f031e3e9037 h1:oIW9HwuWrhxv+4HZxA+QQSKHLqWFyXZ2FmNjUYwkdiM=
Expand Down
13 changes: 9 additions & 4 deletions server/ast/set_var.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/cockroachdb/errors"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/planbuilder"
vitess "github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
Expand All @@ -42,9 +43,9 @@ func nodeSetVar(ctx *Context, node *tree.SetVar) (vitess.Statement, error) {
if node.Namespace == "" && !config.IsValidPostgresConfigParameter(node.Name) && !config.IsValidDoltConfigParameter(node.Name) {
return nil, errors.Errorf(`ERROR: unrecognized configuration parameter "%s"`, node.Name)
}
if node.IsLocal {
// TODO: takes effect for only the current transaction rather than the current session.
return nil, errors.Errorf("SET LOCAL is not yet supported")
if node.IsLocal && node.Namespace != "" {
// TODO: support transaction-local values for custom (namespaced) parameters, which are session user vars
return nil, errors.Errorf("SET LOCAL is not yet supported for customized options")
}
var expr vitess.Expr
var err error
Expand All @@ -71,7 +72,11 @@ func nodeSetVar(ctx *Context, node *tree.SetVar) (vitess.Statement, error) {
// Dolt's cluster replication variables) are routed to their declared scope directly, symmetric with
// current_setting() reading them from the global scope.
scope := vitess.SetScope_Session
if svScope, ok := config.GlobalOnlySystemVariableScope(node.Name); ok {
if node.IsLocal {
// SET LOCAL only applies for the duration of the current transaction; the connection handler restores
// the session values when the transaction ends. Global-only variables are rejected by the engine.
scope = planbuilder.SetScope_TransactionLocal
} else if svScope, ok := config.GlobalOnlySystemVariableScope(node.Name); ok {
switch svScope {
case sql.SystemVariableScope_Persist:
scope = vitess.SetScope_Persist
Expand Down
18 changes: 14 additions & 4 deletions server/config/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ func (p *Parameter) GetSessionScope() sql.SystemVariableScope {
return GetPgsqlScope(PsqlScopeSession)
}

// GetLocalScope implements sql.SystemVariable. Any parameter that can be set at session scope can also be set with
// transaction-local scope (SET LOCAL).
func (p *Parameter) GetLocalScope() sql.SystemVariableScope {
return GetPgsqlScope(PsqlScopeLocal)
}

// SetDefault implements sql.SystemVariable.
func (p *Parameter) SetDefault(a any) {
if validatedVal, ok := p.ValidateFunc(p.Default, a); ok {
Expand Down Expand Up @@ -223,8 +229,8 @@ func (p *PgsqlScope) SetValue(ctx *sql.Context, name string, val any) error {
err := ctx.SetSessionVariable(ctx, name, val)
return err
case PsqlScopeLocal:
// TODO: support LOCAL scope
return cerrors.Errorf("unsupported scope `%v` on configuration parameter `%s`", p.Type, name)
_ = core.SetDateStyleOutputFormat(ctx, "")
return ctx.Session.SetTransactionLocalVariable(ctx, name, val)
default:
return cerrors.Errorf("unable to set `%s` due to unknown scope `%v`", name, p.Type)
}
Expand All @@ -240,8 +246,12 @@ func (p *PgsqlScope) GetValue(ctx *sql.Context, name string, _ sql.CollationID)
}
return val, nil
case PsqlScopeLocal:
// TODO: support LOCAL scope
return nil, cerrors.Errorf("unsupported scope `%v` on configuration parameter `%s`", p.Type, name)
// The session value already reflects any transaction-local override
val, err := ctx.GetSessionVariable(ctx, name)
if err != nil {
return nil, err
}
return val, nil
default:
return nil, cerrors.Errorf("unknown scope `%v` on configuration parameter `%s`", p.Type, name)
}
Expand Down
23 changes: 23 additions & 0 deletions server/connection_handler.go
Comment thread
zachmu marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"github.com/mitchellh/go-ps"
"github.com/sirupsen/logrus"

"github.com/dolthub/doltgresql/core"
"github.com/dolthub/doltgresql/core/dataloader"
"github.com/dolthub/doltgresql/postgres/parser/parser"
psql "github.com/dolthub/doltgresql/postgres/parser/parser/sql"
Expand Down Expand Up @@ -604,6 +605,7 @@ func (h *ConnectionHandler) handleQueryOutsideEngine(query ConvertedQuery) (hand
// A COMMIT issued inside a failed transaction block ends the block by rolling it back, and reports
// ROLLBACK to the client to indicate that the transaction's effects were discarded.
h.transactionState = idleTransactionState
h.clearTransactionLocalVars()
if err := h.runEngineTransactionControl("ROLLBACK"); err != nil {
return true, true, err
}
Expand All @@ -612,9 +614,11 @@ func (h *ConnectionHandler) handleQueryOutsideEngine(query ConvertedQuery) (hand
// A COMMIT closes the current transaction block, whether explicit or implicit. Any statements that
// follow it in the same Query message (or extended-query batch) run in a new implicit transaction block.
h.transactionState = idleTransactionState
h.clearTransactionLocalVars()
case *sqlparser.Rollback:
// Like COMMIT, a ROLLBACK closes the current transaction block, whether explicit, implicit, or failed.
h.transactionState = idleTransactionState
h.clearTransactionLocalVars()
case *sqlparser.Savepoint:
if !h.transactionState.inExplicitTransactionBlock() {
return true, true, noActiveTransactionError("SAVEPOINT")
Expand Down Expand Up @@ -1326,6 +1330,7 @@ func (h *ConnectionHandler) commitImplicitTransaction() error {
return nil
}
h.transactionState = idleTransactionState
h.clearTransactionLocalVars()
if h.restoredAutoCommitWithoutTransaction() {
return nil
}
Expand All @@ -1344,6 +1349,7 @@ func (h *ConnectionHandler) rollbackImplicitTransaction() {
return
}
h.transactionState = idleTransactionState
h.clearTransactionLocalVars()
if h.restoredAutoCommitWithoutTransaction() {
return
}
Expand All @@ -1352,6 +1358,23 @@ func (h *ConnectionHandler) rollbackImplicitTransaction() {
}
}

// clearTransactionLocalVars removes any system variable values that were set with transaction-local scope
// (SET LOCAL, or set_config with is_local), restoring the variables' session values. Called whenever the current
// transaction block ends, whether by COMMIT or ROLLBACK: Postgres reverts SET LOCAL values in both cases.
func (h *ConnectionHandler) clearTransactionLocalVars() {
ctx, err := h.doltgresHandler.NewContext(context.Background(), h.mysqlConn, "")
if err != nil {
logrus.Warnf("error creating context to clear transaction-local variables: %s", err)
return
}
if err = ctx.Session.ClearTransactionLocalVariables(ctx); err != nil {
logrus.Warnf("error clearing transaction-local variables: %s", err)
return
}
// Reset any cached variables in ContextValues, in case a cached parameter (e.g. datestyle) was overridden
_ = core.SetDateStyleOutputFormat(ctx, "")
}

// restoredAutoCommitWithoutTransaction returns whether the session no longer has an engine transaction in
// progress, restoring the session's autocommit behavior if so. Some statements end the engine transaction
// themselves as a side effect of executing (e.g. dolt_assume_cluster_role, which also poisons the session
Expand Down
13 changes: 7 additions & 6 deletions server/functions/set_config.go
Comment thread
zachmu marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ var set_config_text_text_boolean = framework.Function3{
newValue = ""
}

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

settingNameStr, err := framework.UnwrapString(ctx, settingName)
if err != nil {
return nil, err
Expand All @@ -61,7 +56,13 @@ var set_config_text_text_boolean = framework.Function3{
// 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(settingNameStr, ".")
if isUserConfig {
if isLocal == true {
// A transaction-local value overrides the session value until the transaction ends, when the
// connection handler clears it
if err := ctx.Session.SetTransactionLocalVariable(ctx, settingName.(string), newValue.(string)); err != nil {
return nil, err
}
} else if isUserConfig {
if err := ctx.SetUserVariable(ctx, settingNameStr, newValueStr, pgtypes.Text); err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions testing/generation/command_docs/output/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ func TestSet(t *testing.T) {
Parses("SET LOCAL configuration_parameter = DEFAULT"),
Converts("SET TIME ZONE 1"),
Converts("SET SESSION TIME ZONE 1"),
Parses("SET LOCAL TIME ZONE 1"),
Converts("SET LOCAL TIME ZONE 1"),
Converts("SET TIME ZONE ' 1 '"),
Converts("SET SESSION TIME ZONE ' 1 '"),
Parses("SET LOCAL TIME ZONE ' 1 '"),
Converts("SET LOCAL TIME ZONE ' 1 '"),
Converts("SET TIME ZONE LOCAL"),
Converts("SET SESSION TIME ZONE LOCAL"),
Parses("SET LOCAL TIME ZONE LOCAL"),
Converts("SET LOCAL TIME ZONE LOCAL"),
Converts("SET TIME ZONE DEFAULT"),
Converts("SET SESSION TIME ZONE DEFAULT"),
Parses("SET LOCAL TIME ZONE DEFAULT"),
Converts("SET LOCAL TIME ZONE DEFAULT"),
}
RunTests(t, tests)
}
Loading
Loading