THe SqlLexer also now recognizes casts.
This commit is contained in:
parent
a99f059b70
commit
b436814eb5
3 changed files with 55 additions and 1 deletions
|
|
@ -23,6 +23,24 @@ QChar SqlLexer::peekChar()
|
||||||
return result;
|
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 <typename C>
|
||||||
|
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
|
* @brief NextBasicToken
|
||||||
* @param in
|
* @param in
|
||||||
|
|
@ -75,6 +93,17 @@ bool SqlLexer::nextBasicToken(int &startpos, int &length, BasicTokenType &tokent
|
||||||
else if (c == '$') {
|
else if (c == '$') {
|
||||||
return parseDollarQuote(startpos, length, tokentype, out);
|
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 {
|
else {
|
||||||
// Undetermined symbol
|
// Undetermined symbol
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ enum class BasicTokenType {
|
||||||
QuotedString,
|
QuotedString,
|
||||||
DollarQuote, // Return the dollar quote tag, do not consume the entire string (potentially long)
|
DollarQuote, // Return the dollar quote tag, do not consume the entire string (potentially long)
|
||||||
QuotedIdentifier,
|
QuotedIdentifier,
|
||||||
Parameter
|
Parameter,
|
||||||
|
Cast
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class LexerState {
|
enum class LexerState {
|
||||||
|
|
|
||||||
|
|
@ -36,3 +36,27 @@ TEST(SqlLexer, lexer_quote_in_string)
|
||||||
ASSERT_THAT(tokentype, Eq(BasicTokenType::QuotedString));
|
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));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue