github.com/matrixorigin/matrixone@v0.7.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 OrderBy OrderBy 31 Limit *Limit 32 With *With 33 Ep *ExportParam 34 } 35 36 func (node *Select) Format(ctx *FmtCtx) { 37 if node.With != nil { 38 node.With.Format(ctx) 39 ctx.WriteByte(' ') 40 } 41 node.Select.Format(ctx) 42 if len(node.OrderBy) > 0 { 43 ctx.WriteByte(' ') 44 node.OrderBy.Format(ctx) 45 } 46 if node.Limit != nil { 47 ctx.WriteByte(' ') 48 node.Limit.Format(ctx) 49 } 50 if node.Ep != nil { 51 ctx.WriteByte(' ') 52 node.Ep.Format(ctx) 53 } 54 } 55 56 func (node *Select) GetStatementType() string { return "Select" } 57 func (node *Select) GetQueryType() string { return QueryTypeDQL } 58 59 func NewSelect(s SelectStatement, o OrderBy, l *Limit) *Select { 60 return &Select{ 61 Select: s, 62 OrderBy: o, 63 Limit: l, 64 } 65 } 66 67 // OrderBy represents an ORDER BY clause. 68 type OrderBy []*Order 69 70 func (node *OrderBy) Format(ctx *FmtCtx) { 71 prefix := "order by " 72 for _, n := range *node { 73 ctx.WriteString(prefix) 74 n.Format(ctx) 75 prefix = ", " 76 } 77 } 78 79 // the ordering expression. 80 type Order struct { 81 Expr Expr 82 Direction Direction 83 NullsPosition NullsPosition 84 //without order 85 NullOrder bool 86 } 87 88 func (node *Order) Format(ctx *FmtCtx) { 89 node.Expr.Format(ctx) 90 if node.Direction != DefaultDirection { 91 ctx.WriteByte(' ') 92 ctx.WriteString(node.Direction.String()) 93 } 94 if node.NullsPosition != DefaultNullsPosition { 95 ctx.WriteByte(' ') 96 ctx.WriteString(node.NullsPosition.String()) 97 } 98 } 99 100 func NewOrder(e Expr, d Direction, np NullsPosition, o bool) *Order { 101 return &Order{ 102 Expr: e, 103 Direction: d, 104 NullsPosition: np, 105 NullOrder: o, 106 } 107 } 108 109 // Direction for ordering results. 110 type Direction int8 111 112 // Direction values. 113 const ( 114 DefaultDirection Direction = iota 115 Ascending 116 Descending 117 ) 118 119 var directionName = [...]string{ 120 DefaultDirection: "", 121 Ascending: "asc", 122 Descending: "desc", 123 } 124 125 func (d Direction) String() string { 126 if d < 0 || d > Direction(len(directionName)-1) { 127 return fmt.Sprintf("Direction(%d)", d) 128 } 129 return directionName[d] 130 } 131 132 type NullsPosition int8 133 134 const ( 135 DefaultNullsPosition NullsPosition = iota 136 NullsFirst 137 NullsLast 138 ) 139 140 var nullsPositionName = [...]string{ 141 DefaultNullsPosition: "", 142 NullsFirst: "nulls first", 143 NullsLast: "nulls last", 144 } 145 146 func (np NullsPosition) String() string { 147 if np < 0 || np >= NullsPosition(len(nullsPositionName)) { 148 return fmt.Sprintf("NullsPosition(%d)", np) 149 } 150 return nullsPositionName[np] 151 } 152 153 // the LIMIT clause. 154 type Limit struct { 155 Offset, Count Expr 156 } 157 158 func (node *Limit) Format(ctx *FmtCtx) { 159 needSpace := false 160 if node != nil && node.Count != nil { 161 ctx.WriteString("limit ") 162 node.Count.Format(ctx) 163 needSpace = true 164 } 165 if node != nil && node.Offset != nil { 166 if needSpace { 167 ctx.WriteByte(' ') 168 } 169 ctx.WriteString("offset ") 170 node.Offset.Format(ctx) 171 } 172 } 173 174 func NewLimit(o, c Expr) *Limit { 175 return &Limit{ 176 Offset: o, 177 Count: c, 178 } 179 } 180 181 // the parenthesized SELECT/UNION/VALUES statement. 182 type ParenSelect struct { 183 SelectStatement 184 Select *Select 185 } 186 187 func (node *ParenSelect) Format(ctx *FmtCtx) { 188 ctx.WriteByte('(') 189 node.Select.Format(ctx) 190 ctx.WriteByte(')') 191 } 192 193 // SelectClause represents a SELECT statement. 194 type SelectClause struct { 195 SelectStatement 196 Distinct bool 197 Exprs SelectExprs 198 From *From 199 Where *Where 200 GroupBy GroupBy 201 Having *Where 202 Option string 203 } 204 205 func (node *SelectClause) Format(ctx *FmtCtx) { 206 ctx.WriteString("select ") 207 if node.Distinct { 208 ctx.WriteString("distinct ") 209 } 210 if node.Option != "" { 211 ctx.WriteString(node.Option) 212 ctx.WriteByte(' ') 213 } 214 node.Exprs.Format(ctx) 215 if len(node.From.Tables) > 0 { 216 canFrom := true 217 als, ok := node.From.Tables[0].(*AliasedTableExpr) 218 if ok { 219 tbl, ok := als.Expr.(*TableName) 220 if ok { 221 if string(tbl.ObjectName) == "" { 222 canFrom = false 223 } 224 } 225 } 226 if canFrom { 227 ctx.WriteByte(' ') 228 node.From.Format(ctx) 229 } 230 } 231 if node.Where != nil { 232 ctx.WriteByte(' ') 233 node.Where.Format(ctx) 234 } 235 if len(node.GroupBy) > 0 { 236 ctx.WriteByte(' ') 237 node.GroupBy.Format(ctx) 238 } 239 if node.Having != nil { 240 ctx.WriteByte(' ') 241 node.Having.Format(ctx) 242 } 243 } 244 245 func (node *SelectClause) GetStatementType() string { return "Select" } 246 func (node *SelectClause) GetQueryType() string { return QueryTypeDQL } 247 248 // WHERE or HAVING clause. 249 type Where struct { 250 Type string 251 Expr Expr 252 } 253 254 func (node *Where) Format(ctx *FmtCtx) { 255 ctx.WriteString(node.Type) 256 ctx.WriteByte(' ') 257 node.Expr.Format(ctx) 258 } 259 260 const ( 261 AstWhere = "where" 262 AstHaving = "having" 263 ) 264 265 func NewWhere(e Expr) *Where { 266 return &Where{Expr: e} 267 } 268 269 // SELECT expressions. 270 type SelectExprs []SelectExpr 271 272 func (node *SelectExprs) Format(ctx *FmtCtx) { 273 for i, n := range *node { 274 if i > 0 { 275 ctx.WriteString(", ") 276 } 277 n.Format(ctx) 278 } 279 } 280 281 // a SELECT expression. 282 type SelectExpr struct { 283 exprImpl 284 Expr Expr 285 As UnrestrictedIdentifier 286 } 287 288 func (node *SelectExpr) Format(ctx *FmtCtx) { 289 node.Expr.Format(ctx) 290 if node.As != "" { 291 ctx.WriteString(" as ") 292 ctx.WriteString(string(node.As)) 293 } 294 } 295 296 // a GROUP BY clause. 297 type GroupBy []Expr 298 299 func (node *GroupBy) Format(ctx *FmtCtx) { 300 prefix := "group by " 301 for _, n := range *node { 302 ctx.WriteString(prefix) 303 n.Format(ctx) 304 prefix = ", " 305 } 306 } 307 308 const ( 309 JOIN_TYPE_FULL = "FULL" 310 JOIN_TYPE_LEFT = "LEFT" 311 JOIN_TYPE_RIGHT = "RIGHT" 312 JOIN_TYPE_CROSS = "CROSS" 313 JOIN_TYPE_INNER = "INNER" 314 JOIN_TYPE_STRAIGHT = "STRAIGHT_JOIN" 315 JOIN_TYPE_NATURAL = "NATURAL" 316 JOIN_TYPE_NATURAL_LEFT = "NATURAL LEFT" 317 JOIN_TYPE_NATURAL_RIGHT = "NATURAL RIGHT" 318 ) 319 320 // the table expression 321 type TableExpr interface { 322 NodeFormatter 323 } 324 325 var _ TableExpr = &Subquery{} 326 327 type JoinTableExpr struct { 328 TableExpr 329 JoinType string 330 Left TableExpr 331 Right TableExpr 332 Cond JoinCond 333 } 334 335 func (node *JoinTableExpr) Format(ctx *FmtCtx) { 336 if node.Left != nil { 337 node.Left.Format(ctx) 338 } 339 if node.JoinType != "" && node.Right != nil { 340 ctx.WriteByte(' ') 341 ctx.WriteString(strings.ToLower(node.JoinType)) 342 } 343 if node.JoinType != JOIN_TYPE_STRAIGHT && node.Right != nil { 344 ctx.WriteByte(' ') 345 ctx.WriteString("join") 346 } 347 if node.Right != nil { 348 ctx.WriteByte(' ') 349 node.Right.Format(ctx) 350 } 351 if node.Cond != nil { 352 ctx.WriteByte(' ') 353 node.Cond.Format(ctx) 354 } 355 } 356 357 func NewJoinTableExpr(jt string, l, r TableExpr, jc JoinCond) *JoinTableExpr { 358 return &JoinTableExpr{ 359 JoinType: jt, 360 Left: l, 361 Right: r, 362 Cond: jc, 363 } 364 } 365 366 // the join condition. 367 type JoinCond interface { 368 NodeFormatter 369 } 370 371 // the NATURAL join condition 372 type NaturalJoinCond struct { 373 JoinCond 374 } 375 376 func (node *NaturalJoinCond) Format(ctx *FmtCtx) { 377 ctx.WriteString("natural") 378 } 379 380 func NewNaturalJoinCond() *NaturalJoinCond { 381 return &NaturalJoinCond{} 382 } 383 384 // the ON condition for join 385 type OnJoinCond struct { 386 JoinCond 387 Expr Expr 388 } 389 390 func (node *OnJoinCond) Format(ctx *FmtCtx) { 391 ctx.WriteString("on ") 392 node.Expr.Format(ctx) 393 } 394 395 func NewOnJoinCond(e Expr) *OnJoinCond { 396 return &OnJoinCond{Expr: e} 397 } 398 399 // the USING condition 400 type UsingJoinCond struct { 401 JoinCond 402 Cols IdentifierList 403 } 404 405 func (node *UsingJoinCond) Format(ctx *FmtCtx) { 406 ctx.WriteString("using (") 407 node.Cols.Format(ctx) 408 ctx.WriteByte(')') 409 } 410 411 func NewUsingJoinCond(c IdentifierList) *UsingJoinCond { 412 return &UsingJoinCond{Cols: c} 413 } 414 415 // the parenthesized TableExpr. 416 type ParenTableExpr struct { 417 TableExpr 418 Expr TableExpr 419 } 420 421 func (node *ParenTableExpr) Format(ctx *FmtCtx) { 422 ctx.WriteByte('(') 423 node.Expr.Format(ctx) 424 ctx.WriteByte(')') 425 } 426 427 func NewParenTableExpr(e TableExpr) *ParenTableExpr { 428 return &ParenTableExpr{Expr: e} 429 } 430 431 // The alias, optionally with a column list: 432 // "AS name" or "AS name(col1, col2)". 433 type AliasClause struct { 434 NodeFormatter 435 Alias Identifier 436 Cols IdentifierList 437 } 438 439 func (node *AliasClause) Format(ctx *FmtCtx) { 440 if node.Alias != "" { 441 ctx.WriteString(string(node.Alias)) 442 } 443 if node.Cols != nil { 444 ctx.WriteByte('(') 445 node.Cols.Format(ctx) 446 ctx.WriteByte(')') 447 } 448 } 449 450 // the table expression coupled with an optional alias. 451 type AliasedTableExpr struct { 452 TableExpr 453 Expr TableExpr 454 As AliasClause 455 IndexHints []*IndexHint 456 } 457 458 func (node *AliasedTableExpr) Format(ctx *FmtCtx) { 459 node.Expr.Format(ctx) 460 if node.As.Alias != "" { 461 ctx.WriteString(" as ") 462 node.As.Format(ctx) 463 } 464 if node.IndexHints != nil { 465 prefix := " " 466 for _, hint := range node.IndexHints { 467 ctx.WriteString(prefix) 468 hint.Format(ctx) 469 prefix = " " 470 } 471 } 472 } 473 474 func NewAliasedTableExpr(e TableExpr, a AliasClause) *AliasedTableExpr { 475 return &AliasedTableExpr{ 476 Expr: e, 477 As: a, 478 } 479 } 480 481 // the statements as a data source includes the select statement. 482 type StatementSource struct { 483 TableExpr 484 Statement Statement 485 } 486 487 func NewStatementSource(s Statement) *StatementSource { 488 return &StatementSource{ 489 Statement: s, 490 } 491 } 492 493 // the list of table expressions. 494 type TableExprs []TableExpr 495 496 func (node *TableExprs) Format(ctx *FmtCtx) { 497 prefix := "" 498 for _, n := range *node { 499 ctx.WriteString(prefix) 500 n.Format(ctx) 501 prefix = ", " 502 } 503 } 504 505 // the FROM clause. 506 type From struct { 507 Tables TableExprs 508 } 509 510 func (node *From) Format(ctx *FmtCtx) { 511 ctx.WriteString("from ") 512 node.Tables.Format(ctx) 513 } 514 515 func NewFrom(t TableExprs) *From { 516 return &From{Tables: t} 517 } 518 519 type IndexHintType int 520 521 const ( 522 HintUse IndexHintType = iota + 1 523 HintIgnore 524 HintForce 525 ) 526 527 type IndexHintScope int 528 529 // Index hint scopes. 530 const ( 531 HintForScan IndexHintScope = iota + 1 532 HintForJoin 533 HintForOrderBy 534 HintForGroupBy 535 ) 536 537 type IndexHint struct { 538 IndexNames []string 539 HintType IndexHintType 540 HintScope IndexHintScope 541 } 542 543 func (node *IndexHint) Format(ctx *FmtCtx) { 544 indexHintType := "" 545 switch node.HintType { 546 case HintUse: 547 indexHintType = "use index" 548 case HintIgnore: 549 indexHintType = "ignore index" 550 case HintForce: 551 indexHintType = "force index" 552 } 553 554 indexHintScope := "" 555 switch node.HintScope { 556 case HintForScan: 557 indexHintScope = "" 558 case HintForJoin: 559 indexHintScope = " for join" 560 case HintForOrderBy: 561 indexHintScope = " for order by" 562 case HintForGroupBy: 563 indexHintScope = " for group by" 564 } 565 ctx.WriteString(indexHintType) 566 ctx.WriteString(indexHintScope) 567 ctx.WriteString("(") 568 if node.IndexNames != nil { 569 for i, value := range node.IndexNames { 570 if i > 0 { 571 ctx.WriteString(", ") 572 } 573 ctx.WriteString(value) 574 } 575 } 576 ctx.WriteString(")") 577 }