func()

in query/sql/sql_parser.go [956:1018]


func (v *ASTBuilder) VisitFunctionCall(ctx *antlrgen.FunctionCallContext) interface{} {
	v.Logger.Debugf("VisitFunctionCall: %s", ctx.GetText())

	// 1. timebucket and numbericbucket are only from groupBy clause
	// 2. timefilter is only from where clause
	location := v.getLocation(ctx)
	name := v.getText(ctx.QualifiedName())
	udfDef, ok := util.UdfTable[name]
	if ok {
		if ctx.SetQuantifier() != nil || ctx.Filter() != nil || len(ctx.AllSortItem()) != 0 || ctx.AllExpression() == nil {
			panic(fmt.Errorf("quantifier/filter/over/sort not supported in %s function at (line:%d, col:%d)",
				name, location.Line, location.CharPosition))
		}
		if len(ctx.AllExpression()) != udfDef.ArgsNum {
			panic(fmt.Errorf("%s should have %d parameters at (line:%d, col:%d)",
				name, udfDef.ArgsNum, location.Line, location.CharPosition))
		}
		if v.hasORInPath(ctx.BaseParserRuleContext) == tree.OR {
			panic(fmt.Errorf("function %s can not appear in OR logicalBinaryExpression at (line:%d, col:%d)",
				name, location.Line, location.CharPosition))
		}
		if (udfDef.Type == util.Timebucket || udfDef.Type == util.Numericbucket) && v.SQL2AqlCtx.exprOrigin != ExprOriginGroupBy {
			panic(fmt.Errorf("function %s at (line:%d, col:%d) can only appear in group by clause",
				name, location.Line, location.CharPosition))
		}
		if udfDef.Type == util.Timefilter && v.SQL2AqlCtx.exprOrigin != ExprOriginWhere {
			panic(fmt.Errorf("function %s at (line:%d, col:%d) can only appear in where clause",
				name, location.Line, location.CharPosition))
		}

		switch udfDef.Type {
		case util.Timefilter:
			v.setTimefilter(ctx.AllExpression())
		case util.TimeNow:
			v.setTimeNow(ctx.AllExpression())
		case util.Timebucket:
			v.SQL2AqlCtx.MapDimensions[v.SQL2AqlCtx.mapKey] = append(
				v.SQL2AqlCtx.MapDimensions[v.SQL2AqlCtx.mapKey],
				queryCom.Dimension{
					Expr:           util.TrimQuote(v.getText(ctx.Expression(0))),
					TimeBucketizer: util.TrimQuote(udfDef.Definition),
					TimeUnit:       util.TrimQuote(v.getText(ctx.Expression(1))),
				})
			if len(v.SQL2AqlCtx.timezone) == 0 {
				v.SQL2AqlCtx.timezone = util.TrimQuote(v.getText(ctx.Expression(2)))
			} else if v.SQL2AqlCtx.timezone != util.TrimQuote(v.getText(ctx.Expression(2))) {
				panic(fmt.Errorf("different timebucket timezone %s at (line:%d, col:%d)",
					v.getText(ctx.Expression(2)), location.Line, location.CharPosition))
			}
		case util.Numericbucket:
			v.setNumericBucketizer(ctx.AllExpression(), udfDef.Definition)
		}
	} else if strings.HasPrefix(name, _aqlPrefix) {
		panic(fmt.Errorf("function %s at (line:%d, col:%d) is not registered in AQL udf",
			name, location.Line, location.CharPosition))
	}

	if exist := util.AggregateFunctions[name]; exist {
		v.aggFuncExists = true
	}

	return tree.NewExpression(v.getLocation(ctx))
}