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  }