8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 22:43:03 +01:00

WIP - attachDatabase() completed, trivial SQL runs ok

This commit is contained in:
AlexPeshkoff 2024-04-22 19:51:54 +03:00
parent 35c7428bcc
commit 7609c96218
12 changed files with 132 additions and 103 deletions

View File

@ -4039,7 +4039,7 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
specificAttributes = temp;
}
info.charsetName = forCharSet.c_str();
info.charsetName.push(forCharSet.c_str());
info.collationName = name;
if (X.RDB$BASE_COLLATION_NAME.NULL)
info.baseCollationName = info.collationName;
@ -4048,11 +4048,11 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
info.ignoreAttributes = false;
if (!IntlManager::collationInstalled(info.baseCollationName.c_str(),
info.charsetName.c_str()))
info.charsetName[0].c_str()))
{
// msg: 223: "Collation @1 not installed for character set @2"
status_exception::raise(
Arg::PrivateDyn(223) << info.baseCollationName << info.charsetName);
Arg::PrivateDyn(223) << info.baseCollationName << info.charsetName[0]);
}
IntlUtil::SpecificAttributesMap map;
@ -4070,7 +4070,7 @@ void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
string newSpecificAttributes;
if (!IntlManager::setupCollationAttributes(
info.baseCollationName.c_str(), info.charsetName.c_str(), s,
info.baseCollationName.c_str(), info.charsetName[0].c_str(), s,
newSpecificAttributes))
{
// msg: 222: "Invalid collation attributes"

View File

@ -30,12 +30,14 @@
#include "../jrd/HazardPtr.h"
#include "../jrd/Collation.h"
#include "../jrd/Resources.h"
#include "../jrd/met_proto.h"
#include "../common/classes/alloc.h"
struct SubtypeInfo;
namespace Jrd {
struct SubtypeInfo;
class CharSetContainer : public Firebird::PermanentStorage
{
public:
@ -92,7 +94,7 @@ private:
static bool lookupInternalCharSet(CSetId id, SubtypeInfo* info);
public:
Firebird::HalfStaticArray<MetaName, 4> names;
CharsetVariants names;
private:
CharSet* cs;

View File

@ -1237,6 +1237,7 @@ public:
class Iterator
{
static const FB_SIZE_T eof = ~0u;
static const FB_SIZE_T endloop = ~0u;
public:
StoredElement* operator*()
@ -1258,7 +1259,9 @@ public:
bool operator==(const Iterator& itr) const
{
fb_assert(data == itr.data);
return index == itr.index || index == eof || itr.index == eof;
return index == itr.index ||
(index == endloop && itr.index == eof) ||
(itr.index == endloop && index == eof);
}
bool operator!=(const Iterator& itr) const
@ -1275,7 +1278,7 @@ public:
enum class Location {Begin, End};
Iterator(const CacheVector* v, Location loc)
: data(v),
index(loc == Location::Begin ? locateData(0) : eof)
index(loc == Location::Begin ? locateData(0) : endloop)
{ }
StoredElement* get()

View File

@ -640,63 +640,77 @@ bool IntlManager::lookupCharSet(const string& charSetName, charset* cs)
void IntlManager::lookupCollation(const string& collationName,
const string& charSetName,
const Jrd::CharsetVariants& charsetVariants,
USHORT attributes, const UCHAR* specificAttributes,
ULONG specificAttributesLen, bool ignoreAttributes,
texttype* tt)
{
ExternalInfo charSetExternalInfo;
ExternalInfo collationExternalInfo;
char statusBuffer[BUFFER_LARGE] = "";
char statusBufferBig[BUFFER_LARGE] = "";
char statusBufferTiny[BUFFER_TINY];
char *statusBuffer = statusBufferBig;
ULONG bufferLength = sizeof(statusBufferBig);
if (charSetCollations->get(charSetName + ":" + charSetName, charSetExternalInfo) &&
charSetCollations->get(charSetName + ":" + collationName, collationExternalInfo))
for(const auto& charSetMetaName : charsetVariants)
{
ModuleLoader::Module* module = nullptr;
if (collationExternalInfo.moduleName.hasData())
modules->get(collationExternalInfo.moduleName, module);
pfn_INTL_lookup_texttype_with_status lookupStatusFunction = nullptr;
if (collationExternalInfo.moduleName.isEmpty())
lookupStatusFunction = INTL_builtin_lookup_texttype_status;
else if (module)
module->findSymbol(nullptr, STRINGIZE(TEXTTYPE_WITH_STATUS_ENTRYPOINT), lookupStatusFunction);
if (lookupStatusFunction)
string charSetName(charSetMetaName);
if (charSetCollations->get(charSetName + ":" + charSetName, charSetExternalInfo) &&
charSetCollations->get(charSetName + ":" + collationName, collationExternalInfo))
{
if ((*lookupStatusFunction)(statusBuffer, sizeof(statusBuffer),
tt, collationExternalInfo.name.c_str(), charSetExternalInfo.name.c_str(),
attributes, specificAttributes, specificAttributesLen, ignoreAttributes,
collationExternalInfo.configInfo.c_str()))
ModuleLoader::Module* module = nullptr;
if (collationExternalInfo.moduleName.hasData())
modules->get(collationExternalInfo.moduleName, module);
pfn_INTL_lookup_texttype_with_status lookupStatusFunction = nullptr;
if (collationExternalInfo.moduleName.isEmpty())
lookupStatusFunction = INTL_builtin_lookup_texttype_status;
else if (module)
module->findSymbol(nullptr, STRINGIZE(TEXTTYPE_WITH_STATUS_ENTRYPOINT), lookupStatusFunction);
if (lookupStatusFunction)
{
return;
if ((*lookupStatusFunction)(statusBuffer, bufferLength,
tt, collationExternalInfo.name.c_str(), charSetExternalInfo.name.c_str(),
attributes, specificAttributes, specificAttributesLen, ignoreAttributes,
collationExternalInfo.configInfo.c_str()))
{
return;
}
if (statusBuffer[0])
{
statusBuffer = statusBufferTiny;
bufferLength = sizeof(statusBufferTiny);
statusBuffer[0] = '\0';
}
}
}
else if (module)
{
pfn_INTL_lookup_texttype lookupFunction = nullptr;
module->findSymbol(nullptr, STRINGIZE(TEXTTYPE_ENTRYPOINT), lookupFunction);
if (lookupFunction &&
(*lookupFunction)(tt, collationExternalInfo.name.c_str(), charSetExternalInfo.name.c_str(),
attributes, specificAttributes, specificAttributesLen, ignoreAttributes,
collationExternalInfo.configInfo.c_str()))
else if (module)
{
return;
pfn_INTL_lookup_texttype lookupFunction = nullptr;
module->findSymbol(nullptr, STRINGIZE(TEXTTYPE_ENTRYPOINT), lookupFunction);
if (lookupFunction &&
(*lookupFunction)(tt, collationExternalInfo.name.c_str(), charSetExternalInfo.name.c_str(),
attributes, specificAttributes, specificAttributesLen, ignoreAttributes,
collationExternalInfo.configInfo.c_str()))
{
return;
}
}
}
}
if (statusBuffer[0])
if (statusBufferBig[0])
{
(Arg::Gds(isc_collation_not_installed) << collationName << charSetName <<
Arg::Gds(isc_random) << statusBuffer
(Arg::Gds(isc_collation_not_installed) << collationName << charsetVariants[0] <<
Arg::Gds(isc_random) << statusBufferBig
).raise();
}
else
(Arg::Gds(isc_collation_not_installed) << collationName << charSetName).raise();
(Arg::Gds(isc_collation_not_installed) << collationName << charsetVariants[0]).raise();
}

View File

@ -30,6 +30,7 @@
#include "../common/classes/fb_string.h"
#include "../common/config/config_file.h"
#include "../jrd/intl.h"
#include "../jrd/met_proto.h"
struct charset;
struct texttype;
@ -49,7 +50,7 @@ public:
static bool lookupCharSet(const Firebird::string& charSetName, charset* cs);
static void lookupCollation(const Firebird::string& collationName,
const Firebird::string& charSetName,
const Jrd::CharsetVariants& charsetVariants,
USHORT attributes, const UCHAR* specificAttributes,
ULONG specificAttributesLen, bool ignoreAttributes,
texttype* tt);

View File

@ -624,15 +624,9 @@ RelationSourceNode* RelationSourceNode::parse(thread_db* tdbb, CompilerScratch*
if (aliasString)
node->alias = *aliasString;
// Load latest relation version
// Latest relation version should be here
if (rel->rel_flags & REL_sys_triggers) // should not happen...
{
fprintf(stderr, "REL_sys_triggers\n");
fb_assert(false);
jrd_rel* latestVersion = rel->getObject(tdbb, CacheFlag::AUTOCREATE);
MET_parse_sys_trigger(tdbb, latestVersion);
}
fb_assert(!(rel->rel_flags & REL_sys_triggers));
// generate a stream for the relation reference, assuming it is a real reference

View File

@ -170,7 +170,8 @@ RelationPermanent::RelationPermanent(thread_db* tdbb, MemoryPool& p, MetaId id,
rel_existence_lock = FB_NEW_RPT(getPool(), 0)
Lock(tdbb, sizeof(SLONG), LCK_rel_exist, this, blocking_ast_relation);
rel_existence_lock->setKey(rel_id);
} */
}
*/
}
RelationPermanent::~RelationPermanent()
@ -751,7 +752,8 @@ void GCLock::ensureReleased(thread_db* tdbb)
void GCLock::forcedRelease(thread_db* tdbb)
{
flags.fetch_and(~GC_locked);
LCK_release(tdbb, lck);
if (lck)
LCK_release(tdbb, lck);
}
void GCLock::enable(thread_db* tdbb, Lock* tempLock)
@ -933,18 +935,17 @@ void IndexLock::recreate(thread_db*)
void jrd_rel::destroy(jrd_rel* rel)
{
/*
thread_db* tdbb = JRD_get_thread_data();
LCK_release(tdbb, rel->rel_existence_lock);
if (rel->rel_partners_lock)
LCK_release(tdbb, rel->rel_perm->rel_existence_lock);
if (rel->rel_perm->rel_partners_lock)
{
rel->rel_flags |= REL_check_partners;
LCK_release(tdbb, rel->rel_partners_lock);
rel->rel_flags &= ~REL_check_partners;
rel->rel_perm->rel_flags |= REL_check_partners;
LCK_release(tdbb, rel->rel_perm->rel_partners_lock);
rel->rel_perm->rel_flags &= ~REL_check_partners;
}
LCK_release(tdbb, rel->rel_rescan_lock);
*/
LCK_release(tdbb, rel->rel_perm->rel_rescan_lock);
// A lot more things to do !!!!!!!!!!!!!!!!
delete rel;

View File

@ -176,7 +176,8 @@ bool CharSetContainer::lookupInternalCharSet(CSetId id, SubtypeInfo* info)
{
if (id == CS_UTF16)
{
info->charsetName = "UTF16";
info->charsetName.clear();
info->charsetName.push("UTF16");
return true;
}
@ -196,7 +197,8 @@ bool CharSetContainer::lookupInternalCharSet(CSetId id, SubtypeInfo* info)
{
if (colDef->charSetId == id && colDef->collationId == 0)
{
info->charsetName = csDef->name;
info->charsetName.clear();
info->charsetName.push(csDef->name);
info->collationName = colDef->name;
info->attributes = colDef->attributes;
info->ignoreAttributes = false;
@ -228,22 +230,27 @@ CharSetContainer::CharSetContainer(thread_db* tdbb, MemoryPool& p, MetaId id, Ma
ERR_post(Arg::Gds(isc_text_subtype) << Arg::Num(cs_id));
charset* csL = FB_NEW_POOL(p) charset;
memset(csL, 0, sizeof(charset));
if (IntlManager::lookupCharSet(info.charsetName.c_str(), csL) &&
(csL->charset_flags & CHARSET_ASCII_BASED))
for (auto& csName : info.charsetName)
{
cs = CharSet::createInstance(p, cs_id, csL);
}
else
{
delete csL;
ERR_post(Arg::Gds(isc_charset_not_installed) << Arg::Str(info.charsetName));
memset(csL, 0, sizeof(charset));
if (IntlManager::lookupCharSet(csName.c_str(), csL) &&
(csL->charset_flags & CHARSET_ASCII_BASED))
{
cs = CharSet::createInstance(p, cs_id, csL);
cs_lock = makeLock(tdbb, p);
cs_lock->setKey(cs_id);
cs_lock->lck_object = this;
return;
}
}
cs_lock = makeLock(tdbb, p);
cs_lock->setKey(cs_id);
cs_lock->lck_object = this;
delete csL;
ERR_post(Arg::Gds(isc_charset_not_installed) <<
(info.charsetName.hasData() ? Arg::Str(info.charsetName[0]) : Arg::Str("<Unknown character set>")));
}
CsConvert CharSetContainer::lookupConverter(thread_db* tdbb, CSetId toCsId)
@ -315,7 +322,7 @@ void CharSetContainer::unloadCollation(thread_db* tdbb, USHORT tt_id)
void INTL_lookup_texttype(texttype* tt, const SubtypeInfo* info)
{
IntlManager::lookupCollation(info->baseCollationName.c_str(), info->charsetName.c_str(),
IntlManager::lookupCollation(info->baseCollationName.c_str(), info->charsetName,
info->attributes, info->specificAttributes.begin(),
info->specificAttributes.getCount(), info->ignoreAttributes, tt);
}

View File

@ -32,10 +32,10 @@ namespace Jrd {
class thread_db;
class Lock;
class Collation;
struct SubtypeInfo;
}
struct dsc;
struct SubtypeInfo;
struct texttype;
void INTL_adjust_text_descriptor(Jrd::thread_db* tdbb, dsc* desc);
@ -52,10 +52,10 @@ USHORT INTL_key_length(Jrd::thread_db*, USHORT, USHORT);
Jrd::CharSet* INTL_charset_lookup(Jrd::thread_db* tdbb, CSetId parm1);
Jrd::Collation* INTL_texttype_lookup(Jrd::thread_db* tdbb, TTypeId parm1);
//void INTL_texttype_unload(Jrd::thread_db*, USHORT);
bool INTL_texttype_validate(Jrd::thread_db*, const SubtypeInfo*);
bool INTL_texttype_validate(Jrd::thread_db*, const Jrd::SubtypeInfo*);
void INTL_pad_spaces(Jrd::thread_db*, dsc*, UCHAR*, ULONG);
USHORT INTL_string_to_key(Jrd::thread_db*, USHORT, const dsc*, dsc*, USHORT);
void INTL_lookup_texttype(texttype* tt, const SubtypeInfo* info);
void INTL_lookup_texttype(texttype* tt, const Jrd::SubtypeInfo* info);
// Built-in charsets/texttypes interface
INTL_BOOL INTL_builtin_lookup_charset(charset* cs, const ASCII* charset_name, const ASCII* config_info);

View File

@ -1285,6 +1285,7 @@ bool MET_get_char_coll_subtype_info(thread_db* tdbb, USHORT id, SubtypeInfo* inf
AutoCacheRequest request(tdbb, irq_l_subtype, IRQ_REQUESTS);
bool found = false;
info->charsetName.clear();
FOR(REQUEST_HANDLE request) FIRST 1
CL IN RDB$COLLATIONS CROSS
@ -1295,7 +1296,7 @@ bool MET_get_char_coll_subtype_info(thread_db* tdbb, USHORT id, SubtypeInfo* inf
{
found = true;
info->charsetName = CS.RDB$CHARACTER_SET_NAME;
info->charsetName.push(CS.RDB$CHARACTER_SET_NAME);
info->collationName = CL.RDB$COLLATION_NAME;
if (CL.RDB$BASE_COLLATION_NAME.NULL)
@ -3325,7 +3326,6 @@ bool jrd_rel::scan(thread_db* tdbb, ObjectBase::Flag flags)
if (sys_triggers)
{
fprintf(stderr, "SCAN %s: REL_sys_triggers\n", c_name());
MET_parse_sys_trigger(tdbb, this);
return true;
}
@ -3621,8 +3621,11 @@ bool jrd_rel::scan(thread_db* tdbb, ObjectBase::Flag flags)
rel_current_format = NULL;
} // try
catch (const Exception&)
catch (const Exception& ex)
{
if (sys_triggers)
iscLogException("!!!!!!!!!!!!!!!!!!!!", ex);
if (dependencies) {
rel_perm->rel_flags |= REL_get_dependencies;
}
@ -4239,12 +4242,15 @@ bool CharSetVers::scan(thread_db* tdbb, ObjectBase::Flag flags)
if (perm->names.getCount() == 0)
{
perm->names.push(getName());
FOR(REQUEST_HANDLE handle)
T IN RDB$TYPES
WITH T.RDB$FIELD_NAME EQ "RDB$CHARACTER_SET_NAME"
AND T.RDB$TYPE EQ getId()
{
perm->names.push(T.RDB$TYPE_NAME);
if (getName() != T.RDB$TYPE_NAME)
perm->names.push(T.RDB$TYPE_NAME);
}
END_FOR
@ -4259,7 +4265,7 @@ bool CharSetVers::scan(thread_db* tdbb, ObjectBase::Flag flags)
fb_assert(perm->names.exist(CS.RDB$CHARACTER_SET_NAME));
SubtypeInfo info;
info.charsetName = getName();
info.charsetName = perm->names;
info.collationName = COL.RDB$COLLATION_NAME;
info.attributes = (USHORT)COL.RDB$COLLATION_ATTRIBUTES;
info.ignoreAttributes = COL.RDB$COLLATION_ATTRIBUTES.NULL;

View File

@ -57,23 +57,25 @@ namespace Jrd
class RelationPermanent;
class Triggers;
class TrigArray;
}
struct SubtypeInfo
{
SubtypeInfo()
: attributes(0),
ignoreAttributes(true)
typedef Firebird::HalfStaticArray<Jrd::MetaName, 4> CharsetVariants;
struct SubtypeInfo
{
}
SubtypeInfo()
: attributes(0),
ignoreAttributes(true)
{
}
Jrd::MetaName charsetName;
Jrd::MetaName collationName;
Jrd::MetaName baseCollationName;
USHORT attributes;
bool ignoreAttributes;
Firebird::UCharBuffer specificAttributes;
};
CharsetVariants charsetName;
MetaName collationName;
MetaName baseCollationName;
USHORT attributes;
bool ignoreAttributes;
Firebird::UCharBuffer specificAttributes;
};
}
void MET_activate_shadow(Jrd::thread_db*);
ULONG MET_align(const dsc*, ULONG);
@ -83,7 +85,7 @@ void MET_delete_dependencies(Jrd::thread_db*, const Jrd::MetaName&, int, Jrd::j
void MET_delete_shadow(Jrd::thread_db*, USHORT);
void MET_error(const TEXT*, ...);
Jrd::Format* MET_format(Jrd::thread_db*, Jrd::RelationPermanent*, USHORT);
bool MET_get_char_coll_subtype_info(Jrd::thread_db*, USHORT, SubtypeInfo* info);
bool MET_get_char_coll_subtype_info(Jrd::thread_db*, USHORT, Jrd::SubtypeInfo* info);
Jrd::DmlNode* MET_get_dependencies(Jrd::thread_db*, Jrd::jrd_rel*, const UCHAR*, const ULONG,
Jrd::CompilerScratch*, Jrd::bid*, Jrd::Statement**,
Jrd::CompilerScratch**, const Jrd::MetaName&, int, USHORT,

View File

@ -5258,7 +5258,6 @@ void Database::garbage_collector(Database* dbb)
try
{
LCK_init(tdbb, LCK_OWNER_attachment);
INI_init(tdbb);
PAG_header(tdbb, true);
PAG_attachment_id(tdbb);
TRA_init(attachment);