Page 1 of 1

[patch_done] Invalid size of string fields

Posted: 25.09.2012, 10:07
by raistware
ZQuery.FieldDefs gets incorrect size when fieldtype is ftString, checked with firebird-2.5.

Size is incorrectly multiplied by 4, so if table field is defined at database as varchar(10), ZQuery.FieldDefs tells as if defined varchar(40).

Posted: 25.09.2012, 12:37
by EgonHugeist
raistware,

this was done with a good reason! And it is a known issue. Field.Size is NOT Field.DisplayWidth. Field.Size means count of bytes. One UTF8-Char char can have a size of 1-4Bytes/Char. Nothing prevents you to assign the fields in the Property-Editors and rearrange the DisplayWidth.

What do you think happens if you try to insert some chinese characters and they are trunced after refresh?

But you are right for the Unicode-Compilers where one UTF8 4Byte char needs only 2Byte(except some EUC/SJS chars)/WideChar... Which compiler do you use?

Posted: 25.09.2012, 12:38
by Zoran
raistware wrote:ZQuery.FieldDefs gets incorrect size when fieldtype is ftString, checked with firebird-2.5.

Size is incorrectly multiplied by 4, so if table field is defined at database as varchar(10), ZQuery.FieldDefs tells as if defined varchar(40).
The size in characters can differ from size in bytes.
I believe that Zeos must make room for the longest possible string in bytes and if your database is utf8 encoded, then one character can occupy up to four bytes that is why fields are made to get four times length of your definition in db.

However, if you know that you don't use characters longer than two bytes (which is I believe true for all european languages characters — that includes all latin, cyrilic or greek letters — do not occupy more than two bytes in utf8), then I believe that you can safely change the size to 2 * defined size.

Apart from Size property, there is also DisplayWidth, which should not be larger then field size defined in your db. However, it is also 4 * defined size. I can't tell if this can be fixed.

Posted: 25.09.2012, 12:43
by EgonHugeist
Zoran,

woops you was also typing here.
I can't tell if this can be changed.
Well with some extra code, known active client codepage and CountOfBytes/char/(IDE_UsedBytes/Char) can this be done. But again DisplayWidth is not Field.Size. Also do we have problems if a user adds Calcultated Fields which can't be handled from our internal MetaInformations. Next point is IF we do this for the user what happens IF this behavior is wanted...

A nigthmare...

Posted: 25.09.2012, 13:03
by raistware
Well, so for FieldType ftString I need to do FieldDefs[FieldIndex].Size / 4 to get real printed characters? Why not use other field (like precision) to store 'extended' size and let FieldDefs[].Size store just what field metadata should have?

As far as I know if I create a table like:
Create table t1 (
f1 varchar(10)
)

For me it's a bug if FieldDefs[f1.index].Size is not 10.

Posted: 25.09.2012, 14:48
by EgonHugeist
raistware,
FieldDefs[FieldIndex].Size / 4 to get real printed characters?
No. Again: Bytes are not visible characters! I made Zeos a little bit smarter accordingly such constants.

I've commited a patch for FireBird which works nice except you have the fields assigned before. Which means place a TZDataSet component to your formular link it with a DBGrid and open it. The ColumnDisplaySize is now arranged(10 instead of 40) but not Field.Size! This is impossible! If you assign the Fields @designtime then YOU have to do it because i don't know what you want and i'm not willing to play with your defaults, eye?!

Btw. FireBird does return the Size in Bytes we need and not Zeos does something wrong here!

Patch done R1855 \testing.

If that is not enought for you i propose you write Borland, Inprice, Codegear, Embarcadero, FPC/Lazarus that the should use Chars instead of Bytes for there FieldBuffers.

Hope this helps you a little bit.

Posted: 25.09.2012, 14:54
by raistware
Thanks, I will try

Posted: 25.09.2012, 15:40
by EgonHugeist
ok waiting for reply..

Posted: 25.09.2012, 15:58
by raistware
It helps, thanks a lot.