/// <summary>
        /// Given the <paramref name="member"/> and one of its <paramref name="possibleType"/>s, determine the attributes that are relevant
        /// for this <paramref name="possibleType"/> and return a <see cref="MemberPath"/> signature corresponding to the <paramref name="possibleType"/> and the attributes.
        /// If <paramref name="needKeysOnly"/>=true, collect the key fields only.
        /// </summary>
        /// <param name="possibleType">the <paramref name="member"/>'s type or one of its subtypes</param>
        private static void GatherSignatureFromTypeStructuralMembers(MemberProjectionIndex index,
                                                                     EdmItemCollection edmItemCollection,
                                                                     MemberPath member,
                                                                     StructuralType possibleType,
                                                                     bool needKeysOnly)
        {
            // For each child member of this type, collect all the relevant scalar fields
            foreach (EdmMember structuralMember in Helper.GetAllStructuralMembers(possibleType))
            {
                if (MetadataHelper.IsNonRefSimpleMember(structuralMember))
                {
                    if (!needKeysOnly || MetadataHelper.IsPartOfEntityTypeKey(structuralMember))
                    {
                        MemberPath nonStructuredMember = new MemberPath(member, structuralMember);
                        // Note: scalarMember's parent has already been added to the projectedSlotMap
                        index.CreateIndex(nonStructuredMember);
                    }
                }
                else
                {
                    Debug.Assert(structuralMember.TypeUsage.EdmType is ComplexType ||
                                 structuralMember.TypeUsage.EdmType is RefType, // for association ends
                                 "Only non-scalars expected - complex types, association ends");



                    MemberPath structuredMember = new MemberPath(member, structuralMember);
                    GatherPartialSignature(index,
                                           edmItemCollection,
                                           structuredMember,
                                           // Only keys are required for entities referenced by association ends of an association.
                                           needKeysOnly || Helper.IsAssociationEndMember(structuralMember));
                }
            }
        }
Exemple #2
0
            internal static void GetRequiredSlots(DomainBoolExpr expression, MemberProjectionIndex projectedSlotMap,
                                                  bool[] requiredSlots)
            {
                RequiredSlotsVisitor visitor = new RequiredSlotsVisitor(projectedSlotMap, requiredSlots);

                expression.Accept <DomainBoolExpr>(visitor);
            }
        /// <summary>
        /// Starting at the <paramref name="member"/>, recursively generates <see cref="MemberPath"/>s for the fields embedded in it.
        /// </summary>
        /// <param name="member">corresponds to a value of an Entity or Complex or Association type</param>
        /// <param name="needKeysOnly">indicates whether we need to only collect members that are keys</param>
        private static void GatherPartialSignature(MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly)
        {
            EdmType     memberType        = member.EdmType;
            ComplexType complexTypemember = memberType as ComplexType;

            Debug.Assert(complexTypemember != null ||
                         memberType is EntityType ||      // for entity sets
                         memberType is AssociationType || // For association sets
                         memberType is RefType,           // for association ends
                         "GatherPartialSignature can be called only for complex types, entity sets, association ends");

            if (memberType is ComplexType && needKeysOnly)
            {
                // Check if the complex type needs to be traversed or not. If not, just return
                // from here. Else we need to continue to the code below. Right now, we do not
                // allow keys inside complex types
                return;
            }

            // Make sure that this member is in the slot map before any of its embedded objects.
            index.CreateIndex(member);

            // Consider each possible type value -- each type value conributes to a tuple in the result.
            // For that possible type, add all the type members into the signature.
            foreach (EdmType possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/))
            {
                StructuralType possibleStructuralType = possibleType as StructuralType;
                Debug.Assert(possibleStructuralType != null, "Non-structural subtype?");

                GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly);
            }
        }
 /// <summary>
 /// Recursively generates <see cref="MemberPath"/>s for the members of the types stored in the <paramref name="extent"/>.
 /// </summary>
 internal static MemberProjectionIndex Create(EntitySetBase extent, EdmItemCollection edmItemCollection)
 {
     // We generate the indices for the projected slots as we traverse the metadata.
     MemberProjectionIndex index = new MemberProjectionIndex();
     GatherPartialSignature(index, edmItemCollection, new MemberPath(extent), false); // need not only keys
     return index;
 }
Exemple #5
0
 internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
 {
     // The slot corresponding to from1, etc
     int numBoolSlots = requiredSlots.Length - projectedSlotMap.Count;
     int slotNum = projectedSlotMap.BoolIndexToSlot(m_index, numBoolSlots);
     requiredSlots[slotNum] = true;
 }
