/// <summary>
 /// Fixes the range of the restriction in accordance with <paramref name="range"/>.
 /// Member restriction must be complete for this operation. 
 /// </summary>
 internal override DomainBoolExpr FixRange(Set<Constant> range, MemberDomainMap memberDomainMap)
 {
     Debug.Assert(IsComplete, "Ranges are fixed only for complete scalar restrictions.");
     IEnumerable<Constant> newPossibleValues = memberDomainMap.GetDomain(RestrictedMemberSlot.MemberPath);
     BoolLiteral newLiteral = new ScalarRestriction(RestrictedMemberSlot, new Domain(range, newPossibleValues));
     return newLiteral.GetDomainBoolExpression(memberDomainMap);
 }
        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>();
        }
        internal override BoolExpr<DomainConstraint<BoolLiteral, Constant>> GetDomainBoolExpression(MemberDomainMap domainMap)
        {
            // Essentially say that the variable can take values true or false and here its value is only true
            IEnumerable<Constant> actualValues = new Constant[] { new ScalarConstant(true) };
            IEnumerable<Constant> possibleValues = new Constant[] { new ScalarConstant(true), new ScalarConstant(false) };
            var variableDomain = new Set<Constant>(possibleValues, Constant.EqualityComparer).MakeReadOnly();
            var thisDomain = new Set<Constant>(actualValues, Constant.EqualityComparer).MakeReadOnly();

            var result = MakeTermExpression(this, variableDomain, thisDomain);
            return result;
        }
 // 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;
 }
        internal MemberMaps(ViewTarget viewTarget, MemberProjectionIndex projectedSlotMap,
                            MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap)
        {

            m_projectedSlotMap = projectedSlotMap;
            m_queryDomainMap = queryDomainMap;
            m_updateDomainMap = updateDomainMap;

            Debug.Assert(m_queryDomainMap != null);
            Debug.Assert(m_updateDomainMap != null);
            Debug.Assert(m_projectedSlotMap != null);
            m_viewTarget = viewTarget;
        }
        internal override BoolExpr<DomainConstraint<BoolLiteral, Constant>> FixRange(Set<Constant> range, MemberDomainMap memberDomainMap)
        {
            Debug.Assert(range.Count == 1, "For BoolLiterals, there should be precisely one value - true or false");
            var scalar = (ScalarConstant)range.First();
            var expr = GetDomainBoolExpression(memberDomainMap);

            if ((bool)scalar.Value == false)
            {
                // The range of the variable was "inverted". Return a NOT of
                // the expression
                expr = new NotExpr<DomainConstraint<BoolLiteral, Constant>>(expr);
            }
            return expr;
        }
        // effects: Creates a ViewGenerator object that is capable of
        // producing query or update mapping views given the relevant schema
        // given the "cells"
        internal ViewGenerator(
            CellGroup cellGroup, ConfigViewGenerator config,
            List<ForeignConstraint> foreignKeyConstraints,
            StorageEntityContainerMapping entityContainerMapping)
        {
            m_cellGroup = cellGroup;
            m_config = config;
            m_queryRewriterCache = new Dictionary<EntitySetBase, QueryRewriter>();
            m_foreignKeyConstraints = foreignKeyConstraints;
            m_entityContainerMapping = entityContainerMapping;

            var inheritanceGraph =
                MetadataHelper.BuildUndirectedGraphOfTypes(entityContainerMapping.StorageMappingItemCollection.EdmItemCollection);
            SetConfiguration(entityContainerMapping);

            // We fix all the cells at this point
            m_queryDomainMap = new MemberDomainMap(
                ViewTarget.QueryView, m_config.IsValidationEnabled, cellGroup,
                entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, m_config, inheritanceGraph);
            m_updateDomainMap = new MemberDomainMap(
                ViewTarget.UpdateView, m_config.IsValidationEnabled, cellGroup,
                entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, m_config, inheritanceGraph);

            // We now go and fix the queryDomain map so that it has all the
            // values from the S-side as well -- this is needed for domain
            // constraint propagation, i.e., values from the S-side get
            // propagated to te oneOfConst on the C-side. So we better get
            // the "possiblveValues" stuff to contain those constants as well
            MemberDomainMap.PropagateUpdateDomainToQueryDomain(cellGroup, m_queryDomainMap, m_updateDomainMap);

            UpdateWhereClauseForEachCell(cellGroup, m_queryDomainMap, m_updateDomainMap, m_config);

            // We need to simplify cell queries, yet we don't want the conditions to disappear
            // So, add an extra value to the domain, temporarily
            var queryOpenDomain = m_queryDomainMap.GetOpenDomain();
            var updateOpenDomain = m_updateDomainMap.GetOpenDomain();

            // Make sure the WHERE clauses of the cells reflect the changes
            foreach (var cell in cellGroup)
            {
                cell.CQuery.WhereClause.FixDomainMap(queryOpenDomain);
                cell.SQuery.WhereClause.FixDomainMap(updateOpenDomain);
                cell.CQuery.WhereClause.ExpensiveSimplify();
                cell.SQuery.WhereClause.ExpensiveSimplify();
                cell.CQuery.WhereClause.FixDomainMap(m_queryDomainMap);
                cell.SQuery.WhereClause.FixDomainMap(m_updateDomainMap);
            }
        }
        // effects: Given the extent cells and a map for the domains of all
        // variables in it, fixes the cell constant domains of the where
        // clauses in the left queries of cells (left is defined using viewTarget)
        private static void UpdateWhereClauseForEachCell(
            IEnumerable<Cell> extentCells, MemberDomainMap queryDomainMap,
            MemberDomainMap updateDomainMap, ConfigViewGenerator config)
        {
            foreach (var cell in extentCells)
            {
                cell.CQuery.UpdateWhereClause(queryDomainMap);
                cell.SQuery.UpdateWhereClause(updateDomainMap);
            }

            // Fix enumerable domains - currently it is only applicable to boolean type. Note that it is 
            // not applicable to enumerated types since we allow any value of the underlying type of the enum type.
            queryDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
            updateDomainMap.ReduceEnumerableDomainToEnumeratedValues(config);
        }
