This commit is contained in:
Alexander Tokmakov 2020-06-14 19:17:22 +03:00
parent 5f9739fbf9
commit 6a439a5eb5
8 changed files with 39 additions and 68 deletions

View File

@ -287,29 +287,23 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(
const auto & col_decl = ast->as<ASTColumnDeclaration &>(); const auto & col_decl = ast->as<ASTColumnDeclaration &>();
DataTypePtr column_type = nullptr; DataTypePtr column_type = nullptr;
if (!col_decl.is_null && col_decl.is_not)
throw Exception{"Cant use NOT without NULL", ErrorCodes::ILLEGAL_SYNTAX_FOR_DATA_TYPE};
if (col_decl.type) if (col_decl.type)
{ {
column_type = DataTypeFactory::instance().get(col_decl.type); column_type = DataTypeFactory::instance().get(col_decl.type);
if (col_decl.is_not && col_decl.is_null) if (col_decl.null_modifier)
{ {
if (column_type->isNullable()) if (column_type->isNullable())
throw Exception{"Cant use NOT NULL with Nullable", ErrorCodes::ILLEGAL_SYNTAX_FOR_DATA_TYPE}; throw Exception("Cant use [NOT] NULL modifier with Nullable type", ErrorCodes::ILLEGAL_SYNTAX_FOR_DATA_TYPE);
if (*col_decl.null_modifier)
column_type = makeNullable(column_type);
} }
else if (col_decl.is_null && !col_decl.is_not) else if (context.getSettingsRef().data_type_default_nullable)
{ {
if (column_type->isNullable())
throw Exception{"Cant use NULL with Nullable", ErrorCodes::ILLEGAL_SYNTAX_FOR_DATA_TYPE};
else
column_type = makeNullable(column_type); column_type = makeNullable(column_type);
} }
if (context.getSettingsRef().data_type_default_nullable && !column_type->isNullable() && !col_decl.is_not && !col_decl.is_null)
column_type = makeNullable(column_type);
column_names_and_types.emplace_back(col_decl.name, column_type); column_names_and_types.emplace_back(col_decl.name, column_type);
} }
else else

View File

@ -18,18 +18,6 @@ ASTPtr ASTColumnDeclaration::clone() const
res->children.push_back(res->type); res->children.push_back(res->type);
} }
if (is_null)
{
res->is_null = is_null;
res->children.push_back(res->is_null);
}
if (is_not)
{
res->is_not = is_not;
res->children.push_back(res->is_not);
}
if (default_expression) if (default_expression)
{ {
res->default_expression = default_expression->clone(); res->default_expression = default_expression->clone();
@ -73,16 +61,10 @@ void ASTColumnDeclaration::formatImpl(const FormatSettings & settings, FormatSta
type->formatImpl(settings, state, frame); type->formatImpl(settings, state, frame);
} }
if (is_not) if (null_modifier)
{ {
settings.ostr << ' '; settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "")
is_not->formatImpl(settings, state, frame); << (*null_modifier ? "" : "NOT ") << "NULL" << (settings.hilite ? hilite_none : "");
}
if (is_null)
{
settings.ostr << ' ';
is_null->formatImpl(settings, state, frame);
} }
if (default_expression) if (default_expression)

View File

@ -13,8 +13,7 @@ class ASTColumnDeclaration : public IAST
public: public:
String name; String name;
ASTPtr type; ASTPtr type;
ASTPtr is_null; std::optional<bool> null_modifier;
ASTPtr is_not;
String default_specifier; String default_specifier;
ASTPtr default_expression; ASTPtr default_expression;
ASTPtr comment; ASTPtr comment;

View File

