in api/query_handler.go [107:216]
func (handler *QueryHandler) handleAQLInternal(aqlRequest apiCom.AQLRequest, w *utils.ResponseWriter, r *http.Request) {
var err error
var duration time.Duration
var qcs []*query.AQLQueryContext
var statusCode int
defer func() {
var errStr string
if err != nil {
errStr = err.Error()
}
l := utils.GetQueryLogger().With(
"error", errStr,
"request", aqlRequest,
"queries_enabled_", aqlRequest.Body.Queries,
"duration", duration,
"statusCode", statusCode,
"contexts_enabled_", qcs,
"headers", r.Header,
)
if statusCode == http.StatusOK {
l.Info("All queries succeeded")
} else {
l.Error("Some of the queries finished with error")
}
}()
if aqlRequest.Query != "" {
// Override from query parameter
err = json.Unmarshal([]byte(aqlRequest.Query), &aqlRequest.Body)
if err != nil {
statusCode = http.StatusBadRequest
w.WriteError(utils.APIError{
Code: statusCode,
Message: ErrMsgFailedToUnmarshalRequest,
Cause: err,
})
return
}
}
if aqlRequest.Body.Queries == nil {
statusCode = http.StatusBadRequest
w.WriteError(ErrMissingParameter)
return
}
returnHLL := aqlRequest.Accept == utils.HTTPContentTypeHyperLogLog
if aqlRequest.DeviceChoosingTimeout <= 0 {
aqlRequest.DeviceChoosingTimeout = -1
}
queryTimer := utils.GetRootReporter().GetTimer(utils.QueryLatency)
start := utils.Now()
var requestResponseWriter QueryResponseWriter
if !returnHLL && canEagerFlush(aqlRequest.Body.Queries) {
statusCode = http.StatusOK
aqlQuery := aqlRequest.Body.Queries[0]
qc := &query.AQLQueryContext{
Query: &aqlQuery,
ReturnHLLData: false,
DataOnly: aqlRequest.DataOnly != 0,
}
qc.InitQCHelper()
qc.Compile(handler.memStore, handler.shardOwner)
qc.ResponseWriter = w
if qc.Error != nil {
err = qc.Error
statusCode = http.StatusBadRequest
w.WriteErrorWithCode(statusCode, err)
return
}
// for logging purpose only
qcs = append(qcs, qc)
qc.FindDeviceForQuery(handler.memStore, aqlRequest.Device, handler.deviceManager, aqlRequest.DeviceChoosingTimeout)
if qc.Error != nil {
err = qc.Error
statusCode = http.StatusServiceUnavailable
w.WriteErrorWithCode(statusCode, err)
return
}
defer handler.deviceManager.ReleaseReservedMemory(qc.Device, qc.Query)
qc.ProcessQuery(handler.memStore)
if qc.Error != nil {
err = qc.Error
utils.GetQueryLogger().With(
"error", err,
"query", aqlQuery,
"context", qc,
).Error("Error happened when processing query")
statusCode = http.StatusInternalServerError
return
}
if !qc.DataOnly {
w.Write([]byte(`]}]`))
if aqlRequest.Verbose > 0 {
w.Write([]byte(`,"context":`))
qcBytes, _ := json.Marshal(qcs)
w.Write(qcBytes)
}
w.Write([]byte(`}`))
}