예제 #1
0
 internal static Node Copy(Command cmd, Node n, out VarMap varMap)
 {
     OpCopier oc = new OpCopier(cmd);
     Node newNode = oc.CopyNode(n);
     varMap = oc.m_varMap;
     return newNode;
 }
 /// <summary>
 /// Compute the hash value for this node
 /// </summary>
 /// <param name="cmd"></param>
 /// <param name="n"></param>
 internal override void ComputeHashValue(Command cmd, Node n)
 {
     base.ComputeHashValue(cmd, n);
     m_hashValue = (m_hashValue << 4) ^ GetHashValue(Definitions);
     m_hashValue = (m_hashValue << 4) ^ GetHashValue(Keys.KeyVars);
     return;
 }
 /// <summary>
 /// Private constructor 
 /// </summary>
 /// <param name="command"></param>
 /// <param name="groupAggregateVarInfoManager"></param>
 private GroupAggregateVarComputationTranslator(
     Command command,
     GroupAggregateVarInfoManager groupAggregateVarInfoManager)
 {
     _command = command;
     _groupAggregateVarInfoManager = groupAggregateVarInfoManager;
 }
예제 #4
0
        internal Table(Command command, TableMD tableMetadata, int tableId)
        {
            m_tableMetadata = tableMetadata;
            m_columns = Command.CreateVarList();
            m_keys = command.CreateVarVec();
            m_nonnullableColumns = command.CreateVarVec();
            m_tableId = tableId;

            var columnVarMap = new Dictionary<string, ColumnVar>();
            foreach (var c in tableMetadata.Columns)
            {
                var v = command.CreateColumnVar(this, c);
                columnVarMap[c.Name] = v;
                if (!c.IsNullable)
                {
                    m_nonnullableColumns.Set(v);
                }
            }

            foreach (var c in tableMetadata.Keys)
            {
                var v = columnVarMap[c.Name];
                m_keys.Set(v);
            }

            m_referencedColumns = command.CreateVarVec(m_columns);
        }
        /// <summary>
        /// Produces a list of all GroupAggregateVarInfos, each of which represents a single group aggregate 
        /// and it candidate function aggregates. It also produces a delegate that given a child node returns the parent node
        /// </summary>
        /// <param name="itree"></param>
        /// <param name="tryGetParent"></param>
        /// <returns></returns>
        internal static IEnumerable<GroupAggregateVarInfo> Process(Command itree, out TryGetValue tryGetParent)
        {
            var groupRefComputingVisitor = new GroupAggregateRefComputingVisitor(itree);
            groupRefComputingVisitor.VisitNode(itree.Root);
            tryGetParent = groupRefComputingVisitor._childToParent.TryGetValue;

            return groupRefComputingVisitor._groupAggregateVarInfoManager.GroupAggregateVarInfos;
        }
 /// <summary>
 /// Equivalent to OpCopier.Copy, only in addition it keeps track of the defining subtrees
 /// of collection vars defined in the subtree rooted at the copy of the input node n.
 /// </summary>
 /// <param name="cmd"></param>
 /// <param name="n"></param>
 /// <param name="varMap"></param>
 /// <param name="newCollectionVarDefinitions"></param>
 /// <returns></returns>
 internal static Node Copy(Command cmd, Node n, out VarMap varMap, out Dictionary<Var, Node> newCollectionVarDefinitions)
 {
     var oc = new OpCopierTrackingCollectionVars(cmd);
     var newNode = oc.CopyNode(n);
     varMap = oc.m_varMap;
     newCollectionVarDefinitions = oc.m_newCollectionVarDefinitions;
     return newNode;
 }
 /// <summary>
 /// Creates a ProviderCommandInfo for the given node. 
 /// This method should be called when the keys and the sort keys are not known ahead of time.
 /// Typically it is used when there is only one command, that is no query factoring is done.
 /// This method also has the option of pulling up keys and sort information. 
 /// </summary>
 /// <param name="command">The owning command, used for creating VarVecs, etc</param>
 /// <param name="node">The root of the sub-command for which a ProviderCommandInfo should be generated</param>
 /// <returns>The resulting ProviderCommandInfo</returns>
 internal static ProviderCommandInfo Create(
     Command command,
     Node node)
 {   
     return Create(
         command, 
         node, 
         new List<ProviderCommandInfo>() //children 
         );
 }
 internal ExtendedNodeInfo(Command cmd)
     : base(cmd)
 {
     m_localDefinitions = cmd.CreateVarVec();
     m_definitions = cmd.CreateVarVec();
     m_nonNullableDefinitions = cmd.CreateVarVec();
     m_nonNullableVisibleDefinitions = cmd.CreateVarVec();
     m_keys = new KeyVec(cmd);
     m_minRows = RowCount.Zero;
     m_maxRows = RowCount.Unbounded;
 }
