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.
