github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/window.go (about) 1 // Copyright 2021 Dolthub, Inc. 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 plan 16 17 import ( 18 "errors" 19 "strings" 20 21 "github.com/dolthub/go-mysql-server/sql" 22 "github.com/dolthub/go-mysql-server/sql/expression" 23 "github.com/dolthub/go-mysql-server/sql/transform" 24 ) 25 26 var ErrAggregationMissingWindow = errors.New("aggregation missing window expression") 27 28 type Window struct { 29 SelectExprs []sql.Expression 30 UnaryNode 31 } 32 33 var _ sql.Expressioner = (*Window)(nil) 34 var _ sql.Node = (*Window)(nil) 35 var _ sql.Projector = (*Window)(nil) 36 var _ sql.CollationCoercible = (*Window)(nil) 37 38 func NewWindow(selectExprs []sql.Expression, node sql.Node) *Window { 39 return &Window{ 40 SelectExprs: selectExprs, 41 UnaryNode: UnaryNode{node}, 42 } 43 } 44 45 // Resolved implements sql.Node 46 func (w *Window) Resolved() bool { 47 return w.UnaryNode.Child.Resolved() && 48 expression.ExpressionsResolved(w.SelectExprs...) 49 } 50 51 func (w *Window) IsReadOnly() bool { 52 return w.Child.IsReadOnly() 53 } 54 55 func (w *Window) String() string { 56 pr := sql.NewTreePrinter() 57 var exprs = make([]string, len(w.SelectExprs)) 58 for i, expr := range w.SelectExprs { 59 exprs[i] = expr.String() 60 } 61 _ = pr.WriteNode("Window(%s)", strings.Join(exprs, ", ")) 62 _ = pr.WriteChildren(w.Child.String()) 63 return pr.String() 64 } 65 66 func (w *Window) DebugString() string { 67 pr := sql.NewTreePrinter() 68 var exprs = make([]string, len(w.SelectExprs)) 69 for i, expr := range w.SelectExprs { 70 exprs[i] = sql.DebugString(expr) 71 } 72 _ = pr.WriteNode("Window") 73 exprs = append(exprs, sql.DebugString(w.Child)) 74 _ = pr.WriteChildren(exprs...) 75 return pr.String() 76 } 77 78 // Schema implements sql.Node 79 func (w *Window) Schema() sql.Schema { 80 var s = make(sql.Schema, len(w.SelectExprs)) 81 for i, e := range w.SelectExprs { 82 s[i] = transform.ExpressionToColumn(e, AliasSubqueryString(e)) 83 } 84 return s 85 } 86 87 // WithChildren implements sql.Node 88 func (w *Window) WithChildren(children ...sql.Node) (sql.Node, error) { 89 if len(children) != 1 { 90 return nil, sql.ErrInvalidChildrenNumber.New(w, len(children), 1) 91 } 92 93 return NewWindow(w.SelectExprs, children[0]), nil 94 } 95 96 // CheckPrivileges implements the interface sql.Node. 97 func (w *Window) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 98 return w.Child.CheckPrivileges(ctx, opChecker) 99 } 100 101 // CollationCoercibility implements the interface sql.CollationCoercible. 102 func (w *Window) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 103 return sql.GetCoercibility(ctx, w.Child) 104 } 105 106 // Expressions implements sql.Expressioner 107 func (w *Window) Expressions() []sql.Expression { 108 return w.SelectExprs 109 } 110 111 // ProjectedExprs implements sql.Projector 112 func (w *Window) ProjectedExprs() []sql.Expression { 113 return w.SelectExprs 114 } 115 116 // WithExpressions implements sql.Expressioner 117 func (w *Window) WithExpressions(e ...sql.Expression) (sql.Node, error) { 118 if len(e) != len(w.SelectExprs) { 119 return nil, sql.ErrInvalidChildrenNumber.New(w, len(e), len(w.SelectExprs)) 120 } 121 122 return NewWindow(e, w.Child), nil 123 }