// requires: constraint.ChildColumns form a key in
        // constraint.ChildTable (actually they should subsume the primary key)
        private void GuaranteeForeignKeyConstraintInCSpace(QueryRewriter childRewriter, QueryRewriter parentRewriter,
                                                           ErrorLog errorLog, ConfigViewGenerator config)
        {
            ViewgenContext childContext  = childRewriter.ViewgenContext;
            ViewgenContext parentContext = parentRewriter.ViewgenContext;
            CellTreeNode   cNode         = childRewriter.BasicView;
            CellTreeNode   pNode         = parentRewriter.BasicView;

            FragmentQueryProcessor qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            bool cImpliesP            = qp.IsContainedIn(cNode.RightFragmentQuery, pNode.RightFragmentQuery);

            if (false == cImpliesP)
            {
                // Foreign key constraint not being ensured in C-space
                string childExtents  = LeftCellWrapper.GetExtentListAsUserString(cNode.GetLeaves());
                string parentExtents = LeftCellWrapper.GetExtentListAsUserString(pNode.GetLeaves());
                string message       = System.Data.Entity.Strings.ViewGen_Foreign_Key_Not_Guaranteed_InCSpace(
                    ToUserString());
                // Add all wrappers into allWrappers
                Set <LeftCellWrapper> allWrappers = new Set <LeftCellWrapper>(pNode.GetLeaves());
                allWrappers.AddRange(cNode.GetLeaves());
                ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ForeignKeyNotGuaranteedInCSpace, message, allWrappers, String.Empty);
                errorLog.AddEntry(record);
            }
        }
示例#2
0
        // requires: constraint.ChildColumns form a key in
        // constraint.ChildTable (actually they should subsume the primary key)
        private void GuaranteeForeignKeyConstraintInCSpace(
            QueryRewriter childRewriter, QueryRewriter parentRewriter,
            ErrorLog errorLog)
        {
            var childContext  = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;
            var cNode         = childRewriter.BasicView;
            var pNode         = parentRewriter.BasicView;

            var qp        = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            var cImpliesP = qp.IsContainedIn(cNode.RightFragmentQuery, pNode.RightFragmentQuery);

            if (false == cImpliesP)
            {
                // Foreign key constraint not being ensured in C-space
                var childExtents  = LeftCellWrapper.GetExtentListAsUserString(cNode.GetLeaves());
                var parentExtents = LeftCellWrapper.GetExtentListAsUserString(pNode.GetLeaves());
                var message       = Strings.ViewGen_Foreign_Key_Not_Guaranteed_InCSpace(
                    ToUserString());
                // Add all wrappers into allWrappers
                var allWrappers = new Set <LeftCellWrapper>(pNode.GetLeaves());
                allWrappers.AddRange(cNode.GetLeaves());
                var record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyNotGuaranteedInCSpace, message, allWrappers, String.Empty);
                errorLog.AddEntry(record);
            }
        }
