Example #1
0
        internal ViewgenContext(
            ViewTarget viewTarget, EntitySetBase extent, IList <Cell> extentCells,
            CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap, EntityContainerMapping entityContainerMapping)
        {
            foreach (var cell in extentCells)
            {
                Debug.Assert(extent.Equals(cell.GetLeftQuery(viewTarget).Extent));
                Debug.Assert(cell.CQuery.NumProjectedSlots == cell.SQuery.NumProjectedSlots);
            }

            m_extent                 = extent;
            m_viewTarget             = viewTarget;
            m_config                 = config;
            m_edmItemCollection      = entityContainerMapping.StorageMappingItemCollection.EdmItemCollection;
            m_entityContainerMapping = entityContainerMapping;
            m_identifiers            = identifiers;

            // create a copy of updateDomainMap so generation of query views later on is not affected
            // it is modified in QueryRewriter.AdjustMemberDomainsForUpdateViews
            updateDomainMap = updateDomainMap.MakeCopy();

            // Create a signature generator that handles all the
            // multiconstant work and generating the signatures
            var domainMap = viewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap;

            m_memberMaps = new MemberMaps(
                viewTarget, MemberProjectionIndex.Create(extent, m_edmItemCollection), queryDomainMap, updateDomainMap);

            // Create left fragment KB: includes constraints for the extent to be constructed
            var leftKB = new FragmentQueryKBChaseSupport();

            leftKB.CreateVariableConstraints(extent, domainMap, m_edmItemCollection);
            m_leftFragmentQP = new FragmentQueryProcessor(leftKB);
            m_rewritingCache = new Dictionary <FragmentQuery, Tile <FragmentQuery> >(
                FragmentQuery.GetEqualityComparer(m_leftFragmentQP));

            // Now using the signatures, create new cells such that
            // "extent's" query (C or S) is described in terms of multiconstants
            if (!CreateLeftCellWrappers(extentCells, viewTarget))
            {
                return;
            }

            // Create right fragment KB: includes constraints for all extents and association roles of right queries
            var rightKB        = new FragmentQueryKBChaseSupport();
            var rightDomainMap = viewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap;

            foreach (var leftCellWrapper in m_cellWrappers)
            {
                var rightExtent = leftCellWrapper.RightExtent;
                rightKB.CreateVariableConstraints(rightExtent, rightDomainMap, m_edmItemCollection);
                rightKB.CreateAssociationConstraints(rightExtent, rightDomainMap, m_edmItemCollection);
            }

            if (m_viewTarget == ViewTarget.UpdateView)
            {
                CreateConstraintsForForeignKeyAssociationsAffectingThisWrapper(rightKB, rightDomainMap);
            }

            m_rightFragmentQP = new FragmentQueryProcessor(rightKB);

            // Check for concurrency control tokens
            if (m_viewTarget == ViewTarget.QueryView)
            {
                CheckConcurrencyControlTokens();
            }
            // For backward compatibility -
            // order wrappers by increasing domain size, decreasing number of attributes
            m_cellWrappers.Sort(LeftCellWrapper.Comparer);
        }
Example #2
0
        // effects: Returns a context corresponding to extent (if one does not exist, creates one)
        private ViewgenContext CreateViewgenContext(EntitySetBase extent, ViewTarget viewTarget, CqlIdentifiers identifiers)
        {
            QueryRewriter queryRewriter;

            if (!m_queryRewriterCache.TryGetValue(extent, out queryRewriter))
            {
                // collect the cells that belong to this extent (just a few of them since we segment the mapping first)
                var cellsForExtent = m_cellGroup.Where(c => c.GetLeftQuery(viewTarget).Extent == extent).ToList();

                return(new ViewgenContext(
                           viewTarget, extent, cellsForExtent, identifiers, m_config, m_queryDomainMap, m_updateDomainMap, m_entityContainerMapping));
            }
            else
            {
                return(queryRewriter.ViewgenContext);
            }
        }
