Exemplo n.º 1
0
        private void GenerateCellRelations(int cellNumber)
        {
            // Generate the view cell relation
            List <ViewCellSlot> projectedSlots = new List <ViewCellSlot>();

            // construct a ViewCellSlot for each slot
            Debug.Assert(CQuery.NumProjectedSlots == SQuery.NumProjectedSlots,
                         "Cell queries in cell have a different number of slots");
            for (int i = 0; i < CQuery.NumProjectedSlots; i++)
            {
                ProjectedSlot cSlot = CQuery.ProjectedSlotAt(i);
                ProjectedSlot sSlot = SQuery.ProjectedSlotAt(i);
                Debug.Assert(cSlot != null, "Has cell query been normalized?");
                Debug.Assert(sSlot != null, "Has cell query been normalized?");

                // These slots better be MemberProjectedSlots. We do not have constants etc at this point.
                Debug.Assert(cSlot is MemberProjectedSlot, "cSlot is expected to be MemberProjectedSlot");
                Debug.Assert(sSlot is MemberProjectedSlot, "sSlot is expected to be MemberProjectedSlot");

                MemberProjectedSlot cJoinSlot = (MemberProjectedSlot)cSlot;
                MemberProjectedSlot sJoinSlot = (MemberProjectedSlot)sSlot;

                ViewCellSlot slot = new ViewCellSlot(i, cJoinSlot, sJoinSlot);
                projectedSlots.Add(slot);
            }
            m_viewCellRelation = new ViewCellRelation(this, projectedSlots, cellNumber);
        }
Exemplo n.º 2
0
        // effects: Given a cell, determines the paths to which the paths in
        // columns map to in the C-space and returns them. If some columns
        // are not projected in the cell, or if the corresponding properties
        // are not mapped into C-space, returns null
        internal Set <EdmProperty> GetCSlotsForTableColumns(IEnumerable <MemberPath> columns)
        {
            List <int> fieldNums = SQuery.GetProjectedPositions(columns);

            if (fieldNums == null)
            {
                return(null);
            }

            // The fields are mapped -- see if they are mapped on the
            // cSide and they correspond to the primary key of the
            // entity set

            Set <EdmProperty> cSideMembers = new Set <EdmProperty>();

            foreach (int fieldNum in fieldNums)
            {
                ProjectedSlot       projectedSlot = CQuery.ProjectedSlotAt(fieldNum);
                MemberProjectedSlot slot          = projectedSlot as MemberProjectedSlot;
                if (slot != null)
                {
                    // We can call LastMember since columns do not map to
                    // extents or memberEnds. Can cast to EdmProperty since it
                    // cannot be an association end
                    cSideMembers.Add((EdmProperty)slot.MemberPath.LeafEdmMember);
                }
                else
                {
                    return(null);
                }
            }
            return(cSideMembers);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        //True = domain is restricted, False = domain is not restricted (because there is no condition)
        private static bool GetRestrictedOrUnrestrictedDomain(MemberProjectedSlot slot, CellQuery cellQuery, EdmItemCollection edmItemCollection, out CellConstantSet domain)
        {
            CellConstantSet domainValues = DeriveDomainFromMemberPath(slot.MemberPath, edmItemCollection, true /* leaveDomainUnbounded */);

            //Note, out domain is set even in the case where method call returns false
            return(TryGetDomainRestrictedByWhereClause(domainValues, slot, cellQuery, out domain));
        }
Exemplo n.º 5
0
        // requires: children to be a list of nodes that are children of an
        // Inner Join node. slotNum does not correspond to the key slot
        // effects: Determines the child number from which the slot should be
        // picked up.
        private static int GetInnerJoinChildForSlot(List <CqlBlock> children, int slotNum)
        {
            // Picks the child with the non-constant slot first. If none, picks a non-null constant slot.
            // If not een that, picks any one
            int result = -1;

            for (int i = 0; i < children.Count; i++)
            {
                CqlBlock child = children[i];
                if (false == child.IsProjected(slotNum))
                {
                    continue;
                }
                ProjectedSlot         slot         = child.SlotValue(slotNum);
                ConstantProjectedSlot constantSlot = slot as ConstantProjectedSlot;
                MemberProjectedSlot   joinSlot     = slot as MemberProjectedSlot;
                if (joinSlot != null)
                { // Pick the non-constant slot
                    result = i;
                }
                else if (constantSlot != null && constantSlot.CellConstant.IsNull())
                {
                    if (result == -1)
                    { // In case, all are null
                        result = i;
                    }
                }
                else
                {
                    // Just pick anything
                    result = i;
                }
            }
            return(result);
        }
 /// <summary>
 /// Creates a complete member restriction with the meaning "<paramref name="slot"/> in <paramref name="domain"/>".
 /// </summary>
 protected MemberRestriction(MemberProjectedSlot slot, Domain domain)
 {
     m_restrictedMemberSlot = slot;
     m_domain = domain;
     m_isComplete = true;
     Debug.Assert(m_domain.Count != 0, "If you want a boolean that evaluates to false, " +
                  "use the ConstantBool abstraction");
 }
Exemplo n.º 7
0
 /// <summary>
 /// Creates a complete member restriction with the meaning "<paramref name="slot"/> in <paramref name="domain"/>".
 /// </summary>
 protected MemberRestriction(MemberProjectedSlot slot, Domain domain)
 {
     m_restrictedMemberSlot = slot;
     m_domain     = domain;
     m_isComplete = true;
     Debug.Assert(m_domain.Count != 0, "If you want a boolean that evaluates to false, " +
                  "use the ConstantBool abstraction");
 }
        private bool TryGetWithRelationship(StorageAssociationSetMapping colocatedAssociationSetMap,
                                            EntitySetBase thisExtent,
                                            MemberPath sRootNode,
                                            ref List <SlotInfo> foreignKeySlots,
                                            out WithRelationship withRelationship)
        {
            Debug.Assert(foreignKeySlots != null);
            withRelationship = null;

            //Get the map for foreign key end
            StorageEndPropertyMapping foreignKeyEndMap = GetForeignKeyEndMapFromAssocitionMap(colocatedAssociationSetMap, thisExtent);

            if (foreignKeyEndMap == null || foreignKeyEndMap.EndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
            {
                return(false);
            }

            AssociationEndMember toEnd             = (AssociationEndMember)foreignKeyEndMap.EndMember;
            AssociationEndMember fromEnd           = MetadataHelper.GetOtherAssociationEnd(toEnd);
            EntityType           toEndEntityType   = (EntityType)((RefType)(toEnd.TypeUsage.EdmType)).ElementType;
            EntityType           fromEndEntityType = (EntityType)(((RefType)fromEnd.TypeUsage.EdmType).ElementType);

            // Get the member path for AssociationSet
            AssociationSet associationSet = (AssociationSet)colocatedAssociationSetMap.Set;
            MemberPath     prefix         = new MemberPath(associationSet, toEnd);

            // Collect the member paths for edm scalar properties that belong to the target entity key.
            // These will be used as part of WITH RELATIONSHIP.
            // Get the key properties from edm type since the query parser depends on the order of key members
            IEnumerable <StorageScalarPropertyMapping> propertyMaps = foreignKeyEndMap.Properties.Cast <StorageScalarPropertyMapping>();
            List <MemberPath> toEndEntityKeyMemberPaths             = new List <MemberPath>();

            foreach (EdmProperty edmProperty in toEndEntityType.KeyMembers)
            {
                IEnumerable <StorageScalarPropertyMapping> scalarPropertyMaps = propertyMaps.Where(propMap => (propMap.EdmProperty.Equals(edmProperty)));
                Debug.Assert(scalarPropertyMaps.Count() == 1, "Can't Map the same column multiple times in the same end");
                StorageScalarPropertyMapping scalarPropertyMap = scalarPropertyMaps.First();

                // Create SlotInfo for Freign Key member that needs to be projected.
                MemberProjectedSlot sSlot            = new MemberProjectedSlot(new MemberPath(sRootNode, scalarPropertyMap.ColumnProperty));
                MemberPath          endMemberKeyPath = new MemberPath(prefix, edmProperty);
                toEndEntityKeyMemberPaths.Add(endMemberKeyPath);
                foreignKeySlots.Add(new SlotInfo(true, true, sSlot, endMemberKeyPath));
            }

            // Parent assignable from child: Ensures they are in the same hierarchy.
            if (thisExtent.ElementType.IsAssignableFrom(fromEndEntityType))
            {
                // Now create the WITH RELATIONSHIP with all the needed info.
                withRelationship = new WithRelationship(associationSet, fromEnd, fromEndEntityType, toEnd, toEndEntityType, toEndEntityKeyMemberPaths);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 9
0
        // requires: The Where clause satisfies the same requirements a GetConjunctsFromWhereClause
        // effects: For each slot that has a NotNull condition in the where
        // clause, checks if it is projected. If all such slots are
        // projected, returns null. Else returns an error record
        internal ErrorLog.Record CheckForProjectedNotNullSlots(Cell sourceCell, IEnumerable <Cell> associationSets)
        {
            StringBuilder builder    = new StringBuilder();
            bool          foundError = false;

            foreach (MemberRestriction restriction in Conditions)
            {
                if (restriction.Domain.ContainsNotNull())
                {
                    MemberProjectedSlot slot = MemberProjectedSlot.GetSlotForMember(m_projectedSlots, restriction.RestrictedMemberSlot.MemberPath);
                    if (slot == null) //member with not null condition is not mapped in this extent
                    {
                        bool missingMapping = true;
                        if (Extent is EntitySet)
                        {
                            bool       isCQuery       = sourceCell.CQuery == this;
                            ViewTarget target         = isCQuery ? ViewTarget.QueryView : ViewTarget.UpdateView;
                            CellQuery  rightCellQuery = isCQuery? sourceCell.SQuery : sourceCell.CQuery;

                            //Find out if there is an association mapping but only if the current Not Null condition is on an EntitySet
                            EntitySet rightExtent = rightCellQuery.Extent as EntitySet;
                            if (rightExtent != null)
                            {
                                List <AssociationSet> associations = MetadataHelper.GetAssociationsForEntitySet(rightCellQuery.Extent as EntitySet);
                                foreach (var association in associations.Where(association => association.AssociationSetEnds.Any(end => (end.CorrespondingAssociationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One &&
                                                                                                                                         (MetadataHelper.GetOppositeEnd(end).EntitySet.EdmEquals(rightExtent))))))
                                {
                                    foreach (var associationCell in associationSets.Where(c => c.GetRightQuery(target).Extent.EdmEquals(association)))
                                    {
                                        if (MemberProjectedSlot.GetSlotForMember(associationCell.GetLeftQuery(target).ProjectedSlots, restriction.RestrictedMemberSlot.MemberPath) != null)
                                        {
                                            missingMapping = false;
                                        }
                                    }
                                }
                            }
                        }

                        if (missingMapping)
                        {
                            // condition of NotNull and slot not being projected
                            builder.AppendLine(System.Data.Entity.Strings.ViewGen_NotNull_No_Projected_Slot(
                                                   restriction.RestrictedMemberSlot.MemberPath.PathToString(false)));
                            foundError = true;
                        }
                    }
                }
            }
            if (false == foundError)
            {
                return(null);
            }
            ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.NotNullNoProjectedSlot, builder.ToString(), sourceCell, String.Empty);
            return(record);
        }
Exemplo n.º 10
0
 // effects: Returns the fields in this, i.e., not constants or null slots
 private IEnumerable <MemberProjectedSlot> GetMemberProjectedSlots()
 {
     foreach (ProjectedSlot slot in m_projectedSlots)
     {
         MemberProjectedSlot memberSlot = slot as MemberProjectedSlot;
         if (memberSlot != null)
         {
             yield return(memberSlot);
         }
     }
 }
Exemplo n.º 11
0
        protected override bool IsEqualTo(ProjectedSlot right)
        {
            MemberProjectedSlot rightSlot = right as MemberProjectedSlot;

            if (rightSlot == null)
            {
                return(false);
            }
            // We want equality of the paths
            return(MemberPath.EqualityComparer.Equals(m_memberPath, rightSlot.m_memberPath));
        }
Exemplo n.º 12
0
 // effects: returns the index at which this slot appears in the projection
 // or -1 if it is not projected
 internal int GetProjectedPosition(MemberProjectedSlot slot)
 {
     for (int i = 0; i < m_projectedSlots.Length; i++)
     {
         if (MemberProjectedSlot.EqualityComparer.Equals(slot, m_projectedSlots[i]))
         {
             return(i);
         }
     }
     return(-1);
 }
Exemplo n.º 13
0
 // effects: Determines all the identifiers used in this and adds them to identifiers
 internal void GetIdentifiers(CqlIdentifiers identifiers)
 {
     foreach (ProjectedSlot projectedSlot in m_projectedSlots)
     {
         MemberProjectedSlot slot = projectedSlot as MemberProjectedSlot;
         if (slot != null)
         {
             slot.MemberPath.GetIdentifiers(identifiers);
         }
     }
     m_extentMemberPath.GetIdentifiers(identifiers);
 }
Exemplo n.º 14
0
 // requires: slot corresponds to a slot in the corresponding
 // BasicCellRelation
 // effects: Given a slot in the corresponding basicCellRelation,
 // looks up the slot in this viewcellrelation and returns it. Returns
 // null if it does not find the slot in the left or right side of the viewrelation
 internal ViewCellSlot LookupViewSlot(MemberProjectedSlot slot)
 {
     // CHANGE_Microsoft_IMPROVE: We could have a dictionary to speed this up
     foreach (ViewCellSlot viewSlot in m_slots)
     {
         // If the left or right slots are equal, return the viewSlot
         if (ProjectedSlot.EqualityComparer.Equals(slot, viewSlot.CSlot) ||
             ProjectedSlot.EqualityComparer.Equals(slot, viewSlot.SSlot))
         {
             return viewSlot;
         }
     }
     return null;
 }
Exemplo n.º 15
0
        // effects: returns the List of indexes at which this member appears in the projection
        // or empty list if it is not projected
        internal List <int> GetProjectedPositions(MemberPath member)
        {
            List <int> pathIndexes = new List <int>();

            for (int i = 0; i < m_projectedSlots.Length; i++)
            {
                MemberProjectedSlot slot = m_projectedSlots[i] as MemberProjectedSlot;
                if (slot != null && MemberPath.EqualityComparer.Equals(member, slot.MemberPath))
                {
                    pathIndexes.Add(i);
                }
            }
            return(pathIndexes);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Searches for members in <paramref name="slots"/> and returns the corresponding slots in the same order as present in
        /// <paramref name="members"/>. Returns null if even one member is not present in slots.
        /// </summary>
        internal static List <MemberProjectedSlot> GetSlots(IEnumerable <MemberProjectedSlot> slots, IEnumerable <MemberPath> members)
        {
            List <MemberProjectedSlot> result = new List <MemberProjectedSlot>();

            foreach (MemberPath member in members)
            {
                MemberProjectedSlot slot = GetSlotForMember(Helpers.AsSuperTypeList <MemberProjectedSlot, ProjectedSlot>(slots), member);
                if (slot == null)
                {
                    return(null);
                }
                result.Add(slot);
            }
            return(result);
        }
Exemplo n.º 17
0
        // effects : Return the slot numbers for members in Cell Query that
        //           represent the association end member passed in.
        internal List <int> GetAssociationEndSlots(AssociationEndMember endMember)
        {
            List <int> slotIndexes = new List <int>();

            Debug.Assert(this.Extent is AssociationSet);
            for (int i = 0; i < m_projectedSlots.Length; i++)
            {
                MemberProjectedSlot slot = m_projectedSlots[i] as MemberProjectedSlot;
                if (slot != null && slot.MemberPath.RootEdmMember.Equals(endMember))
                {
                    slotIndexes.Add(i);
                }
            }
            return(slotIndexes);
        }
Exemplo n.º 18
0
        // requires: All slots in this are null or non-constants
        // effects: Returns the non-null slots of this
        internal AttributeSet GetNonNullSlots()
        {
            AttributeSet attributes = new AttributeSet(MemberPath.EqualityComparer);

            foreach (ProjectedSlot projectedSlot in m_projectedSlots)
            {
                // null means 'unused' slot -- we ignore those
                if (projectedSlot != null)
                {
                    MemberProjectedSlot projectedVar = projectedSlot as MemberProjectedSlot;
                    Debug.Assert(projectedVar != null, "Projected slot must not be a constant");
                    attributes.Add(projectedVar.MemberPath);
                }
            }
            return(attributes);
        }
Exemplo n.º 19
0
        // requires: RightCellQuery.Extent corresponds to a relationship set
        // effects: Returns the ends to which the key of the corresponding
        // table (i.e., the left query) maps to in the relationship set. For
        // example, if RightCellQuery.Extent is OrderOrders and it maps to
        // <oid, otherOid> of table SOrders with key oid, this returns the
        // end to which oid is mapped. Similarly, if we have a link table
        // with the whole key mapped to two ends of the association set, it
        // returns both ends
        private Set <AssociationEndMember> GetEndsForTablePrimaryKey()
        {
            CellQuery rightQuery = RightCellQuery;
            Set <AssociationEndMember> result = new Set <AssociationEndMember>(EqualityComparer <AssociationEndMember> .Default);

            // Get the key slots for the table (they are in the slotMap) and
            // check for that slot on the C-side
            foreach (int keySlot in m_memberMaps.ProjectedSlotMap.KeySlots)
            {
                MemberProjectedSlot slot = (MemberProjectedSlot)rightQuery.ProjectedSlotAt(keySlot);
                MemberPath          path = slot.MemberPath;
                // See what end it maps to in the relationSet
                AssociationEndMember endMember = (AssociationEndMember)path.RootEdmMember;
                Debug.Assert(endMember != null, "Element in path before scalar path is not end property?");
                result.Add(endMember);
            }
            Debug.Assert(result != null, "No end found for keyslots of table?");
            return(result);
        }
Exemplo n.º 20
0
        // requires: projectedSlotMap which contains a mapping of the fields
        // for "this" to integers
        // effects: Align the fields of this cell query using the
        // projectedSlotMap and generates a new query into newMainQuery
        // Based on the re-aligned fields in this, re-aligns the
        // corresponding fields in otherQuery as well and modifies
        // newOtherQuery to contain it
        // Example:
        //    input:  Proj[A,B,"5"] = Proj[F,"7",G]
        //            Proj[C,B]     = Proj[H,I]
        //            projectedSlotMap: A -> 0, B -> 1, C -> 2
        //   output:  Proj[A,B,null] = Proj[F,"7",null]
        //            Proj[null,B,C] = Proj[null,I,H]
        internal void CreateFieldAlignedCellQueries(CellQuery otherQuery, MemberProjectionIndex projectedSlotMap,
                                                    out CellQuery newMainQuery, out CellQuery newOtherQuery)
        {
            // mainSlots and otherSlots hold the new slots for two queries
            int numAlignedSlots = projectedSlotMap.Count;

            ProjectedSlot[] mainSlots  = new ProjectedSlot[numAlignedSlots];
            ProjectedSlot[] otherSlots = new ProjectedSlot[numAlignedSlots];

            // Go through the slots for this query and find the new slot for them
            for (int i = 0; i < m_projectedSlots.Length; i++)
            {
                MemberProjectedSlot slot = m_projectedSlots[i] as MemberProjectedSlot;
                Debug.Assert(slot != null, "All slots during cell normalization must field slots");
                // Get the the ith slot's variable and then get the
                // new slot number from the field map
                int newSlotNum = projectedSlotMap.IndexOf(slot.MemberPath);
                Debug.Assert(newSlotNum >= 0, "Field projected but not in projectedSlotMap");
                mainSlots[newSlotNum]  = m_projectedSlots[i];
                otherSlots[newSlotNum] = otherQuery.m_projectedSlots[i];

                // We ignore constants -- note that this is not the
                // isHighpriority or discriminator case.  An example of this
                // is when (say) Address does not have zip but USAddress
                // does.  Then the constraint looks like Pi_NULL, A, B(E) =
                // Pi_x, y, z(S)

                // We don't care about this null in the view generation of
                // the left side. Note that this could happen in inheritance
                // or in cases when say the S side has 20 fields but the C
                // side has only 3 - the other 17 are null or default.

                // NOTE: We allow such constants only on the C side and not
                // ont the S side. Otherwise, we can have a situation Pi_A,
                // B, C(E) = Pi_5, y, z(S) Then someone can set A to 7 and we
                // will not roundtrip. We check for this in validation
            }

            // Make the new cell queries with the new slots
            newMainQuery  = new CellQuery(this, mainSlots);
            newOtherQuery = new CellQuery(otherQuery, otherSlots);
        }
Exemplo n.º 21
0
        internal string ToESqlString()
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("\n\tSELECT ");

            if (m_selectDistinct == SelectDistinct.Yes)
            {
                builder.Append("DISTINCT ");
            }

            foreach (ProjectedSlot ps in m_projectedSlots)
            {
                MemberProjectedSlot jtn = ps as MemberProjectedSlot;
                StructuralType      st  = jtn.MemberPath.LeafEdmMember.DeclaringType;
                StringBuilder       sb  = new StringBuilder();
                jtn.MemberPath.AsEsql(sb, "e");
                builder.AppendFormat("{0}, ", sb.ToString());
            }
            //remove the extra-comma after the last slot
            builder.Remove(builder.Length - 2, 2);

            builder.Append("\n\tFROM ");
            EntitySetBase extent = m_extentMemberPath.Extent;

            CqlWriter.AppendEscapedQualifiedName(builder, extent.EntityContainer.Name, extent.Name);
            builder.Append(" AS e");

            if (m_whereClause.IsTrue == false)
            {
                builder.Append("\n\tWHERE ");

                StringBuilder qbuilder = new StringBuilder();
                m_whereClause.AsEsql(qbuilder, "e");

                builder.Append(qbuilder.ToString());
            }
            builder.Append("\n    ");

            return(builder.ToString());
        }
Exemplo n.º 22
0
        /// <summary>
        /// Given two lists <paramref name="slots1"/> and <paramref name="slots2"/>, merge them and returnthe resulting slots,
        /// i.e., empty slots from one are overridden by the slots from the other.
        /// </summary>
        private static bool TryMergeSlots(ProjectedSlot[] slots1, ProjectedSlot[] slots2, out ProjectedSlot[] slots)
        {
            Debug.Assert(slots1.Length == slots2.Length, "Merged slots of two cells must be same size");
            slots = new ProjectedSlot[slots1.Length];

            for (int i = 0; i < slots.Length; i++)
            {
                ProjectedSlot slot1 = slots1[i];
                ProjectedSlot slot2 = slots2[i];
                if (slot1 == null)
                {
                    slots[i] = slot2;
                }
                else if (slot2 == null)
                {
                    slots[i] = slot1;
                }
                else
                {
                    // Both slots are non-null: Either both are the same
                    // members or one of them is a constant
                    // Note: if both are constants (even different constants)
                    // it does not matter which one we pick because the CASE statement will override it
                    MemberProjectedSlot memberSlot1 = slot1 as MemberProjectedSlot;
                    MemberProjectedSlot memberSlot2 = slot2 as MemberProjectedSlot;

                    if (memberSlot1 != null && memberSlot2 != null &&
                        false == EqualityComparer.Equals(memberSlot1, memberSlot2))
                    {
                        // Illegal combination of slots; non-constant fields disagree
                        return(false);
                    }

                    // If one of them is a field we have to get the field
                    ProjectedSlot pickedSlot = (memberSlot1 != null) ? slot1 : slot2;
                    slots[i] = pickedSlot;
                }
            }
            return(true);
        }
Exemplo n.º 23
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);
        }
Exemplo n.º 24
0
        // requires: "this" is a query on the C-side
        // and cSideSlotIndexes corresponds to the indexes
        // (into "this") that the slot is being mapped into
        // cSideSlotIndexes.Count > 1 - that is, a particular column in "this"'s corresponding S-Query
        // has been mapped to more than one property in "this"
        //
        // effects: Checks that the multiple mappings on the C-side are
        // backed by an appropriate Referential constraint
        // If a column is mapped to two properties <A, B> in a single cell:
        // (a) Must be an association
        // (b) The two properties must be on opposite ends of the association
        // (c) The association must have a RI constraint
        // (d) Ordinal[A] == Ordinal[B] in the RI constraint
        // (c) and (d) can be stated as - the slots are equivalent, i.e.,
        // kept equal via an RI constraint
        private bool AreSlotsEquivalentViaRefConstraints(ReadOnlyCollection <int> cSideSlotIndexes)
        {
            // Check (a): Must be an association
            AssociationSet assocSet = Extent as AssociationSet;

            if (assocSet == null)
            {
                return(false);
            }

            // Check (b): The two properties must be on opposite ends of the association
            // There better be exactly two properties!
            Debug.Assert(cSideSlotIndexes.Count > 1, "Method called when no duplicate mapping");
            if (cSideSlotIndexes.Count > 2)
            {
                return(false);
            }

            // They better be join tree slots (if they are mapped!) and map to opposite ends
            MemberProjectedSlot slot0 = (MemberProjectedSlot)m_projectedSlots[cSideSlotIndexes[0]];
            MemberProjectedSlot slot1 = (MemberProjectedSlot)m_projectedSlots[cSideSlotIndexes[1]];

            return(slot0.MemberPath.IsEquivalentViaRefConstraint(slot1.MemberPath));
        }
Exemplo n.º 25
0
        internal override BoolLiteral RemapBool(Dictionary <MemberPath, MemberPath> remap)
        {
            MemberProjectedSlot newVar = (MemberProjectedSlot)this.RestrictedMemberSlot.RemapSlot(remap);

            return(new TypeRestriction(newVar, this.Domain));
        }
Exemplo n.º 26
0
 /// <summary>
 /// Creates a complete type restriction of the form "<paramref name="slot"/> in <paramref name="domain"/>".
 /// </summary>
 internal TypeRestriction(MemberProjectedSlot slot, Domain domain)
     : base(slot, domain)
 {
 }
 /// <summary>
 /// Creates a scalar member restriction with the meaning "<paramref name="slot"/> in <paramref name="domain"/>".
 /// </summary>
 internal ScalarRestriction(MemberProjectedSlot slot, Domain domain)
     : base(slot, domain)
 { }
Exemplo n.º 28
0
        // returns true when the case statement is completed
        private bool AddRewritingToCaseStatement(
            Tile<FragmentQuery> rewriting, CaseStatement caseStatement, MemberPath currentPath, Constant domainValue)
        {
            var whenCondition = BoolExpression.True;
            // check whether the rewriting is always true or always false
            // if it's always true, we don't need any other WHEN clauses in the case statement
            // if it's always false, we don't need to add this WHEN clause to the case statement
            // given: domainQuery is satisfied. Check (domainQuery -> rewriting)
            var isAlwaysTrue = _qp.IsContainedIn(CreateTile(_domainQuery), rewriting);
            var isAlwaysFalse = _qp.IsDisjointFrom(CreateTile(_domainQuery), rewriting);
            Debug.Assert(!(isAlwaysTrue && isAlwaysFalse));
            if (isAlwaysFalse)
            {
                return false; // don't need an unsatisfiable WHEN clause
            }
            if (isAlwaysTrue)
            {
                Debug.Assert(caseStatement.Clauses.Count == 0);
            }

            ProjectedSlot projectedSlot;
            if (domainValue.HasNotNull())
            {
                projectedSlot = new MemberProjectedSlot(currentPath);
            }
            else
            {
                projectedSlot = new ConstantProjectedSlot(domainValue);
            }

            if (!isAlwaysTrue)
            {
                whenCondition = TileToBoolExpr(rewriting);
            }
            else
            {
                whenCondition = BoolExpression.True;
            }
            caseStatement.AddWhenThen(whenCondition, projectedSlot);

            return isAlwaysTrue;
        }
Exemplo n.º 29
0
        // effects: Returns an error record if the keys of the extent/associationSet being mapped  are
        // present in the projected slots of this query. Returns null
        // otherwise. ownerCell indicates the cell that owns this and
        // resourceString is a resource used for error messages
        internal ErrorLog.Record VerifyKeysPresent(Cell ownerCell, Func <object, object, string> formatEntitySetMessage,
                                                   Func <object, object, object, string> formatAssociationSetMessage, ViewGenErrorCode errorCode)
        {
            List <MemberPath> prefixes = new List <MemberPath>(1);
            // Keep track of the key corresponding to each prefix
            List <ExtentKey> keys = new List <ExtentKey>(1);

            if (Extent is EntitySet)
            {
                // For entity set just get the full path of the key properties
                MemberPath prefix = new MemberPath(Extent);
                prefixes.Add(prefix);
                EntityType       entityType    = (EntityType)Extent.ElementType;
                List <ExtentKey> entitySetKeys = ExtentKey.GetKeysForEntityType(prefix, entityType);
                Debug.Assert(entitySetKeys.Count == 1, "Currently, we only support primary keys");
                keys.Add(entitySetKeys[0]);
            }
            else
            {
                AssociationSet relationshipSet = (AssociationSet)Extent;
                // For association set, get the full path of the key
                // properties of each end

                foreach (AssociationSetEnd relationEnd in relationshipSet.AssociationSetEnds)
                {
                    AssociationEndMember assocEndMember = relationEnd.CorrespondingAssociationEndMember;
                    MemberPath           prefix         = new MemberPath(relationshipSet, assocEndMember);
                    prefixes.Add(prefix);
                    List <ExtentKey> endKeys = ExtentKey.GetKeysForEntityType(prefix,
                                                                              MetadataHelper.GetEntityTypeForEnd(assocEndMember));
                    Debug.Assert(endKeys.Count == 1, "Currently, we only support primary keys");
                    keys.Add(endKeys[0]);
                }
            }

            for (int i = 0; i < prefixes.Count; i++)
            {
                MemberPath prefix = prefixes[i];
                // Get all or none key slots that are being projected in this cell query
                List <MemberProjectedSlot> keySlots = MemberProjectedSlot.GetKeySlots(GetMemberProjectedSlots(), prefix);
                if (keySlots == null)
                {
                    ExtentKey key = keys[i];
                    string    message;
                    if (Extent is EntitySet)
                    {
                        string keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, true);
                        message = formatEntitySetMessage(keyPropertiesString, Extent.Name);
                    }
                    else
                    {
                        string endName             = prefix.RootEdmMember.Name;
                        string keyPropertiesString = MemberPath.PropertiesToUserString(key.KeyFields, false);
                        message = formatAssociationSetMessage(keyPropertiesString, endName, Extent.Name);
                    }
                    ErrorLog.Record error = new ErrorLog.Record(true, errorCode, message, ownerCell, String.Empty);
                    return(error);
                }
            }
            return(null);
        }
 /// <summary>
 /// Creates an incomplete member restriction with the meaning "<paramref name="slot"/> in <paramref name="values"/>".
 /// </summary>
 protected MemberRestriction(MemberProjectedSlot slot, IEnumerable<Constant> values)
 {
     m_restrictedMemberSlot = slot;
     m_domain = new Domain(values, values);
 }
