示例#1
0
        // requires: domain not have any Negated constants other than NotNull
        // Also, cellQuery contains all final oneOfConsts or all partial oneOfConsts
        // cellquery must contain a whereclause of the form "True", "OneOfConst" or "
        // "OneOfConst AND ... AND OneOfConst"
        // slot must present in cellQuery and incomingDomain is the domain for it
        // effects: Returns the set of values that slot can take as restricted by cellQuery's whereClause
        private static bool TryGetDomainRestrictedByWhereClause(IEnumerable <Constant> domain, MemberProjectedSlot slot, CellQuery cellQuery, out CellConstantSet result)
        {
            var conditionsForSlot = cellQuery.GetConjunctsFromWhereClause()
                                    .Where(restriction => MemberPath.EqualityComparer.Equals(restriction.RestrictedMemberSlot.MemberPath, slot.MemberPath))
                                    .Select(restriction => new CellConstantSet(restriction.Domain.Values, Constant.EqualityComparer));

            //Debug.Assert(!conditionsForSlot.Skip(1).Any(), "More than one Clause with the same path");

            if (!conditionsForSlot.Any())
            {
                // If the slot was not mentioned in the query return the domain without restricting it
                result = new CellConstantSet(domain);
                return(false);
            }



            // Now get all the possible values from domain and conditionValues
            CellConstantSet possibleValues = DeterminePossibleValues(conditionsForSlot.SelectMany(m => m.Select(c => c)), domain);

            Domain restrictedDomain = new Domain(domain, possibleValues);

            foreach (var conditionValues in conditionsForSlot)
            {
                // Domain derived from Edm-Type INTERSECTED with Conditions
                restrictedDomain = restrictedDomain.Intersect(new Domain(conditionValues, possibleValues));
            }

            result = new CellConstantSet(restrictedDomain.Values, Constant.EqualityComparer);
            return(!domain.SequenceEqual(result));
        }
示例#2
0
        ComputeConstantDomainSetsForSlotsInQueryViews(IEnumerable <Cell> cells, EdmItemCollection edmItemCollection, bool isValidationEnabled)
        {
            Dictionary <MemberPath, CellConstantSet> cDomainMap =
                new Dictionary <MemberPath, CellConstantSet>(MemberPath.EqualityComparer);

            foreach (Cell cell in cells)
            {
                CellQuery cQuery = cell.CQuery;
                // Go through the conjuncts to get the constants (e.g., we
                // just don't want to NULL, NOT(NULL). We want to say that
                // the possible values are NULL, 4, NOT(NULL, 4)
                foreach (MemberRestriction restriction in cQuery.GetConjunctsFromWhereClause())
                {
                    MemberProjectedSlot slot    = restriction.RestrictedMemberSlot;
                    CellConstantSet     cDomain = DeriveDomainFromMemberPath(slot.MemberPath, edmItemCollection, isValidationEnabled);
                    // Now we add the domain of oneConst into this
                    //Isnull=true and Isnull=false conditions should not contribute to a member's domain
                    cDomain.AddRange(restriction.Domain.Values.Where(c => !(c.Equals(Constant.Null) || c.Equals(Constant.NotNull))));
                    CellConstantSet values;
                    bool            found = cDomainMap.TryGetValue(slot.MemberPath, out values);
                    if (!found)
                    {
                        cDomainMap[slot.MemberPath] = cDomain;
                    }
                    else
                    {
                        values.AddRange(cDomain);
                    }
                }
            }
            return(cDomainMap);
        }
