github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/istrue.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 expression
    16  
    17  import (
    18  	"errors"
    19  
    20  	"github.com/dolthub/go-mysql-server/sql"
    21  	"github.com/dolthub/go-mysql-server/sql/types"
    22  )
    23  
    24  // IsTrue is an expression that checks if an expression is true.
    25  type IsTrue struct {
    26  	UnaryExpression
    27  	invert bool
    28  }
    29  
    30  var _ sql.Expression = (*IsTrue)(nil)
    31  var _ sql.CollationCoercible = (*IsTrue)(nil)
    32  
    33  const IsTrueStr = "IS TRUE"
    34  const IsFalseStr = "IS FALSE"
    35  
    36  // NewIsTrue creates a new IsTrue expression.
    37  func NewIsTrue(child sql.Expression) *IsTrue {
    38  	return &IsTrue{UnaryExpression: UnaryExpression{child}}
    39  }
    40  
    41  // NewIsFalse creates a new IsTrue expression with its boolean sense inverted (IsFalse, effectively).
    42  func NewIsFalse(child sql.Expression) *IsTrue {
    43  	return &IsTrue{UnaryExpression: UnaryExpression{child}, invert: true}
    44  }
    45  
    46  // Type implements the Expression interface.
    47  func (*IsTrue) Type() sql.Type {
    48  	return types.Boolean
    49  }
    50  
    51  // CollationCoercibility implements the interface sql.CollationCoercible.
    52  func (*IsTrue) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
    53  	return sql.Collation_binary, 5
    54  }
    55  
    56  // IsNullable implements the Expression interface.
    57  func (*IsTrue) IsNullable() bool {
    58  	return false
    59  }
    60  
    61  // Eval implements the Expression interface.
    62  func (e *IsTrue) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
    63  	v, err := e.Child.Eval(ctx, row)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	var boolVal interface{}
    69  	if v == nil {
    70  		return false, nil
    71  	}
    72  	boolVal, err = sql.ConvertToBool(ctx, v)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	if e.invert {
    78  		return !boolVal.(bool), nil
    79  	}
    80  	return boolVal, nil
    81  }
    82  
    83  func (e *IsTrue) String() string {
    84  	isStr := IsTrueStr
    85  	if e.invert {
    86  		isStr = IsFalseStr
    87  	}
    88  	return e.Child.String() + " " + isStr
    89  }
    90  
    91  // WithChildren implements the Expression interface.
    92  func (e *IsTrue) WithChildren(children ...sql.Expression) (sql.Expression, error) {
    93  	if len(children) != 1 {
    94  		return nil, errors.New("incorrect number of children")
    95  	}
    96  
    97  	if e.invert {
    98  		return NewIsFalse(children[0]), nil
    99  	}
   100  	return NewIsTrue(children[0]), nil
   101  }