Exemplo n.º 31
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);
        }
Exemplo n.º 32
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);
        }
 /// <summary>
 /// Creates an incomplete member restriction with the meaning "<paramref name="slot"/> = <paramref name="value"/>".
 /// "Partial" means that the <see cref="Domain"/> in this restriction is partial - hence the operations on the restriction are limited.
 /// </summary>
 protected MemberRestriction(MemberProjectedSlot slot, Constant value)
     : this(slot, new Constant[] { value })
 { }
Exemplo n.º 34
0
        //True = domain is restricted, False = domain is not restricted (because there is no condition)
        private static bool GetRestrictedOrUnrestrictedDomain(MemberProjectedSlot slot, CellQuery cellQuery, EdmItemCollection edmItemCollection, out CellConstantSet domain)
        {
            CellConstantSet domainValues = DeriveDomainFromMemberPath(slot.MemberPath, edmItemCollection, true /* leaveDomainUnbounded */);

            //Note, out domain is set even in the case where method call returns false
            return TryGetDomainRestrictedByWhereClause(domainValues, slot, cellQuery, out domain);
        }
Exemplo n.º 35
0
 internal CellConstantSetInfo(Set<Constant> iconstants, MemberProjectedSlot islot)
     : base(iconstants)
 {
     slot = islot;
 }
