| 926 | |
| 927 | |
| 928 | void StorageBuffer::writeBlockToDestination(const Block & block, StoragePtr table) |
| 929 | { |
| 930 | if (!destination_id || !block) |
| 931 | return; |
| 932 | |
| 933 | if (!table) |
| 934 | { |
| 935 | LOG_ERROR(log, "Destination table {} doesn't exist. Block of data is discarded.", destination_id.getNameForLogs()); |
| 936 | return; |
| 937 | } |
| 938 | auto destination_metadata_snapshot = table->getInMemoryMetadataPtr(); |
| 939 | |
| 940 | MemoryTracker::BlockerInThread temporarily_disable_memory_tracker; |
| 941 | |
| 942 | auto insert = std::make_shared<ASTInsertQuery>(); |
| 943 | insert->table_id = destination_id; |
| 944 | |
| 945 | /** We will insert columns that are the intersection set of columns of the buffer table and the subordinate table. |
| 946 | * This will support some of the cases (but not all) when the table structure does not match. |
| 947 | */ |
| 948 | Block structure_of_destination_table = allow_materialized ? destination_metadata_snapshot->getSampleBlock() |
| 949 | : destination_metadata_snapshot->getSampleBlockNonMaterialized(); |
| 950 | Block block_to_write; |
| 951 | for (size_t i : collections::range(0, structure_of_destination_table.columns())) |
| 952 | { |
| 953 | auto dst_col = structure_of_destination_table.getByPosition(i); |
| 954 | if (block.has(dst_col.name)) |
| 955 | { |
| 956 | auto column = block.getByName(dst_col.name); |
| 957 | if (!column.type->equals(*dst_col.type)) |
| 958 | { |
| 959 | LOG_WARNING(log, "Destination table {} have different type of column {} ({} != {}). Block of data is converted.", destination_id.getNameForLogs(), backQuoteIfNeed(column.name), dst_col.type->getName(), column.type->getName()); |
| 960 | column.column = castColumn(column, dst_col.type); |
| 961 | column.type = dst_col.type; |
| 962 | } |
| 963 | |
| 964 | block_to_write.insert(column); |
| 965 | } |
| 966 | } |
| 967 | |
| 968 | if (block_to_write.columns() == 0) |
| 969 | { |
| 970 | LOG_ERROR(log, "Destination table {} have no common columns with block in buffer. Block of data is discarded.", destination_id.getNameForLogs()); |
| 971 | return; |
| 972 | } |
| 973 | |
| 974 | if (block_to_write.columns() != block.columns()) |
| 975 | LOG_WARNING(log, "Not all columns from block in buffer exist in destination table {}. Some columns are discarded.", destination_id.getNameForLogs()); |
| 976 | |
| 977 | auto list_of_columns = std::make_shared<ASTExpressionList>(); |
| 978 | insert->columns = list_of_columns; |
| 979 | list_of_columns->children.reserve(block_to_write.columns()); |
| 980 | for (const auto & column : block_to_write) |
| 981 | list_of_columns->children.push_back(std::make_shared<ASTIdentifier>(column.name)); |
| 982 | |
| 983 | auto insert_context = Context::createCopy(getContext()); |
| 984 | insert_context->makeQueryContext(); |
| 985 |
no test coverage detected