Example #1
0
            internal override bool VisitLeaf(LeafCellTreeNode node, bool dummy)
            {
                CellQuery         rightCellQuery1 = this.m_wrapper.RightCellQuery;
                CellQuery         rightCellQuery2 = node.LeftCellWrapper.RightCellQuery;
                List <MemberPath> memberPathList  = new List <MemberPath>();

                if (rightCellQuery1 != rightCellQuery2)
                {
                    for (int slotNum = 0; slotNum < rightCellQuery1.NumProjectedSlots; ++slotNum)
                    {
                        MemberProjectedSlot memberProjectedSlot1 = rightCellQuery1.ProjectedSlotAt(slotNum) as MemberProjectedSlot;
                        if (memberProjectedSlot1 != null)
                        {
                            MemberProjectedSlot memberProjectedSlot2 = rightCellQuery2.ProjectedSlotAt(slotNum) as MemberProjectedSlot;
                            if (memberProjectedSlot2 != null)
                            {
                                MemberPath projectedSlot = this.m_viewgenContext.MemberMaps.ProjectedSlotMap[slotNum];
                                if (!projectedSlot.IsPartOfKey && !MemberPath.EqualityComparer.Equals(memberProjectedSlot1.MemberPath, memberProjectedSlot2.MemberPath))
                                {
                                    memberPathList.Add(projectedSlot);
                                }
                            }
                        }
                    }
                }
                if (memberPathList.Count > 0)
                {
                    this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.NonKeyProjectedWithOverlappingPartitions, Strings.ViewGen_NonKeyProjectedWithOverlappingPartitions((object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)memberPathList, false)), (IEnumerable <LeftCellWrapper>) new LeftCellWrapper[2]
                    {
                        this.m_wrapper,
                        node.LeftCellWrapper
                    }, string.Empty));
                }
                return(true);
            }
Example #2
0
        internal static string SlotToUserString(ViewCellSlot slot, bool isFromCside)
        {
            MemberProjectedSlot actualSlot = isFromCside ? slot.CSlot : slot.SSlot;
            string result = StringUtil.FormatInvariant("{0}", actualSlot);

            return(result);
        }
Example #3
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 ViewCellSlot LookupViewSlot(MemberProjectedSlot slot)
 {
     foreach (ViewCellSlot slot1 in this.m_slots)
     {
         if (ProjectedSlot.EqualityComparer.Equals((ProjectedSlot)slot, (ProjectedSlot)slot1.CSlot) || ProjectedSlot.EqualityComparer.Equals((ProjectedSlot)slot, (ProjectedSlot)slot1.SSlot))
         {
             return(slot1);
         }
     }
     return((ViewCellSlot)null);
 }
Example #5
0
 // requires: slot corresponds to a slot in the corresponding
 // BasicCellRelation
 // effects: Given a slot in the corresponding basicCellRelation,
 // looks up the slot in this viewcellrelation and returns it. Returns
 // null if it does not find the slot in the left or right side of the viewrelation
 internal ViewCellSlot LookupViewSlot(MemberProjectedSlot slot)
 {
     // CHANGE_Microsoft_IMPROVE: We could have a dictionary to speed this up
     foreach (ViewCellSlot viewSlot in m_slots)
     {
         // If the left or right slots are equal, return the viewSlot
         if (ProjectedSlot.EqualityComparer.Equals(slot, viewSlot.CSlot) ||
             ProjectedSlot.EqualityComparer.Equals(slot, viewSlot.SSlot))
         {
             return viewSlot;
         }
     }
     return null;
 }
Example #6
0
        // effects: Given keys for this relation, adds one key constraint for
        // each key present in keys
        private void AddKeyConstraints(IEnumerable <ExtentKey> keys, BasicSchemaConstraints constraints)
        {
            foreach (var key in keys)
            {
                // If the key is being projected, only then do we add the key constraint

                var keySlots = MemberProjectedSlot.GetSlots(m_slots, key.KeyFields);
                if (keySlots != null)
                {
                    var keyConstraint = new BasicKeyConstraint(this, keySlots);
                    constraints.Add(keyConstraint);
                }
            }
        }
 private void AddKeyConstraints(
     IEnumerable <ExtentKey> keys,
     SchemaConstraints <BasicKeyConstraint> constraints)
 {
     foreach (ExtentKey key in keys)
     {
         List <MemberProjectedSlot> slots = MemberProjectedSlot.GetSlots((IEnumerable <MemberProjectedSlot>) this.m_slots, key.KeyFields);
         if (slots != null)
         {
             BasicKeyConstraint constraint = new BasicKeyConstraint(this, (IEnumerable <MemberProjectedSlot>)slots);
             constraints.Add(constraint);
         }
     }
 }
Example #8
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
                         }));
                     }
                 }
             }
         }
     }
 }
Example #9
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))));
        }
Example #10
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));
        }
Example #11
0
            internal override bool VisitLeaf(LeafCellTreeNode node, bool dummy)
            {
                // make sure all projected attributes in wrapper correspond exactly to those in node
                CellQuery         thisQuery        = m_wrapper.RightCellQuery;
                CellQuery         thatQuery        = node.LeftCellWrapper.RightCellQuery;
                List <MemberPath> collidingColumns = new List <MemberPath>();

                if (thisQuery != thatQuery)
                {
                    for (int i = 0; i < thisQuery.NumProjectedSlots; i++)
                    {
                        MemberProjectedSlot thisSlot = thisQuery.ProjectedSlotAt(i) as MemberProjectedSlot;
                        if (thisSlot != null)
                        {
                            MemberProjectedSlot thatSlot = thatQuery.ProjectedSlotAt(i) as MemberProjectedSlot;
                            if (thatSlot != null)
                            {
                                MemberPath tableMember = m_viewgenContext.MemberMaps.ProjectedSlotMap[i];
                                if (!tableMember.IsPartOfKey)
                                {
                                    if (!MemberPath.EqualityComparer.Equals(thisSlot.MemberPath, thatSlot.MemberPath))
                                    {
                                        collidingColumns.Add(tableMember);
                                    }
                                }
                            }
                        }
                    }
                }
                if (collidingColumns.Count > 0)
                {
                    string          columnsString = MemberPath.PropertiesToUserString(collidingColumns, false);
                    string          message       = Strings.ViewGen_NonKeyProjectedWithOverlappingPartitions(columnsString);
                    ErrorLog.Record record        = new ErrorLog.Record(true, ViewGenErrorCode.NonKeyProjectedWithOverlappingPartitions, message,
                                                                        new LeftCellWrapper[] { m_wrapper, node.LeftCellWrapper }, String.Empty);
                    m_errorLog.AddEntry(record);
                }
                return(true);
            }
Example #12
0
        // 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)
        {
            MemberProjectedSlot joinSlot = wrapper.GetCSideMappedSlotForSMember(member);

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

            // 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() || constant is NegatedConstant, "Invalid type of constant");

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

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

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

            return(result);
        }
