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

Let's transfer procedure aliases to the engine similarly to how it is done for relations. This allows more precise plan reporting.

I hate to waste the BLR space in such a vandal way, so I'm open to any better suggestions.
This commit is contained in:
dimitr 2009-12-14 11:19:26 +00:00
parent a0278f77b1
commit b9f0242ffd
3 changed files with 126 additions and 67 deletions

View File

@ -2234,23 +2234,19 @@ static void gen_relation( CompiledStatement* statement, dsql_ctx* context)
{
if (DDL_ids(statement))
{
if (context->ctx_alias)
stuff(statement, blr_rid2);
else
stuff(statement, blr_rid);
stuff(statement, context->ctx_alias ? blr_rid2 : blr_rid);
stuff_word(statement, relation->rel_id);
}
else
{
if (context->ctx_alias)
stuff(statement, blr_relation2);
else
stuff(statement, blr_relation);
stuff(statement, context->ctx_alias ? blr_relation2 : blr_relation);
stuff_meta_string(statement, relation->rel_name.c_str());
}
if (context->ctx_alias)
{
stuff_meta_string(statement, context->ctx_alias);
}
stuff_context(statement, context);
}
@ -2258,23 +2254,29 @@ static void gen_relation( CompiledStatement* statement, dsql_ctx* context)
{
if (DDL_ids(statement))
{
stuff(statement, blr_pid);
stuff(statement, context->ctx_alias ? blr_pid2 : blr_pid);
stuff_word(statement, procedure->prc_id);
}
else
{
if (procedure->prc_name.qualifier.hasData())
{
stuff(statement, blr_procedure2);
stuff(statement, context->ctx_alias ? blr_procedure4 : blr_procedure3);
stuff_meta_string(statement, procedure->prc_name.qualifier.c_str());
stuff_meta_string(statement, procedure->prc_name.identifier.c_str());
}
else
{
stuff(statement, blr_procedure);
stuff(statement, context->ctx_alias ? blr_procedure2 : blr_procedure);
stuff_meta_string(statement, procedure->prc_name.identifier.c_str());
}
}
if (context->ctx_alias)
{
stuff_meta_string(statement, context->ctx_alias);
}
stuff_context(statement, context);
dsql_nod* inputs = context->ctx_proc_inputs;

View File

@ -222,7 +222,8 @@
#define blr_cast (unsigned char)131
// unused codes: 132..133
#define blr_pid2 (unsigned char)132
#define blr_procedure2 (unsigned char)133
#define blr_start_savepoint (unsigned char)134
#define blr_end_savepoint (unsigned char)135
@ -380,7 +381,7 @@
// FB 3.0 specific BLR
#define blr_procedure2 (unsigned char) 192
#define blr_procedure3 (unsigned char) 192
#define blr_exec_proc2 (unsigned char) 193
#define blr_function2 (unsigned char) 194
@ -388,5 +389,6 @@
#define blr_partition_by (unsigned char) 196
#define blr_continue_loop (unsigned char) 197
#define blr_procedure4 (unsigned char) 198
#endif // JRD_BLR_H

View File

@ -1157,25 +1157,25 @@ static jrd_nod* par_exec_proc(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_
SET_TDBB(tdbb);
jrd_prc* procedure = NULL;
QualifiedName name;
if (blr_operator == blr_exec_pid)
{
QualifiedName name;
const USHORT pid = csb->csb_blr_reader.getWord();
if (!(procedure = MET_lookup_procedure_id(tdbb, pid, false, false, 0)))
name.identifier.printf("id %d", pid);
}
else
{
if (blr_operator == blr_exec_proc2)
PAR_name(csb, name.qualifier);
PAR_name(csb, name.identifier);
procedure = MET_lookup_procedure(tdbb, name, false);
}
if (blr_operator == blr_exec_pid)
{
const USHORT pid = csb->csb_blr_reader.getWord();
if (!(procedure = MET_lookup_procedure_id(tdbb, pid, false, false, 0)))
name.identifier.printf("id %d", pid);
}
else
{
if (blr_operator == blr_exec_proc2)
PAR_name(csb, name.qualifier);
PAR_name(csb, name.identifier);
procedure = MET_lookup_procedure(tdbb, name, false);
}
if (!procedure)
error(csb, Arg::Gds(isc_prcnotdef) << Arg::Str(name.toString()));
if (!procedure)
{
error(csb, Arg::Gds(isc_prcnotdef) << Arg::Str(name.toString()));
}
jrd_nod* node = PAR_make_node(tdbb, e_esp_length);
@ -2077,30 +2077,61 @@ static jrd_nod* par_procedure(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_
* Parse an procedural view reference.
*
**************************************/
jrd_prc* procedure;
SET_TDBB(tdbb);
jrd_prc* procedure = NULL;
Firebird::string* alias_string = NULL;
QualifiedName name;
switch (blr_operator)
{
QualifiedName name;
if (blr_operator == blr_procedure || blr_operator == blr_procedure2)
{
if (blr_operator == blr_procedure2)
PAR_name(csb, name.qualifier);
PAR_name(csb, name.identifier);
procedure = MET_lookup_procedure(tdbb, name, false);
}
else
case blr_pid:
case blr_pid2:
{
const SSHORT pid = csb->csb_blr_reader.getWord();
if (!(procedure = MET_lookup_procedure_id(tdbb, pid, false, false, 0)))
name.identifier.printf("id %d", pid);
}
if (!procedure)
error(csb, Arg::Gds(isc_prcnotdef) << Arg::Str(name.toString()));
if (blr_operator == blr_pid2)
{
alias_string = FB_NEW(csb->csb_pool) Firebird::string(csb->csb_pool);
PAR_name(csb, *alias_string);
}
if (!(procedure = MET_lookup_procedure_id(tdbb, pid, false, false, 0)))
{
name.identifier.printf("id %d", pid);
}
}
break;
case blr_procedure:
case blr_procedure2:
case blr_procedure3:
case blr_procedure4:
{
if (blr_operator == blr_procedure3 || blr_operator == blr_procedure4)
{
PAR_name(csb, name.qualifier);
}
PAR_name(csb, name.identifier);
if (blr_operator == blr_procedure2 || blr_operator == blr_procedure4)
{
alias_string = FB_NEW(csb->csb_pool) Firebird::string(csb->csb_pool);
PAR_name(csb, *alias_string);
}
procedure = MET_lookup_procedure(tdbb, name, false);
}
break;
default:
fb_assert(false);
}
if (!procedure)
{
error(csb, Arg::Gds(isc_prcnotdef) << Arg::Str(name.toString()));
}
if (procedure->prc_type == prc_executable)
@ -2108,7 +2139,7 @@ static jrd_nod* par_procedure(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_
error(csb, Arg::Gds(isc_illegal_prc_type) << Arg::Str(procedure->prc_name.toString()));
}
jrd_nod* node = PAR_make_node(tdbb, e_prc_length);
jrd_nod* const node = PAR_make_node(tdbb, e_prc_length);
node->nod_type = nod_procedure;
node->nod_count = count_table[blr_procedure];
node->nod_arg[e_prc_procedure] = (jrd_nod*) (IPTR) procedure->prc_id;
@ -2116,14 +2147,18 @@ static jrd_nod* par_procedure(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_
SSHORT context;
const SSHORT stream = par_context(csb, &context);
node->nod_arg[e_prc_stream] = (jrd_nod*) (IPTR) stream;
csb->csb_rpt[stream].csb_procedure = procedure;
node->nod_arg[e_prc_context] = (jrd_nod*) (IPTR) context;
csb->csb_rpt[stream].csb_procedure = procedure;
csb->csb_rpt[stream].csb_alias = alias_string;
par_procedure_parms(tdbb, csb, procedure, &node->nod_arg[e_prc_in_msg],
&node->nod_arg[e_prc_inputs], true);
if (csb->csb_g_flags & csb_get_dependencies)
{
par_dependency(tdbb, csb, stream, (SSHORT) -1, "");
}
return node;
}
@ -2273,55 +2308,68 @@ static jrd_nod* par_relation(thread_db* tdbb,
* Parse a relation reference.
*
**************************************/
Firebird::MetaName name;
SET_TDBB(tdbb);
// Make a relation reference node
jrd_nod* node = PAR_make_node(tdbb, e_rel_length);
node->nod_count = 0;
// Find relation either by id or by name
jrd_rel* relation = 0;
Firebird::string* alias_string = 0;
jrd_rel* relation = NULL;
Firebird::string* alias_string = NULL;
Firebird::MetaName name;
switch (blr_operator)
{
case blr_rid:
case blr_rid2:
{
const SSHORT id = csb->csb_blr_reader.getWord();
if (blr_operator == blr_rid2)
{
alias_string = FB_NEW(csb->csb_pool) Firebird::string(csb->csb_pool);
PAR_name(csb, *alias_string);
}
if (!(relation = MET_lookup_relation_id(tdbb, id, false)))
{
name.printf("id %d", id);
error(csb, Arg::Gds(isc_relnotdef) << Arg::Str(name), false);
}
}
break;
case blr_relation:
case blr_relation2:
PAR_name(csb, name);
if (blr_operator == blr_relation2)
{
alias_string = FB_NEW(csb->csb_pool) Firebird::string(csb->csb_pool);
PAR_name(csb, *alias_string);
PAR_name(csb, name);
if (blr_operator == blr_relation2)
{
alias_string = FB_NEW(csb->csb_pool) Firebird::string(csb->csb_pool);
PAR_name(csb, *alias_string);
}
relation = MET_lookup_relation(tdbb, name);
}
if (!(relation = MET_lookup_relation(tdbb, name)))
error(csb, Arg::Gds(isc_relnotdef) << Arg::Str(name), false);
break;
default:
fb_assert(false);
}
if (!relation)
{
error(csb, Arg::Gds(isc_relnotdef) << Arg::Str(name), false);
}
// Make a relation reference node
jrd_nod* const node = PAR_make_node(tdbb, e_rel_length);
node->nod_count = 0;
// if an alias was passed, store with the relation
if (alias_string)
{
node->nod_arg[e_rel_alias] =
(jrd_nod*) stringDup(*tdbb->getDefaultPool(), alias_string->c_str());
(jrd_nod*) stringDup(*tdbb->getDefaultPool(), *alias_string);
}
// Scan the relation if it hasn't already been scanned for meta data
@ -2351,7 +2399,9 @@ static jrd_nod* par_relation(thread_db* tdbb,
csb->csb_rpt[stream].csb_alias = alias_string;
if (csb->csb_g_flags & csb_get_dependencies)
{
par_dependency(tdbb, csb, stream, (SSHORT) -1, "");
}
}
else
{
@ -3038,12 +3088,17 @@ jrd_nod* PAR_parse_node(thread_db* tdbb, CompilerScratch* csb, USHORT expected)
case blr_exec_proc2:
case blr_exec_pid:
node = par_exec_proc(tdbb, csb, blr_operator);
set_type = false;
break;
case blr_pid:
case blr_pid2:
case blr_procedure:
case blr_procedure2:
case blr_procedure3:
case blr_procedure4:
node = par_procedure(tdbb, csb, blr_operator);
set_type = false;
break;
case blr_function: