********************* primary expressions ********************** VisitFunctionCall visits the node
(ctx *antlrgen.FunctionCallContext)
| 954 | |
| 955 | // VisitFunctionCall visits the node |
| 956 | func (v *ASTBuilder) VisitFunctionCall(ctx *antlrgen.FunctionCallContext) interface{} { |
| 957 | v.Logger.Debugf("VisitFunctionCall: %s", ctx.GetText()) |
| 958 | |
| 959 | // 1. timebucket and numbericbucket are only from groupBy clause |
| 960 | // 2. timefilter is only from where clause |
| 961 | location := v.getLocation(ctx) |
| 962 | name := v.getText(ctx.QualifiedName()) |
| 963 | udfDef, ok := util.UdfTable[name] |
| 964 | if ok { |
| 965 | if ctx.SetQuantifier() != nil || ctx.Filter() != nil || len(ctx.AllSortItem()) != 0 || ctx.AllExpression() == nil { |
| 966 | panic(fmt.Errorf("quantifier/filter/over/sort not supported in %s function at (line:%d, col:%d)", |
| 967 | name, location.Line, location.CharPosition)) |
| 968 | } |
| 969 | if len(ctx.AllExpression()) != udfDef.ArgsNum { |
| 970 | panic(fmt.Errorf("%s should have %d parameters at (line:%d, col:%d)", |
| 971 | name, udfDef.ArgsNum, location.Line, location.CharPosition)) |
| 972 | } |
| 973 | if v.hasORInPath(ctx.BaseParserRuleContext) == tree.OR { |
| 974 | panic(fmt.Errorf("function %s can not appear in OR logicalBinaryExpression at (line:%d, col:%d)", |
| 975 | name, location.Line, location.CharPosition)) |
| 976 | } |
| 977 | if (udfDef.Type == util.Timebucket || udfDef.Type == util.Numericbucket) && v.SQL2AqlCtx.exprOrigin != ExprOriginGroupBy { |
| 978 | panic(fmt.Errorf("function %s at (line:%d, col:%d) can only appear in group by clause", |
| 979 | name, location.Line, location.CharPosition)) |
| 980 | } |
| 981 | if udfDef.Type == util.Timefilter && v.SQL2AqlCtx.exprOrigin != ExprOriginWhere { |
| 982 | panic(fmt.Errorf("function %s at (line:%d, col:%d) can only appear in where clause", |
| 983 | name, location.Line, location.CharPosition)) |
| 984 | } |
| 985 | |
| 986 | switch udfDef.Type { |
| 987 | case util.Timefilter: |
| 988 | v.setTimefilter(ctx.AllExpression()) |
| 989 | case util.TimeNow: |
| 990 | v.setTimeNow(ctx.AllExpression()) |
| 991 | case util.Timebucket: |
| 992 | v.SQL2AqlCtx.MapDimensions[v.SQL2AqlCtx.mapKey] = append( |
| 993 | v.SQL2AqlCtx.MapDimensions[v.SQL2AqlCtx.mapKey], |
| 994 | queryCom.Dimension{ |
| 995 | Expr: util.TrimQuote(v.getText(ctx.Expression(0))), |
| 996 | TimeBucketizer: util.TrimQuote(udfDef.Definition), |
| 997 | TimeUnit: util.TrimQuote(v.getText(ctx.Expression(1))), |
| 998 | }) |
| 999 | if len(v.SQL2AqlCtx.timezone) == 0 { |
| 1000 | v.SQL2AqlCtx.timezone = util.TrimQuote(v.getText(ctx.Expression(2))) |
| 1001 | } else if v.SQL2AqlCtx.timezone != util.TrimQuote(v.getText(ctx.Expression(2))) { |
| 1002 | panic(fmt.Errorf("different timebucket timezone %s at (line:%d, col:%d)", |
| 1003 | v.getText(ctx.Expression(2)), location.Line, location.CharPosition)) |
| 1004 | } |
| 1005 | case util.Numericbucket: |
| 1006 | v.setNumericBucketizer(ctx.AllExpression(), udfDef.Definition) |
| 1007 | } |
| 1008 | } else if strings.HasPrefix(name, _aqlPrefix) { |
| 1009 | panic(fmt.Errorf("function %s at (line:%d, col:%d) is not registered in AQL udf", |
| 1010 | name, location.Line, location.CharPosition)) |
| 1011 | } |
| 1012 | |
| 1013 | if exist := util.AggregateFunctions[name]; exist { |
nothing calls this directly
no test coverage detected