Bug 40144 - PreparedStatement setDate call from BASIC unnatural; error message wrong and confusing
Summary: PreparedStatement setDate call from BASIC unnatural; error message wrong and ...
Status: NEW
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: BASIC (show other bugs)
Version:
(earliest affected)
3.4 Daily
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: Error-Messages
  Show dependency treegraph
 
Reported: 2011-08-16 08:17 UTC by Lionel Elie Mamane
Modified: 2022-10-15 03:40 UTC (History)
4 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lionel Elie Mamane 2011-08-16 08:17:37 UTC
In Basic, the setDate method on a prepared statement throws error "Objet variable not set", but setString and setInt work as expected. Maybe a cpp_uno bridge problem.

These methods are supposed to come from the XParameters interface served by the object.

I tried with HSQLDB database and with MySQL database and (with my own modified driver) PostgreSQL database.

Adding debug printf's at entrance of these functions shows that dbaccess::OPreparedStatement::setInt and dbaccess::OPreparedStatement::setString are called, but dbaccess::OPreparedStatement::setDate is *never* called.

Basic test code:

Sub Tst_StatementWithDate
	Dim IntrctHndl as Object
	Dim conn as Object
	Dim stmt as Object
	Dim rs as Object
	IntrctHndl = createUnoService("com.sun.star.sdb.InteractionHandler")
	conn = ThisDatabaseDocument.DataSource.connectWithCompletion(IntrctHndl)
	stmt = conn.prepareStatement("SELECT * FROM tblName WHERE tblName.dateColumn > ? LIMIT 1")
	stmt.setString(1, DateSerial(2005, 1, 1))
	stmt.setInt(1, DateSerial(2005, 1, 1))
	stmt.setDate(1, DateSerial(2005, 1, 1))
	rs = stmt.executeQuery()
End Sub


I ran libreoffice under gdb; all the set* calls end up in callVirtualMethod at line 91 in file /home/master/src/libreoffice/libreoffice-3.4/clone/ure/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx

*But* the setInt and setString calls look similar:

Breakpoint 1, callVirtualMethod (pThis=0x1fff560, nVtableIndex=8, pRegisterReturn=0x7fffd50c1370, pReturnTypeRef=0x60ea08, bSimpleReturn=true, 
    pStack=0x7fffd50c0fb0, nStack=0, pGPR=0x7fffd50c1070, nGPR=3, pFPR=0x7fffd50c1030, nFPR=0)
    at /home/master/src/libreoffice/libreoffice-3.4/clone/ure/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:91

with ONLY the nVtableIndex argument changing (8 for setInt and 12 for setString), which sounds good.


But the setDate call looks quite different:


Breakpoint 1, callVirtualMethod (pThis=0x7ffff5fccca0, nVtableIndex=4, pRegisterReturn=0x0, pReturnTypeRef=0x60ea08, bSimpleReturn=true, 
    pStack=0x7fffd50c1030, nStack=0, pGPR=0x7fffd50c10e0, nGPR=1, pFPR=0x7fffd50c10a0, nFPR=0)
    at /home/master/src/libreoffice/libreoffice-3.4/clone/ure/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:91


From there, if I step the code line by line, I end up in the ASM code at lines 120-158; gdb executes that block in _one_ "next" command and the error is there.


But if at entry of callVirtualMethod, I manually set the arguments "right" by copying from the setInt or setString call (and putting 14 for nVtableIndex), then I do end up at dbaccess::OPreparedStatement::setDate:


Breakpoint 1, callVirtualMethod (pThis=0x7ffff5fccca0, nVtableIndex=4, pRegisterReturn=0x0, pReturnTypeRef=0x60ea08, bSimpleReturn=true, 
    pStack=0x7fffd50c1030, nStack=0, pGPR=0x7fffd50c10e0, nGPR=1, pFPR=0x7fffd50c10a0, nFPR=0)
    at /home/master/src/libreoffice/libreoffice-3.4/clone/ure/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:91
91	    if ( !pThis )
(gdb) set pThis=0x1fff560
(gdb) set nVtableIndex=14
(gdb) set pRegisterReturn=0x7fffd50c1370
(gdb) set pStack=0x7fffd50c0fb0
(gdb) set pGPR=0x7fffd50c1070
(gdb) set nGPR=3
(gdb) set pFPR=0x7fffd50c1030
(gdb) c
Continuing.

Breakpoint 2, dbaccess::OPreparedStatement::setDate (this=0xfffffffffffffee0, parameterIndex=0, x=...)
    at /home/master/src/libreoffice/libreoffice-3.4/clone/base/dbaccess/source/core/api/preparedstatement.cxx:341
341	    MutexGuard aGuard(m_aMutex);


Obviously the arguments are all wrong, but this at least shows that the cpp_uno bridge somehow does not call the right member function on the right object.
Comment 1 Lionel Elie Mamane 2011-08-16 08:19:43 UTC
May be useful:

 system: Debian GNU/Linux
 architecture: amd64
 g++ (Debian 4.6.1-4) 4.6.1
 libstdc++6     4.6.1-4
Comment 2 Lionel Elie Mamane 2011-08-17 00:17:21 UTC
Reproduced with:
 LibreOffice 3.3.3
 OOO330m19 (Build:301)
 tag libreoffice-3.3.3.1, Debian package 1:3.3.3-4+b1
Still on amd64

This one was compiled with
 g++ 4:4.6.0-6
 lbstdc++6 4.6.1-1
Comment 3 Lionel Elie Mamane 2011-08-17 05:16:19 UTC
The python scripting does *not* have this problem with LO 3.3 (Debian package as above), still on amd64, on the same computer, so same run-time libstdc++ and all that.

Test script:

import uno
from com.sun.star.util import Date


def getThisDataBaseDocument():
    doc = XSCRIPTCONTEXT.getDocument()
    while not 'com.sun.star.sdb.OfficeDatabaseDocument' in doc.SupportedServiceNames:
        doc = doc.Parent
    return doc


def tst_setDate(e):
    ctx = uno.getComponentContext()
    smgr = ctx.ServiceManager
    IntrcHndl = smgr.createInstanceWithContext( "com.sun.star.task.InteractionHandler",ctx)
    db = getThisDataBaseDocument()
    conn = db.DataSource.connectWithCompletion(IntrcHndl)
    stmt = conn.prepareStatement("SELECT * FROM tblName WHERE colName > ? LIMIT 1")
    stmt.setString(1, "1/1/2005")
    stmt.setInt(1, 18)
    stmt.setDate(1, Date(1, 1, 2005))
    rs = stmt.executeQuery()
    while rs.next():
        print "Col1:", rs.getString(1)
Comment 4 Lionel Elie Mamane 2011-08-18 00:16:07 UTC
Reproduced this with
 OO.org 3.2.1
 OOO320m18 (Build:9502)
on Microsoft Windows.

