github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/transform/aggregates.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package transform 12 13 import ( 14 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 15 "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" 16 ) 17 18 // IsAggregateVisitor checks if walked expressions contain aggregate functions. 19 type IsAggregateVisitor struct { 20 Aggregated bool 21 // searchPath is used to search for unqualified function names. 22 searchPath sessiondata.SearchPath 23 } 24 25 var _ tree.Visitor = &IsAggregateVisitor{} 26 27 // VisitPre satisfies the Visitor interface. 28 func (v *IsAggregateVisitor) VisitPre(expr tree.Expr) (recurse bool, newExpr tree.Expr) { 29 switch t := expr.(type) { 30 case *tree.FuncExpr: 31 if t.IsWindowFunctionApplication() { 32 // A window function application of an aggregate builtin is not an 33 // aggregate function, but it can contain aggregate functions. 34 return true, expr 35 } 36 fd, err := t.Func.Resolve(v.searchPath) 37 if err != nil { 38 return false, expr 39 } 40 if fd.Class == tree.AggregateClass { 41 v.Aggregated = true 42 return false, expr 43 } 44 case *tree.Subquery: 45 return false, expr 46 } 47 48 return true, expr 49 } 50 51 // VisitPost satisfies the Visitor interface. 52 func (*IsAggregateVisitor) VisitPost(expr tree.Expr) tree.Expr { return expr }