BlockInputStreams StorageSystemTables::read(
    const Names & column_names,
    const SelectQueryInfo & query_info,
    const Context & context,
    QueryProcessingStage::Enum /*processed_stage*/,
    const size_t max_block_size,
    const unsigned /*num_streams*/)
{
    check(column_names);

    /// Create a mask of what columns are needed in the result.

    NameSet names_set(column_names.begin(), column_names.end());

    Block sample_block = getSampleBlock();
    Block res_block;

    std::vector<UInt8> columns_mask(sample_block.columns());
    for (size_t i = 0, size = columns_mask.size(); i < size; ++i)
    {
        if (names_set.count(sample_block.getByPosition(i).name))
        {
            columns_mask[i] = 1;
            res_block.insert(sample_block.getByPosition(i));
        }
    }

    ColumnPtr filtered_databases_column = getFilteredDatabases(query_info.query, context);
    return {std::make_shared<TablesBlockInputStream>(
        std::move(columns_mask), std::move(res_block), max_block_size, std::move(filtered_databases_column), context)};
}
BlockInputStreams StorageSystemTables::read(
	const Names & column_names,
	ASTPtr query,
	const Context & context,
	const Settings & settings,
	QueryProcessingStage::Enum & processed_stage,
	const size_t max_block_size,
	const unsigned threads)
{
	check(column_names);
	processed_stage = QueryProcessingStage::FetchColumns;

	Block block;

	ColumnWithTypeAndName col_db;
	col_db.name = "database";
	col_db.type = std::make_shared<DataTypeString>();
	col_db.column = std::make_shared<ColumnString>();
	block.insert(col_db);

	ColumnWithTypeAndName col_name;
	col_name.name = "name";
	col_name.type = std::make_shared<DataTypeString>();
	col_name.column = std::make_shared<ColumnString>();
	block.insert(col_name);

	ColumnWithTypeAndName col_engine;
	col_engine.name = "engine";
	col_engine.type = std::make_shared<DataTypeString>();
	col_engine.column = std::make_shared<ColumnString>();
	block.insert(col_engine);

	ColumnWithTypeAndName filtered_databases_column = getFilteredDatabases(query, context);

	for (size_t row_number = 0; row_number < filtered_databases_column.column->size(); ++row_number)
	{
		std::string database_name = filtered_databases_column.column->getDataAt(row_number).toString();
		auto database = context.tryGetDatabase(database_name);

		if (!database)
		{
			/// Базу данных только что удалили.
			continue;
		}

		for (auto iterator = database->getIterator(); iterator->isValid(); iterator->next())
		{
			col_db.column->insert(database_name);
			col_name.column->insert(iterator->name());
			col_engine.column->insert(iterator->table()->getName());
		}
	}

	return BlockInputStreams(1, std::make_shared<OneBlockInputStream>(block));
}