Skip to content

Commit 2f459bb

Browse files
author
Artyom Abakumov
committed
Move impure-related string allocation to helper methods
1 parent 29bca14 commit 2f459bb

File tree

6 files changed

+54
-118
lines changed

6 files changed

+54
-118
lines changed

src/common/dsc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ typedef struct dsc
228228
return dsc_dtype == dtype_unknown;
229229
}
230230

231+
bool hasDynamicLength() const
232+
{
233+
return isText(); // TODO: add isJson();
234+
}
235+
231236
SSHORT getBlobSubType() const
232237
{
233238
if (isBlob())

src/dsql/ExprNodes.cpp

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3752,25 +3752,8 @@ dsc* CastNode::perform(thread_db* tdbb, impure_value* impure, dsc* value,
37523752
impure->vlu_desc.dsc_length = length;
37533753
}
37543754

3755-
length = impure->vlu_desc.dsc_length;
3756-
37573755
// Allocate a string block of sufficient size.
3758-
3759-
auto string = impure->vlu_string;
3760-
3761-
if (string && string->str_length < length)
3762-
{
3763-
delete string;
3764-
string = nullptr;
3765-
}
3766-
3767-
if (!string)
3768-
{
3769-
string = impure->vlu_string = FB_NEW_RPT(*tdbb->getDefaultPool(), length) VaryingString();
3770-
string->str_length = length;
3771-
}
3772-
3773-
impure->vlu_desc.dsc_address = string->str_data;
3756+
impure->allocateTextImpureDscAddress(*tdbb->getDefaultPool());
37743757
}
37753758

37763759
EVL_validate(tdbb, Item(Item::TYPE_CAST), itemInfo,
@@ -7139,29 +7122,7 @@ dsc* FieldNode::execute(thread_db* tdbb, Request* request) const
71397122
dsc desc = impure->vlu_desc;
71407123
impure->vlu_desc = format->fmt_desc[fieldId];
71417124

7142-
if (impure->vlu_desc.isText())
7143-
{
7144-
// Allocate a string block of sufficient size.
7145-
VaryingString* string = impure->vlu_string;
7146-
7147-
if (string && string->str_length < impure->vlu_desc.dsc_length)
7148-
{
7149-
delete string;
7150-
string = NULL;
7151-
}
7152-
7153-
if (!string)
7154-
{
7155-
string = impure->vlu_string = FB_NEW_RPT(*tdbb->getDefaultPool(),
7156-
impure->vlu_desc.dsc_length) VaryingString();
7157-
string->str_length = impure->vlu_desc.dsc_length;
7158-
}
7159-
7160-
impure->vlu_desc.dsc_address = string->str_data;
7161-
}
7162-
else
7163-
impure->vlu_desc.dsc_address = (UCHAR*) &impure->vlu_misc;
7164-
7125+
impure->makeImpureDscAddress(*tdbb->getDefaultPool());
71657126
MOV_move(tdbb, &desc, &impure->vlu_desc);
71667127
}
71677128

@@ -13687,30 +13648,7 @@ dsc* UdfCallNode::execute(thread_db* tdbb, Request* request) const
1368713648
const Parameter* const returnParam = function->getOutputFields()[0];
1368813649
value->vlu_desc = returnParam->prm_desc;
1368913650

13690-
// If the return data type is any of the string types, allocate space to hold value.
13691-
13692-
if (value->vlu_desc.dsc_dtype <= dtype_varying)
13693-
{
13694-
const USHORT retLength = value->vlu_desc.dsc_length;
13695-
VaryingString* string = value->vlu_string;
13696-
13697-
if (string && string->str_length < retLength)
13698-
{
13699-
delete string;
13700-
string = NULL;
13701-
}
13702-
13703-
if (!string)
13704-
{
13705-
string = FB_NEW_RPT(*tdbb->getDefaultPool(), retLength) VaryingString;
13706-
string->str_length = retLength;
13707-
value->vlu_string = string;
13708-
}
13709-
13710-
value->vlu_desc.dsc_address = string->str_data;
13711-
}
13712-
else
13713-
value->vlu_desc.dsc_address = (UCHAR*) &value->vlu_misc;
13651+
value->makeImpureDscAddress(*tdbb->getDefaultPool());
1371413652

