connectivity/source/drivers/firebird/PreparedStatement.cxx |   35 ++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

New commits:
commit 605298a6e06ccb02b206f90fb9d0b8f831349fd8
Author:     Julien Nabet <serval2...@yahoo.fr>
AuthorDate: Tue Jun 7 22:57:43 2022 +0200
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Thu Jun 9 09:44:51 2022 +0200

    tdf#149470: Firebird, Clob may need several segments to store a very long 
input
    
    Change-Id: I85c7789f46d834d2ae1b251f915382f833bd529d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135480
    Reviewed-by: Julien Nabet <serval2...@yahoo.fr>
    (cherry picked from commit a943e7ddd13315b18d7b33cd1b2f852144f54344)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135392
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx 
b/connectivity/source/drivers/firebird/PreparedStatement.cxx
index 392785b9c816..3209f9d02aea 100644
--- a/connectivity/source/drivers/firebird/PreparedStatement.cxx
+++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx
@@ -52,6 +52,8 @@ using namespace com::sun::star::util;
 
 
IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.firebird.PreparedStatement","com.sun.star.sdbc.PreparedStatement");
 
+constexpr size_t MAX_SIZE_SEGMENT = 65535; // max value of a segment of CLOB, 
if we want more than 65535 bytes, we need more segments
+
 
 OPreparedStatement::OPreparedStatement( Connection* _pConnection,
                                         const OUString& sql)
@@ -663,10 +665,41 @@ void OPreparedStatement::setClob( sal_Int32 
nParameterIndex, const OUString& rSt
     OString sData = OUStringToOString(
             rStr,
             RTL_TEXTENCODING_UTF8);
-    ISC_STATUS aErr = isc_put_segment( m_statusVector,
+    size_t nDataSize = sData.getLength();
+    ISC_STATUS aErr = 0;
+    // we can't store  more than MAX_SIZE_SEGMENT in a segment
+    if (nDataSize <= MAX_SIZE_SEGMENT)
+    {
+        aErr = isc_put_segment( m_statusVector,
                             &aBlobHandle,
                             sData.getLength(),
                             sData.getStr() );
+    }
+    else
+    {
+        // if we need more, let's split the input and first let's calculate 
the nb of entire chunks needed
+        size_t nNbEntireChunks = nDataSize / MAX_SIZE_SEGMENT;
+        for (size_t i = 0; i < nNbEntireChunks; ++i)
+        {
+            OString strCurrentChunk = sData.copy(i * MAX_SIZE_SEGMENT, 
MAX_SIZE_SEGMENT);
+            aErr = isc_put_segment( m_statusVector,
+                            &aBlobHandle,
+                            strCurrentChunk.getLength(),
+                            strCurrentChunk.getStr() );
+            if (aErr)
+                break;
+        }
+        size_t nRemainingBytes = nDataSize - (nNbEntireChunks * 
MAX_SIZE_SEGMENT);
+        if (nRemainingBytes && !aErr)
+        {
+            // then copy the remaining
+            OString strCurrentChunk = sData.copy(nNbEntireChunks * 
MAX_SIZE_SEGMENT, nRemainingBytes);
+            aErr = isc_put_segment( m_statusVector,
+                            &aBlobHandle,
+                            strCurrentChunk.getLength(),
+                            strCurrentChunk.getStr() );
+        }
+    }
 
     // We need to make sure we close the Blob even if there are errors, hence 
evaluate
     // errors after closing.

Reply via email to