8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00
This commit is contained in:
asfernandes 2014-06-20 02:28:22 +00:00
parent 8d078b04ea
commit 08f3a00cb0
11 changed files with 134 additions and 136 deletions

View File

@ -6,7 +6,7 @@ Cursor variables
Allow usage of explicit or implicit cursors without needing the use of INTO clause in FETCH and Allow usage of explicit or implicit cursors without needing the use of INTO clause in FETCH and
FOR SELECT. FOR SELECT.
An explicit cursor automatically becomes a cursor variable. 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: Author:
Adriano dos Santos Fernandes <adrianosf@gmail.com> 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. 3) It's allowed to use the colon prefix with trigger's NEW and OLD contexts.
4) Cursor variables are read-only. 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, 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: Examples:
1. 1.

View File

@ -1096,7 +1096,7 @@ void MemoryPool::print_contents(FILE* file, bool used_only, const char* filter_p
TLS_DECLARE(MemoryPool*, contextPool); TLS_DECLARE(MemoryPool*, contextPool);
#else #else
TLS_DECLARE(MemoryPool*, *contextPoolPtr); TLS_DECLARE(MemoryPool*, *contextPoolPtr);
#endif //TLS_CLASS #endif // TLS_CLASS
MemoryPool* MemoryPool::setContextPool(MemoryPool* newPool) MemoryPool* MemoryPool::setContextPool(MemoryPool* newPool)
{ {
@ -1106,7 +1106,7 @@ MemoryPool* MemoryPool::setContextPool(MemoryPool* newPool)
#else #else
MemoryPool* const old = TLS_GET(*contextPoolPtr); MemoryPool* const old = TLS_GET(*contextPoolPtr);
TLS_SET(*contextPoolPtr, newPool); TLS_SET(*contextPoolPtr, newPool);
#endif //TLS_CLASS #endif // TLS_CLASS
return old; return old;
} }
@ -1116,7 +1116,7 @@ MemoryPool* MemoryPool::getContextPool()
return TLS_GET(contextPool); return TLS_GET(contextPool);
#else #else
return TLS_GET(*contextPoolPtr); return TLS_GET(*contextPoolPtr);
#endif //TLS_CLASS #endif // TLS_CLASS
} }
void MemoryPool::contextPoolInit() void MemoryPool::contextPoolInit()
@ -1125,7 +1125,7 @@ void MemoryPool::contextPoolInit()
// Allocate TLS entry for context pool // Allocate TLS entry for context pool
contextPoolPtr = FB_NEW(*getDefaultMemoryPool()) TLS_CLASS<MemoryPool*>; contextPoolPtr = FB_NEW(*getDefaultMemoryPool()) TLS_CLASS<MemoryPool*>;
// To be deleted by InstanceControl::InstanceList::destructors() at TLS priority // To be deleted by InstanceControl::InstanceList::destructors() at TLS priority
#endif //TLS_CLASS #endif // TLS_CLASS
} }
MemoryPool& AutoStorage::getAutoMemoryPool() MemoryPool& AutoStorage::getAutoMemoryPool()

View File

