mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +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);
|
const char * delimiter_or_end = find_first_symbols<symbols...>(pos, end);
|
||||||
|
|
||||||
if (!token_compress || pos < delimiter_or_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)
|
if (delimiter_or_end < end)
|
||||||
pos = delimiter_or_end + 1;
|
pos = delimiter_or_end + 1;
|
||||||
|
@ -122,6 +122,11 @@ inline bool isPrintableASCII(char c)
|
|||||||
return uc >= 32 && uc <= 126; /// 127 is ASCII DEL.
|
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.
|
/// Works assuming isAlphaASCII.
|
||||||
inline char toLowerIfAlphaASCII(char c)
|
inline char toLowerIfAlphaASCII(char c)
|
||||||
{
|
{
|
||||||
|
@ -68,22 +68,10 @@ void writeException(const Exception & e, WriteBuffer & buf, bool with_stack_trac
|
|||||||
template <typename F>
|
template <typename F>
|
||||||
static inline void writeProbablyQuotedStringImpl(const StringRef & s, WriteBuffer & buf, F && write_quoted_string)
|
static inline void writeProbablyQuotedStringImpl(const StringRef & s, WriteBuffer & buf, F && write_quoted_string)
|
||||||
{
|
{
|
||||||
if (!s.size || !isValidIdentifierBegin(s.data[0]))
|
if (isValidIdentifier(std::string_view{s}))
|
||||||
{
|
writeString(s, buf);
|
||||||
write_quoted_string(s, buf);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
write_quoted_string(s, buf);
|
||||||
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)
|
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
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/** SET query
|
/** SET query
|
||||||
*/
|
*/
|
||||||
class ASTSetQuery : public IAST
|
class ASTSetQuery : public IAST
|
||||||
@ -23,19 +22,7 @@ public:
|
|||||||
|
|
||||||
ASTPtr clone() const override { return std::make_shared<ASTSetQuery>(*this); }
|
ASTPtr clone() const override { return std::make_shared<ASTSetQuery>(*this); }
|
||||||
|
|
||||||
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override
|
void formatImpl(const FormatSettings & format, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <Parsers/ASTSettingsProfileElement.h>
|
#include <Parsers/ASTSettingsProfileElement.h>
|
||||||
|
#include <Parsers/formatSettingName.h>
|
||||||
#include <Common/FieldVisitors.h>
|
#include <Common/FieldVisitors.h>
|
||||||
#include <Common/quoteString.h>
|
#include <Common/quoteString.h>
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ void ASTSettingsProfileElement::formatImpl(const FormatSettings & settings, Form
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.ostr << setting_name;
|
formatSettingName(setting_name, settings.ostr);
|
||||||
|
|
||||||
if (!value.isNull())
|
if (!value.isNull())
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace DB
|
|||||||
/// Parse `name = value`.
|
/// Parse `name = value`.
|
||||||
bool ParserSetQuery::parseNameValuePair(SettingChange & change, IParser::Pos & pos, Expected & expected)
|
bool ParserSetQuery::parseNameValuePair(SettingChange & change, IParser::Pos & pos, Expected & expected)
|
||||||
{
|
{
|
||||||
ParserIdentifier name_p;
|
ParserCompoundIdentifier name_p;
|
||||||
ParserLiteral value_p;
|
ParserLiteral value_p;
|
||||||
ParserToken s_eq(TokenType::Equals);
|
ParserToken s_eq(TokenType::Equals);
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ namespace
|
|||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
ASTPtr name_ast;
|
ASTPtr name_ast;
|
||||||
if (!ParserIdentifier{}.parse(pos, name_ast, expected))
|
if (!ParserCompoundIdentifier{}.parse(pos, name_ast, expected))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
String res_setting_name = getIdentifierName(name_ast);
|
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
|
ASTSampleRatio.cpp
|
||||||
ASTSelectQuery.cpp
|
ASTSelectQuery.cpp
|
||||||
ASTSelectWithUnionQuery.cpp
|
ASTSelectWithUnionQuery.cpp
|
||||||
|
ASTSetQuery.cpp
|
||||||
ASTSetRoleQuery.cpp
|
ASTSetRoleQuery.cpp
|
||||||
ASTSettingsProfileElement.cpp
|
ASTSettingsProfileElement.cpp
|
||||||
ASTShowAccessEntitiesQuery.cpp
|
ASTShowAccessEntitiesQuery.cpp
|
||||||
@ -61,6 +62,7 @@ SRCS(
|
|||||||
ExpressionElementParsers.cpp
|
ExpressionElementParsers.cpp
|
||||||
ExpressionListParsers.cpp
|
ExpressionListParsers.cpp
|
||||||
formatAST.cpp
|
formatAST.cpp
|
||||||
|
formatSettingName.cpp
|
||||||
IAST.cpp
|
IAST.cpp
|
||||||
iostream_debug_helpers.cpp
|
iostream_debug_helpers.cpp
|
||||||
IParserBase.cpp
|
IParserBase.cpp
|
||||||
|
@ -15,3 +15,7 @@ custom_b NULL
|
|||||||
custom_c UInt64_50000
|
custom_c UInt64_50000
|
||||||
custom_d Float64_1.11
|
custom_d Float64_1.11
|
||||||
0 UInt8
|
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);
|
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.
|
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