mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +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 {#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.
|
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}
|
### ALIAS {#alias}
|
||||||
|
@ -110,9 +110,9 @@ SELECT x, toTypeName(x) FROM t1;
|
|||||||
|
|
||||||
### EPHEMERAL {#ephemeral}
|
### EPHEMERAL {#ephemeral}
|
||||||
|
|
||||||
`EPHEMERAL expr`
|
`EPHEMERAL [expr]`
|
||||||
|
|
||||||
Эфемерное выражение. Такой столбец не хранится в таблице и не может быть получен в запросе SELECT, но на него можно ссылаться в выражениях по умолчанию запроса CREATE.
|
Эфемерное выражение. Такой столбец не хранится в таблице и не может быть получен в запросе SELECT, но на него можно ссылаться в выражениях по умолчанию запроса CREATE. Если значение по умолчанию `expr` не указано, то тип колонки должен быть специфицирован.
|
||||||
INSERT без списка столбцов игнорирует этот столбец, таким образом сохраняется инвариант - т.е. дамп, полученный путём `SELECT *`, можно вставить обратно в таблицу INSERT-ом без указания списка столбцов.
|
INSERT без списка столбцов игнорирует этот столбец, таким образом сохраняется инвариант - т.е. дамп, полученный путём `SELECT *`, можно вставить обратно в таблицу INSERT-ом без указания списка столбцов.
|
||||||
|
|
||||||
### ALIAS {#alias}
|
### ALIAS {#alias}
|
||||||
|
@ -508,7 +508,9 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(
|
|||||||
|
|
||||||
default_expr_list->children.emplace_back(
|
default_expr_list->children.emplace_back(
|
||||||
setAlias(
|
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));
|
tmp_column_name));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -536,7 +538,11 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(
|
|||||||
|
|
||||||
if (col_decl.default_expression)
|
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)
|
if (col_decl.type)
|
||||||
column.type = name_type_it->type;
|
column.type = name_type_it->type;
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <Parsers/ASTColumnDeclaration.h>
|
#include <Parsers/ASTColumnDeclaration.h>
|
||||||
#include <Common/quoteString.h>
|
#include <Common/quoteString.h>
|
||||||
#include <IO/Operators.h>
|
#include <IO/Operators.h>
|
||||||
|
#include <Parsers/ASTLiteral.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -71,8 +72,12 @@ void ASTColumnDeclaration::formatImpl(const FormatSettings & settings, FormatSta
|
|||||||
|
|
||||||
if (default_expression)
|
if (default_expression)
|
||||||
{
|
{
|
||||||
settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "") << default_specifier << (settings.hilite ? hilite_none : "") << ' ';
|
settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "") << default_specifier << (settings.hilite ? hilite_none : "");
|
||||||
default_expression->formatImpl(settings, state, frame);
|
if (default_specifier != "EPHEMERAL" || !default_expression->as<ASTLiteral>()->value.isNull())
|
||||||
|
{
|
||||||
|
settings.ostr << ' ';
|
||||||
|
default_expression->formatImpl(settings, state, frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment)
|
if (comment)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <Parsers/CommonParsers.h>
|
#include <Parsers/CommonParsers.h>
|
||||||
#include <Parsers/ParserDataType.h>
|
#include <Parsers/ParserDataType.h>
|
||||||
#include <Poco/String.h>
|
#include <Poco/String.h>
|
||||||
|
#include <Parsers/ASTLiteral.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -185,8 +186,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
|
|||||||
}
|
}
|
||||||
|
|
||||||
Pos pos_before_specifier = pos;
|
Pos pos_before_specifier = pos;
|
||||||
if (s_default.ignore(pos, expected) || s_materialized.ignore(pos, expected) ||
|
if (s_default.ignore(pos, expected) || s_materialized.ignore(pos, expected) || s_alias.ignore(pos, expected))
|
||||||
s_ephemeral.ignore(pos, expected) || s_alias.ignore(pos, expected))
|
|
||||||
{
|
{
|
||||||
default_specifier = Poco::toUpper(std::string{pos_before_specifier->begin, pos_before_specifier->end});
|
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))
|
if (!expr_parser.parse(pos, default_expression, expected))
|
||||||
return false;
|
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)
|
if (require_type && !type && !default_expression)
|
||||||
return false; /// reject column name without type
|
return false; /// reject column name without type
|
||||||
|
@ -6,3 +6,11 @@ z UInt32 DEFAULT 5
|
|||||||
17 5
|
17 5
|
||||||
7 5
|
7 5
|
||||||
21 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;
|
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