[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - 33 commits - accessibility/source avmedia/Library_avmedia.mk avmedia/source basctl/source basic/source chart2/Library_chartcore.mk chart2/source connectivity/source cui/source dbaccess/source desktop/source editeng/source embeddedobj/source extensions/source external/cairo filter/source forms/source formula/source fpicker/inc framework/source .gitignore include/basic include/editeng include/rtl include/sfx2 include/svl include/svtools include/svx libreofficekit/Executable_tilebench.mk libreofficekit/Module_libreofficekit.mk libreofficekit/qa officecfg/registry oox/source reportdesign/source Repository.mk sal/inc sal/qa sal/rtl sccomp/source sc/source sdext/source sd/source sfx2/source solenv/vs starmath/source svl/source svtools/source svx/source sw/inc sw/qa sw/source tools/source vcl/headless vcl/inc vcl/qa vcl/source writerperfect/inc writerperfect/Library_writerperfect.mk writerperfect/source xmlsecurity/inc xmlsecurity/source

Jan Holesovsky kendy at collabora.com
Tue Mar 20 15:09:20 UTC 2018


 .gitignore                                                    |    2 
 Repository.mk                                                 |    4 
 accessibility/source/helper/accresmgr.cxx                     |    3 
 avmedia/Library_avmedia.mk                                    |    1 
 avmedia/source/framework/mediamisc.cxx                        |   33 -
 avmedia/source/inc/mediamisc.hxx                              |    7 
 basctl/source/basicide/basicmod.hxx                           |    4 
 basctl/source/basicide/iderdll.cxx                            |    4 
 basic/source/sbx/sbxscan.cxx                                  |    5 
 chart2/Library_chartcore.mk                                   |    1 
 chart2/source/inc/ResourceManager.hxx                         |   38 -
 chart2/source/tools/ResId.cxx                                 |    3 
 chart2/source/tools/ResourceManager.cxx                       |   34 -
 connectivity/source/drivers/firebird/Blob.cxx                 |   65 +++
 connectivity/source/drivers/firebird/Blob.hxx                 |    4 
 connectivity/source/drivers/firebird/Clob.cxx                 |   92 +++-
 connectivity/source/drivers/firebird/Clob.hxx                 |    2 
 connectivity/source/drivers/firebird/DatabaseMetaData.cxx     |  111 +++--
 connectivity/source/drivers/firebird/PreparedStatement.cxx    |  111 +++++
 connectivity/source/drivers/firebird/PreparedStatement.hxx    |    1 
 connectivity/source/drivers/firebird/ResultSet.cxx            |   17 
 connectivity/source/drivers/firebird/ResultSetMetaData.cxx    |   59 ++-
 connectivity/source/drivers/firebird/ResultSetMetaData.hxx    |    1 
 connectivity/source/drivers/firebird/Tables.cxx               |   29 +
 connectivity/source/drivers/firebird/Util.cxx                 |  193 +++++-----
 connectivity/source/drivers/firebird/Util.hxx                 |   45 ++
 connectivity/source/parse/sqlbison.y                          |    4 
 connectivity/source/parse/sqlflex.l                           |    3 
 cui/source/factory/cuiresmgr.cxx                              |    3 
 dbaccess/source/core/resource/core_resource.cxx               |    3 
 desktop/source/lib/init.cxx                                   |    6 
 desktop/source/lib/lokinteractionhandler.cxx                  |   12 
 editeng/source/editeng/eerdll.cxx                             |    8 
 embeddedobj/source/msole/olevisual.cxx                        |    6 
 extensions/source/inc/componentmodule.cxx                     |    3 
 extensions/source/propctrlr/modulepcr.cxx                     |    3 
 extensions/source/scanner/sanedlg.cxx                         |    3 
 extensions/source/scanner/scanwin.cxx                         |   10 
 external/cairo/cairo/cairo-1.10.2.patch                       |  137 ++++++-
 external/cairo/pixman/pixman-0.24.4.patch                     |   72 +++
 filter/source/pdf/impdialog.cxx                               |    9 
 filter/source/xsltdialog/xmlfiltersettingsdialog.cxx          |    3 
 forms/source/resource/frm_resource.cxx                        |    3 
 formula/source/core/resource/core_resource.cxx                |    3 
 fpicker/inc/fpsofficeResMgr.hxx                               |    3 
 framework/source/fwe/classes/fwkresid.cxx                     |    3 
 include/basic/sbdef.hxx                                       |    2 
 include/editeng/eerdll.hxx                                    |    1 
 include/rtl/alloc.h                                           |   42 +-
 include/sfx2/module.hxx                                       |    8 
 include/sfx2/viewsh.hxx                                       |    2 
 include/svl/languageoptions.hxx                               |    2 
 include/svtools/svtresid.hxx                                  |    2 
 include/svx/dialmgr.hxx                                       |    2 
 libreofficekit/Executable_tilebench.mk                        |    1 
 libreofficekit/Module_libreofficekit.mk                       |    5 
 libreofficekit/qa/tilebench/tilebench.cxx                     |  157 ++++++--
 officecfg/registry/data/org/openoffice/Office/TableWizard.xcu |   76 +--
 oox/source/ole/axcontrol.cxx                                  |    7 
 reportdesign/source/core/resource/core_resource.cxx           |    3 
 sal/inc/rtllifecycle.h                                        |    4 
 sal/qa/rtl/alloc/rtl_alloc.cxx                                |    4 
 sal/rtl/alloc_cache.cxx                                       |   10 
 sal/rtl/strimp.cxx                                            |   53 +-
 sc/source/ui/app/scmod.cxx                                    |    2 
 sccomp/source/solver/SolverComponent.cxx                      |    3 
 sccomp/source/solver/SwarmSolver.cxx                          |    3 
 sd/source/ui/app/sdmod.cxx                                    |    2 
 sdext/source/pdfimport/inc/pdfiprocessor.hxx                  |   10 
 sdext/source/pdfimport/tree/pdfiprocessor.cxx                 |   18 
 sfx2/source/appl/module.cxx                                   |   16 
 sfx2/source/bastyp/sfxresid.cxx                               |    4 
 sfx2/source/dialog/basedlgs.cxx                               |    4 
 sfx2/source/dialog/tabdlg.cxx                                 |    2 
 sfx2/source/doc/sfxbasemodel.cxx                              |    4 
 sfx2/source/view/viewsh.cxx                                   |    7 
 solenv/vs/LibreOffice.natvis                                  |   48 +-
 starmath/source/smmod.cxx                                     |    2 
 svl/source/config/languageoptions.cxx                         |    8 
 svl/source/misc/getstringresource.cxx                         |    3 
 svtools/source/misc/svtresid.cxx                              |    5 
 svx/source/dialog/dialmgr.cxx                                 |    5 
 sw/inc/section.hxx                                            |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx                     |    3 
 sw/qa/python/text_portion_enumeration_test.py                 |   21 -
 sw/source/core/docnode/ndsect.cxx                             |    2 
 sw/source/core/undo/SwUndoPageDesc.cxx                        |  114 -----
 sw/source/core/unocore/unoportenum.cxx                        |  111 +++++
 sw/source/uibase/app/swmodule.cxx                             |    2 
 tools/source/memtools/multisel.cxx                            |   19 
 vcl/headless/svpbmp.cxx                                       |    5 
 vcl/headless/svpgdi.cxx                                       |  118 +++++-
 vcl/inc/headless/svpgdi.hxx                                   |    4 
 vcl/qa/cppunit/BitmapTest.cxx                                 |    9 
 vcl/qa/cppunit/svm/svmtest.cxx                                |   12 
 vcl/source/app/settings.cxx                                   |    6 
 vcl/source/control/imp_listbox.cxx                            |    1 
 vcl/source/outdev/font.cxx                                    |    1 
 writerperfect/Library_writerperfect.mk                        |    1 
 writerperfect/inc/WPFTResMgr.hxx                              |    7 
 writerperfect/source/common/WPFTResMgr.cxx                    |   11 
 xmlsecurity/inc/resourcemanager.hxx                           |    4 
 xmlsecurity/source/dialogs/resourcemanager.cxx                |    6 
 103 files changed, 1423 insertions(+), 729 deletions(-)

New commits:
commit 7ff6b33f740ff28d6821863978df1ff82fa7616a
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Jan 3 17:49:25 2018 +0100

    lokdialog: Use only one of the installed langpacks when setting locale.
    
    Change-Id: I446775b121b7806a549f4dbbaa1f2dcf019d9bc2
    Reviewed-on: https://gerrit.libreoffice.org/47334
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index 0c83f5faee15..e7a0f6d7fec1 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -344,7 +344,7 @@ public:
     virtual vcl::Window* GetEditWindowForActiveOLEObj() const override;
 
     /// Set the LibreOfficeKit language of this view.
-    void SetLOKLanguageTag(const OUString& rBcp47LanguageTag) { maLOKLanguageTag = LanguageTag(rBcp47LanguageTag, true); }
+    void SetLOKLanguageTag(const OUString& rBcp47LanguageTag);
     /// Get the LibreOfficeKit language of this view.
     const LanguageTag& GetLOKLanguageTag() const { return maLOKLanguageTag; }
 };
diff --git a/include/svl/languageoptions.hxx b/include/svl/languageoptions.hxx
index f386cb6b0e00..389eae8aa346 100644
--- a/include/svl/languageoptions.hxx
+++ b/include/svl/languageoptions.hxx
@@ -132,7 +132,7 @@ public:
 };
 
 OUString SVL_DLLPUBLIC getInstalledLocaleForLanguage(css::uno::Sequence<OUString> const & installed, OUString const & locale);
-OUString SVL_DLLPUBLIC getInstalledLocaleForSystemUILanguage(css::uno::Sequence<OUString> const & installed);
+OUString SVL_DLLPUBLIC getInstalledLocaleForSystemUILanguage(css::uno::Sequence<OUString> const & installed, const OUString& rPreferredLocale = OUString());
 
 #endif // INCLUDED_SVL_LANGUAGEOPTIONS_HXX
 
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index ad0fce0a6466..3eb162ffe642 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -57,6 +57,7 @@
 #include <vcl/commandinfoprovider.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
+#include <officecfg/Setup.hxx>
 #include <sfx2/app.hxx>
 #include <sfx2/viewsh.hxx>
 #include "viewimp.hxx"
@@ -1488,6 +1489,12 @@ vcl::Window* SfxViewShell::GetEditWindowForActiveOLEObj() const
     return pEditWin;
 }
 
+void SfxViewShell::SetLOKLanguageTag(const OUString& rBcp47LanguageTag)
+{
+    css::uno::Sequence<OUString> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
+    maLOKLanguageTag = LanguageTag(getInstalledLocaleForSystemUILanguage(inst, rBcp47LanguageTag), true).makeFallback();
+}
+
 void SfxViewShell::NotifyCursor(SfxViewShell* /*pViewShell*/) const
 {
 }
diff --git a/svl/source/config/languageoptions.cxx b/svl/source/config/languageoptions.cxx
index 9f9fe4513819..faa573069e5c 100644
--- a/svl/source/config/languageoptions.cxx
+++ b/svl/source/config/languageoptions.cxx
@@ -283,9 +283,13 @@ OUString getInstalledLocaleForLanguage(css::uno::Sequence<OUString> const & inst
     return OUString();
 }
 
