Bug 40144

Summary: PreparedStatement setDate call from BASIC unnatural; error message wrong and confusing
Product: LibreOffice Reporter: Lionel Elie Mamane <lionel>
Component: BASICAssignee: Not Assigned <libreoffice-bugs>
Status: NEW --- QA Contact:
Severity: normal    
Priority: medium CC: iplaw67, lemoyne.castle, LibreOffice, lionel
Version: 3.4 Daily   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

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
[This is an automated message.]
This bug was filed before the changes to Bugzilla on 2011-10-16. Thus it
started right out as NEW without ever being explicitly confirmed. The bug is
changed to state NEEDINFO for this reason. To move this bug from NEEDINFO back
to NEW please check if the bug still persists with the 3.5.0 beta1 or beta2 prereleases.
Details on how to test the 3.5.0 beta1 can be found at:
http://wiki.documentfoundation.org/QA/BugHunting_Session_3.5.0.-1

more detail on this bulk operation: http://nabble.documentfoundation.org/RFC-Operation-Spamzilla-tp3607474p3607474.html
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

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.