Exemplo n.º 36
0
 // effects: 
 /// <summary>
 /// Creates a view cell slot that corresponds to <paramref name="slotNum"/> in some cell. The <paramref name="cSlot"/> and <paramref name="sSlot"/> represent the
 /// slots in the left and right queries of the view cell.
 /// </summary>
 internal ViewCellSlot(int slotNum, MemberProjectedSlot cSlot, MemberProjectedSlot sSlot)
 {
     m_slotNum = slotNum;
     m_cSlot = cSlot;
     m_sSlot = sSlot;
 }
Exemplo n.º 37
0
        // requires: All slots in this are join tree slots
        // This method is called for an S-side query
        // cQuery is the corresponding C-side query in the cell
        // sourceCell is the original cell for "this" and cQuery
        // effects: Checks if any of the columns in "this" are mapped to multiple properties in cQuery. If so,
        // returns an error record about the duplicated slots
        internal ErrorLog.Record CheckForDuplicateFields(CellQuery cQuery, Cell sourceCell)
        {
            // slotMap stores the slots on the S-side and the
            // C-side properties that it maps to
            KeyToListMap <MemberProjectedSlot, int> slotMap = new KeyToListMap <MemberProjectedSlot, int>(ProjectedSlot.EqualityComparer);

            // Note that this does work for self-association. In the manager
            // employee example, ManagerId and EmployeeId from the SEmployee
            // table map to the two ends -- Manager.ManagerId and
            // Employee.EmployeeId in the C Space

            for (int i = 0; i < m_projectedSlots.Length; i++)
            {
                ProjectedSlot       projectedSlot = m_projectedSlots[i];
                MemberProjectedSlot slot          = projectedSlot as MemberProjectedSlot;
                Debug.Assert(slot != null, "All slots for this method must be JoinTreeSlots");
                slotMap.Add(slot, i);
            }

            StringBuilder builder = null;

            // Now determine the entries that have more than one integer per slot
            bool isErrorSituation = false;

            foreach (MemberProjectedSlot slot in slotMap.Keys)
            {
                ReadOnlyCollection <int> indexes = slotMap.ListForKey(slot);
                Debug.Assert(indexes.Count >= 1, "Each slot must have one index at least");

                if (indexes.Count > 1 &&
                    cQuery.AreSlotsEquivalentViaRefConstraints(indexes) == false)
                {
                    // The column is mapped to more than one property and it
                    // failed the "association corresponds to referential
                    // constraints" check

                    isErrorSituation = true;
                    if (builder == null)
                    {
                        builder = new StringBuilder(System.Data.Entity.Strings.ViewGen_Duplicate_CProperties(Extent.Name));
                        builder.AppendLine();
                    }
                    StringBuilder tmpBuilder = new StringBuilder();
                    for (int i = 0; i < indexes.Count; i++)
                    {
                        int index = indexes[i];
                        if (i != 0)
                        {
                            tmpBuilder.Append(", ");
                        }
                        // The slot must be a JoinTreeSlot. If it isn't it is an internal error
                        MemberProjectedSlot cSlot = (MemberProjectedSlot)cQuery.m_projectedSlots[index];
                        tmpBuilder.Append(cSlot.ToUserString());
                    }
                    builder.AppendLine(Strings.ViewGen_Duplicate_CProperties_IsMapped(slot.ToUserString(), tmpBuilder.ToString()));
                }
            }

            if (false == isErrorSituation)
            {
                return(null);
            }

            ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.DuplicateCPropertiesMapped, builder.ToString(), sourceCell, String.Empty);
            return(record);
        }
