private void RemapVarMapKey(VarMap varMap, Var newVar)
            {
                Var var = varMap[this.m_oldVar];

                varMap.Remove(this.m_oldVar);
                varMap.Add(newVar, var);
            }
Пример #2
0
            // <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);
            }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #6
0
        // <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;
        }
Пример #8
0
        // <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);
        }
Пример #9
0
 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);
     }
 }
Пример #10
0
 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);
     }
 }
Пример #11
0
        // <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;
        }