private static void GetTypesAndConditionForWrapper(
     LeftCellWrapper wrapper,
     out bool hasCondition,
     out List <EdmType> edmTypes)
 {
     hasCondition = false;
     edmTypes     = new List <EdmType>();
     foreach (Cell cell in wrapper.Cells)
     {
         foreach (MemberRestriction condition in cell.CQuery.Conditions)
         {
             foreach (Constant constant in condition.Domain.Values)
             {
                 TypeConstant typeConstant = constant as TypeConstant;
                 if (typeConstant != null)
                 {
                     edmTypes.Add(typeConstant.EdmType);
                 }
                 else
                 {
                     hasCondition = true;
                 }
             }
         }
     }
 }
        private bool TryMergeCellQueries(
            CellTreeOpType opType,
            ref CellTreeNode node1,
            CellTreeNode node2)
        {
            LeafCellTreeNode leafCellTreeNode1 = node1 as LeafCellTreeNode;
            LeafCellTreeNode leafCellTreeNode2 = node2 as LeafCellTreeNode;
            CellQuery        mergedQuery1;
            CellQuery        mergedQuery2;

            if (!CellTreeSimplifier.TryMergeTwoCellQueries(leafCellTreeNode1.LeftCellWrapper.RightCellQuery, leafCellTreeNode2.LeftCellWrapper.RightCellQuery, opType, out mergedQuery1) || !CellTreeSimplifier.TryMergeTwoCellQueries(leafCellTreeNode1.LeftCellWrapper.LeftCellQuery, leafCellTreeNode2.LeftCellWrapper.LeftCellQuery, opType, out mergedQuery2))
            {
                return(false);
            }
            OpCellTreeNode opCellTreeNode = new OpCellTreeNode(this.m_viewgenContext, opType);

            opCellTreeNode.Add(node1);
            opCellTreeNode.Add(node2);
            if (opType != CellTreeOpType.FOJ)
            {
                ;
            }
            LeftCellWrapper cellWrapper = new LeftCellWrapper(this.m_viewgenContext.ViewTarget, opCellTreeNode.Attributes, opCellTreeNode.LeftFragmentQuery, mergedQuery2, mergedQuery1, this.m_viewgenContext.MemberMaps, leafCellTreeNode1.LeftCellWrapper.Cells.Concat <Cell>(leafCellTreeNode2.LeftCellWrapper.Cells));

            node1 = (CellTreeNode) new LeafCellTreeNode(this.m_viewgenContext, cellWrapper, opCellTreeNode.RightFragmentQuery);
            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// When we are dealing with an update view, this method
        /// finds out if the given Table is mapped to different EntitySets
        /// </summary>
        private void MatchSplitErrors()
        {
            List <LeftCellWrapper> leftCellWrappers = m_viewgenContext.AllWrappersForExtent;

            //Check that the given Table is mapped to only one EntitySet (avoid AssociationSets)
            var nonAssociationWrappers = leftCellWrappers.Where(r => !(r.LeftExtent is AssociationSet) && !(r.RightCellQuery.Extent is AssociationSet));

            if (m_viewgenContext.ViewTarget == ViewTarget.UpdateView && nonAssociationWrappers.Any())
            {
                LeftCellWrapper firstLeftCWrapper = nonAssociationWrappers.First();
                EntitySetBase   rightExtent       = firstLeftCWrapper.RightCellQuery.Extent;

                foreach (var leftCellWrapper in nonAssociationWrappers)
                {
                    //!(leftCellWrapper.RightCellQuery.Extent is AssociationSet) &&
                    if (!leftCellWrapper.RightCellQuery.Extent.EdmEquals(rightExtent))
                    {
                        //A Table may be mapped to two extents but the extents may be Equal (by some form of Refconstraint)
                        if (!RightSideEqual(leftCellWrapper, firstLeftCWrapper))
                        {
                            //Report Error
                            m_errorLog.AddEntry(new ErrorLog.Record(true, ViewGenErrorCode.ErrorPatternSplittingError,
                                                                    Strings.Viewgen_ErrorPattern_TableMappedToMultipleES(leftCellWrapper.LeftExtent.ToString(), leftCellWrapper.RightCellQuery.Extent.ToString(), rightExtent.ToString()),
                                                                    leftCellWrapper.Cells.First(), ""));
                        }
                    }
                }
            }
        }
        private void MatchSplitErrors()
        {
            IEnumerable <LeftCellWrapper> source = this.m_viewgenContext.AllWrappersForExtent.Where <LeftCellWrapper>((Func <LeftCellWrapper, bool>)(r =>
            {
                if (!(r.LeftExtent is AssociationSet))
                {
                    return(!(r.RightCellQuery.Extent is AssociationSet));
                }
                return(false);
            }));

            if (this.m_viewgenContext.ViewTarget != ViewTarget.UpdateView || !source.Any <LeftCellWrapper>())
            {
                return;
            }
            LeftCellWrapper wrapper2 = source.First <LeftCellWrapper>();
            EntitySetBase   extent   = wrapper2.RightCellQuery.Extent;

            foreach (LeftCellWrapper wrapper1 in source)
            {
                if (!wrapper1.RightCellQuery.Extent.EdmEquals((MetadataItem)extent) && !this.RightSideEqual(wrapper1, wrapper2))
                {
                    this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.ErrorPatternSplittingError, Strings.Viewgen_ErrorPattern_TableMappedToMultipleES((object)wrapper1.LeftExtent.ToString(), (object)wrapper1.RightCellQuery.Extent.ToString(), (object)extent.ToString()), wrapper1.Cells.First <Cell>(), ""));
                }
            }
        }
