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  }