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

Improvement #7652 - Make the profiler store aggregated requests by default, with option for detailed store.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Adriano dos Santos Fernandes 2023-06-26 22:53:23 -03:00
parent cfffebf92e
commit 00bb8e4581
9 changed files with 317 additions and 250 deletions

View File

@ -57,7 +57,7 @@ set term ;!
-- Start profiling
select rdb$profiler.start_session('Profile Session 1') from rdb$database;
select rdb$profiler.start_session('Profile Session 1', null, null, null, 'DETAILED_REQUESTS') from rdb$database;
set term !;
@ -126,16 +126,20 @@ select pstat.*
`RDB$PROFILER.START_SESSION` starts a new profiler session, makes it the current session (of the given `ATTACHMENT_ID`) and returns its identifier.
If `FLUSH_INTERVAL` is different from `NULL`, auto-flush is setup in the same way as manually calling `RDB$PROFILER.SET_FLUSH_INTERVAL`.
If `FLUSH_INTERVAL` is different than `NULL`, auto-flush is setup in the same way as manually calling `RDB$PROFILER.SET_FLUSH_INTERVAL`.
If `PLUGIN_NAME` is `NULL` (the default), it uses the database configuration `DefaultProfilerPlugin`.
`PLUGIN_OPTIONS` are plugin specific options and currently should be `NULL` for `Default_Profiler` plugin.
`PLUGIN_OPTIONS` are plugin specific options and currently could be `NULL` or the string `DETAILED_REQUESTS` for `Default_Profiler` plugin.
When `DETAILED_REQUESTS` is used, `PLG$PROF_REQUESTS` will store detailed requests data, i.e., one record per each invocation of a statement. This may generate a lot of records, causing `RDB$PROFILER.FLUSH` to be slow.
When `DETAILED_REQUESTS` is not used (the default), `PLG$PROF_REQUESTS` stores an aggregated record per statement, using `REQUEST_ID = 0`.
Input parameters:
- `DESCRIPTION` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
- `FLUSH_INTERVAL` type `INTEGER` default `NULL`
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
- `PLUGIN_NAME` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
- `PLUGIN_OPTIONS` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
@ -151,14 +155,14 @@ Calling `RDB$PROFILER.PAUSE_SESSION(TRUE)` has the same semantics of calling `RD
Input parameters:
- `FLUSH` type `BOOLEAN NOT NULL` default `FALSE`
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
## Procedure `RESUME_SESSION`
`RDB$PROFILER.RESUME_SESSION` resumes the current profiler session (of the given `ATTACHMENT_ID`), if it was paused, so the next executed statements statistics are collected again.
Input parameters:
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
## Procedure `FINISH_SESSION`
@ -170,7 +174,7 @@ Calling `RDB$PROFILER.FINISH_SESSION(TRUE)` has the same semantics of calling `R
Input parameters:
- `FLUSH` type `BOOLEAN NOT NULL` default `TRUE`
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
## Procedure `CANCEL_SESSION`
@ -181,7 +185,7 @@ All session data present in the profiler plugin is discarded and will not be flu
Data already flushed is not deleted automatically.
Input parameters:
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
## Procedure `DISCARD`
@ -190,7 +194,7 @@ Input parameters:
If there is a active session, it is cancelled.
Input parameters:
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
## Procedure `FLUSH`
@ -203,7 +207,7 @@ Data is updated using an autonomous transaction, so if the procedure is called i
Once flush happens, finished sessions are removed from memory.
Input parameters:
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
## Procedure `SET_FLUSH_INTERVAL`
@ -213,7 +217,7 @@ Input parameters:
Input parameters:
- `FLUSH_INTERVAL` type `INTEGER NOT NULL`
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
- `ATTACHMENT_ID` type `BIGINT` default `NULL` (meaning `CURRENT_CONNECTION`)
# Snapshot tables
@ -267,34 +271,35 @@ Below is the list of tables that stores profile data.
## Table `PLG$PROF_REQUESTS`
- `PROFILE_ID` type `BIGINT` - Profile session ID
- `REQUEST_ID` type `BIGINT` - Request ID
- `STATEMENT_ID` type `BIGINT` - Statement ID
- `REQUEST_ID` type `BIGINT` - Request ID
- `CALLER_STATEMENT_ID` type `BIGINT` - Caller statement ID
- `CALLER_REQUEST_ID` type `BIGINT` - Caller request ID
- `START_TIMESTAMP` type `TIMESTAMP WITH TIME ZONE` - Moment this request was first gathered profile data
- `FINISH_TIMESTAMP` type `TIMESTAMP WITH TIME ZONE` - Moment this request was finished
- `TOTAL_ELAPSED_TIME` type `BIGINT` - Accumulated elapsed time (in nanoseconds) of the request
- Primary key: `PROFILE_ID, REQUEST_ID`
- Primary key: `PROFILE_ID, STATEMENT_ID, REQUEST_ID`
## Table `PLG$PROF_PSQL_STATS`
- `PROFILE_ID` type `BIGINT` - Profile session ID
- `STATEMENT_ID` type `BIGINT` - Statement ID
- `REQUEST_ID` type `BIGINT` - Request ID
- `LINE_NUM` type `INTEGER` - Line number of the statement
- `COLUMN_NUM` type `INTEGER` - Column number of the statement
- `STATEMENT_ID` type `BIGINT` - Statement ID
- `COUNTER` type `BIGINT` - Number of executed times of the line/column
- `MIN_ELAPSED_TIME` type `BIGINT` - Minimal elapsed time (in nanoseconds) of a line/column execution
- `MAX_ELAPSED_TIME` type `BIGINT` - Maximum elapsed time (in nanoseconds) of a line/column execution
- `TOTAL_ELAPSED_TIME` type `BIGINT` - Accumulated elapsed time (in nanoseconds) of the line/column executions
- Primary key: `PROFILE_ID, REQUEST_ID, LINE_NUM, COLUMN_NUM`
- Primary key: `PROFILE_ID, STATEMENT_ID, REQUEST_ID, LINE_NUM, COLUMN_NUM`
## Table `PLG$PROF_RECORD_SOURCE_STATS`
- `PROFILE_ID` type `BIGINT` - Profile session ID
- `STATEMENT_ID` type `BIGINT` - Statement ID
- `REQUEST_ID` type `BIGINT` - Request ID
- `CURSOR_ID` type `INTEGER` - Cursor ID
- `RECORD_SOURCE_ID` type `INTEGER` - Record source ID
- `STATEMENT_ID` type `BIGINT` - Statement ID
- `OPEN_COUNTER` type `BIGINT` - Number of open times of the record source
- `OPEN_MIN_ELAPSED_TIME` type `BIGINT` - Minimal elapsed time (in nanoseconds) of a record source open
- `OPEN_MAX_ELAPSED_TIME` type `BIGINT` - Maximum elapsed time (in nanoseconds) of a record source open
@ -303,7 +308,7 @@ Below is the list of tables that stores profile data.
- `FETCH_MIN_ELAPSED_TIME` type `BIGINT` - Minimal elapsed time (in nanoseconds) of a record source fetch
- `FETCH_MAX_ELAPSED_TIME` type `BIGINT` - Maximum elapsed time (in nanoseconds) of a record source fetch
- `FETCH_TOTAL_ELAPSED_TIME` type `BIGINT` - Accumulated elapsed time (in nanoseconds) of the record source fetches
- Primary key: `PROFILE_ID, REQUEST_ID, CURSOR_ID, RECORD_SOURCE_ID`
- Primary key: `PROFILE_ID, STATEMENT_ID, REQUEST_ID, CURSOR_ID, RECORD_SOURCE_ID`
# Auxiliary views

View File

