166 lines
5.0 KiB
C++
166 lines
5.0 KiB
C++
/* Copyright (c) 2012, 2015, 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 St, 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 "sys_vars.h"
|
|
|
|
#include "filesort.h"
|
|
#include "sql_sort.h"
|
|
|
|
namespace make_sortkey_unittest {
|
|
|
|
using my_testing::Server_initializer;
|
|
using my_testing::Mock_error_handler;
|
|
|
|
/**
|
|
Test that sortlength() and make_sortkey() agree on what to do:
|
|
i.e. that there is no buffer underwrite/overwrite in make_sortkey()
|
|
if sortlength() has set a very small size.
|
|
|
|
We allocate a buffer, fill it with 'a's and then tell make_sortkey()
|
|
to put it's result somewhere in the middle.
|
|
The buffer should be unchanged outside of the area determined by sortlength.
|
|
*/
|
|
class MakeSortKeyTest : public ::testing::Test
|
|
{
|
|
protected:
|
|
MakeSortKeyTest()
|
|
{
|
|
m_sort_fields[0].field= NULL;
|
|
m_sort_fields[1].field= NULL;
|
|
m_sort_fields[0].reverse= false;
|
|
m_sort_fields[1].reverse= false;
|
|
m_sort_param.local_sortorder=
|
|
Bounds_checked_array<st_sort_field>(m_sort_fields, 1);
|
|
memset(m_buff, 'a', sizeof(m_buff));
|
|
m_to= &m_buff[8];
|
|
}
|
|
|
|
virtual void SetUp() { initializer.SetUp(); }
|
|
virtual void TearDown() { initializer.TearDown(); }
|
|
|
|
THD *thd() { return initializer.thd(); }
|
|
|
|
void verify_buff(uint length)
|
|
{
|
|
for (uchar *pu= m_buff; pu < m_to; ++pu)
|
|
{
|
|
EXPECT_EQ('a', *pu) << " position " << pu - m_buff;
|
|
}
|
|
for (uchar *pu= m_to + length; pu < m_buff + 100; ++pu)
|
|
{
|
|
EXPECT_EQ('a', *pu) << " position " << pu - m_buff;
|
|
}
|
|
}
|
|
|
|
Server_initializer initializer;
|
|
|
|
Sort_param m_sort_param;
|
|
st_sort_field m_sort_fields[2]; // sortlength() adds an end marker !!
|
|
bool m_multi_byte_charset;
|
|
bool m_use_hash;
|
|
uchar m_ref_buff[4]; // unused, but needed for make_sortkey()
|
|
uchar m_buff[100];
|
|
uchar *m_to;
|
|
};
|
|
|
|
|
|
TEST_F(MakeSortKeyTest, IntResult)
|
|
{
|
|
thd()->variables.max_sort_length= 4U;
|
|
m_sort_fields[0].item= new Item_int(42);
|
|
|
|
const uint total_length=
|
|
sortlength(thd(), m_sort_fields, 1, &m_multi_byte_charset, &m_use_hash);
|
|
EXPECT_EQ(sizeof(longlong), total_length);
|
|
EXPECT_FALSE(m_multi_byte_charset);
|
|
EXPECT_FALSE(m_use_hash);
|
|
EXPECT_EQ(sizeof(longlong), m_sort_fields[0].length);
|
|
EXPECT_EQ(INT_RESULT, m_sort_fields[0].result_type);
|
|
|
|
m_sort_param.make_sortkey(m_to, m_ref_buff);
|
|
SCOPED_TRACE("");
|
|
verify_buff(total_length);
|
|
}
|
|
|
|
|
|
TEST_F(MakeSortKeyTest, IntResultNull)
|
|
{
|
|
thd()->variables.max_sort_length= 4U;
|
|
Item *int_item= m_sort_fields[0].item= new Item_int(42);
|
|
int_item->maybe_null= true;
|
|
int_item->null_value= true;
|
|
|
|
const uint total_length=
|
|
sortlength(thd(), m_sort_fields, 1, &m_multi_byte_charset, &m_use_hash);
|
|
EXPECT_EQ(1 + sizeof(longlong), total_length);
|
|
EXPECT_FALSE(m_multi_byte_charset);
|
|
EXPECT_FALSE(m_use_hash);
|
|
EXPECT_EQ(sizeof(longlong), m_sort_fields[0].length);
|
|
EXPECT_EQ(INT_RESULT, m_sort_fields[0].result_type);
|
|
|
|
m_sort_param.make_sortkey(m_to, m_ref_buff);
|
|
SCOPED_TRACE("");
|
|
verify_buff(total_length);
|
|
}
|
|
|
|
TEST_F(MakeSortKeyTest, DecimalResult)
|
|
{
|
|
const char dec_str[]= "1234567890.1234567890";
|
|
thd()->variables.max_sort_length= 4U;
|
|
m_sort_fields[0].item=
|
|
new Item_decimal(POS(), dec_str, strlen(dec_str), &my_charset_bin);
|
|
Parse_context pc(thd(), thd()->lex->current_select());
|
|
EXPECT_FALSE(m_sort_fields[0].item->itemize(&pc, &m_sort_fields[0].item));
|
|
|
|
const uint total_length=
|
|
sortlength(thd(), m_sort_fields, 1, &m_multi_byte_charset, &m_use_hash);
|
|
EXPECT_EQ(10U, total_length);
|
|
EXPECT_FALSE(m_multi_byte_charset);
|
|
EXPECT_FALSE(m_use_hash);
|
|
EXPECT_EQ(10U, m_sort_fields[0].length);
|
|
EXPECT_EQ(DECIMAL_RESULT, m_sort_fields[0].result_type);
|
|
|
|
m_sort_param.make_sortkey(m_to, m_ref_buff);
|
|
SCOPED_TRACE("");
|
|
verify_buff(total_length);
|
|
}
|
|
|
|
TEST_F(MakeSortKeyTest, RealResult)
|
|
{
|
|
const char dbl_str[]= "1234567890.1234567890";
|
|
thd()->variables.max_sort_length= 4U;
|
|
m_sort_fields[0].item= new Item_float(dbl_str, strlen(dbl_str));
|
|
|
|
const uint total_length=
|
|
sortlength(thd(), m_sort_fields, 1, &m_multi_byte_charset, &m_use_hash);
|
|
EXPECT_EQ(sizeof(double), total_length);
|
|
EXPECT_FALSE(m_multi_byte_charset);
|
|
EXPECT_FALSE(m_use_hash);
|
|
EXPECT_EQ(sizeof(double), m_sort_fields[0].length);
|
|
EXPECT_EQ(REAL_RESULT, m_sort_fields[0].result_type);
|
|
|
|
m_sort_param.make_sortkey(m_to, m_ref_buff);
|
|
SCOPED_TRACE("");
|
|
verify_buff(total_length);
|
|
}
|
|
|
|
}
|