dbms: fixed segfault when using INSERT SELECT or CREATE AS SELECT with extremes=1 or WITH TOTALS [#METR-17491].

This commit is contained in:
Alexey Milovidov 2015-07-27 18:51:37 +03:00
parent bc6598371c
commit e3b5bc0ea6
6 changed files with 30 additions and 14 deletions

View File

@ -14,10 +14,10 @@ class FormatFactory
{
public:
BlockInputStreamPtr getInput(const String & name, ReadBuffer & buf,
Block & sample, size_t max_block_size) const;
const Block & sample, size_t max_block_size) const;
BlockOutputStreamPtr getOutput(const String & name, WriteBuffer & buf,
Block & sample) const;
const Block & sample) const;
};
}

View File

@ -860,15 +860,8 @@ private:
}
void onData(Block & block)
void initBlockOutputStream(const Block & block)
{
if (written_progress_chars)
clearProgress();
if (!block)
return;
processed_rows += block.rows();
if (!block_std_out)
{
String current_format = format;
@ -891,8 +884,21 @@ private:
block_std_out = context.getFormatFactory().getOutput(current_format, std_out, block);
block_std_out->writePrefix();
}
}
/// Загаловочный блок с нулем строк использовался для инициализации block_std_out,
void onData(Block & block)
{
if (written_progress_chars)
clearProgress();
if (!block)
return;
processed_rows += block.rows();
initBlockOutputStream(block);
/// Заголовочный блок с нулем строк использовался для инициализации block_std_out,
/// выводить его не нужно
if (block.rows() != 0)
{
@ -907,11 +913,13 @@ private:
void onTotals(Block & block)
{
initBlockOutputStream(block);
block_std_out->setTotals(block);
}
void onExtremes(Block & block)
{
initBlockOutputStream(block);
block_std_out->setExtremes(block);
}

View File

@ -302,7 +302,13 @@ std::string Block::dumpStructure() const
{
if (it != data.begin())
res << ", ";
res << it->name << ' ' << it->type->getName() << ' ' << it->column->getName() << ' ' << it->column->size();
res << it->name << ' ' << it->type->getName();
if (it->column)
res << ' ' << it->column->getName() << ' ' << it->column->size();
else
res << "nullptr";
}
return res.str();
}

View File

@ -26,7 +26,7 @@ namespace DB
{
BlockInputStreamPtr FormatFactory::getInput(const String & name, ReadBuffer & buf,
Block & sample, size_t max_block_size) const
const Block & sample, size_t max_block_size) const
{
if (name == "Native")
return new NativeBlockInputStream(buf);
@ -48,7 +48,7 @@ BlockInputStreamPtr FormatFactory::getInput(const String & name, ReadBuffer & bu
BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & buf,
Block & sample) const
const Block & sample) const
{
if (name == "Native")
return new NativeBlockOutputStream(buf);

View File

@ -252,6 +252,7 @@ BlockIO InterpreterCreateQuery::executeImpl(bool assume_metadata_exists)
if (create.select && storage_name != "View" && (storage_name != "MaterializedView" || create.is_populate))
{
BlockIO io;
io.in_sample = select_sample;
io.in = new NullAndDoCopyBlockInputStream(
new MaterializingBlockInputStream(interpreter_select->execute().in),
res->write(query_ptr));

View File

@ -100,6 +100,7 @@ BlockIO InterpreterInsertQuery::execute()
InterpreterSelectQuery interpreter_select{query.select, context};
BlockInputStreamPtr in{interpreter_select.execute().in};
res.in = new NullAndDoCopyBlockInputStream{in, out};
res.in_sample = interpreter_select.getSampleBlock();
}
return res;