You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.8 KiB
115 lines
3.8 KiB
/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License, version 2.0,
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is also distributed with certain software (including
|
|
but not limited to OpenSSL) that is licensed under separate terms,
|
|
as designated in a particular file or component or in included license
|
|
documentation. The authors of MySQL hereby grant you an additional
|
|
permission to link the program and your derivative works with the
|
|
separately licensed software that they have included with MySQL.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License, version 2.0, for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
#include "sql/hash_join_chunk.h"
|
|
|
|
#include <cstring>
|
|
|
|
#include "my_base.h"
|
|
#include "my_dbug.h"
|
|
#include "my_sys.h"
|
|
#include "scope_guard.h"
|
|
#include "sql/hash_join_buffer.h"
|
|
#include "sql/mysqld.h"
|
|
#include "sql/sql_base.h"
|
|
#include "sql/sql_const.h"
|
|
|
|
HashJoinChunk::HashJoinChunk(HashJoinChunk &&other)
|
|
: m_tables(std::move(other.m_tables)),
|
|
m_num_rows(other.m_num_rows),
|
|
m_file(other.m_file) {
|
|
// Reset the IO_CACHE structure so that the destructor doesn't close/clear the
|
|
// file contents and it's buffers.
|
|
new (&other.m_file) IO_CACHE();
|
|
}
|
|
|
|
HashJoinChunk::~HashJoinChunk() { close_cached_file(&m_file); }
|
|
|
|
bool HashJoinChunk::Init(const hash_join_buffer::TableCollection &tables) {
|
|
m_tables = tables;
|
|
m_file.file_key = key_file_hash_join;
|
|
return open_cached_file(&m_file, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
|
|
MYF(MY_WME));
|
|
}
|
|
|
|
bool HashJoinChunk::Rewind() {
|
|
if (my_b_flush_io_cache(&m_file, /*need_append_buffer_lock=*/0) == -1 ||
|
|
reinit_io_cache(&m_file, READ_CACHE, 0, false, false)) {
|
|
my_error(ER_TEMP_FILE_WRITE_FAILURE, MYF(0));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool HashJoinChunk::WriteRowToChunk(String *buffer) {
|
|
if (hash_join_buffer::StoreFromTableBuffers(m_tables, buffer)) {
|
|
my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR),
|
|
ComputeRowSizeUpperBound(m_tables));
|
|
return true;
|
|
}
|
|
|
|
// Write out the length of the data.
|
|
size_t data_length = buffer->length();
|
|
if (my_b_write(&m_file, pointer_cast<const uchar *>(&data_length),
|
|
sizeof(data_length)) != 0) {
|
|
my_error(ER_TEMP_FILE_WRITE_FAILURE, MYF(0));
|
|
return true;
|
|
}
|
|
|
|
// ... and then write the actual data.
|
|
if (my_b_write(&m_file, pointer_cast<uchar *>(buffer->ptr()), data_length) !=
|
|
0) {
|
|
my_error(ER_TEMP_FILE_WRITE_FAILURE, MYF(0));
|
|
return true;
|
|
}
|
|
m_num_rows++;
|
|
return false;
|
|
}
|
|
|
|
bool HashJoinChunk::LoadRowFromChunk(String *buffer) {
|
|
// Read the length of the row.
|
|
size_t row_length;
|
|
if (my_b_read(&m_file, pointer_cast<uchar *>(&row_length),
|
|
sizeof(row_length)) != 0) {
|
|
my_error(ER_TEMP_FILE_WRITE_FAILURE, MYF(0));
|
|
return true;
|
|
}
|
|
|
|
// Read the actual data of the row.
|
|
if (buffer->reserve(row_length)) {
|
|
my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), row_length);
|
|
return true;
|
|
}
|
|
|
|
buffer->length(row_length);
|
|
if (my_b_read(&m_file, pointer_cast<uchar *>(buffer->ptr()), row_length) !=
|
|
0) {
|
|
my_error(ER_TEMP_FILE_WRITE_FAILURE, MYF(0));
|
|
return true;
|
|
}
|
|
|
|
hash_join_buffer::LoadIntoTableBuffers(
|
|
m_tables, {pointer_cast<const uchar *>(buffer->ptr()), buffer->length()});
|
|
|
|
return false;
|
|
}
|
|
|