Thanks for your answers.
The change I have made is this:
Its not very sophisticated and I used already existing functions. I did not
want to make a big change.
First i call toCharSet->length but counting trailing spaces.
If that exceeds the limits I call again toCharSet->length removing trailing
spaces
if that exceeds the limits it throws exception
if not, the length in bytes to copy is calculated with the sentence:
toLength = dest_len + (toLength - src_len);
jrt/cvt.cpp (replace full method EngineCallback:validateLength; sorry for
the indentation):
ULONG EngineCallbacks::validateLength(CharSet* toCharSet, ULONG toLength,
const UCHAR* start,
const USHORT to_size)
{
if (toCharSet && toCharSet->isMultiByte())
{
const ULONG src_len = toCharSet->length(toLength, start, true); //AA
const ULONG dest_len = (ULONG) to_size / toCharSet->maxBytesPerChar();
if (src_len > dest_len)
{
const ULONG srcLenWithoutTrailingSpaces = toCharSet->length(toLength,
start, false); //AA
if (srcLenWithoutTrailingSpaces > dest_len)
{
err(Arg::Gds(isc_arith_except) << Arg::Gds(isc_string_truncation) <<
Arg::Gds(isc_trunc_limits) << Arg::Num(dest_len) <<
Arg::Num(srcLenWithoutTrailingSpaces));
} else {
toLength = dest_len + (toLength - src_len); //length in bytes of chars
truncating at dest_len when there are trailing spaces
}
}
}
return toLength;
}
common/cvt.cpp
in method CVT_move_common, after the lines:
cb->validateData(toCharset, length, q);
ULONG toLength = cb->validateLength(toCharset, length, q, to_size);
i had to put this sentence:
length = toLength;
to make the engine enter this: if (len && toLength == length)
maybe is better changing that 'if' instead, but I did not want to break
something else.
I tested with the following:
set term ^ ;
EXECUTE BLOCK AS BEGIN
INSERT INTO prueba (descripcion) VALUES ('1234567890');
INSERT INTO prueba (descripcion) VALUES ('1234567890
');
INSERT INTO prueba (descripcion) VALUES ('12345678á😉
');
INSERT INTO prueba (descripcion) VALUES ('12345678á😉');
INSERT INTO prueba (descripcion) VALUES ('1234😉');
INSERT INTO prueba (descripcion) VALUES ('Влади́мир');
INSERT INTO prueba (descripcion) VALUES ('Влади́мир
');
INSERT INTO prueba (descripcion) VALUES ('1');
INSERT INTO prueba (descripcion) VALUES ('12');
INSERT INTO prueba (descripcion) VALUES ('123');
INSERT INTO prueba (descripcion) VALUES ('1234');
INSERT INTO prueba (descripcion) VALUES ('12345');
INSERT INTO prueba (descripcion) VALUES ('123456');
INSERT INTO prueba (descripcion) VALUES ('1234567');
INSERT INTO prueba (descripcion) VALUES ('12345678');
INSERT INTO prueba (descripcion) VALUES ('123456789');
INSERT INTO prueba (descripcion) VALUES ('1234567890');
INSERT INTO prueba (descripcion) VALUES ('áéíóú12345');
INSERT INTO prueba (descripcion) VALUES ('Влади́мир ');
INSERT INTO prueba (descripcion) VALUES ('');
END
set term ; ^
performance should be evaluated in at bigger detail.
Let me know If you wish me to make that pull request. I work mostly with
svn so I am not familiarized with git, but I can investigate that.
Regards,
Ariel
El mar., 19 may. 2020 a las 8:23, Adriano dos Santos Fernandes (<
[email protected]>) escribió:
> On 19/05/2020 07:45, Dmitry Yemanov wrote:
> >
> > Truncation at 40 bytes rather than at 10 characters is a bug, however.
> > And this is due to UTF8, single-byte charsets are not affected.
>
> Ok.
>
> Ariel, would be good if you create a pool request in github.
>
>
> Adriano
>
>
>
> Firebird-Devel mailing list, web interface at
> https://lists.sourceforge.net/lists/listinfo/firebird-devel
>
Firebird-Devel mailing list, web interface at
https://lists.sourceforge.net/lists/listinfo/firebird-devel