From 164cd3c7b2f8cf4ba0deab183261d16cd968cd4e Mon Sep 17 00:00:00 2001 From: Vlad Khorsun Date: Fri, 17 Jan 2025 15:18:27 +0200 Subject: [PATCH] =?UTF-8?q?Improvement=20#8356=20:=20Make=20Trace=20use=20?= =?UTF-8?q?HEX=20representation=20for=20parameter=20values=20=E2=80=8B?= =?UTF-8?q?=E2=80=8Bof=20types=20[VAR]CHAR=20CHARACTER=20SET=20OCTETS=20an?= =?UTF-8?q?d=20[VAR]BINARY.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/jrd/trace/TraceObjects.cpp | 127 ++++++++++++----------- src/jrd/trace/TraceObjects.h | 4 +- src/utilities/ntrace/TracePluginImpl.cpp | 10 +- 3 files changed, 77 insertions(+), 64 deletions(-) diff --git a/src/jrd/trace/TraceObjects.cpp b/src/jrd/trace/TraceObjects.cpp index dc6bab88895..2e4058e3299 100644 --- a/src/jrd/trace/TraceObjects.cpp +++ b/src/jrd/trace/TraceObjects.cpp @@ -56,6 +56,67 @@ using namespace Firebird; +namespace +{ + +// Convert text descriptor into UTF8 string. +// Binary data converted into HEX representation. +bool descToUTF8(const dsc* param, string& result) +{ + UCHAR* address; + USHORT length; + + switch (param->dsc_dtype) + { + case dtype_text: + address = param->dsc_address; + length = param->dsc_length; + break; + + case dtype_varying: + address = param->dsc_address + sizeof(USHORT); + length = *(USHORT*) param->dsc_address; + fb_assert(length <= param->dsc_length - 2); + break; + + default: + return false; + } + + if (param->getCharSet() == CS_BINARY) + { + // Convert OCTETS and [VAR]BINARY to HEX string + + char* hex = result.getBuffer(length * 2); + + for (UCHAR* p = address; p < address + length; p++) + { + UCHAR c = (*p & 0xF0) >> 4; + *hex++ = c + (c < 10 ? '0' : 'A' - 10); + + c = (*p & 0x0F); + *hex++ = c + (c < 10 ? '0' : 'A' - 10); + } + return result.c_str(); + } + + string src(address, length); + + try + { + if (!Jrd::DataTypeUtil::convertToUTF8(src, result, param->dsc_sub_type, status_exception::raise)) + result = src; + } + catch (const Firebird::Exception&) + { + result = src; + } + + return true; +} + +} // namespace + namespace Jrd { const char* StatementHolder::ensurePlan(bool explained) @@ -287,38 +348,11 @@ const dsc* TraceSQLStatementImpl::DSQLParamsImpl::getParam(FB_SIZE_T idx) const char* TraceSQLStatementImpl::DSQLParamsImpl::getTextUTF8(CheckStatusWrapper* status, FB_SIZE_T idx) { const dsc* param = getParam(idx); - UCHAR* address; - USHORT length; - switch (param->dsc_dtype) - { - case dtype_text: - address = param->dsc_address; - length = param->dsc_length; - break; - - case dtype_varying: - address = param->dsc_address + sizeof(USHORT); - length = *(USHORT*) param->dsc_address; - break; - - default: - return NULL; - } + if (descToUTF8(param, m_tempUTF8)) + return m_tempUTF8.c_str(); - string src(address, length); - - try - { - if (!DataTypeUtil::convertToUTF8(src, temp_utf8_text, param->dsc_sub_type, status_exception::raise)) - temp_utf8_text = src; - } - catch (const Firebird::Exception&) - { - temp_utf8_text = src; - } - - return temp_utf8_text.c_str(); + return nullptr; } @@ -351,38 +385,11 @@ const dsc* TraceParamsImpl::getParam(FB_SIZE_T idx) const char* TraceParamsImpl::getTextUTF8(CheckStatusWrapper* status, FB_SIZE_T idx) { const dsc* param = getParam(idx); - UCHAR* address; - USHORT length; - switch (param->dsc_dtype) - { - case dtype_text: - address = param->dsc_address; - length = param->dsc_length; - break; - - case dtype_varying: - address = param->dsc_address + sizeof(USHORT); - length = *(USHORT*) param->dsc_address; - break; - - default: - return NULL; - } - - string src(address, length); - - try - { - if (!DataTypeUtil::convertToUTF8(src, temp_utf8_text, param->dsc_sub_type, status_exception::raise)) - temp_utf8_text = src; - } - catch (const Firebird::Exception&) - { - temp_utf8_text = src; - } + if (descToUTF8(param, m_tempUTF8)) + return m_tempUTF8.c_str(); - return temp_utf8_text.c_str(); + return nullptr; } diff --git a/src/jrd/trace/TraceObjects.h b/src/jrd/trace/TraceObjects.h index 31c70778482..cbbefa8e14e 100644 --- a/src/jrd/trace/TraceObjects.h +++ b/src/jrd/trace/TraceObjects.h @@ -267,7 +267,7 @@ class TraceSQLStatementImpl : DsqlRequest* const m_stmt; const Firebird::Array* m_params = nullptr; Firebird::HalfStaticArray m_descs; - Firebird::string temp_utf8_text; + Firebird::string m_tempUTF8; }; DsqlRequest* const m_stmt; @@ -340,7 +340,7 @@ class TraceParamsImpl : private: TraceDescriptors* m_descs; - Firebird::string temp_utf8_text; + Firebird::string m_tempUTF8; }; diff --git a/src/utilities/ntrace/TracePluginImpl.cpp b/src/utilities/ntrace/TracePluginImpl.cpp index 766613c1a50..7c241ee57d4 100644 --- a/src/utilities/ntrace/TracePluginImpl.cpp +++ b/src/utilities/ntrace/TracePluginImpl.cpp @@ -829,13 +829,19 @@ void TracePluginImpl::appendParams(ITraceParams* params) switch (parameters->dsc_dtype) { case dtype_text: - paramtype.printf("char(%d)", parameters->dsc_length); + if (parameters->getTextType() == fb_text_subtype_binary) + paramtype.printf("binary(%d)", parameters->dsc_length); + else + paramtype.printf("char(%d)", parameters->dsc_length); break; case dtype_cstring: paramtype.printf("cstring(%d)", parameters->dsc_length - 1); break; case dtype_varying: - paramtype.printf("varchar(%d)", parameters->dsc_length - 2); + if (parameters->getTextType() == fb_text_subtype_binary) + paramtype.printf("varbinary(%d)", parameters->dsc_length - 2); + else + paramtype.printf("varchar(%d)", parameters->dsc_length - 2); break; case dtype_blob: paramtype = "blob";