ClickHouse crushed on request to system.tables if has an incorrect "self-flushing" buffer table.

```
xxxx :) CREATE TABLE test (key UInt32) Engine=Buffer(default, test, 16, 10, 100, 10000, 1000000, 10000000, 100000000);


CREATE TABLE test
(
    `key` UInt32
)
ENGINE = Buffer(default, test, 16, 10, 100, 10000, 1000000, 10000000, 100000000)

Query id: a90ea965-ac7c-420f-a947-f900b6b0d014

Ok.

0 rows in set. Elapsed: 0.005 sec. 

xxxx :) select * from system.tables

SELECT *
FROM system.tables

Query id: bbb7d7eb-b782-4527-9803-ddc4f8703d5c

[xxxx] 2022.08.25 21:44:05.507879 [ 841325 ] <Fatal> BaseDaemon: ########################################
[xxxx] 2022.08.25 21:44:05.508036 [ 841325 ] <Fatal> BaseDaemon: (version 22.8.2.11 (official build), build id: F509FE73D83F8136) (from thread 841253) (query_id: bbb7d7eb-b782-4527-9803-ddc4f8703d5c) (query: select * from system.tables) Received signal Segmentation fault (11)
[xxxx] 2022.08.25 21:44:05.508105 [ 841325 ] <Fatal> BaseDaemon: Address: 0x7f06c12f7ff8 Access: write. Attempted access has violated the permissions assigned to the memory area.
[xxxx] 2022.08.25 21:44:05.508141 [ 841325 ] <Fatal> BaseDaemon: Stack trace: 0xa480065
[xxxx] 2022.08.25 21:44:05.508200 [ 841325 ] <Fatal> BaseDaemon: 2. ? @ 0xa480065 in /usr/bin/clickhouse
[xxxx] 2022.08.25 21:44:05.697982 [ 841325 ] <Fatal> BaseDaemon: Integrity check of the executable successfully passed (checksum: 26BBB329434F6C45E2D0312BCEE49FC1)
↘ Progress: 0.00 rows, 0.00 B (0.00 rows/s., 0.00 B/s.)                                                                                                                                                   Exception on client:
Code: 32. DB::Exception: Attempt to read after eof: while receiving packet from localhost:9000. (ATTEMPT_TO_READ_AFTER_EOF)

Connecting to localhost:9000 as user default.
Code: 210. DB::NetException: Connection reset by peer, while writing to socket ([::1]:9000). (NETWORK_ERROR)

```

Found on version 22.3.9.19, reproduced also on 22.8.2.11

UInt64 milliseconds = watch.elapsedMilliseconds();
    LOG_DEBUG(log, "Flushing buffer with {} rows, {} bytes, age {} seconds, took {} ms {}.", rows, bytes, time_passed, milliseconds, (check_thresholds ? "(bg)" : "(direct)"));
    return true;
}
void StorageBuffer::writeBlockToDestination(const Block & block, StoragePtr table)
{
    if (!destination_id || !block)
        return;
    if (!table)
    {
        LOG_ERROR(log, "Destination table {} doesn't exist. Block of data is discarded.", destination_id.getNameForLogs());
        return;
    }
    auto destination_metadata_snapshot = table->getInMemoryMetadataPtr();
    MemoryTrackerBlockerInThread temporarily_disable_memory_tracker;
    auto insert = std::make_shared<ASTInsertQuery>();
    insert->table_id = destination_id;
    /** We will insert columns that are the intersection set of columns of the buffer table and the subordinate table.
      * This will support some of the cases (but not all) when the table structure does not match.
      */
    Block structure_of_destination_table = allow_materialized ? destination_metadata_snapshot->getSampleBlock()
                                                              : destination_metadata_snapshot->getSampleBlockNonMaterialized();
    Block block_to_write;
    for (size_t i : collections::range(0, structure_of_destination_table.columns()))
    {
        auto dst_col = structure_of_destination_table.getByPosition(i);
        if (block.has(dst_col.name))
        {
            auto column = block.getByName(dst_col.name);
            if (!column.type->equals(*dst_col.type))