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

Add PLUGIN_OPTIONS parameters to RDB$PROFILER.START_SESSION.

This commit is contained in:
Adriano dos Santos Fernandes 2022-05-16 11:00:18 -03:00
parent 12f8d087d3
commit b3654c48e8
7 changed files with 44 additions and 22 deletions

View File

@ -4,7 +4,7 @@ The profiler allows users to measure performance cost of SQL and PSQL code.
It's implemented with a system package in the engine passing data to a profiler plugin.
This documentation treats the engine and plugin parts as a single thing, in the way the default profiler is going to be used.
This documentation treats the engine and plugin parts as a single thing, in the way the default profiler (`Default_Profiler`) is going to be used.
The `RDB$PROFILER` package allows to profile execution of PSQL code collecting statistics of how many times each line was executed along with its minimum, maximum and accumulated execution times (with nanoseconds precision), as well open and fetch statistics of implicit and explicit SQL cursors.
@ -124,9 +124,12 @@ select pstat.*
If `PLUGIN_NAME` is `NULL` (the default) it uses the database configuration `DefaultProfilerPlugin`.
`PLUGIN_OPTIONS` is plugin specific options and currently should be `NULL` for `Default_Profiler` plugin.
Input parameters:
- `DESCRIPTION` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
- `PLUGIN_NAME` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
- `PLUGIN_OPTIONS` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
Return type: `BIGINT NOT NULL`.

View File

@ -1705,7 +1705,7 @@ interface ProfilerPlugin : PluginBase
// The transaction should not be stored for later usage after the method returns.
ProfilerSession startSession(Status status, Transaction transaction, const string description,
ISC_TIMESTAMP_TZ timestamp);
const string options, ISC_TIMESTAMP_TZ timestamp);
// The transaction should not be stored for later usage after the method returns.
void flush(Status status, Transaction transaction);

View File

@ -6649,7 +6649,7 @@ namespace Firebird
struct VTable : public IPluginBase::VTable
{
void (CLOOP_CARG *init)(IProfilerPlugin* self, IStatus* status, IAttachment* attachment, ITransaction* transaction) throw();
IProfilerSession* (CLOOP_CARG *startSession)(IProfilerPlugin* self, IStatus* status, ITransaction* transaction, const char* description, ISC_TIMESTAMP_TZ timestamp) throw();
IProfilerSession* (CLOOP_CARG *startSession)(IProfilerPlugin* self, IStatus* status, ITransaction* transaction, const char* description, const char* options, ISC_TIMESTAMP_TZ timestamp) throw();
void (CLOOP_CARG *flush)(IProfilerPlugin* self, IStatus* status, ITransaction* transaction) throw();
};
@ -6673,10 +6673,10 @@ namespace Firebird
StatusType::checkException(status);
}
template <typename StatusType> IProfilerSession* startSession(StatusType* status, ITransaction* transaction, const char* description, ISC_TIMESTAMP_TZ timestamp)
template <typename StatusType> IProfilerSession* startSession(StatusType* status, ITransaction* transaction, const char* description, const char* options, ISC_TIMESTAMP_TZ timestamp)
{
StatusType::clearException(status);
IProfilerSession* ret = static_cast<VTable*>(this->cloopVTable)->startSession(this, status, transaction, description, timestamp);
IProfilerSession* ret = static_cast<VTable*>(this->cloopVTable)->startSession(this, status, transaction, description, options, timestamp);
StatusType::checkException(status);
return ret;
}
@ -19978,13 +19978,13 @@ namespace Firebird
}
}
static IProfilerSession* CLOOP_CARG cloopstartSessionDispatcher(IProfilerPlugin* self, IStatus* status, ITransaction* transaction, const char* description, ISC_TIMESTAMP_TZ timestamp) throw()
static IProfilerSession* CLOOP_CARG cloopstartSessionDispatcher(IProfilerPlugin* self, IStatus* status, ITransaction* transaction, const char* description, const char* options, ISC_TIMESTAMP_TZ timestamp) throw()
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::startSession(&status2, transaction, description, timestamp);
return static_cast<Name*>(self)->Name::startSession(&status2, transaction, description, options, timestamp);
}
catch (...)
{
@ -20072,7 +20072,7 @@ namespace Firebird
}
virtual void init(StatusType* status, IAttachment* attachment, ITransaction* transaction) = 0;
virtual IProfilerSession* startSession(StatusType* status, ITransaction* transaction, const char* description, ISC_TIMESTAMP_TZ timestamp) = 0;
virtual IProfilerSession* startSession(StatusType* status, ITransaction* transaction, const char* description, const char* options, ISC_TIMESTAMP_TZ timestamp) = 0;
virtual void flush(StatusType* status, ITransaction* transaction) = 0;
};

