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)
            }));
        }
        private void AddElseDefaultToCaseStatement(
            MemberPath currentPath,
            CaseStatement caseStatement,
            List <Constant> domain,
            CellTreeNode rightDomainQuery,
            Tile <FragmentQuery> unionCaseRewriting)
        {
            Constant defaultConstant;
            bool     valueForMemberPath = Domain.TryGetDefaultValueForMemberPath(currentPath, out defaultConstant);

            if (valueForMemberPath && domain.Contains(defaultConstant))
            {
                return;
            }
            CellTreeNode  cellTree = QueryRewriter.TileToCellTree(unionCaseRewriting, this._context);
            FragmentQuery query    = this._context.RightFragmentQP.Difference(rightDomainQuery.RightFragmentQuery, cellTree.RightFragmentQuery);

            if (!this._context.RightFragmentQP.IsSatisfiable(query))
            {
                return;
            }
            if (valueForMemberPath)
            {
                caseStatement.AddWhenThen(BoolExpression.True, (ProjectedSlot) new ConstantProjectedSlot(defaultConstant));
            }
            else
            {
                query.Condition.ExpensiveSimplify();
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendLine(Strings.ViewGen_No_Default_Value_For_Configuration((object)currentPath.PathToString(new bool?(false))));
                this._errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.NoDefaultValue, stringBuilder.ToString(), (IEnumerable <LeftCellWrapper>) this._context.AllWrappersForExtent, string.Empty));
            }
        }
        private static BoolExpression TileToBoolExpr(Tile <FragmentQuery> tile)
        {
            switch (tile.OpKind)
            {
            case TileOpKind.Union:
                return(BoolExpression.CreateOr(QueryRewriter.TileToBoolExpr(tile.Arg1), QueryRewriter.TileToBoolExpr(tile.Arg2)));

            case TileOpKind.Join:
                return(BoolExpression.CreateAnd(QueryRewriter.TileToBoolExpr(tile.Arg1), QueryRewriter.TileToBoolExpr(tile.Arg2)));

            case TileOpKind.AntiSemiJoin:
                return(BoolExpression.CreateAnd(QueryRewriter.TileToBoolExpr(tile.Arg1), BoolExpression.CreateNot(QueryRewriter.TileToBoolExpr(tile.Arg2))));

            case TileOpKind.Named:
                FragmentQuery namedQuery = ((TileNamed <FragmentQuery>)tile).NamedQuery;
                if (namedQuery.Condition.IsAlwaysTrue())
                {
                    return(BoolExpression.True);
                }
                return(namedQuery.FromVariable);

            default:
                return((BoolExpression)null);
            }
        }
 internal QueryRewriter(
     EdmType generatedType,
     ViewgenContext context,
     ViewGenMode typesGenerationMode)
 {
     this._typesGenerationMode = typesGenerationMode;
     this._context             = context;
     this._generatedType       = generatedType;
     this._domainMap           = context.MemberMaps.LeftDomainMap;
     this._config        = context.Config;
     this._identifiers   = context.CqlIdentifiers;
     this._qp            = new RewritingProcessor <Tile <FragmentQuery> >((TileProcessor <Tile <FragmentQuery> >) new DefaultTileProcessor <FragmentQuery>((TileQueryProcessor <FragmentQuery>)context.LeftFragmentQP));
     this._extentPath    = new MemberPath(context.Extent);
     this._keyAttributes = new List <MemberPath>(MemberPath.GetKeyMembers(context.Extent, this._domainMap));
     foreach (LeftCellWrapper leftCellWrapper in this._context.AllWrappersForExtent)
     {
         FragmentQuery        fragmentQuery = leftCellWrapper.FragmentQuery;
         Tile <FragmentQuery> tile          = (Tile <FragmentQuery>)QueryRewriter.CreateTile(fragmentQuery);
         this._fragmentQueries.Add(fragmentQuery);
         this._views.Add(tile);
     }
     this.AdjustMemberDomainsForUpdateViews();
     this._domainQuery = this.GetDomainQuery(this.FragmentQueries, generatedType);
     this._usedViews   = new HashSet <FragmentQuery>();
 }
 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 FindRewriting(
            IEnumerable <MemberPath> attributes,
            BoolExpression whereClause,
            out Tile <FragmentQuery> rewriting,
            out IEnumerable <MemberPath> notCoveredAttributes)
        {
            Tile <FragmentQuery> tile1 = (Tile <FragmentQuery>)QueryRewriter.CreateTile(FragmentQuery.Create(attributes, whereClause));
            Tile <FragmentQuery> tile2 = (Tile <FragmentQuery>)QueryRewriter.CreateTile(FragmentQuery.Create((IEnumerable <MemberPath>) this._keyAttributes, BoolExpression.CreateNot(whereClause)));
            bool isRelaxed             = this._context.ViewTarget == ViewTarget.UpdateView;

            return(this.RewriteQuery(tile1, tile2, out rewriting, out notCoveredAttributes, isRelaxed));
        }
        private BoolExpression GetTopLevelWhereClause(
            HashSet <FragmentQuery> outputUsedViews)
        {
            BoolExpression       boolExpr = BoolExpression.True;
            Tile <FragmentQuery> rewriting;

            if (this._context.ViewTarget == ViewTarget.QueryView && !this._domainQuery.Condition.IsTrue && this.FindRewritingAndUsedViews((IEnumerable <MemberPath>) this._keyAttributes, this._domainQuery.Condition, outputUsedViews, out rewriting))
            {
                boolExpr = QueryRewriter.TileToBoolExpr(rewriting);
                boolExpr.ExpensiveSimplify();
            }
            return(boolExpr);
        }
        private IEnumerable <Tile <FragmentQuery> > GetRelevantViews(
            FragmentQuery query)
        {
            Set <MemberPath>             variables = QueryRewriter.GetVariables(query);
            Tile <FragmentQuery>         a1        = (Tile <FragmentQuery>)null;
            List <Tile <FragmentQuery> > tileList  = new List <Tile <FragmentQuery> >();
            Tile <FragmentQuery>         tile      = (Tile <FragmentQuery>)null;

            foreach (Tile <FragmentQuery> view in this._views)
            {
                if (QueryRewriter.GetVariables(view.Query).Overlaps(variables))
                {
                    a1 = a1 == null ? view : this._qp.Union(a1, view);
                    tileList.Add(view);
                }
                else if (this.IsTrue(view.Query) && tile == null)
                {
                    tile = view;
                }
            }
            if (a1 != null && this.IsTrue(a1.Query))
            {
                return((IEnumerable <Tile <FragmentQuery> >)tileList);
            }
            if (tile == null)
            {
                Tile <FragmentQuery> a2 = (Tile <FragmentQuery>)null;
                foreach (FragmentQuery fragmentQuery in this._fragmentQueries)
                {
                    a2 = a2 == null ? (Tile <FragmentQuery>)QueryRewriter.CreateTile(fragmentQuery) : this._qp.Union(a2, (Tile <FragmentQuery>)QueryRewriter.CreateTile(fragmentQuery));
                    if (this.IsTrue(a2.Query))
                    {
                        tile = QueryRewriter._trueViewSurrogate;
                        break;
                    }
                }
            }
            if (tile == null)
            {
                return((IEnumerable <Tile <FragmentQuery> >) this._views);
            }
            tileList.Add(tile);
            return((IEnumerable <Tile <FragmentQuery> >)tileList);
        }
        private bool AddRewritingToCaseStatement(
            Tile <FragmentQuery> rewriting,
            CaseStatement caseStatement,
            MemberPath currentPath,
            Constant domainValue)
        {
            BoolExpression boolExpression = BoolExpression.True;
            bool           flag           = this._qp.IsContainedIn((Tile <FragmentQuery>)QueryRewriter.CreateTile(this._domainQuery), rewriting);

            if (this._qp.IsDisjointFrom((Tile <FragmentQuery>)QueryRewriter.CreateTile(this._domainQuery), rewriting))
            {
                return(false);
            }
            int            num           = flag ? 1 : 0;
            ProjectedSlot  projectedSlot = !domainValue.HasNotNull() ? (ProjectedSlot) new ConstantProjectedSlot(domainValue) : (ProjectedSlot) new MemberProjectedSlot(currentPath);
            BoolExpression condition     = flag ? BoolExpression.True : QueryRewriter.TileToBoolExpr(rewriting);

            caseStatement.AddWhenThen(condition, projectedSlot);
            return(flag);
        }
        private IEnumerable <Constant> GetDomain(MemberPath currentPath)
        {
            if (this._context.ViewTarget != ViewTarget.QueryView || !MemberPath.EqualityComparer.Equals(currentPath, this._extentPath))
            {
                return(this._domainMap.GetDomain(currentPath));
            }
            IEnumerable <EdmType> types;

            if (this._typesGenerationMode == ViewGenMode.OfTypeOnlyViews)
            {
                types = (IEnumerable <EdmType>) new HashSet <EdmType>()
                {
                    this._generatedType
                }
            }
            ;
            else
            {
                types = MetadataHelper.GetTypeAndSubtypesOf(this._generatedType, (ItemCollection)this._context.EdmItemCollection, false);
            }
            return(QueryRewriter.GetTypeConstants(types));
        }
        private bool CoverAttributes(
            ref Tile <FragmentQuery> rewriting,
            Dictionary <MemberPath, FragmentQuery> attributeConditions)
        {
            foreach (FragmentQuery view in new HashSet <FragmentQuery>(rewriting.GetNamedQueries()))
            {
                foreach (MemberPath nonKey in QueryRewriter.NonKeys((IEnumerable <MemberPath>)view.Attributes))
                {
                    this.CoverAttribute(nonKey, view, attributeConditions);
                }
                if (attributeConditions.Count == 0)
                {
                    return(true);
                }
            }
            Tile <FragmentQuery> tile = (Tile <FragmentQuery>)null;

            foreach (FragmentQuery fragmentQuery in this._fragmentQueries)
            {
                foreach (MemberPath nonKey in QueryRewriter.NonKeys((IEnumerable <MemberPath>)fragmentQuery.Attributes))
                {
                    if (this.CoverAttribute(nonKey, fragmentQuery, attributeConditions))
                    {
                        tile = tile == null ? (Tile <FragmentQuery>)QueryRewriter.CreateTile(fragmentQuery) : this._qp.Union(tile, (Tile <FragmentQuery>)QueryRewriter.CreateTile(fragmentQuery));
                    }
                }
                if (attributeConditions.Count == 0)
                {
                    break;
                }
            }
            if (attributeConditions.Count != 0)
            {
                return(false);
            }
            rewriting = this._qp.Join(rewriting, tile);
            return(true);
        }
        private bool CoverAttribute(
            MemberPath projectedAttribute,
            FragmentQuery view,
            Dictionary <MemberPath, FragmentQuery> attributeConditions)
        {
            FragmentQuery fragmentQuery;

            if (!attributeConditions.TryGetValue(projectedAttribute, out fragmentQuery))
            {
                return(false);
            }
            FragmentQuery query = FragmentQuery.Create(BoolExpression.CreateAndNot(fragmentQuery.Condition, view.Condition));

            if (this._qp.IsEmpty((Tile <FragmentQuery>)QueryRewriter.CreateTile(query)))
            {
                attributeConditions.Remove(projectedAttribute);
            }
            else
            {
                attributeConditions[projectedAttribute] = query;
            }
            return(true);
        }
        private void RemoveUnusedValueFromStoreDomain(Constant domainValue, MemberPath currentPath)
        {
            BoolExpression          memberCondition = this.CreateMemberCondition(currentPath, domainValue);
            HashSet <FragmentQuery> outputUsedViews = new HashSet <FragmentQuery>();
            bool flag = false;
            Tile <FragmentQuery> rewriting;

            if (this.FindRewritingAndUsedViews((IEnumerable <MemberPath>) this._keyAttributes, memberCondition, outputUsedViews, out rewriting))
            {
                flag = !QueryRewriter.TileToCellTree(rewriting, this._context).IsEmptyRightFragmentQuery;
            }
            if (flag)
            {
                return;
            }
            Set <Constant> set = new Set <Constant>(this._domainMap.GetDomain(currentPath), Constant.EqualityComparer);

            set.Remove(domainValue);
            this._domainMap.UpdateConditionMemberDomain(currentPath, (IEnumerable <Constant>)set);
            foreach (FragmentQuery fragmentQuery in this._fragmentQueries)
            {
                fragmentQuery.Condition.FixDomainMap(this._domainMap);
            }
        }
        private HashSet <FragmentQuery> GetUsedViewsAndRemoveTrueSurrogate(
            ref Tile <FragmentQuery> rewriting)
        {
            HashSet <FragmentQuery> first = new HashSet <FragmentQuery>(rewriting.GetNamedQueries());

            if (!first.Contains(QueryRewriter._trueViewSurrogate.Query))
            {
                return(first);
            }
            first.Remove(QueryRewriter._trueViewSurrogate.Query);
            Tile <FragmentQuery> tile = (Tile <FragmentQuery>)null;

            foreach (FragmentQuery query in first.Concat <FragmentQuery>((IEnumerable <FragmentQuery>) this._fragmentQueries))
            {
                tile = tile == null ? (Tile <FragmentQuery>)QueryRewriter.CreateTile(query) : this._qp.Union(tile, (Tile <FragmentQuery>)QueryRewriter.CreateTile(query));
                first.Add(query);
                if (this.IsTrue(tile.Query))
                {
                    rewriting = rewriting.Replace(QueryRewriter._trueViewSurrogate, tile);
                    return(first);
                }
            }
            return(first);
        }
        private bool CheckIfConstraintMappedToForeignKeyAssociation(
            QueryRewriter childRewriter, QueryRewriter parentRewriter,
            Set<Cell> cells)
        {
            var childContext = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;

            //First collect the sets of properties that the principal and dependant ends of this FK
            //are mapped to in the Edm side.
            var childPropertiesSet = new List<Set<EdmProperty>>();
            var parentPropertiesSet = new List<Set<EdmProperty>>();
            foreach (var cell in cells)
            {
                if (cell.CQuery.Extent.BuiltInTypeKind
                    != BuiltInTypeKind.AssociationSet)
                {
                    var childProperties = cell.GetCSlotsForTableColumns(ChildColumns);
                    if ((childProperties != null)
                        && (childProperties.Count != 0))
                    {
                        childPropertiesSet.Add(childProperties);
                    }
                    var parentProperties = cell.GetCSlotsForTableColumns(ParentColumns);
                    if ((parentProperties != null)
                        && (parentProperties.Count != 0))
                    {
                        parentPropertiesSet.Add(parentProperties);
                    }
                }
            }

            //Now Check if the properties on the Edm side are connected via an FK relationship.
            if ((childPropertiesSet.Count != 0)
                && (parentPropertiesSet.Count != 0))
            {
                var foreignKeyAssociations =
                    childContext.EntityContainerMapping.EdmEntityContainer.BaseEntitySets.OfType<AssociationSet>().Where(
                        it => it.ElementType.IsForeignKey).Select(it => it.ElementType);
                foreach (var association in foreignKeyAssociations)
                {
                    var refConstraint = association.ReferentialConstraints.FirstOrDefault();
                    //We need to check to see if the dependent properties that were mapped from S side are present as
                    //dependant properties of this ref constraint on the Edm side. We need to do the same for principal side but
                    //we can not enforce equality since the order of the properties participating in the constraint on the S side and
                    //C side could be different. This is OK as long as they are mapped appropriately. We also can not use Existance as a sufficient
                    //condition since it will allow invalid mapping where FK columns could have been flipped when mapping to the Edm side. So
                    //we make sure that the index of the properties in the principal and dependant are same on the Edm side even if they are in
                    //different order for ref constraints for Edm and store side.
                    var childRefPropertiesCollection =
                        childPropertiesSet.Where(it => it.SetEquals(new Set<EdmProperty>(refConstraint.ToProperties)));
                    var parentRefPropertiesCollection =
                        parentPropertiesSet.Where(it => it.SetEquals(new Set<EdmProperty>(refConstraint.FromProperties)));
                    if ((childRefPropertiesCollection.Count() != 0 && parentRefPropertiesCollection.Count() != 0))
                    {
                        foreach (var parentRefProperties in parentRefPropertiesCollection)
                        {
                            var parentIndexes = GetPropertyIndexes(parentRefProperties, refConstraint.FromProperties);
                            foreach (var childRefProperties in childRefPropertiesCollection)
                            {
                                var childIndexes = GetPropertyIndexes(childRefProperties, refConstraint.ToProperties);

                                if (childIndexes.SequenceEqual(parentIndexes))
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }
        // effects: Ensures that there is a relationship mapped into the C-space for some cell in m_cellGroup. Else
        // adds an error to errorLog
        private void GuaranteeMappedRelationshipForForeignKey(
            QueryRewriter childRewriter, QueryRewriter parentRewriter,
            IEnumerable<Cell> cells,
            ErrorLog errorLog, ConfigViewGenerator config)
        {
            var childContext = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;

            // Find a cell where this foreign key is mapped as a relationship
            var prefix = new MemberPath(ChildTable);
            var primaryKey = ExtentKey.GetPrimaryKeyForEntityType(prefix, ChildTable.ElementType);
            var primaryKeyFields = primaryKey.KeyFields;
            var foundCell = false;

            var foundValidParentColumnsForForeignKey = false; //we need to find only one, dont error on any one check being false
            List<ErrorLog.Record> errorListForInvalidParentColumnsForForeignKey = null;
            foreach (var cell in cells)
            {
                if (cell.SQuery.Extent.Equals(ChildTable) == false)
                {
                    continue;
                }

                // The childtable is mapped to a relationship in the C-space in cell
                // Check that all the columns of the foreign key and the primary key in the child table are mapped to some
                // property in the C-space

                var parentEnd = GetRelationEndForColumns(cell, ChildColumns);
                if (parentEnd != null
                    && CheckParentColumnsForForeignKey(cell, cells, parentEnd, ref errorListForInvalidParentColumnsForForeignKey) == false)
                {
                    // Not an error unless we find no valid case
                    continue;
                }
                else
                {
                    foundValidParentColumnsForForeignKey = true;
                }

                var childEnd = GetRelationEndForColumns(cell, primaryKeyFields);
                Debug.Assert(
                    childEnd == null || parentEnd != childEnd,
                    "Ends are same => PKey and child columns are same - code should gone to other method");
                // Note: If both of them are not-null, they are mapped to the
                // same association set -- since we checked that particular cell

                if (childEnd != null && parentEnd != null
                    &&
                    FindEntitySetForColumnsMappedToEntityKeys(cells, primaryKeyFields) != null)
                {
                    foundCell = true;
                    CheckConstraintWhenParentChildMapped(cell, errorLog, parentEnd, config);
                    break; // Done processing for the foreign key - either it was mapped correctly or it was not
                }
                else if (parentEnd != null)
                {
                    // At this point, we know cell corresponds to an association set
                    var assocSet = (AssociationSet)cell.CQuery.Extent;
                    var parentSet = MetadataHelper.GetEntitySetAtEnd(assocSet, parentEnd);
                    foundCell = CheckConstraintWhenOnlyParentMapped(assocSet, parentEnd, childRewriter, parentRewriter);
                    if (foundCell)
                    {
                        break;
                    }
                }
            }

            //CheckParentColumnsForForeignKey has returned no matches, Error.
            if (!foundValidParentColumnsForForeignKey)
            {
                Debug.Assert(
                    errorListForInvalidParentColumnsForForeignKey != null && errorListForInvalidParentColumnsForForeignKey.Count > 0);
                foreach (var errorRecord in errorListForInvalidParentColumnsForForeignKey)
                {
                    errorLog.AddEntry(errorRecord);
                }
                return;
            }

            if (foundCell == false)
            {
                // No cell found -- Declare error
                var message = Strings.ViewGen_Foreign_Key_Missing_Relationship_Mapping(ToUserString());

                IEnumerable<LeftCellWrapper> parentWrappers = GetWrappersFromContext(parentContext, ParentTable);
                IEnumerable<LeftCellWrapper> childWrappers = GetWrappersFromContext(childContext, ChildTable);
                var bothExtentWrappers =
                    new Set<LeftCellWrapper>(parentWrappers);
                bothExtentWrappers.AddRange(childWrappers);
                var record = new ErrorLog.Record(
                    ViewGenErrorCode.ForeignKeyMissingRelationshipMapping, message, bothExtentWrappers, String.Empty);
                errorLog.AddEntry(record);
            }
        }
        // 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);
            }
        }
        // effects: Checks that this foreign key constraints for all the
        // tables are being ensured on the C-side as well. If not, adds 
        // errors to the errorLog
        internal void CheckConstraint(
            Set<Cell> cells, QueryRewriter childRewriter, QueryRewriter parentRewriter,
            ErrorLog errorLog, ConfigViewGenerator config)
        {
            if (IsConstraintRelevantForCells(cells) == false)
            {
                // if the constraint does not deal with any cell in this group, ignore it
                return;
            }

            if (config.IsNormalTracing)
            {
                Trace.WriteLine(String.Empty);
                Trace.WriteLine(String.Empty);
                Trace.Write("Checking: ");
                Trace.WriteLine(this);
            }

            if (childRewriter == null
                && parentRewriter == null)
            {
                // Neither table is mapped - so we are fine
                return;
            }

            // If the child table has not been mapped, we used to say that we
            // are fine. However, if we have SPerson(pid) and SAddress(aid,
            // pid), where pid is an FK into SPerson, we are in trouble if
            // SAddress is not mapped - SPerson could get deleted. So we
            // check for it as well
            // if the parent table is not mapped, we also have a problem

            if (childRewriter == null)
            {
                var message = Strings.ViewGen_Foreign_Key_Missing_Table_Mapping(
                    ToUserString(), ChildTable.Name);
                // Get the cells from the parent table
                var record = new ErrorLog.Record(
                    ViewGenErrorCode.ForeignKeyMissingTableMapping, message, parentRewriter.UsedCells, String.Empty);
                errorLog.AddEntry(record);
                return;
            }

            if (parentRewriter == null)
            {
                var message = Strings.ViewGen_Foreign_Key_Missing_Table_Mapping(
                    ToUserString(), ParentTable.Name);
                // Get the cells from the child table
                var record = new ErrorLog.Record(
                    ViewGenErrorCode.ForeignKeyMissingTableMapping, message, childRewriter.UsedCells, String.Empty);
                errorLog.AddEntry(record);
                return;
            }

            // Note: we do not check if the parent columns correspond to the
            // table's keys - metadata checks for that

            //First check if the FK is covered by Foreign Key Association
            //If we find this, we don't need to check for independent associations. If user maps the Fk to both FK and independent associations,
            //the regular round tripping validation will catch the error.
            if (CheckIfConstraintMappedToForeignKeyAssociation(childRewriter, parentRewriter, cells))
            {
                return;
            }

            // Check if the foreign key in the child table corresponds to the primary key, i.e., if
            // the foreign key (e.g., pid, pid2) is a superset of the actual key members (e.g., pid), it means
            // that the foreign key is also the primary key for this table -- so we can propagate the queries upto C-Space
            // rather than doing the cell check

            var initialErrorLogSize = errorLog.Count;
            if (IsForeignKeySuperSetOfPrimaryKeyInChildTable())
            {
                GuaranteeForeignKeyConstraintInCSpace(childRewriter, parentRewriter, errorLog);
            }
            else
            {
                GuaranteeMappedRelationshipForForeignKey(childRewriter, parentRewriter, cells, errorLog, config);
            }

            if (initialErrorLogSize == errorLog.Count)
            {
                // Check if the order of columns in foreign key correponds to the
                // mappings in m_cellGroup, e.g., if <pid1, pid2> in SAddress is
                // a foreign key into <pid1, pid2> of the SPerson table, make
                // sure that this order is preserved through the mappings in m_cellGroup
                CheckForeignKeyColumnOrder(cells, errorLog);
            }
        }
        internal FragmentQuery GetDomainQuery(
            IEnumerable <FragmentQuery> fragmentQueries,
            EdmType generatedType)
        {
            if (this._context.ViewTarget != ViewTarget.QueryView)
            {
                return(FragmentQuery.Create((IEnumerable <MemberPath>) this._keyAttributes, BoolExpression.CreateOr(fragmentQueries.Select <FragmentQuery, BoolExpression>((Func <FragmentQuery, BoolExpression>)(fragmentQuery => fragmentQuery.Condition)).ToArray <BoolExpression>())));
            }
            BoolExpression literal;

            if (generatedType == null)
            {
                literal = BoolExpression.True;
            }
            else
            {
                IEnumerable <EdmType> types;
                if (this._typesGenerationMode == ViewGenMode.OfTypeOnlyViews)
                {
                    types = (IEnumerable <EdmType>) new HashSet <EdmType>()
                    {
                        this._generatedType
                    }
                }
                ;
                else
                {
                    types = MetadataHelper.GetTypeAndSubtypesOf(generatedType, (ItemCollection)this._context.EdmItemCollection, false);
                }
                literal = BoolExpression.CreateLiteral((BoolLiteral) new TypeRestriction(new MemberProjectedSlot(this._extentPath), new Domain(QueryRewriter.GetTypeConstants(types), this._domainMap.GetDomain(this._extentPath))), this._domainMap);
            }
            return(FragmentQuery.Create((IEnumerable <MemberPath>) this._keyAttributes, literal));
        }
 private FragmentQuery CreateMemberConditionQuery(
     MemberPath currentPath,
     Constant domainValue)
 {
     return(QueryRewriter.CreateMemberConditionQuery(currentPath, domainValue, (IEnumerable <MemberPath>) this._keyAttributes, this._domainMap));
 }
 private void EnsureConfigurationIsFullyMapped(
     MemberPath currentPath,
     BoolExpression currentWhereClause,
     HashSet <FragmentQuery> outputUsedViews,
     ErrorLog errorLog)
 {
     foreach (Constant domainValue in this.GetDomain(currentPath))
     {
         if (domainValue != Constant.Undefined)
         {
             BoolExpression       memberCondition = this.CreateMemberCondition(currentPath, domainValue);
             BoolExpression       and             = BoolExpression.CreateAnd(currentWhereClause, memberCondition);
             Tile <FragmentQuery> rewriting;
             if (!this.FindRewritingAndUsedViews((IEnumerable <MemberPath>) this._keyAttributes, and, outputUsedViews, out rewriting))
             {
                 if (!ErrorPatternMatcher.FindMappingErrors(this._context, this._domainMap, this._errorLog))
                 {
                     StringBuilder  builder   = new StringBuilder();
                     string         str       = StringUtil.FormatInvariant("{0}", (object)this._extentPath);
                     BoolExpression condition = rewriting.Query.Condition;
                     condition.ExpensiveSimplify();
                     if (condition.RepresentsAllTypeConditions)
                     {
                         string viewGenExtent = Strings.ViewGen_Extent;
                         builder.AppendLine(Strings.ViewGen_Cannot_Recover_Types((object)viewGenExtent, (object)str));
                     }
                     else
                     {
                         string viewGenEntities = Strings.ViewGen_Entities;
                         builder.AppendLine(Strings.ViewGen_Cannot_Disambiguate_MultiConstant((object)viewGenEntities, (object)str));
                     }
                     RewritingValidator.EntityConfigurationToUserString(condition, builder);
                     ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.AmbiguousMultiConstants, builder.ToString(), (IEnumerable <LeftCellWrapper>) this._context.AllWrappersForExtent, string.Empty);
                     errorLog.AddEntry(record);
                 }
             }
             else
             {
                 TypeConstant typeConstant = domainValue as TypeConstant;
                 if (typeConstant != null)
                 {
                     EdmType                  edmType = typeConstant.EdmType;
                     List <MemberPath>        list    = QueryRewriter.GetNonConditionalScalarMembers(edmType, currentPath, this._domainMap).Union <MemberPath>(QueryRewriter.GetNonConditionalComplexMembers(edmType, currentPath, this._domainMap)).ToList <MemberPath>();
                     IEnumerable <MemberPath> notCoveredAttributes;
                     if (list.Count > 0 && !this.FindRewritingAndUsedViews((IEnumerable <MemberPath>)list, and, outputUsedViews, out rewriting, out notCoveredAttributes))
                     {
                         List <MemberPath> memberPathList = new List <MemberPath>(list.Where <MemberPath>((Func <MemberPath, bool>)(a => !a.IsPartOfKey)));
                         this.AddUnrecoverableAttributesError(notCoveredAttributes, memberCondition, errorLog);
                     }
                     else
                     {
                         foreach (MemberPath conditionalComplexMember in QueryRewriter.GetConditionalComplexMembers(edmType, currentPath, this._domainMap))
                         {
                             this.EnsureConfigurationIsFullyMapped(conditionalComplexMember, and, outputUsedViews, errorLog);
                         }
                         foreach (MemberPath conditionalScalarMember in QueryRewriter.GetConditionalScalarMembers(edmType, currentPath, this._domainMap))
                         {
                             this.EnsureConfigurationIsFullyMapped(conditionalScalarMember, and, outputUsedViews, errorLog);
                         }
                     }
                 }
             }
         }
     }
 }
 private void AdjustMemberDomainsForUpdateViews()
 {
     if (this._context.ViewTarget != ViewTarget.UpdateView)
     {
         return;
     }
     foreach (MemberPath memberPath in new List <MemberPath>(this._domainMap.ConditionMembers(this._extentPath.Extent)))
     {
         MemberPath currentPath  = memberPath;
         Constant   domainValue1 = this._domainMap.GetDomain(currentPath).FirstOrDefault <Constant>((Func <Constant, bool>)(domainValue => QueryRewriter.IsDefaultValue(domainValue, currentPath)));
         if (domainValue1 != null)
         {
             this.RemoveUnusedValueFromStoreDomain(domainValue1, currentPath);
         }
         Constant domainValue2 = this._domainMap.GetDomain(currentPath).FirstOrDefault <Constant>((Func <Constant, bool>)(domainValue => domainValue is NegatedConstant));
         if (domainValue2 != null)
         {
             this.RemoveUnusedValueFromStoreDomain(domainValue2, currentPath);
         }
     }
 }
        // 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;
        }
        private void AddUnrecoverableAttributesError(
            IEnumerable <MemberPath> attributes,
            BoolExpression domainAddedWhereClause,
            ErrorLog errorLog)
        {
            StringBuilder builder              = new StringBuilder();
            string        str                  = StringUtil.FormatInvariant("{0}", (object)this._extentPath);
            string        viewGenExtent        = Strings.ViewGen_Extent;
            string        commaSeparatedString = StringUtil.ToCommaSeparatedString((IEnumerable)QueryRewriter.GetTypeBasedMemberPathList(attributes));

            builder.AppendLine(Strings.ViewGen_Cannot_Recover_Attributes((object)commaSeparatedString, (object)viewGenExtent, (object)str));
            RewritingValidator.EntityConfigurationToUserString(domainAddedWhereClause, builder);
            ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.AttributesUnrecoverable, builder.ToString(), (IEnumerable <LeftCellWrapper>) this._context.AllWrappersForExtent, string.Empty);
            errorLog.AddEntry(record);
        }
        private void GenerateCaseStatements(
            IEnumerable <MemberPath> members,
            HashSet <FragmentQuery> outputUsedViews)
        {
            CellTreeNode rightDomainQuery = (CellTreeNode) new OpCellTreeNode(this._context, CellTreeOpType.Union, (CellTreeNode[])this._context.AllWrappersForExtent.Where <LeftCellWrapper>((Func <LeftCellWrapper, bool>)(w => this._usedViews.Contains(w.FragmentQuery))).Select <LeftCellWrapper, LeafCellTreeNode>((Func <LeftCellWrapper, LeafCellTreeNode>)(wrapper => new LeafCellTreeNode(this._context, wrapper))).ToArray <LeafCellTreeNode>());

            foreach (MemberPath member in members)
            {
                List <Constant>      list          = this.GetDomain(member).ToList <Constant>();
                CaseStatement        caseStatement = new CaseStatement(member);
                Tile <FragmentQuery> tile          = (Tile <FragmentQuery>)null;
                bool flag = list.Count != 2 || !list.Contains <Constant>(Constant.Null, Constant.EqualityComparer) || !list.Contains <Constant>(Constant.NotNull, Constant.EqualityComparer);
                foreach (Constant domainValue in list)
                {
                    if (domainValue == Constant.Undefined && this._context.ViewTarget == ViewTarget.QueryView)
                    {
                        caseStatement.AddWhenThen(BoolExpression.False, (ProjectedSlot) new ConstantProjectedSlot(Constant.Undefined));
                    }
                    else
                    {
                        FragmentQuery        memberConditionQuery = this.CreateMemberConditionQuery(member, domainValue);
                        Tile <FragmentQuery> rewriting;
                        if (this.FindRewritingAndUsedViews((IEnumerable <MemberPath>)memberConditionQuery.Attributes, memberConditionQuery.Condition, outputUsedViews, out rewriting))
                        {
                            if (this._context.ViewTarget == ViewTarget.UpdateView)
                            {
                                tile = tile != null?this._qp.Union(tile, rewriting) : rewriting;
                            }
                            if (flag)
                            {
                                if (this.AddRewritingToCaseStatement(rewriting, caseStatement, member, domainValue))
                                {
                                    break;
                                }
                            }
                        }
                        else if (!QueryRewriter.IsDefaultValue(domainValue, member) && !ErrorPatternMatcher.FindMappingErrors(this._context, this._domainMap, this._errorLog))
                        {
                            StringBuilder builder = new StringBuilder();
                            string        str1    = StringUtil.FormatInvariant("{0}", (object)this._extentPath);
                            string        str2    = this._context.ViewTarget == ViewTarget.QueryView ? Strings.ViewGen_Entities : Strings.ViewGen_Tuples;
                            if (this._context.ViewTarget == ViewTarget.QueryView)
                            {
                                builder.AppendLine(Strings.Viewgen_CannotGenerateQueryViewUnderNoValidation((object)str1));
                            }
                            else
                            {
                                builder.AppendLine(Strings.ViewGen_Cannot_Disambiguate_MultiConstant((object)str2, (object)str1));
                            }
                            RewritingValidator.EntityConfigurationToUserString(memberConditionQuery.Condition, builder, this._context.ViewTarget == ViewTarget.UpdateView);
                            this._errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.AmbiguousMultiConstants, builder.ToString(), (IEnumerable <LeftCellWrapper>) this._context.AllWrappersForExtent, string.Empty));
                        }
                    }
                }
                if (this._errorLog.Count == 0)
                {
                    if (this._context.ViewTarget == ViewTarget.UpdateView && flag)
                    {
                        this.AddElseDefaultToCaseStatement(member, caseStatement, list, rightDomainQuery, tile);
                    }
                    if (caseStatement.Clauses.Count > 0)
                    {
                        this._caseStatements[member] = caseStatement;
                    }
                }
            }
        }
