// effects: Creates a view generator object that can be used to generate views
 // based on usedCells (projectedSlotMap are useful for deciphering the fields)
 internal BasicViewGenerator(MemberProjectionIndex projectedSlotMap, List<LeftCellWrapper> usedCells, FragmentQuery activeDomain,
                             ViewgenContext context, MemberDomainMap domainMap, ErrorLog errorLog, ConfigViewGenerator config)
 {
     Debug.Assert(usedCells.Count > 0, "No used cells");
     m_projectedSlotMap = projectedSlotMap;
     m_usedCells = usedCells;
     m_viewgenContext = context;
     m_activeDomain = activeDomain;
     m_errorLog = errorLog;
     m_config = config;
     m_domainMap = domainMap;
 }
Exemplo n.º 2
0
 // effects: Returns the cached rewriting of (left) queries in terms of views, if any
 internal bool TryGetCachedRewriting(FragmentQuery query, out Tile<FragmentQuery> rewriting)
 {
     return m_rewritingCache.TryGetValue(query, out rewriting);
 }
Exemplo n.º 3
0
 // effects: Records the cached rewriting of (left) queries in terms of views
 internal void SetCachedRewriting(FragmentQuery query, Tile<FragmentQuery> rewriting)
 {
     m_rewritingCache[query] = rewriting;
 }
Exemplo n.º 4
0
        internal QueryRewriter(EdmType generatedType, ViewgenContext context, ViewGenMode typesGenerationMode)
        {
            Debug.Assert(typesGenerationMode != ViewGenMode.GenerateAllViews);

            _typesGenerationMode = typesGenerationMode;
            _context = context;
            _generatedType = generatedType;
            _domainMap = context.MemberMaps.LeftDomainMap;
            _config = context.Config;
            _identifiers = context.CqlIdentifiers;
            _qp = new RewritingProcessor<Tile<FragmentQuery>>(new DefaultTileProcessor<FragmentQuery>(context.LeftFragmentQP));
            _extentPath = new MemberPath(context.Extent);
            _keyAttributes = new List<MemberPath>(MemberPath.GetKeyMembers(context.Extent, _domainMap));

            // populate _fragmentQueries and _views
            foreach (var leftCellWrapper in _context.AllWrappersForExtent)
            {
                var query = leftCellWrapper.FragmentQuery;
                Tile<FragmentQuery> tile = CreateTile(query);
                _fragmentQueries.Add(query);
                _views.Add(tile);
            }
            Debug.Assert(_views.Count > 0);

            AdjustMemberDomainsForUpdateViews();

            // must be done after adjusting domains
            _domainQuery = GetDomainQuery(FragmentQueries, generatedType);

            _usedViews = new HashSet<FragmentQuery>();
        }