@ -77,7 +77,7 @@ void Jrd::Attachment::destroy(Attachment* const attachment)
fb_assert(sAtt); fb_assert(sAtt);
if (sAtt) if (sAtt)
{ {
// break link between attachment and it's stable part // break link between attachment and its stable part
sAtt->cancel(); sAtt->cancel();
attachment->setStable(NULL); attachment->setStable(NULL);

View File

@ -914,7 +914,7 @@ void DatabaseSnapshot::dumpAttachment(thread_db* tdbb, DumpRecord& record,
const jrd_req* const request = *i; const jrd_req* const request = *i;
if (!(request->getStatement()->flags & 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); const string plan = OPT_get_plan(tdbb, request, true);
putRequest(record, request, writer, fb_utils::genUniqueId(), plan); putRequest(record, request, writer, fb_utils::genUniqueId(), plan);

View File

@ -899,142 +899,138 @@ void mapUser(string& name, string& trusted_role, Firebird::string* auth_method,
try try
{ {
for (;;) for (;;)
{
if (syncType == SYNC_EXCLUSIVE)
{ {
DispatcherPtr prov; if (syncType == SYNC_EXCLUSIVE)
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)
{ {
iSec = prov->attachDatabase(&st, securityAlias, DispatcherPtr prov;
embeddedSysdba.getBufferLength(), embeddedSysdba.getBuffer());
if (!st.isSuccess()) 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)) iSec = prov->attachDatabase(&st, securityAlias,
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,
embeddedSysdba.getBufferLength(), embeddedSysdba.getBuffer()); 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)) const char* conf = "Providers=" CURRENT_ENGINE;
check("IProvider::attachDatabase", &st); embeddedSysdba.insertString(isc_dpb_config, conf, strlen(conf));
// missing DB is not a reason to fail mapping if (!iDb)
iDb = NULL; {
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); MutexEnsureUnlock g(treeMutex, FB_FUNCTION);
g.enter(); g.enter();
Cache* cDb = NULL; Cache* cDb = NULL;
if (db) if (db)
cDb = locate(alias, db); cDb = locate(alias, db);
Cache* cSec = locate(securityAlias, securityDb); Cache* cSec = locate(securityAlias, securityDb);
SyncObject dummySync; SyncObject dummySync;
Sync sDb((!(flags & FLAG_DB)) ? &cDb->syncObject : &dummySync, FB_FUNCTION); Sync sDb((!(flags & FLAG_DB)) ? &cDb->syncObject : &dummySync, FB_FUNCTION);
Sync sSec((!(flags & FLAG_SEC)) ? &cSec->syncObject : &dummySync, FB_FUNCTION); Sync sSec((!(flags & FLAG_SEC)) ? &cSec->syncObject : &dummySync, FB_FUNCTION);
sSec.lock(syncType); sSec.lock(syncType);
if (!sDb.lockConditional(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)
{ {
syncType = SYNC_EXCLUSIVE; // Avoid deadlocks cause hell knows which db is security for which
sSec.unlock(); sSec.unlock();
sDb.unlock(); // Now safely wait for sSec
sDb.lock(syncType);
// and repeat whole operation
continue; continue;
} }
if (cDb) // Required cache(s) are locked somehow - release treeMutex
cDb->populate(iDb); g.leave();
cSec->populate(iSec);
sSec.downgrade(SYNC_SHARED); // Check is it required to populate caches from DB
sDb.downgrade(SYNC_SHARED); 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 if (iDb)
AuthReader auth(authBlock); {
iDb->detach(&st);
// Map in simple mode first main, next security db check("IAttachment::detach", &st);
if (cDb && cDb->map4(false, flags & FLAG_DB, auth, info, newBlock)) iDb = NULL;
break; }
if (cSec->map4(false, flags & FLAG_SEC, auth, info, newBlock)) if (iSec)
break; {
iSec->detach(&st);
// Map in wildcard mode first main, next security db check("IAttachment::detach", &st);
if (cDb && cDb->map4(true, flags & FLAG_DB, auth, info, newBlock)) iSec = NULL;
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;
}
} }
catch(const Exception&) catch (const Exception&)
{ {
if (iDb) if (iDb)
{ iDb->release();
iDb->release(); if (iSec)
} iSec->release();
if (iSec) throw;
{
iSec->release();
}
throw;
} }
for (AuthReader rdr(newBlock); rdr.getInfo(info); rdr.moveNext()) for (AuthReader rdr(newBlock); rdr.getInfo(info); rdr.moveNext())

View File

@ -6103,7 +6103,7 @@ static JAttachment* create_attachment(const PathName& alias_name,
sAtt->manualLock(attachment->att_flags); sAtt->manualLock(attachment->att_flags);
jAtt = new JAttachment(sAtt); jAtt = new JAttachment(sAtt);
} }
catch(const Exception&) catch (const Exception&)
{ {
sAtt->release(); sAtt->release();
throw; throw;
@ -7890,7 +7890,8 @@ void JRD_shutdown_attachments(Database* dbb)
guard.lock(SYNC_SHARED); guard.lock(SYNC_SHARED);
for (Jrd::Attachment* attachment = dbb->dbb_attachments; for (Jrd::Attachment* attachment = dbb->dbb_attachments;
attachment; attachment = attachment->att_next) attachment;
attachment = attachment->att_next)
{ {
if (attachment->att_flags & ATT_shutdown) if (attachment->att_flags & ATT_shutdown)
{ {

View File

@ -381,7 +381,8 @@ bool BackupManager::extendDatabase(thread_db* tdbb)
LocalAllocReadGuard localAllocGuard(this); LocalAllocReadGuard localAllocGuard(this);
AllocItemTree::Accessor all(alloc_table); AllocItemTree::Accessor all(alloc_table);
if (all.getFirst()) { if (all.getFirst())
{
do do
{ {
const ULONG pg = all.current().db_page; const ULONG pg = all.current().db_page;
@ -402,7 +403,7 @@ bool BackupManager::extendDatabase(thread_db* tdbb)
maxAllocPage = pgSpace->maxAlloc(); maxAllocPage = pgSpace->maxAlloc();
while (maxAllocPage < maxPage) 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); maxAllocPage, 256);
if (ret != 256) if (ret != 256)
@ -410,6 +411,7 @@ bool BackupManager::extendDatabase(thread_db* tdbb)
maxAllocPage += ret; maxAllocPage += ret;
} }
return true; return true;
} }

View File

@ -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; MAX_ULONG : file->fil_max_page - file->fil_min_page + 1;
if (filePages < fileMaxPages) if (filePages < fileMaxPages)
{ {
if (file->fil_flags & FIL_no_fast_extend) if (file->fil_flags & FIL_no_fast_extend)
return; return;
const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages); const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages);

View File

@ -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); const ssize_t res = read(file, buffer, bufsize);
if (res < 0) if (res < 0)
{
status_exception::raise(Arg::Gds(isc_nbackup_err_read) << status_exception::raise(Arg::Gds(isc_nbackup_err_read) <<
(&file == &dbase ? dbname.c_str() : (&file == &dbase ? dbname.c_str() :
&file == &backup ? bakname.c_str() : "unknown") << &file == &backup ? bakname.c_str() : "unknown") <<
Arg::OsError()); Arg::OsError());
}
if (!res) if (!res)
break; break;
@ -591,9 +593,9 @@ void NBackup::open_backup_scan()
unsigned narg = 0; unsigned narg = 0;
char* args[ARGCOUNT + 1]; char* args[ARGCOUNT + 1];
bool inStr = false; 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 ' ':
case '\t': case '\t':
@ -1325,8 +1327,10 @@ void NBackup::backup_database(int level, const PathName& fname)
time_t finish = time(NULL); time_t finish = time(NULL);
double elapsed = difftime(finish, start); double elapsed = difftime(finish, start);
if (bakname != "stdout") if (bakname != "stdout")
{
uSvc->printf(false, "time elapsed\t%.0f sec \npage reads\t%u \npage writes\t%u\n", uSvc->printf(false, "time elapsed\t%.0f sec \npage reads\t%u \npage writes\t%u\n",
elapsed, page_reads, page_writes); elapsed, page_reads, page_writes);
}
} }
void NBackup::restore_database(const BackupFiles& files) void NBackup::restore_database(const BackupFiles& files)

View File

@ -1382,7 +1382,7 @@ void TracePluginImpl::register_sql_statement(TraceSQLStatement* statement)
} }
*stmt_data.description += temp; *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()) (config.explain_plan ? statement->getPlanExplained() : statement->getPlan())
: NULL; : NULL;

View File

@ -4312,9 +4312,7 @@ ITransaction* YStatement::execute(IStatus* status, ITransaction* transaction,
outMetadata, outBuffer); outMetadata, outBuffer);
if (newTrans == trans) if (newTrans == trans)
{
newTrans = transaction; newTrans = transaction;
}
else else
{ {
if (transaction) if (transaction)
@ -4324,10 +4322,9 @@ ITransaction* YStatement::execute(IStatus* status, ITransaction* transaction,
transaction->release(); transaction->release();
transaction = NULL; // Get ready for correct return in OOM case transaction = NULL; // Get ready for correct return in OOM case
} }
if (newTrans) if (newTrans)
{
newTrans = new YTransaction(attachment, newTrans); newTrans = new YTransaction(attachment, newTrans);
}
} }
return newTrans; return newTrans;
@ -5210,9 +5207,7 @@ ITransaction* YAttachment::execute(IStatus* status, ITransaction* transaction,
inMetadata, inBuffer, outMetadata, outBuffer); inMetadata, inBuffer, outMetadata, outBuffer);
if (newTrans == trans) if (newTrans == trans)
{
newTrans = transaction; newTrans = transaction;
}
else else
{ {
if (transaction) if (transaction)
@ -5222,10 +5217,9 @@ ITransaction* YAttachment::execute(IStatus* status, ITransaction* transaction,
transaction->release(); transaction->release();
transaction = NULL; // Get ready for correct return in OOM case transaction = NULL; // Get ready for correct return in OOM case
} }
if (newTrans) if (newTrans)
{
newTrans = new YTransaction(this, newTrans); newTrans = new YTransaction(this, newTrans);
}
} }
return newTrans; return newTrans;