Beispiel #9
0
        // effects: Create a boolean expression from a literal value
        internal static BoolExpression CreateLiteral(BoolLiteral literal, MemberDomainMap memberDomainMap)
        {
            DomainBoolExpr expr = literal.GetDomainBoolExpression(memberDomainMap);

            return(new BoolExpression(expr, memberDomainMap));
        }
 /// <summary>
 /// Returns a boolean expression that is domain-aware and ready for optimizations etc.
 /// </summary>
 /// <param name="domainMap">Maps members to the values that each member can take;
 /// it can be null in which case the possible and actual values are the same.</param>
 internal override DomainBoolExpr GetDomainBoolExpression(MemberDomainMap domainMap)
 {
     // Get the variable name from the slot's memberpath and the possible domain values from the slot
     DomainTermExpr result;
     if (domainMap != null)
     {
         // Look up the domain from the domainMap
         IEnumerable<Constant> domain = domainMap.GetDomain(m_restrictedMemberSlot.MemberPath);
         result = MakeTermExpression(this, domain, m_domain.Values);
     }
     else
     {
         result = MakeTermExpression(this, m_domain.AllPossibleValues, m_domain.Values);
     }
     return result;
 }
        // effects: Merges query2 with this according to the TM/SP rules for opType and
        // returns the merged result. canBooleansOverlap indicates whether the bools in this and query2 can overlap, i.e.
        // the same cells may have contributed to query2 and this earlier in the merge process
        internal bool TryMergeTwoCellQueries(CellQuery query1, CellQuery query2, CellTreeOpType opType,
                               MemberDomainMap memberDomainMap, out CellQuery mergedQuery)
        {

            mergedQuery = null;
            // Initialize g1 and g2 according to the TM/SP rules for IJ, LOJ, Union, FOJ cases
            BoolExpression g1 = null;
            BoolExpression g2 = null;
            switch (opType)
            {
                case CellTreeOpType.IJ:
                    break;
                case CellTreeOpType.LOJ:
                case CellTreeOpType.LASJ:
                    g2 = BoolExpression.True;
                    break;
                case CellTreeOpType.FOJ:
                case CellTreeOpType.Union:
                    g1 = BoolExpression.True;
                    g2 = BoolExpression.True;
                    break;
                default:
                    Debug.Fail("Unsupported operator");
                    break;
            }

            Dictionary<MemberPath, MemberPath> remap =
                new Dictionary<MemberPath, MemberPath>(MemberPath.EqualityComparer);

            //Continue merging only if both queries are over the same source
            MemberPath newRoot;
            if (!query1.Extent.Equals(query2.Extent))
            { // could not merge
                return false;
            }
            else
            {
                newRoot = query1.SourceExtentMemberPath;
            }

            // Conjuncts for ANDing with the previous whereClauses
            BoolExpression conjunct1 = BoolExpression.True;
            BoolExpression conjunct2 = BoolExpression.True;
            BoolExpression whereClause = null;

            switch (opType)
            {
                case CellTreeOpType.IJ:
                    // Project[D1, D2, A, B, C] Select[cond1 and cond2] (T)
                    // We simply merge the two lists of booleans -- no conjuct is added
                    // conjunct1 and conjunct2 don't change

                    // query1.WhereCaluse AND query2.WhereCaluse
                    Debug.Assert(g1 == null && g2 == null, "IJ does not affect g1 and g2");
                    whereClause = BoolExpression.CreateAnd(query1.WhereClause, query2.WhereClause);
                    break;

                case CellTreeOpType.LOJ:
                    // conjunct1 does not change since D1 remains as is
                    // Project[D1, (expr2 and cond2 and G2) as D2, A, B, C] Select[cond1] (T)
                    // D1 does not change. New d2 is the list of booleans expressions
                    // for query2 ANDed with g2 AND query2.WhereClause
                    Debug.Assert(g1 == null, "LOJ does not affect g1");
                    conjunct2 = BoolExpression.CreateAnd(query2.WhereClause, g2);
                    // Just query1's whereclause
                    whereClause = query1.WhereClause;
                    break;

                case CellTreeOpType.FOJ:
                case CellTreeOpType.Union:
                    // Project[(expr1 and cond1 and G1) as D1, (expr2 and cond2 and G2) as D2, A, B, C] Select[cond1] (T)
                    // New D1 is a list -- newD1 = D1 AND query1.WhereClause AND g1
                    // New D1 is a list -- newD2 = D2 AND query2.WhereClause AND g2
                    conjunct1 = BoolExpression.CreateAnd(query1.WhereClause, g1);
                    conjunct2 = BoolExpression.CreateAnd(query2.WhereClause, g2);

                    // The new whereClause -- g1 AND query1.WhereCaluse OR g2 AND query2.WhereClause
                    whereClause = BoolExpression.CreateOr(BoolExpression.CreateAnd(query1.WhereClause, g1),
                                                          BoolExpression.CreateAnd(query2.WhereClause, g2));
                    break;

                case CellTreeOpType.LASJ:
                    // conjunct1 does not change since D1 remains as is
                    // Project[D1, (expr2 and cond2 and G2) as D2, A, B, C] Select[cond1] (T)
                    // D1 does not change. New d2 is the list of booleans expressions
                    // for query2 ANDed with g2 AND NOT query2.WhereClause
                    Debug.Assert(g1 == null, "LASJ does not affect g1");
                    conjunct2 = BoolExpression.CreateAnd(query2.WhereClause, g2);
                    whereClause = BoolExpression.CreateAnd(query1.WhereClause, BoolExpression.CreateNot(conjunct2));
                    break;
                default:
                    Debug.Fail("Unsupported operator");
                    break;
            }

            // Create the various remapped parts for the cell query --
            // boolean expressions, merged slots, whereclause, duplicate
            // elimination, join tree
            List<BoolExpression> boolExprs =
                MergeBoolExpressions(query1, query2, conjunct1, conjunct2, opType);
            //BoolExpression.RemapBools(boolExprs, remap);

            ProjectedSlot[] mergedSlots;
            if (false == ProjectedSlot.TryMergeRemapSlots(query1.ProjectedSlots, query2.ProjectedSlots, out mergedSlots))
            {
                // merging failed because two different right slots go to same left slot
                return false;
            }

            whereClause = whereClause.RemapBool(remap);

            CellQuery.SelectDistinct elimDupl = MergeDupl(query1.SelectDistinctFlag, query2.SelectDistinctFlag);

            whereClause.ExpensiveSimplify();
            mergedQuery = new CellQuery(mergedSlots, whereClause,
                                                  boolExprs, elimDupl, newRoot);
            return true;
        }
