mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Column declaration: [NOT] NULL right after type
+ fixed: data_type_default_nullable=true, it didn't make columns nullable if the column declaration contains default expression w/o type Issue #37229
This commit is contained in:
parent
bc145294a6
commit
838a6c6f61
@ -578,7 +578,12 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(
|
||||
if (col_decl.type)
|
||||
column.type = name_type_it->type;
|
||||
else
|
||||
{
|
||||
column.type = defaults_sample_block.getByName(column.name).type;
|
||||
/// set nullability for case of column declaration w/o type but with default expression
|
||||
if ((col_decl.null_modifier && *col_decl.null_modifier) || make_columns_nullable)
|
||||
column.type = makeNullable(column.type);
|
||||
}
|
||||
|
||||
column.default_desc.kind = columnDefaultKindFromString(col_decl.default_specifier);
|
||||
column.default_desc.expression = default_expr;
|
||||
|
@ -105,9 +105,9 @@ protected:
|
||||
|
||||
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||
|
||||
bool require_type = true;
|
||||
bool allow_null_modifiers = false;
|
||||
bool check_keywords_after_name = false;
|
||||
const bool require_type = true;
|
||||
const bool allow_null_modifiers = false;
|
||||
const bool check_keywords_after_name = false;
|
||||
/// just for ALTER TABLE ALTER COLUMN use
|
||||
bool check_type_keyword = false;
|
||||
};
|
||||
@ -175,7 +175,22 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
|
||||
ASTPtr ttl_expression;
|
||||
ASTPtr collation_expression;
|
||||
|
||||
if (!s_default.checkWithoutMoving(pos, expected)
|
||||
auto null_check_without_moving = [&]() -> bool
|
||||
{
|
||||
if (!allow_null_modifiers)
|
||||
return false;
|
||||
|
||||
if (s_null.checkWithoutMoving(pos, expected))
|
||||
return true;
|
||||
|
||||
Pos before_null = pos;
|
||||
bool res = s_not.check(pos, expected) && s_null.checkWithoutMoving(pos, expected);
|
||||
pos = before_null;
|
||||
return res;
|
||||
};
|
||||
|
||||
if (!null_check_without_moving()
|
||||
&& !s_default.checkWithoutMoving(pos, expected)
|
||||
&& !s_materialized.checkWithoutMoving(pos, expected)
|
||||
&& !s_ephemeral.checkWithoutMoving(pos, expected)
|
||||
&& !s_alias.checkWithoutMoving(pos, expected)
|
||||
@ -195,6 +210,18 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
|
||||
}
|
||||
}
|
||||
|
||||
if (allow_null_modifiers)
|
||||
{
|
||||
if (s_not.check(pos, expected))
|
||||
{
|
||||
if (!s_null.check(pos, expected))
|
||||
return false;
|
||||
null_modifier.emplace(false);
|
||||
}
|
||||
else if (s_null.check(pos, expected))
|
||||
null_modifier.emplace(true);
|
||||
}
|
||||
|
||||
Pos pos_before_specifier = pos;
|
||||
if (s_default.ignore(pos, expected) || s_materialized.ignore(pos, expected) || s_alias.ignore(pos, expected))
|
||||
{
|
||||
@ -230,7 +257,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
|
||||
if (require_type && !type && !default_expression)
|
||||
return false; /// reject column name without type
|
||||
|
||||
if (type && allow_null_modifiers)
|
||||
if ((type || default_expression) && allow_null_modifiers && !null_modifier.has_value())
|
||||
{
|
||||
if (s_not.ignore(pos, expected))
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
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)
|
||||
CREATE TABLE default.set_null\n(\n `a` Nullable(Int32),\n `b` Int32,\n `c` Nullable(Int32),\n `d` Nullable(Int32)\n)\nENGINE = Memory
|
||||
CREATE TABLE default.set_null\n(\n `a` Nullable(Int32),\n `b` Int32,\n `c` Nullable(Int32),\n `d` Nullable(Int32)\n)\nENGINE = Memory
|
||||
Nullable(Int32) Int32 Nullable(Int32) Nullable(Int32) Nullable(UInt8)
|
||||
CREATE TABLE default.set_null\n(\n `a` Nullable(Int32),\n `b` Int32,\n `c` Nullable(Int32),\n `d` Nullable(Int32),\n `f` Nullable(UInt8) DEFAULT 1\n)\nENGINE = Memory
|
||||
CREATE TABLE default.set_null\n(\n `a` Nullable(Int32),\n `b` Int32,\n `c` Nullable(Int32),\n `d` Nullable(Int32),\n `f` Nullable(UInt8) DEFAULT 1\n)\nENGINE = Memory
|
||||
CREATE TABLE default.cannot_be_nullable\n(\n `n` Nullable(Int8),\n `a` Array(UInt8)\n)\nENGINE = Memory
|
||||
CREATE TABLE default.cannot_be_nullable\n(\n `n` Nullable(Int8),\n `a` Array(UInt8)\n)\nENGINE = Memory
|
||||
|
@ -39,13 +39,14 @@ CREATE TABLE set_null (
|
||||
a INT NULL,
|
||||
b INT NOT NULL,
|
||||
c Nullable(INT),
|
||||
d INT
|
||||
d INT,
|
||||
f DEFAULT 1
|
||||
) engine=Memory();
|
||||
|
||||
|
||||
INSERT INTO set_null VALUES (NULL, 2, NULL, NULL);
|
||||
INSERT INTO set_null VALUES (NULL, 2, NULL, NULL, NULL);
|
||||
|
||||
SELECT toTypeName(a), toTypeName(b), toTypeName(c), toTypeName(d) FROM set_null;
|
||||
SELECT toTypeName(a), toTypeName(b), toTypeName(c), toTypeName(d), toTypeName(f) FROM set_null;
|
||||
|
||||
SHOW CREATE TABLE set_null;
|
||||
DETACH TABLE set_null;
|
||||
|
@ -0,0 +1,22 @@
|
||||
create table, column +type +NULL
|
||||
id Nullable(Int32)
|
||||
create table, column +type +NOT NULL
|
||||
id Int32
|
||||
create table, column +type +NULL +DEFAULT
|
||||
id Nullable(Int32) DEFAULT 1
|
||||
create table, column +type +NOT NULL +DEFAULT
|
||||
id Int32 DEFAULT 1
|
||||
create table, column +type +DEFAULT +NULL
|
||||
id Nullable(Int32) DEFAULT 1
|
||||
create table, column +type +DEFAULT +NOT NULL
|
||||
id Int32 DEFAULT 1
|
||||
create table, column -type +NULL +DEFAULT
|
||||
id Nullable(UInt8) DEFAULT 1
|
||||
create table, column -type +NOT NULL +DEFAULT
|
||||
id UInt8 DEFAULT 1
|
||||
create table, column -type +DEFAULT +NULL
|
||||
id Nullable(UInt8) DEFAULT 1
|
||||
create table, column -type +DEFAULT +NOT NULL
|
||||
id UInt8 DEFAULT 1
|
||||
alter column, NULL modifier is not allowed
|
||||
modify column, NULL modifier is not allowed
|
@ -0,0 +1,61 @@
|
||||
select 'create table, column +type +NULL';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column +type +NOT NULL';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT NOT NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column +type +NULL +DEFAULT';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT NULL DEFAULT 1) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column +type +NOT NULL +DEFAULT';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT NOT NULL DEFAULT 1) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column +type +DEFAULT +NULL';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT DEFAULT 1 NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column +type +DEFAULT +NOT NULL';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT DEFAULT 1 NOT NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column -type +NULL +DEFAULT';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id NULL DEFAULT 1) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column -type +NOT NULL +DEFAULT';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id NOT NULL DEFAULT 1) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column -type +DEFAULT +NULL';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id DEFAULT 1 NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'create table, column -type +DEFAULT +NOT NULL';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id DEFAULT 1 NOT NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
DESCRIBE TABLE null_before;
|
||||
|
||||
select 'alter column, NULL modifier is not allowed';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT NOT NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
ALTER TABLE null_before ALTER COLUMN id TYPE INT NULL; -- { clientError SYNTAX_ERROR }
|
||||
|
||||
select 'modify column, NULL modifier is not allowed';
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
||||
CREATE TABLE null_before (id INT NOT NULL) ENGINE=MergeTree() ORDER BY tuple();
|
||||
ALTER TABLE null_before MODIFY COLUMN id NULL DEFAULT 1; -- { serverError UNKNOWN_TYPE }
|
||||
|
||||
DROP TABLE IF EXISTS null_before SYNC;
|
Loading…
Reference in New Issue
Block a user