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