column transformers in insert select

This commit is contained in:
Amos Bird 2020-09-04 01:51:16 +08:00
parent c2f762e20a
commit 016f707ea1
No known key found for this signature in database
GPG Key ID: 80D430DCBECFEDB4
5 changed files with 66 additions and 2 deletions

View File

@ -17,6 +17,7 @@
#include <Interpreters/InterpreterWatchQuery.h> #include <Interpreters/InterpreterWatchQuery.h>
#include <Interpreters/JoinedTables.h> #include <Interpreters/JoinedTables.h>
#include <Parsers/ASTFunction.h> #include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTInsertQuery.h> #include <Parsers/ASTInsertQuery.h>
#include <Parsers/ASTSelectQuery.h> #include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTSelectWithUnionQuery.h> #include <Parsers/ASTSelectWithUnionQuery.h>
@ -29,6 +30,8 @@
#include <Storages/StorageDistributed.h> #include <Storages/StorageDistributed.h>
#include <TableFunctions/TableFunctionFactory.h> #include <TableFunctions/TableFunctionFactory.h>
#include <Common/checkStackSize.h> #include <Common/checkStackSize.h>
#include <Interpreters/TranslateQualifiedNamesVisitor.h>
#include <Interpreters/getTableExpressions.h>
namespace namespace
{ {
@ -90,9 +93,30 @@ Block InterpreterInsertQuery::getSampleBlock(
} }
Block table_sample = metadata_snapshot->getSampleBlock(); Block table_sample = metadata_snapshot->getSampleBlock();
const auto & columns = metadata_snapshot->getColumns();
auto names_and_types = columns.getOrdinary();
removeDuplicateColumns(names_and_types);
auto table_expr = std::make_shared<ASTTableExpression>();
table_expr->database_and_table_name = createTableIdentifier(table->getStorageID());
table_expr->children.push_back(table_expr->database_and_table_name);
TablesWithColumns tables_with_columns;
tables_with_columns.emplace_back(DatabaseAndTableWithAlias(*table_expr, context.getCurrentDatabase()), names_and_types);
tables_with_columns[0].addHiddenColumns(columns.getMaterialized());
tables_with_columns[0].addHiddenColumns(columns.getAliases());
tables_with_columns[0].addHiddenColumns(table->getVirtuals());
NameSet source_columns_set;
for (const auto & identifier : query.columns->children)
source_columns_set.insert(identifier->getColumnName());
TranslateQualifiedNamesVisitor::Data visitor_data(source_columns_set, tables_with_columns);
TranslateQualifiedNamesVisitor visitor(visitor_data);
auto columns_ast = query.columns->clone();
visitor.visit(columns_ast);
/// Form the block based on the column names from the query /// Form the block based on the column names from the query
Block res; Block res;
for (const auto & identifier : query.columns->children) for (const auto & identifier : columns_ast->children)
{ {
std::string current_name = identifier->getColumnName(); std::string current_name = identifier->getColumnName();

View File

@ -36,7 +36,7 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
ParserToken s_lparen(TokenType::OpeningRoundBracket); ParserToken s_lparen(TokenType::OpeningRoundBracket);
ParserToken s_rparen(TokenType::ClosingRoundBracket); ParserToken s_rparen(TokenType::ClosingRoundBracket);
ParserIdentifier name_p; ParserIdentifier name_p;
ParserList columns_p(std::make_unique<ParserCompoundIdentifier>(), std::make_unique<ParserToken>(TokenType::Comma), false); ParserList columns_p(std::make_unique<ParserInsertElement>(), std::make_unique<ParserToken>(TokenType::Comma), false);
ParserFunction table_function_p{false}; ParserFunction table_function_p{false};
ASTPtr database; ASTPtr database;
@ -189,5 +189,12 @@ bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
return true; return true;
} }
bool ParserInsertElement::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return ParserColumnsMatcher().parse(pos, node, expected)
|| ParserQualifiedAsterisk().parse(pos, node, expected)
|| ParserAsterisk().parse(pos, node, expected)
|| ParserCompoundIdentifier().parse(pos, node, expected);
}
} }

View File

@ -33,4 +33,13 @@ public:
ParserInsertQuery(const char * end_) : end(end_) {} ParserInsertQuery(const char * end_) : end(end_) {}
}; };
/** Insert accepts an identifier and an asterisk with variants.
*/
class ParserInsertElement : public IParserBase
{
protected:
const char * getName() const override { return "insert element"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};
} }

View File

@ -0,0 +1,6 @@
1 0 0 2
3 0 0 4
1 0 0 2
3 0 0 4
1 0 0 2
3 0 0 4

View File

@ -0,0 +1,18 @@
DROP TABLE IF EXISTS insert_select_dst;
DROP TABLE IF EXISTS insert_select_src;
CREATE TABLE insert_select_dst (i int, middle_a int, middle_b int, j int) ENGINE = Log;
CREATE TABLE insert_select_src (i int, j int) ENGINE = Log;
INSERT INTO insert_select_src VALUES (1, 2), (3, 4);
INSERT INTO insert_select_dst(* EXCEPT (middle_a, middle_b)) SELECT * FROM insert_select_src;
INSERT INTO insert_select_dst(insert_select_dst.* EXCEPT (middle_a, middle_b)) SELECT * FROM insert_select_src;
INSERT INTO insert_select_dst(COLUMNS('.*') EXCEPT (middle_a, middle_b)) SELECT * FROM insert_select_src;
INSERT INTO insert_select_dst(insert_select_src.* EXCEPT (middle_a, middle_b)) SELECT * FROM insert_select_src; -- { serverError 47 }
SELECT * FROM insert_select_dst;
DROP TABLE IF EXISTS insert_select_dst;
DROP TABLE IF EXISTS insert_select_src;