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

Refactor statement and request parts so multiple DSQL requests could be created from a single compiled statement.

Pave the ground for compiled statement cache.
This commit is contained in:
Adriano dos Santos Fernandes 2022-02-07 15:52:12 -03:00
parent 1a072f43d8
commit 391e7ef4fc
45 changed files with 2452 additions and 2100 deletions

View File

@ -41,6 +41,8 @@
<ClCompile Include="..\..\..\src\dsql\DsqlCompilerScratch.cpp" />
<ClCompile Include="..\..\..\src\dsql\DsqlCursor.cpp" />
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp" />
<ClCompile Include="..\..\..\src\dsql\DsqlRequests.cpp" />
<ClCompile Include="..\..\..\src\dsql\DsqlStatements.cpp" />
<ClCompile Include="..\..\..\src\dsql\errd.cpp" />
<ClCompile Include="..\..\..\src\dsql\ExprNodes.cpp" />
<ClCompile Include="..\..\..\src\dsql\gen.cpp" />
@ -186,6 +188,8 @@
<ClInclude Include="..\..\..\src\dsql\DsqlCompilerScratch.h" />
<ClInclude Include="..\..\..\src\dsql\DsqlCursor.h" />
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h" />
<ClInclude Include="..\..\..\src\dsql\DsqlRequests.h" />
<ClInclude Include="..\..\..\src\dsql\DsqlStatements.h" />
<ClInclude Include="..\..\..\src\dsql\dsql_proto.h" />
<ClInclude Include="..\..\..\src\dsql\errd_proto.h" />
<ClInclude Include="..\..\..\src\dsql\ExprNodes.h" />

View File

@ -138,6 +138,12 @@
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp">
<Filter>DSQL</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\dsql\DsqlRequests.cpp">
<Filter>DSQL</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\dsql\DsqlStatements.cpp">
<Filter>DSQL</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\dsql\errd.cpp">
<Filter>DSQL</Filter>
</ClCompile>
@ -545,6 +551,12 @@
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\dsql\DsqlRequests.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\dsql\DsqlStatements.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\dsql\errd_proto.h">
<Filter>Header files</Filter>
</ClInclude>

View File

@ -2354,7 +2354,7 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
stmtNode->genBlr(dsqlScratch);
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_DDL);
dsqlScratch->appendUChar(blr_end);
dsqlScratch->genReturn(false);
dsqlScratch->appendUChar(blr_end);
@ -2879,7 +2879,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS);
bool modified = false;
DsqlCompiledStatement* statement = dsqlScratch->getStatement();
DsqlStatement* statement = dsqlScratch->getStatement();
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
P IN RDB$PROCEDURES
@ -2973,7 +2973,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
P.RDB$PROCEDURE_TYPE.NULL = FALSE;
P.RDB$PROCEDURE_TYPE = (USHORT)
(statement->getFlags() & DsqlCompiledStatement::FLAG_SELECTABLE ?
(statement->getFlags() & DsqlStatement::FLAG_SELECTABLE ?
prc_selectable : prc_executable);
}
}
@ -3249,7 +3249,7 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
stmtNode->genBlr(dsqlScratch);
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_DDL);
dsqlScratch->appendUChar(blr_end);
dsqlScratch->genReturn(true);
dsqlScratch->appendUChar(blr_end);
@ -3780,7 +3780,7 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
// The statement type may have been set incorrectly when parsing
// the trigger actions, so reset it to reflect the fact that this
// is a data definition statement; also reset the ddl node.
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_DDL);
}
invalid = false;
@ -10742,7 +10742,7 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
(Arg::Gds(isc_adm_task_denied) << Arg::Gds(isc_miss_prvlg) << "CHANGE_MAPPING_RULES").raise();
if (from)
fromUtf8 = from->toUtf8(dsqlScratch);
fromUtf8 = from->toUtf8(transaction);
if (global)
{

View File

@ -1130,7 +1130,7 @@ public:
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->getStatement()->setType(
legacy ? DsqlCompiledStatement::TYPE_SET_GENERATOR : DsqlCompiledStatement::TYPE_DDL);
legacy ? DsqlStatement::TYPE_SET_GENERATOR : DsqlStatement::TYPE_DDL);
return this;
}
@ -2418,7 +2418,7 @@ public:
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->getStatement()->setType(
create ? DsqlCompiledStatement::TYPE_CREATE_DB : DsqlCompiledStatement::TYPE_DDL);
create ? DsqlStatement::TYPE_CREATE_DB : DsqlStatement::TYPE_DDL);
return this;
}

View File

@ -60,7 +60,7 @@ namespace {
};
}
DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb)
DsqlBatch::DsqlBatch(DsqlDmlRequest* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb)
: m_request(req),
m_batch(NULL),
m_meta(inMeta),
@ -183,7 +183,7 @@ void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
m_batch = interfacePtr;
}
DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inMetadata,
DsqlBatch* DsqlBatch::open(thread_db* tdbb, DsqlDmlRequest* req, IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par)
{
SET_TDBB(tdbb);
@ -205,15 +205,15 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
// Sanity checks before creating batch
if (!req->req_request)
if (!req->getJrdRequest())
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
Arg::Gds(isc_unprepared_stmt));
}
const DsqlCompiledStatement* statement = req->getStatement();
const DsqlStatement* statement = req->getStatement();
if (statement->getFlags() & DsqlCompiledStatement::FLAG_ORPHAN)
if (statement->getFlags() & DsqlStatement::FLAG_ORPHAN)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
Arg::Gds(isc_bad_req_handle));
@ -221,11 +221,11 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
switch (statement->getType())
{
case DsqlCompiledStatement::TYPE_INSERT:
case DsqlCompiledStatement::TYPE_DELETE:
case DsqlCompiledStatement::TYPE_UPDATE:
case DsqlCompiledStatement::TYPE_EXEC_PROCEDURE:
case DsqlCompiledStatement::TYPE_EXEC_BLOCK:
case DsqlStatement::TYPE_INSERT:
case DsqlStatement::TYPE_DELETE:
case DsqlStatement::TYPE_UPDATE:
case DsqlStatement::TYPE_EXEC_PROCEDURE:
case DsqlStatement::TYPE_EXEC_BLOCK:
break;
default:
@ -652,7 +652,7 @@ private:
// execute request
m_request->req_transaction = transaction;
jrd_req* req = m_request->req_request;
jrd_req* req = m_request->getJrdRequest();
fb_assert(req);
// prepare completion interface
@ -662,7 +662,7 @@ private:
const dsql_msg* message = m_request->getStatement()->getSendMsg();
bool startRequest = true;
bool isExecBlock = m_request->getStatement()->getType() == DsqlCompiledStatement::TYPE_EXEC_BLOCK;
bool isExecBlock = m_request->getStatement()->getType() == DsqlStatement::TYPE_EXEC_BLOCK;
const auto receiveMessage = isExecBlock ? m_request->getStatement()->getReceiveMsg() : nullptr;
auto receiveMsgBuffer = isExecBlock ? m_request->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr;

View File

@ -41,7 +41,7 @@ class ClumpletReader;
namespace Jrd {
class dsql_req;
class DsqlDmlRequest;
class dsql_msg;
class thread_db;
class JBatch;
@ -50,7 +50,7 @@ class Attachment;
class DsqlBatch
{
public:
DsqlBatch(dsql_req* req, const dsql_msg* message, Firebird::IMessageMetadata* inMetadata,
DsqlBatch(DsqlDmlRequest* req, const dsql_msg* message, Firebird::IMessageMetadata* inMetadata,
Firebird::ClumpletReader& pb);
~DsqlBatch();
@ -61,7 +61,7 @@ public:
static const ULONG SIZEOF_BLOB_HEAD = sizeof(ISC_QUAD) + 2 * sizeof(ULONG);
static const unsigned BLOB_STREAM_ALIGN = 4;
static DsqlBatch* open(thread_db* tdbb, dsql_req* req, Firebird::IMessageMetadata* inMetadata,
static DsqlBatch* open(thread_db* tdbb, DsqlDmlRequest* req, Firebird::IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par);
Attachment* getAttachment() const;
@ -101,7 +101,7 @@ private:
m_flags &= ~(1 << bit);
}
dsql_req* const m_request;
DsqlDmlRequest* const m_request;
JBatch* m_batch;
Firebird::IMessageMetadata* m_meta;

View File

@ -24,6 +24,7 @@
#include "../jrd/jrd.h"
#include "../dsql/dsql.h"
#include "../dsql/DsqlStatements.h"
#include "../dsql/BlrDebugWriter.h"
#include "../common/classes/array.h"
#include "../jrd/MetaName.h"
@ -73,14 +74,13 @@ public:
public:
DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
DsqlCompiledStatement* aStatement, DsqlCompilerScratch* aMainScratch = NULL)
DsqlStatement* aStatement = nullptr, DsqlCompilerScratch* aMainScratch = nullptr)
: BlrDebugWriter(p),
dbb(aDbb),
transaction(aTransaction),
statement(aStatement),
flags(0),
nestingLevel(0),
ports(p),
relation(NULL),
mainContext(p),
context(&mainContext),
@ -167,14 +167,14 @@ public:
transaction = value;
}
DsqlCompiledStatement* getStatement()
DsqlStatement* getStatement() const
{
return statement;
}
DsqlCompiledStatement* getStatement() const
void setStatement(DsqlStatement* aStatement)
{
return statement;
statement = aStatement;
}
void putBlrMarkers(ULONG marks);
@ -272,12 +272,11 @@ private:
dsql_dbb* dbb; // DSQL attachment
jrd_tra* transaction; // Transaction
DsqlCompiledStatement* statement; // Compiled statement
DsqlStatement* statement; // Compiled statement
public:
unsigned flags; // flags
unsigned nestingLevel; // begin...end nesting level
Firebird::Array<dsql_msg*> ports; // Port messages
dsql_rel* relation; // relation created by this request (for DDL)
DsqlContextStack mainContext;
DsqlContextStack* context;

View File

@ -33,7 +33,7 @@ using namespace Jrd;
static const char* const SCRATCH = "fb_cursor_";
static const ULONG PREFETCH_SIZE = 65536; // 64 KB
DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags)
DsqlCursor::DsqlCursor(DsqlDmlRequest* req, ULONG flags)
: m_request(req), m_message(req->getStatement()->getReceiveMsg()),
m_resultSet(NULL), m_flags(flags),
m_space(req->getPool(), SCRATCH),
@ -69,10 +69,10 @@ void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
if (!cursor)
return;
Jrd::Attachment* const attachment = cursor->getAttachment();
dsql_req* const request = cursor->m_request;
const auto attachment = cursor->getAttachment();
const auto request = cursor->m_request;
if (request->req_request)
if (request->getJrdRequest())
{
ThreadStatusGuard status_vector(tdbb);
try
@ -90,7 +90,7 @@ void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
}
JRD_unwind_request(tdbb, request->req_request);
JRD_unwind_request(tdbb, request->getJrdRequest());
}
catch (Firebird::Exception&)
{} // no-op

View File

@ -27,7 +27,7 @@
namespace Jrd {
class dsql_req;
class DsqlDmlRequest;
class JResultSet;
class DsqlCursor
@ -35,7 +35,7 @@ class DsqlCursor
enum State { BOS, POSITIONED, EOS };
public:
DsqlCursor(dsql_req* req, ULONG flags);
DsqlCursor(DsqlDmlRequest* req, ULONG flags);
~DsqlCursor();
jrd_tra* getTransaction() const;
@ -65,7 +65,7 @@ private:
int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position);
bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64);
dsql_req* const m_request;
DsqlDmlRequest* const m_request;
const dsql_msg* const m_message;
JResultSet* m_resultSet;
const ULONG m_flags;

1123
src/dsql/DsqlRequests.cpp Normal file

File diff suppressed because it is too large Load Diff

271
src/dsql/DsqlRequests.h Normal file
View File

