diff --git a/src/common/classes/array.h b/src/common/classes/array.h index 36ed9ccbdd..d79a5e0e81 100644 --- a/src/common/classes/array.h +++ b/src/common/classes/array.h @@ -28,6 +28,7 @@ #define CLASSES_ARRAY_H #include "../common/gdsassert.h" +#include #include #include "../common/classes/vector.h" #include "../common/classes/alloc.h" @@ -115,6 +116,13 @@ public: copyFrom(source); } + Array(MemoryPool& p, std::initializer_list items) + : Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage()) + { + for (auto& item : items) + add(item); + } + ~Array() { freeData(); diff --git a/src/common/classes/objects_array.h b/src/common/classes/objects_array.h index 7f548bee14..e3fa95c6cc 100644 --- a/src/common/classes/objects_array.h +++ b/src/common/classes/objects_array.h @@ -28,6 +28,7 @@ #ifndef CLASSES_OBJECTS_ARRAY_H #define CLASSES_OBJECTS_ARRAY_H +#include #include "../common/classes/alloc.h" #include "../common/classes/array.h" @@ -338,6 +339,13 @@ namespace Firebird add(o); } + ObjectsArray(MemoryPool& p, std::initializer_list items) + : A(p) + { + for (auto& item : items) + add(item); + } + ObjectsArray() : A() { diff --git a/src/include/firebird/Message.h b/src/include/firebird/Message.h index 5899663dc8..d89e7051e2 100644 --- a/src/include/firebird/Message.h +++ b/src/include/firebird/Message.h @@ -249,8 +249,9 @@ struct FbVarChar void set(const char* s) { - length = strlen(s); - assert(length <= N); + size_t len = strlen(s); + assert(len <= N); + length = (ISC_USHORT) len; memcpy(str, s, (length <= N ? length : N)); } }; diff --git a/src/jrd/ExtEngineManager.cpp b/src/jrd/ExtEngineManager.cpp index c17af29431..e43f292b52 100644 --- a/src/jrd/ExtEngineManager.cpp +++ b/src/jrd/ExtEngineManager.cpp @@ -1058,7 +1058,7 @@ namespace const char* packageName = metadata->getPackage(status); const char* routineName = metadata->getName(status); - for (auto& package : SystemPackage::LIST) + for (auto& package : SystemPackage::get()) { if (strcmp(package.name, packageName) == 0) { @@ -1080,7 +1080,7 @@ namespace const char* packageName = metadata->getPackage(status); const char* routineName = metadata->getName(status); - for (auto& package : SystemPackage::LIST) + for (auto& package : SystemPackage::get()) { if (strcmp(package.name, packageName) == 0) { diff --git a/src/jrd/SystemPackages.cpp b/src/jrd/SystemPackages.cpp index 251607e3e7..b66f248a91 100644 --- a/src/jrd/SystemPackages.cpp +++ b/src/jrd/SystemPackages.cpp @@ -30,51 +30,75 @@ using namespace Firebird; using namespace Jrd; -std::initializer_list SystemPackage::LIST = +namespace { - // packages + struct SystemPackageInit { - "RDB$TIME_ZONE_UTIL", - ODS_13_0, + explicit SystemPackageInit(MemoryPool& pool) + : list(FB_NEW_POOL(pool) ObjectsArray(pool, { + SystemPackage( + pool, + "RDB$TIME_ZONE_UTIL", + ODS_13_0, + // procedures + { + SystemProcedure( + pool, + "TRANSITIONS", + [] + (ThrowStatusExceptionWrapper* status, IExternalContext* /*context*/, + IRoutineMetadata* /*metadata*/, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) + { + return FB_NEW TimeZoneTransitionsProcedure(status, inBuilder, outBuilder); + }, + prc_selectable, + // input parameters + { + {"TIME_ZONE_NAME", fld_tz_name, false}, + {"FROM_TIMESTAMP", fld_timestamp_tz, false}, + {"TO_TIMESTAMP", fld_timestamp_tz, false} + }, + // output parameters + { + {"START_TIMESTAMP", fld_timestamp_tz, false}, + {"END_TIMESTAMP", fld_timestamp_tz, false}, + {"ZONE_OFFSET", fld_tz_offset, false}, + {"DST_OFFSET", fld_tz_offset, false}, + {"EFFECTIVE_OFFSET", fld_tz_offset, false} + } + ) + }, + // functions + { + SystemFunction( + pool, + "DATABASE_VERSION", + [] + (ThrowStatusExceptionWrapper* status, IExternalContext* /*context*/, + IRoutineMetadata* /*metadata*/, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) + { + return FB_NEW TimeZoneDatabaseVersionFunction(status, inBuilder, outBuilder); + }, + // parameters + {}, + { fld_tz_db_version, false } + ) + } + ) + })) { - // procedures - { - "TRANSITIONS", - [] - (ThrowStatusExceptionWrapper* status, IExternalContext* /*context*/, - IRoutineMetadata* /*metadata*/, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) - { - return FB_NEW TimeZoneTransitionsProcedure(status, inBuilder, outBuilder); - }, - prc_selectable, - { // input parameters - {"TIME_ZONE_NAME", fld_tz_name, false}, - {"FROM_TIMESTAMP", fld_timestamp_tz, false}, - {"TO_TIMESTAMP", fld_timestamp_tz, false} - }, - { // output parameters - {"START_TIMESTAMP", fld_timestamp_tz, false}, - {"END_TIMESTAMP", fld_timestamp_tz, false}, - {"ZONE_OFFSET", fld_tz_offset, false}, - {"DST_OFFSET", fld_tz_offset, false}, - {"EFFECTIVE_OFFSET", fld_tz_offset, false} - } - }, - }, - { - // functions - { - "DATABASE_VERSION", - [] - (ThrowStatusExceptionWrapper* status, IExternalContext* /*context*/, - IRoutineMetadata* /*metadata*/, IMetadataBuilder* inBuilder, IMetadataBuilder* outBuilder) - { - return FB_NEW TimeZoneDatabaseVersionFunction(status, inBuilder, outBuilder); - }, - { // parameters - }, - {fld_tz_db_version, false} - } } - } -}; + + static InitInstance INSTANCE; + + AutoPtr > list; + }; + + InitInstance SystemPackageInit::INSTANCE; +} + + +ObjectsArray& SystemPackage::get() +{ + return *SystemPackageInit::INSTANCE().list.get(); +} diff --git a/src/jrd/SystemPackages.h b/src/jrd/SystemPackages.h index 9cdfc1b97d..698a611730 100644 --- a/src/jrd/SystemPackages.h +++ b/src/jrd/SystemPackages.h @@ -25,6 +25,9 @@ #include "firebird.h" #include "../common/status.h" +#include "../common/classes/init.h" +#include "../common/classes/array.h" +#include "../common/classes/objects_array.h" #include "../jrd/constants.h" #include "firebird/Interface.h" #include @@ -41,17 +44,42 @@ namespace Jrd struct SystemProcedure { - const char* name; - std::function factory; + )> Factory; + + SystemProcedure( + Firebird::MemoryPool& pool, + const char* aName, + Factory aFactory, + prc_t aType, + std::initializer_list aInputParameters, + std::initializer_list aOutputParameters + ) + : name(aName), + factory(aFactory), + type(aType), + inputParameters(pool, aInputParameters), + outputParameters(pool, aOutputParameters) + { + } + + SystemProcedure(Firebird::MemoryPool& pool, const SystemProcedure& other) + : inputParameters(pool), + outputParameters(pool) + { + *this = other; + } + + const char* name; + Factory factory; prc_t type; - std::initializer_list inputParameters; - std::initializer_list outputParameters; + Firebird::Array inputParameters; + Firebird::Array outputParameters; }; struct SystemFunctionParameter @@ -69,26 +97,69 @@ namespace Jrd struct SystemFunction { - const char* name; - std::function factory; - std::initializer_list parameters; + )> Factory; + + SystemFunction( + Firebird::MemoryPool& pool, + const char* aName, + Factory aFactory, + std::initializer_list aParameters, + SystemFunctionReturnType aReturnType + ) + : name(aName), + factory(aFactory), + parameters(pool, aParameters), + returnType(aReturnType) + { + } + + SystemFunction(Firebird::MemoryPool& pool, const SystemFunction& other) + : parameters(pool) + { + *this = other; + } + + const char* name; + Factory factory; + Firebird::Array parameters; SystemFunctionReturnType returnType; }; struct SystemPackage { + SystemPackage( + Firebird::MemoryPool& pool, + const char* aName, + USHORT aOdsVersion, + std::initializer_list aProcedures, + std::initializer_list aFunctions + ) + : name(aName), + odsVersion(aOdsVersion), + procedures(pool, aProcedures), + functions(pool, aFunctions) + { + } + + SystemPackage(Firebird::MemoryPool& pool, const SystemPackage& other) + : procedures(pool), + functions(pool) + { + *this = other; + } + const char* name; USHORT odsVersion; - std::initializer_list procedures; - std::initializer_list functions; + Firebird::ObjectsArray procedures; + Firebird::ObjectsArray functions; - static std::initializer_list LIST; + static Firebird::ObjectsArray& get(); }; } // namespace Jrd diff --git a/src/jrd/TimeZone.h b/src/jrd/TimeZone.h index 27fd904664..0f91f8e1d9 100644 --- a/src/jrd/TimeZone.h +++ b/src/jrd/TimeZone.h @@ -122,9 +122,6 @@ public: }; -FB_MESSAGE(TimeZoneDatabaseVersionInput, Firebird::ThrowStatusExceptionWrapper, -); - FB_MESSAGE(TimeZoneDatabaseVersionOutput, Firebird::ThrowStatusExceptionWrapper, (FB_INTL_VARCHAR(10, CS_ASCII), version) ); @@ -137,7 +134,6 @@ public: TimeZoneDatabaseVersionFunction(Firebird::ThrowStatusExceptionWrapper* status, Firebird::IMetadataBuilder* inBuilder, Firebird::IMetadataBuilder* outBuilder) { - TimeZoneDatabaseVersionInput::setup(status, inBuilder); TimeZoneDatabaseVersionOutput::setup(status, outBuilder); } diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index 09a7b24059..0337b61cbd 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -462,7 +462,7 @@ void INI_format(const char* owner, const char* charset) add_security_to_sys_obj(tdbb, ownerName, obj_collation, collation->name, length, buffer); } - for (auto& systemPackage : SystemPackage::LIST) + for (auto& systemPackage : SystemPackage::get()) { if (systemPackage.odsVersion > ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_version)) continue; @@ -1665,7 +1665,7 @@ static void store_packages(thread_db* tdbb, const MetaName& owner) SLONG procGen = MET_lookup_generator(tdbb, PROCEDURES_GENERATOR); SLONG funcGen = MET_lookup_generator(tdbb, FUNCTIONS_GENERATOR); - for (auto& systemPackage : SystemPackage::LIST) + for (auto& systemPackage : SystemPackage::get()) { if (systemPackage.odsVersion > ENCODE_ODS(majorVersion, minorVersion)) continue; @@ -1692,8 +1692,8 @@ static void store_packages(thread_db* tdbb, const MetaName& owner) PRC.RDB$PROCEDURE_ID = DPM_gen_id(tdbb, procGen, false, 1); - PRC.RDB$PROCEDURE_INPUTS = (SSHORT) procedure.inputParameters.size(); - PRC.RDB$PROCEDURE_OUTPUTS = (SSHORT) procedure.outputParameters.size(); + PRC.RDB$PROCEDURE_INPUTS = (SSHORT) procedure.inputParameters.getCount(); + PRC.RDB$PROCEDURE_OUTPUTS = (SSHORT) procedure.outputParameters.getCount(); PRC.RDB$PROCEDURE_TYPE = (SSHORT) procedure.type; PRC.RDB$PRIVATE_FLAG = FALSE; PRC.RDB$VALID_BLR = TRUE;