public override Expression Evaluate(EvalStore store) { Stopwatch watch; store.Remove("$DATA"); var facts = store.Get<Table>("Facts"); var fromList = store.Get<Dictionary<string, Table>>("$FROM_LIST"); if (fromList == null || fromList.Count == 0) { return ConstExpr.Empty; } HashSet<string> refIds = store.Get<HashSet<string>>("$REFIDS"); var selFacts = SelectFactTableRows(fromList, facts); for (int i = 0; i < _exprs.Count; i++) { _exprs[i] = Reduce(store, _exprs[i]); } Dictionary<int, List<Expression>> exprGroups; Dictionary<string, Expression> idExprMap; NormalizeExpressions(selFacts, _exprs, out exprGroups, out idExprMap); //find out the time range if (exprGroups[TIME_FILTER].Count == 0) { throw new Exception("Time range expression is not specified."); } DateTime min = DateTime.MaxValue; DateTime max = DateTime.MinValue; DateTime[] range = ExtraTimeRange(store, exprGroups[TIME_FILTER][0]); if (range != null) { if (range[0] < min) min = range[0]; if (range[1] > max) max = range[1]; } else { throw new Exception("Time range is not specified."); } //find a list of data log by applying filters of various properties from the fact table Table sel = null; using (EvalScope scope = new EvalScope(store, new EvalContext(EvalContext.ContextType.SEARCH))) { if (exprGroups[ATTR_FILTER].Count == 0) { sel = (Table) selFacts["_"]; } else { store.Put<Dictionary<string, Table>>("$SEL_FACTS", selFacts); foreach (Expression expr in exprGroups[ATTR_FILTER]) { Expression e = expr.Evaluate(store); if (e.ExpressionType != Language.ExpressionType.CONST) { throw new Exception("The expression should be evaluated to a value. " + e.ToString()); } ConstExpr c = e as ConstExpr; if (c.Value.DataType == ElementType.TABLE) { Table s = c.Value.GetObject<Table>(); if (sel == null) sel = s; else sel.IntersectWith(s); } else { if (c.Value.DataType != ElementType.EMPTY) { throw new Exception("The expression should be evaluated to a set of rows or an empty set. " + e.ToString()); } } } } } if (sel == null || sel.Rows == 0) return ConstExpr.Empty; //creating additional filters for the metric loading queries string resFilter = CreateResourceFilters(sel); string ctxFilter = CreateContextFilter(store, exprGroups); string filters; if (!string.IsNullOrEmpty(resFilter) && !string.IsNullOrEmpty(ctxFilter)) { filters = (resFilter + " AND " + ctxFilter); } else if (string.IsNullOrEmpty(resFilter)) { filters = ctxFilter; } else { filters = resFilter; } MetricsDataLoader dataLoader = new MetricsDataLoader(); Table data = dataLoader.Load(sel, min, max, filters, refIds); Trace.WriteLine("WhereClase.Evaluate.TotalRows: " + data.Rows); //applies filters that involve result columns watch = Stopwatch.StartNew(); if (exprGroups[OTHER_FILTER].Count > 0) { using (EvalScope scope = new EvalScope(store, new EvalContext(EvalContext.ContextType.FILTER))) { store.Put<Table>("$DATA", data); HashSet<int> selRows = new HashSet<int>(); for (int i = 0; i < data.Rows; i++) { store.Put<Element[]>("$ROW", data.Row(i)); bool include = true; foreach (Expression expr in exprGroups[OTHER_FILTER]) { ConstExpr c = expr.Evaluate(store) as ConstExpr; if (!((bool)c.Value)) { include = false; break; } } if (include) { selRows.Add(i); } } data = data.Select(selRows); } } if (data == null) data = new Table(); watch.Stop(); Trace.WriteLine("WhereClase.Evaluate.Filter: " + watch.ElapsedMilliseconds + "ms"); Trace.WriteLine("WhereClase.Evaluate.SelectedRows: " + data.Rows); store.Put<Table>("$DATA", data); return new ConstExpr(data); }