Exemple #6
0
        /// <summary>
        /// See <see cref="BoolLiteral.GetRequiredSlots"/>.
        /// </summary>
        internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
        {
            // Simply get the slot for the variable var in "var in values"
            MemberPath member  = RestrictedMemberSlot.MemberPath;
            int        slotNum = projectedSlotMap.IndexOf(member);

            requiredSlots[slotNum] = true;
        }
        internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
        {
            // The slot corresponding to from1, etc
            int numBoolSlots = requiredSlots.Length - projectedSlotMap.Count;
            int slotNum      = projectedSlotMap.BoolIndexToSlot(m_index, numBoolSlots);

            requiredSlots[slotNum] = true;
        }
        /// <summary>
        /// Recursively generates <see cref="MemberPath"/>s for the members of the types stored in the <paramref name="extent"/>.
        /// </summary>
        internal static MemberProjectionIndex Create(EntitySetBase extent, EdmItemCollection edmItemCollection)
        {
            // We generate the indices for the projected slots as we traverse the metadata.
            MemberProjectionIndex index = new MemberProjectionIndex();

            GatherPartialSignature(index, edmItemCollection, new MemberPath(extent), false); // need not only keys
            return(index);
        }
 // 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;
 }
Exemple #10
0
        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 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;
        }
Exemple #12
0
 /// <summary>
 /// Given the generated <paramref name="view"/>, the <paramref name="caseStatements"/> for the multiconstant fields,
 /// the <paramref name="projectedSlotMap"/> that maps different paths of the entityset (for which the view is being generated) to slot indexes in the view,
 /// creates an object that is capable of generating the Cql for <paramref name="view"/>.
 /// </summary>
 internal CqlGenerator(CellTreeNode view,
                       Dictionary<MemberPath,
                       CaseStatement> caseStatements,
                       CqlIdentifiers identifiers,
                       MemberProjectionIndex projectedSlotMap,
                       int numCellsInView,
                       BoolExpression topLevelWhereClause,
                       StorageMappingItemCollection mappingItemCollection)
 {
     m_view = view;
     m_caseStatements = caseStatements;
     m_projectedSlotMap = projectedSlotMap;
     m_numBools = numCellsInView; // We have that many booleans
     m_topLevelWhereClause = topLevelWhereClause;
     m_identifiers = identifiers;
     m_mappingItemCollection = mappingItemCollection;
 }
Exemple #13
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);
        }
 internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
 {
     throw new NotImplementedException();
 }
 internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Given the <paramref name="member"/> and one of its <paramref name="possibleType"/>s, determine the attributes that are relevant
        /// for this <paramref name="possibleType"/> and return a <see cref="MemberPath"/> signature corresponding to the <paramref name="possibleType"/> and the attributes.
        /// If <paramref name="needKeysOnly"/>=true, collect the key fields only.
        /// </summary>
        /// <param name="possibleType">the <paramref name="member"/>'s type or one of its subtypes</param>
        private static void GatherSignatureFromTypeStructuralMembers(MemberProjectionIndex index,
                                                                     EdmItemCollection edmItemCollection,
                                                                     MemberPath member, 
                                                                     StructuralType possibleType, 
                                                                     bool needKeysOnly)
        {
            // For each child member of this type, collect all the relevant scalar fields
            foreach (EdmMember structuralMember in Helper.GetAllStructuralMembers(possibleType))
            {
                if (MetadataHelper.IsNonRefSimpleMember(structuralMember))
                {
                    if (!needKeysOnly || MetadataHelper.IsPartOfEntityTypeKey(structuralMember))
                    {
                        MemberPath nonStructuredMember = new MemberPath(member, structuralMember);
                        // Note: scalarMember's parent has already been added to the projectedSlotMap
                        index.CreateIndex(nonStructuredMember);
                    }
                }
                else
                {
                    Debug.Assert(structuralMember.TypeUsage.EdmType is ComplexType ||
                                 structuralMember.TypeUsage.EdmType is RefType, // for association ends
                                 "Only non-scalars expected - complex types, association ends");

                    

                    MemberPath structuredMember = new MemberPath(member, structuralMember);
                    GatherPartialSignature(index, 
                                           edmItemCollection, 
                                           structuredMember,
                                           // Only keys are required for entities referenced by association ends of an association.
                                           needKeysOnly || Helper.IsAssociationEndMember(structuralMember));
                }
            }
        }
        /// <summary>
        /// Starting at the <paramref name="member"/>, recursively generates <see cref="MemberPath"/>s for the fields embedded in it.
        /// </summary>
        /// <param name="member">corresponds to a value of an Entity or Complex or Association type</param>
        /// <param name="needKeysOnly">indicates whether we need to only collect members that are keys</param>
        private static void GatherPartialSignature(MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly)
        {
            EdmType memberType = member.EdmType;
            ComplexType complexTypemember = memberType as ComplexType;
            Debug.Assert(complexTypemember != null ||
                         memberType is EntityType || // for entity sets
                         memberType is AssociationType || // For association sets
                         memberType is RefType, // for association ends
                         "GatherPartialSignature can be called only for complex types, entity sets, association ends");

            if (memberType is ComplexType && needKeysOnly)
            {
                // Check if the complex type needs to be traversed or not. If not, just return 
                // from here. Else we need to continue to the code below. Right now, we do not
                // allow keys inside complex types
                return;
            }

            // Make sure that this member is in the slot map before any of its embedded objects.
            index.CreateIndex(member);

            // Consider each possible type value -- each type value conributes to a tuple in the result.
            // For that possible type, add all the type members into the signature.
            foreach (EdmType possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/))
            {
                StructuralType possibleStructuralType = possibleType as StructuralType;
                Debug.Assert(possibleStructuralType != null, "Non-structural subtype?");

                GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly);
            }
        }
