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

Add SET DEBUG OPTION DSQL_KEEP_BLR and remove Statement::PREPARE_KEEP_EXEC_PATH flag.

Make ISQL' SET EXEC_PATH_DISPLAY persistent between connections.
This commit is contained in:
Adriano dos Santos Fernandes 2021-07-30 16:35:48 -03:00
parent ee53a7c46b
commit 32c3cf573b
14 changed files with 143 additions and 33 deletions

View File

@ -169,6 +169,7 @@ static const TOK tokens[] =
{TOK_DATEDIFF, "DATEDIFF", true},
{TOK_DAY, "DAY", false},
{TOK_DDL, "DDL", true},
{TOK_DEBUG, "DEBUG", true},
{TOK_DEC, "DEC", false},
{TOK_DECFLOAT, "DECFLOAT", false},
{TOK_DECIMAL, "DECIMAL", false},

View File

@ -76,7 +76,6 @@ public:
transaction(aTransaction),
statement(aStatement),
flags(0),
prepareFlags(0),
nestingLevel(0),
ports(p),
relation(NULL),
@ -268,7 +267,6 @@ private:
public:
unsigned flags; // flags
unsigned prepareFlags; // prepare flags (IStatement::PREPARE*)
unsigned nestingLevel; // begin...end nesting level
Firebird::Array<dsql_msg*> ports; // Port messages
dsql_rel* relation; // relation created by this request (for DDL)

View File

@ -229,7 +229,6 @@ DdlNode* CreateAlterPackageNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->prepareFlags = dsqlScratch->prepareFlags;
itemScratch->package = name;
switch ((*items)[i].type)
@ -625,7 +624,6 @@ DdlNode* CreatePackageBodyNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
itemScratch->clientDialect = dsqlScratch->clientDialect;
itemScratch->flags |= DsqlCompilerScratch::FLAG_DDL;
itemScratch->prepareFlags = dsqlScratch->prepareFlags;
itemScratch->package = name;
switch ((*arrays[i])[j].type)

View File

