mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Quote some identifiers when formatting SQL queries. (#9142)
* Added test * Different way to fix the issue * Different way to fix the issue * Descend instead of syntax error while parsing INTERVAL operators * Remove old comment
This commit is contained in:
parent
e64e6d7b57
commit
a4573ab7df
@ -62,4 +62,43 @@ void writeException(const Exception & e, WriteBuffer & buf, bool with_stack_trac
|
||||
bool has_nested = false;
|
||||
writeBinary(has_nested, buf);
|
||||
}
|
||||
|
||||
|
||||
/// The same, but quotes apply only if there are characters that do not match the identifier without quotes
|
||||
template <typename F>
|
||||
static inline void writeProbablyQuotedStringImpl(const StringRef & s, WriteBuffer & buf, F && write_quoted_string)
|
||||
{
|
||||
if (!s.size || !isValidIdentifierBegin(s.data[0]))
|
||||
{
|
||||
write_quoted_string(s, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * pos = s.data + 1;
|
||||
const char * end = s.data + s.size;
|
||||
for (; pos < end; ++pos)
|
||||
if (!isWordCharASCII(*pos))
|
||||
break;
|
||||
if (pos != end)
|
||||
write_quoted_string(s, buf);
|
||||
else
|
||||
writeString(s, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void writeProbablyBackQuotedString(const StringRef & s, WriteBuffer & buf)
|
||||
{
|
||||
writeProbablyQuotedStringImpl(s, buf, [](const StringRef & s_, WriteBuffer & buf_) { return writeBackQuotedString(s_, buf_); });
|
||||
}
|
||||
|
||||
void writeProbablyDoubleQuotedString(const StringRef & s, WriteBuffer & buf)
|
||||
{
|
||||
writeProbablyQuotedStringImpl(s, buf, [](const StringRef & s_, WriteBuffer & buf_) { return writeDoubleQuotedString(s_, buf_); });
|
||||
}
|
||||
|
||||
void writeProbablyBackQuotedStringMySQL(const StringRef & s, WriteBuffer & buf)
|
||||
{
|
||||
writeProbablyQuotedStringImpl(s, buf, [](const StringRef & s_, WriteBuffer & buf_) { return writeBackQuotedStringMySQL(s_, buf_); });
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -509,40 +509,10 @@ inline void writeBackQuotedStringMySQL(const StringRef & s, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
/// The same, but quotes apply only if there are characters that do not match the identifier without quotes.
|
||||
template <typename F>
|
||||
inline void writeProbablyQuotedStringImpl(const StringRef & s, WriteBuffer & buf, F && write_quoted_string)
|
||||
{
|
||||
if (!s.size || !isValidIdentifierBegin(s.data[0]))
|
||||
write_quoted_string(s, buf);
|
||||
else
|
||||
{
|
||||
const char * pos = s.data + 1;
|
||||
const char * end = s.data + s.size;
|
||||
for (; pos < end; ++pos)
|
||||
if (!isWordCharASCII(*pos))
|
||||
break;
|
||||
if (pos != end)
|
||||
write_quoted_string(s, buf);
|
||||
else
|
||||
writeString(s, buf);
|
||||
}
|
||||
}
|
||||
|
||||
inline void writeProbablyBackQuotedString(const StringRef & s, WriteBuffer & buf)
|
||||
{
|
||||
writeProbablyQuotedStringImpl(s, buf, [](const StringRef & s_, WriteBuffer & buf_) { return writeBackQuotedString(s_, buf_); });
|
||||
}
|
||||
|
||||
inline void writeProbablyDoubleQuotedString(const StringRef & s, WriteBuffer & buf)
|
||||
{
|
||||
writeProbablyQuotedStringImpl(s, buf, [](const StringRef & s_, WriteBuffer & buf_) { return writeDoubleQuotedString(s_, buf_); });
|
||||
}
|
||||
|
||||
inline void writeProbablyBackQuotedStringMySQL(const StringRef & s, WriteBuffer & buf)
|
||||
{
|
||||
writeProbablyQuotedStringImpl(s, buf, [](const StringRef & s_, WriteBuffer & buf_) { return writeBackQuotedStringMySQL(s_, buf_); });
|
||||
}
|
||||
/// Write quoted if the string doesn't look like and identifier.
|
||||
void writeProbablyBackQuotedString(const StringRef & s, WriteBuffer & buf);
|
||||
void writeProbablyDoubleQuotedString(const StringRef & s, WriteBuffer & buf);
|
||||
void writeProbablyBackQuotedStringMySQL(const StringRef & s, WriteBuffer & buf);
|
||||
|
||||
|
||||
/** Outputs the string in for the CSV format.
|
||||
|
@ -601,18 +601,26 @@ bool ParserNullityChecking::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
||||
|
||||
bool ParserIntervalOperatorExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
/// If no INTERVAL keyword, go to nested parser.
|
||||
auto begin = pos;
|
||||
|
||||
/// If no INTERVAL keyword, go to the nested parser.
|
||||
if (!ParserKeyword("INTERVAL").ignore(pos, expected))
|
||||
return next_parser.parse(pos, node, expected);
|
||||
|
||||
ASTPtr expr;
|
||||
/// Any expression can be inside, because operator surrounds it.
|
||||
if (!ParserExpressionWithOptionalAlias(false).parse(pos, expr, expected))
|
||||
return false;
|
||||
{
|
||||
pos = begin;
|
||||
return next_parser.parse(pos, node, expected);
|
||||
}
|
||||
|
||||
IntervalKind interval_kind;
|
||||
if (!parseIntervalKind(pos, expected, interval_kind))
|
||||
return false;
|
||||
{
|
||||
pos = begin;
|
||||
return next_parser.parse(pos, node, expected);
|
||||
}
|
||||
|
||||
/// the function corresponding to the operator
|
||||
auto function = std::make_shared<ASTFunction>();
|
||||
|
@ -0,0 +1 @@
|
||||
2
|
@ -0,0 +1 @@
|
||||
SELECT (1 AS `interval`) + `interval`;
|
Loading…
Reference in New Issue
Block a user