示例#1
0
        /// <summary>
        /// Creates generated view object for the combination of the <paramref name="extent"/> and the <paramref name="type"/>. 
        /// This constructor is used for regular cell-based view generation.
        /// </summary>
        internal static GeneratedView CreateGeneratedView(EntitySetBase extent,
                                                          EdmType type,
                                                          DbQueryCommandTree commandTree,
                                                          string eSQL,
                                                          StorageMappingItemCollection mappingItemCollection,
                                                          ConfigViewGenerator config)
        {
            // If config.GenerateEsql is specified, eSQL must be non-null.
            // If config.GenerateEsql is false, commandTree is non-null except the case when loading pre-compiled eSQL views.
            Debug.Assert(!config.GenerateEsql || !String.IsNullOrEmpty(eSQL), "eSQL must be specified");

            DiscriminatorMap discriminatorMap = null;
            if (commandTree != null)
            {
                commandTree = ViewSimplifier.SimplifyView(extent, commandTree);

                // See if the view matches the "discriminated" pattern (allows simplification of generated store commands)
                if (extent.BuiltInTypeKind == BuiltInTypeKind.EntitySet)
                {
                    if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap))
                    {
                        Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created");
                    }
                }
            }

            return new GeneratedView(extent, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config);
        }
示例#2
0
        internal static bool TryRewrite(DbQueryCommandTree tree, Span span, MergeOption mergeOption, AliasGenerator aliasGenerator, out DbExpression newQuery, out SpanIndex spanInfo)
        {
            newQuery = null;
            spanInfo = null;

            ObjectSpanRewriter rewriter = null;
            bool requiresRelationshipSpan = Span.RequiresRelationshipSpan(mergeOption);

            // Potentially perform a rewrite for span.
            // Note that the public 'Span' property is NOT used to retrieve the Span instance
            // since this forces creation of a Span object that may not be required.
            if (span != null && span.SpanList.Count > 0)
            {
                rewriter = new ObjectFullSpanRewriter(tree, tree.Query, span, aliasGenerator);
            }
            else if (requiresRelationshipSpan)
            {
                rewriter = new ObjectSpanRewriter(tree, tree.Query, aliasGenerator);
            }

            if (rewriter != null)
            {
                rewriter.RelationshipSpan = requiresRelationshipSpan;
                newQuery = rewriter.RewriteQuery();
                if (newQuery != null)
                {
                    Debug.Assert(rewriter.SpanIndex != null || tree.Query.ResultType.EdmEquals(newQuery.ResultType), "Query was rewritten for Span but no SpanIndex was created?");
                    spanInfo = rewriter.SpanIndex;
                }
            }

            return (spanInfo != null);
        }
 /// <summary>
 /// The only entry point. 
 /// Rewrites the given tree by replacing expressions that are not directly supported on SQL Server 2000
 /// with alterntive translations.
 /// </summary>
 /// <param name="originalTree">The tree to rewrite</param>
 /// <returns>The new tree</returns>
 internal static DbQueryCommandTree Rewrite(DbQueryCommandTree originalTree)
 {
     Debug.Assert(originalTree != null, "OriginalTree is null");
     Sql8ExpressionRewriter rewriter = new Sql8ExpressionRewriter(originalTree.MetadataWorkspace);
     DbExpression newQuery = rewriter.VisitExpression(originalTree.Query);
     return DbQueryCommandTree.FromValidExpression(originalTree.MetadataWorkspace, originalTree.DataSpace, newQuery);
 }
