private ISqlNode ParseFunctionCall(ITokenizer t) { var name = t.GetNext(); if (name.Type != SqlTokenType.Keyword && name.Type != SqlTokenType.Identifier) { throw ParsingException.UnexpectedToken(SqlTokenType.Identifier, name); } // "COUNT" "(" "*" ")" if (name.IsKeyword("COUNT")) { var openParen = t.Expect(SqlTokenType.Symbol, "("); var maybeStar = t.Peek(); if (maybeStar.IsSymbol("*")) { t.GetNext(); t.Expect(SqlTokenType.Symbol, ")"); return(new SqlFunctionCallNode { Location = name.Location, Name = new SqlKeywordNode(name), Arguments = new SqlListNode <ISqlNode> { new SqlOperatorNode(maybeStar) } }); } // It's not *, so put everything back, fallthrough, and let the rest of the parsing happen t.PutBack(openParen); } // TODO: "CONVERT" "(" <DataType>, <ScalarExpression> ("," <int>)? ")" // "CAST" "(" <ScalarExpression> "AS" <DataType> ")" if (name.IsKeyword("CAST")) { t.Expect(SqlTokenType.Symbol, "("); var first = ParseScalarExpression(t); t.Expect(SqlTokenType.Keyword, "AS"); var type = ParseDataType(t); t.Expect(SqlTokenType.Symbol, ")"); return(new SqlCastNode { Location = name.Location, Expression = first, DataType = type }); } // <Name> "(" <ScalarExpressionList> ")" return(new SqlFunctionCallNode { Location = name.Location, Name = Facts.IsBuiltInFunctionName(name.Value) ? (ISqlNode) new SqlKeywordNode(name.Value.ToUpperInvariant(), name.Location) : new SqlIdentifierNode(name), Arguments = ParseParenthesis(t, x => ParseList(x, ParseScalarExpression)).Expression }); }