示例#3
0
        private static FragmentQuery GenerateFragmentQuery(IEnumerable <CellTreeNode> children, bool isLeft, ViewgenContext context, CellTreeOpType OpType)
        {
            Debug.Assert(children.Any());
            FragmentQuery fragmentQuery = isLeft ? children.First().LeftFragmentQuery : children.First().RightFragmentQuery;

            FragmentQueryProcessor qp = isLeft ? context.LeftFragmentQP : context.RightFragmentQP;

            foreach (var child in children.Skip(1))
            {
                FragmentQuery nextQuery = isLeft ? child.LeftFragmentQuery : child.RightFragmentQuery;
                switch (OpType)
                {
                case CellTreeOpType.IJ:
                    fragmentQuery = qp.Intersect(fragmentQuery, nextQuery);
                    break;

                case CellTreeOpType.LOJ:
                    // Left outer join means keeping the domain of the leftmost child
                    break;

                case CellTreeOpType.LASJ:
                    // not used in basic view generation but current validation calls Simplify, so add this for debugging
                    fragmentQuery = qp.Difference(fragmentQuery, nextQuery);
                    break;

                default:
                    // All other operators (Union, FOJ) require union of the domains
                    fragmentQuery = qp.Union(fragmentQuery, nextQuery);
                    break;
                }
            }
            return(fragmentQuery);
        }
        private static FragmentQuery GenerateFragmentQuery(
            IEnumerable <CellTreeNode> children,
            bool isLeft,
            ViewgenContext context,
            CellTreeOpType OpType)
        {
            FragmentQuery          fragmentQuery1         = isLeft ? children.First <CellTreeNode>().LeftFragmentQuery : children.First <CellTreeNode>().RightFragmentQuery;
            FragmentQueryProcessor fragmentQueryProcessor = isLeft ? context.LeftFragmentQP : context.RightFragmentQP;

            foreach (CellTreeNode cellTreeNode in children.Skip <CellTreeNode>(1))
            {
                FragmentQuery fragmentQuery2 = isLeft ? cellTreeNode.LeftFragmentQuery : cellTreeNode.RightFragmentQuery;
                switch (OpType)
                {
                case CellTreeOpType.LOJ:
                    continue;

                case CellTreeOpType.IJ:
                    fragmentQuery1 = fragmentQueryProcessor.Intersect(fragmentQuery1, fragmentQuery2);
                    continue;

                case CellTreeOpType.LASJ:
                    fragmentQuery1 = fragmentQueryProcessor.Difference(fragmentQuery1, fragmentQuery2);
                    continue;

                default:
                    fragmentQuery1 = fragmentQueryProcessor.Union(fragmentQuery1, fragmentQuery2);
                    continue;
                }
            }
            return(fragmentQuery1);
        }
        internal ViewgenContext(
            ViewTarget viewTarget,
            EntitySetBase extent,
            IList <Cell> extentCells,
            CqlIdentifiers identifiers,
            ConfigViewGenerator config,
            MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap,
            EntityContainerMapping entityContainerMapping)
        {
            foreach (Cell extentCell in (IEnumerable <Cell>)extentCells)
            {
                ;
            }
            this.m_extent                 = extent;
            this.m_viewTarget             = viewTarget;
            this.m_config                 = config;
            this.m_edmItemCollection      = entityContainerMapping.StorageMappingItemCollection.EdmItemCollection;
            this.m_entityContainerMapping = entityContainerMapping;
            this.m_identifiers            = identifiers;
            updateDomainMap               = updateDomainMap.MakeCopy();
            MemberDomainMap domainMap = viewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap;

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

            kb1.CreateVariableConstraints(extent, domainMap, this.m_edmItemCollection);
            this.m_leftFragmentQP = new FragmentQueryProcessor(kb1);
            this.m_rewritingCache = new Dictionary <FragmentQuery, Tile <FragmentQuery> >(FragmentQuery.GetEqualityComparer(this.m_leftFragmentQP));
            if (!this.CreateLeftCellWrappers(extentCells, viewTarget))
            {
                return;
            }
            FragmentQueryKBChaseSupport kb2             = new FragmentQueryKBChaseSupport();
            MemberDomainMap             memberDomainMap = viewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap;

            foreach (LeftCellWrapper cellWrapper in this.m_cellWrappers)
            {
                EntitySetBase rightExtent = cellWrapper.RightExtent;
                kb2.CreateVariableConstraints(rightExtent, memberDomainMap, this.m_edmItemCollection);
                kb2.CreateAssociationConstraints(rightExtent, memberDomainMap, this.m_edmItemCollection);
            }
            if (this.m_viewTarget == ViewTarget.UpdateView)
            {
                this.CreateConstraintsForForeignKeyAssociationsAffectingThisWrapper((FragmentQueryKB)kb2, memberDomainMap);
            }
            this.m_rightFragmentQP = new FragmentQueryProcessor(kb2);
            if (this.m_viewTarget == ViewTarget.QueryView)
            {
                this.CheckConcurrencyControlTokens();
            }
            this.m_cellWrappers.Sort(LeftCellWrapper.Comparer);
        }
        private static bool CheckConstraintWhenOnlyParentMapped(
            AssociationSet assocSet,
            AssociationEndMember endMember,
            QueryRewriter childRewriter,
            QueryRewriter parentRewriter)
        {
            ViewgenContext viewgenContext1 = childRewriter.ViewgenContext;
            ViewgenContext viewgenContext2 = parentRewriter.ViewgenContext;
            CellTreeNode   basicView       = parentRewriter.BasicView;
            RoleBoolean    roleBoolean     = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]);
            BoolExpression whereClause     = basicView.RightFragmentQuery.Condition.Create((BoolLiteral)roleBoolean);
            FragmentQuery  q1 = FragmentQuery.Create((IEnumerable <MemberPath>)basicView.RightFragmentQuery.Attributes, whereClause);

            return(FragmentQueryProcessor.Merge(viewgenContext1.RightFragmentQP, viewgenContext2.RightFragmentQP).IsContainedIn(q1, basicView.RightFragmentQuery));
        }
