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