(n ast.Node, name string, arg ast.Expr, filter ast.Expr, distinct bool, inType super.Type)
| 1141 | } |
| 1142 | |
| 1143 | func (t *translator) aggFunc(n ast.Node, name string, arg ast.Expr, filter ast.Expr, distinct bool, inType super.Type) (sem.Expr, super.Type) { |
| 1144 | // If we are in the context of a having clause, re-expose the select schema |
| 1145 | // since the agg func's arguments and where clause operate on the input relation |
| 1146 | // not the output. |
| 1147 | scope, ok := t.scope.sql.(*selectScope) |
| 1148 | if ok { |
| 1149 | if !scope.aggOk { |
| 1150 | if scope.groupByLoc != nil { |
| 1151 | t.error(scope.groupByLoc, fmt.Errorf("aggregate function %q cannot appear in GROUP BY via positional reference", name)) |
| 1152 | } else { |
| 1153 | t.error(n, fmt.Errorf("aggregate function %q called in non-aggregate context", name)) |
| 1154 | } |
| 1155 | return badExpr, t.checker.unknown |
| 1156 | } |
| 1157 | scope.aggOk = false |
| 1158 | save := scope.out |
| 1159 | defer func() { |
| 1160 | scope.aggOk = true |
| 1161 | scope.out = save |
| 1162 | }() |
| 1163 | scope.out = nil |
| 1164 | } |
| 1165 | argExpr, argType := t.exprNullable(arg, inType) |
| 1166 | filterExpr, filterType := t.exprNullable(filter, inType) |
| 1167 | f := &sem.AggFunc{ |
| 1168 | Node: n, |
| 1169 | Name: name, |
| 1170 | Expr: argExpr, |
| 1171 | Filter: filterExpr, |
| 1172 | Distinct: distinct, |
| 1173 | } |
| 1174 | if !ok { |
| 1175 | typ := t.checker.aggFunc(name, arg, argType, filter, filterType) |
| 1176 | return f, typ |
| 1177 | } |
| 1178 | for k, previous := range scope.aggs { |
| 1179 | if f.Name == previous.Name && f.Distinct == previous.Distinct && eqExpr(f.Expr, previous.Expr) && eqExpr(f.Filter, previous.Filter) { |
| 1180 | return &sem.AggRef{Node: n, Index: k}, scope.aggTypes[k] |
| 1181 | } |
| 1182 | } |
| 1183 | typ := t.checker.aggFunc(name, arg, argType, filter, filterType) |
| 1184 | ref := &sem.AggRef{Node: f, Index: len(scope.aggs)} |
| 1185 | scope.aggs = append(scope.aggs, f) |
| 1186 | scope.aggTypes = append(scope.aggTypes, typ) |
| 1187 | return ref, typ |
| 1188 | } |
| 1189 | |
| 1190 | func DotExprToFieldPath(e ast.Expr) *sem.ThisExpr { |
| 1191 | switch e := e.(type) { |
no test coverage detected