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  }