8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 23:23:04 +01:00

Conversion of statements, procedures and functions parameters (CHAR and VARCHAR) to UTF8 in trace log (#95) (#100)

* Conversion of statements, procedures and functions parameters (CHAR and VARCHAR) to UTF8 in trace log

* cloop interface version check is added for getTextUTF8 function
This commit is contained in:
Ilya Eremin 2017-07-20 17:03:34 +03:00 committed by Alexander Peshkov
parent 0a74b4c478
commit b17a729ab2
5 changed files with 122 additions and 6 deletions

View File

@ -1080,6 +1080,9 @@ interface TraceParams : Versioned
{
uint getCount();
const dsc* getParam(uint idx);
version:
const string getTextUTF8(Status status, uint idx);
}
interface TraceStatement : Versioned

View File

@ -4259,6 +4259,7 @@ namespace Firebird
{
unsigned (CLOOP_CARG *getCount)(ITraceParams* self) throw();
const dsc* (CLOOP_CARG *getParam)(ITraceParams* self, unsigned idx) throw();
const char* (CLOOP_CARG *getTextUTF8)(ITraceParams* self, IStatus* status, unsigned idx) throw();
};
protected:
@ -4272,7 +4273,7 @@ namespace Firebird
}
public:
static const unsigned VERSION = 2;
static const unsigned VERSION = 3;
unsigned getCount()
{
@ -4285,6 +4286,20 @@ namespace Firebird
const dsc* ret = static_cast<VTable*>(this->cloopVTable)->getParam(this, idx);
return ret;
}
template <typename StatusType> const char* getTextUTF8(StatusType* status, unsigned idx)
{
if (cloopVTable->version < 3)
{
StatusType::setVersionError(status, "ITraceParams", cloopVTable->version, 3);
StatusType::checkException(status);
return 0;
}
StatusType::clearException(status);
const char* ret = static_cast<VTable*>(this->cloopVTable)->getTextUTF8(this, status, idx);
StatusType::checkException(status);
return ret;
}
};
class ITraceStatement : public IVersioned
@ -14254,6 +14269,7 @@ namespace Firebird
this->version = Base::VERSION;
this->getCount = &Name::cloopgetCountDispatcher;
this->getParam = &Name::cloopgetParamDispatcher;
this->getTextUTF8 = &Name::cloopgetTextUTF8Dispatcher;
}
} vTable;
@ -14285,6 +14301,21 @@ namespace Firebird
return static_cast<const dsc*>(0);
}
}
static const char* CLOOP_CARG cloopgetTextUTF8Dispatcher(ITraceParams* self, IStatus* status, unsigned idx) throw()
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::getTextUTF8(&status2, idx);
}
catch (...)
{
StatusType::catchException(&status2);
return static_cast<const char*>(0);
}
}
};
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<ITraceParams> > >
@ -14302,6 +14333,7 @@ namespace Firebird
virtual unsigned getCount() = 0;
virtual const dsc* getParam(unsigned idx) = 0;
virtual const char* getTextUTF8(StatusType* status, unsigned idx) = 0;
};
template <typename Name, typename StatusType, typename Base>

View File

@ -280,6 +280,33 @@ const dsc* TraceSQLStatementImpl::DSQLParamsImpl::getParam(FB_SIZE_T idx)
return NULL;
}
const char* TraceSQLStatementImpl::DSQLParamsImpl::getTextUTF8(CheckStatusWrapper* status, FB_SIZE_T idx)
{
const dsc* param = getParam(idx);
UCHAR* address;
switch (param->dsc_dtype)
{
case dtype_text:
address = param->dsc_address;
break;
case dtype_varying:
address = param->dsc_address + sizeof(USHORT);
break;
default:
return NULL;
}
string src(address);
if (DataTypeUtil::convertToUTF8(src, temp_utf8_text, param->dsc_sub_type))
return temp_utf8_text.c_str();
else
return (const char*)address;
}
/// TraceFailedSQLStatement
@ -307,6 +334,33 @@ const dsc* TraceParamsImpl::getParam(FB_SIZE_T idx)
return m_descs->getParam(idx);
}
const char* TraceParamsImpl::getTextUTF8(CheckStatusWrapper* status, FB_SIZE_T idx)
{
const dsc* param = getParam(idx);
UCHAR* address;
switch (param->dsc_dtype)
{
case dtype_text:
address = param->dsc_address;
break;
case dtype_varying:
address = param->dsc_address + sizeof(USHORT);
break;
default:
return NULL;
}
string src(address);
if (DataTypeUtil::convertToUTF8(src, temp_utf8_text, param->dsc_sub_type))
return temp_utf8_text.c_str();
else
return (const char*)address;
}
/// TraceDscFromValues

View File

@ -206,6 +206,7 @@ private:
FB_SIZE_T getCount();
const dsc* getParam(FB_SIZE_T idx);
const char* getTextUTF8(Firebird::CheckStatusWrapper* status, FB_SIZE_T idx);
private:
void fillParams();
@ -213,6 +214,7 @@ private:
const dsql_req* const m_stmt;
const Firebird::Array<dsql_par*>* m_params;
Firebird::HalfStaticArray<dsc, 16> m_descs;
Firebird::string temp_utf8_text;
};
void fillPlan(bool explained);
@ -285,9 +287,11 @@ public:
// TraceParams implementation
FB_SIZE_T getCount();
const dsc* getParam(FB_SIZE_T idx);
const char* getTextUTF8(Firebird::CheckStatusWrapper* status, FB_SIZE_T idx);
private:
TraceDescriptors* m_descs;
Firebird::string temp_utf8_text;
};

View File

@ -46,6 +46,7 @@
#include "../../dsql/sqlda_pub.h"
#include "../../common/classes/ImplementHelper.h"
#include "../../common/SimpleStatusVector.h"
#include "../../jrd/status.h"
using namespace Firebird;
using namespace Jrd;
@ -789,19 +790,41 @@ void TracePluginImpl::appendParams(ITraceParams* params)
{
// Handle potentially long string values
case dtype_text:
formatStringArgument(paramvalue,
parameters->dsc_address, parameters->dsc_length);
{
FbLocalStatus status;
const char* text = params->getTextUTF8(&status, i);
if (status->getState() & IStatus::STATE_ERRORS)
{
formatStringArgument(paramvalue,
parameters->dsc_address, parameters->dsc_length);
}
else
formatStringArgument(paramvalue, (UCHAR*)text, strlen(text));
break;
}
case dtype_cstring:
formatStringArgument(paramvalue,
parameters->dsc_address,
strlen(reinterpret_cast<const char*>(parameters->dsc_address)));
break;
case dtype_varying:
formatStringArgument(paramvalue,
parameters->dsc_address + 2,
*(USHORT*)parameters->dsc_address);
{
FbLocalStatus status;
const char* text = params->getTextUTF8(&status, i);
if (status->getState() & IStatus::STATE_ERRORS)
{
formatStringArgument(paramvalue,
parameters->dsc_address + 2,
*(USHORT*)parameters->dsc_address);
}
else
formatStringArgument(paramvalue, (UCHAR*)text, strlen(text));
break;
}
// Handle quad
case dtype_quad: