8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 18:03:04 +01:00

Slightly reworked the key processing in the hash join algorithm.

This commit is contained in:
dimitr 2014-05-14 08:28:13 +00:00
parent 1ca0ace21f
commit 15e8bbd4e8

View File

@ -366,12 +366,10 @@ HashJoin::HashJoin(thread_db* tdbb, CompilerScratch* csb, size_t count,
dsc desc;
(*m_leader.keys)[j]->getDesc(tdbb, csb, &desc);
USHORT keyLength = desc.dsc_length;
USHORT keyLength = desc.isText() ? desc.getStringLength() : desc.dsc_length;
if (IS_INTL_DATA(&desc))
keyLength = INTL_key_length(tdbb, INTL_INDEX_TYPE(&desc), desc.dsc_length);
else if (desc.dsc_dtype == dtype_varying)
keyLength -= sizeof(USHORT);
keyLength = INTL_key_length(tdbb, INTL_INDEX_TYPE(&desc), keyLength);
m_leader.keyLengths->add(keyLength);
m_leader.totalKeyLength += keyLength;
@ -394,12 +392,10 @@ HashJoin::HashJoin(thread_db* tdbb, CompilerScratch* csb, size_t count,
dsc desc;
(*sub.keys)[j]->getDesc(tdbb, csb, &desc);
USHORT keyLength = desc.dsc_length;
USHORT keyLength = desc.isText() ? desc.getStringLength() : desc.dsc_length;
if (IS_INTL_DATA(&desc))
keyLength = INTL_key_length(tdbb, INTL_INDEX_TYPE(&desc), desc.dsc_length);
else if (desc.dsc_dtype == dtype_varying)
keyLength -= sizeof(USHORT);
keyLength = INTL_key_length(tdbb, INTL_INDEX_TYPE(&desc), keyLength);
sub.keyLengths->add(keyLength);
sub.totalKeyLength += keyLength;
@ -641,37 +637,35 @@ void HashJoin::computeKeys(thread_db* tdbb, jrd_req* request,
{
for (size_t i = 0; i < sub.keys->getCount(); i++)
{
const dsc* const desc = EVL_expr(tdbb, request, (*sub.keys)[i]);
dsc* const desc = EVL_expr(tdbb, request, (*sub.keys)[i]);
const USHORT keyLength = (*sub.keyLengths)[i];
if (desc && !(request->req_flags & req_null))
{
USHORT length = desc->dsc_length;
UCHAR* address = desc->dsc_address;
MoveBuffer buffer;
if (IS_INTL_DATA(desc))
if (desc->isText())
{
// Convert the INTL string into the binary comparable form
dsc to;
to.makeText(keyLength, ttype_binary, keyBuffer);
address = buffer.getBuffer(keyLength);
dsc temp;
temp.makeText(keyLength, ttype_sort_key, address);
length = INTL_string_to_key(tdbb, INTL_INDEX_TYPE(desc),
desc, &temp, INTL_KEY_UNIQUE);
if (IS_INTL_DATA(desc))
{
// Convert the INTL string into the binary comparable form
INTL_string_to_key(tdbb, INTL_INDEX_TYPE(desc),
desc, &to, INTL_KEY_UNIQUE);
}
else
{
// This call ensures that the padding bytes are appended
MOV_move(tdbb, desc, &to);
}
}
else if (desc->dsc_dtype == dtype_varying)
else
{
length -= sizeof(USHORT);
address += sizeof(USHORT);
// We don't enforce proper alignments inside the key buffer,
// so use plain byte copying instead of MOV_move() to avoid bus errors
fb_assert(keyLength == desc->dsc_length);
memcpy(keyBuffer, desc->dsc_address, keyLength);
}
fb_assert(length <= keyLength);
memcpy(keyBuffer, address, length);
}
keyBuffer += keyLength;