Skip to content

Commit 725f43c

Browse files
authored
allow setting session variable default value (#3203)
1 parent 60a7f34 commit 725f43c

File tree

4 files changed

+57
-5
lines changed

4 files changed

+57
-5
lines changed

server/context.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,15 @@ func (s *SessionManager) getOrCreateSession(ctx context.Context, conn *mysql.Con
235235
return sess, nil
236236
}
237237

238+
// InitSessionDefaultVariable sets a default value to a parameter of a session at start.
239+
func (s *SessionManager) InitSessionDefaultVariable(ctx context.Context, conn *mysql.Conn, name, value string) error {
240+
sess, err := s.getOrCreateSession(ctx, conn)
241+
if err != nil {
242+
return err
243+
}
244+
return sess.InitSessionVariableDefault(s.ctxFactory(ctx, sql.WithSession(sess)), name, value)
245+
}
246+
238247
// NewContextWithQuery creates a new context for the session at the given conn.
239248
func (s *SessionManager) NewContextWithQuery(ctx context.Context, conn *mysql.Conn, query string) (*sql.Context, error) {
240249
sess, err := s.getOrCreateSession(ctx, conn)

sql/base_session.go

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,37 @@ func (s *BaseSession) InitSessionVariable(ctx *Context, sysVarName string, value
159159
return s.setSessVar(ctx, sysVar, value, true)
160160
}
161161

162-
func (s *BaseSession) setSessVar(ctx *Context, sysVar SystemVariable, value interface{}, init bool) error {
162+
// InitSessionVariableDefault implements the Session interface and is used to initialize variables (Including read-only variables)
163+
func (s *BaseSession) InitSessionVariableDefault(ctx *Context, sysVarName string, value interface{}) error {
164+
sysVar, _, ok := SystemVariables.GetGlobal(sysVarName)
165+
if !ok {
166+
return ErrUnknownSystemVariable.New(sysVarName)
167+
}
168+
169+
sysVar.SetDefault(value)
170+
svv, err := sysVar.InitValue(ctx, value, false)
171+
if err != nil {
172+
return err
173+
}
174+
175+
sysVarName = strings.ToLower(sysVarName)
176+
s.systemVars[sysVarName] = svv
177+
if sysVarName == characterSetResultsSysVarName {
178+
s.charset = CharacterSet_Unspecified
179+
}
180+
return nil
181+
}
182+
183+
func (s *BaseSession) setSessVar(ctx *Context, sysVar SystemVariable, val interface{}, init bool) error {
163184
var svv SystemVarValue
164185
var err error
165186
if init {
166-
svv, err = sysVar.InitValue(ctx, value, false)
187+
svv, err = sysVar.InitValue(ctx, val, false)
167188
if err != nil {
168189
return err
169190
}
170191
} else {
171-
svv, err = sysVar.SetValue(ctx, value, false)
192+
svv, err = sysVar.SetValue(ctx, val, false)
172193
if err != nil {
173194
return err
174195
}
@@ -202,6 +223,22 @@ func (s *BaseSession) GetSessionVariable(ctx *Context, sysVarName string) (inter
202223
return sysVar.Val, nil
203224
}
204225

226+
// GetSessionVariableDefault implements the Session interface.
227+
func (s *BaseSession) GetSessionVariableDefault(ctx *Context, sysVarName string) (interface{}, error) {
228+
sysVarName = strings.ToLower(sysVarName)
229+
sysVar, ok := s.systemVars[sysVarName]
230+
if !ok {
231+
return nil, ErrUnknownSystemVariable.New(sysVarName)
232+
}
233+
// TODO: this is duplicated from within variables.globalSystemVariables, suggesting the need for an interface
234+
if sysType, ok := sysVar.Var.GetType().(SetType); ok {
235+
if sv, ok := sysVar.Var.GetDefault().(uint64); ok {
236+
return sysType.BitsToString(sv)
237+
}
238+
}
239+
return sysVar.Var.GetDefault(), nil
240+
}
241+
205242
// GetUserVariable implements the Session interface.
206243
func (s *BaseSession) GetUserVariable(ctx *Context, varName string) (Type, interface{}, error) {
207244
return s.userVars.GetUserVariable(ctx, varName)

sql/planbuilder/set.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,9 @@ func (b *Builder) simplifySetExpr(name *ast.ColName, varScope ast.SetScope, val
341341

342342
switch varScope {
343343
case ast.SetScope_None, ast.SetScope_Session, ast.SetScope_Global:
344-
_, value, ok := sql.SystemVariables.GetGlobal(varName)
345-
if ok {
344+
// cannot use sql.SystemVariables.GetGlobal as the default value can be defined at session start runtime.
345+
value, err := b.ctx.GetSessionVariableDefault(b.ctx, varName)
346+
if err == nil {
346347
return expression.NewLiteral(value, types.ApproximateTypeFromValue(value)), true
347348
}
348349
err = sql.ErrUnknownSystemVariable.New(varName)

sql/session.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ type Session interface {
6666
Client() Client
6767
// SetClient returns a new session with the given client.
6868
SetClient(Client)
69+
// InitSessionVariableDefault sets this session's default value of the system variable with the given name.
70+
InitSessionVariableDefault(ctx *Context, sysVarName string, value interface{}) error
6971
// SetSessionVariable sets the given system variable to the value given for this session.
7072
SetSessionVariable(ctx *Context, sysVarName string, value interface{}) error
7173
// InitSessionVariable sets the given system variable to the value given for this session and will allow for
@@ -76,6 +78,9 @@ type Session interface {
7678
// GetSessionVariable returns this session's value of the system variable with the given name.
7779
// To access global scope, use sql.SystemVariables.GetGlobal instead.
7880
GetSessionVariable(ctx *Context, sysVarName string) (interface{}, error)
81+
// GetSessionVariableDefault returns this session's default value of the system variable with the given name.
82+
// To access global scope, use sql.SystemVariables.GetGlobal instead.
83+
GetSessionVariableDefault(ctx *Context, sysVarName string) (interface{}, error)
7984
// GetUserVariable returns this session's value of the user variable with the given name, along with its most
8085
// appropriate type.
8186
GetUserVariable(ctx *Context, varName string) (Type, interface{}, error)

0 commit comments

Comments
 (0)