From c07548447a564b2d142cc439a124b76e6a71dfbd Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Tue, 19 Mar 2024 16:48:19 +0500 Subject: [PATCH] Related: tdf#108057 Use autoincrement for automatically added primary key This partially undoes commit 24940e2c3717ad7b07d43db4f08cf7e09cfcc22f (#100599# #95927# check if row is readonly and disable autoincrement column for auto primarykey, 2002-06-27), enabling autoincrement again. Make sure to use the largest type that supports autoincrement. Change-Id: I4dfdbfb0c3d9b94c7634082b029c6e66aa01c782 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165027 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- dbaccess/source/ui/misc/UITools.cxx | 45 ++++++++++++------- dbaccess/source/ui/misc/WCopyTable.cxx | 1 + .../source/ui/tabledesign/TableController.cxx | 4 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/dbaccess/source/ui/misc/UITools.cxx b/dbaccess/source/ui/misc/UITools.cxx index 55e7f709f7b2..088f91cb2ba5 100644 --- a/dbaccess/source/ui/misc/UITools.cxx +++ b/dbaccess/source/ui/misc/UITools.cxx @@ -1052,29 +1052,40 @@ void setEvalDateFormatForFormatter(Reference< css::util::XNumberFormatter > cons } } +static bool TypeIsGreater(const TOTypeInfoSP& lhs, const TOTypeInfoSP& rhs) +{ + assert(lhs); + if (!rhs) + return true; + if (lhs->nNumPrecRadix == rhs->nNumPrecRadix) + return lhs->nPrecision > rhs->nPrecision; + if (lhs->nPrecision == rhs->nPrecision) + return lhs->nNumPrecRadix > rhs->nNumPrecRadix; + if ((lhs->nNumPrecRadix > rhs->nNumPrecRadix) == (lhs->nPrecision > rhs->nPrecision)) + return lhs->nPrecision > rhs->nPrecision; + return std::pow(lhs->nNumPrecRadix, lhs->nPrecision) + > std::pow(rhs->nNumPrecRadix, rhs->nPrecision); +} + TOTypeInfoSP queryPrimaryKeyType(const OTypeInfoMap& _rTypeInfo) { - TOTypeInfoSP pTypeInfo; - // first we search for a type which supports autoIncrement + TOTypeInfoSP pTypeInfo, pFallback; + // first we search for a largest type which supports autoIncrement for (auto const& elem : _rTypeInfo) { - // OJ: we don't want to set an autoincrement column to be key - // because we don't have the possibility to know how to create - // such auto increment column later on - // so until we know how to do it, we create a column without autoincrement - // therefore we have searched - if ( elem.second->nType == DataType::INTEGER ) - { - pTypeInfo = elem.second; // alternative - break; - } - else if ( !pTypeInfo && elem.second->nType == DataType::DOUBLE ) - pTypeInfo = elem.second; // alternative - else if ( !pTypeInfo && elem.second->nType == DataType::REAL ) - pTypeInfo = elem.second; // alternative + if (elem.second->bAutoIncrement && TypeIsGreater(elem.second, pTypeInfo)) + pTypeInfo = elem.second; + if (pTypeInfo) + continue; + if (elem.second->nType == DataType::INTEGER) + pFallback = elem.second; // default alternative + else if (!pFallback && elem.second->nType == DataType::DOUBLE) + pFallback = elem.second; // alternative + else if (!pFallback && elem.second->nType == DataType::REAL) + pFallback = elem.second; // alternative } if ( !pTypeInfo ) // just a fallback - pTypeInfo = queryTypeInfoByType(DataType::VARCHAR,_rTypeInfo); + pTypeInfo = pFallback ? pFallback : queryTypeInfoByType(DataType::VARCHAR, _rTypeInfo); OSL_ENSURE(pTypeInfo,"checkColumns: can't find a type which is usable as a key!"); return pTypeInfo; diff --git a/dbaccess/source/ui/misc/WCopyTable.cxx b/dbaccess/source/ui/misc/WCopyTable.cxx index 29be8774747b..a2737543c705 100644 --- a/dbaccess/source/ui/misc/WCopyTable.cxx +++ b/dbaccess/source/ui/misc/WCopyTable.cxx @@ -737,6 +737,7 @@ bool OCopyTableWizard::CheckColumns(sal_Int32& _rnBreakPos) OFieldDescription* pField = new OFieldDescription(); pField->SetName(m_aKeyName); pField->FillFromTypeInfo(pTypeInfo,true,true); + pField->SetAutoIncrement(pTypeInfo->bAutoIncrement); pField->SetPrimaryKey(true); m_bAddPKFirstTime = false; insertColumn(0,pField); diff --git a/dbaccess/source/ui/tabledesign/TableController.cxx b/dbaccess/source/ui/tabledesign/TableController.cxx index 7e13ba566bb2..fd53297cad00 100644 --- a/dbaccess/source/ui/tabledesign/TableController.cxx +++ b/dbaccess/source/ui/tabledesign/TableController.cxx @@ -903,15 +903,15 @@ bool OTableController::checkColumns(bool _bNew) { case RET_YES: { - auto pNewRow = std::make_shared(); TOTypeInfoSP pTypeInfo = ::dbaui::queryPrimaryKeyType(m_aTypeInfo); if ( !pTypeInfo ) break; + auto pNewRow = std::make_shared(); pNewRow->SetFieldType( pTypeInfo ); OFieldDescription* pActFieldDescr = pNewRow->GetActFieldDescr(); - pActFieldDescr->SetAutoIncrement(false); + pActFieldDescr->SetAutoIncrement(pTypeInfo->bAutoIncrement); pActFieldDescr->SetIsNullable(ColumnValue::NO_NULLS); pActFieldDescr->SetName( createUniqueName("ID" ));