Now layout type for dictionaries DDL with no arguments can be written without brackets

This commit is contained in:
alesapin 2020-04-06 14:02:17 +03:00
parent 110eb599c1
commit 848678d656
9 changed files with 88 additions and 12 deletions

View File

@ -24,6 +24,7 @@ void ASTDictionaryRange::formatImpl(const FormatSettings & settings,
<< "(" << "("
<< (settings.hilite ? hilite_keyword : "") << (settings.hilite ? hilite_keyword : "")
<< "MIN " << "MIN "
<< (settings.hilite ? hilite_none : "")
<< min_attr_name << " " << min_attr_name << " "
<< (settings.hilite ? hilite_keyword : "") << (settings.hilite ? hilite_keyword : "")
<< "MAX " << "MAX "
@ -52,6 +53,7 @@ void ASTDictionaryLifetime::formatImpl(const FormatSettings & settings,
<< "(" << "("
<< (settings.hilite ? hilite_keyword : "") << (settings.hilite ? hilite_keyword : "")
<< "MIN " << "MIN "
<< (settings.hilite ? hilite_none : "")
<< min_sec << " " << min_sec << " "
<< (settings.hilite ? hilite_keyword : "") << (settings.hilite ? hilite_keyword : "")
<< "MAX " << "MAX "
@ -86,7 +88,9 @@ void ASTDictionaryLayout::formatImpl(const FormatSettings & settings,
<< Poco::toUpper(layout_type) << Poco::toUpper(layout_type)
<< (settings.hilite ? hilite_none : ""); << (settings.hilite ? hilite_none : "");
if (has_brackets)
settings.ostr << "("; settings.ostr << "(";
if (parameter) if (parameter)
{ {
settings.ostr << (settings.hilite ? hilite_keyword : "") settings.ostr << (settings.hilite ? hilite_keyword : "")
@ -96,7 +100,10 @@ void ASTDictionaryLayout::formatImpl(const FormatSettings & settings,
parameter->second->formatImpl(settings, state, frame); parameter->second->formatImpl(settings, state, frame);
} }
if (has_brackets)
settings.ostr << ")"; settings.ostr << ")";
settings.ostr << ")"; settings.ostr << ")";
} }

View File

@ -33,6 +33,8 @@ public:
String layout_type; String layout_type;
/// optional parameter (size_in_cells) /// optional parameter (size_in_cells)
std::optional<KeyValue> parameter; std::optional<KeyValue> parameter;
/// has brackets after layout type
bool has_brackets = true;
String getID(char) const override { return "Dictionary layout"; } String getID(char) const override { return "Dictionary layout"; }

View File

@ -64,9 +64,9 @@ ASTPtr ASTFunctionWithKeyValueArguments::clone() const
void ASTFunctionWithKeyValueArguments::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const void ASTFunctionWithKeyValueArguments::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{ {
settings.ostr << (settings.hilite ? hilite_keyword : "") << Poco::toUpper(name) << (settings.hilite ? hilite_none : "") << "("; settings.ostr << (settings.hilite ? hilite_keyword : "") << Poco::toUpper(name) << (settings.hilite ? hilite_none : "") << (has_brackets ? "(" : "");
elements->formatImpl(settings, state, frame); elements->formatImpl(settings, state, frame);
settings.ostr << ")"; settings.ostr << (has_brackets ? ")" : "");
settings.ostr << (settings.hilite ? hilite_none : ""); settings.ostr << (settings.hilite ? hilite_none : "");
} }

View File

@ -44,6 +44,13 @@ public:
String name; String name;
/// Expression list /// Expression list
ASTPtr elements; ASTPtr elements;
/// Has brackets around arguments
bool has_brackets;
ASTFunctionWithKeyValueArguments(bool has_brackets_ = true)
: has_brackets(has_brackets_)
{
}
public: public:
String getID(char delim) const override; String getID(char delim) const override;

View File

@ -1400,18 +1400,30 @@ bool ParserFunctionWithKeyValueArguments::parseImpl(Pos & pos, ASTPtr & node, Ex
if (!id_parser.parse(pos, identifier, expected)) if (!id_parser.parse(pos, identifier, expected))
return false; return false;
if (pos.get().type != TokenType::OpeningRoundBracket)
return false;
bool left_bracket_found = false;
if (pos.get().type != TokenType::OpeningRoundBracket)
{
if (!brackets_can_be_omitted)
return false;
}
else
{
++pos; ++pos;
left_bracket_found = true;
}
if (!pairs_list_parser.parse(pos, expr_list_args, expected)) if (!pairs_list_parser.parse(pos, expr_list_args, expected))
return false; return false;
if (left_bracket_found)
{
if (pos.get().type != TokenType::ClosingRoundBracket) if (pos.get().type != TokenType::ClosingRoundBracket)
return false; return false;
++pos; ++pos;
auto function = std::make_shared<ASTFunctionWithKeyValueArguments>(); }
auto function = std::make_shared<ASTFunctionWithKeyValueArguments>(left_bracket_found);
function->name = Poco::toLower(typeid_cast<ASTIdentifier &>(*identifier.get()).name); function->name = Poco::toLower(typeid_cast<ASTIdentifier &>(*identifier.get()).name);
function->elements = expr_list_args; function->elements = expr_list_args;
function->children.push_back(function->elements); function->children.push_back(function->elements);

View File

@ -346,9 +346,16 @@ protected:
*/ */
class ParserFunctionWithKeyValueArguments : public IParserBase class ParserFunctionWithKeyValueArguments : public IParserBase
{ {
public:
ParserFunctionWithKeyValueArguments(bool brackets_can_be_omitted_ = false)
: brackets_can_be_omitted(brackets_can_be_omitted_) {}
protected: protected:
const char * getName() const override { return "function with key-value arguments"; } const char * getName() const override { return "function with key-value arguments"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override; bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
/// brackets for function arguments can be omitted
bool brackets_can_be_omitted;
}; };
/** Data type or table engine, possibly with parameters. For example, UInt8 or see examples from ParserIdentifierWithParameters /** Data type or table engine, possibly with parameters. For example, UInt8 or see examples from ParserIdentifierWithParameters

View File

@ -109,7 +109,7 @@ bool ParserDictionaryRange::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
bool ParserDictionaryLayout::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) bool ParserDictionaryLayout::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{ {
ParserFunctionWithKeyValueArguments key_value_func_p; ParserFunctionWithKeyValueArguments key_value_func_p(/* brackets_can_be_omitted = */ true);
ASTPtr ast_func; ASTPtr ast_func;
if (!key_value_func_p.parse(pos, ast_func, expected)) if (!key_value_func_p.parse(pos, ast_func, expected))
return false; return false;
@ -121,12 +121,17 @@ bool ParserDictionaryLayout::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
return false; return false;
res->layout_type = func.name; res->layout_type = func.name;
res->has_brackets = func.has_brackets;
const ASTExpressionList & type_expr_list = func.elements->as<const ASTExpressionList &>(); const ASTExpressionList & type_expr_list = func.elements->as<const ASTExpressionList &>();
/// there are no layout with more than 1 parameter /// there are no layout with more than 1 parameter
if (type_expr_list.children.size() > 1) if (type_expr_list.children.size() > 1)
return false; return false;
/// if layout has params than brackets must be specified
if (type_expr_list.children.size() != 0 && !res->has_brackets)
return false;
if (type_expr_list.children.size() == 1) if (type_expr_list.children.size() == 1)
{ {
const ASTPair * pair = dynamic_cast<const ASTPair *>(type_expr_list.children.at(0).get()); const ASTPair * pair = dynamic_cast<const ASTPair *>(type_expr_list.children.at(0).get());

View File

@ -0,0 +1,3 @@
World
CREATE DICTIONARY db_for_dict.dict_with_hashed_layout (`key1` UInt64, `value` String) PRIMARY KEY key1 SOURCE(CLICKHOUSE(HOST \'localhost\' PORT 9000 USER \'default\' TABLE \'table_for_dict\' DB \'db_for_dict\')) LIFETIME(MIN 1 MAX 10) LAYOUT(HASHED)
Hello

View File

@ -0,0 +1,33 @@
DROP DATABASE IF EXISTS db_for_dict;
CREATE DATABASE db_for_dict;
CREATE TABLE db_for_dict.table_for_dict
(
key1 UInt64,
value String
)
ENGINE = Memory();
INSERT INTO db_for_dict.table_for_dict VALUES (1, 'Hello'), (2, 'World');
CREATE DICTIONARY db_for_dict.dict_with_hashed_layout
(
key1 UInt64,
value String
)
PRIMARY KEY key1
LAYOUT(HASHED)
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'table_for_dict' DB 'db_for_dict'))
LIFETIME(MIN 1 MAX 10);
SELECT dictGet('db_for_dict.dict_with_hashed_layout', 'value', toUInt64(2));
DETACH DICTIONARY db_for_dict.dict_with_hashed_layout;
ATTACH DICTIONARY db_for_dict.dict_with_hashed_layout;
SHOW CREATE DICTIONARY db_for_dict.dict_with_hashed_layout;
SELECT dictGet('db_for_dict.dict_with_hashed_layout', 'value', toUInt64(1));
DROP DATABASE IF EXISTS db_for_dict;