예제 #9
0
 /// <summary>
 /// Make a copy of the current node. Also return an ordered list of the new
 /// Vars corresponding to the vars in "varList"
 /// </summary>
 /// <param name="cmd">current command</param>
 /// <param name="node">the node to clone</param>
 /// <param name="varList">list of Vars</param>
 /// <param name="newVarList">list of "new" Vars</param>
 /// <returns>the cloned node</returns>
 internal static Node Copy(Command cmd, Node node, VarList varList, out VarList newVarList)
 {
     VarMap varMap;
     Node newNode = Copy(cmd, node, out varMap);
     newVarList = Command.CreateVarList();
     foreach (Var v in varList)
     {
         Var newVar = varMap[v];
         newVarList.Add(newVar);
     }
     return newNode;
 }
예제 #10
0
        /// <summary>
        /// Computes the hash value for this node. The hash value is simply the 
        /// local hash value for this node info added with the hash values of the child 
        /// nodes
        /// </summary>
        /// <param name="cmd">current command</param>
        /// <param name="n">current node</param>
        internal virtual void ComputeHashValue(Command cmd, Node n)
        {
            m_hashValue = 0;
            foreach (var chi in n.Children)
            {
                var chiNodeInfo = cmd.GetNodeInfo(chi);
                m_hashValue ^= chiNodeInfo.HashValue;
            }

            m_hashValue = (m_hashValue << 4) ^ ((int)n.Op.OpType); // include the optype somehow
            // Now compute my local hash value
            m_hashValue = (m_hashValue << 4) ^ GetHashValue(m_externalReferences);
        }
예제 #11
0
 internal static void Process(Command command)
 {
     Node topMostSort;
     if (command.Root.Child0 != null
         && command.Root.Child0.Op.OpType == OpType.Sort)
     {
         topMostSort = command.Root.Child0;
     }
     else
     {
         topMostSort = null;
     }
     var sortRemover = new SortRemover(command, topMostSort);
     command.Root = sortRemover.VisitNode(command.Root);
 }
        internal static ProviderCommandInfo Create(
            Command command,
            Node node)
        {
            var projectOp = node.Op as PhysicalProjectOp;
            PlanCompiler.Assert(projectOp != null, "Expected root Op to be a physical Project");

            // build up the CQT
            var ctree = CTreeGenerator.Generate(command, node);
            var cqtree = ctree as DbQueryCommandTree;
            PlanCompiler.Assert(cqtree != null, "null query command tree");

            // Get the rowtype for the result cqt
            var collType = TypeHelpers.GetEdmType<md.CollectionType>(cqtree.Query.ResultType);
            PlanCompiler.Assert(md.TypeSemantics.IsRowType(collType.TypeUsage), "command rowtype is not a record");

            // Build up a mapping from Vars to the corresponding output property/column
            var outputVarMap = BuildOutputVarMap(projectOp, collType.TypeUsage);

            return new ProviderCommandInfo(ctree);
        }
예제 #13
0
        /// <summary>
        /// Split up a predicate into 2 parts - the pushdown and the non-pushdown predicate. 
        /// 
        /// If the filter node has no external references *and* the "columns" parameter is null,
        /// then the entire predicate can be pushed down
        /// 
        /// We then compute the set of valid column references - if the "columns" parameter
        /// is non-null, this set is used. Otherwise, we get the definitions of the 
        /// input relop node of the filterOp, and use that.
        /// 
        /// We use this list of valid column references to identify which parts of the filter
        /// predicate can be pushed down - only those parts of the predicate that do not 
        /// reference anything beyond these columns are considered for pushdown. The rest are
        /// stuffed into the nonPushdownPredicate output parameter
        /// 
        /// </summary>
        /// <param name="command">Command object</param>
        /// <param name="filterNode">the FilterOp subtree</param>
        /// <param name="columns">(Optional) List of columns to consider for "pushdown"</param>
        /// <param name="nonPushdownPredicateNode">(output) Part of the predicate that cannot be pushed down</param>
        /// <returns>part of the predicate that can be pushed down</returns>
        private static Node GetPushdownPredicate(Command command, Node filterNode, VarVec columns, out Node nonPushdownPredicateNode)
        {
            var pushdownPredicateNode = filterNode.Child1;
            nonPushdownPredicateNode = null;
            var filterNodeInfo = command.GetExtendedNodeInfo(filterNode);
            if (columns == null
                && filterNodeInfo.ExternalReferences.IsEmpty)
            {
                return pushdownPredicateNode;
            }

            if (columns == null)
            {
                var inputNodeInfo = command.GetExtendedNodeInfo(filterNode.Child0);
                columns = inputNodeInfo.Definitions;
            }

            var predicate = new Predicate(command, pushdownPredicateNode);
            Predicate nonPushdownPredicate;
            predicate = predicate.GetSingleTablePredicates(columns, out nonPushdownPredicate);
            pushdownPredicateNode = predicate.BuildAndTree();
            nonPushdownPredicateNode = nonPushdownPredicate.BuildAndTree();
            return pushdownPredicateNode;
        }
