@@ -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+
12491282void 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