/// <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. var index = new MemberProjectionIndex(); GatherPartialSignature(index, edmItemCollection, new MemberPath(extent), false); // need not only keys return index; }
// <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) { var memberType = member.EdmType; var 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 (var possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/)) { var possibleStructuralType = possibleType as StructuralType; Debug.Assert(possibleStructuralType != null, "Non-structural subtype?"); GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly); } }
internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { // The slot corresponding to from1, etc var numBoolSlots = requiredSlots.Length - projectedSlotMap.Count; var slotNum = projectedSlotMap.BoolIndexToSlot(m_index, numBoolSlots); requiredSlots[slotNum] = true; }
internal static void GetRequiredSlots( DomainBoolExpr expression, MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { var visitor = new RequiredSlotsVisitor(projectedSlotMap, requiredSlots); expression.Accept(visitor); }
// <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" var member = RestrictedMemberSlot.MemberPath; var slotNum = projectedSlotMap.IndexOf(member); requiredSlots[slotNum] = true; }
internal static void GetRequiredSlots( BoolExpr <DomainConstraint <BoolLiteral, Constant> > expression, MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { BoolExpression.RequiredSlotsVisitor requiredSlotsVisitor = new BoolExpression.RequiredSlotsVisitor(projectedSlotMap, requiredSlots); expression.Accept <BoolExpr <DomainConstraint <BoolLiteral, Constant> > >((Visitor <DomainConstraint <BoolLiteral, Constant>, BoolExpr <DomainConstraint <BoolLiteral, Constant> > >)requiredSlotsVisitor); }
// <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. var index = new MemberProjectionIndex(); GatherPartialSignature(index, edmItemCollection, new MemberPath(extent), false); // need not only keys return(index); }
internal static MemberProjectionIndex Create( EntitySetBase extent, EdmItemCollection edmItemCollection) { MemberProjectionIndex index = new MemberProjectionIndex(); MemberProjectionIndex.GatherPartialSignature(index, edmItemCollection, new MemberPath(extent), false); return(index); }
internal override void GetRequiredSlots( MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { int numBoolSlots = requiredSlots.Length - projectedSlotMap.Count; int slot = projectedSlotMap.BoolIndexToSlot(this.m_index, numBoolSlots); requiredSlots[slot] = true; }
internal override void GetRequiredSlots( MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { MemberPath memberPath = this.RestrictedMemberSlot.MemberPath; int index = projectedSlotMap.IndexOf(memberPath); requiredSlots[index] = true; }
// effects: Creates a view generator object that can be used to generate views // based on usedCells (projectedSlotMap are useful for deciphering the fields) internal BasicViewGenerator( MemberProjectionIndex projectedSlotMap, List<LeftCellWrapper> usedCells, FragmentQuery activeDomain, ViewgenContext context, MemberDomainMap domainMap, ErrorLog errorLog, ConfigViewGenerator config) { Debug.Assert(usedCells.Count > 0, "No used cells"); m_projectedSlotMap = projectedSlotMap; m_usedCells = usedCells; m_viewgenContext = context; m_activeDomain = activeDomain; m_errorLog = errorLog; m_config = config; m_domainMap = domainMap; }
internal MemberMaps( ViewTarget viewTarget, MemberProjectionIndex projectedSlotMap, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap) { m_projectedSlotMap = projectedSlotMap; m_queryDomainMap = queryDomainMap; m_updateDomainMap = updateDomainMap; Debug.Assert(m_queryDomainMap != null); Debug.Assert(m_updateDomainMap != null); Debug.Assert(m_projectedSlotMap != null); m_viewTarget = viewTarget; }
/// <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; }
private static void GatherPartialSignature( MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly) { EdmType edmType1 = member.EdmType; if (edmType1 is ComplexType && needKeysOnly) { return; } index.CreateIndex(member); foreach (EdmType edmType2 in MetadataHelper.GetTypeAndSubtypesOf(edmType1, (ItemCollection)edmItemCollection, false)) { StructuralType possibleType = edmType2 as StructuralType; MemberProjectionIndex.GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleType, needKeysOnly); } }
// 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); }
internal void CreateFieldAlignedCellQueries( CellQuery otherQuery, MemberProjectionIndex projectedSlotMap, out CellQuery newMainQuery, out CellQuery newOtherQuery) { int count = projectedSlotMap.Count; ProjectedSlot[] newSlots1 = new ProjectedSlot[count]; ProjectedSlot[] newSlots2 = new ProjectedSlot[count]; for (int index1 = 0; index1 < this.m_projectedSlots.Length; ++index1) { MemberProjectedSlot projectedSlot = this.m_projectedSlots[index1] as MemberProjectedSlot; int index2 = projectedSlotMap.IndexOf(projectedSlot.MemberPath); newSlots1[index2] = this.m_projectedSlots[index1]; newSlots2[index2] = otherQuery.m_projectedSlots[index1]; } newMainQuery = new CellQuery(this, newSlots1); newOtherQuery = new CellQuery(otherQuery, newSlots2); }
// <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)) { var 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"); var 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)); } } }
private static void GatherSignatureFromTypeStructuralMembers( MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, StructuralType possibleType, bool needKeysOnly) { foreach (EdmMember structuralMember in (IEnumerable)Helper.GetAllStructuralMembers((EdmType)possibleType)) { if (MetadataHelper.IsNonRefSimpleMember(structuralMember)) { if (!needKeysOnly || MetadataHelper.IsPartOfEntityTypeKey(structuralMember)) { MemberPath member1 = new MemberPath(member, structuralMember); index.CreateIndex(member1); } } else { MemberPath member1 = new MemberPath(member, structuralMember); MemberProjectionIndex.GatherPartialSignature(index, edmItemCollection, member1, needKeysOnly || Helper.IsAssociationEndMember(structuralMember)); } } }
internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { throw new NotImplementedException(); }
internal virtual void GetRequiredSlots( MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { BoolExpression.RequiredSlotsVisitor.GetRequiredSlots(this.m_tree, projectedSlotMap, requiredSlots); }
/// <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)) { var 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"); var 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) { var memberType = member.EdmType; var 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 (var possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/)) { var possibleStructuralType = possibleType as StructuralType; Debug.Assert(possibleStructuralType != null, "Non-structural subtype?"); GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly); } }
private RequiredSlotsVisitor(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) { m_projectedSlotMap = projectedSlotMap; m_requiredSlots = requiredSlots; }
// 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) { var outputCells = new List<Cell>(); // Determine the aligned field for each cell // The new cells have ProjectedSlotMap.Count number of fields foreach (var 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 var mainQuery = cell.GetLeftQuery(viewTarget); var 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); var 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; }
/// <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" var member = RestrictedMemberSlot.MemberPath; var slotNum = projectedSlotMap.IndexOf(member); requiredSlots[slotNum] = true; }
/// <summary> /// See <see cref="BoolExpression.GetRequiredSlots" />. /// </summary> internal abstract void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots);
// 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); }