github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/select.go (about) 1 // Copyright 2012, Google Inc. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in licenses/BSD-vitess.txt. 4 5 // Portions of this file are additionally subject to the following 6 // license and copyright. 7 // 8 // Copyright 2015 The Cockroach Authors. 9 // 10 // Use of this software is governed by the Business Source License 11 // included in the file licenses/BSL.txt. 12 // 13 // As of the Change Date specified in that file, in accordance with 14 // the Business Source License, use of this software will be governed 15 // by the Apache License, Version 2.0, included in the file 16 // licenses/APL.txt. 17 18 // This code was derived from https://github.com/youtube/vitess. 19 20 package tree 21 22 import ( 23 "fmt" 24 25 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 26 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 27 "github.com/cockroachdb/cockroach/pkg/util/log" 28 "github.com/cockroachdb/errors" 29 ) 30 31 // SelectStatement represents any SELECT statement. 32 type SelectStatement interface { 33 Statement 34 selectStatement() 35 } 36 37 func (*ParenSelect) selectStatement() {} 38 func (*SelectClause) selectStatement() {} 39 func (*UnionClause) selectStatement() {} 40 func (*ValuesClause) selectStatement() {} 41 42 // Select represents a SelectStatement with an ORDER and/or LIMIT. 43 type Select struct { 44 With *With 45 Select SelectStatement 46 OrderBy OrderBy 47 Limit *Limit 48 Locking LockingClause 49 } 50 51 // Format implements the NodeFormatter interface. 52 func (node *Select) Format(ctx *FmtCtx) { 53 ctx.FormatNode(node.With) 54 ctx.FormatNode(node.Select) 55 if len(node.OrderBy) > 0 { 56 ctx.WriteByte(' ') 57 ctx.FormatNode(&node.OrderBy) 58 } 59 if node.Limit != nil { 60 ctx.WriteByte(' ') 61 ctx.FormatNode(node.Limit) 62 } 63 ctx.FormatNode(&node.Locking) 64 } 65 66 // ParenSelect represents a parenthesized SELECT/UNION/VALUES statement. 67 type ParenSelect struct { 68 Select *Select 69 } 70 71 // Format implements the NodeFormatter interface. 72 func (node *ParenSelect) Format(ctx *FmtCtx) { 73 ctx.WriteByte('(') 74 ctx.FormatNode(node.Select) 75 ctx.WriteByte(')') 76 } 77 78 // SelectClause represents a SELECT statement. 79 type SelectClause struct { 80 Distinct bool 81 DistinctOn DistinctOn 82 Exprs SelectExprs 83 From From 84 Where *Where 85 GroupBy GroupBy 86 Having *Where 87 Window Window 88 TableSelect bool 89 } 90 91 // Format implements the NodeFormatter interface. 92 func (node *SelectClause) Format(ctx *FmtCtx) { 93 if node.TableSelect { 94 ctx.WriteString("TABLE ") 95 ctx.FormatNode(node.From.Tables[0]) 96 } else { 97 ctx.WriteString("SELECT ") 98 if node.Distinct { 99 if node.DistinctOn != nil { 100 ctx.FormatNode(&node.DistinctOn) 101 ctx.WriteByte(' ') 102 } else { 103 ctx.WriteString("DISTINCT ") 104 } 105 } 106 ctx.FormatNode(&node.Exprs) 107 if len(node.From.Tables) > 0 { 108 ctx.WriteByte(' ') 109 ctx.FormatNode(&node.From) 110 } 111 if node.Where != nil { 112 ctx.WriteByte(' ') 113 ctx.FormatNode(node.Where) 114 } 115 if len(node.GroupBy) > 0 { 116 ctx.WriteByte(' ') 117 ctx.FormatNode(&node.GroupBy) 118 } 119 if node.Having != nil { 120 ctx.WriteByte(' ') 121 ctx.FormatNode(node.Having) 122 } 123 if len(node.Window) > 0 { 124 ctx.WriteByte(' ') 125 ctx.FormatNode(&node.Window) 126 } 127 } 128 } 129 130 // SelectExprs represents SELECT expressions. 131 type SelectExprs []SelectExpr 132 133 // Format implements the NodeFormatter interface. 134 func (node *SelectExprs) Format(ctx *FmtCtx) { 135 for i := range *node { 136 if i > 0 { 137 ctx.WriteString(", ") 138 } 139 ctx.FormatNode(&(*node)[i]) 140 } 141 } 142 143 // SelectExpr represents a SELECT expression. 144 type SelectExpr struct { 145 Expr Expr 146 As UnrestrictedName 147 } 148 149 // NormalizeTopLevelVarName preemptively expands any UnresolvedName at 150 // the top level of the expression into a VarName. This is meant 151 // to catch stars so that sql.checkRenderStar() can see it prior to 152 // other expression transformations. 153 func (node *SelectExpr) NormalizeTopLevelVarName() error { 154 if vBase, ok := node.Expr.(VarName); ok { 155 v, err := vBase.NormalizeVarName() 156 if err != nil { 157 return err 158 } 159 node.Expr = v 160 } 161 return nil 162 } 163 164 // StarSelectExpr is a convenience function that represents an unqualified "*" 165 // in a select expression. 166 func StarSelectExpr() SelectExpr { 167 return SelectExpr{Expr: StarExpr()} 168 } 169 170 // Format implements the NodeFormatter interface. 171 func (node *SelectExpr) Format(ctx *FmtCtx) { 172 ctx.FormatNode(node.Expr) 173 if node.As != "" { 174 ctx.WriteString(" AS ") 175 ctx.FormatNode(&node.As) 176 } 177 } 178 179 // AliasClause represents an alias, optionally with a column list: 180 // "AS name" or "AS name(col1, col2)". 181 type AliasClause struct { 182 Alias Name 183 Cols NameList 184 } 185 186 // Format implements the NodeFormatter interface. 187 func (a *AliasClause) Format(ctx *FmtCtx) { 188 ctx.FormatNode(&a.Alias) 189 if len(a.Cols) != 0 { 190 // Format as "alias (col1, col2, ...)". 191 ctx.WriteString(" (") 192 ctx.FormatNode(&a.Cols) 193 ctx.WriteByte(')') 194 } 195 } 196 197 // AsOfClause represents an as of time. 198 type AsOfClause struct { 199 Expr Expr 200 } 201 202 // Format implements the NodeFormatter interface. 203 func (a *AsOfClause) Format(ctx *FmtCtx) { 204 ctx.WriteString("AS OF SYSTEM TIME ") 205 ctx.FormatNode(a.Expr) 206 } 207 208 // From represents a FROM clause. 209 type From struct { 210 Tables TableExprs 211 AsOf AsOfClause 212 } 213 214 // Format implements the NodeFormatter interface. 215 func (node *From) Format(ctx *FmtCtx) { 216 ctx.WriteString("FROM ") 217 ctx.FormatNode(&node.Tables) 218 if node.AsOf.Expr != nil { 219 ctx.WriteByte(' ') 220 ctx.FormatNode(&node.AsOf) 221 } 222 } 223 224 // TableExprs represents a list of table expressions. 225 type TableExprs []TableExpr 226 227 // Format implements the NodeFormatter interface. 228 func (node *TableExprs) Format(ctx *FmtCtx) { 229 prefix := "" 230 for _, n := range *node { 231 ctx.WriteString(prefix) 232 ctx.FormatNode(n) 233 prefix = ", " 234 } 235 } 236 237 // TableExpr represents a table expression. 238 type TableExpr interface { 239 NodeFormatter 240 tableExpr() 241 } 242 243 func (*AliasedTableExpr) tableExpr() {} 244 func (*ParenTableExpr) tableExpr() {} 245 func (*JoinTableExpr) tableExpr() {} 246 func (*RowsFromExpr) tableExpr() {} 247 func (*Subquery) tableExpr() {} 248 func (*StatementSource) tableExpr() {} 249 250 // StatementSource encapsulates one of the other statements as a data source. 251 type StatementSource struct { 252 Statement Statement 253 } 254 255 // Format implements the NodeFormatter interface. 256 func (node *StatementSource) Format(ctx *FmtCtx) { 257 ctx.WriteByte('[') 258 ctx.FormatNode(node.Statement) 259 ctx.WriteByte(']') 260 } 261 262 // IndexID is a custom type for IndexDescriptor IDs. 263 type IndexID uint32 264 265 // IndexFlags represents "@<index_name|index_id>" or "@{param[,param]}" where 266 // param is one of: 267 // - FORCE_INDEX=<index_name|index_id> 268 // - ASC / DESC 269 // - NO_INDEX_JOIN 270 // - IGNORE_FOREIGN_KEYS 271 // It is used optionally after a table name in SELECT statements. 272 type IndexFlags struct { 273 Index UnrestrictedName 274 IndexID IndexID 275 // Direction of the scan, if provided. Can only be set if 276 // one of Index or IndexID is set. 277 Direction Direction 278 // NoIndexJoin cannot be specified together with an index. 279 NoIndexJoin bool 280 // IgnoreForeignKeys disables optimizations based on outbound foreign key 281 // references from this table. This is useful in particular for scrub queries 282 // used to verify the consistency of foreign key relations. 283 IgnoreForeignKeys bool 284 } 285 286 // ForceIndex returns true if a forced index was specified, either using a name 287 // or an IndexID. 288 func (ih *IndexFlags) ForceIndex() bool { 289 return ih.Index != "" || ih.IndexID != 0 290 } 291 292 // CombineWith combines two IndexFlags structures, returning an error if they 293 // conflict with one another. 294 func (ih *IndexFlags) CombineWith(other *IndexFlags) error { 295 if ih.NoIndexJoin && other.NoIndexJoin { 296 return errors.New("NO_INDEX_JOIN specified multiple times") 297 } 298 if ih.IgnoreForeignKeys && other.IgnoreForeignKeys { 299 return errors.New("IGNORE_FOREIGN_KEYS specified multiple times") 300 } 301 result := *ih 302 result.NoIndexJoin = ih.NoIndexJoin || other.NoIndexJoin 303 result.IgnoreForeignKeys = ih.IgnoreForeignKeys || other.IgnoreForeignKeys 304 305 if other.Direction != 0 { 306 if ih.Direction != 0 { 307 return errors.New("ASC/DESC specified multiple times") 308 } 309 result.Direction = other.Direction 310 } 311 312 if other.ForceIndex() { 313 if ih.ForceIndex() { 314 return errors.New("FORCE_INDEX specified multiple times") 315 } 316 result.Index = other.Index 317 result.IndexID = other.IndexID 318 } 319 320 // We only set at the end to avoid a partially changed structure in one of the 321 // error cases above. 322 *ih = result 323 return nil 324 } 325 326 // Check verifies if the flags are valid: 327 // - ascending/descending is not specified without an index; 328 // - no_index_join isn't specified with an index. 329 func (ih *IndexFlags) Check() error { 330 if ih.NoIndexJoin && ih.ForceIndex() { 331 return errors.New("FORCE_INDEX cannot be specified in conjunction with NO_INDEX_JOIN") 332 } 333 if ih.Direction != 0 && !ih.ForceIndex() { 334 return errors.New("ASC/DESC must be specified in conjunction with an index") 335 } 336 return nil 337 } 338 339 // Format implements the NodeFormatter interface. 340 func (ih *IndexFlags) Format(ctx *FmtCtx) { 341 ctx.WriteByte('@') 342 if !ih.NoIndexJoin && !ih.IgnoreForeignKeys && ih.Direction == 0 { 343 if ih.Index != "" { 344 ctx.FormatNode(&ih.Index) 345 } else { 346 ctx.Printf("[%d]", ih.IndexID) 347 } 348 } else { 349 ctx.WriteByte('{') 350 var sep func() 351 sep = func() { 352 sep = func() { ctx.WriteByte(',') } 353 } 354 if ih.Index != "" || ih.IndexID != 0 { 355 sep() 356 ctx.WriteString("FORCE_INDEX=") 357 if ih.Index != "" { 358 ctx.FormatNode(&ih.Index) 359 } else { 360 ctx.Printf("[%d]", ih.IndexID) 361 } 362 363 if ih.Direction != 0 { 364 ctx.Printf(",%s", ih.Direction) 365 } 366 } 367 if ih.NoIndexJoin { 368 sep() 369 ctx.WriteString("NO_INDEX_JOIN") 370 } 371 372 if ih.IgnoreForeignKeys { 373 sep() 374 ctx.WriteString("IGNORE_FOREIGN_KEYS") 375 } 376 ctx.WriteString("}") 377 } 378 } 379 380 // AliasedTableExpr represents a table expression coupled with an optional 381 // alias. 382 type AliasedTableExpr struct { 383 Expr TableExpr 384 IndexFlags *IndexFlags 385 Ordinality bool 386 Lateral bool 387 As AliasClause 388 } 389 390 // Format implements the NodeFormatter interface. 391 func (node *AliasedTableExpr) Format(ctx *FmtCtx) { 392 if node.Lateral { 393 ctx.WriteString("LATERAL ") 394 } 395 ctx.FormatNode(node.Expr) 396 if node.IndexFlags != nil { 397 ctx.FormatNode(node.IndexFlags) 398 } 399 if node.Ordinality { 400 ctx.WriteString(" WITH ORDINALITY") 401 } 402 if node.As.Alias != "" { 403 ctx.WriteString(" AS ") 404 ctx.FormatNode(&node.As) 405 } 406 } 407 408 // ParenTableExpr represents a parenthesized TableExpr. 409 type ParenTableExpr struct { 410 Expr TableExpr 411 } 412 413 // Format implements the NodeFormatter interface. 414 func (node *ParenTableExpr) Format(ctx *FmtCtx) { 415 ctx.WriteByte('(') 416 ctx.FormatNode(node.Expr) 417 ctx.WriteByte(')') 418 } 419 420 // StripTableParens strips any parentheses surrounding a selection clause. 421 func StripTableParens(expr TableExpr) TableExpr { 422 if p, ok := expr.(*ParenTableExpr); ok { 423 return StripTableParens(p.Expr) 424 } 425 return expr 426 } 427 428 // JoinTableExpr represents a TableExpr that's a JOIN operation. 429 type JoinTableExpr struct { 430 JoinType string 431 Left TableExpr 432 Right TableExpr 433 Cond JoinCond 434 Hint string 435 } 436 437 // JoinTableExpr.Join 438 const ( 439 AstFull = "FULL" 440 AstLeft = "LEFT" 441 AstRight = "RIGHT" 442 AstCross = "CROSS" 443 AstInner = "INNER" 444 ) 445 446 // JoinTableExpr.Hint 447 const ( 448 AstHash = "HASH" 449 AstLookup = "LOOKUP" 450 AstMerge = "MERGE" 451 ) 452 453 // Format implements the NodeFormatter interface. 454 func (node *JoinTableExpr) Format(ctx *FmtCtx) { 455 ctx.FormatNode(node.Left) 456 ctx.WriteByte(' ') 457 if _, isNatural := node.Cond.(NaturalJoinCond); isNatural { 458 // Natural joins have a different syntax: "<a> NATURAL <join_type> <b>" 459 ctx.FormatNode(node.Cond) 460 ctx.WriteByte(' ') 461 if node.JoinType != "" { 462 ctx.WriteString(node.JoinType) 463 ctx.WriteByte(' ') 464 if node.Hint != "" { 465 ctx.WriteString(node.Hint) 466 ctx.WriteByte(' ') 467 } 468 } 469 ctx.WriteString("JOIN ") 470 ctx.FormatNode(node.Right) 471 } else { 472 // General syntax: "<a> <join_type> [<join_hint>] JOIN <b> <condition>" 473 if node.JoinType != "" { 474 ctx.WriteString(node.JoinType) 475 ctx.WriteByte(' ') 476 if node.Hint != "" { 477 ctx.WriteString(node.Hint) 478 ctx.WriteByte(' ') 479 } 480 } 481 ctx.WriteString("JOIN ") 482 ctx.FormatNode(node.Right) 483 if node.Cond != nil { 484 ctx.WriteByte(' ') 485 ctx.FormatNode(node.Cond) 486 } 487 } 488 } 489 490 // JoinCond represents a join condition. 491 type JoinCond interface { 492 NodeFormatter 493 joinCond() 494 } 495 496 func (NaturalJoinCond) joinCond() {} 497 func (*OnJoinCond) joinCond() {} 498 func (*UsingJoinCond) joinCond() {} 499 500 // NaturalJoinCond represents a NATURAL join condition 501 type NaturalJoinCond struct{} 502 503 // Format implements the NodeFormatter interface. 504 func (NaturalJoinCond) Format(ctx *FmtCtx) { 505 ctx.WriteString("NATURAL") 506 } 507 508 // OnJoinCond represents an ON join condition. 509 type OnJoinCond struct { 510 Expr Expr 511 } 512 513 // Format implements the NodeFormatter interface. 514 func (node *OnJoinCond) Format(ctx *FmtCtx) { 515 ctx.WriteString("ON ") 516 ctx.FormatNode(node.Expr) 517 } 518 519 // UsingJoinCond represents a USING join condition. 520 type UsingJoinCond struct { 521 Cols NameList 522 } 523 524 // Format implements the NodeFormatter interface. 525 func (node *UsingJoinCond) Format(ctx *FmtCtx) { 526 ctx.WriteString("USING (") 527 ctx.FormatNode(&node.Cols) 528 ctx.WriteByte(')') 529 } 530 531 // Where represents a WHERE or HAVING clause. 532 type Where struct { 533 Type string 534 Expr Expr 535 } 536 537 // Where.Type 538 const ( 539 AstWhere = "WHERE" 540 AstHaving = "HAVING" 541 ) 542 543 // NewWhere creates a WHERE or HAVING clause out of an Expr. If the expression 544 // is nil, it returns nil. 545 func NewWhere(typ string, expr Expr) *Where { 546 if expr == nil { 547 return nil 548 } 549 return &Where{Type: typ, Expr: expr} 550 } 551 552 // Format implements the NodeFormatter interface. 553 func (node *Where) Format(ctx *FmtCtx) { 554 ctx.WriteString(node.Type) 555 ctx.WriteByte(' ') 556 ctx.FormatNode(node.Expr) 557 } 558 559 // GroupBy represents a GROUP BY clause. 560 type GroupBy []Expr 561 562 // Format implements the NodeFormatter interface. 563 func (node *GroupBy) Format(ctx *FmtCtx) { 564 prefix := "GROUP BY " 565 for _, n := range *node { 566 ctx.WriteString(prefix) 567 ctx.FormatNode(n) 568 prefix = ", " 569 } 570 } 571 572 // DistinctOn represents a DISTINCT ON clause. 573 type DistinctOn []Expr 574 575 // Format implements the NodeFormatter interface. 576 func (node *DistinctOn) Format(ctx *FmtCtx) { 577 ctx.WriteString("DISTINCT ON (") 578 ctx.FormatNode((*Exprs)(node)) 579 ctx.WriteByte(')') 580 } 581 582 // OrderBy represents an ORDER BY clause. 583 type OrderBy []*Order 584 585 // Format implements the NodeFormatter interface. 586 func (node *OrderBy) Format(ctx *FmtCtx) { 587 prefix := "ORDER BY " 588 for _, n := range *node { 589 ctx.WriteString(prefix) 590 ctx.FormatNode(n) 591 prefix = ", " 592 } 593 } 594 595 // Direction for ordering results. 596 type Direction int8 597 598 // Direction values. 599 const ( 600 DefaultDirection Direction = iota 601 Ascending 602 Descending 603 ) 604 605 var directionName = [...]string{ 606 DefaultDirection: "", 607 Ascending: "ASC", 608 Descending: "DESC", 609 } 610 611 func (d Direction) String() string { 612 if d < 0 || d > Direction(len(directionName)-1) { 613 return fmt.Sprintf("Direction(%d)", d) 614 } 615 return directionName[d] 616 } 617 618 // NullsOrder for specifying ordering of NULLs. 619 type NullsOrder int8 620 621 // Null order values. 622 const ( 623 DefaultNullsOrder NullsOrder = iota 624 NullsFirst 625 NullsLast 626 ) 627 628 var nullsOrderName = [...]string{ 629 DefaultNullsOrder: "", 630 NullsFirst: "NULLS FIRST", 631 NullsLast: "NULLS LAST", 632 } 633 634 func (n NullsOrder) String() string { 635 if n < 0 || n > NullsOrder(len(nullsOrderName)-1) { 636 return fmt.Sprintf("NullsOrder(%d)", n) 637 } 638 return nullsOrderName[n] 639 } 640 641 // OrderType indicates which type of expression is used in ORDER BY. 642 type OrderType int 643 644 const ( 645 // OrderByColumn is the regular "by expression/column" ORDER BY specification. 646 OrderByColumn OrderType = iota 647 // OrderByIndex enables the user to specify a given index' columns implicitly. 648 OrderByIndex 649 ) 650 651 // Order represents an ordering expression. 652 type Order struct { 653 OrderType OrderType 654 Expr Expr 655 Direction Direction 656 NullsOrder NullsOrder 657 // Table/Index replaces Expr when OrderType = OrderByIndex. 658 Table TableName 659 // If Index is empty, then the order should use the primary key. 660 Index UnrestrictedName 661 } 662 663 // Format implements the NodeFormatter interface. 664 func (node *Order) Format(ctx *FmtCtx) { 665 if node.OrderType == OrderByColumn { 666 ctx.FormatNode(node.Expr) 667 } else { 668 if node.Index == "" { 669 ctx.WriteString("PRIMARY KEY ") 670 ctx.FormatNode(&node.Table) 671 } else { 672 ctx.WriteString("INDEX ") 673 ctx.FormatNode(&node.Table) 674 ctx.WriteByte('@') 675 ctx.FormatNode(&node.Index) 676 } 677 } 678 if node.Direction != DefaultDirection { 679 ctx.WriteByte(' ') 680 ctx.WriteString(node.Direction.String()) 681 } 682 if node.NullsOrder != DefaultNullsOrder { 683 ctx.WriteByte(' ') 684 ctx.WriteString(node.NullsOrder.String()) 685 } 686 } 687 688 // Equal checks if the node ordering is equivalent to other. 689 func (node *Order) Equal(other *Order) bool { 690 return node.Expr.String() == other.Expr.String() && node.Direction == other.Direction && 691 node.Table == other.Table && node.OrderType == other.OrderType && 692 node.NullsOrder == other.NullsOrder 693 } 694 695 // Limit represents a LIMIT clause. 696 type Limit struct { 697 Offset, Count Expr 698 LimitAll bool 699 } 700 701 // Format implements the NodeFormatter interface. 702 func (node *Limit) Format(ctx *FmtCtx) { 703 needSpace := false 704 if node.Count != nil { 705 ctx.WriteString("LIMIT ") 706 ctx.FormatNode(node.Count) 707 needSpace = true 708 } else if node.LimitAll { 709 ctx.WriteString("LIMIT ALL") 710 needSpace = true 711 } 712 if node.Offset != nil { 713 if needSpace { 714 ctx.WriteByte(' ') 715 } 716 ctx.WriteString("OFFSET ") 717 ctx.FormatNode(node.Offset) 718 } 719 } 720 721 // RowsFromExpr represents a ROWS FROM(...) expression. 722 type RowsFromExpr struct { 723 Items Exprs 724 } 725 726 // Format implements the NodeFormatter interface. 727 func (node *RowsFromExpr) Format(ctx *FmtCtx) { 728 ctx.WriteString("ROWS FROM (") 729 ctx.FormatNode(&node.Items) 730 ctx.WriteByte(')') 731 } 732 733 // Window represents a WINDOW clause. 734 type Window []*WindowDef 735 736 // Format implements the NodeFormatter interface. 737 func (node *Window) Format(ctx *FmtCtx) { 738 prefix := "WINDOW " 739 for _, n := range *node { 740 ctx.WriteString(prefix) 741 ctx.FormatNode(&n.Name) 742 ctx.WriteString(" AS ") 743 ctx.FormatNode(n) 744 prefix = ", " 745 } 746 } 747 748 // WindowDef represents a single window definition expression. 749 type WindowDef struct { 750 Name Name 751 RefName Name 752 Partitions Exprs 753 OrderBy OrderBy 754 Frame *WindowFrame 755 } 756 757 // Format implements the NodeFormatter interface. 758 func (node *WindowDef) Format(ctx *FmtCtx) { 759 ctx.WriteByte('(') 760 needSpaceSeparator := false 761 if node.RefName != "" { 762 ctx.FormatNode(&node.RefName) 763 needSpaceSeparator = true 764 } 765 if len(node.Partitions) > 0 { 766 if needSpaceSeparator { 767 ctx.WriteByte(' ') 768 } 769 ctx.WriteString("PARTITION BY ") 770 ctx.FormatNode(&node.Partitions) 771 needSpaceSeparator = true 772 } 773 if len(node.OrderBy) > 0 { 774 if needSpaceSeparator { 775 ctx.WriteByte(' ') 776 } 777 ctx.FormatNode(&node.OrderBy) 778 needSpaceSeparator = true 779 } 780 if node.Frame != nil { 781 if needSpaceSeparator { 782 ctx.WriteByte(' ') 783 } 784 ctx.FormatNode(node.Frame) 785 } 786 ctx.WriteRune(')') 787 } 788 789 // WindowFrameMode indicates which mode of framing is used. 790 type WindowFrameMode int 791 792 const ( 793 // RANGE is the mode of specifying frame in terms of logical range (e.g. 100 units cheaper). 794 RANGE WindowFrameMode = iota 795 // ROWS is the mode of specifying frame in terms of physical offsets (e.g. 1 row before etc). 796 ROWS 797 // GROUPS is the mode of specifying frame in terms of peer groups. 798 GROUPS 799 ) 800 801 // OverrideWindowDef implements the logic to have a base window definition which 802 // then gets augmented by a different window definition. 803 func OverrideWindowDef(base *WindowDef, override WindowDef) (WindowDef, error) { 804 // base.Partitions is always used. 805 if len(override.Partitions) > 0 { 806 return WindowDef{}, pgerror.Newf(pgcode.Windowing, "cannot override PARTITION BY clause of window %q", base.Name) 807 } 808 override.Partitions = base.Partitions 809 810 // base.OrderBy is used if set. 811 if len(base.OrderBy) > 0 { 812 if len(override.OrderBy) > 0 { 813 return WindowDef{}, pgerror.Newf(pgcode.Windowing, "cannot override ORDER BY clause of window %q", base.Name) 814 } 815 override.OrderBy = base.OrderBy 816 } 817 818 if base.Frame != nil { 819 return WindowDef{}, pgerror.Newf(pgcode.Windowing, "cannot copy window %q because it has a frame clause", base.Name) 820 } 821 822 return override, nil 823 } 824 825 // WindowFrameBoundType indicates which type of boundary is used. 826 type WindowFrameBoundType int 827 828 const ( 829 // UnboundedPreceding represents UNBOUNDED PRECEDING type of boundary. 830 UnboundedPreceding WindowFrameBoundType = iota 831 // OffsetPreceding represents 'value' PRECEDING type of boundary. 832 OffsetPreceding 833 // CurrentRow represents CURRENT ROW type of boundary. 834 CurrentRow 835 // OffsetFollowing represents 'value' FOLLOWING type of boundary. 836 OffsetFollowing 837 // UnboundedFollowing represents UNBOUNDED FOLLOWING type of boundary. 838 UnboundedFollowing 839 ) 840 841 // WindowFrameBound specifies the offset and the type of boundary. 842 type WindowFrameBound struct { 843 BoundType WindowFrameBoundType 844 OffsetExpr Expr 845 } 846 847 // HasOffset returns whether node contains an offset. 848 func (node *WindowFrameBound) HasOffset() bool { 849 return node.BoundType == OffsetPreceding || node.BoundType == OffsetFollowing 850 } 851 852 // WindowFrameBounds specifies boundaries of the window frame. 853 // The row at StartBound is included whereas the row at EndBound is not. 854 type WindowFrameBounds struct { 855 StartBound *WindowFrameBound 856 EndBound *WindowFrameBound 857 } 858 859 // HasOffset returns whether node contains an offset in either of the bounds. 860 func (node *WindowFrameBounds) HasOffset() bool { 861 return node.StartBound.HasOffset() || (node.EndBound != nil && node.EndBound.HasOffset()) 862 } 863 864 // WindowFrameExclusion indicates which mode of exclusion is used. 865 type WindowFrameExclusion int 866 867 const ( 868 // NoExclusion represents an omitted frame exclusion clause. 869 NoExclusion WindowFrameExclusion = iota 870 // ExcludeCurrentRow represents EXCLUDE CURRENT ROW mode of frame exclusion. 871 ExcludeCurrentRow 872 // ExcludeGroup represents EXCLUDE GROUP mode of frame exclusion. 873 ExcludeGroup 874 // ExcludeTies represents EXCLUDE TIES mode of frame exclusion. 875 ExcludeTies 876 ) 877 878 // WindowFrame represents static state of window frame over which calculations are made. 879 type WindowFrame struct { 880 Mode WindowFrameMode // the mode of framing being used 881 Bounds WindowFrameBounds // the bounds of the frame 882 Exclusion WindowFrameExclusion // optional frame exclusion 883 } 884 885 // Format implements the NodeFormatter interface. 886 func (node *WindowFrameBound) Format(ctx *FmtCtx) { 887 switch node.BoundType { 888 case UnboundedPreceding: 889 ctx.WriteString("UNBOUNDED PRECEDING") 890 case OffsetPreceding: 891 ctx.FormatNode(node.OffsetExpr) 892 ctx.WriteString(" PRECEDING") 893 case CurrentRow: 894 ctx.WriteString("CURRENT ROW") 895 case OffsetFollowing: 896 ctx.FormatNode(node.OffsetExpr) 897 ctx.WriteString(" FOLLOWING") 898 case UnboundedFollowing: 899 ctx.WriteString("UNBOUNDED FOLLOWING") 900 default: 901 panic(errors.AssertionFailedf("unhandled case: %d", log.Safe(node.BoundType))) 902 } 903 } 904 905 // Format implements the NodeFormatter interface. 906 func (node WindowFrameExclusion) Format(ctx *FmtCtx) { 907 if node == NoExclusion { 908 return 909 } 910 ctx.WriteString("EXCLUDE ") 911 switch node { 912 case ExcludeCurrentRow: 913 ctx.WriteString("CURRENT ROW") 914 case ExcludeGroup: 915 ctx.WriteString("GROUP") 916 case ExcludeTies: 917 ctx.WriteString("TIES") 918 default: 919 panic(errors.AssertionFailedf("unhandled case: %d", log.Safe(node))) 920 } 921 } 922 923 // WindowModeName returns the name of the window frame mode. 924 func WindowModeName(mode WindowFrameMode) string { 925 switch mode { 926 case RANGE: 927 return "RANGE" 928 case ROWS: 929 return "ROWS" 930 case GROUPS: 931 return "GROUPS" 932 default: 933 panic(errors.AssertionFailedf("unhandled case: %d", log.Safe(mode))) 934 } 935 } 936 937 // Format implements the NodeFormatter interface. 938 func (node *WindowFrame) Format(ctx *FmtCtx) { 939 ctx.WriteString(WindowModeName(node.Mode)) 940 ctx.WriteByte(' ') 941 if node.Bounds.EndBound != nil { 942 ctx.WriteString("BETWEEN ") 943 ctx.FormatNode(node.Bounds.StartBound) 944 ctx.WriteString(" AND ") 945 ctx.FormatNode(node.Bounds.EndBound) 946 } else { 947 ctx.FormatNode(node.Bounds.StartBound) 948 } 949 if node.Exclusion != NoExclusion { 950 ctx.WriteByte(' ') 951 ctx.FormatNode(node.Exclusion) 952 } 953 } 954 955 // LockingClause represents a locking clause, like FOR UPDATE. 956 type LockingClause []*LockingItem 957 958 // Format implements the NodeFormatter interface. 959 func (node *LockingClause) Format(ctx *FmtCtx) { 960 for _, n := range *node { 961 ctx.FormatNode(n) 962 } 963 } 964 965 // LockingItem represents a single locking item in a locking clause. 966 // 967 // NOTE: if this struct changes, HashLockingItem and IsLockingItemEqual 968 // in opt/memo/interner.go will need to be updated accordingly. 969 type LockingItem struct { 970 Strength LockingStrength 971 Targets TableNames 972 WaitPolicy LockingWaitPolicy 973 } 974 975 // Format implements the NodeFormatter interface. 976 func (f *LockingItem) Format(ctx *FmtCtx) { 977 f.Strength.Format(ctx) 978 if len(f.Targets) > 0 { 979 ctx.WriteString(" OF ") 980 f.Targets.Format(ctx) 981 } 982 f.WaitPolicy.Format(ctx) 983 } 984 985 // LockingStrength represents the possible row-level lock modes for a SELECT 986 // statement. 987 type LockingStrength byte 988 989 // The ordering of the variants is important, because the highest numerical 990 // value takes precedence when row-level locking is specified multiple ways. 991 const ( 992 // ForNone represents the default - no for statement at all. 993 // LockingItem AST nodes are never created with this strength. 994 ForNone LockingStrength = iota 995 // ForKeyShare represents FOR KEY SHARE. 996 ForKeyShare 997 // ForShare represents FOR SHARE. 998 ForShare 999 // ForNoKeyUpdate represents FOR NO KEY UPDATE. 1000 ForNoKeyUpdate 1001 // ForUpdate represents FOR UPDATE. 1002 ForUpdate 1003 ) 1004 1005 var lockingStrengthName = [...]string{ 1006 ForNone: "", 1007 ForKeyShare: "FOR KEY SHARE", 1008 ForShare: "FOR SHARE", 1009 ForNoKeyUpdate: "FOR NO KEY UPDATE", 1010 ForUpdate: "FOR UPDATE", 1011 } 1012 1013 func (s LockingStrength) String() string { 1014 return lockingStrengthName[s] 1015 } 1016 1017 // Format implements the NodeFormatter interface. 1018 func (s LockingStrength) Format(ctx *FmtCtx) { 1019 if s != ForNone { 1020 ctx.WriteString(" ") 1021 ctx.WriteString(s.String()) 1022 } 1023 } 1024 1025 // Max returns the maximum of the two locking strengths. 1026 func (s LockingStrength) Max(s2 LockingStrength) LockingStrength { 1027 return LockingStrength(max(byte(s), byte(s2))) 1028 } 1029 1030 // LockingWaitPolicy represents the possible policies for dealing with rows 1031 // being locked by FOR UPDATE/SHARE clauses (i.e., it represents the NOWAIT 1032 // and SKIP LOCKED options). 1033 type LockingWaitPolicy byte 1034 1035 // The ordering of the variants is important, because the highest numerical 1036 // value takes precedence when row-level locking is specified multiple ways. 1037 const ( 1038 // LockWaitBlock represents the default - wait for the lock to become 1039 // available. 1040 LockWaitBlock LockingWaitPolicy = iota 1041 // LockWaitSkip represents SKIP LOCKED - skip rows that can't be locked. 1042 LockWaitSkip 1043 // LockWaitError represents NOWAIT - raise an error if a row cannot be 1044 // locked. 1045 LockWaitError 1046 ) 1047 1048 var lockingWaitPolicyName = [...]string{ 1049 LockWaitBlock: "", 1050 LockWaitSkip: "SKIP LOCKED", 1051 LockWaitError: "NOWAIT", 1052 } 1053 1054 func (p LockingWaitPolicy) String() string { 1055 return lockingWaitPolicyName[p] 1056 } 1057 1058 // Format implements the NodeFormatter interface. 1059 func (p LockingWaitPolicy) Format(ctx *FmtCtx) { 1060 if p != LockWaitBlock { 1061 ctx.WriteString(" ") 1062 ctx.WriteString(p.String()) 1063 } 1064 } 1065 1066 // Max returns the maximum of the two locking wait policies. 1067 func (p LockingWaitPolicy) Max(p2 LockingWaitPolicy) LockingWaitPolicy { 1068 return LockingWaitPolicy(max(byte(p), byte(p2))) 1069 } 1070 1071 func max(a, b byte) byte { 1072 if a > b { 1073 return a 1074 } 1075 return b 1076 }