Skip to content

Commit a1ff809

Browse files
committed
Return assignment optimization to chosen places
1 parent e1e68d1 commit a1ff809

File tree

8 files changed

+37
-17
lines changed

8 files changed

+37
-17
lines changed

src/common/cvt.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,7 +1648,7 @@ double CVT_get_double(const dsc* desc, DecimalStatus decSt, ErrorFunction err, b
16481648
}
16491649

16501650

1651-
void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* cb)
1651+
void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* cb, bool trustedSource)
16521652
{
16531653
/**************************************
16541654
*
@@ -1673,7 +1673,9 @@ void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* c
16731673
// (real source length must be validated against target maximum length
16741674
// and this is the first common place where both are present).
16751675

1676-
if (DSC_EQUIV(from, to, false) && !DTYPE_IS_TEXT(from->dsc_dtype))
1676+
// ...unless these strings are coming from a trusted source (for example a cached record buffer)
1677+
1678+
if (DSC_EQUIV(from, to, false) && (trustedSource || !DTYPE_IS_TEXT(from->dsc_dtype)))
16771679
{
16781680
if (length) {
16791681
memcpy(p, q, length);
@@ -1987,6 +1989,9 @@ void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* c
19871989
if (cb->transliterate(from, to, charset2))
19881990
return;
19891991

1992+
// At this point both `from` and `to` are guaranteed to have the same charset and this is stored in charset2
1993+
// Because of this we can freely use `toCharset` against `from`.
1994+
19901995
{ // scope
19911996
USHORT strtype_unused;
19921997
UCHAR *ptr;
@@ -1997,8 +2002,23 @@ void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* c
19972002
const USHORT to_size = TEXT_LEN(to);
19982003
CharSet* toCharset = cb->getToCharset(charset2);
19992004

2000-
cb->validateData(toCharset, length, q);
2001-
ULONG toLength = cb->validateLength(toCharset, charset2, length, q, to_size);
2005+
ULONG toLength = length;
2006+
2007+
if (!trustedSource)
2008+
{
2009+
// Most likely data already has been validated once or twice, but another validation won't hurt much.
2010+
cb->validateData(toCharset, length, q);
2011+
toLength = cb->validateLength(toCharset, charset2, length, q, to_size);
2012+
}
2013+
else
2014+
{
2015+
// Silently truncate. In the wild this should never happen
2016+
if (length > to_size)
2017+
{
2018+
fb_assert(from->dsc_dtype == dtype_text);
2019+
toLength = to_size;
2020+
}
2021+
}
20022022

20032023
switch (to->dsc_dtype)
20042024
{
@@ -3776,7 +3796,7 @@ USHORT CVT_get_string_ptr(const dsc* desc, USHORT* ttype, UCHAR** address,
37763796
}
37773797

37783798

3779-
void CVT_move(const dsc* from, dsc* to, DecimalStatus decSt, ErrorFunction err)
3799+
void CVT_move(const dsc* from, dsc* to, DecimalStatus decSt, ErrorFunction err, bool trustedSource)
37803800
{
37813801
/**************************************
37823802
*
@@ -3789,5 +3809,5 @@ void CVT_move(const dsc* from, dsc* to, DecimalStatus decSt, ErrorFunction err)
37893809
*
37903810
**************************************/
37913811
CommonCallbacks callbacks(err);
3792-
CVT_move_common(from, to, decSt, &callbacks);
3812+
CVT_move_common(from, to, decSt, &callbacks, trustedSource);
37933813
}

src/common/cvt.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ Firebird::Decimal128 CVT_get_dec128(const dsc*, Firebird::DecimalStatus, ErrorFu
9595
Firebird::Int128 CVT_get_int128(const dsc*, SSHORT, Firebird::DecimalStatus, ErrorFunction);
9696
Firebird::Int128 CVT_hex_to_int128(const char* str, USHORT len);
9797
USHORT CVT_make_string(const dsc*, USHORT, const char**, vary*, USHORT, Firebird::DecimalStatus, ErrorFunction);
98-
void CVT_move_common(const dsc*, dsc*, Firebird::DecimalStatus, Firebird::Callbacks*);
99-
void CVT_move(const dsc*, dsc*, Firebird::DecimalStatus, ErrorFunction);
98+
void CVT_move_common(const dsc*, dsc*, Firebird::DecimalStatus, Firebird::Callbacks*, bool trustedSource = false);
99+
void CVT_move(const dsc*, dsc*, Firebird::DecimalStatus, ErrorFunction, bool trustedSource = false);
100100
SSHORT CVT_decompose(const char*, USHORT, Firebird::Int128*, ErrorFunction);
101101
USHORT CVT_get_string_ptr(const dsc*, USHORT*, UCHAR**, vary*, USHORT, Firebird::DecimalStatus, ErrorFunction);
102102
USHORT CVT_get_string_ptr_common(const dsc*, USHORT*, UCHAR**, vary*, USHORT, Firebird::DecimalStatus, Firebird::Callbacks*);

src/jrd/mov.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ Firebird::string MOV_make_string2(Jrd::thread_db* tdbb, const dsc* desc, USHORT
438438
}
439439

440440

441-
void MOV_move(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to)
441+
void MOV_move(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to, bool trustedSource)
442442
{
443443
/**************************************
444444
*
@@ -454,7 +454,7 @@ void MOV_move(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to)
454454
if (DTYPE_IS_BLOB_OR_QUAD(from->dsc_dtype) || DTYPE_IS_BLOB_OR_QUAD(to->dsc_dtype))
455455
Jrd::blb::move(tdbb, from, to);
456456
else
457-
CVT_move(from, to, tdbb->getAttachment()->att_dec_status);
457+
CVT_move_common(from, to, tdbb->getAttachment()->att_dec_status, &Jrd::EngineCallbacks::instance, trustedSource);
458458
}
459459

460460

src/jrd/mov_proto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ USHORT MOV_make_string(Jrd::thread_db*, const dsc*, USHORT, const char**, vary*,
5252
ULONG MOV_make_string2(Jrd::thread_db*, const dsc*, USHORT, UCHAR**, Jrd::MoveBuffer&, bool = true);
5353
Firebird::string MOV_make_string2(Jrd::thread_db* tdbb, const dsc* desc, USHORT ttype,
5454
bool limit = true);
55-
void MOV_move(Jrd::thread_db*, /*const*/ dsc*, dsc*);
55+
void MOV_move(Jrd::thread_db*, /*const*/ dsc*, dsc*, bool trustedSource = false);
5656
Firebird::Decimal64 MOV_get_dec64(Jrd::thread_db*, const dsc*);
5757
Firebird::Decimal128 MOV_get_dec128(Jrd::thread_db*, const dsc*);
5858
Firebird::Int128 MOV_get_int128(Jrd::thread_db*, const dsc*, SSHORT);

src/jrd/recsrc/BufferedStream.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ bool BufferedStream::internalGetRecord(thread_db* tdbb) const
199199
switch (map.map_type)
200200
{
201201
case FieldMap::REGULAR_FIELD:
202-
MOV_move(tdbb, &from, &to);
202+
MOV_move(tdbb, &from, &to, true);
203203
break;
204204

205205
case FieldMap::TRANSACTION_ID:
@@ -271,7 +271,7 @@ bool BufferedStream::internalGetRecord(thread_db* tdbb) const
271271
else
272272
{
273273
EVL_field(relation, record, map.map_id, &to);
274-
MOV_move(tdbb, &from, &to);
274+
MOV_move(tdbb, &from, &to, true);
275275
record->clearNull(map.map_id);
276276
}
277277

src/jrd/recsrc/HashJoin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ ULONG HashJoin::computeHash(thread_db* tdbb,
687687
else
688688
{
689689
// This call ensures that the padding bytes are appended
690-
MOV_move(tdbb, desc, &to);
690+
MOV_move(tdbb, desc, &to, true);
691691
}
692692
}
693693
else

src/jrd/recsrc/SortedStream.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ Sort* SortedStream::init(thread_db* tdbb) const
278278
}
279279
else
280280
{
281-
MOV_move(tdbb, from, &to);
281+
MOV_move(tdbb, from, &to, true);
282282
}
283283
}
284284
}
@@ -438,7 +438,7 @@ void SortedStream::mapData(thread_db* tdbb, Request* request, UCHAR* data) const
438438
else
439439
{
440440
EVL_field(relation, record, id, &to);
441-
MOV_move(tdbb, &from, &to);
441+
MOV_move(tdbb, &from, &to, true);
442442
record->clearNull(id);
443443
}
444444
}

src/jrd/recsrc/WindowedStream.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ bool WindowedStream::WindowStream::internalGetRecord(thread_db* tdbb) const
889889
record->setNull(id);
890890
else
891891
{
892-
MOV_move(tdbb, desc, EVL_assign_to(tdbb, *target));
892+
MOV_move(tdbb, desc, EVL_assign_to(tdbb, *target), true);
893893
record->clearNull(id);
894894
}
895895

0 commit comments

Comments
 (0)