Exemplo n.º 5
0
        // This makes sure that the mapping describes how to store all C-side data,
        // i.e., the view given by C-side cell queries is injective
        internal void EnsureExtentIsFullyMapped(HashSet<FragmentQuery> outputUsedViews)
        {
            if (_context.ViewTarget == ViewTarget.QueryView
                && _config.IsValidationEnabled)
            {
                // Run the check below for OfType views too so we can determine
                // what views are used (low overhead due to caching of rewritings)
                EnsureConfigurationIsFullyMapped(_extentPath, BoolExpression.True, outputUsedViews, _errorLog);
                if (_errorLog.Count > 0)
                {
                    ExceptionHelpers.ThrowMappingException(_errorLog, _config);
                }
            }
            else
            {
                if (_config.IsValidationEnabled)
                {
                    // Ensure that non-nullable, no-default attributes are always populated properly
                    foreach (var memberPath in _context.MemberMaps.ProjectedSlotMap.Members)
                    {
                        Constant defaultConstant;
                        if (memberPath.IsScalarType()
                            &&
                            !memberPath.IsPartOfKey
                            &&
                            !_domainMap.IsConditionMember(memberPath)
                            &&
                            !Domain.TryGetDefaultValueForMemberPath(memberPath, out defaultConstant))
                        {
                            var attributes = new HashSet<MemberPath>(_keyAttributes);
                            attributes.Add(memberPath);
                            foreach (var leftCellWrapper in _context.AllWrappersForExtent)
                            {
                                var fragmentQuery = leftCellWrapper.FragmentQuery;

                                var tileQuery = new FragmentQuery(
                                    fragmentQuery.Description, fragmentQuery.FromVariable,
                                    attributes, fragmentQuery.Condition);
                                Tile<FragmentQuery> noNullToAvoid =
                                    CreateTile(FragmentQuery.Create(_keyAttributes, BoolExpression.CreateNot(fragmentQuery.Condition)));
                                Tile<FragmentQuery> noNullRewriting;
                                IEnumerable<MemberPath> notCoveredAttributes;
                                if (
                                    !RewriteQuery(
                                        CreateTile(tileQuery), noNullToAvoid, /*_views,*/ out noNullRewriting, out notCoveredAttributes,
                                        false /* isRelaxed */))
                                {
                                    // force error
                                    Domain.GetDefaultValueForMemberPath(memberPath, new[] { leftCellWrapper }, _config);
                                }
                            }
                        }
                    }
                }

                // find a rewriting for each tile
                // some of the views may be redundant and unused
                foreach (var toFill in _views)
                {
                    Tile<FragmentQuery> rewriting;
                    Tile<FragmentQuery> toAvoid =
                        CreateTile(FragmentQuery.Create(_keyAttributes, BoolExpression.CreateNot(toFill.Query.Condition)));
                    IEnumerable<MemberPath> notCoveredAttributes;
                    var found = RewriteQuery(toFill, toAvoid, out rewriting, out notCoveredAttributes, true /* isRelaxed */);

                    //Must be able to find the rewriting since the query is one of the views
                    // otherwise it means condition on the fragment is not satisfiable 
                    if (!found)
                    {
                        var fragment = _context.AllWrappersForExtent.First(lcr => lcr.FragmentQuery.Equals(toFill.Query));
                        Debug.Assert(fragment != null);

                        var record = new ErrorLog.Record(
                            ViewGenErrorCode.ImpopssibleCondition, Strings.Viewgen_QV_RewritingNotFound(fragment.RightExtent.ToString()),
                            fragment.Cells, String.Empty);
                        _errorLog.AddEntry(record);
                    }
                    else
                    {
                        outputUsedViews.UnionWith(rewriting.GetNamedQueries());
                    }
                }
            }
        }
Exemplo n.º 6
0
        // Returns MemberPaths which have conditions in the where clause
        // Filters out all trivial conditions (e.g., num=1 where dom(num)={1})
        // i.e., where all constants from the domain are contained in range
        private static Set<MemberPath> GetVariables(FragmentQuery query)
        {
            var memberVariables =
                from domainConstraint in query.Condition.VariableConstraints
                where domainConstraint.Variable.Identifier is MemberRestriction &&
                      false == domainConstraint.Variable.Domain.All(constant => domainConstraint.Range.Contains(constant))
                select ((MemberRestriction)domainConstraint.Variable.Identifier).RestrictedMemberSlot.MemberPath;

            return new Set<MemberPath>(memberVariables, MemberPath.EqualityComparer);
        }
Exemplo n.º 7
0
 private bool IsTrue(FragmentQuery query)
 {
     return !_context.LeftFragmentQP.IsSatisfiable(FragmentQuery.Create(BoolExpression.CreateNot(query.Condition)));
 }
