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; }
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; }
/// <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; }
/// <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); }
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); }
/// <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; }
internal RuleProcessingContext(Command command) { m_command = command; }
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); }
/// <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; }
/// <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; }
/// <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) { }
/// <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; }
/// <summary> /// Create an empty predicate /// </summary> /// <param name="command"></param> internal Predicate(Command command) { m_command = command; m_parts = new List<Node>(); }
/// <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; }
/// <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) {}
protected BasicValidator(Command command) { m_command = command; }
/// <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(); }
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; }
/// <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); }
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); }
/// <summary> /// Internal constructor /// </summary> /// <param name="command">Current iqt command</param> internal VarRemapper(Command command) :this(command, new Dictionary<Var,Var>()) { }