func()

in query/aql_compiler.go [1139:1250]


func (qc *AQLQueryContext) processMeasure() {
	// OOPK engine only supports one measure per query.
	if len(qc.Query.Measures) != 1 {
		qc.Error = utils.StackError(nil, "expect one measure per query, but got %d",
			len(qc.Query.Measures))
		return
	}

	if _, ok := qc.Query.Measures[0].ExprParsed.(*expr.NumberLiteral); ok {
		qc.IsNonAggregationQuery = true
		// in case user forgot to provide limit
		if qc.Query.Limit == 0 {
			qc.Query.Limit = nonAggregationQueryLimit
		}
		return
	}

	// Match and strip the aggregate function.
	aggregate, ok := qc.Query.Measures[0].ExprParsed.(*expr.Call)
	if !ok {
		qc.Error = utils.StackError(nil, "expect aggregate function, but got %s",
			qc.Query.Measures[0].Expr)
		return
	}

	if qc.ReturnHLLData && aggregate.Name != expr.HllCallName {
		qc.Error = utils.StackError(nil, "expect hll aggregate function as client specify 'Accept' as "+
			"'application/hll', but got %s",
			qc.Query.Measures[0].Expr)
		return
	}

	if len(aggregate.Args) != 1 {
		qc.Error = utils.StackError(nil,
			"expect one parameter for aggregate function %s, but got %d",
			aggregate.Name, len(aggregate.Args))
		return
	}
	qc.OOPK.Measure = aggregate.Args[0]

	// check if any array column is used in measure
	ac := &arrayColumnUsageCollector{}
	expr.Walk(ac, qc.OOPK.Measure)
	if ac.useArrayColumn {
		qc.Error = utils.StackError(nil,
			"Array column is not allowed to be used in measure: %s", qc.OOPK.Measure.String())
		return
	}

	// default is 4 bytes
	qc.OOPK.MeasureBytes = 4
	switch strings.ToLower(aggregate.Name) {
	case expr.CountCallName:
		qc.OOPK.Measure = &expr.NumberLiteral{
			Int:      1,
			Expr:     "1",
			ExprType: expr.Unsigned,
		}
		qc.OOPK.AggregateType = C.AGGR_SUM_UNSIGNED
	case expr.SumCallName:
		qc.OOPK.MeasureBytes = 8
		switch qc.OOPK.Measure.Type() {
		case expr.Float:
			qc.OOPK.AggregateType = C.AGGR_SUM_FLOAT
		case expr.Signed:
			qc.OOPK.AggregateType = C.AGGR_SUM_SIGNED
		case expr.Unsigned:
			qc.OOPK.AggregateType = C.AGGR_SUM_UNSIGNED
		default:
			qc.Error = utils.StackError(nil,
				unsupportedInputType, expr.SumCallName, qc.OOPK.Measure.String())
			return
		}
	case expr.AvgCallName:
		// 4 bytes for storing average result and another 4 byte for count
		qc.OOPK.MeasureBytes = 8
		// for average, we should always use float type as the agg type.
		qc.OOPK.AggregateType = C.AGGR_AVG_FLOAT
	case expr.MinCallName:
		switch qc.OOPK.Measure.Type() {
		case expr.Float:
			qc.OOPK.AggregateType = C.AGGR_MIN_FLOAT
		case expr.Signed:
			qc.OOPK.AggregateType = C.AGGR_MIN_SIGNED
		case expr.Unsigned:
			qc.OOPK.AggregateType = C.AGGR_MIN_UNSIGNED
		default:
			qc.Error = utils.StackError(nil,
				unsupportedInputType, expr.MinCallName, qc.OOPK.Measure.String())
			return
		}
	case expr.MaxCallName:
		switch qc.OOPK.Measure.Type() {
		case expr.Float:
			qc.OOPK.AggregateType = C.AGGR_MAX_FLOAT
		case expr.Signed:
			qc.OOPK.AggregateType = C.AGGR_MAX_SIGNED
		case expr.Unsigned:
			qc.OOPK.AggregateType = C.AGGR_MAX_UNSIGNED
		default:
			qc.Error = utils.StackError(nil,
				unsupportedInputType, expr.MaxCallName, qc.OOPK.Measure.String())
			return
		}
	case expr.HllCallName:
		qc.OOPK.AggregateType = C.AGGR_HLL
	default:
		qc.Error = utils.StackError(nil,
			"unsupported aggregate function: %s", aggregate.Name)
		return
	}
}