@ -0,0 +1,271 @@
/*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 2022.02.07 Adriano dos Santos Fernandes: Refactored from dsql.h
*/
#ifndef DSQL_REQUESTS_H
#define DSQL_REQUESTS_H
#include "firebird/Interface.h"
#include "../common/StatusArg.h"
#include "../common/classes/alloc.h"
#include "../common/classes/array.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/NestConst.h"
#include "../common/classes/RefCounted.h"
#include "../jrd/jrd.h"
namespace Jrd {
class DdlNode;
class dsql_dbb;
class DsqlStatement;
class DsqlCompilerScratch;
class DsqlCursor;
class DsqlDmlStatement;
class dsql_par;
class jrd_req;
class jrd_tra;
class JrdStatement;
class SessionManagementNode;
class TransactionNode;
class DsqlRequest : public Firebird::PermanentStorage
{
public:
DsqlRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement);
virtual ~DsqlRequest();
public:
jrd_tra* getTransaction()
{
return req_transaction;
}
Firebird::RefPtr<DsqlStatement> getStatement()
{
return statement;
}
virtual JrdStatement* getJrdStatement() const
{
return nullptr;
}
virtual jrd_req* getJrdRequest() const
{
return nullptr;
}
virtual bool isDml() const
{
return false;
}
virtual DsqlCursor* openCursor(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMeta, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMeta, ULONG flags)
{
Firebird::Arg::Gds(isc_no_cursor).raise();
}
virtual DsqlBatch* openBatch(thread_db* tdbb, Firebird::IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par)
{
(Firebird::Arg::Gds(isc_sqlerr) <<
Firebird::Arg::Num(-504) <<
Firebird::Arg::Gds(isc_unprepared_stmt)
).raise();
}
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) = 0;
virtual void setCursor(thread_db* tdbb, const TEXT* name);
virtual bool fetch(thread_db* tdbb, UCHAR* buffer);
virtual void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata);
// Get session-level timeout, milliseconds
unsigned int getTimeout();
// Set session-level timeout, milliseconds
void setTimeout(unsigned int timeOut);
// Get actual timeout, milliseconds
unsigned int getActualTimeout();
// Evaluate actual timeout value, consider config- and session-level timeout values,
// setup and start timer
TimeoutTimer* setupTimer(thread_db* tdbb);
USHORT parseMetadata(Firebird::IMessageMetadata* meta, const Firebird::Array<dsql_par*>& parameters_list);
static void destroy(thread_db* tdbb, DsqlRequest* request);
public:
dsql_dbb* req_dbb; // DSQL attachment
Firebird::RefPtr<DsqlStatement> statement;
Firebird::Array<DsqlDmlStatement*> cursors{getPool()}; // Cursor update statements
jrd_tra* req_transaction = nullptr; // JRD transaction
Firebird::string req_cursor_name{getPool()}; // Cursor name, if any
DsqlCursor* req_cursor = nullptr; // Open cursor, if any
DsqlBatch* req_batch = nullptr; // Active batch, if any
Firebird::NonPooledMap<const dsql_par*, dsc> req_user_descs{getPool()}; // SQLDA data type
Firebird::AutoPtr<Jrd::RuntimeStatistics> req_fetch_baseline; // State of request performance counters when we reported it last time
SINT64 req_fetch_elapsed = 0; // Number of clock ticks spent while fetching rows for this request since we reported it last time
SINT64 req_fetch_rowcount = 0; // Total number of rows returned by this request
bool req_traced = false; // request is traced via TraceAPI
protected:
unsigned int req_timeout = 0; // query timeout in milliseconds, set by the user
Firebird::RefPtr<TimeoutTimer> req_timer; // timeout timer
};
class DsqlDmlRequest final : public DsqlRequest
{
public:
DsqlDmlRequest(thread_db* tdbb, MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement);
// Reintroduce method to fake covariant return type with RefPtr.
auto getStatement()
{
return Firebird::RefPtr<DsqlDmlStatement>((DsqlDmlStatement*) statement.getPtr());
}
JrdStatement* getJrdStatement() const override;
jrd_req* getJrdRequest() const override
{
return jrdRequest;
}
bool isDml() const override
{
return true;
}
DsqlCursor* openCursor(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMeta, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMeta, ULONG flags) override;
DsqlBatch* openBatch(thread_db* tdbb, Firebird::IMessageMetadata* inMetadata,
unsigned parLength, const UCHAR* par) override;
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
void setCursor(thread_db* tdbb, const TEXT* name) override;
bool fetch(thread_db* tdbb, UCHAR* buffer) override;
void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata) override;
void mapInOut(Jrd::thread_db* tdbb, bool toExternal, const dsql_msg* message, Firebird::IMessageMetadata* meta,
UCHAR* dsql_msg_buf, const UCHAR* in_dsql_msg_buf = nullptr);
private:
// True, if request could be restarted
bool needRestarts();
void doExecute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton);
// [Re]start part of "request restarts" algorithm
void executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton, bool exec, bool fetch);
public:
Firebird::Array<UCHAR*> req_msg_buffers;
private:
Firebird::RefPtr<Firebird::IMessageMetadata> delayedFormat;
jrd_req* jrdRequest = nullptr;
bool needDelayedFormat = false;
bool firstRowFetched = false;
};
class DsqlDdlRequest final : public DsqlRequest
{
public:
DsqlDdlRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlCompilerScratch* aInternalScratch, DdlNode* aNode);
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
private:
DsqlCompilerScratch* internalScratch;
NestConst<DdlNode> node;
};
class DsqlTransactionRequest final : public DsqlRequest
{
public:
DsqlTransactionRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement, TransactionNode* aNode);
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
private:
NestConst<TransactionNode> node;
};
class DsqlSessionManagementRequest final : public DsqlRequest
{
public:
DsqlSessionManagementRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement,
SessionManagementNode* aNode)
: DsqlRequest(pool, dbb, aStatement),
node(aNode)
{
}
void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) override;
private:
NestConst<SessionManagementNode> node;
};
} // namespace Jrd
#endif // DSQL_REQUESTS_H

298
src/dsql/DsqlStatements.cpp Normal file
View File

@ -0,0 +1,298 @@
/*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 2022.02.07 Adriano dos Santos Fernandes: Refactored from dsql.cpp
*/
#include "firebird.h"
#include "../dsql/DsqlStatements.h"
#include "../dsql/dsql.h"
#include "../dsql/Nodes.h"
#include "../dsql/DsqlCompilerScratch.h"
#include "../jrd/JrdStatement.h"
#include "../dsql/errd_proto.h"
#include "../dsql/gen_proto.h"
#include "../jrd/cmp_proto.h"
using namespace Firebird;
using namespace Jrd;
// Class DsqlStatement
// Rethrow an exception with isc_no_meta_update and prefix codes.
void DsqlStatement::rethrowDdlException(status_exception& ex, bool metadataUpdate, DdlNode* node)
{
Arg::StatusVector newVector;
if (metadataUpdate)
newVector << Arg::Gds(isc_no_meta_update);
node->putErrorPrefix(newVector);
const ISC_STATUS* status = ex.value();
if (status[1] == isc_no_meta_update)
status += 2;
newVector.append(Arg::StatusVector(status));
status_exception::raise(newVector);
}
int DsqlStatement::release()
{
fb_assert(refCounter.value() > 0);
const int refCnt = --refCounter;
if (!refCnt)
{
doRelease();
dsqlAttachment->deletePool(&getPool());
}
return refCnt;
}
void DsqlStatement::doRelease()
{
setSqlText(nullptr);
setOrgText(nullptr, 0);
}
void DsqlStatement::setOrgText(const char* ptr, ULONG len)
{
if (!ptr || !len)
{
orgText = NULL;
return;
}
const string text(ptr, len);
if (text == *sqlText)
orgText = sqlText;
else
orgText = FB_NEW_POOL(getPool()) RefString(getPool(), text);
}
// DsqlDmlStatement
void DsqlDmlStatement::doRelease()
{
if (auto parent = getParentRequest())
{
FB_SIZE_T pos;
if (parent->cursors.find(this, pos))
parent->cursors.remove(pos);
}
if (jrdStatement)
{
thread_db* tdbb = JRD_get_thread_data();
ThreadStatusGuard status_vector(tdbb);
try
{
jrdStatement->release(tdbb);
}
catch (Exception&)
{} // no-op
}
DsqlStatement::doRelease();
}
void DsqlDmlStatement::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, ntrace_result_t* traceResult)
{
{ // scope
ContextPoolHolder scratchContext(tdbb, &scratch->getPool());
node = Node::doDsqlPass(scratch, node);
}
if (scratch->clientDialect > SQL_DIALECT_V5)
scratch->getStatement()->setBlrVersion(5);
else
scratch->getStatement()->setBlrVersion(4);
GEN_statement(scratch, node);
unsigned messageNumber = 0;
for (auto message : ports)
message->msg_buffer_number = messageNumber++;
// have the access method compile the statement
#ifdef DSQL_DEBUG
if (DSQL_debug & 64)
{
dsql_trace("Resulting BLR code for DSQL:");
gds__trace_raw("Statement:\n");
gds__trace_raw(getSqlText()->c_str(), getSqlText()->length());
gds__trace_raw("\nBLR:\n");
fb_print_blr(scratch->getBlrData().begin(),
(ULONG) scratch->getBlrData().getCount(),
gds__trace_printer, 0, 0);
}
#endif
FbLocalStatus localStatus;
// check for warnings
if (tdbb->tdbb_status_vector->getState() & IStatus::STATE_WARNINGS)
{
// save a status vector
fb_utils::copyStatus(&localStatus, tdbb->tdbb_status_vector);
fb_utils::init_status(tdbb->tdbb_status_vector);
}
ISC_STATUS status = FB_SUCCESS;
try
{
const auto attachment = scratch->getAttachment()->dbb_attachment;
const auto& blr = scratch->getBlrData();
const auto& debugData = scratch->getDebugData();
jrdStatement = CMP_compile(tdbb, blr.begin(), blr.getCount(),
(scratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST),
debugData.getCount(), debugData.begin());
if (getSqlText())
jrdStatement->sqlText = getSqlText();
fb_assert(jrdStatement->blr.isEmpty());
if (attachment->getDebugOptions().getDsqlKeepBlr())
jrdStatement->blr.insert(0, blr.begin(), blr.getCount());
}
catch (const Exception&)
{
status = tdbb->tdbb_status_vector->getErrors()[1];
*traceResult = status == isc_no_priv ?
ITracePlugin::RESULT_UNAUTHORIZED : ITracePlugin::RESULT_FAILED;
}
// restore warnings (if there are any)
if (localStatus->getState() & IStatus::STATE_WARNINGS)
{
Arg::StatusVector cur(tdbb->tdbb_status_vector->getWarnings());
Arg::StatusVector saved(localStatus->getWarnings());
saved << cur;
tdbb->tdbb_status_vector->setWarnings2(saved.length(), saved.value());
}
// free blr memory
scratch->getBlrData().free();
if (status)
status_exception::raise(tdbb->tdbb_status_vector);
node = NULL;
}
DsqlDmlRequest* DsqlDmlStatement::createRequest(thread_db* tdbb, dsql_dbb* dbb)
{
return FB_NEW_POOL(getPool()) DsqlDmlRequest(tdbb, getPool(), dbb, this);
}
// DsqlDdlStatement
DsqlDdlStatement::~DsqlDdlStatement()
{
dsqlAttachment->deletePool(&scratch->getPool());
}
bool DsqlDdlStatement::mustBeReplicated() const
{
return node->mustBeReplicated();
}
void DsqlDdlStatement::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, ntrace_result_t* traceResult)
{
Database* const dbb = tdbb->getDatabase();
scratch->flags |= DsqlCompilerScratch::FLAG_DDL;
try
{
node = Node::doDsqlPass(scratch, node);
}
catch (status_exception& ex)
{
rethrowDdlException(ex, false, node);
}
if (dbb->readOnly())
ERRD_post(Arg::Gds(isc_read_only_database));
// In read-only replica, only replicator is allowed to execute DDL.
// As an exception, not replicated DDL statements are also allowed.
if (dbb->isReplica(REPLICA_READ_ONLY) &&
!(tdbb->tdbb_flags & TDBB_replicator) &&
node->mustBeReplicated())
{
ERRD_post(Arg::Gds(isc_read_only_trans));
}
const auto dbDialect = (dbb->dbb_flags & DBB_DB_SQL_dialect_3) ? SQL_DIALECT_V6 : SQL_DIALECT_V5;
if ((scratch->flags & DsqlCompilerScratch::FLAG_AMBIGUOUS_STMT) &&
dbDialect != scratch->clientDialect)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-817) <<
Arg::Gds(isc_ddl_not_allowed_by_db_sql_dial) << Arg::Num(dbDialect));
}
if (scratch->clientDialect > SQL_DIALECT_V5)
scratch->getStatement()->setBlrVersion(5);
else
scratch->getStatement()->setBlrVersion(4);
this->scratch = scratch;
}
DsqlDdlRequest* DsqlDdlStatement::createRequest(thread_db* tdbb, dsql_dbb* dbb)
{
return FB_NEW_POOL(getPool()) DsqlDdlRequest(getPool(), dbb, scratch, node);
}
// DsqlTransactionStatement
DsqlTransactionStatement::~DsqlTransactionStatement()
{
dsqlAttachment->deletePool(&scratch->getPool());
}
void DsqlTransactionStatement::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
ntrace_result_t* /*traceResult*/)
{
node = Node::doDsqlPass(scratch, node);
this->scratch = scratch;
}
DsqlTransactionRequest* DsqlTransactionStatement::createRequest(thread_db* tdbb, dsql_dbb* dbb)
{
return FB_NEW_POOL(getPool()) DsqlTransactionRequest(getPool(), dbb, this, node);
}

292
src/dsql/DsqlStatements.h Normal file
View File

