/// <summary> /// The driver routine. /// </summary> /// <param name="planCompilerState">plan compiler state</param> /// <param name="typeInfo">type information about all types/sets referenced in the query</param> /// <param name="tvfResultKeys">inferred key columns of tvfs return types</param> internal static void Process( PlanCompiler planCompilerState, out StructuredTypeInfo typeInfo, out Dictionary<EdmFunction, EdmProperty[]> tvfResultKeys) { var preProcessor = new PreProcessor(planCompilerState); preProcessor.Process(out tvfResultKeys); StructuredTypeInfo.Process( planCompilerState.Command, preProcessor.m_referencedTypes, preProcessor.m_referencedEntitySets, preProcessor.m_freeFloatingEntityConstructorTypes, preProcessor.m_suppressDiscriminatorMaps ? null : preProcessor.m_discriminatorMaps, preProcessor.m_relPropertyHelper, preProcessor.m_typesNeedingNullSentinel, out typeInfo); }
/// <summary> /// Runs through the root node of the tree, and eliminates all /// unreferenced expressions /// </summary> /// <param name="compilerState">current compiler state</param> internal static void Process(PlanCompiler compilerState) { compilerState.Command.Root = Process(compilerState, compilerState.Command.Root); }
private const string PrefixMatchCharacter = "%"; // This is ANSI-SQL defined, but it should probably be configurable. #endregion #region constructors private NominalTypeEliminator(PlanCompiler compilerState, StructuredTypeInfo typeInfo, Dictionary<Var, PropertyRefList> varPropertyMap, Dictionary<Node, PropertyRefList> nodePropertyMap, Dictionary<md.EdmFunction, md.EdmProperty[]> tvfResultKeys) { m_compilerState = compilerState; m_typeInfo = typeInfo; m_varPropertyMap = varPropertyMap; m_nodePropertyMap = nodePropertyMap; m_varInfoMap = new VarInfoMap(); m_tvfResultKeys = tvfResultKeys; m_typeToNewTypeMap = new Dictionary<md.TypeUsage, md.TypeUsage>(TypeUsageEqualityComparer.Instance); }
private NestPullup(PlanCompiler compilerState) { m_compilerState = compilerState; m_varRemapper = new VarRemapper(compilerState.Command); }
private PreProcessor(PlanCompiler planCompilerState) : base(planCompilerState) { m_relPropertyHelper = new RelPropertyHelper(m_command.MetadataWorkspace, m_command.ReferencedRelProperties); }
private JoinElimination(PlanCompiler compilerState) { m_compilerState = compilerState; m_varRemapper = new VarRemapper(m_compilerState.Command); m_varRefManager = new VarRefManager(m_compilerState.Command); }
private Normalizer(PlanCompiler planCompilerState) :base(planCompilerState) { }
internal static void Validate(PlanCompiler compilerState) { Validate(compilerState, compilerState.Command.Root); }
internal static void Validate(PlanCompiler compilerState) { Validate(compilerState, compilerState.Command.Root); }
internal static void Validate(PlanCompiler compilerState, Node n) { Validator validator = new Validator(compilerState); validator.Validate(n); }
/// <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> /// Apply Aggregate Pushdown over the tree in the given plan complier state. /// </summary> /// <param name="planCompilerState"></param> internal static void Process(PlanCompiler planCompilerState) { AggregatePushdown aggregatePushdown = new AggregatePushdown(planCompilerState.Command); aggregatePushdown.Process(); }
/// <summary> /// If the Subtree rooted at the collect is of the following structure: /// /// PhysicalProject(outputVar) /// | /// Project(s) /// | /// Unnest /// /// where the unnest is over the group aggregate var and the output var /// is either a reference to the group aggregate var or to a constant, it returns the /// translation of the ouput var. /// </summary> /// <param name="n"></param> /// <returns></returns> private Node VisitCollect(Node n) { //Make sure the only children are projects over unnest Node currentNode = n.Child0; Dictionary <Var, Node> constantDefinitions = new Dictionary <Var, Node>(); while (currentNode.Child0.Op.OpType == OpType.Project) { currentNode = currentNode.Child0; //Visit the VarDefListOp child if (VisitDefault(currentNode.Child1) == null) { return(null); } foreach (Node definitionNode in currentNode.Child1.Children) { if (IsConstant(definitionNode.Child0)) { constantDefinitions.Add(((VarDefOp)definitionNode.Op).Var, definitionNode.Child0); } } } if (currentNode.Child0.Op.OpType != OpType.Unnest) { return(null); } // Handle the unnest UnnestOp unnestOp = (UnnestOp)currentNode.Child0.Op; GroupAggregateVarRefInfo groupAggregateVarRefInfo; if (_groupAggregateVarInfoManager.TryGetReferencedGroupAggregateVarInfo(unnestOp.Var, out groupAggregateVarRefInfo)) { if (_targetGroupAggregateVarInfo == null) { _targetGroupAggregateVarInfo = groupAggregateVarRefInfo.GroupAggregateVarInfo; } else if (_targetGroupAggregateVarInfo != groupAggregateVarRefInfo.GroupAggregateVarInfo) { return(null); } if (!_isUnnested) { return(null); } } else { return(null); } PhysicalProjectOp physicalProjectOp = (PhysicalProjectOp)n.Child0.Op; PlanCompiler.Assert(physicalProjectOp.Outputs.Count == 1, "PhysicalProject should only have one output at this stage"); Var outputVar = physicalProjectOp.Outputs[0]; Node computationTemplate = TranslateOverGroupAggregateVar(outputVar, null); if (computationTemplate != null) { _isUnnested = true; return(computationTemplate); } Node constantDefinitionNode; if (constantDefinitions.TryGetValue(outputVar, out constantDefinitionNode)) { _isUnnested = true; return(constantDefinitionNode); } return(null); }
internal TransformationRulesContext(PlanCompiler compilerState) : base(compilerState.Command) { m_compilerState = compilerState; m_remapper = new VarRemapper(compilerState.Command); m_suppressions = new Dictionary<Node, Node>(); m_remappedVars = compilerState.Command.CreateVarVec(); }
/// <summary> /// Runs through the given subtree, and eliminates all /// unreferenced expressions /// </summary> /// <param name="compilerState">current compiler state</param> /// <param name="node">The node to be processed</param> /// <returns>The processed, i.e. transformed node</returns> internal static Node Process(PlanCompiler compilerState, Node node) { ProjectionPruner pruner = new ProjectionPruner(compilerState); return(pruner.Process(node)); }
private CodeGen(PlanCompiler compilerState) { m_compilerState = compilerState; }
internal static void Validate(PlanCompiler compilerState, Node n) { Validator validator = new Validator(compilerState); validator.Validate(n); }
private Validator(PlanCompiler compilerState) : base(compilerState.Command) { m_compilerState = compilerState; }
private Validator(PlanCompiler compilerState) : base(compilerState.Command) { m_compilerState = compilerState; }
internal static void Compile( cqt.DbCommandTree ctree, out List<ProviderCommandInfo> providerCommands, out ColumnMap resultColumnMap, out int columnCount, out Set<md.EntitySet> entitySets) { Assert(ctree != null, "Expected a valid, non-null Command Tree input"); var pc = new PlanCompiler(ctree); pc.Compile(out providerCommands, out resultColumnMap, out columnCount, out entitySets); }
/// <summary> /// The driver routine. /// </summary> /// <param name="planCompilerState">plan compiler state</param> internal static void Process(PlanCompiler planCompilerState) { Normalizer normalizer = new Normalizer(planCompilerState); normalizer.Process(); }
protected SubqueryTrackingVisitor(PlanCompiler planCompilerState) { this.m_compilerState = planCompilerState; }
internal static bool Process(PlanCompiler compilerState) { JoinElimination je = new JoinElimination(compilerState); je.Process(); return je.m_treeModified; }
/// <summary> /// Apply Aggregate Pushdown over the tree in the given plan complier state. /// </summary> /// <param name="planCompilerState"></param> internal static void Process(PlanCompiler planCompilerState) { AggregatePushdown aggregatePushdown = new AggregatePushdown(planCompilerState.Command); aggregatePushdown.Process(); }
/// <summary> /// Apply the rules that belong to the specified group to the given query tree. /// </summary> /// <param name="compilerState"></param> /// <param name="rulesGroup"></param> internal static bool Process(PlanCompiler compilerState, TransformationRulesGroup rulesGroup) { ReadOnlyCollection<ReadOnlyCollection<Rule>> rulesTable = null; switch (rulesGroup) { case TransformationRulesGroup.All: rulesTable = AllRulesTable; break; case TransformationRulesGroup.PostJoinElimination: rulesTable = PostJoinEliminationRulesTable; break; case TransformationRulesGroup.Project: rulesTable = ProjectRulesTable; break; } // If any rule has been applied after which reapplying nullability rules may be useful, // reapply nullability rules. bool projectionPrunningRequired; if (Process(compilerState, rulesTable, out projectionPrunningRequired)) { bool projectionPrunningRequired2; Process(compilerState, NullabilityRulesTable, out projectionPrunningRequired2); projectionPrunningRequired = projectionPrunningRequired || projectionPrunningRequired2; } return projectionPrunningRequired; }
/// <summary> /// Apply the rules that belong to the specified rules table to the given query tree. /// </summary> /// <param name="compilerState"></param> /// <param name="rulesTable"></param> /// <param name="projectionPruningRequired">is projection pruning required after the rule application</param> /// <returns>Whether any rule has been applied after which reapplying nullability rules may be useful</returns> private static bool Process( PlanCompiler compilerState, ReadOnlyCollection<ReadOnlyCollection<Rule>> rulesTable, out bool projectionPruningRequired) { var ruleProcessor = new RuleProcessor(); var context = new TransformationRulesContext(compilerState); compilerState.Command.Root = ruleProcessor.ApplyRulesToSubtree(context, rulesTable, compilerState.Command.Root); projectionPruningRequired = context.ProjectionPrunningRequired; return context.ReapplyNullabilityRules; }
internal static void Process(PlanCompiler compilerState) { var np = new NestPullup(compilerState); np.Process(); }
/// <summary> /// This involves /// * Converting the ITree into a set of ProviderCommandInfo objects /// * Creating a column map to enable result assembly /// Currently, we only produce a single ITree, and correspondingly, the /// following steps are trivial /// </summary> /// <param name="compilerState">current compiler state</param> /// <param name="childCommands">CQTs for each store command</param> /// <param name="resultColumnMap">column map to help in result assembly</param> internal static void Process(PlanCompiler compilerState, out List<ProviderCommandInfo> childCommands, out ColumnMap resultColumnMap, out int columnCount) { CodeGen codeGen = new CodeGen(compilerState); codeGen.Process(out childCommands, out resultColumnMap, out columnCount); }
/// <summary> /// Eliminates all structural types from the query /// </summary> /// <param name="compilerState">current compiler state</param> /// <param name="structuredTypeInfo"></param> /// <param name="tvfResultKeys">inferred s-space keys for TVFs that are mapped to entities</param> internal static void Process( PlanCompiler compilerState, StructuredTypeInfo structuredTypeInfo, Dictionary<md.EdmFunction, md.EdmProperty[]> tvfResultKeys) { #if DEBUG //string phase0 = Dump.ToXml(compilerState.Command); Validator.Validate(compilerState); #endif // Phase 1: Top-down property pushdown Dictionary<Var, PropertyRefList> varPropertyMap; Dictionary<Node, PropertyRefList> nodePropertyMap; PropertyPushdownHelper.Process(compilerState.Command, structuredTypeInfo, out varPropertyMap, out nodePropertyMap); #if DEBUG //string phase1 = Dump.ToXml(compilerState.Command); Validator.Validate(compilerState); #endif // Phase 2: actually eliminate nominal types NominalTypeEliminator nte = new NominalTypeEliminator( compilerState, structuredTypeInfo, varPropertyMap, nodePropertyMap, tvfResultKeys); nte.Process(); #if DEBUG //string phase2 = Dump.ToXml(compilerState.Command); Validator.Validate(compilerState); #endif #if DEBUG //To avoid garbage collection //int size = phase0.Length; //size = phase1.Length; //size = phase2.Length; #endif }
private VarVec m_referencedVars; // the list of referenced vars in the query #endregion #region constructor /// <summary> /// Trivial private constructor /// </summary> /// <param name="compilerState">current compiler state</param> private ProjectionPruner(PlanCompiler compilerState) { m_compilerState = compilerState; m_referencedVars = compilerState.Command.CreateVarVec(); }