示例#3
0
        ComputeConstantDomainSetsForSlotsInUpdateViews(IEnumerable <Cell> cells, EdmItemCollection edmItemCollection)
        {
            Dictionary <MemberPath, CellConstantSet> updateDomainMap = new Dictionary <MemberPath, CellConstantSet>(MemberPath.EqualityComparer);

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

                foreach (MemberProjectedSlot sSlot in sQuery.GetConjunctsFromWhereClause().Select(oneOfConst => oneOfConst.RestrictedMemberSlot))
                {
                    // obtain initial slot domain and restrict it if the slot has conditions


                    CellConstantSet restrictedDomain;
                    bool            wasDomainRestricted = GetRestrictedOrUnrestrictedDomain(sSlot, sQuery, edmItemCollection, out restrictedDomain);

                    // Suppose that we have a cell:
                    //      Proj(ID, A) WHERE(A=5) FROM E   =   Proj(ID, B) FROM T

                    // In the above cell, B on the S-side is 5 and we add that to its range. But if B had a restriction,
                    // we do not add 5. Note that do we not have a problem w.r.t. possibleValues since if A=5 and B=1, we have an
                    // empty cell -- we should catch that as an error. If A = 5 and B = 5 is present then restrictedDomain
                    // and domainValues are the same

                    // if no restriction on the S-side and the slot is projected then take the domain from the C-side
                    if (!wasDomainRestricted)
                    {
                        int projectedPosition = sQuery.GetProjectedPosition(sSlot);
                        if (projectedPosition >= 0)
                        {
                            // get the domain of the respective C-side slot
                            MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(projectedPosition) as MemberProjectedSlot;
                            Debug.Assert(cSlot != null, "Assuming constants are not projected");

                            wasDomainRestricted = GetRestrictedOrUnrestrictedDomain(cSlot, cQuery, edmItemCollection, out restrictedDomain);

                            if (!wasDomainRestricted)
                            {
                                continue;
                            }
                        }
                    }

                    // Add the default value to the domain
                    MemberPath sSlotMemberPath = sSlot.MemberPath;
                    Constant   defaultValue;
                    if (TryGetDefaultValueForMemberPath(sSlotMemberPath, out defaultValue))
                    {
                        restrictedDomain.Add(defaultValue);
                    }

                    // add all constants appearing in the domain to sDomainMap
                    CellConstantSet sSlotDomain;
                    if (!updateDomainMap.TryGetValue(sSlotMemberPath, out sSlotDomain))
                    {
                        updateDomainMap[sSlotMemberPath] = restrictedDomain;
                    }
                    else
                    {
                        sSlotDomain.AddRange(restrictedDomain);
                    }
                }
            }
            return(updateDomainMap);
        }
示例#4
0
        // requires: domain not have any Negated constants other than NotNull
        // Also, cellQuery contains all final oneOfConsts or all partial oneOfConsts
        // cellquery must contain a whereclause of the form "True", "OneOfConst" or "
        // "OneOfConst AND ... AND OneOfConst"
        // slot must present in cellQuery and incomingDomain is the domain for it
        // effects: Returns the set of values that slot can take as restricted by cellQuery's whereClause
        private static bool TryGetDomainRestrictedByWhereClause(IEnumerable<Constant> domain, MemberProjectedSlot slot, CellQuery cellQuery, out CellConstantSet result)
        {

            var conditionsForSlot = cellQuery.GetConjunctsFromWhereClause()
                                  .Where(restriction => MemberPath.EqualityComparer.Equals(restriction.RestrictedMemberSlot.MemberPath, slot.MemberPath))
                                  .Select(restriction => new CellConstantSet(restriction.Domain.Values, Constant.EqualityComparer));

            //Debug.Assert(!conditionsForSlot.Skip(1).Any(), "More than one Clause with the same path");

            if (!conditionsForSlot.Any())
            {
                // If the slot was not mentioned in the query return the domain without restricting it 
                result = new CellConstantSet(domain);
                return false;
            }



            // Now get all the possible values from domain and conditionValues
            CellConstantSet possibleValues = DeterminePossibleValues(conditionsForSlot.SelectMany(m => m.Select(c => c)), domain);

            Domain restrictedDomain = new Domain(domain, possibleValues);
            foreach (var conditionValues in conditionsForSlot)
            {
                // Domain derived from Edm-Type INTERSECTED with Conditions
                restrictedDomain = restrictedDomain.Intersect(new Domain(conditionValues, possibleValues));
            }

            result = new CellConstantSet(restrictedDomain.Values, Constant.EqualityComparer);
            return !domain.SequenceEqual(result);
        }
