github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/having.go (about) 1 // Copyright 2020-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 "github.com/dolthub/go-mysql-server/sql" 18 19 // Having node is a filter that supports aggregate expressions. A having node 20 // is identical to a filter node in behaviour. The difference is that some 21 // analyzer rules work specifically on having clauses and not filters. For 22 // that reason, Having is a completely new node instead of using just filter. 23 type Having struct { 24 UnaryNode 25 Cond sql.Expression 26 } 27 28 var _ sql.Node = (*Having)(nil) 29 var _ sql.Expressioner = (*Having)(nil) 30 var _ sql.CollationCoercible = (*Having)(nil) 31 32 // NewHaving creates a new having node. 33 func NewHaving(cond sql.Expression, child sql.Node) *Having { 34 return &Having{UnaryNode{Child: child}, cond} 35 } 36 37 // Resolved implements the sql.Node interface. 38 func (h *Having) Resolved() bool { return h.Cond.Resolved() && h.Child.Resolved() } 39 40 func (h *Having) IsReadOnly() bool { 41 return h.Child.IsReadOnly() 42 } 43 44 // Expressions implements the sql.Expressioner interface. 45 func (h *Having) Expressions() []sql.Expression { return []sql.Expression{h.Cond} } 46 47 // WithChildren implements the Node interface. 48 func (h *Having) WithChildren(children ...sql.Node) (sql.Node, error) { 49 if len(children) != 1 { 50 return nil, sql.ErrInvalidChildrenNumber.New(h, len(children), 1) 51 } 52 53 return NewHaving(h.Cond, children[0]), nil 54 } 55 56 // CheckPrivileges implements the interface sql.Node. 57 func (h *Having) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 58 return h.Child.CheckPrivileges(ctx, opChecker) 59 } 60 61 // CollationCoercibility implements the interface sql.CollationCoercible. 62 func (h *Having) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 63 return sql.GetCoercibility(ctx, h.Child) 64 } 65 66 // WithExpressions implements the Expressioner interface. 67 func (h *Having) WithExpressions(exprs ...sql.Expression) (sql.Node, error) { 68 if len(exprs) != 1 { 69 return nil, sql.ErrInvalidChildrenNumber.New(h, len(exprs), 1) 70 } 71 72 return NewHaving(exprs[0], h.Child), nil 73 } 74 75 func (h *Having) String() string { 76 p := sql.NewTreePrinter() 77 _ = p.WriteNode("Having(%s)", h.Cond) 78 _ = p.WriteChildren(h.Child.String()) 79 return p.String() 80 } 81 82 func (h *Having) DebugString() string { 83 pr := sql.NewTreePrinter() 84 _ = pr.WriteNode("Having") 85 children := []string{sql.DebugString(h.Cond), sql.DebugString(h.Child)} 86 _ = pr.WriteChildren(children...) 87 return pr.String() 88 }