Exemplo n.º 5
0
        // effects: Given the cells for the extent (extentCells) along with
        // the signatures (multiconstants + needed attributes) for this extent, generates
        // the left cell wrappers for it extent (viewTarget indicates whether
        // the view is for querying or update purposes
        // Modifies m_cellWrappers to contain this list
        private bool CreateLeftCellWrappers(IList <Cell> extentCells, ViewTarget viewTarget)
        {
            var alignedCells = AlignFields(extentCells, m_memberMaps.ProjectedSlotMap, viewTarget);

            Debug.Assert(alignedCells.Count == extentCells.Count, "Cell counts disagree");

            // Go through all the cells and create cell wrappers that can be used for generating the view
            m_cellWrappers = new List <LeftCellWrapper>();

            for (var i = 0; i < alignedCells.Count; i++)
            {
                var alignedCell = alignedCells[i];
                var left        = alignedCell.GetLeftQuery(viewTarget);
                var right       = alignedCell.GetRightQuery(viewTarget);

                // Obtain the non-null projected slots into attributes
                var attributes = left.GetNonNullSlots();

                var fromVariable = BoolExpression.CreateLiteral(
                    new CellIdBoolean(m_identifiers, extentCells[i].CellNumber), m_memberMaps.LeftDomainMap);
                var leftFragmentQuery = FragmentQuery.Create(fromVariable, left);

                if (viewTarget == ViewTarget.UpdateView)
                {
                    leftFragmentQuery = m_leftFragmentQP.CreateDerivedViewBySelectingConstantAttributes(leftFragmentQuery)
                                        ?? leftFragmentQuery;
                }

                var leftWrapper = new LeftCellWrapper(
                    m_viewTarget, attributes, leftFragmentQuery, left, right, m_memberMaps,
                    extentCells[i]);
                m_cellWrappers.Add(leftWrapper);
            }
            return(true);
        }
Exemplo n.º 6
0
        private bool RightSideEqual(LeftCellWrapper wrapper1, LeftCellWrapper wrapper2)
        {
            var rightFragmentQuery1 = CreateRightFragmentQuery(wrapper1);
            var rightFragmentQuery2 = CreateRightFragmentQuery(wrapper2);

            return(m_viewgenContext.RightFragmentQP.IsEquivalentTo(rightFragmentQuery1, rightFragmentQuery2));
        }
Exemplo n.º 7
0
 // <summary>
 // Gets the types on the Edm side mapped in this fragment wrapper.
 // It also returns an out parameter indicating whether there were any C side conditions.
 // </summary>
 private static void GetTypesAndConditionForWrapper(LeftCellWrapper wrapper, out bool hasCondition, out List <EdmType> edmTypes)
 {
     hasCondition = false;
     edmTypes     = new List <EdmType>();
     //Figure out which type has no Cell mapped to it
     foreach (var cell in wrapper.Cells)
     {
         foreach (var restriction in cell.CQuery.Conditions)
         {
             foreach (var cellConst in restriction.Domain.Values)
             {
                 //if there is a mapping to this type...
                 var typeConst = cellConst as TypeConstant;
                 if (typeConst != null)
                 {
                     edmTypes.Add(typeConst.EdmType);
                 }
                 else
                 {
                     hasCondition = true;
                 }
             }
         }
     }
 }
        // 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);
            }
        }