Beispiel #12
0
 internal abstract DomainBoolExpr GetDomainBoolExpression(MemberDomainMap domainMap);
Beispiel #13
0
 /// <summary>
 /// Fixes the range of the literal using the new values provided in <paramref name="range"/> and returns a boolean expression corresponding to the new value.
 /// </summary>
 internal abstract DomainBoolExpr FixRange(Set <Constant> range, MemberDomainMap memberDomainMap);
Beispiel #14
0
        // requires: this domainMap has been created for the C-side
        // effects: Fixes the mergedDomain map in this by merging entries
        // available in updateDomainMap
        internal static void PropagateUpdateDomainToQueryDomain(IEnumerable <Cell> cells, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap)
        {
            foreach (Cell cell in cells)
            {
                CellQuery cQuery = cell.CQuery;
                CellQuery sQuery = cell.SQuery;

                for (int i = 0; i < cQuery.NumProjectedSlots; i++)
                {
                    MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(i) as MemberProjectedSlot;
                    MemberProjectedSlot sSlot = sQuery.ProjectedSlotAt(i) as MemberProjectedSlot;

                    if (cSlot == null || sSlot == null)
                    {
                        continue;
                    }

                    // Get the domain for sSlot and merge with cSlot's
                    MemberPath      cPath   = cSlot.MemberPath;
                    MemberPath      sPath   = sSlot.MemberPath;
                    CellConstantSet cDomain = queryDomainMap.GetDomainInternal(cPath);
                    CellConstantSet sDomain = updateDomainMap.GetDomainInternal(sPath);

                    // skip NULL because if c-side member is nullable, it's already there, and otherwise can't be taken
                    // skip negated because negated values are translated in a special way
                    cDomain.Unite(sDomain.Where(constant => !constant.IsNull() && !(constant is NegatedConstant)));

                    if (updateDomainMap.IsConditionMember(sPath) && !queryDomainMap.IsConditionMember(cPath))
                    {
                        // record this member so KB knows we have to generate constraints for it
                        queryDomainMap.m_projectedConditionMembers.Add(cPath);
                    }
                }
            }

            ExpandNegationsInDomainMap(queryDomainMap.m_conditionDomainMap);
            ExpandNegationsInDomainMap(queryDomainMap.m_nonConditionDomainMap);
        }
