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