summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Elie Mamane <lionel@mamane.lu>2013-08-27 17:59:42 +0200
committerMiklos Vajna <vmiklos@suse.cz>2013-08-28 08:36:17 +0000
commitb17f6475d732f4123f4334cc02af18308c1d1256 (patch)
tree677784b5117208c83f78e83fdfce63ca9f3bf466
parent2729009dcfa1bc4a4a0f5547fff1b75b5ff9fecb (diff)
fdo#68315 odbc update *reads* a bookmark, not *writes* a bookmark
This code was completely inverted. The row update operation *reads* a bookmark (that is, what row to update), not *writes* a bookmark. So we were passing an empty bookmark, and thus the update was failing because we were refering to a non-existent row. Change-Id: I676b1a7727a88e13a3e465bd96cbbaf18dad2fa6 Reviewed-on: https://gerrit.libreoffice.org/5648 Reviewed-by: Miklos Vajna <vmiklos@suse.cz> Tested-by: Miklos Vajna <vmiklos@suse.cz>
-rw-r--r--connectivity/source/drivers/odbcbase/OResultSet.cxx60
1 files changed, 39 insertions, 21 deletions
diff --git a/connectivity/source/drivers/odbcbase/OResultSet.cxx b/connectivity/source/drivers/odbcbase/OResultSet.cxx
index 9d77984501db..bac7e4d91914 100644
--- a/connectivity/source/drivers/odbcbase/OResultSet.cxx
+++ b/connectivity/source/drivers/odbcbase/OResultSet.cxx
@@ -938,29 +938,47 @@ void SAL_CALL OResultSet::updateRow( ) throw(SQLException, RuntimeException)
SQLRETURN nRet;
- sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) );
- Sequence<sal_Int8> aBookmark(nMaxBookmarkLen);
- if ( bPositionByBookmark )
+ try
{
- SQLLEN nRealLen = 0;
- nRet = N3SQLBindCol(m_aStatementHandle,
- 0,
- SQL_C_VARBOOKMARK,
- aBookmark.getArray(),
- aBookmark.getLength(),
- &nRealLen
- );
- fillNeededData(nRet = N3SQLBulkOperations(m_aStatementHandle, SQL_UPDATE_BY_BOOKMARK));
- aBookmark.realloc(nRealLen);
- m_aRow[0]=aBookmark;
- m_aRow[0].setBound(true);
+ sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) );
+ if ( bPositionByBookmark )
+ {
+ getBookmark();
+ assert(m_aRow[0].isBound());
+ Sequence<sal_Int8> aBookmark(m_aRow[0].getSequence());
+ SQLLEN nRealLen = aBookmark.getLength();
+ nRet = N3SQLBindCol(m_aStatementHandle,
+ 0,
+ SQL_C_VARBOOKMARK,
+ aBookmark.getArray(),
+ aBookmark.getLength(),
+ &nRealLen
+ );
+ OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
+ fillNeededData(nRet = N3SQLBulkOperations(m_aStatementHandle, SQL_UPDATE_BY_BOOKMARK));
+ // the driver should not have touched this
+ // (neither the contents of aBookmark FWIW)
+ assert(nRealLen == aBookmark.getLength());
+ }
+ else
+ {
+ fillNeededData(nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_UPDATE,SQL_LOCK_NO_CHANGE));
+ }
+ OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
+ // unbind all columns so we can fetch all columns again with SQLGetData
+ // (and also so that our buffers don't clobber anything, and
+ // so that a subsequent fetch does not overwrite m_aRow[0])
+ invalidateCache();
+ nRet = unbind();
+ OSL_ENSURE(nRet == SQL_SUCCESS,"ODBC insert could not unbind the columns after success");
+ }
+ catch(...)
+ {
+ // unbind all columns so that a subsequent fetch does not overwrite m_aRow[0]
+ nRet = unbind();
+ OSL_ENSURE(nRet == SQL_SUCCESS,"ODBC insert could not unbind the columns after failure");
+ throw;
}
- else
- fillNeededData(nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_UPDATE,SQL_LOCK_NO_CHANGE));
- OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
- // now unbind all columns so we can fetch all columns again with SQLGetData
- nRet = unbind();
- OSL_ENSURE(nRet == SQL_SUCCESS,"Could not unbind the columns!");
}
// -------------------------------------------------------------------------
void SAL_CALL OResultSet::deleteRow( ) throw(SQLException, RuntimeException)