1371513653
if (!impureArea->temp)
1371613654
{

src/dsql/StmtNodes.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,19 +2248,7 @@ const StmtNode* DeclareVariableNode::execute(thread_db* tdbb, Request* request,
22482248
variable->vlu_desc = varDesc;
22492249
variable->vlu_desc.clearFlags();
22502250

2251-
if (variable->vlu_desc.dsc_dtype <= dtype_varying)
2252-
{
2253-
if (!variable->vlu_string)
2254-
{
2255-
const USHORT len = variable->vlu_desc.dsc_length;
2256-
variable->vlu_string = FB_NEW_RPT(*tdbb->getDefaultPool(), len) VaryingString();
2257-
variable->vlu_string->str_length = len;
2258-
}
2259-
2260-
variable->vlu_desc.dsc_address = variable->vlu_string->str_data;
2261-
}
2262-
else
2263-
variable->vlu_desc.dsc_address = (UCHAR*) &variable->vlu_misc;
2251+
variable->makeImpureDscAddress(*tdbb->getDefaultPool());
22642252

22652253
request->req_operation = Request::req_return;
22662254
}

src/jrd/SysFunction.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5545,31 +5545,7 @@ dsc* evlMaxMinValue(thread_db* tdbb, const SysFunction* function, const NestValu
55455545

55465546
DataTypeUtil(tdbb).makeFromList(&impure->vlu_desc, function->name, argTypes.getCount(), argTypes.begin());
55475547

5548-
if (impure->vlu_desc.isText())
5549-
{
5550-
const USHORT length = impure->vlu_desc.dsc_length;
5551-
5552-
// Allocate a string block of sufficient size
5553-
5554-
auto string = impure->vlu_string;
5555-
5556-
if (string && string->str_length < length)
5557-
{
5558-
delete string;
5559-
string = nullptr;
5560-
}
5561-
5562-
if (!string)
5563-
{
5564-
string = impure->vlu_string = FB_NEW_RPT(*tdbb->getDefaultPool(), length) VaryingString();
5565-
string->str_length = length;
5566-
}
5567-
5568-
impure->vlu_desc.dsc_address = string->str_data;
5569-
}
5570-
else
5571-
impure->vlu_desc.dsc_address = (UCHAR*) &impure->vlu_misc;
5572-
5548+
impure->makeImpureDscAddress(*tdbb->getDefaultPool());
55735549
MOV_move(tdbb, result, &impure->vlu_desc);
55745550

55755551
if (impure->vlu_desc.dsc_dtype == dtype_text)

src/jrd/evl.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -573,22 +573,10 @@ void EVL_make_value(thread_db* tdbb, const dsc* desc, impure_value* value, Memor
573573

574574
// Allocate a string block of sufficient size.
575575

576-
VaryingString* string = value->vlu_string;
576+
if (!pool)
577+
pool = tdbb->getDefaultPool();
577578

578-
if (string && string->str_length < length)
579-
{
580-
delete string;
581-
string = NULL;
582-
}
583-
584-
if (!string)
585-
{
586-
if (!pool)
587-
pool = tdbb->getDefaultPool();
588-
589-
string = value->vlu_string = FB_NEW_RPT(*pool, length) VaryingString();
590-
string->str_length = length;
591-
}
579+
VaryingString* string = value->getAllocateString(from.dsc_length, *pool);
592580

593581
value->vlu_desc.dsc_length = length;
594582
UCHAR* target = string->str_data;

src/jrd/val.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ struct impure_value
168168
void make_double(const double val);
169169
void make_decimal128(const Firebird::Decimal128 val);
170170
void make_decimal_fixed(const Firebird::Int128 val, const signed char scale);
171+
172+
template<class T>
173+
VaryingString* getAllocateString(T requeuedLength, MemoryPool& pool) = delete; // Prevent dangerous length shrink
174+
VaryingString* getAllocateString(USHORT requeuedLength, MemoryPool& pool);
175+
176+
void makeImpureDscAddress(MemoryPool& pool);
177+
void allocateTextImpureDscAddress(MemoryPool& pool);
171178
};
172179

173180
// Do not use these methods where dsc_sub_type is not explicitly set to zero.
@@ -221,6 +228,40 @@ inline void impure_value::make_decimal_fixed(const Firebird::Int128 val, const s
221228
this->vlu_desc.dsc_address = reinterpret_cast<UCHAR*>(&this->vlu_misc.vlu_int128);
222229
}
223230

231+
inline VaryingString* impure_value::getAllocateString(USHORT requeuedLength, MemoryPool& pool)
232+
{
233+
if (vlu_string && vlu_string->str_length < requeuedLength)
234+
{
235+
delete vlu_string;
236+
vlu_string = nullptr;
237+
}
238+
239+
if (!vlu_string)
240+
{
241+
vlu_string = FB_NEW_RPT(pool, requeuedLength) VaryingString();
242+
vlu_string->str_length = requeuedLength;
243+
}
244+
245+
return vlu_string;
246+
}
247+
248+
inline void impure_value::makeImpureDscAddress(MemoryPool& pool)
249+
{
250+
if (vlu_desc.hasDynamicLength())
251+
{
252+
// If the data type is any of the string types, allocate space to hold value.
253+
allocateTextImpureDscAddress(pool);
254+
}
255+
else
256+
vlu_desc.dsc_address = (UCHAR*) &vlu_misc;
257+
}
258+
259+
inline void impure_value::allocateTextImpureDscAddress(MemoryPool& pool)
260+
{
261+
vlu_desc.dsc_address = getAllocateString(vlu_desc.dsc_length, pool)->str_data;
262+
}
263+
264+
224265
struct impure_value_ex : public impure_value
225266
{
226267
SINT64 vlux_count;

0 commit comments

Comments
 (0)