示例#4
0
 /// <summary>
 /// Creates generated view object for the combination of the <paramref name="extent"/> and the <paramref name="type"/>. 
 /// This constructor is used for FK association sets only.
 /// </summary>
 internal static GeneratedView CreateGeneratedViewForFKAssociationSet(EntitySetBase extent,
                                                                      EdmType type,
                                                                      DbQueryCommandTree commandTree,
                                                                      StorageMappingItemCollection mappingItemCollection,
                                                                      ConfigViewGenerator config)
 {
     return new GeneratedView(extent, type, commandTree, null, null, mappingItemCollection, config);
 }
        /// <summary>
        /// Converts the CTree into an ITree, and initializes the plan
        /// </summary>
        private void Initialize()
        {
            // Only support queries for now
            cqt.DbQueryCommandTree cqtree = m_ctree as cqt.DbQueryCommandTree;
            PlanCompiler.Assert(cqtree != null, "Unexpected command tree kind. Only query command tree is supported.");

            // Generate the ITree
            m_command = ITreeGenerator.Generate(cqtree);
            PlanCompiler.Assert(m_command != null, "Unable to generate internal tree from Command Tree");
        }
        /// <summary>
        /// The only entry point. 
        /// Rewrites the given tree by replacing expressions that are not directly supported on SQL Server 2000
        /// with alterntive translations.
        /// </summary>
        /// <param name="originalTree">The tree to rewrite</param>
        /// <returns>The new tree</returns>
        internal static DbQueryCommandTree Rewrite(DbQueryCommandTree originalTree)
        {
            Debug.Assert(originalTree != null, "OriginalTree is null");
            var rewriter = new Sql8ExpressionRewriter(originalTree.MetadataWorkspace);
            var newQuery = rewriter.VisitExpression(originalTree.Query);

#if DEBUG
            return new DbQueryCommandTree(originalTree.MetadataWorkspace, originalTree.DataSpace, newQuery);
#else
            return new DbQueryCommandTree(originalTree.MetadataWorkspace, originalTree.DataSpace, newQuery, validate: false);
#endif
        }
        private DbQueryCommandTree Simplify(DbQueryCommandTree view)
        {
            var simplifier = PatternMatchRuleProcessor.Create(
                // determines if an expression is of the form outerProject(outerProjection(innerProject(innerNew)))
                PatternMatchRule.Create(Pattern_CollapseNestedProjection, ViewSimplifier.CollapseNestedProjection),
                
                // A case statement can potentially be simplified
                PatternMatchRule.Create(Pattern_Case, ViewSimplifier.SimplifyCaseStatement),

                // Nested TPH discriminator pattern can be converted to the expected TPH discriminator pattern
                PatternMatchRule.Create(Pattern_NestedTphDiscriminator, ViewSimplifier.SimplifyNestedTphDiscriminator),

                // Entity constructors may be augmented with FK-based related entity refs
                PatternMatchRule.Create(Pattern_EntityConstructor, this.AddFkRelatedEntityRefs)
            );
                
            DbExpression queryExpression = view.Query;
            queryExpression = simplifier(queryExpression);

            view = DbQueryCommandTree.FromValidExpression(view.MetadataWorkspace, view.DataSpace, queryExpression);
            return view;
        }
示例#8
0
    /// <summary>
    /// Sets the expected column types for a given query command tree
    /// </summary>
    private void SetQueryExpectedTypes(DbQueryCommandTree tree, EFMySqlCommand cmd)
    {
      DbProjectExpression projectExpression = tree.Query as DbProjectExpression;
      if (projectExpression != null)
      {
        EdmType resultsType = projectExpression.Projection.ResultType.EdmType;

        StructuralType resultsAsStructuralType = resultsType as StructuralType;
        if (resultsAsStructuralType != null)
        {
          cmd.ColumnTypes = new PrimitiveType[resultsAsStructuralType.Members.Count];

          for (int ordinal = 0; ordinal < resultsAsStructuralType.Members.Count; ordinal++)
          {
            EdmMember member = resultsAsStructuralType.Members[ordinal];
            PrimitiveType primitiveType = member.TypeUsage.EdmType as PrimitiveType;
            cmd.ColumnTypes[ordinal] = primitiveType;
          }
        }
      }
    }
 internal static DbQueryCommandTree SimplifyView(EntitySetBase extent, DbQueryCommandTree view)
 {
     ViewSimplifier vs = new ViewSimplifier(view.MetadataWorkspace, extent);
     view = vs.Simplify(view);
     return view;
 }
示例#10
0
        /// <summary>
        /// Given an extent and its corresponding view, invokes the parser to check if the view definition is syntactically correct.
        /// Iff parsing succeeds: <paramref name="commandTree"/> and <paramref name="discriminatorMap"/> are set to the parse result and method returns true,
        /// otherwise if parser has thrown a catchable exception, it is returned via <paramref name="parserException"/> parameter, 
        /// otherwise exception is re-thrown.
        /// </summary>
        private static bool TryParseView(string eSQL,
                                         bool isUserSpecified,
                                         EntitySetBase extent,
                                         StorageMappingItemCollection mappingItemCollection,
                                         ConfigViewGenerator config,
                                         out DbQueryCommandTree commandTree,
                                         out DiscriminatorMap discriminatorMap,
                                         out Exception parserException)
        {
            commandTree = null;
            discriminatorMap = null;
            parserException = null;

            // We do not catch any internal exceptions any more
            config.StartSingleWatch(PerfType.ViewParsing);
            try
            {
                // If it is a user specified view, allow all queries. Otherwise parse the view in the restricted mode.
                ParserOptions.CompilationMode compilationMode = ParserOptions.CompilationMode.RestrictedViewGenerationMode;
                if (isUserSpecified)
                {
                    compilationMode = ParserOptions.CompilationMode.UserViewGenerationMode;
                }

                Debug.Assert(!String.IsNullOrEmpty(eSQL), "eSQL query is not specified");
                commandTree = (DbQueryCommandTree)ExternalCalls.CompileView(eSQL, mappingItemCollection, compilationMode);

                // For non user-specified views, perform simplification.
                if (!isUserSpecified)
                {
                    commandTree = ViewSimplifier.SimplifyView(extent, commandTree);
                }

                // See if the view matches the "discriminated" pattern (allows simplification of generated store commands)
                if (extent.BuiltInTypeKind == BuiltInTypeKind.EntitySet)
                {
                    if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap))
                    {
                        Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created");
                    }
                }
            }
            catch (Exception e)
            {
                // Catching all the exception types since Query parser seems to be throwing veriety of
                // exceptions - EntityException, ArgumentException, ArgumentNullException etc.
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    parserException = e;
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                config.StopSingleWatch(PerfType.ViewParsing);
            }

            Debug.Assert(commandTree != null || parserException != null, "Either commandTree or parserException is expected.");
            // Note: m_commandTree might have been initialized by a previous call to this method, so in consequent calls it might occur that
            // both m_commandTree and parserException are not null - this would mean that the last parse attempt failed, but m_commandTree value is 
            // preserved from the previous call.

            return parserException == null;
        }
