Failure to save as postgresql database

Jack ostroffjh at users.sourceforge.net
Tue Jan 12 00:10:58 GMT 2021


Update on status, quoting below from different messages.

On 2021.01.05 08:22, Thomas Baumgart wrote:
> On Dienstag, 5. Januar 2021 01:58:33 CET Jack wrote:
....
> This happens in qMakePreparedStmtId(). Since the stmtId in the  
> failing case is empty, it must have been cleared or never set. The  
> member variable is set when a call to QPSQLResult::prepare() returns  
> true. If it returns false, the stmtId is cleared.
So this does seem to be the case.  More below, but yes, the prepare is  
failing, but I still can't figure out why, despite lots of stepping  
with gdb.

....
> So it seems to me, that exec is called in the wrong spot. To track  
> this down (After all F1 identifies 241 iterations) I would derive a  
> new result object from QPSQLResult or QSqlResult and override  
> prepare() and exec() to keep track of the calls and their return  
> code. Then use this object to add specific debugging code/output.
That many iterations was only due to multiple attempts within the same  
session.
I had been misreadeing your suggestion, as far as I can tell, the basic  
code paths are traversed several times successfully before something  
going wrong, so perhaps adding debugging code with some sort of  
conditional execution would be better - but I'm still at a bit of a  
loss to see where to add stuff.

> I think I have done something similar for MySQL to track down a DB  
> problem in the past. Yes, it's in
>   kmymoney/kmymoney/plugins/sql/kmmsqlquery.[h,cpp]
I was on the 5.1 branch, and wondered why I wasn't finding this - but  
finally realized I needed to be in master branch.
> 
> and can be turned on using ENABLE_SQLTRACER. You may use it to add a  
> KMMSqlResult object. The #define at the end of kmmsqlquery.h and the  
> #undef at the beginning of kmmsqlquery.cpp do the trick of using the  
> identical (KMyMoney) source code and switch the stuff with cmake or  
> ccmake (ENABLE_SQLTRACER).
I also turned on QT_DEBUG_SQL and recomipled qtsql, which gave me a  
little further debugging output.  I may now almost understand how this  
works, but haven't yet figured out how to expand on it.

[from later email]
>> But the whole thing works for sqlite and MySql/Mariadb, so I'm  
>> assuming  the problem is likely in postgres specifics of qsql.
> or in the way we use it. I still have the feeling that one of the  
> calls to prepare() fails and we don't take notice and then calling  
> exec() causes the problem. Not sure though. Have not looked at our  
> code lately in that area.
Yes, the prepare is what fails, even though it is preparing the exact  
same statement as a few times earlier in the process.  My efforts now  
are trying to figure out why the prepare fails.  Eventually we should  
probably put a try/catch around the prepare's as well as the exec's.

>> I think the only reason that number is so high is that I made a  
>> whole  lot of attempts within that ddd/gdb session.   I just started  
>> a new  session, and the first iteration I saw was _A, so I might try  
>> putting a  watch on that value, if it is something gdb can do.
> Yes, GDB should be able to do that.
I haven't figured out where to do that - it seems that particular value  
is part of a result, which is created for each new query.  Anyway, the  
relevant part of the output is below, with some comments in []

-------------------
[this is starting about line 333 of .../plugins/sql/mymoneystorage.cpp,  
calling d->writeOnlineJobs()]

Created 79
Executed query (0ms, 1 results, 1 affected): "SELECT count(*) FROM  
kmmOnlineJobs"
79 executed "SELECT count(*) FROM kmmOnlineJobs"
Executed query (0ms, -1 results, 0 affected): "SELECT count(*) FROM  
kmmSepaOrders"
79 executed "SELECT count(*) FROM kmmSepaOrders"
Executed query (0ms, -1 results, 0 affected): "SELECT count(*) FROM  
kmmNationalAccountNumber"
79 executed "SELECT count(*) FROM kmmNationalAccountNumber"
Destroyed 79

[and finally calling d->writeFileInfo(), which calls  
deleteKeyValuePairs]
Created 80

  QSqlQuery::prepare: DELETE FROM kmmKeyValuePairs WHERE kvpType =  
:kvpType AND kvpId = :kvpId;
Error in function void  
MyMoneyStorageSqlPrivate::deleteKeyValuePairs(const QString&, const  
QVariantList&) : preparing statement to delete kvp for STORAGE
Driver = QPSQL, Host = localhost, User = jack, Database = kmm
Driver Error:
Database Error No -1:
Text:
Error type 0
Executed: DELETE FROM kmmKeyValuePairs WHERE kvpType = ? AND kvpId = ?;
Query error No 0: ERROR:  current transaction is aborted, commands  
ignored until end of transaction block
(25P02) QPSQL: Unable to prepare statement
Error type 2
void MyMoneyStorageSql::cancelCommitUnit(const QString&) - void  
MyMoneyStorageSqlPrivate::deleteKeyValuePairs(const QString&, const  
QVariantList&) s/be bool MyMoneyStorageSql::writeFile()
Destroyed 80
-------------------
Considering there is no code between "QSqlQuery query(*q);" and "if  
(!query.prepare("DELETE FROM kmmKeyValuePairs WHERE kvpType = :kvpType  
AND kvpId = :kvpId;"))" I don't know where or why the transaction gets  
aborted.  I've traced this into the bowels of qtsql  
..../src/plugins/sqldrivers/psql/qsql_psql.cpp, but I still can't  
figure out exactly what is failing.  However, at about the point of the  
failure, there is a local result which is optimized out, so I think my  
next step is to recompile qtsql with less optimization.

Jack


More information about the KMyMoney-devel mailing list