mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 15:23:02 +01:00
Transform two GDML STORE statements that run on database creation time to DSQL statements and preload DSQL cache objects to make that possible
This commit is contained in:
parent
57f6cfa131
commit
b2fe37a833
@ -58,6 +58,7 @@
|
||||
#include "../jrd/cmp_proto.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
#include "../jrd/inf_proto.h"
|
||||
#include "../jrd/ini_proto.h"
|
||||
#include "../jrd/intl_proto.h"
|
||||
#include "../jrd/jrd_proto.h"
|
||||
#include "../jrd/tra_proto.h"
|
||||
@ -2008,6 +2009,8 @@ static dsql_dbb* init(Jrd::Attachment* attachment)
|
||||
database->dbb_database = attachment->att_database;
|
||||
attachment->att_dsql_instance = database;
|
||||
|
||||
INI_init3(tdbb, database);
|
||||
|
||||
UCHAR buffer[BUFFER_TINY];
|
||||
|
||||
try
|
||||
|
@ -94,6 +94,16 @@ public:
|
||||
*reinterpret_cast<SSHORT*>(desc->dsc_address) = -1;
|
||||
}
|
||||
|
||||
void setInt(thread_db* tdbb, unsigned param, int value)
|
||||
{
|
||||
fb_assert(param > 0);
|
||||
|
||||
dsc desc;
|
||||
desc.makeLong(0, &value);
|
||||
|
||||
setDesc(tdbb, param, desc);
|
||||
}
|
||||
|
||||
void setString(thread_db* tdbb, unsigned param, const Firebird::AbstractString& value)
|
||||
{
|
||||
fb_assert(param > 0);
|
||||
|
198
src/jrd/ini.epp
198
src/jrd/ini.epp
@ -40,6 +40,7 @@
|
||||
#include "../jrd/ini.h"
|
||||
#include "../jrd/idx.h"
|
||||
#include "../jrd/gdsassert.h"
|
||||
#include "../dsql/dsql.h"
|
||||
#include "../jrd/blb_proto.h"
|
||||
#include "../jrd/cch_proto.h"
|
||||
#include "../jrd/cmp_proto.h"
|
||||
@ -56,6 +57,7 @@
|
||||
#include "../jrd/acl.h"
|
||||
#include "../jrd/irq.h"
|
||||
#include "../jrd/IntlManager.h"
|
||||
#include "../jrd/PreparedStatement.h"
|
||||
#include "../jrd/constants.h"
|
||||
|
||||
|
||||
@ -281,73 +283,58 @@ void INI_format(const TEXT* owner, const TEXT* charset)
|
||||
;
|
||||
}
|
||||
|
||||
jrd_tra* transaction = dbb->dbb_sys_trans;
|
||||
|
||||
// Store RELATIONS and RELATION_FIELDS
|
||||
|
||||
Firebird::string sql("insert into rdb$relations (rdb$relation_id, rdb$relation_name, "
|
||||
"rdb$field_id, rdb$format, rdb$system_flag, rdb$dbkey_length, rdb$owner_name, "
|
||||
"rdb$relation_type) values (?, ?, ?, 0, ?, 8, ?, ?)");
|
||||
Firebird::AutoPtr<PreparedStatement> ps(tdbb->getAttachment()->prepareStatement(tdbb,
|
||||
*tdbb->getDefaultPool(), transaction, sql));
|
||||
|
||||
jrd_req* handle1 = NULL;
|
||||
jrd_req* handle2 = NULL;
|
||||
for (const int* relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld + 1)
|
||||
{
|
||||
for (n = 0, fld = relfld + RFLD_RPT; fld[RFLD_F_NAME]; fld += RFLD_F_LENGTH)
|
||||
{
|
||||
const int* pFld = fld;
|
||||
const int* pRelFld = relfld;
|
||||
store_relation_field(tdbb, pFld, pRelFld, n, &handle2);
|
||||
store_relation_field(tdbb, pFld, pRelFld, n, &handle1);
|
||||
n++;
|
||||
}
|
||||
|
||||
STORE(REQUEST_HANDLE handle1) X IN RDB$RELATIONS
|
||||
X.RDB$RELATION_ID = relfld[RFLD_R_ID];
|
||||
PAD(names[relfld[RFLD_R_NAME]], X.RDB$RELATION_NAME);
|
||||
X.RDB$FIELD_ID = n;
|
||||
X.RDB$FORMAT = 0;
|
||||
X.RDB$SYSTEM_FLAG = RDB_system;
|
||||
X.RDB$SYSTEM_FLAG.NULL = FALSE;
|
||||
X.RDB$DBKEY_LENGTH = 8;
|
||||
X.RDB$OWNER_NAME.NULL = TRUE;
|
||||
X.RDB$RELATION_TYPE = relfld[RFLD_R_TYPE];
|
||||
unsigned col = 0;
|
||||
ps->setInt(tdbb, ++col, relfld[RFLD_R_ID]);
|
||||
ps->setString(tdbb, ++col, names[relfld[RFLD_R_NAME]]);
|
||||
ps->setInt(tdbb, ++col, n);
|
||||
ps->setInt(tdbb, ++col, RDB_system);
|
||||
++col;
|
||||
if (string.hasData())
|
||||
ps->setString(tdbb, col, string);
|
||||
ps->setInt(tdbb, ++col, relfld[RFLD_R_TYPE]);
|
||||
|
||||
if (string.length())
|
||||
{
|
||||
PAD(string.c_str(), X.RDB$OWNER_NAME);
|
||||
X.RDB$OWNER_NAME.NULL = FALSE;
|
||||
}
|
||||
|
||||
END_STORE;
|
||||
ps->execute(tdbb, transaction);
|
||||
}
|
||||
|
||||
CMP_release(tdbb, handle1);
|
||||
CMP_release(tdbb, handle2);
|
||||
handle1 = handle2 = NULL;
|
||||
handle1 = NULL;
|
||||
|
||||
// Store global FIELDS
|
||||
|
||||
for (const gfld* gfield = gfields; gfield->gfld_name; gfield++)
|
||||
{
|
||||
store_global_field(tdbb, gfield, &handle1);
|
||||
}
|
||||
|
||||
CMP_release(tdbb, handle1);
|
||||
handle1 = NULL;
|
||||
|
||||
// Store DATABASE record
|
||||
|
||||
STORE(REQUEST_HANDLE handle1) X IN RDB$DATABASE
|
||||
X.RDB$RELATION_ID = (int) USER_DEF_REL_INIT_ID;
|
||||
X.RDB$CHARACTER_SET_NAME.NULL = TRUE;
|
||||
if (string2.hasData())
|
||||
{
|
||||
PAD (string2.c_str(), X.RDB$CHARACTER_SET_NAME);
|
||||
X.RDB$CHARACTER_SET_NAME.NULL = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PAD (DEFAULT_DB_CHARACTER_SET_NAME, X.RDB$CHARACTER_SET_NAME);
|
||||
X.RDB$CHARACTER_SET_NAME.NULL = FALSE;
|
||||
}
|
||||
END_STORE
|
||||
|
||||
CMP_release(tdbb, handle1);
|
||||
handle1 = NULL;
|
||||
sql = "insert into rdb$database (rdb$relation_id, rdb$character_set_name) values (?, ?)";
|
||||
ps.reset(tdbb->getAttachment()->prepareStatement(tdbb,
|
||||
*tdbb->getDefaultPool(), transaction, sql));
|
||||
ps->setInt(tdbb, 1, USER_DEF_REL_INIT_ID);
|
||||
ps->setString(tdbb, 2, (string2.hasData() ? string2 : DEFAULT_DB_CHARACTER_SET_NAME));
|
||||
ps->execute(tdbb, transaction);
|
||||
|
||||
// Store ADMIN_ROLE record
|
||||
|
||||
@ -673,6 +660,135 @@ void INI_init2(thread_db* tdbb)
|
||||
}
|
||||
|
||||
|
||||
// Load system objects into DSQL metadata cache.
|
||||
void INI_init3(thread_db* tdbb, dsql_dbb* database)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
const USHORT majorVersion = dbb->dbb_ods_version;
|
||||
const USHORT minorVersion = dbb->dbb_minor_version;
|
||||
const int* fld;
|
||||
|
||||
// Load relation and fields.
|
||||
|
||||
for (const int* relfld = relfields; relfld[RFLD_R_NAME]; relfld = fld + 1)
|
||||
{
|
||||
if (relfld[RFLD_R_ODS] > ENCODE_ODS(majorVersion, minorVersion))
|
||||
continue;
|
||||
|
||||
dsql_rel* relation = FB_NEW(database->dbb_pool) dsql_rel(database->dbb_pool);
|
||||
|
||||
relation->rel_id = relfld[RFLD_R_ID];
|
||||
relation->rel_name = names[relfld[RFLD_R_NAME]];
|
||||
relation->rel_owner = SYSDBA_USER_NAME;
|
||||
relation->rel_dbkey_length = 8;
|
||||
|
||||
dsql_fld** ptr = &relation->rel_fields;
|
||||
int n = 0;
|
||||
|
||||
for (fld = relfld + RFLD_RPT; fld[RFLD_F_NAME]; fld += RFLD_F_LENGTH)
|
||||
{
|
||||
if (ENCODE_ODS(majorVersion, minorVersion) < fld[RFLD_F_ODS])
|
||||
continue;
|
||||
|
||||
dsql_fld* field = FB_NEW(database->dbb_pool) dsql_fld(database->dbb_pool);
|
||||
field->fld_id = n++;
|
||||
|
||||
*ptr = field;
|
||||
ptr = &field->fld_next;
|
||||
|
||||
// get field information
|
||||
|
||||
const gfld* gfield = &gfields[fld[RFLD_F_ID]];
|
||||
|
||||
field->fld_name = names[fld[RFLD_F_NAME]];
|
||||
field->fld_source = names[gfield->gfld_name];
|
||||
field->fld_length = gfield->gfld_length;
|
||||
field->fld_scale = 0;
|
||||
field->fld_sub_type = gfield->gfld_sub_type;
|
||||
field->fld_relation = relation;
|
||||
|
||||
field->fld_dtype = gfield->gfld_dtype;
|
||||
|
||||
if (field->fld_dtype == dtype_varying)
|
||||
field->fld_length += sizeof(USHORT);
|
||||
else if (field->fld_dtype == dtype_blob)
|
||||
{
|
||||
field->fld_seg_length = 80;
|
||||
if (gfield->gfld_sub_type == isc_blob_text)
|
||||
field->fld_character_set_id = CS_METADATA;
|
||||
}
|
||||
|
||||
if (DTYPE_IS_TEXT(gfield->gfld_dtype))
|
||||
{
|
||||
switch (gfield->gfld_sub_type)
|
||||
{
|
||||
case dsc_text_type_metadata:
|
||||
field->fld_character_set_id = CS_METADATA;
|
||||
break;
|
||||
case dsc_text_type_ascii:
|
||||
field->fld_character_set_id = CS_ASCII;
|
||||
break;
|
||||
case dsc_text_type_fixed:
|
||||
field->fld_character_set_id = CS_BINARY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gfield->gfld_nullable)
|
||||
field->fld_flags |= FLD_nullable;
|
||||
|
||||
field->fld_flags |= FLD_system;
|
||||
}
|
||||
|
||||
database->dbb_relations.put(relation->rel_name, relation);
|
||||
MET_dsql_cache_use(tdbb, SYM_relation, relation->rel_name);
|
||||
}
|
||||
|
||||
// Load internal character sets and collations, necessary for engine operation.
|
||||
|
||||
for (const IntlManager::CharSetDefinition* csDef = IntlManager::defaultCharSets;
|
||||
csDef->name; ++csDef)
|
||||
{
|
||||
if (csDef->id > ttype_last_internal)
|
||||
continue;
|
||||
|
||||
dsql_intlsym* csSymbol = FB_NEW(database->dbb_pool) dsql_intlsym(database->dbb_pool);
|
||||
csSymbol->intlsym_name = csDef->name;
|
||||
csSymbol->intlsym_flags = 0;
|
||||
csSymbol->intlsym_charset_id = csDef->id;
|
||||
csSymbol->intlsym_collate_id = 0;
|
||||
csSymbol->intlsym_ttype =
|
||||
INTL_CS_COLL_TO_TTYPE(csSymbol->intlsym_charset_id, csSymbol->intlsym_collate_id);
|
||||
csSymbol->intlsym_bytes_per_char = csDef->maxBytes;
|
||||
|
||||
database->dbb_charsets.put(csDef->name, csSymbol);
|
||||
database->dbb_charsets_by_id.put(csSymbol->intlsym_charset_id, csSymbol);
|
||||
MET_dsql_cache_use(tdbb, SYM_intlsym_charset, csDef->name);
|
||||
|
||||
for (const IntlManager::CollationDefinition* colDef = IntlManager::defaultCollations;
|
||||
colDef->name; ++colDef)
|
||||
{
|
||||
if (colDef->charSetId != csDef->id)
|
||||
continue;
|
||||
|
||||
dsql_intlsym* colSymbol = FB_NEW(database->dbb_pool) dsql_intlsym(database->dbb_pool);
|
||||
colSymbol->intlsym_name = colDef->name;
|
||||
colSymbol->intlsym_flags = 0;
|
||||
colSymbol->intlsym_charset_id = csDef->id;
|
||||
colSymbol->intlsym_collate_id = colDef->collationId;
|
||||
colSymbol->intlsym_ttype =
|
||||
INTL_CS_COLL_TO_TTYPE(colSymbol->intlsym_charset_id, colSymbol->intlsym_collate_id);
|
||||
colSymbol->intlsym_bytes_per_char = csDef->maxBytes;
|
||||
|
||||
database->dbb_collations.put(colDef->name, colSymbol);
|
||||
MET_dsql_cache_use(tdbb, SYM_intlsym_collation, colDef->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void add_index_set(Database* dbb)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -26,12 +26,14 @@
|
||||
|
||||
namespace Jrd {
|
||||
struct jrd_trg;
|
||||
class dsql_dbb;
|
||||
}
|
||||
|
||||
void INI_format(const TEXT*, const TEXT*);
|
||||
USHORT INI_get_trig_flags(const TEXT*);
|
||||
void INI_init(Jrd::thread_db*);
|
||||
void INI_init2(Jrd::thread_db*);
|
||||
void INI_init3(Jrd::thread_db*, Jrd::dsql_dbb* database);
|
||||
|
||||
#endif // JRD_INI_PROTO_H
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user