@@ -10282,17 +10282,6 @@ void SubstringNode::getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc)
10282
10282
desc->dsc_flags |= DSC_null;
10283
10283
else
10284
10284
{
10285
- if (offsetNode->is <LiteralNode>() && desc1.dsc_dtype == dtype_long)
10286
- {
10287
- SLONG offset = MOV_get_long (&desc1, 0 );
10288
-
10289
- if (decrementNode && decrementNode->is <LiteralNode>() && desc3.dsc_dtype == dtype_long)
10290
- offset -= MOV_get_long (&desc3, 0 );
10291
-
10292
- if (offset < 0 )
10293
- ERR_post (Arg::Gds (isc_bad_substring_offset) << Arg::Num (offset + 1 ));
10294
- }
10295
-
10296
10285
if (length->is <LiteralNode>() && desc2.dsc_dtype == dtype_long)
10297
10286
{
10298
10287
const SLONG len = MOV_get_long (&desc2, 0 );
@@ -10349,20 +10338,24 @@ dsc* SubstringNode::execute(thread_db* tdbb, jrd_req* request) const
10349
10338
dsc* SubstringNode::perform (thread_db* tdbb, impure_value* impure, const dsc* valueDsc,
10350
10339
const dsc* startDsc, const dsc* lengthDsc)
10351
10340
{
10352
- const SLONG sStart = MOV_get_long (startDsc, 0 );
10353
- const SLONG sLength = MOV_get_long (lengthDsc, 0 );
10341
+ SINT64 sStart = MOV_get_long (startDsc, 0 );
10342
+ SINT64 sLength = MOV_get_long (lengthDsc, 0 );
10354
10343
10355
- if (sStart < 0 )
10356
- status_exception::raise (Arg::Gds (isc_bad_substring_offset) << Arg::Num (sStart + 1 ));
10357
- else if (sLength < 0 )
10344
+ if (sLength < 0 )
10358
10345
status_exception::raise (Arg::Gds (isc_bad_substring_length) << Arg::Num (sLength ));
10359
10346
10347
+ if (sStart < 0 )
10348
+ {
10349
+ sLength = MAX (sLength + sStart , 0 );
10350
+ sStart = 1 ;
10351
+ }
10352
+
10353
+ FB_UINT64 start = FB_UINT64 (sStart );
10354
+ FB_UINT64 length = FB_UINT64 (sLength );
10355
+
10360
10356
dsc desc;
10361
10357
DataTypeUtil (tdbb).makeSubstr (&desc, valueDsc, startDsc, lengthDsc);
10362
10358
10363
- ULONG start = (ULONG) sStart ;
10364
- ULONG length = (ULONG) sLength ;
10365
-
10366
10359
if (desc.isText () && length > MAX_STR_SIZE)
10367
10360
length = MAX_STR_SIZE;
10368
10361
@@ -10384,7 +10377,7 @@ dsc* SubstringNode::perform(thread_db* tdbb, impure_value* impure, const dsc* va
10384
10377
HalfStaticArray<UCHAR, BUFFER_LARGE> buffer;
10385
10378
CharSet* charSet = INTL_charset_lookup (tdbb, valueDsc->getCharSet ());
10386
10379
10387
- const FB_UINT64 byte_offset = FB_UINT64 ( start) * charSet->maxBytesPerChar ();
10380
+ const FB_UINT64 byte_offset = start * charSet->maxBytesPerChar ();
10388
10381
const FB_UINT64 byte_length = FB_UINT64 (length) * charSet->maxBytesPerChar ();
10389
10382
10390
10383
if (charSet->isMultiByte ())
0 commit comments