Example #13
0
        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 (MemberPath column in _domainMap.ConditionMembers(_viewgenContext.Extent))
            {
                // Get the slot on the C side and see if it is projected
                int index = _viewgenContext.MemberMaps.ProjectedSlotMap.IndexOf(column);
                MemberProjectedSlot slot = wrapper.RightCellQuery.ProjectedSlotAt(index) as MemberProjectedSlot;
                if (slot != null)
                {
                    foreach (Constant domainValue in _domainMap.GetDomain(column))
                    {
                        CellTreeNode sQueryTreeForDomainValue;
                        if (memberValueTrees.TryGetValue(new MemberValueBinding(column, domainValue), out sQueryTreeForDomainValue))
                        {
                            BoolExpression cWhereClause = PropagateCellConstantsToWhereClause(wrapper, wrapper.RightCellQuery.WhereClause,
                                                                                              domainValue, column, _viewgenContext.MemberMaps);
                            FragmentQuery cCombinedQuery = FragmentQuery.Create(cWhereClause);
                            CellTreeNode  sCombinedTree  = (sQueryTree == _basicView) ?
                                                           sQueryTreeForDomainValue :
                                                           new OpCellTreeNode(_viewgenContext, CellTreeOpType.IJ, sQueryTreeForDomainValue, sQueryTree);

                            BoolExpression unsatisfiedConstraint;
                            if (!CheckEquivalence(cCombinedQuery, sCombinedTree.RightFragmentQuery, inExtentCondition,
                                                  out unsatisfiedConstraint))
                            {
                                string memberLossMessage = Strings.ViewGen_CQ_DomainConstraint(slot.ToUserString());
                                ReportConstraintViolation(memberLossMessage, unsatisfiedConstraint, ViewGenErrorCode.DomainConstraintViolation,
                                                          sCombinedTree.GetLeaves().Concat(new LeftCellWrapper[] { wrapper }));
                            }
                        }
                    }
                }
            }
        }
 internal ViewCellSlot(int slotNum, MemberProjectedSlot cSlot, MemberProjectedSlot sSlot)
 {
     this.m_slotNum = slotNum;
     this.m_cSlot   = cSlot;
     this.m_sSlot   = sSlot;
 }
        /// <summary>
        /// Given a cell, a member and a boolean condition on that member, creates additional cell
        /// which with the specified restriction on the member in addition to original condition.
        /// e.i conjunction of original condition AND member in newCondition
        ///
        /// Creation fails when the original condition contradicts new boolean condition
        ///
        /// ViewTarget tells whether MemberPath is in Cquery or SQuery
        /// </summary>
        private bool TryCreateAdditionalCellWithCondition(Cell originalCell, MemberPath memberToExpand, bool conditionValue, ViewTarget viewTarget, out Cell result)
        {
            Debug.Assert(originalCell != null);
            Debug.Assert(memberToExpand != null);
            result = null;

            //Create required structures
            MemberPath leftExtent  = originalCell.GetLeftQuery(viewTarget).SourceExtentMemberPath;
            MemberPath rightExtent = originalCell.GetRightQuery(viewTarget).SourceExtentMemberPath;

            //Now for the given left-side projected member, find corresponding right-side member that it is mapped to
            int indexOfBooLMemberInProjection            = originalCell.GetLeftQuery(viewTarget).GetProjectedMembers().TakeWhile(path => !path.Equals(memberToExpand)).Count();
            MemberProjectedSlot rightConditionMemberSlot = ((MemberProjectedSlot)originalCell.GetRightQuery(viewTarget).ProjectedSlotAt(indexOfBooLMemberInProjection));
            MemberPath          rightSidePath            = rightConditionMemberSlot.MemberPath;

            List <ProjectedSlot> leftSlots  = new List <ProjectedSlot>();
            List <ProjectedSlot> rightSlots = new List <ProjectedSlot>();

            //Check for impossible conditions (otehrwise we get inaccurate pre-validation errors)
            ScalarConstant negatedCondition = new ScalarConstant(!conditionValue);

            if (originalCell.GetLeftQuery(viewTarget).Conditions
                .Where(restriction => restriction.RestrictedMemberSlot.MemberPath.Equals(memberToExpand))
                .Where(restriction => restriction.Domain.Values.Contains(negatedCondition)).Any() ||
                originalCell.GetRightQuery(viewTarget).Conditions
                .Where(restriction => restriction.RestrictedMemberSlot.MemberPath.Equals(rightSidePath))
                .Where(restriction => restriction.Domain.Values.Contains(negatedCondition)).Any())
            {
                return(false);
            }
            //End check

            //Create Projected Slots
            // Map all slots in original cell (not just keys) because some may be required (non nullable and no default)
            // and others may have not_null condition so MUST be projected. Rely on the user doing the right thing, otherwise
            // they will get the error message anyway
            for (int i = 0; i < originalCell.GetLeftQuery(viewTarget).NumProjectedSlots; i++)
            {
                leftSlots.Add(originalCell.GetLeftQuery(viewTarget).ProjectedSlotAt(i));
            }

            for (int i = 0; i < originalCell.GetRightQuery(viewTarget).NumProjectedSlots; i++)
            {
                rightSlots.Add(originalCell.GetRightQuery(viewTarget).ProjectedSlotAt(i));
            }

            //Create condition boolena expressions
            BoolExpression leftQueryWhereClause = BoolExpression.CreateLiteral(new ScalarRestriction(memberToExpand, new ScalarConstant(conditionValue)), null);

            leftQueryWhereClause = BoolExpression.CreateAnd(originalCell.GetLeftQuery(viewTarget).WhereClause, leftQueryWhereClause);

            BoolExpression rightQueryWhereClause = BoolExpression.CreateLiteral(new ScalarRestriction(rightSidePath, new ScalarConstant(conditionValue)), null);

            rightQueryWhereClause = BoolExpression.CreateAnd(originalCell.GetRightQuery(viewTarget).WhereClause, rightQueryWhereClause);

            //Create additional Cells
            CellQuery rightQuery = new CellQuery(rightSlots, rightQueryWhereClause, rightExtent, originalCell.GetRightQuery(viewTarget).SelectDistinctFlag);
            CellQuery leftQuery  = new CellQuery(leftSlots, leftQueryWhereClause, leftExtent, originalCell.GetLeftQuery(viewTarget).SelectDistinctFlag);

            Cell newCell;

            if (viewTarget == ViewTarget.UpdateView)
            {
                newCell = Cell.CreateCS(rightQuery, leftQuery, originalCell.CellLabel, m_currentCellNumber);
            }
            else
            {
                newCell = Cell.CreateCS(leftQuery, rightQuery, originalCell.CellLabel, m_currentCellNumber);
            }

            m_currentCellNumber++;
            result = newCell;
            return(true);
        }
        // requires: all columns in constraint.ParentColumns and
        // constraint.ChildColumns must have been mapped in some cell in m_cellGroup
        // effects: Given the foreign key constraint, checks if the
        // constraint.ChildColumns are mapped to the constraint.ParentColumns
        // in m_cellGroup in the right oder. If not, adds an error to m_errorLog and returns
        // false. Else returns true
        private bool CheckForeignKeyColumnOrder(Set <Cell> cells, ErrorLog errorLog)
        {
            // Go through every cell and find the cells that are relevant to
            // parent and those that are relevant to child
            // Then for each cell pair (parent, child) make sure that the
            // projected foreign keys columns in C-space are aligned

            List <Cell> parentCells = new List <Cell>();
            List <Cell> childCells  = new List <Cell>();

            foreach (Cell cell in cells)
            {
                if (cell.SQuery.Extent.Equals(ChildTable))
                {
                    childCells.Add(cell);
                }

                if (cell.SQuery.Extent.Equals(ParentTable))
                {
                    parentCells.Add(cell);
                }
            }

            // Make sure that all child cells and parent cells align on
            // the columns, i.e., for each DISTINCT pair C and P, get the columns
            // on the S-side. Then get the corresponding fields on the
            // C-side. The fields on the C-side should match

            bool foundParentCell = false;
            bool foundChildCell  = false;

            foreach (Cell childCell in childCells)
            {
                List <List <int> > allChildSlotNums = GetSlotNumsForColumns(childCell, ChildColumns);

                if (allChildSlotNums.Count == 0)
                { // slots in present in S-side, ignore
                    continue;
                }

                List <MemberPath> childPaths  = null;
                List <MemberPath> parentPaths = null;
                Cell errorParentCell          = null;

                foreach (List <int> childSlotNums in allChildSlotNums)
                {
                    foundChildCell = true;

                    // Get the fields on the C-side
                    childPaths = new List <MemberPath>(childSlotNums.Count);
                    foreach (int childSlotNum in childSlotNums)
                    {
                        // Initial slots only have JoinTreeSlots
                        MemberProjectedSlot childSlot = (MemberProjectedSlot)childCell.CQuery.ProjectedSlotAt(childSlotNum);
                        Debug.Assert(childSlot != null);
                        childPaths.Add(childSlot.MemberPath);
                    }

                    foreach (Cell parentCell in parentCells)
                    {
                        List <List <int> > allParentSlotNums = GetSlotNumsForColumns(parentCell, ParentColumns);
                        if (allParentSlotNums.Count == 0)
                        {
                            // * Parent and child cell are the same - we do not
                            // need to check since we want to check the foreign
                            // key constraint mapping across cells
                            // * Some slots not in present in S-side, ignore
                            continue;
                        }
                        foreach (List <int> parentSlotNums in allParentSlotNums)
                        {
                            foundParentCell = true;

                            parentPaths = new List <MemberPath>(parentSlotNums.Count);
                            foreach (int parentSlotNum in parentSlotNums)
                            {
                                MemberProjectedSlot parentSlot = (MemberProjectedSlot)parentCell.CQuery.ProjectedSlotAt(parentSlotNum);
                                Debug.Assert(parentSlot != null);
                                parentPaths.Add(parentSlot.MemberPath);
                            }

                            // Make sure that the last member of each of these is the same
                            // or the paths are essentially equivalent via referential constraints
                            // We need to check that the last member is essentially the same because it could
                            // be a regular scenario where aid is mapped to PersonAddress and Address - there
                            // is no ref constraint. So when projected into C-Space, we will get Address.aid
                            // and PersonAddress.Address.aid
                            if (childPaths.Count == parentPaths.Count)
                            {
                                bool notAllPathsMatched = false;
                                for (int i = 0; i < childPaths.Count && !notAllPathsMatched; i++)
                                {
                                    MemberPath parentPath = parentPaths[i];
                                    MemberPath childPath  = childPaths[i];

                                    if (!parentPath.LeafEdmMember.Equals(childPath.LeafEdmMember)) //Child path did not match
                                    {
                                        if (parentPath.IsEquivalentViaRefConstraint(childPath))
                                        {
                                            //Specifying the referential constraint once in the C space should be enough.
                                            //This is the only way possible today.
                                            //We might be able to derive more knowledge by using boolean logic
                                            return(true);
                                        }
                                        else
                                        {
                                            notAllPathsMatched = true;
                                        }
                                    }
                                }

                                if (!notAllPathsMatched)
                                {
                                    return(true); //all childPaths matched parentPaths
                                }
                                else
                                {
                                    //If not this one, some other Parent Cell may match.
                                    errorParentCell = parentCell;
                                }
                            }
                        }
                    } //foreach parentCell
                }

                //If execution is at this point, no parent cell's end has matched (otherwise it would have returned true)

                Debug.Assert(childPaths != null, "child paths should be set");
                Debug.Assert(parentPaths != null, "parent paths should be set");
                Debug.Assert(errorParentCell != null, "errorParentCell should be set");
                // using EntityRes. instead of Strings. because the generated method includes 6 instead of 9 parameters
                string message = EntityRes.GetString(EntityRes.ViewGen_Foreign_Key_ColumnOrder_Incorrect,
                                                     ToUserString(),
                                                     MemberPath.PropertiesToUserString(ChildColumns, false),
                                                     ChildTable.Name,
                                                     MemberPath.PropertiesToUserString(childPaths, false),
                                                     childCell.CQuery.Extent.Name,
                                                     MemberPath.PropertiesToUserString(ParentColumns, false),
                                                     ParentTable.Name,
                                                     MemberPath.PropertiesToUserString(parentPaths, false),
                                                     errorParentCell.CQuery.Extent.Name);
                ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ForeignKeyColumnOrderIncorrect, message, new Cell[] { errorParentCell, childCell }, String.Empty);
                errorLog.AddEntry(record);
                return(false);
            }
            Debug.Assert(foundParentCell == true, "Some cell that mapped the parent's key must be present!");
            Debug.Assert(foundChildCell == true, "Some cell that mapped the child's foreign key must be present according to the requires clause!");
            return(true);
        }
        private bool CheckForeignKeyColumnOrder(Set <Cell> cells, ErrorLog errorLog)
        {
            List <Cell> cellList1 = new List <Cell>();
            List <Cell> cellList2 = new List <Cell>();

            foreach (Cell cell in cells)
            {
                if (cell.SQuery.Extent.Equals((object)this.ChildTable))
                {
                    cellList2.Add(cell);
                }
                if (cell.SQuery.Extent.Equals((object)this.ParentTable))
                {
                    cellList1.Add(cell);
                }
            }
            foreach (Cell cell1 in cellList2)
            {
                List <List <int> > slotNumsForColumns1 = ForeignConstraint.GetSlotNumsForColumns(cell1, this.ChildColumns);
                if (slotNumsForColumns1.Count != 0)
                {
                    List <MemberPath> memberPathList1 = (List <MemberPath>)null;
                    List <MemberPath> memberPathList2 = (List <MemberPath>)null;
                    Cell cell2 = (Cell)null;
                    foreach (List <int> intList1 in slotNumsForColumns1)
                    {
                        memberPathList1 = new List <MemberPath>(intList1.Count);
                        foreach (int slotNum in intList1)
                        {
                            MemberProjectedSlot memberProjectedSlot = (MemberProjectedSlot)cell1.CQuery.ProjectedSlotAt(slotNum);
                            memberPathList1.Add(memberProjectedSlot.MemberPath);
                        }
                        foreach (Cell cell3 in cellList1)
                        {
                            List <List <int> > slotNumsForColumns2 = ForeignConstraint.GetSlotNumsForColumns(cell3, this.ParentColumns);
                            if (slotNumsForColumns2.Count != 0)
                            {
                                foreach (List <int> intList2 in slotNumsForColumns2)
                                {
                                    memberPathList2 = new List <MemberPath>(intList2.Count);
                                    foreach (int slotNum in intList2)
                                    {
                                        MemberProjectedSlot memberProjectedSlot = (MemberProjectedSlot)cell3.CQuery.ProjectedSlotAt(slotNum);
                                        memberPathList2.Add(memberProjectedSlot.MemberPath);
                                    }
                                    if (memberPathList1.Count == memberPathList2.Count)
                                    {
                                        bool flag = false;
                                        for (int index = 0; index < memberPathList1.Count && !flag; ++index)
                                        {
                                            MemberPath memberPath = memberPathList2[index];
                                            MemberPath path1      = memberPathList1[index];
                                            if (!memberPath.LeafEdmMember.Equals((object)path1.LeafEdmMember))
                                            {
                                                if (memberPath.IsEquivalentViaRefConstraint(path1))
                                                {
                                                    return(true);
                                                }
                                                flag = true;
                                            }
                                        }
                                        if (!flag)
                                        {
                                            return(true);
                                        }
                                        cell2 = cell3;
                                    }
                                }
                            }
                        }
                    }
                    ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyColumnOrderIncorrect, Strings.ViewGen_Foreign_Key_ColumnOrder_Incorrect((object)this.ToUserString(), (object)MemberPath.PropertiesToUserString(this.ChildColumns, false), (object)this.ChildTable.Name, (object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)memberPathList1, false), (object)cell1.CQuery.Extent.Name, (object)MemberPath.PropertiesToUserString(this.ParentColumns, false), (object)this.ParentTable.Name, (object)MemberPath.PropertiesToUserString((IEnumerable <MemberPath>)memberPathList2, false), (object)cell2.CQuery.Extent.Name), (IEnumerable <Cell>) new Cell[2]
                    {
                        cell2,
                        cell1
                    }, string.Empty);
                    errorLog.AddEntry(record);
                    return(false);
                }
            }
            return(true);
        }