github.com/pingcap/tidb/parser@v0.0.0-20231013125129-93a834a6bf8d/mysql/const.go (about)

     1  // Copyright 2017 PingCAP, 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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package mysql
    15  
    16  import (
    17  	"fmt"
    18  	"strings"
    19  
    20  	"github.com/pingcap/errors"
    21  	"github.com/pingcap/tidb/parser/format"
    22  )
    23  
    24  func newInvalidModeErr(s string) error {
    25  	return NewErr(ErrWrongValueForVar, "sql_mode", s)
    26  }
    27  
    28  // Version information.
    29  var (
    30  	// TiDBReleaseVersion is initialized by (git describe --tags) in Makefile.
    31  	TiDBReleaseVersion = "None"
    32  
    33  	// ServerVersion is the version information of this tidb-server in MySQL's format.
    34  	ServerVersion = fmt.Sprintf("8.0.11-TiDB-%s", TiDBReleaseVersion)
    35  )
    36  
    37  // Header information.
    38  const (
    39  	OKHeader          byte = 0x00
    40  	ErrHeader         byte = 0xff
    41  	EOFHeader         byte = 0xfe
    42  	LocalInFileHeader byte = 0xfb
    43  )
    44  
    45  // AuthSwitchRequest is a protocol feature.
    46  const AuthSwitchRequest byte = 0xfe
    47  
    48  // Server information.
    49  const (
    50  	ServerStatusInTrans            uint16 = 0x0001
    51  	ServerStatusAutocommit         uint16 = 0x0002
    52  	ServerMoreResultsExists        uint16 = 0x0008
    53  	ServerStatusNoGoodIndexUsed    uint16 = 0x0010
    54  	ServerStatusNoIndexUsed        uint16 = 0x0020
    55  	ServerStatusCursorExists       uint16 = 0x0040
    56  	ServerStatusLastRowSend        uint16 = 0x0080
    57  	ServerStatusDBDropped          uint16 = 0x0100
    58  	ServerStatusNoBackslashEscaped uint16 = 0x0200
    59  	ServerStatusMetadataChanged    uint16 = 0x0400
    60  	ServerStatusWasSlow            uint16 = 0x0800
    61  	ServerPSOutParams              uint16 = 0x1000
    62  )
    63  
    64  // HasCursorExistsFlag return true if cursor exists indicated by server status.
    65  func HasCursorExistsFlag(serverStatus uint16) bool {
    66  	return serverStatus&ServerStatusCursorExists > 0
    67  }
    68  
    69  // Identifier length limitations.
    70  // See https://dev.mysql.com/doc/refman/5.7/en/identifiers.html
    71  const (
    72  	// MaxPayloadLen is the max packet payload length.
    73  	MaxPayloadLen = 1<<24 - 1
    74  	// MaxTableNameLength is max length of table name identifier.
    75  	MaxTableNameLength = 64
    76  	// MaxDatabaseNameLength is max length of database name identifier.
    77  	MaxDatabaseNameLength = 64
    78  	// MaxColumnNameLength is max length of column name identifier.
    79  	MaxColumnNameLength = 64
    80  	// MaxKeyParts is max length of key parts.
    81  	MaxKeyParts = 16
    82  	// MaxIndexIdentifierLen is max length of index identifier.
    83  	MaxIndexIdentifierLen = 64
    84  	// MaxForeignKeyIdentifierLen is max length of foreign key identifier.
    85  	MaxForeignKeyIdentifierLen = 64
    86  	// MaxConstraintIdentifierLen is max length of constrain identifier.
    87  	MaxConstraintIdentifierLen = 64
    88  	// MaxViewIdentifierLen is max length of view identifier.
    89  	MaxViewIdentifierLen = 64
    90  	// MaxAliasIdentifierLen is max length of alias identifier.
    91  	MaxAliasIdentifierLen = 256
    92  	// MaxUserDefinedVariableLen is max length of user-defined variable.
    93  	MaxUserDefinedVariableLen = 64
    94  )
    95  
    96  // ErrTextLength error text length limit.
    97  const ErrTextLength = 80
    98  
    99  // Command information.
   100  const (
   101  	ComSleep byte = iota
   102  	ComQuit
   103  	ComInitDB
   104  	ComQuery
   105  	ComFieldList
   106  	ComCreateDB
   107  	ComDropDB
   108  	ComRefresh
   109  	ComShutdown
   110  	ComStatistics
   111  	ComProcessInfo
   112  	ComConnect
   113  	ComProcessKill
   114  	ComDebug
   115  	ComPing
   116  	ComTime
   117  	ComDelayedInsert
   118  	ComChangeUser
   119  	ComBinlogDump
   120  	ComTableDump
   121  	ComConnectOut
   122  	ComRegisterSlave
   123  	ComStmtPrepare
   124  	ComStmtExecute
   125  	ComStmtSendLongData
   126  	ComStmtClose
   127  	ComStmtReset
   128  	ComSetOption
   129  	ComStmtFetch
   130  	ComDaemon
   131  	ComBinlogDumpGtid
   132  	ComResetConnection
   133  	ComEnd
   134  )
   135  
   136  // Client information. https://dev.mysql.com/doc/dev/mysql-server/latest/group__group__cs__capabilities__flags.html
   137  const (
   138  	ClientLongPassword               uint32 = 1 << iota // CLIENT_LONG_PASSWORD
   139  	ClientFoundRows                                     // CLIENT_FOUND_ROWS
   140  	ClientLongFlag                                      // CLIENT_LONG_FLAG
   141  	ClientConnectWithDB                                 // CLIENT_CONNECT_WITH_DB
   142  	ClientNoSchema                                      // CLIENT_NO_SCHEMA
   143  	ClientCompress                                      // CLIENT_COMPRESS
   144  	ClientODBC                                          // CLIENT_ODBC
   145  	ClientLocalFiles                                    // CLIENT_LOCAL_FILES
   146  	ClientIgnoreSpace                                   // CLIENT_IGNORE_SPACE
   147  	ClientProtocol41                                    // CLIENT_PROTOCOL_41
   148  	ClientInteractive                                   // CLIENT_INTERACTIVE
   149  	ClientSSL                                           // CLIENT_SSL
   150  	ClientIgnoreSigpipe                                 // CLIENT_IGNORE_SIGPIPE
   151  	ClientTransactions                                  // CLIENT_TRANSACTIONS
   152  	ClientReserved                                      // Deprecated: CLIENT_RESERVED
   153  	ClientSecureConnection                              // Deprecated: CLIENT_SECURE_CONNECTION
   154  	ClientMultiStatements                               // CLIENT_MULTI_STATEMENTS
   155  	ClientMultiResults                                  // CLIENT_MULTI_RESULTS
   156  	ClientPSMultiResults                                // CLIENT_PS_MULTI_RESULTS
   157  	ClientPluginAuth                                    // CLIENT_PLUGIN_AUTH
   158  	ClientConnectAtts                                   // CLIENT_CONNECT_ATTRS
   159  	ClientPluginAuthLenencClientData                    // CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA
   160  	ClientHandleExpiredPasswords                        // CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS, Not supported: https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_expired_passwords.html
   161  	ClientSessionTrack                                  // CLIENT_SESSION_TRACK, Not supported: https://github.com/pingcap/tidb/issues/35309
   162  	ClientDeprecateEOF                                  // CLIENT_DEPRECATE_EOF
   163  	ClientOptionalResultsetMetadata                     // CLIENT_OPTIONAL_RESULTSET_METADATA, Not supported: https://dev.mysql.com/doc/c-api/8.0/en/c-api-optional-metadata.html
   164  	ClientZstdCompressionAlgorithm                      // CLIENT_ZSTD_COMPRESSION_ALGORITHM
   165  	// 1 << 27 == CLIENT_QUERY_ATTRIBUTES
   166  	// 1 << 28 == MULTI_FACTOR_AUTHENTICATION
   167  	// 1 << 29 == CLIENT_CAPABILITY_EXTENSION
   168  	// 1 << 30 == CLIENT_SSL_VERIFY_SERVER_CERT
   169  	// 1 << 31 == CLIENT_REMEMBER_OPTIONS
   170  )
   171  
   172  // Cache type information.
   173  const (
   174  	TypeNoCache byte = 0xff
   175  )
   176  
   177  // Auth name information.
   178  const (
   179  	AuthNativePassword      = "mysql_native_password" // #nosec G101
   180  	AuthCachingSha2Password = "caching_sha2_password" // #nosec G101
   181  	AuthTiDBSM3Password     = "tidb_sm3_password"     // #nosec G101
   182  	AuthMySQLClearPassword  = "mysql_clear_password"
   183  	AuthSocket              = "auth_socket"
   184  	AuthTiDBSessionToken    = "tidb_session_token"
   185  	AuthTiDBAuthToken       = "tidb_auth_token"
   186  	AuthLDAPSimple          = "authentication_ldap_simple"
   187  	AuthLDAPSASL            = "authentication_ldap_sasl"
   188  )
   189  
   190  // MySQL database and tables.
   191  const (
   192  	// SystemDB is the name of system database.
   193  	SystemDB = "mysql"
   194  	// GlobalPrivTable is the table in system db contains global scope privilege info.
   195  	GlobalPrivTable = "global_priv"
   196  	// UserTable is the table in system db contains user info.
   197  	UserTable = "User"
   198  	// DBTable is the table in system db contains db scope privilege info.
   199  	DBTable = "DB"
   200  	// TablePrivTable is the table in system db contains table scope privilege info.
   201  	TablePrivTable = "Tables_priv"
   202  	// ColumnPrivTable is the table in system db contains column scope privilege info.
   203  	ColumnPrivTable = "Columns_priv"
   204  	// GlobalVariablesTable is the table contains global system variables.
   205  	GlobalVariablesTable = "GLOBAL_VARIABLES"
   206  	// GlobalStatusTable is the table contains global status variables.
   207  	GlobalStatusTable = "GLOBAL_STATUS"
   208  	// TiDBTable is the table contains tidb info.
   209  	TiDBTable = "tidb"
   210  	// RoleEdgeTable is the table contains role relation info
   211  	RoleEdgeTable = "role_edges"
   212  	// DefaultRoleTable is the table contain default active role info
   213  	DefaultRoleTable = "default_roles"
   214  	// PasswordHistoryTable is the table in system db contains password history.
   215  	PasswordHistoryTable = "password_history"
   216  )
   217  
   218  // MySQL type maximum length.
   219  const (
   220  	// NotFixedDec For arguments that have no fixed number of decimals, the decimals value is set to 31,
   221  	// which is 1 more than the maximum number of decimals permitted for the DECIMAL, FLOAT, and DOUBLE data types.
   222  	NotFixedDec = 31
   223  
   224  	MaxIntWidth              = 20
   225  	MaxRealWidth             = 23
   226  	MaxFloatingTypeScale     = 30
   227  	MaxFloatingTypeWidth     = 255
   228  	MaxDecimalScale          = 30
   229  	MaxDecimalWidth          = 65
   230  	MaxDateWidth             = 10 // YYYY-MM-DD.
   231  	MaxDatetimeWidthNoFsp    = 19 // YYYY-MM-DD HH:MM:SS
   232  	MaxDatetimeWidthWithFsp  = 26 // YYYY-MM-DD HH:MM:SS[.fraction]
   233  	MaxDatetimeFullWidth     = 29 // YYYY-MM-DD HH:MM:SS.###### AM
   234  	MaxDurationWidthNoFsp    = 10 // HH:MM:SS
   235  	MaxDurationWidthWithFsp  = 17 // HH:MM:SS[.fraction] -838:59:59.000000 to 838:59:59.000000
   236  	MaxBlobWidth             = 16777216
   237  	MaxLongBlobWidth         = 4294967295
   238  	MaxBitDisplayWidth       = 64
   239  	MaxFloatPrecisionLength  = 24
   240  	MaxDoublePrecisionLength = 53
   241  )
   242  
   243  // MySQL max type field length.
   244  const (
   245  	MaxFieldCharLength    = 255
   246  	MaxFieldVarCharLength = 65535
   247  )
   248  
   249  // MaxTypeSetMembers is the number of set members.
   250  const MaxTypeSetMembers = 64
   251  
   252  // PWDHashLen is the length of mysql_native_password's hash.
   253  const PWDHashLen = 40 // excluding the '*'
   254  
   255  // SHAPWDHashLen is the length of sha256_password's hash.
   256  const SHAPWDHashLen = 70
   257  
   258  // SM3PWDHashLen is the length of tidb_sm3_password's hash.
   259  const SM3PWDHashLen = 70
   260  
   261  // Command2Str is the command information to command name.
   262  var Command2Str = map[byte]string{
   263  	ComSleep:            "Sleep",
   264  	ComQuit:             "Quit",
   265  	ComInitDB:           "Init DB",
   266  	ComQuery:            "Query",
   267  	ComFieldList:        "Field List",
   268  	ComCreateDB:         "Create DB",
   269  	ComDropDB:           "Drop DB",
   270  	ComRefresh:          "Refresh",
   271  	ComShutdown:         "Shutdown",
   272  	ComStatistics:       "Statistics",
   273  	ComProcessInfo:      "Processlist",
   274  	ComConnect:          "Connect",
   275  	ComProcessKill:      "Kill",
   276  	ComDebug:            "Debug",
   277  	ComPing:             "Ping",
   278  	ComTime:             "Time",
   279  	ComDelayedInsert:    "Delayed Insert",
   280  	ComChangeUser:       "Change User",
   281  	ComBinlogDump:       "Binlog Dump",
   282  	ComTableDump:        "Table Dump",
   283  	ComConnectOut:       "Connect out",
   284  	ComRegisterSlave:    "Register Slave",
   285  	ComStmtPrepare:      "Prepare",
   286  	ComStmtExecute:      "Execute",
   287  	ComStmtSendLongData: "Long Data",
   288  	ComStmtClose:        "Close stmt",
   289  	ComStmtReset:        "Reset stmt",
   290  	ComSetOption:        "Set option",
   291  	ComStmtFetch:        "Fetch",
   292  	ComDaemon:           "Daemon",
   293  	ComBinlogDumpGtid:   "Binlog Dump",
   294  	ComResetConnection:  "Reset connect",
   295  }
   296  
   297  // DefaultSQLMode for GLOBAL_VARIABLES
   298  const DefaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
   299  
   300  // DefaultLengthOfMysqlTypes is the map for default physical length of MySQL data types.
   301  // See http://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html
   302  var DefaultLengthOfMysqlTypes = map[byte]int{
   303  	TypeYear:      1,
   304  	TypeDate:      3,
   305  	TypeDuration:  3,
   306  	TypeDatetime:  8,
   307  	TypeTimestamp: 4,
   308  
   309  	TypeTiny:     1,
   310  	TypeShort:    2,
   311  	TypeInt24:    3,
   312  	TypeLong:     4,
   313  	TypeLonglong: 8,
   314  	TypeFloat:    4,
   315  	TypeDouble:   8,
   316  
   317  	TypeEnum:   2,
   318  	TypeString: 1,
   319  	TypeSet:    8,
   320  }
   321  
   322  // DefaultLengthOfTimeFraction is the map for default physical length of time fractions.
   323  var DefaultLengthOfTimeFraction = map[int]int{
   324  	0: 0,
   325  
   326  	1: 1,
   327  	2: 1,
   328  
   329  	3: 2,
   330  	4: 2,
   331  
   332  	5: 3,
   333  	6: 3,
   334  }
   335  
   336  // SQLMode is the type for MySQL sql_mode.
   337  // See https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html
   338  type SQLMode int
   339  
   340  // HasNoZeroDateMode detects if 'NO_ZERO_DATE' mode is set in SQLMode
   341  func (m SQLMode) HasNoZeroDateMode() bool {
   342  	return m&ModeNoZeroDate == ModeNoZeroDate
   343  }
   344  
   345  // HasNoZeroInDateMode detects if 'NO_ZERO_IN_DATE' mode is set in SQLMode
   346  func (m SQLMode) HasNoZeroInDateMode() bool {
   347  	return m&ModeNoZeroInDate == ModeNoZeroInDate
   348  }
   349  
   350  // HasErrorForDivisionByZeroMode detects if 'ERROR_FOR_DIVISION_BY_ZERO' mode is set in SQLMode
   351  func (m SQLMode) HasErrorForDivisionByZeroMode() bool {
   352  	return m&ModeErrorForDivisionByZero == ModeErrorForDivisionByZero
   353  }
   354  
   355  // HasOnlyFullGroupBy detects if 'ONLY_FULL_GROUP_BY' mode is set in SQLMode
   356  func (m SQLMode) HasOnlyFullGroupBy() bool {
   357  	return m&ModeOnlyFullGroupBy == ModeOnlyFullGroupBy
   358  }
   359  
   360  // HasStrictMode detects if 'STRICT_TRANS_TABLES' or 'STRICT_ALL_TABLES' mode is set in SQLMode
   361  func (m SQLMode) HasStrictMode() bool {
   362  	return m&ModeStrictTransTables == ModeStrictTransTables || m&ModeStrictAllTables == ModeStrictAllTables
   363  }
   364  
   365  // HasPipesAsConcatMode detects if 'PIPES_AS_CONCAT' mode is set in SQLMode
   366  func (m SQLMode) HasPipesAsConcatMode() bool {
   367  	return m&ModePipesAsConcat == ModePipesAsConcat
   368  }
   369  
   370  // HasNoUnsignedSubtractionMode detects if 'NO_UNSIGNED_SUBTRACTION' mode is set in SQLMode
   371  func (m SQLMode) HasNoUnsignedSubtractionMode() bool {
   372  	return m&ModeNoUnsignedSubtraction == ModeNoUnsignedSubtraction
   373  }
   374  
   375  // HasHighNotPrecedenceMode detects if 'HIGH_NOT_PRECEDENCE' mode is set in SQLMode
   376  func (m SQLMode) HasHighNotPrecedenceMode() bool {
   377  	return m&ModeHighNotPrecedence == ModeHighNotPrecedence
   378  }
   379  
   380  // HasANSIQuotesMode detects if 'ANSI_QUOTES' mode is set in SQLMode
   381  func (m SQLMode) HasANSIQuotesMode() bool {
   382  	return m&ModeANSIQuotes == ModeANSIQuotes
   383  }
   384  
   385  // HasRealAsFloatMode detects if 'REAL_AS_FLOAT' mode is set in SQLMode
   386  func (m SQLMode) HasRealAsFloatMode() bool {
   387  	return m&ModeRealAsFloat == ModeRealAsFloat
   388  }
   389  
   390  // HasPadCharToFullLengthMode detects if 'PAD_CHAR_TO_FULL_LENGTH' mode is set in SQLMode
   391  func (m SQLMode) HasPadCharToFullLengthMode() bool {
   392  	return m&ModePadCharToFullLength == ModePadCharToFullLength
   393  }
   394  
   395  // HasNoBackslashEscapesMode detects if 'NO_BACKSLASH_ESCAPES' mode is set in SQLMode
   396  func (m SQLMode) HasNoBackslashEscapesMode() bool {
   397  	return m&ModeNoBackslashEscapes == ModeNoBackslashEscapes
   398  }
   399  
   400  // HasIgnoreSpaceMode detects if 'IGNORE_SPACE' mode is set in SQLMode
   401  func (m SQLMode) HasIgnoreSpaceMode() bool {
   402  	return m&ModeIgnoreSpace == ModeIgnoreSpace
   403  }
   404  
   405  // HasNoAutoCreateUserMode detects if 'NO_AUTO_CREATE_USER' mode is set in SQLMode
   406  func (m SQLMode) HasNoAutoCreateUserMode() bool {
   407  	return m&ModeNoAutoCreateUser == ModeNoAutoCreateUser
   408  }
   409  
   410  // HasAllowInvalidDatesMode detects if 'ALLOW_INVALID_DATES' mode is set in SQLMode
   411  func (m SQLMode) HasAllowInvalidDatesMode() bool {
   412  	return m&ModeAllowInvalidDates == ModeAllowInvalidDates
   413  }
   414  
   415  // DelSQLMode delete sql mode from ori
   416  func DelSQLMode(ori SQLMode, del SQLMode) SQLMode {
   417  	return ori & (^del)
   418  }
   419  
   420  // SetSQLMode add sql mode to ori
   421  func SetSQLMode(ori SQLMode, add SQLMode) SQLMode {
   422  	return ori | add
   423  }
   424  
   425  // consts for sql modes.
   426  // see https://dev.mysql.com/doc/internals/en/query-event.html#q-sql-mode-code
   427  const (
   428  	ModeRealAsFloat SQLMode = 1 << iota
   429  	ModePipesAsConcat
   430  	ModeANSIQuotes
   431  	ModeIgnoreSpace
   432  	ModeNotUsed
   433  	ModeOnlyFullGroupBy
   434  	ModeNoUnsignedSubtraction
   435  	ModeNoDirInCreate
   436  	ModePostgreSQL
   437  	ModeOracle
   438  	ModeMsSQL
   439  	ModeDb2
   440  	ModeMaxdb
   441  	ModeNoKeyOptions
   442  	ModeNoTableOptions
   443  	ModeNoFieldOptions
   444  	ModeMySQL323
   445  	ModeMySQL40
   446  	ModeANSI
   447  	ModeNoAutoValueOnZero
   448  	ModeNoBackslashEscapes
   449  	ModeStrictTransTables
   450  	ModeStrictAllTables
   451  	ModeNoZeroInDate
   452  	ModeNoZeroDate
   453  	ModeInvalidDates
   454  	ModeErrorForDivisionByZero
   455  	ModeTraditional
   456  	ModeNoAutoCreateUser
   457  	ModeHighNotPrecedence
   458  	ModeNoEngineSubstitution
   459  	ModePadCharToFullLength
   460  	ModeAllowInvalidDates
   461  	ModeNone = 0
   462  )
   463  
   464  // FormatSQLModeStr re-format 'SQL_MODE' variable.
   465  func FormatSQLModeStr(s string) string {
   466  	s = strings.ToUpper(strings.TrimRight(s, " "))
   467  	parts := strings.Split(s, ",")
   468  	var nonEmptyParts []string
   469  	existParts := make(map[string]string)
   470  	for _, part := range parts {
   471  		if len(part) == 0 {
   472  			continue
   473  		}
   474  		if modeParts, ok := CombinationSQLMode[part]; ok {
   475  			for _, modePart := range modeParts {
   476  				if _, exist := existParts[modePart]; !exist {
   477  					nonEmptyParts = append(nonEmptyParts, modePart)
   478  					existParts[modePart] = modePart
   479  				}
   480  			}
   481  		}
   482  		if _, exist := existParts[part]; !exist {
   483  			nonEmptyParts = append(nonEmptyParts, part)
   484  			existParts[part] = part
   485  		}
   486  	}
   487  	return strings.Join(nonEmptyParts, ",")
   488  }
   489  
   490  // GetSQLMode gets the sql mode for string literal. SQL_mode is a list of different modes separated by commas.
   491  // The input string must be formatted by 'FormatSQLModeStr'
   492  func GetSQLMode(s string) (SQLMode, error) {
   493  	strs := strings.Split(s, ",")
   494  	var sqlMode SQLMode
   495  	for i, length := 0, len(strs); i < length; i++ {
   496  		mode, ok := Str2SQLMode[strs[i]]
   497  		if !ok && strs[i] != "" {
   498  			return sqlMode, newInvalidModeErr(strs[i])
   499  		}
   500  		sqlMode = sqlMode | mode
   501  	}
   502  	return sqlMode, nil
   503  }
   504  
   505  // Str2SQLMode is the string represent of sql_mode to sql_mode map.
   506  var Str2SQLMode = map[string]SQLMode{
   507  	"REAL_AS_FLOAT":              ModeRealAsFloat,
   508  	"PIPES_AS_CONCAT":            ModePipesAsConcat,
   509  	"ANSI_QUOTES":                ModeANSIQuotes,
   510  	"IGNORE_SPACE":               ModeIgnoreSpace,
   511  	"NOT_USED":                   ModeNotUsed,
   512  	"ONLY_FULL_GROUP_BY":         ModeOnlyFullGroupBy,
   513  	"NO_UNSIGNED_SUBTRACTION":    ModeNoUnsignedSubtraction,
   514  	"NO_DIR_IN_CREATE":           ModeNoDirInCreate,
   515  	"POSTGRESQL":                 ModePostgreSQL,
   516  	"ORACLE":                     ModeOracle,
   517  	"MSSQL":                      ModeMsSQL,
   518  	"DB2":                        ModeDb2,
   519  	"MAXDB":                      ModeMaxdb,
   520  	"NO_KEY_OPTIONS":             ModeNoKeyOptions,
   521  	"NO_TABLE_OPTIONS":           ModeNoTableOptions,
   522  	"NO_FIELD_OPTIONS":           ModeNoFieldOptions,
   523  	"MYSQL323":                   ModeMySQL323,
   524  	"MYSQL40":                    ModeMySQL40,
   525  	"ANSI":                       ModeANSI,
   526  	"NO_AUTO_VALUE_ON_ZERO":      ModeNoAutoValueOnZero,
   527  	"NO_BACKSLASH_ESCAPES":       ModeNoBackslashEscapes,
   528  	"STRICT_TRANS_TABLES":        ModeStrictTransTables,
   529  	"STRICT_ALL_TABLES":          ModeStrictAllTables,
   530  	"NO_ZERO_IN_DATE":            ModeNoZeroInDate,
   531  	"NO_ZERO_DATE":               ModeNoZeroDate,
   532  	"INVALID_DATES":              ModeInvalidDates,
   533  	"ERROR_FOR_DIVISION_BY_ZERO": ModeErrorForDivisionByZero,
   534  	"TRADITIONAL":                ModeTraditional,
   535  	"NO_AUTO_CREATE_USER":        ModeNoAutoCreateUser,
   536  	"HIGH_NOT_PRECEDENCE":        ModeHighNotPrecedence,
   537  	"NO_ENGINE_SUBSTITUTION":     ModeNoEngineSubstitution,
   538  	"PAD_CHAR_TO_FULL_LENGTH":    ModePadCharToFullLength,
   539  	"ALLOW_INVALID_DATES":        ModeAllowInvalidDates,
   540  }
   541  
   542  // CombinationSQLMode is the special modes that provided as shorthand for combinations of mode values.
   543  // See https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-combo.
   544  var CombinationSQLMode = map[string][]string{
   545  	"ANSI":        {"REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "ONLY_FULL_GROUP_BY"},
   546  	"DB2":         {"PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS"},
   547  	"MAXDB":       {"PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "NO_AUTO_CREATE_USER"},
   548  	"MSSQL":       {"PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS"},
   549  	"MYSQL323":    {"MYSQL323", "HIGH_NOT_PRECEDENCE"},
   550  	"MYSQL40":     {"MYSQL40", "HIGH_NOT_PRECEDENCE"},
   551  	"ORACLE":      {"PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "NO_AUTO_CREATE_USER"},
   552  	"POSTGRESQL":  {"PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS"},
   553  	"TRADITIONAL": {"STRICT_TRANS_TABLES", "STRICT_ALL_TABLES", "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ERROR_FOR_DIVISION_BY_ZERO", "NO_AUTO_CREATE_USER", "NO_ENGINE_SUBSTITUTION"},
   554  }
   555  
   556  // FormatFunc is the locale format function signature.
   557  type FormatFunc func(string, string) (string, error)
   558  
   559  // GetLocaleFormatFunction get the format function for sepcific locale.
   560  func GetLocaleFormatFunction(loc string) FormatFunc {
   561  	locale, exist := locale2FormatFunction[loc]
   562  	if !exist {
   563  		return formatNotSupport
   564  	}
   565  	return locale
   566  }
   567  
   568  // locale2FormatFunction is the string represent of locale format function.
   569  var locale2FormatFunction = map[string]FormatFunc{
   570  	"en_US": formatENUS,
   571  	"zh_CN": formatZHCN,
   572  }
   573  
   574  // PriorityEnum is defined for Priority const values.
   575  type PriorityEnum int
   576  
   577  // Priority const values.
   578  // See https://dev.mysql.com/doc/refman/5.7/en/insert.html
   579  const (
   580  	NoPriority PriorityEnum = iota
   581  	LowPriority
   582  	HighPriority
   583  	DelayedPriority
   584  )
   585  
   586  // Priority2Str is used to convert the statement priority to string.
   587  var Priority2Str = map[PriorityEnum]string{
   588  	NoPriority:      "NO_PRIORITY",
   589  	LowPriority:     "LOW_PRIORITY",
   590  	HighPriority:    "HIGH_PRIORITY",
   591  	DelayedPriority: "DELAYED",
   592  }
   593  
   594  // Str2Priority is used to convert a string to a priority.
   595  func Str2Priority(val string) PriorityEnum {
   596  	val = strings.ToUpper(val)
   597  	switch val {
   598  	case "NO_PRIORITY":
   599  		return NoPriority
   600  	case "HIGH_PRIORITY":
   601  		return HighPriority
   602  	case "LOW_PRIORITY":
   603  		return LowPriority
   604  	case "DELAYED":
   605  		return DelayedPriority
   606  	default:
   607  		return NoPriority
   608  	}
   609  }
   610  
   611  // Restore implements Node interface.
   612  func (n *PriorityEnum) Restore(ctx *format.RestoreCtx) error {
   613  	switch *n {
   614  	case NoPriority:
   615  		return nil
   616  	case LowPriority:
   617  		ctx.WriteKeyWord("LOW_PRIORITY")
   618  	case HighPriority:
   619  		ctx.WriteKeyWord("HIGH_PRIORITY")
   620  	case DelayedPriority:
   621  		ctx.WriteKeyWord("DELAYED")
   622  	default:
   623  		return errors.Errorf("undefined PriorityEnum Type[%d]", *n)
   624  	}
   625  	return nil
   626  }
   627  
   628  const (
   629  	// PrimaryKeyName defines primary key name.
   630  	PrimaryKeyName = "PRIMARY"
   631  	// DefaultDecimal defines the default decimal value when the value out of range.
   632  	DefaultDecimal = "99999999999999999999999999999999999999999999999999999999999999999"
   633  	// PartitionCountLimit is limit of the number of partitions in a table.
   634  	// Reference linking https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations.html.
   635  	PartitionCountLimit = 8192
   636  )
   637  
   638  // This is enum_cursor_type in MySQL
   639  const (
   640  	CursorTypeReadOnly = 1 << iota
   641  	CursorTypeForUpdate
   642  	CursorTypeScrollable
   643  )
   644  
   645  const (
   646  	// CompressionNone is no compression in use
   647  	CompressionNone = iota
   648  	// CompressionZlib is zlib/deflate
   649  	CompressionZlib
   650  	// CompressionZstd is Facebook's Zstandard
   651  	CompressionZstd
   652  )