2018-01-10 00:04:08 +00:00
|
|
|
#include <Parsers/ASTInsertQuery.h>
|
|
|
|
#include <Interpreters/Context.h>
|
|
|
|
#include <IO/ConcatReadBuffer.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <IO/ReadBufferFromMemory.h>
|
2018-01-10 00:04:08 +00:00
|
|
|
#include <DataStreams/BlockIO.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <DataStreams/InputStreamFromASTInsertQuery.h>
|
2018-07-10 17:20:55 +00:00
|
|
|
#include <DataStreams/AddingDefaultsBlockInputStream.h>
|
|
|
|
#include <Storages/TableMetadata.h>
|
2017-01-03 01:42:17 +00:00
|
|
|
|
2016-12-09 10:10:12 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2018-01-10 00:04:08 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int LOGICAL_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-09 10:10:12 +00:00
|
|
|
InputStreamFromASTInsertQuery::InputStreamFromASTInsertQuery(
|
2017-04-01 07:20:54 +00:00
|
|
|
const ASTPtr & ast, ReadBuffer & input_buffer_tail_part, const BlockIO & streams, Context & context)
|
2016-12-09 10:10:12 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
const ASTInsertQuery * ast_insert_query = dynamic_cast<const ASTInsertQuery *>(ast.get());
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
if (!ast_insert_query)
|
|
|
|
throw Exception("Logical error: query requires data to insert, but it is not INSERT query", ErrorCodes::LOGICAL_ERROR);
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
String format = ast_insert_query->format;
|
|
|
|
if (format.empty())
|
|
|
|
format = "Values";
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// Data could be in parsed (ast_insert_query.data) and in not parsed yet (input_buffer_tail_part) part of query.
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
input_buffer_ast_part = std::make_unique<ReadBufferFromMemory>(
|
|
|
|
ast_insert_query->data, ast_insert_query->data ? ast_insert_query->end - ast_insert_query->data : 0);
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
ConcatReadBuffer::ReadBuffers buffers;
|
|
|
|
if (ast_insert_query->data)
|
|
|
|
buffers.push_back(input_buffer_ast_part.get());
|
|
|
|
buffers.push_back(&input_buffer_tail_part);
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/** NOTE Must not read from 'input_buffer_tail_part' before read all between 'ast_insert_query.data' and 'ast_insert_query.end'.
|
|
|
|
* - because 'query.data' could refer to memory piece, used as buffer for 'input_buffer_tail_part'.
|
|
|
|
*/
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
input_buffer_contacenated = std::make_unique<ConcatReadBuffer>(buffers);
|
2016-12-09 10:10:12 +00:00
|
|
|
|
2018-07-10 17:20:55 +00:00
|
|
|
TableMetadata table_meta(ast_insert_query->database, ast_insert_query->table);
|
|
|
|
table_meta.loadFromContext(context);
|
|
|
|
|
2018-07-11 12:05:04 +00:00
|
|
|
res_stream = context.getInputFormat(
|
|
|
|
format, *input_buffer_contacenated, streams.out->getHeader(), context.getSettings().max_insert_block_size);
|
|
|
|
|
|
|
|
if (!table_meta.column_defaults.empty())
|
|
|
|
res_stream = std::make_shared<AddingDefaultsBlockInputStream>(res_stream, table_meta.column_defaults, context);
|
2016-12-09 10:10:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|