github.com/vedadiyan/sqlparser@v1.0.0/pkg/sqlparser/ast_funcs.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package sqlparser
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/hex"
    22  	"encoding/json"
    23  	"fmt"
    24  	"regexp"
    25  	"strconv"
    26  	"strings"
    27  
    28  	"github.com/vedadiyan/sqlparser/pkg/vterrors"
    29  	vtrpcpb "github.com/vedadiyan/sqlparser/pkg/vtrpc"
    30  
    31  	"github.com/vedadiyan/sqlparser/pkg/log"
    32  
    33  	querypb "github.com/vedadiyan/sqlparser/pkg/query"
    34  	"github.com/vedadiyan/sqlparser/pkg/sqltypes"
    35  )
    36  
    37  // Generate all the AST helpers using the tooling in `go/tools`
    38  
    39  //go:generate go run ../../tools/asthelpergen/main  --in . --iface vitess.io/vitess/go/vt/sqlparser.SQLNode --clone_exclude "*ColName" --equals_custom "*ColName"
    40  //go:generate go run ../../tools/astfmtgen vitess.io/vitess/go/vt/sqlparser/...
    41  
    42  // Walk calls postVisit on every node.
    43  // If postVisit returns true, the underlying nodes
    44  // are also visited. If it returns an error, walking
    45  // is interrupted, and the error is returned.
    46  func Walk(visit Visit, nodes ...SQLNode) error {
    47  	for _, node := range nodes {
    48  		err := VisitSQLNode(node, visit)
    49  		if err != nil {
    50  			return err
    51  		}
    52  	}
    53  	return nil
    54  }
    55  
    56  // Visit defines the signature of a function that
    57  // can be used to postVisit all nodes of a parse tree.
    58  // returning false on kontinue means that children will not be visited
    59  // returning an error will abort the visitation and return the error
    60  type Visit func(node SQLNode) (kontinue bool, err error)
    61  
    62  // Append appends the SQLNode to the buffer.
    63  func Append(buf *strings.Builder, node SQLNode) {
    64  	tbuf := &TrackedBuffer{
    65  		Builder: buf,
    66  		fast:    true,
    67  	}
    68  	node.formatFast(tbuf)
    69  }
    70  
    71  // IndexColumn describes a column or expression in an index definition with optional length (for column)
    72  type IndexColumn struct {
    73  	// Only one of Column or Expression can be specified
    74  	// Length is an optional field which is only applicable when Column is used
    75  	Column     IdentifierCI
    76  	Length     *Literal
    77  	Expression Expr
    78  	Direction  OrderDirection
    79  }
    80  
    81  // LengthScaleOption is used for types that have an optional length
    82  // and scale
    83  type LengthScaleOption struct {
    84  	Length *Literal
    85  	Scale  *Literal
    86  }
    87  
    88  // IndexOption is used for trailing options for indexes: COMMENT, KEY_BLOCK_SIZE, USING, WITH PARSER
    89  type IndexOption struct {
    90  	Name   string
    91  	Value  *Literal
    92  	String string
    93  }
    94  
    95  // TableOption is used for create table options like AUTO_INCREMENT, INSERT_METHOD, etc
    96  type TableOption struct {
    97  	Name          string
    98  	Value         *Literal
    99  	String        string
   100  	Tables        TableNames
   101  	CaseSensitive bool
   102  }
   103  
   104  // ColumnKeyOption indicates whether or not the given column is defined as an
   105  // index element and contains the type of the option
   106  type ColumnKeyOption int
   107  
   108  const (
   109  	ColKeyNone ColumnKeyOption = iota
   110  	ColKeyPrimary
   111  	ColKeySpatialKey
   112  	ColKeyFulltextKey
   113  	ColKeyUnique
   114  	ColKeyUniqueKey
   115  	ColKey
   116  )
   117  
   118  // ReferenceAction indicates the action takes by a referential constraint e.g.
   119  // the `CASCADE` in a `FOREIGN KEY .. ON DELETE CASCADE` table definition.
   120  type ReferenceAction int
   121  
   122  // These map to the SQL-defined reference actions.
   123  // See https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html#foreign-keys-referential-actions
   124  const (
   125  	// DefaultAction indicates no action was explicitly specified.
   126  	DefaultAction ReferenceAction = iota
   127  	Restrict
   128  	Cascade
   129  	NoAction
   130  	SetNull
   131  	SetDefault
   132  )
   133  
   134  // MatchAction indicates the type of match for a referential constraint, so
   135  // a `MATCH FULL`, `MATCH SIMPLE` or `MATCH PARTIAL`.
   136  type MatchAction int
   137  
   138  const (
   139  	// DefaultAction indicates no action was explicitly specified.
   140  	DefaultMatch MatchAction = iota
   141  	Full
   142  	Partial
   143  	Simple
   144  )
   145  
   146  // ShowTablesOpt is show tables option
   147  type ShowTablesOpt struct {
   148  	Full   string
   149  	DbName string
   150  	Filter *ShowFilter
   151  }
   152  
   153  // ValType specifies the type for Literal.
   154  type ValType int
   155  
   156  // These are the possible Valtype values.
   157  // HexNum represents a 0x... value. It cannot
   158  // be treated as a simple value because it can
   159  // be interpreted differently depending on the
   160  // context.
   161  const (
   162  	StrVal = ValType(iota)
   163  	IntVal
   164  	DecimalVal
   165  	FloatVal
   166  	HexNum
   167  	HexVal
   168  	BitVal
   169  	DateVal
   170  	TimeVal
   171  	TimestampVal
   172  )
   173  
   174  // queryOptimizerPrefix is the prefix of an optimizer hint comment.
   175  const queryOptimizerPrefix = "/*+"
   176  
   177  // AddColumn appends the given column to the list in the spec
   178  func (ts *TableSpec) AddColumn(cd *ColumnDefinition) {
   179  	ts.Columns = append(ts.Columns, cd)
   180  }
   181  
   182  // AddIndex appends the given index to the list in the spec
   183  func (ts *TableSpec) AddIndex(id *IndexDefinition) {
   184  	ts.Indexes = append(ts.Indexes, id)
   185  }
   186  
   187  // AddConstraint appends the given index to the list in the spec
   188  func (ts *TableSpec) AddConstraint(cd *ConstraintDefinition) {
   189  	ts.Constraints = append(ts.Constraints, cd)
   190  }
   191  
   192  // DescribeType returns the abbreviated type information as required for
   193  // describe table
   194  func (ct *ColumnType) DescribeType() string {
   195  	buf := NewTrackedBuffer(nil)
   196  	buf.Myprintf("%s", ct.Type)
   197  	if ct.Length != nil && ct.Scale != nil {
   198  		buf.Myprintf("(%v,%v)", ct.Length, ct.Scale)
   199  	} else if ct.Length != nil {
   200  		buf.Myprintf("(%v)", ct.Length)
   201  	}
   202  
   203  	opts := make([]string, 0, 16)
   204  	if ct.Unsigned {
   205  		opts = append(opts, keywordStrings[UNSIGNED])
   206  	}
   207  	if ct.Zerofill {
   208  		opts = append(opts, keywordStrings[ZEROFILL])
   209  	}
   210  	if len(opts) != 0 {
   211  		buf.Myprintf(" %s", strings.Join(opts, " "))
   212  	}
   213  	return buf.String()
   214  }
   215  
   216  // SQLType returns the sqltypes type code for the given column
   217  func (ct *ColumnType) SQLType() querypb.Type {
   218  	return SQLTypeToQueryType(ct.Type, ct.Unsigned)
   219  }
   220  
   221  func SQLTypeToQueryType(typeName string, unsigned bool) querypb.Type {
   222  	switch keywordVals[strings.ToLower(typeName)] {
   223  	case TINYINT:
   224  		if unsigned {
   225  			return sqltypes.Uint8
   226  		}
   227  		return sqltypes.Int8
   228  	case SMALLINT:
   229  		if unsigned {
   230  			return sqltypes.Uint16
   231  		}
   232  		return sqltypes.Int16
   233  	case MEDIUMINT:
   234  		if unsigned {
   235  			return sqltypes.Uint24
   236  		}
   237  		return sqltypes.Int24
   238  	case INT, INTEGER:
   239  		if unsigned {
   240  			return sqltypes.Uint32
   241  		}
   242  		return sqltypes.Int32
   243  	case BIGINT:
   244  		if unsigned {
   245  			return sqltypes.Uint64
   246  		}
   247  		return sqltypes.Int64
   248  	case BOOL, BOOLEAN:
   249  		return sqltypes.Uint8
   250  	case TEXT:
   251  		return sqltypes.Text
   252  	case TINYTEXT:
   253  		return sqltypes.Text
   254  	case MEDIUMTEXT:
   255  		return sqltypes.Text
   256  	case LONGTEXT:
   257  		return sqltypes.Text
   258  	case BLOB:
   259  		return sqltypes.Blob
   260  	case TINYBLOB:
   261  		return sqltypes.Blob
   262  	case MEDIUMBLOB:
   263  		return sqltypes.Blob
   264  	case LONGBLOB:
   265  		return sqltypes.Blob
   266  	case CHAR:
   267  		return sqltypes.Char
   268  	case VARCHAR:
   269  		return sqltypes.VarChar
   270  	case BINARY:
   271  		return sqltypes.Binary
   272  	case VARBINARY:
   273  		return sqltypes.VarBinary
   274  	case DATE:
   275  		return sqltypes.Date
   276  	case TIME:
   277  		return sqltypes.Time
   278  	case DATETIME:
   279  		return sqltypes.Datetime
   280  	case TIMESTAMP:
   281  		return sqltypes.Timestamp
   282  	case YEAR:
   283  		return sqltypes.Year
   284  	case FLOAT_TYPE, FLOAT4_TYPE:
   285  		return sqltypes.Float32
   286  	case DOUBLE, FLOAT8_TYPE:
   287  		return sqltypes.Float64
   288  	case DECIMAL, DECIMAL_TYPE:
   289  		return sqltypes.Decimal
   290  	case BIT:
   291  		return sqltypes.Bit
   292  	case ENUM:
   293  		return sqltypes.Enum
   294  	case SET:
   295  		return sqltypes.Set
   296  	case JSON:
   297  		return sqltypes.TypeJSON
   298  	case GEOMETRY:
   299  		return sqltypes.Geometry
   300  	case POINT:
   301  		return sqltypes.Geometry
   302  	case LINESTRING:
   303  		return sqltypes.Geometry
   304  	case POLYGON:
   305  		return sqltypes.Geometry
   306  	case GEOMETRYCOLLECTION:
   307  		return sqltypes.Geometry
   308  	case MULTIPOINT:
   309  		return sqltypes.Geometry
   310  	case MULTILINESTRING:
   311  		return sqltypes.Geometry
   312  	case MULTIPOLYGON:
   313  		return sqltypes.Geometry
   314  	}
   315  	return sqltypes.Null
   316  }
   317  
   318  // AddQueryHint adds the given string to list of comment.
   319  // If the list is empty, one will be created containing the query hint.
   320  // If the list already contains a query hint, the given string will be merged with the existing one.
   321  // This is done because only one query hint is allowed per query.
   322  func (node *ParsedComments) AddQueryHint(queryHint string) (Comments, error) {
   323  	if queryHint == "" {
   324  		if node == nil {
   325  			return nil, nil
   326  		}
   327  		return node.comments, nil
   328  	}
   329  
   330  	var newComments Comments
   331  	var hasQueryHint bool
   332  
   333  	if node != nil {
   334  		for _, comment := range node.comments {
   335  			if strings.HasPrefix(comment, queryOptimizerPrefix) {
   336  				if hasQueryHint {
   337  					return nil, vterrors.New(vtrpcpb.Code_INTERNAL, "Must have only one query hint")
   338  				}
   339  				hasQueryHint = true
   340  				idx := strings.Index(comment, "*/")
   341  				if idx == -1 {
   342  					return nil, vterrors.New(vtrpcpb.Code_INTERNAL, "Query hint comment is malformed")
   343  				}
   344  				if strings.Contains(comment, queryHint) {
   345  					newComments = append(Comments{comment}, newComments...)
   346  					continue
   347  				}
   348  				newComment := fmt.Sprintf("%s %s */", strings.TrimSpace(comment[:idx]), queryHint)
   349  				newComments = append(Comments{newComment}, newComments...)
   350  				continue
   351  			}
   352  			newComments = append(newComments, comment)
   353  		}
   354  	}
   355  	if !hasQueryHint {
   356  		queryHintCommentStr := fmt.Sprintf("%s %s */", queryOptimizerPrefix, queryHint)
   357  		newComments = append(Comments{queryHintCommentStr}, newComments...)
   358  	}
   359  	return newComments, nil
   360  }
   361  
   362  // ParseParams parses the vindex parameter list, pulling out the special-case
   363  // "owner" parameter
   364  func (node *VindexSpec) ParseParams() (string, map[string]string) {
   365  	var owner string
   366  	params := map[string]string{}
   367  	for _, p := range node.Params {
   368  		if p.Key.Lowered() == VindexOwnerStr {
   369  			owner = p.Val
   370  		} else {
   371  			params[p.Key.String()] = p.Val
   372  		}
   373  	}
   374  	return owner, params
   375  }
   376  
   377  var _ ConstraintInfo = &ForeignKeyDefinition{}
   378  
   379  func (f *ForeignKeyDefinition) iConstraintInfo() {}
   380  
   381  var _ ConstraintInfo = &CheckConstraintDefinition{}
   382  
   383  func (c *CheckConstraintDefinition) iConstraintInfo() {}
   384  
   385  // FindColumn finds a column in the column list, returning
   386  // the index if it exists or -1 otherwise
   387  func (node Columns) FindColumn(col IdentifierCI) int {
   388  	for i, colName := range node {
   389  		if colName.Equal(col) {
   390  			return i
   391  		}
   392  	}
   393  	return -1
   394  }
   395  
   396  // RemoveHints returns a new AliasedTableExpr with the hints removed.
   397  func (node *AliasedTableExpr) RemoveHints() *AliasedTableExpr {
   398  	noHints := *node
   399  	noHints.Hints = nil
   400  	return &noHints
   401  }
   402  
   403  // TableName returns a TableName pointing to this table expr
   404  func (node *AliasedTableExpr) TableName() (TableName, error) {
   405  	if !node.As.IsEmpty() {
   406  		return TableName{Name: node.As}, nil
   407  	}
   408  
   409  	tableName, ok := node.Expr.(TableName)
   410  	if !ok {
   411  		return TableName{}, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "BUG: the AST has changed. This should not be possible")
   412  	}
   413  
   414  	return tableName, nil
   415  }
   416  
   417  // IsEmpty returns true if TableName is nil or empty.
   418  func (node TableName) IsEmpty() bool {
   419  	// If Name is empty, Qualifier is also empty.
   420  	return node.Name.IsEmpty()
   421  }
   422  
   423  // ToViewName returns a TableName acceptable for use as a VIEW. VIEW names are
   424  // always lowercase, so ToViewName lowercasese the name. Databases are case-sensitive
   425  // so Qualifier is left untouched.
   426  func (node TableName) ToViewName() TableName {
   427  	return TableName{
   428  		Qualifier: node.Qualifier,
   429  		Name:      NewIdentifierCS(strings.ToLower(node.Name.v)),
   430  	}
   431  }
   432  
   433  // NewWhere creates a WHERE or HAVING clause out
   434  // of a Expr. If the expression is nil, it returns nil.
   435  func NewWhere(typ WhereType, expr Expr) *Where {
   436  	if expr == nil {
   437  		return nil
   438  	}
   439  	return &Where{Type: typ, Expr: expr}
   440  }
   441  
   442  // ReplaceExpr finds the from expression from root
   443  // and replaces it with to. If from matches root,
   444  // then to is returned.
   445  func ReplaceExpr(root, from, to Expr) Expr {
   446  	tmp := SafeRewrite(root, stopWalking, replaceExpr(from, to))
   447  
   448  	expr, success := tmp.(Expr)
   449  	if !success {
   450  		log.Errorf("Failed to rewrite expression. Rewriter returned a non-expression:  %s", String(tmp))
   451  		return from
   452  	}
   453  
   454  	return expr
   455  }
   456  
   457  func stopWalking(e SQLNode, _ SQLNode) bool {
   458  	switch e.(type) {
   459  	case *ExistsExpr, *Literal, *Subquery, *ValuesFuncExpr, *Default:
   460  		return false
   461  	default:
   462  		return true
   463  	}
   464  }
   465  
   466  func replaceExpr(from, to Expr) func(cursor *Cursor) bool {
   467  	return func(cursor *Cursor) bool {
   468  		if cursor.Node() == from {
   469  			cursor.Replace(to)
   470  		}
   471  		return true
   472  	}
   473  }
   474  
   475  // IsImpossible returns true if the comparison in the expression can never evaluate to true.
   476  // Note that this is not currently exhaustive to ALL impossible comparisons.
   477  func (node *ComparisonExpr) IsImpossible() bool {
   478  	var left, right *Literal
   479  	var ok bool
   480  	if left, ok = node.Left.(*Literal); !ok {
   481  		return false
   482  	}
   483  	if right, ok = node.Right.(*Literal); !ok {
   484  		return false
   485  	}
   486  	if node.Operator == NotEqualOp && left.Type == right.Type {
   487  		if len(left.Val) != len(right.Val) {
   488  			return false
   489  		}
   490  
   491  		for i := range left.Val {
   492  			if left.Val[i] != right.Val[i] {
   493  				return false
   494  			}
   495  		}
   496  		return true
   497  	}
   498  	return false
   499  }
   500  
   501  // NewStrLiteral builds a new StrVal.
   502  func NewStrLiteral(in string) *Literal {
   503  	return &Literal{Type: StrVal, Val: in}
   504  }
   505  
   506  // NewIntLiteral builds a new IntVal.
   507  func NewIntLiteral(in string) *Literal {
   508  	return &Literal{Type: IntVal, Val: in}
   509  }
   510  
   511  func NewDecimalLiteral(in string) *Literal {
   512  	return &Literal{Type: DecimalVal, Val: in}
   513  }
   514  
   515  // NewFloatLiteral builds a new FloatVal.
   516  func NewFloatLiteral(in string) *Literal {
   517  	return &Literal{Type: FloatVal, Val: in}
   518  }
   519  
   520  // NewHexNumLiteral builds a new HexNum.
   521  func NewHexNumLiteral(in string) *Literal {
   522  	return &Literal{Type: HexNum, Val: in}
   523  }
   524  
   525  // NewHexLiteral builds a new HexVal.
   526  func NewHexLiteral(in string) *Literal {
   527  	return &Literal{Type: HexVal, Val: in}
   528  }
   529  
   530  // NewBitLiteral builds a new BitVal containing a bit literal.
   531  func NewBitLiteral(in string) *Literal {
   532  	return &Literal{Type: BitVal, Val: in}
   533  }
   534  
   535  // NewDateLiteral builds a new Date.
   536  func NewDateLiteral(in string) *Literal {
   537  	return &Literal{Type: DateVal, Val: in}
   538  }
   539  
   540  // NewTimeLiteral builds a new Date.
   541  func NewTimeLiteral(in string) *Literal {
   542  	return &Literal{Type: TimeVal, Val: in}
   543  }
   544  
   545  // NewTimestampLiteral builds a new Date.
   546  func NewTimestampLiteral(in string) *Literal {
   547  	return &Literal{Type: TimestampVal, Val: in}
   548  }
   549  
   550  // NewArgument builds a new ValArg.
   551  func NewArgument(in string) Argument {
   552  	return Argument(in)
   553  }
   554  
   555  // NewListArg builds a new ListArg.
   556  func NewListArg(in string) ListArg {
   557  	return ListArg(in)
   558  }
   559  
   560  // String returns ListArg as a string.
   561  func (node ListArg) String() string {
   562  	return string(node)
   563  }
   564  
   565  // Bytes return the []byte
   566  func (node *Literal) Bytes() []byte {
   567  	return []byte(node.Val)
   568  }
   569  
   570  // HexDecode decodes the hexval into bytes.
   571  func (node *Literal) HexDecode() ([]byte, error) {
   572  	return hex.DecodeString(node.Val)
   573  }
   574  
   575  // encodeHexOrBitValToMySQLQueryFormat encodes the hexval or bitval back into the query format
   576  // for passing on to MySQL as a bind var
   577  func (node *Literal) encodeHexOrBitValToMySQLQueryFormat() ([]byte, error) {
   578  	nb := node.Bytes()
   579  	if node.Type != HexVal && node.Type != BitVal {
   580  		return nb, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Literal value is not a HexVal")
   581  	}
   582  
   583  	prefix := 'x'
   584  	regex := "^x'.*'$"
   585  	if node.Type == BitVal {
   586  		prefix = 'b'
   587  		regex = "^b'.*'$"
   588  	}
   589  	// Let's make this idempotent in case it's called more than once
   590  	match, err := regexp.Match(regex, nb)
   591  	if err != nil {
   592  		return nb, err
   593  	}
   594  	if match {
   595  		return nb, nil
   596  	}
   597  
   598  	var bb bytes.Buffer
   599  	bb.WriteByte(byte(prefix))
   600  	bb.WriteByte('\'')
   601  	bb.WriteString(string(nb))
   602  	bb.WriteByte('\'')
   603  	nb = bb.Bytes()
   604  	return nb, nil
   605  }
   606  
   607  // Equal returns true if the column names match.
   608  func (node *ColName) Equal(c *ColName) bool {
   609  	// Failsafe: ColName should not be empty.
   610  	if node == nil || c == nil {
   611  		return false
   612  	}
   613  	return node.Name.Equal(c.Name) && node.Qualifier == c.Qualifier
   614  }
   615  
   616  // Aggregates is a map of all aggregate functions.
   617  var Aggregates = map[string]bool{
   618  	"avg":          true,
   619  	"bit_and":      true,
   620  	"bit_or":       true,
   621  	"bit_xor":      true,
   622  	"count":        true,
   623  	"group_concat": true,
   624  	"max":          true,
   625  	"min":          true,
   626  	"std":          true,
   627  	"stddev_pop":   true,
   628  	"stddev_samp":  true,
   629  	"stddev":       true,
   630  	"sum":          true,
   631  	"var_pop":      true,
   632  	"var_samp":     true,
   633  	"variance":     true,
   634  }
   635  
   636  // IsAggregate returns true if the function is an aggregate.
   637  func (node *FuncExpr) IsAggregate() bool {
   638  	return Aggregates[node.Name.Lowered()]
   639  }
   640  
   641  // NewIdentifierCI makes a new IdentifierCI.
   642  func NewIdentifierCI(str string) IdentifierCI {
   643  	return IdentifierCI{
   644  		val: str,
   645  	}
   646  }
   647  
   648  // NewColName makes a new ColName
   649  func NewColName(str string) *ColName {
   650  	return &ColName{
   651  		Name: NewIdentifierCI(str),
   652  	}
   653  }
   654  
   655  // NewColNameWithQualifier makes a new ColName pointing to a specific table
   656  func NewColNameWithQualifier(identifier string, table TableName) *ColName {
   657  	return &ColName{
   658  		Name: NewIdentifierCI(identifier),
   659  		Qualifier: TableName{
   660  			Name:      NewIdentifierCS(table.Name.String()),
   661  			Qualifier: NewIdentifierCS(table.Qualifier.String()),
   662  		},
   663  	}
   664  }
   665  
   666  // NewSelect is used to create a select statement
   667  func NewSelect(comments Comments, exprs SelectExprs, selectOptions []string, into *SelectInto, from TableExprs, where *Where, groupBy GroupBy, having *Where, windows NamedWindows) *Select {
   668  	var cache *bool
   669  	var distinct, straightJoinHint, sqlFoundRows bool
   670  
   671  	for _, option := range selectOptions {
   672  		switch strings.ToLower(option) {
   673  		case DistinctStr:
   674  			distinct = true
   675  		case SQLCacheStr:
   676  			truth := true
   677  			cache = &truth
   678  		case SQLNoCacheStr:
   679  			truth := false
   680  			cache = &truth
   681  		case StraightJoinHint:
   682  			straightJoinHint = true
   683  		case SQLCalcFoundRowsStr:
   684  			sqlFoundRows = true
   685  		}
   686  	}
   687  	return &Select{
   688  		Cache:            cache,
   689  		Comments:         comments.Parsed(),
   690  		Distinct:         distinct,
   691  		StraightJoinHint: straightJoinHint,
   692  		SQLCalcFoundRows: sqlFoundRows,
   693  		SelectExprs:      exprs,
   694  		Into:             into,
   695  		From:             from,
   696  		Where:            where,
   697  		GroupBy:          groupBy,
   698  		Having:           having,
   699  		Windows:          windows,
   700  	}
   701  }
   702  
   703  // UpdateSetExprsScope updates the scope of the variables in SetExprs.
   704  func UpdateSetExprsScope(setExprs SetExprs, scope Scope) SetExprs {
   705  	for _, setExpr := range setExprs {
   706  		setExpr.Var.Scope = scope
   707  	}
   708  	return setExprs
   709  }
   710  
   711  // NewSetVariable returns a variable that can be used with SET.
   712  func NewSetVariable(str string, scope Scope) *Variable {
   713  	return &Variable{Name: createIdentifierCI(str), Scope: scope}
   714  }
   715  
   716  // NewSetStatement returns a Set struct
   717  func NewSetStatement(comments *ParsedComments, exprs SetExprs) *Set {
   718  	return &Set{Exprs: exprs, Comments: comments}
   719  }
   720  
   721  // NewVariableExpression returns an expression the evaluates to a variable at runtime.
   722  // The AtCount and the prefix of the name of the variable will decide how it's evaluated
   723  func NewVariableExpression(str string, at AtCount) *Variable {
   724  	l := strings.ToLower(str)
   725  	v := &Variable{
   726  		Name: createIdentifierCI(str),
   727  	}
   728  
   729  	switch at {
   730  	case DoubleAt:
   731  		switch {
   732  		case strings.HasPrefix(l, "local."):
   733  			v.Name = createIdentifierCI(str[6:])
   734  			v.Scope = SessionScope
   735  		case strings.HasPrefix(l, "session."):
   736  			v.Name = createIdentifierCI(str[8:])
   737  			v.Scope = SessionScope
   738  		case strings.HasPrefix(l, "global."):
   739  			v.Name = createIdentifierCI(str[7:])
   740  			v.Scope = GlobalScope
   741  		case strings.HasPrefix(l, "vitess_metadata."):
   742  			v.Name = createIdentifierCI(str[16:])
   743  			v.Scope = VitessMetadataScope
   744  		case strings.HasSuffix(l, TransactionIsolationStr) || strings.HasSuffix(l, TransactionReadOnlyStr):
   745  			v.Scope = NextTxScope
   746  		default:
   747  			v.Scope = SessionScope
   748  		}
   749  	case SingleAt:
   750  		v.Scope = VariableScope
   751  	case NoAt:
   752  		panic("we should never see NoAt here")
   753  	}
   754  
   755  	return v
   756  }
   757  
   758  func createIdentifierCI(str string) IdentifierCI {
   759  	size := len(str)
   760  	if str[0] == '`' && str[size-1] == '`' {
   761  		str = str[1 : size-1]
   762  	}
   763  	return NewIdentifierCI(str)
   764  }
   765  
   766  // NewOffset creates an offset and returns it
   767  func NewOffset(v int, original Expr) *Offset {
   768  	return &Offset{V: v, Original: String(original)}
   769  }
   770  
   771  // IsEmpty returns true if the name is empty.
   772  func (node IdentifierCI) IsEmpty() bool {
   773  	return node.val == ""
   774  }
   775  
   776  // String returns the unescaped column name. It must
   777  // not be used for SQL generation. Use sqlparser.String
   778  // instead. The Stringer conformance is for usage
   779  // in templates.
   780  func (node IdentifierCI) String() string {
   781  	return node.val
   782  }
   783  
   784  // CompliantName returns a compliant id name
   785  // that can be used for a bind var.
   786  func (node IdentifierCI) CompliantName() string {
   787  	return compliantName(node.val)
   788  }
   789  
   790  // Lowered returns a lower-cased column name.
   791  // This function should generally be used only for optimizing
   792  // comparisons.
   793  func (node IdentifierCI) Lowered() string {
   794  	if node.val == "" {
   795  		return ""
   796  	}
   797  	if node.lowered == "" {
   798  		node.lowered = strings.ToLower(node.val)
   799  	}
   800  	return node.lowered
   801  }
   802  
   803  // Equal performs a case-insensitive compare.
   804  func (node IdentifierCI) Equal(in IdentifierCI) bool {
   805  	return node.Lowered() == in.Lowered()
   806  }
   807  
   808  // EqualString performs a case-insensitive compare with str.
   809  func (node IdentifierCI) EqualString(str string) bool {
   810  	return node.Lowered() == strings.ToLower(str)
   811  }
   812  
   813  // MarshalJSON marshals into JSON.
   814  func (node IdentifierCI) MarshalJSON() ([]byte, error) {
   815  	return json.Marshal(node.val)
   816  }
   817  
   818  // UnmarshalJSON unmarshals from JSON.
   819  func (node *IdentifierCI) UnmarshalJSON(b []byte) error {
   820  	var result string
   821  	err := json.Unmarshal(b, &result)
   822  	if err != nil {
   823  		return err
   824  	}
   825  	node.val = result
   826  	return nil
   827  }
   828  
   829  // NewIdentifierCS creates a new IdentifierCS.
   830  func NewIdentifierCS(str string) IdentifierCS {
   831  	// Use StringClone on the table name to ensure it is not pinned to the
   832  	// underlying query string that has been generated by the parser. This
   833  	// could lead to a significant increase in memory usage when the table
   834  	// name comes from a large query.
   835  	return IdentifierCS{v: strings.Clone(str)}
   836  }
   837  
   838  // IsEmpty returns true if TabIdent is empty.
   839  func (node IdentifierCS) IsEmpty() bool {
   840  	return node.v == ""
   841  }
   842  
   843  // String returns the unescaped table name. It must
   844  // not be used for SQL generation. Use sqlparser.String
   845  // instead. The Stringer conformance is for usage
   846  // in templates.
   847  func (node IdentifierCS) String() string {
   848  	return node.v
   849  }
   850  
   851  // CompliantName returns a compliant id name
   852  // that can be used for a bind var.
   853  func (node IdentifierCS) CompliantName() string {
   854  	return compliantName(node.v)
   855  }
   856  
   857  // MarshalJSON marshals into JSON.
   858  func (node IdentifierCS) MarshalJSON() ([]byte, error) {
   859  	return json.Marshal(node.v)
   860  }
   861  
   862  // UnmarshalJSON unmarshals from JSON.
   863  func (node *IdentifierCS) UnmarshalJSON(b []byte) error {
   864  	var result string
   865  	err := json.Unmarshal(b, &result)
   866  	if err != nil {
   867  		return err
   868  	}
   869  	node.v = result
   870  	return nil
   871  }
   872  
   873  func containEscapableChars(s string, at AtCount) bool {
   874  	isDbSystemVariable := at != NoAt
   875  
   876  	for i := range s {
   877  		c := uint16(s[i])
   878  		letter := isLetter(c)
   879  		systemVarChar := isDbSystemVariable && isCarat(c)
   880  		if !(letter || systemVarChar) {
   881  			if i == 0 || !isDigit(c) {
   882  				return true
   883  			}
   884  		}
   885  	}
   886  
   887  	return false
   888  }
   889  
   890  func formatID(buf *TrackedBuffer, original string, at AtCount) {
   891  	_, isKeyword := keywordLookupTable.LookupString(original)
   892  	if buf.escape || isKeyword || containEscapableChars(original, at) {
   893  		writeEscapedString(buf, original)
   894  	} else {
   895  		buf.WriteString(original)
   896  	}
   897  }
   898  
   899  func writeEscapedString(buf *TrackedBuffer, original string) {
   900  	buf.WriteByte('`')
   901  	for _, c := range original {
   902  		buf.WriteRune(c)
   903  		if c == '`' {
   904  			buf.WriteByte('`')
   905  		}
   906  	}
   907  	buf.WriteByte('`')
   908  }
   909  
   910  func compliantName(in string) string {
   911  	var buf strings.Builder
   912  	for i, c := range in {
   913  		if !isLetter(uint16(c)) {
   914  			if i == 0 || !isDigit(uint16(c)) {
   915  				buf.WriteByte('_')
   916  				continue
   917  			}
   918  		}
   919  		buf.WriteRune(c)
   920  	}
   921  	return buf.String()
   922  }
   923  
   924  // AddOrder adds an order by element
   925  func (node *Select) AddOrder(order *Order) {
   926  	node.OrderBy = append(node.OrderBy, order)
   927  }
   928  
   929  // SetOrderBy sets the order by clause
   930  func (node *Select) SetOrderBy(orderBy OrderBy) {
   931  	node.OrderBy = orderBy
   932  }
   933  
   934  // GetOrderBy gets the order by clause
   935  func (node *Select) GetOrderBy() OrderBy {
   936  	return node.OrderBy
   937  }
   938  
   939  // SetLimit sets the limit clause
   940  func (node *Select) SetLimit(limit *Limit) {
   941  	node.Limit = limit
   942  }
   943  
   944  // GetLimit gets the limit
   945  func (node *Select) GetLimit() *Limit {
   946  	return node.Limit
   947  }
   948  
   949  // SetLock sets the lock clause
   950  func (node *Select) SetLock(lock Lock) {
   951  	node.Lock = lock
   952  }
   953  
   954  // SetInto sets the into clause
   955  func (node *Select) SetInto(into *SelectInto) {
   956  	node.Into = into
   957  }
   958  
   959  // SetWith sets the with clause to a select statement
   960  func (node *Select) SetWith(with *With) {
   961  	node.With = with
   962  }
   963  
   964  // MakeDistinct makes the statement distinct
   965  func (node *Select) MakeDistinct() {
   966  	node.Distinct = true
   967  }
   968  
   969  // GetColumnCount return SelectExprs count.
   970  func (node *Select) GetColumnCount() int {
   971  	return len(node.SelectExprs)
   972  }
   973  
   974  // GetColumns gets the columns
   975  func (node *Select) GetColumns() SelectExprs {
   976  	return node.SelectExprs
   977  }
   978  
   979  // SetComments implements the SelectStatement interface
   980  func (node *Select) SetComments(comments Comments) {
   981  	node.Comments = comments.Parsed()
   982  }
   983  
   984  // GetComments implements the SelectStatement interface
   985  func (node *Select) GetParsedComments() *ParsedComments {
   986  	return node.Comments
   987  }
   988  
   989  // AddWhere adds the boolean expression to the
   990  // WHERE clause as an AND condition.
   991  func (node *Select) AddWhere(expr Expr) {
   992  	if node.Where == nil {
   993  		node.Where = &Where{
   994  			Type: WhereClause,
   995  			Expr: expr,
   996  		}
   997  		return
   998  	}
   999  	exprs := SplitAndExpression(nil, node.Where.Expr)
  1000  	node.Where.Expr = AndExpressions(append(exprs, expr)...)
  1001  }
  1002  
  1003  // AddHaving adds the boolean expression to the
  1004  // HAVING clause as an AND condition.
  1005  func (node *Select) AddHaving(expr Expr) {
  1006  	if node.Having == nil {
  1007  		node.Having = &Where{
  1008  			Type: HavingClause,
  1009  			Expr: expr,
  1010  		}
  1011  		return
  1012  	}
  1013  	node.Having.Expr = &AndExpr{
  1014  		Left:  node.Having.Expr,
  1015  		Right: expr,
  1016  	}
  1017  }
  1018  
  1019  // AddGroupBy adds a grouping expression, unless it's already present
  1020  func (node *Select) AddGroupBy(expr Expr) {
  1021  	for _, gb := range node.GroupBy {
  1022  		if Equals.Expr(gb, expr) {
  1023  			// group by columns are sets - duplicates don't add anything, so we can just skip these
  1024  			return
  1025  		}
  1026  	}
  1027  	node.GroupBy = append(node.GroupBy, expr)
  1028  }
  1029  
  1030  // AddWhere adds the boolean expression to the
  1031  // WHERE clause as an AND condition.
  1032  func (node *Update) AddWhere(expr Expr) {
  1033  	if node.Where == nil {
  1034  		node.Where = &Where{
  1035  			Type: WhereClause,
  1036  			Expr: expr,
  1037  		}
  1038  		return
  1039  	}
  1040  	node.Where.Expr = &AndExpr{
  1041  		Left:  node.Where.Expr,
  1042  		Right: expr,
  1043  	}
  1044  }
  1045  
  1046  // AddOrder adds an order by element
  1047  func (node *Union) AddOrder(order *Order) {
  1048  	node.OrderBy = append(node.OrderBy, order)
  1049  }
  1050  
  1051  // SetOrderBy sets the order by clause
  1052  func (node *Union) SetOrderBy(orderBy OrderBy) {
  1053  	node.OrderBy = orderBy
  1054  }
  1055  
  1056  // GetOrderBy gets the order by clause
  1057  func (node *Union) GetOrderBy() OrderBy {
  1058  	return node.OrderBy
  1059  }
  1060  
  1061  // SetLimit sets the limit clause
  1062  func (node *Union) SetLimit(limit *Limit) {
  1063  	node.Limit = limit
  1064  }
  1065  
  1066  // GetLimit gets the limit
  1067  func (node *Union) GetLimit() *Limit {
  1068  	return node.Limit
  1069  }
  1070  
  1071  // GetColumns gets the columns
  1072  func (node *Union) GetColumns() SelectExprs {
  1073  	return node.Left.GetColumns()
  1074  }
  1075  
  1076  // SetLock sets the lock clause
  1077  func (node *Union) SetLock(lock Lock) {
  1078  	node.Lock = lock
  1079  }
  1080  
  1081  // SetInto sets the into clause
  1082  func (node *Union) SetInto(into *SelectInto) {
  1083  	node.Into = into
  1084  }
  1085  
  1086  // SetWith sets the with clause to a union statement
  1087  func (node *Union) SetWith(with *With) {
  1088  	node.With = with
  1089  }
  1090  
  1091  // MakeDistinct implements the SelectStatement interface
  1092  func (node *Union) MakeDistinct() {
  1093  	node.Distinct = true
  1094  }
  1095  
  1096  // GetColumnCount implements the SelectStatement interface
  1097  func (node *Union) GetColumnCount() int {
  1098  	return node.Left.GetColumnCount()
  1099  }
  1100  
  1101  // SetComments implements the SelectStatement interface
  1102  func (node *Union) SetComments(comments Comments) {
  1103  	node.Left.SetComments(comments)
  1104  }
  1105  
  1106  // GetComments implements the SelectStatement interface
  1107  func (node *Union) GetParsedComments() *ParsedComments {
  1108  	return node.Left.GetParsedComments()
  1109  }
  1110  
  1111  func requiresParen(stmt SelectStatement) bool {
  1112  	switch node := stmt.(type) {
  1113  	case *Union:
  1114  		return len(node.OrderBy) != 0 || node.Lock != 0 || node.Into != nil || node.Limit != nil
  1115  	case *Select:
  1116  		return len(node.OrderBy) != 0 || node.Lock != 0 || node.Into != nil || node.Limit != nil
  1117  	}
  1118  
  1119  	return false
  1120  }
  1121  
  1122  func setLockInSelect(stmt SelectStatement, lock Lock) {
  1123  	stmt.SetLock(lock)
  1124  }
  1125  
  1126  // ToString returns the string associated with the DDLAction Enum
  1127  func (action DDLAction) ToString() string {
  1128  	switch action {
  1129  	case CreateDDLAction:
  1130  		return CreateStr
  1131  	case AlterDDLAction:
  1132  		return AlterStr
  1133  	case DropDDLAction:
  1134  		return DropStr
  1135  	case RenameDDLAction:
  1136  		return RenameStr
  1137  	case TruncateDDLAction:
  1138  		return TruncateStr
  1139  	case CreateVindexDDLAction:
  1140  		return CreateVindexStr
  1141  	case DropVindexDDLAction:
  1142  		return DropVindexStr
  1143  	case AddVschemaTableDDLAction:
  1144  		return AddVschemaTableStr
  1145  	case DropVschemaTableDDLAction:
  1146  		return DropVschemaTableStr
  1147  	case AddColVindexDDLAction:
  1148  		return AddColVindexStr
  1149  	case DropColVindexDDLAction:
  1150  		return DropColVindexStr
  1151  	case AddSequenceDDLAction:
  1152  		return AddSequenceStr
  1153  	case AddAutoIncDDLAction:
  1154  		return AddAutoIncStr
  1155  	default:
  1156  		return "Unknown DDL Action"
  1157  	}
  1158  }
  1159  
  1160  // ToString returns the string associated with the Scope enum
  1161  func (scope Scope) ToString() string {
  1162  	switch scope {
  1163  	case SessionScope:
  1164  		return SessionStr
  1165  	case GlobalScope:
  1166  		return GlobalStr
  1167  	case VitessMetadataScope:
  1168  		return VitessMetadataStr
  1169  	case VariableScope:
  1170  		return VariableStr
  1171  	case NoScope, NextTxScope:
  1172  		return ""
  1173  	default:
  1174  		return "Unknown Scope"
  1175  	}
  1176  }
  1177  
  1178  // ToString returns the IgnoreStr if ignore is true.
  1179  func (ignore Ignore) ToString() string {
  1180  	if ignore {
  1181  		return IgnoreStr
  1182  	}
  1183  	return ""
  1184  }
  1185  
  1186  // ToString returns the string associated with the type of lock
  1187  func (lock Lock) ToString() string {
  1188  	switch lock {
  1189  	case NoLock:
  1190  		return NoLockStr
  1191  	case ForUpdateLock:
  1192  		return ForUpdateStr
  1193  	case ShareModeLock:
  1194  		return ShareModeStr
  1195  	default:
  1196  		return "Unknown lock"
  1197  	}
  1198  }
  1199  
  1200  // ToString returns the string associated with WhereType
  1201  func (whereType WhereType) ToString() string {
  1202  	switch whereType {
  1203  	case WhereClause:
  1204  		return WhereStr
  1205  	case HavingClause:
  1206  		return HavingStr
  1207  	default:
  1208  		return "Unknown where type"
  1209  	}
  1210  }
  1211  
  1212  // ToString returns the string associated with JoinType
  1213  func (joinType JoinType) ToString() string {
  1214  	switch joinType {
  1215  	case NormalJoinType:
  1216  		return JoinStr
  1217  	case StraightJoinType:
  1218  		return StraightJoinStr
  1219  	case LeftJoinType:
  1220  		return LeftJoinStr
  1221  	case RightJoinType:
  1222  		return RightJoinStr
  1223  	case NaturalJoinType:
  1224  		return NaturalJoinStr
  1225  	case NaturalLeftJoinType:
  1226  		return NaturalLeftJoinStr
  1227  	case NaturalRightJoinType:
  1228  		return NaturalRightJoinStr
  1229  	default:
  1230  		return "Unknown join type"
  1231  	}
  1232  }
  1233  
  1234  // ToString returns the operator as a string
  1235  func (op ComparisonExprOperator) ToString() string {
  1236  	switch op {
  1237  	case EqualOp:
  1238  		return EqualStr
  1239  	case LessThanOp:
  1240  		return LessThanStr
  1241  	case GreaterThanOp:
  1242  		return GreaterThanStr
  1243  	case LessEqualOp:
  1244  		return LessEqualStr
  1245  	case GreaterEqualOp:
  1246  		return GreaterEqualStr
  1247  	case NotEqualOp:
  1248  		return NotEqualStr
  1249  	case NullSafeEqualOp:
  1250  		return NullSafeEqualStr
  1251  	case InOp:
  1252  		return InStr
  1253  	case NotInOp:
  1254  		return NotInStr
  1255  	case LikeOp:
  1256  		return LikeStr
  1257  	case NotLikeOp:
  1258  		return NotLikeStr
  1259  	case RegexpOp:
  1260  		return RegexpStr
  1261  	case NotRegexpOp:
  1262  		return NotRegexpStr
  1263  	default:
  1264  		return "Unknown ComparisonExpOperator"
  1265  	}
  1266  }
  1267  
  1268  // ToString returns the operator as a string
  1269  func (op IsExprOperator) ToString() string {
  1270  	switch op {
  1271  	case IsNullOp:
  1272  		return IsNullStr
  1273  	case IsNotNullOp:
  1274  		return IsNotNullStr
  1275  	case IsTrueOp:
  1276  		return IsTrueStr
  1277  	case IsNotTrueOp:
  1278  		return IsNotTrueStr
  1279  	case IsFalseOp:
  1280  		return IsFalseStr
  1281  	case IsNotFalseOp:
  1282  		return IsNotFalseStr
  1283  	default:
  1284  		return "Unknown IsExprOperator"
  1285  	}
  1286  }
  1287  
  1288  // ToString returns the operator as a string
  1289  func (op BinaryExprOperator) ToString() string {
  1290  	switch op {
  1291  	case BitAndOp:
  1292  		return BitAndStr
  1293  	case BitOrOp:
  1294  		return BitOrStr
  1295  	case BitXorOp:
  1296  		return BitXorStr
  1297  	case PlusOp:
  1298  		return PlusStr
  1299  	case MinusOp:
  1300  		return MinusStr
  1301  	case MultOp:
  1302  		return MultStr
  1303  	case DivOp:
  1304  		return DivStr
  1305  	case IntDivOp:
  1306  		return IntDivStr
  1307  	case ModOp:
  1308  		return ModStr
  1309  	case ShiftLeftOp:
  1310  		return ShiftLeftStr
  1311  	case ShiftRightOp:
  1312  		return ShiftRightStr
  1313  	case JSONExtractOp:
  1314  		return JSONExtractOpStr
  1315  	case JSONUnquoteExtractOp:
  1316  		return JSONUnquoteExtractOpStr
  1317  	default:
  1318  		return "Unknown BinaryExprOperator"
  1319  	}
  1320  }
  1321  
  1322  // ToString returns the partition type as a string
  1323  func (partitionType PartitionByType) ToString() string {
  1324  	switch partitionType {
  1325  	case HashType:
  1326  		return HashTypeStr
  1327  	case KeyType:
  1328  		return KeyTypeStr
  1329  	case ListType:
  1330  		return ListTypeStr
  1331  	case RangeType:
  1332  		return RangeTypeStr
  1333  	default:
  1334  		return "Unknown PartitionByType"
  1335  	}
  1336  }
  1337  
  1338  // ToString returns the partition value range type as a string
  1339  func (t PartitionValueRangeType) ToString() string {
  1340  	switch t {
  1341  	case LessThanType:
  1342  		return LessThanTypeStr
  1343  	case InType:
  1344  		return InTypeStr
  1345  	default:
  1346  		return "Unknown PartitionValueRangeType"
  1347  	}
  1348  }
  1349  
  1350  // ToString returns the operator as a string
  1351  func (op UnaryExprOperator) ToString() string {
  1352  	switch op {
  1353  	case UPlusOp:
  1354  		return UPlusStr
  1355  	case UMinusOp:
  1356  		return UMinusStr
  1357  	case TildaOp:
  1358  		return TildaStr
  1359  	case BangOp:
  1360  		return BangStr
  1361  	case NStringOp:
  1362  		return NStringStr
  1363  	default:
  1364  		return "Unknown UnaryExprOperator"
  1365  	}
  1366  }
  1367  
  1368  // ToString returns the option as a string
  1369  func (option MatchExprOption) ToString() string {
  1370  	switch option {
  1371  	case NoOption:
  1372  		return NoOptionStr
  1373  	case BooleanModeOpt:
  1374  		return BooleanModeStr
  1375  	case NaturalLanguageModeOpt:
  1376  		return NaturalLanguageModeStr
  1377  	case NaturalLanguageModeWithQueryExpansionOpt:
  1378  		return NaturalLanguageModeWithQueryExpansionStr
  1379  	case QueryExpansionOpt:
  1380  		return QueryExpansionStr
  1381  	default:
  1382  		return "Unknown MatchExprOption"
  1383  	}
  1384  }
  1385  
  1386  // ToString returns the direction as a string
  1387  func (dir OrderDirection) ToString() string {
  1388  	switch dir {
  1389  	case AscOrder:
  1390  		return AscScr
  1391  	case DescOrder:
  1392  		return DescScr
  1393  	default:
  1394  		return "Unknown OrderDirection"
  1395  	}
  1396  }
  1397  
  1398  // ToString returns the type as a string
  1399  func (ty IndexHintType) ToString() string {
  1400  	switch ty {
  1401  	case UseOp:
  1402  		return UseStr
  1403  	case IgnoreOp:
  1404  		return IgnoreStr
  1405  	case ForceOp:
  1406  		return ForceStr
  1407  	default:
  1408  		return "Unknown IndexHintType"
  1409  	}
  1410  }
  1411  
  1412  // ToString returns the type as a string
  1413  func (ty DeallocateStmtType) ToString() string {
  1414  	switch ty {
  1415  	case DeallocateType:
  1416  		return DeallocateStr
  1417  	case DropType:
  1418  		return DropStr
  1419  	default:
  1420  		return "Unknown Deallocate Statement Type"
  1421  	}
  1422  }
  1423  
  1424  // ToString returns the type as a string
  1425  func (ty IndexHintForType) ToString() string {
  1426  	switch ty {
  1427  	case NoForType:
  1428  		return ""
  1429  	case JoinForType:
  1430  		return JoinForStr
  1431  	case GroupByForType:
  1432  		return GroupByForStr
  1433  	case OrderByForType:
  1434  		return OrderByForStr
  1435  	default:
  1436  		return "Unknown IndexHintForType"
  1437  	}
  1438  }
  1439  
  1440  // ToString returns the type as a string
  1441  func (ty TrimFuncType) ToString() string {
  1442  	switch ty {
  1443  	case NormalTrimType:
  1444  		return NormalTrimStr
  1445  	case LTrimType:
  1446  		return LTrimStr
  1447  	case RTrimType:
  1448  		return RTrimStr
  1449  	default:
  1450  		return "Unknown TrimFuncType"
  1451  	}
  1452  }
  1453  
  1454  // ToString returns the type as a string
  1455  func (ty TrimType) ToString() string {
  1456  	switch ty {
  1457  	case NoTrimType:
  1458  		return ""
  1459  	case BothTrimType:
  1460  		return BothTrimStr
  1461  	case LeadingTrimType:
  1462  		return LeadingTrimStr
  1463  	case TrailingTrimType:
  1464  		return TrailingTrimStr
  1465  	default:
  1466  		return "Unknown TrimType"
  1467  	}
  1468  }
  1469  
  1470  // ToString returns the type as a string
  1471  func (ty FrameUnitType) ToString() string {
  1472  	switch ty {
  1473  	case FrameRowsType:
  1474  		return FrameRowsStr
  1475  	case FrameRangeType:
  1476  		return FrameRangeStr
  1477  	default:
  1478  		return "Unknown FrameUnitType"
  1479  	}
  1480  }
  1481  
  1482  // ToString returns the type as a string
  1483  func (ty FramePointType) ToString() string {
  1484  	switch ty {
  1485  	case CurrentRowType:
  1486  		return CurrentRowStr
  1487  	case UnboundedPrecedingType:
  1488  		return UnboundedPrecedingStr
  1489  	case UnboundedFollowingType:
  1490  		return UnboundedFollowingStr
  1491  	case ExprPrecedingType:
  1492  		return ExprPrecedingStr
  1493  	case ExprFollowingType:
  1494  		return ExprFollowingStr
  1495  	default:
  1496  		return "Unknown FramePointType"
  1497  	}
  1498  }
  1499  
  1500  // ToString returns the type as a string
  1501  func (ty ArgumentLessWindowExprType) ToString() string {
  1502  	switch ty {
  1503  	case CumeDistExprType:
  1504  		return CumeDistExprStr
  1505  	case DenseRankExprType:
  1506  		return DenseRankExprStr
  1507  	case PercentRankExprType:
  1508  		return PercentRankExprStr
  1509  	case RankExprType:
  1510  		return RankExprStr
  1511  	case RowNumberExprType:
  1512  		return RowNumberExprStr
  1513  	default:
  1514  		return "Unknown ArgumentLessWindowExprType"
  1515  	}
  1516  }
  1517  
  1518  // ToString returns the type as a string
  1519  func (ty NullTreatmentType) ToString() string {
  1520  	switch ty {
  1521  	case RespectNullsType:
  1522  		return RespectNullsStr
  1523  	case IgnoreNullsType:
  1524  		return IgnoreNullsStr
  1525  	default:
  1526  		return "Unknown NullTreatmentType"
  1527  	}
  1528  }
  1529  
  1530  // ToString returns the type as a string
  1531  func (ty FromFirstLastType) ToString() string {
  1532  	switch ty {
  1533  	case FromFirstType:
  1534  		return FromFirstStr
  1535  	case FromLastType:
  1536  		return FromLastStr
  1537  	default:
  1538  		return "Unknown FromFirstLastType"
  1539  	}
  1540  }
  1541  
  1542  // ToString returns the type as a string
  1543  func (ty FirstOrLastValueExprType) ToString() string {
  1544  	switch ty {
  1545  	case FirstValueExprType:
  1546  		return FirstValueExprStr
  1547  	case LastValueExprType:
  1548  		return LastValueExprStr
  1549  	default:
  1550  		return "Unknown FirstOrLastValueExprType"
  1551  	}
  1552  }
  1553  
  1554  // ToString returns the type as a string
  1555  func (ty LagLeadExprType) ToString() string {
  1556  	switch ty {
  1557  	case LagExprType:
  1558  		return LagExprStr
  1559  	case LeadExprType:
  1560  		return LeadExprStr
  1561  	default:
  1562  		return "Unknown LagLeadExprType"
  1563  	}
  1564  }
  1565  
  1566  // ToString returns the type as a string
  1567  func (ty JSONAttributeType) ToString() string {
  1568  	switch ty {
  1569  	case DepthAttributeType:
  1570  		return DepthAttributeStr
  1571  	case ValidAttributeType:
  1572  		return ValidAttributeStr
  1573  	case TypeAttributeType:
  1574  		return TypeAttributeStr
  1575  	case LengthAttributeType:
  1576  		return LengthAttributeStr
  1577  	default:
  1578  		return "Unknown JSONAttributeType"
  1579  	}
  1580  }
  1581  
  1582  // ToString returns the type as a string
  1583  func (ty JSONValueModifierType) ToString() string {
  1584  	switch ty {
  1585  	case JSONArrayAppendType:
  1586  		return JSONArrayAppendStr
  1587  	case JSONArrayInsertType:
  1588  		return JSONArrayInsertStr
  1589  	case JSONInsertType:
  1590  		return JSONInsertStr
  1591  	case JSONReplaceType:
  1592  		return JSONReplaceStr
  1593  	case JSONSetType:
  1594  		return JSONSetStr
  1595  	default:
  1596  		return "Unknown JSONValueModifierType"
  1597  	}
  1598  }
  1599  
  1600  // ToString returns the type as a string
  1601  func (ty JSONValueMergeType) ToString() string {
  1602  	switch ty {
  1603  	case JSONMergeType:
  1604  		return JSONMergeStr
  1605  	case JSONMergePatchType:
  1606  		return JSONMergePatchStr
  1607  	case JSONMergePreserveType:
  1608  		return JSONMergePreserveStr
  1609  	default:
  1610  		return "Unknown JSONValueMergeType"
  1611  	}
  1612  }
  1613  
  1614  // ToString returns the type as a string
  1615  func (ty LockingFuncType) ToString() string {
  1616  	switch ty {
  1617  	case GetLock:
  1618  		return GetLockStr
  1619  	case IsFreeLock:
  1620  		return IsFreeLockStr
  1621  	case IsUsedLock:
  1622  		return IsUsedLockStr
  1623  	case ReleaseAllLocks:
  1624  		return ReleaseAllLocksStr
  1625  	case ReleaseLock:
  1626  		return ReleaseLockStr
  1627  	default:
  1628  		return "Unknown LockingFuncType"
  1629  	}
  1630  }
  1631  
  1632  // ToString returns the type as a string
  1633  func (ty PerformanceSchemaType) ToString() string {
  1634  	switch ty {
  1635  	case FormatBytesType:
  1636  		return FormatBytesStr
  1637  	case FormatPicoTimeType:
  1638  		return FormatPicoTimeStr
  1639  	case PsCurrentThreadIDType:
  1640  		return PsCurrentThreadIDStr
  1641  	case PsThreadIDType:
  1642  		return PsThreadIDStr
  1643  	default:
  1644  		return "Unknown PerformaceSchemaType"
  1645  	}
  1646  }
  1647  
  1648  // ToString returns the type as a string
  1649  func (ty GTIDType) ToString() string {
  1650  	switch ty {
  1651  	case GTIDSubsetType:
  1652  		return GTIDSubsetStr
  1653  	case GTIDSubtractType:
  1654  		return GTIDSubtractStr
  1655  	case WaitForExecutedGTIDSetType:
  1656  		return WaitForExecutedGTIDSetStr
  1657  	case WaitUntilSQLThreadAfterGTIDSType:
  1658  		return WaitUntilSQLThreadAfterGTIDSStr
  1659  	default:
  1660  		return "Unknown GTIDType"
  1661  	}
  1662  }
  1663  
  1664  // ToString returns the type as a string
  1665  func (ty ExplainType) ToString() string {
  1666  	switch ty {
  1667  	case EmptyType:
  1668  		return EmptyStr
  1669  	case TreeType:
  1670  		return TreeStr
  1671  	case JSONType:
  1672  		return JSONStr
  1673  	case VitessType:
  1674  		return VitessStr
  1675  	case VTExplainType:
  1676  		return VTExplainStr
  1677  	case TraditionalType:
  1678  		return TraditionalStr
  1679  	case AnalyzeType:
  1680  		return AnalyzeStr
  1681  	default:
  1682  		return "Unknown ExplainType"
  1683  	}
  1684  }
  1685  
  1686  // ToString returns the type as a string
  1687  func (ty VExplainType) ToString() string {
  1688  	switch ty {
  1689  	case PlanVExplainType:
  1690  		return PlanStr
  1691  	case QueriesVExplainType:
  1692  		return QueriesStr
  1693  	case AllVExplainType:
  1694  		return AllVExplainStr
  1695  	default:
  1696  		return "Unknown VExplainType"
  1697  	}
  1698  }
  1699  
  1700  // ToString returns the type as a string
  1701  func (ty IntervalTypes) ToString() string {
  1702  	switch ty {
  1703  	case IntervalYear:
  1704  		return YearStr
  1705  	case IntervalQuarter:
  1706  		return QuarterStr
  1707  	case IntervalMonth:
  1708  		return MonthStr
  1709  	case IntervalWeek:
  1710  		return WeekStr
  1711  	case IntervalDay:
  1712  		return DayStr
  1713  	case IntervalHour:
  1714  		return HourStr
  1715  	case IntervalMinute:
  1716  		return MinuteStr
  1717  	case IntervalSecond:
  1718  		return SecondStr
  1719  	case IntervalMicrosecond:
  1720  		return MicrosecondStr
  1721  	case IntervalYearMonth:
  1722  		return YearMonthStr
  1723  	case IntervalDayHour:
  1724  		return DayHourStr
  1725  	case IntervalDayMinute:
  1726  		return DayMinuteStr
  1727  	case IntervalDaySecond:
  1728  		return DaySecondStr
  1729  	case IntervalHourMinute:
  1730  		return HourMinuteStr
  1731  	case IntervalHourSecond:
  1732  		return HourSecondStr
  1733  	case IntervalMinuteSecond:
  1734  		return MinuteSecondStr
  1735  	case IntervalDayMicrosecond:
  1736  		return DayMicrosecondStr
  1737  	case IntervalHourMicrosecond:
  1738  		return HourMicrosecondStr
  1739  	case IntervalMinuteMicrosecond:
  1740  		return MinuteMicrosecondStr
  1741  	case IntervalSecondMicrosecond:
  1742  		return SecondMicrosecondStr
  1743  	default:
  1744  		return "Unknown IntervalType"
  1745  	}
  1746  }
  1747  
  1748  // ToString returns the type as a string
  1749  func (sel SelectIntoType) ToString() string {
  1750  	switch sel {
  1751  	case IntoOutfile:
  1752  		return IntoOutfileStr
  1753  	case IntoOutfileS3:
  1754  		return IntoOutfileS3Str
  1755  	case IntoDumpfile:
  1756  		return IntoDumpfileStr
  1757  	default:
  1758  		return "Unknown Select Into Type"
  1759  	}
  1760  }
  1761  
  1762  // ToString returns the type as a string
  1763  func (node DatabaseOptionType) ToString() string {
  1764  	switch node {
  1765  	case CharacterSetType:
  1766  		return CharacterSetStr
  1767  	case CollateType:
  1768  		return CollateStr
  1769  	case EncryptionType:
  1770  		return EncryptionStr
  1771  	default:
  1772  		return "Unknown DatabaseOptionType Type"
  1773  	}
  1774  }
  1775  
  1776  // ToString returns the type as a string
  1777  func (ty LockType) ToString() string {
  1778  	switch ty {
  1779  	case Read:
  1780  		return ReadStr
  1781  	case ReadLocal:
  1782  		return ReadLocalStr
  1783  	case Write:
  1784  		return WriteStr
  1785  	case LowPriorityWrite:
  1786  		return LowPriorityWriteStr
  1787  	default:
  1788  		return "Unknown LockType"
  1789  	}
  1790  }
  1791  
  1792  // ToString returns ShowCommandType as a string
  1793  func (ty ShowCommandType) ToString() string {
  1794  	switch ty {
  1795  	case Charset:
  1796  		return CharsetStr
  1797  	case Collation:
  1798  		return CollationStr
  1799  	case Column:
  1800  		return ColumnStr
  1801  	case CreateDb:
  1802  		return CreateDbStr
  1803  	case CreateE:
  1804  		return CreateEStr
  1805  	case CreateF:
  1806  		return CreateFStr
  1807  	case CreateProc:
  1808  		return CreateProcStr
  1809  	case CreateTbl:
  1810  		return CreateTblStr
  1811  	case CreateTr:
  1812  		return CreateTrStr
  1813  	case CreateV:
  1814  		return CreateVStr
  1815  	case Database:
  1816  		return DatabaseStr
  1817  	case Engines:
  1818  		return EnginesStr
  1819  	case FunctionC:
  1820  		return FunctionCStr
  1821  	case Function:
  1822  		return FunctionStr
  1823  	case GtidExecGlobal:
  1824  		return GtidExecGlobalStr
  1825  	case Index:
  1826  		return IndexStr
  1827  	case OpenTable:
  1828  		return OpenTableStr
  1829  	case Plugins:
  1830  		return PluginsStr
  1831  	case Privilege:
  1832  		return PrivilegeStr
  1833  	case ProcedureC:
  1834  		return ProcedureCStr
  1835  	case Procedure:
  1836  		return ProcedureStr
  1837  	case StatusGlobal:
  1838  		return StatusGlobalStr
  1839  	case StatusSession:
  1840  		return StatusSessionStr
  1841  	case Table:
  1842  		return TablesStr
  1843  	case TableStatus:
  1844  		return TableStatusStr
  1845  	case Trigger:
  1846  		return TriggerStr
  1847  	case VariableGlobal:
  1848  		return VariableGlobalStr
  1849  	case VariableSession:
  1850  		return VariableSessionStr
  1851  	case VGtidExecGlobal:
  1852  		return VGtidExecGlobalStr
  1853  	case VitessMigrations:
  1854  		return VitessMigrationsStr
  1855  	case VitessReplicationStatus:
  1856  		return VitessReplicationStatusStr
  1857  	case VitessShards:
  1858  		return VitessShardsStr
  1859  	case VitessTablets:
  1860  		return VitessTabletsStr
  1861  	case VitessTarget:
  1862  		return VitessTargetStr
  1863  	case VitessVariables:
  1864  		return VitessVariablesStr
  1865  	case VschemaTables:
  1866  		return VschemaTablesStr
  1867  	case VschemaVindexes:
  1868  		return VschemaVindexesStr
  1869  	case Warnings:
  1870  		return WarningsStr
  1871  	case Keyspace:
  1872  		return KeyspaceStr
  1873  	default:
  1874  		return "" +
  1875  			"Unknown ShowCommandType"
  1876  	}
  1877  }
  1878  
  1879  // ToString returns the DropKeyType as a string
  1880  func (key DropKeyType) ToString() string {
  1881  	switch key {
  1882  	case PrimaryKeyType:
  1883  		return PrimaryKeyTypeStr
  1884  	case ForeignKeyType:
  1885  		return ForeignKeyTypeStr
  1886  	case NormalKeyType:
  1887  		return NormalKeyTypeStr
  1888  	case CheckKeyType:
  1889  		return CheckKeyTypeStr
  1890  	default:
  1891  		return "Unknown DropKeyType"
  1892  	}
  1893  }
  1894  
  1895  // ToString returns the LockOptionType as a string
  1896  func (lock LockOptionType) ToString() string {
  1897  	switch lock {
  1898  	case NoneType:
  1899  		return NoneTypeStr
  1900  	case DefaultType:
  1901  		return DefaultTypeStr
  1902  	case SharedType:
  1903  		return SharedTypeStr
  1904  	case ExclusiveType:
  1905  		return ExclusiveTypeStr
  1906  	default:
  1907  		return "Unknown type LockOptionType"
  1908  	}
  1909  }
  1910  
  1911  // ToString returns the string associated with JoinType
  1912  func (columnFormat ColumnFormat) ToString() string {
  1913  	switch columnFormat {
  1914  	case FixedFormat:
  1915  		return keywordStrings[FIXED]
  1916  	case DynamicFormat:
  1917  		return keywordStrings[DYNAMIC]
  1918  	case DefaultFormat:
  1919  		return keywordStrings[DEFAULT]
  1920  	default:
  1921  		return "Unknown column format type"
  1922  	}
  1923  }
  1924  
  1925  // ToString returns the TxAccessMode type as a string
  1926  func (ty TxAccessMode) ToString() string {
  1927  	switch ty {
  1928  	case WithConsistentSnapshot:
  1929  		return WithConsistentSnapshotStr
  1930  	case ReadWrite:
  1931  		return ReadWriteStr
  1932  	case ReadOnly:
  1933  		return ReadOnlyStr
  1934  	default:
  1935  		return "Unknown Transaction Access Mode"
  1936  	}
  1937  }
  1938  
  1939  // CompliantName is used to get the name of the bind variable to use for this column name
  1940  func (node *ColName) CompliantName() string {
  1941  	if !node.Qualifier.IsEmpty() {
  1942  		return node.Qualifier.Name.CompliantName() + "_" + node.Name.CompliantName()
  1943  	}
  1944  	return node.Name.CompliantName()
  1945  }
  1946  
  1947  // isExprAliasForCurrentTimeStamp returns true if the Expr provided is an alias for CURRENT_TIMESTAMP
  1948  func isExprAliasForCurrentTimeStamp(expr Expr) bool {
  1949  	switch node := expr.(type) {
  1950  	case *FuncExpr:
  1951  		return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
  1952  	case *CurTimeFuncExpr:
  1953  		return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
  1954  	}
  1955  	return false
  1956  }
  1957  
  1958  // AtCount represents the '@' count in IdentifierCI
  1959  type AtCount int
  1960  
  1961  const (
  1962  	// NoAt represents no @
  1963  	NoAt AtCount = iota
  1964  	// SingleAt represents @
  1965  	SingleAt
  1966  	// DoubleAt represents @@
  1967  	DoubleAt
  1968  )
  1969  
  1970  // encodeSQLString encodes the string as a SQL string.
  1971  func encodeSQLString(val string) string {
  1972  	return sqltypes.EncodeStringSQL(val)
  1973  }
  1974  
  1975  // ToString prints the list of table expressions as a string
  1976  // To be used as an alternate for String for []TableExpr
  1977  func ToString(exprs []TableExpr) string {
  1978  	buf := NewTrackedBuffer(nil)
  1979  	prefix := ""
  1980  	for _, expr := range exprs {
  1981  		buf.astPrintf(nil, "%s%v", prefix, expr)
  1982  		prefix = ", "
  1983  	}
  1984  	return buf.String()
  1985  }
  1986  
  1987  func formatIdentifier(id string) string {
  1988  	buf := NewTrackedBuffer(nil)
  1989  	formatID(buf, id, NoAt)
  1990  	return buf.String()
  1991  }
  1992  
  1993  func formatAddress(address string) string {
  1994  	if len(address) > 0 && address[0] == '\'' {
  1995  		return address
  1996  	}
  1997  	buf := NewTrackedBuffer(nil)
  1998  	formatID(buf, address, NoAt)
  1999  	return buf.String()
  2000  }
  2001  
  2002  // ContainsAggregation returns true if the expression contains aggregation
  2003  func ContainsAggregation(e SQLNode) bool {
  2004  	hasAggregates := false
  2005  	_ = Walk(func(node SQLNode) (kontinue bool, err error) {
  2006  		if _, isAggregate := node.(AggrFunc); isAggregate {
  2007  			hasAggregates = true
  2008  			return false, nil
  2009  		}
  2010  		return true, nil
  2011  	}, e)
  2012  	return hasAggregates
  2013  }
  2014  
  2015  // GetFirstSelect gets the first select statement
  2016  func GetFirstSelect(selStmt SelectStatement) *Select {
  2017  	if selStmt == nil {
  2018  		return nil
  2019  	}
  2020  	switch node := selStmt.(type) {
  2021  	case *Select:
  2022  		return node
  2023  	case *Union:
  2024  		return GetFirstSelect(node.Left)
  2025  	}
  2026  	panic("[BUG]: unknown type for SelectStatement")
  2027  }
  2028  
  2029  // GetAllSelects gets all the select statement s
  2030  func GetAllSelects(selStmt SelectStatement) []*Select {
  2031  	switch node := selStmt.(type) {
  2032  	case *Select:
  2033  		return []*Select{node}
  2034  	case *Union:
  2035  		return append(GetAllSelects(node.Left), GetAllSelects(node.Right)...)
  2036  	}
  2037  	panic("[BUG]: unknown type for SelectStatement")
  2038  }
  2039  
  2040  // SetArgName sets argument name.
  2041  func (es *ExtractedSubquery) SetArgName(n string) {
  2042  	es.argName = n
  2043  	es.updateAlternative()
  2044  }
  2045  
  2046  // SetHasValuesArg sets has_values argument.
  2047  func (es *ExtractedSubquery) SetHasValuesArg(n string) {
  2048  	es.hasValuesArg = n
  2049  	es.updateAlternative()
  2050  }
  2051  
  2052  // GetArgName returns argument name.
  2053  func (es *ExtractedSubquery) GetArgName() string {
  2054  	return es.argName
  2055  }
  2056  
  2057  // GetHasValuesArg returns has values argument.
  2058  func (es *ExtractedSubquery) GetHasValuesArg() string {
  2059  	return es.hasValuesArg
  2060  
  2061  }
  2062  
  2063  func (es *ExtractedSubquery) updateAlternative() {
  2064  	switch original := es.Original.(type) {
  2065  	case *ExistsExpr:
  2066  		es.alternative = NewArgument(es.hasValuesArg)
  2067  	case *Subquery:
  2068  		es.alternative = NewArgument(es.argName)
  2069  	case *ComparisonExpr:
  2070  		// other_side = :__sq
  2071  		cmp := &ComparisonExpr{
  2072  			Left:     es.OtherSide,
  2073  			Right:    NewArgument(es.argName),
  2074  			Operator: original.Operator,
  2075  		}
  2076  		var expr Expr = cmp
  2077  		switch original.Operator {
  2078  		case InOp:
  2079  			// :__sq_has_values = 1 and other_side in ::__sq
  2080  			cmp.Right = NewListArg(es.argName)
  2081  			hasValue := &ComparisonExpr{Left: NewArgument(es.hasValuesArg), Right: NewIntLiteral("1"), Operator: EqualOp}
  2082  			expr = AndExpressions(hasValue, cmp)
  2083  		case NotInOp:
  2084  			// :__sq_has_values = 0 or other_side not in ::__sq
  2085  			cmp.Right = NewListArg(es.argName)
  2086  			hasValue := &ComparisonExpr{Left: NewArgument(es.hasValuesArg), Right: NewIntLiteral("0"), Operator: EqualOp}
  2087  			expr = &OrExpr{hasValue, cmp}
  2088  		}
  2089  		es.alternative = expr
  2090  	}
  2091  }
  2092  
  2093  // ColumnName returns the alias if one was provided, otherwise prints the AST
  2094  func (ae *AliasedExpr) ColumnName() string {
  2095  	if !ae.As.IsEmpty() {
  2096  		return ae.As.String()
  2097  	}
  2098  
  2099  	if col, ok := ae.Expr.(*ColName); ok {
  2100  		return col.Name.String()
  2101  	}
  2102  
  2103  	return String(ae.Expr)
  2104  }
  2105  
  2106  // AllAggregation returns true if all the expressions contain aggregation
  2107  func (s SelectExprs) AllAggregation() bool {
  2108  	for _, k := range s {
  2109  		if !ContainsAggregation(k) {
  2110  			return false
  2111  		}
  2112  	}
  2113  	return true
  2114  }
  2115  
  2116  func isExprLiteral(expr Expr) bool {
  2117  	switch expr := expr.(type) {
  2118  	case *Literal:
  2119  		return true
  2120  	case BoolVal:
  2121  		return true
  2122  	case *UnaryExpr:
  2123  		return isExprLiteral(expr.Expr)
  2124  	default:
  2125  		return false
  2126  	}
  2127  }
  2128  
  2129  func defaultRequiresParens(ct *ColumnType) bool {
  2130  	// in 5.7 null value should be without parenthesis, in 8.0 it is allowed either way.
  2131  	// so it is safe to not keep parenthesis around null.
  2132  	if _, isNullVal := ct.Options.Default.(*NullVal); isNullVal {
  2133  		return false
  2134  	}
  2135  
  2136  	switch strings.ToUpper(ct.Type) {
  2137  	case "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "TINYBLOB", "BLOB", "MEDIUMBLOB",
  2138  		"LONGBLOB", "JSON", "GEOMETRY", "POINT",
  2139  		"LINESTRING", "POLYGON", "MULTIPOINT", "MULTILINESTRING",
  2140  		"MULTIPOLYGON", "GEOMETRYCOLLECTION":
  2141  		return true
  2142  	}
  2143  
  2144  	if isExprLiteral(ct.Options.Default) || isExprAliasForCurrentTimeStamp(ct.Options.Default) {
  2145  		return false
  2146  	}
  2147  
  2148  	return true
  2149  }
  2150  
  2151  // RemoveKeyspaceFromColName removes the Qualifier.Qualifier on all ColNames in the expression tree
  2152  func RemoveKeyspaceFromColName(expr Expr) {
  2153  	RemoveKeyspace(expr)
  2154  }
  2155  
  2156  // RemoveKeyspace removes the Qualifier.Qualifier on all ColNames in the AST
  2157  func RemoveKeyspace(in SQLNode) {
  2158  	// Walk will only return an error if we return an error from the inner func. safe to ignore here
  2159  	_ = Walk(func(node SQLNode) (kontinue bool, err error) {
  2160  		switch col := node.(type) {
  2161  		case *ColName:
  2162  			if !col.Qualifier.Qualifier.IsEmpty() {
  2163  				col.Qualifier.Qualifier = NewIdentifierCS("")
  2164  			}
  2165  		}
  2166  		return true, nil
  2167  	}, in)
  2168  }
  2169  
  2170  func convertStringToInt(integer string) int {
  2171  	val, _ := strconv.Atoi(integer)
  2172  	return val
  2173  }
  2174  
  2175  // SplitAndExpression breaks up the Expr into AND-separated conditions
  2176  // and appends them to filters. Outer parenthesis are removed. Precedence
  2177  // should be taken into account if expressions are recombined.
  2178  func SplitAndExpression(filters []Expr, node Expr) []Expr {
  2179  	if node == nil {
  2180  		return filters
  2181  	}
  2182  	switch node := node.(type) {
  2183  	case *AndExpr:
  2184  		filters = SplitAndExpression(filters, node.Left)
  2185  		return SplitAndExpression(filters, node.Right)
  2186  	}
  2187  	return append(filters, node)
  2188  }
  2189  
  2190  // AndExpressions ands together two or more expressions, minimising the expr when possible
  2191  func AndExpressions(exprs ...Expr) Expr {
  2192  	switch len(exprs) {
  2193  	case 0:
  2194  		return nil
  2195  	case 1:
  2196  		return exprs[0]
  2197  	default:
  2198  		result := (Expr)(nil)
  2199  	outer:
  2200  		// we'll loop and remove any duplicates
  2201  		for i, expr := range exprs {
  2202  			if expr == nil {
  2203  				continue
  2204  			}
  2205  			if result == nil {
  2206  				result = expr
  2207  				continue outer
  2208  			}
  2209  
  2210  			for j := 0; j < i; j++ {
  2211  				if Equals.Expr(expr, exprs[j]) {
  2212  					continue outer
  2213  				}
  2214  			}
  2215  			result = &AndExpr{Left: result, Right: expr}
  2216  		}
  2217  		return result
  2218  	}
  2219  }
  2220  
  2221  // Equals is the default Comparator for AST expressions.
  2222  var Equals = &Comparator{}