In queries collect all needed data
authorKlaus Aehlig <aehlig@google.com>
Tue, 4 Aug 2015 13:19:01 +0000 (15:19 +0200)
committerKlaus Aehlig <aehlig@google.com>
Tue, 4 Aug 2015 14:56:27 +0000 (16:56 +0200)
Queries are affected by two forms of fields:
- those the user wishes to see, and
- those needed to evaluate the filter provided.
For internal handling, we do have to fetch the
fields of either category to avoid wrong results,
even if we only output fields of the first category.
Ensure this fetch.

Signed-off-by: Klaus Aehlig <aehlig@google.com>
Reviewed-by: Petr Pudlak <pudlak@google.com>

src/Ganeti/Query/Query.hs

index 09cadf9..4d8fc83 100644 (file)
@@ -218,7 +218,9 @@ genericQuery fieldsMap collector nameFn configFn getFn cfg
              live fields qfilter wanted =
   runResultT $ do
   cfilter <- toError $ compileFilter fieldsMap qfilter
-  let selected = getSelectedFields fieldsMap fields
+  let allfields = ordNub $ fields ++ filterArguments qfilter
+      count = length $ ordNub fields
+      selected = getSelectedFields fieldsMap allfields
       (fdefs, fgetters, _) = unzip3 selected
       live' = live && needsLiveData fgetters
   objects <- toError $ case wanted of
@@ -233,13 +235,14 @@ genericQuery fieldsMap collector nameFn configFn getFn cfg
   -- based on the gathered data
   runtimes <- (case collector of
     CollectorSimple     collFn -> lift $ collFn live' cfg fobjects
-    CollectorFieldAware collFn -> lift $ collFn live' cfg fields fobjects) >>=
-    (toError . filterM (\(obj, runtime) ->
+    CollectorFieldAware collFn -> lift $ collFn live' cfg allfields fobjects)
+    >>= (toError . filterM (\(obj, runtime) ->
       evaluateFilter cfg (Just runtime) obj cfilter))
   let fdata = map (\(obj, runtime) ->
                      map (execGetter cfg runtime obj) fgetters)
               runtimes
-  return QueryResult { qresFields = fdefs, qresData = fdata }
+  return QueryResult { qresFields = take count fdefs
+                     , qresData = map (take count) fdata }
 
 -- | Dummy recollection of the data for a lock from the prefected
 -- data for all locks.