Exemplo n.º 9
0
        internal static BoolExpression PropagateCellConstantsToWhereClause(
            LeftCellWrapper wrapper,
            BoolExpression expression,
            Constant constant,
            MemberPath member,
            MemberMaps memberMaps)
        {
            MemberProjectedSlot mappedSlotForSmember = wrapper.GetCSideMappedSlotForSMember(member);

            if (mappedSlotForSmember == null)
            {
                return(expression);
            }
            NegatedConstant        negatedConstant = constant as NegatedConstant;
            IEnumerable <Constant> domain          = memberMaps.QueryDomainMap.GetDomain(mappedSlotForSmember.MemberPath);
            Set <Constant>         set             = new Set <Constant>(Constant.EqualityComparer);

            if (negatedConstant != null)
            {
                set.Unite(domain);
                set.Difference(negatedConstant.Elements);
            }
            else
            {
                set.Add(constant);
            }
            MemberRestriction memberRestriction = (MemberRestriction) new ScalarRestriction(mappedSlotForSmember.MemberPath, (IEnumerable <Constant>)set, domain);

            return(BoolExpression.CreateAnd(expression, BoolExpression.CreateLiteral((BoolLiteral)memberRestriction, memberMaps.QueryDomainMap)));
        }
        internal static CellTreeNode TileToCellTree(
            Tile <FragmentQuery> tile,
            ViewgenContext context)
        {
            if (tile.OpKind == TileOpKind.Named)
            {
                FragmentQuery   view        = ((TileNamed <FragmentQuery>)tile).NamedQuery;
                LeftCellWrapper cellWrapper = context.AllWrappersForExtent.First <LeftCellWrapper>((Func <LeftCellWrapper, bool>)(w => w.FragmentQuery == view));
                return((CellTreeNode) new LeafCellTreeNode(context, cellWrapper));
            }
            CellTreeOpType opType;

            switch (tile.OpKind)
            {
            case TileOpKind.Union:
                opType = CellTreeOpType.Union;
                break;

            case TileOpKind.Join:
                opType = CellTreeOpType.IJ;
                break;

            case TileOpKind.AntiSemiJoin:
                opType = CellTreeOpType.LASJ;
                break;

            default:
                return((CellTreeNode)null);
            }
            return((CellTreeNode) new OpCellTreeNode(context, opType, new CellTreeNode[2]
            {
                QueryRewriter.TileToCellTree(tile.Arg1, context),
                QueryRewriter.TileToCellTree(tile.Arg2, context)
            }));
        }
Exemplo n.º 11
0
            internal static void CheckConstraints(CellTreeNode node, LeftCellWrapper wrapper,
                                                  ViewgenContext context, ErrorLog errorLog)
            {
                DomainConstraintVisitor visitor = new DomainConstraintVisitor(wrapper, context, errorLog);

                node.Accept <bool, bool>(visitor, true);
            }
Exemplo n.º 12
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);
            }
        }
        // requires: node1 and node2 are two children of the same parent
        // connected by opType
        // effects: Given two cell tree nodes, node1 and node2, runs the
        // TM/SP rule on them to merge them (if they belong to the same
        // extent). Returns true if the merge succeeds
        private bool TryMergeCellQueries(
            CellTreeOpType opType, ref CellTreeNode node1,
            CellTreeNode node2)
        {
            var leaf1 = node1 as LeafCellTreeNode;
            var leaf2 = node2 as LeafCellTreeNode;

            Debug.Assert(leaf1 != null, "Merge only possible on leaf nodes (1)");
            Debug.Assert(leaf2 != null, "Merge only possible on leaf nodes (2)");

            CellQuery mergedLeftCellQuery;
            CellQuery mergedRightCellQuery;

            if (
                !TryMergeTwoCellQueries(
                    leaf1.LeftCellWrapper.RightCellQuery, leaf2.LeftCellWrapper.RightCellQuery, opType, out mergedRightCellQuery))
            {
                return(false);
            }

            if (
                !TryMergeTwoCellQueries(
                    leaf1.LeftCellWrapper.LeftCellQuery, leaf2.LeftCellWrapper.LeftCellQuery, opType, out mergedLeftCellQuery))
            {
                return(false);
            }

            // Create a temporary node and add the two children
            // so that we can get the merged selectiondomains and attributes
            // Note that temp.SelectionDomain below determines the domain
            // based on the opType, e.g., for IJ, it intersects the
            // multiconstants of all the children
            var temp = new OpCellTreeNode(m_viewgenContext, opType);

            temp.Add(node1);
            temp.Add(node2);
            // Note: We are losing the original cell number information here and the line number information
            // But we will not raise any

            // We do not create CellExpressions with LOJ, FOJ - canBooleansOverlap is true for validation
            var inputOpType = opType;

            if (opType == CellTreeOpType.FOJ ||
                opType == CellTreeOpType.LOJ)
            {
                inputOpType = CellTreeOpType.IJ;
            }

            var wrapper = new LeftCellWrapper(
                m_viewgenContext.ViewTarget, temp.Attributes,
                temp.LeftFragmentQuery,
                mergedLeftCellQuery,
                mergedRightCellQuery,
                m_viewgenContext.MemberMaps,
                leaf1.LeftCellWrapper.Cells.Concat(leaf2.LeftCellWrapper.Cells));

            node1 = new LeafCellTreeNode(m_viewgenContext, wrapper, temp.RightFragmentQuery);
            return(true);
        }
 private bool CSideHasDifferentEntitySets(LeftCellWrapper a, LeftCellWrapper b)
 {
     if (this.IsQueryView())
     {
         return(a.LeftExtent == b.LeftExtent);
     }
     return(a.RightCellQuery == b.RightCellQuery);
 }
Exemplo n.º 15
0
 internal static void CheckConstraints(
     CellTreeNode node,
     LeftCellWrapper wrapper,
     ViewgenContext context,
     ErrorLog errorLog)
 {
     RewritingValidator.DomainConstraintVisitor constraintVisitor = new RewritingValidator.DomainConstraintVisitor(wrapper, context, errorLog);
     node.Accept <bool, bool>((CellTreeNode.SimpleCellTreeVisitor <bool, bool>)constraintVisitor, true);
 }
