https://bugs.documentfoundation.org/show_bug.cgi?id=156530

Julien Nabet <[email protected]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |[email protected]

--- Comment #11 from Julien Nabet <[email protected]> ---
Trying to debugging a bit:
when copying the table, we go in:
dbaccess/source/ui/uno/copytablewizard.cxx
1178                     case DataType::CHAR:
1179                     case DataType::VARCHAR:
1180                     case DataType::LONGVARCHAR:
1181                     case DataType::DECIMAL:
1182                     case DataType::NUMERIC:
1183                         aTransfer.transferComplexValue( nSourceColumn,
nDestColumn, &XRow::getString, &XParameters::setString );

(see
https://opengrok.libreoffice.org/xref/core/dbaccess/source/ui/uno/copytablewizard.cxx?r=9d2355b6#1183)

then LO goes in OPreparedStatement::setString
See
https://opengrok.libreoffice.org/xref/core/connectivity/source/drivers/firebird/PreparedStatement.cxx?r=9227fbab#181

and pbs happen:
181 void SAL_CALL OPreparedStatement::setString(sal_Int32 nParameterIndex,
182                                             const OUString& sInput)
...
194     OString str = OUStringToOString(sInput , RTL_TEXTENCODING_UTF8 );
...
198     int dtype = (pVar->sqltype & ~1); // drop flag bit for now
...
200     if (str.getLength() > pVar->sqllen)
201         str = str.copy(0, pVar->sqllen);

"sInput" is "123.45"
"str" is well converted to "123.45"
"dtype" is SQL_LONG (it'll be important next)

str.getLength() is equal to 6 => OK
but
pVar->sqllen = 4 so the str is truncated to "123."
not right but whatever, since "dtype" is SQL_LONG, we go there:
242     case SQL_LONG:
243     {
244         sal_Int32 int32Value = sInput.toInt32();
245         setInt(nParameterIndex, int32Value);
246         break;

so we don't use str but "sInput", sInput which contains "123.45" is converted
to Int32 so 123.


Trying to understand how to fix this, I noticed:
https://opengrok.libreoffice.org/xref/core/offapi/com/sun/star/sdbc/XParameters.idl?r=5687eba4#343
...
334         @param scale
335             for
336             com::sun::star::sdbc::DataType::DECIMAL
337              or
338              com::sun::star::sdbc::DataType::NUMERIC
339              types, this is the number of digits after the decimal point.
For all other types, this value will be ignored.
340         @throws SQLException
341             if a database access error occurs.
342      */
343     void setObjectWithInfo([in]long parameterIndex,
344                               [in]any x, [in]long targetSqlType, [in]long
scale)
345             raises (SQLException);

so "setObjectWithInfo" should be used instead of "setString" in
copytablewizard.cxx part.

but there's no "getObjectWithInfo" in XRow.idl, just "getObject" in
https://opengrok.libreoffice.org/xref/core/offapi/com/sun/star/sdbc/XRow.idl?r=5687eba4#244

Is it sufficient, don't know but I gave a try and then the pb how to adapt the
method "transferValue" or "transferComplexValue", 2 template methods
from
https://opengrok.libreoffice.org/xref/core/dbaccess/source/ui/uno/copytablewizard.cxx?r=9d2355b6#952


In //, I read some info about DECIMAL and NUMERIC here:
https://firebirdsql.org/file/documentation/chunk/en/refdocs/fblangref30/fblangref30-datatypes-fixedtypes.html

a lot of info here but the point to have in mind is this one:
"The form of declaration for fixed-point data, for instance, NUMERIC(p, s), is
common to both types. It is important to realise that the s argument in this
template is scale, rather than "a count of digits after the decimal point".
Understanding the mechanism for storing and retrieving fixed-point data should
help to visualise why: for storage, the number is multiplied by 10s (10 to the
power of s), converting it to an integer; when read, the integer is converted
back."

If I don't misunderstand, it means that in Firebird a DECIMAL or NUMERIC with
display value "123.45" stores physically "12345" plus some info to indicate it
must be divided by 100.


Lionel: perhaps you may have some hints to how to fix this? (for devs in
general because I expect it won't be easy enough for me :-))

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to