github.com/team-ide/go-dialect@v1.9.20/vitess/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  	"github.com/team-ide/go-dialect/vitess/hack"
    24  	"github.com/team-ide/go-dialect/vitess/vterrors"
    25  	vtrpcpb "github.com/team-ide/go-dialect/vitess/vtrpc"
    26  	"regexp"
    27  	"strings"
    28  
    29  	//"github.com/team-ide/go-dialect/vitess/log"
    30  
    31  	querypb "github.com/team-ide/go-dialect/vitess/query"
    32  	"github.com/team-ide/go-dialect/vitess/sqltypes"
    33  )
    34  
    35  // Walk calls visit on every node.
    36  // If visit returns true, the underlying nodes
    37  // are also visited. If it returns an error, walking
    38  // is interrupted, and the error is returned.
    39  func Walk(visit Visit, nodes ...SQLNode) error {
    40  	for _, node := range nodes {
    41  		err := VisitSQLNode(node, visit)
    42  		if err != nil {
    43  			return err
    44  		}
    45  	}
    46  	return nil
    47  }
    48  
    49  // Visit defines the signature of a function that
    50  // can be used to visit all nodes of a parse tree.
    51  // returning false on kontinue means that children will not be visited
    52  // returning an error will abort the visitation and return the error
    53  type Visit func(node SQLNode) (kontinue bool, err error)
    54  
    55  // Append appends the SQLNode to the buffer.
    56  func Append(buf *strings.Builder, node SQLNode) {
    57  	tbuf := &TrackedBuffer{
    58  		Builder: buf,
    59  	}
    60  	node.Format(tbuf)
    61  }
    62  
    63  // IndexColumn describes a column in an index definition with optional length
    64  type IndexColumn struct {
    65  	Column    ColIdent
    66  	Length    *Literal
    67  	Direction OrderDirection
    68  }
    69  
    70  // LengthScaleOption is used for types that have an optional length
    71  // and scale
    72  type LengthScaleOption struct {
    73  	Length *Literal
    74  	Scale  *Literal
    75  }
    76  
    77  // IndexOption is used for trailing options for indexes: COMMENT, KEY_BLOCK_SIZE, USING, WITH PARSER
    78  type IndexOption struct {
    79  	Name   string
    80  	Value  *Literal
    81  	String string
    82  }
    83  
    84  // TableOption is used for create table options like AUTO_INCREMENT, INSERT_METHOD, etc
    85  type TableOption struct {
    86  	Name   string
    87  	Value  *Literal
    88  	String string
    89  	Tables TableNames
    90  }
    91  
    92  // ColumnKeyOption indicates whether or not the given column is defined as an
    93  // index element and contains the type of the option
    94  type ColumnKeyOption int
    95  
    96  const (
    97  	colKeyNone ColumnKeyOption = iota
    98  	colKeyPrimary
    99  	colKeySpatialKey
   100  	colKeyFulltextKey
   101  	colKeyUnique
   102  	colKeyUniqueKey
   103  	colKey
   104  )
   105  
   106  // ReferenceAction indicates the action takes by a referential constraint e.g.
   107  // the `CASCADE` in a `FOREIGN KEY .. ON DELETE CASCADE` table definition.
   108  type ReferenceAction int
   109  
   110  // These map to the SQL-defined reference actions.
   111  // See https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html#foreign-keys-referential-actions
   112  const (
   113  	// DefaultAction indicates no action was explicitly specified.
   114  	DefaultAction ReferenceAction = iota
   115  	Restrict
   116  	Cascade
   117  	NoAction
   118  	SetNull
   119  	SetDefault
   120  )
   121  
   122  // ShowTablesOpt is show tables option
   123  type ShowTablesOpt struct {
   124  	Full   string
   125  	DbName string
   126  	Filter *ShowFilter
   127  }
   128  
   129  // ValType specifies the type for Literal.
   130  type ValType int
   131  
   132  // These are the possible Valtype values.
   133  // HexNum represents a 0x... value. It cannot
   134  // be treated as a simple value because it can
   135  // be interpreted differently depending on the
   136  // context.
   137  const (
   138  	StrVal = ValType(iota)
   139  	IntVal
   140  	DecimalVal
   141  	FloatVal
   142  	HexNum
   143  	HexVal
   144  	BitVal
   145  )
   146  
   147  // AddColumn appends the given column to the list in the spec
   148  func (ts *TableSpec) AddColumn(cd *ColumnDefinition) {
   149  	ts.Columns = append(ts.Columns, cd)
   150  }
   151  
   152  // AddIndex appends the given index to the list in the spec
   153  func (ts *TableSpec) AddIndex(id *IndexDefinition) {
   154  	ts.Indexes = append(ts.Indexes, id)
   155  }
   156  
   157  // AddConstraint appends the given index to the list in the spec
   158  func (ts *TableSpec) AddConstraint(cd *ConstraintDefinition) {
   159  	ts.Constraints = append(ts.Constraints, cd)
   160  }
   161  
   162  // DescribeType returns the abbreviated type information as required for
   163  // describe table
   164  func (ct *ColumnType) DescribeType() string {
   165  	buf := NewTrackedBuffer(nil)
   166  	buf.Myprintf("%s", ct.Type)
   167  	if ct.Length != nil && ct.Scale != nil {
   168  		buf.Myprintf("(%v,%v)", ct.Length, ct.Scale)
   169  	} else if ct.Length != nil {
   170  		buf.Myprintf("(%v)", ct.Length)
   171  	}
   172  
   173  	opts := make([]string, 0, 16)
   174  	if ct.Unsigned {
   175  		opts = append(opts, keywordStrings[UNSIGNED])
   176  	}
   177  	if ct.Zerofill {
   178  		opts = append(opts, keywordStrings[ZEROFILL])
   179  	}
   180  	if len(opts) != 0 {
   181  		buf.Myprintf(" %s", strings.Join(opts, " "))
   182  	}
   183  	return buf.String()
   184  }
   185  
   186  // SQLType returns the sqltypes type code for the given column
   187  func (ct *ColumnType) SQLType() querypb.Type {
   188  	switch strings.ToLower(ct.Type) {
   189  	case keywordStrings[TINYINT]:
   190  		if ct.Unsigned {
   191  			return sqltypes.Uint8
   192  		}
   193  		return sqltypes.Int8
   194  	case keywordStrings[SMALLINT]:
   195  		if ct.Unsigned {
   196  			return sqltypes.Uint16
   197  		}
   198  		return sqltypes.Int16
   199  	case keywordStrings[MEDIUMINT]:
   200  		if ct.Unsigned {
   201  			return sqltypes.Uint24
   202  		}
   203  		return sqltypes.Int24
   204  	case keywordStrings[INT], keywordStrings[INTEGER]:
   205  		if ct.Unsigned {
   206  			return sqltypes.Uint32
   207  		}
   208  		return sqltypes.Int32
   209  	case keywordStrings[BIGINT]:
   210  		if ct.Unsigned {
   211  			return sqltypes.Uint64
   212  		}
   213  		return sqltypes.Int64
   214  	case keywordStrings[BOOL], keywordStrings[BOOLEAN]:
   215  		return sqltypes.Uint8
   216  	case keywordStrings[TEXT]:
   217  		return sqltypes.Text
   218  	case keywordStrings[TINYTEXT]:
   219  		return sqltypes.Text
   220  	case keywordStrings[MEDIUMTEXT]:
   221  		return sqltypes.Text
   222  	case keywordStrings[LONGTEXT]:
   223  		return sqltypes.Text
   224  	case keywordStrings[BLOB]:
   225  		return sqltypes.Blob
   226  	case keywordStrings[TINYBLOB]:
   227  		return sqltypes.Blob
   228  	case keywordStrings[MEDIUMBLOB]:
   229  		return sqltypes.Blob
   230  	case keywordStrings[LONGBLOB]:
   231  		return sqltypes.Blob
   232  	case keywordStrings[CHAR]:
   233  		return sqltypes.Char
   234  	case keywordStrings[VARCHAR]:
   235  		return sqltypes.VarChar
   236  	case keywordStrings[BINARY]:
   237  		return sqltypes.Binary
   238  	case keywordStrings[VARBINARY]:
   239  		return sqltypes.VarBinary
   240  	case keywordStrings[DATE]:
   241  		return sqltypes.Date
   242  	case keywordStrings[TIME]:
   243  		return sqltypes.Time
   244  	case keywordStrings[DATETIME]:
   245  		return sqltypes.Datetime
   246  	case keywordStrings[TIMESTAMP]:
   247  		return sqltypes.Timestamp
   248  	case keywordStrings[YEAR]:
   249  		return sqltypes.Year
   250  	case keywordStrings[FLOAT_TYPE]:
   251  		return sqltypes.Float32
   252  	case keywordStrings[DOUBLE]:
   253  		return sqltypes.Float64
   254  	case keywordStrings[DECIMAL]:
   255  		return sqltypes.Decimal
   256  	case keywordStrings[BIT]:
   257  		return sqltypes.Bit
   258  	case keywordStrings[ENUM]:
   259  		return sqltypes.Enum
   260  	case keywordStrings[SET]:
   261  		return sqltypes.Set
   262  	case keywordStrings[JSON]:
   263  		return sqltypes.TypeJSON
   264  	case keywordStrings[GEOMETRY]:
   265  		return sqltypes.Geometry
   266  	case keywordStrings[POINT]:
   267  		return sqltypes.Geometry
   268  	case keywordStrings[LINESTRING]:
   269  		return sqltypes.Geometry
   270  	case keywordStrings[POLYGON]:
   271  		return sqltypes.Geometry
   272  	case keywordStrings[GEOMETRYCOLLECTION]:
   273  		return sqltypes.Geometry
   274  	case keywordStrings[MULTIPOINT]:
   275  		return sqltypes.Geometry
   276  	case keywordStrings[MULTILINESTRING]:
   277  		return sqltypes.Geometry
   278  	case keywordStrings[MULTIPOLYGON]:
   279  		return sqltypes.Geometry
   280  	}
   281  	return sqltypes.Null
   282  }
   283  
   284  // ParseParams parses the vindex parameter list, pulling out the special-case
   285  // "owner" parameter
   286  func (node *VindexSpec) ParseParams() (string, map[string]string) {
   287  	var owner string
   288  	params := map[string]string{}
   289  	for _, p := range node.Params {
   290  		if p.Key.Lowered() == VindexOwnerStr {
   291  			owner = p.Val
   292  		} else {
   293  			params[p.Key.String()] = p.Val
   294  		}
   295  	}
   296  	return owner, params
   297  }
   298  
   299  var _ ConstraintInfo = &ForeignKeyDefinition{}
   300  
   301  func (f *ForeignKeyDefinition) iConstraintInfo() {}
   302  
   303  var _ ConstraintInfo = &CheckConstraintDefinition{}
   304  
   305  func (c *CheckConstraintDefinition) iConstraintInfo() {}
   306  
   307  // HasOnTable returns true if the show statement has an "on" clause
   308  func (node *ShowLegacy) HasOnTable() bool {
   309  	return node.OnTable.Name.v != ""
   310  }
   311  
   312  // HasTable returns true if the show statement has a parsed table name.
   313  // Not all show statements parse table names.
   314  func (node *ShowLegacy) HasTable() bool {
   315  	return node.Table.Name.v != ""
   316  }
   317  
   318  // FindColumn finds a column in the column list, returning
   319  // the index if it exists or -1 otherwise
   320  func (node Columns) FindColumn(col ColIdent) int {
   321  	for i, colName := range node {
   322  		if colName.Equal(col) {
   323  			return i
   324  		}
   325  	}
   326  	return -1
   327  }
   328  
   329  // RemoveHints returns a new AliasedTableExpr with the hints removed.
   330  func (node *AliasedTableExpr) RemoveHints() *AliasedTableExpr {
   331  	noHints := *node
   332  	noHints.Hints = nil
   333  	return &noHints
   334  }
   335  
   336  //TableName returns a TableName pointing to this table expr
   337  func (node *AliasedTableExpr) TableName() (TableName, error) {
   338  	if !node.As.IsEmpty() {
   339  		return TableName{Name: node.As}, nil
   340  	}
   341  
   342  	tableName, ok := node.Expr.(TableName)
   343  	if !ok {
   344  		return TableName{}, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "BUG: the AST has changed. This should not be possible")
   345  	}
   346  
   347  	return tableName, nil
   348  }
   349  
   350  // IsEmpty returns true if TableName is nil or empty.
   351  func (node TableName) IsEmpty() bool {
   352  	// If Name is empty, Qualifier is also empty.
   353  	return node.Name.IsEmpty()
   354  }
   355  
   356  // ToViewName returns a TableName acceptable for use as a VIEW. VIEW names are
   357  // always lowercase, so ToViewName lowercasese the name. Databases are case-sensitive
   358  // so Qualifier is left untouched.
   359  func (node TableName) ToViewName() TableName {
   360  	return TableName{
   361  		Qualifier: node.Qualifier,
   362  		Name:      NewTableIdent(strings.ToLower(node.Name.v)),
   363  	}
   364  }
   365  
   366  // NewWhere creates a WHERE or HAVING clause out
   367  // of a Expr. If the expression is nil, it returns nil.
   368  func NewWhere(typ WhereType, expr Expr) *Where {
   369  	if expr == nil {
   370  		return nil
   371  	}
   372  	return &Where{Type: typ, Expr: expr}
   373  }
   374  
   375  // ReplaceExpr finds the from expression from root
   376  // and replaces it with to. If from matches root,
   377  // then to is returned.
   378  func ReplaceExpr(root, from, to Expr) (Expr, bool) {
   379  	tmp := Rewrite(root, replaceExpr(from, to), nil)
   380  
   381  	expr, success := tmp.(Expr)
   382  
   383  	return expr, success
   384  }
   385  
   386  func replaceExpr(from, to Expr) func(cursor *Cursor) bool {
   387  	return func(cursor *Cursor) bool {
   388  		if cursor.Node() == from {
   389  			cursor.Replace(to)
   390  		}
   391  		switch cursor.Node().(type) {
   392  		case *ExistsExpr, *Literal, *Subquery, *ValuesFuncExpr, *Default:
   393  			return false
   394  		}
   395  
   396  		return true
   397  	}
   398  }
   399  
   400  // IsImpossible returns true if the comparison in the expression can never evaluate to true.
   401  // Note that this is not currently exhaustive to ALL impossible comparisons.
   402  func (node *ComparisonExpr) IsImpossible() bool {
   403  	var left, right *Literal
   404  	var ok bool
   405  	if left, ok = node.Left.(*Literal); !ok {
   406  		return false
   407  	}
   408  	if right, ok = node.Right.(*Literal); !ok {
   409  		return false
   410  	}
   411  	if node.Operator == NotEqualOp && left.Type == right.Type {
   412  		if len(left.Val) != len(right.Val) {
   413  			return false
   414  		}
   415  
   416  		for i := range left.Val {
   417  			if left.Val[i] != right.Val[i] {
   418  				return false
   419  			}
   420  		}
   421  		return true
   422  	}
   423  	return false
   424  }
   425  
   426  // NewStrLiteral builds a new StrVal.
   427  func NewStrLiteral(in string) *Literal {
   428  	return &Literal{Type: StrVal, Val: in}
   429  }
   430  
   431  // NewIntLiteral builds a new IntVal.
   432  func NewIntLiteral(in string) *Literal {
   433  	return &Literal{Type: IntVal, Val: in}
   434  }
   435  
   436  func NewDecimalLiteral(in string) *Literal {
   437  	return &Literal{Type: DecimalVal, Val: in}
   438  }
   439  
   440  // NewFloatLiteral builds a new FloatVal.
   441  func NewFloatLiteral(in string) *Literal {
   442  	return &Literal{Type: FloatVal, Val: in}
   443  }
   444  
   445  // NewHexNumLiteral builds a new HexNum.
   446  func NewHexNumLiteral(in string) *Literal {
   447  	return &Literal{Type: HexNum, Val: in}
   448  }
   449  
   450  // NewHexLiteral builds a new HexVal.
   451  func NewHexLiteral(in string) *Literal {
   452  	return &Literal{Type: HexVal, Val: in}
   453  }
   454  
   455  // NewBitLiteral builds a new BitVal containing a bit literal.
   456  func NewBitLiteral(in string) *Literal {
   457  	return &Literal{Type: BitVal, Val: in}
   458  }
   459  
   460  // NewArgument builds a new ValArg.
   461  func NewArgument(in string) Argument {
   462  	return Argument(in)
   463  }
   464  
   465  // NewListArg builds a new ListArg.
   466  func NewListArg(in string) ListArg {
   467  	return ListArg(in)
   468  }
   469  
   470  // String returns ListArg as a string.
   471  func (node ListArg) String() string {
   472  	return string(node)
   473  }
   474  
   475  // Bytes return the []byte
   476  func (node *Literal) Bytes() []byte {
   477  	return []byte(node.Val)
   478  }
   479  
   480  // HexDecode decodes the hexval into bytes.
   481  func (node *Literal) HexDecode() ([]byte, error) {
   482  	return hex.DecodeString(node.Val)
   483  }
   484  
   485  // encodeHexValToMySQLQueryFormat encodes the hexval back into the query format
   486  // for passing on to MySQL as a bind var
   487  func (node *Literal) encodeHexValToMySQLQueryFormat() ([]byte, error) {
   488  	nb := node.Bytes()
   489  	if node.Type != HexVal {
   490  		return nb, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Literal value is not a HexVal")
   491  	}
   492  
   493  	// Let's make this idempotent in case it's called more than once
   494  	match, err := regexp.Match("^x'.*'$", nb)
   495  	if err != nil {
   496  		return nb, err
   497  	}
   498  	if match {
   499  		return nb, nil
   500  	}
   501  
   502  	var bb bytes.Buffer
   503  	bb.WriteByte('x')
   504  	bb.WriteByte('\'')
   505  	bb.WriteString(string(nb))
   506  	bb.WriteByte('\'')
   507  	nb = bb.Bytes()
   508  	return nb, nil
   509  }
   510  
   511  // Equal returns true if the column names match.
   512  func (node *ColName) Equal(c *ColName) bool {
   513  	// Failsafe: ColName should not be empty.
   514  	if node == nil || c == nil {
   515  		return false
   516  	}
   517  	return node.Name.Equal(c.Name) && node.Qualifier == c.Qualifier
   518  }
   519  
   520  // Aggregates is a map of all aggregate functions.
   521  var Aggregates = map[string]bool{
   522  	"avg":          true,
   523  	"bit_and":      true,
   524  	"bit_or":       true,
   525  	"bit_xor":      true,
   526  	"count":        true,
   527  	"group_concat": true,
   528  	"max":          true,
   529  	"min":          true,
   530  	"std":          true,
   531  	"stddev_pop":   true,
   532  	"stddev_samp":  true,
   533  	"stddev":       true,
   534  	"sum":          true,
   535  	"var_pop":      true,
   536  	"var_samp":     true,
   537  	"variance":     true,
   538  }
   539  
   540  // IsAggregate returns true if the function is an aggregate.
   541  func (node *FuncExpr) IsAggregate() bool {
   542  	return Aggregates[node.Name.Lowered()]
   543  }
   544  
   545  // NewColIdent makes a new ColIdent.
   546  func NewColIdent(str string) ColIdent {
   547  	return ColIdent{
   548  		val: str,
   549  	}
   550  }
   551  
   552  // NewColName makes a new ColName
   553  func NewColName(str string) *ColName {
   554  	return &ColName{
   555  		Name: NewColIdent(str),
   556  	}
   557  }
   558  
   559  // NewColNameWithQualifier makes a new ColName pointing to a specific table
   560  func NewColNameWithQualifier(identifier string, table TableName) *ColName {
   561  	return &ColName{
   562  		Name: NewColIdent(identifier),
   563  		Qualifier: TableName{
   564  			Name:      NewTableIdent(table.Name.String()),
   565  			Qualifier: NewTableIdent(table.Qualifier.String()),
   566  		},
   567  	}
   568  }
   569  
   570  //NewSelect is used to create a select statement
   571  func NewSelect(comments Comments, exprs SelectExprs, selectOptions []string, into *SelectInto, from TableExprs, where *Where, groupBy GroupBy, having *Where) *Select {
   572  	var cache *bool
   573  	var distinct, straightJoinHint, sqlFoundRows bool
   574  
   575  	for _, option := range selectOptions {
   576  		switch strings.ToLower(option) {
   577  		case DistinctStr:
   578  			distinct = true
   579  		case SQLCacheStr:
   580  			truth := true
   581  			cache = &truth
   582  		case SQLNoCacheStr:
   583  			truth := false
   584  			cache = &truth
   585  		case StraightJoinHint:
   586  			straightJoinHint = true
   587  		case SQLCalcFoundRowsStr:
   588  			sqlFoundRows = true
   589  		}
   590  	}
   591  	return &Select{
   592  		Cache:            cache,
   593  		Comments:         comments,
   594  		Distinct:         distinct,
   595  		StraightJoinHint: straightJoinHint,
   596  		SQLCalcFoundRows: sqlFoundRows,
   597  		SelectExprs:      exprs,
   598  		Into:             into,
   599  		From:             from,
   600  		Where:            where,
   601  		GroupBy:          groupBy,
   602  		Having:           having,
   603  	}
   604  }
   605  
   606  // NewColIdentWithAt makes a new ColIdent.
   607  func NewColIdentWithAt(str string, at AtCount) ColIdent {
   608  	return ColIdent{
   609  		val: str,
   610  		at:  at,
   611  	}
   612  }
   613  
   614  // IsEmpty returns true if the name is empty.
   615  func (node ColIdent) IsEmpty() bool {
   616  	return node.val == ""
   617  }
   618  
   619  // String returns the unescaped column name. It must
   620  // not be used for SQL generation. Use sqlparser.String
   621  // instead. The Stringer conformance is for usage
   622  // in templates.
   623  func (node ColIdent) String() string {
   624  	atStr := ""
   625  	for i := NoAt; i < node.at; i++ {
   626  		atStr += "@"
   627  	}
   628  	return atStr + node.val
   629  }
   630  
   631  // CompliantName returns a compliant id name
   632  // that can be used for a bind var.
   633  func (node ColIdent) CompliantName() string {
   634  	return compliantName(node.val)
   635  }
   636  
   637  // Lowered returns a lower-cased column name.
   638  // This function should generally be used only for optimizing
   639  // comparisons.
   640  func (node ColIdent) Lowered() string {
   641  	if node.val == "" {
   642  		return ""
   643  	}
   644  	if node.lowered == "" {
   645  		node.lowered = strings.ToLower(node.val)
   646  	}
   647  	return node.lowered
   648  }
   649  
   650  // Equal performs a case-insensitive compare.
   651  func (node ColIdent) Equal(in ColIdent) bool {
   652  	return node.Lowered() == in.Lowered()
   653  }
   654  
   655  // EqualString performs a case-insensitive compare with str.
   656  func (node ColIdent) EqualString(str string) bool {
   657  	return node.Lowered() == strings.ToLower(str)
   658  }
   659  
   660  // MarshalJSON marshals into JSON.
   661  func (node ColIdent) MarshalJSON() ([]byte, error) {
   662  	return json.Marshal(node.val)
   663  }
   664  
   665  // UnmarshalJSON unmarshals from JSON.
   666  func (node *ColIdent) UnmarshalJSON(b []byte) error {
   667  	var result string
   668  	err := json.Unmarshal(b, &result)
   669  	if err != nil {
   670  		return err
   671  	}
   672  	node.val = result
   673  	return nil
   674  }
   675  
   676  // NewTableIdent creates a new TableIdent.
   677  func NewTableIdent(str string) TableIdent {
   678  	// Use StringClone on the table name to ensure it is not pinned to the
   679  	// underlying query string that has been generated by the parser. This
   680  	// could lead to a significant increase in memory usage when the table
   681  	// name comes from a large query.
   682  	return TableIdent{v: hack.StringClone(str)}
   683  }
   684  
   685  // IsEmpty returns true if TabIdent is empty.
   686  func (node TableIdent) IsEmpty() bool {
   687  	return node.v == ""
   688  }
   689  
   690  // String returns the unescaped table name. It must
   691  // not be used for SQL generation. Use sqlparser.String
   692  // instead. The Stringer conformance is for usage
   693  // in templates.
   694  func (node TableIdent) String() string {
   695  	return node.v
   696  }
   697  
   698  // CompliantName returns a compliant id name
   699  // that can be used for a bind var.
   700  func (node TableIdent) CompliantName() string {
   701  	return compliantName(node.v)
   702  }
   703  
   704  // MarshalJSON marshals into JSON.
   705  func (node TableIdent) MarshalJSON() ([]byte, error) {
   706  	return json.Marshal(node.v)
   707  }
   708  
   709  // UnmarshalJSON unmarshals from JSON.
   710  func (node *TableIdent) UnmarshalJSON(b []byte) error {
   711  	var result string
   712  	err := json.Unmarshal(b, &result)
   713  	if err != nil {
   714  		return err
   715  	}
   716  	node.v = result
   717  	return nil
   718  }
   719  
   720  func containEscapableChars(s string, at AtCount) bool {
   721  	isDbSystemVariable := at != NoAt
   722  
   723  	for i := range s {
   724  		c := uint16(s[i])
   725  		letter := isLetter(c)
   726  		systemVarChar := isDbSystemVariable && isCarat(c)
   727  		if !(letter || systemVarChar) {
   728  			if i == 0 || !isDigit(c) {
   729  				return true
   730  			}
   731  		}
   732  	}
   733  
   734  	return false
   735  }
   736  
   737  func formatID(buf *TrackedBuffer, original string, at AtCount) {
   738  	_, isKeyword := keywordLookupTable.LookupString(original)
   739  	if isKeyword || containEscapableChars(original, at) {
   740  		writeEscapedString(buf, original)
   741  	} else {
   742  		buf.WriteString(original)
   743  	}
   744  }
   745  
   746  func writeEscapedString(buf *TrackedBuffer, original string) {
   747  	buf.WriteByte('`')
   748  	for _, c := range original {
   749  		buf.WriteRune(c)
   750  		if c == '`' {
   751  			buf.WriteByte('`')
   752  		}
   753  	}
   754  	buf.WriteByte('`')
   755  }
   756  
   757  func compliantName(in string) string {
   758  	var buf strings.Builder
   759  	for i, c := range in {
   760  		if !isLetter(uint16(c)) {
   761  			if i == 0 || !isDigit(uint16(c)) {
   762  				buf.WriteByte('_')
   763  				continue
   764  			}
   765  		}
   766  		buf.WriteRune(c)
   767  	}
   768  	return buf.String()
   769  }
   770  
   771  // AddOrder adds an order by element
   772  func (node *Select) AddOrder(order *Order) {
   773  	node.OrderBy = append(node.OrderBy, order)
   774  }
   775  
   776  // SetOrderBy sets the order by clause
   777  func (node *Select) SetOrderBy(orderBy OrderBy) {
   778  	node.OrderBy = orderBy
   779  }
   780  
   781  // SetLimit sets the limit clause
   782  func (node *Select) SetLimit(limit *Limit) {
   783  	node.Limit = limit
   784  }
   785  
   786  // SetLock sets the lock clause
   787  func (node *Select) SetLock(lock Lock) {
   788  	node.Lock = lock
   789  }
   790  
   791  // SetInto sets the into clause
   792  func (node *Select) SetInto(into *SelectInto) {
   793  	node.Into = into
   794  }
   795  
   796  // SetWith sets the with clause to a select statement
   797  func (node *Select) SetWith(with *With) {
   798  	node.With = with
   799  }
   800  
   801  // MakeDistinct makes the statement distinct
   802  func (node *Select) MakeDistinct() {
   803  	node.Distinct = true
   804  }
   805  
   806  // GetColumnCount return SelectExprs count.
   807  func (node *Select) GetColumnCount() int {
   808  	return len(node.SelectExprs)
   809  }
   810  
   811  // SetComments implements the SelectStatement interface
   812  func (node *Select) SetComments(comments Comments) {
   813  	node.Comments = comments
   814  }
   815  
   816  // GetComments implements the SelectStatement interface
   817  func (node *Select) GetComments() Comments {
   818  	return node.Comments
   819  }
   820  
   821  // AddWhere adds the boolean expression to the
   822  // WHERE clause as an AND condition.
   823  func (node *Select) AddWhere(expr Expr) {
   824  	if node.Where == nil {
   825  		node.Where = &Where{
   826  			Type: WhereClause,
   827  			Expr: expr,
   828  		}
   829  		return
   830  	}
   831  	node.Where.Expr = &AndExpr{
   832  		Left:  node.Where.Expr,
   833  		Right: expr,
   834  	}
   835  }
   836  
   837  // AddHaving adds the boolean expression to the
   838  // HAVING clause as an AND condition.
   839  func (node *Select) AddHaving(expr Expr) {
   840  	if node.Having == nil {
   841  		node.Having = &Where{
   842  			Type: HavingClause,
   843  			Expr: expr,
   844  		}
   845  		return
   846  	}
   847  	node.Having.Expr = &AndExpr{
   848  		Left:  node.Having.Expr,
   849  		Right: expr,
   850  	}
   851  }
   852  
   853  // AddWhere adds the boolean expression to the
   854  // WHERE clause as an AND condition.
   855  func (node *Update) AddWhere(expr Expr) {
   856  	if node.Where == nil {
   857  		node.Where = &Where{
   858  			Type: WhereClause,
   859  			Expr: expr,
   860  		}
   861  		return
   862  	}
   863  	node.Where.Expr = &AndExpr{
   864  		Left:  node.Where.Expr,
   865  		Right: expr,
   866  	}
   867  }
   868  
   869  // AddOrder adds an order by element
   870  func (node *Union) AddOrder(order *Order) {
   871  	node.OrderBy = append(node.OrderBy, order)
   872  }
   873  
   874  // SetOrderBy sets the order by clause
   875  func (node *Union) SetOrderBy(orderBy OrderBy) {
   876  	node.OrderBy = orderBy
   877  }
   878  
   879  // SetLimit sets the limit clause
   880  func (node *Union) SetLimit(limit *Limit) {
   881  	node.Limit = limit
   882  }
   883  
   884  // SetLock sets the lock clause
   885  func (node *Union) SetLock(lock Lock) {
   886  	node.Lock = lock
   887  }
   888  
   889  // SetInto sets the into clause
   890  func (node *Union) SetInto(into *SelectInto) {
   891  	node.Into = into
   892  }
   893  
   894  // SetWith sets the with clause to a union statement
   895  func (node *Union) SetWith(with *With) {
   896  	node.With = with
   897  }
   898  
   899  // MakeDistinct implements the SelectStatement interface
   900  func (node *Union) MakeDistinct() {
   901  	node.Distinct = true
   902  }
   903  
   904  // GetColumnCount implements the SelectStatement interface
   905  func (node *Union) GetColumnCount() int {
   906  	return node.Left.GetColumnCount()
   907  }
   908  
   909  // SetComments implements the SelectStatement interface
   910  func (node *Union) SetComments(comments Comments) {
   911  	node.Left.SetComments(comments)
   912  }
   913  
   914  // GetComments implements the SelectStatement interface
   915  func (node *Union) GetComments() Comments {
   916  	return node.Left.GetComments()
   917  }
   918  
   919  func requiresParen(stmt SelectStatement) bool {
   920  	switch node := stmt.(type) {
   921  	case *Union:
   922  		return len(node.OrderBy) != 0 || node.Lock != 0 || node.Into != nil || node.Limit != nil
   923  	case *Select:
   924  		return len(node.OrderBy) != 0 || node.Lock != 0 || node.Into != nil || node.Limit != nil
   925  	}
   926  
   927  	return false
   928  }
   929  
   930  func setLockInSelect(stmt SelectStatement, lock Lock) {
   931  	stmt.SetLock(lock)
   932  }
   933  
   934  // ToString returns the string associated with the DDLAction Enum
   935  func (action DDLAction) ToString() string {
   936  	switch action {
   937  	case CreateDDLAction:
   938  		return CreateStr
   939  	case AlterDDLAction:
   940  		return AlterStr
   941  	case DropDDLAction:
   942  		return DropStr
   943  	case RenameDDLAction:
   944  		return RenameStr
   945  	case TruncateDDLAction:
   946  		return TruncateStr
   947  	case CreateVindexDDLAction:
   948  		return CreateVindexStr
   949  	case DropVindexDDLAction:
   950  		return DropVindexStr
   951  	case AddVschemaTableDDLAction:
   952  		return AddVschemaTableStr
   953  	case DropVschemaTableDDLAction:
   954  		return DropVschemaTableStr
   955  	case AddColVindexDDLAction:
   956  		return AddColVindexStr
   957  	case DropColVindexDDLAction:
   958  		return DropColVindexStr
   959  	case AddSequenceDDLAction:
   960  		return AddSequenceStr
   961  	case AddAutoIncDDLAction:
   962  		return AddAutoIncStr
   963  	default:
   964  		return "Unknown DDL Action"
   965  	}
   966  }
   967  
   968  // ToString returns the string associated with the Scope enum
   969  func (scope Scope) ToString() string {
   970  	switch scope {
   971  	case SessionScope:
   972  		return SessionStr
   973  	case GlobalScope:
   974  		return GlobalStr
   975  	case VitessMetadataScope:
   976  		return VitessMetadataStr
   977  	case VariableScope:
   978  		return VariableStr
   979  	case LocalScope:
   980  		return LocalStr
   981  	case ImplicitScope:
   982  		return ImplicitStr
   983  	default:
   984  		return "Unknown Scope"
   985  	}
   986  }
   987  
   988  // ToString returns the IgnoreStr if ignore is true.
   989  func (ignore Ignore) ToString() string {
   990  	if ignore {
   991  		return IgnoreStr
   992  	}
   993  	return ""
   994  }
   995  
   996  // ToString returns the string associated with the type of lock
   997  func (lock Lock) ToString() string {
   998  	switch lock {
   999  	case NoLock:
  1000  		return NoLockStr
  1001  	case ForUpdateLock:
  1002  		return ForUpdateStr
  1003  	case ShareModeLock:
  1004  		return ShareModeStr
  1005  	default:
  1006  		return "Unknown lock"
  1007  	}
  1008  }
  1009  
  1010  // ToString returns the string associated with WhereType
  1011  func (whereType WhereType) ToString() string {
  1012  	switch whereType {
  1013  	case WhereClause:
  1014  		return WhereStr
  1015  	case HavingClause:
  1016  		return HavingStr
  1017  	default:
  1018  		return "Unknown where type"
  1019  	}
  1020  }
  1021  
  1022  // ToString returns the string associated with JoinType
  1023  func (joinType JoinType) ToString() string {
  1024  	switch joinType {
  1025  	case NormalJoinType:
  1026  		return JoinStr
  1027  	case StraightJoinType:
  1028  		return StraightJoinStr
  1029  	case LeftJoinType:
  1030  		return LeftJoinStr
  1031  	case RightJoinType:
  1032  		return RightJoinStr
  1033  	case NaturalJoinType:
  1034  		return NaturalJoinStr
  1035  	case NaturalLeftJoinType:
  1036  		return NaturalLeftJoinStr
  1037  	case NaturalRightJoinType:
  1038  		return NaturalRightJoinStr
  1039  	default:
  1040  		return "Unknown join type"
  1041  	}
  1042  }
  1043  
  1044  // ToString returns the operator as a string
  1045  func (op ComparisonExprOperator) ToString() string {
  1046  	switch op {
  1047  	case EqualOp:
  1048  		return EqualStr
  1049  	case LessThanOp:
  1050  		return LessThanStr
  1051  	case GreaterThanOp:
  1052  		return GreaterThanStr
  1053  	case LessEqualOp:
  1054  		return LessEqualStr
  1055  	case GreaterEqualOp:
  1056  		return GreaterEqualStr
  1057  	case NotEqualOp:
  1058  		return NotEqualStr
  1059  	case NullSafeEqualOp:
  1060  		return NullSafeEqualStr
  1061  	case InOp:
  1062  		return InStr
  1063  	case NotInOp:
  1064  		return NotInStr
  1065  	case LikeOp:
  1066  		return LikeStr
  1067  	case NotLikeOp:
  1068  		return NotLikeStr
  1069  	case RegexpOp:
  1070  		return RegexpStr
  1071  	case NotRegexpOp:
  1072  		return NotRegexpStr
  1073  	default:
  1074  		return "Unknown ComparisonExpOperator"
  1075  	}
  1076  }
  1077  
  1078  // ToString returns the operator as a string
  1079  func (op IsExprOperator) ToString() string {
  1080  	switch op {
  1081  	case IsNullOp:
  1082  		return IsNullStr
  1083  	case IsNotNullOp:
  1084  		return IsNotNullStr
  1085  	case IsTrueOp:
  1086  		return IsTrueStr
  1087  	case IsNotTrueOp:
  1088  		return IsNotTrueStr
  1089  	case IsFalseOp:
  1090  		return IsFalseStr
  1091  	case IsNotFalseOp:
  1092  		return IsNotFalseStr
  1093  	default:
  1094  		return "Unknown IsExprOperator"
  1095  	}
  1096  }
  1097  
  1098  // ToString returns the operator as a string
  1099  func (op BinaryExprOperator) ToString() string {
  1100  	switch op {
  1101  	case BitAndOp:
  1102  		return BitAndStr
  1103  	case BitOrOp:
  1104  		return BitOrStr
  1105  	case BitXorOp:
  1106  		return BitXorStr
  1107  	case PlusOp:
  1108  		return PlusStr
  1109  	case MinusOp:
  1110  		return MinusStr
  1111  	case MultOp:
  1112  		return MultStr
  1113  	case DivOp:
  1114  		return DivStr
  1115  	case IntDivOp:
  1116  		return IntDivStr
  1117  	case ModOp:
  1118  		return ModStr
  1119  	case ShiftLeftOp:
  1120  		return ShiftLeftStr
  1121  	case ShiftRightOp:
  1122  		return ShiftRightStr
  1123  	case JSONExtractOp:
  1124  		return JSONExtractOpStr
  1125  	case JSONUnquoteExtractOp:
  1126  		return JSONUnquoteExtractOpStr
  1127  	default:
  1128  		return "Unknown BinaryExprOperator"
  1129  	}
  1130  }
  1131  
  1132  // ToString returns the operator as a string
  1133  func (op UnaryExprOperator) ToString() string {
  1134  	switch op {
  1135  	case UPlusOp:
  1136  		return UPlusStr
  1137  	case UMinusOp:
  1138  		return UMinusStr
  1139  	case TildaOp:
  1140  		return TildaStr
  1141  	case BangOp:
  1142  		return BangStr
  1143  	case BinaryOp:
  1144  		return BinaryStr
  1145  	case NStringOp:
  1146  		return NStringStr
  1147  	default:
  1148  		return "Unknown UnaryExprOperator"
  1149  	}
  1150  }
  1151  
  1152  // ToString returns the option as a string
  1153  func (option MatchExprOption) ToString() string {
  1154  	switch option {
  1155  	case NoOption:
  1156  		return NoOptionStr
  1157  	case BooleanModeOpt:
  1158  		return BooleanModeStr
  1159  	case NaturalLanguageModeOpt:
  1160  		return NaturalLanguageModeStr
  1161  	case NaturalLanguageModeWithQueryExpansionOpt:
  1162  		return NaturalLanguageModeWithQueryExpansionStr
  1163  	case QueryExpansionOpt:
  1164  		return QueryExpansionStr
  1165  	default:
  1166  		return "Unknown MatchExprOption"
  1167  	}
  1168  }
  1169  
  1170  // ToString returns the direction as a string
  1171  func (dir OrderDirection) ToString() string {
  1172  	switch dir {
  1173  	case AscOrder:
  1174  		return AscScr
  1175  	case DescOrder:
  1176  		return DescScr
  1177  	default:
  1178  		return "Unknown OrderDirection"
  1179  	}
  1180  }
  1181  
  1182  // ToString returns the operator as a string
  1183  func (op ConvertTypeOperator) ToString() string {
  1184  	switch op {
  1185  	case NoOperator:
  1186  		return NoOperatorStr
  1187  	case CharacterSetOp:
  1188  		return CharacterSetStr
  1189  	default:
  1190  		return "Unknown ConvertTypeOperator"
  1191  	}
  1192  }
  1193  
  1194  // ToString returns the type as a string
  1195  func (ty IndexHintsType) ToString() string {
  1196  	switch ty {
  1197  	case UseOp:
  1198  		return UseStr
  1199  	case IgnoreOp:
  1200  		return IgnoreStr
  1201  	case ForceOp:
  1202  		return ForceStr
  1203  	default:
  1204  		return "Unknown IndexHintsType"
  1205  	}
  1206  }
  1207  
  1208  // ToString returns the type as a string
  1209  func (ty ExplainType) ToString() string {
  1210  	switch ty {
  1211  	case EmptyType:
  1212  		return EmptyStr
  1213  	case TreeType:
  1214  		return TreeStr
  1215  	case JSONType:
  1216  		return JSONStr
  1217  	case VitessType:
  1218  		return VitessStr
  1219  	case TraditionalType:
  1220  		return TraditionalStr
  1221  	case AnalyzeType:
  1222  		return AnalyzeStr
  1223  	default:
  1224  		return "Unknown ExplainType"
  1225  	}
  1226  }
  1227  
  1228  // ToString returns the type as a string
  1229  func (ty IntervalTypes) ToString() string {
  1230  	switch ty {
  1231  	case IntervalYear:
  1232  		return YearStr
  1233  	case IntervalQuarter:
  1234  		return QuarterStr
  1235  	case IntervalMonth:
  1236  		return MonthStr
  1237  	case IntervalWeek:
  1238  		return WeekStr
  1239  	case IntervalDay:
  1240  		return DayStr
  1241  	case IntervalHour:
  1242  		return HourStr
  1243  	case IntervalMinute:
  1244  		return MinuteStr
  1245  	case IntervalSecond:
  1246  		return SecondStr
  1247  	case IntervalMicrosecond:
  1248  		return MicrosecondStr
  1249  	case IntervalYearMonth:
  1250  		return YearMonthStr
  1251  	case IntervalDayHour:
  1252  		return DayHourStr
  1253  	case IntervalDayMinute:
  1254  		return DayMinuteStr
  1255  	case IntervalDaySecond:
  1256  		return DaySecondStr
  1257  	case IntervalHourMinute:
  1258  		return HourMinuteStr
  1259  	case IntervalHourSecond:
  1260  		return HourSecondStr
  1261  	case IntervalMinuteSecond:
  1262  		return MinuteSecondStr
  1263  	case IntervalDayMicrosecond:
  1264  		return DayMicrosecondStr
  1265  	case IntervalHourMicrosecond:
  1266  		return HourMicrosecondStr
  1267  	case IntervalMinuteMicrosecond:
  1268  		return MinuteMicrosecondStr
  1269  	case IntervalSecondMicrosecond:
  1270  		return SecondMicrosecondStr
  1271  	default:
  1272  		return "Unknown IntervalType"
  1273  	}
  1274  }
  1275  
  1276  // ToString returns the type as a string
  1277  func (sel SelectIntoType) ToString() string {
  1278  	switch sel {
  1279  	case IntoOutfile:
  1280  		return IntoOutfileStr
  1281  	case IntoOutfileS3:
  1282  		return IntoOutfileS3Str
  1283  	case IntoDumpfile:
  1284  		return IntoDumpfileStr
  1285  	default:
  1286  		return "Unknown Select Into Type"
  1287  	}
  1288  }
  1289  
  1290  // ToString returns the type as a string
  1291  func (node CollateAndCharsetType) ToString() string {
  1292  	switch node {
  1293  	case CharacterSetType:
  1294  		return CharacterSetStr
  1295  	case CollateType:
  1296  		return CollateStr
  1297  	default:
  1298  		return "Unknown CollateAndCharsetType Type"
  1299  	}
  1300  }
  1301  
  1302  // ToString returns the type as a string
  1303  func (ty LockType) ToString() string {
  1304  	switch ty {
  1305  	case Read:
  1306  		return ReadStr
  1307  	case ReadLocal:
  1308  		return ReadLocalStr
  1309  	case Write:
  1310  		return WriteStr
  1311  	case LowPriorityWrite:
  1312  		return LowPriorityWriteStr
  1313  	default:
  1314  		return "Unknown LockType"
  1315  	}
  1316  }
  1317  
  1318  // ToString returns ShowCommandType as a string
  1319  func (ty ShowCommandType) ToString() string {
  1320  	switch ty {
  1321  	case Charset:
  1322  		return CharsetStr
  1323  	case Collation:
  1324  		return CollationStr
  1325  	case Column:
  1326  		return ColumnStr
  1327  	case CreateDb:
  1328  		return CreateDbStr
  1329  	case CreateE:
  1330  		return CreateEStr
  1331  	case CreateF:
  1332  		return CreateFStr
  1333  	case CreateProc:
  1334  		return CreateProcStr
  1335  	case CreateTbl:
  1336  		return CreateTblStr
  1337  	case CreateTr:
  1338  		return CreateTrStr
  1339  	case CreateV:
  1340  		return CreateVStr
  1341  	case Database:
  1342  		return DatabaseStr
  1343  	case FunctionC:
  1344  		return FunctionCStr
  1345  	case Function:
  1346  		return FunctionStr
  1347  	case GtidExecGlobal:
  1348  		return GtidExecGlobalStr
  1349  	case Index:
  1350  		return IndexStr
  1351  	case OpenTable:
  1352  		return OpenTableStr
  1353  	case Privilege:
  1354  		return PrivilegeStr
  1355  	case ProcedureC:
  1356  		return ProcedureCStr
  1357  	case Procedure:
  1358  		return ProcedureStr
  1359  	case StatusGlobal:
  1360  		return StatusGlobalStr
  1361  	case StatusSession:
  1362  		return StatusSessionStr
  1363  	case Table:
  1364  		return TableStr
  1365  	case TableStatus:
  1366  		return TableStatusStr
  1367  	case Trigger:
  1368  		return TriggerStr
  1369  	case VariableGlobal:
  1370  		return VariableGlobalStr
  1371  	case VariableSession:
  1372  		return VariableSessionStr
  1373  	case VGtidExecGlobal:
  1374  		return VGtidExecGlobalStr
  1375  	case VitessMigrations:
  1376  		return VitessMigrationsStr
  1377  	case Warnings:
  1378  		return WarningsStr
  1379  	case Keyspace:
  1380  		return KeyspaceStr
  1381  	default:
  1382  		return "" +
  1383  			"Unknown ShowCommandType"
  1384  	}
  1385  }
  1386  
  1387  // ToString returns the DropKeyType as a string
  1388  func (key DropKeyType) ToString() string {
  1389  	switch key {
  1390  	case PrimaryKeyType:
  1391  		return PrimaryKeyTypeStr
  1392  	case ForeignKeyType:
  1393  		return ForeignKeyTypeStr
  1394  	case NormalKeyType:
  1395  		return NormalKeyTypeStr
  1396  	default:
  1397  		return "Unknown DropKeyType"
  1398  	}
  1399  }
  1400  
  1401  // ToString returns the LockOptionType as a string
  1402  func (lock LockOptionType) ToString() string {
  1403  	switch lock {
  1404  	case NoneType:
  1405  		return NoneTypeStr
  1406  	case DefaultType:
  1407  		return DefaultTypeStr
  1408  	case SharedType:
  1409  		return SharedTypeStr
  1410  	case ExclusiveType:
  1411  		return ExclusiveTypeStr
  1412  	default:
  1413  		return "Unknown type LockOptionType"
  1414  	}
  1415  }
  1416  
  1417  // CompliantName is used to get the name of the bind variable to use for this column name
  1418  func (node *ColName) CompliantName() string {
  1419  	if !node.Qualifier.IsEmpty() {
  1420  		return node.Qualifier.Name.CompliantName() + "_" + node.Name.CompliantName()
  1421  	}
  1422  	return node.Name.CompliantName()
  1423  }
  1424  
  1425  // isExprAliasForCurrentTimeStamp returns true if the Expr provided is an alias for CURRENT_TIMESTAMP
  1426  func isExprAliasForCurrentTimeStamp(expr Expr) bool {
  1427  	switch node := expr.(type) {
  1428  	case *FuncExpr:
  1429  		return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
  1430  	case *CurTimeFuncExpr:
  1431  		return node.Name.EqualString("current_timestamp") || node.Name.EqualString("now") || node.Name.EqualString("localtimestamp") || node.Name.EqualString("localtime")
  1432  	}
  1433  	return false
  1434  }
  1435  
  1436  // AtCount represents the '@' count in ColIdent
  1437  type AtCount int
  1438  
  1439  const (
  1440  	// NoAt represents no @
  1441  	NoAt AtCount = iota
  1442  	// SingleAt represents @
  1443  	SingleAt
  1444  	// DoubleAt represnts @@
  1445  	DoubleAt
  1446  )
  1447  
  1448  // encodeSQLString encodes the string as a SQL string.
  1449  func encodeSQLString(val string) string {
  1450  	return sqltypes.EncodeStringSQL(val)
  1451  }
  1452  
  1453  // ToString prints the list of table expressions as a string
  1454  // To be used as an alternate for String for []TableExpr
  1455  func ToString(exprs []TableExpr) string {
  1456  	buf := NewTrackedBuffer(nil)
  1457  	prefix := ""
  1458  	for _, expr := range exprs {
  1459  		buf.astPrintf(nil, "%s%v", prefix, expr)
  1460  		prefix = ", "
  1461  	}
  1462  	return buf.String()
  1463  }
  1464  
  1465  // ContainsAggregation returns true if the expression contains aggregation
  1466  func ContainsAggregation(e SQLNode) bool {
  1467  	hasAggregates := false
  1468  	_ = Walk(func(node SQLNode) (kontinue bool, err error) {
  1469  		if IsAggregation(node) {
  1470  			hasAggregates = true
  1471  			return false, nil
  1472  		}
  1473  		return true, nil
  1474  	}, e)
  1475  	return hasAggregates
  1476  }
  1477  
  1478  // IsAggregation returns true if the node is an aggregation expression
  1479  func IsAggregation(node SQLNode) bool {
  1480  	switch node := node.(type) {
  1481  	case *FuncExpr:
  1482  		return node.IsAggregate()
  1483  	case *GroupConcatExpr:
  1484  		return true
  1485  	}
  1486  	return false
  1487  }
  1488  
  1489  // GetFirstSelect gets the first select statement
  1490  func GetFirstSelect(selStmt SelectStatement) *Select {
  1491  	if selStmt == nil {
  1492  		return nil
  1493  	}
  1494  	switch node := selStmt.(type) {
  1495  	case *Select:
  1496  		return node
  1497  	case *Union:
  1498  		return GetFirstSelect(node.Left)
  1499  	}
  1500  	panic("[BUG]: unknown type for SelectStatement")
  1501  }
  1502  
  1503  // GetAllSelects gets all the select statement s
  1504  func GetAllSelects(selStmt SelectStatement) []*Select {
  1505  	switch node := selStmt.(type) {
  1506  	case *Select:
  1507  		return []*Select{node}
  1508  	case *Union:
  1509  		return append(GetAllSelects(node.Left), GetAllSelects(node.Right)...)
  1510  	}
  1511  	panic("[BUG]: unknown type for SelectStatement")
  1512  }
  1513  
  1514  // SetArgName sets argument name.
  1515  func (es *ExtractedSubquery) SetArgName(n string) {
  1516  	es.argName = n
  1517  	es.updateAlternative()
  1518  }
  1519  
  1520  // SetHasValuesArg sets has_values argument.
  1521  func (es *ExtractedSubquery) SetHasValuesArg(n string) {
  1522  	es.hasValuesArg = n
  1523  	es.updateAlternative()
  1524  }
  1525  
  1526  // GetArgName returns argument name.
  1527  func (es *ExtractedSubquery) GetArgName() string {
  1528  	return es.argName
  1529  }
  1530  
  1531  // GetHasValuesArg returns has values argument.
  1532  func (es *ExtractedSubquery) GetHasValuesArg() string {
  1533  	return es.hasValuesArg
  1534  
  1535  }
  1536  
  1537  func (es *ExtractedSubquery) updateAlternative() {
  1538  	switch original := es.Original.(type) {
  1539  	case *ExistsExpr:
  1540  		es.alternative = NewArgument(es.hasValuesArg)
  1541  	case *Subquery:
  1542  		es.alternative = NewArgument(es.argName)
  1543  	case *ComparisonExpr:
  1544  		// other_side = :__sq
  1545  		cmp := &ComparisonExpr{
  1546  			Left:     es.OtherSide,
  1547  			Right:    NewArgument(es.argName),
  1548  			Operator: original.Operator,
  1549  		}
  1550  		var expr Expr = cmp
  1551  		switch original.Operator {
  1552  		case InOp:
  1553  			// :__sq_has_values = 1 and other_side in ::__sq
  1554  			cmp.Right = NewListArg(es.argName)
  1555  			hasValue := &ComparisonExpr{Left: NewArgument(es.hasValuesArg), Right: NewIntLiteral("1"), Operator: EqualOp}
  1556  			expr = AndExpressions(hasValue, cmp)
  1557  		case NotInOp:
  1558  			// :__sq_has_values = 0 or other_side not in ::__sq
  1559  			cmp.Right = NewListArg(es.argName)
  1560  			hasValue := &ComparisonExpr{Left: NewArgument(es.hasValuesArg), Right: NewIntLiteral("0"), Operator: EqualOp}
  1561  			expr = &OrExpr{hasValue, cmp}
  1562  		}
  1563  		es.alternative = expr
  1564  	}
  1565  }
  1566  
  1567  func isExprLiteral(expr Expr) bool {
  1568  	switch expr := expr.(type) {
  1569  	case *Literal:
  1570  		return true
  1571  	case BoolVal:
  1572  		return true
  1573  	case *UnaryExpr:
  1574  		return isExprLiteral(expr.Expr)
  1575  	default:
  1576  		return false
  1577  	}
  1578  }
  1579  
  1580  func defaultRequiresParens(ct *ColumnType) bool {
  1581  	// in 5.7 null value should be without parenthesis, in 8.0 it is allowed either way.
  1582  	// so it is safe to not keep parenthesis around null.
  1583  	if _, isNullVal := ct.Options.Default.(*NullVal); isNullVal {
  1584  		return false
  1585  	}
  1586  
  1587  	switch strings.ToUpper(ct.Type) {
  1588  	case "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "TINYBLOB", "BLOB", "MEDIUMBLOB",
  1589  		"LONGBLOB", "JSON", "GEOMETRY", "POINT",
  1590  		"LINESTRING", "POLYGON", "MULTIPOINT", "MULTILINESTRING",
  1591  		"MULTIPOLYGON", "GEOMETRYCOLLECTION":
  1592  		return true
  1593  	}
  1594  
  1595  	if isExprLiteral(ct.Options.Default) || isExprAliasForCurrentTimeStamp(ct.Options.Default) {
  1596  		return false
  1597  	}
  1598  
  1599  	return true
  1600  }
  1601  
  1602  // RemoveKeyspaceFromColName removes the Qualifier.Qualifier on all ColNames in the expression tree
  1603  func RemoveKeyspaceFromColName(expr Expr) Expr {
  1604  	return RemoveKeyspace(expr).(Expr) // This hard cast is safe because we do not change the type the input
  1605  }
  1606  
  1607  // RemoveKeyspace removes the Qualifier.Qualifier on all ColNames in the AST
  1608  func RemoveKeyspace(in SQLNode) SQLNode {
  1609  	return Rewrite(in, nil, func(cursor *Cursor) bool {
  1610  		switch col := cursor.Node().(type) {
  1611  		case *ColName:
  1612  			if !col.Qualifier.Qualifier.IsEmpty() {
  1613  				col.Qualifier.Qualifier = NewTableIdent("")
  1614  			}
  1615  		}
  1616  		return true
  1617  	})
  1618  }