View File

@ -715,7 +715,7 @@ type
IReplicatedSession_cleanupTransactionPtr = procedure(this: IReplicatedSession; status: IStatus; number: Int64); cdecl;
IReplicatedSession_setSequencePtr = procedure(this: IReplicatedSession; status: IStatus; name: PAnsiChar; value: Int64); cdecl;
IProfilerPlugin_initPtr = procedure(this: IProfilerPlugin; status: IStatus; attachment: IAttachment; transaction: ITransaction); cdecl;
IProfilerPlugin_startSessionPtr = function(this: IProfilerPlugin; status: IStatus; transaction: ITransaction; description: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; cdecl;
IProfilerPlugin_startSessionPtr = function(this: IProfilerPlugin; status: IStatus; transaction: ITransaction; description: PAnsiChar; options: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; cdecl;
IProfilerPlugin_flushPtr = procedure(this: IProfilerPlugin; status: IStatus; transaction: ITransaction); cdecl;
IProfilerSession_getIdPtr = function(this: IProfilerSession): Int64; cdecl;
IProfilerSession_getFlagsPtr = function(this: IProfilerSession): Cardinal; cdecl;
@ -3776,7 +3776,7 @@ type
const VERSION = 4;
procedure init(status: IStatus; attachment: IAttachment; transaction: ITransaction);
function startSession(status: IStatus; transaction: ITransaction; description: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession;
function startSession(status: IStatus; transaction: ITransaction; description: PAnsiChar; options: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession;
procedure flush(status: IStatus; transaction: ITransaction);
end;
@ -3788,7 +3788,7 @@ type
procedure setOwner(r: IReferenceCounted); virtual; abstract;
function getOwner(): IReferenceCounted; virtual; abstract;
procedure init(status: IStatus; attachment: IAttachment; transaction: ITransaction); virtual; abstract;
function startSession(status: IStatus; transaction: ITransaction; description: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; virtual; abstract;
function startSession(status: IStatus; transaction: ITransaction; description: PAnsiChar; options: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; virtual; abstract;
procedure flush(status: IStatus; transaction: ITransaction); virtual; abstract;
end;
@ -8951,9 +8951,9 @@ begin
FbException.checkException(status);
end;
function IProfilerPlugin.startSession(status: IStatus; transaction: ITransaction; description: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession;
function IProfilerPlugin.startSession(status: IStatus; transaction: ITransaction; description: PAnsiChar; options: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession;
begin
Result := ProfilerPluginVTable(vTable).startSession(Self, status, transaction, description, timestamp);
Result := ProfilerPluginVTable(vTable).startSession(Self, status, transaction, description, options, timestamp);
FbException.checkException(status);
end;
@ -15585,10 +15585,10 @@ begin
end
end;
function IProfilerPluginImpl_startSessionDispatcher(this: IProfilerPlugin; status: IStatus; transaction: ITransaction; description: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; cdecl;
function IProfilerPluginImpl_startSessionDispatcher(this: IProfilerPlugin; status: IStatus; transaction: ITransaction; description: PAnsiChar; options: PAnsiChar; timestamp: ISC_TIMESTAMP_TZ): IProfilerSession; cdecl;
begin
try
Result := IProfilerPluginImpl(this).startSession(status, transaction, description, timestamp);
Result := IProfilerPluginImpl(this).startSession(status, transaction, description, options, timestamp);
except
on e: Exception do FbException.catchException(status, e);
end

View File

@ -153,12 +153,13 @@ void ProfilerPackage::startSessionFunction(ThrowStatusExceptionWrapper* /*status
const string description(in->description.str, in->descriptionNull ? 0 : in->description.length);
const PathName pluginName(in->pluginName.str, in->pluginNameNull ? 0 : in->pluginName.length);
const string pluginOptions(in->pluginOptions.str, in->pluginOptionsNull ? 0 : in->pluginOptions.length);
const auto profilerManager = attachment->getProfilerManager(tdbb);
AutoSetRestore<bool> pauseProfiler(&profilerManager->paused, true);
out->sessionIdNull = FB_FALSE;
out->sessionId = profilerManager->startSession(tdbb, pluginName, description);
out->sessionId = profilerManager->startSession(tdbb, pluginName, description, pluginOptions);
}
@ -175,7 +176,8 @@ ProfilerManager* ProfilerManager::create(thread_db* tdbb)
return FB_NEW_POOL(*tdbb->getAttachment()->att_pool) ProfilerManager(tdbb);
}
SINT64 ProfilerManager::startSession(thread_db* tdbb, const PathName& pluginName, const string& description)
SINT64 ProfilerManager::startSession(thread_db* tdbb, const PathName& pluginName, const string& description,
const string& options)
{
const auto attachment = tdbb->getAttachment();
const auto transaction = tdbb->getTransaction();
@ -221,6 +223,7 @@ SINT64 ProfilerManager::startSession(thread_db* tdbb, const PathName& pluginName
AutoDispose<IProfilerSession> pluginSession = plugin->startSession(&status,
transaction->getInterface(true),
description.c_str(),
options.c_str(),
timestamp);
auto& pool = *tdbb->getAttachment()->att_pool;
@ -580,6 +583,7 @@ ProfilerPackage::ProfilerPackage(MemoryPool& pool)
{
{"DESCRIPTION", fld_short_description, true, "null", {blr_null}},
{"PLUGIN_NAME", fld_file_name2, true, "null", {blr_null}},
{"PLUGIN_OPTIONS", fld_short_description, true, "null", {blr_null}},
},
{fld_prof_ses_id, false}
)

View File

@ -90,7 +90,9 @@ public:
void operator=(const ProfilerManager&) = delete;
public:
SINT64 startSession(thread_db* tdbb, const Firebird::PathName& pluginName, const Firebird::string& description);
SINT64 startSession(thread_db* tdbb, const Firebird::PathName& pluginName, const Firebird::string& description,
const Firebird::string& options);
void prepareRecSource(thread_db* tdbb, jrd_req* request, const RecordSource* rsb);
void onRequestFinish(jrd_req* request);
void beforePsqlLineColumn(jrd_req* request, ULONG line, ULONG column);
@ -165,8 +167,7 @@ private:
FB_MESSAGE(StartSessionInput, Firebird::ThrowStatusExceptionWrapper,
(FB_INTL_VARCHAR(255, CS_METADATA), description)
(FB_INTL_VARCHAR(255, CS_METADATA), pluginName)
//// TODO: Options: PSQL, SQL.
//// TODO: Plugin options.
(FB_INTL_VARCHAR(255, CS_METADATA), pluginOptions)
);
FB_MESSAGE(StartSessionOutput, Firebird::ThrowStatusExceptionWrapper,

View File

@ -207,7 +207,7 @@ public:
void init(ThrowStatusExceptionWrapper* status, IAttachment* attachment, ITransaction* transaction) override;
IProfilerSession* startSession(ThrowStatusExceptionWrapper* status, ITransaction* transaction,
const char* description, ISC_TIMESTAMP_TZ timestamp) override;
const char* description, const char* options, ISC_TIMESTAMP_TZ timestamp) override;
void flush(ThrowStatusExceptionWrapper* status, ITransaction* transaction) override;
@ -317,8 +317,22 @@ void ProfilerPlugin::init(ThrowStatusExceptionWrapper* status, IAttachment* atta
}
IProfilerSession* ProfilerPlugin::startSession(ThrowStatusExceptionWrapper* status, ITransaction* transaction,
const char* description, ISC_TIMESTAMP_TZ timestamp)
const char* description, const char* options, ISC_TIMESTAMP_TZ 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
};
status->setErrors(statusVector);
return nullptr;
}
return FB_NEW Session(status, this, transaction, description, timestamp);
}