예제 #14
0
 internal RuleProcessingContext(Command command)
 {
     m_command = command;
 }
예제 #15
0
 private void InitializeNodeInfo(Command command)
 {
     if (this.Op.IsRelOp || this.Op.IsPhysicalOp)
     {
         m_nodeInfo = new ExtendedNodeInfo(command);
     }
     else
     {
         m_nodeInfo = new NodeInfo(command);
     }
     command.RecomputeNodeInfo(this);
 }
예제 #16
0
 /// <summary>
 /// Gets the "extended" nodeinfo for a node; if it has not yet been initialized, then it will be
 /// </summary>
 /// <param name="command">current command object</param>
 /// <returns>extended nodeinfo for this node</returns>
 internal ExtendedNodeInfo GetExtendedNodeInfo(Command command)
 {
     if (m_nodeInfo == null)
     {
         InitializeNodeInfo(command);
     }
     ExtendedNodeInfo extendedNodeInfo = m_nodeInfo as ExtendedNodeInfo;
     Debug.Assert(extendedNodeInfo != null);
     return extendedNodeInfo;
 }
예제 #17
0
 /// <summary>
 /// Get the nodeInfo for a node. Initializes it, if it has not yet been initialized
 /// </summary>
 /// <param name="command">Current command object</param>
 /// <returns>NodeInfo for this node</returns>
 internal NodeInfo GetNodeInfo(Command command)
 {
     if (m_nodeInfo == null)
     {
         InitializeNodeInfo(command);
     }
     return m_nodeInfo;
 }
예제 #18
0
 /// <summary>
 /// Create a predicate from a node tree
 /// </summary>
 /// <param name="command">current iqt command</param>
 /// <param name="andTree">the node tree</param>
 internal Predicate(Command command, Node andTree)
     : this(command)
 {
     PlanCompiler.Assert(andTree != null, "null node passed to Predicate() constructor");
     InitFromAndTree(andTree);
 }
 private OpCopierTrackingCollectionVars(Command cmd)
     : base(cmd)
 {
 }
예제 #20
0
 /// <summary>
 /// Constructs a new VarRefManager given a command.
 /// </summary>
 /// <param name="command"></param>
 internal VarRefManager(Command command)
 {
     m_nodeToParentMap = new Dictionary<Node, Node>();
     m_nodeToSiblingNumber = new Dictionary<Node, int>();
     m_command = command;
 }
예제 #21
0
 /// <summary>
 /// Create an empty predicate
 /// </summary>
 /// <param name="command"></param>
 internal Predicate(Command command)
 {
     m_command = command;
     m_parts = new List<Node>();
 }
예제 #22
0
 /// <summary>
 /// Internal constructor
 /// </summary>
 /// <param name="command">Current iqt command</param>
 /// <param name="varMap">Var map to be used</param>
 internal VarRemapper(Command command, Dictionary<Var, Var> varMap)
 {
     m_command = command;
     m_varMap = varMap;
 }
예제 #23
0
 /// <summary>
 /// Constructor. Allows for cloning of nodes within the same command
 /// </summary>
 /// <param name="cmd">The command</param>
 protected OpCopier(Command cmd) : this(cmd, cmd) {}
예제 #24
0
 protected BasicValidator(Command command)
 {
     m_command = command;
 }
예제 #25
0
 /// <summary>
 /// Constructor. Allows for cloning of nodes across commands
 /// </summary>
 /// <param name="destCommand">The Command to which Nodes to be cloned must belong</param>
 /// <param name="sourceCommand">The Command to which cloned Nodes will belong</param>
 private OpCopier(Command destCommand, Command sourceCommand)
 {
     m_srcCmd = sourceCommand;
     m_destCmd = destCommand;
     m_varMap = new VarMap();
 }
