github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/parsers/tree/select.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tree 16 17 import ( 18 "fmt" 19 "strings" 20 ) 21 22 type SelectStatement interface { 23 Statement 24 } 25 26 // Select represents a SelectStatement with an ORDER and/or LIMIT. 27 type Select struct { 28 statementImpl 29 Select SelectStatement 30 TimeWindow *TimeWindow 31 OrderBy OrderBy 32 Limit *Limit 33 With *With 34 Ep *ExportParam 35 SelectLockInfo *SelectLockInfo 36 } 37 38 func (node *Select) Format(ctx *FmtCtx) { 39 if node.With != nil { 40 node.With.Format(ctx) 41 ctx.WriteByte(' ') 42 } 43 node.Select.Format(ctx) 44 if len(node.OrderBy) > 0 { 45 ctx.WriteByte(' ') 46 node.OrderBy.Format(ctx) 47 } 48 if node.TimeWindow != nil { 49 ctx.WriteByte(' ') 50 node.TimeWindow.Format(ctx) 51 } 52 if node.Limit != nil { 53 ctx.WriteByte(' ') 54 node.Limit.Format(ctx) 55 } 56 if node.Ep != nil { 57 ctx.WriteByte(' ') 58 node.Ep.Format(ctx) 59 } 60 if node.SelectLockInfo != nil { 61 ctx.WriteByte(' ') 62 node.SelectLockInfo.Format(ctx) 63 } 64 } 65 66 func (node *Select) GetStatementType() string { return "Select" } 67 func (node *Select) GetQueryType() string { return QueryTypeDQL } 68 69 func NewSelect(s SelectStatement, o OrderBy, l *Limit) *Select { 70 return &Select{ 71 Select: s, 72 OrderBy: o, 73 Limit: l, 74 } 75 } 76 77 type TimeWindow struct { 78 Interval *Interval 79 Sliding *Sliding 80 Fill *Fill 81 } 82 83 func (node *TimeWindow) Format(ctx *FmtCtx) { 84 node.Interval.Format(ctx) 85 if node.Sliding != nil { 86 ctx.WriteByte(' ') 87 node.Sliding.Format(ctx) 88 } 89 if node.Fill != nil { 90 ctx.WriteByte(' ') 91 node.Fill.Format(ctx) 92 } 93 } 94 95 type Interval struct { 96 Col *UnresolvedName 97 Val Expr 98 Unit string 99 } 100 101 func (node *Interval) Format(ctx *FmtCtx) { 102 ctx.WriteString("interval(") 103 node.Col.Format(ctx) 104 ctx.WriteString(", ") 105 node.Val.Format(ctx) 106 ctx.WriteString(", ") 107 ctx.WriteString(node.Unit) 108 ctx.WriteByte(')') 109 } 110 111 type Sliding struct { 112 Val Expr 113 Unit string 114 } 115 116 func (node *Sliding) Format(ctx *FmtCtx) { 117 ctx.WriteString("sliding(") 118 node.Val.Format(ctx) 119 ctx.WriteString(", ") 120 ctx.WriteString(node.Unit) 121 ctx.WriteByte(')') 122 } 123 124 type FillMode int 125 126 const ( 127 FillNone FillMode = iota 128 FillPrev 129 FillNext 130 FillValue 131 FillNull 132 FillLinear 133 ) 134 135 func (f FillMode) String() string { 136 switch f { 137 case FillNone: 138 return "none" 139 case FillPrev: 140 return "prev" 141 case FillNext: 142 return "next" 143 case FillValue: 144 return "value" 145 case FillNull: 146 return "null" 147 case FillLinear: 148 return "linear" 149 default: 150 return "" 151 } 152 } 153 154 type Fill struct { 155 Mode FillMode 156 Val Expr 157 } 158 159 func (node *Fill) Format(ctx *FmtCtx) { 160 ctx.WriteString("fill(") 161 ctx.WriteString(node.Mode.String()) 162 163 if node.Mode == FillValue { 164 ctx.WriteString(", ") 165 node.Val.Format(ctx) 166 } 167 ctx.WriteByte(')') 168 } 169 170 // OrderBy represents an ORDER BY clause. 171 type OrderBy []*Order 172 173 func (node *OrderBy) Format(ctx *FmtCtx) { 174 prefix := "order by " 175 for _, n := range *node { 176 ctx.WriteString(prefix) 177 n.Format(ctx) 178 prefix = ", " 179 } 180 } 181 182 // the ordering expression. 183 type Order struct { 184 Expr Expr 185 Direction Direction 186 NullsPosition NullsPosition 187 //without order 188 NullOrder bool 189 } 190 191 func (node *Order) Format(ctx *FmtCtx) { 192 node.Expr.Format(ctx) 193 if node.Direction != DefaultDirection { 194 ctx.WriteByte(' ') 195 ctx.WriteString(node.Direction.String()) 196 } 197 if node.NullsPosition != DefaultNullsPosition { 198 ctx.WriteByte(' ') 199 ctx.WriteString(node.NullsPosition.String()) 200 } 201 } 202 203 func NewOrder(e Expr, d Direction, np NullsPosition, o bool) *Order { 204 return &Order{ 205 Expr: e, 206 Direction: d, 207 NullsPosition: np, 208 NullOrder: o, 209 } 210 } 211 212 // Direction for ordering results. 213 type Direction int8 214 215 // Direction values. 216 const ( 217 DefaultDirection Direction = iota 218 Ascending 219 Descending 220 ) 221 222 var directionName = [...]string{ 223 DefaultDirection: "", 224 Ascending: "asc", 225 Descending: "desc", 226 } 227 228 func (d Direction) String() string { 229 if d < 0 || d > Direction(len(directionName)-1) { 230 return fmt.Sprintf("Direction(%d)", d) 231 } 232 return directionName[d] 233 } 234 235 type NullsPosition int8 236 237 const ( 238 DefaultNullsPosition NullsPosition = iota 239 NullsFirst 240 NullsLast 241 ) 242 243 var nullsPositionName = [...]string{ 244 DefaultNullsPosition: "", 245 NullsFirst: "nulls first", 246 NullsLast: "nulls last", 247 } 248 249 func (np NullsPosition) String() string { 250 if np < 0 || np >= NullsPosition(len(nullsPositionName)) { 251 return fmt.Sprintf("NullsPosition(%d)", np) 252 } 253 return nullsPositionName[np] 254 } 255 256 // the LIMIT clause. 257 type Limit struct { 258 Offset, Count Expr 259 } 260 261 func (node *Limit) Format(ctx *FmtCtx) { 262 needSpace := false 263 if node != nil && node.Count != nil { 264 ctx.WriteString("limit ") 265 node.Count.Format(ctx) 266 needSpace = true 267 } 268 if node != nil && node.Offset != nil { 269 if needSpace { 270 ctx.WriteByte(' ') 271 } 272 ctx.WriteString("offset ") 273 node.Offset.Format(ctx) 274 } 275 } 276 277 func NewLimit(o, c Expr) *Limit { 278 return &Limit{ 279 Offset: o, 280 Count: c, 281 } 282 } 283 284 // the parenthesized SELECT/UNION/VALUES statement. 285 type ParenSelect struct { 286 SelectStatement 287 Select *Select 288 } 289 290 func (node *ParenSelect) Format(ctx *FmtCtx) { 291 ctx.WriteByte('(') 292 node.Select.Format(ctx) 293 ctx.WriteByte(')') 294 } 295 296 // SelectClause represents a SELECT statement. 297 type SelectClause struct { 298 SelectStatement 299 Distinct bool 300 Exprs SelectExprs 301 From *From 302 Where *Where 303 GroupBy GroupBy 304 Having *Where 305 Option string 306 } 307 308 func (node *SelectClause) Format(ctx *FmtCtx) { 309 ctx.WriteString("select ") 310 if node.Distinct { 311 ctx.WriteString("distinct ") 312 } 313 if node.Option != "" { 314 ctx.WriteString(node.Option) 315 ctx.WriteByte(' ') 316 } 317 node.Exprs.Format(ctx) 318 if len(node.From.Tables) > 0 { 319 canFrom := true 320 als, ok := node.From.Tables[0].(*AliasedTableExpr) 321 if ok { 322 tbl, ok := als.Expr.(*TableName) 323 if ok { 324 if string(tbl.ObjectName) == "" { 325 canFrom = false 326 } 327 } 328 } 329 if canFrom { 330 ctx.WriteByte(' ') 331 node.From.Format(ctx) 332 } 333 } 334 if node.Where != nil { 335 ctx.WriteByte(' ') 336 node.Where.Format(ctx) 337 } 338 if len(node.GroupBy) > 0 { 339 ctx.WriteByte(' ') 340 node.GroupBy.Format(ctx) 341 } 342 if node.Having != nil { 343 ctx.WriteByte(' ') 344 node.Having.Format(ctx) 345 } 346 } 347 348 func (node *SelectClause) GetStatementType() string { return "Select" } 349 func (node *SelectClause) GetQueryType() string { return QueryTypeDQL } 350 351 // WHERE or HAVING clause. 352 type Where struct { 353 Type string 354 Expr Expr 355 } 356 357 func (node *Where) Format(ctx *FmtCtx) { 358 ctx.WriteString(node.Type) 359 ctx.WriteByte(' ') 360 node.Expr.Format(ctx) 361 } 362 363 const ( 364 AstWhere = "where" 365 AstHaving = "having" 366 ) 367 368 func NewWhere(e Expr) *Where { 369 return &Where{Expr: e} 370 } 371 372 // SELECT expressions. 373 type SelectExprs []SelectExpr 374 375 func (node *SelectExprs) Format(ctx *FmtCtx) { 376 for i, n := range *node { 377 if i > 0 { 378 ctx.WriteString(", ") 379 } 380 n.Format(ctx) 381 } 382 } 383 384 // a SELECT expression. 385 type SelectExpr struct { 386 exprImpl 387 Expr Expr 388 As *CStr 389 } 390 391 func (node *SelectExpr) Format(ctx *FmtCtx) { 392 node.Expr.Format(ctx) 393 if node.As != nil && !node.As.Empty() { 394 ctx.WriteString(" as ") 395 ctx.WriteString(node.As.Origin()) 396 } 397 } 398 399 // a GROUP BY clause. 400 type GroupBy []Expr 401 402 func (node *GroupBy) Format(ctx *FmtCtx) { 403 prefix := "group by " 404 for _, n := range *node { 405 ctx.WriteString(prefix) 406 n.Format(ctx) 407 prefix = ", " 408 } 409 } 410 411 const ( 412 JOIN_TYPE_FULL = "FULL" 413 JOIN_TYPE_LEFT = "LEFT" 414 JOIN_TYPE_RIGHT = "RIGHT" 415 JOIN_TYPE_CROSS = "CROSS" 416 JOIN_TYPE_INNER = "INNER" 417 JOIN_TYPE_STRAIGHT = "STRAIGHT_JOIN" 418 JOIN_TYPE_NATURAL = "NATURAL" 419 JOIN_TYPE_NATURAL_LEFT = "NATURAL LEFT" 420 JOIN_TYPE_NATURAL_RIGHT = "NATURAL RIGHT" 421 ) 422 423 // the table expression 424 type TableExpr interface { 425 NodeFormatter 426 } 427 428 var _ TableExpr = &Subquery{} 429 430 type JoinTableExpr struct { 431 TableExpr 432 JoinType string 433 Left TableExpr 434 Right TableExpr 435 Cond JoinCond 436 } 437 438 func (node *JoinTableExpr) Format(ctx *FmtCtx) { 439 if node.Left != nil { 440 node.Left.Format(ctx) 441 } 442 if node.JoinType != "" && node.Right != nil { 443 ctx.WriteByte(' ') 444 ctx.WriteString(strings.ToLower(node.JoinType)) 445 } 446 if node.JoinType != JOIN_TYPE_STRAIGHT && node.Right != nil { 447 ctx.WriteByte(' ') 448 ctx.WriteString("join") 449 } 450 if node.Right != nil { 451 ctx.WriteByte(' ') 452 node.Right.Format(ctx) 453 } 454 if node.Cond != nil { 455 ctx.WriteByte(' ') 456 node.Cond.Format(ctx) 457 } 458 } 459 460 func NewJoinTableExpr(jt string, l, r TableExpr, jc JoinCond) *JoinTableExpr { 461 return &JoinTableExpr{ 462 JoinType: jt, 463 Left: l, 464 Right: r, 465 Cond: jc, 466 } 467 } 468 469 // the join condition. 470 type JoinCond interface { 471 NodeFormatter 472 } 473 474 // the NATURAL join condition 475 type NaturalJoinCond struct { 476 JoinCond 477 } 478 479 func (node *NaturalJoinCond) Format(ctx *FmtCtx) { 480 ctx.WriteString("natural") 481 } 482 483 func NewNaturalJoinCond() *NaturalJoinCond { 484 return &NaturalJoinCond{} 485 } 486 487 // the ON condition for join 488 type OnJoinCond struct { 489 JoinCond 490 Expr Expr 491 } 492 493 func (node *OnJoinCond) Format(ctx *FmtCtx) { 494 ctx.WriteString("on ") 495 node.Expr.Format(ctx) 496 } 497 498 func NewOnJoinCond(e Expr) *OnJoinCond { 499 return &OnJoinCond{Expr: e} 500 } 501 502 // the USING condition 503 type UsingJoinCond struct { 504 JoinCond 505 Cols IdentifierList 506 } 507 508 func (node *UsingJoinCond) Format(ctx *FmtCtx) { 509 ctx.WriteString("using (") 510 node.Cols.Format(ctx) 511 ctx.WriteByte(')') 512 } 513 514 func NewUsingJoinCond(c IdentifierList) *UsingJoinCond { 515 return &UsingJoinCond{Cols: c} 516 } 517 518 // the parenthesized TableExpr. 519 type ParenTableExpr struct { 520 TableExpr 521 Expr TableExpr 522 } 523 524 func (node *ParenTableExpr) Format(ctx *FmtCtx) { 525 ctx.WriteByte('(') 526 node.Expr.Format(ctx) 527 ctx.WriteByte(')') 528 } 529 530 func NewParenTableExpr(e TableExpr) *ParenTableExpr { 531 return &ParenTableExpr{Expr: e} 532 } 533 534 // The alias, optionally with a column list: 535 // "AS name" or "AS name(col1, col2)". 536 type AliasClause struct { 537 NodeFormatter 538 Alias Identifier 539 Cols IdentifierList 540 } 541 542 func (node *AliasClause) Format(ctx *FmtCtx) { 543 if node.Alias != "" { 544 ctx.WriteString(string(node.Alias)) 545 } 546 if node.Cols != nil { 547 ctx.WriteByte('(') 548 node.Cols.Format(ctx) 549 ctx.WriteByte(')') 550 } 551 } 552 553 // the table expression coupled with an optional alias. 554 type AliasedTableExpr struct { 555 TableExpr 556 Expr TableExpr 557 As AliasClause 558 IndexHints []*IndexHint 559 } 560 561 func (node *AliasedTableExpr) Format(ctx *FmtCtx) { 562 node.Expr.Format(ctx) 563 if node.As.Alias != "" { 564 ctx.WriteString(" as ") 565 node.As.Format(ctx) 566 } 567 if node.IndexHints != nil { 568 prefix := " " 569 for _, hint := range node.IndexHints { 570 ctx.WriteString(prefix) 571 hint.Format(ctx) 572 prefix = " " 573 } 574 } 575 } 576 577 func NewAliasedTableExpr(e TableExpr, a AliasClause) *AliasedTableExpr { 578 return &AliasedTableExpr{ 579 Expr: e, 580 As: a, 581 } 582 } 583 584 // the statements as a data source includes the select statement. 585 type StatementSource struct { 586 TableExpr 587 Statement Statement 588 } 589 590 func NewStatementSource(s Statement) *StatementSource { 591 return &StatementSource{ 592 Statement: s, 593 } 594 } 595 596 // the list of table expressions. 597 type TableExprs []TableExpr 598 599 func (node *TableExprs) Format(ctx *FmtCtx) { 600 prefix := "" 601 for _, n := range *node { 602 ctx.WriteString(prefix) 603 n.Format(ctx) 604 prefix = ", " 605 } 606 } 607 608 // the FROM clause. 609 type From struct { 610 Tables TableExprs 611 } 612 613 func (node *From) Format(ctx *FmtCtx) { 614 ctx.WriteString("from ") 615 node.Tables.Format(ctx) 616 } 617 618 func NewFrom(t TableExprs) *From { 619 return &From{Tables: t} 620 } 621 622 type IndexHintType int 623 624 const ( 625 HintUse IndexHintType = iota + 1 626 HintIgnore 627 HintForce 628 ) 629 630 type IndexHintScope int 631 632 // Index hint scopes. 633 const ( 634 HintForScan IndexHintScope = iota + 1 635 HintForJoin 636 HintForOrderBy 637 HintForGroupBy 638 ) 639 640 type IndexHint struct { 641 IndexNames []string 642 HintType IndexHintType 643 HintScope IndexHintScope 644 } 645 646 func (node *IndexHint) Format(ctx *FmtCtx) { 647 indexHintType := "" 648 switch node.HintType { 649 case HintUse: 650 indexHintType = "use index" 651 case HintIgnore: 652 indexHintType = "ignore index" 653 case HintForce: 654 indexHintType = "force index" 655 } 656 657 indexHintScope := "" 658 switch node.HintScope { 659 case HintForScan: 660 indexHintScope = "" 661 case HintForJoin: 662 indexHintScope = " for join" 663 case HintForOrderBy: 664 indexHintScope = " for order by" 665 case HintForGroupBy: 666 indexHintScope = " for group by" 667 } 668 ctx.WriteString(indexHintType) 669 ctx.WriteString(indexHintScope) 670 ctx.WriteString("(") 671 if node.IndexNames != nil { 672 for i, value := range node.IndexNames { 673 if i > 0 { 674 ctx.WriteString(", ") 675 } 676 ctx.WriteString(value) 677 } 678 } 679 ctx.WriteString(")") 680 }