示例#1
0
        /// <summary>
        /// Write the function call token as URI part to this builder.
        /// </summary>
        /// <param name="functionQueryToken">To write as URI part.</param>
        protected virtual void WriteFunctionCall(FunctionCallQueryToken functionQueryToken)
        {
            ExceptionUtils.CheckArgumentNotNull(functionQueryToken, "functionQueryToken");

            this.builder.Append(functionQueryToken.Name);
            this.builder.Append(ExpressionConstants.SymbolOpenParen);

            bool needComma = false;

            foreach (QueryToken parameter in functionQueryToken.Arguments)
            {
                if (needComma)
                {
                    this.builder.Append(ExpressionConstants.SymbolComma);
                }
                else
                {
                    needComma = true;
                }

                this.WriteQuery(parameter);
            }

            this.builder.Append(ExpressionConstants.SymbolClosedParen);
        }
示例#2
0
        /// <summary>
        /// Binds a function call token.
        /// </summary>
        /// <param name="functionCallToken">The function call token to bind.</param>
        /// <returns>The bound function call token.</returns>
        protected virtual QueryNode BindFunctionCall(FunctionCallQueryToken functionCallToken)
        {
            ExceptionUtils.CheckArgumentNotNull(functionCallToken, "functionCallToken");
            ExceptionUtils.CheckArgumentNotNull(functionCallToken.Name, "functionCallToken.Name");

            // Bind all arguments
            List<QueryNode> argumentNodes = new List<QueryNode>(functionCallToken.Arguments.Select(ar => this.Bind(ar)));

            // Special case the operators which look like function calls
            if (functionCallToken.Name == "cast")
            {
                // TODO: Implement cast operators
                throw new NotImplementedException();
            }
            else if (functionCallToken.Name == "isof")
            {
                // TODO: Implement cast operators
                throw new NotImplementedException();
            }
            else
            {
                // Try to find the function in our built-in functions
                BuiltInFunctionSignature[] signatures;
                if (!BuiltInFunctions.TryGetBuiltInFunction(functionCallToken.Name, out signatures))
                {
                    throw new ODataException(Strings.MetadataBinder_UnknownFunction(functionCallToken.Name));
                }

                // Right now all functions take a single value for all arguments
                IEdmTypeReference[] argumentTypes = new IEdmTypeReference[argumentNodes.Count];
                for (int i = 0; i < argumentNodes.Count; i++)
                {
                    SingleValueQueryNode argumentNode = argumentNodes[i] as SingleValueQueryNode;
                    if (argumentNode == null)
                    {
                        throw new ODataException(Strings.MetadataBinder_FunctionArgumentNotSingleValue(functionCallToken.Name));
                    }

                    argumentTypes[i] = argumentNode.TypeReference;
                }

                BuiltInFunctionSignature signature = (BuiltInFunctionSignature)
                    TypePromotionUtils.FindBestFunctionSignature(signatures, argumentTypes);
                if (signature == null)
                {
                    throw new ODataException(Strings.MetadataBinder_NoApplicableFunctionFound(
                        functionCallToken.Name,
                        BuiltInFunctions.BuildFunctionSignatureListDescription(functionCallToken.Name, signatures)));
                }

                // Convert all argument nodes to the best signature argument type
                Debug.Assert(signature.ArgumentTypes.Length == argumentNodes.Count, "The best signature match doesn't have the same number of arguments.");
                for (int i = 0; i < argumentNodes.Count; i++)
                {
                    Debug.Assert(argumentNodes[i] is SingleValueQueryNode, "We should have already verified that all arguments are single values.");
                    SingleValueQueryNode argumentNode = (SingleValueQueryNode)argumentNodes[i];
                    IEdmTypeReference signatureArgumentType = signature.ArgumentTypes[i];
                    if (signatureArgumentType != argumentNode.TypeReference)
                    {
                        argumentNodes[i] = ConvertToType(argumentNode, signatureArgumentType);
                    }
                }

                return new SingleValueFunctionCallQueryNode
                {
                    Name = functionCallToken.Name,
                    Arguments = new ReadOnlyCollection<QueryNode>(argumentNodes),
                    ReturnType = signature.ReturnType
                };
            }
        }
示例#3
0
        /// <summary>
        /// Write the function call token as URI part to this builder.
        /// </summary>
        /// <param name="functionQueryToken">To write as URI part.</param>
        protected virtual void WriteFunctionCall(FunctionCallQueryToken functionQueryToken)
        {
            ExceptionUtils.CheckArgumentNotNull(functionQueryToken, "functionQueryToken");

            this.builder.Append(functionQueryToken.Name);
            this.builder.Append(ExpressionConstants.SymbolOpenParen);

            bool needComma = false;
            foreach (QueryToken parameter in functionQueryToken.Arguments)
            {
                if (needComma)
                {
                    this.builder.Append(ExpressionConstants.SymbolComma);
                }
                else
                {
                    needComma = true;
                }

                this.WriteQuery(parameter);
            }

            this.builder.Append(ExpressionConstants.SymbolClosedParen);
        }