internal override Expression Visit(Expression expr) { if (expr == null) { return(expr); } if (HpcLinqExpression.IsConstant(expr)) { object val = ExpressionSimplifier.Evaluate(expr); if (val is IQueryable) { QueryNodeInfo nodeInfo; if (this.m_referencedQueryMap.TryGetValue(((IQueryable)val).Expression, out nodeInfo)) { string name = "side__" + this.m_idx; this.m_idx++; this.m_referencedQueries.Add(new Pair <string, DryadQueryNode>(name, nodeInfo.queryNode)); return(Expression.Parameter(expr.Type, name)); } throw new DryadLinqException(HpcLinqErrorCode.UnhandledQuery, String.Format(SR.UnhandledQuery, HpcLinqExpression.Summarize(expr))); } return(expr); } return(base.Visit(expr)); }
internal static Exception Create(int errorCode, string msg, Expression expr) { StringBuilder sb = new StringBuilder(); sb.Append(msg); sb.Append(" Expression : "); sb.AppendLine(HpcLinqExpression.Summarize(expr, 1)); return(new DryadLinqException(errorCode, sb.ToString())); }
//This is the IQueryProvider.Execute() method used for execution when a single value is produced (rather than an enumerable) public override TResult Execute <TResult>(Expression expression) { MethodCallExpression callExpr = expression as MethodCallExpression; if (callExpr == null) { throw new ArgumentException(String.Format(SR.ExpressionMustBeMethodCall, HpcLinqExpression.Summarize(expression)), "expression"); } string methodName = callExpr.Method.Name; if (methodName == "FirstOrDefault" || methodName == "SingleOrDefault" || methodName == "LastOrDefault") { Type qType = typeof(DryadLinqQuery <>).MakeGenericType(typeof(AggregateValue <>).MakeGenericType(expression.Type)); AggregateValue <TResult> res = ((IEnumerable <AggregateValue <TResult> >) Activator.CreateInstance( qType, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this, expression }, CultureInfo.CurrentCulture )).Single(); if (res.Count == 0) { return(default(TResult)); } return(res.Value); } else { Type qType = typeof(DryadLinqQuery <>).MakeGenericType(expression.Type); return(((IEnumerable <TResult>)Activator.CreateInstance( qType, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this, expression }, CultureInfo.CurrentCulture )).Single()); } }
/// <summary> /// Explain one query node. /// </summary> /// <param name="plan">Return plan here.</param> /// <param name="n">Node to explain.</param> internal static void ExplainNode(StringBuilder plan, DryadQueryNode n) { if (n is DryadTeeNode || n is DryadOutputNode) { return; } else if (n is DryadInputNode) { plan.AppendLine("Input:"); plan.Append("\t"); n.BuildString(plan); plan.AppendLine(); return; } plan.Append(n.m_vertexEntryMethod); plan.AppendLine(":"); HashSet <DryadQueryNode> allchildren = new HashSet <DryadQueryNode>(); if (n is DryadSuperNode) { DryadSuperNode sn = n as DryadSuperNode; List <DryadQueryNode> tovisit = new List <DryadQueryNode>(); tovisit.Add(sn.RootNode); while (tovisit.Count > 0) { DryadQueryNode t = tovisit[0]; tovisit.RemoveAt(0); if (!(t is DryadSuperNode)) { allchildren.Add(t); } foreach (DryadQueryNode tc in t.Children) { if (!allchildren.Contains(tc) && sn.Contains(tc)) { tovisit.Add(tc); } } } } else { allchildren.Add(n); } foreach (DryadQueryNode nc in allchildren.Reverse()) { Expression expression = null; // expression to print List <string> additional = new List <string>(); // additional arguments to print int argsToSkip = 0; string methodname = nc.OpName; plan.Append("\t"); if (nc is DryadMergeNode) { expression = ((DryadMergeNode)nc).ComparerExpression; } else if (nc is DryadHashPartitionNode) { DryadHashPartitionNode hp = (DryadHashPartitionNode)nc; expression = hp.KeySelectExpression; additional.Add(hp.NumberOfPartitions.ToString()); } else if (nc is DryadGroupByNode) { DryadGroupByNode gb = (DryadGroupByNode)nc; expression = gb.KeySelectExpression; if (gb.ElemSelectExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.ElemSelectExpression)); } if (gb.ResSelectExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.ResSelectExpression)); } if (gb.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.ComparerExpression)); } if (gb.SeedExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.SeedExpression)); } if (gb.AccumulatorExpression != null) { additional.Add(HpcLinqExpression.Summarize(gb.AccumulatorExpression)); } } else if (nc is DryadOrderByNode) { DryadOrderByNode ob = (DryadOrderByNode)nc; expression = ob.KeySelectExpression; if (ob.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(ob.ComparerExpression)); } } else if (nc is DryadWhereNode) { expression = ((DryadWhereNode)nc).WhereExpression; } else if (nc is DryadSelectNode) { DryadSelectNode s = (DryadSelectNode)nc; expression = s.SelectExpression; if (s.ResultSelectExpression != null) { additional.Add(HpcLinqExpression.Summarize(s.ResultSelectExpression)); } } else if (nc is DryadAggregateNode) { DryadAggregateNode a = (DryadAggregateNode)nc; expression = a.FuncLambda; if (a.SeedExpression != null) { additional.Add(HpcLinqExpression.Summarize(a.SeedExpression)); } if (a.ResultLambda != null) { additional.Add(HpcLinqExpression.Summarize(a.ResultLambda)); } } else if (nc is DryadPartitionOpNode) { expression = ((DryadPartitionOpNode)nc).ControlExpression; } else if (nc is DryadJoinNode) { DryadJoinNode j = (DryadJoinNode)nc; expression = j.OuterKeySelectorExpression; additional.Add(HpcLinqExpression.Summarize(j.InnerKeySelectorExpression)); additional.Add(HpcLinqExpression.Summarize(j.ResultSelectorExpression)); if (j.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(j.ComparerExpression)); } } else if (nc is DryadDistinctNode) { expression = ((DryadDistinctNode)nc).ComparerExpression; } else if (nc is DryadContainsNode) { DryadContainsNode c = (DryadContainsNode)nc; expression = c.ValueExpression; if (c.ComparerExpression != null) { additional.Add(HpcLinqExpression.Summarize(c.ComparerExpression)); } } else if (nc is DryadBasicAggregateNode) { expression = ((DryadBasicAggregateNode)nc).SelectExpression; } else if (nc is DryadConcatNode) // nothing to do { } else if (nc is DryadSetOperationNode) { expression = ((DryadSetOperationNode)nc).ComparerExpression; } else if (nc is DryadRangePartitionNode) { DryadRangePartitionNode r = (DryadRangePartitionNode)nc; expression = r.CountExpression; // TODO: there's some other possible interesting info } else if (nc is DryadApplyNode) { expression = ((DryadApplyNode)nc).LambdaExpression; } else if (nc is DryadForkNode) { expression = ((DryadForkNode)nc).ForkLambda; } else if (nc is DryadTeeNode) { // nothing } else if (nc is DryadDynamicNode) { // nothing } else { expression = nc.QueryExpression; } if (expression is MethodCallExpression) { MethodCallExpression mc = (MethodCallExpression)expression; methodname = mc.Method.Name; // overwrite methodname // determine which arguments to skip #region LINQMETHODS switch (mc.Method.Name) { case "Aggregate": case "AggregateAsQuery": case "Select": case "LongSelect": case "SelectMany": case "LongSelectMany": case "OfType": case "Where": case "LongWhere": case "First": case "FirstOrDefault": case "FirstAsQuery": case "Single": case "SingleOrDefault": case "SingleAsQuery": case "Last": case "LastOrDefault": case "LastAsQuery": case "Distinct": case "Any": case "AnyAsQuery": case "All": case "AllAsQuery": case "Count": case "CountAsQuery": case "LongCount": case "LongCountAsQuery": case "Sum": case "SumAsQuery": case "Min": case "MinAsQuery": case "Max": case "MaxAsQuery": case "Average": case "AverageAsQuery": case "GroupBy": case "OrderBy": case "OrderByDescending": case "ThenBy": case "ThenByDescending": case "Take": case "TakeWhile": case "LongTakeWhile": case "Skip": case "SkipWhile": case "LongSkipWhile": case "Contains": case "ContainsAsQuery": case "Reverse": case "Merge": case "HashPartition": case "RangePartition": case "Fork": case "ForkChoose": case "AssumeHashPartition": case "AssumeRangePartition": case "AssumeOrderBy": case "ToPartitionedTableLazy": case "AddCacheEntry": case "SlidingWindow": case "SelectWithPartitionIndex": case "ApplyWithPartitionIndex": argsToSkip = 1; break; case "Join": case "GroupJoin": case "Concat": case "MultiConcat": case "Union": case "Intersect": case "Except": case "SequenceEqual": case "SequenceEqualAsQuery": case "Zip": argsToSkip = 2; break; case "Apply": case "ApplyPerPartition": if (mc.Arguments.Count < 3) { argsToSkip = 1; } else { argsToSkip = 2; } break; default: throw DryadLinqException.Create(HpcLinqErrorCode.OperatorNotSupported, String.Format(SR.OperatorNotSupported, mc.Method.Name), expression); } #endregion plan.Append(methodname); plan.Append("("); int argno = 0; foreach (var arg in mc.Arguments) { argno++; if (argno <= argsToSkip) { continue; } if (argno > argsToSkip + 1) { plan.Append(","); } plan.Append(HpcLinqExpression.Summarize(arg)); } plan.AppendLine(")"); } else { // expression is not methodcall plan.Append(methodname); plan.Append("("); if (expression != null) { plan.Append(HpcLinqExpression.Summarize(expression)); } foreach (string e in additional) { plan.Append(","); plan.Append(e); } plan.AppendLine(")"); } } }