/// <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);
 }
Beispiel #6
0
 private JoinElimination(PlanCompiler compilerState)
 {
     m_compilerState = compilerState;
     m_varRemapper = new VarRemapper(m_compilerState.Command);
     m_varRefManager = new VarRefManager(m_compilerState.Command); 
 }
Beispiel #7
0
 private Normalizer(PlanCompiler planCompilerState)
     :base(planCompilerState)
 {
 }
 internal static void Validate(PlanCompiler compilerState)
 {
     Validate(compilerState, compilerState.Command.Root);
 }
Beispiel #9
0
 internal static void Validate(PlanCompiler compilerState)
 {
     Validate(compilerState, compilerState.Command.Root);
 }
Beispiel #10
0
        internal static void Validate(PlanCompiler compilerState, Node n)
        {
            Validator validator = new Validator(compilerState);

            validator.Validate(n);
        }
Beispiel #11
0
        /// <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();
        }
Beispiel #12
0
        /// <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();
        }
Beispiel #13
0
        /// <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));
        }
Beispiel #16
0
 private CodeGen(PlanCompiler compilerState)
 {
     m_compilerState = compilerState;           
 }
 internal static void Validate(PlanCompiler compilerState, Node n)
 {
     Validator validator = new Validator(compilerState);
     validator.Validate(n);
 }
Beispiel #18
0
 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);
 }
Beispiel #21
0
 /// <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;
 }
Beispiel #23
0
 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();
 }
Beispiel #28
0
 /// <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();
        }