On 11-2-2012 16:03, Mark Rotteveel wrote:
> And just after I sent my mail I thought of a potential cause which I am
> now investigating. It looks like the XSQLVAR sqllen field 4, while the
> data array was only 1 entry long. Reducing the sqllen to the actual
> length of the array *or* padding the array seems to fix it.
>
> Which course of action would be better? Padding the data array or
> reducing the sqllen to the actual length?
It looks like the native code of Jaybird should take care of this, but
actually doesn't when the datatype is CHAR (SQL_TEXT)
The code in question is in xsqlda_wrapper.cpp (in
client-java/src/native/jaygds/source, specifically the code below.
Do you see anything wrong with this?
Also when looking at this I am wondering at a few things:
* Is the size being allocated for SQL_TEXT right? It is allocating
sqllen + 1 and null-terminating it, while looking at the Interbase 6
ApiGuide they are always allocating sqllen and not null-terminating
* Is the size being allocated to data for SQL_VARYING right, shouldn't
the actual size of the byteArray[1] + 3 (or 2) be sufficient instead of
sqllen + 3 (especially for UTF8 and for strings shorter than the maximum
size this is larger than necessary)
* Also is the size + 3 and null-terminating the right course of action
for SQL_VARYING?
* For all datatypes other than SQL_VARYING, it is first storing
byteArray size and then overwriting that with the byteArray, so actually
storing that size first is unnecessary, right?
* Is 0x20 (space) the right pad char for connection characterset NONE?
[1] This byteArray is coming from Java and for UTF8 a single character
in the ASCII range would be just a single byte.
const bool isVarying = ( (currentXsqlvar.sqltype & ~1) == SQL_VARYING );
const int dataSizeToAllocate = isVarying ? currentXsqlvar.sqllen + 3 :
currentXsqlvar.sqllen + 1;
currentXsqlvar.sqldata = mAllocator.AllocateMemory(dataSizeToAllocate);
if( isVarying )
{
memset(currentXsqlvar.sqldata, 0, 2);
memset(currentXsqlvar.sqldata+2, ' ', currentXsqlvar.sqllen);
currentXsqlvar.sqldata[currentXsqlvar.sqllen+2] = '\0';
}
else if( ( (currentXsqlvar.sqltype & ~1) == SQL_TEXT ) )
{
memset(currentXsqlvar.sqldata, ' ', currentXsqlvar.sqllen);
currentXsqlvar.sqldata[currentXsqlvar.sqllen] = '\0';
}
else
{
memset(currentXsqlvar.sqldata, 0, dataSizeToAllocate);
}
if(byteArray.Read() != NULL)
{
if( isVarying )
{
*((short*)currentXsqlvar.sqldata) = (short)byteArray.Size();
memcpy( currentXsqlvar.sqldata + 2, byteArray.Read(),
byteArray.Size());
}
else
{
*((short*)currentXsqlvar.sqldata) = (short)byteArray.Size();
memcpy( currentXsqlvar.sqldata, byteArray.Read(),
byteArray.Size());
}
}
--
Mark Rotteveel
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
Firebird-Devel mailing list, web interface at
https://lists.sourceforge.net/lists/listinfo/firebird-devel