github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/lower_upper.go (about)

     1  // Copyright 2020-2021 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 function
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/dolthub/go-mysql-server/sql"
    21  	"github.com/dolthub/go-mysql-server/sql/expression"
    22  	"github.com/dolthub/go-mysql-server/sql/types"
    23  )
    24  
    25  // Lower is a function that returns the lowercase of the text provided.
    26  type Lower struct {
    27  	expression.UnaryExpression
    28  }
    29  
    30  var _ sql.FunctionExpression = (*Lower)(nil)
    31  var _ sql.CollationCoercible = (*Lower)(nil)
    32  
    33  // NewLower creates a new Lower expression.
    34  func NewLower(e sql.Expression) sql.Expression {
    35  	return &Lower{expression.UnaryExpression{Child: e}}
    36  }
    37  
    38  // FunctionName implements sql.FunctionExpression
    39  func (l *Lower) FunctionName() string {
    40  	return "lower"
    41  }
    42  
    43  // Description implements sql.FunctionExpression
    44  func (l *Lower) Description() string {
    45  	return "returns the string str with all characters in lower case."
    46  }
    47  
    48  // Eval implements the Expression interface.
    49  func (l *Lower) Eval(
    50  	ctx *sql.Context,
    51  	row sql.Row,
    52  ) (interface{}, error) {
    53  	v, err := l.Child.Eval(ctx, row)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	if v == nil {
    59  		return nil, nil
    60  	}
    61  
    62  	vStr, collation, err := types.ConvertToCollatedString(v, l.Child.Type())
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	return collation.CharacterSet().Encoder().Lowercase(vStr), nil
    67  }
    68  
    69  func (l *Lower) String() string {
    70  	return fmt.Sprintf("%s(%s)", l.FunctionName(), l.Child)
    71  }
    72  
    73  // WithChildren implements the Expression interface.
    74  func (l *Lower) WithChildren(children ...sql.Expression) (sql.Expression, error) {
    75  	if len(children) != 1 {
    76  		return nil, sql.ErrInvalidChildrenNumber.New(l, len(children), 1)
    77  	}
    78  	return NewLower(children[0]), nil
    79  }
    80  
    81  // Type implements the Expression interface.
    82  func (l *Lower) Type() sql.Type {
    83  	return l.Child.Type()
    84  }
    85  
    86  // CollationCoercibility implements the interface sql.CollationCoercible.
    87  func (l *Lower) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
    88  	return sql.GetCoercibility(ctx, l.Child)
    89  }
    90  
    91  // Upper is a function that returns the UPPERCASE of the text provided.
    92  type Upper struct {
    93  	expression.UnaryExpression
    94  }
    95  
    96  var _ sql.FunctionExpression = (*Upper)(nil)
    97  var _ sql.CollationCoercible = (*Upper)(nil)
    98  
    99  // NewUpper creates a new Lower expression.
   100  func NewUpper(e sql.Expression) sql.Expression {
   101  	return &Upper{expression.UnaryExpression{Child: e}}
   102  }
   103  
   104  // FunctionName implements sql.FunctionExpression
   105  func (u *Upper) FunctionName() string {
   106  	return "upper"
   107  }
   108  
   109  // Description implements sql.FunctionExpression
   110  func (u *Upper) Description() string {
   111  	return "converts string to uppercase."
   112  }
   113  
   114  // Eval implements the Expression interface.
   115  func (u *Upper) Eval(
   116  	ctx *sql.Context,
   117  	row sql.Row,
   118  ) (interface{}, error) {
   119  	v, err := u.Child.Eval(ctx, row)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	if v == nil {
   125  		return nil, nil
   126  	}
   127  
   128  	vStr, collation, err := types.ConvertToCollatedString(v, u.Child.Type())
   129  	if err != nil {
   130  		return nil, err
   131  	}
   132  	return collation.CharacterSet().Encoder().Uppercase(vStr), nil
   133  }
   134  
   135  func (u *Upper) String() string {
   136  	return fmt.Sprintf("%s(%s)", u.FunctionName(), u.Child)
   137  }
   138  
   139  // WithChildren implements the Expression interface.
   140  func (u *Upper) WithChildren(children ...sql.Expression) (sql.Expression, error) {
   141  	if len(children) != 1 {
   142  		return nil, sql.ErrInvalidChildrenNumber.New(u, len(children), 1)
   143  	}
   144  	return NewUpper(children[0]), nil
   145  }
   146  
   147  // Type implements the Expression interface.
   148  func (u *Upper) Type() sql.Type {
   149  	return u.Child.Type()
   150  }
   151  
   152  // CollationCoercibility implements the interface sql.CollationCoercible.
   153  func (u *Upper) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
   154  	return sql.GetCoercibility(ctx, u.Child)
   155  }