예제 #26
0
 internal KeyVec(Command itree)
 {
     m_keys = itree.CreateVarVec();
     m_noKeys = true;
 }
        /// <summary>
        /// Try to produce an equivalent tree to the input subtree, over a single group aggregate variable.
        /// Such translation can only be produced if all external references of the input subtree are to a 
        /// single group aggregate var, or to vars that are can be translated over that single group 
        /// aggregate var
        /// </summary>
        /// <param name="subtree">The input subtree</param>
        /// <param name="isVarDefinition"></param>
        /// <param name="command"></param>
        /// <param name="groupAggregateVarInfoManager"></param>
        /// <param name="groupAggregateVarInfo">The groupAggregateVarInfo over which the input subtree can be translated </param>
        /// <param name="templateNode">A tree that is equvalent to the input tree, but over the group aggregate variable
        /// represented by the groupAggregetVarInfo</param>
        /// <param name="isUnnested"></param>
        /// <returns>True, if the translation can be done, false otherwise</returns>
        public static bool TryTranslateOverGroupAggregateVar(
            Node subtree,
            bool isVarDefinition,
            Command command,
            GroupAggregateVarInfoManager groupAggregateVarInfoManager,
            out GroupAggregateVarInfo groupAggregateVarInfo,
            out Node templateNode,
            out bool isUnnested)
        {
            var handler = new GroupAggregateVarComputationTranslator(command, groupAggregateVarInfoManager);

            var inputNode = subtree;
            SoftCastOp softCastOp = null;
            bool isCollect;
            if (inputNode.Op.OpType
                == OpType.SoftCast)
            {
                softCastOp = (SoftCastOp)inputNode.Op;
                inputNode = inputNode.Child0;
            }

            if (inputNode.Op.OpType
                == OpType.Collect)
            {
                templateNode = handler.VisitCollect(inputNode);
                isCollect = true;
            }
            else
            {
                templateNode = handler.VisitNode(inputNode);
                isCollect = false;
            }

            groupAggregateVarInfo = handler._targetGroupAggregateVarInfo;
            isUnnested = handler._isUnnested;

            if (handler._targetGroupAggregateVarInfo == null
                || templateNode == null)
            {
                return false;
            }
            if (softCastOp != null)
            {
                SoftCastOp newSoftCastOp;
                // 
                // The type needs to be fixed only if the unnesting happened during this translation.
                // That can be recognized by these two cases: 
                //      1) if the input node was a collect, or 
                //      2) if the input did not represent a var definition, but a function aggregate argument and 
                //              the template is VarRef of a group aggregate var.
                //
                if (isCollect
                    ||
                    !isVarDefinition
                    && AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, handler._targetGroupAggregateVarInfo.GroupAggregateVar))
                {
                    newSoftCastOp = command.CreateSoftCastOp(TypeHelpers.GetEdmType<CollectionType>(softCastOp.Type).TypeUsage);
                }
                else
                {
                    newSoftCastOp = softCastOp;
                }
                templateNode = command.CreateNode(newSoftCastOp, templateNode);
            }
            return true;
        }
예제 #28
0
 /// <summary>
 /// Remap the given varList using the given varMap
 /// </summary>
 /// <param name="command"></param>
 /// <param name="varMap"></param>
 /// <param name="varList"></param>
 internal static VarList RemapVarList(Command command, Dictionary<Var, Var> varMap, VarList varList)
 {
     VarRemapper varRemapper = new VarRemapper(command, varMap);
     return varRemapper.RemapVarList(varList);
 }
예제 #29
0
 internal Node GetInternalTree(Command targetIqtCommand)
 {
     Debug.Assert(m_extent.EntityContainer.DataSpace == DataSpace.CSpace, "Internal Tree should be asked only for query view");
     if (m_internalTreeNode == null)
     {
         DbQueryCommandTree tree = GetCommandTree();
         // Convert this into an ITree first
         Command itree = ITreeGenerator.Generate(tree, m_discriminatorMap);
         // Pull out the root physical project-op, and copy this itree into our own itree
         PlanCompiler.Assert(itree.Root.Op.OpType == OpType.PhysicalProject,
             "Expected a physical projectOp at the root of the tree - found " + itree.Root.Op.OpType);
         // #554756: VarVec enumerators are not cached on the shared Command instance.
         itree.DisableVarVecEnumCaching();
         m_internalTreeNode = itree.Root.Child0;
     }
     Debug.Assert(m_internalTreeNode != null, "m_internalTreeNode != null");
     return OpCopier.Copy(targetIqtCommand, m_internalTreeNode);
 }
예제 #30
0
 /// <summary>
 /// Internal constructor
 /// </summary>
 /// <param name="command">Current iqt command</param>
 internal VarRemapper(Command command)
     :this(command, new Dictionary<Var,Var>())
 {
 }