mysql5/mysql-5.7.27/unittest/gunit/join_tab_sort-t.cc

279 lines
7.0 KiB
C++

/* Copyright (c) 2012, 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 as published by
the Free Software Foundation; version 2 of the License.
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 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
// First include (the generated) my_config.h, to get correct platform defines.
#include "my_config.h"
#include <gtest/gtest.h>
#include "test_utils.h"
#include "sql_select.h"
#include "merge_sort.h"
#include <vector>
namespace join_tab_sort_unittest {
using my_testing::Server_initializer;
using my_testing::Mock_error_handler;
class JTSortTest : public ::testing::Test
{
protected:
virtual void SetUp() { initializer.SetUp(); }
virtual void TearDown() { initializer.TearDown(); }
Server_initializer initializer;
};
class MOCK_JOIN_TAB : public JOIN_TAB
{
public:
MOCK_JOIN_TAB(uint recs, uint table_no) : JOIN_TAB()
{
found_records= recs;
set_qs(&m_shared);
this->set_table(&m_table);
m_table_list.set_tableno(table_no);
this->table_ref= &m_table_list;
}
TABLE m_table;
TABLE_LIST m_table_list;
QEP_shared m_shared;
};
std::ostream &operator<<(std::ostream &s, const MOCK_JOIN_TAB &jt)
{
return s << "{"
<< jt.found_records << ", "
<< jt.m_table_list.map()
<< "}";
}
TEST_F(JTSortTest, SimpleSortTest)
{
MOCK_JOIN_TAB jt1(UINT_MAX, 0);
MOCK_JOIN_TAB jt2(2, 0);
MOCK_JOIN_TAB jt3(1, 0);
MOCK_JOIN_TAB jt4(10, 0);
MOCK_JOIN_TAB jt5(5, 0);
MOCK_JOIN_TAB *arr[5];
arr[0]= &jt1;
arr[1]= &jt2;
arr[2]= &jt3;
arr[3]= &jt4;
arr[4]= &jt5;
insert_sort(arr, arr+5, Join_tab_compare_default());
EXPECT_EQ(1U, arr[0]->found_records);
EXPECT_EQ(2U, arr[1]->found_records);
EXPECT_EQ(5U, arr[2]->found_records);
EXPECT_EQ(10U, arr[3]->found_records);
EXPECT_EQ(UINT_MAX, arr[4]->found_records);
}
TEST_F(JTSortTest, SortFoundRecordsTest)
{
const int num_tables= 50;
MOCK_JOIN_TAB *arr[num_tables];
for (int i= 0; i < num_tables; i++)
arr[i]= new MOCK_JOIN_TAB(i, 0);
// MERGE SORT
std::random_shuffle(arr, arr + 50);
merge_sort(arr, arr + num_tables, Join_tab_compare_default());
for (int i= 1; i < num_tables; i++)
EXPECT_TRUE(arr[i]->found_records > arr[i-1]->found_records);
// INSERT SORT
std::random_shuffle(arr, arr + 50);
insert_sort(arr, arr + num_tables, Join_tab_compare_default());
for (int i= 1; i < num_tables; i++)
EXPECT_TRUE(arr[i]->found_records > arr[i-1]->found_records);
for (int i= 0; i < num_tables; i++)
{
delete arr[i];
}
}
TEST_F(JTSortTest, SortDependsTest)
{
const int num_tables= 50;
MOCK_JOIN_TAB *arr[num_tables];
/*
dependency has higher precedence than found_records, so the tables
shall be ordered with decreasing number of records in this test
*/
for (int i= 0; i < num_tables; i++)
{
arr[i]= new MOCK_JOIN_TAB(i, i);
for (int j= i+1; j < num_tables; j++)
arr[i]->dependent|= 1ULL << j;
}
// MERGE SORT
std::random_shuffle(arr, arr + num_tables);
merge_sort(arr, arr + num_tables, Join_tab_compare_default());
for (int i= 1; i < num_tables; i++)
EXPECT_TRUE(arr[i]->found_records < arr[i-1]->found_records)
<< "i: " << *(arr[i]) << " "
<< "i-1: " << *(arr[i-1]);
// INSERT SORT
std::random_shuffle(arr, arr + num_tables);
insert_sort(arr, arr + num_tables, Join_tab_compare_default());
for (int i= 1; i < num_tables; i++)
EXPECT_TRUE(arr[i]->found_records < arr[i-1]->found_records);
for (int i= 0; i < num_tables; i++)
{
delete arr[i];
}
}
TEST_F(JTSortTest, SortKeyDependsTest)
{
const int num_tables= 50;
MOCK_JOIN_TAB *arr[num_tables];
/*
key_dependency has higher precedence than found_records, so the
tables shall be ordered with decreasing number of records in this
test
*/
for (int i= 0; i < num_tables; i++)
{
arr[i]= new MOCK_JOIN_TAB(i, i);
for (int j= i+1; j < num_tables; j++)
arr[i]->key_dependent|= 1ULL << j;
}
// MERGE SORT
std::random_shuffle(arr, arr + num_tables);
merge_sort(arr, arr + num_tables, Join_tab_compare_default());
for (int i= 1; i < num_tables; i++)
EXPECT_TRUE(arr[i]->found_records < arr[i-1]->found_records);
// INSERT SORT
std::random_shuffle(arr, arr + num_tables);
insert_sort(arr, arr + num_tables, Join_tab_compare_default());
for (int i= 1; i < num_tables; i++)
EXPECT_TRUE(arr[i]->found_records < arr[i-1]->found_records);
for (int i= 0; i < num_tables; i++)
delete arr[i];
}
/*
Above, sorting for JOIN_TABs were tested. Below we check that the
sorting works for ints types as well.
*/
class Int_compare_ptr :
public std::binary_function<const int*, const int*, bool>
{
public:
bool operator()(const int *i1, const int *i2) const
{
return *i1 < *i2;
}
};
TEST_F(JTSortTest, SortIntTest)
{
const uint ints_to_sort= 1000;
std::vector<int> arr;
std::vector<int*> arr_ptr;
arr.reserve(ints_to_sort);
arr_ptr.reserve(ints_to_sort);
for (uint i= 0; i < ints_to_sort; i++)
{
arr.push_back(i);
arr_ptr.push_back(&arr[i]);
}
EXPECT_TRUE(arr.size() == ints_to_sort);
EXPECT_TRUE(arr_ptr.size() == ints_to_sort);
// MERGE SORT
std::random_shuffle(&arr_ptr.front(), &arr_ptr.back() + 1);
merge_sort(&arr_ptr.front(), &arr_ptr.back() + 1, Int_compare_ptr());
for (uint i= 0; i < arr_ptr.size(); i++)
EXPECT_TRUE(*arr_ptr[i] == (int)i);
// INSERT SORT
std::random_shuffle(&arr_ptr.front(), &arr_ptr.back() + 1);
insert_sort(&arr_ptr.front(), &arr_ptr.back() + 1, Int_compare_ptr());
for (uint i= 0; i < arr_ptr.size(); i++)
EXPECT_TRUE(*arr_ptr[i] == (int)i);
}
TEST_F(JTSortTest, SortInt2Test)
{
const uint ints_to_sort= 1000;
std::vector<int> arr;
std::vector<int*> arr_ptr;
arr.reserve(ints_to_sort);
arr_ptr.reserve(ints_to_sort);
for (uint i= 0; i < (ints_to_sort - 2); i++)
{
arr.push_back((i % 2) ? i : (i * -1));
arr_ptr.push_back(&arr[i]);
}
arr.push_back(INT_MAX32);
arr_ptr.push_back(&arr.back());
arr.push_back(INT_MIN32);
arr_ptr.push_back(&arr.back());
EXPECT_TRUE(arr.size() == ints_to_sort);
EXPECT_TRUE(arr_ptr.size() == ints_to_sort);
// MERGE SORT
std::random_shuffle(&arr_ptr.front(), &arr_ptr.back() + 1);
merge_sort(&arr_ptr.front(), &arr_ptr.back() + 1, Int_compare_ptr());
for (uint i= 1; i < arr_ptr.size(); i++)
EXPECT_TRUE(*arr_ptr[i-1] < *arr_ptr[i]);
// INSERT SORT
std::random_shuffle(&arr_ptr.front(), &arr_ptr.back() + 1);
insert_sort(&arr_ptr.front(), &arr_ptr.back() + 1, Int_compare_ptr());
for (uint i= 1; i < arr_ptr.size(); i++)
EXPECT_TRUE(*arr_ptr[i-1] < *arr_ptr[i]);
}
}