Exemplo n.º 16
0
 private DomainConstraintVisitor(
     LeftCellWrapper wrapper,
     ViewgenContext context,
     ErrorLog errorLog)
 {
     this.m_wrapper        = wrapper;
     this.m_viewgenContext = context;
     this.m_errorLog       = errorLog;
 }
 internal void EnsureExtentIsFullyMapped(HashSet <FragmentQuery> outputUsedViews)
 {
     if (this._context.ViewTarget == ViewTarget.QueryView && this._config.IsValidationEnabled)
     {
         this.EnsureConfigurationIsFullyMapped(this._extentPath, BoolExpression.True, outputUsedViews, this._errorLog);
         if (this._errorLog.Count <= 0)
         {
             return;
         }
         ExceptionHelpers.ThrowMappingException(this._errorLog, this._config);
     }
     else
     {
         if (this._config.IsValidationEnabled)
         {
             foreach (MemberPath member in this._context.MemberMaps.ProjectedSlotMap.Members)
             {
                 Constant defaultConstant;
                 if (member.IsScalarType() && !member.IsPartOfKey && (!this._domainMap.IsConditionMember(member) && !Domain.TryGetDefaultValueForMemberPath(member, out defaultConstant)))
                 {
                     HashSet <MemberPath> memberPathSet = new HashSet <MemberPath>((IEnumerable <MemberPath>) this._keyAttributes);
                     memberPathSet.Add(member);
                     foreach (LeftCellWrapper leftCellWrapper in this._context.AllWrappersForExtent)
                     {
                         FragmentQuery            fragmentQuery = leftCellWrapper.FragmentQuery;
                         Tile <FragmentQuery>     rewriting;
                         IEnumerable <MemberPath> notCoveredAttributes;
                         if (!this.RewriteQuery((Tile <FragmentQuery>)QueryRewriter.CreateTile(new FragmentQuery(fragmentQuery.Description, fragmentQuery.FromVariable, (IEnumerable <MemberPath>)memberPathSet, fragmentQuery.Condition)), (Tile <FragmentQuery>)QueryRewriter.CreateTile(FragmentQuery.Create((IEnumerable <MemberPath>) this._keyAttributes, BoolExpression.CreateNot(fragmentQuery.Condition))), out rewriting, out notCoveredAttributes, false))
                         {
                             Domain.GetDefaultValueForMemberPath(member, (IEnumerable <LeftCellWrapper>) new LeftCellWrapper[1]
                             {
                                 leftCellWrapper
                             }, this._config);
                         }
                     }
                 }
             }
         }
         foreach (Tile <FragmentQuery> view in this._views)
         {
             Tile <FragmentQuery>     toFill = view;
             Tile <FragmentQuery>     tile   = (Tile <FragmentQuery>)QueryRewriter.CreateTile(FragmentQuery.Create((IEnumerable <MemberPath>) this._keyAttributes, BoolExpression.CreateNot(toFill.Query.Condition)));
             Tile <FragmentQuery>     rewriting;
             IEnumerable <MemberPath> notCoveredAttributes;
             if (!this.RewriteQuery(toFill, tile, out rewriting, out notCoveredAttributes, true))
             {
                 LeftCellWrapper leftCellWrapper = this._context.AllWrappersForExtent.First <LeftCellWrapper>((Func <LeftCellWrapper, bool>)(lcr => lcr.FragmentQuery.Equals((object)toFill.Query)));
                 this._errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.ImpopssibleCondition, Strings.Viewgen_QV_RewritingNotFound((object)leftCellWrapper.RightExtent.ToString()), leftCellWrapper.Cells, string.Empty));
             }
             else
             {
                 outputUsedViews.UnionWith(rewriting.GetNamedQueries());
             }
         }
     }
 }
 private bool CompareS(
     ErrorPatternMatcher.ComparisonOP op,
     ViewgenContext context,
     LeftCellWrapper leftWrapper1,
     LeftCellWrapper leftWrapper2,
     FragmentQuery rightQuery1,
     FragmentQuery rightQuery2)
 {
     return(this.Compare(false, op, context, leftWrapper1, leftWrapper2, rightQuery1, rightQuery2));
 }
        private static MemberPath GetRightMemberPath(
            MemberPath conditionMember,
            LeftCellWrapper leftCellWrapper)
        {
            List <int> projectedPositions = leftCellWrapper.OnlyInputCell.GetRightQuery(ViewTarget.QueryView).GetProjectedPositions(conditionMember);

            if (projectedPositions.Count != 1)
            {
                return((MemberPath)null);
            }
            int slotNum = projectedPositions.First <int>();

            return(((MemberProjectedSlot)leftCellWrapper.OnlyInputCell.GetLeftQuery(ViewTarget.QueryView).ProjectedSlotAt(slotNum)).MemberPath);
        }
