From b436814eb57a2176eafb191e326d6419d938f840 Mon Sep 17 00:00:00 2001 From: eelke Date: Sat, 6 Jan 2018 21:18:28 +0100 Subject: [PATCH] THe SqlLexer also now recognizes casts. --- core/SqlLexer.cpp | 29 +++++++++++++++++++++++++++++ core/SqlLexer.h | 3 ++- tests/auto/mycase/tst_SqlLexer.h | 24 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/core/SqlLexer.cpp b/core/SqlLexer.cpp index e211996..ecb94e6 100644 --- a/core/SqlLexer.cpp +++ b/core/SqlLexer.cpp @@ -23,6 +23,24 @@ QChar SqlLexer::peekChar() return result; } + +//+ - * / < > = ~ ! @ # % ^ & | ` ? +//There are a few restrictions on your choice of name: +// -- and /* cannot appear anywhere in an operator name, since they will be taken as the start of a comment. +// A multicharacter operator name cannot end in + or -, unless the name also contains at least one of these characters: +// ~ ! @ # % ^ & | ` ? +// For example, @- is an allowed operator name, but *- is not. This restriction allows PostgreSQL to parse SQL-compliant commands without requiring spaces between tokens. +// The use of => as an operator name is deprecated. It may be disallowed altogether in a future release. +//The operator != is mapped to <> on input, so these two names are always equivalent. +template +inline bool isOperatorChar(C c) +{ + return c == '+' || c == '-' || c == '*' || c == '/' || c == '<' || c == '>' || c == '=' + || c == '~' || c == '!' || c == '@' || c == '#' || c == '%' || c == '^' || c == '&' + || c == '|' || c == '`' || c == '?'; +} + + /** * @brief NextBasicToken * @param in @@ -75,6 +93,17 @@ bool SqlLexer::nextBasicToken(int &startpos, int &length, BasicTokenType &tokent else if (c == '$') { return parseDollarQuote(startpos, length, tokentype, out); } + else if (c == ':') { + c = peekChar(); + if (c == ':') { + nextChar(); + length = m_pos - startpos; + tokentype = BasicTokenType::Cast; + QStringRef sr(&m_block, startpos, length); + out = sr.toString(); + return true; + } + } else { // Undetermined symbol for (;;) { diff --git a/core/SqlLexer.h b/core/SqlLexer.h index 18bbd35..c9684d8 100644 --- a/core/SqlLexer.h +++ b/core/SqlLexer.h @@ -13,7 +13,8 @@ enum class BasicTokenType { QuotedString, DollarQuote, // Return the dollar quote tag, do not consume the entire string (potentially long) QuotedIdentifier, - Parameter + Parameter, + Cast }; enum class LexerState { diff --git a/tests/auto/mycase/tst_SqlLexer.h b/tests/auto/mycase/tst_SqlLexer.h index 25d6535..76dd1f7 100644 --- a/tests/auto/mycase/tst_SqlLexer.h +++ b/tests/auto/mycase/tst_SqlLexer.h @@ -36,3 +36,27 @@ TEST(SqlLexer, lexer_quote_in_string) ASSERT_THAT(tokentype, Eq(BasicTokenType::QuotedString)); } +TEST(SqlLexer, lexer_cast) +{ + QString input = "'1'::integer"; + SqlLexer lexer(input, LexerState::Null); + + int startpos, length; + BasicTokenType tokentype; + QString out; + lexer.nextBasicToken(startpos, length, tokentype, out); + + ASSERT_THAT(startpos, Eq(0)); + ASSERT_THAT(length, Eq(3)); + ASSERT_THAT(tokentype, Eq(BasicTokenType::QuotedString)); + lexer.nextBasicToken(startpos, length, tokentype, out); + + ASSERT_THAT(startpos, Eq(3)); + ASSERT_THAT(length, Eq(2)); + ASSERT_THAT(tokentype, Eq(BasicTokenType::Cast)); + lexer.nextBasicToken(startpos, length, tokentype, out); + + ASSERT_THAT(startpos, Eq(5)); + ASSERT_THAT(length, Eq(7)); + ASSERT_THAT(tokentype, Eq(BasicTokenType::Symbol)); +}