예제 #1
0
        public override DbExpression Visit(DbParameterReferenceExpression expression)
        {
            Check.NotNull(expression, "expression");

            var result = base.Visit(expression);

            if (result.ExpressionKind
                == DbExpressionKind.ParameterReference)
            {
                var paramRef = result as DbParameterReferenceExpression;

                DbParameterReferenceExpression foundParam;
                if (paramMappings.TryGetValue(paramRef.ParameterName, out foundParam))
                {
                    // SQLBUDT#545720: Equivalence is not a sufficient check (consider row types for TVPs) - equality is required.
                    if (!TypeSemantics.IsEqual(paramRef.ResultType, foundParam.ResultType))
                    {
                        ThrowInvalid(Strings.Cqt_Validator_InvalidIncompatibleParameterReferences(paramRef.ParameterName));
                    }
                }
                else
                {
                    paramMappings.Add(paramRef.ParameterName, paramRef);
                }
            }
            return(result);
        }
예제 #2
0
        internal DbQueryCommandTree GenerateFunctionView(out DiscriminatorMap discriminatorMap)
        {
            DebugCheck.NotNull(m_mappingItemCollection);

            discriminatorMap = null;

            // Prepare the direct call of the store function as StoreFunction(@EdmFunc_p1, ..., @EdmFunc_pN).
            // Note that function call arguments are command parameters created from the m_edmFunction parameters.
            Debug.Assert(TargetFunction != null, "this.TargetFunction != null");
            DbExpression storeFunctionInvoke = TargetFunction.Invoke(GetParametersForTargetFunctionCall());

            // Generate the query expression producing c-space result from s-space function call(s).
            DbExpression queryExpression;

            if (m_structuralTypeMappings != null)
            {
                queryExpression = GenerateStructuralTypeResultMappingView(storeFunctionInvoke, out discriminatorMap);
                Debug.Assert(
                    queryExpression != null &&
                    TypeSemantics.IsPromotableTo(queryExpression.ResultType, FunctionImport.ReturnParameter.TypeUsage),
                    "TypeSemantics.IsPromotableTo(queryExpression.ResultType, this.FunctionImport.ReturnParameter.TypeUsage)");
            }
            else
            {
                queryExpression = GenerateScalarResultMappingView(storeFunctionInvoke);
                Debug.Assert(
                    queryExpression != null &&
                    TypeSemantics.IsEqual(queryExpression.ResultType, FunctionImport.ReturnParameter.TypeUsage),
                    "TypeSemantics.IsEqual(queryExpression.ResultType, this.FunctionImport.ReturnParameter.TypeUsage)");
            }

            // Generate parameterized command, where command parameters are semantically the c-space function parameters.
            return(DbQueryCommandTree.FromValidExpression(
                       m_mappingItemCollection.Workspace, TargetPerspective.TargetPerspectiveDataSpace, queryExpression));
        }
예제 #3
0
        public override DbExpression Visit(DbVariableReferenceExpression expression)
        {
            Check.NotNull(expression, "expression");

            var result = base.Visit(expression);

            if (result.ExpressionKind
                == DbExpressionKind.VariableReference)
            {
                var       varRef    = (DbVariableReferenceExpression)result;
                TypeUsage foundType = null;
                foreach (var scope in variableScopes)
                {
                    if (scope.TryGetValue(varRef.VariableName, out foundType))
                    {
                        break;
                    }
                }

                if (foundType == null)
                {
                    ThrowInvalid(Strings.Cqt_Validator_VarRefInvalid(varRef.VariableName));
                }

                // SQLBUDT#545720: Equivalence is not a sufficient check (consider row types) - equality is required.
                if (!TypeSemantics.IsEqual(varRef.ResultType, foundType))
                {
                    ThrowInvalid(Strings.Cqt_Validator_VarRefTypeMismatch(varRef.VariableName));
                }
            }

            return(result);
        }