Exemplo n.º 20
0
 private void CheckConstraintsOnNonNullableMembers(LeftCellWrapper wrapper)
 {
     foreach (MemberPath nonConditionMember in this._domainMap.NonConditionMembers(this._viewgenContext.Extent))
     {
         bool flag = nonConditionMember.EdmType is System.Data.Entity.Core.Metadata.Edm.SimpleType;
         if (!nonConditionMember.IsNullable && flag)
         {
             FragmentQuery query = RewritingValidator.AddNullConditionOnCSideFragment(wrapper, nonConditionMember, this._viewgenContext.MemberMaps);
             if (query != null && this._viewgenContext.RightFragmentQP.IsSatisfiable(query))
             {
                 this._errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.NullableMappingForNonNullableColumn, Strings.Viewgen_NullableMappingForNonNullableColumn((object)wrapper.LeftExtent.ToString(), (object)nonConditionMember.ToFullString()), wrapper.Cells, ""));
             }
         }
     }
 }
Exemplo n.º 21
0
        private static MemberPath GetRightMemberPath(MemberPath conditionMember, LeftCellWrapper leftCellWrapper)
        {
            var rightCellQuery   = leftCellWrapper.OnlyInputCell.GetRightQuery(ViewTarget.QueryView);
            var projectPositions = rightCellQuery.GetProjectedPositions(conditionMember);

            //Make the case simple. If the member is mapped more than once in the same cell wrapper
            //we are not going try and guess the pattern
            if (projectPositions.Count != 1)
            {
                return(null);
            }
            var firstProjectedPosition = projectPositions.First();
            var leftCellQuery          = leftCellWrapper.OnlyInputCell.GetLeftQuery(ViewTarget.QueryView);

            return(((MemberProjectedSlot)leftCellQuery.ProjectedSlotAt(firstProjectedPosition)).MemberPath);
        }
Exemplo n.º 22
0
 private void CheckConstraintsOnProjectedConditionMembers(
     Dictionary <RewritingValidator.MemberValueBinding, CellTreeNode> memberValueTrees,
     LeftCellWrapper wrapper,
     CellTreeNode sQueryTree,
     BoolExpression inExtentCondition)
 {
     foreach (MemberPath conditionMember in this._domainMap.ConditionMembers(this._viewgenContext.Extent))
     {
         int slotNum = this._viewgenContext.MemberMaps.ProjectedSlotMap.IndexOf(conditionMember);
         MemberProjectedSlot memberProjectedSlot = wrapper.RightCellQuery.ProjectedSlotAt(slotNum) as MemberProjectedSlot;
         if (memberProjectedSlot != null)
         {
             foreach (Constant constant in this._domainMap.GetDomain(conditionMember))
             {
                 CellTreeNode cellTreeNode1;
                 if (memberValueTrees.TryGetValue(new RewritingValidator.MemberValueBinding(conditionMember, constant), out cellTreeNode1))
                 {
                     FragmentQuery cQuery = FragmentQuery.Create(RewritingValidator.PropagateCellConstantsToWhereClause(wrapper, wrapper.RightCellQuery.WhereClause, constant, conditionMember, this._viewgenContext.MemberMaps));
                     CellTreeNode  cellTreeNode2;
                     if (sQueryTree != this._basicView)
                     {
                         cellTreeNode2 = (CellTreeNode) new OpCellTreeNode(this._viewgenContext, CellTreeOpType.IJ, new CellTreeNode[2]
                         {
                             cellTreeNode1,
                             sQueryTree
                         });
                     }
                     else
                     {
                         cellTreeNode2 = cellTreeNode1;
                     }
                     CellTreeNode   cellTreeNode3 = cellTreeNode2;
                     BoolExpression unsatisfiedConstraint;
                     if (!this.CheckEquivalence(cQuery, cellTreeNode3.RightFragmentQuery, inExtentCondition, out unsatisfiedConstraint))
                     {
                         this.ReportConstraintViolation(Strings.ViewGen_CQ_DomainConstraint((object)memberProjectedSlot.ToUserString()), unsatisfiedConstraint, ViewGenErrorCode.DomainConstraintViolation, cellTreeNode3.GetLeaves().Concat <LeftCellWrapper>((IEnumerable <LeftCellWrapper>) new LeftCellWrapper[1]
                         {
                             wrapper
                         }));
                     }
                 }
             }
         }
     }
 }
        private bool Compare(
            bool lookingForC,
            ErrorPatternMatcher.ComparisonOP op,
            ViewgenContext context,
            LeftCellWrapper leftWrapper1,
            LeftCellWrapper leftWrapper2,
            FragmentQuery rightQuery1,
            FragmentQuery rightQuery2)
        {
            if (lookingForC && this.IsQueryView() || !lookingForC && !this.IsQueryView())
            {
                LCWComparer lcwComparer;
                switch (op)
                {
                case ErrorPatternMatcher.ComparisonOP.IsContainedIn:
                    lcwComparer = new LCWComparer(context.LeftFragmentQP.IsContainedIn);
                    break;

                case ErrorPatternMatcher.ComparisonOP.IsDisjointFrom:
                    lcwComparer = new LCWComparer(context.LeftFragmentQP.IsDisjointFrom);
                    break;

                default:
                    return(false);
                }
                return(lcwComparer(leftWrapper1.FragmentQuery, leftWrapper2.FragmentQuery));
            }
            LCWComparer lcwComparer1;

            switch (op)
            {
            case ErrorPatternMatcher.ComparisonOP.IsContainedIn:
                lcwComparer1 = new LCWComparer(context.RightFragmentQP.IsContainedIn);
                break;

            case ErrorPatternMatcher.ComparisonOP.IsDisjointFrom:
                lcwComparer1 = new LCWComparer(context.RightFragmentQP.IsDisjointFrom);
                break;

            default:
                return(false);
            }
            return(lcwComparer1(rightQuery1, rightQuery2));
        }
