private static bool ProcessOuterApplyOverProject( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node applyNode, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { newNode = applyNode; System.Data.Entity.Core.Query.InternalTrees.Node child1_1 = applyNode.Child1; System.Data.Entity.Core.Query.InternalTrees.Node child1_2 = child1_1.Child1; TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context; Var computedVar = context.Command.GetExtendedNodeInfo(child1_1.Child0).NonNullableDefinitions.First; if (computedVar == null && child1_2.Children.Count == 1 && (child1_2.Child0.Child0.Op.OpType == OpType.InternalConstant || child1_2.Child0.Child0.Op.OpType == OpType.NullSentinel)) { return(false); } Command command = context.Command; System.Data.Entity.Core.Query.InternalTrees.Node node1 = (System.Data.Entity.Core.Query.InternalTrees.Node)null; InternalConstantOp internalConstantOp = (InternalConstantOp)null; ExtendedNodeInfo extendedNodeInfo1 = command.GetExtendedNodeInfo(child1_1.Child0); bool flag = false; foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in child1_2.Children) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(child.Op.OpType == OpType.VarDef, "Expected VarDefOp. Found " + (object)child.Op.OpType + " instead"); VarRefOp op = child.Child0.Op as VarRefOp; if (op == null || !extendedNodeInfo1.Definitions.IsSet(op.Var)) { if (computedVar == null) { internalConstantOp = command.CreateInternalConstantOp(command.IntegerType, (object)1); System.Data.Entity.Core.Query.InternalTrees.Node node2 = command.CreateNode((Op)internalConstantOp); System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode = command.CreateVarDefListNode(node2, out computedVar); ProjectOp projectOp = command.CreateProjectOp(computedVar); projectOp.Outputs.Or(extendedNodeInfo1.Definitions); node1 = command.CreateNode((Op)projectOp, child1_1.Child0, varDefListNode); } System.Data.Entity.Core.Query.InternalTrees.Node node3 = internalConstantOp == null || !internalConstantOp.IsEquivalent(child.Child0.Op) && child.Child0.Op.OpType != OpType.NullSentinel ? transformationRulesContext.BuildNullIfExpression(computedVar, child.Child0) : command.CreateNode((Op)command.CreateVarRefOp(computedVar)); child.Child0 = node3; command.RecomputeNodeInfo(child); flag = true; } } if (flag) { command.RecomputeNodeInfo(child1_2); } applyNode.Child1 = node1 ?? child1_1.Child0; command.RecomputeNodeInfo(applyNode); child1_1.Child0 = applyNode; ExtendedNodeInfo extendedNodeInfo2 = command.GetExtendedNodeInfo(applyNode.Child0); ((ProjectOp)child1_1.Op).Outputs.Or(extendedNodeInfo2.Definitions); newNode = child1_1; return(true); }
public override System.Data.Entity.Core.Query.InternalTrees.Node Visit(ProjectOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { this.PruneVarSet(op.Outputs); this.VisitChildrenReverse(n); if (!op.Outputs.IsEmpty) { return(n); } return(n.Child0); }
private static bool ProcessProjectWithSimpleVarRedefinitions( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node n, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { newNode = n; ProjectOp op1 = (ProjectOp)n.Op; if (n.Child1.Children.Count == 0) { return(false); } TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context; Command command = transformationRulesContext.Command; ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(n); bool flag = false; foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Child1.Children) { System.Data.Entity.Core.Query.InternalTrees.Node child0 = child.Child0; if (child0.Op.OpType == OpType.VarRef) { VarRefOp op2 = (VarRefOp)child0.Op; if (!extendedNodeInfo.ExternalReferences.IsSet(op2.Var)) { flag = true; break; } } } if (!flag) { return(false); } List <System.Data.Entity.Core.Query.InternalTrees.Node> args = new List <System.Data.Entity.Core.Query.InternalTrees.Node>(); foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Child1.Children) { VarDefOp op2 = (VarDefOp)child.Op; VarRefOp op3 = child.Child0.Op as VarRefOp; if (op3 != null && !extendedNodeInfo.ExternalReferences.IsSet(op3.Var)) { op1.Outputs.Clear(op2.Var); op1.Outputs.Set(op3.Var); transformationRulesContext.AddVarMapping(op2.Var, op3.Var); } else { args.Add(child); } } System.Data.Entity.Core.Query.InternalTrees.Node node = command.CreateNode((Op)command.CreateVarDefListOp(), args); n.Child1 = node; return(true); }
/// <summary> /// ExistsOp /// /// The child must be a ProjectOp - with exactly 1 var. Mark it as referenced /// </summary> /// <param name="op">the ExistsOp</param> /// <param name="n">the input node</param> /// <returns></returns> public override Node Visit(ExistsOp op, Node n) { // Ensure that the child is a projectOp, and has exactly one var. Mark // that var as referenced always ProjectOp projectOp = (ProjectOp)n.Child0.Op; //It is enougth to reference the first output, this usually is a simple constant AddReference(projectOp.Outputs.First); VisitChildren(n); return(n); }
/// <summary> /// ProjectOp /// We visit the projections first (the VarDefListOp child), and then /// the input (the RelOp child) - this reverse order is necessary, since /// the projections need to be visited to determine if anything from /// the input is really needed. /// The VarDefListOp child will handle the removal of unnecessary VarDefOps. /// On the way out, we then update our "Vars" property to reflect the Vars /// that have been eliminated /// </summary> /// <param name="op"> the ProjectOp </param> /// <param name="n"> the current node </param> /// <returns> modified subtree </returns> public override Node Visit(ProjectOp op, Node n) { // Update my Vars - to remove "unreferenced" vars. Do this before visiting // the children - the outputs of the ProjectOp are only consumed by upstream // consumers, and if a Var has not yet been referenced, its not needed upstream PruneVarSet(op.Outputs); // first visit the computed expressions, then visit the input relop VisitChildrenReverse(n); // If there are no Vars left, then simply return my child - otherwise, // return the current node return(op.Outputs.IsEmpty ? n.Child0 : n); }
public override void Visit(ProjectOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { this.VisitChildren(n); ExtendedNodeInfo extendedNodeInfo = n.Child0.GetExtendedNodeInfo(this.m_command); if (!extendedNodeInfo.Keys.NoKeys) { VarVec varVec = this.m_command.CreateVarVec(op.Outputs); Dictionary <Var, Var> varRemappings = NodeInfoVisitor.ComputeVarRemappings(n.Child1); VarVec other = extendedNodeInfo.Keys.KeyVars.Remap(varRemappings); varVec.Or(other); op.Outputs.InitFrom(varVec); } this.m_command.RecomputeNodeInfo(n); }
private static bool ProcessProjectOverProject( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node projectNode, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { newNode = projectNode; ProjectOp op1 = (ProjectOp)projectNode.Op; System.Data.Entity.Core.Query.InternalTrees.Node child1 = projectNode.Child1; System.Data.Entity.Core.Query.InternalTrees.Node child0 = projectNode.Child0; ProjectOp op2 = (ProjectOp)child0.Op; TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context; Dictionary <Var, int> varRefMap = new Dictionary <Var, int>(); foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in child1.Children) { if (!transformationRulesContext.IsScalarOpTree(child.Child0, varRefMap)) { return(false); } } Dictionary <Var, System.Data.Entity.Core.Query.InternalTrees.Node> varMap = transformationRulesContext.GetVarMap(child0.Child1, varRefMap); if (varMap == null) { return(false); } System.Data.Entity.Core.Query.InternalTrees.Node node = transformationRulesContext.Command.CreateNode((Op)transformationRulesContext.Command.CreateVarDefListOp()); foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in child1.Children) { child.Child0 = transformationRulesContext.ReMap(child.Child0, varMap); transformationRulesContext.Command.RecomputeNodeInfo(child); node.Children.Add(child); } ExtendedNodeInfo extendedNodeInfo = transformationRulesContext.Command.GetExtendedNodeInfo(projectNode); foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in child0.Child1.Children) { VarDefOp op3 = (VarDefOp)child.Op; if (extendedNodeInfo.Definitions.IsSet(op3.Var)) { node.Children.Add(child); } } projectNode.Child0 = child0.Child0; projectNode.Child1 = node; return(true); }
/// <summary> /// Pulls up keys for a ProjectOp. First visits its children to pull /// up its keys; then identifies any keys from the input that it may have /// projected out - and adds them to the output list of vars /// </summary> /// <param name="op">Current ProjectOp</param> /// <param name="n">Current subtree</param> public override void Visit(ProjectOp op, Node n) { VisitChildren(n); ExtendedNodeInfo childNodeInfo = n.Child0.GetExtendedNodeInfo(m_command); if (!childNodeInfo.Keys.NoKeys) { VarVec outputVars = m_command.CreateVarVec(op.Outputs); // NOTE: This code appears in NodeInfoVisitor as well. Try to see if we // can share this somehow. Dictionary <Var, Var> varRenameMap = NodeInfoVisitor.ComputeVarRemappings(n.Child1); VarVec mappedKeyVec = childNodeInfo.Keys.KeyVars.Remap(varRenameMap); outputVars.Or(mappedKeyVec); op.Outputs.InitFrom(outputVars); } m_command.RecomputeNodeInfo(n); }
private static bool ProcessGroupByOpWithNoAggregates( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node n, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { Command command = context.Command; GroupByOp op = (GroupByOp)n.Op; ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(n.Child0); ProjectOp projectOp = command.CreateProjectOp(op.Keys); VarDefListOp varDefListOp = command.CreateVarDefListOp(); command.CreateNode((Op)varDefListOp); newNode = command.CreateNode((Op)projectOp, n.Child0, n.Child1); if (extendedNodeInfo.Keys.NoKeys || !op.Keys.Subsumes(extendedNodeInfo.Keys.KeyVars)) { newNode = command.CreateNode((Op)command.CreateDistinctOp(command.CreateVarVec(op.Keys)), newNode); } return(true); }
private static bool ProcessDistinctOpOfKeys( RuleProcessingContext context, Node n, out Node newNode) { Command command = context.Command; ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(n.Child0); DistinctOp op = (DistinctOp)n.Op; if (!extendedNodeInfo.Keys.NoKeys && op.Keys.Subsumes(extendedNodeInfo.Keys.KeyVars)) { ProjectOp projectOp = command.CreateProjectOp(op.Keys); VarDefListOp varDefListOp = command.CreateVarDefListOp(); Node node = command.CreateNode((Op)varDefListOp); newNode = command.CreateNode((Op)projectOp, n.Child0, node); return(true); } newNode = n; return(false); }
private static bool ProcessCrossApplyOverProject( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node applyNode, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { newNode = applyNode; System.Data.Entity.Core.Query.InternalTrees.Node child1 = applyNode.Child1; ProjectOp op = (ProjectOp)child1.Op; Command command = context.Command; ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(applyNode); VarVec varVec = command.CreateVarVec(op.Outputs); varVec.Or(extendedNodeInfo.Definitions); op.Outputs.InitFrom(varVec); applyNode.Child1 = child1.Child0; context.Command.RecomputeNodeInfo(applyNode); child1.Child0 = applyNode; newNode = child1; return(true); }
internal System.Data.Entity.Core.Query.InternalTrees.Node GetInternalTree( Command targetIqtCommand, IList <System.Data.Entity.Core.Query.InternalTrees.Node> targetIqtArguments) { if (this.m_internalTreeNode == null) { DiscriminatorMap discriminatorMap; Command command = ITreeGenerator.Generate(this.GenerateFunctionView(out discriminatorMap), discriminatorMap); System.Data.Entity.Core.Query.InternalTrees.Node root = command.Root; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(root.Op.OpType == OpType.PhysicalProject, "Expected a physical projectOp at the root of the tree - found " + (object)root.Op.OpType); PhysicalProjectOp op = (PhysicalProjectOp)root.Op; System.Data.Entity.Core.Query.InternalTrees.Node child0 = root.Child0; command.DisableVarVecEnumCaching(); System.Data.Entity.Core.Query.InternalTrees.Node relOpNode = child0; Var computedVar = op.Outputs[0]; if (!Command.EqualTypes(op.ColumnMap.Type, this.FunctionImport.ReturnParameter.TypeUsage)) { TypeUsage typeUsage = ((CollectionType)this.FunctionImport.ReturnParameter.TypeUsage.EdmType).TypeUsage; System.Data.Entity.Core.Query.InternalTrees.Node node1 = command.CreateNode((Op)command.CreateVarRefOp(computedVar)); System.Data.Entity.Core.Query.InternalTrees.Node node2 = command.CreateNode((Op)command.CreateSoftCastOp(typeUsage), node1); System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode = command.CreateVarDefListNode(node2, out computedVar); ProjectOp projectOp = command.CreateProjectOp(computedVar); relOpNode = command.CreateNode((Op)projectOp, relOpNode, varDefListNode); } this.m_internalTreeNode = command.BuildCollect(relOpNode, computedVar); } Dictionary <string, System.Data.Entity.Core.Query.InternalTrees.Node> viewArguments = new Dictionary <string, System.Data.Entity.Core.Query.InternalTrees.Node>(this.m_commandParameters.Length); for (int index = 0; index < this.m_commandParameters.Length; ++index) { DbParameterReferenceExpression commandParameter = this.m_commandParameters[index]; System.Data.Entity.Core.Query.InternalTrees.Node node = targetIqtArguments[index]; if (TypeSemantics.IsEnumerationType(node.Op.Type)) { node = targetIqtCommand.CreateNode((Op)targetIqtCommand.CreateSoftCastOp(TypeHelpers.CreateEnumUnderlyingTypeUsage(node.Op.Type)), node); } viewArguments.Add(commandParameter.ParameterName, node); } return(FunctionImportMappingComposable.FunctionViewOpCopier.Copy(targetIqtCommand, this.m_internalTreeNode, viewArguments)); }
public override void Visit(ProjectOp op, Node n) { VisitRelOpDefault(op, n); AssertRelOpOrPhysicalOp(n.Child0.Op); AssertOpType(n.Child1.Op, OpType.VarDefList); }
private static bool ProcessProjectOpWithNullSentinel( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node n, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { newNode = n; ProjectOp op = (ProjectOp)n.Op; if (n.Child1.Children.Where <System.Data.Entity.Core.Query.InternalTrees.Node>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, bool>)(c => c.Child0.Op.OpType == OpType.NullSentinel)).Count <System.Data.Entity.Core.Query.InternalTrees.Node>() == 0) { return(false); } TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context; Command command = transformationRulesContext.Command; ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(n.Child0); bool flag1 = false; bool nullSentinelValue = transformationRulesContext.CanChangeNullSentinelValue; Var int32Var; if (!nullSentinelValue || !TransformationRulesContext.TryGetInt32Var((IEnumerable <Var>)extendedNodeInfo.NonNullableDefinitions, out int32Var)) { flag1 = true; if (!nullSentinelValue || !TransformationRulesContext.TryGetInt32Var(n.Child1.Children.Where <System.Data.Entity.Core.Query.InternalTrees.Node>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, bool>)(child => { if (child.Child0.Op.OpType != OpType.Constant) { return(child.Child0.Op.OpType == OpType.InternalConstant); } return(true); })).Select <System.Data.Entity.Core.Query.InternalTrees.Node, Var>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, Var>)(child => ((VarDefOp)child.Op).Var)), out int32Var)) { int32Var = n.Child1.Children.Where <System.Data.Entity.Core.Query.InternalTrees.Node>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, bool>)(child => child.Child0.Op.OpType == OpType.NullSentinel)).Select <System.Data.Entity.Core.Query.InternalTrees.Node, Var>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, Var>)(child => ((VarDefOp)child.Op).Var)).FirstOrDefault <Var>(); if (int32Var == null) { return(false); } } } bool flag2 = false; for (int index = n.Child1.Children.Count - 1; index >= 0; --index) { System.Data.Entity.Core.Query.InternalTrees.Node child = n.Child1.Children[index]; if (child.Child0.Op.OpType == OpType.NullSentinel) { if (!flag1) { VarRefOp varRefOp = command.CreateVarRefOp(int32Var); child.Child0 = command.CreateNode((Op)varRefOp); command.RecomputeNodeInfo(child); flag2 = true; } else if (!int32Var.Equals((object)((VarDefOp)child.Op).Var)) { op.Outputs.Clear(((VarDefOp)child.Op).Var); n.Child1.Children.RemoveAt(index); transformationRulesContext.AddVarMapping(((VarDefOp)child.Op).Var, int32Var); flag2 = true; } } } if (flag2) { command.RecomputeNodeInfo(n.Child1); } return(flag2); }
private static bool ProcessJoinOverProject( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node joinNode, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { newNode = joinNode; TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context; Command command = transformationRulesContext.Command; System.Data.Entity.Core.Query.InternalTrees.Node node1 = joinNode.HasChild2 ? joinNode.Child2 : (System.Data.Entity.Core.Query.InternalTrees.Node)null; Dictionary <Var, int> varRefMap = new Dictionary <Var, int>(); if (node1 != null && !transformationRulesContext.IsScalarOpTree(node1, varRefMap)) { return(false); } VarVec varVec1 = command.CreateVarVec(); List <System.Data.Entity.Core.Query.InternalTrees.Node> args = new List <System.Data.Entity.Core.Query.InternalTrees.Node>(); if (joinNode.Op.OpType != OpType.LeftOuterJoin && joinNode.Child0.Op.OpType == OpType.Project && joinNode.Child1.Op.OpType == OpType.Project) { ProjectOp op1 = (ProjectOp)joinNode.Child0.Op; ProjectOp op2 = (ProjectOp)joinNode.Child1.Op; Dictionary <Var, System.Data.Entity.Core.Query.InternalTrees.Node> varMap1 = transformationRulesContext.GetVarMap(joinNode.Child0.Child1, varRefMap); Dictionary <Var, System.Data.Entity.Core.Query.InternalTrees.Node> varMap2 = transformationRulesContext.GetVarMap(joinNode.Child1.Child1, varRefMap); if (varMap1 == null || varMap2 == null) { return(false); } System.Data.Entity.Core.Query.InternalTrees.Node node2; if (node1 != null) { System.Data.Entity.Core.Query.InternalTrees.Node node3 = transformationRulesContext.ReMap(node1, varMap1); System.Data.Entity.Core.Query.InternalTrees.Node node4 = transformationRulesContext.ReMap(node3, varMap2); node2 = context.Command.CreateNode(joinNode.Op, joinNode.Child0.Child0, joinNode.Child1.Child0, node4); } else { node2 = context.Command.CreateNode(joinNode.Op, joinNode.Child0.Child0, joinNode.Child1.Child0); } varVec1.InitFrom(op1.Outputs); foreach (Var output in op2.Outputs) { varVec1.Set(output); } ProjectOp projectOp = command.CreateProjectOp(varVec1); args.AddRange((IEnumerable <System.Data.Entity.Core.Query.InternalTrees.Node>)joinNode.Child0.Child1.Children); args.AddRange((IEnumerable <System.Data.Entity.Core.Query.InternalTrees.Node>)joinNode.Child1.Child1.Children); System.Data.Entity.Core.Query.InternalTrees.Node node5 = command.CreateNode((Op)command.CreateVarDefListOp(), args); System.Data.Entity.Core.Query.InternalTrees.Node node6 = command.CreateNode((Op)projectOp, node2, node5); newNode = node6; return(true); } int index1; int index2; if (joinNode.Child0.Op.OpType == OpType.Project) { index1 = 0; index2 = 1; } else { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(joinNode.Op.OpType != OpType.LeftOuterJoin, "unexpected non-LeftOuterJoin"); index1 = 1; index2 = 0; } System.Data.Entity.Core.Query.InternalTrees.Node child = joinNode.Children[index1]; ProjectOp op = child.Op as ProjectOp; Dictionary <Var, System.Data.Entity.Core.Query.InternalTrees.Node> varMap = transformationRulesContext.GetVarMap(child.Child1, varRefMap); if (varMap == null) { return(false); } ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(joinNode.Children[index2]); VarVec varVec2 = command.CreateVarVec(op.Outputs); varVec2.Or(extendedNodeInfo.Definitions); op.Outputs.InitFrom(varVec2); if (node1 != null) { System.Data.Entity.Core.Query.InternalTrees.Node node2 = transformationRulesContext.ReMap(node1, varMap); joinNode.Child2 = node2; } joinNode.Children[index1] = child.Child0; context.Command.RecomputeNodeInfo(joinNode); newNode = context.Command.CreateNode((Op)op, joinNode, child.Child1); return(true); }
public override void Visit(ProjectOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { this.VisitRelOpDefault((RelOp)op, n); this.Map(op.Outputs); }
public override void Visit(ProjectOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { this.VisitNode(n.Child1); this.VisitNode(n.Child0); }
private static bool ProcessOuterApplyOverDummyProjectOverFilter( RuleProcessingContext context, System.Data.Entity.Core.Query.InternalTrees.Node applyNode, out System.Data.Entity.Core.Query.InternalTrees.Node newNode) { newNode = applyNode; System.Data.Entity.Core.Query.InternalTrees.Node child1 = applyNode.Child1; ProjectOp op = (ProjectOp)child1.Op; System.Data.Entity.Core.Query.InternalTrees.Node child0_1 = child1.Child0; System.Data.Entity.Core.Query.InternalTrees.Node child0_2 = child0_1.Child0; Command command = context.Command; ExtendedNodeInfo extendedNodeInfo1 = command.GetExtendedNodeInfo(child0_2); ExtendedNodeInfo extendedNodeInfo2 = command.GetExtendedNodeInfo(applyNode.Child0); if (op.Outputs.Overlaps(extendedNodeInfo2.Definitions) || extendedNodeInfo1.ExternalReferences.Overlaps(extendedNodeInfo2.Definitions)) { return(false); } bool flag1 = false; TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context; Var int32Var; bool flag2; if (TransformationRulesContext.TryGetInt32Var((IEnumerable <Var>)extendedNodeInfo1.NonNullableDefinitions, out int32Var)) { flag2 = true; } else { int32Var = extendedNodeInfo1.NonNullableDefinitions.First; flag2 = false; } System.Data.Entity.Core.Query.InternalTrees.Node node1; if (int32Var != null) { flag1 = true; System.Data.Entity.Core.Query.InternalTrees.Node child0_3 = child1.Child1.Child0; child0_3.Child0 = child0_3.Child0.Op.OpType != OpType.NullSentinel || !flag2 || !transformationRulesContext.CanChangeNullSentinelValue ? transformationRulesContext.BuildNullIfExpression(int32Var, child0_3.Child0) : context.Command.CreateNode((Op)context.Command.CreateVarRefOp(int32Var)); command.RecomputeNodeInfo(child0_3); command.RecomputeNodeInfo(child1.Child1); node1 = child0_2; } else { node1 = child1; foreach (Var externalReference in command.GetNodeInfo(child0_1.Child1).ExternalReferences) { if (extendedNodeInfo1.Definitions.IsSet(externalReference)) { op.Outputs.Set(externalReference); } } child1.Child0 = child0_2; } context.Command.RecomputeNodeInfo(child1); System.Data.Entity.Core.Query.InternalTrees.Node node2 = command.CreateNode((Op)command.CreateLeftOuterJoinOp(), applyNode.Child0, node1, child0_1.Child1); if (flag1) { ExtendedNodeInfo extendedNodeInfo3 = command.GetExtendedNodeInfo(node2); child1.Child0 = node2; op.Outputs.Or(extendedNodeInfo3.Definitions); newNode = child1; } else { newNode = node2; } return(true); }
internal Node GetInternalTree(Command targetIqtCommand, IList <Node> targetIqtArguments) { if (m_internalTreeNode == null) { var viewGenErrors = new List <EdmSchemaError>(); DiscriminatorMap discriminatorMap; DbQueryCommandTree tree = GenerateFunctionView(viewGenErrors, out discriminatorMap); if (viewGenErrors.Count > 0) { throw new MappingException(Helper.CombineErrorMessage(viewGenErrors)); } Debug.Assert(tree != null, "tree != null"); // Convert this into an ITree first Command itree = ITreeGenerator.Generate(tree, discriminatorMap); var rootProject = itree.Root; // PhysicalProject(RelInput) PlanCompiler.Assert(rootProject.Op.OpType == OpType.PhysicalProject, "Expected a physical projectOp at the root of the tree - found " + rootProject.Op.OpType); var rootProjectOp = (PhysicalProjectOp)rootProject.Op; Debug.Assert(rootProjectOp.Outputs.Count == 1, "rootProjectOp.Outputs.Count == 1"); var rootInput = rootProject.Child0; // the RelInput in PhysicalProject(RelInput) // #554756: VarVec enumerators are not cached on the shared Command instance. itree.DisableVarVecEnumCaching(); // Function import returns a collection, so convert it to a scalar by wrapping into CollectOp. Node relNode = rootInput; Var relVar = rootProjectOp.Outputs[0]; // ProjectOp does not implement Type property, so get the type from the column map. TypeUsage functionViewType = rootProjectOp.ColumnMap.Type; if (!Command.EqualTypes(functionViewType, this.FunctionImport.ReturnParameter.TypeUsage)) { Debug.Assert(TypeSemantics.IsPromotableTo(functionViewType, this.FunctionImport.ReturnParameter.TypeUsage), "Mapping expression result type must be promotable to the c-space function return type."); // Build "relNode = Project(relNode, SoftCast(relVar))" CollectionType expectedCollectionType = (CollectionType)this.FunctionImport.ReturnParameter.TypeUsage.EdmType; var expectedElementType = expectedCollectionType.TypeUsage; Node varRefNode = itree.CreateNode(itree.CreateVarRefOp(relVar)); Node castNode = itree.CreateNode(itree.CreateSoftCastOp(expectedElementType), varRefNode); Node varDefListNode = itree.CreateVarDefListNode(castNode, out relVar); ProjectOp projectOp = itree.CreateProjectOp(relVar); relNode = itree.CreateNode(projectOp, relNode, varDefListNode); } // Build "Collect(PhysicalProject(relNode)) m_internalTreeNode = itree.BuildCollect(relNode, relVar); } Debug.Assert(m_internalTreeNode != null, "m_internalTreeNode != null"); // Prepare argument replacement dictionary Debug.Assert(m_commandParameters.Length == targetIqtArguments.Count, "m_commandParameters.Length == targetIqtArguments.Count"); Dictionary <string, Node> viewArguments = new Dictionary <string, Node>(m_commandParameters.Length); for (int i = 0; i < m_commandParameters.Length; ++i) { var commandParam = (DbParameterReferenceExpression)m_commandParameters[i]; var argumentNode = targetIqtArguments[i]; // If function import parameter is of enum type, the argument value for it will be of enum type. We however have // converted enum types to underlying types for m_commandParameters. So we now need to softcast the argument // expression to the underlying type as well. if (TypeSemantics.IsEnumerationType(argumentNode.Op.Type)) { argumentNode = targetIqtCommand.CreateNode( targetIqtCommand.CreateSoftCastOp(TypeHelpers.CreateEnumUnderlyingTypeUsage(argumentNode.Op.Type)), argumentNode); } Debug.Assert(TypeSemantics.IsPromotableTo(argumentNode.Op.Type, commandParam.ResultType), "Argument type must be promotable to parameter type."); viewArguments.Add(commandParam.ParameterName, argumentNode); } return(FunctionViewOpCopier.Copy(targetIqtCommand, m_internalTreeNode, viewArguments)); }
public override void Visit(ProjectOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Outputs); }
/// <summary> /// Visitor pattern method for ProjectOp /// </summary> /// <param name="op"> The ProjectOp being visited </param> /// <param name="n"> The Node that references the Op </param> public virtual void Visit(ProjectOp op, Node n) { VisitRelOpDefault(op, n); }
// <summary> // ProjectOp // </summary> public override int Visit(ProjectOp op, Node n) { return(op.Outputs.Count); }
/// <summary> /// ProjectOp handling /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> public override void Visit(ProjectOp op, Node n) { VisitNode(n.Child1); // visit projections first VisitNode(n.Child0); // then visit the relop input }
/// <summary> /// Try to push the given function aggregate candidate to the corresponding group into node. /// The candidate can be pushed if all ancestors of the group into node up to the least common /// ancestor between the group into node and the function aggregate have one of the following node op types: /// Project /// Filter /// ConstraintSortOp /// </summary> /// <param name="command"></param> /// <param name="candidate"></param> /// <param name="groupAggregateVarInfo"></param> /// <param name="m_childToParent"></param> private void TryProcessCandidate( KeyValuePair <Node, Node> candidate, GroupAggregateVarInfo groupAggregateVarInfo) { IList <Node> functionAncestors; IList <Node> groupByAncestors; Node definingGroupNode = groupAggregateVarInfo.DefiningGroupNode; FindPathsToLeastCommonAncestor(candidate.Key, definingGroupNode, out functionAncestors, out groupByAncestors); //Check whether all ancestors of the GroupByInto node are of type that we support propagating through if (!AreAllNodesSupportedForPropagation(groupByAncestors)) { return; } //Add the function to the group by node GroupByIntoOp definingGroupOp = (GroupByIntoOp)definingGroupNode.Op; PlanCompiler.Assert(definingGroupOp.Inputs.Count == 1, "There should be one input var to GroupByInto at this stage"); Var inputVar = definingGroupOp.Inputs.First; FunctionOp functionOp = (FunctionOp)candidate.Key.Op; // // Remap the template from referencing the groupAggregate var to reference the input to // the group by into // Node argumentNode = OpCopier.Copy(m_command, candidate.Value); Dictionary <Var, Var> dictionary = new Dictionary <Var, Var>(1); dictionary.Add(groupAggregateVarInfo.GroupAggregateVar, inputVar); VarRemapper remapper = new VarRemapper(m_command, dictionary); remapper.RemapSubtree(argumentNode); Node newFunctionDefiningNode = m_command.CreateNode( m_command.CreateAggregateOp(functionOp.Function, false), argumentNode); Var newFunctionVar; Node varDefNode = m_command.CreateVarDefNode(newFunctionDefiningNode, out newFunctionVar); // Add the new aggregate to the list of aggregates definingGroupNode.Child2.Children.Add(varDefNode); GroupByIntoOp groupByOp = (GroupByIntoOp)definingGroupNode.Op; groupByOp.Outputs.Set(newFunctionVar); //Propagate the new var throught the ancestors of the GroupByInto for (int i = 0; i < groupByAncestors.Count; i++) { Node groupByAncestor = groupByAncestors[i]; if (groupByAncestor.Op.OpType == OpType.Project) { ProjectOp ancestorProjectOp = (ProjectOp)groupByAncestor.Op; ancestorProjectOp.Outputs.Set(newFunctionVar); } } //Update the functionNode candidate.Key.Op = m_command.CreateVarRefOp(newFunctionVar); candidate.Key.Children.Clear(); }
// <summary> // ProjectOp // </summary> // <remarks> // If after visiting the children, the ProjectOp's input is a SortOp, swap the ProjectOp and the SortOp, // to allow the SortOp to bubble up and be honored. This may only occur if the original input to the // ProjectOp was an UnnestOp. // There are three cases to handle in ProjectOp: // (1) The input is not a NestOp; but the ProjectOp locally defines some Vars // as collections: // ProjectOp(X,{a,CollectOp(PhysicalProjectOp(Y)),b,...}) ==> MsnOp(ProjectOp'(X,{a,b,...}),Y) // ProjectOp(X,{a,VarRef(ref-to-collect-var-Y),b,...}) ==> MsnOp(ProjectOp'(X,{a,b,...}),copy-of-Y) // Where: // ProjectOp' is ProjectOp less any vars that were collection vars, plus // any additional Vars needed by the collection. // (2) The input is a NestOp, but the ProjectOp does not local define some Vars // as collections: // ProjectOp(MsnOp(X,Y,...)) => MsnOp'(ProjectOp'(X),Y,...) // Where: // ProjectOp' is ProjectOp plus any additional Vars needed by NestOp // (see NestOp.Outputs – except the collection vars) // MsnOp' should be MsnOp. Additionally, its Outputs should be enhanced // to include any Vars produced by the ProjectOp // (3) The combination of both (1) and (2) -- both the vars define a collection, // and the input is also a nestOp. we handle this by first processing Case1, // then processing Case2. // </remarks> public override Node Visit(ProjectOp op, Node n) { #if DEBUG var input = Dump.ToXml(n); #endif //DEBUG // First, visit my children VisitChildren(n); m_varRemapper.RemapNode(n); Node newNode; // If the ProjectOp's input is a SortOp, swap the ProjectOp and the SortOp, // to allow the SortOp to buble up and be honored. This may only occur if the original input to the // ProjectOp was an UnnestOp (or a Project over a Unnest Op). if (n.Child0.Op.OpType == OpType.Sort) { var sortNode = n.Child0; foreach (var key in ((SortOp)sortNode.Op).Keys) { if (!Command.GetExtendedNodeInfo(sortNode).ExternalReferences.IsSet(key.Var)) { op.Outputs.Set(key.Var); } } n.Child0 = sortNode.Child0; Command.RecomputeNodeInfo(n); sortNode.Child0 = HandleProjectNode(n); Command.RecomputeNodeInfo(sortNode); newNode = sortNode; } else { newNode = HandleProjectNode(n); } #if DEBUG var size = input.Length; // GC.KeepAlive makes FxCop Grumpy. var output = Dump.ToXml(newNode); #endif //DEBUG return newNode; }
// <summary> // Copies a ProjectOp // </summary> // <param name="op"> The Op to Copy </param> // <param name="n"> The Node that references the Op </param> // <returns> A copy of the original Node that references a copy of the original Op </returns> public override Node Visit(ProjectOp op, Node n) { // Visit the Node's children and map their Vars var children = ProcessChildren(n); // Copy the ProjectOp's VarSet var newVarSet = Copy(op.Outputs); // Create a new ProjectOp based on the copied VarSet var newProject = m_destCmd.CreateProjectOp(newVarSet); // Return a new Node that references the copied ProjectOp and has the copied child Nodes as its children return m_destCmd.CreateNode(newProject, children); }
public override Node Visit(ProjectOp op, Node n) { PlanCompiler.Assert(n.HasChild0, "projectOp without input?"); if (OpType.Sort == n.Child0.Op.OpType || OpType.ConstrainedSort == n.Child0.Op.OpType) { var sort = (SortBaseOp)n.Child0.Op; // Don't pullup the sort if it doesn't have any keys. // An example of such sort is "ctx.Products.Take(1)". if (sort.Keys.Count > 0) { IList<Node> sortChildren = new List<Node>(); sortChildren.Add(n); //A ConstrainedSort has two other children besides the input and it needs to keep them. for (var i = 1; i < n.Child0.Children.Count; i++) { sortChildren.Add(n.Child0.Children[i]); } // Replace the ProjectOp input (currently the Sort node) with the input to the Sort. n.Child0 = n.Child0.Child0; // Vars produced by the Sort input and used as SortKeys should be considered outputs // of the ProjectOp that now operates over what was the Sort input. foreach (var key in sort.Keys) { op.Outputs.Set(key.Var); } // Finally, pull the Sort over the Project by creating a new Sort node with the original // Sort as its Op and the Project node as its only child. This is sufficient because // the ITreeGenerator ensures that the SortOp does not have any local VarDefs. return VisitNode(m_command.CreateNode(sort, sortChildren)); } } // perform default processing var newNode = VisitRelOpDefault(op, n); return newNode; }
/// <summary> /// Pulls up keys for a ProjectOp. First visits its children to pull /// up its keys; then identifies any keys from the input that it may have /// projected out - and adds them to the output list of vars /// </summary> /// <param name="op"> Current ProjectOp </param> /// <param name="n"> Current subtree </param> public override void Visit(ProjectOp op, Node n) { VisitChildren(n); var childNodeInfo = n.Child0.GetExtendedNodeInfo(m_command); if (!childNodeInfo.Keys.NoKeys) { var outputVars = m_command.CreateVarVec(op.Outputs); // NOTE: This code appears in NodeInfoVisitor as well. Try to see if we // can share this somehow. var varRenameMap = NodeInfoVisitor.ComputeVarRemappings(n.Child1); var mappedKeyVec = childNodeInfo.Keys.KeyVars.Remap(varRenameMap); outputVars.Or(mappedKeyVec); op.Outputs.InitFrom(outputVars); } m_command.RecomputeNodeInfo(n); }
/// <summary> /// ProjectOp /// The computedVars (the VarDefList) are processed via the VisitChildren() call /// We then try to update the "Vars" property to flatten out any structured /// type Vars - if a new VarSet is produced, then the ProjectOp is cloned /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> /// <returns> new subtree </returns> public override Node Visit(ProjectOp op, Node n) { VisitChildren(n); // update the output Vars with the right set of information var newVars = FlattenVarSet(op.Outputs); if (op.Outputs != newVars) { // If the set of vars is empty, that means we didn;t need any of the Vars if (newVars.IsEmpty) { return n.Child0; } n.Op = m_command.CreateProjectOp(newVars); } return n; }
/// <summary> /// ProjectOp handling /// </summary> /// <param name="op"></param> /// <param name="n"></param> public override void Visit(ProjectOp op, Node n) { VisitNode(n.Child1); // visit projections first VisitNode(n.Child0); // then visit the relop input }
public override int Visit(ProjectOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { return(op.Outputs.Count); }