Beispiel #15
0
 internal void FixDomainMap(MemberDomainMap domainMap)
 {
     Debug.Assert(domainMap != null, "Member domain map is not set");
     m_tree = FixRangeVisitor.FixRange(m_tree, domainMap);
 }
        /// <summary>
        /// Find the Foreign Key Associations that relate EntitySets used in these left cell wrappers and 
        /// add any equivalence facts between sets implied by 1:1 associations.
        /// We can collect other implication facts but we don't have a scenario that needs them( yet ).
        /// </summary>
        /// <param name="rightKB"></param>
        /// <param name="rightDomainMap"></param>
        private void CreateConstraintsForForeignKeyAssociationsAffectingThisWarapper(FragmentQueryKB rightKB, MemberDomainMap rightDomainMap)
        {
            //First find the entity types of the sets in these cell wrappers.
            var entityTypes = m_cellWrappers.Select(it => it.RightExtent).OfType<EntitySet>().Select(it => it.ElementType);
            //Get all the foreign key association sets in these entity sets
            var allForeignKeyAssociationSets = this.m_entityContainerMapping.EdmEntityContainer.BaseEntitySets.OfType<AssociationSet>().Where(it => it.ElementType.IsForeignKey);
            //Find all the foreign key associations that have corresponding sets
            var oneToOneForeignKeyAssociationsForThisWrapper = allForeignKeyAssociationSets.Select(it => it.ElementType);
            //Find all the 1:1 associations from the above list
            oneToOneForeignKeyAssociationsForThisWrapper = oneToOneForeignKeyAssociationsForThisWrapper.Where(it => (it.AssociationEndMembers.All(endMember => endMember.RelationshipMultiplicity == RelationshipMultiplicity.One)));
            //Filter the 1:1 foreign key associations to the ones relating the sets used in these cell wrappers.
            oneToOneForeignKeyAssociationsForThisWrapper = oneToOneForeignKeyAssociationsForThisWrapper.Where(it => (it.AssociationEndMembers.All(endMember => entityTypes.Contains(endMember.GetEntityType()))));

            //filter foreign key association sets to the sets that are 1:1 and affecting this wrapper.
            var oneToOneForeignKeyAssociationSetsForThisWrapper = allForeignKeyAssociationSets.Where(it => oneToOneForeignKeyAssociationsForThisWrapper.Contains(it.ElementType));

            //Collect the facts for the foreign key association sets that are 1:1 and affecting this wrapper
            foreach (var assocSet in oneToOneForeignKeyAssociationSetsForThisWrapper)
            {
                rightKB.CreateEquivalenceConstraintForOneToOneForeignKeyAssociation(assocSet, rightDomainMap, m_edmItemCollection);
            }
        }
        internal ViewgenContext(ViewTarget viewTarget, EntitySetBase extent, IEnumerable<Cell> extentCells,
                                CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap,
                                MemberDomainMap updateDomainMap, StorageEntityContainerMapping entityContainerMapping)
        {
            foreach (Cell cell in extentCells)
            {
                Debug.Assert(extent.Equals(cell.GetLeftQuery(viewTarget).Extent));
                Debug.Assert(cell.CQuery.NumProjectedSlots == cell.SQuery.NumProjectedSlots);
            }

            m_extent = extent;
            m_viewTarget = viewTarget;
            m_config = config;
            m_edmItemCollection = entityContainerMapping.StorageMappingItemCollection.EdmItemCollection;
            m_entityContainerMapping = entityContainerMapping;
            m_identifiers = identifiers;

            // create a copy of updateDomainMap so generation of query views later on is not affected
            // it is modified in QueryRewriter.AdjustMemberDomainsForUpdateViews
            updateDomainMap = updateDomainMap.MakeCopy();

            // Create a signature generator that handles all the
            // multiconstant work and generating the signatures
            MemberDomainMap domainMap = viewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap;

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

            // Create left fragment KB: includes constraints for the extent to be constructed
            FragmentQueryKB leftKB = new FragmentQueryKB();
            leftKB.CreateVariableConstraints(extent, domainMap, m_edmItemCollection);
            m_leftFragmentQP = new FragmentQueryProcessor(leftKB);
            m_rewritingCache = new Dictionary<FragmentQuery, Tile<FragmentQuery>>(
                FragmentQuery.GetEqualityComparer(m_leftFragmentQP));

            // Now using the signatures, create new cells such that
            // "extent's" query (C or S) is described in terms of multiconstants
            if (!CreateLeftCellWrappers(extentCells, viewTarget))
            {
                return;
            }

            // Create right fragment KB: includes constraints for all extents and association roles of right queries
            FragmentQueryKB rightKB = new FragmentQueryKB();
            MemberDomainMap rightDomainMap = viewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap;
            foreach (LeftCellWrapper leftCellWrapper in m_cellWrappers)
            {
                EntitySetBase rightExtent = leftCellWrapper.RightExtent;
                rightKB.CreateVariableConstraints(rightExtent, rightDomainMap, m_edmItemCollection);
                rightKB.CreateAssociationConstraints(rightExtent, rightDomainMap, m_edmItemCollection);
            }
            
            if (m_viewTarget == ViewTarget.UpdateView)
            {
                CreateConstraintsForForeignKeyAssociationsAffectingThisWarapper(rightKB, rightDomainMap);
            }

            m_rightFragmentQP = new FragmentQueryProcessor(rightKB);

            // Check for concurrency control tokens
            if (m_viewTarget == ViewTarget.QueryView)
            {
                CheckConcurrencyControlTokens();
            }
            // For backward compatibility -
            // order wrappers by increasing domain size, decreasing number of attributes
            m_cellWrappers.Sort(LeftCellWrapper.Comparer);
        }