@ -0,0 +1,292 @@
/*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 2022.02.07 Adriano dos Santos Fernandes: Refactored from dsql.h
*/
#ifndef DSQL_STATEMENTS_H
#define DSQL_STATEMENTS_H
#include "../common/classes/alloc.h"
#include "../common/classes/array.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/NestConst.h"
#include "../jrd/jrd.h"
#include "../jrd/ntrace.h"
#include "../dsql/DsqlRequests.h"
namespace Jrd {
class DdlNode;
class dsql_dbb;
class dsql_msg;
class dsql_par;
class DsqlRequest;
class DsqlCompilerScratch;
class JrdStatement;
class SessionManagementNode;
class TransactionNode;
// Compiled statement - shared by multiple requests.
class DsqlStatement : public Firebird::PermanentStorage
{
public:
enum Type // statement type
{
TYPE_SELECT, TYPE_SELECT_UPD, TYPE_INSERT, TYPE_DELETE, TYPE_UPDATE, TYPE_UPDATE_CURSOR,
TYPE_DELETE_CURSOR, TYPE_COMMIT, TYPE_ROLLBACK, TYPE_CREATE_DB, TYPE_DDL, TYPE_START_TRANS,
TYPE_EXEC_PROCEDURE, TYPE_COMMIT_RETAIN, TYPE_ROLLBACK_RETAIN, TYPE_SET_GENERATOR,
TYPE_SAVEPOINT, TYPE_EXEC_BLOCK, TYPE_SELECT_BLOCK, TYPE_SESSION_MANAGEMENT,
TYPE_RETURNING_CURSOR
};
// Statement flags.
static const unsigned FLAG_ORPHAN = 0x01;
static const unsigned FLAG_NO_BATCH = 0x02;
//static const unsigned FLAG_BLR_VERSION4 = 0x04;
//static const unsigned FLAG_BLR_VERSION5 = 0x08;
static const unsigned FLAG_SELECTABLE = 0x10;
static void rethrowDdlException(Firebird::status_exception& ex, bool metadataUpdate, DdlNode* node);
public:
DsqlStatement(MemoryPool& p, dsql_dbb* aDsqlAttachment)
: PermanentStorage(p),
dsqlAttachment(aDsqlAttachment),
type(TYPE_SELECT),
flags(0),
blrVersion(5),
ports(p)
{
}
protected:
virtual ~DsqlStatement() = default;
public:
int addRef()
{
return ++refCounter;
}
int release();
bool isCursorBased() const
{
switch (type)
{
case TYPE_SELECT:
case TYPE_SELECT_BLOCK:
case TYPE_SELECT_UPD:
case TYPE_RETURNING_CURSOR:
return true;
}
return false;
}
Type getType() const { return type; }
void setType(Type value) { type = value; }
ULONG getFlags() const { return flags; }
void setFlags(ULONG value) { flags = value; }
void addFlags(ULONG value) { flags |= value; }
unsigned getBlrVersion() const { return blrVersion; }
void setBlrVersion(unsigned value) { blrVersion = value; }
Firebird::RefStrPtr& getSqlText() { return sqlText; }
const Firebird::RefStrPtr& getSqlText() const { return sqlText; }
void setSqlText(Firebird::RefString* value) { sqlText = value; }
void setOrgText(const char* ptr, ULONG len);
const Firebird::string& getOrgText() const { return *orgText; }
Firebird::Array<dsql_msg*>& getPorts() { return ports; }
dsql_msg* getSendMsg() { return sendMsg; }
const dsql_msg* getSendMsg() const { return sendMsg; }
void setSendMsg(dsql_msg* value) { sendMsg = value; }
dsql_msg* getReceiveMsg() { return receiveMsg; }
const dsql_msg* getReceiveMsg() const { return receiveMsg; }
void setReceiveMsg(dsql_msg* value) { receiveMsg = value; }
dsql_par* getEof() { return eof; }
const dsql_par* getEof() const { return eof; }
void setEof(dsql_par* value) { eof = value; }
public:
virtual JrdStatement* getJrdStatement() const
{
return nullptr;
}
virtual bool mustBeReplicated() const
{
return false;
}
virtual bool shouldPreserveScratch() const
{
return true;
}
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, ntrace_result_t* traceResult) = 0;
virtual DsqlRequest* createRequest(thread_db* tdbb, dsql_dbb* dbb) = 0;
protected:
virtual void doRelease();
protected:
dsql_dbb* dsqlAttachment;
Type type; // Type of statement
ULONG flags; // generic flag
unsigned blrVersion;
Firebird::RefStrPtr sqlText;
Firebird::RefStrPtr orgText;
Firebird::Array<dsql_msg*> ports; // Port messages
dsql_msg* sendMsg = nullptr; // Message to be sent to start request
dsql_msg* receiveMsg = nullptr; // Per record message to be received
dsql_par* eof = nullptr; // End of file parameter
private:
Firebird::AtomicCounter refCounter;
};
class DsqlDmlStatement final : public DsqlStatement
{
public:
DsqlDmlStatement(MemoryPool& p, dsql_dbb* aDsqlAttachment, StmtNode* aNode)
: DsqlStatement(p, aDsqlAttachment),
node(aNode)
{
}
public:
JrdStatement* getJrdStatement() const override
{
return jrdStatement;
}
void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, ntrace_result_t* traceResult) override;
DsqlDmlRequest* createRequest(thread_db* tdbb, dsql_dbb* dbb) override;
dsql_par* getDbKey() { return dbKey; }
const dsql_par* getDbKey() const { return dbKey; }
void setDbKey(dsql_par* value) { dbKey = value; }
dsql_par* getRecVersion() { return recVersion; }
const dsql_par* getRecVersion() const { return recVersion; }
void setRecVersion(dsql_par* value) { recVersion = value; }
dsql_par* getParentRecVersion() { return parentRecVersion; }
const dsql_par* getParentRecVersion() const { return parentRecVersion; }
void setParentRecVersion(dsql_par* value) { parentRecVersion = value; }
dsql_par* getParentDbKey() { return parentDbKey; }
const dsql_par* getParentDbKey() const { return parentDbKey; }
void setParentDbKey(dsql_par* value) { parentDbKey = value; }
DsqlDmlRequest* getParentRequest() const { return parentRequest; }
void setParentRequest(DsqlDmlRequest* value) { parentRequest = value; }
protected:
void doRelease() override;
private:
NestConst<StmtNode> node;
JrdStatement* jrdStatement = nullptr;
dsql_par* dbKey = nullptr; // Database key for current of
dsql_par* recVersion = nullptr; // Record Version for current of
dsql_par* parentRecVersion = nullptr; // parent record version
dsql_par* parentDbKey = nullptr; // Parent database key for current of
DsqlDmlRequest* parentRequest = nullptr; // Source request, if cursor update
};
class DsqlDdlStatement final : public DsqlStatement
{
public:
DsqlDdlStatement(MemoryPool& p, dsql_dbb* aDsqlAttachment, DdlNode* aNode)
: DsqlStatement(p, aDsqlAttachment),
node(aNode)
{
}
~DsqlDdlStatement();
public:
bool mustBeReplicated() const override;
void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, ntrace_result_t* traceResult) override;
DsqlDdlRequest* createRequest(thread_db* tdbb, dsql_dbb* dbb) override;
private:
NestConst<DdlNode> node;
DsqlCompilerScratch* scratch = nullptr;
};
class DsqlTransactionStatement final : public DsqlStatement
{
public:
DsqlTransactionStatement(MemoryPool& p, dsql_dbb* aDsqlAttachment, TransactionNode* aNode)
: DsqlStatement(p, aDsqlAttachment),
node(aNode)
{
}
~DsqlTransactionStatement();
public:
void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, ntrace_result_t* traceResult) override;
DsqlTransactionRequest* createRequest(thread_db* tdbb, dsql_dbb* dbb) override;
private:
NestConst<TransactionNode> node;
DsqlCompilerScratch* scratch = nullptr;
};
class DsqlSessionManagementStatement final : public DsqlStatement
{
public:
DsqlSessionManagementStatement(MemoryPool& p, dsql_dbb* aDsqlAttachment, SessionManagementNode* aNode)
: DsqlStatement(p, aDsqlAttachment),
node(aNode)
{
}
~DsqlSessionManagementStatement();
public:
void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, ntrace_result_t* traceResult) override;
DsqlSessionManagementRequest* createRequest(thread_db* tdbb, dsql_dbb* dbb) override;
private:
NestConst<SessionManagementNode> node;
DsqlCompilerScratch* scratch = nullptr;
};
} // namespace Jrd
#endif // DSQL_STATEMENTS_H

View File

@ -213,7 +213,7 @@ public:
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_DDL);
return this;
}
@ -283,7 +283,7 @@ public:
return this;
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const = 0;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const = 0;
};
@ -300,12 +300,12 @@ public:
{
Node::dsqlPass(dsqlScratch);
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_SESSION_MANAGEMENT);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_SESSION_MANAGEMENT);
return this;
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const = 0;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const = 0;
};

View File

@ -221,21 +221,14 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
// items
for (unsigned i = 0; i < items->getCount(); ++i)
{
DsqlCompiledStatement* itemStatement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool);
DsqlCompilerScratch* itemScratch = (*items)[i].dsqlScratch =
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement);
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name;
DdlNode* ddlNode;
switch ((*items)[i].type)
{
case CreateAlterPackageNode::Item::FUNCTION:
{
CreateAlterFunctionNode* const fun = (*items)[i].function;
ddlNode = fun;
if (functionNames.exist(fun->name))
{
@ -249,13 +242,13 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
fun->alter = true;
fun->package = name;
fun->dsqlPass(itemScratch);
break;
}
case CreateAlterPackageNode::Item::PROCEDURE:
{
CreateAlterProcedureNode* const proc = (*items)[i].procedure;
ddlNode = proc;
if (procedureNames.exist(proc->name))
{
@ -269,10 +262,24 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
proc->alter = true;
proc->package = name;
proc->dsqlPass(itemScratch);
break;
}
default:
fb_assert(false);
}
auto itemStatement = FB_NEW_POOL(pool) DsqlDdlStatement(pool, dsqlScratch->getAttachment(), ddlNode);
auto itemScratch = (*items)[i].dsqlScratch =
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement);
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name;
ddlNode->dsqlPass(itemScratch);
}
return DdlNode::dsqlPass(dsqlScratch);
@ -616,21 +623,14 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
for (unsigned j = 0; j < arrays[i]->getCount(); ++j)
{
DsqlCompiledStatement* itemStatement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool);
DsqlCompilerScratch* itemScratch = (*arrays[i])[j].dsqlScratch =
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement);
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name;
DdlNode* ddlNode;
switch ((*arrays[i])[j].type)
{
case CreateAlterPackageNode::Item::FUNCTION:
{
CreateAlterFunctionNode* const fun = (*arrays[i])[j].function;
ddlNode = fun;
if (functionNames[i].exist(fun->name))
{
@ -648,14 +648,13 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
if (arrays[i] == items)
fun->alter = true;
fun->dsqlPass(itemScratch);
break;
}
case CreateAlterPackageNode::Item::PROCEDURE:
{
CreateAlterProcedureNode* const proc = (*arrays[i])[j].procedure;
ddlNode = proc;
if (procedureNames[i].exist(proc->name))
{
@ -673,11 +672,24 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
if (arrays[i] == items)
proc->alter = true;
proc->dsqlPass(itemScratch);
break;
}
default:
fb_assert(false);
}
auto itemStatement = FB_NEW_POOL(pool) DsqlDdlStatement(pool, dsqlScratch->getAttachment(), ddlNode);
auto itemScratch = (*arrays[i])[j].dsqlScratch =
FB_NEW_POOL(pool) DsqlCompilerScratch(pool, dsqlScratch->getAttachment(),
dsqlScratch->getTransaction(), itemStatement);
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->package = name;
ddlNode->dsqlPass(itemScratch);
}
}

View File

