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

View File

@ -33,6 +33,8 @@ public:
String layout_type;
/// optional parameter (size_in_cells)
std::optional<KeyValue> parameter;
/// has brackets after layout type
bool has_brackets = true;
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
{
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);
settings.ostr << ")";
settings.ostr << (has_brackets ? ")" : "");
settings.ostr << (settings.hilite ? hilite_none : "");
}

View File

@ -44,6 +44,13 @@ public:
String name;
/// Expression list
ASTPtr elements;
/// Has brackets around arguments
bool has_brackets;
ASTFunctionWithKeyValueArguments(bool has_brackets_ = true)
: has_brackets(has_brackets_)
{
}
public:
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))
return false;
if (pos.get().type != TokenType::OpeningRoundBracket)
return false;
++pos;
bool left_bracket_found = false;
if (pos.get().type != TokenType::OpeningRoundBracket)
{
if (!brackets_can_be_omitted)
return false;
}
else
{
++pos;
left_bracket_found = true;
}
if (!pairs_list_parser.parse(pos, expr_list_args, expected))
return false;
if (pos.get().type != TokenType::ClosingRoundBracket)
return false;
if (left_bracket_found)
{
if (pos.get().type != TokenType::ClosingRoundBracket)
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->elements = expr_list_args;
function->children.push_back(function->elements);

View File

@ -346,9 +346,16 @@ protected:
*/
class ParserFunctionWithKeyValueArguments : public IParserBase
{
public:
ParserFunctionWithKeyValueArguments(bool brackets_can_be_omitted_ = false)
: brackets_can_be_omitted(brackets_can_be_omitted_) {}
protected:
const char * getName() const override { return "function with key-value arguments"; }
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

View File

@ -109,7 +109,7 @@ bool ParserDictionaryRange::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
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;
if (!key_value_func_p.parse(pos, ast_func, expected))
return false;
@ -121,12 +121,17 @@ bool ParserDictionaryLayout::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
return false;
res->layout_type = func.name;
res->has_brackets = func.has_brackets;
const ASTExpressionList & type_expr_list = func.elements->as<const ASTExpressionList &>();
/// there are no layout with more than 1 parameter
if (type_expr_list.children.size() > 1)
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)
{
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;