Exemplo n.º 24
0
        private bool Compare(
            bool lookingForC, ComparisonOP op, ViewgenContext context, LeftCellWrapper leftWrapper1, LeftCellWrapper leftWrapper2,
            FragmentQuery rightQuery1, FragmentQuery rightQuery2)
        {
            LCWComparer comparer;

            if ((lookingForC && IsQueryView()) ||
                (!lookingForC && !IsQueryView()))
            {
                if (op == ComparisonOP.IsContainedIn)
                {
                    comparer = context.LeftFragmentQP.IsContainedIn;
                }
                else if (op == ComparisonOP.IsDisjointFrom)
                {
                    comparer = context.LeftFragmentQP.IsDisjointFrom;
                }
                else
                {
                    Debug.Fail("Unexpected comparison operator, only IsDisjointFrom and IsContainedIn are expected");
                    return(false);
                }

                return(comparer(leftWrapper1.FragmentQuery, leftWrapper2.FragmentQuery));
            }
            else
            {
                if (op == ComparisonOP.IsContainedIn)
                {
                    comparer = context.RightFragmentQP.IsContainedIn;
                }
                else if (op == ComparisonOP.IsDisjointFrom)
                {
                    comparer = context.RightFragmentQP.IsDisjointFrom;
                }
                else
                {
                    Debug.Fail("Unexpected comparison operator, only IsDisjointFrom and IsContainedIn are expected");
                    return(false);
                }

                return(comparer(rightQuery1, rightQuery2));
            }
        }
        private void CheckConstraintsOnProjectedConditionMembers(
            Dictionary <MemberValueBinding, CellTreeNode> memberValueTrees, LeftCellWrapper wrapper, CellTreeNode sQueryTree,
            BoolExpression inExtentCondition)
        {
            // for S-side condition members that are projected,
            // add condition <member=value> on both sides of the mapping constraint, and check key equivalence
            // applies to columns that are (1) projected and (2) conditional
            foreach (var column in _domainMap.ConditionMembers(_viewgenContext.Extent))
            {
                // Get the slot on the C side and see if it is projected
                var index = _viewgenContext.MemberMaps.ProjectedSlotMap.IndexOf(column);
                var slot  = wrapper.RightCellQuery.ProjectedSlotAt(index) as MemberProjectedSlot;
                if (slot != null)
                {
                    foreach (var domainValue in _domainMap.GetDomain(column))
                    {
                        CellTreeNode sQueryTreeForDomainValue;
                        if (memberValueTrees.TryGetValue(new MemberValueBinding(column, domainValue), out sQueryTreeForDomainValue))
                        {
                            var cWhereClause = PropagateCellConstantsToWhereClause(
                                wrapper, wrapper.RightCellQuery.WhereClause,
                                domainValue, column, _viewgenContext.MemberMaps);
                            var cCombinedQuery = FragmentQuery.Create(cWhereClause);
                            var sCombinedTree  = (sQueryTree == _basicView)
                                                    ? sQueryTreeForDomainValue
                                                    : new OpCellTreeNode(
                                _viewgenContext, CellTreeOpType.IJ, sQueryTreeForDomainValue, sQueryTree);

                            BoolExpression unsatisfiedConstraint;
                            if (!CheckEquivalence(
                                    cCombinedQuery, sCombinedTree.RightFragmentQuery, inExtentCondition,
                                    out unsatisfiedConstraint))
                            {
                                var memberLossMessage = Strings.ViewGen_CQ_DomainConstraint(slot.ToUserString());
                                ReportConstraintViolation(
                                    memberLossMessage, unsatisfiedConstraint, ViewGenErrorCode.DomainConstraintViolation,
                                    sCombinedTree.GetLeaves().Concat(new[] { wrapper }));
                            }
                        }
                    }
                }
            }
        }
        // effects: Given a sequence of constants that need to be propagated
        // to the C-side and the current boolean expression, generates a new
        // expression of the form "expression AND C-side Member in constants"
        // expression" and returns it. Each constant is propagated only if member
        // is projected -- if member is not projected, returns "expression"
        internal static BoolExpression PropagateCellConstantsToWhereClause(
            LeftCellWrapper wrapper, BoolExpression expression,
            Constant constant, MemberPath member,
            MemberMaps memberMaps)
        {
            var joinSlot = wrapper.GetCSideMappedSlotForSMember(member);

            if (joinSlot == null)
            {
                return(expression);
            }

            var negatedConstant = constant as NegatedConstant;

            // Look at the constants and determine if they correspond to
            // typeConstants or scalarConstants
            // This slot is being projected. We need to add a where clause element
            Debug.Assert(constant is ScalarConstant || constant.IsNull() || negatedConstant != null, "Invalid type of constant");

            // We want the possible values for joinSlot.MemberPath which is a
            // C-side element -- so we use the queryDomainMap
            var possibleValues = memberMaps.QueryDomainMap.GetDomain(joinSlot.MemberPath);
            // Note: the values in constaints can be null or not null as
            // well (i.e., just not scalarConstants)
            var allowedValues = new Set <Constant>(Constant.EqualityComparer);

            if (negatedConstant != null)
            {
                // select all values from the c-side domain that are not in the negated set
                allowedValues.Unite(possibleValues);
                allowedValues.Difference(negatedConstant.Elements);
            }
            else
            {
                allowedValues.Add(constant);
            }
            MemberRestriction restriction = new ScalarRestriction(joinSlot.MemberPath, allowedValues, possibleValues);

            var result = BoolExpression.CreateAnd(expression, BoolExpression.CreateLiteral(restriction, memberMaps.QueryDomainMap));

            return(result);
        }
