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