mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 16:43:03 +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:
parent
1a072f43d8
commit
391e7ef4fc
@ -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" />
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
1123
src/dsql/DsqlRequests.cpp
Normal file
File diff suppressed because it is too large
Load Diff
271
src/dsql/DsqlRequests.h
Normal file
271
src/dsql/DsqlRequests.h
Normal 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
298
src/dsql/DsqlStatements.cpp
Normal 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
292
src/dsql/DsqlStatements.h
Normal 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
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
1557
src/dsql/dsql.cpp
1557
src/dsql/dsql.cpp
File diff suppressed because it is too large
Load Diff
321
src/dsql/dsql.h
321
src/dsql/dsql.h
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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*);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 ->()
|
||||
|
@ -392,7 +392,7 @@ void InternalTransaction::doRollback(FbStatusVector* status, thread_db* tdbb, bo
|
||||
else
|
||||
m_transaction->rollback(status);
|
||||
|
||||
if (status->getState() & IStatus::STATE_ERRORS)
|
||||
if (status->getState() & IStatus::STATE_ERRORS)
|
||||
err = status->getErrors()[1];
|
||||
|
||||
if (err == isc_cancelled)
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "../jrd/lls.h"
|
||||
|
||||
namespace Jrd {
|
||||
class jrd_req;
|
||||
class JrdStatement;
|
||||
class jrd_rel;
|
||||
class RecordSource;
|
||||
struct index_desc;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user