示例#7
0
        // requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false
        // and primaryKeys of ChildTable are not mapped in cell. cell
        // corresponds to an association set. parentSet is the set
        // corresponding to the end that we are looking at
        // effects: Checks if the constraint is correctly maintained in
        // C-space via an association set (being a subset of the
        // corresponding entitySet)
        private static bool CheckConstraintWhenOnlyParentMapped(
            AssociationSet assocSet, AssociationEndMember endMember,
            QueryRewriter childRewriter, QueryRewriter parentRewriter)
        {
            var childContext  = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;

            var pNode = parentRewriter.BasicView;

            Debug.Assert(pNode != null);

            var endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]);
            // use query in pNode as a factory to create a bool expression for the endRoleBoolean
            var endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean);
            var cNodeQuery   = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition);

            var qp        = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            var cImpliesP = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery);

            return(cImpliesP);
        }
        // requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false
        // and primaryKeys of ChildTable are not mapped in cell. cell
        // corresponds to an association set. parentSet is the set
        // corresponding to the end that we are looking at
        // effects: Checks if the constraint is correctly maintained in
        // C-space via an association set (being a subset of the
        // corresponding entitySet)
        private bool CheckConstraintWhenOnlyParentMapped(Cell cell, EntitySet parentSet, AssociationSet assocSet, AssociationEndMember endMember,
                                                         QueryRewriter childRewriter, QueryRewriter parentRewriter,
                                                         ConfigViewGenerator config)
        {
            ViewgenContext childContext  = childRewriter.ViewgenContext;
            ViewgenContext parentContext = parentRewriter.ViewgenContext;

            CellTreeNode pNode = parentRewriter.BasicView;

            Debug.Assert(pNode != null);

            RoleBoolean endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]);
            // use query in pNode as a factory to create a bool expression for the endRoleBoolean
            BoolExpression endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean);
            FragmentQuery  cNodeQuery   = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition);

            FragmentQueryProcessor qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            bool cImpliesP            = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery);

            return(cImpliesP);
        }
        private void GuaranteeForeignKeyConstraintInCSpace(
            QueryRewriter childRewriter,
            QueryRewriter parentRewriter,
            ErrorLog errorLog)
        {
            ViewgenContext viewgenContext1 = childRewriter.ViewgenContext;
            ViewgenContext viewgenContext2 = parentRewriter.ViewgenContext;
            CellTreeNode   basicView1      = childRewriter.BasicView;
            CellTreeNode   basicView2      = parentRewriter.BasicView;

            if (FragmentQueryProcessor.Merge(viewgenContext1.RightFragmentQP, viewgenContext2.RightFragmentQP).IsContainedIn(basicView1.RightFragmentQuery, basicView2.RightFragmentQuery))
            {
                return;
            }
            LeftCellWrapper.GetExtentListAsUserString((IEnumerable <LeftCellWrapper>)basicView1.GetLeaves());
            LeftCellWrapper.GetExtentListAsUserString((IEnumerable <LeftCellWrapper>)basicView2.GetLeaves());
            string message            = Strings.ViewGen_Foreign_Key_Not_Guaranteed_InCSpace((object)this.ToUserString());
            Set <LeftCellWrapper> set = new Set <LeftCellWrapper>((IEnumerable <LeftCellWrapper>)basicView2.GetLeaves());

            set.AddRange((IEnumerable <LeftCellWrapper>)basicView1.GetLeaves());
            ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyNotGuaranteedInCSpace, message, (IEnumerable <LeftCellWrapper>)set, string.Empty);
            errorLog.AddEntry(record);
        }
示例#10
0
        internal ViewgenContext(
            ViewTarget viewTarget, EntitySetBase extent, IList <Cell> extentCells,
            CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap, StorageEntityContainerMapping 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);
        }
示例#11
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);
        }