Beispiel #18
0
        // requires: The CellConstantDomains in the OneOfConsts of the where
        // clause are partially done
        // effects: Given the domains of different variables in domainMap,
        // fixes the whereClause of this such that all the
        // CellConstantDomains in OneOfConsts are complete
        internal void UpdateWhereClause(MemberDomainMap domainMap)
        {
            var atoms = new List<BoolExpression>();
            foreach (var atom in WhereClause.Atoms)
            {
                var literal = atom.AsLiteral;
                var restriction = literal as MemberRestriction;
                Debug.Assert(restriction != null, "All bool literals must be OneOfConst at this point");
                // The oneOfConst needs to be fixed with the new possible values from the domainMap.
                var possibleValues = domainMap.GetDomain(restriction.RestrictedMemberSlot.MemberPath);
                var newOneOf = restriction.CreateCompleteMemberRestriction(possibleValues);

                // Prevent optimization of single constraint e.g: "300 in (300)"
                // But we want to optimize type constants e.g: "category in (Category)"
                // To prevent optimization of bool expressions we add a Sentinel OneOF

                var scalarConst = restriction as ScalarRestriction;
                var addSentinel =
                    scalarConst != null &&
                    !scalarConst.Domain.Contains(Constant.Null) &&
                    !scalarConst.Domain.Contains(Constant.NotNull) &&
                    !scalarConst.Domain.Contains(Constant.Undefined);

                if (addSentinel)
                {
                    domainMap.AddSentinel(newOneOf.RestrictedMemberSlot.MemberPath);
                }

                atoms.Add(BoolExpression.CreateLiteral(newOneOf, domainMap));

                if (addSentinel)
                {
                    domainMap.RemoveSentinel(newOneOf.RestrictedMemberSlot.MemberPath);
                }
            }
            // We create a new whereClause that has the memberDomainMap set
            if (atoms.Count > 0)
            {
                m_whereClause = BoolExpression.CreateAnd(atoms.ToArray());
            }
        }
