mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 18:12:02 +00:00
Merge pull request #35706 from yakov-olkhovskiy/ephemeral-35641
Allow EPHEMERAL without explicit default expression
This commit is contained in:
commit
38993f215f
@ -114,9 +114,9 @@ In addition, this column is not substituted when using an asterisk in a SELECT q
|
||||
|
||||
### EPHEMERAL {#ephemeral}
|
||||
|
||||
`EPHEMERAL expr`
|
||||
`EPHEMERAL [expr]`
|
||||
|
||||
Ephemeral column. Such a column isn't stored in the table and cannot be SELECTed, but can be referenced in the defaults of CREATE statement.
|
||||
Ephemeral column. Such a column isn't stored in the table and cannot be SELECTed, but can be referenced in the defaults of CREATE statement. If `expr` is omitted type for column is required.
|
||||
INSERT without list of columns will skip such column, so SELECT/INSERT invariant is preserved - the dump obtained using `SELECT *` can be inserted back into the table using INSERT without specifying the list of columns.
|
||||
|
||||
### ALIAS {#alias}
|
||||
|
@ -110,9 +110,9 @@ SELECT x, toTypeName(x) FROM t1;
|
||||
|
||||
### EPHEMERAL {#ephemeral}
|
||||
|
||||
`EPHEMERAL expr`
|
||||
`EPHEMERAL [expr]`
|
||||
|
||||
Эфемерное выражение. Такой столбец не хранится в таблице и не может быть получен в запросе SELECT, но на него можно ссылаться в выражениях по умолчанию запроса CREATE.
|
||||
Эфемерное выражение. Такой столбец не хранится в таблице и не может быть получен в запросе SELECT, но на него можно ссылаться в выражениях по умолчанию запроса CREATE. Если значение по умолчанию `expr` не указано, то тип колонки должен быть специфицирован.
|
||||
INSERT без списка столбцов игнорирует этот столбец, таким образом сохраняется инвариант - т.е. дамп, полученный путём `SELECT *`, можно вставить обратно в таблицу INSERT-ом без указания списка столбцов.
|
||||
|
||||
### ALIAS {#alias}
|
||||
|
@ -508,7 +508,9 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(
|
||||
|
||||
default_expr_list->children.emplace_back(
|
||||
setAlias(
|
||||
col_decl.default_expression->clone(),
|
||||
col_decl.default_specifier == "EPHEMERAL" ? /// can be ASTLiteral::value NULL
|
||||
std::make_shared<ASTLiteral>(data_type_ptr->getDefault()) :
|
||||
col_decl.default_expression->clone(),
|
||||
tmp_column_name));
|
||||
}
|
||||
else
|
||||
@ -536,7 +538,11 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(
|
||||
|
||||
if (col_decl.default_expression)
|
||||
{
|
||||
ASTPtr default_expr = col_decl.default_expression->clone();
|
||||
ASTPtr default_expr =
|
||||
col_decl.default_specifier == "EPHEMERAL" && col_decl.default_expression->as<ASTLiteral>()->value.isNull() ?
|
||||
std::make_shared<ASTLiteral>(DataTypeFactory::instance().get(col_decl.type)->getDefault()) :
|
||||
col_decl.default_expression->clone();
|
||||
|
||||
if (col_decl.type)
|
||||
column.type = name_type_it->type;
|
||||
else
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <Parsers/ASTColumnDeclaration.h>
|
||||
#include <Common/quoteString.h>
|
||||
#include <IO/Operators.h>
|
||||
#include <Parsers/ASTLiteral.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -71,8 +72,12 @@ void ASTColumnDeclaration::formatImpl(const FormatSettings & settings, FormatSta
|
||||
|
||||
if (default_expression)
|
||||
{
|
||||
settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "") << default_specifier << (settings.hilite ? hilite_none : "") << ' ';
|
||||
default_expression->formatImpl(settings, state, frame);
|
||||
settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "") << default_specifier << (settings.hilite ? hilite_none : "");
|
||||
if (default_specifier != "EPHEMERAL" || !default_expression->as<ASTLiteral>()->value.isNull())
|
||||
{
|
||||
settings.ostr << ' ';
|
||||
default_expression->formatImpl(settings, state, frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (comment)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <Parsers/CommonParsers.h>
|
||||
#include <Parsers/ParserDataType.h>
|
||||
#include <Poco/String.h>
|
||||
#include <Parsers/ASTLiteral.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -185,8 +186,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
|
||||
}
|
||||
|
||||
Pos pos_before_specifier = pos;
|
||||
if (s_default.ignore(pos, expected) || s_materialized.ignore(pos, expected) ||
|
||||
s_ephemeral.ignore(pos, expected) || s_alias.ignore(pos, expected))
|
||||
if (s_default.ignore(pos, expected) || s_materialized.ignore(pos, expected) || s_alias.ignore(pos, expected))
|
||||
{
|
||||
default_specifier = Poco::toUpper(std::string{pos_before_specifier->begin, pos_before_specifier->end});
|
||||
|
||||
@ -194,6 +194,12 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
|
||||
if (!expr_parser.parse(pos, default_expression, expected))
|
||||
return false;
|
||||
}
|
||||
else if (s_ephemeral.ignore(pos, expected))
|
||||
{
|
||||
default_specifier = "EPHEMERAL";
|
||||
if (!expr_parser.parse(pos, default_expression, expected) && type)
|
||||
default_expression = std::make_shared<ASTLiteral>(Field());
|
||||
}
|
||||
|
||||
if (require_type && !type && !default_expression)
|
||||
return false; /// reject column name without type
|
||||
|
@ -6,3 +6,11 @@ z UInt32 DEFAULT 5
|
||||
17 5
|
||||
7 5
|
||||
21 5
|
||||
x UInt32 DEFAULT y
|
||||
y UInt32 EPHEMERAL 0
|
||||
z UInt32 DEFAULT 5
|
||||
1 2
|
||||
0 2
|
||||
0 5
|
||||
7 5
|
||||
21 5
|
||||
|
@ -38,3 +38,43 @@ SELECT * FROM t_ephemeral_02205_1;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS t_ephemeral_02205_1;
|
||||
|
||||
# Test without default
|
||||
CREATE TABLE t_ephemeral_02205_1 (x UInt32 DEFAULT y, y UInt32 EPHEMERAL, z UInt32 DEFAULT 5) ENGINE = Memory;
|
||||
|
||||
DESCRIBE t_ephemeral_02205_1;
|
||||
|
||||
# Test INSERT without columns list - should participate only ordinary columns (x, z)
|
||||
INSERT INTO t_ephemeral_02205_1 VALUES (1, 2);
|
||||
# SELECT * should only return ordinary columns (x, z) - ephemeral is not stored in the table
|
||||
SELECT * FROM t_ephemeral_02205_1;
|
||||
|
||||
TRUNCATE TABLE t_ephemeral_02205_1;
|
||||
|
||||
INSERT INTO t_ephemeral_02205_1 VALUES (DEFAULT, 2);
|
||||
SELECT * FROM t_ephemeral_02205_1;
|
||||
|
||||
TRUNCATE TABLE t_ephemeral_02205_1;
|
||||
|
||||
# Test INSERT using ephemerals default
|
||||
INSERT INTO t_ephemeral_02205_1 (x, y) VALUES (DEFAULT, DEFAULT);
|
||||
SELECT * FROM t_ephemeral_02205_1;
|
||||
|
||||
TRUNCATE TABLE t_ephemeral_02205_1;
|
||||
|
||||
# Test INSERT using explicit ephemerals value
|
||||
INSERT INTO t_ephemeral_02205_1 (x, y) VALUES (DEFAULT, 7);
|
||||
SELECT * FROM t_ephemeral_02205_1;
|
||||
|
||||
# Test ALTER TABLE DELETE
|
||||
ALTER TABLE t_ephemeral_02205_1 DELETE WHERE x = 7;
|
||||
SELECT * FROM t_ephemeral_02205_1;
|
||||
|
||||
TRUNCATE TABLE t_ephemeral_02205_1;
|
||||
|
||||
# Test INSERT into column, defaulted to ephemeral, but explicitly provided with value
|
||||
INSERT INTO t_ephemeral_02205_1 (x, y) VALUES (21, 7);
|
||||
SELECT * FROM t_ephemeral_02205_1;
|
||||
|
||||
DROP TABLE IF EXISTS t_ephemeral_02205_1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user