示例#11
0
        private GeneratedView(EntitySetBase extent,
                              EdmType type,
                              DbQueryCommandTree commandTree,
                              string eSQL,
                              DiscriminatorMap discriminatorMap,
                              StorageMappingItemCollection mappingItemCollection,
                              ConfigViewGenerator config)
        {
            // At least one of the commandTree or eSQL must be specified. 
            // Both are specified in the case of user-defined views.
            Debug.Assert(commandTree != null || !String.IsNullOrEmpty(eSQL), "commandTree or eSQL must be specified");

            m_extent = extent;
            m_type = type;
            m_commandTree = commandTree;
            m_eSQL = eSQL;
            m_discriminatorMap = discriminatorMap;
            m_mappingItemCollection = mappingItemCollection;
            m_config = config;

            if (m_config.IsViewTracing)
            {
                StringBuilder trace = new StringBuilder(1024);
                this.ToCompactString(trace);
                Helpers.FormatTraceLine("CQL view for {0}", trace.ToString());
            }
        }
 protected virtual void VisitQueryCommandTree(DbQueryCommandTree queryTree)
 {
     EntityUtil.CheckArgumentNull(queryTree, "queryTree");
     this.VisitExpression(queryTree.Query);
 }
示例#13
0
 public SqlSelectGenerator(DbQueryCommandTree commandTree)
 {
     _commandTree = commandTree;
 }
 protected virtual void VisitQueryCommandTree(DbQueryCommandTree queryTree)
 {
     //Contract.Requires(queryTree != null);
     VisitExpression(queryTree.Query);
 }
        /// <summary>
        /// Generates provider specific, read only SQL and updates entitySet DefiningQuery 
        /// </summary>
        /// <param name="entitySet"></param>
        /// <param name="metadataWorkspace"></param>
        private void FixupViewEntitySetDefiningQuery(EntitySet entitySet, MetadataWorkspace metadataWorkspace)
        {
            DbExpressionBinding inputBinding = DbExpressionBuilder.BindAs(DbExpressionBuilder.Scan(entitySet), entitySet.Name);
            List<KeyValuePair<string, DbExpression>> projectList = new List<KeyValuePair<string, DbExpression>>(entitySet.ElementType.Members.Count);
            foreach (EdmMember member in entitySet.ElementType.Members)
            {
                Debug.Assert(member.BuiltInTypeKind == BuiltInTypeKind.EdmProperty, "Every member must be a edmproperty");
                EdmProperty propertyInfo = (EdmProperty)member;
                projectList.Add(new KeyValuePair<string, DbExpression>(member.Name,
                                                                       DbExpressionBuilder.Property(inputBinding.Variable, propertyInfo)));
            }
            DbExpression query = inputBinding.Project(DbExpressionBuilder.NewRow(projectList));
            DbQueryCommandTree dbCommandTree = new DbQueryCommandTree(metadataWorkspace, DataSpace.SSpace, query);

            //
            // get provider SQL and set entitySet DefiningQuery
            //
            entitySet.DefiningQuery = (DbProviderServices.GetProviderServices(_loader.EntityConnection.StoreProviderFactory)
                                                            .CreateCommandDefinition(dbCommandTree))
                                                                .CreateCommand().CommandText;

            Debug.Assert(!String.IsNullOrEmpty(entitySet.DefiningQuery), "DefiningQuery must not be null or empty");
        }
 protected virtual void VisitQueryCommandTree(DbQueryCommandTree queryTree)
 {
     EntityUtil.CheckArgumentNull(queryTree, "queryTree");
     this.VisitExpression(queryTree.Query);
 }