Beispiel #19
0
        // requires: this domainMap has been created for the C-side
        // effects: Fixes the mergedDomain map in this by merging entries
        // available in updateDomainMap
        internal static void PropagateUpdateDomainToQueryDomain(IEnumerable<Cell> cells, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap)
        {

            foreach (Cell cell in cells)
            {
                CellQuery cQuery = cell.CQuery;
                CellQuery sQuery = cell.SQuery;

                for (int i = 0; i < cQuery.NumProjectedSlots; i++)
                {
                    MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(i) as MemberProjectedSlot;
                    MemberProjectedSlot sSlot = sQuery.ProjectedSlotAt(i) as MemberProjectedSlot;

                    if (cSlot == null || sSlot == null)
                    {
                        continue;
                    }

                    // Get the domain for sSlot and merge with cSlot's
                    MemberPath cPath = cSlot.MemberPath;
                    MemberPath sPath = sSlot.MemberPath;
                    CellConstantSet cDomain = queryDomainMap.GetDomainInternal(cPath);
                    CellConstantSet sDomain = updateDomainMap.GetDomainInternal(sPath);

                    // skip NULL because if c-side member is nullable, it's already there, and otherwise can't be taken
                    // skip negated because negated values are translated in a special way
                    cDomain.Unite(sDomain.Where(constant => !constant.IsNull() && !(constant is NegatedConstant)));

                    if (updateDomainMap.IsConditionMember(sPath) && !queryDomainMap.IsConditionMember(cPath))
                    {
                        // record this member so KB knows we have to generate constraints for it
                        queryDomainMap.m_projectedConditionMembers.Add(cPath);
                    }
                }
            }

            ExpandNegationsInDomainMap(queryDomainMap.m_conditionDomainMap);
            ExpandNegationsInDomainMap(queryDomainMap.m_nonConditionDomainMap);
        }
        internal static FragmentQuery CreateMemberConditionQuery(
            MemberPath currentPath, Constant domainValue,
            IEnumerable<MemberPath> keyAttributes, MemberDomainMap domainMap)
        {
            // construct WHERE clause for this value
            var domainWhereClause = FragmentQuery.CreateMemberCondition(currentPath, domainValue, domainMap);

            // get a rewriting for CASE statements by not requesting any attributes beyond key
            var attributes = keyAttributes;
            if (domainValue is NegatedConstant)
            {
                // we need the attribute value
                attributes = keyAttributes.Concat(new[] { currentPath });
            }
            return FragmentQuery.Create(attributes, domainWhereClause);
        }
 private static IEnumerable<MemberPath> GetConditionalScalarMembers(
     EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap)
 {
     return currentPath.GetMembers(edmType, true /* isScalar */, true /* isConditional */, null /* isPartOfKey */, domainMap);
 }
Beispiel #22
0
 // effects: Creates a boolean expression based on expr
 internal BoolExpression(DomainBoolExpr expr, MemberDomainMap memberDomainMap)
 {
     m_tree            = expr;
     m_memberDomainMap = memberDomainMap;
 }