github.com/dolthub/go-mysql-server@v0.18.0/sql/types/system_string.go (about) 1 // Copyright 2022 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 types 16 17 import ( 18 "reflect" 19 20 "github.com/dolthub/vitess/go/sqltypes" 21 "github.com/dolthub/vitess/go/vt/proto/query" 22 23 "github.com/dolthub/go-mysql-server/sql" 24 ) 25 26 var systemStringValueType = reflect.TypeOf(string("")) 27 28 // systemStringType is an internal string type ONLY for system variables. 29 type systemStringType struct { 30 varName string 31 } 32 33 var _ sql.SystemVariableType = systemStringType{} 34 var _ sql.CollationCoercible = systemStringType{} 35 36 // NewSystemStringType returns a new systemStringType. 37 func NewSystemStringType(varName string) sql.SystemVariableType { 38 return systemStringType{varName} 39 } 40 41 // Compare implements Type interface. 42 func (t systemStringType) Compare(a interface{}, b interface{}) (int, error) { 43 as, _, err := t.Convert(a) 44 if err != nil { 45 return 0, err 46 } 47 bs, _, err := t.Convert(b) 48 if err != nil { 49 return 0, err 50 } 51 ai := as.(string) 52 bi := bs.(string) 53 54 if ai == bi { 55 return 0, nil 56 } 57 if ai < bi { 58 return -1, nil 59 } 60 return 1, nil 61 } 62 63 // Convert implements Type interface. 64 func (t systemStringType) Convert(v interface{}) (interface{}, sql.ConvertInRange, error) { 65 if v == nil { 66 return "", sql.InRange, nil 67 } 68 if value, ok := v.(string); ok { 69 return value, sql.InRange, nil 70 } 71 72 return nil, sql.OutOfRange, sql.ErrInvalidSystemVariableValue.New(t.varName, v) 73 } 74 75 // MustConvert implements the Type interface. 76 func (t systemStringType) MustConvert(v interface{}) interface{} { 77 value, _, err := t.Convert(v) 78 if err != nil { 79 panic(err) 80 } 81 return value 82 } 83 84 // Equals implements the Type interface. 85 func (t systemStringType) Equals(otherType sql.Type) bool { 86 if ot, ok := otherType.(systemStringType); ok { 87 return t.varName == ot.varName 88 } 89 return false 90 } 91 92 // MaxTextResponseByteLength implements the Type interface 93 func (t systemStringType) MaxTextResponseByteLength(ctx *sql.Context) uint32 { 94 return t.UnderlyingType().MaxTextResponseByteLength(ctx) 95 } 96 97 // Promote implements the Type interface. 98 func (t systemStringType) Promote() sql.Type { 99 return t 100 } 101 102 // SQL implements Type interface. 103 func (t systemStringType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes.Value, error) { 104 if v == nil { 105 return sqltypes.NULL, nil 106 } 107 108 v, _, err := t.Convert(v) 109 if err != nil { 110 return sqltypes.Value{}, err 111 } 112 113 val := AppendAndSliceString(dest, v.(string)) 114 115 return sqltypes.MakeTrusted(t.Type(), val), nil 116 } 117 118 // String implements Type interface. 119 func (t systemStringType) String() string { 120 return "system_string" 121 } 122 123 // Type implements Type interface. 124 func (t systemStringType) Type() query.Type { 125 return sqltypes.VarChar 126 } 127 128 // ValueType implements Type interface. 129 func (t systemStringType) ValueType() reflect.Type { 130 return systemStringValueType 131 } 132 133 // Zero implements Type interface. 134 func (t systemStringType) Zero() interface{} { 135 return "" 136 } 137 138 // CollationCoercibility implements sql.CollationCoercible interface. 139 func (t systemStringType) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 140 return sql.Collation_utf8mb3_general_ci, 3 141 } 142 143 // EncodeValue implements SystemVariableType interface. 144 func (t systemStringType) EncodeValue(val interface{}) (string, error) { 145 expectedVal, ok := val.(string) 146 if !ok { 147 return "", sql.ErrSystemVariableCodeFail.New(val, t.String()) 148 } 149 return expectedVal, nil 150 } 151 152 // DecodeValue implements SystemVariableType interface. 153 func (t systemStringType) DecodeValue(val string) (interface{}, error) { 154 return val, nil 155 } 156 157 func (t systemStringType) UnderlyingType() sql.Type { 158 return LongText 159 }