-OUString getInstalledLocaleForSystemUILanguage(const css::uno::Sequence<OUString>& rLocaleElementNames)
+OUString getInstalledLocaleForSystemUILanguage(const css::uno::Sequence<OUString>& rLocaleElementNames, const OUString& rPreferredLocale)
 {
-    OUString locale = getInstalledLocaleForLanguage(rLocaleElementNames, officecfg::System::L10N::UILocale::get());
+    OUString aPreferredLocale(rPreferredLocale);
+    if (aPreferredLocale.isEmpty())
+        aPreferredLocale = officecfg::System::L10N::UILocale::get();
+
+    OUString locale = getInstalledLocaleForLanguage(rLocaleElementNames, aPreferredLocale);
     if (locale.isEmpty())
         locale = getInstalledLocaleForLanguage(rLocaleElementNames, "en-US");
     if (locale.isEmpty() && rLocaleElementNames.hasElements())
commit 23b811466e53a30efde898a6fd9b3a55aff33a38
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Jan 3 14:08:55 2018 +0100

    lokdialog: Allow language switching in SfxModule(s).
    
    Change-Id: Icef0b3610c3bfa858cdd61de6ef3f5edc1e3c96b
    Reviewed-on: https://gerrit.libreoffice.org/47385
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    (cherry picked from commit 028fd03cdf4d3d8072289a5c4d476435c18f90d0)

diff --git a/basctl/source/basicide/basicmod.hxx b/basctl/source/basicide/basicmod.hxx
index 7dcee5a16420..d94a2198d440 100644
--- a/basctl/source/basicide/basicmod.hxx
+++ b/basctl/source/basicide/basicmod.hxx
@@ -29,8 +29,8 @@ namespace basctl
 class Module : public SfxModule
 {
 public:
-    Module(const std::locale& rResLocale, SfxObjectFactory *pObjFact)
-        : SfxModule(rResLocale, {pObjFact})
+    Module(const OString& rResName, SfxObjectFactory *pObjFact)
+        : SfxModule(rResName, {pObjFact})
     {
     }
 };
diff --git a/basctl/source/basicide/iderdll.cxx b/basctl/source/basicide/iderdll.cxx
index 19d21c32eedb..b80ce1f38970 100644
--- a/basctl/source/basicide/iderdll.cxx
+++ b/basctl/source/basicide/iderdll.cxx
@@ -118,9 +118,7 @@ Dll::Dll () :
 {
     SfxObjectFactory& rFactory = DocShell::Factory();
 
-    std::locale loc = Translate::Create("basctl");
-
-    auto pModule = o3tl::make_unique<Module>(loc, &rFactory);
+    auto pModule = o3tl::make_unique<Module>("basctl", &rFactory);
     SfxModule* pMod = pModule.get();
     SfxApplication::SetModule(SfxToolsModule::Basic, std::move(pModule));
 
diff --git a/include/sfx2/module.hxx b/include/sfx2/module.hxx
index de487dafaa3f..352d1e46ba6f 100644
--- a/include/sfx2/module.hxx
+++ b/include/sfx2/module.hxx
@@ -52,13 +52,11 @@ namespace com { namespace sun { namespace star { namespace frame {
 class SFX2_DLLPUBLIC SfxModule : public SfxShell
 {
 private:
-    std::locale                 m_aResLocale;
-
     // Warning this cannot be turned into a unique_ptr.
     // SfxInterface destruction in the SfxSlotPool refers again to pImpl after deletion of pImpl has commenced. See tdf#100270
     SfxModule_Impl*             pImpl;
 
-    SAL_DLLPRIVATE void Construct_Impl();
+    SAL_DLLPRIVATE void Construct_Impl(const OString& rResName);
 
 public:
                                 SFX_DECL_INTERFACE(SFX_INTERFACE_SFXMODULE)
@@ -69,10 +67,10 @@ private:
 
 public:
 
-    SfxModule(const std::locale& rResLocale, std::initializer_list<SfxObjectFactory*> pFactoryList);
+    SfxModule(const OString& rResName, std::initializer_list<SfxObjectFactory*> pFactoryList);
     virtual ~SfxModule() override;
 
-    const std::locale&          GetResLocale() const { return m_aResLocale; }
+    std::locale                 GetResLocale() const;
     SfxSlotPool*                GetSlotPool() const;
 
     void                        RegisterToolBoxControl(const SfxTbxCtrlFactory&);
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index aba269d29aa4..a78716d3fa66 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -137,7 +137,7 @@ void ScModule::InitInterface_Impl()
 }
 
 ScModule::ScModule( SfxObjectFactory* pFact ) :
-    SfxModule( Translate::Create("sc"), {pFact} ),
+    SfxModule("sc", {pFact}),
     aIdleTimer("sc ScModule IdleTimer"),
     aSpellIdle("sc ScModule SpellIdle"),
     mpDragData(new ScDragData),
diff --git a/sd/source/ui/app/sdmod.cxx b/sd/source/ui/app/sdmod.cxx
index 61dd5e6b10a4..9d9eaa53aecb 100644
--- a/sd/source/ui/app/sdmod.cxx
+++ b/sd/source/ui/app/sdmod.cxx
@@ -65,7 +65,7 @@ void SdModule::InitInterface_Impl()
 
 // Ctor
 SdModule::SdModule(SfxObjectFactory* pFact1, SfxObjectFactory* pFact2 )
-:   SfxModule( Translate::Create("sd"), {pFact1, pFact2} ),
+:   SfxModule("sd", {pFact1, pFact2}),
     pTransferClip(nullptr),
     pTransferDrag(nullptr),
     pTransferSelection(nullptr),
diff --git a/sfx2/source/appl/module.cxx b/sfx2/source/appl/module.cxx
index ef37f8e41ada..3fb4376cc7a1 100644
--- a/sfx2/source/appl/module.cxx
+++ b/sfx2/source/appl/module.cxx
@@ -48,6 +48,7 @@ public:
     SfxTbxCtrlFactArr_Impl*     pTbxCtrlFac;
     SfxStbCtrlFactArr_Impl*     pStbCtrlFac;
     SfxChildWinFactArr_Impl*    pFactArr;
+    OString                     maResName;
 
                                 SfxModule_Impl();
                                 ~SfxModule_Impl();
@@ -68,11 +69,10 @@ SfxModule_Impl::~SfxModule_Impl()
 
 SFX_IMPL_SUPERCLASS_INTERFACE(SfxModule, SfxShell)
 
-SfxModule::SfxModule(const std::locale& rLocale, std::initializer_list<SfxObjectFactory*> pFactoryList)
-    : m_aResLocale(rLocale)
-    , pImpl(nullptr)
+SfxModule::SfxModule(const OString& rResName, std::initializer_list<SfxObjectFactory*> pFactoryList)
+    : pImpl(nullptr)
 {
-    Construct_Impl();
+    Construct_Impl(rResName);
     for (auto pFactory : pFactoryList)
     {
         if (pFactory)
@@ -80,7 +80,7 @@ SfxModule::SfxModule(const std::locale& rLocale, std::initializer_list<SfxObject
     }
 }
 
-void SfxModule::Construct_Impl()
+void SfxModule::Construct_Impl(const OString& rResName)
 {
     SfxApplication *pApp = SfxApplication::GetOrCreate();
     pImpl = new SfxModule_Impl;
@@ -89,6 +89,7 @@ void SfxModule::Construct_Impl()
     pImpl->pTbxCtrlFac=nullptr;
     pImpl->pStbCtrlFac=nullptr;
     pImpl->pFactArr=nullptr;
+    pImpl->maResName = rResName;
 
     SetPool( &pApp->GetPool() );
 }
@@ -102,6 +103,11 @@ SfxModule::~SfxModule()
     }
 }
 
+std::locale SfxModule::GetResLocale() const
+{
+    return Translate::Create(pImpl->maResName.getStr());
+}
+
 SfxSlotPool* SfxModule::GetSlotPool() const
 {
     return pImpl->pSlotPool;
diff --git a/starmath/source/smmod.cxx b/starmath/source/smmod.cxx
index 08bec54144cf..02a8fec7a572 100644
--- a/starmath/source/smmod.cxx
+++ b/starmath/source/smmod.cxx
@@ -119,7 +119,7 @@ void SmModule::InitInterface_Impl()
 }
 
 SmModule::SmModule(SfxObjectFactory* pObjFact)
-    : SfxModule(Translate::Create("sm"), {pObjFact})
+    : SfxModule("sm", {pObjFact})
 {
     SetName("StarMath");
 
diff --git a/sw/source/uibase/app/swmodule.cxx b/sw/source/uibase/app/swmodule.cxx
index 71264ffd5bea..b4c271d66852 100644
--- a/sw/source/uibase/app/swmodule.cxx
+++ b/sw/source/uibase/app/swmodule.cxx
@@ -146,7 +146,7 @@ using namespace ::com::sun::star::uno;
 SwModule::SwModule( SfxObjectFactory* pWebFact,
                     SfxObjectFactory* pFact,
                     SfxObjectFactory* pGlobalFact )
-    : SfxModule( Translate::Create("sw"), {pWebFact, pFact, pGlobalFact} ),
+    : SfxModule("sw", {pWebFact, pFact, pGlobalFact}),
     m_pModuleConfig(nullptr),
     m_pUsrPref(nullptr),
     m_pWebUsrPref(nullptr),
commit 5eca99187e576389a33e73e3053a29dfd2b417e0
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Thu Jan 4 14:11:05 2018 +0100

    Remove redundant control flow branch
    
    Change-Id: I5f63f2a7ad6eb6bf85b21b6936a1488ce13ccc93
    Reviewed-on: https://gerrit.libreoffice.org/47394
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit d86d3caf9853e930eb686b63309a7cc6c29cc0d2)

diff --git a/embeddedobj/source/msole/olevisual.cxx b/embeddedobj/source/msole/olevisual.cxx
index a9faa3a83eeb..820e39c2f7f0 100644
--- a/embeddedobj/source/msole/olevisual.cxx
+++ b/embeddedobj/source/msole/olevisual.cxx
@@ -345,12 +345,8 @@ embed::VisualRepresentation SAL_CALL OleEmbeddedObject::getPreferredVisualRepres
         SetVisReplInStream( m_xCachedVisualRepresentation.is() );
     }
 
-    if ( m_xCachedVisualRepresentation.is() )
-    {
-        return GetVisualRepresentationInNativeFormat_Impl( m_xCachedVisualRepresentation );
-    }
 #ifdef _WIN32
-    else if ( m_pOleComponent )
+    if ( !m_xCachedVisualRepresentation.is() && m_pOleComponent )
     {
         try
         {
commit 22779e8220848a5d52ee313a180535d4f6359ad0
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jan 3 14:55:30 2018 +0100

    sfx2: improve reported error message in SfxBaseModel::impl_store()
    
    Old: com.sun.star.io.IOException: SfxBaseModel::impl_store <file:///c:/lo/bugs/saved.xhtml> failed: 0x507
    
    New: com.sun.star.io.IOException: SfxBaseModel::impl_store <file:///c:/lo/bugs/saved.xhtml> failed: 0x507(Error Area:Io Class:Access Code:1287)
    
    It's much easier to find the relevant define in include/vcl/errcode.hxx based
    on the new output.
    
    Change-Id: I7d98dcf1ead10264672b45de570e51a153090499
    Reviewed-on: https://gerrit.libreoffice.org/47319
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 050c0422b9c8a859d886748ae70e99274d1d9afa)

diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index 7cb1076485a5..577562aa974c 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -3019,8 +3019,10 @@ void SfxBaseModel::impl_store(  const   OUString&                   sURL
             SfxGetpApp()->NotifyEvent( SfxEventHint( bSaveTo ? SfxEventHintId::SaveToDocFailed : SfxEventHintId::SaveAsDocFailed, GlobalEventConfig::GetEventName( bSaveTo ? GlobalEventId::SAVETODOCFAILED : GlobalEventId::SAVEASDOCFAILED),
                                                     m_pData->m_pObjectShell.get() ) );
 
+            std::stringstream aErrCode;
+            aErrCode << nErrCode;
             throw task::ErrorCodeIOException(
-                "SfxBaseModel::impl_store <" + sURL + "> failed: " + nErrCode.toHexString(),
+                "SfxBaseModel::impl_store <" + sURL + "> failed: " + OUString::fromUtf8(aErrCode.str().c_str()),
                 Reference< XInterface >(), sal_uInt32(nErrCode));
         }
     }
commit 6f6814b9a354f712a4069932271dc7ba578774fd
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Jan 2 18:46:33 2018 +0200

    tdf#104986: Add MILLISECOND, WEEKDAY, and YEARDAY tokens for Firebird
    
    Change-Id: I2ba866c408dbf49f1655cc08cc5d0df840eaf01e
    Reviewed-on: https://gerrit.libreoffice.org/47271
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    (cherry picked from commit 72ff62a13af402d19e6e53b809b29033a985c04a)

diff --git a/connectivity/source/parse/sqlbison.y b/connectivity/source/parse/sqlbison.y
index 2c55bae0f66b..0f21bcc6fcc9 100644
--- a/connectivity/source/parse/sqlbison.y
+++ b/connectivity/source/parse/sqlbison.y
@@ -146,8 +146,8 @@ using namespace connectivity;
 /* time and date functions */
 %token <pParseNode> SQL_TOKEN_CURRENT_DATE SQL_TOKEN_CURRENT_TIME SQL_TOKEN_CURRENT_TIMESTAMP SQL_TOKEN_CURDATE SQL_TOKEN_CURTIME
 %token <pParseNode> SQL_TOKEN_DAYNAME  SQL_TOKEN_DAYOFMONTH  SQL_TOKEN_DAYOFWEEK  SQL_TOKEN_DAYOFYEAR SQL_TOKEN_EXTRACT
-%token <pParseNode> SQL_TOKEN_HOUR SQL_TOKEN_MINUTE  SQL_TOKEN_MONTH  SQL_TOKEN_MONTHNAME SQL_TOKEN_NOW SQL_TOKEN_QUARTER SQL_TOKEN_DATEDIFF
-%token <pParseNode> SQL_TOKEN_SECOND SQL_TOKEN_TIMESTAMPADD SQL_TOKEN_TIMESTAMPDIFF SQL_TOKEN_TIMEVALUE SQL_TOKEN_WEEK SQL_TOKEN_YEAR
+%token <pParseNode> SQL_TOKEN_HOUR SQL_TOKEN_MILLISECOND SQL_TOKEN_MINUTE  SQL_TOKEN_MONTH  SQL_TOKEN_MONTHNAME SQL_TOKEN_NOW SQL_TOKEN_QUARTER SQL_TOKEN_DATEDIFF
+%token <pParseNode> SQL_TOKEN_SECOND SQL_TOKEN_TIMESTAMPADD SQL_TOKEN_TIMESTAMPDIFF SQL_TOKEN_TIMEVALUE SQL_TOKEN_WEEK SQL_TOKEN_WEEKDAY SQL_TOKEN_YEAR SQL_TOKEN_YEARDAY
 
 /* numeric functions */
 %token <pParseNode> SQL_TOKEN_ABS SQL_TOKEN_ACOS SQL_TOKEN_ASIN SQL_TOKEN_ATAN SQL_TOKEN_ATAN2 SQL_TOKEN_CEILING
diff --git a/connectivity/source/parse/sqlflex.l b/connectivity/source/parse/sqlflex.l
index 9d9f119fd640..5d8a59c27844 100644
--- a/connectivity/source/parse/sqlflex.l
+++ b/connectivity/source/parse/sqlflex.l
@@ -260,6 +260,7 @@ LOWER               {SQL_NEW_KEYWORD(SQL_TOKEN_LOWER);  }
 LTRIM               {SQL_NEW_KEYWORD(SQL_TOKEN_LTRIM);  }
 
 MAX                 {SQL_NEW_KEYWORD(SQL_TOKEN_MAX);  }
+MILLISECOND         {SQL_NEW_KEYWORD(SQL_TOKEN_MILLISECOND);  }
 MIN                 {SQL_NEW_KEYWORD(SQL_TOKEN_MIN);  }
 MINUTE              {SQL_NEW_KEYWORD(SQL_TOKEN_MINUTE);  }
 MOD                 {SQL_NEW_KEYWORD(SQL_TOKEN_MOD);  }
@@ -394,6 +395,7 @@ VALUES              {SQL_NEW_KEYWORD(SQL_TOKEN_VALUES);  }
 VIEW                {SQL_NEW_KEYWORD(SQL_TOKEN_VIEW);  }
 
 WEEK                {SQL_NEW_KEYWORD(SQL_TOKEN_WEEK);  }
+WEEKDAY             {SQL_NEW_KEYWORD(SQL_TOKEN_WEEKDAY);  }
 WHEN                {SQL_NEW_KEYWORD(SQL_TOKEN_WHEN);  }
 WHERE               {SQL_NEW_KEYWORD(SQL_TOKEN_WHERE);  }
 WITH                {SQL_NEW_KEYWORD(SQL_TOKEN_WITH);  }
@@ -402,6 +404,7 @@ WITHOUT             {SQL_NEW_KEYWORD(SQL_TOKEN_WITHOUT);  }
 WORK                {SQL_NEW_KEYWORD(SQL_TOKEN_WORK);  }
 
 YEAR                {SQL_NEW_KEYWORD(SQL_TOKEN_YEAR);  }
+YEARDAY             {SQL_NEW_KEYWORD(SQL_TOKEN_YEARDAY);  }
 
 ZONE                {SQL_NEW_KEYWORD(SQL_TOKEN_ZONE);  }
 
commit 72922b519becc66a285ae7ae82aadb4eb4d41992
Author: Tor Lillqvist <tml at collabora.com>
Date:   Tue Jan 2 16:54:40 2018 +0200

    tdf#71007: Pass also fractional seconds to/from Firebird
    
    We know that ISC_TIME is simply in units of
    seconds/ISC_TIME_SECONDS_PRECISION.
    
    Change-Id: I2896f53c2d32a773c535e19f55dd1314abd18ec9
    Reviewed-on: https://gerrit.libreoffice.org/47266
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    (cherry picked from commit e0a22d47d281f61f51ead6d2831cd53c15036ffe)

diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx
index afe1fa3229a6..f97895ec530e 100644
--- a/connectivity/source/drivers/firebird/PreparedStatement.cxx
+++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
 /*
  * This file is part of the LibreOffice project.
  *
@@ -463,6 +463,10 @@ void SAL_CALL OPreparedStatement::setTime( sal_Int32 nIndex, const css::util::Ti
     ISC_TIME aISCTime;
     isc_encode_sql_time(&aCTime, &aISCTime);
 
+    // Here we "know" that ISC_TIME is simply in units of seconds/ISC_TIME_SECONDS_PRECISION with no
+    // other funkiness, so we can simply add the fraction of a second.
+    aISCTime += rTime.NanoSeconds / (1000000000 / ISC_TIME_SECONDS_PRECISION);
+
     setValue< ISC_TIME >(nIndex, aISCTime, SQL_TYPE_TIME);
 }
 
@@ -479,6 +483,9 @@ void SAL_CALL OPreparedStatement::setTimestamp(sal_Int32 nIndex, const DateTime&
     ISC_TIMESTAMP aISCTimestamp;
     isc_encode_timestamp(&aCTime, &aISCTimestamp);
 
+    // As in previous function
+    aISCTimestamp.timestamp_time += rTimestamp.NanoSeconds / (1000000000 / ISC_TIME_SECONDS_PRECISION);
+
     setValue< ISC_TIMESTAMP >(nIndex, aISCTimestamp, SQL_TIMESTAMP);
 }
 
diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx
index 9e8387d39a3d..20fe2a4dab1e 100644
--- a/connectivity/source/drivers/firebird/ResultSet.cxx
+++ b/connectivity/source/drivers/firebird/ResultSet.cxx
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
 /*
  * This file is part of the LibreOffice project.
  *
@@ -526,9 +526,12 @@ Time OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT /*n
         struct tm aCTime;
         isc_decode_sql_time(&aISCTime, &aCTime);
 
-        // first field is nanoseconds -- not supported in firebird or struct tm.
+        // First field is nanoseconds.
         // last field denotes UTC (true) or unknown (false)
-        return Time(0, aCTime.tm_sec, aCTime.tm_min, aCTime.tm_hour, false);
+        // Here we "know" that ISC_TIME is simply in units of seconds/ISC_TIME_SECONDS_PRECISION
+        // with no other funkiness, so we can get the fractional seconds easily.
+        return Time((aISCTime % ISC_TIME_SECONDS_PRECISION) * (1000000000 / ISC_TIME_SECONDS_PRECISION),
+                    aCTime.tm_sec, aCTime.tm_min, aCTime.tm_hour, false);
     }
     else
     {
@@ -546,7 +549,8 @@ DateTime OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT
         struct tm aCTime;
         isc_decode_timestamp(&aISCTimestamp, &aCTime);
 
-        return DateTime(0, //nanoseconds, not supported
+        // Ditto here, see comment in previous function about ISC_TIME and ISC_TIME_SECONDS_PRECISION.
+        return DateTime((aISCTimestamp.timestamp_time % ISC_TIME_SECONDS_PRECISION) * (1000000000 / ISC_TIME_SECONDS_PRECISION), //nanoseconds
                         aCTime.tm_sec,
                         aCTime.tm_min,
                         aCTime.tm_hour,
commit c35c0630e43025308bc1cbbf50019458a926f3a7
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Jan 1 15:14:20 2018 +0200

    Reduce large VARCHAR columns of the wizard sample databases to fit Firebird
    
    The maximum size of a VARCHAR column in Firebird is 32765 bytes [sic].
    We use the UTF8 character set and that means 8190 characters as each
    character might take four bytes. The maximum size of a row in Firebird
    is 64 KB [sic].
    
    Avoids errors when creating sample tables using the wizard using just
    the default values. If the varchar column lengths are under 8190 but
    the total row size is too large you do get a relatively helpful error
    message "new record size of <N> bytes is too big", but if you try use
    a too large size for a varchar column, just some "SQL error code =
    -204", "Impmentation limit exceeded", etc.
    
    Change-Id: I17c2bed4fc098f4e159822f6f81242aae274da7b
    Reviewed-on: https://gerrit.libreoffice.org/47232
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    (cherry picked from commit ee29c944868a578b002103bb58595029bf385473)

diff --git a/officecfg/registry/data/org/openoffice/Office/TableWizard.xcu b/officecfg/registry/data/org/openoffice/Office/TableWizard.xcu
index 2b1876005ef8..e748eda1d272 100644
--- a/officecfg/registry/data/org/openoffice/Office/TableWizard.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/TableWizard.xcu
@@ -513,7 +513,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -987,7 +987,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -1379,7 +1379,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -1661,7 +1661,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -2152,7 +2152,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -2956,7 +2956,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -3158,7 +3158,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -3359,7 +3359,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="clientID" oor:op="replace">
@@ -3513,7 +3513,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="eventtypeID" oor:op="replace">
@@ -3710,7 +3710,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -3912,7 +3912,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -4052,7 +4052,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -4229,7 +4229,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -4649,7 +4649,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -4984,7 +4984,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="nextscheduledmaintenance" oor:op="replace">
@@ -5294,7 +5294,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -5338,7 +5338,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="startdate" oor:op="replace">
@@ -5383,7 +5383,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -5884,7 +5884,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="dateupdated" oor:op="replace">
@@ -6174,7 +6174,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -6345,7 +6345,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>4000</value>
               </prop>
             </node>
             <node oor:name="ingredients" oor:op="replace">
@@ -6362,7 +6362,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>4000</value>
               </prop>
             </node>
             <node oor:name="instructions" oor:op="replace">
@@ -6379,7 +6379,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>4000</value>
               </prop>
             </node>
             <node oor:name="utensils" oor:op="replace">
@@ -6413,7 +6413,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>2000</value>
               </prop>
             </node>
           </node>
@@ -6691,7 +6691,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -6893,7 +6893,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -7061,7 +7061,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -7306,7 +7306,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="notes" oor:op="replace">
@@ -7323,7 +7323,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -7562,7 +7562,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="notes" oor:op="replace">
@@ -7579,7 +7579,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -7849,7 +7849,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -8006,7 +8006,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
             <node oor:name="photo" oor:op="replace">
@@ -8037,7 +8037,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -8163,7 +8163,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -8286,7 +8286,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -8482,7 +8482,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
@@ -8675,7 +8675,7 @@
                 <value>-1</value>
               </prop>
               <prop oor:name="Precision">
-                <value>65000</value>
+                <value>8000</value>
               </prop>
             </node>
           </node>
commit 6dc0f9b66987a314540aac11061b361423a054f6
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Sat Dec 30 13:49:18 2017 +0100

    Enable test for exporting text color of activeX checkbox control
    
    It's fixed in:
    05f72a2a39fccb58f59b99ebfd3e7d0d8ff354e9
    
    Change-Id: I5f82b1bd5dc0b2155398e4fc74da21f1a96e1d56
    Reviewed-on: https://gerrit.libreoffice.org/47193
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 6246d44680ec9b4cc132614e664c4cb88095b09e)

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index dddc7b2b918c..f71241a025d3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -922,8 +922,7 @@ DECLARE_OOXMLEXPORT_TEST( testActiveXCheckbox, "activex_checkbox.docx" )
     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0x316AC5 ), getProperty<sal_Int32>(xPropertySet, "BackgroundColor") );
 
     // Check Text color (active border system color)
-    if(!mbExported) // Bug: text color is not exported
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD4D0C8), getProperty<sal_Int32>(xPropertySet, "TextColor"));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD4D0C8), getProperty<sal_Int32>(xPropertySet, "TextColor"));
 
     // Check state of the checkbox
     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPropertySet, "State"));
commit e887d2bbd81e2c1188b6fd20d06689fda1604e23
Author: Bán Róbert <robert.ban102 at gmail.com>
Date:   Fri Dec 29 23:49:00 2017 +0100

    tdf#113788 ActiveX controls' text color is not exported to DOCX
    
    The convertFromProperties function does not set the text color.
    Background color is a similar property and it is handled similarly.
    
    Change-Id: I2c1bff6198640b9a30f70d9db641425166ced992
    Reviewed-on: https://gerrit.libreoffice.org/47185
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 05f72a2a39fccb58f59b99ebfd3e7d0d8ff354e9)

diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx
index 7ab805691c82..a697fddfe33c 100644
--- a/oox/source/ole/axcontrol.cxx
+++ b/oox/source/ole/axcontrol.cxx
@@ -1585,6 +1585,7 @@ void AxToggleButtonModel::convertFromProperties( PropertySet& rPropSet, const Co
         setFlag( mnFlags, AX_FLAGS_WORDWRAP, bRes );
 
     ControlConverter::convertToMSColor( rPropSet, PROP_BackgroundColor, mnBackColor );
+    ControlConverter::convertToMSColor( rPropSet, PROP_TextColor, mnTextColor );
     // need to process the image if one exists
     ControlConverter::convertToAxState( rPropSet, maValue, mnMultiSelect, API_DEFAULTSTATE_BOOLEAN );
     AxMorphDataModelBase::convertFromProperties( rPropSet, rConv );
@@ -1660,6 +1661,7 @@ void AxCheckBoxModel::convertFromProperties( PropertySet& rPropSet, const Contro
 
     ControlConverter::convertToAxVisualEffect( rPropSet, mnSpecialEffect );
     ControlConverter::convertToMSColor( rPropSet, PROP_BackgroundColor, mnBackColor );
+    ControlConverter::convertToMSColor( rPropSet, PROP_TextColor, mnTextColor );
     // need to process the image if one exists
     ControlConverter::convertToAxState( rPropSet, maValue, mnMultiSelect, API_DEFAULTSTATE_BOOLEAN );
     AxMorphDataModelBase::convertFromProperties( rPropSet, rConv );
@@ -1722,6 +1724,7 @@ void AxOptionButtonModel::convertFromProperties( PropertySet& rPropSet, const Co
 
     ControlConverter::convertToAxVisualEffect( rPropSet, mnSpecialEffect );
     ControlConverter::convertToMSColor( rPropSet, PROP_BackgroundColor, mnBackColor );
+    ControlConverter::convertToMSColor( rPropSet, PROP_TextColor, mnTextColor );
     // need to process the image if one exists
     ControlConverter::convertToAxState( rPropSet, maValue, mnMultiSelect, API_DEFAULTSTATE_BOOLEAN );
     AxMorphDataModelBase::convertFromProperties( rPropSet, rConv );
@@ -1800,6 +1803,7 @@ void AxTextBoxModel::convertFromProperties( PropertySet& rPropSet, const Control
         setFlag( mnScrollBars, AX_SCROLLBAR_VERTICAL, bRes );
 
     ControlConverter::convertToMSColor( rPropSet, PROP_BackgroundColor, mnBackColor, 0x80000005L );
+    ControlConverter::convertToMSColor( rPropSet, PROP_TextColor, mnTextColor );
 
     ControlConverter::convertToAxBorder( rPropSet, mnBorderColor, mnBorderStyle, mnSpecialEffect );
     AxMorphDataModelBase::convertFromProperties( rPropSet, rConv );
@@ -1862,6 +1866,7 @@ void AxNumericFieldModel::convertFromProperties( PropertySet& rPropSet, const Co
         setFlag( mnScrollBars, AX_SCROLLBAR_VERTICAL, bRes );
 
     ControlConverter::convertToMSColor( rPropSet, PROP_BackgroundColor, mnBackColor );
+    ControlConverter::convertToMSColor( rPropSet, PROP_TextColor, mnTextColor );
 
     ControlConverter::convertToAxBorder( rPropSet, mnBorderColor, mnBorderStyle, mnSpecialEffect );
     AxMorphDataModelBase::convertFromProperties( rPropSet, rConv );
@@ -1919,6 +1924,7 @@ void AxListBoxModel::convertFromProperties( PropertySet& rPropSet, const Control
         ControlConverter::convertToMSColor( rPropSet, PROP_BackgroundColor, mnBackColor );
 
     ControlConverter::convertToAxBorder( rPropSet, mnBorderColor, mnBorderStyle, mnSpecialEffect );
+    ControlConverter::convertToMSColor( rPropSet, PROP_TextColor, mnTextColor );
     AxMorphDataModelBase::convertFromProperties( rPropSet, rConv );
 }
 
@@ -2004,6 +2010,7 @@ void AxComboBoxModel::convertFromProperties( PropertySet& rPropSet, const Contro
             mnListRows = 1;
     }
     ControlConverter::convertToMSColor( rPropSet, PROP_BackgroundColor, mnBackColor );
+    ControlConverter::convertToMSColor( rPropSet, PROP_TextColor, mnTextColor );
 
     ControlConverter::convertToAxBorder( rPropSet, mnBorderColor, mnBorderStyle, mnSpecialEffect );
     AxMorphDataModelBase::convertFromProperties( rPropSet, rConv );
commit e97590d3abd430d353cc692124bc41d0111e6cd4
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Mon Dec 25 15:02:41 2017 -0500

    rtl: support start/stop threads around pre-init
    
    This is necessary to avoid having extra threads
    while forking. After forking, the second stage
    of pre-init is started and so we start the stopped
    rtl threads.
    
    The comment for rtl_alloc_preInit_phase_t has
    more details.
    
    Reviewed-on: https://gerrit.libreoffice.org/47060
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 271a663d2f098f3f665cab6da2e13b265a7eab93)
    
    Change-Id: I1a3f7be74d4b04d0b2fc4a72b02124c2faa3c047

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index f87caa5b0787..f8aebcfc8606 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3552,7 +3552,9 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
         return 1;
 
     if (eStage == PRE_INIT)
-        rtl_alloc_preInit(true);
+        rtl_alloc_preInit(rtlAllocPreInitStart);
+    else if (eStage == SECOND_INIT)
+        rtl_alloc_preInit(rtlAllocPreInitEnd);
 
     if (eStage != SECOND_INIT)
         comphelper::LibreOfficeKit::setActive();
@@ -3707,7 +3709,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
     }
 
     if (eStage == PRE_INIT)
-        rtl_alloc_preInit(false);
+        rtl_alloc_preInit(rtlAllocPostInit);
 
     return bInitialized;
 }
diff --git a/include/rtl/alloc.h b/include/rtl/alloc.h
index cb4f09cbb67c..83babccb9e70 100644
--- a/include/rtl/alloc.h
+++ b/include/rtl/alloc.h
@@ -289,15 +289,49 @@ SAL_DLLPUBLIC void SAL_CALL rtl_cache_free (
 #ifdef LIBO_INTERNAL_ONLY
 
 /** @cond INTERNAL */
+/** rtl_alloc_preInit_phase_t
+ *
+ * This is used to control the pre-init logic
+ * in rtl_alloc_preInit. The reason for this is
+ * to first initialize all caching and other memory
+ * logic from WSD (the Online demaon) at startup.
+ * All these pages will then be forked over when
+ * spawning per-document instances. This is done
+ * by calling rtl_alloc_preInit with rtlAllocPreInitStart.
+ *
+ * However before forking we need to wind down
+ * all threads, which is required by design.
+ * This is done by calling rtl_alloc_preInit
+ * with rtlAllocPreInitEnd.
+ *
+ * And of course the stopped threads need restarting
+ * after forking to ensure correct cleanup of the
+ * caches and other memory allocations. This is done
+ * by calling rtl_alloc_preInit with rtlAllocPostInit.
+ *
+ * @since LibreOffice 6.1
+ */
+typedef enum
+{
+    // Start phase I of pre-init.
+    rtlAllocPreInitStart,
+    // Finish phase I of pre-init (before forking).
+    rtlAllocPreInitEnd,
+    // Post pre-init and after forking.
+    rtlAllocPostInit
+
+} rtl_alloc_preInit_phase_t;
+
+/** @cond INTERNAL */
 /** rtl_alloc_preInit
  *
  * This function, is called at the beginning and again
  * at the end of LibreOfficeKit pre-initialization to enable
  * various optimizations.
  *
- * Its function is to annotate a section @start = true to
- * end (@start = false) via. two calls. Inside this section
- * string allocators are replaced with ones which cause the
+ * Its function is to annotate a section @phase = rtlAllocPreInitStart
+ * to end (@phase = rtlAllocPreInitEnd) via. two calls. Inside this
+ * section string allocators are replaced with ones which cause the
  * strings to be staticized at the end of the section.
  *
  * This brings a number of constraints - in particular no
@@ -317,7 +351,7 @@ SAL_DLLPUBLIC void SAL_CALL rtl_cache_free (
  * @since LibreOffice 6.1
  */
 SAL_DLLPUBLIC void SAL_CALL rtl_alloc_preInit (
-    sal_Bool start
+    rtl_alloc_preInit_phase_t phase
 ) SAL_THROW_EXTERN_C();
 /** @endcond */
 
diff --git a/sal/inc/rtllifecycle.h b/sal/inc/rtllifecycle.h
index 82e38dee6372..528f4cc48a2f 100644
--- a/sal/inc/rtllifecycle.h
+++ b/sal/inc/rtllifecycle.h
@@ -26,6 +26,10 @@ void rtl_cache_fini(void);
 
 void ensureCacheSingleton(void);
 
+void rtl_cache_stop_threads(void);
+
+void rtl_cache_start_threads(void);
+
 void rtl_memory_init(void);
 
 void rtl_memory_fini(void);
diff --git a/sal/qa/rtl/alloc/rtl_alloc.cxx b/sal/qa/rtl/alloc/rtl_alloc.cxx
index 0e9b7c0f47a8..37c7b41eb338 100644
--- a/sal/qa/rtl/alloc/rtl_alloc.cxx
+++ b/sal/qa/rtl/alloc/rtl_alloc.cxx
@@ -158,7 +158,7 @@ public:
         const char *sample = "Hello World";
         std::vector<OUString> aStrings;
 
-        rtl_alloc_preInit(true);
+        rtl_alloc_preInit(rtlAllocPreInitStart);
 
         OUString aFoo("foo");
 
@@ -183,7 +183,7 @@ public:
         }
 
         // should static-ize all the strings.
-        rtl_alloc_preInit(false);
+        rtl_alloc_preInit(rtlAllocPreInitEnd);
 
         for (size_t i = 0; i < aStrings.size(); ++i)
             CPPUNIT_ASSERT_MESSAGE( "static after.", (aStrings[i].pData->refCount & SAL_STRING_STATIC_FLAG) );
diff --git a/sal/rtl/alloc_cache.cxx b/sal/rtl/alloc_cache.cxx
index 468bbdcdbf04..5ad8690e3152 100644
--- a/sal/rtl/alloc_cache.cxx
+++ b/sal/rtl/alloc_cache.cxx
@@ -1353,6 +1353,16 @@ rtl_cache_wsupdate_all(void * arg)
 #endif
 }
 
+void rtl_cache_stop_threads(void)
+{
+    rtl_cache_wsupdate_fini();
+}
+
+void rtl_cache_start_threads(void)
+{
+    rtl_cache_wsupdate_init();
+}
+
 void rtl_cache_init()
 {
     {
diff --git a/sal/rtl/strimp.cxx b/sal/rtl/strimp.cxx
index a739bda8f155..d520d2412b6e 100644
--- a/sal/rtl/strimp.cxx
+++ b/sal/rtl/strimp.cxx
@@ -21,6 +21,7 @@
 #include <assert.h>
 #include <rtl/alloc.h>
 #include <rtl/ustring.h>
+#include <rtllifecycle.h>
 
 #include "strimp.hxx"
 #include "alloc_impl.hxx"
@@ -93,25 +94,45 @@ static void mark_static(void *addr, sal_Size /* size */, void *)
     str->refCount |= SAL_STRING_STATIC_FLAG;
 }
 
-void SAL_CALL rtl_alloc_preInit (sal_Bool start) SAL_THROW_EXTERN_C()
+void SAL_CALL rtl_alloc_preInit (rtl_alloc_preInit_phase_t phase) SAL_THROW_EXTERN_C()
 {
-    if (start)
+    switch (phase)
     {
-        rtl_allocateString = pre_allocateStringFn;
-        rtl_freeString = pre_freeStringFn;
-        pre_arena = rtl_arena_create("pre-init strings", 4, 0,
-                                     nullptr, rtl_arena_alloc,
-                                     rtl_arena_free, 0);
-    }
-    else // back to normal
-    {
-        rtl_arena_foreach(pre_arena, mark_static, nullptr);
-        rtl_allocateString = rtl_allocateMemory;
-        rtl_freeString = rtl_freeMemory;
-
-        // TODO: also re-intialize main allocator as well.
+        case rtlAllocPreInitStart:
+        {
+            rtl_allocateString = pre_allocateStringFn;
+            rtl_freeString = pre_freeStringFn;
+            pre_arena = rtl_arena_create("pre-init strings", 4, 0,
+                                         nullptr, rtl_arena_alloc,
+                                         rtl_arena_free, 0);
+
+            // To be consistent (and to ensure the rtl_cache threads are started).
+            ensureCacheSingleton();
+        }
+        break;
+
+        case rtlAllocPreInitEnd:
+        // back to normal
+        {
+            rtl_arena_foreach(pre_arena, mark_static, nullptr);
+            rtl_allocateString = rtl_allocateMemory;
+            rtl_freeString = rtl_freeMemory;
+
+            // Stop the rtl cache thread to have no extra threads while forking.
+            rtl_cache_stop_threads();
+
+            // TODO: also re-initialize main allocator as well.
+        }
+        break;
+
+        case rtlAllocPostInit:
+        {
+            // We have forked and need to restart threads and anything
+            // that must start after forking.
+            rtl_cache_start_threads();
+        }
+        break;
     }
 }
 
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 6fb9ccd212130c890f93e27cf3a3b0743b42f45d
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Wed Dec 27 20:25:33 2017 +0100

    tdf#104734 Firebird: Add LONGVARBINARY/Image type
    
    Implement it as a user-defined Blob subtype.
    
    Change-Id: Ia369b6858e7d9191f34032445c1003931273e926
    Reviewed-on: https://gerrit.libreoffice.org/47098
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>
    Tested-by: Tamás Bunth <btomi96 at gmail.com>
    (cherry picked from commit 0217031a98508731f15df9d361a6e5b584db5716)

diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index f18d903a7402..0015219d53eb 100644
--- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
@@ -883,6 +883,11 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
         aResults.push_back(aRow);
 
+        // Longvarbinary (SQL_BLOB)
+        // Distinguished from simple blob with a user-defined subtype.
+        aRow[2] = new ORowSetValueDecorator(DataType::LONGVARBINARY);
+        aResults.push_back(aRow);
+
         // Integer Types common
         {
             aRow[6] = new ORowSetValueDecorator(); // Create Params
diff --git a/connectivity/source/drivers/firebird/Tables.cxx b/connectivity/source/drivers/firebird/Tables.cxx
index 53c388f4e01c..b41ea4e2d21b 100644
--- a/connectivity/source/drivers/firebird/Tables.cxx
+++ b/connectivity/source/drivers/firebird/Tables.cxx
@@ -10,6 +10,7 @@
 #include "Table.hxx"
 #include "Tables.hxx"
 #include "Catalog.hxx"
+#include "Util.hxx"
 
 #include <TConnection.hxx>
 
@@ -113,6 +114,12 @@ OUString Tables::createStandardColumnPart(const Reference< XPropertySet >& xColP
             aSql.append(" ");
             aSql.append("SUB_TYPE 1");
         }
+        else if(aType == DataType::LONGVARBINARY)
+        {
+            aSql.append(" ");
+            aSql.append("SUB_TYPE ");
+            aSql.append(OUString::number(static_cast<short>(BlobSubtype::Image)));
+        }
     }
 
     if ( bIsAutoIncrement && !sAutoIncrementValue.isEmpty())
diff --git a/connectivity/source/drivers/firebird/Util.cxx b/connectivity/source/drivers/firebird/Util.cxx
index 4036566b88dd..dd1213238d56 100644
--- a/connectivity/source/drivers/firebird/Util.cxx
+++ b/connectivity/source/drivers/firebird/Util.cxx
@@ -151,6 +151,8 @@ sal_Int32 firebird::ColumnTypeInfo::getSdbcType() const
                 return DataType::BLOB;
             case BlobSubtype::Clob:
                 return DataType::CLOB;
+            case BlobSubtype::Image:
+                return DataType::LONGVARBINARY;
             default:
                 SAL_WARN("connectivity.firebird", "Unknown subtype for Blob type: " << aSubType);
                 assert(!"Unknown subtype for Blob type"); // Should never happen
diff --git a/connectivity/source/drivers/firebird/Util.hxx b/connectivity/source/drivers/firebird/Util.hxx
index 2bf242ff441b..e93d3b68f288 100644
--- a/connectivity/source/drivers/firebird/Util.hxx
+++ b/connectivity/source/drivers/firebird/Util.hxx
@@ -28,9 +28,13 @@ namespace connectivity
         // Type Blob has 2 subtypes values
         // 0 for BLOB, 1 for CLOB
         // see http://www.firebirdfaq.org/faq48/
+        // User-defined subtypes are negative.
+        // Use a number for image which is very unlikely to be defined by a
+        // user.
         enum class BlobSubtype {
             Blob = 0,
-            Clob = 1
+            Clob = 1,
+            Image = -9546
         };
 
         // Numeric and decimal types can be identified by their subtype
commit 2c05c3bd2876707286cc9aec1ff9b9fbfa8e1b69
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Thu Dec 28 11:53:24 2017 +0100

    Firebird: use 32 bit
    
    Change-Id: I435524d1852a6691b382b93c9b6d2a7705938cd7
    Reviewed-on: https://gerrit.libreoffice.org/47130
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>
    Tested-by: Tamás Bunth <btomi96 at gmail.com>
    (cherry picked from commit 64d4f117447d990ed3215b0dd619e07de26ce417)

diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index d1de5787ab85..f18d903a7402 100644
--- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
@@ -874,7 +874,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         // Clob (SQL_BLOB)
         aRow[1] = new ORowSetValueDecorator(OUString("BLOB")); // BLOB, with subtype 1
         aRow[2] = new ORowSetValueDecorator(DataType::CLOB);
-        aRow[3] = new ORowSetValueDecorator(sal_Int16(2147483647)); // Precision = max length
+        aRow[3] = new ORowSetValueDecorator(sal_Int32(2147483647)); // Precision = max length
         aRow[6] = new ORowSetValueDecorator(); // Create Params
         aRow[9] = new ORowSetValueDecorator(
                 sal_Int16(ColumnSearch::FULL)); // Searchable
commit d12526684a43477a7c600936c17c27d28effa1df
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Wed Dec 13 13:46:39 2017 +0100

    tdf#104734 Firebird improve XClob implementation
    
    Create a more effective implementation of XClob::length() and
    XClob::getSubString() methods, where string is read segment-by-segment
    instead of reading the whole underlying blob. That way it is possible to
    handle big texts which would not fit into memory.
    
    Also allow reading Clob data from a resultset with getString() and
    writing it in a prepared statement with setString().
    
    Implement XPreparedStatement::setClob(). Also implement a private
    version of setClob() for creating a clob from OUString:
    
    Allow the creation of a clob column with GUI by adding a new type in
    ODataBaseMetaData::getTypeInfo().
    
    Change-Id: Ibcbbdd80e8eed5e2a3fe55b0fa196401f1bcbcdf
    Reviewed-on: https://gerrit.libreoffice.org/47093
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>
    Tested-by: Tamás Bunth <btomi96 at gmail.com>
    (cherry picked from commit f80b51ae441e3483a2e9b77a30b932d4e8fba192)

diff --git a/connectivity/source/drivers/firebird/Blob.cxx b/connectivity/source/drivers/firebird/Blob.cxx
index d7e3ac40f016..96e350d7a89b 100644
--- a/connectivity/source/drivers/firebird/Blob.cxx
+++ b/connectivity/source/drivers/firebird/Blob.cxx
@@ -70,9 +70,14 @@ void Blob::ensureBlobIsOpened()
     m_nBlobPosition = 0;
 
     char aBlobItems[] = {
-        isc_info_blob_total_length
+        isc_info_blob_total_length,
+        isc_info_blob_max_segment
     };
-    char aResultBuffer[20];
+
+    // Assuming a data (e.g. legth of blob) is maximum 64 bit.
+    // That means we need 8 bytes for data + 2 for length of data + 1 for item
+    // identifier for each item.
+    char aResultBuffer[11 + 11];
 
     aErr = isc_blob_info(m_statusVector,
                   &m_blobHandle,
@@ -84,17 +89,63 @@ void Blob::ensureBlobIsOpened()
     if (aErr)
         evaluateStatusVector(m_statusVector, "isc_blob_info", *this);
 
-    if (*aResultBuffer == isc_info_blob_total_length)
+    char* pIt = aResultBuffer;
+    while( *pIt != isc_info_end ) // info is in clusters
     {
-        short aResultLength = (short) isc_vax_integer(aResultBuffer+1, 2);
-        m_nBlobLength =  isc_vax_integer(aResultBuffer+3, aResultLength);
+        char item = *pIt++;
+        short aResultLength = (short) isc_vax_integer(pIt, 2);
+
+        pIt += 2;
+        switch(item)
+        {
+            case isc_info_blob_total_length:
+                m_nBlobLength = isc_vax_integer(pIt, aResultLength);
+                break;
+            case isc_info_blob_max_segment:
+                m_nMaxSegmentSize = isc_vax_integer(pIt, aResultLength);
+                break;
+            default:
+                assert(false);
+                break;
+        }
+        pIt += aResultLength;
     }
-    else
+}
+
+sal_uInt16 Blob::getMaximumSegmentSize()
+{
+    ensureBlobIsOpened();
+
+    return m_nMaxSegmentSize;
+}
+
+bool Blob::readOneSegment(uno::Sequence< sal_Int8 >& rDataOut)
+{
+    checkDisposed(Blob_BASE::rBHelper.bDisposed);
+    ensureBlobIsOpened();
+
+    sal_uInt16 nMaxSize = getMaximumSegmentSize();
+
+    if(rDataOut.getLength() < nMaxSize)
+        rDataOut.realloc(nMaxSize);
+
+    sal_uInt16 nActualSize = 0;
+    ISC_STATUS aRet = isc_get_segment(m_statusVector,
+            &m_blobHandle,
+            &nActualSize,
+            nMaxSize,
+            reinterpret_cast<char*>(rDataOut.getArray()) );
+
+    if (aRet && aRet != isc_segstr_eof && IndicatesError(m_statusVector))
     {
-        assert(false);
+        OUString sError(StatusVectorToString(m_statusVector, "isc_get_segment"));
+        throw IOException(sError, *this);
     }
+    m_nBlobPosition += nActualSize;
+    return aRet == isc_segstr_eof;  // last segment read
 }
 
+
 void Blob::closeBlob()
 {
     MutexGuard aGuard(m_aMutex);
diff --git a/connectivity/source/drivers/firebird/Blob.hxx b/connectivity/source/drivers/firebird/Blob.hxx
index 9afa09dec8fd..0a3627de417c 100644
--- a/connectivity/source/drivers/firebird/Blob.hxx
+++ b/connectivity/source/drivers/firebird/Blob.hxx
@@ -41,6 +41,7 @@ namespace connectivity
 
             bool                m_bBlobOpened;
             sal_Int64           m_nBlobLength;
+            sal_uInt16          m_nMaxSegmentSize;
             sal_Int64           m_nBlobPosition;
 
             ISC_STATUS_ARRAY    m_statusVector;
@@ -54,12 +55,15 @@ namespace connectivity
              * @throws css::sdbc::SQLException
              */
             void closeBlob();
+            sal_uInt16 getMaximumSegmentSize();
 
         public:
             Blob(isc_db_handle* pDatabaseHandle,
                  isc_tr_handle* pTransactionHandle,
                  ISC_QUAD const & aBlobID);
 
+            bool readOneSegment(css::uno::Sequence< sal_Int8 >& rDataOut);
+
             // ---- XBlob ----------------------------------------------------
             virtual sal_Int64 SAL_CALL
                 length() override;
diff --git a/connectivity/source/drivers/firebird/Clob.cxx b/connectivity/source/drivers/firebird/Clob.cxx
index 7e2d49727ed1..d14e35723569 100644
--- a/connectivity/source/drivers/firebird/Clob.cxx
+++ b/connectivity/source/drivers/firebird/Clob.cxx
@@ -28,7 +28,8 @@ Clob::Clob(isc_db_handle* pDatabaseHandle,
            isc_tr_handle* pTransactionHandle,
            ISC_QUAD const & aBlobID):
     Clob_BASE(m_aMutex),
-    m_aBlob(new connectivity::firebird::Blob(pDatabaseHandle, pTransactionHandle, aBlobID))
+    m_aBlob(new connectivity::firebird::Blob(pDatabaseHandle, pTransactionHandle, aBlobID)),
+    m_nCharCount(-1)
 {
 }
 
@@ -44,13 +45,27 @@ sal_Int64 SAL_CALL Clob::length()
     MutexGuard aGuard(m_aMutex);
     checkDisposed(Clob_BASE::rBHelper.bDisposed);
 
-    // read the entire blob
-    // TODO FIXME better solution?
-    uno::Sequence < sal_Int8 > aEntireBlob = m_aBlob->getBytes( 1, m_aBlob->length());
-    OUString sEntireClob (  reinterpret_cast< sal_Char *>( aEntireBlob.getArray() ),
-                            aEntireBlob.getLength(),
+    if( m_nCharCount >= 0 )
+        return m_nCharCount;
+    m_nCharCount = 0;
+
+    // Read each segment, and calculate it's size by interpreting it as a
+    // character stream. Assume that no characters are split by the segments.
+    bool bLastSegmRead = false;
+    do
+    {
+        uno::Sequence < sal_Int8 > aSegmentBytes;
+        bLastSegmRead = m_aBlob->readOneSegment( aSegmentBytes );
+        OUString sSegment ( reinterpret_cast< sal_Char *>( aSegmentBytes.getArray() ),
+                            aSegmentBytes.getLength(),
                             RTL_TEXTENCODING_UTF8 );
-    return sEntireClob.getLength();
+
+        if( !bLastSegmRead)
+            m_nCharCount += sSegment.getLength();
+    }while( !bLastSegmRead );
+
+    m_aBlob->closeInput(); // reset position
+    return m_nCharCount;
 }
 
 OUString SAL_CALL Clob::getSubString(sal_Int64 nPosition,
@@ -58,19 +73,58 @@ OUString SAL_CALL Clob::getSubString(sal_Int64 nPosition,
 {
     MutexGuard aGuard(m_aMutex);
     checkDisposed(Clob_BASE::rBHelper.bDisposed);
-
-    // read the entire blob
-    // TODO FIXME better solution?
-    // TODO FIXME Assume indexing of nPosition starts at position 1.
-    uno::Sequence < sal_Int8 > aEntireBlob = m_aBlob->getBytes( 1, m_aBlob->length());
-    OUString sEntireClob (  reinterpret_cast< sal_Char *>( aEntireBlob.getArray() ),
-                            aEntireBlob.getLength(),
+    // TODO do not reset position if it is not necessary
+    m_aBlob->closeInput(); // reset position
+
+    OUStringBuffer sSegmentBuffer;
+    sal_Int64 nActPos = 1;
+    sal_Int32 nActLen = 0;
+
+    // skip irrelevant parts
+    while( nActPos < nPosition )
+    {
+        uno::Sequence < sal_Int8 > aSegmentBytes;
+        bool bLastRead = m_aBlob->readOneSegment( aSegmentBytes );
+        if( bLastRead )
+            throw lang::IllegalArgumentException("nPosition out of range", *this, 0);
+
+        OUString sSegment ( reinterpret_cast< sal_Char *>( aSegmentBytes.getArray() ),
+                            aSegmentBytes.getLength(),
                             RTL_TEXTENCODING_UTF8 );
-
-    if( nPosition + nLength - 1 > sEntireClob.getLength() )
-        throw lang::IllegalArgumentException("nPosition out of range", *this, 0);
-
-    return sEntireClob.copy(nPosition - 1 , nLength);
+        sal_Int32 nStrLen = sSegment.getLength();
+        nActPos += nStrLen;
+        if( nActPos > nPosition )
+        {
+            sal_Int32 nCharsToCopy = static_cast<sal_Int32>(nActPos - nPosition);
+            if( nCharsToCopy > nLength )
+                nCharsToCopy = nLength;
+            // append relevant part of first segment
+            sSegmentBuffer.append( sSegment.copy(0, nCharsToCopy ) );
+            nActLen += sSegmentBuffer.getLength();
+        }
+    }
+
+    // read nLength characters
+    while( nActLen < nLength )
+    {
+        uno::Sequence < sal_Int8 > aSegmentBytes;
+        bool bLastRead = m_aBlob->readOneSegment( aSegmentBytes );
+
+        OUString sSegment ( reinterpret_cast< sal_Char *>( aSegmentBytes.getArray() ),
+                            aSegmentBytes.getLength(),
+                            RTL_TEXTENCODING_UTF8 );
+        sal_Int32 nStrLen = sSegment.getLength();
+        if( nActLen + nStrLen > nLength )
+            sSegmentBuffer.append(sSegment.copy(0, nLength - nActLen) );
+        else
+            sSegmentBuffer.append(sSegment);
+        nActLen += nStrLen;
+
+        if( bLastRead && nActLen < nLength )
+            throw lang::IllegalArgumentException("out of range", *this, 0);
+    }
+
+    return sSegmentBuffer.makeStringAndClear();
 }
 
 uno::Reference< XInputStream > SAL_CALL  Clob::getCharacterStream()
diff --git a/connectivity/source/drivers/firebird/Clob.hxx b/connectivity/source/drivers/firebird/Clob.hxx
index d435312f9f36..738b0ce86c64 100644
--- a/connectivity/source/drivers/firebird/Clob.hxx
+++ b/connectivity/source/drivers/firebird/Clob.hxx
@@ -38,6 +38,8 @@ namespace connectivity
              */
             rtl::Reference<connectivity::firebird::Blob> m_aBlob;
 
+            sal_Int64 m_nCharCount;
+
         public:
             Clob(isc_db_handle* pDatabaseHandle,
                  isc_tr_handle* pTransactionHandle,
diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index 614ccf7c2409..d1de5787ab85 100644
--- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
@@ -870,6 +870,15 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
         aRow[9] = new ORowSetValueDecorator(
                 sal_Int16(ColumnSearch::NONE)); // Searchable
+
+        // Clob (SQL_BLOB)
+        aRow[1] = new ORowSetValueDecorator(OUString("BLOB")); // BLOB, with subtype 1
+        aRow[2] = new ORowSetValueDecorator(DataType::CLOB);
+        aRow[3] = new ORowSetValueDecorator(sal_Int16(2147483647)); // Precision = max length
+        aRow[6] = new ORowSetValueDecorator(); // Create Params
+        aRow[9] = new ORowSetValueDecorator(
+                sal_Int16(ColumnSearch::FULL)); // Searchable
+        aRow[12] = new ORowSetValueDecorator(false); // Autoincrement
         aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
         aResults.push_back(aRow);
diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx
index 37441d5c6b1f..afe1fa3229a6 100644
--- a/connectivity/source/drivers/firebird/PreparedStatement.cxx
+++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx
@@ -178,10 +178,10 @@ void SAL_CALL OPreparedStatement::disposing()
 }
 
 void SAL_CALL OPreparedStatement::setString(sal_Int32 nParameterIndex,
-                                            const OUString& x)
+                                            const OUString& sInput)
 {
     SAL_INFO("connectivity.firebird",
-             "setString(" << nParameterIndex << " , " << x << ")");
+             "setString(" << nParameterIndex << " , " << sInput << ")");
 
     MutexGuard aGuard( m_aMutex );
     checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
@@ -190,7 +190,7 @@ void SAL_CALL OPreparedStatement::setString(sal_Int32 nParameterIndex,
     checkParameterIndex(nParameterIndex);
     setParameterNull(nParameterIndex, false);
 
-    OString str = OUStringToOString(x , RTL_TEXTENCODING_UTF8 );
+    OString str = OUStringToOString(sInput , RTL_TEXTENCODING_UTF8 );
 
     XSQLVAR* pVar = m_pInSqlda->sqlvar + (nParameterIndex - 1);
 
@@ -219,6 +219,10 @@ void SAL_CALL OPreparedStatement::setString(sal_Int32 nParameterIndex,
         // Fill remainder with spaces
         memset(pVar->sqldata + str.getLength(), ' ', pVar->sqllen - str.getLength());
         break;
+    case SQL_BLOB: // Clob
+        assert( pVar->sqlsubtype == static_cast<short>(BlobSubtype::Clob) );
+        setClob(nParameterIndex, sInput );
+        break;
     default:
         ::dbtools::throwSQLException(
             "Incorrect type for setString",
@@ -506,21 +510,105 @@ void OPreparedStatement::closeBlobAfterWriting(isc_blob_handle& rBlobHandle)
     ISC_STATUS aErr;
 
     aErr = isc_close_blob(m_statusVector,
-                          &rBlobHandle);
+            &rBlobHandle);
     if (aErr)
     {
         evaluateStatusVector(m_statusVector,
-                             "isc_close_blob failed",
-                             *this);
+                "isc_close_blob failed",
+                *this);
+        assert(false);
+    }
+}
+
+void SAL_CALL OPreparedStatement::setClob(sal_Int32 nParameterIndex, const Reference< XClob >& xClob )
+{
+    ::osl::MutexGuard aGuard( m_aMutex );
+    checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
+
+#if SAL_TYPES_SIZEOFPOINTER == 8
+    isc_blob_handle aBlobHandle = 0;
+#else
+    isc_blob_handle aBlobHandle = nullptr;
+#endif
+    ISC_QUAD aBlobId;
+
+    openBlobForWriting(aBlobHandle, aBlobId);
+
+
+    // Max segment size is 2^16 == SAL_MAX_UINT16
+    // SAL_MAX_UINT16 / 4 is surely enough for UTF-8
+    // TODO apply max segment size to character encoding
+    sal_Int64 nCharWritten = 1; // XClob is indexed from 1
+    ISC_STATUS aErr = 0;
+    sal_Int64 nLen = xClob->length();
+    while ( nLen > nCharWritten )
+    {
+        sal_Int64 nCharRemain = nLen - nCharWritten;
+        constexpr sal_uInt16 MAX_SIZE = SAL_MAX_UINT16 / 4;
+        sal_uInt16 nWriteSize = (nCharRemain > MAX_SIZE) ? MAX_SIZE : nCharRemain;
+        OString sData = OUStringToOString(
+                xClob->getSubString(nCharWritten, nWriteSize),
+                RTL_TEXTENCODING_UTF8);
+        aErr = isc_put_segment( m_statusVector,
+                &aBlobHandle,
+                sData.getLength(),
+                sData.getStr() );
+        nCharWritten += nWriteSize;
+
+        if (aErr)
+            break;
+    }
+
+    // We need to make sure we close the Blob even if their are errors, hence evaluate
+    // errors after closing.
+    closeBlobAfterWriting(aBlobHandle);
+
+    if (aErr)
+    {
+        evaluateStatusVector(m_statusVector,
+                "isc_put_segment failed",
+                *this);
         assert(false);
     }
+
+    setValue< ISC_QUAD >(nParameterIndex, aBlobId, SQL_BLOB);
 }
 
-void SAL_CALL OPreparedStatement::setClob( sal_Int32, const Reference< XClob >& )
+void OPreparedStatement::setClob( sal_Int32 nParameterIndex, const OUString& rStr )
 {
     ::osl::MutexGuard aGuard( m_aMutex );
     checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
 
+#if SAL_TYPES_SIZEOFPOINTER == 8
+    isc_blob_handle aBlobHandle = 0;
+#else
+    isc_blob_handle aBlobHandle = nullptr;
+#endif
+    ISC_QUAD aBlobId;
+
+    openBlobForWriting(aBlobHandle, aBlobId);
+
+    OString sData = OUStringToOString(
+            rStr,
+            RTL_TEXTENCODING_UTF8);
+    ISC_STATUS aErr = isc_put_segment( m_statusVector,
+                            &aBlobHandle,
+                            sData.getLength(),
+                            sData.getStr() );
+
+    // We need to make sure we close the Blob even if their are errors, hence evaluate
+    // errors after closing.
+    closeBlobAfterWriting(aBlobHandle);
+
+    if (aErr)
+    {
+        evaluateStatusVector(m_statusVector,
+                             "isc_put_segment failed",
+                             *this);
+        assert(false);
+    }
+
+    setValue< ISC_QUAD >(nParameterIndex, aBlobId, SQL_BLOB);
 }
 
 void SAL_CALL OPreparedStatement::setBlob(sal_Int32 nParameterIndex,
diff --git a/connectivity/source/drivers/firebird/PreparedStatement.hxx b/connectivity/source/drivers/firebird/PreparedStatement.hxx
index 81910ad1f3dd..19f19d423c7b 100644
--- a/connectivity/source/drivers/firebird/PreparedStatement.hxx
+++ b/connectivity/source/drivers/firebird/PreparedStatement.hxx
@@ -78,6 +78,7 @@ namespace connectivity
              * Assumes that all necessary mutexes have been taken.
              */
             void closeBlobAfterWriting(isc_blob_handle& rBlobHandle);
+            void setClob(sal_Int32 nParamIndex, const OUString& rStr);
 
         protected:
             virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,
diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx
index abb0c03b8be0..9e8387d39a3d 100644
--- a/connectivity/source/drivers/firebird/ResultSet.cxx
+++ b/connectivity/source/drivers/firebird/ResultSet.cxx
@@ -604,6 +604,11 @@ OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT
                 return OUString(); // never reached
         }
     }
+    else if(aSqlType == SQL_BLOB && aSqlSubType == static_cast<short>(BlobSubtype::Clob) )
+    {
+        uno::Reference<XClob> xClob = getClob(nColumnIndex);
+        return xClob->getSubString( 0, xClob->length() );
+    }
     else
     {
         return retrieveValue< ORowSetValue >(nColumnIndex, 0);
diff --git a/connectivity/source/drivers/firebird/Tables.cxx b/connectivity/source/drivers/firebird/Tables.cxx
index 57a44650589e..53c388f4e01c 100644
--- a/connectivity/source/drivers/firebird/Tables.cxx
+++ b/connectivity/source/drivers/firebird/Tables.cxx
@@ -106,6 +106,13 @@ OUString Tables::createStandardColumnPart(const Reference< XPropertySet >& xColP
             aSql.append(" ");
             aSql.append("CHARACTER SET OCTETS");
         }
+        else if(aType == DataType::CLOB)
+        {
+            // CLOB is a special type of blob in Firebird context.
+            // Subtype number 1 always refers to CLOB
+            aSql.append(" ");
+            aSql.append("SUB_TYPE 1");
+        }
     }
 
     if ( bIsAutoIncrement && !sAutoIncrementValue.isEmpty())
diff --git a/connectivity/source/drivers/firebird/Util.cxx b/connectivity/source/drivers/firebird/Util.cxx
index e91e0da0bdf9..4036566b88dd 100644
--- a/connectivity/source/drivers/firebird/Util.cxx
+++ b/connectivity/source/drivers/firebird/Util.cxx
@@ -118,13 +118,14 @@ sal_Int32 firebird::ColumnTypeInfo::getSdbcType() const
     short aSubType = m_aSubType;
     if( m_nScale > 0 )
     {
-        // scale makes sense only for decimal and numeric types
-        assert(aType == SQL_SHORT || aType == SQL_LONG || aType == SQL_DOUBLE
-                || aType == SQL_INT64);
-
-        // if scale is set without subtype then imply numeric
-        if( static_cast<NumberSubType>(aSubType) == NumberSubType::Other )
-            aSubType = static_cast<short>(NumberSubType::Numeric);
+        // numeric / decimal
+        if(aType == SQL_SHORT || aType == SQL_LONG || aType == SQL_DOUBLE
+                || aType == SQL_INT64)
+        {
+            // if scale is set without subtype then imply numeric
+            if( static_cast<NumberSubType>(aSubType) == NumberSubType::Other )
+                aSubType = static_cast<short>(NumberSubType::Numeric);
+        }
     }
 
     switch (aType)
commit d0f6e30ed05b3949436eb2d49f33bf8a30dc47ef
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Mon Dec 18 14:47:40 2017 +0100

    tdf#104734 Firebird: Add VARBINARY type to driver
    
    Change-Id: I9a1b3aa9bde855577078fe0db2e31a9c160031d7
    Reviewed-on: https://gerrit.libreoffice.org/47092
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>
    (cherry picked from commit e7a80ddb91c44711296aa996bf00242edbfba32d)

diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index dcb617363692..614ccf7c2409 100644
--- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
@@ -863,6 +863,17 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
         aResults.push_back(aRow);
 
+        // Varbinary (VARCHAR)
+        aRow[1] = new ORowSetValueDecorator(OUString("VARCHAR"));
+        aRow[2] = new ORowSetValueDecorator(DataType::VARBINARY);
+        aRow[3] = new ORowSetValueDecorator(sal_Int16(32765)); // Prevision = max length
+        aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
+        aRow[9] = new ORowSetValueDecorator(
+                sal_Int16(ColumnSearch::NONE)); // Searchable
+        aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
+        aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
+        aResults.push_back(aRow);
+
         // Integer Types common
         {
             aRow[6] = new ORowSetValueDecorator(); // Create Params
diff --git a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
index 725ed288d00a..b598846545de 100644
--- a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
+++ b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
@@ -96,7 +96,8 @@ sal_Int32 SAL_CALL OResultSetMetaData::getColumnType(sal_Int32 column)
     short aType = m_pSqlda->sqlvar[column-1].sqltype & ~1;
     OUString sCharset;
 
-    if(aType == SQL_TEXT)
+    // do not query the character set unnecessarily
+    if(aType == SQL_TEXT || aType == SQL_VARYING)
     {
         sCharset = getCharacterSet(column);
     }
diff --git a/connectivity/source/drivers/firebird/Tables.cxx b/connectivity/source/drivers/firebird/Tables.cxx
index 5a79f8afe33d..57a44650589e 100644
--- a/connectivity/source/drivers/firebird/Tables.cxx
+++ b/connectivity/source/drivers/firebird/Tables.cxx
@@ -101,7 +101,7 @@ OUString Tables::createStandardColumnPart(const Reference< XPropertySet >& xColP
         sal_Int32 aType = 0;
         xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE))
             >>= aType;
-        if(aType == DataType::BINARY)
+        if(aType == DataType::BINARY || aType == DataType::VARBINARY)
         {
             aSql.append(" ");
             aSql.append("CHARACTER SET OCTETS");
diff --git a/connectivity/source/drivers/firebird/Util.cxx b/connectivity/source/drivers/firebird/Util.cxx
index 20587e5172ba..e91e0da0bdf9 100644
--- a/connectivity/source/drivers/firebird/Util.cxx
+++ b/connectivity/source/drivers/firebird/Util.cxx
@@ -100,8 +100,11 @@ sal_Int32 lcl_getCharColumnType( short aType, const OUString& sCharset )
                 return DataType::BINARY;
             else
                 return DataType::CHAR;
-        case SQL_VARYING: // TODO VARBINARY
-            return DataType::VARCHAR;
+        case SQL_VARYING:
+            if( sCharset == "OCTETS")
+                return DataType::VARBINARY;
+            else
+                return DataType::VARCHAR;
         default:
             assert(false);
             return 0;
commit a50a418c946c5f37de9bc6ae5853744e71f78147
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date:   Sat Dec 16 12:57:43 2017 +0100

    tdf#104734 Firebird: Add Binary (fix) type
    
    There is no explicit binary type in Firebird. It can be accomplished
    using the CHAR type with a special character set, which tells the
    database that it is binary data and there is no collation. (called
    OCTETS).
    
    Because of that, we also need the character set to decide the exact
    column type.
    
    And also refactor some parts of the driver:
    - Create class to determine internal type from firebird type, subtype,
    scale and character set.
    - Use internal type (DataType::XXX) in XDatabaseMetaData::getTypeInfo()
    indirectly. (We want to return a Firebird type for each internal type,
    not in the opposite direction.
    
    Change-Id: Ica56a84d89253e11936e7012086fe1d9f61a65f0
    Reviewed-on: https://gerrit.libreoffice.org/47091
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Bunth <btomi96 at gmail.com>
    (cherry picked from commit bf662904c4b60e93c6b86e06288d41996eed12a2)

diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index 92e46c8ba95d..dcb617363692 100644
--- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
@@ -827,9 +827,9 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aRow[17] = new ORowSetValueDecorator();             // Unused
         aRow[18] = new ORowSetValueDecorator(sal_Int16(10));// Radix
 
-        // SQL_TEXT
+        // Char
         aRow[1] = new ORowSetValueDecorator(OUString("CHAR"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TEXT, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::CHAR);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(32765)); // Prevision = max length
         aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
         aRow[9] = new ORowSetValueDecorator(
@@ -839,9 +839,9 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
         aResults.push_back(aRow);
 
-        // SQL_VARYING
+        // Varchar
         aRow[1] = new ORowSetValueDecorator(OUString("VARCHAR"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_VARYING, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::VARCHAR);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(32765)); // Prevision = max length
         aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
         aRow[9] = new ORowSetValueDecorator(
@@ -851,6 +851,18 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
         aResults.push_back(aRow);
 
+        // Binary (CHAR)
+        // It is distinguished from Text type by its character set
+        aRow[1] = new ORowSetValueDecorator(OUString("CHAR"));
+        aRow[2] = new ORowSetValueDecorator(DataType::BINARY);
+        aRow[3] = new ORowSetValueDecorator(sal_Int16(32765)); // Prevision = max length
+        aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
+        aRow[9] = new ORowSetValueDecorator(
+                sal_Int16(ColumnSearch::NONE)); // Searchable
+        aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
+        aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
+        aResults.push_back(aRow);
+
         // Integer Types common
         {
             aRow[6] = new ORowSetValueDecorator(); // Create Params
@@ -860,19 +872,19 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
             aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
             aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
         }
-        // SQL_SHORT
+        // Smallint (SQL_SHORT)
         aRow[1] = new ORowSetValueDecorator(OUString("SMALLINT"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_SHORT, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::SMALLINT);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(5)); // Prevision
         aResults.push_back(aRow);
-        // SQL_LONG
+        // Integer (SQL_LONG)
         aRow[1] = new ORowSetValueDecorator(OUString("INTEGER"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_LONG, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::INTEGER);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(10)); // Precision
         aResults.push_back(aRow);
-        // SQL_INT64
+        // Bigint (SQL_INT64)
         aRow[1] = new ORowSetValueDecorator(OUString("BIGINT"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_INT64, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::BIGINT);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(20)); // Precision
         aResults.push_back(aRow);
 
@@ -884,14 +896,14 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         }
 
         aRow[6] = new ORowSetValueDecorator(OUString("PRECISION,SCALE")); // Create params
-        // NUMERIC
+        // Numeric
         aRow[1] = new ORowSetValueDecorator(OUString("NUMERIC"));
         aRow[2] = new ORowSetValueDecorator(DataType::NUMERIC);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
         aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
         aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
         aResults.push_back(aRow);
-        // DECIMAL
+        // Decimal
         aRow[1] = new ORowSetValueDecorator(OUString("DECIMAL"));
         aRow[2] = new ORowSetValueDecorator(DataType::DECIMAL);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
@@ -900,34 +912,26 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aResults.push_back(aRow);
 
         aRow[6] = new ORowSetValueDecorator(); // Create Params
-        // SQL_FLOAT
+        // Float (SQL_FLOAT)
         aRow[1] = new ORowSetValueDecorator(OUString("FLOAT"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_FLOAT, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::FLOAT);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(7)); // Precision
         aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
         aRow[15] = new ORowSetValueDecorator(sal_Int16(7)); // Max scale
         aResults.push_back(aRow);
-        // SQL_DOUBLE
+        // Double (SQL_DOUBLE)
         aRow[1] = new ORowSetValueDecorator(OUString("DOUBLE PRECISION"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_DOUBLE, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::DOUBLE);
         aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
         aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
         aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
         aResults.push_back(aRow);
 
-//         // SQL_D_FLOAT
-//         aRow[1] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(SQL_D_FLOAT, 0, 0));
-//         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_D_FLOAT, 0, 0));
-//         aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
-//         aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
-//         aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
-//         aResults.push_back(aRow);
         // TODO: no idea whether D_FLOAT corresponds to an sql type
 
         // SQL_TIMESTAMP
-        // TODO: precision?
         aRow[1] = new ORowSetValueDecorator(OUString("TIMESTAMP"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TIMESTAMP, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::TIMESTAMP);
         aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
         aRow[6] = new ORowSetValueDecorator(); // Create Params
         aRow[9] = new ORowSetValueDecorator(
@@ -938,9 +942,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aResults.push_back(aRow);
 
         // SQL_TYPE_TIME
-        // TODO: precision?
         aRow[1] = new ORowSetValueDecorator(OUString("TIME"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_TIME, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::TIME);
         aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
         aRow[6] = new ORowSetValueDecorator(); // Create Params
         aRow[9] = new ORowSetValueDecorator(
@@ -951,9 +954,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aResults.push_back(aRow);
 
         // SQL_TYPE_DATE
-        // TODO: precision?
         aRow[1] = new ORowSetValueDecorator(OUString("DATE"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_DATE, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::DATE);
         aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
         aRow[6] = new ORowSetValueDecorator(); // Create Params
         aRow[9] = new ORowSetValueDecorator(
@@ -964,9 +966,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aResults.push_back(aRow);
 
         // SQL_BLOB
-        // TODO: precision?
         aRow[1] = new ORowSetValueDecorator(OUString("BLOB"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BLOB, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::BLOB);
         aRow[3] = new ORowSetValueDecorator(sal_Int32(0)); // Prevision = max length
         aRow[6] = new ORowSetValueDecorator(); // Create Params
         aRow[9] = new ORowSetValueDecorator(
@@ -977,9 +978,8 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aResults.push_back(aRow);
 
         // SQL_BOOLEAN
-        // TODO FIXME precision
         aRow[1] = new ORowSetValueDecorator(OUString("BOOLEAN"));
-        aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BOOLEAN, 0, 0));
+        aRow[2] = new ORowSetValueDecorator(DataType::BOOLEAN);
         aRow[3] = new ORowSetValueDecorator(sal_Int32(1)); // Prevision = max length
         aRow[6] = new ORowSetValueDecorator(); // Create Params
         aRow[9] = new ORowSetValueDecorator(
@@ -989,10 +989,6 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
         aResults.push_back(aRow);
 
-        // TODO: complete
-//     case SQL_ARRAY:
-//     case SQL_NULL:
-//     case SQL_QUAD:      // Is a "Blob ID" according to the docs
     }
     pResultSet->setRows(aResults);
     return xResultSet;
@@ -1099,10 +1095,13 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns(
         // this is also the one we manually fiddle when changin NULL/NOT NULL
         // (see Table.cxx)
         "relfields.RDB$NULL_FLAG, "      // 11
-        "fields.RDB$CHARACTER_LENGTH "   // 12
+        "fields.RDB$CHARACTER_LENGTH, "   // 12
+        "charset.RDB$CHARACTER_SET_NAME " // 13
         "FROM RDB$RELATION_FIELDS relfields "
         "JOIN RDB$FIELDS fields "
         "on (fields.RDB$FIELD_NAME = relfields.RDB$FIELD_SOURCE) "
+        "LEFT JOIN RDB$CHARACTER_SETS charset "
+        "on (fields.RDB$CHARACTER_SET_ID = charset.RDB$CHARACTER_SET_ID) "
         "WHERE (1 = 1) ");
 
     if (!tableNamePattern.isEmpty())
@@ -1152,11 +1151,16 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns(
         aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
         // 5. Datatype
         short aType = getFBTypeFromBlrType(xRow->getShort(6));
-        short aSubType = xRow->getShort(7);
         short aScale = xRow->getShort(10);
-        aCurrentRow[5] = new ORowSetValueDecorator(getColumnTypeFromFBType(aType, aSubType, aScale));
+        OUString sCharsetName = xRow->getString(13);
+        // result field may be filled with spaces
+        sCharsetName = sCharsetName.trim();
+        ColumnTypeInfo aInfo(aType, xRow->getShort(7), aScale,
+                xRow->getString(13));
+
+        aCurrentRow[5] = new ORowSetValueDecorator(aInfo.getSdbcType());
         // 6. Typename (SQL_*)
-        aCurrentRow[6] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(aType, aSubType, aScale));
+        aCurrentRow[6] = new ORowSetValueDecorator(aInfo.getColumnTypeName());
 
         // 7. Column Sizes
         {
diff --git a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
index e5ba68a3bd72..725ed288d00a 100644
--- a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
+++ b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
@@ -39,6 +39,39 @@ OResultSetMetaData::~OResultSetMetaData()
 {
 }
 
+OUString OResultSetMetaData::getCharacterSet( sal_Int32 nIndex )
+{
+    OUString sTable = getTableName( nIndex );
+    if( !sTable.isEmpty() )
+    {
+        OUString sColumnName = getColumnName( nIndex );
+
+        OUString sSql = "SELECT charset.RDB$CHARACTER_SET_NAME "
+                        "FROM RDB$CHARACTER_SETS charset "
+                        "JOIN RDB$FIELDS fields "
+                        "ON (fields.RDB$CHARACTER_SET_ID = charset.RDB$CHARACTER_SET_ID) "
+                        "JOIN RDB$RELATION_FIELDS relfields "
+                        "ON (fields.RDB$FIELD_NAME = relfields.RDB$FIELD_SOURCE) "
+                        "WHERE relfields.RDB$RELATION_NAME = '"
+                   + escapeWith(sTable, '\'', '\'') + "' AND "
+                   "relfields.RDB$FIELD_NAME = '"+ escapeWith(sColumnName, '\'', '\'') +"'";
+
+        Reference<XStatement> xStmt= m_pConnection->createStatement();
+
+        Reference<XResultSet> xRes =
+                xStmt->executeQuery(sSql);
+        Reference<XRow> xRow ( xRes, UNO_QUERY);
+        if(xRes->next())
+        {
+            OUString sCharset = xRow->getString(1).trim();
+            return sCharset;
+        }
+    }
+    return OUString();
+
+
+}
+
 void OResultSetMetaData::verifyValidColumn(sal_Int32 column)
 {
     if (column>getColumnCount() || column < 1)
@@ -60,11 +93,20 @@ sal_Int32 SAL_CALL OResultSetMetaData::getColumnType(sal_Int32 column)
 {
     verifyValidColumn(column);
 
-    short aType = m_pSqlda->sqlvar[column-1].sqltype;
-    short aSubType = m_pSqlda->sqlvar[column-1].sqlsubtype;
-    short aScale = m_pSqlda->sqlvar[column-1].sqlscale;
+    short aType = m_pSqlda->sqlvar[column-1].sqltype & ~1;
+    OUString sCharset;
+
+    if(aType == SQL_TEXT)
+    {
+        sCharset = getCharacterSet(column);
+    }
+
+    ColumnTypeInfo aInfo( m_pSqlda->sqlvar[column-1].sqltype,
+            m_pSqlda->sqlvar[column-1].sqlsubtype,
+            m_pSqlda->sqlvar[column-1].sqlscale,
+            sCharset );
 
-    return getColumnTypeFromFBType(aType, aSubType, aScale);
+    return aInfo.getSdbcType();
 }
 
 sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive(sal_Int32)
@@ -109,11 +151,11 @@ OUString SAL_CALL OResultSetMetaData::getColumnTypeName(sal_Int32 column)
 {
     verifyValidColumn(column);
 
-    short aType = m_pSqlda->sqlvar[column-1].sqltype;
-    short aSubType = m_pSqlda->sqlvar[column-1].sqlsubtype;
-    short aScale = m_pSqlda->sqlvar[column-1].sqlscale;
+    ColumnTypeInfo aInfo( m_pSqlda->sqlvar[column-1].sqltype,
+            m_pSqlda->sqlvar[column-1].sqlsubtype,
+            m_pSqlda->sqlvar[column-1].sqlscale );
 
-    return getColumnTypeNameFromFBType(aType, aSubType, aScale);
+    return aInfo.getColumnTypeName();
 }
 
 OUString SAL_CALL OResultSetMetaData::getColumnLabel(sal_Int32 column)
diff --git a/connectivity/source/drivers/firebird/ResultSetMetaData.hxx b/connectivity/source/drivers/firebird/ResultSetMetaData.hxx
index d6dffe0cd708..1b134a0628fd 100644
--- a/connectivity/source/drivers/firebird/ResultSetMetaData.hxx
+++ b/connectivity/source/drivers/firebird/ResultSetMetaData.hxx
@@ -45,6 +45,7 @@ namespace connectivity
 
             /// @throws css::sdbc::SQLException
             void verifyValidColumn(sal_Int32 column);
+            OUString getCharacterSet(sal_Int32 nIndex);
         public:
             // a constructor, which is required for returning objects:
             OResultSetMetaData(Connection* pConnection,
diff --git a/connectivity/source/drivers/firebird/Tables.cxx b/connectivity/source/drivers/firebird/Tables.cxx
index c78939cdc201..5a79f8afe33d 100644
--- a/connectivity/source/drivers/firebird/Tables.cxx
+++ b/connectivity/source/drivers/firebird/Tables.cxx
@@ -92,6 +92,21 @@ OUString Tables::createStandardColumnPart(const Reference< XPropertySet >& xColP
 
     aSql.append(dbtools::createStandardTypePart(xColProp, _xConnection));
 
+    // Add character set for BINARY (fix) type:
+    // BINARY is distinguished from other CHAR types by its character set.
+    // Octets is a special character set for binary data.
+    if ( xPropInfo.is() && xPropInfo->hasPropertyByName(rPropMap.getNameByIndex(
+                    PROPERTY_ID_TYPE)) )
+    {
+        sal_Int32 aType = 0;
+        xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE))
+            >>= aType;
+        if(aType == DataType::BINARY)
+        {
+            aSql.append(" ");
+            aSql.append("CHARACTER SET OCTETS");
+        }
+    }
 
     if ( bIsAutoIncrement && !sAutoIncrementValue.isEmpty())
     {
diff --git a/connectivity/source/drivers/firebird/Util.cxx b/connectivity/source/drivers/firebird/Util.cxx
index e30a7a9b41f8..20587e5172ba 100644
--- a/connectivity/source/drivers/firebird/Util.cxx
+++ b/connectivity/source/drivers/firebird/Util.cxx
@@ -17,6 +17,8 @@ using namespace ::com::sun::star;
 using namespace ::com::sun::star::sdbc;
 using namespace ::com::sun::star::uno;
 
+using namespace firebird;
+
 OUString firebird::sanitizeIdentifier(const OUString& rIdentifier)
 {
     OUString sRet = rIdentifier.trim();
@@ -64,41 +66,76 @@ void firebird::evaluateStatusVector(const ISC_STATUS_ARRAY& rStatusVector,
     }
 }
 
-sal_Int32 firebird::getColumnTypeFromFBType(short aType, short aSubType, short aScale)
+sal_Int32 lcl_getNumberType( short aType, NumberSubType aSubType )
+{
+    switch(aSubType)
+    {
+        case NumberSubType::Numeric:
+            return DataType::NUMERIC;
+        case NumberSubType::Decimal:
+            return DataType::DECIMAL;
+        default:
+            switch(aType)
+            {
+                case SQL_SHORT:
+                    return DataType::SMALLINT;
+                case SQL_LONG:
+                    return DataType::INTEGER;
+                case SQL_DOUBLE:
+                    return DataType::DOUBLE;
+                case SQL_INT64:
+                    return DataType::BIGINT;
+                default:
+                    assert(false); // not a number
+                    return 0;
+            }
+    }
+}
+sal_Int32 lcl_getCharColumnType( short aType, const OUString& sCharset )
+{
+    switch(aType)
+    {
+        case SQL_TEXT:
+            if( sCharset == "OCTETS")
+                return DataType::BINARY;
+            else
+                return DataType::CHAR;
+        case SQL_VARYING: // TODO VARBINARY
+            return DataType::VARCHAR;
+        default:
+            assert(false);
+            return 0;
+    }
+}
+
+sal_Int32 firebird::ColumnTypeInfo::getSdbcType() const
 {
-    aType &= ~1; // Remove last bit -- it is used to denote whether column
+    short aType = m_aType & ~1; // Remove last bit -- it is used to denote whether column
                  // can store Null, not needed for type determination
+    short aSubType = m_aSubType;
+    if( m_nScale > 0 )
+    {
+        // scale makes sense only for decimal and numeric types
+        assert(aType == SQL_SHORT || aType == SQL_LONG || aType == SQL_DOUBLE
+                || aType == SQL_INT64);
 
-    // if scale is set without subtype then imply numeric
-    if(aSubType == 0 && aScale < 0)
-        aSubType = 1;
+        // if scale is set without subtype then imply numeric
+        if( static_cast<NumberSubType>(aSubType) == NumberSubType::Other )
+            aSubType = static_cast<short>(NumberSubType::Numeric);
+    }
 
     switch (aType)
     {
     case SQL_TEXT:
-        return DataType::CHAR;
     case SQL_VARYING:
-        return DataType::VARCHAR;
+        return lcl_getCharColumnType(aType, m_sCharsetName);
     case SQL_SHORT:
-        if(aSubType == 1)
-            return DataType::NUMERIC;
-        if(aSubType == 2)
-            return DataType::DECIMAL;
-        return DataType::SMALLINT;
     case SQL_LONG:
-        if(aSubType == 1)
-            return DataType::NUMERIC;
-        if(aSubType == 2)
-            return DataType::DECIMAL;
-        return DataType::INTEGER;
+    case SQL_DOUBLE:
+    case SQL_INT64:
+        return lcl_getNumberType(aType, static_cast<NumberSubType>(aSubType) );
     case SQL_FLOAT:
         return DataType::FLOAT;
-    case SQL_DOUBLE:
-        if(aSubType == 1)
-            return DataType::NUMERIC;
-        if(aSubType == 2)
-            return DataType::DECIMAL;
-        return DataType::DOUBLE;
     case SQL_D_FLOAT:
         return DataType::DOUBLE;
     case SQL_TIMESTAMP:
@@ -121,12 +158,6 @@ sal_Int32 firebird::getColumnTypeFromFBType(short aType, short aSubType, short a
         return DataType::TIME;
     case SQL_TYPE_DATE:
         return DataType::DATE;
-    case SQL_INT64:
-        if(aSubType == 1)
-            return DataType::NUMERIC;
-        if(aSubType == 2)
-            return DataType::DECIMAL;
-        return DataType::BIGINT;
     case SQL_NULL:
         return DataType::SQLNULL;
     case SQL_QUAD:      // Is a "Blob ID" according to the docs
@@ -139,68 +170,48 @@ sal_Int32 firebird::getColumnTypeFromFBType(short aType, short aSubType, short a
     }
 }
 
-OUString firebird::getColumnTypeNameFromFBType(short aType, short aSubType, short aScale)
+OUString firebird::ColumnTypeInfo::getColumnTypeName() const
 {
-    aType &= ~1; // Remove last bit -- it is used to denote whether column
+    short aType = m_aType & ~1; // Remove last bit -- it is used to denote whether column
                 // can store Null, not needed for type determination
 
-    // if scale is set without subtype than imply numeric
-    if(aSubType == 0 && aScale < 0)
-        aSubType = 1;
-
-   switch (aType)
+    switch (aType)
     {
-    case SQL_TEXT:
-        return OUString("SQL_TEXT");
-    case SQL_VARYING:
-        return OUString("SQL_VARYING");
-    case SQL_SHORT:
-        if(aSubType == 1)
-            return OUString("SQL_NUMERIC");
-        if(aSubType == 2)
-            return OUString("SQL_DECIMAL");
-        return OUString("SQL_SHORT");
-    case SQL_LONG:
-        if(aSubType == 1)
-            return OUString("SQL_NUMERIC");
-        if(aSubType == 2)
-            return OUString("SQL_DECIMAL");
-        return OUString("SQL_LONG");
-    case SQL_FLOAT:
-        return OUString("SQL_FLOAT");
-    case SQL_DOUBLE:
-        if(aSubType == 1)
-            return OUString("SQL_NUMERIC");
-        if(aSubType == 2)
-            return OUString("SQL_DECIMAL");
-        return OUString("SQL_DOUBLE");
-    case SQL_D_FLOAT:
-        return OUString("SQL_D_FLOAT");
-    case SQL_TIMESTAMP:
-        return OUString("SQL_TIMESTAMP");
-    case SQL_BLOB:
-        return OUString("SQL_BLOB");
-    case SQL_ARRAY:
-        return OUString("SQL_ARRAY");
-    case SQL_TYPE_TIME:
-        return OUString("SQL_TYPE_TIME");
-    case SQL_TYPE_DATE:

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list