private void RemapVarMapKey(VarMap varMap, Var newVar) { Var var = varMap[this.m_oldVar]; varMap.Remove(this.m_oldVar); varMap.Add(newVar, var); }
// <summary> // Replaces the entry in the varMap in which m_oldVar is a key // with an entry in which newVAr is the key and the value remains the same. // </summary> private void RemapVarMapKey(VarMap varMap, Var newVar) { var value = varMap[m_oldVar]; varMap.Remove(m_oldVar); varMap.Add(newVar, value); }
private void Map(VarMap varMap) { VarMap varMap1 = new VarMap(); foreach (KeyValuePair <Var, Var> var1 in (Dictionary <Var, Var>)varMap) { Var var2 = this.Map(var1.Value); varMap1.Add(var1.Key, var2); } varMap.Clear(); foreach (KeyValuePair <Var, Var> keyValuePair in (Dictionary <Var, Var>)varMap1) { varMap.Add(keyValuePair.Key, keyValuePair.Value); } }
private void Map(VarMap varMap) { var newVarMap = new VarMap(); foreach (var kv in varMap) { var newVar = Map(kv.Value); newVarMap.Add(kv.Key, newVar); } varMap.Clear(); foreach (var kv in newVarMap) { varMap.Add(kv.Key, kv.Value); } }
private void Map(VarMap varMap) { VarMap newVarMap = new VarMap(); foreach (KeyValuePair <Var, Var> kv in varMap) { Var newVar = Map(kv.Value); newVarMap.Add(kv.Key, newVar); } varMap.Clear(); foreach (KeyValuePair <Var, Var> kv in newVarMap) { varMap.Add(kv.Key, kv.Value); } }
// <summary> // Convert a SingleStreamNestOp into a massive UnionAllOp // </summary> private Node BuildUnionAllSubqueryForNestOp( NestBaseOp nestOp, Node nestNode, VarList drivingNodeVars, VarList discriminatorVarList, out Var discriminatorVar, out List<Dictionary<Var, Var>> varMapList) { var drivingNode = nestNode.Child0; // For each of the NESTED collections... Node unionAllNode = null; VarList unionAllOutputs = null; for (var i = 1; i < nestNode.Children.Count; i++) { // Ensure we only use the driving collection tree once, so other // transformations do not unintentionally change more than one path. // To prevent nodes in the tree from being used in multiple paths, // we copy the driving input on successive nodes. VarList newDrivingNodeVars; Node newDrivingNode; VarList newFlattenedElementVars; Op op; if (i > 1) { newDrivingNode = OpCopier.Copy(Command, drivingNode, drivingNodeVars, out newDrivingNodeVars); // // Bug 450245: If we copied the driver node, then references to driver node vars // from the collection subquery must be patched up // var varRemapper = new VarRemapper(Command); for (var j = 0; j < drivingNodeVars.Count; j++) { varRemapper.AddMapping(drivingNodeVars[j], newDrivingNodeVars[j]); } // Remap all references in the current subquery varRemapper.RemapSubtree(nestNode.Children[i]); // Bug 479183: Remap the flattened element vars newFlattenedElementVars = varRemapper.RemapVarList(nestOp.CollectionInfo[i - 1].FlattenedElementVars); // Create a cross apply for all but the first collection op = Command.CreateCrossApplyOp(); } else { newDrivingNode = drivingNode; newDrivingNodeVars = drivingNodeVars; newFlattenedElementVars = nestOp.CollectionInfo[i - 1].FlattenedElementVars; // Create an outer apply for the first collection, // that way we ensure at least one row for each row in the driver node. op = Command.CreateOuterApplyOp(); } // Create an outer apply with the driver node and the nested collection. var applyNode = Command.CreateNode(op, newDrivingNode, nestNode.Children[i]); // Now create a ProjectOp that augments the output from the OuterApplyOp // with nulls for each column from other collections // Build the VarDefList (the list of vars) for the Project, starting // with the collection discriminator var var varDefListChildren = new List<Node>(); var projectOutputs = Command.CreateVarList(); // Add the collection discriminator var to the output. projectOutputs.Add(discriminatorVarList[i]); // Add all columns from the driving node projectOutputs.AddRange(newDrivingNodeVars); // Add all the vars from all the nested collections; for (var j = 1; j < nestNode.Children.Count; j++) { var otherCollectionInfo = nestOp.CollectionInfo[j - 1]; // For the current nested collection, we just pick the var that's // coming from there and don't need have a new var defined, but for // the rest we construct null values. if (i == j) { projectOutputs.AddRange(newFlattenedElementVars); } else { foreach (var v in otherCollectionInfo.FlattenedElementVars) { var nullOp = Command.CreateNullOp(v.Type); var nullOpNode = Command.CreateNode(nullOp); Var nullOpVar; var nullOpVarDefNode = Command.CreateVarDefNode(nullOpNode, out nullOpVar); varDefListChildren.Add(nullOpVarDefNode); projectOutputs.Add(nullOpVar); } } } var varDefListNode = Command.CreateNode(Command.CreateVarDefListOp(), varDefListChildren); // Now, build up the projectOp var projectOutputsVarSet = Command.CreateVarVec(projectOutputs); var projectOp = Command.CreateProjectOp(projectOutputsVarSet); var projectNode = Command.CreateNode(projectOp, applyNode, varDefListNode); // finally, build the union all if (unionAllNode == null) { unionAllNode = projectNode; unionAllOutputs = projectOutputs; } else { var unionAllMap = new VarMap(); var projectMap = new VarMap(); for (var idx = 0; idx < unionAllOutputs.Count; idx++) { Var outputVar = Command.CreateSetOpVar(unionAllOutputs[idx].Type); unionAllMap.Add(outputVar, unionAllOutputs[idx]); projectMap.Add(outputVar, projectOutputs[idx]); } var unionAllOp = Command.CreateUnionAllOp(unionAllMap, projectMap); unionAllNode = Command.CreateNode(unionAllOp, unionAllNode, projectNode); // Get the output vars from the union-op. This must be in the same order // as the original list of Vars unionAllOutputs = GetUnionOutputs(unionAllOp, unionAllOutputs); } } // We're done building the node, but now we have to build a mapping from // the before-Vars to the after-Vars varMapList = new List<Dictionary<Var, Var>>(); IEnumerator<Var> outputVarsEnumerator = unionAllOutputs.GetEnumerator(); if (!outputVarsEnumerator.MoveNext()) { throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.ColumnCountMismatch, 4, null); // more columns from children than are on the unionAll? } // The discriminator var is always first discriminatorVar = outputVarsEnumerator.Current; // Build a map for each input for (var i = 0; i < nestNode.Children.Count; i++) { var varMap = new Dictionary<Var, Var>(); var varList = (i == 0) ? drivingNodeVars : nestOp.CollectionInfo[i - 1].FlattenedElementVars; foreach (var v in varList) { if (!outputVarsEnumerator.MoveNext()) { throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.ColumnCountMismatch, 5, null); // more columns from children than are on the unionAll? } varMap[v] = outputVarsEnumerator.Current; } varMapList.Add(varMap); } if (outputVarsEnumerator.MoveNext()) { throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.ColumnCountMismatch, 6, null); // at this point, we better be done with both lists... } return unionAllNode; }
private VarMap FlattenVarMap(VarMap varMap, out List<ComputedVar> newComputedVars) { newComputedVars = null; var newVarMap = new VarMap(); foreach (var kv in varMap) { VarInfo innerVarInfo; VarInfo outerVarInfo; // Does the inner var have a Varinfo - if not, simply add it // to the VarMap, and continue. // Otherwise, the Outer var must have a VarInfo too if (!m_varInfoMap.TryGetVarInfo(kv.Value, out innerVarInfo)) { newVarMap.Add(kv.Key, kv.Value); } else { // get my own var info if (!m_varInfoMap.TryGetVarInfo(kv.Key, out outerVarInfo)) { outerVarInfo = FlattenSetOpVar((SetOpVar)kv.Key); } // If this Var represents a collection type, then simply // replace the singleton Var if (outerVarInfo.Kind == VarInfoKind.CollectionVarInfo) { newVarMap.Add(((CollectionVarInfo)outerVarInfo).NewVar, ((CollectionVarInfo)innerVarInfo).NewVar); } else if (outerVarInfo.Kind == VarInfoKind.PrimitiveTypeVarInfo) { newVarMap.Add(((PrimitiveTypeVarInfo)outerVarInfo).NewVar, ((PrimitiveTypeVarInfo)innerVarInfo).NewVar); } else { // structured type Debug.Assert(outerVarInfo.Kind == VarInfoKind.StructuredTypeVarInfo, "StructuredVarInfo expected"); var outerSvarInfo = (StructuredVarInfo)outerVarInfo; var innerSvarInfo = (StructuredVarInfo)innerVarInfo; // walk through each property, and find the innerVar corresponding // to that property foreach (var prop in outerSvarInfo.Fields) { Var outerVar; Var innerVar; var ret = outerSvarInfo.TryGetVar(prop, out outerVar); PlanCompiler.Assert(ret, "Could not find VarInfo for prop " + prop.Name); if (!innerSvarInfo.TryGetVar(prop, out innerVar)) { // we didn't find a corresponding innerVar. innerVar = m_command.CreateComputedVar(outerVar.Type); if (newComputedVars == null) { newComputedVars = new List<ComputedVar>(); } newComputedVars.Add((ComputedVar)innerVar); } newVarMap.Add(outerVar, innerVar); } } } } return newVarMap; }
// <summary> // Common copy path for all SetOps // </summary> // <param name="op"> The SetOp to Copy (must be one of ExceptOp, IntersectOp, UnionAllOp) </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> private Node CopySetOp(SetOp op, Node n) { // Visit the Node's children and map their Vars var children = ProcessChildren(n); var leftMap = new VarMap(); var rightMap = new VarMap(); foreach (var kv in op.VarMap[0]) { // Create a new output Var that is a copy of the original output Var Var outputVar = m_destCmd.CreateSetOpVar(kv.Key.Type); // Add a mapping for the new output var we've just created SetMappedVar(kv.Key, outputVar); // Add this output var's entries to the new VarMaps leftMap.Add(outputVar, GetMappedVar(kv.Value)); rightMap.Add(outputVar, GetMappedVar((op.VarMap[1])[kv.Key])); } SetOp newSetOp = null; switch (op.OpType) { case OpType.UnionAll: { var branchDiscriminator = ((UnionAllOp)op).BranchDiscriminator; if (null != branchDiscriminator) { branchDiscriminator = GetMappedVar(branchDiscriminator); } newSetOp = m_destCmd.CreateUnionAllOp(leftMap, rightMap, branchDiscriminator); } break; case OpType.Intersect: { newSetOp = m_destCmd.CreateIntersectOp(leftMap, rightMap); } break; case OpType.Except: { newSetOp = m_destCmd.CreateExceptOp(leftMap, rightMap); } break; default: { Debug.Assert(false, "Unexpected SetOpType"); } break; } return m_destCmd.CreateNode(newSetOp, children); }
private void Map(VarMap varMap) { VarMap newVarMap = new VarMap(); foreach (KeyValuePair<Var, Var> kv in varMap) { Var newVar = Map(kv.Value); newVarMap.Add(kv.Key, newVar); } varMap.Clear(); foreach (KeyValuePair<Var, Var> kv in newVarMap) { varMap.Add(kv.Key, kv.Value); } }
// <summary> // Builds out a UNION-ALL ladder from a sequence of node,var pairs. // Assumption: Each node produces exactly one Var // If the input sequence has zero elements, we return null // If the input sequence has one element, we return that single element // Otherwise, we build out a UnionAll ladder from each of the inputs. If the input sequence was {A,B,C,D}, // we build up a union-all ladder that looks like // (((A UA B) UA C) UA D) // </summary> // <param name="inputNodes"> list of input nodes - one for each branch </param> // <param name="inputVars"> list of input vars - N for each branch </param> // <param name="resultNode"> the resulting union-all subtree </param> // <param name="resultVars"> the output vars from the union-all subtree </param> internal virtual void BuildUnionAllLadder( IList<Node> inputNodes, IList<Var> inputVars, out Node resultNode, out IList<Var> resultVars) { if (inputNodes.Count == 0) { resultNode = null; resultVars = null; return; } var varPerNode = inputVars.Count / inputNodes.Count; Debug.Assert( (inputVars.Count % inputNodes.Count == 0) && (varPerNode >= 1), "Inconsistent nodes/vars count:" + inputNodes.Count + "," + inputVars.Count); if (inputNodes.Count == 1) { resultNode = inputNodes[0]; resultVars = inputVars; return; } var unionAllVars = new List<Var>(); var unionAllNode = inputNodes[0]; for (var j = 0; j < varPerNode; j++) { unionAllVars.Add(inputVars[j]); } for (var i = 1; i < inputNodes.Count; i++) { var leftVarMap = new VarMap(); var rightVarMap = new VarMap(); var setOpVars = new List<Var>(); for (var j = 0; j < varPerNode; j++) { var newVar = CreateSetOpVar(unionAllVars[j].Type); setOpVars.Add(newVar); leftVarMap.Add(newVar, unionAllVars[j]); rightVarMap.Add(newVar, inputVars[i * varPerNode + j]); } Op unionAllOp = CreateUnionAllOp(leftVarMap, rightVarMap); unionAllNode = CreateNode(unionAllOp, unionAllNode, inputNodes[i]); unionAllVars = setOpVars; } resultNode = unionAllNode; resultVars = unionAllVars; }