Exemplo n.º 26
0
        private QueryRewriter GenerateViewsForExtentAndType(
            EdmType generatedType, ViewgenContext context, CqlIdentifiers identifiers, ViewSet views, ViewGenMode mode)
        {
            Debug.Assert(mode != ViewGenMode.GenerateAllViews, "By definition this method can not handle generating views for all extents");

            var queryRewriter = new QueryRewriter(generatedType, context, mode);
            queryRewriter.GenerateViewComponents();

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

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

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

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

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

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

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

            return queryRewriter;
        }
        private bool RewriteQuery(
            Tile <FragmentQuery> toFill,
            Tile <FragmentQuery> toAvoid,
            out Tile <FragmentQuery> rewriting,
            out IEnumerable <MemberPath> notCoveredAttributes,
            bool isRelaxed)
        {
            notCoveredAttributes = (IEnumerable <MemberPath>) new List <MemberPath>();
            FragmentQuery query1 = toFill.Query;

            if (this._context.TryGetCachedRewriting(query1, out rewriting))
            {
                return(true);
            }
            IEnumerable <Tile <FragmentQuery> > relevantViews = this.GetRelevantViews(query1);
            FragmentQuery query2 = query1;

            if (!this.RewriteQueryCached((Tile <FragmentQuery>)QueryRewriter.CreateTile(FragmentQuery.Create(query1.Condition)), toAvoid, relevantViews, out rewriting))
            {
                if (!isRelaxed)
                {
                    return(false);
                }
                query1 = FragmentQuery.Create((IEnumerable <MemberPath>)query1.Attributes, BoolExpression.CreateAndNot(query1.Condition, rewriting.Query.Condition));
                if (this._qp.IsEmpty((Tile <FragmentQuery>)QueryRewriter.CreateTile(query1)) || !this.RewriteQueryCached((Tile <FragmentQuery>)QueryRewriter.CreateTile(FragmentQuery.Create(query1.Condition)), toAvoid, relevantViews, out rewriting))
                {
                    return(false);
                }
            }
            if (query1.Attributes.Count == 0)
            {
                return(true);
            }
            Dictionary <MemberPath, FragmentQuery> attributeConditions = new Dictionary <MemberPath, FragmentQuery>();

            foreach (MemberPath nonKey in QueryRewriter.NonKeys((IEnumerable <MemberPath>)query1.Attributes))
            {
                attributeConditions[nonKey] = query1;
            }
            if (attributeConditions.Count == 0 || this.CoverAttributes(ref rewriting, attributeConditions))
            {
                this.GetUsedViewsAndRemoveTrueSurrogate(ref rewriting);
                this._context.SetCachedRewriting(query2, rewriting);
                return(true);
            }
            if (isRelaxed)
            {
                foreach (MemberPath nonKey in QueryRewriter.NonKeys((IEnumerable <MemberPath>)query1.Attributes))
                {
                    FragmentQuery fragmentQuery;
                    attributeConditions[nonKey] = !attributeConditions.TryGetValue(nonKey, out fragmentQuery) ? query1 : FragmentQuery.Create(BoolExpression.CreateAndNot(query1.Condition, fragmentQuery.Condition));
                }
                if (this.CoverAttributes(ref rewriting, attributeConditions))
                {
                    this.GetUsedViewsAndRemoveTrueSurrogate(ref rewriting);
                    this._context.SetCachedRewriting(query2, rewriting);
                    return(true);
                }
            }
            notCoveredAttributes = (IEnumerable <MemberPath>)attributeConditions.Keys;
            return(false);
        }