private TypeUsage GetNewType(TypeUsage type) { if (TypeUtils.IsStructuredType(type)) { return(this.GetTypeInfo(type).FlattenedTypeUsage); } TypeUsage elementType; if (TypeHelpers.TryGetCollectionElementType(type, out elementType)) { TypeUsage newType = this.GetNewType(elementType); if (newType.EdmEquals((MetadataItem)elementType)) { return(type); } return(TypeHelpers.CreateCollectionTypeUsage(newType)); } if (TypeUtils.IsEnumerationType(type)) { return(TypeHelpers.CreateEnumUnderlyingTypeUsage(type)); } if (TypeSemantics.IsStrongSpatialType(type)) { return(TypeHelpers.CreateSpatialUnionTypeUsage(type)); } return(type); }
// <summary> // SetOp handling // UnionAllOp handling // IntersectOp handling // ExceptOp handling // Visitor for a SetOp. Pushes desired properties to the corresponding // Vars of the input // </summary> // <param name="op"> the setop </param> protected override void VisitSetOp(SetOp op, Node n) { foreach (var varMap in op.VarMap) { foreach (var kv in varMap) { if (TypeUtils.IsStructuredType(kv.Key.Type)) { // Get the set of expected properties for the unionVar, and // push it down to the inputvars // For Intersect and ExceptOps, we need all properties // from the input // We call GetPropertyRefList() always to initialize // the map, even though we may not use it // var myProps = GetPropertyRefList(kv.Key); if (op.OpType == OpType.Intersect || op.OpType == OpType.Except) { myProps = PropertyRefList.All; // We "want" all properties even on the output of the setop AddPropertyRefs(kv.Key, myProps); } else { myProps = myProps.Clone(); } AddPropertyRefs(kv.Value, myProps); } } } VisitChildren(n); }
public override void Visit(ComparisonOp op, Node n) { // Check to see if the children are structured types. Furthermore, // if the children are of entity types, then all we really need are // the key properties (and the entityset property) // For record and ref types, simply keep going var childOpType = (n.Child0.Op as ScalarOp).Type; if (!TypeUtils.IsStructuredType(childOpType)) { VisitChildren(n); } else if (md.TypeSemantics.IsRowType(childOpType) || md.TypeSemantics.IsReferenceType(childOpType)) { VisitDefault(n); } else { PlanCompiler.Assert(md.TypeSemantics.IsEntityType(childOpType), "unexpected childOpType?"); var desiredProperties = GetIdentityProperties(TypeHelpers.GetEdmType <md.EntityType>(childOpType)); // Now push these set of properties to each child foreach (var chi in n.Children) { AddPropertyRefs(chi, desiredProperties); } // Visit the children VisitChildren(n); } }
// <summary> // Get the "new" type corresponding to the input type. For structured types, // we return the flattened record type. // For collections of structured type, we return a new collection type of the corresponding flattened // type. // For enum types we return the underlying type of the enum type. // For strong spatial types we return the union type that includes the strong spatial type. // For everything else, we return the input type // </summary> // <param name="type"> the original type </param> // <returns> the new type (if any) </returns> private md.TypeUsage GetNewType(md.TypeUsage type) { if (TypeUtils.IsStructuredType(type)) { var typeInfo = GetTypeInfo(type); return(typeInfo.FlattenedTypeUsage); } md.TypeUsage elementType; if (TypeHelpers.TryGetCollectionElementType(type, out elementType)) { var newElementType = GetNewType(elementType); if (newElementType.EdmEquals(elementType)) { return(type); } else { return(TypeHelpers.CreateCollectionTypeUsage(newElementType)); } } if (TypeUtils.IsEnumerationType(type)) { return(TypeHelpers.CreateEnumUnderlyingTypeUsage(type)); } if (md.TypeSemantics.IsStrongSpatialType(type)) { return(TypeHelpers.CreateSpatialUnionTypeUsage(type)); } // simple scalar return(type); }
private ColumnMap CreateColumnMap(TypeUsage type, string name) { if (!TypeUtils.IsStructuredType(type)) { return((ColumnMap)this.CreateSimpleColumnMap(type, name)); } return(this.CreateStructuralColumnMap(type, name)); }
public override void Visit(VarDefOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { if (TypeUtils.IsStructuredType(op.Var.Type)) { PropertyRefList propertyRefList = this.GetPropertyRefList(op.Var); this.AddPropertyRefs(n.Child0, propertyRefList); } this.VisitChildren(n); }
/// <summary> /// VarRefOp handling /// Simply passes along the current "desired" properties /// to the corresponding Var /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> public override void Visit(VarRefOp op, Node n) { if (TypeUtils.IsStructuredType(op.Var.Type)) { // Get the properties that my parent expects from me. var myProps = GetPropertyRefList(n); // Add this onto the list of properties expected from the var itself AddPropertyRefs(op.Var, myProps); } }
/// <summary> /// VarDefOp handling /// Pushes the "desired" properties to the /// defining expression /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> public override void Visit(VarDefOp op, Node n) { if (TypeUtils.IsStructuredType(op.Var.Type)) { var myProps = GetPropertyRefList(op.Var); // Push this down to the expression defining the var AddPropertyRefs(n.Child0, myProps); } VisitChildren(n); }
public override void Visit(VarRefOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { if (!TypeUtils.IsStructuredType(op.Var.Type)) { return; } PropertyRefList propertyRefList = this.GetPropertyRefList(n); this.AddPropertyRefs(op.Var, propertyRefList); }
public override void Visit(PhysicalProjectOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { foreach (Var output in (List <Var>)op.Outputs) { if (TypeUtils.IsStructuredType(output.Type)) { this.AddPropertyRefs(output, PropertyRefList.All); } } this.VisitChildren(n); }
protected override void VisitGroupByOp(GroupByBaseOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { foreach (Var key in op.Keys) { if (TypeUtils.IsStructuredType(key.Type)) { this.AddPropertyRefs(key, PropertyRefList.All); } } this.VisitChildrenReverse(n); }
public override void Visit(DistinctOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { foreach (Var key in op.Keys) { if (TypeUtils.IsStructuredType(key.Type)) { this.AddPropertyRefs(key, PropertyRefList.All); } } this.VisitChildren(n); }
/// <summary> /// DistinctOp handling /// Require all properties out of all structured vars /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> public override void Visit(DistinctOp op, Node n) { foreach (var v in op.Keys) { if (TypeUtils.IsStructuredType(v.Type)) { AddPropertyRefs(v, PropertyRefList.All); } } VisitChildren(n); }
protected override void VisitDefault(System.Data.Entity.Core.Query.InternalTrees.Node n) { foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Children) { ScalarOp op = child.Op as ScalarOp; if (op != null && TypeUtils.IsStructuredType(op.Type)) { this.AddPropertyRefs(child, PropertyRefList.All); } } this.VisitChildren(n); }
// <summary> // Creates a column map for a column // </summary> // <param name="type"> column datatype </param> // <param name="name"> column name </param> private ColumnMap CreateColumnMap(md.TypeUsage type, string name) { // For simple types, create a simple column map // Temporarily, handle collections exactly the same way if (!TypeUtils.IsStructuredType(type)) { return(CreateSimpleColumnMap(type, name)); } // At this point, we must be dealing with either a record type, a // complex type, or an entity type return(CreateStructuralColumnMap(type, name)); }
/// <summary> /// PhysicalProjectOp handling /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> public override void Visit(PhysicalProjectOp op, Node n) { // Insist that we need all properties from all the outputs foreach (var v in op.Outputs) { if (TypeUtils.IsStructuredType(v.Type)) { AddPropertyRefs(v, PropertyRefList.All); } } // simply visit the children VisitChildren(n); }
/// <summary> /// Default visitor for an Op. /// Simply walks through all children looking for Ops of structured /// types, and asks for all their properties. /// </summary> /// <remarks> /// Several of the ScalarOps take the default handling, to simply ask /// for all the children's properties: /// AggegateOp /// ArithmeticOp /// CastOp /// ConditionalOp /// ConstantOp /// ElementOp /// ExistsOp /// FunctionOp /// GetRefKeyOp /// LikeOp /// NestAggregateOp /// NewInstanceOp /// NewMultisetOp /// NewRecordOp /// RefOp /// They do not exist here to eliminate noise. /// Note that the NewRecordOp and the NewInstanceOp could be optimized to only /// push down the appropriate references, but it isn't clear to Murali that the /// complexity is worth it. /// </remarks> /// <param name="n"> </param> protected override void VisitDefault(Node n) { // for each child that is a complex type, simply ask for all properties foreach (var chi in n.Children) { var chiOp = chi.Op as ScalarOp; if (chiOp != null && TypeUtils.IsStructuredType(chiOp.Type)) { AddPropertyRefs(chi, PropertyRefList.All); } } VisitChildren(n); }
internal TypeInfo GetTypeInfo(TypeUsage type) { if (!TypeUtils.IsStructuredType(type)) { return((TypeInfo)null); } TypeInfo typeInfo = (TypeInfo)null; if (!this.m_typeInfoMap.TryGetValue(type, out typeInfo)) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(!TypeUtils.IsStructuredType(type) || !this.m_typeInfoMapPopulated, "cannot find typeInfo for type " + (object)type); } return(typeInfo); }
/// <summary> /// GroupByOp handling /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> protected override void VisitGroupByOp(GroupByBaseOp op, Node n) { // First "request" all properties for every key (that is a structured type) foreach (var v in op.Keys) { if (TypeUtils.IsStructuredType(v.Type)) { AddPropertyRefs(v, PropertyRefList.All); } } // Now visit the aggregate definitions, the key definitions, and // the relop input in that order VisitChildrenReverse(n); }
private void CreateTypeInfoForType(TypeUsage type) { while (TypeUtils.IsCollectionType(type)) { type = TypeHelpers.GetEdmType <CollectionType>(type).TypeUsage; } if (!TypeUtils.IsStructuredType(type)) { return; } ExplicitDiscriminatorMap discriminatorMap; this.TryGetDiscriminatorMap(type.EdmType, out discriminatorMap); this.CreateTypeInfoForStructuredType(type, discriminatorMap); }
private TypeInfo ExplodeType(TypeUsage type) { if (TypeUtils.IsStructuredType(type)) { TypeInfo typeInfo = this.GetTypeInfo(type); this.ExplodeType(typeInfo); return(typeInfo); } if (!TypeUtils.IsCollectionType(type)) { return((TypeInfo)null); } this.ExplodeType(TypeHelpers.GetEdmType <CollectionType>(type).TypeUsage); return((TypeInfo)null); }
protected override void VisitSortOp(SortBaseOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { foreach (SortKey key in op.Keys) { if (TypeUtils.IsStructuredType(key.Var.Type)) { this.AddPropertyRefs(key.Var, PropertyRefList.All); } } if (n.HasChild1) { this.VisitNode(n.Child1); } this.VisitNode(n.Child0); }
internal TypeInfo GetTypeInfo(md.TypeUsage type) { if (!TypeUtils.IsStructuredType(type)) { return(null); } TypeInfo typeInfo = null; if (!m_typeInfoMap.TryGetValue(type, out typeInfo)) { PlanCompiler.Assert( !TypeUtils.IsStructuredType(type) || !m_typeInfoMapPopulated, "cannot find typeInfo for type " + type); } return(typeInfo); }
private TypeInfo CreateTypeInfoForStructuredType( TypeUsage type, ExplicitDiscriminatorMap discriminatorMap) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeUtils.IsStructuredType(type), "expected structured type. Found " + (object)type); TypeInfo typeInfo1 = this.GetTypeInfo(type); if (typeInfo1 != null) { return(typeInfo1); } TypeInfo superTypeInfo = (TypeInfo)null; if (type.EdmType.BaseType != null) { superTypeInfo = this.CreateTypeInfoForStructuredType(TypeUsage.Create(type.EdmType.BaseType), discriminatorMap); } else { RefType type1; if (TypeHelpers.TryGetEdmType <RefType>(type, out type1)) { EntityType elementType = type1.ElementType as EntityType; if (elementType != null && elementType.BaseType != null) { superTypeInfo = this.CreateTypeInfoForStructuredType(TypeHelpers.CreateReferenceTypeUsage(elementType.BaseType as EntityType), discriminatorMap); } } } foreach (EdmMember structuralMember in TypeHelpers.GetDeclaredStructuralMembers(type)) { this.CreateTypeInfoForType(structuralMember.TypeUsage); } EntityTypeBase type2; if (TypeHelpers.TryGetEdmType <EntityTypeBase>(type, out type2)) { foreach (RelProperty declaredOnlyRelProperty in this.m_relPropertyHelper.GetDeclaredOnlyRelProperties(type2)) { this.CreateTypeInfoForType(declaredOnlyRelProperty.ToEnd.TypeUsage); } } TypeInfo typeInfo2 = TypeInfo.Create(type, superTypeInfo, discriminatorMap); this.m_typeInfoMap.Add(type, typeInfo2); return(typeInfo2); }
// <summary> // "Explode" a type. (ie) produce a flat record type with one property for each // scalar property (top-level or nested) of the original type. // Really deals with structured types, but also // peels off collection wrappers // </summary> // <param name="type"> the type to explode </param> // <returns> the typeinfo for this type (with the explosion) </returns> private TypeInfo ExplodeType(md.TypeUsage type) { if (TypeUtils.IsStructuredType(type)) { var typeInfo = GetTypeInfo(type); ExplodeType(typeInfo); return(typeInfo); } if (TypeUtils.IsCollectionType(type)) { var elementType = TypeHelpers.GetEdmType <md.CollectionType>(type).TypeUsage; ExplodeType(elementType); return(null); } return(null); }
/// <summary> /// SortOp handling /// First, "request" that for any sort key that is a structured type, we /// need all its properties. Then process any local definitions, and /// finally the relop input /// </summary> /// <param name="op"> </param> /// <param name="n"> </param> protected override void VisitSortOp(SortBaseOp op, Node n) { // foreach sort key, every single bit of the Var is needed foreach (var sk in op.Keys) { if (TypeUtils.IsStructuredType(sk.Var.Type)) { AddPropertyRefs(sk.Var, PropertyRefList.All); } } // if the sort has any local definitions, process those first if (n.HasChild1) { VisitNode(n.Child1); } // then process the relop input VisitNode(n.Child0); }
// <summary> // Create a TypeInfo (if necessary) for the type, and add it to the TypeInfo map // </summary> // <param name="type"> the type to process </param> private void CreateTypeInfoForType(md.TypeUsage type) { // // peel off all collection wrappers // while (TypeUtils.IsCollectionType(type)) { type = TypeHelpers.GetEdmType <md.CollectionType>(type).TypeUsage; } // Only add "structured" types if (TypeUtils.IsStructuredType(type)) { // check for discriminator map... ExplicitDiscriminatorMap discriminatorMap; TryGetDiscriminatorMap(type.EdmType, out discriminatorMap); CreateTypeInfoForStructuredType(type, discriminatorMap); } }
/// <summary> /// Common handler for RelPropertyOp and PropertyOp. /// Simply pushes down the desired set of properties to the child /// </summary> /// <param name="op"> the *propertyOp </param> /// <param name="n"> node tree corresponding to the Op </param> /// <param name="propertyRef"> the property reference </param> private void VisitPropertyOp(Op op, Node n, PropertyRef propertyRef) { var cdProps = new PropertyRefList(); if (!TypeUtils.IsStructuredType(op.Type)) { cdProps.Add(propertyRef); } else { // Get the list of properties my parent expects from me. var pdProps = GetPropertyRefList(n); // Ask my child (which is really my container type) for each of these // properties // If I've been asked for all my properties, then get the // corresponding flat list of properties from my children. // For now, however, simply ask for all properties in this case // What we really need to do is to get the "flattened" list of // properties from the input, and prepend each of these with // our property name. We don't have that info available, so // I'm taking the easier route. if (pdProps.AllProperties) { cdProps = pdProps; } else { foreach (var p in pdProps.Properties) { cdProps.Add(p.CreateNestedPropertyRef(propertyRef)); } } } // push down my expectations AddPropertyRefs(n.Child0, cdProps); VisitChildren(n); }
public override void Visit(ComparisonOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { TypeUsage type = (n.Child0.Op as ScalarOp).Type; if (!TypeUtils.IsStructuredType(type)) { this.VisitChildren(n); } else if (TypeSemantics.IsRowType(type) || TypeSemantics.IsReferenceType(type)) { this.VisitDefault(n); } else { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsEntityType(type), "unexpected childOpType?"); PropertyRefList identityProperties = PropertyPushdownHelper.GetIdentityProperties(TypeHelpers.GetEdmType <EntityType>(type)); foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Children) { this.AddPropertyRefs(child, identityProperties); } this.VisitChildren(n); } }
private TypeInfo CreateTypeInfoForStructuredType(md.TypeUsage type, ExplicitDiscriminatorMap discriminatorMap) { TypeInfo typeInfo; PlanCompiler.Assert(TypeUtils.IsStructuredType(type), "expected structured type. Found " + type); // Return existing entry, if one is available typeInfo = GetTypeInfo(type); if (typeInfo != null) { return(typeInfo); } // Ensure that my supertype has been added to the map. TypeInfo superTypeInfo = null; md.RefType refType; if (type.EdmType.BaseType != null) { superTypeInfo = CreateTypeInfoForStructuredType(md.TypeUsage.Create(type.EdmType.BaseType), discriminatorMap); } // // Handle Ref types also in a similar fashion // else if (TypeHelpers.TryGetEdmType(type, out refType)) { var entityType = refType.ElementType as md.EntityType; if (entityType != null && entityType.BaseType != null) { var baseRefType = TypeHelpers.CreateReferenceTypeUsage(entityType.BaseType as md.EntityType); superTypeInfo = CreateTypeInfoForStructuredType(baseRefType, discriminatorMap); } } // // Add the types of my properties to the TypeInfo map // foreach (md.EdmMember m in TypeHelpers.GetDeclaredStructuralMembers(type)) { CreateTypeInfoForType(m.TypeUsage); } // // Get the types of the rel properties also // { md.EntityTypeBase entityType; if (TypeHelpers.TryGetEdmType(type, out entityType)) { foreach (var p in m_relPropertyHelper.GetDeclaredOnlyRelProperties(entityType)) { CreateTypeInfoForType(p.ToEnd.TypeUsage); } } } // Now add myself to the map typeInfo = TypeInfo.Create(type, superTypeInfo, discriminatorMap); m_typeInfoMap.Add(type, typeInfo); return(typeInfo); }