Exemplo n.º 8
0
        private IEnumerable<Tile<FragmentQuery>> GetRelevantViews(FragmentQuery query)
        {
            // Step 1:
            // Determine connected and directly/indirectly connected variables
            // Directly connected variables: those that appear in query's WHERE clause
            // Indirectly connected variables: directly connected variables + variables in all views that contain directly connected variables
            // Disconnected variables: those that appear in some view's WHERE clause but are not indirectly connected
            var connectedVariables = GetVariables(query);

            // Step 2:
            // Take a union of all views that contain connected variables
            // If it evaluates to True, we can discard all other views; no special True-view is needed
            // Otherwise:
            //   If isRelaxed == false:
            //       Take a union of all views. If it yields True, than assume that True-view is available.
            //       Later, try to pick a smaller subset (instead of all views) once we know that attributes are needed
            //   If isRelaxed == true:
            //       Discard all views that don't contain connected variables; assume that True-view is available
            Tile<FragmentQuery> unionOfConnectedViews = null;
            var connectedViews = new List<Tile<FragmentQuery>>();
            Tile<FragmentQuery> firstTrueView = null;
            foreach (var tile in _views)
            {
                // notice: this is a syntactic check. We assume that if the variable is not present in the condition,
                // its value is unrestricted (which in general may not be true because the KB may have e.g., X=1 => Y=1,
                // so even if condition on Y is absent, the view would still be relevant
                if (GetVariables(tile.Query).Overlaps(connectedVariables))
                {
                    unionOfConnectedViews = (unionOfConnectedViews == null) ? tile : _qp.Union(unionOfConnectedViews, tile);
                    connectedViews.Add(tile);
                }
                else if (IsTrue(tile.Query)
                         && firstTrueView == null)
                {
                    firstTrueView = tile; // don't add True views; only one of them might be needed, if at all
                }
            }
            if (unionOfConnectedViews != null
                &&
                IsTrue(unionOfConnectedViews.Query)) // the collected views give us "True"
            {
                return connectedViews;
            }
            if (firstTrueView == null)
            {
                // can we obtain True at all?
                Tile<FragmentQuery> unionTile = null;
                foreach (var view in _fragmentQueries)
                {
                    unionTile = (unionTile == null) ? CreateTile(view) : _qp.Union(unionTile, CreateTile(view));
                    if (IsTrue(unionTile.Query))
                    {
                        // yes, we can; use a surrogate view - replace it later
                        firstTrueView = _trueViewSurrogate;
                        break;
                    }
                }
            }

            if (firstTrueView != null) // the collected views don't give us True, but 
            {
                connectedViews.Add(firstTrueView);
                return connectedViews;
            }

            // Step 3:
            // For each indirectly-connected variable x:
            // Union all views that contain x. The condition on x must disappear, i.e., union must imply that x is in Domain(x)
            // That is, the union must be equivalent to the expression in which all conditions on x have been eliminated.
            // If that's not the case (i.e., can't get rid of x), remove all these views from consideration.

            return _views;
        }
Exemplo n.º 9
0
 private static TileNamed<FragmentQuery> CreateTile(FragmentQuery query)
 {
     return new TileNamed<FragmentQuery>(query);
 }
Exemplo n.º 10
0
 // returns true if the view is useful for covering the projected attribute
 private bool CoverAttribute(
     MemberPath projectedAttribute, FragmentQuery view, Dictionary<MemberPath, FragmentQuery> attributeConditions)
 {
     FragmentQuery currentAttributeCondition;
     if (attributeConditions.TryGetValue(projectedAttribute, out currentAttributeCondition))
     {
         currentAttributeCondition =
             FragmentQuery.Create(BoolExpression.CreateAndNot(currentAttributeCondition.Condition, view.Condition));
         if (_qp.IsEmpty(CreateTile(currentAttributeCondition)))
         {
             // this attribute is covered! remove it from the list
             attributeConditions.Remove(projectedAttribute);
         }
         else
         {
             attributeConditions[projectedAttribute] = currentAttributeCondition;
         }
         return true;
     }
     return false;
 }
Exemplo n.º 11
0
 private bool CoverAttributes(ref Tile<FragmentQuery> rewriting, FragmentQuery toFillQuery,
     Dictionary<MemberPath, FragmentQuery> attributeConditions)
 {
     // first, account for already used views
     HashSet<FragmentQuery> usedViews = new HashSet<FragmentQuery>(rewriting.GetNamedQueries());
     Debug.Assert(usedViews.Count > 0);
     //List<FragmentQuery> usedViewsList = new List<FragmentQuery>(usedViews);
     //usedViewsList.Sort(FragmentQuery.GetComparer(toFillQuery.Attributes));
     foreach (FragmentQuery view in usedViews)
     {
         foreach (MemberPath projectedAttribute in NonKeys(view.Attributes))
         {
             CoverAttribute(projectedAttribute, view, attributeConditions, toFillQuery);
         }
         if (attributeConditions.Count == 0)
         {
             return true; // we are done
         }
     }
     // still need to fill some attributes
     Tile<FragmentQuery> attributeTile = null;
     foreach (FragmentQuery view in _fragmentQueries)
     {
         foreach (MemberPath projectedAttribute in NonKeys(view.Attributes))
         {
             if (CoverAttribute(projectedAttribute, view, attributeConditions, toFillQuery))
             {
                 attributeTile = (attributeTile == null) ? CreateTile(view) : _qp.Union(attributeTile, CreateTile(view));
             }
         }
         if (attributeConditions.Count == 0)
         {
             break; // we are done!
         }
     }
     if (attributeConditions.Count == 0)
     {
         // yes, we covered all attributes
         Debug.Assert(attributeTile != null);
         rewriting = _qp.Join(rewriting, attributeTile);
         return true;
     }
     else
     {
         // create rewriting that we couldn't satisfy
         return false; // couldn't cover some attribute(s)
     }
 }