Exemple #18
0
 // effects: Given a boolean expression, modifies requiredSlots
 // to indicate which slots are required to generate the expression
 // projectedSlotMap indicates a mapping from member paths to slot
 // numbers (that need to be checked off in requiredSlots)
 internal virtual void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
 {
     RequiredSlotsVisitor.GetRequiredSlots(m_tree, projectedSlotMap, requiredSlots);
 }
 /// <summary>
 /// See <see cref="BoolLiteral.GetRequiredSlots"/>.
 /// </summary>
 internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
 {
     // Simply get the slot for the variable var in "var in values"
     MemberPath member = RestrictedMemberSlot.MemberPath;
     int slotNum = projectedSlotMap.IndexOf(member);
     requiredSlots[slotNum] = true;
 }
Exemple #20
0
 /// <summary>
 /// See <see cref="BoolExpression.GetRequiredSlots"/>.
 /// </summary>
 /// <param name="projectedSlotMap"></param>
 /// <param name="requiredSlots"></param>
 internal abstract void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots);
Exemple #21
0
 private RequiredSlotsVisitor(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots)
 {
     m_projectedSlotMap = projectedSlotMap;
     m_requiredSlots    = requiredSlots;
 }
        // 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
            var numAlignedSlots = projectedSlotMap.Count;
            var mainSlots = new ProjectedSlot[numAlignedSlots];
            var otherSlots = new ProjectedSlot[numAlignedSlots];

            // Go through the slots for this query and find the new slot for them
            for (var i = 0; i < m_projectedSlots.Length; i++)
            {
                var 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
                var 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);
        }
        // effects: Align the fields of each cell in mapping using projectedSlotMap that has a mapping 
        // for each member of this extent to the slot number of that member in the projected slots
        // example:
        //    input:  Proj[A,B,"5"] = Proj[F,"7",G]
        //            Proj[C,B]     = Proj[H,I]
        //   output:  m_projectedSlotMap: A -> 0, B -> 1, C -> 2
        //            Proj[A,B,null] = Proj[F,"7",null]
        //            Proj[null,B,C] = Proj[null,I,H]
        private static List<Cell> AlignFields(IEnumerable<Cell> cells, MemberProjectionIndex projectedSlotMap,
                                              ViewTarget viewTarget)
        {

            List<Cell> outputCells = new List<Cell>();

            // Determine the aligned field for each cell
            // The new cells have ProjectedSlotMap.Count number of fields
            foreach (Cell cell in cells)
            {

                // If isQueryView is true, we need to consider the C side of
                // the cells; otherwise, we look at the S side. Note that we
                // CANNOT use cell.LeftQuery since that is determined by
                // cell's isQueryView

                // The query for which we are constructing the extent
                CellQuery mainQuery = cell.GetLeftQuery(viewTarget);
                CellQuery otherQuery = cell.GetRightQuery(viewTarget);

                CellQuery newMainQuery;
                CellQuery newOtherQuery;
                // Create both queries where the projected slot map is used
                // to determine the order of the fields of the mainquery (of
                // course, the otherQuery's fields are aligned automatically)
                mainQuery.CreateFieldAlignedCellQueries(otherQuery, projectedSlotMap,
                                                        out newMainQuery, out newOtherQuery);

                Cell outputCell = viewTarget == ViewTarget.QueryView ?
                    Cell.CreateCS(newMainQuery, newOtherQuery, cell.CellLabel, cell.CellNumber) :
                    Cell.CreateCS(newOtherQuery, newMainQuery, cell.CellLabel, cell.CellNumber);
                outputCells.Add(outputCell);
            }
            return outputCells;
        }