mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 04:43:03 +01:00
Fixed bug #7256 : Inconsistent conversion of non-TEXT blobs in BLOB_APPEND
Changed according to discussion on GH.
This commit is contained in:
parent
275245ad22
commit
517fc10a4f
@ -1246,19 +1246,54 @@ void makeBinShift(DataTypeUtilBase*, const SysFunction* function, dsc* result,
|
||||
}
|
||||
|
||||
|
||||
bool makeBlobAppendBlob(dsc* result, const dsc* arg, bid* blob_id = nullptr)
|
||||
{
|
||||
if (!arg)
|
||||
return false;
|
||||
|
||||
ISC_QUAD* ptr = reinterpret_cast<ISC_QUAD*>(blob_id);
|
||||
|
||||
if (arg->isBlob())
|
||||
{
|
||||
result->makeBlob(arg->getBlobSubType(), arg->getTextType(), ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (arg->isNull())
|
||||
return false;
|
||||
|
||||
if (arg->isText())
|
||||
{
|
||||
USHORT ttype = arg->getTextType();
|
||||
if (ttype == ttype_binary)
|
||||
result->makeBlob(isc_blob_untyped, ttype_binary, ptr);
|
||||
else
|
||||
result->makeBlob(isc_blob_text, ttype, ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
result->makeBlob(isc_blob_text, ttype_ascii, ptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void makeBlobAppend(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result,
|
||||
int argsCount, const dsc** args)
|
||||
{
|
||||
if (argsCount > 0 && args[0])
|
||||
if (argsCount > 0)
|
||||
{
|
||||
auto arg = args[0];
|
||||
if (arg->isBlob())
|
||||
result->makeBlob(arg->getBlobSubType(), arg->getTextType());
|
||||
else if (arg->isText())
|
||||
result->makeBlob(isc_blob_text, arg->getTextType());
|
||||
const dsc** ppArg = args;
|
||||
const dsc** const end = args + argsCount;
|
||||
|
||||
for (; ppArg < end; ppArg++)
|
||||
if (makeBlobAppendBlob(result, *ppArg))
|
||||
return;
|
||||
}
|
||||
else
|
||||
result->makeBlob(isc_blob_text, CS_dynamic);
|
||||
|
||||
fb_assert(false);
|
||||
result->makeBlob(isc_blob_untyped, ttype_binary);
|
||||
}
|
||||
|
||||
|
||||
@ -2331,8 +2366,6 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
|
||||
jrd_tra* transaction = request ? request->req_transaction : tdbb->getTransaction();
|
||||
transaction = transaction->getOuter();
|
||||
|
||||
USHORT ttype = tdbb->getCharSet();
|
||||
|
||||
blb* blob = NULL;
|
||||
bid blob_id;
|
||||
dsc blobDsc;
|
||||
@ -2346,21 +2379,13 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
|
||||
if (!arg0_null && argDsc->isBlob())
|
||||
blob_id = *reinterpret_cast<bid*>(argDsc->dsc_address);
|
||||
|
||||
const dsc* declDsc = argDsc;
|
||||
if (!declDsc)
|
||||
declDsc = EVL_assign_to(tdbb, args[0]);
|
||||
|
||||
if (declDsc && declDsc->isBlob())
|
||||
// Try to get blob type from declared var\param
|
||||
if (!argDsc && (nodeIs<VariableNode>(args[0]) ||
|
||||
nodeIs<ParameterNode>(args[0]) ))
|
||||
{
|
||||
ttype = declDsc->getTextType();
|
||||
blobDsc.makeBlob(declDsc->getBlobSubType(), ttype, (ISC_QUAD*)&blob_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (declDsc && declDsc->isText())
|
||||
ttype = declDsc->getTextType();
|
||||
|
||||
blobDsc.makeBlob(isc_blob_text, ttype, (ISC_QUAD*) &blob_id);
|
||||
argDsc = EVL_assign_to(tdbb, args[0]);
|
||||
if (argDsc && argDsc->isBlob())
|
||||
makeBlobAppendBlob(&blobDsc, argDsc, &blob_id);
|
||||
}
|
||||
|
||||
bool copyBlob = !blob_id.isEmpty();
|
||||
@ -2380,23 +2405,6 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
|
||||
}
|
||||
}
|
||||
|
||||
if (!blob)
|
||||
{
|
||||
UCharBuffer bpb;
|
||||
BLB_gen_bpb_from_descs(&blobDsc, &blobDsc, bpb);
|
||||
bpb.push(isc_bpb_storage);
|
||||
bpb.push(1);
|
||||
bpb.push(isc_bpb_storage_temp);
|
||||
|
||||
blob = blb::create2(tdbb, transaction, &blob_id, bpb.getCount(), bpb.begin());
|
||||
blob->blb_flags |= BLB_stream | BLB_close_on_read;
|
||||
}
|
||||
|
||||
// if (copyBlob && argDsc && argDsc->isBlob())
|
||||
// appendFromBlob(tdbb, transaction, blob, &blobDsc, argDsc);
|
||||
|
||||
EVL_make_value(tdbb, &blobDsc, impure);
|
||||
|
||||
for (FB_SIZE_T i = 0; i < args.getCount(); i++)
|
||||
{
|
||||
if (i == 0)
|
||||
@ -2411,11 +2419,30 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!blobDsc.isBlob())
|
||||
if (!makeBlobAppendBlob(&blobDsc, argDsc, &blob_id))
|
||||
continue;
|
||||
|
||||
fb_assert(blobDsc.isBlob());
|
||||
fb_assert(argDsc != nullptr);
|
||||
|
||||
if (!blob)
|
||||
{
|
||||
UCharBuffer bpb;
|
||||
BLB_gen_bpb_from_descs(&blobDsc, &blobDsc, bpb);
|
||||
bpb.push(isc_bpb_storage);
|
||||
bpb.push(1);
|
||||
bpb.push(isc_bpb_storage_temp);
|
||||
|
||||
blob = blb::create2(tdbb, transaction, &blob_id, bpb.getCount(), bpb.begin());
|
||||
blob->blb_flags |= BLB_stream | BLB_close_on_read;
|
||||
}
|
||||
|
||||
if (!argDsc->isBlob())
|
||||
{
|
||||
MoveBuffer temp;
|
||||
UCHAR* addr = NULL;
|
||||
SLONG len = MOV_make_string2(tdbb, argDsc, ttype, &addr, temp);
|
||||
SLONG len = MOV_make_string2(tdbb, argDsc, blobDsc.getTextType(), &addr, temp);
|
||||
|
||||
if (addr)
|
||||
blob->BLB_put_data(tdbb, addr, len);
|
||||
@ -2426,6 +2453,10 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
|
||||
}
|
||||
}
|
||||
|
||||
if (!blob)
|
||||
return nullptr;
|
||||
|
||||
EVL_make_value(tdbb, &blobDsc, impure);
|
||||
return &impure->vlu_desc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user