@ -1746,19 +1746,22 @@ interface ProfilerSession : Disposable
void defineRecordSource(int64 statementId, uint cursorId, uint recSourceId,
const string accessPath, uint parentRecSourceId);
void onRequestStart(Status status, int64 requestId, int64 statementId, int64 callerRequestId,
ISC_TIMESTAMP_TZ timestamp);
void onRequestStart(Status status, int64 statementId, int64 requestId,
int64 callerStatementId, int64 callerRequestId, ISC_TIMESTAMP_TZ timestamp);
void onRequestFinish(Status status, int64 requestId, ISC_TIMESTAMP_TZ timestamp, ProfilerStats stats);
void onRequestFinish(Status status, int64 statementId, int64 requestId,
ISC_TIMESTAMP_TZ timestamp, ProfilerStats stats);
void beforePsqlLineColumn(int64 requestId, uint line, uint column);
void afterPsqlLineColumn(int64 requestId, uint line, uint column, ProfilerStats stats);
void beforePsqlLineColumn(int64 statementId, int64 requestId, uint line, uint column);
void afterPsqlLineColumn(int64 statementId, int64 requestId, uint line, uint column, ProfilerStats stats);
void beforeRecordSourceOpen(int64 requestId, uint cursorId, uint recSourceId);
void afterRecordSourceOpen(int64 requestId, uint cursorId, uint recSourceId, ProfilerStats stats);
void beforeRecordSourceOpen(int64 statementId, int64 requestId, uint cursorId, uint recSourceId);
void afterRecordSourceOpen(int64 statementId, int64 requestId, uint cursorId, uint recSourceId,
ProfilerStats stats);
void beforeRecordSourceGetRecord(int64 requestId, uint cursorId, uint recSourceId);
void afterRecordSourceGetRecord(int64 requestId, uint cursorId, uint recSourceId, ProfilerStats stats);
void beforeRecordSourceGetRecord(int64 statementId, int64 requestId, uint cursorId, uint recSourceId);
void afterRecordSourceGetRecord(int64 statementId, int64 requestId, uint cursorId, uint recSourceId,
ProfilerStats stats);
}
interface ProfilerStats : Versioned

View File