So the problem is most probably not in architecture/OS-specific bridge code, but in the general Basic<->Uno glue code. Now, what makes "setDate" special, I don't know. My first hunch was another setDate from another interface, but grepping through the code does not find a likely candidate.
Comment 5 Alex Thurgood 2011-08-18 00:53:36 UTC
(In reply to comment #4)

Hi Lionel,

> 
> So the problem is most probably not in architecture/OS-specific bridge code,
> but in the general Basic<->Uno glue code. Now, what makes "setDate" special, I
> don't know. My first hunch was another setDate from another interface, but
> grepping through the code does not find a likely candidate.


I remember reading a reply (in a bug report I think) from Frank Schoenheit (former OOo dba longtime dev also from StarOffice times) where he recognised that there are places in the UNO/CPP code where there are possibly mismatches between functions, or even functions that were included in the CPP, but had no corresponding or conflicting calls in UNO. This might be one of them.


Alex
Comment 6 Alex Thurgood 2011-08-18 01:10:08 UTC
Hmmm,

Trawling around in old stuff brings this up as a known problem, at least in the context of usage of setDate() in prepared statements, see this post from 2009 :

http://www.oooforum.org/forum/viewtopic.phtml?t=86978


Alex
Comment 7 Alex Thurgood 2011-08-18 01:14:07 UTC
Is this of any use ?

http://www.mail-archive.com/dba-bugs@openoffice.org/msg35418.html


Alex
Comment 8 Lionel Elie Mamane 2011-08-20 13:36:26 UTC
(In reply to comment #7)

> Is this of any use ?

> http://www.mail-archive.com/dba-bugs@openoffice.org/msg35418.html

Yes, indeed. If one passes a proper "com.sun.star.util.Date" structure as second argument of setDate(), then it works.

As I understand your link (and generally http://openoffice.org/bugzilla/show_bug.cgi?id=113436), LOBasic/UNO calls the setDate method for a ::com::sun::star::awt::XDateField because the type signature happens to match (a Basic "Date" type is convertible to a long integer). I would consider that a bug; the object "stmt" in my example code does not implement the XDateField interface, so there is no good reason to even consider XDateField's setDate method.
Comment 9 Rainer Bielefeld Retired 2011-09-11 22:12:14 UTC
@Lionel
do your comments 2,3 say that the problem appeared for you between LibO 3.3.0 and LibO 3.3.3? Or what was the first version for what yo observed the problem?
Comment 10 Lionel Elie Mamane 2011-09-12 02:42:16 UTC
(In reply to comment #9)
> @Lionel
> do your comments 2,3 say that the problem appeared for you between LibO 3.3.0
> and LibO 3.3.3? Or what was the first version for what yo observed the problem?

First version I observed the problem; according to references given in other comments the "problem" is actually much older than that, as it no a straight bug, rather more a very unnatural interface, coupled with no or bad typechecking, leading to non-useful error messages.

The situation is that XStatement::setDate expects a com.sun.star.util.Date UNO structure. However, it seems "natural" from a BASIC programmer's point of view that DateSerial(year, month, day) will return the right thing, or it will be automatically converted or some such, since it is the "canonical" way to construct a date in BASIC.

Compare with:

 stmt.setInt(1, "142")

which will correctly call XStatement::setInt(1, 142): the string is automatically parsed and converted to an integer.

The error message is not very informative, and is actually wrong: it says "Object variable not set": which variable? Which object? The first thought is of the "stmt" variable, so one does not understand the error message, as the stmt variable _is_ set. It is the only variable in that statement, so from the user's POV, it can only be about this variable.

A much better error message would be "XInterface::setDate argument 2: com.sun.star.util.Date expected, but integer provided".

Some lesser, but still OK alternatives:
 - Could not initialise com.sun.star.util.Date from integer
 - Could not initialise com.sun.star.util.Date
 - com.sun.star.util.Date expected

The least good, but still better than the present would be "Object value not set": value instead of variable. Slightly better "Object of type com.sun.star.Date not set".
Comment 11 Björn Michaelsen 2011-12-23 12:31:54 UTC Comment hidden (obsolete)
Comment 12 Lionel Elie Mamane 2012-07-11 14:15:00 UTC
AFAIK, situation has not changed in LibO 3.5 or even LibO 3.6
Comment 13 Alex Thurgood 2015-01-03 17:39:54 UTC
Adding self to CC if not already on
Comment 14 QA Administrators 2016-01-17 20:01:48 UTC Comment hidden (obsolete)
Comment 15 QA Administrators 2017-03-06 13:43:24 UTC Comment hidden (obsolete)
Comment 16 QA Administrators 2020-10-14 04:30:21 UTC Comment hidden (obsolete)
Comment 17 QA Administrators 2022-10-15 03:40:07 UTC
Dear Lionel Elie Mamane,

To make sure we're focusing on the bugs that affect our users today, LibreOffice QA is asking bug reporters and confirmers to retest open, confirmed bugs which have not been touched for over a year.

There have been thousands of bug fixes and commits since anyone checked on this bug report. During that time, it's possible that the bug has been fixed, or the details of the problem have changed. We'd really appreciate your help in getting confirmation that the bug is still present.

If you have time, please do the following:

Test to see if the bug is still present with the latest version of LibreOffice from https://www.libreoffice.org/download/

If the bug is present, please leave a comment that includes the information from Help - About LibreOffice.
 
If the bug is NOT present, please set the bug's Status field to RESOLVED-WORKSFORME and leave a comment that includes the information from Help - About LibreOffice.

Please DO NOT

Update the version field
Reply via email (please reply directly on the bug tracker)
Set the bug's Status field to RESOLVED - FIXED (this status has a particular meaning that is not 
appropriate in this case)


If you want to do more to help you can test to see if your issue is a REGRESSION. To do so:
1. Download and install oldest version of LibreOffice (usually 3.3 unless your bug pertains to a feature added after 3.3) from https://downloadarchive.documentfoundation.org/libreoffice/old/

2. Test your bug
3. Leave a comment with your results.
4a. If the bug was present with 3.3 - set version to 'inherited from OOo';
4b. If the bug was not present in 3.3 - add 'regression' to keyword


Feel free to come ask questions or to say hello in our QA chat: https://web.libera.chat/?settings=#libreoffice-qa

Thank you for helping us make LibreOffice even better for everyone!

Warm Regards,
QA Team

MassPing-UntouchedBug