/// <summary> /// Add a new property reference to this list /// </summary> /// <param name="property">new property reference</param> internal void Add(PropertyRef property) { if (m_allProperties) { return; } else if (property is AllPropertyRef) { MakeAllProperties(); } else { m_propertyReferences[property] = property; } }
/// <summary> /// Add a mapping from the propertyRef (of the old type) to the /// corresponding property in the new type. /// /// NOTE: Only to be used by StructuredTypeInfo /// </summary> /// <param name="propertyRef"></param> /// <param name="newProperty"></param> internal void AddPropertyMapping(PropertyRef propertyRef, EdmProperty newProperty) { m_propertyMap[propertyRef] = newProperty; if (propertyRef is TypeIdPropertyRef) { m_typeIdProperty = newProperty; } else if (propertyRef is EntitySetIdPropertyRef) { m_entitySetIdProperty = newProperty; } else if (propertyRef is NullSentinelPropertyRef) { m_nullSentinelProperty = newProperty; } }
/// <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) { PropertyRefList cdProps = new PropertyRefList(); if (!TypeUtils.IsStructuredType(op.Type)) { cdProps.Add(propertyRef); } else { // Get the list of properties my parent expects from me. PropertyRefList 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 (PropertyRef p in pdProps.Properties) { cdProps.Add(p.CreateNestedPropertyRef(propertyRef)); } } } // push down my expectations AddPropertyRefs(n.Child0, cdProps); VisitChildren(n); }
/// <summary> /// Do I contain the specifed property? /// </summary> /// <param name="p">The property</param> /// <returns>true, if I do</returns> internal bool Contains(PropertyRef p) { return(m_allProperties || m_propertyReferences.ContainsKey(p)); }
/// <summary> /// Basic constructor. /// Represents the access of property "propertyRef" within property "property" /// </summary> /// <param name="innerProperty">the inner property</param> /// <param name="outerProperty">the outer property</param> internal NestedPropertyRef(PropertyRef innerProperty, PropertyRef outerProperty) { PlanCompiler.Assert(!(innerProperty is NestedPropertyRef), "innerProperty cannot be a NestedPropertyRef"); m_inner = innerProperty; m_outer = outerProperty; }
/// <summary> /// Create a nested property ref, with "p" as the prefix /// </summary> /// <param name="p">the property to prefix with</param> /// <returns>the nested property reference</returns> internal override PropertyRef CreateNestedPropertyRef(PropertyRef p) { return(p); }
/// <summary> /// Determines the offset for structured types in Flattened type. For instance, if the original type is of the form: /// /// { int X, ComplexType Y } /// /// and the flattened type is of the form: /// /// { int X, Y_ComplexType_Prop1, Y_ComplexType_Prop2 } /// /// GetNestedStructureOffset(Y) returns 1 /// </summary> /// <param name="property">Complex property.</param> /// <returns>Offset.</returns> internal int GetNestedStructureOffset(PropertyRef property) { // m_propertyRefList contains every element of the flattened type for (int i = 0; i < m_propertyRefList.Count; i++) { NestedPropertyRef nestedPropertyRef = m_propertyRefList[i] as NestedPropertyRef; // match offset of the first element of the complex type property if (null != nestedPropertyRef && nestedPropertyRef.InnerProperty.Equals(property)) { return i; } } PlanCompiler.Assert(false, "no complex structure " + property + " found in TypeInfo"); // return something so that the compiler doesn't complain return default(int); }
/// <summary> /// Try get the new property for the supplied propertyRef /// </summary> /// <param name="propertyRef">property reference (on the old type)</param> /// <param name="throwIfMissing">throw if the property is not found</param> /// <param name="property">the corresponding property on the new type</param> /// <returns></returns> internal new bool TryGetNewProperty(PropertyRef propertyRef, bool throwIfMissing, out md.EdmProperty property) { bool result = m_propertyMap.TryGetValue(propertyRef, out property); if (throwIfMissing && !result) { { PlanCompiler.Assert(false, "Unable to find property " + propertyRef.ToString() + " in type " + this.Type.EdmType.Identity); } } return result; }
/// <summary> /// Is the given propertyRef representing a null sentinel /// It is if: /// - it is a NullSentinelPropertyRef /// - it is a NestedPropertyRef with the outer property being a NullSentinelPropertyRef /// </summary> /// <param name="propertyRef"></param> /// <returns></returns> private bool IsNullSentinelPropertyRef(PropertyRef propertyRef) { if (propertyRef is NullSentinelPropertyRef) { return true; } NestedPropertyRef nestedPropertyRef = propertyRef as NestedPropertyRef; if (nestedPropertyRef == null) { return false; } return nestedPropertyRef.OuterProperty is NullSentinelPropertyRef; }
/// <summary> /// Adds a new property reference to the list of desired properties /// NOTE: Only to be used by StructuredTypeInfo /// </summary> /// <param name="propertyRef"></param> internal void AddPropertyRef(PropertyRef propertyRef) { m_propertyRefList.Add(propertyRef); }
/// <summary> /// Get the datatype for a propertyRef. The only concrete classes that we /// handle are TypeIdPropertyRef, and BasicPropertyRef. /// AllPropertyRef is illegal here. /// For BasicPropertyRef, we simply pick up the type from the corresponding /// property. For TypeIdPropertyRef, we use "string" as the default type /// or the discriminator property type where one is available. /// </summary> /// <param name="typeInfo">typeinfo of the current type</param> /// <param name="p">current property ref</param> /// <returns>the datatype of the property</returns> private md.TypeUsage GetPropertyType(RootTypeInfo typeInfo, PropertyRef p) { md.TypeUsage result = null; PropertyRef innerProperty = null; // Get the "leaf" property first while (p is NestedPropertyRef) { NestedPropertyRef npr = (NestedPropertyRef)p; p = npr.OuterProperty; innerProperty = npr.InnerProperty; } if (p is TypeIdPropertyRef) { // // Get to the innermost type that specifies this typeid (the entity type), // get the datatype for the typeid column from that type // if (innerProperty != null && innerProperty is SimplePropertyRef) { md.TypeUsage innerType = ((SimplePropertyRef)innerProperty).Property.TypeUsage; TypeInfo innerTypeInfo = GetTypeInfo(innerType); result = innerTypeInfo.RootType.TypeIdType; } else { result = typeInfo.TypeIdType; } } else if (p is EntitySetIdPropertyRef || p is NullSentinelPropertyRef) { result = m_intType; } else if (p is RelPropertyRef) { result = (p as RelPropertyRef).Property.ToEnd.TypeUsage; } else { SimplePropertyRef simpleP = p as SimplePropertyRef; if (simpleP != null) { result = md.Helper.GetModelTypeUsage(simpleP.Property); } } result = GetNewType(result); PlanCompiler.Assert(null != result, "unrecognized property type?"); return result; }
/// <summary> /// Do I contain the specifed property? /// </summary> /// <param name="p">The property</param> /// <returns>true, if I do</returns> internal bool Contains(PropertyRef p) { return m_allProperties || m_propertyReferences.ContainsKey(p); }
/// <summary> /// Create a nested property ref, with "p" as the prefix. /// The best way to think of this function as follows. /// Consider a type T where "this" describes a property X on T. Now /// consider a new type S, where "p" is a property of S and is of type T. /// This function creates a PropertyRef that describes the same property X /// from S.p instead /// </summary> /// <param name="p">the property to prefix with</param> /// <returns>the nested property reference</returns> internal virtual PropertyRef CreateNestedPropertyRef(PropertyRef p) { return new NestedPropertyRef(p, this); }
/// <summary> /// Add a new property reference to this list /// </summary> /// <param name="property">new property reference</param> internal void Add(PropertyRef property) { if (m_allProperties) return; else if (property is AllPropertyRef) MakeAllProperties(); else m_propertyReferences[property] = property; }
/// <summary> /// Create a nested property ref, with "p" as the prefix /// </summary> /// <param name="p">the property to prefix with</param> /// <returns>the nested property reference</returns> internal override PropertyRef CreateNestedPropertyRef(PropertyRef p) { return p; }
/// <summary> /// Create a nested property ref, with "p" as the prefix. /// The best way to think of this function as follows. /// Consider a type T where "this" describes a property X on T. Now /// consider a new type S, where "p" is a property of S and is of type T. /// This function creates a PropertyRef that describes the same property X /// from S.p instead /// </summary> /// <param name="p">the property to prefix with</param> /// <returns>the nested property reference</returns> internal virtual PropertyRef CreateNestedPropertyRef(PropertyRef p) { return(new NestedPropertyRef(p, this)); }
/// <summary> /// Try get the new property for the supplied propertyRef /// </summary> /// <param name="propertyRef">property reference (on the old type)</param> /// <param name="throwIfMissing">throw if the property is not found</param> /// <param name="newProperty">the corresponding property on the new type</param> /// <returns></returns> internal bool TryGetNewProperty(PropertyRef propertyRef, bool throwIfMissing, out md.EdmProperty newProperty) { return this.RootType.TryGetNewProperty(propertyRef, throwIfMissing, out newProperty); }
/// <summary> /// Common handler for PropertyOp and RelPropertyOp /// </summary> /// <param name="op"></param> /// <param name="n"></param> /// <param name="propertyRef"></param> /// <param name="throwIfMissing">ignore missing properties</param> /// <returns></returns> private Node VisitPropertyOp(Op op, Node n, PropertyRef propertyRef, bool throwIfMissing) { PlanCompiler.Assert(op.OpType == OpType.Property || op.OpType == OpType.RelProperty, "Unexpected optype: " + op.OpType); md.TypeUsage inputType = n.Child0.Op.Type; md.TypeUsage outputType = op.Type; // First visit all my children VisitChildren(n); // If the instance is not a structured type (ie) it is a udt, then there // is little for us to do. Simply return if (TypeUtils.IsUdt(inputType)) { return n; } Node newNode = null; TypeInfo inputTypeInfo = m_typeInfo.GetTypeInfo(inputType); if (TypeUtils.IsStructuredType(outputType)) { TypeInfo outputTypeInfo = m_typeInfo.GetTypeInfo(outputType); List<md.EdmProperty> fieldTypes = new List<md.EdmProperty>(); List<Node> fieldValues = new List<Node>(); PropertyRefList expectedProperties = m_nodePropertyMap[n]; foreach (PropertyRef npr in outputTypeInfo.PropertyRefList) { // Is this a property that's desired by my consumers? if (expectedProperties.Contains(npr)) { PropertyRef newPropRef = npr.CreateNestedPropertyRef(propertyRef); md.EdmProperty newNestedProp; if (inputTypeInfo.TryGetNewProperty(newPropRef, throwIfMissing, out newNestedProp)) { md.EdmProperty outputNestedProp = outputTypeInfo.GetNewProperty(npr); Node field = BuildAccessor(n.Child0, newNestedProp); if (null != field) { fieldTypes.Add(outputNestedProp); fieldValues.Add(field); } } } } Op newRecordOp = m_command.CreateNewRecordOp(outputTypeInfo.FlattenedTypeUsage, fieldTypes); newNode = m_command.CreateNode(newRecordOp, fieldValues); } else { md.EdmProperty newProp = inputTypeInfo.GetNewProperty(propertyRef); // Build an accessor over the new property newNode = this.BuildAccessorWithNulls(n.Child0, newProp); } return newNode; }
/// <summary> /// Get the new property for the supplied propertyRef /// </summary> /// <param name="propertyRef">property reference (on the old type)</param> /// <returns></returns> internal md.EdmProperty GetNewProperty(PropertyRef propertyRef) { md.EdmProperty property; bool result = TryGetNewProperty(propertyRef, true, out property); Debug.Assert(result, "Should have thrown if the property was not found"); return property; }
/// <summary> /// Try get the new property for the supplied propertyRef /// </summary> /// <param name="propertyRef">property reference (on the old type)</param> /// <param name="throwIfMissing">throw if the property is not found</param> /// <param name="newProperty">the corresponding property on the new type</param> /// <returns></returns> internal bool TryGetNewProperty(PropertyRef propertyRef, bool throwIfMissing, out md.EdmProperty newProperty) { return(this.RootType.TryGetNewProperty(propertyRef, throwIfMissing, out newProperty)); }