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

Fixed CORE-3672 - Computed index by substring function for long columns.

This commit is contained in:
asfernandes 2012-05-10 16:05:18 +00:00
parent 5697e01098
commit 86d787b83e
3 changed files with 27 additions and 7 deletions

View File

@ -63,6 +63,7 @@ using namespace Jrd;
namespace Jrd {
static const long LONG_POS_MAX = 2147483647;
static const SINT64 MAX_INT64_LIMIT = MAX_SINT64 / 10;
static const SINT64 MIN_INT64_LIMIT = MIN_SINT64 / 10;
static const SINT64 SECONDS_PER_DAY = 24 * 60 * 60;
@ -9492,9 +9493,20 @@ bool SubstringNode::setParameterType(DsqlCompilerScratch* dsqlScratch,
void SubstringNode::genBlr(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->appendUChar(blr_substring);
GEN_expr(dsqlScratch, expr);
GEN_expr(dsqlScratch, start);
GEN_expr(dsqlScratch, length);
if (length)
GEN_expr(dsqlScratch, length);
else
{
dsqlScratch->appendUChar(blr_literal);
dsqlScratch->appendUChar(blr_long);
dsqlScratch->appendUChar(0);
dsqlScratch->appendUShort(LONG_POS_MAX);
dsqlScratch->appendUShort(LONG_POS_MAX >> 16);
}
}
void SubstringNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
@ -9503,9 +9515,10 @@ void SubstringNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
MAKE_desc(dsqlScratch, &desc1, expr);
MAKE_desc(dsqlScratch, &desc2, start);
MAKE_desc(dsqlScratch, &desc3, length);
if (length)
MAKE_desc(dsqlScratch, &desc3, length);
DSqlDataTypeUtil(dsqlScratch).makeSubstr(desc, &desc1, &desc2, &desc3);
DSqlDataTypeUtil(dsqlScratch).makeSubstr(desc, &desc1, &desc2, (length ? &desc3 : NULL));
}
void SubstringNode::getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc)

View File

@ -101,7 +101,6 @@
const long SHRT_POS_MAX = 32767;
const long SHRT_UNSIGNED_MAX = 65535;
const long SHRT_NEG_MAX = 32768;
const long LONG_POS_MAX = 2147483647;
const int POSITIVE = 0;
const int NEGATIVE = 1;
const int UNSIGNED = 2;
@ -6255,7 +6254,7 @@ substring_function
%type <valueExprNode> string_length_opt
string_length_opt
: /* nothing */ { $$ = MAKE_const_slong(LONG_POS_MAX); }
: /* nothing */ { $$ = NULL; }
| FOR value { $$ = $2; }
;

View File

@ -28,6 +28,7 @@
#include "../jrd/DataTypeUtil.h"
#include "../jrd/SysFunction.h"
#include "../jrd/align.h"
#include "../common/cvt.h"
#include "../common/dsc.h"
#include "../jrd/ibase.h"
#include "../jrd/intl.h"
@ -300,10 +301,17 @@ void DataTypeUtilBase::makeSubstr(dsc* result, const dsc* value, const dsc* offs
}
result->setTextType(value->getTextType());
result->setNullable(value->isNullable() || offset->isNullable() || length->isNullable());
result->setNullable(value->isNullable() || offset->isNullable() || (length && length->isNullable()));
if (result->isText())
result->dsc_length = fixLength(result, convertLength(value, result)) + sizeof(USHORT);
{
SLONG len = convertLength(value, result);
if (length && length->dsc_address) // constant
len = MIN(len, CVT_get_long(length, 0, ERR_post) * maxBytesPerChar(result->getCharSet()));
result->dsc_length = fixLength(result, len) + sizeof(USHORT);
}
}