Exemplo n.º 38
0
 // effects: returns the index at which this slot appears in the projection
 // or -1 if it is not projected
 internal int GetProjectedPosition(MemberProjectedSlot slot)
 {
     for (var i = 0; i < m_projectedSlots.Length; i++)
     {
         if (ProjectedSlot.EqualityComparer.Equals(slot, m_projectedSlots[i]))
         {
             return i;
         }
     }
     return -1;
 }
Exemplo n.º 39
0
 /// <summary>
 /// Creates a complete member restriction with the meaning "<paramref name="slot"/> in <paramref name="values"/>".
 /// </summary>
 /// <param name="possibleValues">all the values that the <paramref name="slot"/> can take</param>
 protected MemberRestriction(MemberProjectedSlot slot, IEnumerable <Constant> values, IEnumerable <Constant> possibleValues)
     : this(slot, new Domain(values, possibleValues))
 {
     Debug.Assert(possibleValues != null);
 }
 /// <summary>
 /// Creates a complete member restriction with the meaning "<paramref name="slot"/> in <paramref name="values"/>".
 /// </summary>
 /// <param name="possibleValues">all the values that the <paramref name="slot"/> can take</param>
 protected MemberRestriction(MemberProjectedSlot slot, IEnumerable<Constant> values, IEnumerable<Constant> possibleValues)
     : this(slot, new Domain(values, possibleValues))
 {
     Debug.Assert(possibleValues != null);
 }
Exemplo n.º 41
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));
        }
Exemplo n.º 42
0
 /// <summary>
 /// Creates an incomplete member restriction with the meaning "<paramref name="slot"/> in <paramref name="values"/>".
 /// </summary>
 protected MemberRestriction(MemberProjectedSlot slot, IEnumerable <Constant> values)
 {
     m_restrictedMemberSlot = slot;
     m_domain = new Domain(values, values);
 }