@ -1725,7 +1725,6 @@ DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
DsqlCompilerScratch::FLAG_FUNCTION |
DsqlCompilerScratch::FLAG_SUB_ROUTINE |
(dsqlScratch->flags & DsqlCompilerScratch::FLAG_DDL);
blockScratch->prepareFlags = dsqlScratch->prepareFlags;
dsqlBlock = dsqlBlock->dsqlPass(blockScratch);
@ -2069,7 +2068,6 @@ DeclareSubProcNode* DeclareSubProcNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
DsqlCompilerScratch::FLAG_PROCEDURE |
DsqlCompilerScratch::FLAG_SUB_ROUTINE |
(dsqlScratch->flags & DsqlCompilerScratch::FLAG_DDL);
blockScratch->prepareFlags = dsqlScratch->prepareFlags;
dsqlBlock = dsqlBlock->dsqlPass(blockScratch);
@ -8587,6 +8585,39 @@ void SetRoleNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** /*traHan
//--------------------
SetDebugOptionNode::SetDebugOptionNode(MemoryPool& pool, MetaName* aName, ExprNode* aValue)
: SessionManagementNode(pool),
name(pool, *aName),
value(aValue)
{
}
void SetDebugOptionNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
{
SET_TDBB(tdbb);
auto& debugOptions = tdbb->getAttachment()->getDebugOptions();
const auto literal = nodeAs<LiteralNode>(value);
if (!literal)
{
// This currently can happen with negative numbers.
// Since it's not relevant for DSQL_KEEP_BLR, let's throw an error.
ERR_post(Arg::Gds(isc_random) << "Invalid DEBUG option value");
}
const auto litDesc = &literal->litDesc;
if (name == "DSQL_KEEP_BLR")
debugOptions.setDsqlKeepBlr(MOV_get_boolean(litDesc));
else
ERR_post(Arg::Gds(isc_random) << "Invalid DEBUG option");
}
//--------------------
SetDecFloatRoundNode::SetDecFloatRoundNode(MemoryPool& pool, MetaName* name)
: SessionManagementNode(pool)
{

View File

@ -1725,6 +1725,30 @@ private:
};
class SetDebugOptionNode : public SessionManagementNode
{
public:
SetDebugOptionNode(MemoryPool& pool, MetaName* aName, ExprNode* aValue);
public:
virtual Firebird::string internalPrint(NodePrinter& printer) const
{
SessionManagementNode::internalPrint(printer);
NODE_PRINT(printer, name);
NODE_PRINT(printer, value);
return "SetDebugOptionNode";
}
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
private:
MetaName name;
ExprNode* value;
};
class SetDecFloatRoundNode : public SessionManagementNode
{
public:

View File

@ -82,8 +82,8 @@ using namespace Firebird;
static ULONG get_request_info(thread_db*, dsql_req*, ULONG, UCHAR*);
static dsql_dbb* init(Jrd::thread_db*, Jrd::Attachment*);
static dsql_req* prepareRequest(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, unsigned, bool);
static dsql_req* prepareStatement(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, unsigned, bool);
static dsql_req* prepareRequest(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, bool);
static dsql_req* prepareStatement(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, bool);
static UCHAR* put_item(UCHAR, const USHORT, const UCHAR*, UCHAR*, const UCHAR* const);
static void release_statement(DsqlCompiledStatement* statement);
static void sql_info(thread_db*, dsql_req*, ULONG, const UCHAR*, ULONG, UCHAR*);
@ -406,7 +406,7 @@ dsql_req* DSQL_prepare(thread_db* tdbb,
// Allocate a new request block and then prepare the request.
request = prepareRequest(tdbb, database, transaction, length, string, dialect,
prepareFlags, isInternalRequest);
isInternalRequest);
// Can not prepare a CREATE DATABASE/SCHEMA statement
@ -557,7 +557,7 @@ void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tr
try
{
request = prepareRequest(tdbb, database, *tra_handle, length, string, dialect,
0, isInternalRequest);
isInternalRequest);
const DsqlCompiledStatement* statement = request->getStatement();
@ -659,8 +659,7 @@ void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch, boo
scratch->getBlrData().getCount(), scratch->getBlrData().begin(),
statement->getSqlText(),
scratch->getDebugData().getCount(), scratch->getDebugData().begin(),
(scratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST),
(scratch->prepareFlags & IStatement::PREPARE_KEEP_EXEC_PATH));
(scratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST));
}
catch (const Exception&)
{
@ -1478,17 +1477,16 @@ static void checkD(IStatus* st)
// Prepare a request for execution. Return SQL status code.
// Note: caller is responsible for pool handling.
static dsql_req* prepareRequest(thread_db* tdbb, dsql_dbb* database, jrd_tra* transaction,
ULONG textLength, const TEXT* text, USHORT clientDialect, unsigned prepareFlags, bool isInternalRequest)
ULONG textLength, const TEXT* text, USHORT clientDialect, bool isInternalRequest)
{
return prepareStatement(tdbb, database, transaction, textLength, text, clientDialect,
prepareFlags, isInternalRequest);
return prepareStatement(tdbb, database, transaction, textLength, text, clientDialect, isInternalRequest);
}
// Prepare a statement for execution. Return SQL status code.
// Note: caller is responsible for pool handling.
static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra* transaction,
ULONG textLength, const TEXT* text, USHORT clientDialect, unsigned prepareFlags, bool isInternalRequest)
ULONG textLength, const TEXT* text, USHORT clientDialect, bool isInternalRequest)
{
Database* const dbb = tdbb->getDatabase();
@ -1548,7 +1546,6 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra*
DsqlCompilerScratch* scratch = FB_NEW_POOL(*scratchPool) DsqlCompilerScratch(*scratchPool, database,
transaction, statement);
scratch->prepareFlags = prepareFlags;
scratch->clientDialect = clientDialect;
if (isInternalRequest)

View File

@ -677,6 +677,10 @@ using namespace Firebird;
%token <metaNamePtr> CLEAR
%token <metaNamePtr> OLDEST
// tokens added for Firebird 4.0.1
%token <metaNamePtr> DEBUG
// precedence declarations for expression evaluation
%left OR
@ -884,7 +888,8 @@ tra_statement
%type <mngNode> mng_statement
mng_statement
: set_decfloat_round { $$ = $1; }
: set_debug_option { $$ = $1; }
| set_decfloat_round { $$ = $1; }
| set_decfloat_traps { $$ = $1; }
| session_statement { $$ = $1; }
| set_role { $$ = $1; }
@ -5348,6 +5353,12 @@ set_role
{ $$ = newNode<SetRoleNode>(); }
;
%type <mngNode> set_debug_option
set_debug_option
: SET DEBUG OPTION valid_symbol_name '=' constant
{ $$ = newNode<SetDebugOptionNode>($4, $6); }
;
%type <setDecFloatRoundNode> set_decfloat_round
set_decfloat_round
: SET DECFLOAT ROUND valid_symbol_name
@ -9040,6 +9051,7 @@ non_reserved_word
| TOTALORDER
| TRAPS
| ZONE
| DEBUG // added in FB 4.0.1
;
%%

View File

@ -452,11 +452,6 @@ interface Statement : ReferenceCounted
PREPARE_PREFETCH_METADATA | PREPARE_PREFETCH_LEGACY_PLAN | PREPARE_PREFETCH_DETAILED_PLAN |
PREPARE_PREFETCH_AFFECTED_RECORDS;
// Keep the execution path information to be retrieved with getInfo and isc_info_sql_exec_path_*
// Warning: this feature is very tied to engine internals and its usage is discouraged if you do
// not understand very well how these internals are subject to change between versions.
const uint PREPARE_KEEP_EXEC_PATH = 0x80;
// Statement flags.
const uint FLAG_HAS_CURSOR = 0x01;
const uint FLAG_REPEAT_EXECUTE = 0x02;

View File

@ -1718,7 +1718,6 @@ namespace Firebird
static const unsigned PREPARE_PREFETCH_FLAGS = 0x40;
static const unsigned PREPARE_PREFETCH_METADATA = IStatement::PREPARE_PREFETCH_TYPE | IStatement::PREPARE_PREFETCH_FLAGS | IStatement::PREPARE_PREFETCH_INPUT_PARAMETERS | IStatement::PREPARE_PREFETCH_OUTPUT_PARAMETERS;
static const unsigned PREPARE_PREFETCH_ALL = IStatement::PREPARE_PREFETCH_METADATA | IStatement::PREPARE_PREFETCH_LEGACY_PLAN | IStatement::PREPARE_PREFETCH_DETAILED_PLAN | IStatement::PREPARE_PREFETCH_AFFECTED_RECORDS;
static const unsigned PREPARE_KEEP_EXEC_PATH = 0x80;
static const unsigned FLAG_HAS_CURSOR = 0x1;
static const unsigned FLAG_REPEAT_EXECUTE = 0x2;
static const unsigned CURSOR_TYPE_SCROLLABLE = 0x1;

View File

@ -1457,7 +1457,6 @@ type
const PREPARE_PREFETCH_FLAGS = Cardinal($40);
const PREPARE_PREFETCH_METADATA = Cardinal(IStatement.PREPARE_PREFETCH_TYPE or IStatement.PREPARE_PREFETCH_FLAGS or IStatement.PREPARE_PREFETCH_INPUT_PARAMETERS or IStatement.PREPARE_PREFETCH_OUTPUT_PARAMETERS);
const PREPARE_PREFETCH_ALL = Cardinal(IStatement.PREPARE_PREFETCH_METADATA or IStatement.PREPARE_PREFETCH_LEGACY_PLAN or IStatement.PREPARE_PREFETCH_DETAILED_PLAN or IStatement.PREPARE_PREFETCH_AFFECTED_RECORDS);
const PREPARE_KEEP_EXEC_PATH = Cardinal($80);
const FLAG_HAS_CURSOR = Cardinal($1);
const FLAG_REPEAT_EXECUTE = Cardinal($2);
const CURSOR_TYPE_SCROLLABLE = Cardinal($1);

View File

@ -368,6 +368,7 @@ static processing_state drop_db();
static processing_state edit(const TEXT* const*);
static processing_state end_trans();
static processing_state escape(const TEXT*);
static processing_state execSetDebugCommand();
static processing_state frontend(const TEXT*);
static processing_state frontend_set(const char* cmd, const char* const* parms,
const char* const* lparms, char* const bad_dialect_buf, bool& bad_dialect);
@ -4790,6 +4791,27 @@ static processing_state escape(const TEXT* cmd)
}
static processing_state execSetDebugCommand()
{
if (!DB)
return SKIP;
const char* stmt = setValues.ExecPathDisplay[0] ?
"set debug option dsql_keep_blr = true" :
"set debug option dsql_keep_blr = false";
DB->execute(fbStatus, nullptr, 0, stmt, isqlGlob.SQL_dialect, nullptr, nullptr, nullptr, nullptr);
if (setValues.ExecPathDisplay[0] && (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS))
{
STDERROUT("SET EXEC_PATH_DISPLAY is not supported in this connection.");
return FAIL;
}
return SKIP;
}
static processing_state frontend(const TEXT* statement)
{
/**************************************
@ -5357,7 +5379,10 @@ static processing_state frontend_set(const char* cmd, const char* const* parms,
case SetOptions::exec_path_display:
ret = SKIP;
if (strcmp(parms[2], "OFF") == 0)
if (!*parms[2])
ret = ps_ERR;
else if (strcmp(parms[2], "OFF") == 0)
setValues.ExecPathDisplay[0] = 0;
else
{
@ -5396,6 +5421,10 @@ static processing_state frontend_set(const char* cmd, const char* const* parms,
ret = ps_ERR;
}
}
if (ret != ps_ERR)
ret = execSetDebugCommand();
break;
case SetOptions::sql:
@ -6100,6 +6129,9 @@ void ISQL_get_version(bool call_by_create_db)
isqlGlob.db_SQL_dialect = global_dialect_spoken;
else
isqlGlob.db_SQL_dialect = SQL_DIALECT_V5;
if (setValues.ExecPathDisplay[0])
execSetDebugCommand();
}
@ -6761,6 +6793,9 @@ static processing_state newdb(TEXT* dbname,
}
}
if (setValues.ExecPathDisplay[0])
execSetDebugCommand();
global_Stmt = NULL;
return SKIP;
@ -8852,8 +8887,7 @@ static processing_state process_statement(const TEXT* str2)
}
global_Stmt = DB->prepare(fbStatus, prepare_trans, 0, str2, isqlGlob.SQL_dialect,
Firebird::IStatement::PREPARE_PREFETCH_METADATA |
(setValues.ExecPathDisplay[0] ? Firebird::IStatement::PREPARE_KEEP_EXEC_PATH : 0));
Firebird::IStatement::PREPARE_PREFETCH_METADATA);
if (failed())
{
if (isqlGlob.SQL_dialect == SQL_DIALECT_V6_TRANSITION && Input_file)

View File

@ -401,6 +401,23 @@ public:
USHORT originalTimeZone = Firebird::TimeZoneUtil::GMT_ZONE;
};
class DebugOptions
{
public:
bool getDsqlKeepBlr() const
{
return dsqlKeepBlr;
}
void setDsqlKeepBlr(bool value)
{
dsqlKeepBlr = value;
}
private:
bool dsqlKeepBlr = false;
};
public:
static Attachment* create(Database* dbb, JProvider* provider);
static void destroy(Attachment* const attachment);
@ -656,6 +673,11 @@ public:
return att_initial_options.getBindings();
}
DebugOptions& getDebugOptions()
{
return att_debug_options;
}
void checkReplSetLock(thread_db* tdbb);
void invalidateReplSet(thread_db* tdbb, bool broadcast);
@ -677,6 +699,7 @@ private:
Firebird::Array<JBatch*> att_batches;
InitialOptions att_initial_options; // Initial session options
DebugOptions att_debug_options;
Lock* att_repl_lock; // Replication set lock
JProvider* att_provider; // Provider which created this attachment

View File

@ -2646,7 +2646,7 @@ JRequest* JAttachment::compileRequest(CheckStatusWrapper* user_status,
try
{
jrd_req* request = NULL;
JRD_compile(tdbb, getHandle(), &request, blr_length, blr, RefStrPtr(), 0, NULL, false, false);
JRD_compile(tdbb, getHandle(), &request, blr_length, blr, RefStrPtr(), 0, NULL, false);
stmt = request->getStatement();
trace.finish(request, ITracePlugin::RESULT_SUCCESS);
@ -9189,8 +9189,7 @@ void JRD_compile(thread_db* tdbb,
RefStrPtr ref_str,
ULONG dbginfo_length,
const UCHAR* dbginfo,
bool isInternalRequest,
bool preserveBlrData)
bool isInternalRequest)
{
/**************************************
*
@ -9216,7 +9215,7 @@ void JRD_compile(thread_db* tdbb,
fb_assert(statement->blr.isEmpty());
if (preserveBlrData)
if (attachment->getDebugOptions().getDsqlKeepBlr())
statement->blr.insert(0, blr, blr_length);
*req_handle = request;

View File

@ -73,7 +73,7 @@ void JRD_start_transaction(Jrd::thread_db* tdbb, Jrd::jrd_tra** transaction,
void JRD_unwind_request(Jrd::thread_db* tdbb, Jrd::jrd_req* request);
void JRD_compile(Jrd::thread_db* tdbb, Jrd::Attachment* attachment, Jrd::jrd_req** req_handle,
ULONG blr_length, const UCHAR* blr, Firebird::RefStrPtr,
ULONG dbginfo_length, const UCHAR* dbginfo, bool isInternalRequest, bool preserveBlrData);
ULONG dbginfo_length, const UCHAR* dbginfo, bool isInternalRequest);
bool JRD_verify_database_access(const Firebird::PathName&);
void JRD_shutdown_attachment(Jrd::Attachment* attachment);
void JRD_shutdown_attachments(Jrd::Database* dbb);