mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Merge pull request #13496 from vitlibar/compound-identifiers-for-custom-settings
Support compound identifiers for custom settings.
This commit is contained in:
commit
2e6ba2a05d
@ -308,7 +308,7 @@ inline void splitInto(To & to, const std::string & what, bool token_compress = f
|
||||
const char * delimiter_or_end = find_first_symbols<symbols...>(pos, end);
|
||||
|
||||
if (!token_compress || pos < delimiter_or_end)
|
||||
to.emplace_back(pos, delimiter_or_end);
|
||||
to.emplace_back(pos, delimiter_or_end - pos);
|
||||
|
||||
if (delimiter_or_end < end)
|
||||
pos = delimiter_or_end + 1;
|
||||
|
@ -122,6 +122,11 @@ inline bool isPrintableASCII(char c)
|
||||
return uc >= 32 && uc <= 126; /// 127 is ASCII DEL.
|
||||
}
|
||||
|
||||
inline bool isValidIdentifier(const std::string_view & str)
|
||||
{
|
||||
return !str.empty() && isValidIdentifierBegin(str[0]) && std::all_of(str.begin() + 1, str.end(), isWordCharASCII);
|
||||
}
|
||||
|
||||
/// Works assuming isAlphaASCII.
|
||||
inline char toLowerIfAlphaASCII(char c)
|
||||
{
|
||||
|
@ -68,22 +68,10 @@ void writeException(const Exception & e, WriteBuffer & buf, bool with_stack_trac
|
||||
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);
|
||||
}
|
||||
if (isValidIdentifier(std::string_view{s}))
|
||||
writeString(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);
|
||||
}
|
||||
write_quoted_string(s, buf);
|
||||
}
|
||||
|
||||
void writeProbablyBackQuotedString(const StringRef & s, WriteBuffer & buf)
|
||||
|
22
src/Parsers/ASTSetQuery.cpp
Normal file
22
src/Parsers/ASTSetQuery.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <Parsers/ASTSetQuery.h>
|
||||
#include <Parsers/formatSettingName.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
void ASTSetQuery::formatImpl(const FormatSettings & format, FormatState &, FormatStateStacked) const
|
||||
{
|
||||
if (is_standalone)
|
||||
format.ostr << (format.hilite ? hilite_keyword : "") << "SET " << (format.hilite ? hilite_none : "");
|
||||
|
||||
for (auto it = changes.begin(); it != changes.end(); ++it)
|
||||
{
|
||||
if (it != changes.begin())
|
||||
format.ostr << ", ";
|
||||
|
||||
formatSettingName(it->name, format.ostr);
|
||||
format.ostr << " = " << applyVisitor(FieldVisitorToString(), it->value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
||||
/** SET query
|
||||
*/
|
||||
class ASTSetQuery : public IAST
|
||||
@ -23,19 +22,7 @@ public:
|
||||
|
||||
ASTPtr clone() const override { return std::make_shared<ASTSetQuery>(*this); }
|
||||
|
||||
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override
|
||||
{
|
||||
if (is_standalone)
|
||||
settings.ostr << (settings.hilite ? hilite_keyword : "") << "SET " << (settings.hilite ? hilite_none : "");
|
||||
|
||||
for (auto it = changes.begin(); it != changes.end(); ++it)
|
||||
{
|
||||
if (it != changes.begin())
|
||||
settings.ostr << ", ";
|
||||
|
||||
settings.ostr << it->name << " = " << applyVisitor(FieldVisitorToString(), it->value);
|
||||
}
|
||||
}
|
||||
void formatImpl(const FormatSettings & format, FormatState &, FormatStateStacked) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <Parsers/ASTSettingsProfileElement.h>
|
||||
#include <Parsers/formatSettingName.h>
|
||||
#include <Common/FieldVisitors.h>
|
||||
#include <Common/quoteString.h>
|
||||
|
||||
@ -31,7 +32,7 @@ void ASTSettingsProfileElement::formatImpl(const FormatSettings & settings, Form
|
||||
return;
|
||||
}
|
||||
|
||||
settings.ostr << setting_name;
|
||||
formatSettingName(setting_name, settings.ostr);
|
||||
|
||||
if (!value.isNull())
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ namespace DB
|
||||
/// Parse `name = value`.
|
||||
bool ParserSetQuery::parseNameValuePair(SettingChange & change, IParser::Pos & pos, Expected & expected)
|
||||
{
|
||||
ParserIdentifier name_p;
|
||||
ParserCompoundIdentifier name_p;
|
||||
ParserLiteral value_p;
|
||||
ParserToken s_eq(TokenType::Equals);
|
||||
|
||||
|
@ -118,7 +118,7 @@ namespace
|
||||
return IParserBase::wrapParseImpl(pos, [&]
|
||||
{
|
||||
ASTPtr name_ast;
|
||||
if (!ParserIdentifier{}.parse(pos, name_ast, expected))
|
||||
if (!ParserCompoundIdentifier{}.parse(pos, name_ast, expected))
|
||||
return false;
|
||||
|
||||
String res_setting_name = getIdentifierName(name_ast);
|
||||
|
36
src/Parsers/formatSettingName.cpp
Normal file
36
src/Parsers/formatSettingName.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include <Parsers/formatSettingName.h>
|
||||
#include <Common/StringUtils/StringUtils.h>
|
||||
#include <Common/quoteString.h>
|
||||
#include <common/find_symbols.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void formatSettingName(const String & setting_name, std::ostream & out)
|
||||
{
|
||||
if (isValidIdentifier(setting_name))
|
||||
{
|
||||
out << setting_name;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string_view> parts;
|
||||
splitInto<'.'>(parts, setting_name);
|
||||
bool all_parts_are_identifiers = std::all_of(parts.begin(), parts.end(), isValidIdentifier);
|
||||
if (all_parts_are_identifiers && !parts.empty())
|
||||
{
|
||||
bool need_dot = false;
|
||||
for (const auto & part : parts)
|
||||
{
|
||||
if (std::exchange(need_dot, true))
|
||||
out << ".";
|
||||
out << part;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
out << backQuote(setting_name);
|
||||
}
|
||||
|
||||
}
|
14
src/Parsers/formatSettingName.h
Normal file
14
src/Parsers/formatSettingName.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Types.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// Outputs built-in or custom setting's name.
|
||||
/// The function is like backQuoteIfNeed() but didn't quote with backticks
|
||||
/// if the name consists of identifiers joined with dots.
|
||||
void formatSettingName(const String & setting_name, std::ostream & out);
|
||||
|
||||
}
|
@ -44,6 +44,7 @@ SRCS(
|
||||
ASTSampleRatio.cpp
|
||||
ASTSelectQuery.cpp
|
||||
ASTSelectWithUnionQuery.cpp
|
||||
ASTSetQuery.cpp
|
||||
ASTSetRoleQuery.cpp
|
||||
ASTSettingsProfileElement.cpp
|
||||
ASTShowAccessEntitiesQuery.cpp
|
||||
@ -61,6 +62,7 @@ SRCS(
|
||||
ExpressionElementParsers.cpp
|
||||
ExpressionListParsers.cpp
|
||||
formatAST.cpp
|
||||
formatSettingName.cpp
|
||||
IAST.cpp
|
||||
iostream_debug_helpers.cpp
|
||||
IParserBase.cpp
|
||||
|
@ -15,3 +15,7 @@ custom_b NULL
|
||||
custom_c UInt64_50000
|
||||
custom_d Float64_1.11
|
||||
0 UInt8
|
||||
|
||||
test String
|
||||
custom_compound.identifier.v1 \'test\'
|
||||
CREATE SETTINGS PROFILE s1_01418 SETTINGS custom_compound.identifier.v2 = 100
|
||||
|
@ -23,3 +23,12 @@ SET custom_e = 0;
|
||||
SELECT getSetting('custom_e') as v, toTypeName(v);
|
||||
|
||||
SET invalid_custom = 8; -- { serverError 115 } -- Setting is neither a builtin nor started with one of the registered prefixes for user-defined settings.
|
||||
|
||||
SELECT '';
|
||||
SET custom_compound.identifier.v1 = 'test';
|
||||
SELECT getSetting('custom_compound.identifier.v1') as v, toTypeName(v);
|
||||
SELECT name, value FROM system.settings WHERE name = 'custom_compound.identifier.v1';
|
||||
|
||||
CREATE SETTINGS PROFILE s1_01418 SETTINGS custom_compound.identifier.v2 = 100;
|
||||
SHOW CREATE SETTINGS PROFILE s1_01418;
|
||||
DROP SETTINGS PROFILE s1_01418;
|
||||
|
Loading…
Reference in New Issue
Block a user