https://clickhouse-test-reports.s3.yandex.net/21020/2ced21c837006053542b9f04c338faebf504f413/fuzzer_asan/server.log
constexpr bool left = KIND == ASTTableJoin::Kind::Left;
    constexpr bool right = KIND == ASTTableJoin::Kind::Right;
    constexpr bool inner = KIND == ASTTableJoin::Kind::Inner;
    constexpr bool full = KIND == ASTTableJoin::Kind::Full;
    constexpr bool need_replication = is_all_join || (is_any_join && right) || (is_semi_join && right);
    constexpr bool need_filter = !need_replication && (inner || right || (is_semi_join && left) || (is_anti_join && left));
    
    Columns materialized_keys = JoinCommon::materializeColumns(block, key_names_left);
    ColumnRawPtrs left_key_columns = JoinCommon::getRawPointers(materialized_keys);
    
    ConstNullMapPtr null_map{};
    ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(left_key_columns, null_map);
    size_t existing_columns = block.columns();
    /** If you use FULL or RIGHT JOIN, then the columns from the "left" table must be materialized.
      * Because if they are constants, then in the "not joined" rows, they may have different values
      *  - default values, which can differ from the values of these constants.
      */
    if constexpr (right || full)
    {
        materializeBlockInplace(block);
        if (nullable_left_side)
            JoinCommon::convertColumnsToNullable(block);
    }
    /** For LEFT/INNER JOIN, the saved blocks do not contain keys.
      * For FULL/RIGHT JOIN, the saved blocks contain keys;
      *  but they will not be used at this stage of joining (and will be in `AdderNonJoined`), and they need to be skipped.
      * For ASOF, the last column is used as the ASOF column
      */
    AddedColumns added_columns(block_with_columns_to_add, block, savedBlockSample(), *this, left_key_columns, key_sizes, is_asof_join);
    bool has_required_right_keys = (required_right_keys.columns() != 0);