private ColumnMap CreateStructuralColumnMap(TypeUsage type, string name) { TypeInfo typeInfo = this.m_typeInfo.GetTypeInfo(type); if (TypeSemantics.IsRowType(type)) { return((ColumnMap)this.CreateRecordColumnMap(typeInfo, name)); } if (TypeSemantics.IsReferenceType(type)) { return((ColumnMap)this.CreateRefColumnMap(typeInfo, name)); } if (typeInfo.HasTypeIdProperty) { return((ColumnMap)this.CreatePolymorphicColumnMap(typeInfo, name)); } if (TypeSemantics.IsComplexType(type)) { return((ColumnMap)this.CreateComplexTypeColumnMap(typeInfo, name, (ComplexTypeColumnMap)null, (Dictionary <object, TypedColumnMap>)null, (List <TypedColumnMap>)null)); } if (TypeSemantics.IsEntityType(type)) { return((ColumnMap)this.CreateEntityColumnMap(typeInfo, name, (EntityColumnMap)null, (Dictionary <object, TypedColumnMap>)null, (List <TypedColumnMap>)null, true)); } throw new NotSupportedException(type.Identity); }
private DbExpression GenerateScalarResultMappingView(DbExpression storeFunctionInvoke) { DbExpression queryExpression = storeFunctionInvoke; CollectionType functionImportReturnType; if (!MetadataHelper.TryGetFunctionImportReturnCollectionType(this.FunctionImport, 0, out functionImportReturnType)) { Debug.Fail("Failed to get the result type of the function import."); } Debug.Assert(TypeSemantics.IsCollectionType(queryExpression.ResultType), "Store function must be TVF (collection expected)."); var collectionType = (CollectionType)queryExpression.ResultType.EdmType; Debug.Assert(TypeSemantics.IsRowType(collectionType.TypeUsage), "Store function must be TVF (collection of rows expected)."); var rowType = (RowType)collectionType.TypeUsage.EdmType; var column = rowType.Properties[0]; Func <DbExpression, DbExpression> scalarView = (DbExpression row) => { var propertyAccess = row.Property(column); if (TypeSemantics.IsEqual(functionImportReturnType.TypeUsage, column.TypeUsage)) { return(propertyAccess); } else { return(propertyAccess.CastTo(functionImportReturnType.TypeUsage)); } }; queryExpression = queryExpression.Select(row => scalarView(row)); return(queryExpression); }
/// <summary> /// Utility method that determines whether a given CaseOp subtree can be optimized. /// Called by both PreProcessor and NominalTypeEliminator. /// /// If the case statement is of the shape: /// case when X then NULL else Y, or /// case when X then Y else NULL, /// where Y is of row type, and the types of the input CaseOp, the NULL and Y are the same, /// return true /// </summary> /// <param name="op"></param> /// <param name="n"></param> /// <returns></returns> internal static bool IsRowTypeCaseOpWithNullability(CaseOp op, Node n, out bool thenClauseIsNull) { thenClauseIsNull = false; //any default value will do if (!TypeSemantics.IsRowType(op.Type)) { return(false); } if (n.Children.Count != 3) { return(false); } //All three types must be equal if (!n.Child1.Op.Type.EdmEquals(op.Type) || !n.Child2.Op.Type.EdmEquals(op.Type)) { return(false); } //At least one of Child1 and Child2 needs to be a null if (n.Child1.Op.OpType == OpType.Null) { thenClauseIsNull = true; return(true); } if (n.Child2.Op.OpType == OpType.Null) { // thenClauseIsNull stays false return(true); } return(false); }
/// <summary> /// Determine wheter a given typeusage is valid for set comparison operator such as UNION, INTERSECT and EXCEPT /// </summary> /// <param name="typeUsage"> </param> /// <returns> </returns> internal static bool IsSetComparableOpType(TypeUsage typeUsage) { if (Helper.IsEntityType(typeUsage.EdmType) || Helper.IsPrimitiveType(typeUsage.EdmType) || Helper.IsEnumType(typeUsage.EdmType) || Helper.IsRefType(typeUsage.EdmType)) { return(true); } else if (TypeSemantics.IsRowType(typeUsage)) { var rowType = (RowType)typeUsage.EdmType; foreach (var property in rowType.Properties) { if (!IsSetComparableOpType(property.TypeUsage)) { return(false); } } return(true); } return(false); }
private static Dictionary <Var, EdmProperty> BuildOutputVarMap( PhysicalProjectOp projectOp, TypeUsage outputType) { Dictionary <Var, EdmProperty> dictionary = new Dictionary <Var, EdmProperty>(); System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsRowType(outputType), "PhysicalProjectOp result type is not a RowType?"); IEnumerator <EdmProperty> enumerator1 = (IEnumerator <EdmProperty>)TypeHelpers.GetEdmType <RowType>(outputType).Properties.GetEnumerator(); IEnumerator <Var> enumerator2 = (IEnumerator <Var>)projectOp.Outputs.GetEnumerator(); while (true) { bool flag1 = enumerator1.MoveNext(); bool flag2 = enumerator2.MoveNext(); if (flag1 == flag2) { if (flag1) { dictionary[enumerator2.Current] = enumerator1.Current; } else { goto label_5; } } else { break; } } throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.ColumnCountMismatch, 1, (object)null); label_5: return(dictionary); }
// <summary> // Returns true if typeUsage type is valid for IS [NOT] NULL (expr) operator // </summary> internal static bool IsValidIsNullOpType(TypeUsage typeUsage) { return(TypeSemantics.IsReferenceType(typeUsage) || TypeSemantics.IsEntityType(typeUsage) || TypeSemantics.IsScalarType(typeUsage) || TypeSemantics.IsRowType(typeUsage)); }
internal static bool IsStructuredType(TypeUsage type) { if (!TypeSemantics.IsReferenceType(type) && !TypeSemantics.IsRowType(type) && (!TypeSemantics.IsEntityType(type) && !TypeSemantics.IsRelationshipType(type))) { return(TypeSemantics.IsComplexType(type)); } return(true); }
public override DbExpression Visit(DbIsNullExpression expression) { Check.NotNull(expression, "expression"); return(VisitUnary( expression, exp => TypeSemantics.IsRowType(exp.ResultType) ? CqtBuilder.CreateIsNullExpressionAllowingRowTypeArgument(exp) : CqtBuilder.IsNull(exp))); }
/// <summary> /// Returns row type if supplied function is a tvf returning Collection(RowType), otherwise null. /// </summary> internal static RowType GetTvfReturnType(EdmFunction tvf) { if (tvf.ReturnParameter != null && TypeSemantics.IsCollectionType(tvf.ReturnParameter.TypeUsage)) { var expectedElementTypeUsage = ((CollectionType)tvf.ReturnParameter.TypeUsage.EdmType).TypeUsage; if (TypeSemantics.IsRowType(expectedElementTypeUsage)) { return((RowType)expectedElementTypeUsage.EdmType); } } return(null); }
internal static bool IsValidSortOpKeyType(TypeUsage typeUsage) { if (!TypeSemantics.IsRowType(typeUsage)) { return(TypeSemantics.IsOrderComparable(typeUsage)); } foreach (EdmMember property in ((RowType)typeUsage.EdmType).Properties) { if (!TypeHelpers.IsValidSortOpKeyType(property.TypeUsage)) { return(false); } } return(true); }
internal static ProviderCommandInfo Create(Command command, System.Data.Entity.Core.Query.InternalTrees.Node node) { PhysicalProjectOp op = node.Op as PhysicalProjectOp; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(op != null, "Expected root Op to be a physical Project"); DbCommandTree commandTree = CTreeGenerator.Generate(command, node); DbQueryCommandTree queryCommandTree = commandTree as DbQueryCommandTree; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(queryCommandTree != null, "null query command tree"); CollectionType edmType = TypeHelpers.GetEdmType <CollectionType>(queryCommandTree.Query.ResultType); System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsRowType(edmType.TypeUsage), "command rowtype is not a record"); ProviderCommandInfoUtils.BuildOutputVarMap(op, edmType.TypeUsage); return(new ProviderCommandInfo(commandTree)); }
internal static bool IsRowTypeCaseOpWithNullability( CaseOp op, System.Data.Entity.Core.Query.InternalTrees.Node n, out bool thenClauseIsNull) { thenClauseIsNull = false; if (!TypeSemantics.IsRowType(op.Type) || n.Children.Count != 3 || (!n.Child1.Op.Type.EdmEquals((MetadataItem)op.Type) || !n.Child2.Op.Type.EdmEquals((MetadataItem)op.Type))) { return(false); } if (n.Child1.Op.OpType == OpType.Null) { thenClauseIsNull = true; return(true); } return(n.Child2.Op.OpType == OpType.Null); }
public override DbExpression Visit(DbIsNullExpression expression) { EntityUtil.CheckArgumentNull(expression, "expression"); return(VisitUnary(expression, exp => { if (TypeSemantics.IsRowType(exp.ResultType)) { // return CqtBuilder.CreateIsNullExpressionAllowingRowTypeArgument(exp); } else { return CqtBuilder.IsNull(exp); } } )); }
/// <summary> /// Recursively add any Row types to the list of types needing a sentinel. /// </summary> /// <param name="typesNeedingNullableSentinel"> </param> /// <param name="typeUsage"> </param> private static void AddTypeNeedingNullSentinel(HashSet <string> typesNeedingNullSentinel, TypeUsage typeUsage) { if (TypeSemantics.IsCollectionType(typeUsage)) { AddTypeNeedingNullSentinel(typesNeedingNullSentinel, TypeHelpers.GetElementTypeUsage(typeUsage)); } else { if (TypeSemantics.IsRowType(typeUsage) || TypeSemantics.IsComplexType(typeUsage)) { MarkAsNeedingNullSentinel(typesNeedingNullSentinel, typeUsage); } foreach (EdmMember m in TypeHelpers.GetAllStructuralMembers(typeUsage)) { AddTypeNeedingNullSentinel(typesNeedingNullSentinel, m.TypeUsage); } } }
// // Type Semantics // /// <summary> /// Determines whether a given typeUsage is valid as OrderBy sort key /// </summary> /// <param name="typeUsage"> </param> /// <returns> </returns> internal static bool IsValidSortOpKeyType(TypeUsage typeUsage) { if (TypeSemantics.IsRowType(typeUsage)) { var rowType = (RowType)typeUsage.EdmType; foreach (var property in rowType.Properties) { if (!IsValidSortOpKeyType(property.TypeUsage)) { return(false); } } return(true); } else { return(TypeSemantics.IsOrderComparable(typeUsage)); } }
internal static bool IsSetComparableOpType(TypeUsage typeUsage) { if (Helper.IsEntityType(typeUsage.EdmType) || Helper.IsPrimitiveType(typeUsage.EdmType) || (Helper.IsEnumType(typeUsage.EdmType) || Helper.IsRefType((GlobalItem)typeUsage.EdmType))) { return(true); } if (!TypeSemantics.IsRowType(typeUsage)) { return(false); } foreach (EdmMember property in ((RowType)typeUsage.EdmType).Properties) { if (!TypeHelpers.IsSetComparableOpType(property.TypeUsage)) { return(false); } } return(true); }
private static void AddTypeNeedingNullSentinel( HashSet <string> typesNeedingNullSentinel, TypeUsage typeUsage) { if (TypeSemantics.IsCollectionType(typeUsage)) { StructuredTypeNullabilityAnalyzer.AddTypeNeedingNullSentinel(typesNeedingNullSentinel, TypeHelpers.GetElementTypeUsage(typeUsage)); } else { if (TypeSemantics.IsRowType(typeUsage) || TypeSemantics.IsComplexType(typeUsage)) { StructuredTypeNullabilityAnalyzer.MarkAsNeedingNullSentinel(typesNeedingNullSentinel, typeUsage); } foreach (EdmMember structuralMember in (IEnumerable)TypeHelpers.GetAllStructuralMembers(typeUsage)) { StructuredTypeNullabilityAnalyzer.AddTypeNeedingNullSentinel(typesNeedingNullSentinel, structuralMember.TypeUsage); } } }
public override void Visit(SoftCastOp op, System.Data.Entity.Core.Query.InternalTrees.Node n) { PropertyRefList propertyRefs = (PropertyRefList)null; if (TypeSemantics.IsReferenceType(op.Type)) { propertyRefs = PropertyRefList.All; } else if (TypeSemantics.IsNominalType(op.Type)) { propertyRefs = this.m_nodePropertyRefMap[n].Clone(); } else if (TypeSemantics.IsRowType(op.Type)) { propertyRefs = PropertyRefList.All; } if (propertyRefs != null) { this.AddPropertyRefs(n.Child0, propertyRefs); } this.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 DbExpression GenerateScalarResultMappingView(DbExpression storeFunctionInvoke) { var queryExpression = storeFunctionInvoke; CollectionType functionImportReturnType; if (!MetadataHelper.TryGetFunctionImportReturnCollectionType(FunctionImport, 0, out functionImportReturnType)) { Debug.Fail("Failed to get the result type of the function import."); } Debug.Assert(TypeSemantics.IsCollectionType(queryExpression.ResultType), "Store function must be TVF (collection expected)."); var collectionType = (CollectionType)queryExpression.ResultType.EdmType; Debug.Assert(TypeSemantics.IsRowType(collectionType.TypeUsage), "Store function must be TVF (collection of rows expected)."); var rowType = (RowType)collectionType.TypeUsage.EdmType; var column = rowType.Properties[0]; Func <DbExpression, DbExpression> scalarView = row => { var propertyAccess = row.Property(column); if (TypeSemantics.IsEqual( functionImportReturnType.TypeUsage, column.TypeUsage)) { return(propertyAccess); } else { return(propertyAccess.CastTo(functionImportReturnType.TypeUsage)); } }; // ReSharper disable ConvertClosureToMethodGroup // using Method Group breaks matching the expression in DbExpressionBuilder.ResolveToExpression return(queryExpression.Select(row => scalarView(row))); // ReSharper restore ConvertClosureToMethodGroup }
/// <summary> /// Adds the flattened properties on the input to the flattenedProperties list. /// </summary> /// <param name="input"></param> /// <param name="flattenedProperties"></param> private void FlattenProperties(DbExpression input, IList <DbPropertyExpression> flattenedProperties) { IList <EdmProperty> properties = TypeHelpers.GetProperties(input.ResultType); Debug.Assert(properties.Count != 0, "No nested properties when FlattenProperties called?"); for (int i = 0; i < properties.Count; i++) { DbExpression propertyInput = input; DbPropertyExpression propertyExpression = propertyInput.Property(properties[i]); if (TypeSemantics.IsPrimitiveType(properties[i].TypeUsage)) { flattenedProperties.Add(propertyExpression); } else { Debug.Assert(TypeSemantics.IsEntityType(properties[i].TypeUsage) || TypeSemantics.IsRowType(properties[i].TypeUsage), "The input to FlattenProperties is not of EntityType or RowType?"); FlattenProperties(propertyExpression, flattenedProperties); } } }
internal DbRefKeyExpression(TypeUsage rowResultType, DbExpression reference) : base(DbExpressionKind.RefKey, rowResultType, reference) { Debug.Assert(TypeSemantics.IsRowType(rowResultType), "DbRefKeyExpression requires a row result type"); }