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
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.

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -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())

View File

@ -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)
{

View File

@ -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;
}

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;
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);

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);
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)

View File

@ -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;

View File

@ -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;