Example #3
0
        private QueryRewriter GenerateViewsForExtentAndType(EdmType generatedType, ViewgenContext context, CqlIdentifiers identifiers, ViewSet views, ViewGenMode mode)
        {
            Debug.Assert(mode != ViewGenMode.GenerateAllViews, "By definition this method can not handle generating views for all extents");

            QueryRewriter queryRewriter = new QueryRewriter(generatedType, context, mode);

            queryRewriter.GenerateViewComponents();

            // Get the basic view
            CellTreeNode basicView = queryRewriter.BasicView;

            if (m_config.IsNormalTracing)
            {
                Helpers.StringTrace("Basic View: ");
                Helpers.StringTraceLine(basicView.ToString());
            }

            CellTreeNode simplifiedView = GenerateSimplifiedView(basicView, queryRewriter.UsedCells);

            if (m_config.IsNormalTracing)
            {
                Helpers.StringTraceLine(String.Empty);
                Helpers.StringTrace("Simplified View: ");
                Helpers.StringTraceLine(simplifiedView.ToString());
            }

            CqlGenerator cqlGen = new CqlGenerator(simplifiedView,
                                                   queryRewriter.CaseStatements,
                                                   identifiers,
                                                   context.MemberMaps.ProjectedSlotMap,
                                                   queryRewriter.UsedCells.Count,
                                                   queryRewriter.TopLevelWhereClause,
                                                   m_entityContainerMapping.StorageMappingItemCollection);

            string             eSQLView;
            DbQueryCommandTree commandTree;

            if (m_config.GenerateEsql)
            {
                eSQLView    = cqlGen.GenerateEsql();
                commandTree = null;
            }
            else
            {
                eSQLView    = null;
                commandTree = cqlGen.GenerateCqt();
            }

            GeneratedView generatedView = GeneratedView.CreateGeneratedView(context.Extent, generatedType, commandTree, eSQLView, m_entityContainerMapping.StorageMappingItemCollection, m_config);

            views.Add(context.Extent, generatedView);

            return(queryRewriter);
        }
 /// <summary>
 ///     Creates a union block with SELECT (<paramref name="slotInfos" />), FROM (<paramref name="children" />), WHERE (true), AS (
 ///     <paramref
 ///         name="blockAliasNum" />
 ///     ).
 /// </summary>
 internal UnionCqlBlock(SlotInfo[] slotInfos, List <CqlBlock> children, CqlIdentifiers identifiers, int blockAliasNum)
     : base(slotInfos, children, BoolExpression.True, identifiers, blockAliasNum)
 {
 }
Example #5
0
        private ErrorLog GenerateQueryViewForExtentAndType(StorageEntityContainerMapping entityContainerMapping, CqlIdentifiers identifiers, ViewSet views, EntitySetBase entity, EntityTypeBase type, ViewGenMode mode)
        {
            Debug.Assert(mode != ViewGenMode.GenerateAllViews);

            // Keep track of the mapping exceptions that we have generated
            ErrorLog errorLog = new ErrorLog();

            if (m_config.IsViewTracing)
            {
                Helpers.StringTraceLine(String.Empty);
                Helpers.StringTraceLine(String.Empty);
                Helpers.FormatTraceLine("================= Generating {0} Query View for: {1} ===========================",
                                        (mode == ViewGenMode.OfTypeViews) ? "OfType" : "OfTypeOnly",
                                        entity.Name);
                Helpers.StringTraceLine(String.Empty);
                Helpers.StringTraceLine(String.Empty);
            }

            try
            {
                // (1) view generation (checks that extents are fully mapped)
                ViewgenContext context       = CreateViewgenContext(entity, ViewTarget.QueryView, identifiers);
                QueryRewriter  queryRewriter = GenerateViewsForExtentAndType(type, context, identifiers, views, mode);
            }
            catch (InternalMappingException exception)
            {
                // All exceptions have mapping errors in them
                Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                errorLog.Merge(exception.ErrorLog);
            }

            return(errorLog);
        }