Exemplo n.º 12
0
 // effects: Returns the cached rewriting of (left) queries in terms of views, if any
 internal bool TryGetCachedRewriting(FragmentQuery query, out Tile <FragmentQuery> rewriting)
 {
     return(m_rewritingCache.TryGetValue(query, out rewriting));
 }
 private FragmentQuery CreateRightFragmentQuery(LeftCellWrapper wrapper)
 {
     return(FragmentQuery.Create(wrapper.OnlyInputCell.CellLabel.ToString(), wrapper.CreateRoleBoolean(), wrapper.OnlyInputCell.GetRightQuery(this.m_viewgenContext.ViewTarget)));
 }
        private void MatchPartitionErrors()
        {
            List <LeftCellWrapper> wrappersForExtent = this.m_viewgenContext.AllWrappersForExtent;
            int num = 0;

            foreach (LeftCellWrapper leftCellWrapper1 in wrappersForExtent)
            {
                foreach (LeftCellWrapper leftCellWrapper2 in wrappersForExtent.Skip <LeftCellWrapper>(++num))
                {
                    FragmentQuery rightFragmentQuery1 = this.CreateRightFragmentQuery(leftCellWrapper1);
                    FragmentQuery rightFragmentQuery2 = this.CreateRightFragmentQuery(leftCellWrapper2);
                    bool          flag1 = this.CompareS(ErrorPatternMatcher.ComparisonOP.IsDisjointFrom, this.m_viewgenContext, leftCellWrapper1, leftCellWrapper2, rightFragmentQuery1, rightFragmentQuery2);
                    bool          flag2 = this.CompareC(ErrorPatternMatcher.ComparisonOP.IsDisjointFrom, this.m_viewgenContext, leftCellWrapper1, leftCellWrapper2, rightFragmentQuery1, rightFragmentQuery2);
                    bool          flag3;
                    bool          flag4;
                    if (flag1)
                    {
                        if (!flag2)
                        {
                            flag3 = this.CompareC(ErrorPatternMatcher.ComparisonOP.IsContainedIn, this.m_viewgenContext, leftCellWrapper1, leftCellWrapper2, rightFragmentQuery1, rightFragmentQuery2);
                            flag4 = this.CompareC(ErrorPatternMatcher.ComparisonOP.IsContainedIn, this.m_viewgenContext, leftCellWrapper2, leftCellWrapper1, rightFragmentQuery2, rightFragmentQuery1);
                            bool          flag5         = flag3 && flag4;
                            StringBuilder stringBuilder = new StringBuilder();
                            if (flag5)
                            {
                                stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Disj_Eq);
                            }
                            else if (flag3 || flag4)
                            {
                                if (this.CSideHasDifferentEntitySets(leftCellWrapper1, leftCellWrapper2))
                                {
                                    stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Disj_Subs_Ref);
                                }
                                else
                                {
                                    stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Disj_Subs);
                                }
                            }
                            else
                            {
                                stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Disj_Unk);
                            }
                            this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.ErrorPatternInvalidPartitionError, stringBuilder.ToString(), ErrorPatternMatcher.ToIEnum(leftCellWrapper1.OnlyInputCell, leftCellWrapper2.OnlyInputCell), ""));
                            if (this.FoundTooManyErrors())
                            {
                                return;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        flag3 = this.CompareC(ErrorPatternMatcher.ComparisonOP.IsContainedIn, this.m_viewgenContext, leftCellWrapper1, leftCellWrapper2, rightFragmentQuery1, rightFragmentQuery2);
                        flag4 = this.CompareC(ErrorPatternMatcher.ComparisonOP.IsContainedIn, this.m_viewgenContext, leftCellWrapper2, leftCellWrapper1, rightFragmentQuery2, rightFragmentQuery1);
                    }
                    bool flag6 = this.CompareS(ErrorPatternMatcher.ComparisonOP.IsContainedIn, this.m_viewgenContext, leftCellWrapper1, leftCellWrapper2, rightFragmentQuery1, rightFragmentQuery2);
                    bool flag7 = this.CompareS(ErrorPatternMatcher.ComparisonOP.IsContainedIn, this.m_viewgenContext, leftCellWrapper2, leftCellWrapper1, rightFragmentQuery2, rightFragmentQuery1);
                    bool flag8 = flag3 && flag4;
                    if (flag6 && flag7)
                    {
                        if (!flag8)
                        {
                            StringBuilder stringBuilder = new StringBuilder();
                            if (flag2)
                            {
                                stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Eq_Disj);
                            }
                            else if (flag3 || flag4)
                            {
                                if (this.CSideHasDifferentEntitySets(leftCellWrapper1, leftCellWrapper2))
                                {
                                    stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Eq_Subs_Ref);
                                }
                                else
                                {
                                    if (leftCellWrapper1.LeftExtent.Equals((object)leftCellWrapper2.LeftExtent))
                                    {
                                        bool           hasCondition1;
                                        List <EdmType> edmTypes1;
                                        ErrorPatternMatcher.GetTypesAndConditionForWrapper(leftCellWrapper1, out hasCondition1, out edmTypes1);
                                        bool           hasCondition2;
                                        List <EdmType> edmTypes2;
                                        ErrorPatternMatcher.GetTypesAndConditionForWrapper(leftCellWrapper2, out hasCondition2, out edmTypes2);
                                        if (!hasCondition1 && !hasCondition2 && (edmTypes1.Except <EdmType>((IEnumerable <EdmType>)edmTypes2).Count <EdmType>() != 0 || edmTypes2.Except <EdmType>((IEnumerable <EdmType>)edmTypes1).Count <EdmType>() != 0) && (!ErrorPatternMatcher.CheckForStoreConditions(leftCellWrapper1) || !ErrorPatternMatcher.CheckForStoreConditions(leftCellWrapper2)))
                                        {
                                            this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.ErrorPatternConditionError, Strings.Viewgen_ErrorPattern_Partition_MultipleTypesMappedToSameTable_WithoutCondition((object)StringUtil.ToCommaSeparatedString((IEnumerable)edmTypes1.Select <EdmType, string>((Func <EdmType, string>)(it => it.FullName)).Union <string>(edmTypes2.Select <EdmType, string>((Func <EdmType, string>)(it => it.FullName)))), (object)leftCellWrapper1.LeftExtent), ErrorPatternMatcher.ToIEnum(leftCellWrapper1.OnlyInputCell, leftCellWrapper2.OnlyInputCell), ""));
                                            return;
                                        }
                                    }
                                    stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Eq_Subs);
                                }
                            }
                            else if (!this.IsQueryView() && (leftCellWrapper1.OnlyInputCell.CQuery.Extent is AssociationSet || leftCellWrapper2.OnlyInputCell.CQuery.Extent is AssociationSet))
                            {
                                stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Eq_Unk_Association);
                            }
                            else
                            {
                                stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Eq_Unk);
                            }
                            this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.ErrorPatternInvalidPartitionError, stringBuilder.ToString(), ErrorPatternMatcher.ToIEnum(leftCellWrapper1.OnlyInputCell, leftCellWrapper2.OnlyInputCell), ""));
                            if (this.FoundTooManyErrors())
                            {
                                return;
                            }
                        }
                    }
                    else if ((flag6 || flag7) && (!flag6 || !flag3 || flag4) && (!flag7 || !flag4 || flag3))
                    {
                        StringBuilder stringBuilder = new StringBuilder();
                        if (flag2)
                        {
                            stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Sub_Disj);
                        }
                        else if (flag8)
                        {
                            if (this.CSideHasDifferentEntitySets(leftCellWrapper1, leftCellWrapper2))
                            {
                                stringBuilder.Append(" " + Strings.Viewgen_ErrorPattern_Partition_Sub_Eq_Ref);
                            }
                            else
                            {
                                stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Sub_Eq);
                            }
                        }
                        else
                        {
                            stringBuilder.Append(Strings.Viewgen_ErrorPattern_Partition_Sub_Unk);
                        }
                        this.m_errorLog.AddEntry(new ErrorLog.Record(ViewGenErrorCode.ErrorPatternInvalidPartitionError, stringBuilder.ToString(), ErrorPatternMatcher.ToIEnum(leftCellWrapper1.OnlyInputCell, leftCellWrapper2.OnlyInputCell), ""));
                        if (this.FoundTooManyErrors())
                        {
                            return;
                        }
                    }
                }
            }
        }