예제 #4
0
        public override DbExpression Visit(DbVariableReferenceExpression expression)
        {
            Check.NotNull <DbVariableReferenceExpression>(expression, nameof(expression));
            DbExpression dbExpression = base.Visit(expression);

            if (dbExpression.ExpressionKind == DbExpressionKind.VariableReference)
            {
                DbVariableReferenceExpression referenceExpression = (DbVariableReferenceExpression)dbExpression;
                TypeUsage type2 = (TypeUsage)null;
                foreach (Dictionary <string, TypeUsage> variableScope in this.variableScopes)
                {
                    if (variableScope.TryGetValue(referenceExpression.VariableName, out type2))
                    {
                        break;
                    }
                }
                if (type2 == null)
                {
                    this.ThrowInvalid(Strings.Cqt_Validator_VarRefInvalid((object)referenceExpression.VariableName));
                }
                if (!TypeSemantics.IsEqual(referenceExpression.ResultType, type2))
                {
                    this.ThrowInvalid(Strings.Cqt_Validator_VarRefTypeMismatch((object)referenceExpression.VariableName));
                }
            }
            return(dbExpression);
        }
예제 #5
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);
        }
        private static DbExpression GenerateScalarPropertyMappingView(EdmProperty edmProperty, EdmProperty columnProperty, DbExpression row)
        {
            var accessorExpr = GenerateColumnRef(row, columnProperty);

            if (!TypeSemantics.IsEqual(accessorExpr.ResultType, edmProperty.TypeUsage))
            {
                accessorExpr = accessorExpr.CastTo(edmProperty.TypeUsage);
            }
            return(accessorExpr);
        }
예제 #7
0
        internal DbInExpression(TypeUsage booleanResultType, DbExpression item, DbExpressionList list)
            : base(DbExpressionKind.In, booleanResultType)
        {
            DebugCheck.NotNull(item);
            DebugCheck.NotNull(list);
            Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbInExpression must have a Boolean result type");
            Debug.Assert(
                list.All(e => TypeSemantics.IsEqual(e.ResultType, item.ResultType)),
                "DbInExpression requires the same result type for the input expressions");

            _item = item;
            _list = list;
        }
예제 #8
0
        private static DbExpression GenerateScalarPropertyMappingView(
            EdmProperty edmProperty,
            EdmProperty columnProperty,
            DbExpression row)
        {
            DbExpression columnRef = FunctionImportMappingComposable.GenerateColumnRef(row, columnProperty);

            if (!TypeSemantics.IsEqual(columnRef.ResultType, edmProperty.TypeUsage))
            {
                columnRef = (DbExpression)columnRef.CastTo(edmProperty.TypeUsage);
            }
            return(columnRef);
        }
예제 #9
0
        private DbExpression GenerateScalarResultMappingView(
            DbExpression storeFunctionInvoke)
        {
            DbExpression   source = storeFunctionInvoke;
            CollectionType functionImportReturnType;

            MetadataHelper.TryGetFunctionImportReturnCollectionType(this.FunctionImport, 0, out functionImportReturnType);
            EdmProperty column = ((RowType)((CollectionType)source.ResultType.EdmType).TypeUsage.EdmType).Properties[0];
            Func <DbExpression, DbExpression> scalarView = (Func <DbExpression, DbExpression>)(row =>
            {
                DbPropertyExpression propertyExpression = row.Property(column);
                if (TypeSemantics.IsEqual(functionImportReturnType.TypeUsage, column.TypeUsage))
                {
                    return((DbExpression)propertyExpression);
                }
                return((DbExpression)propertyExpression.CastTo(functionImportReturnType.TypeUsage));
            });

            return((DbExpression)source.Select <DbExpression>((Func <DbExpression, DbExpression>)(row => scalarView(row))));
        }
예제 #10
0
        public override DbExpression Visit(DbParameterReferenceExpression expression)
        {
            Check.NotNull <DbParameterReferenceExpression>(expression, nameof(expression));
            DbExpression dbExpression = base.Visit(expression);

            if (dbExpression.ExpressionKind == DbExpressionKind.ParameterReference)
            {
                DbParameterReferenceExpression referenceExpression1 = dbExpression as DbParameterReferenceExpression;
                DbParameterReferenceExpression referenceExpression2;
                if (this.paramMappings.TryGetValue(referenceExpression1.ParameterName, out referenceExpression2))
                {
                    if (!TypeSemantics.IsEqual(referenceExpression1.ResultType, referenceExpression2.ResultType))
                    {
                        this.ThrowInvalid(Strings.Cqt_Validator_InvalidIncompatibleParameterReferences((object)referenceExpression1.ParameterName));
                    }
                }
                else
                {
                    this.paramMappings.Add(referenceExpression1.ParameterName, referenceExpression1);
                }
            }
            return(dbExpression);
        }
        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
        }