Example #6
0
        // effects: Generates a view for an extent "extent" that belongs to
        // schema "schema". extentCells are the cells for this extent.
        // Adds the view corrsponding to the extent to "views"
        private QueryRewriter GenerateDirectionalViewsForExtent(ViewTarget viewTarget, EntitySetBase extent, CqlIdentifiers identifiers, ViewSet views)
        {
            // First normalize the cells in terms of multiconstants, etc
            // and then generate the view for the extent
            ViewgenContext context       = CreateViewgenContext(extent, viewTarget, identifiers);
            QueryRewriter  queryRewriter = null;

            if (m_config.GenerateViewsForEachType)
            {
                // generate views for each OFTYPE(Extent, Type) combination
                foreach (EdmType type in MetadataHelper.GetTypeAndSubtypesOf(extent.ElementType, m_entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, false /*includeAbstractTypes*/))
                {
                    if (m_config.IsViewTracing && false == type.Equals(extent.ElementType))
                    {
                        Helpers.FormatTraceLine("CQL View for {0} and type {1}", extent.Name, type.Name);
                    }
                    queryRewriter = GenerateViewsForExtentAndType(type, context, identifiers, views, ViewGenMode.OfTypeViews);
                }
            }
            else
            {
                // generate the view for Extent only
                queryRewriter = GenerateViewsForExtentAndType(extent.ElementType, context, identifiers, views, ViewGenMode.OfTypeViews);
            }
            if (viewTarget == ViewTarget.QueryView)
            {
                m_config.SetTimeForFinishedActivity(PerfType.QueryViews);
            }
            else
            {
                m_config.SetTimeForFinishedActivity(PerfType.UpdateViews);
            }

            // cache this rewriter (and context inside it) for future use in FK checking
            m_queryRewriterCache[extent] = queryRewriter;
            return(queryRewriter);
        }
Example #7
0
        // effects: Given a list of cells in the schema, generates the query and
        // update mapping views for OFTYPE(Extent, Type) combinations in this schema
        // container. Returns a list of generated query and update views.
        // If it is false and some columns in a table are unmapped, an
        // exception is raised
        private static ViewGenResults GenerateViewsFromCells(
            List <Cell> cells, ConfigViewGenerator config,
            CqlIdentifiers identifiers,
            EntityContainerMapping containerMapping)
        {
            DebugCheck.NotNull(cells);
            DebugCheck.NotNull(config);
            Debug.Assert(cells.Count > 0, "There must be at least one cell in the container mapping");

            // Go through each table and determine their foreign key constraints
            var container = containerMapping.StorageEntityContainer;

            Debug.Assert(container != null);

            var viewGenResults = new ViewGenResults();
            var tmpLog         = EnsureAllCSpaceContainerSetsAreMapped(cells, containerMapping);

            if (tmpLog.Count > 0)
            {
                viewGenResults.AddErrors(tmpLog);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                return(viewGenResults);
            }

            var foreignKeyConstraints = ForeignConstraint.GetForeignConstraints(container);

            var partitioner = new CellPartitioner(cells, foreignKeyConstraints);
            var cellGroups  = partitioner.GroupRelatedCells();

            foreach (var cellGroup in cellGroups)
            {
                ViewGenerator viewGenerator = null;
                var           groupErrorLog = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping);
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                    groupErrorLog = exception.ErrorLog;
                }

                if (groupErrorLog.Count == 0)
                {
                    Debug.Assert(viewGenerator != null);
                    groupErrorLog = viewGenerator.GenerateAllBidirectionalViews(viewGenResults.Views, identifiers);
                }

                if (groupErrorLog.Count != 0)
                {
                    viewGenResults.AddErrors(groupErrorLog);
                }
            }
            // We used to print the errors here. Now we trace them as they are being thrown
            //if (viewGenResults.HasErrors && config.IsViewTracing) {
            //    Helpers.StringTraceLine(viewGenResults.ErrorsToString());
            //}
            return(viewGenResults);
        }