@ -157,7 +157,7 @@ bool ParserTablePropertyDeclaration::parseImpl(Pos & pos, ASTPtr & node, Expecte
ParserIndexDeclaration index_p; ParserIndexDeclaration index_p;
ParserConstraintDeclaration constraint_p; ParserConstraintDeclaration constraint_p;
ParserColumnDeclaration column_p; ParserColumnDeclaration column_p{true, true};
ASTPtr new_node = nullptr; ASTPtr new_node = nullptr;

View File

@ -92,7 +92,8 @@ template <typename NameParser>
class IParserColumnDeclaration : public IParserBase class IParserColumnDeclaration : public IParserBase
{ {
public: public:
explicit IParserColumnDeclaration(bool require_type_ = true) : require_type(require_type_) explicit IParserColumnDeclaration(bool require_type_ = true, bool allow_null_modifiers_ = false)
: require_type(require_type_), allow_null_modifiers(allow_null_modifiers_)
{ {
} }
@ -104,6 +105,7 @@ protected:
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override; bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
bool require_type = true; bool require_type = true;
bool allow_null_modifiers = false;
}; };
using ParserColumnDeclaration = IParserColumnDeclaration<ParserIdentifier>; using ParserColumnDeclaration = IParserColumnDeclaration<ParserIdentifier>;
@ -126,8 +128,6 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
ParserStringLiteral string_literal_parser; ParserStringLiteral string_literal_parser;
ParserCodec codec_parser; ParserCodec codec_parser;
ParserExpression expression_parser; ParserExpression expression_parser;
ParserIdentifier null_parser;
ParserCompoundIdentifier not_null_parser;
/// mandatory column name /// mandatory column name
ASTPtr name; ASTPtr name;
@ -139,8 +139,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
*/ */
ASTPtr type; ASTPtr type;
String default_specifier; String default_specifier;
ASTPtr is_null; std::optional<bool> null_modifier;
ASTPtr is_not;
ASTPtr default_expression; ASTPtr default_expression;
ASTPtr comment_expression; ASTPtr comment_expression;
ASTPtr codec_expression; ASTPtr codec_expression;
@ -169,19 +168,17 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
if (require_type && !type && !default_expression) if (require_type && !type && !default_expression)
return false; /// reject column name without type return false; /// reject column name without type
// Pos pos_before_null = pos; if (type && allow_null_modifiers)
if (s_not.check(pos, expected))
if (s_null.check(pos, expected))
{ {
is_not = std::make_shared<ASTIdentifier>("NOT"); if (s_not.ignore(pos, expected))
is_null = std::make_shared<ASTIdentifier>("NULL"); {
} if (!s_null.ignore(pos, expected))
else
return false; return false;
else null_modifier.emplace(false);
if (s_null.check(pos, expected)) }
is_null = std::make_shared<ASTIdentifier>("NULL"); else if (s_null.ignore(pos, expected))
null_modifier.emplace(true);
}
if (s_comment.ignore(pos, expected)) if (s_comment.ignore(pos, expected))
{ {
@ -212,17 +209,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
column_declaration->children.push_back(std::move(type)); column_declaration->children.push_back(std::move(type));
} }
if (is_null) column_declaration->null_modifier = null_modifier;
{
column_declaration->is_null = is_null;
column_declaration->children.push_back(std::move(is_null));
}
if (is_not)
{
column_declaration->is_not = is_not;
column_declaration->children.push_back(std::move(is_not));
}
if (default_expression) if (default_expression)
{ {

View File

@ -1 +0,0 @@
Nullable(Int32) Int32 Nullable(Int32)

View File

@ -1,2 +1,4 @@
Nullable(Int32) Int32 Nullable(Int32) Int32 Nullable(Int32) Int32 Nullable(Int32) Int32
CREATE TABLE default.data_null\n(\n `a` Nullable(Int32), \n `b` Int32, \n `c` Nullable(Int32), \n `d` Int32\n)\nENGINE = Memory()
Nullable(Int32) Int32 Nullable(Int32) Nullable(Int32) Nullable(Int32) Int32 Nullable(Int32) Nullable(Int32)
CREATE TABLE default.set_null\n(\n `a` Nullable(Int32), \n `b` Int32, \n `c` Nullable(Int32), \n `d` Nullable(Int32)\n)\nENGINE = Memory()

View File

@ -1,6 +1,8 @@
DROP TABLE IF EXISTS data_null; DROP TABLE IF EXISTS data_null;
DROP TABLE IF EXISTS set_null; DROP TABLE IF EXISTS set_null;
SET data_type_default_nullable='false';
CREATE TABLE data_null ( CREATE TABLE data_null (
a INT NULL, a INT NULL,
b INT NOT NULL, b INT NOT NULL,
@ -9,19 +11,20 @@ CREATE TABLE data_null (
) engine=Memory(); ) engine=Memory();
INSERT INTO data_null VALUES (1, 2, 3, 4); INSERT INTO data_null VALUES (NULL, 2, NULL, 4);
SELECT toTypeName(a), toTypeName(b), toTypeName(c), toTypeName(d) FROM data_null; SELECT toTypeName(a), toTypeName(b), toTypeName(c), toTypeName(d) FROM data_null;
SHOW CREATE TABLE data_null;
CREATE TABLE data_null ( CREATE TABLE data_null_error (
a Nullable(INT) NULL, a Nullable(INT) NULL,
b INT NOT NULL, b INT NOT NULL,
c Nullable(INT) c Nullable(INT)
) engine=Memory(); --{serverError 377} ) engine=Memory(); --{serverError 377}
CREATE TABLE data_null ( CREATE TABLE data_null_error (
a INT NULL, a INT NULL,
b Nullable(INT) NOT NULL, b Nullable(INT) NOT NULL,
c Nullable(INT) c Nullable(INT)
@ -37,6 +40,11 @@ CREATE TABLE set_null (
) engine=Memory(); ) engine=Memory();
INSERT INTO set_null VALUES (1, 2, 3, 4); INSERT INTO set_null VALUES (NULL, 2, NULL, NULL);
SELECT toTypeName(a), toTypeName(b), toTypeName(c), toTypeName(d) FROM set_null; SELECT toTypeName(a), toTypeName(b), toTypeName(c), toTypeName(d) FROM set_null;
SHOW CREATE TABLE set_null;
DROP TABLE data_null;
DROP TABLE set_null;