@ -6955,14 +6955,14 @@ namespace Firebird
void (CLOOP_CARG *defineStatement)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) CLOOP_NOEXCEPT;
void (CLOOP_CARG *defineCursor)(IProfilerSession* self, ISC_INT64 statementId, unsigned cursorId, const char* name, unsigned line, unsigned column) CLOOP_NOEXCEPT;
void (CLOOP_CARG *defineRecordSource)(IProfilerSession* self, ISC_INT64 statementId, unsigned cursorId, unsigned recSourceId, const char* accessPath, unsigned parentRecSourceId) CLOOP_NOEXCEPT;
void (CLOOP_CARG *onRequestStart)(IProfilerSession* self, IStatus* status, ISC_INT64 requestId, ISC_INT64 statementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) CLOOP_NOEXCEPT;
void (CLOOP_CARG *onRequestFinish)(IProfilerSession* self, IStatus* status, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *beforePsqlLineColumn)(IProfilerSession* self, ISC_INT64 requestId, unsigned line, unsigned column) CLOOP_NOEXCEPT;
void (CLOOP_CARG *afterPsqlLineColumn)(IProfilerSession* self, ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *beforeRecordSourceOpen)(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT;
void (CLOOP_CARG *afterRecordSourceOpen)(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *beforeRecordSourceGetRecord)(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT;
void (CLOOP_CARG *afterRecordSourceGetRecord)(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *onRequestStart)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_INT64 callerStatementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) CLOOP_NOEXCEPT;
void (CLOOP_CARG *onRequestFinish)(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *beforePsqlLineColumn)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column) CLOOP_NOEXCEPT;
void (CLOOP_CARG *afterPsqlLineColumn)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *beforeRecordSourceOpen)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT;
void (CLOOP_CARG *afterRecordSourceOpen)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT;
void (CLOOP_CARG *beforeRecordSourceGetRecord)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT;
void (CLOOP_CARG *afterRecordSourceGetRecord)(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT;
};
protected:
@ -7024,48 +7024,48 @@ namespace Firebird
static_cast<VTable*>(this->cloopVTable)->defineRecordSource(this, statementId, cursorId, recSourceId, accessPath, parentRecSourceId);
}
template <typename StatusType> void onRequestStart(StatusType* status, ISC_INT64 requestId, ISC_INT64 statementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp)
template <typename StatusType> void onRequestStart(StatusType* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_INT64 callerStatementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->onRequestStart(this, status, requestId, statementId, callerRequestId, timestamp);
static_cast<VTable*>(this->cloopVTable)->onRequestStart(this, status, statementId, requestId, callerStatementId, callerRequestId, timestamp);
StatusType::checkException(status);
}
template <typename StatusType> void onRequestFinish(StatusType* status, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats)
template <typename StatusType> void onRequestFinish(StatusType* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats)
{
StatusType::clearException(status);
static_cast<VTable*>(this->cloopVTable)->onRequestFinish(this, status, requestId, timestamp, stats);
static_cast<VTable*>(this->cloopVTable)->onRequestFinish(this, status, statementId, requestId, timestamp, stats);
StatusType::checkException(status);
}
void beforePsqlLineColumn(ISC_INT64 requestId, unsigned line, unsigned column)
void beforePsqlLineColumn(ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column)
{
static_cast<VTable*>(this->cloopVTable)->beforePsqlLineColumn(this, requestId, line, column);
static_cast<VTable*>(this->cloopVTable)->beforePsqlLineColumn(this, statementId, requestId, line, column);
}
void afterPsqlLineColumn(ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats)
void afterPsqlLineColumn(ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats)
{
static_cast<VTable*>(this->cloopVTable)->afterPsqlLineColumn(this, requestId, line, column, stats);
static_cast<VTable*>(this->cloopVTable)->afterPsqlLineColumn(this, statementId, requestId, line, column, stats);
}
void beforeRecordSourceOpen(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId)
void beforeRecordSourceOpen(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId)
{
static_cast<VTable*>(this->cloopVTable)->beforeRecordSourceOpen(this, requestId, cursorId, recSourceId);
static_cast<VTable*>(this->cloopVTable)->beforeRecordSourceOpen(this, statementId, requestId, cursorId, recSourceId);
}
void afterRecordSourceOpen(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats)
void afterRecordSourceOpen(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats)
{
static_cast<VTable*>(this->cloopVTable)->afterRecordSourceOpen(this, requestId, cursorId, recSourceId, stats);
static_cast<VTable*>(this->cloopVTable)->afterRecordSourceOpen(this, statementId, requestId, cursorId, recSourceId, stats);
}
void beforeRecordSourceGetRecord(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId)
void beforeRecordSourceGetRecord(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId)
{
static_cast<VTable*>(this->cloopVTable)->beforeRecordSourceGetRecord(this, requestId, cursorId, recSourceId);
static_cast<VTable*>(this->cloopVTable)->beforeRecordSourceGetRecord(this, statementId, requestId, cursorId, recSourceId);
}
void afterRecordSourceGetRecord(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats)
void afterRecordSourceGetRecord(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats)
{
static_cast<VTable*>(this->cloopVTable)->afterRecordSourceGetRecord(this, requestId, cursorId, recSourceId, stats);
static_cast<VTable*>(this->cloopVTable)->afterRecordSourceGetRecord(this, statementId, requestId, cursorId, recSourceId, stats);
}
};
@ -20540,13 +20540,13 @@ namespace Firebird
}
}
static void CLOOP_CARG clooponRequestStartDispatcher(IProfilerSession* self, IStatus* status, ISC_INT64 requestId, ISC_INT64 statementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) CLOOP_NOEXCEPT
static void CLOOP_CARG clooponRequestStartDispatcher(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_INT64 callerStatementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::onRequestStart(&status2, requestId, statementId, callerRequestId, timestamp);
static_cast<Name*>(self)->Name::onRequestStart(&status2, statementId, requestId, callerStatementId, callerRequestId, timestamp);
}
catch (...)
{
@ -20554,13 +20554,13 @@ namespace Firebird
}
}
static void CLOOP_CARG clooponRequestFinishDispatcher(IProfilerSession* self, IStatus* status, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats) CLOOP_NOEXCEPT
static void CLOOP_CARG clooponRequestFinishDispatcher(IProfilerSession* self, IStatus* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats) CLOOP_NOEXCEPT
{
StatusType status2(status);
try
{
static_cast<Name*>(self)->Name::onRequestFinish(&status2, requestId, timestamp, stats);
static_cast<Name*>(self)->Name::onRequestFinish(&status2, statementId, requestId, timestamp, stats);
}
catch (...)
{
@ -20568,11 +20568,11 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopbeforePsqlLineColumnDispatcher(IProfilerSession* self, ISC_INT64 requestId, unsigned line, unsigned column) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopbeforePsqlLineColumnDispatcher(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column) CLOOP_NOEXCEPT
{
try
{
static_cast<Name*>(self)->Name::beforePsqlLineColumn(requestId, line, column);
static_cast<Name*>(self)->Name::beforePsqlLineColumn(statementId, requestId, line, column);
}
catch (...)
{
@ -20580,11 +20580,11 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopafterPsqlLineColumnDispatcher(IProfilerSession* self, ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopafterPsqlLineColumnDispatcher(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats) CLOOP_NOEXCEPT
{
try
{
static_cast<Name*>(self)->Name::afterPsqlLineColumn(requestId, line, column, stats);
static_cast<Name*>(self)->Name::afterPsqlLineColumn(statementId, requestId, line, column, stats);
}
catch (...)
{
@ -20592,11 +20592,11 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopbeforeRecordSourceOpenDispatcher(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopbeforeRecordSourceOpenDispatcher(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT
{
try
{
static_cast<Name*>(self)->Name::beforeRecordSourceOpen(requestId, cursorId, recSourceId);
static_cast<Name*>(self)->Name::beforeRecordSourceOpen(statementId, requestId, cursorId, recSourceId);
}
catch (...)
{
@ -20604,11 +20604,11 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopafterRecordSourceOpenDispatcher(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopafterRecordSourceOpenDispatcher(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT
{
try
{
static_cast<Name*>(self)->Name::afterRecordSourceOpen(requestId, cursorId, recSourceId, stats);
static_cast<Name*>(self)->Name::afterRecordSourceOpen(statementId, requestId, cursorId, recSourceId, stats);
}
catch (...)
{
@ -20616,11 +20616,11 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopbeforeRecordSourceGetRecordDispatcher(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopbeforeRecordSourceGetRecordDispatcher(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) CLOOP_NOEXCEPT
{
try
{
static_cast<Name*>(self)->Name::beforeRecordSourceGetRecord(requestId, cursorId, recSourceId);
static_cast<Name*>(self)->Name::beforeRecordSourceGetRecord(statementId, requestId, cursorId, recSourceId);
}
catch (...)
{
@ -20628,11 +20628,11 @@ namespace Firebird
}
}
static void CLOOP_CARG cloopafterRecordSourceGetRecordDispatcher(IProfilerSession* self, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT
static void CLOOP_CARG cloopafterRecordSourceGetRecordDispatcher(IProfilerSession* self, ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) CLOOP_NOEXCEPT
{
try
{
static_cast<Name*>(self)->Name::afterRecordSourceGetRecord(requestId, cursorId, recSourceId, stats);
static_cast<Name*>(self)->Name::afterRecordSourceGetRecord(statementId, requestId, cursorId, recSourceId, stats);
}
catch (...)
{
@ -20673,14 +20673,14 @@ namespace Firebird
virtual void defineStatement(StatusType* status, ISC_INT64 statementId, ISC_INT64 parentStatementId, const char* type, const char* packageName, const char* routineName, const char* sqlText) = 0;
virtual void defineCursor(ISC_INT64 statementId, unsigned cursorId, const char* name, unsigned line, unsigned column) = 0;
virtual void defineRecordSource(ISC_INT64 statementId, unsigned cursorId, unsigned recSourceId, const char* accessPath, unsigned parentRecSourceId) = 0;
virtual void onRequestStart(StatusType* status, ISC_INT64 requestId, ISC_INT64 statementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) = 0;
virtual void onRequestFinish(StatusType* status, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats) = 0;
virtual void beforePsqlLineColumn(ISC_INT64 requestId, unsigned line, unsigned column) = 0;
virtual void afterPsqlLineColumn(ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats) = 0;
virtual void beforeRecordSourceOpen(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) = 0;
virtual void afterRecordSourceOpen(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) = 0;
virtual void beforeRecordSourceGetRecord(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) = 0;
virtual void afterRecordSourceGetRecord(ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) = 0;
virtual void onRequestStart(StatusType* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_INT64 callerStatementId, ISC_INT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) = 0;
virtual void onRequestFinish(StatusType* status, ISC_INT64 statementId, ISC_INT64 requestId, ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats) = 0;
virtual void beforePsqlLineColumn(ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column) = 0;
virtual void afterPsqlLineColumn(ISC_INT64 statementId, ISC_INT64 requestId, unsigned line, unsigned column, IProfilerStats* stats) = 0;
virtual void beforeRecordSourceOpen(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) = 0;
virtual void afterRecordSourceOpen(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) = 0;
virtual void beforeRecordSourceGetRecord(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId) = 0;
virtual void afterRecordSourceGetRecord(ISC_INT64 statementId, ISC_INT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats) = 0;
};
template <typename Name, typename StatusType, typename Base>

View File

@ -728,14 +728,14 @@ type
IProfilerSession_defineStatementPtr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); cdecl;
IProfilerSession_defineCursorPtr = procedure(this: IProfilerSession; statementId: Int64; cursorId: Cardinal; name: PAnsiChar; line: Cardinal; column: Cardinal); cdecl;
IProfilerSession_defineRecordSourcePtr = procedure(this: IProfilerSession; statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal); cdecl;
IProfilerSession_onRequestStartPtr = procedure(this: IProfilerSession; status: IStatus; requestId: Int64; statementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); cdecl;
IProfilerSession_onRequestFinishPtr = procedure(this: IProfilerSession; status: IStatus; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats); cdecl;
IProfilerSession_beforePsqlLineColumnPtr = procedure(this: IProfilerSession; requestId: Int64; line: Cardinal; column: Cardinal); cdecl;
IProfilerSession_afterPsqlLineColumnPtr = procedure(this: IProfilerSession; requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_beforeRecordSourceOpenPtr = procedure(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
IProfilerSession_afterRecordSourceOpenPtr = procedure(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_beforeRecordSourceGetRecordPtr = procedure(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
IProfilerSession_afterRecordSourceGetRecordPtr = procedure(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_onRequestStartPtr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); cdecl;
IProfilerSession_onRequestFinishPtr = procedure(this: IProfilerSession; status: IStatus; statementId: Int64; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats); cdecl;
IProfilerSession_beforePsqlLineColumnPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal); cdecl;
IProfilerSession_afterPsqlLineColumnPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_beforeRecordSourceOpenPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
IProfilerSession_afterRecordSourceOpenPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
IProfilerSession_beforeRecordSourceGetRecordPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
IProfilerSession_afterRecordSourceGetRecordPtr = procedure(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
IProfilerStats_getElapsedTicksPtr = function(this: IProfilerStats): QWord; cdecl;
VersionedVTable = class
@ -3839,14 +3839,14 @@ type
procedure defineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar);
procedure defineCursor(statementId: Int64; cursorId: Cardinal; name: PAnsiChar; line: Cardinal; column: Cardinal);
procedure defineRecordSource(statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal);
procedure onRequestStart(status: IStatus; requestId: Int64; statementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ);
procedure onRequestFinish(status: IStatus; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats);
procedure beforePsqlLineColumn(requestId: Int64; line: Cardinal; column: Cardinal);
procedure afterPsqlLineColumn(requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats);
procedure beforeRecordSourceOpen(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure afterRecordSourceOpen(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure beforeRecordSourceGetRecord(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure afterRecordSourceGetRecord(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure onRequestStart(status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ);
procedure onRequestFinish(status: IStatus; statementId: Int64; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats);
procedure beforePsqlLineColumn(statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal);
procedure afterPsqlLineColumn(statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats);
procedure beforeRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure afterRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure beforeRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure afterRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
end;
IProfilerSessionImpl = class(IProfilerSession)
@ -3860,14 +3860,14 @@ type
procedure defineStatement(status: IStatus; statementId: Int64; parentStatementId: Int64; type_: PAnsiChar; packageName: PAnsiChar; routineName: PAnsiChar; sqlText: PAnsiChar); virtual; abstract;
procedure defineCursor(statementId: Int64; cursorId: Cardinal; name: PAnsiChar; line: Cardinal; column: Cardinal); virtual; abstract;
procedure defineRecordSource(statementId: Int64; cursorId: Cardinal; recSourceId: Cardinal; accessPath: PAnsiChar; parentRecSourceId: Cardinal); virtual; abstract;
procedure onRequestStart(status: IStatus; requestId: Int64; statementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); virtual; abstract;
procedure onRequestFinish(status: IStatus; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats); virtual; abstract;
procedure beforePsqlLineColumn(requestId: Int64; line: Cardinal; column: Cardinal); virtual; abstract;
procedure afterPsqlLineColumn(requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats); virtual; abstract;
procedure beforeRecordSourceOpen(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); virtual; abstract;
procedure afterRecordSourceOpen(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); virtual; abstract;
procedure beforeRecordSourceGetRecord(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); virtual; abstract;
procedure afterRecordSourceGetRecord(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); virtual; abstract;
procedure onRequestStart(status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); virtual; abstract;
procedure onRequestFinish(status: IStatus; statementId: Int64; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats); virtual; abstract;
procedure beforePsqlLineColumn(statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal); virtual; abstract;
procedure afterPsqlLineColumn(statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats); virtual; abstract;
procedure beforeRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); virtual; abstract;
procedure afterRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); virtual; abstract;
procedure beforeRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); virtual; abstract;
procedure afterRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); virtual; abstract;
end;
ProfilerStatsVTable = class(VersionedVTable)
@ -9433,46 +9433,46 @@ begin
ProfilerSessionVTable(vTable).defineRecordSource(Self, statementId, cursorId, recSourceId, accessPath, parentRecSourceId);
end;
procedure IProfilerSession.onRequestStart(status: IStatus; requestId: Int64; statementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ);
procedure IProfilerSession.onRequestStart(status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ);
begin
ProfilerSessionVTable(vTable).onRequestStart(Self, status, requestId, statementId, callerRequestId, timestamp);
ProfilerSessionVTable(vTable).onRequestStart(Self, status, statementId, requestId, callerStatementId, callerRequestId, timestamp);
FbException.checkException(status);
end;
procedure IProfilerSession.onRequestFinish(status: IStatus; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats);
procedure IProfilerSession.onRequestFinish(status: IStatus; statementId: Int64; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats);
begin
ProfilerSessionVTable(vTable).onRequestFinish(Self, status, requestId, timestamp, stats);
ProfilerSessionVTable(vTable).onRequestFinish(Self, status, statementId, requestId, timestamp, stats);
FbException.checkException(status);
end;
procedure IProfilerSession.beforePsqlLineColumn(requestId: Int64; line: Cardinal; column: Cardinal);
procedure IProfilerSession.beforePsqlLineColumn(statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal);
begin
ProfilerSessionVTable(vTable).beforePsqlLineColumn(Self, requestId, line, column);
ProfilerSessionVTable(vTable).beforePsqlLineColumn(Self, statementId, requestId, line, column);
end;
procedure IProfilerSession.afterPsqlLineColumn(requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats);
procedure IProfilerSession.afterPsqlLineColumn(statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats);
begin
ProfilerSessionVTable(vTable).afterPsqlLineColumn(Self, requestId, line, column, stats);
ProfilerSessionVTable(vTable).afterPsqlLineColumn(Self, statementId, requestId, line, column, stats);
end;
procedure IProfilerSession.beforeRecordSourceOpen(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure IProfilerSession.beforeRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
begin
ProfilerSessionVTable(vTable).beforeRecordSourceOpen(Self, requestId, cursorId, recSourceId);
ProfilerSessionVTable(vTable).beforeRecordSourceOpen(Self, statementId, requestId, cursorId, recSourceId);
end;
procedure IProfilerSession.afterRecordSourceOpen(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure IProfilerSession.afterRecordSourceOpen(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
begin
ProfilerSessionVTable(vTable).afterRecordSourceOpen(Self, requestId, cursorId, recSourceId, stats);
ProfilerSessionVTable(vTable).afterRecordSourceOpen(Self, statementId, requestId, cursorId, recSourceId, stats);
end;
procedure IProfilerSession.beforeRecordSourceGetRecord(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
procedure IProfilerSession.beforeRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal);
begin
ProfilerSessionVTable(vTable).beforeRecordSourceGetRecord(Self, requestId, cursorId, recSourceId);
ProfilerSessionVTable(vTable).beforeRecordSourceGetRecord(Self, statementId, requestId, cursorId, recSourceId);
end;
procedure IProfilerSession.afterRecordSourceGetRecord(requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
procedure IProfilerSession.afterRecordSourceGetRecord(statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats);
begin
ProfilerSessionVTable(vTable).afterRecordSourceGetRecord(Self, requestId, cursorId, recSourceId, stats);
ProfilerSessionVTable(vTable).afterRecordSourceGetRecord(Self, statementId, requestId, cursorId, recSourceId, stats);
end;
function IProfilerStats.getElapsedTicks(): QWord;
@ -16550,73 +16550,73 @@ begin
end
end;
procedure IProfilerSessionImpl_onRequestStartDispatcher(this: IProfilerSession; status: IStatus; requestId: Int64; statementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); cdecl;
procedure IProfilerSessionImpl_onRequestStartDispatcher(this: IProfilerSession; status: IStatus; statementId: Int64; requestId: Int64; callerStatementId: Int64; callerRequestId: Int64; timestamp: ISC_TIMESTAMP_TZ); cdecl;
begin
try
IProfilerSessionImpl(this).onRequestStart(status, requestId, statementId, callerRequestId, timestamp);
IProfilerSessionImpl(this).onRequestStart(status, statementId, requestId, callerStatementId, callerRequestId, timestamp);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IProfilerSessionImpl_onRequestFinishDispatcher(this: IProfilerSession; status: IStatus; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats); cdecl;
procedure IProfilerSessionImpl_onRequestFinishDispatcher(this: IProfilerSession; status: IStatus; statementId: Int64; requestId: Int64; timestamp: ISC_TIMESTAMP_TZ; stats: IProfilerStats); cdecl;
begin
try
IProfilerSessionImpl(this).onRequestFinish(status, requestId, timestamp, stats);
IProfilerSessionImpl(this).onRequestFinish(status, statementId, requestId, timestamp, stats);
except
on e: Exception do FbException.catchException(status, e);
end
end;
procedure IProfilerSessionImpl_beforePsqlLineColumnDispatcher(this: IProfilerSession; requestId: Int64; line: Cardinal; column: Cardinal); cdecl;
procedure IProfilerSessionImpl_beforePsqlLineColumnDispatcher(this: IProfilerSession; statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal); cdecl;
begin
try
IProfilerSessionImpl(this).beforePsqlLineColumn(requestId, line, column);
IProfilerSessionImpl(this).beforePsqlLineColumn(statementId, requestId, line, column);
except
on e: Exception do FbException.catchException(nil, e);
end
end;
procedure IProfilerSessionImpl_afterPsqlLineColumnDispatcher(this: IProfilerSession; requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats); cdecl;
procedure IProfilerSessionImpl_afterPsqlLineColumnDispatcher(this: IProfilerSession; statementId: Int64; requestId: Int64; line: Cardinal; column: Cardinal; stats: IProfilerStats); cdecl;
begin
try
IProfilerSessionImpl(this).afterPsqlLineColumn(requestId, line, column, stats);
IProfilerSessionImpl(this).afterPsqlLineColumn(statementId, requestId, line, column, stats);
except
on e: Exception do FbException.catchException(nil, e);
end
end;
procedure IProfilerSessionImpl_beforeRecordSourceOpenDispatcher(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
procedure IProfilerSessionImpl_beforeRecordSourceOpenDispatcher(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
begin
try
IProfilerSessionImpl(this).beforeRecordSourceOpen(requestId, cursorId, recSourceId);
IProfilerSessionImpl(this).beforeRecordSourceOpen(statementId, requestId, cursorId, recSourceId);
except
on e: Exception do FbException.catchException(nil, e);
end
end;
procedure IProfilerSessionImpl_afterRecordSourceOpenDispatcher(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
procedure IProfilerSessionImpl_afterRecordSourceOpenDispatcher(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
begin
try
IProfilerSessionImpl(this).afterRecordSourceOpen(requestId, cursorId, recSourceId, stats);
IProfilerSessionImpl(this).afterRecordSourceOpen(statementId, requestId, cursorId, recSourceId, stats);
except
on e: Exception do FbException.catchException(nil, e);
end
end;
procedure IProfilerSessionImpl_beforeRecordSourceGetRecordDispatcher(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
procedure IProfilerSessionImpl_beforeRecordSourceGetRecordDispatcher(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal); cdecl;
begin
try
IProfilerSessionImpl(this).beforeRecordSourceGetRecord(requestId, cursorId, recSourceId);
IProfilerSessionImpl(this).beforeRecordSourceGetRecord(statementId, requestId, cursorId, recSourceId);
except
on e: Exception do FbException.catchException(nil, e);
end
end;
procedure IProfilerSessionImpl_afterRecordSourceGetRecordDispatcher(this: IProfilerSession; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
procedure IProfilerSessionImpl_afterRecordSourceGetRecordDispatcher(this: IProfilerSession; statementId: Int64; requestId: Int64; cursorId: Cardinal; recSourceId: Cardinal; stats: IProfilerStats); cdecl;
begin
try
IProfilerSessionImpl(this).afterRecordSourceGetRecord(requestId, cursorId, recSourceId, stats);
IProfilerSessionImpl(this).afterRecordSourceGetRecord(statementId, requestId, cursorId, recSourceId, stats);
except
on e: Exception do FbException.catchException(nil, e);
end

View File

@ -588,7 +588,15 @@ public:
ULONG att_flags; // Flags describing the state of the attachment
SSHORT att_client_charset; // user's charset specified in dpb
SSHORT att_charset; // current (client or external) attachment charset
// ASF: Attention: att_in_system_routine was initially added to support the profiler plugin
// writing to system tables. But a modified implementation used non-system tables and
// a problem was discovered that when writing to user's table from a "system context"
// (csb_internal) FK validations are not enforced becase MET_scan_relation is not called
// for the relation.
// Currently all "turning on" code for att_in_system_routine are disabled in SystemPackages.h.
bool att_in_system_routine = false; // running a system routine
Lock* att_long_locks; // outstanding two phased locks
#ifdef DEBUG_LCK_LIST
UCHAR att_long_locks_type; // Lock type of the first lock in list

View File

@ -186,7 +186,7 @@ IExternalResultSet* ProfilerPackage::discardProcedure(ThrowStatusExceptionWrappe
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.send(tdbb, ProfilerIpc::Tag::DISCARD, in);
@ -206,7 +206,7 @@ IExternalResultSet* ProfilerPackage::flushProcedure(ThrowStatusExceptionWrapper*
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.send(tdbb, ProfilerIpc::Tag::FLUSH, in);
@ -226,7 +226,7 @@ IExternalResultSet* ProfilerPackage::cancelSessionProcedure(ThrowStatusException
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.send(tdbb, ProfilerIpc::Tag::CANCEL_SESSION, in);
@ -247,7 +247,7 @@ IExternalResultSet* ProfilerPackage::finishSessionProcedure(ThrowStatusException
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.send(tdbb, ProfilerIpc::Tag::FINISH_SESSION, in);
@ -267,7 +267,7 @@ IExternalResultSet* ProfilerPackage::pauseSessionProcedure(ThrowStatusExceptionW
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.send(tdbb, ProfilerIpc::Tag::PAUSE_SESSION, in);
@ -287,7 +287,7 @@ IExternalResultSet* ProfilerPackage::resumeSessionProcedure(ThrowStatusException
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.send(tdbb, ProfilerIpc::Tag::RESUME_SESSION, in);
@ -307,7 +307,7 @@ IExternalResultSet* ProfilerPackage::setFlushIntervalProcedure(ThrowStatusExcept
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.send(tdbb, ProfilerIpc::Tag::SET_FLUSH_INTERVAL, in);
@ -327,7 +327,7 @@ void ProfilerPackage::startSessionFunction(ThrowStatusExceptionWrapper* /*status
const auto tdbb = JRD_get_thread_data();
const auto attachment = tdbb->getAttachment();
if (AttNumber(in->attachmentId) != attachment->att_attachment_id)
if (!in->attachmentIdNull && AttNumber(in->attachmentId) != attachment->att_attachment_id)
{
ProfilerIpc ipc(tdbb, *getDefaultMemoryPool(), in->attachmentId);
ipc.sendAndReceive(tdbb, ProfilerIpc::Tag::START_SESSION, in, out);
@ -551,10 +551,12 @@ void ProfilerManager::onRequestFinish(Request* request, Stats& stats)
{
if (const auto profileRequestId = getRequest(request, 0))
{
const auto profileStatement = getStatement(request);
const auto timestamp = TimeZoneUtil::getCurrentTimeStamp(request->req_attachment->att_current_timezone);
LogLocalStatus status("Profiler onRequestFinish");
currentSession->pluginSession->onRequestFinish(&status, profileRequestId, timestamp, &stats);
currentSession->pluginSession->onRequestFinish(&status, profileStatement->id, profileRequestId,
timestamp, &stats);
currentSession->requests.findAndRemove(profileRequestId);
}
@ -1050,8 +1052,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
prc_executable,
// input parameters
{
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}}
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}}
},
// output parameters
{
@ -1064,8 +1065,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
prc_executable,
// input parameters
{
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}}
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}}
},
// output parameters
{
@ -1079,8 +1079,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
// input parameters
{
{"FLUSH", fld_bool, false, "true", {blr_literal, blr_bool, 1}},
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}}
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}}
},
// output parameters
{
@ -1093,8 +1092,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
prc_executable,
// input parameters
{
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}}
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}}
},
// output parameters
{
@ -1108,8 +1106,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
// input parameters
{
{"FLUSH", fld_bool, false, "false", {blr_literal, blr_bool, 0}},
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}}
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}}
},
// output parameters
{
@ -1122,8 +1119,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
prc_executable,
// input parameters
{
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}}
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}}
},
// output parameters
{
@ -1137,8 +1133,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
// input parameters
{
{"FLUSH_INTERVAL", fld_seconds_interval, false},
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}}
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}}
},
// output parameters
{
@ -1155,8 +1150,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
{
{"DESCRIPTION", fld_short_description, true, "null", {blr_null}},
{"FLUSH_INTERVAL", fld_seconds_interval, true, "null", {blr_null}},
{"ATTACHMENT_ID", fld_att_id, false, "current_connection",
{blr_internal_info, blr_literal, blr_long, 0, INFO_TYPE_CONNECTION_ID, 0, 0, 0}},
{"ATTACHMENT_ID", fld_att_id, true, "null", {blr_null}},
{"PLUGIN_NAME", fld_file_name2, true, "null", {blr_null}},
{"PLUGIN_OPTIONS", fld_short_description, true, "null", {blr_null}},
},

View File

@ -197,13 +197,20 @@ public:
void beforePsqlLineColumn(Request* request, ULONG line, ULONG column)
{
if (const auto profileRequestId = getRequest(request, Firebird::IProfilerSession::FLAG_BEFORE_EVENTS))
currentSession->pluginSession->beforePsqlLineColumn(profileRequestId, line, column);
{
const auto profileStatement = getStatement(request);
currentSession->pluginSession->beforePsqlLineColumn(profileStatement->id, profileRequestId, line, column);
}
}
void afterPsqlLineColumn(Request* request, ULONG line, ULONG column, Stats& stats)
{
if (const auto profileRequestId = getRequest(request, Firebird::IProfilerSession::FLAG_AFTER_EVENTS))
currentSession->pluginSession->afterPsqlLineColumn(profileRequestId, line, column, &stats);
{
const auto profileStatement = getStatement(request);
currentSession->pluginSession->afterPsqlLineColumn(profileStatement->id, profileRequestId,
line, column, &stats);
}
}
void beforeRecordSourceOpen(Request* request, const RecordSource* rsb)
@ -215,7 +222,7 @@ public:
fb_assert(sequencePtr);
currentSession->pluginSession->beforeRecordSourceOpen(
profileRequestId, rsb->getCursorProfileId(), *sequencePtr);
profileStatement->id, profileRequestId, rsb->getCursorProfileId(), *sequencePtr);
}
}
@ -228,7 +235,7 @@ public:
fb_assert(sequencePtr);
currentSession->pluginSession->afterRecordSourceOpen(
profileRequestId, rsb->getCursorProfileId(), *sequencePtr, &stats);
profileStatement->id, profileRequestId, rsb->getCursorProfileId(), *sequencePtr, &stats);
}
}
@ -241,7 +248,7 @@ public:
fb_assert(sequencePtr);
currentSession->pluginSession->beforeRecordSourceGetRecord(
profileRequestId, rsb->getCursorProfileId(), *sequencePtr);
profileStatement->id, profileRequestId, rsb->getCursorProfileId(), *sequencePtr);
}
}
@ -254,7 +261,7 @@ public:
fb_assert(sequencePtr);
currentSession->pluginSession->afterRecordSourceGetRecord(
profileRequestId, rsb->getCursorProfileId(), *sequencePtr, &stats);
profileStatement->id, profileRequestId, rsb->getCursorProfileId(), *sequencePtr, &stats);
}
}
@ -304,12 +311,14 @@ private:
{
getStatement(request); // define the statement and ignore the result
const StmtNumber callerStatementId = request->req_caller ?
request->req_caller->getStatement()->getStatementId() : 0;
const StmtNumber callerRequestId = request->req_caller ? request->req_caller->getRequestId() : 0;
LogLocalStatus status("Profiler onRequestStart");
currentSession->pluginSession->onRequestStart(&status,
(SINT64) request->getRequestId(), (SINT64) request->getStatement()->getStatementId(),
(SINT64) callerRequestId, timestamp);
(SINT64) request->getStatement()->getStatementId(), (SINT64) request->getRequestId(),
(SINT64) callerStatementId, (SINT64) callerRequestId, timestamp);
currentSession->requests.add(request->getRequestId());

View File

@ -262,7 +262,8 @@ namespace Jrd
public:
FB_BOOLEAN fetch(Firebird::ThrowStatusExceptionWrapper* status) override
{
Firebird::AutoSetRestore<bool> autoInSystemPackage(&attachment->att_in_system_routine, true);
// See comment in Attachment.h.
// Firebird::AutoSetRestore<bool> autoInSystemPackage(&attachment->att_in_system_routine, true);
return resultSet->fetch(status);
}
@ -308,7 +309,8 @@ namespace Jrd
Firebird::IExternalResultSet* open(Firebird::ThrowStatusExceptionWrapper* status,
Firebird::IExternalContext* context, void* inMsg, void* outMsg) override
{
Firebird::AutoSetRestore<bool> autoInSystemPackage(&attachment->att_in_system_routine, true);
// See comment in Attachment.h.
// Firebird::AutoSetRestore<bool> autoInSystemPackage(&attachment->att_in_system_routine, true);
const auto resultSet = OpenFunction(status, context,
static_cast<typename Input::Type*>(inMsg),
@ -374,7 +376,8 @@ namespace Jrd
void execute(Firebird::ThrowStatusExceptionWrapper* status,
Firebird::IExternalContext* context, void* inMsg, void* outMsg) override
{
Firebird::AutoSetRestore<bool> autoInSystemPackage(&attachment->att_in_system_routine, true);
// See comment in Attachment.h.
// Firebird::AutoSetRestore<bool> autoInSystemPackage(&attachment->att_in_system_routine, true);
ExecFunction(status, context,
static_cast<typename Input::Type*>(inMsg),

View File

@ -133,7 +133,8 @@ struct Request
bool dirty = true;
unsigned level = 0;
SINT64 statementId;
SINT64 callerRequestId;
SINT64 callerStatementId = 0;
SINT64 callerRequestId = 0;
ISC_TIMESTAMP_TZ startTimestamp;
Nullable<ISC_TIMESTAMP_TZ> finishTimestamp;
Nullable<FB_UINT64> totalElapsedTicks;
@ -182,32 +183,40 @@ public:
void defineRecordSource(SINT64 statementId, unsigned cursorId, unsigned recSourceId,
const char* accessPath, unsigned parentRecordSourceId) override;
void onRequestStart(ThrowStatusExceptionWrapper* status, SINT64 requestId, SINT64 statementId,
SINT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) override;
void onRequestStart(ThrowStatusExceptionWrapper* status, SINT64 statementId, SINT64 requestId,
SINT64 callerStatementId, SINT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp) override;
void onRequestFinish(ThrowStatusExceptionWrapper* status, SINT64 requestId,
void onRequestFinish(ThrowStatusExceptionWrapper* status, SINT64 statementId, SINT64 requestId,
ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats) override;
void beforePsqlLineColumn(SINT64 requestId, unsigned line, unsigned column) override
void beforePsqlLineColumn(SINT64 statementId, SINT64 requestId, unsigned line, unsigned column) override
{
}
void afterPsqlLineColumn(SINT64 requestId, unsigned line, unsigned column, IProfilerStats* stats) override;
void afterPsqlLineColumn(SINT64 statementId, SINT64 requestId,
unsigned line, unsigned column, IProfilerStats* stats) override;
void beforeRecordSourceOpen(SINT64 requestId, unsigned cursorId, unsigned recSourceId) override
void beforeRecordSourceOpen(SINT64 statementId, SINT64 requestId, unsigned cursorId, unsigned recSourceId) override
{
}
void afterRecordSourceOpen(SINT64 requestId, unsigned cursorId, unsigned recSourceId,
void afterRecordSourceOpen(SINT64 statementId, SINT64 requestId, unsigned cursorId, unsigned recSourceId,
IProfilerStats* stats) override;
void beforeRecordSourceGetRecord(SINT64 requestId, unsigned cursorId, unsigned recSourceId) override
void beforeRecordSourceGetRecord(SINT64 statementId, SINT64 requestId,
unsigned cursorId, unsigned recSourceId) override
{
}
void afterRecordSourceGetRecord(SINT64 requestId, unsigned cursorId, unsigned recSourceId,
void afterRecordSourceGetRecord(SINT64 statementId, SINT64 requestId, unsigned cursorId, unsigned recSourceId,
IProfilerStats* stats) override;
private:
Request* getRequest(SINT64 statementId, SINT64 requestId)
{
return requests.get(detailedRequests ? requestId : -statementId);
}
public:
RefPtr<ProfilerPlugin> plugin;
NonPooledMap<SINT64, Statement> statements{defaultPool()};
@ -215,10 +224,11 @@ public:
NonPooledMap<StatementCursorRecSourceKey, RecordSource> recordSources{defaultPool()};
NonPooledMap<SINT64, Request> requests{defaultPool()};
SINT64 id;
bool dirty = true;
ISC_TIMESTAMP_TZ startTimestamp;
Nullable<ISC_TIMESTAMP_TZ> finishTimestamp;
string description{defaultPool()};
bool detailedRequests = false;
bool dirty = true;
};
class ProfilerPlugin final : public StdPlugin<IProfilerPluginImpl<ProfilerPlugin, ThrowStatusExceptionWrapper>>
@ -344,21 +354,36 @@ void ProfilerPlugin::init(ThrowStatusExceptionWrapper* status, IAttachment* atta
IProfilerSession* ProfilerPlugin::startSession(ThrowStatusExceptionWrapper* status,
const char* description, const char* options, ISC_TIMESTAMP_TZ timestamp)
{
AutoDispose<Session> session(FB_NEW Session(status, this, description, timestamp));
if (options && options[0])
{
static const ISC_STATUS statusVector[] = {
isc_arg_gds,
isc_random,
isc_arg_string,
(ISC_STATUS) "Invalid OPTIONS for Default_Profiler. Should be empty or NULL.",
isc_arg_end
};
string optionsStr = options;
optionsStr.alltrim();
status->setErrors(statusVector);
return nullptr;
if (optionsStr.hasData())
{
optionsStr.upper();
if (optionsStr == "DETAILED_REQUESTS")
session->detailedRequests = true;
else
{
static const ISC_STATUS statusVector[] = {
isc_arg_gds,
isc_random,
isc_arg_string,
(ISC_STATUS) "Invalid OPTIONS for Default_Profiler.",
isc_arg_end
};
status->setErrors(statusVector);
return nullptr;
}
}
}
return FB_NEW Session(status, this, description, timestamp);
return session.release();
}
void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
@ -433,15 +458,17 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
constexpr auto requestSql = R"""(
update or insert into plg$prof_requests
(profile_id, request_id, statement_id, caller_request_id, start_timestamp, finish_timestamp, total_elapsed_time)
values (?, ?, ?, ?, ?, ?, ?)
matching (profile_id, request_id)
(profile_id, statement_id, request_id, caller_statement_id, caller_request_id, start_timestamp,
finish_timestamp, total_elapsed_time)
values (?, ?, ?, ?, ?, ?, ?, ?)
matching (profile_id, statement_id, request_id)
)""";
FB_MESSAGE(RequestMessage, ThrowStatusExceptionWrapper,
(FB_BIGINT, profileId)
(FB_BIGINT, requestId)
(FB_BIGINT, statementId)
(FB_BIGINT, requestId)
(FB_BIGINT, callerStatementId)
(FB_BIGINT, callerRequestId)
(FB_TIMESTAMP_TZ, startTimestamp)
(FB_TIMESTAMP_TZ, finishTimestamp)
@ -452,10 +479,10 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
constexpr auto recSrcStatSql = R"""(
execute block (
profile_id type of column plg$prof_record_source_stats.profile_id = ?,
statement_id type of column plg$prof_record_source_stats.statement_id = ?,
request_id type of column plg$prof_record_source_stats.request_id = ?,
cursor_id type of column plg$prof_record_source_stats.cursor_id = ?,
record_source_id type of column plg$prof_record_source_stats.record_source_id = ?,
statement_id type of column plg$prof_record_source_stats.statement_id = ?,
open_counter type of column plg$prof_record_source_stats.open_counter = ?,
open_min_elapsed_time type of column plg$prof_record_source_stats.open_min_elapsed_time = ?,
open_max_elapsed_time type of column plg$prof_record_source_stats.open_max_elapsed_time = ?,
@ -470,14 +497,15 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
merge into plg$prof_record_source_stats
using rdb$database on
profile_id = :profile_id and
statement_id = :statement_id and
request_id = :request_id and
cursor_id = :cursor_id and
record_source_id = :record_source_id
when not matched then
insert (profile_id, request_id, cursor_id, record_source_id, statement_id,
insert (profile_id, statement_id, request_id, cursor_id, record_source_id,
open_counter, open_min_elapsed_time, open_max_elapsed_time, open_total_elapsed_time,
fetch_counter, fetch_min_elapsed_time, fetch_max_elapsed_time, fetch_total_elapsed_time)
values (:profile_id, :request_id, :cursor_id, :record_source_id, :statement_id,
values (:profile_id, :statement_id, :request_id, :cursor_id, :record_source_id,
:open_counter, :open_min_elapsed_time, :open_max_elapsed_time, :open_total_elapsed_time,
:fetch_counter, :fetch_min_elapsed_time, :fetch_max_elapsed_time, :fetch_total_elapsed_time)
when matched then
@ -495,10 +523,10 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
FB_MESSAGE(RecSrcStatMessage, ThrowStatusExceptionWrapper,
(FB_BIGINT, profileId)
(FB_BIGINT, statementId)
(FB_BIGINT, requestId)
(FB_INTEGER, cursorId)
(FB_INTEGER, recordSourceId)
(FB_BIGINT, statementId)
(FB_BIGINT, openCounter)
(FB_BIGINT, openMinElapsedTime)
(FB_BIGINT, openMaxElapsedTime)
@ -513,10 +541,10 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
constexpr auto psqlStatSql = R"""(
execute block (
profile_id type of column plg$prof_psql_stats.profile_id = ?,
statement_id type of column plg$prof_psql_stats.statement_id = ?,
request_id type of column plg$prof_psql_stats.request_id = ?,
line_num type of column plg$prof_psql_stats.line_num = ?,
column_num type of column plg$prof_psql_stats.column_num = ?,
statement_id type of column plg$prof_psql_stats.statement_id = ?,
counter type of column plg$prof_psql_stats.counter = ?,
min_elapsed_time type of column plg$prof_psql_stats.min_elapsed_time = ?,
max_elapsed_time type of column plg$prof_psql_stats.max_elapsed_time = ?,
@ -527,14 +555,15 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
merge into plg$prof_psql_stats
using rdb$database on
profile_id = :profile_id and
statement_id = :statement_id and
request_id = :request_id and
line_num = :line_num and
column_num = :column_num
when not matched then
insert (profile_id, request_id, line_num, column_num,
statement_id, counter, min_elapsed_time, max_elapsed_time, total_elapsed_time)
values (:profile_id, :request_id, :line_num, :column_num,
:statement_id, :counter, :min_elapsed_time, :max_elapsed_time, :total_elapsed_time)
insert (profile_id, statement_id, request_id, line_num, column_num,
counter, min_elapsed_time, max_elapsed_time, total_elapsed_time)
values (:profile_id, :statement_id, :request_id, :line_num, :column_num,
:counter, :min_elapsed_time, :max_elapsed_time, :total_elapsed_time)
when matched then
update set
counter = counter + :counter,
@ -546,10 +575,10 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
FB_MESSAGE(PsqlStatMessage, ThrowStatusExceptionWrapper,
(FB_BIGINT, profileId)
(FB_BIGINT, statementId)
(FB_BIGINT, requestId)
(FB_INTEGER, lineNum)
(FB_INTEGER, columnNum)
(FB_BIGINT, statementId)
(FB_BIGINT, counter)
(FB_BIGINT, minElapsedTime)
(FB_BIGINT, maxElapsedTime)
@ -577,25 +606,25 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
unsigned recSrcStatBatchSize = 0;
unsigned psqlStatBatchSize = 0;
auto executeBatch = [&](IBatch* batch, unsigned& batchSize)
const auto executeBatch = [&](IBatch* batch, unsigned& batchSize)
{
if (batchSize)
{
batchSize = 0;
if (auto batchCs = batch->execute(status, transaction))
if (const auto batchCs = batch->execute(status, transaction))
batchCs->dispose();
}
};
auto executeBatches = [&]()
const auto executeBatches = [&]()
{
executeBatch(requestBatch, requestBatchSize);
executeBatch(recSrcStatBatch, recSrcStatBatchSize);
executeBatch(psqlStatBatch, psqlStatBatchSize);
};
auto addBatch = [&](IBatch* batch, unsigned& batchSize, const auto& message)
const auto addBatch = [&](IBatch* batch, unsigned& batchSize, const auto& message)
{
batch->add(status, 1, message.getData());
@ -649,15 +678,15 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
stack.pop()->level = ++level;
}
auto levelArray = statementsByLevel.getOrPut(profileStatement.level);
const auto levelArray = statementsByLevel.getOrPut(profileStatement.level);
levelArray->add(&statementIt);
}
for (auto& levelIt : statementsByLevel)
{
for (auto statementIt : levelIt.second)
for (const auto statementIt : levelIt.second)
{
auto profileStatementId = statementIt->first;
const auto profileStatementId = statementIt->first;
auto& profileStatement = statementIt->second;
statementMessage->profileIdNull = FB_FALSE;
@ -774,15 +803,15 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
stack.pop()->level = ++level;
}
auto levelArray = requestsByLevel.getOrPut(profileRequest.level);
const auto levelArray = requestsByLevel.getOrPut(profileRequest.level);
levelArray->add(&requestIt);
}
for (auto& levelIt : requestsByLevel)
{
for (auto requestIt : levelIt.second)
for (const auto requestIt : levelIt.second)
{
auto profileRequestId = requestIt->first;
const auto profileRequestId = MAX(requestIt->first, 0);
auto& profileRequest = requestIt->second;
if (profileRequest.dirty)
@ -796,6 +825,9 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
requestMessage->statementIdNull = FB_FALSE;
requestMessage->statementId = profileRequest.statementId;
requestMessage->callerStatementIdNull = profileRequest.callerStatementId == 0 ? FB_TRUE : FB_FALSE;
requestMessage->callerStatementId = profileRequest.callerStatementId;
requestMessage->callerRequestIdNull = profileRequest.callerRequestId == 0 ? FB_TRUE : FB_FALSE;
requestMessage->callerRequestId = profileRequest.callerRequestId;
@ -811,7 +843,7 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
addBatch(requestBatch, requestBatchSize, requestMessage);
if (profileRequest.finishTimestamp.isAssigned())
finishedRequests.add(profileRequestId);
finishedRequests.add(requestIt->first);
profileRequest.dirty = false;
}
@ -824,6 +856,9 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
recSrcStatMessage->profileIdNull = FB_FALSE;
recSrcStatMessage->profileId = session->getId();
recSrcStatMessage->statementIdNull = FB_FALSE;
recSrcStatMessage->statementId = profileRequest.statementId;
recSrcStatMessage->requestIdNull = FB_FALSE;
recSrcStatMessage->requestId = profileRequestId;
@ -833,9 +868,6 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
recSrcStatMessage->recordSourceIdNull = FB_FALSE;
recSrcStatMessage->recordSourceId = cursorRecSource.second;
recSrcStatMessage->statementIdNull = FB_FALSE;
recSrcStatMessage->statementId = profileRequest.statementId;
recSrcStatMessage->openCounterNull = FB_FALSE;
recSrcStatMessage->openCounter = stats.openStats.counter;
@ -872,6 +904,9 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
psqlStatMessage->profileIdNull = FB_FALSE;
psqlStatMessage->profileId = session->getId();
psqlStatMessage->statementIdNull = FB_FALSE;
psqlStatMessage->statementId = profileRequest.statementId;
psqlStatMessage->requestIdNull = FB_FALSE;
psqlStatMessage->requestId = profileRequestId;
@ -881,9 +916,6 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
psqlStatMessage->columnNumNull = FB_FALSE;
psqlStatMessage->columnNum = lineColumn.second;
psqlStatMessage->statementIdNull = FB_FALSE;
psqlStatMessage->statementId = profileRequest.statementId;
psqlStatMessage->counterNull = FB_FALSE;
psqlStatMessage->counter = statsIt.second.counter;
@ -1037,23 +1069,29 @@ void ProfilerPlugin::createMetadata(ThrowStatusExceptionWrapper* status, RefPtr<
references plg$prof_sessions
on delete cascade
using index plg$prof_requests_profile,
request_id bigint not null,
statement_id bigint not null,
request_id bigint not null,
caller_statement_id bigint,
caller_request_id bigint,
start_timestamp timestamp with time zone not null,
finish_timestamp timestamp with time zone,
total_elapsed_time bigint,
constraint plg$prof_requests_pk
primary key (profile_id, request_id)
using index plg$prof_requests_profile_request,
primary key (profile_id, statement_id, request_id)
using index plg$prof_requests_profile_request_statement,
constraint plg$prof_requests_statement_fk
foreign key (profile_id, statement_id) references plg$prof_statements
on delete cascade
using index plg$prof_requests_profile_statement,
constraint plg$prof_requests_caller_request_fk
foreign key (profile_id, caller_request_id) references plg$prof_requests (profile_id, request_id)
constraint plg$prof_requests_caller_statement_fk
foreign key (profile_id, caller_statement_id) references plg$prof_statements
on delete cascade
using index plg$prof_requests_caller_request
using index plg$prof_requests_profile_caller_statement,
constraint plg$prof_requests_caller_request_fk
foreign key (profile_id, caller_statement_id, caller_request_id)
references plg$prof_requests (profile_id, statement_id, request_id)
on delete cascade
using index plg$prof_requests_profile_caller_statement_caller_request
))""",
"grant select, update, insert, delete on table plg$prof_requests to plg$profiler",
@ -1065,19 +1103,19 @@ void ProfilerPlugin::createMetadata(ThrowStatusExceptionWrapper* status, RefPtr<
references plg$prof_sessions
on delete cascade
using index plg$prof_psql_stats_profile,
statement_id bigint not null,
request_id bigint not null,
line_num integer not null,
column_num integer not null,
statement_id bigint not null,
counter bigint not null,
min_elapsed_time bigint not null,
max_elapsed_time bigint not null,
total_elapsed_time bigint not null,
constraint plg$prof_psql_stats_pk
primary key (profile_id, request_id, line_num, column_num)
using index plg$prof_psql_stats_profile_request_line_column,
primary key (profile_id, statement_id, request_id, line_num, column_num)
using index plg$prof_psql_stats_profile_statement_request_line_column,
constraint plg$prof_psql_stats_request_fk
foreign key (profile_id, request_id) references plg$prof_requests
foreign key (profile_id, statement_id, request_id) references plg$prof_requests
on delete cascade
using index plg$prof_psql_stats_profile_request,
constraint plg$prof_psql_stats_statement_fk
@ -1095,10 +1133,10 @@ void ProfilerPlugin::createMetadata(ThrowStatusExceptionWrapper* status, RefPtr<
references plg$prof_sessions
on delete cascade
using index plg$prof_record_source_stats_profile_id,
statement_id bigint not null,
request_id bigint not null,
cursor_id integer not null,
record_source_id integer not null,
statement_id bigint not null,
open_counter bigint not null,
open_min_elapsed_time bigint not null,
open_max_elapsed_time bigint not null,
@ -1108,10 +1146,10 @@ void ProfilerPlugin::createMetadata(ThrowStatusExceptionWrapper* status, RefPtr<
fetch_max_elapsed_time bigint not null,
fetch_total_elapsed_time bigint not null,
constraint plg$prof_record_source_stats_pk
primary key (profile_id, request_id, cursor_id, record_source_id)
using index plg$prof_record_source_stats_profile_request_cursor_recsource,
primary key (profile_id, statement_id, request_id, cursor_id, record_source_id)
using index plg$prof_record_source_stats_profile_stat_req_cur_recsource,
constraint plg$prof_record_source_stats_request_fk
foreign key (profile_id, request_id) references plg$prof_requests
foreign key (profile_id, statement_id, request_id) references plg$prof_requests
on delete cascade
using index plg$prof_record_source_stats_profile_request,
constraint plg$prof_record_source_stats_statement_fk
@ -1287,7 +1325,7 @@ void ProfilerPlugin::createMetadata(ThrowStatusExceptionWrapper* status, RefPtr<
"grant select on table plg$prof_record_source_stats_view to plg$profiler"
};
for (auto createSql : createSqlStaments)
for (const auto createSql : createSqlStaments)
{
attachment->execute(status, transaction, 0, createSql, SQL_DIALECT_CURRENT,
nullptr, nullptr, nullptr, nullptr);
@ -1375,7 +1413,7 @@ void Session::finish(ThrowStatusExceptionWrapper* status, ISC_TIMESTAMP_TZ times
void Session::defineStatement(ThrowStatusExceptionWrapper* status, SINT64 statementId, SINT64 parentStatementId,
const char* type, const char* packageName, const char* routineName, const char* sqlText)
{
auto statement = statements.put(statementId);
const auto statement = statements.put(statementId);
fb_assert(statement);
if (!statement)
@ -1414,7 +1452,7 @@ void Session::defineRecordSource(SINT64 statementId, unsigned cursorId, unsigned
if (unsigned len = recSource->accessPath.length(); len > MAX_ACCESS_PATH_CHAR_LEN)
{
auto str = recSource->accessPath.c_str();
const auto str = recSource->accessPath.c_str();
unsigned charLen = 0;
unsigned pos = 0;
unsigned truncPos = 0;
@ -1440,24 +1478,28 @@ void Session::defineRecordSource(SINT64 statementId, unsigned cursorId, unsigned
recSource->parentId = parentRecordSourceId;
}
void Session::onRequestStart(ThrowStatusExceptionWrapper* status, SINT64 requestId, SINT64 statementId,
SINT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp)
void Session::onRequestStart(ThrowStatusExceptionWrapper* status, SINT64 statementId, SINT64 requestId,
SINT64 callerStatementId, SINT64 callerRequestId, ISC_TIMESTAMP_TZ timestamp)
{
auto request = requests.put(requestId);
///fb_assert(!request);
const auto request = requests.put(detailedRequests ? requestId : -statementId);
if (!request)
return;
request->statementId = statementId;
request->callerRequestId = callerRequestId;
request->startTimestamp = timestamp;
if (detailedRequests)
{
request->callerStatementId = callerStatementId;
request->callerRequestId = callerRequestId;
}
}
void Session::onRequestFinish(ThrowStatusExceptionWrapper* status, SINT64 requestId,
void Session::onRequestFinish(ThrowStatusExceptionWrapper* status, SINT64 statementId, SINT64 requestId,
ISC_TIMESTAMP_TZ timestamp, IProfilerStats* stats)
{
if (auto request = requests.get(requestId))
if (const auto request = requests.get(requestId))
{
request->dirty = true;
request->finishTimestamp = timestamp;
@ -1465,29 +1507,32 @@ void Session::onRequestFinish(ThrowStatusExceptionWrapper* status, SINT64 reques
}
}
void Session::afterPsqlLineColumn(SINT64 requestId, unsigned line, unsigned column, IProfilerStats* stats)
void Session::afterPsqlLineColumn(SINT64 statementId, SINT64 requestId,
unsigned line, unsigned column, IProfilerStats* stats)
{
if (auto request = requests.get(requestId))
if (const auto request = getRequest(statementId, requestId))
{
const auto profileStats = request->psqlStats.getOrPut({line, column});
profileStats->hit(stats->getElapsedTicks());
}
}
void Session::afterRecordSourceOpen(SINT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats)
void Session::afterRecordSourceOpen(SINT64 statementId, SINT64 requestId, unsigned cursorId, unsigned recSourceId,
IProfilerStats* stats)
{
if (auto request = requests.get(requestId))
if (const auto request = getRequest(statementId, requestId))
{
auto profileStats = request->recordSourcesStats.getOrPut({cursorId, recSourceId});
const auto profileStats = request->recordSourcesStats.getOrPut({cursorId, recSourceId});
profileStats->openStats.hit(stats->getElapsedTicks());
}
}
void Session::afterRecordSourceGetRecord(SINT64 requestId, unsigned cursorId, unsigned recSourceId, IProfilerStats* stats)
void Session::afterRecordSourceGetRecord(SINT64 statementId, SINT64 requestId, unsigned cursorId, unsigned recSourceId,
IProfilerStats* stats)
{
if (auto request = requests.get(requestId))
if (const auto request = getRequest(statementId, requestId))
{
auto profileStats = request->recordSourcesStats.getOrPut({cursorId, recSourceId});
const auto profileStats = request->recordSourcesStats.getOrPut({cursorId, recSourceId});
profileStats->fetchStats.hit(stats->getElapsedTicks());
}
}