vitess.io/vitess@v0.16.2/go/vt/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  	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
    29  	"vitess.io/vitess/go/vt/vterrors"
    30  
    31  	"vitess.io/vitess/go/vt/log"
    32  
    33  	"vitess.io/vitess/go/sqltypes"
    34  	querypb "vitess.io/vitess/go/vt/proto/query"
    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  	exprs := SplitAndExpression(nil, node.Having.Expr)
  1014  	node.Having.Expr = AndExpressions(append(exprs, expr)...)
  1015  }
  1016  
  1017  // AddGroupBy adds a grouping expression, unless it's already present
  1018  func (node *Select) AddGroupBy(expr Expr) {
  1019  	for _, gb := range node.GroupBy {
  1020  		if Equals.Expr(gb, expr) {
  1021  			// group by columns are sets - duplicates don't add anything, so we can just skip these
  1022  			return
  1023  		}
  1024  	}
  1025  	node.GroupBy = append(node.GroupBy, expr)
  1026  }
  1027  
  1028  // AddWhere adds the boolean expression to the
  1029  // WHERE clause as an AND condition.
  1030  func (node *Update) AddWhere(expr Expr) {
  1031  	if node.Where == nil {
  1032  		node.Where = &Where{
  1033  			Type: WhereClause,
  1034  			Expr: expr,
  1035  		}
  1036  		return
  1037  	}
  1038  	node.Where.Expr = &AndExpr{
  1039  		Left:  node.Where.Expr,
  1040  		Right: expr,
  1041  	}
  1042  }
  1043  
  1044  // AddOrder adds an order by element
  1045  func (node *Union) AddOrder(order *Order) {
  1046  	node.OrderBy = append(node.OrderBy, order)
  1047  }
  1048  
  1049  // SetOrderBy sets the order by clause
  1050  func (node *Union) SetOrderBy(orderBy OrderBy) {
  1051  	node.OrderBy = orderBy
  1052  }
  1053  
  1054  // GetOrderBy gets the order by clause
  1055  func (node *Union) GetOrderBy() OrderBy {
  1056  	return node.OrderBy
  1057  }
  1058  
  1059  // SetLimit sets the limit clause
  1060  func (node *Union) SetLimit(limit *Limit) {
  1061  	node.Limit = limit
  1062  }
  1063  
  1064  // GetLimit gets the limit
  1065  func (node *Union) GetLimit() *Limit {
  1066  	return node.Limit
  1067  }
  1068  
  1069  // GetColumns gets the columns
  1070  func (node *Union) GetColumns() SelectExprs {
  1071  	return node.Left.GetColumns()
  1072  }
  1073  
  1074  // SetLock sets the lock clause
  1075  func (node *Union) SetLock(lock Lock) {
  1076  	node.Lock = lock
  1077  }
  1078  
  1079  // SetInto sets the into clause
  1080  func (node *Union) SetInto(into *SelectInto) {
  1081  	node.Into = into
  1082  }
  1083  
  1084  // SetWith sets the with clause to a union statement
  1085  func (node *Union) SetWith(with *With) {
  1086  	node.With = with
  1087  }
  1088  
  1089  // MakeDistinct implements the SelectStatement interface
  1090  func (node *Union) MakeDistinct() {
  1091  	node.Distinct = true
  1092  }
  1093  
  1094  // GetColumnCount implements the SelectStatement interface
  1095  func (node *Union) GetColumnCount() int {
  1096  	return node.Left.GetColumnCount()
  1097  }
  1098  
  1099  // SetComments implements the SelectStatement interface
  1100  func (node *Union) SetComments(comments Comments) {
  1101  	node.Left.SetComments(comments)
  1102  }
  1103  
  1104  // GetComments implements the SelectStatement interface
  1105  func (node *Union) GetParsedComments() *ParsedComments {
  1106  	return node.Left.GetParsedComments()
  1107  }
  1108  
  1109  func requiresParen(stmt SelectStatement) bool {
  1110  	switch node := stmt.(type) {
  1111  	case *Union:
  1112  		return len(node.OrderBy) != 0 || node.Lock != 0 || node.Into != nil || node.Limit != nil
  1113  	case *Select:
  1114  		return len(node.OrderBy) != 0 || node.Lock != 0 || node.Into != nil || node.Limit != nil
  1115  	}
  1116  
  1117  	return false
  1118  }
  1119  
  1120  func setLockInSelect(stmt SelectStatement, lock Lock) {
  1121  	stmt.SetLock(lock)
  1122  }
  1123  
  1124  // ToString returns the string associated with the DDLAction Enum
  1125  func (action DDLAction) ToString() string {
  1126  	switch action {
  1127  	case CreateDDLAction:
  1128  		return CreateStr
  1129  	case AlterDDLAction:
  1130  		return AlterStr
  1131  	case DropDDLAction:
  1132  		return DropStr
  1133  	case RenameDDLAction:
  1134  		return RenameStr
  1135  	case TruncateDDLAction:
  1136  		return TruncateStr
  1137  	case CreateVindexDDLAction:
  1138  		return CreateVindexStr
  1139  	case DropVindexDDLAction:
  1140  		return DropVindexStr
  1141  	case AddVschemaTableDDLAction:
  1142  		return AddVschemaTableStr
  1143  	case DropVschemaTableDDLAction:
  1144  		return DropVschemaTableStr
  1145  	case AddColVindexDDLAction:
  1146  		return AddColVindexStr
  1147  	case DropColVindexDDLAction:
  1148  		return DropColVindexStr
  1149  	case AddSequenceDDLAction:
  1150  		return AddSequenceStr
  1151  	case AddAutoIncDDLAction:
  1152  		return AddAutoIncStr
  1153  	default:
  1154  		return "Unknown DDL Action"
  1155  	}
  1156  }
  1157  
  1158  // ToString returns the string associated with the Scope enum
  1159  func (scope Scope) ToString() string {
  1160  	switch scope {
  1161  	case SessionScope:
  1162  		return SessionStr
  1163  	case GlobalScope:
  1164  		return GlobalStr
  1165  	case VitessMetadataScope:
  1166  		return VitessMetadataStr
  1167  	case VariableScope:
  1168  		return VariableStr
  1169  	case NoScope, NextTxScope:
  1170  		return ""
  1171  	default:
  1172  		return "Unknown Scope"
  1173  	}
  1174  }
  1175  
  1176  // ToString returns the IgnoreStr if ignore is true.
  1177  func (ignore Ignore) ToString() string {
  1178  	if ignore {
  1179  		return IgnoreStr
  1180  	}
  1181  	return ""
  1182  }
  1183  
  1184  // ToString returns the string associated with the type of lock
  1185  func (lock Lock) ToString() string {
  1186  	switch lock {
  1187  	case NoLock:
  1188  		return NoLockStr
  1189  	case ForUpdateLock:
  1190  		return ForUpdateStr
  1191  	case ShareModeLock:
  1192  		return ShareModeStr
  1193  	default:
  1194  		return "Unknown lock"
  1195  	}
  1196  }
  1197  
  1198  // ToString returns the string associated with WhereType
  1199  func (whereType WhereType) ToString() string {
  1200  	switch whereType {
  1201  	case WhereClause:
  1202  		return WhereStr
  1203  	case HavingClause:
  1204  		return HavingStr
  1205  	default:
  1206  		return "Unknown where type"
  1207  	}
  1208  }
  1209  
  1210  // ToString returns the string associated with JoinType
  1211  func (joinType JoinType) ToString() string {
  1212  	switch joinType {
  1213  	case NormalJoinType:
  1214  		return JoinStr
  1215  	case StraightJoinType:
  1216  		return StraightJoinStr
  1217  	case LeftJoinType:
  1218  		return LeftJoinStr
  1219  	case RightJoinType:
  1220  		return RightJoinStr
  1221  	case NaturalJoinType:
  1222  		return NaturalJoinStr
  1223  	case NaturalLeftJoinType:
  1224  		return NaturalLeftJoinStr
  1225  	case NaturalRightJoinType:
  1226  		return NaturalRightJoinStr
  1227  	default:
  1228  		return "Unknown join type"
  1229  	}
  1230  }
  1231  
  1232  // ToString returns the operator as a string
  1233  func (op ComparisonExprOperator) ToString() string {
  1234  	switch op {
  1235  	case EqualOp:
  1236  		return EqualStr
  1237  	case LessThanOp:
  1238  		return LessThanStr
  1239  	case GreaterThanOp:
  1240  		return GreaterThanStr
  1241  	case LessEqualOp:
  1242  		return LessEqualStr
  1243  	case GreaterEqualOp:
  1244  		return GreaterEqualStr
  1245  	case NotEqualOp:
  1246  		return NotEqualStr
  1247  	case NullSafeEqualOp:
  1248  		return NullSafeEqualStr
  1249  	case InOp:
  1250  		return InStr
  1251  	case NotInOp:
  1252  		return NotInStr
  1253  	case LikeOp:
  1254  		return LikeStr
  1255  	case NotLikeOp:
  1256  		return NotLikeStr
  1257  	case RegexpOp:
  1258  		return RegexpStr
  1259  	case NotRegexpOp:
  1260  		return NotRegexpStr
  1261  	default:
  1262  		return "Unknown ComparisonExpOperator"
  1263  	}
  1264  }
  1265  
  1266  // ToString returns the operator as a string
  1267  func (op IsExprOperator) ToString() string {
  1268  	switch op {
  1269  	case IsNullOp:
  1270  		return IsNullStr
  1271  	case IsNotNullOp:
  1272  		return IsNotNullStr
  1273  	case IsTrueOp:
  1274  		return IsTrueStr
  1275  	case IsNotTrueOp:
  1276  		return IsNotTrueStr
  1277  	case IsFalseOp:
  1278  		return IsFalseStr
  1279  	case IsNotFalseOp:
  1280  		return IsNotFalseStr
  1281  	default:
  1282  		return "Unknown IsExprOperator"
  1283  	}
  1284  }
  1285  
  1286  // ToString returns the operator as a string
  1287  func (op BinaryExprOperator) ToString() string {
  1288  	switch op {
  1289  	case BitAndOp:
  1290  		return BitAndStr
  1291  	case BitOrOp:
  1292  		return BitOrStr
  1293  	case BitXorOp:
  1294  		return BitXorStr
  1295  	case PlusOp:
  1296  		return PlusStr
  1297  	case MinusOp:
  1298  		return MinusStr
  1299  	case MultOp:
  1300  		return MultStr
  1301  	case DivOp:
  1302  		return DivStr
  1303  	case IntDivOp:
  1304  		return IntDivStr
  1305  	case ModOp:
  1306  		return ModStr
  1307  	case ShiftLeftOp:
  1308  		return ShiftLeftStr
  1309  	case ShiftRightOp:
  1310  		return ShiftRightStr
  1311  	case JSONExtractOp:
  1312  		return JSONExtractOpStr
  1313  	case JSONUnquoteExtractOp:
  1314  		return JSONUnquoteExtractOpStr
  1315  	default:
  1316  		return "Unknown BinaryExprOperator"
  1317  	}
  1318  }
  1319  
  1320  // ToString returns the partition type as a string
  1321  func (partitionType PartitionByType) ToString() string {
  1322  	switch partitionType {
  1323  	case HashType:
  1324  		return HashTypeStr
  1325  	case KeyType:
  1326  		return KeyTypeStr
  1327  	case ListType:
  1328  		return ListTypeStr
  1329  	case RangeType:
  1330  		return RangeTypeStr
  1331  	default:
  1332  		return "Unknown PartitionByType"
  1333  	}
  1334  }
  1335  
  1336  // ToString returns the partition value range type as a string
  1337  func (t PartitionValueRangeType) ToString() string {
  1338  	switch t {
  1339  	case LessThanType:
  1340  		return LessThanTypeStr
  1341  	case InType:
  1342  		return InTypeStr
  1343  	default:
  1344  		return "Unknown PartitionValueRangeType"
  1345  	}
  1346  }
  1347  
  1348  // ToString returns the operator as a string
  1349  func (op UnaryExprOperator) ToString() string {
  1350  	switch op {
  1351  	case UPlusOp:
  1352  		return UPlusStr
  1353  	case UMinusOp:
  1354  		return UMinusStr
  1355  	case TildaOp:
  1356  		return TildaStr
  1357  	case BangOp:
  1358  		return BangStr
  1359  	case NStringOp:
  1360  		return NStringStr
  1361  	default:
  1362  		return "Unknown UnaryExprOperator"
  1363  	}
  1364  }
  1365  
  1366  // ToString returns the option as a string
  1367  func (option MatchExprOption) ToString() string {
  1368  	switch option {
  1369  	case NoOption:
  1370  		return NoOptionStr
  1371  	case BooleanModeOpt:
  1372  		return BooleanModeStr
  1373  	case NaturalLanguageModeOpt:
  1374  		return NaturalLanguageModeStr
  1375  	case NaturalLanguageModeWithQueryExpansionOpt:
  1376  		return NaturalLanguageModeWithQueryExpansionStr
  1377  	case QueryExpansionOpt:
  1378  		return QueryExpansionStr
  1379  	default:
  1380  		return "Unknown MatchExprOption"
  1381  	}
  1382  }
  1383  
  1384  // ToString returns the direction as a string
  1385  func (dir OrderDirection) ToString() string {
  1386  	switch dir {
  1387  	case AscOrder:
  1388  		return AscScr
  1389  	case DescOrder:
  1390  		return DescScr
  1391  	default:
  1392  		return "Unknown OrderDirection"
  1393  	}
  1394  }
  1395  
  1396  // ToString returns the type as a string
  1397  func (ty IndexHintType) ToString() string {
  1398  	switch ty {
  1399  	case UseOp:
  1400  		return UseStr
  1401  	case IgnoreOp:
  1402  		return IgnoreStr
  1403  	case ForceOp:
  1404  		return ForceStr
  1405  	default:
  1406  		return "Unknown IndexHintType"
  1407  	}
  1408  }
  1409  
  1410  // ToString returns the type as a string
  1411  func (ty DeallocateStmtType) ToString() string {
  1412  	switch ty {
  1413  	case DeallocateType:
  1414  		return DeallocateStr
  1415  	case DropType:
  1416  		return DropStr
  1417  	default:
  1418  		return "Unknown Deallocate Statement Type"
  1419  	}
  1420  }
  1421  
  1422  // ToString returns the type as a string
  1423  func (ty IndexHintForType) ToString() string {
  1424  	switch ty {
  1425  	case NoForType:
  1426  		return ""
  1427  	case JoinForType:
  1428  		return JoinForStr
  1429  	case GroupByForType:
  1430  		return GroupByForStr
  1431  	case OrderByForType:
  1432  		return OrderByForStr
  1433  	default:
  1434  		return "Unknown IndexHintForType"
  1435  	}
  1436  }
  1437  
  1438  // ToString returns the type as a string
  1439  func (ty TrimFuncType) ToString() string {
  1440  	switch ty {
  1441  	case NormalTrimType:
  1442  		return NormalTrimStr
  1443  	case LTrimType:
  1444  		return LTrimStr
  1445  	case RTrimType:
  1446  		return RTrimStr
  1447  	default:
  1448  		return "Unknown TrimFuncType"
  1449  	}
  1450  }
  1451  
  1452  // ToString returns the type as a string
  1453  func (ty TrimType) ToString() string {
  1454  	switch ty {
  1455  	case NoTrimType:
  1456  		return ""
  1457  	case BothTrimType:
  1458  		return BothTrimStr
  1459  	case LeadingTrimType:
  1460  		return LeadingTrimStr
  1461  	case TrailingTrimType:
  1462  		return TrailingTrimStr
  1463  	default:
  1464  		return "Unknown TrimType"
  1465  	}
  1466  }
  1467  
  1468  // ToString returns the type as a string
  1469  func (ty FrameUnitType) ToString() string {
  1470  	switch ty {
  1471  	case FrameRowsType:
  1472  		return FrameRowsStr
  1473  	case FrameRangeType:
  1474  		return FrameRangeStr
  1475  	default:
  1476  		return "Unknown FrameUnitType"
  1477  	}
  1478  }
  1479  
  1480  // ToString returns the type as a string
  1481  func (ty FramePointType) ToString() string {
  1482  	switch ty {
  1483  	case CurrentRowType:
  1484  		return CurrentRowStr
  1485  	case UnboundedPrecedingType:
  1486  		return UnboundedPrecedingStr
  1487  	case UnboundedFollowingType:
  1488  		return UnboundedFollowingStr
  1489  	case ExprPrecedingType:
  1490  		return ExprPrecedingStr
  1491  	case ExprFollowingType:
  1492  		return ExprFollowingStr
  1493  	default:
  1494  		return "Unknown FramePointType"
  1495  	}
  1496  }
  1497  
  1498  // ToString returns the type as a string
  1499  func (ty ArgumentLessWindowExprType) ToString() string {
  1500  	switch ty {
  1501  	case CumeDistExprType:
  1502  		return CumeDistExprStr
  1503  	case DenseRankExprType:
  1504  		return DenseRankExprStr
  1505  	case PercentRankExprType:
  1506  		return PercentRankExprStr
  1507  	case RankExprType:
  1508  		return RankExprStr
  1509  	case RowNumberExprType:
  1510  		return RowNumberExprStr
  1511  	default:
  1512  		return "Unknown ArgumentLessWindowExprType"
  1513  	}
  1514  }
  1515  
  1516  // ToString returns the type as a string
  1517  func (ty NullTreatmentType) ToString() string {
  1518  	switch ty {
  1519  	case RespectNullsType:
  1520  		return RespectNullsStr
  1521  	case IgnoreNullsType:
  1522  		return IgnoreNullsStr
  1523  	default:
  1524  		return "Unknown NullTreatmentType"
  1525  	}
  1526  }
  1527  
  1528  // ToString returns the type as a string
  1529  func (ty FromFirstLastType) ToString() string {
  1530  	switch ty {
  1531  	case FromFirstType:
  1532  		return FromFirstStr
  1533  	case FromLastType:
  1534  		return FromLastStr
  1535  	default:
  1536  		return "Unknown FromFirstLastType"
  1537  	}
  1538  }
  1539  
  1540  // ToString returns the type as a string
  1541  func (ty FirstOrLastValueExprType) ToString() string {
  1542  	switch ty {
  1543  	case FirstValueExprType:
  1544  		return FirstValueExprStr
  1545  	case LastValueExprType:
  1546  		return LastValueExprStr
  1547  	default:
  1548  		return "Unknown FirstOrLastValueExprType"
  1549  	}
  1550  }
  1551  
  1552  // ToString returns the type as a string
  1553  func (ty LagLeadExprType) ToString() string {
  1554  	switch ty {
  1555  	case LagExprType:
  1556  		return LagExprStr
  1557  	case LeadExprType:
  1558  		return LeadExprStr
  1559  	default:
  1560  		return "Unknown LagLeadExprType"
  1561  	}
  1562  }
  1563  
  1564  // ToString returns the type as a string
  1565  func (ty JSONAttributeType) ToString() string {
  1566  	switch ty {
  1567  	case DepthAttributeType:
  1568  		return DepthAttributeStr
  1569  	case ValidAttributeType:
  1570  		return ValidAttributeStr
  1571  	case TypeAttributeType:
  1572  		return TypeAttributeStr
  1573  	case LengthAttributeType:
  1574  		return LengthAttributeStr
  1575  	default:
  1576  		return "Unknown JSONAttributeType"
  1577  	}
  1578  }
  1579  
  1580  // ToString returns the type as a string
  1581  func (ty JSONValueModifierType) ToString() string {
  1582  	switch ty {
  1583  	case JSONArrayAppendType:
  1584  		return JSONArrayAppendStr
  1585  	case JSONArrayInsertType:
  1586  		return JSONArrayInsertStr
  1587  	case JSONInsertType:
  1588  		return JSONInsertStr
  1589  	case JSONReplaceType:
  1590  		return JSONReplaceStr
  1591  	case JSONSetType:
  1592  		return JSONSetStr
  1593  	default:
  1594  		return "Unknown JSONValueModifierType"
  1595  	}
  1596  }
  1597  
  1598  // ToString returns the type as a string
  1599  func (ty JSONValueMergeType) ToString() string {
  1600  	switch ty {
  1601  	case JSONMergeType:
  1602  		return JSONMergeStr
  1603  	case JSONMergePatchType:
  1604  		return JSONMergePatchStr
  1605  	case JSONMergePreserveType:
  1606  		return JSONMergePreserveStr
  1607  	default:
  1608  		return "Unknown JSONValueMergeType"
  1609  	}
  1610  }
  1611  
  1612  // ToString returns the type as a string
  1613  func (ty LockingFuncType) ToString() string {
  1614  	switch ty {
  1615  	case GetLock:
  1616  		return GetLockStr
  1617  	case IsFreeLock:
  1618  		return IsFreeLockStr
  1619  	case IsUsedLock:
  1620  		return IsUsedLockStr
  1621  	case ReleaseAllLocks:
  1622  		return ReleaseAllLocksStr
  1623  	case ReleaseLock:
  1624  		return ReleaseLockStr
  1625  	default:
  1626  		return "Unknown LockingFuncType"
  1627  	}
  1628  }
  1629  
  1630  // ToString returns the type as a string
  1631  func (ty PerformanceSchemaType) ToString() string {
  1632  	switch ty {
  1633  	case FormatBytesType:
  1634  		return FormatBytesStr
  1635  	case FormatPicoTimeType:
  1636  		return FormatPicoTimeStr
  1637  	case PsCurrentThreadIDType:
  1638  		return PsCurrentThreadIDStr
  1639  	case PsThreadIDType:
  1640  		return PsThreadIDStr
  1641  	default:
  1642  		return "Unknown PerformaceSchemaType"
  1643  	}
  1644  }
  1645  
  1646  // ToString returns the type as a string
  1647  func (ty GTIDType) ToString() string {
  1648  	switch ty {
  1649  	case GTIDSubsetType:
  1650  		return GTIDSubsetStr
  1651  	case GTIDSubtractType:
  1652  		return GTIDSubtractStr
  1653  	case WaitForExecutedGTIDSetType:
  1654  		return WaitForExecutedGTIDSetStr
  1655  	case WaitUntilSQLThreadAfterGTIDSType:
  1656  		return WaitUntilSQLThreadAfterGTIDSStr
  1657  	default:
  1658  		return "Unknown GTIDType"
  1659  	}
  1660  }
  1661  
  1662  // ToString returns the type as a string
  1663  func (ty ExplainType) ToString() string {
  1664  	switch ty {
  1665  	case EmptyType:
  1666  		return EmptyStr
  1667  	case TreeType:
  1668  		return TreeStr
  1669  	case JSONType:
  1670  		return JSONStr
  1671  	case VitessType:
  1672  		return VitessStr
  1673  	case VTExplainType:
  1674  		return VTExplainStr
  1675  	case TraditionalType:
  1676  		return TraditionalStr
  1677  	case AnalyzeType:
  1678  		return AnalyzeStr
  1679  	default:
  1680  		return "Unknown ExplainType"
  1681  	}
  1682  }
  1683  
  1684  // ToString returns the type as a string
  1685  func (ty VExplainType) ToString() string {
  1686  	switch ty {
  1687  	case PlanVExplainType:
  1688  		return PlanStr
  1689  	case QueriesVExplainType:
  1690  		return QueriesStr
  1691  	case AllVExplainType:
  1692  		return AllVExplainStr
  1693  	default:
  1694  		return "Unknown VExplainType"
  1695  	}
  1696  }
  1697  
  1698  // ToString returns the type as a string
  1699  func (ty IntervalTypes) ToString() string {
  1700  	switch ty {
  1701  	case IntervalYear:
  1702  		return YearStr
  1703  	case IntervalQuarter:
  1704  		return QuarterStr
  1705  	case IntervalMonth:
  1706  		return MonthStr
  1707  	case IntervalWeek:
  1708  		return WeekStr
  1709  	case IntervalDay:
  1710  		return DayStr
  1711  	case IntervalHour:
  1712  		return HourStr
  1713  	case IntervalMinute:
  1714  		return MinuteStr
  1715  	case IntervalSecond:
  1716  		return SecondStr
  1717  	case IntervalMicrosecond:
  1718  		return MicrosecondStr
  1719  	case IntervalYearMonth:
  1720  		return YearMonthStr
  1721  	case IntervalDayHour:
  1722  		return DayHourStr
  1723  	case IntervalDayMinute:
  1724  		return DayMinuteStr
  1725  	case IntervalDaySecond:
  1726  		return DaySecondStr
  1727  	case IntervalHourMinute:
  1728  		return HourMinuteStr
  1729  	case IntervalHourSecond:
  1730  		return HourSecondStr
  1731  	case IntervalMinuteSecond:
  1732  		return MinuteSecondStr
  1733  	case IntervalDayMicrosecond:
  1734  		return DayMicrosecondStr
  1735  	case IntervalHourMicrosecond:
  1736  		return HourMicrosecondStr
  1737  	case IntervalMinuteMicrosecond:
  1738  		return MinuteMicrosecondStr
  1739  	case IntervalSecondMicrosecond:
  1740  		return SecondMicrosecondStr
  1741  	default:
  1742  		return "Unknown IntervalType"
  1743  	}
  1744  }
  1745  
  1746  // ToString returns the type as a string
  1747  func (sel SelectIntoType) ToString() string {
  1748  	switch sel {
  1749  	case IntoOutfile:
  1750  		return IntoOutfileStr
  1751  	case IntoOutfileS3:
  1752  		return IntoOutfileS3Str
  1753  	case IntoDumpfile:
  1754  		return IntoDumpfileStr
  1755  	default:
  1756  		return "Unknown Select Into Type"
  1757  	}
  1758  }
  1759  
  1760  // ToString returns the type as a string
  1761  func (node DatabaseOptionType) ToString() string {
  1762  	switch node {
  1763  	case CharacterSetType:
  1764  		return CharacterSetStr
  1765  	case CollateType:
  1766  		return CollateStr
  1767  	case EncryptionType:
  1768  		return EncryptionStr
  1769  	default:
  1770  		return "Unknown DatabaseOptionType Type"
  1771  	}
  1772  }
  1773  
  1774  // ToString returns the type as a string
  1775  func (ty LockType) ToString() string {
  1776  	switch ty {
  1777  	case Read:
  1778  		return ReadStr
  1779  	case ReadLocal:
  1780  		return ReadLocalStr
  1781  	case Write:
  1782  		return WriteStr
  1783  	case LowPriorityWrite:
  1784  		return LowPriorityWriteStr
  1785  	default:
  1786  		return "Unknown LockType"
  1787  	}
  1788  }
  1789  
  1790  // ToString returns ShowCommandType as a string
  1791  func (ty ShowCommandType) ToString() string {
  1792  	switch ty {
  1793  	case Charset:
  1794  		return CharsetStr
  1795  	case Collation:
  1796  		return CollationStr
  1797  	case Column:
  1798  		return ColumnStr
  1799  	case CreateDb:
  1800  		return CreateDbStr
  1801  	case CreateE:
  1802  		return CreateEStr
  1803  	case CreateF:
  1804  		return CreateFStr
  1805  	case CreateProc:
  1806  		return CreateProcStr
  1807  	case CreateTbl:
  1808  		return CreateTblStr
  1809  	case CreateTr:
  1810  		return CreateTrStr
  1811  	case CreateV:
  1812  		return CreateVStr
  1813  	case Database:
  1814  		return DatabaseStr
  1815  	case Engines:
  1816  		return EnginesStr
  1817  	case FunctionC:
  1818  		return FunctionCStr
  1819  	case Function:
  1820  		return FunctionStr
  1821  	case GtidExecGlobal:
  1822  		return GtidExecGlobalStr
  1823  	case Index:
  1824  		return IndexStr
  1825  	case OpenTable:
  1826  		return OpenTableStr
  1827  	case Plugins:
  1828  		return PluginsStr
  1829  	case Privilege:
  1830  		return PrivilegeStr
  1831  	case ProcedureC:
  1832  		return ProcedureCStr
  1833  	case Procedure:
  1834  		return ProcedureStr
  1835  	case StatusGlobal:
  1836  		return StatusGlobalStr
  1837  	case StatusSession:
  1838  		return StatusSessionStr
  1839  	case Table:
  1840  		return TablesStr
  1841  	case TableStatus:
  1842  		return TableStatusStr
  1843  	case Trigger:
  1844  		return TriggerStr
  1845  	case VariableGlobal:
  1846  		return VariableGlobalStr
  1847  	case VariableSession:
  1848  		return VariableSessionStr
  1849  	case VGtidExecGlobal:
  1850  		return VGtidExecGlobalStr
  1851  	case VitessMigrations:
  1852  		return VitessMigrationsStr
  1853  	case VitessReplicationStatus:
  1854  		return VitessReplicationStatusStr
  1855  	case VitessShards:
  1856  		return VitessShardsStr
  1857  	case VitessTablets:
  1858  		return VitessTabletsStr
  1859  	case VitessTarget:
  1860  		return VitessTargetStr
  1861  	case VitessVariables:
  1862  		return VitessVariablesStr
  1863  	case VschemaTables:
  1864  		return VschemaTablesStr
  1865  	case VschemaVindexes:
  1866  		return VschemaVindexesStr
  1867  	case Warnings:
  1868  		return WarningsStr
  1869  	case Keyspace:
  1870  		return KeyspaceStr
  1871  	default:
  1872  		return "" +
  1873  			"Unknown ShowCommandType"
  1874  	}
  1875  }
  1876  
  1877  // ToString returns the DropKeyType as a string
  1878  func (key DropKeyType) ToString() string {
  1879  	switch key {
  1880  	case PrimaryKeyType:
  1881  		return PrimaryKeyTypeStr
  1882  	case ForeignKeyType:
  1883  		return ForeignKeyTypeStr
  1884  	case NormalKeyType:
  1885  		return NormalKeyTypeStr
  1886  	case CheckKeyType:
  1887  		return CheckKeyTypeStr
  1888  	default:
  1889  		return "Unknown DropKeyType"
  1890  	}
  1891  }
  1892  
  1893  // ToString returns the LockOptionType as a string
  1894  func (lock LockOptionType) ToString() string {
  1895  	switch lock {
  1896  	case NoneType:
  1897  		return NoneTypeStr
  1898  	case DefaultType:
  1899  		return DefaultTypeStr
  1900  	case SharedType:
  1901  		return SharedTypeStr
  1902  	case ExclusiveType:
  1903  		return ExclusiveTypeStr
  1904  	default:
  1905  		return "Unknown type LockOptionType"
  1906  	}
  1907  }
  1908  
  1909  // ToString returns the string associated with JoinType
  1910  func (columnFormat ColumnFormat) ToString() string {
  1911  	switch columnFormat {
  1912  	case FixedFormat:
  1913  		return keywordStrings[FIXED]
  1914  	case DynamicFormat:
  1915  		return keywordStrings[DYNAMIC]
  1916  	case DefaultFormat:
  1917  		return keywordStrings[DEFAULT]
  1918  	default:
  1919  		return "Unknown column format type"
  1920  	}
  1921  }
  1922  
  1923  // ToString returns the TxAccessMode type as a string
  1924  func (ty TxAccessMode) ToString() string {
  1925  	switch ty {
  1926  	case WithConsistentSnapshot:
  1927  		return WithConsistentSnapshotStr
  1928  	case ReadWrite:
  1929  		return ReadWriteStr
  1930  	case ReadOnly:
  1931  		return ReadOnlyStr
  1932  	default:
  1933  		return "Unknown Transaction Access Mode"
  1934  	}
  1935  }
  1936  
  1937  // CompliantName is used to get the name of the bind variable to use for this column name
  1938  func (node *ColName) CompliantName() string {
  1939  	if !node.Qualifier.IsEmpty() {
  1940  		return node.Qualifier.Name.CompliantName() + "_" + node.Name.CompliantName()
  1941  	}
  1942  	return node.Name.CompliantName()
  1943  }
  1944  
  1945  // isExprAliasForCurrentTimeStamp returns true if the Expr provided is an alias for CURRENT_TIMESTAMP
  1946  func isExprAliasForCurrentTimeStamp(expr Expr) bool {
  1947  	switch node := expr.(type) {
  1948  	case *FuncExpr:
  1949  		return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
  1950  	case *CurTimeFuncExpr:
  1951  		return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
  1952  	}
  1953  	return false
  1954  }
  1955  
  1956  // AtCount represents the '@' count in IdentifierCI
  1957  type AtCount int
  1958  
  1959  const (
  1960  	// NoAt represents no @
  1961  	NoAt AtCount = iota
  1962  	// SingleAt represents @
  1963  	SingleAt
  1964  	// DoubleAt represents @@
  1965  	DoubleAt
  1966  )
  1967  
  1968  // encodeSQLString encodes the string as a SQL string.
  1969  func encodeSQLString(val string) string {
  1970  	return sqltypes.EncodeStringSQL(val)
  1971  }
  1972  
  1973  // ToString prints the list of table expressions as a string
  1974  // To be used as an alternate for String for []TableExpr
  1975  func ToString(exprs []TableExpr) string {
  1976  	buf := NewTrackedBuffer(nil)
  1977  	prefix := ""
  1978  	for _, expr := range exprs {
  1979  		buf.astPrintf(nil, "%s%v", prefix, expr)
  1980  		prefix = ", "
  1981  	}
  1982  	return buf.String()
  1983  }
  1984  
  1985  func formatIdentifier(id string) string {
  1986  	buf := NewTrackedBuffer(nil)
  1987  	formatID(buf, id, NoAt)
  1988  	return buf.String()
  1989  }
  1990  
  1991  func formatAddress(address string) string {
  1992  	if len(address) > 0 && address[0] == '\'' {
  1993  		return address
  1994  	}
  1995  	buf := NewTrackedBuffer(nil)
  1996  	formatID(buf, address, NoAt)
  1997  	return buf.String()
  1998  }
  1999  
  2000  // ContainsAggregation returns true if the expression contains aggregation
  2001  func ContainsAggregation(e SQLNode) bool {
  2002  	hasAggregates := false
  2003  	_ = Walk(func(node SQLNode) (kontinue bool, err error) {
  2004  		if _, isAggregate := node.(AggrFunc); isAggregate {
  2005  			hasAggregates = true
  2006  			return false, nil
  2007  		}
  2008  		return true, nil
  2009  	}, e)
  2010  	return hasAggregates
  2011  }
  2012  
  2013  // GetFirstSelect gets the first select statement
  2014  func GetFirstSelect(selStmt SelectStatement) *Select {
  2015  	if selStmt == nil {
  2016  		return nil
  2017  	}
  2018  	switch node := selStmt.(type) {
  2019  	case *Select:
  2020  		return node
  2021  	case *Union:
  2022  		return GetFirstSelect(node.Left)
  2023  	}
  2024  	panic("[BUG]: unknown type for SelectStatement")
  2025  }
  2026  
  2027  // GetAllSelects gets all the select statement s
  2028  func GetAllSelects(selStmt SelectStatement) []*Select {
  2029  	switch node := selStmt.(type) {
  2030  	case *Select:
  2031  		return []*Select{node}
  2032  	case *Union:
  2033  		return append(GetAllSelects(node.Left), GetAllSelects(node.Right)...)
  2034  	}
  2035  	panic("[BUG]: unknown type for SelectStatement")
  2036  }
  2037  
  2038  // SetArgName sets argument name.
  2039  func (es *ExtractedSubquery) SetArgName(n string) {
  2040  	es.argName = n
  2041  	es.updateAlternative()
  2042  }
  2043  
  2044  // SetHasValuesArg sets has_values argument.
  2045  func (es *ExtractedSubquery) SetHasValuesArg(n string) {
  2046  	es.hasValuesArg = n
  2047  	es.updateAlternative()
  2048  }
  2049  
  2050  // GetArgName returns argument name.
  2051  func (es *ExtractedSubquery) GetArgName() string {
  2052  	return es.argName
  2053  }
  2054  
  2055  // GetHasValuesArg returns has values argument.
  2056  func (es *ExtractedSubquery) GetHasValuesArg() string {
  2057  	return es.hasValuesArg
  2058  
  2059  }
  2060  
  2061  func (es *ExtractedSubquery) updateAlternative() {
  2062  	switch original := es.Original.(type) {
  2063  	case *ExistsExpr:
  2064  		es.alternative = NewArgument(es.hasValuesArg)
  2065  	case *Subquery:
  2066  		es.alternative = NewArgument(es.argName)
  2067  	case *ComparisonExpr:
  2068  		// other_side = :__sq
  2069  		cmp := &ComparisonExpr{
  2070  			Left:     es.OtherSide,
  2071  			Right:    NewArgument(es.argName),
  2072  			Operator: original.Operator,
  2073  		}
  2074  		var expr Expr = cmp
  2075  		switch original.Operator {
  2076  		case InOp:
  2077  			// :__sq_has_values = 1 and other_side in ::__sq
  2078  			cmp.Right = NewListArg(es.argName)
  2079  			hasValue := &ComparisonExpr{Left: NewArgument(es.hasValuesArg), Right: NewIntLiteral("1"), Operator: EqualOp}
  2080  			expr = AndExpressions(hasValue, cmp)
  2081  		case NotInOp:
  2082  			// :__sq_has_values = 0 or other_side not in ::__sq
  2083  			cmp.Right = NewListArg(es.argName)
  2084  			hasValue := &ComparisonExpr{Left: NewArgument(es.hasValuesArg), Right: NewIntLiteral("0"), Operator: EqualOp}
  2085  			expr = &OrExpr{hasValue, cmp}
  2086  		}
  2087  		es.alternative = expr
  2088  	}
  2089  }
  2090  
  2091  // ColumnName returns the alias if one was provided, otherwise prints the AST
  2092  func (ae *AliasedExpr) ColumnName() string {
  2093  	if !ae.As.IsEmpty() {
  2094  		return ae.As.String()
  2095  	}
  2096  
  2097  	if col, ok := ae.Expr.(*ColName); ok {
  2098  		return col.Name.String()
  2099  	}
  2100  
  2101  	return String(ae.Expr)
  2102  }
  2103  
  2104  // AllAggregation returns true if all the expressions contain aggregation
  2105  func (s SelectExprs) AllAggregation() bool {
  2106  	for _, k := range s {
  2107  		if !ContainsAggregation(k) {
  2108  			return false
  2109  		}
  2110  	}
  2111  	return true
  2112  }
  2113  
  2114  func isExprLiteral(expr Expr) bool {
  2115  	switch expr := expr.(type) {
  2116  	case *Literal:
  2117  		return true
  2118  	case BoolVal:
  2119  		return true
  2120  	case *UnaryExpr:
  2121  		return isExprLiteral(expr.Expr)
  2122  	default:
  2123  		return false
  2124  	}
  2125  }
  2126  
  2127  func defaultRequiresParens(ct *ColumnType) bool {
  2128  	// in 5.7 null value should be without parenthesis, in 8.0 it is allowed either way.
  2129  	// so it is safe to not keep parenthesis around null.
  2130  	if _, isNullVal := ct.Options.Default.(*NullVal); isNullVal {
  2131  		return false
  2132  	}
  2133  
  2134  	switch strings.ToUpper(ct.Type) {
  2135  	case "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "TINYBLOB", "BLOB", "MEDIUMBLOB",
  2136  		"LONGBLOB", "JSON", "GEOMETRY", "POINT",
  2137  		"LINESTRING", "POLYGON", "MULTIPOINT", "MULTILINESTRING",
  2138  		"MULTIPOLYGON", "GEOMETRYCOLLECTION":
  2139  		return true
  2140  	}
  2141  
  2142  	if isExprLiteral(ct.Options.Default) || isExprAliasForCurrentTimeStamp(ct.Options.Default) {
  2143  		return false
  2144  	}
  2145  
  2146  	return true
  2147  }
  2148  
  2149  // RemoveKeyspaceFromColName removes the Qualifier.Qualifier on all ColNames in the expression tree
  2150  func RemoveKeyspaceFromColName(expr Expr) {
  2151  	RemoveKeyspace(expr)
  2152  }
  2153  
  2154  // RemoveKeyspace removes the Qualifier.Qualifier on all ColNames in the AST
  2155  func RemoveKeyspace(in SQLNode) {
  2156  	// Walk will only return an error if we return an error from the inner func. safe to ignore here
  2157  	_ = Walk(func(node SQLNode) (kontinue bool, err error) {
  2158  		switch col := node.(type) {
  2159  		case *ColName:
  2160  			if !col.Qualifier.Qualifier.IsEmpty() {
  2161  				col.Qualifier.Qualifier = NewIdentifierCS("")
  2162  			}
  2163  		}
  2164  		return true, nil
  2165  	}, in)
  2166  }
  2167  
  2168  func convertStringToInt(integer string) int {
  2169  	val, _ := strconv.Atoi(integer)
  2170  	return val
  2171  }
  2172  
  2173  // SplitAndExpression breaks up the Expr into AND-separated conditions
  2174  // and appends them to filters. Outer parenthesis are removed. Precedence
  2175  // should be taken into account if expressions are recombined.
  2176  func SplitAndExpression(filters []Expr, node Expr) []Expr {
  2177  	if node == nil {
  2178  		return filters
  2179  	}
  2180  	switch node := node.(type) {
  2181  	case *AndExpr:
  2182  		filters = SplitAndExpression(filters, node.Left)
  2183  		return SplitAndExpression(filters, node.Right)
  2184  	}
  2185  	return append(filters, node)
  2186  }
  2187  
  2188  // AndExpressions ands together two or more expressions, minimising the expr when possible
  2189  func AndExpressions(exprs ...Expr) Expr {
  2190  	switch len(exprs) {
  2191  	case 0:
  2192  		return nil
  2193  	case 1:
  2194  		return exprs[0]
  2195  	default:
  2196  		result := (Expr)(nil)
  2197  	outer:
  2198  		// we'll loop and remove any duplicates
  2199  		for i, expr := range exprs {
  2200  			if expr == nil {
  2201  				continue
  2202  			}
  2203  			if result == nil {
  2204  				result = expr
  2205  				continue outer
  2206  			}
  2207  
  2208  			for j := 0; j < i; j++ {
  2209  				if Equals.Expr(expr, exprs[j]) {
  2210  					continue outer
  2211  				}
  2212  			}
  2213  			result = &AndExpr{Left: result, Right: expr}
  2214  		}
  2215  		return result
  2216  	}
  2217  }
  2218  
  2219  // Equals is the default Comparator for AST expressions.
  2220  var Equals = &Comparator{}