Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
 /// <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);
 }
Пример #5
0
        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);
        }
Пример #6
0
 // <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));
 }
Пример #7
0
 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);
 }
Пример #8
0
        public override DbExpression Visit(DbIsNullExpression expression)
        {
            Check.NotNull(expression, "expression");

            return(VisitUnary(
                       expression,
                       exp =>
                       TypeSemantics.IsRowType(exp.ResultType)
                    ? CqtBuilder.CreateIsNullExpressionAllowingRowTypeArgument(exp)
                    : CqtBuilder.IsNull(exp)));
        }
Пример #9
0
 /// <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);
 }
Пример #11
0
        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));
        }
Пример #12
0
 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);
                }
            }
                              ));
        }
Пример #14
0
 /// <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);
         }
     }
 }
Пример #15
0
        //
        // 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);
 }
Пример #17
0
 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);
         }
     }
 }
Пример #18
0
        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);
        }
Пример #19
0
        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
        }
Пример #21
0
        /// <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");
 }