Example #8
0
 // <summary>
 // Initializes a <see cref="CqlBlock" /> with the SELECT (<paramref name="slotInfos" />), FROM (
 // <paramref
 //     name="children" />
 // ),
 // WHERE (<paramref name="whereClause" />), AS (<paramref name="blockAliasNum" />).
 // </summary>
 protected CqlBlock(
     SlotInfo[] slotInfos, List <CqlBlock> children, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum)
 {
     m_slots       = new ReadOnlyCollection <SlotInfo>(slotInfos);
     m_children    = new ReadOnlyCollection <CqlBlock>(children);
     m_whereClause = whereClause;
     m_blockAlias  = identifiers.GetBlockAlias(blockAliasNum);
 }
Example #9
0
 // <summary>
 // Creates a <see cref="CqlBlock" /> containing the case statememt for the <paramref name="caseSlot" /> and projecting other slots as is from its child (input). CqlBlock with SELECT (slots),
 // </summary>
 // <param name="caseSlot">
 // indicates which slot in <paramref name="slots" /> corresponds to the case statement being generated by this block
 // </param>
 internal CaseCqlBlock(
     SlotInfo[] slots, int caseSlot, CqlBlock child, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum)
     : base(slots, new List <CqlBlock>(new[] { child }), whereClause, identifiers, blockAliasNum)
 {
     m_caseSlotInfo = slots[caseSlot];
 }
        internal static ViewGenResults GenerateTypeSpecificQueryView(
            EntityContainerMapping containerMapping,
            ConfigViewGenerator config,
            EntitySetBase entity,
            EntityTypeBase type,
            bool includeSubtypes,
            out bool success)
        {
            if (config.IsNormalTracing)
            {
                Helpers.StringTraceLine("");
                Helpers.StringTraceLine("<<<<<<<< Generating Query View for Entity [" + entity.Name + "] OfType" + (includeSubtypes ? "" : "Only") + "(" + type.Name + ") >>>>>>>");
            }
            if (containerMapping.GetEntitySetMapping(entity.Name).QueryView != null)
            {
                success = false;
                return((ViewGenResults)null);
            }
            InputForComputingCellGroups args       = new InputForComputingCellGroups(containerMapping, config);
            OutputFromComputeCellGroups cellgroups = containerMapping.GetCellgroups(args);

            success = cellgroups.Success;
            if (!success)
            {
                return((ViewGenResults)null);
            }
            List <ForeignConstraint> foreignKeyConstraints = cellgroups.ForeignKeyConstraints;
            List <Set <Cell> >       list = cellgroups.CellGroups.Select <Set <Cell>, Set <Cell> >((Func <Set <Cell>, Set <Cell> >)(setOfcells => new Set <Cell>(setOfcells.Select <Cell, Cell>((Func <Cell, Cell>)(cell => new Cell(cell)))))).ToList <Set <Cell> >();
            List <Cell>    cells          = cellgroups.Cells;
            CqlIdentifiers identifiers    = cellgroups.Identifiers;
            ViewGenResults viewGenResults = new ViewGenResults();
            ErrorLog       errorLog1      = ViewgenGatekeeper.EnsureAllCSpaceContainerSetsAreMapped((IEnumerable <Cell>)cells, containerMapping);

            if (errorLog1.Count > 0)
            {
                viewGenResults.AddErrors(errorLog1);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                success = true;
                return(viewGenResults);
            }
            foreach (Set <Cell> set in list)
            {
                if (ViewgenGatekeeper.DoesCellGroupContainEntitySet(set, entity))
                {
                    ViewGenerator viewGenerator = (ViewGenerator)null;
                    ErrorLog      errorLog2     = new ErrorLog();
                    try
                    {
                        viewGenerator = new ViewGenerator(set, config, foreignKeyConstraints, containerMapping);
                    }
                    catch (InternalMappingException ex)
                    {
                        errorLog2 = ex.ErrorLog;
                    }
                    if (errorLog2.Count <= 0)
                    {
                        ViewGenMode mode = includeSubtypes ? ViewGenMode.OfTypeViews : ViewGenMode.OfTypeOnlyViews;
                        ErrorLog    viewForSingleExtent = viewGenerator.GenerateQueryViewForSingleExtent(viewGenResults.Views, identifiers, entity, type, mode);
                        if (viewForSingleExtent.Count != 0)
                        {
                            viewGenResults.AddErrors(viewForSingleExtent);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            success = true;
            return(viewGenResults);
        }
Example #11
0
        /// <summary>
        /// Entry point for Type specific generation of Query Views
        /// </summary>
        internal static ViewGenResults GenerateTypeSpecificQueryView(StorageEntityContainerMapping containerMapping,
                                                                     ConfigViewGenerator config,
                                                                     EntitySetBase entity,
                                                                     EntityTypeBase type,
                                                                     bool includeSubtypes,
                                                                     out bool success)
        {
            EntityUtil.CheckArgumentNull(containerMapping, "containerMapping");
            EntityUtil.CheckArgumentNull(config, "config");
            EntityUtil.CheckArgumentNull(entity, "entity");
            EntityUtil.CheckArgumentNull(type, "type");
            Debug.Assert(!type.Abstract, "Can not generate OfType/OfTypeOnly query view for and abstract type");

            if (config.IsNormalTracing)
            {
                Helpers.StringTraceLine("");
                Helpers.StringTraceLine("<<<<<<<< Generating Query View for Entity [" + entity.Name + "] OfType" + (includeSubtypes ? "" : "Only") + "(" + type.Name + ") >>>>>>>");
            }

            if (containerMapping.GetEntitySetMapping(entity.Name).QueryView != null)
            {
                //Type-specific QV does not exist in the cache, but
                // there is a EntitySet QV. So we can't generate the view (no mapping exists for this EntitySet)
                // and we rely on Query to call us again to get the EntitySet View.
                success = false;
                return(null);
            }

            //Compute Cell Groups or get it from Memoizer
            InputForComputingCellGroups args   = new InputForComputingCellGroups(containerMapping, config);
            OutputFromComputeCellGroups result = containerMapping.GetCellgroups(args);

            success = result.Success;

            if (!success)
            {
                return(null);
            }

            List <ForeignConstraint> foreignKeyConstraints = result.ForeignKeyConstraints;
            // Get a Clone of cell groups from cache since cells are modified during viewgen, and we dont want the cached copy to change
            List <CellGroup> cellGroups  = cellGroups = result.CellGroups.Select(setOfcells => new CellGroup(setOfcells.Select(cell => new Cell(cell)))).ToList();
            List <Cell>      cells       = result.Cells;
            CqlIdentifiers   identifiers = result.Identifiers;


            ViewGenResults viewGenResults = new ViewGenResults();
            ErrorLog       tmpLog         = EnsureAllCSpaceContainerSetsAreMapped(cells, config, containerMapping);

            if (tmpLog.Count > 0)
            {
                viewGenResults.AddErrors(tmpLog);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                success = true; //atleast we tried successfully
                return(viewGenResults);
            }

            foreach (CellGroup cellGroup in cellGroups)
            {
                if (!DoesCellGroupContainEntitySet(cellGroup, entity))
                {
                    continue;
                }

                ViewGenerator viewGenerator = null;
                ErrorLog      groupErrorLog = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping);
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                    groupErrorLog = exception.ErrorLog;
                }

                if (groupErrorLog.Count > 0)
                {
                    break;
                }
                Debug.Assert(viewGenerator != null); //make sure there is no exception thrown that does not add error to log

                ViewGenMode mode = includeSubtypes ? ViewGenMode.OfTypeViews : ViewGenMode.OfTypeOnlyViews;

                groupErrorLog = viewGenerator.GenerateQueryViewForSingleExtent(viewGenResults.Views, identifiers, entity, type, mode);

                if (groupErrorLog.Count != 0)
                {
                    viewGenResults.AddErrors(groupErrorLog);
                }
            }

            success = true;
            return(viewGenResults);
        }
Example #12
0
 // effects: Creates a cell creator object for an entity container's
 // mappings (specified in "maps")
 internal CellCreator(StorageEntityContainerMapping containerMapping)
 {
     m_containerMapping = containerMapping;
     m_identifiers      = new CqlIdentifiers();
 }
Example #13
0
 internal CellCreator(EntityContainerMapping containerMapping)
 {
     this.m_containerMapping = containerMapping;
     this.m_identifiers      = new CqlIdentifiers();
 }