Exemplo n.º 27
0
        private static FragmentQuery AddNullConditionOnCSideFragment(
            LeftCellWrapper wrapper,
            MemberPath member,
            MemberMaps memberMaps)
        {
            MemberProjectedSlot mappedSlotForSmember = wrapper.GetCSideMappedSlotForSMember(member);

            if (mappedSlotForSmember == null || !mappedSlotForSmember.MemberPath.IsNullable)
            {
                return((FragmentQuery)null);
            }
            BoolExpression         whereClause       = wrapper.RightCellQuery.WhereClause;
            IEnumerable <Constant> domain            = memberMaps.QueryDomainMap.GetDomain(mappedSlotForSmember.MemberPath);
            MemberRestriction      memberRestriction = (MemberRestriction) new ScalarRestriction(mappedSlotForSmember.MemberPath, (IEnumerable <Constant>) new Set <Constant>(Constant.EqualityComparer)
            {
                Constant.Null
            }, domain);

            return(FragmentQuery.Create(BoolExpression.CreateAnd(whereClause, BoolExpression.CreateLiteral((BoolLiteral)memberRestriction, memberMaps.QueryDomainMap))));
        }
Exemplo n.º 28
0
        /// <summary>
        /// Given a LeftCellWrapper for the S-side fragment and a non-nullable colum m, return a CQuery with nullability condition
        /// appended to Cquery of c-side member that column m is mapped to
        /// </summary>
        private static FragmentQuery AddNullConditionOnCSideFragment(LeftCellWrapper wrapper, MemberPath member, MemberMaps memberMaps)
        {
            MemberProjectedSlot projectedSlot = wrapper.GetCSideMappedSlotForSMember(member);

            if (projectedSlot == null || !projectedSlot.MemberPath.IsNullable) //don't bother checking further fore non nullable C-side member
            {
                return(null);
            }
            BoolExpression expression = wrapper.RightCellQuery.WhereClause;

            IEnumerable <Constant> possibleValues = memberMaps.QueryDomainMap.GetDomain(projectedSlot.MemberPath);
            Set <Constant>         allowedValues  = new Set <Constant>(Constant.EqualityComparer);

            allowedValues.Add(Constant.Null);

            //Create a condition as conjunction of originalCondition and slot IS NULL
            MemberRestriction restriction   = new ScalarRestriction(projectedSlot.MemberPath, allowedValues, possibleValues);
            BoolExpression    resultingExpr = BoolExpression.CreateAnd(expression, BoolExpression.CreateLiteral(restriction, memberMaps.QueryDomainMap));

            return(FragmentQuery.Create(resultingExpr));
        }
        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);
        }
        /// <summary>
        ///     Checks whether non nullable S-side members are mapped to nullable C-query.
        ///     It is possible that C-side attribute is nullable but the fragment's C-query is not
        /// </summary>
        private void CheckConstraintsOnNonNullableMembers(LeftCellWrapper wrapper)
        {
            //For each non-condition member that has non-nullability constraint
            foreach (var column in _domainMap.NonConditionMembers(_viewgenContext.Extent))
            {
                var isColumnSimpleType = (column.EdmType as SimpleType) != null;

                if (!column.IsNullable && isColumnSimpleType)
                {
                    var cFragment = AddNullConditionOnCSideFragment(wrapper, column, _viewgenContext.MemberMaps);

                    if (cFragment != null &&
                        _viewgenContext.RightFragmentQP.IsSatisfiable(cFragment))
                    {
                        _errorLog.AddEntry(
                            new ErrorLog.Record(
                                ViewGenErrorCode.NullableMappingForNonNullableColumn,
                                Strings.Viewgen_NullableMappingForNonNullableColumn(wrapper.LeftExtent.ToString(), column.ToFullString()),
                                wrapper.Cells, ""));
                    }
                }
            }
        }
