mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 18:03:03 +01:00
Misc.
This commit is contained in:
parent
8d078b04ea
commit
08f3a00cb0
@ -6,7 +6,7 @@ Cursor variables
|
||||
Allow usage of explicit or implicit cursors without needing the use of INTO clause in FETCH and
|
||||
FOR SELECT.
|
||||
An explicit cursor automatically becomes a cursor variable.
|
||||
An implicit cursor (FOR SELECT) needs the {AS CURSOR <name>} clause.
|
||||
An implicit cursor (FOR SELECT) needs the {AS CURSOR <name>} clause to become a cursor variable.
|
||||
|
||||
Author:
|
||||
Adriano dos Santos Fernandes <adrianosf@gmail.com>
|
||||
@ -20,7 +20,8 @@ Cursor variables
|
||||
3) It's allowed to use the colon prefix with trigger's NEW and OLD contexts.
|
||||
4) Cursor variables are read-only.
|
||||
5) A FOR SELECT without AS CURSOR needs the use of INTO, while with AS CURSOR it's not required,
|
||||
but still allowed.
|
||||
but still allowed. With FETCH, INTO is now optional.
|
||||
6) It's allowed now to use the colon prefix when assigning to variables or NEW's fields.
|
||||
|
||||
Examples:
|
||||
1.
|
||||
|
@ -1096,7 +1096,7 @@ void MemoryPool::print_contents(FILE* file, bool used_only, const char* filter_p
|
||||
TLS_DECLARE(MemoryPool*, contextPool);
|
||||
#else
|
||||
TLS_DECLARE(MemoryPool*, *contextPoolPtr);
|
||||
#endif //TLS_CLASS
|
||||
#endif // TLS_CLASS
|
||||
|
||||
MemoryPool* MemoryPool::setContextPool(MemoryPool* newPool)
|
||||
{
|
||||
@ -1106,7 +1106,7 @@ MemoryPool* MemoryPool::setContextPool(MemoryPool* newPool)
|
||||
#else
|
||||
MemoryPool* const old = TLS_GET(*contextPoolPtr);
|
||||
TLS_SET(*contextPoolPtr, newPool);
|
||||
#endif //TLS_CLASS
|
||||
#endif // TLS_CLASS
|
||||
return old;
|
||||
}
|
||||
|
||||
@ -1116,7 +1116,7 @@ MemoryPool* MemoryPool::getContextPool()
|
||||
return TLS_GET(contextPool);
|
||||
#else
|
||||
return TLS_GET(*contextPoolPtr);
|
||||
#endif //TLS_CLASS
|
||||
#endif // TLS_CLASS
|
||||
}
|
||||
|
||||
void MemoryPool::contextPoolInit()
|
||||
@ -1125,7 +1125,7 @@ void MemoryPool::contextPoolInit()
|
||||
// Allocate TLS entry for context pool
|
||||
contextPoolPtr = FB_NEW(*getDefaultMemoryPool()) TLS_CLASS<MemoryPool*>;
|
||||
// To be deleted by InstanceControl::InstanceList::destructors() at TLS priority
|
||||
#endif //TLS_CLASS
|
||||
#endif // TLS_CLASS
|
||||
}
|
||||
|
||||
MemoryPool& AutoStorage::getAutoMemoryPool()
|
||||
|
@ -77,7 +77,7 @@ void Jrd::Attachment::destroy(Attachment* const attachment)
|
||||
fb_assert(sAtt);
|
||||
if (sAtt)
|
||||
{
|
||||
// break link between attachment and it's stable part
|
||||
// break link between attachment and its stable part
|
||||
sAtt->cancel();
|
||||
attachment->setStable(NULL);
|
||||
|
||||
|
@ -914,7 +914,7 @@ void DatabaseSnapshot::dumpAttachment(thread_db* tdbb, DumpRecord& record,
|
||||
const jrd_req* const request = *i;
|
||||
|
||||
if (!(request->getStatement()->flags &
|
||||
(JrdStatement::FLAG_INTERNAL | JrdStatement::FLAG_SYS_TRIGGER)))
|
||||
(JrdStatement::FLAG_INTERNAL | JrdStatement::FLAG_SYS_TRIGGER)))
|
||||
{
|
||||
const string plan = OPT_get_plan(tdbb, request, true);
|
||||
putRequest(record, request, writer, fb_utils::genUniqueId(), plan);
|
||||
|
@ -899,142 +899,138 @@ void mapUser(string& name, string& trusted_role, Firebird::string* auth_method,
|
||||
|
||||
try
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (syncType == SYNC_EXCLUSIVE)
|
||||
for (;;)
|
||||
{
|
||||
DispatcherPtr prov;
|
||||
|
||||
ClumpletWriter embeddedSysdba(ClumpletWriter::Tagged,
|
||||
MAX_DPB_SIZE, isc_dpb_version1);
|
||||
embeddedSysdba.insertString(isc_dpb_user_name, SYSDBA_USER_NAME,
|
||||
strlen(SYSDBA_USER_NAME));
|
||||
embeddedSysdba.insertByte(isc_dpb_sec_attach, TRUE);
|
||||
embeddedSysdba.insertByte(isc_dpb_no_db_triggers, TRUE);
|
||||
|
||||
if (!iSec)
|
||||
if (syncType == SYNC_EXCLUSIVE)
|
||||
{
|
||||
iSec = prov->attachDatabase(&st, securityAlias,
|
||||
embeddedSysdba.getBufferLength(), embeddedSysdba.getBuffer());
|
||||
if (!st.isSuccess())
|
||||
DispatcherPtr prov;
|
||||
|
||||
ClumpletWriter embeddedSysdba(ClumpletWriter::Tagged,
|
||||
MAX_DPB_SIZE, isc_dpb_version1);
|
||||
embeddedSysdba.insertString(isc_dpb_user_name, SYSDBA_USER_NAME,
|
||||
strlen(SYSDBA_USER_NAME));
|
||||
embeddedSysdba.insertByte(isc_dpb_sec_attach, TRUE);
|
||||
embeddedSysdba.insertByte(isc_dpb_no_db_triggers, TRUE);
|
||||
|
||||
if (!iSec)
|
||||
{
|
||||
if (!fb_utils::containsErrorCode(st.get(), isc_io_error))
|
||||
check("IProvider::attachDatabase", &st);
|
||||
|
||||
// missing security DB is not a reason to fail mapping
|
||||
iSec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (db && !iDb)
|
||||
{
|
||||
const char* conf = "Providers=" CURRENT_ENGINE;
|
||||
embeddedSysdba.insertString(isc_dpb_config, conf, strlen(conf));
|
||||
|
||||
if (!iDb)
|
||||
{
|
||||
iDb = prov->attachDatabase(&st, alias,
|
||||
iSec = prov->attachDatabase(&st, securityAlias,
|
||||
embeddedSysdba.getBufferLength(), embeddedSysdba.getBuffer());
|
||||
if (!st.isSuccess())
|
||||
{
|
||||
if (!fb_utils::containsErrorCode(st.get(), isc_io_error))
|
||||
check("IProvider::attachDatabase", &st);
|
||||
|
||||
// missing security DB is not a reason to fail mapping
|
||||
iSec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!st.isSuccess())
|
||||
if (db && !iDb)
|
||||
{
|
||||
if (!fb_utils::containsErrorCode(st.get(), isc_io_error))
|
||||
check("IProvider::attachDatabase", &st);
|
||||
const char* conf = "Providers=" CURRENT_ENGINE;
|
||||
embeddedSysdba.insertString(isc_dpb_config, conf, strlen(conf));
|
||||
|
||||
// missing DB is not a reason to fail mapping
|
||||
iDb = NULL;
|
||||
if (!iDb)
|
||||
{
|
||||
iDb = prov->attachDatabase(&st, alias,
|
||||
embeddedSysdba.getBufferLength(), embeddedSysdba.getBuffer());
|
||||
}
|
||||
|
||||
if (!st.isSuccess())
|
||||
{
|
||||
if (!fb_utils::containsErrorCode(st.get(), isc_io_error))
|
||||
check("IProvider::attachDatabase", &st);
|
||||
|
||||
// missing DB is not a reason to fail mapping
|
||||
iDb = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MutexEnsureUnlock g(treeMutex, FB_FUNCTION);
|
||||
g.enter();
|
||||
MutexEnsureUnlock g(treeMutex, FB_FUNCTION);
|
||||
g.enter();
|
||||
|
||||
Cache* cDb = NULL;
|
||||
if (db)
|
||||
cDb = locate(alias, db);
|
||||
Cache* cSec = locate(securityAlias, securityDb);
|
||||
Cache* cDb = NULL;
|
||||
if (db)
|
||||
cDb = locate(alias, db);
|
||||
Cache* cSec = locate(securityAlias, securityDb);
|
||||
|
||||
SyncObject dummySync;
|
||||
Sync sDb((!(flags & FLAG_DB)) ? &cDb->syncObject : &dummySync, FB_FUNCTION);
|
||||
Sync sSec((!(flags & FLAG_SEC)) ? &cSec->syncObject : &dummySync, FB_FUNCTION);
|
||||
SyncObject dummySync;
|
||||
Sync sDb((!(flags & FLAG_DB)) ? &cDb->syncObject : &dummySync, FB_FUNCTION);
|
||||
Sync sSec((!(flags & FLAG_SEC)) ? &cSec->syncObject : &dummySync, FB_FUNCTION);
|
||||
|
||||
sSec.lock(syncType);
|
||||
if (!sDb.lockConditional(syncType))
|
||||
{
|
||||
// Avoid deadlocks cause hell knows which db is security for which
|
||||
sSec.unlock();
|
||||
// Now safely wait for sSec
|
||||
sDb.lock(syncType);
|
||||
// and repeat whole operation
|
||||
continue;
|
||||
}
|
||||
|
||||
// Required cache(s) are locked somehow - release treeMutex
|
||||
g.leave();
|
||||
|
||||
// Check is it required to populate caches from DB
|
||||
if ((cDb && !cDb->dataFlag) || !cSec->dataFlag)
|
||||
{
|
||||
if (syncType != SYNC_EXCLUSIVE)
|
||||
sSec.lock(syncType);
|
||||
if (!sDb.lockConditional(syncType))
|
||||
{
|
||||
syncType = SYNC_EXCLUSIVE;
|
||||
// Avoid deadlocks cause hell knows which db is security for which
|
||||
sSec.unlock();
|
||||
sDb.unlock();
|
||||
|
||||
// Now safely wait for sSec
|
||||
sDb.lock(syncType);
|
||||
// and repeat whole operation
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cDb)
|
||||
cDb->populate(iDb);
|
||||
cSec->populate(iSec);
|
||||
// Required cache(s) are locked somehow - release treeMutex
|
||||
g.leave();
|
||||
|
||||
sSec.downgrade(SYNC_SHARED);
|
||||
sDb.downgrade(SYNC_SHARED);
|
||||
// Check is it required to populate caches from DB
|
||||
if ((cDb && !cDb->dataFlag) || !cSec->dataFlag)
|
||||
{
|
||||
if (syncType != SYNC_EXCLUSIVE)
|
||||
{
|
||||
syncType = SYNC_EXCLUSIVE;
|
||||
sSec.unlock();
|
||||
sDb.unlock();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cDb)
|
||||
cDb->populate(iDb);
|
||||
cSec->populate(iSec);
|
||||
|
||||
sSec.downgrade(SYNC_SHARED);
|
||||
sDb.downgrade(SYNC_SHARED);
|
||||
}
|
||||
|
||||
// Caches are ready somehow - proceed with analysis
|
||||
AuthReader auth(authBlock);
|
||||
|
||||
// Map in simple mode first main, next security db
|
||||
if (cDb && cDb->map4(false, flags & FLAG_DB, auth, info, newBlock))
|
||||
break;
|
||||
if (cSec->map4(false, flags & FLAG_SEC, auth, info, newBlock))
|
||||
break;
|
||||
|
||||
// Map in wildcard mode first main, next security db
|
||||
if (cDb && cDb->map4(true, flags & FLAG_DB, auth, info, newBlock))
|
||||
break;
|
||||
cSec->map4(true, flags & FLAG_SEC, auth, info, newBlock);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Caches are ready somehow - proceed with analysis
|
||||
AuthReader auth(authBlock);
|
||||
|
||||
// Map in simple mode first main, next security db
|
||||
if (cDb && cDb->map4(false, flags & FLAG_DB, auth, info, newBlock))
|
||||
break;
|
||||
if (cSec->map4(false, flags & FLAG_SEC, auth, info, newBlock))
|
||||
break;
|
||||
|
||||
// Map in wildcard mode first main, next security db
|
||||
if (cDb && cDb->map4(true, flags & FLAG_DB, auth, info, newBlock))
|
||||
break;
|
||||
cSec->map4(true, flags & FLAG_SEC, auth, info, newBlock);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (iDb)
|
||||
{
|
||||
iDb->detach(&st);
|
||||
check("IAttachment::detach", &st);
|
||||
iDb = NULL;
|
||||
}
|
||||
if (iSec)
|
||||
{
|
||||
iSec->detach(&st);
|
||||
check("IAttachment::detach", &st);
|
||||
iSec = NULL;
|
||||
}
|
||||
if (iDb)
|
||||
{
|
||||
iDb->detach(&st);
|
||||
check("IAttachment::detach", &st);
|
||||
iDb = NULL;
|
||||
}
|
||||
if (iSec)
|
||||
{
|
||||
iSec->detach(&st);
|
||||
check("IAttachment::detach", &st);
|
||||
iSec = NULL;
|
||||
}
|
||||
}
|
||||
catch(const Exception&)
|
||||
catch (const Exception&)
|
||||
{
|
||||
if (iDb)
|
||||
{
|
||||
iDb->release();
|
||||
}
|
||||
if (iSec)
|
||||
{
|
||||
iSec->release();
|
||||
}
|
||||
throw;
|
||||
if (iDb)
|
||||
iDb->release();
|
||||
if (iSec)
|
||||
iSec->release();
|
||||
throw;
|
||||
}
|
||||
|
||||
for (AuthReader rdr(newBlock); rdr.getInfo(info); rdr.moveNext())
|
||||
|
@ -6103,7 +6103,7 @@ static JAttachment* create_attachment(const PathName& alias_name,
|
||||
sAtt->manualLock(attachment->att_flags);
|
||||
jAtt = new JAttachment(sAtt);
|
||||
}
|
||||
catch(const Exception&)
|
||||
catch (const Exception&)
|
||||
{
|
||||
sAtt->release();
|
||||
throw;
|
||||
@ -7890,7 +7890,8 @@ void JRD_shutdown_attachments(Database* dbb)
|
||||
guard.lock(SYNC_SHARED);
|
||||
|
||||
for (Jrd::Attachment* attachment = dbb->dbb_attachments;
|
||||
attachment; attachment = attachment->att_next)
|
||||
attachment;
|
||||
attachment = attachment->att_next)
|
||||
{
|
||||
if (attachment->att_flags & ATT_shutdown)
|
||||
{
|
||||
|
@ -381,7 +381,8 @@ bool BackupManager::extendDatabase(thread_db* tdbb)
|
||||
LocalAllocReadGuard localAllocGuard(this);
|
||||
AllocItemTree::Accessor all(alloc_table);
|
||||
|
||||
if (all.getFirst()) {
|
||||
if (all.getFirst())
|
||||
{
|
||||
do
|
||||
{
|
||||
const ULONG pg = all.current().db_page;
|
||||
@ -402,7 +403,7 @@ bool BackupManager::extendDatabase(thread_db* tdbb)
|
||||
maxAllocPage = pgSpace->maxAlloc();
|
||||
while (maxAllocPage < maxPage)
|
||||
{
|
||||
const USHORT ret = PIO_init_data(database, pgSpace->file, tdbb->tdbb_status_vector,
|
||||
const USHORT ret = PIO_init_data(database, pgSpace->file, tdbb->tdbb_status_vector,
|
||||
maxAllocPage, 256);
|
||||
|
||||
if (ret != 256)
|
||||
@ -410,6 +411,7 @@ bool BackupManager::extendDatabase(thread_db* tdbb)
|
||||
|
||||
maxAllocPage += ret;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ void PIO_extend(Database* dbb, jrd_file* main_file, const ULONG extPages, const
|
||||
MAX_ULONG : file->fil_max_page - file->fil_min_page + 1;
|
||||
if (filePages < fileMaxPages)
|
||||
{
|
||||
if (file->fil_flags & FIL_no_fast_extend)
|
||||
if (file->fil_flags & FIL_no_fast_extend)
|
||||
return;
|
||||
|
||||
const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages);
|
||||
|
@ -387,10 +387,12 @@ size_t NBackup::read_file(FILE_HANDLE &file, void *buffer, size_t bufsize)
|
||||
{
|
||||
const ssize_t res = read(file, buffer, bufsize);
|
||||
if (res < 0)
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_nbackup_err_read) <<
|
||||
(&file == &dbase ? dbname.c_str() :
|
||||
&file == &backup ? bakname.c_str() : "unknown") <<
|
||||
Arg::OsError());
|
||||
}
|
||||
|
||||
if (!res)
|
||||
break;
|
||||
@ -591,9 +593,9 @@ void NBackup::open_backup_scan()
|
||||
unsigned narg = 0;
|
||||
char* args[ARGCOUNT + 1];
|
||||
bool inStr = false;
|
||||
for(unsigned i = 0; i < command.length(); ++i)
|
||||
for (unsigned i = 0; i < command.length(); ++i)
|
||||
{
|
||||
switch(command[i])
|
||||
switch (command[i])
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
@ -1325,8 +1327,10 @@ void NBackup::backup_database(int level, const PathName& fname)
|
||||
time_t finish = time(NULL);
|
||||
double elapsed = difftime(finish, start);
|
||||
if (bakname != "stdout")
|
||||
{
|
||||
uSvc->printf(false, "time elapsed\t%.0f sec \npage reads\t%u \npage writes\t%u\n",
|
||||
elapsed, page_reads, page_writes);
|
||||
}
|
||||
}
|
||||
|
||||
void NBackup::restore_database(const BackupFiles& files)
|
||||
|
@ -1382,7 +1382,7 @@ void TracePluginImpl::register_sql_statement(TraceSQLStatement* statement)
|
||||
}
|
||||
*stmt_data.description += temp;
|
||||
|
||||
const char* access_path = config.print_plan ?
|
||||
const char* access_path = config.print_plan ?
|
||||
(config.explain_plan ? statement->getPlanExplained() : statement->getPlan())
|
||||
: NULL;
|
||||
|
||||
|
@ -4312,9 +4312,7 @@ ITransaction* YStatement::execute(IStatus* status, ITransaction* transaction,
|
||||
outMetadata, outBuffer);
|
||||
|
||||
if (newTrans == trans)
|
||||
{
|
||||
newTrans = transaction;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transaction)
|
||||
@ -4324,10 +4322,9 @@ ITransaction* YStatement::execute(IStatus* status, ITransaction* transaction,
|
||||
transaction->release();
|
||||
transaction = NULL; // Get ready for correct return in OOM case
|
||||
}
|
||||
|
||||
if (newTrans)
|
||||
{
|
||||
newTrans = new YTransaction(attachment, newTrans);
|
||||
}
|
||||
}
|
||||
|
||||
return newTrans;
|
||||
@ -5210,9 +5207,7 @@ ITransaction* YAttachment::execute(IStatus* status, ITransaction* transaction,
|
||||
inMetadata, inBuffer, outMetadata, outBuffer);
|
||||
|
||||
if (newTrans == trans)
|
||||
{
|
||||
newTrans = transaction;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transaction)
|
||||
@ -5222,10 +5217,9 @@ ITransaction* YAttachment::execute(IStatus* status, ITransaction* transaction,
|
||||
transaction->release();
|
||||
transaction = NULL; // Get ready for correct return in OOM case
|
||||
}
|
||||
|
||||
if (newTrans)
|
||||
{
|
||||
newTrans = new YTransaction(this, newTrans);
|
||||
}
|
||||
}
|
||||
|
||||
return newTrans;
|
||||
|
Loading…
Reference in New Issue
Block a user