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)); }
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)); }
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)); }