Exemplo n.º 31
0
        // effects: Given the cells for the extent (extentCells) along with
        // the signatures (multiconstants + needed attributes) for this extent, generates
        // the left cell wrappers for it extent (viewTarget indicates whether
        // the view is for querying or update purposes
        // Modifies m_cellWrappers to contain this list
        private bool CreateLeftCellWrappers(IList<Cell> extentCells, ViewTarget viewTarget)
        {
            var alignedCells = AlignFields(extentCells, m_memberMaps.ProjectedSlotMap, viewTarget);
            Debug.Assert(alignedCells.Count == extentCells.Count, "Cell counts disagree");

            // Go through all the cells and create cell wrappers that can be used for generating the view
            m_cellWrappers = new List<LeftCellWrapper>();

            for (var i = 0; i < alignedCells.Count; i++)
            {
                var alignedCell = alignedCells[i];
                var left = alignedCell.GetLeftQuery(viewTarget);
                var right = alignedCell.GetRightQuery(viewTarget);

                // Obtain the non-null projected slots into attributes
                var attributes = left.GetNonNullSlots();

                var fromVariable = BoolExpression.CreateLiteral(
                    new CellIdBoolean(m_identifiers, extentCells[i].CellNumber), m_memberMaps.LeftDomainMap);
                var leftFragmentQuery = FragmentQuery.Create(fromVariable, left);

                if (viewTarget == ViewTarget.UpdateView)
                {
                    leftFragmentQuery = m_leftFragmentQP.CreateDerivedViewBySelectingConstantAttributes(leftFragmentQuery)
                                        ?? leftFragmentQuery;
                }

                var leftWrapper = new LeftCellWrapper(
                    m_viewTarget, attributes, leftFragmentQuery, left, right, m_memberMaps,
                    extentCells[i]);
                m_cellWrappers.Add(leftWrapper);
            }
            return true;
        }
        // requires: node1 and node2 are two children of the same parent
        // connected by opType
        // effects: Given two cell tree nodes, node1 and node2, runs the
        // TM/SP rule on them to merge them (if they belong to the same
        // extent). Returns true if the merge succeeds
        private bool TryMergeCellQueries(CellTreeOpType opType, ref CellTreeNode node1,
                                         CellTreeNode node2)
        {

            LeafCellTreeNode leaf1 = node1 as LeafCellTreeNode;
            LeafCellTreeNode leaf2 = node2 as LeafCellTreeNode;

            Debug.Assert(leaf1 != null, "Merge only possible on leaf nodes (1)");
            Debug.Assert(leaf2 != null, "Merge only possible on leaf nodes (2)");

            CellQuery mergedLeftCellQuery;
            CellQuery mergedRightCellQuery;
            if (!TryMergeTwoCellQueries(leaf1.LeftCellWrapper.RightCellQuery, leaf2.LeftCellWrapper.RightCellQuery, opType, m_viewgenContext.MemberMaps.RightDomainMap, out mergedRightCellQuery))
            {
                return false;
            }

            if (!TryMergeTwoCellQueries(leaf1.LeftCellWrapper.LeftCellQuery, leaf2.LeftCellWrapper.LeftCellQuery, opType, m_viewgenContext.MemberMaps.LeftDomainMap, out mergedLeftCellQuery))
            {
                return false;
            }

            // Create a temporary node and add the two children
            // so that we can get the merged selectiondomains and attributes
            // Note that temp.SelectionDomain below determines the domain
            // based on the opType, e.g., for IJ, it intersects the
            // multiconstants of all the children
            OpCellTreeNode temp = new OpCellTreeNode(m_viewgenContext, opType);
            temp.Add(node1);
            temp.Add(node2);
            // Note: We are losing the original cell number information here and the line number information
            // But we will not raise any

            // We do not create CellExpressions with LOJ, FOJ - canBooleansOverlap is true for validation
            CellTreeOpType inputOpType = opType;
            if (opType == CellTreeOpType.FOJ || opType == CellTreeOpType.LOJ)
            {
                inputOpType = CellTreeOpType.IJ;
            }

            LeftCellWrapper wrapper = new LeftCellWrapper(m_viewgenContext.ViewTarget, temp.Attributes,
                                                          temp.LeftFragmentQuery,
                                                          mergedLeftCellQuery,
                                                          mergedRightCellQuery,
                                                          m_viewgenContext.MemberMaps,
                                                          leaf1.LeftCellWrapper.Cells.Concat(leaf2.LeftCellWrapper.Cells));
            node1 = new LeafCellTreeNode(m_viewgenContext, wrapper, temp.RightFragmentQuery);
            return true;
        }