示例#5
0
        // effects: Creates a map with all the condition member constants
        // from extentCells. viewtarget determines whether the view is an
        // update or query view
        internal MemberDomainMap(ViewTarget viewTarget, bool isValidationEnabled, IEnumerable <Cell> extentCells, EdmItemCollection edmItemCollection, ConfigViewGenerator config, Dictionary <EntityType, Set <EntityType> > inheritanceGraph)
        {
            m_conditionDomainMap = new Dictionary <MemberPath, CellConstantSet>(MemberPath.EqualityComparer);
            m_edmItemCollection  = edmItemCollection;

            Dictionary <MemberPath, CellConstantSet> domainMap = null;

            if (viewTarget == ViewTarget.UpdateView)
            {
                domainMap = Domain.ComputeConstantDomainSetsForSlotsInUpdateViews(extentCells, m_edmItemCollection);
            }
            else
            {
                domainMap = Domain.ComputeConstantDomainSetsForSlotsInQueryViews(extentCells, m_edmItemCollection, isValidationEnabled);
            }

            foreach (Cell cell in extentCells)
            {
                CellQuery cellQuery = cell.GetLeftQuery(viewTarget);
                // Get the atoms from cellQuery and only keep the ones that
                // are condition members
                foreach (MemberRestriction condition in cellQuery.GetConjunctsFromWhereClause())
                {
                    // Note: TypeConditions are created using OneOfTypeConst and
                    // scalars are created using OneOfScalarConst
                    MemberPath memberPath = condition.RestrictedMemberSlot.MemberPath;

                    Debug.Assert(condition is ScalarRestriction || condition is TypeRestriction,
                                 "Unexpected restriction");

                    // Take the narrowed domain from domainMap, if any
                    CellConstantSet domainValues;
                    if (!domainMap.TryGetValue(memberPath, out domainValues))
                    {
                        domainValues = Domain.DeriveDomainFromMemberPath(memberPath, edmItemCollection, isValidationEnabled);
                    }

                    //Don't count conditions that are satisfied through IsNull=false
                    if (!domainValues.Contains(Constant.Null))
                    {
                        //multiple values of condition represent disjunction in conditions (not currently supported)
                        // if there is any condition constant that is NotNull
                        if (condition.Domain.Values.All(conditionConstant => (conditionConstant.Equals(Constant.NotNull))))
                        {
                            continue;
                        }
                        //else there is atleast one condition value that is allowed, continue view generation
                    }

                    //------------------------------------------
                    //|  Nullable  |   IsNull  |   Test case   |
                    //|     T      |     T     |       T       |
                    //|     T      |     F     |       T       |
                    //|     F      |     T     |       F       |
                    //|     F      |     F     |       T       |
                    //------------------------------------------
                    //IsNull condition on a member that is non nullable is an invalid condition
                    if (domainValues.Count <= 0 || (!domainValues.Contains(Constant.Null) && condition.Domain.Values.Contains(Constant.Null)))
                    {
                        string          message = System.Data.Entity.Strings.ViewGen_InvalidCondition(memberPath.PathToString(false));
                        ErrorLog.Record record  = new ErrorLog.Record(true, ViewGenErrorCode.InvalidCondition, message, cell, String.Empty);
                        ExceptionHelpers.ThrowMappingException(record, config);
                    }
                    if (memberPath.IsAlwaysDefined(inheritanceGraph) == false)
                    {
                        domainValues.Add(Constant.Undefined);
                    }

                    AddToDomainMap(memberPath, domainValues);
                }
            }

            // Fill up the domains for the remaining slots as well
            m_nonConditionDomainMap = new Dictionary <MemberPath, CellConstantSet>(MemberPath.EqualityComparer);
            foreach (Cell cell in extentCells)
            {
                CellQuery cellQuery = cell.GetLeftQuery(viewTarget);
                // Get the atoms from cellQuery and only keep the ones that
                // are condition members
                foreach (MemberProjectedSlot slot in cellQuery.GetAllQuerySlots())
                {
                    MemberPath member = slot.MemberPath;
                    if (m_conditionDomainMap.ContainsKey(member) == false && m_nonConditionDomainMap.ContainsKey(member) == false)
                    {
                        CellConstantSet memberSet = Domain.DeriveDomainFromMemberPath(member, m_edmItemCollection, true /* Regardless of validation, leave the domain unbounded because this is not a condition member */);
                        if (member.IsAlwaysDefined(inheritanceGraph) == false)
                        { // nonConditionMember may belong to subclass
                            memberSet.Add(Constant.Undefined);
                        }
                        memberSet = Domain.ExpandNegationsInDomain(memberSet, memberSet);
                        m_nonConditionDomainMap.Add(member, new CellConstantSetInfo(memberSet, slot));
                    }
                }
            }
        }