Example #1
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));
        }
Example #2
0
 private static bool UntypedNullAwareIsPromotableTo(TypeUsage fromType, TypeUsage toType)
 {
     if (fromType == null)
     {
         return(!Helper.IsCollectionType((GlobalItem)toType.EdmType));
     }
     return(TypeSemantics.IsPromotableTo(fromType, toType));
 }
 private static bool UntypedNullAwareIsPromotableTo(TypeUsage fromType, TypeUsage toType)
 {
     if (fromType == null)
     {
         //
         // We can implicitly promote null to any type except collection.
         //
         return(!Helper.IsCollectionType(toType.EdmType));
     }
     else
     {
         return(TypeSemantics.IsPromotableTo(fromType, toType));
     }
 }
 /// <summary>
 /// Resolves <paramref name="argTypes"/> against the list of function signatures.
 /// </summary>
 /// <returns>Funciton metadata</returns>
 internal static EdmFunction ResolveFunctionOverloads(IList <EdmFunction> functionsMetadata,
                                                      IList <TypeUsage> argTypes,
                                                      bool isGroupAggregateFunction,
                                                      out bool isAmbiguous)
 {
     return(ResolveFunctionOverloads(
                functionsMetadata,
                argTypes,
                (edmFunction) => edmFunction.Parameters,
                (functionParameter) => functionParameter.TypeUsage,
                (functionParameter) => functionParameter.Mode,
                (argType) => TypeSemantics.FlattenType(argType),
                (paramType, argType) => TypeSemantics.FlattenType(paramType),
                (fromType, toType) => TypeSemantics.IsPromotableTo(fromType, toType),
                (fromType, toType) => TypeSemantics.IsStructurallyEqual(fromType, toType),
                isGroupAggregateFunction,
                out isAmbiguous));
 }
        internal Node GetInternalTree(Command targetIqtCommand, IList <Node> targetIqtArguments)
        {
            if (m_internalTreeNode == null)
            {
                DiscriminatorMap discriminatorMap;
                var tree = GenerateFunctionView(out discriminatorMap);
                Debug.Assert(tree != null, "tree != null");

                // Convert this into an ITree first
                var itree       = ITreeGenerator.Generate(tree, discriminatorMap);
                var rootProject = itree.Root; // PhysicalProject(RelInput)
                PlanCompiler.Assert(
                    rootProject.Op.OpType == OpType.PhysicalProject,
                    "Expected a physical projectOp at the root of the tree - found " + rootProject.Op.OpType);
                var rootProjectOp = (PhysicalProjectOp)rootProject.Op;
                Debug.Assert(rootProjectOp.Outputs.Count == 1, "rootProjectOp.Outputs.Count == 1");
                var rootInput = rootProject.Child0; // the RelInput in PhysicalProject(RelInput)

                // #554756: VarVec enumerators are not cached on the shared Command instance.
                itree.DisableVarVecEnumCaching();

                // Function import returns a collection, so convert it to a scalar by wrapping into CollectOp.
                var relNode = rootInput;
                var relVar  = rootProjectOp.Outputs[0];
                // ProjectOp does not implement Type property, so get the type from the column map.
                var functionViewType = rootProjectOp.ColumnMap.Type;
                if (!Command.EqualTypes(functionViewType, FunctionImport.ReturnParameter.TypeUsage))
                {
                    Debug.Assert(
                        TypeSemantics.IsPromotableTo(functionViewType, FunctionImport.ReturnParameter.TypeUsage),
                        "Mapping expression result type must be promotable to the c-space function return type.");

                    // Build "relNode = Project(relNode, SoftCast(relVar))"
                    var expectedCollectionType = (CollectionType)FunctionImport.ReturnParameter.TypeUsage.EdmType;
                    var expectedElementType    = expectedCollectionType.TypeUsage;

                    var varRefNode     = itree.CreateNode(itree.CreateVarRefOp(relVar));
                    var castNode       = itree.CreateNode(itree.CreateSoftCastOp(expectedElementType), varRefNode);
                    var varDefListNode = itree.CreateVarDefListNode(castNode, out relVar);

                    var projectOp = itree.CreateProjectOp(relVar);
                    relNode = itree.CreateNode(projectOp, relNode, varDefListNode);
                }

                // Build "Collect(PhysicalProject(relNode))
                m_internalTreeNode = itree.BuildCollect(relNode, relVar);
            }
            Debug.Assert(m_internalTreeNode != null, "m_internalTreeNode != null");

            // Prepare argument replacement dictionary
            Debug.Assert(m_commandParameters.Length == targetIqtArguments.Count, "m_commandParameters.Length == targetIqtArguments.Count");
            var viewArguments = new Dictionary <string, Node>(m_commandParameters.Length);

            for (var i = 0; i < m_commandParameters.Length; ++i)
            {
                var commandParam = m_commandParameters[i];
                var argumentNode = targetIqtArguments[i];

                // If function import parameter is of enum type, the argument value for it will be of enum type. We however have
                // converted enum types to underlying types for m_commandParameters. So we now need to softcast the argument
                // expression to the underlying type as well.
                if (TypeSemantics.IsEnumerationType(argumentNode.Op.Type))
                {
                    argumentNode = targetIqtCommand.CreateNode(
                        targetIqtCommand.CreateSoftCastOp(TypeHelpers.CreateEnumUnderlyingTypeUsage(argumentNode.Op.Type)),
                        argumentNode);
                }

                Debug.Assert(
                    TypeSemantics.IsPromotableTo(argumentNode.Op.Type, commandParam.ResultType),
                    "Argument type must be promotable to parameter type.");

                viewArguments.Add(commandParam.ParameterName, argumentNode);
            }

            return(FunctionViewOpCopier.Copy(targetIqtCommand, m_internalTreeNode, viewArguments));
        }
Example #6
0
 internal static EdmFunction ResolveFunctionOverloads(
     IList <EdmFunction> functionsMetadata,
     IList <TypeUsage> argTypes,
     bool isGroupAggregateFunction,
     out bool isAmbiguous)
 {
     return(FunctionOverloadResolver.ResolveFunctionOverloads <EdmFunction, FunctionParameter>(functionsMetadata, argTypes, (Func <EdmFunction, IList <FunctionParameter> >)(edmFunction => (IList <FunctionParameter>)edmFunction.Parameters), (Func <FunctionParameter, TypeUsage>)(functionParameter => functionParameter.TypeUsage), (Func <FunctionParameter, ParameterMode>)(functionParameter => functionParameter.Mode), (Func <TypeUsage, IEnumerable <TypeUsage> >)(argType => TypeSemantics.FlattenType(argType)), (Func <TypeUsage, TypeUsage, IEnumerable <TypeUsage> >)((paramType, argType) => TypeSemantics.FlattenType(paramType)), (Func <TypeUsage, TypeUsage, bool>)((fromType, toType) => TypeSemantics.IsPromotableTo(fromType, toType)), (Func <TypeUsage, TypeUsage, bool>)((fromType, toType) => TypeSemantics.IsStructurallyEqual(fromType, toType)), isGroupAggregateFunction, out isAmbiguous));
 }