Skip to content

Commit 517fc10

Browse files
committed
Fixed bug #7256 : Inconsistent conversion of non-TEXT blobs in BLOB_APPEND
Changed according to discussion on GH.
1 parent 275245a commit 517fc10

File tree

1 file changed

+73
-42
lines changed

1 file changed

+73
-42
lines changed

src/jrd/SysFunction.cpp

Lines changed: 73 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,19 +1246,54 @@ void makeBinShift(DataTypeUtilBase*, const SysFunction* function, dsc* result,
12461246
}
12471247

12481248

1249+
bool makeBlobAppendBlob(dsc* result, const dsc* arg, bid* blob_id = nullptr)
1250+
{
1251+
if (!arg)
1252+
return false;
1253+
1254+
ISC_QUAD* ptr = reinterpret_cast<ISC_QUAD*>(blob_id);
1255+
1256+
if (arg->isBlob())
1257+
{
1258+
result->makeBlob(arg->getBlobSubType(), arg->getTextType(), ptr);
1259+
return true;
1260+
}
1261+
1262+
if (arg->isNull())
1263+
return false;
1264+
1265+
if (arg->isText())
1266+
{
1267+
USHORT ttype = arg->getTextType();
1268+
if (ttype == ttype_binary)
1269+
result->makeBlob(isc_blob_untyped, ttype_binary, ptr);
1270+
else
1271+
result->makeBlob(isc_blob_text, ttype, ptr);
1272+
}
1273+
else
1274+
{
1275+
result->makeBlob(isc_blob_text, ttype_ascii, ptr);
1276+
}
1277+
1278+
return true;
1279+
}
1280+
1281+
12491282
void makeBlobAppend(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result,
12501283
int argsCount, const dsc** args)
12511284
{
1252-
if (argsCount > 0 && args[0])
1285+
if (argsCount > 0)
12531286
{
1254-
auto arg = args[0];
1255-
if (arg->isBlob())
1256-
result->makeBlob(arg->getBlobSubType(), arg->getTextType());
1257-
else if (arg->isText())
1258-
result->makeBlob(isc_blob_text, arg->getTextType());
1287+
const dsc** ppArg = args;
1288+
const dsc** const end = args + argsCount;
1289+
1290+
for (; ppArg < end; ppArg++)
1291+
if (makeBlobAppendBlob(result, *ppArg))
1292+
return;
12591293
}
1260-
else
1261-
result->makeBlob(isc_blob_text, CS_dynamic);
1294+
1295+
fb_assert(false);
1296+
result->makeBlob(isc_blob_untyped, ttype_binary);
12621297
}
12631298

12641299

@@ -2331,8 +2366,6 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
23312366
jrd_tra* transaction = request ? request->req_transaction : tdbb->getTransaction();
23322367
transaction = transaction->getOuter();
23332368

2334-
USHORT ttype = tdbb->getCharSet();
2335-
23362369
blb* blob = NULL;
23372370
bid blob_id;
23382371
dsc blobDsc;
@@ -2346,21 +2379,13 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
23462379
if (!arg0_null && argDsc->isBlob())
23472380
blob_id = *reinterpret_cast<bid*>(argDsc->dsc_address);
23482381

2349-
const dsc* declDsc = argDsc;
2350-
if (!declDsc)
2351-
declDsc = EVL_assign_to(tdbb, args[0]);
2352-
2353-
if (declDsc && declDsc->isBlob())
2382+
// Try to get blob type from declared var\param
2383+
if (!argDsc && (nodeIs<VariableNode>(args[0]) ||
2384+
nodeIs<ParameterNode>(args[0]) ))
23542385
{
2355-
ttype = declDsc->getTextType();
2356-
blobDsc.makeBlob(declDsc->getBlobSubType(), ttype, (ISC_QUAD*)&blob_id);
2357-
}
2358-
else
2359-
{
2360-
if (declDsc && declDsc->isText())
2361-
ttype = declDsc->getTextType();
2362-
2363-
blobDsc.makeBlob(isc_blob_text, ttype, (ISC_QUAD*) &blob_id);
2386+
argDsc = EVL_assign_to(tdbb, args[0]);
2387+
if (argDsc && argDsc->isBlob())
2388+
makeBlobAppendBlob(&blobDsc, argDsc, &blob_id);
23642389
}
23652390

23662391
bool copyBlob = !blob_id.isEmpty();
@@ -2380,23 +2405,6 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
23802405
}
23812406
}
23822407

2383-
if (!blob)
2384-
{
2385-
UCharBuffer bpb;
2386-
BLB_gen_bpb_from_descs(&blobDsc, &blobDsc, bpb);
2387-
bpb.push(isc_bpb_storage);
2388-
bpb.push(1);
2389-
bpb.push(isc_bpb_storage_temp);
2390-
2391-
blob = blb::create2(tdbb, transaction, &blob_id, bpb.getCount(), bpb.begin());
2392-
blob->blb_flags |= BLB_stream | BLB_close_on_read;
2393-
}
2394-
2395-
// if (copyBlob && argDsc && argDsc->isBlob())
2396-
// appendFromBlob(tdbb, transaction, blob, &blobDsc, argDsc);
2397-
2398-
EVL_make_value(tdbb, &blobDsc, impure);
2399-
24002408
for (FB_SIZE_T i = 0; i < args.getCount(); i++)
24012409
{
24022410
if (i == 0)
@@ -2411,11 +2419,30 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
24112419
continue;
24122420
}
24132421

2422+
if (!blobDsc.isBlob())
2423+
if (!makeBlobAppendBlob(&blobDsc, argDsc, &blob_id))
2424+
continue;
2425+
2426+
fb_assert(blobDsc.isBlob());
2427+
fb_assert(argDsc != nullptr);
2428+
2429+
if (!blob)
2430+
{
2431+
UCharBuffer bpb;
2432+
BLB_gen_bpb_from_descs(&blobDsc, &blobDsc, bpb);
2433+
bpb.push(isc_bpb_storage);
2434+
bpb.push(1);
2435+
bpb.push(isc_bpb_storage_temp);
2436+
2437+
blob = blb::create2(tdbb, transaction, &blob_id, bpb.getCount(), bpb.begin());
2438+
blob->blb_flags |= BLB_stream | BLB_close_on_read;
2439+
}
2440+
24142441
if (!argDsc->isBlob())
24152442
{
24162443
MoveBuffer temp;
24172444
UCHAR* addr = NULL;
2418-
SLONG len = MOV_make_string2(tdbb, argDsc, ttype, &addr, temp);
2445+
SLONG len = MOV_make_string2(tdbb, argDsc, blobDsc.getTextType(), &addr, temp);
24192446

24202447
if (addr)
24212448
blob->BLB_put_data(tdbb, addr, len);
@@ -2426,6 +2453,10 @@ dsc* evlBlobAppend(thread_db* tdbb, const SysFunction* function, const NestValue
24262453
}
24272454
}
24282455

2456+
if (!blob)
2457+
return nullptr;
2458+
2459+
EVL_make_value(tdbb, &blobDsc, impure);
24292460
return &impure->vlu_desc;
24302461
}
24312462

0 commit comments

Comments
 (0)