MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / perform

Method perform

src/dsql/ExprNodes.cpp:11834–11985  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

11832}
11833
11834dsc* SubstringNode::perform(thread_db* tdbb, impure_value* impure, const dsc* valueDsc,
11835 const dsc* startDsc, const dsc* lengthDsc)
11836{
11837 SINT64 sStart = MOV_get_long(tdbb, startDsc, 0);
11838 SINT64 sLength = MOV_get_long(tdbb, lengthDsc, 0);
11839
11840 if (sLength < 0)
11841 status_exception::raise(Arg::Gds(isc_bad_substring_length) << Arg::Num(sLength));
11842
11843 if (sStart < 0)
11844 {
11845 sLength = MAX(sLength + sStart, 0);
11846 sStart = 0;
11847 }
11848
11849 FB_UINT64 start = FB_UINT64(sStart);
11850 FB_UINT64 length = FB_UINT64(sLength);
11851
11852 dsc desc;
11853 DataTypeUtil(tdbb).makeSubstr(&desc, valueDsc, startDsc, lengthDsc);
11854
11855 if (desc.isText() && length > MAX_STR_SIZE)
11856 length = MAX_STR_SIZE;
11857
11858 ULONG dataLen;
11859
11860 if (valueDsc->isBlob())
11861 {
11862 // Source string is a blob, things get interesting.
11863
11864 fb_assert(desc.dsc_dtype == dtype_blob);
11865
11866 desc.dsc_address = (UCHAR*) &impure->vlu_misc.vlu_bid;
11867
11868 blb* newBlob = blb::create(tdbb, tdbb->getRequest()->req_transaction, &impure->vlu_misc.vlu_bid);
11869
11870 blb* blob = blb::open(tdbb, tdbb->getRequest()->req_transaction,
11871 reinterpret_cast<bid*>(valueDsc->dsc_address));
11872
11873 HalfStaticArray<UCHAR, BUFFER_LARGE> buffer;
11874 CharSet* charSet = INTL_charset_lookup(tdbb, valueDsc->getCharSet());
11875
11876 const FB_UINT64 byte_offset = start * charSet->maxBytesPerChar();
11877 const FB_UINT64 byte_length = length * charSet->maxBytesPerChar();
11878
11879 if (charSet->isMultiByte())
11880 {
11881 buffer.getBuffer(MIN(blob->blb_length, byte_offset + byte_length));
11882 dataLen = blob->BLB_get_data(tdbb, buffer.begin(), buffer.getCount(), false);
11883
11884 HalfStaticArray<UCHAR, BUFFER_LARGE> buffer2;
11885 buffer2.getBuffer(dataLen);
11886
11887 dataLen = charSet->substring(dataLen, buffer.begin(),
11888 buffer2.getCapacity(), buffer2.begin(), start, length);
11889 newBlob->BLB_put_data(tdbb, buffer2.begin(), dataLen);
11890 }
11891 else if (byte_offset < blob->blb_length)

Callers

nothing calls this directly

Calls 15

MOV_get_longFunction · 0.85
raiseFunction · 0.85
GdsClass · 0.85
NumClass · 0.85
DataTypeUtilClass · 0.85
createFunction · 0.85
INTL_charset_lookupFunction · 0.85
EVL_make_valueFunction · 0.85
MOV_get_string_ptrFunction · 0.85
makeSubstrMethod · 0.80
isTextMethod · 0.80
isBlobMethod · 0.80

Tested by

no test coverage detected