github.com/dolthub/go-mysql-server@v0.18.0/sql/sql_mode.go (about) 1 // Copyright 2023 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package sql 16 17 import ( 18 "sort" 19 "strings" 20 21 "github.com/dolthub/vitess/go/vt/sqlparser" 22 ) 23 24 const SqlModeSessionVar = "SQL_MODE" 25 26 // SqlMode encodes the SQL mode string and provides methods for querying the enabled modes. 27 type SqlMode struct { 28 modes map[string]struct{} 29 modeString string 30 } 31 32 // LoadSqlMode loads the SQL mode using the session data contained in |ctx| and returns a SqlMode 33 // instance that can be used to query which modes are enabled. 34 func LoadSqlMode(ctx *Context) *SqlMode { 35 sqlMode, err := ctx.Session.GetSessionVariable(ctx, SqlModeSessionVar) 36 if err != nil { 37 // if system variables are not initialized, assume default sqlMode 38 return &SqlMode{modes: nil, modeString: ""} 39 } 40 41 sqlModeString, ok := sqlMode.(string) 42 if !ok { 43 ctx.GetLogger().Warnf("sqlMode system variable value is invalid: '%v'", sqlMode) 44 return &SqlMode{modes: nil, modeString: ""} 45 } 46 47 return NewSqlModeFromString(sqlModeString) 48 } 49 50 // NewSqlModeFromString returns a new SqlMode instance, constructed from the specified |sqlModeString| that 51 // has a comma delimited list of SQL modes (e.g. "ONLY_FULLY_GROUP_BY,ANSI_QUOTES"). 52 func NewSqlModeFromString(sqlModeString string) *SqlMode { 53 sqlModeString = strings.ToLower(sqlModeString) 54 elements := strings.Split(sqlModeString, ",") 55 sort.Strings(elements) 56 modes := map[string]struct{}{} 57 for _, element := range elements { 58 modes[element] = struct{}{} 59 } 60 61 return &SqlMode{ 62 modes: modes, 63 modeString: strings.ToUpper(strings.Join(elements, ",")), 64 } 65 } 66 67 // AnsiQuotes returns true if the ANSI_QUOTES SQL mode is enabled. Note that the ANSI mode is a compound mode that 68 // includes ANSI_QUOTES and other options, so if ANSI or ANSI_QUOTES is enabled, this function will return true. 69 func (s *SqlMode) AnsiQuotes() bool { 70 return s.ModeEnabled("ansi_quotes") || s.ModeEnabled("ansi") 71 } 72 73 // ModeEnabled returns true if |mode| was explicitly specified in the SQL_MODE string that was used to 74 // create this SqlMode instance. Note this function does not support expanding compound modes into the 75 // individual modes they contain (e.g. if "ANSI" is the SQL_MODE string, then this function will not 76 // report that "ANSI_QUOTES" is enabled). To deal with compound modes, use the mode specific functions, 77 // such as SqlMode::AnsiQuotes(). 78 func (s *SqlMode) ModeEnabled(mode string) bool { 79 _, ok := s.modes[strings.ToLower(mode)] 80 return ok 81 } 82 83 // ParserOptions returns a ParserOptions struct, with options set based on what SQL modes are enabled. 84 func (s *SqlMode) ParserOptions() sqlparser.ParserOptions { 85 return sqlparser.ParserOptions{ 86 AnsiQuotes: s.AnsiQuotes(), 87 } 88 } 89 90 // String returns the SQL_MODE string representing this SqlMode instance. 91 func (s *SqlMode) String() string { 92 return s.modeString 93 }