internal virtual string Visit(DLinqJoinNode node, CodeMemberMethod vertexMethod, string[] readerNames, string[] writerNames) { return(node.AddVertexCode(vertexMethod, readerNames, writerNames)); }
/// <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, DLinqQueryNode n) { if (n is DLinqTeeNode || n is DLinqOutputNode || n is DLinqDoWhileNode || n is DLinqDummyNode) { return; } else if (n is DLinqInputNode) { plan.AppendLine("Input:"); plan.Append("\t"); n.BuildString(plan); plan.AppendLine(); return; } plan.Append(n.m_vertexEntryMethod); plan.AppendLine(":"); HashSet <DLinqQueryNode> allchildren = new HashSet <DLinqQueryNode>(); if (n is DLinqSuperNode) { DLinqSuperNode sn = n as DLinqSuperNode; List <DLinqQueryNode> tovisit = new List <DLinqQueryNode>(); tovisit.Add(sn.RootNode); while (tovisit.Count > 0) { DLinqQueryNode t = tovisit[0]; tovisit.RemoveAt(0); if (!(t is DLinqSuperNode)) { allchildren.Add(t); } foreach (DLinqQueryNode tc in t.Children) { if (!allchildren.Contains(tc) && sn.Contains(tc)) { tovisit.Add(tc); } } } } else { allchildren.Add(n); } foreach (DLinqQueryNode 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 DLinqMergeNode) { expression = ((DLinqMergeNode)nc).ComparerExpression; } else if (nc is DLinqHashPartitionNode) { DLinqHashPartitionNode hp = (DLinqHashPartitionNode)nc; expression = hp.KeySelectExpression; additional.Add(hp.NumberOfPartitions.ToString()); } else if (nc is DLinqGroupByNode) { DLinqGroupByNode gb = (DLinqGroupByNode)nc; expression = gb.KeySelectExpression; if (gb.ElemSelectExpression != null) { additional.Add(DryadLinqExpression.Summarize(gb.ElemSelectExpression)); } if (gb.ResSelectExpression != null) { additional.Add(DryadLinqExpression.Summarize(gb.ResSelectExpression)); } if (gb.ComparerExpression != null) { additional.Add(DryadLinqExpression.Summarize(gb.ComparerExpression)); } if (gb.SeedExpression != null) { additional.Add(DryadLinqExpression.Summarize(gb.SeedExpression)); } if (gb.AccumulatorExpression != null) { additional.Add(DryadLinqExpression.Summarize(gb.AccumulatorExpression)); } } else if (nc is DLinqOrderByNode) { DLinqOrderByNode ob = (DLinqOrderByNode)nc; expression = ob.KeySelectExpression; if (ob.ComparerExpression != null) { additional.Add(DryadLinqExpression.Summarize(ob.ComparerExpression)); } } else if (nc is DLinqWhereNode) { expression = ((DLinqWhereNode)nc).WhereExpression; } else if (nc is DLinqSelectNode) { DLinqSelectNode s = (DLinqSelectNode)nc; expression = s.SelectExpression; if (s.ResultSelectExpression != null) { additional.Add(DryadLinqExpression.Summarize(s.ResultSelectExpression)); } } else if (nc is DLinqAggregateNode) { DLinqAggregateNode a = (DLinqAggregateNode)nc; expression = a.FuncLambda; if (a.SeedExpression != null) { additional.Add(DryadLinqExpression.Summarize(a.SeedExpression)); } if (a.ResultLambda != null) { additional.Add(DryadLinqExpression.Summarize(a.ResultLambda)); } } else if (nc is DLinqPartitionOpNode) { expression = ((DLinqPartitionOpNode)nc).ControlExpression; } else if (nc is DLinqJoinNode) { DLinqJoinNode j = (DLinqJoinNode)nc; expression = j.OuterKeySelectorExpression; additional.Add(DryadLinqExpression.Summarize(j.InnerKeySelectorExpression)); additional.Add(DryadLinqExpression.Summarize(j.ResultSelectorExpression)); if (j.ComparerExpression != null) { additional.Add(DryadLinqExpression.Summarize(j.ComparerExpression)); } } else if (nc is DLinqDistinctNode) { expression = ((DLinqDistinctNode)nc).ComparerExpression; } else if (nc is DLinqContainsNode) { DLinqContainsNode c = (DLinqContainsNode)nc; expression = c.ValueExpression; if (c.ComparerExpression != null) { additional.Add(DryadLinqExpression.Summarize(c.ComparerExpression)); } } else if (nc is DLinqBasicAggregateNode) { expression = ((DLinqBasicAggregateNode)nc).SelectExpression; } else if (nc is DLinqConcatNode) // nothing to do { } else if (nc is DLinqSetOperationNode) { expression = ((DLinqSetOperationNode)nc).ComparerExpression; } else if (nc is DLinqRangePartitionNode) { DLinqRangePartitionNode r = (DLinqRangePartitionNode)nc; expression = r.CountExpression; // TODO: there's some other possible interesting info } else if (nc is DLinqApplyNode) { expression = ((DLinqApplyNode)nc).LambdaExpression; } else if (nc is DLinqForkNode) { expression = ((DLinqForkNode)nc).ForkLambda; } else if (nc is DLinqTeeNode) { // nothing } else if (nc is DLinqDynamicNode) { // 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 "ApplyWithPartitionIndex": case "DoWhile": 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(DryadLinqErrorCode.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(DryadLinqExpression.Summarize(arg)); } plan.AppendLine(")"); } else { // expression is not methodcall plan.Append(methodname); plan.Append("("); if (expression != null) { plan.Append(DryadLinqExpression.Summarize(expression)); } foreach (string e in additional) { plan.Append(","); plan.Append(e); } plan.AppendLine(")"); } } }