@ -98,10 +98,10 @@ namespace
}
Parser::Parser(thread_db* tdbb, MemoryPool& pool, DsqlCompilerScratch* aScratch,
USHORT aClientDialect, USHORT aDbDialect, const TEXT* string, size_t length,
SSHORT characterSet)
Parser::Parser(thread_db* tdbb, MemoryPool& pool, MemoryPool* aStatementPool, DsqlCompilerScratch* aScratch,
USHORT aClientDialect, USHORT aDbDialect, const TEXT* string, size_t length, SSHORT characterSet)
: PermanentStorage(pool),
statementPool(aStatementPool),
scratch(aScratch),
client_dialect(aClientDialect),
db_dialect(aDbDialect),
@ -172,7 +172,7 @@ Parser::~Parser()
}
dsql_req* Parser::parse()
DsqlStatement* Parser::parse()
{
if (parseAux() != 0)
{
@ -182,7 +182,7 @@ dsql_req* Parser::parse()
transformString(lex.start, lex.end - lex.start, transformedString);
return DSQL_parse;
return parsedStatement;
}

View File

@ -130,13 +130,12 @@ public:
static const int MAX_TOKEN_LEN = 256;
public:
Parser(thread_db* tdbb, MemoryPool& pool, DsqlCompilerScratch* aScratch, USHORT aClientDialect,
USHORT aDbDialect, const TEXT* string, size_t length,
SSHORT characterSet);
Parser(thread_db* tdbb, MemoryPool& pool, MemoryPool* aStatementPool, DsqlCompilerScratch* aScratch,
USHORT aClientDialect, USHORT aDbDialect, const TEXT* string, size_t length, SSHORT characterSet);
~Parser();
public:
dsql_req* parse();
DsqlStatement* parse();
const Firebird::string& getTransformedString() const
{
@ -233,11 +232,6 @@ private:
return cmpNode;
}
MemoryPool& getStatementPool()
{
return scratch->getStatement()->getPool();
}
void yyReducePosn(YYPOSN& ret, YYPOSN* termPosns, YYSTYPE* termVals,
int termNo, int stkPos, int yychar, YYPOSN& yyposn, void*);
@ -376,6 +370,7 @@ private:
// end - defined in btyacc_fb.ske
private:
MemoryPool* statementPool;
DsqlCompilerScratch* scratch;
USHORT client_dialect;
USHORT db_dialect;
@ -385,7 +380,7 @@ private:
Firebird::string transformedString;
Firebird::GenericMap<Firebird::NonPooled<IntlString*, StrMark> > strMarks;
bool stmt_ambiguous;
dsql_req* DSQL_parse;
DsqlStatement* parsedStatement;
// These value/posn are taken from the lexer
YYSTYPE yylval;

View File

@ -72,8 +72,8 @@ namespace Jrd {
template <typename T> static void dsqlExplodeFields(dsql_rel* relation, Array<NestConst<T> >& fields,
bool includeComputed);
static dsql_par* dsqlFindDbKey(const dsql_req*, const RelationSourceNode*);
static dsql_par* dsqlFindRecordVersion(const dsql_req*, const RelationSourceNode*);
static dsql_par* dsqlFindDbKey(const DsqlDmlStatement*, const RelationSourceNode*);
static dsql_par* dsqlFindRecordVersion(const DsqlDmlStatement*, const RelationSourceNode*);
static void dsqlGenEofAssignment(DsqlCompilerScratch* dsqlScratch, SSHORT value);
static void dsqlGenReturning(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
Nullable<USHORT> localTableNumber);
@ -1697,7 +1697,7 @@ DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
if (prevDecl)
dsqlScratch->putSubFunction(this, true);
DsqlCompiledStatement* statement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool);
auto statement = FB_NEW_POOL(pool) DsqlDmlStatement(pool, dsqlScratch->getAttachment(), dsqlBlock);
if (dsqlScratch->clientDialect > SQL_DIALECT_V5)
statement->setBlrVersion(5);
@ -1709,7 +1709,7 @@ DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
statement->setReceiveMsg(message);
message->msg_number = 1;
statement->setType(DsqlCompiledStatement::TYPE_SELECT);
statement->setType(DsqlStatement::TYPE_SELECT);
blockScratch = FB_NEW_POOL(pool) DsqlCompilerScratch(pool,
dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), statement, dsqlScratch);
@ -1729,7 +1729,7 @@ void DeclareSubFuncNode::genBlr(DsqlCompilerScratch* dsqlScratch)
if (!dsqlBlock) // forward decl
return;
GEN_request(blockScratch, dsqlBlock);
GEN_statement(blockScratch, dsqlBlock);
dsqlScratch->appendUChar(blr_subfunc_decl);
dsqlScratch->appendNullString(name.c_str());
@ -2036,7 +2036,7 @@ DeclareSubProcNode* DeclareSubProcNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
if (prevDecl)
dsqlScratch->putSubProcedure(this, true);
DsqlCompiledStatement* statement = FB_NEW_POOL(pool) DsqlCompiledStatement(pool);
auto statement = FB_NEW_POOL(pool) DsqlDmlStatement(pool, dsqlScratch->getAttachment(), dsqlBlock);
if (dsqlScratch->clientDialect > SQL_DIALECT_V5)
statement->setBlrVersion(5);
@ -2048,7 +2048,7 @@ DeclareSubProcNode* DeclareSubProcNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
statement->setReceiveMsg(message);
message->msg_number = 1;
statement->setType(DsqlCompiledStatement::TYPE_SELECT);
statement->setType(DsqlStatement::TYPE_SELECT);
blockScratch = FB_NEW_POOL(pool) DsqlCompilerScratch(pool,
dsqlScratch->getAttachment(), dsqlScratch->getTransaction(), statement, dsqlScratch);
@ -2068,7 +2068,7 @@ void DeclareSubProcNode::genBlr(DsqlCompilerScratch* dsqlScratch)
if (!dsqlBlock) // forward decl
return;
GEN_request(blockScratch, dsqlBlock);
GEN_statement(blockScratch, dsqlBlock);
dsqlScratch->appendUChar(blr_subproc_decl);
dsqlScratch->appendNullString(name.c_str());
@ -2076,7 +2076,7 @@ void DeclareSubProcNode::genBlr(DsqlCompilerScratch* dsqlScratch)
dsqlScratch->appendUChar(SUB_ROUTINE_TYPE_PSQL);
dsqlScratch->appendUChar(
blockScratch->getStatement()->getFlags() & DsqlCompiledStatement::FLAG_SELECTABLE ? 1 : 0);
blockScratch->getStatement()->getFlags() & DsqlStatement::FLAG_SELECTABLE ? 1 : 0);
genParameters(dsqlScratch, dsqlBlock->parameters);
genParameters(dsqlScratch, dsqlBlock->returns);
@ -2291,7 +2291,7 @@ StmtNode* EraseNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
}
dsqlScratch->getStatement()->setType(dsqlCursorName.hasData() ?
DsqlCompiledStatement::TYPE_DELETE_CURSOR : DsqlCompiledStatement::TYPE_DELETE);
DsqlStatement::TYPE_DELETE_CURSOR : DsqlStatement::TYPE_DELETE);
// Generate record selection expression.
@ -2990,7 +2990,7 @@ ExecProcedureNode* ExecProcedureNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
}
if (!dsqlScratch->isPsql())
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_EXEC_PROCEDURE);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_EXEC_PROCEDURE);
ExecProcedureNode* node = FB_NEW_POOL(dsqlScratch->getPool()) ExecProcedureNode(dsqlScratch->getPool(), dsqlName);
node->dsqlProcedure = procedure;
@ -3112,7 +3112,7 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
{
const dsql_msg* message = NULL;
if (dsqlScratch->getStatement()->getType() == DsqlCompiledStatement::TYPE_EXEC_PROCEDURE)
if (dsqlScratch->getStatement()->getType() == DsqlStatement::TYPE_EXEC_PROCEDURE)
{
if ((message = dsqlScratch->getStatement()->getReceiveMsg()))
{
@ -4267,12 +4267,12 @@ const StmtNode* InitVariableNode::execute(thread_db* tdbb, jrd_req* request, Exe
ExecBlockNode* ExecBlockNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
DsqlCompiledStatement* const statement = dsqlScratch->getStatement();
DsqlStatement* const statement = dsqlScratch->getStatement();
if (returns.hasData())
statement->setType(DsqlCompiledStatement::TYPE_SELECT_BLOCK);
statement->setType(DsqlStatement::TYPE_SELECT_BLOCK);
else
statement->setType(DsqlCompiledStatement::TYPE_EXEC_BLOCK);
statement->setType(DsqlStatement::TYPE_EXEC_BLOCK);
dsqlScratch->flags |= DsqlCompilerScratch::FLAG_BLOCK;
@ -4404,7 +4404,7 @@ void ExecBlockNode::genBlr(DsqlCompilerScratch* dsqlScratch)
}
}
DsqlCompiledStatement* const statement = dsqlScratch->getStatement();
DsqlStatement* const statement = dsqlScratch->getStatement();
dsqlScratch->appendUChar(blr_begin);
@ -4503,9 +4503,9 @@ void ExecBlockNode::genBlr(DsqlCompilerScratch* dsqlScratch)
stmtNode->genBlr(dsqlScratch);
if (returns.hasData())
statement->setType(DsqlCompiledStatement::TYPE_SELECT_BLOCK);
statement->setType(DsqlStatement::TYPE_SELECT_BLOCK);
else
statement->setType(DsqlCompiledStatement::TYPE_EXEC_BLOCK);
statement->setType(DsqlStatement::TYPE_EXEC_BLOCK);
dsqlScratch->appendUChar(blr_end);
dsqlScratch->genReturn(true);
@ -5969,8 +5969,8 @@ StmtNode* MergeNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
// Describe it as TYPE_RETURNING_CURSOR if RETURNING is present or as INSERT otherwise.
dsqlScratch->getStatement()->setType(returning ?
DsqlCompiledStatement::TYPE_RETURNING_CURSOR :
DsqlCompiledStatement::TYPE_INSERT);
DsqlStatement::TYPE_RETURNING_CURSOR :
DsqlStatement::TYPE_INSERT);
}
// Setup the main node.
@ -6530,7 +6530,7 @@ StmtNode* ModifyNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool up
}
dsqlScratch->getStatement()->setType(dsqlCursorName.hasData() ?
DsqlCompiledStatement::TYPE_UPDATE_CURSOR : DsqlCompiledStatement::TYPE_UPDATE);
DsqlStatement::TYPE_UPDATE_CURSOR : DsqlStatement::TYPE_UPDATE);
doDsqlPass(dsqlScratch, node->dsqlRelation, relation, false);
dsql_ctx* mod_context = dsqlGetContext(node->dsqlRelation);
@ -7461,7 +7461,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch,
{
DsqlContextStack::AutoRestore autoContext(*dsqlScratch->context);
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_INSERT);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_INSERT);
const auto node = FB_NEW_POOL(dsqlScratch->getPool()) StoreNode(dsqlScratch->getPool());
node->overrideClause = overrideClause;
@ -8164,8 +8164,8 @@ SelectNode* SelectNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
if (dsqlForUpdate)
{
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_SELECT_UPD);
dsqlScratch->getStatement()->addFlags(DsqlCompiledStatement::FLAG_NO_BATCH);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_SELECT_UPD);
dsqlScratch->getStatement()->addFlags(DsqlStatement::FLAG_NO_BATCH);
}
else
{
@ -8178,7 +8178,7 @@ SelectNode* SelectNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
if (rseNode->dsqlOrder || rseNode->dsqlDistinct)
{
dsqlScratch->getStatement()->setFlags(
dsqlScratch->getStatement()->getFlags() & ~DsqlCompiledStatement::FLAG_NO_BATCH);
dsqlScratch->getStatement()->getFlags() & ~DsqlStatement::FLAG_NO_BATCH);
}
}
@ -8204,7 +8204,7 @@ void SelectNode::genBlr(DsqlCompilerScratch* dsqlScratch)
RseNode* const rse = nodeAs<RseNode>(dsqlRse);
fb_assert(rse);
DsqlCompiledStatement* const statement = dsqlScratch->getStatement();
DsqlStatement* const statement = dsqlScratch->getStatement();
// Set up parameter for things in the select list.
ValueListNode* list = rse->dsqlSelectList;
@ -8532,7 +8532,7 @@ DmlNode* SuspendNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch*
SuspendNode* SuspendNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
DsqlCompiledStatement* const statement = dsqlScratch->getStatement();
DsqlStatement* const statement = dsqlScratch->getStatement();
if (dsqlScratch->flags & (DsqlCompilerScratch::FLAG_TRIGGER | DsqlCompilerScratch::FLAG_FUNCTION))
{
@ -8554,7 +8554,7 @@ SuspendNode* SuspendNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
Arg::Gds(isc_dsql_unsupported_in_auto_trans) << Arg::Str("SUSPEND"));
}
statement->addFlags(DsqlCompiledStatement::FLAG_SELECTABLE);
statement->addFlags(DsqlStatement::FLAG_SELECTABLE);
return this;
}
@ -8790,7 +8790,7 @@ const StmtNode* SavepointEncloseNode::execute(thread_db* tdbb, jrd_req* request,
SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_START_TRANS);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_START_TRANS);
// Generate tpb for set transaction. Use blr string of dsqlScratch.
// If a value is not specified, default is not stuffed, let the engine handle it.
@ -8869,7 +8869,7 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
return this;
}
void SetTransactionNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const
void SetTransactionNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const
{
JRD_start_transaction(tdbb, &request->req_transaction, request->req_dbb->dbb_attachment,
tpb.getCount(), tpb.begin());
@ -8906,7 +8906,7 @@ void SetTransactionNode::genTableLock(DsqlCompilerScratch* dsqlScratch,
//--------------------
void SessionResetNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const
void SessionResetNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const
{
SET_TDBB(tdbb);
Attachment* const attachment = tdbb->getAttachment();
@ -8917,7 +8917,7 @@ void SessionResetNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** tra
//--------------------
void SetRoleNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** /*traHandle*/) const
void SetRoleNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** /*traHandle*/) const
{
SET_TDBB(tdbb);
Attachment* const attachment = tdbb->getAttachment();
@ -8948,7 +8948,7 @@ SetDebugOptionNode::SetDebugOptionNode(MemoryPool& pool, MetaName* aName, ExprNo
{
}
void SetDebugOptionNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
void SetDebugOptionNode::execute(thread_db* tdbb, DsqlRequest* /*request*/, jrd_tra** /*traHandle*/) const
{
SET_TDBB(tdbb);
auto& debugOptions = tdbb->getAttachment()->getDebugOptions();
@ -8984,7 +8984,7 @@ SetDecFloatRoundNode::SetDecFloatRoundNode(MemoryPool& pool, MetaName* name)
rndMode = mode->val;
}
void SetDecFloatRoundNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
void SetDecFloatRoundNode::execute(thread_db* tdbb, DsqlRequest* /*request*/, jrd_tra** /*traHandle*/) const
{
SET_TDBB(tdbb);
Attachment* const attachment = tdbb->getAttachment();
@ -9004,7 +9004,7 @@ void SetDecFloatTrapsNode::trap(MetaName* name)
traps |= trap->val;
}
void SetDecFloatTrapsNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
void SetDecFloatTrapsNode::execute(thread_db* tdbb, DsqlRequest* /*request*/, jrd_tra** /*traHandle*/) const
{
SET_TDBB(tdbb);
Attachment* const attachment = tdbb->getAttachment();
@ -9027,7 +9027,7 @@ SessionManagementNode* SetBindNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
}
void SetBindNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
void SetBindNode::execute(thread_db* tdbb, DsqlRequest* /*request*/, jrd_tra** /*traHandle*/) const
{
SET_TDBB(tdbb);
@ -9091,7 +9091,7 @@ string SetSessionNode::internalPrint(NodePrinter& printer) const
return "SetSessionNode";
}
void SetSessionNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** /*traHandle*/) const
void SetSessionNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** /*traHandle*/) const
{
Attachment* att = tdbb->getAttachment();
@ -9111,7 +9111,7 @@ void SetSessionNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** /*tra
//--------------------
void SetTimeZoneNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** /*traHandle*/) const
void SetTimeZoneNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** /*traHandle*/) const
{
Attachment* const attachment = tdbb->getAttachment();
@ -9363,9 +9363,9 @@ StmtNode* UpdateOrInsertNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
node->modifyNode = nodeAs<ModifyNode>(node->modifyNode->internalDsqlPass(dsqlScratch, true));
fb_assert(node->modifyNode);
// If RETURNING is present, type is already DsqlCompiledStatement::TYPE_EXEC_PROCEDURE.
// If RETURNING is present, type is already DsqlStatement::TYPE_EXEC_PROCEDURE.
if (!returning)
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_INSERT);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_INSERT);
return SavepointEncloseNode::make(dsqlScratch->getPool(), dsqlScratch, node);
}
@ -9439,19 +9439,19 @@ CommitRollbackNode* CommitRollbackNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
{
case CMD_COMMIT:
dsqlScratch->getStatement()->setType(retain ?
DsqlCompiledStatement::TYPE_COMMIT_RETAIN : DsqlCompiledStatement::TYPE_COMMIT);
DsqlStatement::TYPE_COMMIT_RETAIN : DsqlStatement::TYPE_COMMIT);
break;
case CMD_ROLLBACK:
dsqlScratch->getStatement()->setType(retain ?
DsqlCompiledStatement::TYPE_ROLLBACK_RETAIN : DsqlCompiledStatement::TYPE_ROLLBACK);
DsqlStatement::TYPE_ROLLBACK_RETAIN : DsqlStatement::TYPE_ROLLBACK);
break;
}
return this;
}
void CommitRollbackNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const
void CommitRollbackNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const
{
if (retain)
{
@ -9499,11 +9499,11 @@ Firebird::string UserSavepointNode::internalPrint(NodePrinter& printer) const
UserSavepointNode* UserSavepointNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_SAVEPOINT);
dsqlScratch->getStatement()->setType(DsqlStatement::TYPE_SAVEPOINT);
return this;
}
void UserSavepointNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** /*transaction*/) const
void UserSavepointNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** /*transaction*/) const
{
jrd_tra* const transaction = request->req_transaction;
fb_assert(!(transaction->tra_flags & TRA_system));
@ -9610,12 +9610,11 @@ static void dsqlExplodeFields(dsql_rel* relation, Array<NestConst<T> >& fields,
}
// Find dbkey for named relation in statement's saved dbkeys.
static dsql_par* dsqlFindDbKey(const dsql_req* request, const RelationSourceNode* relation_name)
static dsql_par* dsqlFindDbKey(const DsqlDmlStatement* statement, const RelationSourceNode* relation_name)
{
DEV_BLKCHK(request, dsql_type_req);
DEV_BLKCHK(relation_name, dsql_type_nod);
const dsql_msg* message = request->getStatement()->getReceiveMsg();
const dsql_msg* message = statement->getReceiveMsg();
dsql_par* candidate = NULL;
const MetaName& relName = relation_name->dsqlName;
@ -9636,11 +9635,9 @@ static dsql_par* dsqlFindDbKey(const dsql_req* request, const RelationSourceNode
}
// Find record version for relation in statement's saved record version.
static dsql_par* dsqlFindRecordVersion(const dsql_req* request, const RelationSourceNode* relation_name)
static dsql_par* dsqlFindRecordVersion(const DsqlDmlStatement* statement, const RelationSourceNode* relation_name)
{
DEV_BLKCHK(request, dsql_type_req);
const dsql_msg* message = request->getStatement()->getReceiveMsg();
const dsql_msg* message = statement->getReceiveMsg();
dsql_par* candidate = NULL;
const MetaName& relName = relation_name->dsqlName;
@ -9993,7 +9990,7 @@ static RseNode* dsqlPassCursorReference(DsqlCompilerScratch* dsqlScratch, const
// Lookup parent dsqlScratch
dsql_req* const* const symbol = dsqlScratch->getAttachment()->dbb_cursors.get(cursor.c_str());
const auto* const symbol = dsqlScratch->getAttachment()->dbb_cursors.get(cursor.c_str());
if (!symbol)
{
@ -10003,12 +10000,12 @@ static RseNode* dsqlPassCursorReference(DsqlCompilerScratch* dsqlScratch, const
Arg::Gds(isc_dsql_cursor_not_found) << cursor);
}
dsql_req* parent = *symbol;
auto parent = *symbol;
// Verify that the cursor is appropriate and updatable
dsql_par* source = dsqlFindDbKey(parent, relation_name);
dsql_par* rv_source = dsqlFindRecordVersion(parent, relation_name);
dsql_par* source = dsqlFindDbKey(parent->getStatement(), relation_name);
dsql_par* rv_source = dsqlFindRecordVersion(parent->getStatement(), relation_name);
if (!source || !rv_source)
{
@ -10017,7 +10014,7 @@ static RseNode* dsqlPassCursorReference(DsqlCompilerScratch* dsqlScratch, const
Arg::Gds(isc_dsql_cursor_update_err) << cursor);
}
DsqlCompiledStatement* const statement = dsqlScratch->getStatement();
const auto statement = static_cast<DsqlDmlStatement*>(dsqlScratch->getStatement());
statement->setParentRequest(parent);
statement->setParentDbKey(source);
@ -10293,7 +10290,7 @@ static ReturningClause* dsqlProcessReturning(DsqlCompilerScratch* dsqlScratch, d
if (!dsqlScratch->isPsql())
{
dsqlScratch->getStatement()->setType(singleton ?
DsqlCompiledStatement::TYPE_EXEC_PROCEDURE : DsqlCompiledStatement::TYPE_RETURNING_CURSOR);
DsqlStatement::TYPE_EXEC_PROCEDURE : DsqlStatement::TYPE_RETURNING_CURSOR);
}
return node;

View File

@ -1473,7 +1473,7 @@ public:
// Save and reset the statement type, as SessionManagementNode sets it to TYPE_SESSION_MANAGEMENT but
// we are a DML statement.
DsqlCompiledStatement::Type statementType = dsqlScratch->getStatement()->getType();
DsqlStatement::Type statementType = dsqlScratch->getStatement()->getType();
wrapped->dsqlPass(dsqlScratch);
dsqlScratch->getStatement()->setType(statementType);
@ -1566,7 +1566,7 @@ public:
}
virtual SetTransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const;
private:
void genTableLock(DsqlCompilerScratch* dsqlScratch, const RestrictionOption& tblLock,
@ -1607,7 +1607,7 @@ public:
public:
virtual Firebird::string internalPrint(NodePrinter& printer) const;
virtual CommitRollbackNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const;
private:
const Command command;
@ -1637,7 +1637,7 @@ public:
public:
virtual Firebird::string internalPrint(NodePrinter& printer) const;
virtual UserSavepointNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const;
public:
const Command command;
@ -1661,7 +1661,7 @@ public:
return "SessionResetNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
};
@ -1693,7 +1693,7 @@ public:
return "SetRoleNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
public:
bool trusted;
@ -1714,7 +1714,7 @@ public:
public:
virtual Firebird::string internalPrint(NodePrinter& printer) const;
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
private:
Type m_type;
@ -1738,7 +1738,7 @@ public:
return "SetDebugOptionNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
private:
MetaName name;
@ -1761,7 +1761,7 @@ public:
return "SetDecFloatRoundNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
public:
USHORT rndMode;
@ -1787,7 +1787,7 @@ public:
return "SetDecFloatTrapsNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
void trap(MetaName* name);
@ -1818,7 +1818,7 @@ public:
}
virtual SessionManagementNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
public:
dsql_fld* from;
@ -1854,7 +1854,7 @@ public:
return "SetTimeZoneNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
public:
Firebird::string str;

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@
#define DSQL_DSQL_H
#include "../common/classes/array.h"
#include "../common/classes/fb_atomic.h"
#include "../common/classes/GenericMap.h"
#include "../jrd/MetaName.h"
#include "../common/classes/stack.h"
@ -76,6 +77,7 @@ namespace Jrd
class Attachment;
class Database;
class DsqlCompilerScratch;
class DsqlDmlStatement;
class DdlNode;
class RseNode;
class StmtNode;
@ -134,7 +136,7 @@ public:
Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<
SSHORT, dsql_intlsym*> > > dbb_charsets_by_id; // charsets sorted by charset_id
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::string, class dsql_req*> > > dbb_cursors; // known cursors in database
Firebird::string, DsqlDmlRequest*>>> dbb_cursors; // known cursors in database
MemoryPool& dbb_pool; // The current pool for the dbb
Attachment* dbb_attachment;
@ -451,321 +453,6 @@ enum intlsym_flags_vals {
INTLSYM_dropped = 1 // intlsym has been dropped
};
// Compiled statement - shared by multiple requests.
class DsqlCompiledStatement : public Firebird::PermanentStorage
{
public:
enum Type // statement type
{
TYPE_SELECT, TYPE_SELECT_UPD, TYPE_INSERT, TYPE_DELETE, TYPE_UPDATE, TYPE_UPDATE_CURSOR,
TYPE_DELETE_CURSOR, TYPE_COMMIT, TYPE_ROLLBACK, TYPE_CREATE_DB, TYPE_DDL, TYPE_START_TRANS,
TYPE_EXEC_PROCEDURE, TYPE_COMMIT_RETAIN, TYPE_ROLLBACK_RETAIN, TYPE_SET_GENERATOR,
TYPE_SAVEPOINT, TYPE_EXEC_BLOCK, TYPE_SELECT_BLOCK, TYPE_SESSION_MANAGEMENT,
TYPE_RETURNING_CURSOR
};
// Statement flags.
static const unsigned FLAG_ORPHAN = 0x01;
static const unsigned FLAG_NO_BATCH = 0x02;
//static const unsigned FLAG_BLR_VERSION4 = 0x04;
//static const unsigned FLAG_BLR_VERSION5 = 0x08;
static const unsigned FLAG_SELECTABLE = 0x10;
public:
explicit DsqlCompiledStatement(MemoryPool& p)
: PermanentStorage(p),
type(TYPE_SELECT),
flags(0),
blrVersion(5),
sendMsg(NULL),
receiveMsg(NULL),
eof(NULL),
dbKey(NULL),
recVersion(NULL),
parentRecVersion(NULL),
parentDbKey(NULL),
parentRequest(NULL)
{
}
public:
Type getType() const { return type; }
void setType(Type value) { type = value; }
ULONG getFlags() const { return flags; }
void setFlags(ULONG value) { flags = value; }
void addFlags(ULONG value) { flags |= value; }
unsigned getBlrVersion() const { return blrVersion; }
void setBlrVersion(unsigned value) { blrVersion = value; }
Firebird::RefStrPtr& getSqlText() { return sqlText; }
const Firebird::RefStrPtr& getSqlText() const { return sqlText; }
void setSqlText(Firebird::RefString* value) { sqlText = value; }
void setOrgText(const char* ptr, ULONG len);
const Firebird::string& getOrgText() const { return *orgText; }
dsql_msg* getSendMsg() { return sendMsg; }
const dsql_msg* getSendMsg() const { return sendMsg; }
void setSendMsg(dsql_msg* value) { sendMsg = value; }
dsql_msg* getReceiveMsg() { return receiveMsg; }
const dsql_msg* getReceiveMsg() const { return receiveMsg; }
void setReceiveMsg(dsql_msg* value) { receiveMsg = value; }
dsql_par* getEof() { return eof; }
const dsql_par* getEof() const { return eof; }
void setEof(dsql_par* value) { eof = value; }
dsql_par* getDbKey() { return dbKey; }
const dsql_par* getDbKey() const { return dbKey; }
void setDbKey(dsql_par* value) { dbKey = value; }
dsql_par* getRecVersion() { return recVersion; }
const dsql_par* getRecVersion() const { return recVersion; }
void setRecVersion(dsql_par* value) { recVersion = value; }
dsql_par* getParentRecVersion() { return parentRecVersion; }
const dsql_par* getParentRecVersion() const { return parentRecVersion; }
void setParentRecVersion(dsql_par* value) { parentRecVersion = value; }
dsql_par* getParentDbKey() { return parentDbKey; }
const dsql_par* getParentDbKey() const { return parentDbKey; }
void setParentDbKey(dsql_par* value) { parentDbKey = value; }
dsql_req* getParentRequest() const { return parentRequest; }
void setParentRequest(dsql_req* value) { parentRequest = value; }
private:
Type type; // Type of statement
ULONG flags; // generic flag
unsigned blrVersion;
Firebird::RefStrPtr sqlText;
Firebird::RefStrPtr orgText;
dsql_msg* sendMsg; // Message to be sent to start request
dsql_msg* receiveMsg; // Per record message to be received
dsql_par* eof; // End of file parameter
dsql_par* dbKey; // Database key for current of
dsql_par* recVersion; // Record Version for current of
dsql_par* parentRecVersion; // parent record version
dsql_par* parentDbKey; // Parent database key for current of
dsql_req* parentRequest; // Source request, if cursor update
};
class dsql_req : public pool_alloc<dsql_type_req>
{
public:
explicit dsql_req(MemoryPool& pool);
public:
MemoryPool& getPool()
{
return req_pool;
}
jrd_tra* getTransaction()
{
return req_transaction;
}
const DsqlCompiledStatement* getStatement() const
{
return statement;
}
virtual bool mustBeReplicated() const
{
return false;
}
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool,
ntrace_result_t* traceResult) = 0;
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton) = 0;
virtual void setCursor(thread_db* tdbb, const TEXT* name);
virtual bool fetch(thread_db* tdbb, UCHAR* buffer);
virtual void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata);
// Get session-level timeout, milliseconds
unsigned int getTimeout();
// Set session-level timeout, milliseconds
void setTimeout(unsigned int timeOut);
// Get actual timeout, milliseconds
unsigned int getActualTimeout();
// Evaluate actual timeout value, consider config- and session-level timeout values,
// setup and start timer
TimeoutTimer* setupTimer(thread_db* tdbb);
USHORT parseMetadata(Firebird::IMessageMetadata* meta, const Firebird::Array<dsql_par*>& parameters_list);
void mapInOut(Jrd::thread_db* tdbb, bool toExternal, const dsql_msg* message, Firebird::IMessageMetadata* meta,
UCHAR* dsql_msg_buf, const UCHAR* in_dsql_msg_buf = NULL);
static void destroy(thread_db* tdbb, dsql_req* request, bool drop);
private:
MemoryPool& req_pool;
public:
const DsqlCompiledStatement* statement;
MemoryPool* liveScratchPool;
Firebird::Array<DsqlCompiledStatement*> cursors; // Cursor update statements
dsql_dbb* req_dbb; // DSQL attachment
jrd_tra* req_transaction; // JRD transaction
jrd_req* req_request; // JRD request
Firebird::Array<UCHAR*> req_msg_buffers;
Firebird::string req_cursor_name; // Cursor name, if any
DsqlCursor* req_cursor; // Open cursor, if any
DsqlBatch* req_batch; // Active batch, if any
Firebird::GenericMap<Firebird::NonPooled<const dsql_par*, dsc> > req_user_descs; // SQLDA data type
Firebird::AutoPtr<Jrd::RuntimeStatistics> req_fetch_baseline; // State of request performance counters when we reported it last time
SINT64 req_fetch_elapsed; // Number of clock ticks spent while fetching rows for this request since we reported it last time
SINT64 req_fetch_rowcount; // Total number of rows returned by this request
bool req_traced; // request is traced via TraceAPI
protected:
unsigned int req_timeout; // query timeout in milliseconds, set by the user
Firebird::RefPtr<TimeoutTimer> req_timer; // timeout timer
// Request should never be destroyed using delete.
// It dies together with it's pool in release_request().
~dsql_req();
// To avoid posix warning about missing public destructor declare
// MemoryPool as friend class. In fact IT releases request memory!
friend class Firebird::MemoryPool;
};
class DsqlDmlRequest : public dsql_req
{
public:
explicit DsqlDmlRequest(MemoryPool& pool, StmtNode* aNode)
: dsql_req(pool),
node(aNode),
needDelayedFormat(false),
firstRowFetched(false)
{
}
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool,
ntrace_result_t* traceResult);
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton);
virtual void setCursor(thread_db* tdbb, const TEXT* name);
virtual bool fetch(thread_db* tdbb, UCHAR* buffer);
virtual void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata);
private:
// True, if request could be restarted
bool needRestarts();
void doExecute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton);
// [Re]start part of "request restarts" algorithm
void executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton, bool exec, bool fetch);
NestConst<StmtNode> node;
Firebird::RefPtr<Firebird::IMessageMetadata> delayedFormat;
bool needDelayedFormat;
bool firstRowFetched;
};
class DsqlDdlRequest : public dsql_req
{
public:
explicit DsqlDdlRequest(MemoryPool& pool, DdlNode* aNode)
: dsql_req(pool),
node(aNode),
internalScratch(NULL)
{
}
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool,
ntrace_result_t* traceResult);
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton);
virtual bool mustBeReplicated() const;
private:
// Rethrow an exception with isc_no_meta_update and prefix codes.
void rethrowDdlException(Firebird::status_exception& ex, bool metadataUpdate);
private:
NestConst<DdlNode> node;
DsqlCompilerScratch* internalScratch;
};
class DsqlTransactionRequest : public dsql_req
{
public:
explicit DsqlTransactionRequest(MemoryPool& pool, TransactionNode* aNode)
: dsql_req(pool),
node(aNode)
{
req_traced = false;
}
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool,
ntrace_result_t* traceResult);
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton);
private:
NestConst<TransactionNode> node;
};
class DsqlSessionManagementRequest : public dsql_req
{
public:
explicit DsqlSessionManagementRequest(MemoryPool& pool, SessionManagementNode* aNode)
: dsql_req(pool),
node(aNode)
{
req_traced = false;
}
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, bool* destroyScratchPool,
ntrace_result_t* traceResult);
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
bool singleton);
private:
NestConst<SessionManagementNode> node;
};
//! Implicit (NATURAL and USING) joins
class ImplicitJoin : public pool_alloc<dsql_type_imp_join>
{
@ -985,7 +672,7 @@ public:
s(p)
{ }
Firebird::string toUtf8(DsqlCompilerScratch*) const;
Firebird::string toUtf8(jrd_tra* transaction) const;
const MetaName& getCharSet() const
{

View File

@ -31,21 +31,19 @@
namespace Jrd {
class Attachment;
class jrd_tra;
class dsql_req;
class DsqlDmlRequest;
class DsqlRequest;
}
void DSQL_execute(Jrd::thread_db*, Jrd::jrd_tra**, Jrd::dsql_req*,
void DSQL_execute(Jrd::thread_db*, Jrd::jrd_tra**, Jrd::DsqlRequest*,
Firebird::IMessageMetadata*, const UCHAR*, Firebird::IMessageMetadata*, UCHAR*);
void DSQL_execute_immediate(Jrd::thread_db*, Jrd::Attachment*, Jrd::jrd_tra**,
ULONG, const TEXT*, USHORT, Firebird::IMessageMetadata*, const UCHAR*,
Firebird::IMessageMetadata*, UCHAR*, bool);
void DSQL_free_statement(Jrd::thread_db*, Jrd::dsql_req*, USHORT);
Jrd::DsqlCursor* DSQL_open(Jrd::thread_db*, Jrd::jrd_tra**, Jrd::dsql_req*,
Firebird::IMessageMetadata*, const UCHAR*,
Firebird::IMessageMetadata*, ULONG);
Jrd::dsql_req* DSQL_prepare(Jrd::thread_db*, Jrd::Attachment*, Jrd::jrd_tra*, ULONG, const TEXT*,
void DSQL_free_statement(Jrd::thread_db*, Jrd::DsqlRequest*, USHORT);
Jrd::DsqlRequest* DSQL_prepare(Jrd::thread_db*, Jrd::Attachment*, Jrd::jrd_tra*, ULONG, const TEXT*,
USHORT, unsigned, Firebird::Array<UCHAR>*, Firebird::Array<UCHAR>*, bool);
void DSQL_sql_info(Jrd::thread_db*, Jrd::dsql_req*,
void DSQL_sql_info(Jrd::thread_db*, Jrd::DsqlRequest*,
ULONG, const UCHAR*, ULONG, UCHAR*);
#endif // DSQL_DSQL_PROTO_H

View File

@ -220,22 +220,22 @@ void GEN_port(DsqlCompilerScratch* dsqlScratch, dsql_msg* message)
message->msg_length = offset;
dsqlScratch->ports.add(message);
dsqlScratch->getStatement()->getPorts().add(message);
}
// Generate complete blr for a dsqlScratch.
void GEN_request(DsqlCompilerScratch* scratch, DmlNode* node)
void GEN_statement(DsqlCompilerScratch* scratch, DmlNode* node)
{
DsqlCompiledStatement* statement = scratch->getStatement();
DsqlStatement* statement = scratch->getStatement();
if (statement->getBlrVersion() == 4)
scratch->appendUChar(blr_version4);
else
scratch->appendUChar(blr_version5);
const bool block = statement->getType() == DsqlCompiledStatement::TYPE_EXEC_BLOCK ||
statement->getType() == DsqlCompiledStatement::TYPE_SELECT_BLOCK;
const bool block = statement->getType() == DsqlStatement::TYPE_EXEC_BLOCK ||
statement->getType() == DsqlStatement::TYPE_SELECT_BLOCK;
// To parse sub-routines messages, they must not have that begin...end pair.
// And since it appears to be unnecessary for execute block too, do not generate them.
@ -247,14 +247,14 @@ void GEN_request(DsqlCompilerScratch* scratch, DmlNode* node)
switch (statement->getType())
{
case DsqlCompiledStatement::TYPE_SELECT:
case DsqlCompiledStatement::TYPE_SELECT_UPD:
case DsqlCompiledStatement::TYPE_EXEC_BLOCK:
case DsqlCompiledStatement::TYPE_SELECT_BLOCK:
case DsqlStatement::TYPE_SELECT:
case DsqlStatement::TYPE_SELECT_UPD:
case DsqlStatement::TYPE_EXEC_BLOCK:
case DsqlStatement::TYPE_SELECT_BLOCK:
node->genBlr(scratch);
break;
///case DsqlCompiledStatement::TYPE_RETURNING_CURSOR:
///case DsqlStatement::TYPE_RETURNING_CURSOR:
default:
{
dsql_msg* message = statement->getSendMsg();

View File

@ -35,7 +35,7 @@ void GEN_expr(Jrd::DsqlCompilerScratch*, Jrd::ExprNode*);
void GEN_hidden_variables(Jrd::DsqlCompilerScratch* dsqlScratch);
void GEN_parameter(Jrd::DsqlCompilerScratch*, const Jrd::dsql_par*);
void GEN_port(Jrd::DsqlCompilerScratch*, Jrd::dsql_msg*);
void GEN_request(Jrd::DsqlCompilerScratch*, Jrd::DmlNode*);
void GEN_statement(Jrd::DsqlCompilerScratch*, Jrd::DmlNode*);
void GEN_rse(Jrd::DsqlCompilerScratch*, Jrd::RseNode*);
void GEN_sort(Jrd::DsqlCompilerScratch*, UCHAR, Jrd::ValueListNode*);
void GEN_stuff_context(Jrd::DsqlCompilerScratch*, const Jrd::dsql_ctx*);

View File

@ -34,7 +34,7 @@ namespace Jrd {
class TypeClause;
class dsql_msg;
class dsql_par;
class dsql_req;
class DsqlRequest;
class DsqlCompilerScratch;
class IntlString;
class ExprNode;

View File

@ -34,7 +34,7 @@
namespace Jrd {
typedef Firebird::GenericMap<Jrd::MetaNamePair> MetaNamePairMap;
class dsql_req;
class DsqlRequest;
class DsqlCompilerScratch;
class jrd_tra;
class dsql_intlsym;

View File

@ -828,7 +828,7 @@ using namespace Firebird;
Jrd::SetTransactionNode::RestrictionOption* setTransactionRestrictionClause;
Jrd::DeclareSubProcNode* declareSubProcNode;
Jrd::DeclareSubFuncNode* declareSubFuncNode;
Jrd::dsql_req* dsqlReq;
Jrd::DsqlStatement* dsqlStatement;
Jrd::CreateAlterUserNode* createAlterUserNode;
Jrd::MappingNode* mappingNode;
Jrd::MappingNode::OP mappingOp;
@ -848,16 +848,23 @@ using namespace Firebird;
// list of possible statements
top
: statement { DSQL_parse = $1; }
| statement ';' { DSQL_parse = $1; }
: statement { parsedStatement = $1; }
| statement ';' { parsedStatement = $1; }
;
%type <dsqlReq> statement
%type <dsqlStatement> statement
statement
: dml_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlDmlRequest(getStatementPool(), $1); }
| ddl_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlDdlRequest(getStatementPool(), $1); }
| tra_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlTransactionRequest(getStatementPool(), $1); }
| mng_statement { $$ = FB_NEW_POOL(getStatementPool()) DsqlSessionManagementRequest(getStatementPool(), $1); }
: dml_statement
{ $$ = FB_NEW_POOL(*statementPool) DsqlDmlStatement(*statementPool, scratch->getAttachment(), $1); }
| ddl_statement
{ $$ = FB_NEW_POOL(*statementPool) DsqlDdlStatement(*statementPool, scratch->getAttachment(), $1); }
| tra_statement
{ $$ = FB_NEW_POOL(*statementPool) DsqlTransactionStatement(*statementPool, scratch->getAttachment(), $1); }
| mng_statement
{
$$ = FB_NEW_POOL(*statementPool) DsqlSessionManagementStatement(
*statementPool, scratch->getAttachment(), $1);
}
;
%type <stmtNode> dml_statement
@ -7743,7 +7750,7 @@ sql_string
%type <stringPtr> utf_string
utf_string
: sql_string
{ $$ = newString($1->toUtf8(scratch)); }
{ $$ = newString($1->toUtf8(scratch->getTransaction())); }
;
%type <int32Val> signed_short_integer

View File

@ -35,7 +35,7 @@ class blb;
class jrd_tra;
class DsqlCursor;
class DsqlBatch;
class dsql_req;
class DsqlRequest;
class JrdStatement;
class StableAttachmentPart;
class Attachment;
@ -305,20 +305,20 @@ public:
unsigned parLength, const unsigned char* par) override;
public:
JStatement(dsql_req* handle, StableAttachmentPart* sa, Firebird::Array<UCHAR>& meta);
JStatement(DsqlRequest* handle, StableAttachmentPart* sa, Firebird::Array<UCHAR>& meta);
StableAttachmentPart* getAttachment()
{
return sAtt;
}
dsql_req* getHandle() throw()
DsqlRequest* getHandle() throw()
{
return statement;
}
private:
dsql_req* statement;
DsqlRequest* statement;
Firebird::RefPtr<StableAttachmentPart> sAtt;
Firebird::StatementMetadata metadata;

View File

@ -410,6 +410,9 @@ jrd_req* JrdStatement::getRequest(thread_db* tdbb, USHORT level)
// Create the request.
jrd_req* const request = FB_NEW_POOL(*pool) jrd_req(attachment, this, parentStats);
if (level == 0)
pool->setStatsGroup(request->req_memory_stats);
requests[level] = request;
return request;

View File

@ -325,7 +325,7 @@ void PreparedStatement::init(thread_db* tdbb, Attachment* attachment, jrd_tra* t
request = DSQL_prepare(tdbb, attachment, transaction, text.length(), text.c_str(), dialect, 0,
NULL, NULL, isInternalRequest);
const DsqlCompiledStatement* statement = request->getStatement();
const DsqlStatement* statement = request->getStatement();
if (statement->getSendMsg())
parseDsqlMessage(statement->getSendMsg(), inValues, inMetadata, inMessage);
@ -348,7 +348,7 @@ void PreparedStatement::setDesc(thread_db* tdbb, unsigned param, const dsc& valu
{
fb_assert(param > 0);
jrd_req* jrdRequest = getRequest()->req_request;
jrd_req* jrdRequest = getRequest()->getJrdRequest();
// Setup tdbb info necessary for blobs.
AutoSetRestore2<jrd_req*, thread_db> autoRequest(
@ -382,7 +382,7 @@ void PreparedStatement::open(thread_db* tdbb, jrd_tra* transaction)
if (builder)
builder->moveToStatement(tdbb, this);
DSQL_open(tdbb, &transaction, request, inMetadata, inMessage.begin(), outMetadata, 0);
request->openCursor(tdbb, &transaction, inMetadata, inMessage.begin(), outMetadata, 0);
}
@ -400,7 +400,7 @@ ResultSet* PreparedStatement::executeQuery(thread_db* tdbb, jrd_tra* transaction
unsigned PreparedStatement::executeUpdate(thread_db* tdbb, jrd_tra* transaction)
{
execute(tdbb, transaction);
return getRequest()->req_request->req_records_updated;
return getRequest()->getJrdRequest()->req_records_updated;
}

View File

@ -40,7 +40,7 @@ namespace Jrd {
class thread_db;
class jrd_tra;
class Attachment;
class dsql_req;
class DsqlRequest;
class dsql_msg;
class ResultSet;
@ -359,7 +359,7 @@ public:
int getResultCount() const;
dsql_req* getRequest()
DsqlRequest* getRequest()
{
return request;
}
@ -369,7 +369,7 @@ public:
private:
const Builder* builder;
dsql_req* request;
DsqlRequest* request;
Firebird::Array<dsc> inValues, outValues;
Firebird::RefPtr<Firebird::MsgMetadata> inMetadata, outMetadata;
Firebird::UCharBuffer inMessage, outMessage;

View File

@ -54,14 +54,14 @@ ResultSet::~ResultSet()
stmt->resultSet = NULL;
if (stmt->request->getStatement()->getType() != DsqlCompiledStatement::TYPE_EXEC_PROCEDURE)
if (stmt->request->getStatement()->getType() != DsqlStatement::TYPE_EXEC_PROCEDURE)
DSQL_free_statement(tdbb, stmt->request, DSQL_close);
}
bool ResultSet::fetch(thread_db* tdbb)
{
if (stmt->request->getStatement()->getType() == DsqlCompiledStatement::TYPE_EXEC_PROCEDURE &&
if (stmt->request->getStatement()->getType() == DsqlStatement::TYPE_EXEC_PROCEDURE &&
firstFetchDone)
{
return false;
@ -103,7 +103,7 @@ Firebird::string ResultSet::getString(thread_db* tdbb, unsigned param)
{
fb_assert(param > 0);
jrd_req* jrdRequest = stmt->getRequest()->req_request;
jrd_req* jrdRequest = stmt->getRequest()->getJrdRequest();
// Setup tdbb info necessary for blobs.
AutoSetRestore2<jrd_req*, thread_db> autoRequest(
@ -131,7 +131,7 @@ void ResultSet::moveDesc(thread_db* tdbb, unsigned param, dsc& desc)
{
fb_assert(param > 0);
jrd_req* jrdRequest = stmt->getRequest()->req_request;
jrd_req* jrdRequest = stmt->getRequest()->getJrdRequest();
// Setup tdbb info necessary for blobs.
AutoSetRestore2<jrd_req*, thread_db> autoRequest(

View File

@ -143,38 +143,26 @@ BoolExprNode* CMP_clone_node_opt(thread_db* tdbb, CompilerScratch* csb, BoolExpr
return clone;
}
jrd_req* CMP_compile2(thread_db* tdbb, const UCHAR* blr, ULONG blr_length, bool internal_flag,
ULONG dbginfo_length, const UCHAR* dbginfo)
// Compile a statement.
JrdStatement* CMP_compile(thread_db* tdbb, const UCHAR* blr, ULONG blrLength, bool internalFlag,
ULONG dbginfoLength, const UCHAR* dbginfo)
{
/**************************************
*
* C M P _ c o m p i l e 2
*
**************************************
*
* Functional description
* Compile a BLR request.
*
**************************************/
jrd_req* request = NULL;
JrdStatement* statement = nullptr;
SET_TDBB(tdbb);
Jrd::Attachment* const att = tdbb->getAttachment();
const auto att = tdbb->getAttachment();
// 26.09.2002 Nickolay Samofatov: default memory pool will become statement pool
// and will be freed by CMP_release
MemoryPool* const new_pool = att->createPool();
const auto newPool = att->createPool();
try
{
Jrd::ContextPoolHolder context(tdbb, new_pool);
Jrd::ContextPoolHolder context(tdbb, newPool);
CompilerScratch* csb =
PAR_parse(tdbb, blr, blr_length, internal_flag, dbginfo_length, dbginfo);
const auto csb = PAR_parse(tdbb, blr, blrLength, internalFlag, dbginfoLength, dbginfo);
request = JrdStatement::makeRequest(tdbb, csb, internal_flag);
new_pool->setStatsGroup(request->req_memory_stats);
statement = JrdStatement::makeStatement(tdbb, csb, internalFlag);
#ifdef CMP_DEBUG
if (csb->csb_dump.hasData())
@ -196,20 +184,40 @@ jrd_req* CMP_compile2(thread_db* tdbb, const UCHAR* blr, ULONG blr_length, bool
}
#endif
request->getStatement()->verifyAccess(tdbb);
statement->verifyAccess(tdbb);
delete csb;
}
catch (const Firebird::Exception& ex)
{
ex.stuffException(tdbb->tdbb_status_vector);
if (request)
CMP_release(tdbb, request);
if (statement)
statement->release(tdbb);
else
att->deletePool(new_pool);
att->deletePool(newPool);
ERR_punt();
}
return statement;
}
jrd_req* CMP_compile_request(thread_db* tdbb, const UCHAR* blr, ULONG blrLength, bool internalFlag)
{
/**************************************
*
* C M P _ c o m p i l e _ r e q u e s t
*
**************************************
*
* Functional description
* Compile a BLR request.
*
**************************************/
SET_TDBB(tdbb);
auto statement = CMP_compile(tdbb, blr, blrLength, internalFlag, 0, nullptr);
auto request = statement->getRequest(tdbb, 0);
return request;
}

View File

@ -37,8 +37,9 @@ StreamType* CMP_alloc_map(Jrd::thread_db*, Jrd::CompilerScratch*, StreamType str
Jrd::ValueExprNode* CMP_clone_node_opt(Jrd::thread_db*, Jrd::CompilerScratch*, Jrd::ValueExprNode*);
Jrd::BoolExprNode* CMP_clone_node_opt(Jrd::thread_db*, Jrd::CompilerScratch*, Jrd::BoolExprNode*);
Jrd::ValueExprNode* CMP_clone_node(Jrd::thread_db*, Jrd::CompilerScratch*, Jrd::ValueExprNode*);
Jrd::jrd_req* CMP_compile2(Jrd::thread_db*, const UCHAR* blr, ULONG blr_length, bool internal_flag,
ULONG = 0, const UCHAR* = NULL);
Jrd::JrdStatement* CMP_compile(Jrd::thread_db* tdbb, const UCHAR* blr, ULONG blrLength, bool internalFlag,
ULONG dbginfoLength, const UCHAR* dbginfo);
Jrd::jrd_req* CMP_compile_request(Jrd::thread_db*, const UCHAR* blr, ULONG blrLength, bool internalFlag);
Jrd::CompilerScratch::csb_repeat* CMP_csb_element(Jrd::CompilerScratch*, StreamType element);
const Jrd::Format* CMP_format(Jrd::thread_db*, Jrd::CompilerScratch*, StreamType);
Jrd::IndexLock* CMP_get_index_lock(Jrd::thread_db*, Jrd::jrd_rel*, USHORT);

View File

@ -93,7 +93,7 @@ namespace Jrd
if (request)
return;
request = CMP_compile2(tdbb, blr, blrLength, true);
request = CMP_compile_request(tdbb, blr, blrLength, true);
cacheRequest();
}
@ -166,7 +166,7 @@ namespace Jrd
if (request)
return;
request = CMP_compile2(tdbb, blr, blrLength, true);
request = CMP_compile_request(tdbb, blr, blrLength, true);
}
jrd_req* operator ->()

View File

@ -504,7 +504,7 @@ void InternalStatement::doPrepare(thread_db* tdbb, const string& sql)
if (status->getState() & IStatus::STATE_ERRORS)
raise(&status, tdbb, "JAttachment::prepare", &sql);
const DsqlCompiledStatement* statement = m_request->getHandle()->getStatement();
const DsqlStatement* statement = m_request->getHandle()->getStatement();
if (statement->getSendMsg())
{
@ -542,33 +542,33 @@ void InternalStatement::doPrepare(thread_db* tdbb, const string& sql)
switch (statement->getType())
{
case DsqlCompiledStatement::TYPE_SELECT:
case DsqlCompiledStatement::TYPE_RETURNING_CURSOR:
case DsqlCompiledStatement::TYPE_SELECT_UPD:
case DsqlCompiledStatement::TYPE_SELECT_BLOCK:
case DsqlStatement::TYPE_SELECT:
case DsqlStatement::TYPE_RETURNING_CURSOR:
case DsqlStatement::TYPE_SELECT_UPD:
case DsqlStatement::TYPE_SELECT_BLOCK:
m_stmt_selectable = true;
break;
case DsqlCompiledStatement::TYPE_START_TRANS:
case DsqlCompiledStatement::TYPE_COMMIT:
case DsqlCompiledStatement::TYPE_ROLLBACK:
case DsqlCompiledStatement::TYPE_COMMIT_RETAIN:
case DsqlCompiledStatement::TYPE_ROLLBACK_RETAIN:
case DsqlCompiledStatement::TYPE_CREATE_DB:
case DsqlStatement::TYPE_START_TRANS:
case DsqlStatement::TYPE_COMMIT:
case DsqlStatement::TYPE_ROLLBACK:
case DsqlStatement::TYPE_COMMIT_RETAIN:
case DsqlStatement::TYPE_ROLLBACK_RETAIN:
case DsqlStatement::TYPE_CREATE_DB:
Arg::Gds(isc_eds_expl_tran_ctrl).copyTo(&status);
raise(&status, tdbb, "JAttachment::prepare", &sql);
break;
case DsqlCompiledStatement::TYPE_INSERT:
case DsqlCompiledStatement::TYPE_DELETE:
case DsqlCompiledStatement::TYPE_UPDATE:
case DsqlCompiledStatement::TYPE_UPDATE_CURSOR:
case DsqlCompiledStatement::TYPE_DELETE_CURSOR:
case DsqlCompiledStatement::TYPE_DDL:
case DsqlCompiledStatement::TYPE_EXEC_PROCEDURE:
case DsqlCompiledStatement::TYPE_SET_GENERATOR:
case DsqlCompiledStatement::TYPE_SAVEPOINT:
case DsqlCompiledStatement::TYPE_EXEC_BLOCK:
case DsqlStatement::TYPE_INSERT:
case DsqlStatement::TYPE_DELETE:
case DsqlStatement::TYPE_UPDATE:
case DsqlStatement::TYPE_UPDATE_CURSOR:
case DsqlStatement::TYPE_DELETE_CURSOR:
case DsqlStatement::TYPE_DDL:
case DsqlStatement::TYPE_EXEC_PROCEDURE:
case DsqlStatement::TYPE_SET_GENERATOR:
case DsqlStatement::TYPE_SAVEPOINT:
case DsqlStatement::TYPE_EXEC_BLOCK:
break;
}
}

View File

@ -345,7 +345,7 @@ JEvents::JEvents(int aId, StableAttachmentPart* sa, Firebird::IEventCallback* aC
{
}
JStatement::JStatement(dsql_req* handle, StableAttachmentPart* sa, Firebird::Array<UCHAR>& meta)
JStatement::JStatement(DsqlRequest* handle, StableAttachmentPart* sa, Firebird::Array<UCHAR>& meta)
: statement(handle), sAtt(sa), metadata(getPool(), this, sAtt)
{
metadata.parse(meta.getCount(), meta.begin());
@ -657,7 +657,7 @@ namespace
validateHandle(tdbb, statement->requests[0]->req_attachment);
}
inline void validateHandle(thread_db* tdbb, dsql_req* const statement)
inline void validateHandle(thread_db* tdbb, DsqlRequest* const statement)
{
if (!statement)
status_exception::raise(Arg::Gds(isc_bad_req_handle));
@ -2693,11 +2693,14 @@ JRequest* JAttachment::compileRequest(CheckStatusWrapper* user_status,
TraceBlrCompile trace(tdbb, blr_length, blr);
try
{
jrd_req* request = NULL;
JRD_compile(tdbb, getHandle(), &request, blr_length, blr, RefStrPtr(), 0, NULL, false);
stmt = request->getStatement();
stmt = CMP_compile(tdbb, blr, blr_length, false, 0, nullptr);
trace.finish(request, ITracePlugin::RESULT_SUCCESS);
const auto attachment = tdbb->getAttachment();
const auto rootRequest = stmt->getRequest(tdbb, 0);
rootRequest->setAttachment(attachment);
attachment->att_requests.add(rootRequest);
trace.finish(stmt, ITracePlugin::RESULT_SUCCESS);
}
catch (const Exception& ex)
{
@ -4717,7 +4720,6 @@ void JAttachment::transactRequest(CheckStatusWrapper* user_status, ITransaction*
for (FB_SIZE_T i = 0; i < csb->csb_rpt.getCount(); i++)
{
const MessageNode* node = csb->csb_rpt[i].csb_message;
if (node)
{
@ -5066,7 +5068,7 @@ JResultSet* JStatement::openCursor(CheckStatusWrapper* user_status, ITransaction
}
}
DsqlCursor* const cursor = DSQL_open(tdbb, &tra, getHandle(),
const auto cursor = getHandle()->openCursor(tdbb, &tra,
inMetadata, static_cast<UCHAR*>(inBuffer), outMetadata, flags);
rs = FB_NEW JResultSet(cursor, this);
@ -5542,7 +5544,7 @@ JStatement* JAttachment::prepare(CheckStatusWrapper* user_status, ITransaction*
validateHandle(tdbb, tra);
check_database(tdbb);
dsql_req* statement = NULL;
DsqlRequest* statement = NULL;
try
{
@ -5814,7 +5816,7 @@ void JResultSet::setDelayedOutputFormat(CheckStatusWrapper* user_status, Firebir
try
{
dsql_req* req = statement->getHandle();
DsqlRequest* req = statement->getHandle();
fb_assert(req);
req->setDelayedFormat(tdbb, outMetadata);
}
@ -5874,7 +5876,7 @@ unsigned int JStatement::getTimeout(CheckStatusWrapper* user_status)
try
{
Jrd::dsql_req* req = getHandle();
Jrd::DsqlRequest* req = getHandle();
return req->getTimeout();
}
catch (const Exception& ex)
@ -5904,7 +5906,7 @@ void JStatement::setTimeout(CheckStatusWrapper* user_status, unsigned int timeOu
try
{
Jrd::dsql_req* req = getHandle();
Jrd::DsqlRequest* req = getHandle();
req->setTimeout(timeOut);
}
catch (const Exception& ex)
@ -5946,11 +5948,11 @@ JBatch* JStatement::createBatch(Firebird::CheckStatusWrapper* status, Firebird::
}
}
DsqlBatch* const b = DsqlBatch::open(tdbb, getHandle(), inMetadata, parLength, par);
const auto dsqlBatch = getHandle()->openBatch(tdbb, inMetadata, parLength, par);
batch = FB_NEW JBatch(b, this, inMetadata);
batch = FB_NEW JBatch(dsqlBatch, this, inMetadata);
batch->addRef();
b->setInterfacePtr(batch);
dsqlBatch->setInterfacePtr(batch);
tdbb->getAttachment()->registerBatch(batch);
}
catch (const Exception& ex)
@ -9367,47 +9369,6 @@ void JRD_unwind_request(thread_db* tdbb, jrd_req* request)
}
void JRD_compile(thread_db* tdbb,
Jrd::Attachment* attachment,
jrd_req** req_handle,
ULONG blr_length,
const UCHAR* blr,
RefStrPtr ref_str,
ULONG dbginfo_length,
const UCHAR* dbginfo,
bool isInternalRequest)
{
/**************************************
*
* J R D _ c o m p i l e
*
**************************************
*
* Functional description
* Compile a request passing the SQL text and debug information.
*
**************************************/
if (*req_handle)
status_exception::raise(Arg::Gds(isc_bad_req_handle));
jrd_req* request = CMP_compile2(tdbb, blr, blr_length, isInternalRequest, dbginfo_length, dbginfo);
request->req_attachment = attachment;
attachment->att_requests.add(request);
JrdStatement* statement = request->getStatement();
if (ref_str)
statement->sqlText = ref_str;
fb_assert(statement->blr.isEmpty());
if (attachment->getDebugOptions().getDsqlKeepBlr())
statement->blr.insert(0, blr, blr_length);
*req_handle = request;
}
namespace
{
class DatabaseDirList : public DirectoryList

View File

@ -40,7 +40,7 @@ namespace Jrd {
class Service;
class thread_db;
struct teb;
class dsql_req;
class DsqlRequest;
class MetaName;
}
@ -71,9 +71,6 @@ void JRD_start_and_send(Jrd::thread_db* tdbb, Jrd::jrd_req* request, Jrd::jrd_tr
void JRD_start_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra** transaction,
Jrd::Attachment* attachment, unsigned int tpb_length, const UCHAR* tpb);
void JRD_unwind_request(Jrd::thread_db* tdbb, Jrd::jrd_req* request);
void JRD_compile(Jrd::thread_db* tdbb, Jrd::Attachment* attachment, Jrd::jrd_req** req_handle,
ULONG blr_length, const UCHAR* blr, Firebird::RefStrPtr,
ULONG dbginfo_length, const UCHAR* dbginfo, bool isInternalRequest);
bool JRD_verify_database_access(const Firebird::PathName&);
void JRD_shutdown_attachment(Jrd::Attachment* attachment);
void JRD_shutdown_attachments(Jrd::Database* dbb);

View File

@ -455,12 +455,10 @@ string OPT_get_plan(thread_db* tdbb, const JrdStatement* statement, bool detaile
if (statement)
{
const Array<const RecordSource*>& fors = statement->fors;
for (FB_SIZE_T i = 0; i < fors.getCount(); i++)
for (const auto& recordSource : statement->fors)
{
plan += detailed ? "\nSelect Expression" : "\nPLAN ";
fors[i]->print(tdbb, plan, detailed, 0);
recordSource->print(tdbb, plan, detailed, 0);
}
}

View File

@ -30,7 +30,7 @@
#include "../jrd/lls.h"
namespace Jrd {
class jrd_req;
class JrdStatement;
class jrd_rel;
class RecordSource;
struct index_desc;

View File

@ -382,8 +382,8 @@ public:
ULONG req_flags; // misc request flags
Savepoint* req_savepoints; // Looper savepoint list
Savepoint* req_proc_sav_point; // procedure savepoint list
unsigned int req_timeout; // query timeout in milliseconds, set by the dsql_req::setupTimer
Firebird::RefPtr<TimeoutTimer> req_timer; // timeout timer, shared with dsql_req
unsigned int req_timeout; // query timeout in milliseconds, set by the DsqlRequest::setupTimer
Firebird::RefPtr<TimeoutTimer> req_timer; // timeout timer, shared with DsqlRequest
Firebird::AutoPtr<Jrd::RuntimeStatistics> req_fetch_baseline; // State of request performance counters when we reported it last time
SINT64 req_fetch_elapsed; // Number of clock ticks spent while fetching rows for this request since we reported it last time

View File

@ -28,6 +28,7 @@
#ifndef JRD_TRACE_DSQL_HELPERS_H
#define JRD_TRACE_DSQL_HELPERS_H
#include "../../jrd/trace/TraceManager.h"
#include "../../jrd/trace/TraceObjects.h"
namespace Jrd {
@ -65,7 +66,7 @@ public:
prepare(ITracePlugin::RESULT_FAILED);
}
void setStatement(dsql_req* request)
void setStatement(DsqlRequest* request)
{
m_request = request;
}
@ -100,7 +101,7 @@ private:
bool m_need_trace;
Attachment* m_attachment;
jrd_tra* const m_transaction;
dsql_req* m_request;
DsqlRequest* m_request;
SINT64 m_start_clock;
FB_SIZE_T m_string_len;
const TEXT* m_string;
@ -110,7 +111,7 @@ private:
class TraceDSQLExecute
{
public:
TraceDSQLExecute(Attachment* attachment, dsql_req* request) :
TraceDSQLExecute(Attachment* attachment, DsqlRequest* request) :
m_attachment(attachment),
m_request(request)
{
@ -131,11 +132,10 @@ public:
fb_assert(!m_request->req_fetch_baseline);
m_request->req_fetch_baseline = NULL;
jrd_req* jrd_request = m_request->req_request;
if (jrd_request)
if (auto jrdRequest = m_request->getJrdRequest())
{
MemoryPool* pool = MemoryPool::getContextPool();
m_request->req_fetch_baseline = FB_NEW_POOL(*pool) RuntimeStatistics(*pool, jrd_request->req_stats);
m_request->req_fetch_baseline = FB_NEW_POOL(*pool) RuntimeStatistics(*pool, jrdRequest->req_stats);
}
}
@ -152,7 +152,7 @@ public:
}
TraceRuntimeStats stats(m_attachment, m_request->req_fetch_baseline,
m_request->req_request ? &m_request->req_request->req_stats : NULL,
m_request->getJrdRequest() ? &m_request->getJrdRequest()->req_stats : NULL,
fb_utils::query_performance_counter() - m_start_clock,
m_request->req_fetch_rowcount);
@ -170,19 +170,19 @@ public:
private:
bool m_need_trace;
Attachment* const m_attachment;
dsql_req* const m_request;
DsqlRequest* const m_request;
SINT64 m_start_clock;
};
class TraceDSQLFetch
{
public:
TraceDSQLFetch(Attachment* attachment, dsql_req* request) :
TraceDSQLFetch(Attachment* attachment, DsqlRequest* request) :
m_attachment(attachment),
m_request(request)
{
m_need_trace = m_request->req_traced && TraceManager::need_dsql_execute(m_attachment) &&
m_request->req_request && (m_request->req_request->req_flags & req_active);
m_request->getJrdRequest() && (m_request->getJrdRequest()->req_flags & req_active);
if (!m_need_trace)
{
@ -212,7 +212,7 @@ public:
}
TraceRuntimeStats stats(m_attachment, m_request->req_fetch_baseline,
&m_request->req_request->req_stats, m_request->req_fetch_elapsed,
&m_request->getJrdRequest()->req_stats, m_request->req_fetch_elapsed,
m_request->req_fetch_rowcount);
TraceSQLStatementImpl stmt(m_request, stats.getPerf());
@ -227,7 +227,7 @@ public:
private:
bool m_need_trace;
Attachment* const m_attachment;
dsql_req* const m_request;
DsqlRequest* const m_request;
SINT64 m_start_clock;
};

View File

@ -392,7 +392,7 @@ public:
m_start_clock = fb_utils::query_performance_counter();
}
void finish(jrd_req* request, ntrace_result_t result)
void finish(JrdStatement* statement, ntrace_result_t result)
{
if (!m_need_trace)
return;
@ -406,9 +406,9 @@ public:
TraceConnectionImpl conn(m_tdbb->getAttachment());
TraceTransactionImpl tran(m_tdbb->getTransaction());
if (request)
if (statement)
{
TraceBLRStatementImpl stmt(request, NULL);
TraceBLRStatementImpl stmt(statement, NULL);
trace_mgr->event_blr_compile(&conn, m_tdbb->getTransaction() ? &tran : NULL, &stmt,
m_start_clock, result);
}
@ -474,7 +474,7 @@ public:
TraceConnectionImpl conn(m_tdbb->getAttachment());
TraceTransactionImpl tran(m_tdbb->getTransaction());
TraceBLRStatementImpl stmt(m_request, stats.getPerf());
TraceBLRStatementImpl stmt(m_request->getStatement(), stats.getPerf());
TraceManager* trace_mgr = m_tdbb->getAttachment()->att_trace_manager;
trace_mgr->event_blr_execute(&conn, &tran, &stmt, result);

View File

@ -169,8 +169,8 @@ ISC_INT64 TraceTransactionImpl::getInitialID()
ISC_INT64 TraceSQLStatementImpl::getStmtID()
{
if (m_stmt->req_request)
return m_stmt->req_request->getRequestId();
if (m_stmt->getJrdRequest())
return m_stmt->getJrdRequest()->getRequestId();
return 0;
}
@ -211,8 +211,8 @@ void TraceSQLStatementImpl::fillPlan(bool explained)
if (m_plan.isEmpty() || m_planExplained != explained)
{
m_planExplained = explained;
if (m_stmt->req_request)
m_plan = OPT_get_plan(JRD_get_thread_data(), m_stmt->req_request->getStatement(), m_planExplained);
if (m_stmt->getJrdStatement())
m_plan = OPT_get_plan(JRD_get_thread_data(), m_stmt->getJrdStatement(), m_planExplained);
}
}
@ -234,6 +234,14 @@ void TraceSQLStatementImpl::DSQLParamsImpl::fillParams()
if (m_descs.getCount() || !m_params)
return;
if (!m_stmt->isDml())
{
fb_assert(false);
return;
}
const auto dmlRequest = (DsqlDmlRequest*) m_stmt;
USHORT first_index = 0;
for (FB_SIZE_T i = 0 ; i < m_params->getCount(); ++i)
{
@ -246,7 +254,7 @@ void TraceSQLStatementImpl::DSQLParamsImpl::fillParams()
if (parameter->par_null)
{
const UCHAR* msgBuffer =
m_stmt->req_msg_buffers[parameter->par_null->par_message->msg_buffer_number];
dmlRequest->req_msg_buffers[parameter->par_null->par_message->msg_buffer_number];
if (*(SSHORT*) (msgBuffer + (IPTR) parameter->par_null->par_desc.dsc_address))
null_flag = DSC_null;
@ -263,7 +271,7 @@ void TraceSQLStatementImpl::DSQLParamsImpl::fillParams()
*desc = parameter->par_desc;
desc->dsc_flags |= null_flag;
UCHAR* msgBuffer = m_stmt->req_msg_buffers[parameter->par_message->msg_buffer_number];
UCHAR* msgBuffer = dmlRequest->req_msg_buffers[parameter->par_message->msg_buffer_number];
desc->dsc_address = msgBuffer + (IPTR) desc->dsc_address;
}
}

View File

@ -146,17 +146,17 @@ private:
class TraceBLRStatementImpl : public BLRPrinter<TraceBLRStatementImpl>
{
public:
TraceBLRStatementImpl(const jrd_req* stmt, Firebird::PerformanceInfo* perf) :
BLRPrinter(stmt->getStatement()->blr.begin(), stmt->getStatement()->blr.getCount()),
TraceBLRStatementImpl(const JrdStatement* stmt, Firebird::PerformanceInfo* perf) :
BLRPrinter(stmt->blr.begin(), stmt->blr.getCount()),
m_stmt(stmt),
m_perf(perf)
{}
ISC_INT64 getStmtID() { return m_stmt->getRequestId(); }
ISC_INT64 getStmtID() { return m_stmt->getStatementId(); }
Firebird::PerformanceInfo* getPerf() { return m_perf; }
private:
const jrd_req* const m_stmt;
const JrdStatement* const m_stmt;
Firebird::PerformanceInfo* const m_perf;
};
@ -177,7 +177,7 @@ class TraceSQLStatementImpl :
public Firebird::AutoIface<Firebird::ITraceSQLStatementImpl<TraceSQLStatementImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceSQLStatementImpl(const dsql_req* stmt, Firebird::PerformanceInfo* perf) :
TraceSQLStatementImpl(DsqlRequest* stmt, Firebird::PerformanceInfo* perf) :
m_stmt(stmt),
m_perf(perf),
m_planExplained(false),
@ -198,7 +198,7 @@ private:
public Firebird::AutoIface<Firebird::ITraceParamsImpl<DSQLParamsImpl, Firebird::CheckStatusWrapper> >
{
public:
DSQLParamsImpl(Firebird::MemoryPool& pool, const dsql_req* const stmt) :
DSQLParamsImpl(Firebird::MemoryPool& pool, DsqlRequest* const stmt) :
m_stmt(stmt),
m_params(NULL),
m_descs(pool)
@ -215,7 +215,7 @@ private:
private:
void fillParams();
const dsql_req* const m_stmt;
DsqlRequest* const m_stmt;
const Firebird::Array<dsql_par*>* m_params;
Firebird::HalfStaticArray<dsc, 16> m_descs;
Firebird::string temp_utf8_text;
@ -223,7 +223,7 @@ private:
void fillPlan(bool explained);
const dsql_req* const m_stmt;
DsqlRequest* const m_stmt;
Firebird::PerformanceInfo* const m_perf;
Firebird::string m_plan;
bool m_planExplained;