mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 12:43:03 +01:00
1) Make procedures and functions member of the same hierarchy (Routine class)
2) Some completion for external functions
This commit is contained in:
parent
24dd5e8f6e
commit
d8c99a9be2
@ -34,7 +34,6 @@ enum BlockType
|
||||
type_riv,
|
||||
type_att,
|
||||
type_sym,
|
||||
type_fun,
|
||||
type_irl,
|
||||
type_idl,
|
||||
type_sdw,
|
||||
@ -42,7 +41,6 @@ enum BlockType
|
||||
type_blf,
|
||||
type_arr,
|
||||
type_map,
|
||||
type_prc,
|
||||
type_prm,
|
||||
type_sav,
|
||||
type_xcp,
|
||||
|
@ -1129,18 +1129,18 @@ void DatabaseSnapshot::putCall(const jrd_req* request, Writer& writer, int stat_
|
||||
// object name/type
|
||||
if (request->req_procedure)
|
||||
{
|
||||
if (request->req_procedure->prc_name.qualifier.hasData())
|
||||
record.storeString(f_mon_call_pkg_name, request->req_procedure->prc_name.qualifier);
|
||||
if (request->req_procedure->getName().qualifier.hasData())
|
||||
record.storeString(f_mon_call_pkg_name, request->req_procedure->getName().qualifier);
|
||||
|
||||
record.storeString(f_mon_call_name, request->req_procedure->prc_name.identifier);
|
||||
record.storeString(f_mon_call_name, request->req_procedure->getName().identifier);
|
||||
record.storeInteger(f_mon_call_type, obj_procedure);
|
||||
}
|
||||
else if (request->req_function)
|
||||
{
|
||||
if (request->req_function->fun_name.qualifier.hasData())
|
||||
record.storeString(f_mon_call_pkg_name, request->req_function->fun_name.qualifier);
|
||||
if (request->req_function->getName().qualifier.hasData())
|
||||
record.storeString(f_mon_call_pkg_name, request->req_function->getName().qualifier);
|
||||
|
||||
record.storeString(f_mon_call_name, request->req_function->fun_name.identifier);
|
||||
record.storeString(f_mon_call_name, request->req_function->getName().identifier);
|
||||
record.storeInteger(f_mon_call_type, obj_udf);
|
||||
}
|
||||
else if (!request->req_trg_name.isEmpty())
|
||||
|
@ -396,8 +396,10 @@ ExtEngineManager::Function::~Function()
|
||||
void ExtEngineManager::Function::execute(thread_db* tdbb, jrd_nod* args, impure_value* impure)
|
||||
{
|
||||
EngineAttachmentInfo* attInfo = extManager->getEngineAttachment(tdbb, engine);
|
||||
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo,
|
||||
function); // CallerName(obj_udf, function->fun_name)
|
||||
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, function,
|
||||
(udf->getName().qualifier.isEmpty() ?
|
||||
CallerName(obj_udf, udf->getName().identifier) :
|
||||
CallerName(obj_package_header, udf->getName().qualifier)));
|
||||
|
||||
impure->vlu_desc.dsc_flags = DSC_null;
|
||||
MemoryPool& pool = *tdbb->getDefaultPool();
|
||||
@ -487,7 +489,7 @@ ExtEngineManager::Procedure::~Procedure()
|
||||
|
||||
|
||||
ExtEngineManager::ResultSet* ExtEngineManager::Procedure::open(thread_db* tdbb,
|
||||
ValuesImpl* inputParams, ValuesImpl* outputParams)
|
||||
ValuesImpl* inputParams, ValuesImpl* outputParams) const
|
||||
{
|
||||
return FB_NEW(*tdbb->getDefaultPool()) ResultSet(tdbb, inputParams, outputParams, this);
|
||||
}
|
||||
@ -497,16 +499,16 @@ ExtEngineManager::ResultSet* ExtEngineManager::Procedure::open(thread_db* tdbb,
|
||||
|
||||
|
||||
ExtEngineManager::ResultSet::ResultSet(thread_db* tdbb, ValuesImpl* inputParams,
|
||||
ValuesImpl* outputParams, ExtEngineManager::Procedure* aProcedure)
|
||||
ValuesImpl* outputParams, const ExtEngineManager::Procedure* aProcedure)
|
||||
: procedure(aProcedure),
|
||||
database(tdbb->getDatabase()),
|
||||
firstFetch(true)
|
||||
{
|
||||
attInfo = procedure->extManager->getEngineAttachment(tdbb, procedure->engine);
|
||||
ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, procedure->procedure,
|
||||
(procedure->prc->prc_name.qualifier.isEmpty() ?
|
||||
CallerName(obj_procedure, procedure->prc->prc_name.identifier) :
|
||||
CallerName(obj_package_header, procedure->prc->prc_name.qualifier)));
|
||||
(procedure->prc->getName().qualifier.isEmpty() ?
|
||||
CallerName(obj_procedure, procedure->prc->getName().identifier) :
|
||||
CallerName(obj_package_header, procedure->prc->getName().qualifier)));
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
charSet = attachment->att_charset;
|
||||
@ -537,9 +539,9 @@ bool ExtEngineManager::ResultSet::fetch(thread_db* tdbb)
|
||||
return wasFirstFetch;
|
||||
|
||||
ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, charSet,
|
||||
(procedure->prc->prc_name.qualifier.isEmpty() ?
|
||||
CallerName(obj_procedure, procedure->prc->prc_name.identifier) :
|
||||
CallerName(obj_package_header, procedure->prc->prc_name.qualifier)));
|
||||
(procedure->prc->getName().qualifier.isEmpty() ?
|
||||
CallerName(obj_procedure, procedure->prc->getName().identifier) :
|
||||
CallerName(obj_package_header, procedure->prc->getName().qualifier)));
|
||||
|
||||
Database::Checkout dcoHolder(tdbb->getDatabase());
|
||||
return resultSet->fetch(RaiseError());
|
||||
@ -756,8 +758,10 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
|
||||
entryPointTrimmed.trim();
|
||||
|
||||
EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine);
|
||||
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo,
|
||||
attInfo->adminCharSet); // CallerName(obj_udf, udf->fun_name)
|
||||
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, attInfo->adminCharSet,
|
||||
(udf->getName().qualifier.isEmpty() ?
|
||||
CallerName(obj_udf, udf->getName().identifier) :
|
||||
CallerName(obj_package_header, udf->getName().qualifier)));
|
||||
|
||||
ExternalFunction* externalFunction;
|
||||
|
||||
@ -765,7 +769,7 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
|
||||
Database::Checkout dcoHolder(tdbb->getDatabase());
|
||||
|
||||
externalFunction = attInfo->engine->makeFunction(RaiseError(),
|
||||
attInfo->context, udf->fun_name.qualifier.nullStr(), udf->fun_name.identifier.c_str(),
|
||||
attInfo->context, udf->getName().qualifier.nullStr(), udf->getName().identifier.c_str(),
|
||||
entryPointTrimmed.nullStr(), body.nullStr());
|
||||
|
||||
if (!externalFunction)
|
||||
@ -799,9 +803,9 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
|
||||
|
||||
EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine);
|
||||
ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, attInfo->adminCharSet,
|
||||
(prc->prc_name.qualifier.isEmpty() ?
|
||||
CallerName(obj_procedure, prc->prc_name.identifier) :
|
||||
CallerName(obj_package_header, prc->prc_name.qualifier)));
|
||||
(prc->getName().qualifier.isEmpty() ?
|
||||
CallerName(obj_procedure, prc->getName().identifier) :
|
||||
CallerName(obj_package_header, prc->getName().qualifier)));
|
||||
|
||||
ExternalProcedure* externalProcedure;
|
||||
|
||||
@ -809,7 +813,7 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
|
||||
Database::Checkout dcoHolder(tdbb->getDatabase());
|
||||
|
||||
externalProcedure = attInfo->engine->makeProcedure(RaiseError(),
|
||||
attInfo->context, prc->prc_name.qualifier.nullStr(), prc->prc_name.identifier.c_str(),
|
||||
attInfo->context, prc->getName().qualifier.nullStr(), prc->getName().identifier.c_str(),
|
||||
entryPointTrimmed.nullStr(), body.nullStr());
|
||||
|
||||
if (!externalProcedure)
|
||||
|
@ -151,7 +151,7 @@ public:
|
||||
const jrd_prc* aPrc);
|
||||
~Procedure();
|
||||
|
||||
ResultSet* open(thread_db* tdbb, ValuesImpl* inputParams, ValuesImpl* outputParams);
|
||||
ResultSet* open(thread_db* tdbb, ValuesImpl* inputParams, ValuesImpl* outputParams) const;
|
||||
|
||||
private:
|
||||
ExtEngineManager* extManager;
|
||||
@ -167,13 +167,13 @@ public:
|
||||
{
|
||||
public:
|
||||
ResultSet(thread_db* tdbb, ValuesImpl* inputParams, ValuesImpl* outputParams,
|
||||
Procedure* aProcedure);
|
||||
const Procedure* aProcedure);
|
||||
~ResultSet();
|
||||
|
||||
bool fetch(thread_db* tdbb);
|
||||
|
||||
private:
|
||||
Procedure* procedure;
|
||||
const Procedure* procedure;
|
||||
Database* database;
|
||||
bool firstFetch;
|
||||
EngineAttachmentInfo* attInfo;
|
||||
|
@ -65,7 +65,7 @@ Function* Function::lookup(thread_db* tdbb, USHORT id, bool return_deleted, bool
|
||||
|
||||
Function* function = (id < dbb->dbb_functions.getCount()) ? dbb->dbb_functions[id] : NULL;
|
||||
|
||||
if (function && function->fun_id == id &&
|
||||
if (function && function->getId() == id &&
|
||||
!(function->fun_flags & FUN_being_scanned) &&
|
||||
((function->fun_flags & FUN_scanned) || noscan) &&
|
||||
!(function->fun_flags & FUN_being_altered) &&
|
||||
@ -129,7 +129,7 @@ Function* Function::lookup(thread_db* tdbb, const QualifiedName& name, bool nosc
|
||||
!(function->fun_flags & FUN_being_scanned) &&
|
||||
!(function->fun_flags & FUN_being_altered))
|
||||
{
|
||||
if (function->fun_name == name)
|
||||
if (function->getName() == name)
|
||||
{
|
||||
if (function->fun_flags & FUN_check_existence)
|
||||
{
|
||||
@ -211,7 +211,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
function->fun_flags |= (FUN_being_scanned | flags);
|
||||
function->fun_flags &= ~FUN_obsolete;
|
||||
|
||||
function->fun_id = id;
|
||||
function->setId(id);
|
||||
dbb->dbb_functions[id] = function;
|
||||
|
||||
if (!function->fun_existence_lock)
|
||||
@ -220,7 +220,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
function->fun_existence_lock = lock;
|
||||
lock->lck_parent = dbb->dbb_lock;
|
||||
lock->lck_dbb = dbb;
|
||||
lock->lck_key.lck_long = function->fun_id;
|
||||
lock->lck_key.lck_long = function->getId();
|
||||
lock->lck_length = sizeof(lock->lck_key.lck_long);
|
||||
lock->lck_type = LCK_fun_exist;
|
||||
lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
|
||||
@ -245,12 +245,12 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
if (!REQUEST(irq_l_functions))
|
||||
REQUEST(irq_l_functions) = request_fun;
|
||||
|
||||
function->fun_name = QualifiedName(X.RDB$FUNCTION_NAME,
|
||||
(X.RDB$PACKAGE_NAME.NULL ? NULL : X.RDB$PACKAGE_NAME));
|
||||
function->setName(QualifiedName(X.RDB$FUNCTION_NAME,
|
||||
(X.RDB$PACKAGE_NAME.NULL ? NULL : X.RDB$PACKAGE_NAME)));
|
||||
|
||||
if (!X.RDB$SECURITY_CLASS.NULL)
|
||||
{
|
||||
function->fun_security_name = X.RDB$SECURITY_CLASS;
|
||||
function->setSecurityName(X.RDB$SECURITY_CLASS);
|
||||
}
|
||||
else if (!X.RDB$PACKAGE_NAME.NULL)
|
||||
{
|
||||
@ -262,7 +262,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
|
||||
if (!PKG.RDB$SECURITY_CLASS.NULL)
|
||||
{
|
||||
function->fun_security_name = PKG.RDB$SECURITY_CLASS;
|
||||
function->setSecurityName(PKG.RDB$SECURITY_CLASS);
|
||||
}
|
||||
|
||||
END_FOR
|
||||
@ -279,8 +279,8 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
|
||||
FOR(REQUEST_HANDLE request_arg)
|
||||
Y IN RDB$FUNCTION_ARGUMENTS
|
||||
WITH Y.RDB$FUNCTION_NAME EQ function->fun_name.identifier.c_str() AND
|
||||
Y.RDB$PACKAGE_NAME EQUIV NULLIF(function->fun_name.qualifier.c_str(), '')
|
||||
WITH Y.RDB$FUNCTION_NAME EQ function->getName().identifier.c_str() AND
|
||||
Y.RDB$PACKAGE_NAME EQUIV NULLIF(function->getName().qualifier.c_str(), '')
|
||||
SORTED BY Y.RDB$ARGUMENT_POSITION
|
||||
|
||||
if (!REQUEST(irq_l_args))
|
||||
@ -396,8 +396,8 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
// Prepare the exception message to be used in case this function ever
|
||||
// causes an exception. This is done at this time to save us from preparing
|
||||
// (thus allocating) this message every time the function is called.
|
||||
function->fun_exception_message.printf(EXCEPTION_MESSAGE, function->fun_name.toString().c_str(),
|
||||
X.RDB$ENTRYPOINT, X.RDB$MODULE_NAME);
|
||||
function->fun_exception_message.printf(EXCEPTION_MESSAGE,
|
||||
function->getName().toString().c_str(), X.RDB$ENTRYPOINT, X.RDB$MODULE_NAME);
|
||||
|
||||
if (!X.RDB$LEGACY_FLAG.NULL)
|
||||
{
|
||||
@ -414,7 +414,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
fb_assert(!function->fun_legacy);
|
||||
|
||||
function->fun_entrypoint = NULL;
|
||||
function->fun_request = NULL;
|
||||
function->setRequest(NULL);
|
||||
|
||||
HalfStaticArray<UCHAR, 512> body;
|
||||
|
||||
@ -458,21 +458,21 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
{
|
||||
delete csb;
|
||||
|
||||
if (function->fun_request)
|
||||
if (function->getRequest())
|
||||
{
|
||||
CMP_release(tdbb, function->fun_request);
|
||||
function->fun_request = NULL;
|
||||
CMP_release(tdbb, function->getRequest());
|
||||
function->setRequest(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbb->deletePool(csb_pool);
|
||||
}
|
||||
|
||||
const string name = function->fun_name.toString();
|
||||
const string name = function->getName().toString();
|
||||
status_exception::raise(Arg::Gds(isc_bad_fun_BLR) << Arg::Str(name));
|
||||
}
|
||||
|
||||
function->fun_request->req_function = function;
|
||||
function->getRequest()->req_function = function;
|
||||
|
||||
delete csb;
|
||||
}
|
||||
@ -481,7 +481,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
fb_assert(function->fun_legacy);
|
||||
|
||||
function->fun_external = NULL;
|
||||
function->fun_request = NULL;
|
||||
function->setRequest(NULL);
|
||||
|
||||
function->fun_entrypoint =
|
||||
Module::lookup(X.RDB$MODULE_NAME, X.RDB$ENTRYPOINT, dbb->dbb_modules);
|
||||
@ -515,7 +515,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
jrd_req* request_set_valid = NULL;
|
||||
|
||||
FOR(REQUEST_HANDLE request_set_valid)
|
||||
F IN RDB$FUNCTIONS WITH F.RDB$FUNCTION_ID EQ function->fun_id
|
||||
F IN RDB$FUNCTIONS WITH F.RDB$FUNCTION_ID EQ function->getId()
|
||||
|
||||
MODIFY F USING
|
||||
F.RDB$VALID_BLR = TRUE;
|
||||
@ -590,10 +590,10 @@ void Function::remove(thread_db* tdbb)
|
||||
}
|
||||
else
|
||||
{
|
||||
fun_name = QualifiedName();
|
||||
fun_security_name = "";
|
||||
setName(QualifiedName());
|
||||
setSecurityName("");
|
||||
fun_defaults = 0;
|
||||
fun_id = 0;
|
||||
setId(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -601,7 +601,9 @@ void Function::parseBlr(thread_db* tdbb, bid* blob_id, CompilerScratch* csb)
|
||||
{
|
||||
fb_assert(blob_id && !blob_id->isEmpty());
|
||||
|
||||
MET_parse_blob(tdbb, NULL, blob_id, &csb, &fun_request, false);
|
||||
jrd_req* request = getRequest();
|
||||
MET_parse_blob(tdbb, NULL, blob_id, &csb, &request, false);
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
void Function::addRef()
|
||||
@ -616,12 +618,12 @@ void Function::release(thread_db* tdbb)
|
||||
fun_use_count--;
|
||||
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
if (fun_use_count == 0 && dbb->dbb_functions[fun_id] != this)
|
||||
if (fun_use_count == 0 && dbb->dbb_functions[getId()] != this)
|
||||
{
|
||||
if (fun_request)
|
||||
if (getRequest())
|
||||
{
|
||||
CMP_release(tdbb, fun_request);
|
||||
fun_request = NULL;
|
||||
CMP_release(tdbb, getRequest());
|
||||
setRequest(NULL);
|
||||
}
|
||||
fun_flags &= ~FUN_being_altered;
|
||||
remove(tdbb);
|
||||
@ -679,7 +681,7 @@ dsc* Function::execute(thread_db* tdbb, jrd_nod* args, impure_value* value) cons
|
||||
}
|
||||
else
|
||||
{
|
||||
fb_assert(fun_request);
|
||||
fb_assert(getRequest());
|
||||
fb_assert(!fun_return_arg);
|
||||
|
||||
Database* const dbb = tdbb->getDatabase();
|
||||
@ -736,7 +738,7 @@ dsc* Function::execute(thread_db* tdbb, jrd_nod* args, impure_value* value) cons
|
||||
UCHAR* const out_msg = out_buffer.getBuffer(out_msg_length);
|
||||
ret_desc.dsc_address = out_msg;
|
||||
|
||||
jrd_req* const new_request = EXE_find_request(tdbb, fun_request, false);
|
||||
jrd_req* const new_request = EXE_find_request(tdbb, getRequest(), false);
|
||||
|
||||
try
|
||||
{
|
||||
@ -804,7 +806,7 @@ USHORT Function::incrementAlterCount()
|
||||
if (fun_alter_count == Function::MAX_ALTER_COUNT)
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_udf_name) << Arg::Str(fun_name.toString()) <<
|
||||
Arg::Gds(isc_udf_name) << Arg::Str(getName().toString()) <<
|
||||
Arg::Gds(isc_version_err));
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef JRD_FUNCTION_H
|
||||
#define JRD_FUNCTION_H
|
||||
|
||||
#include "../jrd/Routine.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../jrd/dsc.h"
|
||||
#include "../jrd/val.h"
|
||||
@ -32,7 +33,7 @@ namespace Jrd
|
||||
FUN_T fun_mechanism; // passing mechanism
|
||||
};
|
||||
|
||||
class Function : public pool_alloc<type_fun>
|
||||
class Function : public Routine
|
||||
{
|
||||
static const USHORT MAX_ALTER_COUNT = 64; // Number of times an in-cache function can be altered
|
||||
static const char* const EXCEPTION_MESSAGE;
|
||||
@ -58,18 +59,28 @@ namespace Jrd
|
||||
|
||||
private:
|
||||
explicit Function(MemoryPool& p)
|
||||
: fun_name(p), fun_security_name(p), fun_args(p), fun_exception_message(p),
|
||||
fun_legacy(true), fun_invariant(false)
|
||||
{}
|
||||
: Routine(p),
|
||||
fun_entrypoint(NULL),
|
||||
fun_inputs(0),
|
||||
fun_defaults(0),
|
||||
fun_return_arg(0),
|
||||
fun_temp_length(0),
|
||||
fun_args(p),
|
||||
fun_flags(0),
|
||||
fun_use_count(0),
|
||||
fun_existence_lock(NULL),
|
||||
fun_alter_count(0),
|
||||
fun_exception_message(p),
|
||||
fun_legacy(true),
|
||||
fun_invariant(false),
|
||||
fun_external(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
static Function* loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT flags);
|
||||
static int blockingAst(void*);
|
||||
|
||||
public:
|
||||
USHORT fun_id; // function ID
|
||||
Firebird::QualifiedName fun_name; // function name
|
||||
Firebird::MetaName fun_security_name; // security class name
|
||||
|
||||
int (*fun_entrypoint)(); // function entrypoint
|
||||
USHORT fun_inputs; // input arguments
|
||||
USHORT fun_defaults; // default input arguments
|
||||
@ -82,7 +93,6 @@ namespace Jrd
|
||||
USHORT fun_use_count; // requests compiled with function
|
||||
Lock* fun_existence_lock; // existence lock, if any
|
||||
USHORT fun_alter_count; // number of times function was altered
|
||||
jrd_req* fun_request; // compiled function request
|
||||
|
||||
Firebird::string fun_exception_message; // message containing the exception error message
|
||||
|
||||
|
@ -702,7 +702,7 @@ Firebird::string OPT_make_alias(thread_db* tdbb, const CompilerScratch* csb,
|
||||
}
|
||||
else if (base_tail->csb_procedure)
|
||||
{
|
||||
alias = base_tail->csb_procedure->prc_name.toString();
|
||||
alias = base_tail->csb_procedure->getName().toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
70
src/jrd/Routine.h
Normal file
70
src/jrd/Routine.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Adriano dos Santos Fernandes
|
||||
*/
|
||||
|
||||
#ifndef JRD_ROUTINE_H
|
||||
#define JRD_ROUTINE_H
|
||||
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/MetaName.h"
|
||||
|
||||
namespace Jrd
|
||||
{
|
||||
class jrd_req;
|
||||
|
||||
class Routine : public Firebird::PermanentStorage
|
||||
{
|
||||
protected:
|
||||
explicit Routine(MemoryPool& p)
|
||||
: PermanentStorage(p),
|
||||
id(0),
|
||||
name(p),
|
||||
securityName(p),
|
||||
request(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~Routine()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
USHORT getId() const { return id; }
|
||||
void setId(USHORT value) { id = value; }
|
||||
|
||||
const Firebird::QualifiedName& getName() const { return name; }
|
||||
void setName(const Firebird::QualifiedName& value) { name = value; }
|
||||
|
||||
const Firebird::MetaName& getSecurityName() const { return securityName; }
|
||||
void setSecurityName(const Firebird::MetaName& value) { securityName = value; }
|
||||
|
||||
/*const*/ jrd_req* getRequest() const { return request; }
|
||||
void setRequest(jrd_req* value) { request = value; }
|
||||
|
||||
private:
|
||||
USHORT id; // routine ID
|
||||
Firebird::QualifiedName name; // routine name
|
||||
Firebird::MetaName securityName; // security class name
|
||||
jrd_req* request; // compiled routine request
|
||||
};
|
||||
}
|
||||
|
||||
#endif // JRD_ROUTINE_H
|
@ -99,7 +99,7 @@ public:
|
||||
}
|
||||
|
||||
ValuesImpl(Firebird::MemoryPool& p, const Format* format, UCHAR* aMsg,
|
||||
const vec<Parameter*>& parameters)
|
||||
const Firebird::Array<Parameter*>& parameters)
|
||||
: PermanentStorage(p),
|
||||
msg(aMsg),
|
||||
msgLength(format->fmt_length),
|
||||
|
156
src/jrd/cmp.cpp
156
src/jrd/cmp.cpp
@ -302,14 +302,14 @@ static void build_external_access(thread_db* tdbb, ExternalAccessList& list, jrd
|
||||
if (item->exa_action == ExternalAccess::exa_procedure)
|
||||
{
|
||||
jrd_prc* const procedure = MET_lookup_procedure_id(tdbb, item->exa_prc_id, false, false, 0);
|
||||
if (procedure && procedure->prc_request)
|
||||
build_external_access(tdbb, list, procedure->prc_request);
|
||||
if (procedure && procedure->getRequest())
|
||||
build_external_access(tdbb, list, procedure->getRequest());
|
||||
}
|
||||
else if (item->exa_action == ExternalAccess::exa_function)
|
||||
{
|
||||
Function* const function = Function::lookup(tdbb, item->exa_fun_id, false, false, 0);
|
||||
if (function && function->fun_request)
|
||||
build_external_access(tdbb, list, function->fun_request);
|
||||
if (function && function->getRequest())
|
||||
build_external_access(tdbb, list, function->getRequest());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -431,61 +431,18 @@ void CMP_verify_access(thread_db* tdbb, jrd_req* request)
|
||||
|
||||
for (ExternalAccess* item = external.begin(); item < external.end(); item++)
|
||||
{
|
||||
const Routine* routine = NULL;
|
||||
int aclType;
|
||||
|
||||
if (item->exa_action == ExternalAccess::exa_procedure)
|
||||
{
|
||||
jrd_prc* const procedure = MET_lookup_procedure_id(tdbb, item->exa_prc_id, false, false, 0);
|
||||
if (!procedure->prc_request)
|
||||
continue;
|
||||
|
||||
for (const AccessItem* access = procedure->prc_request->req_access.begin();
|
||||
access < procedure->prc_request->req_access.end();
|
||||
access++)
|
||||
{
|
||||
const SecurityClass* sec_class = SCL_get_class(tdbb, access->acc_security_name.c_str());
|
||||
|
||||
if (procedure->prc_name.qualifier.isEmpty())
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, access->acc_view_id,
|
||||
id_procedure, procedure->prc_name.identifier,
|
||||
access->acc_mask, access->acc_type,
|
||||
access->acc_name, access->acc_r_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, access->acc_view_id,
|
||||
id_package, procedure->prc_name.qualifier,
|
||||
access->acc_mask, access->acc_type,
|
||||
access->acc_name, access->acc_r_name);
|
||||
}
|
||||
}
|
||||
routine = MET_lookup_procedure_id(tdbb, item->exa_prc_id, false, false, 0);
|
||||
aclType = id_procedure;
|
||||
}
|
||||
else if (item->exa_action == ExternalAccess::exa_function)
|
||||
{
|
||||
Function* const function = Function::lookup(tdbb, item->exa_fun_id, false, false, 0);
|
||||
if (!function->fun_request)
|
||||
continue;
|
||||
|
||||
for (const AccessItem* access = function->fun_request->req_access.begin();
|
||||
access < function->fun_request->req_access.end();
|
||||
access++)
|
||||
{
|
||||
const SecurityClass* sec_class = SCL_get_class(tdbb, access->acc_security_name.c_str());
|
||||
|
||||
if (function->fun_name.qualifier.isEmpty())
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, access->acc_view_id,
|
||||
id_function, function->fun_name.identifier,
|
||||
access->acc_mask, access->acc_type,
|
||||
access->acc_name, access->acc_r_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, access->acc_view_id,
|
||||
id_package, function->fun_name.qualifier,
|
||||
access->acc_mask, access->acc_type,
|
||||
access->acc_name, access->acc_r_name);
|
||||
}
|
||||
}
|
||||
routine = Function::lookup(tdbb, item->exa_fun_id, false, false, 0);
|
||||
aclType = id_function;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -514,6 +471,32 @@ void CMP_verify_access(thread_db* tdbb, jrd_req* request)
|
||||
default:
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!routine->getRequest())
|
||||
continue;
|
||||
|
||||
for (const AccessItem* access = routine->getRequest()->req_access.begin();
|
||||
access < routine->getRequest()->req_access.end();
|
||||
access++)
|
||||
{
|
||||
const SecurityClass* sec_class = SCL_get_class(tdbb, access->acc_security_name.c_str());
|
||||
|
||||
if (routine->getName().qualifier.isEmpty())
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, access->acc_view_id, aclType,
|
||||
routine->getName().identifier, access->acc_mask, access->acc_type,
|
||||
access->acc_name, access->acc_r_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, access->acc_view_id,
|
||||
id_package, routine->getName().qualifier,
|
||||
access->acc_mask, access->acc_type,
|
||||
access->acc_name, access->acc_r_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,19 +587,18 @@ jrd_req* CMP_clone_request(thread_db* tdbb, jrd_req* request, USHORT level, bool
|
||||
|
||||
if (procedure)
|
||||
{
|
||||
const TEXT* sec_name = (procedure->prc_security_name.hasData() ?
|
||||
procedure->prc_security_name.c_str() : NULL);
|
||||
const TEXT* sec_name = procedure->getSecurityName().nullStr();
|
||||
const SecurityClass* sec_class = SCL_get_class(tdbb, sec_name);
|
||||
|
||||
if (procedure->prc_name.qualifier.isEmpty())
|
||||
if (procedure->getName().qualifier.isEmpty())
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, 0, 0, NULL, SCL_execute,
|
||||
object_procedure, procedure->prc_name.identifier);
|
||||
object_procedure, procedure->getName().identifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, 0, 0, NULL, SCL_execute,
|
||||
object_package, procedure->prc_name.qualifier);
|
||||
object_package, procedure->getName().qualifier);
|
||||
}
|
||||
}
|
||||
|
||||
@ -624,19 +606,18 @@ jrd_req* CMP_clone_request(thread_db* tdbb, jrd_req* request, USHORT level, bool
|
||||
|
||||
if (function)
|
||||
{
|
||||
const TEXT* sec_name = (function->fun_security_name.hasData() ?
|
||||
function->fun_security_name.c_str() : NULL);
|
||||
const TEXT* sec_name = function->getSecurityName().nullStr();
|
||||
const SecurityClass* sec_class = SCL_get_class(tdbb, sec_name);
|
||||
|
||||
if (procedure->prc_name.qualifier.isEmpty())
|
||||
if (procedure->getName().qualifier.isEmpty())
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, 0, 0, NULL, SCL_execute,
|
||||
object_function, function->fun_name.identifier);
|
||||
object_function, function->getName().identifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCL_check_access(tdbb, sec_class, 0, 0, NULL, SCL_execute,
|
||||
object_package, function->fun_name.qualifier);
|
||||
object_package, function->getName().qualifier);
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,7 +714,7 @@ jrd_req* CMP_compile2(thread_db* tdbb, const UCHAR* blr, ULONG blr_length, bool
|
||||
i, s.csb_view_stream,
|
||||
(s.csb_alias ? s.csb_alias->c_str() : ""),
|
||||
(s.csb_relation ? s.csb_relation->rel_name.c_str() : ""),
|
||||
(s.csb_procedure ? s.csb_procedure->prc_name.c_str() : ""),
|
||||
(s.csb_procedure ? s.csb_procedure->getName().c_str() : ""),
|
||||
(s.csb_view ? s.csb_view->rel_name.c_str() : ""));
|
||||
}
|
||||
|
||||
@ -2332,7 +2313,7 @@ jrd_req* CMP_make_request(thread_db* tdbb, CompilerScratch* csb, bool internal_f
|
||||
char buffer[256];
|
||||
sprintf(buffer,
|
||||
"Called from CMP_make_request():\n\t Incrementing use count of %s\n",
|
||||
procedure->prc_name->toString().c_str());
|
||||
procedure->getName()->toString().c_str());
|
||||
JRD_print_procedure_info(tdbb, buffer);
|
||||
}
|
||||
#endif
|
||||
@ -2507,8 +2488,6 @@ void CMP_decrement_prc_use_count(thread_db* tdbb, jrd_prc* procedure)
|
||||
* decrement the procedure's use count
|
||||
*
|
||||
*********************************************/
|
||||
DEV_BLKCHK(procedure, type_prc);
|
||||
|
||||
// Actually, it's possible for procedures to have intermixed dependencies, so
|
||||
// this routine can be called for the procedure which is being freed itself.
|
||||
// Hence we should just silently ignore such a situation.
|
||||
@ -2526,7 +2505,7 @@ void CMP_decrement_prc_use_count(thread_db* tdbb, jrd_prc* procedure)
|
||||
char buffer[256];
|
||||
sprintf(buffer,
|
||||
"Called from CMP_decrement():\n\t Decrementing use count of %s\n",
|
||||
procedure->prc_name->toString().c_str());
|
||||
procedure->getName()->toString().c_str());
|
||||
JRD_print_procedure_info(tdbb, buffer);
|
||||
}
|
||||
#endif
|
||||
@ -2536,15 +2515,15 @@ void CMP_decrement_prc_use_count(thread_db* tdbb, jrd_prc* procedure)
|
||||
// The procedure will be different than in dbb_procedures only if it is a
|
||||
// floating copy, i.e. an old copy or a deleted procedure.
|
||||
if ((procedure->prc_use_count == 0) &&
|
||||
( (*tdbb->getDatabase()->dbb_procedures)[procedure->prc_id] != procedure))
|
||||
( (*tdbb->getDatabase()->dbb_procedures)[procedure->getId()] != procedure))
|
||||
{
|
||||
if (procedure->prc_request)
|
||||
if (procedure->getRequest())
|
||||
{
|
||||
CMP_release(tdbb, procedure->prc_request);
|
||||
procedure->prc_request = NULL;
|
||||
CMP_release(tdbb, procedure->getRequest());
|
||||
procedure->setRequest(NULL);
|
||||
}
|
||||
procedure->prc_flags &= ~PRC_being_altered;
|
||||
MET_remove_procedure(tdbb, procedure->prc_id, procedure);
|
||||
MET_remove_procedure(tdbb, procedure->getId(), procedure);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4192,7 +4171,7 @@ jrd_nod* CMP_pass1(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node)
|
||||
// Post access to procedure
|
||||
post_procedure_access(tdbb, csb, procedure);
|
||||
CMP_post_resource(&csb->csb_resources, procedure,
|
||||
Resource::rsc_procedure, procedure->prc_id);
|
||||
Resource::rsc_procedure, procedure->getId());
|
||||
break;
|
||||
|
||||
case nod_function:
|
||||
@ -4201,21 +4180,20 @@ jrd_nod* CMP_pass1(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node)
|
||||
|
||||
if (!(csb->csb_g_flags & (csb_internal | csb_ignore_perm)))
|
||||
{
|
||||
const TEXT* sec_name =
|
||||
(function->fun_security_name.length() > 0 ? function->fun_security_name.c_str() : NULL);
|
||||
const TEXT* sec_name = function->getSecurityName().nullStr();
|
||||
|
||||
if (function->fun_name.qualifier.isEmpty())
|
||||
if (function->getName().qualifier.isEmpty())
|
||||
{
|
||||
CMP_post_access(tdbb, csb, sec_name, 0, SCL_execute, object_function,
|
||||
function->fun_name.identifier.c_str());
|
||||
function->getName().identifier.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
CMP_post_access(tdbb, csb, sec_name, 0, SCL_execute, object_package,
|
||||
function->fun_name.qualifier.c_str());
|
||||
function->getName().qualifier.c_str());
|
||||
}
|
||||
|
||||
ExternalAccess temp(ExternalAccess::exa_function, function->fun_id);
|
||||
ExternalAccess temp(ExternalAccess::exa_function, function->getId());
|
||||
size_t idx;
|
||||
if (!csb->csb_external.find(temp, idx))
|
||||
{
|
||||
@ -4224,7 +4202,7 @@ jrd_nod* CMP_pass1(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node)
|
||||
}
|
||||
|
||||
CMP_post_resource(&csb->csb_resources, function,
|
||||
Resource::rsc_function, function->fun_id);
|
||||
Resource::rsc_function, function->getId());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5072,7 +5050,7 @@ static void pass1_source(thread_db* tdbb,
|
||||
jrd_prc* const procedure =
|
||||
MET_lookup_procedure_id(tdbb, (SSHORT)(IPTR) source->nod_arg[e_prc_procedure], false, false, 0);
|
||||
post_procedure_access(tdbb, csb, procedure);
|
||||
CMP_post_resource(&csb->csb_resources, procedure, Resource::rsc_procedure, procedure->prc_id);
|
||||
CMP_post_resource(&csb->csb_resources, procedure, Resource::rsc_procedure, procedure->getId());
|
||||
|
||||
jrd_rel* const parent_view = csb->csb_view;
|
||||
const USHORT view_stream = csb->csb_view_stream;
|
||||
@ -6393,30 +6371,28 @@ static void post_procedure_access(thread_db* tdbb, CompilerScratch* csb, jrd_prc
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
DEV_BLKCHK(csb, type_csb);
|
||||
DEV_BLKCHK(procedure, type_prc);
|
||||
|
||||
// allow all access to internal requests
|
||||
|
||||
if (csb->csb_g_flags & (csb_internal | csb_ignore_perm))
|
||||
return;
|
||||
|
||||
const TEXT* prc_sec_name =
|
||||
(procedure->prc_security_name.length() > 0 ? procedure->prc_security_name.c_str() : NULL);
|
||||
const TEXT* prc_sec_name = procedure->getSecurityName().nullStr();
|
||||
|
||||
// this request must have EXECUTE permission on the stored procedure
|
||||
if (procedure->prc_name.qualifier.isEmpty())
|
||||
if (procedure->getName().qualifier.isEmpty())
|
||||
{
|
||||
CMP_post_access(tdbb, csb, prc_sec_name, 0, SCL_execute, object_procedure,
|
||||
procedure->prc_name.identifier.c_str());
|
||||
procedure->getName().identifier.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
CMP_post_access(tdbb, csb, prc_sec_name, 0, SCL_execute, object_package,
|
||||
procedure->prc_name.qualifier.c_str());
|
||||
procedure->getName().qualifier.c_str());
|
||||
}
|
||||
|
||||
// Add the procedure to list of external objects accessed
|
||||
ExternalAccess temp(ExternalAccess::exa_procedure, procedure->prc_id);
|
||||
ExternalAccess temp(ExternalAccess::exa_procedure, procedure->getId());
|
||||
size_t idx;
|
||||
if (!csb->csb_external.find(temp, idx))
|
||||
csb->csb_external.insert(idx, temp);
|
||||
|
@ -3596,23 +3596,23 @@ static bool delete_function(thread_db* tdbb, SSHORT phase, DeferredWork* work, j
|
||||
LCK_release(tdbb, function->fun_existence_lock);
|
||||
}
|
||||
|
||||
dbb->dbb_functions[function->fun_id] = NULL;
|
||||
dbb->dbb_functions[function->getId()] = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
const USHORT old_flags = function->fun_flags;
|
||||
function->fun_flags |= FUN_obsolete;
|
||||
if (function->fun_request)
|
||||
if (function->getRequest())
|
||||
{
|
||||
if (CMP_clone_is_active(function->fun_request))
|
||||
if (CMP_clone_is_active(function->getRequest()))
|
||||
{
|
||||
function->fun_flags = old_flags;
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_obj_in_use) << Arg::Str(name.toString()));
|
||||
}
|
||||
|
||||
CMP_release(tdbb, function->fun_request);
|
||||
function->fun_request = NULL;
|
||||
CMP_release(tdbb, function->getRequest());
|
||||
function->setRequest(NULL);
|
||||
}
|
||||
|
||||
// delete dependency lists
|
||||
@ -3955,23 +3955,23 @@ static bool delete_procedure(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
if (procedure->prc_existence_lock) {
|
||||
LCK_release(tdbb, procedure->prc_existence_lock);
|
||||
}
|
||||
(*tdbb->getDatabase()->dbb_procedures)[procedure->prc_id] = NULL;
|
||||
(*tdbb->getDatabase()->dbb_procedures)[procedure->getId()] = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
old_flags = procedure->prc_flags;
|
||||
procedure->prc_flags |= PRC_obsolete;
|
||||
if (procedure->prc_request)
|
||||
if (procedure->getRequest())
|
||||
{
|
||||
if (CMP_clone_is_active(procedure->prc_request))
|
||||
if (CMP_clone_is_active(procedure->getRequest()))
|
||||
{
|
||||
procedure->prc_flags = old_flags;
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_obj_in_use) << Arg::Str(name.toString()));
|
||||
}
|
||||
|
||||
CMP_release(tdbb, procedure->prc_request);
|
||||
procedure->prc_request = 0;
|
||||
CMP_release(tdbb, procedure->getRequest());
|
||||
procedure->setRequest(NULL);
|
||||
}
|
||||
|
||||
// delete dependency lists
|
||||
@ -5595,7 +5595,7 @@ static bool modify_function(thread_db* tdbb, SSHORT phase, DeferredWork* work, j
|
||||
LCK_release(tdbb, function->fun_existence_lock);
|
||||
}
|
||||
|
||||
dbb->dbb_functions[function->fun_id] = NULL;
|
||||
dbb->dbb_functions[function->getId()] = NULL;
|
||||
|
||||
if (!(function = Function::lookup(tdbb, work->dfw_id, false,
|
||||
true, FUN_being_altered)))
|
||||
@ -5608,9 +5608,9 @@ static bool modify_function(thread_db* tdbb, SSHORT phase, DeferredWork* work, j
|
||||
|
||||
function->fun_flags |= FUN_being_altered;
|
||||
|
||||
if (function->fun_request)
|
||||
if (function->getRequest())
|
||||
{
|
||||
if (CMP_clone_is_active(function->fun_request))
|
||||
if (CMP_clone_is_active(function->getRequest()))
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_obj_in_use) << Arg::Str(name.toString()));
|
||||
@ -5618,8 +5618,8 @@ static bool modify_function(thread_db* tdbb, SSHORT phase, DeferredWork* work, j
|
||||
|
||||
// release the request
|
||||
|
||||
CMP_release(tdbb, function->fun_request);
|
||||
function->fun_request = NULL;
|
||||
CMP_release(tdbb, function->getRequest());
|
||||
function->setRequest(NULL);
|
||||
}
|
||||
|
||||
// delete dependency lists
|
||||
@ -5794,7 +5794,7 @@ static bool modify_procedure(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
if (procedure->prc_existence_lock) {
|
||||
LCK_release(tdbb, procedure->prc_existence_lock);
|
||||
}
|
||||
(*tdbb->getDatabase()->dbb_procedures)[procedure->prc_id] = NULL;
|
||||
(*tdbb->getDatabase()->dbb_procedures)[procedure->getId()] = NULL;
|
||||
|
||||
if (!(procedure = MET_lookup_procedure_id(tdbb, work->dfw_id, false,
|
||||
true, PRC_being_altered)))
|
||||
@ -5805,9 +5805,9 @@ static bool modify_procedure(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
}
|
||||
|
||||
procedure->prc_flags |= PRC_being_altered;
|
||||
if (procedure->prc_request)
|
||||
if (procedure->getRequest())
|
||||
{
|
||||
if (CMP_clone_is_active(procedure->prc_request))
|
||||
if (CMP_clone_is_active(procedure->getRequest()))
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_no_meta_update) <<
|
||||
Arg::Gds(isc_obj_in_use) << Arg::Str(name.toString()));
|
||||
@ -5815,8 +5815,8 @@ static bool modify_procedure(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
|
||||
// release the request
|
||||
|
||||
CMP_release(tdbb, procedure->prc_request);
|
||||
procedure->prc_request = 0;
|
||||
CMP_release(tdbb, procedure->getRequest());
|
||||
procedure->setRequest(0);
|
||||
}
|
||||
|
||||
// delete dependency lists
|
||||
|
@ -1457,11 +1457,12 @@ void EVL_validate(thread_db* tdbb, const Item& item, const ItemInfo* itemInfo, d
|
||||
{
|
||||
if (request->req_procedure)
|
||||
{
|
||||
if (index <= request->req_procedure->prc_outputs)
|
||||
if (index <= int(request->req_procedure->prc_output_fields.getCount()))
|
||||
s.printf("output parameter number %d", index);
|
||||
else
|
||||
{
|
||||
s.printf("variable number %d", index - request->req_procedure->prc_outputs);
|
||||
s.printf("variable number %d",
|
||||
index - int(request->req_procedure->prc_output_fields.getCount()));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -749,7 +749,7 @@ void EXE_receive(thread_db* tdbb,
|
||||
try
|
||||
{
|
||||
|
||||
const bool external = request->req_procedure && request->req_procedure->prc_external;
|
||||
const bool external = request->req_procedure && request->req_procedure->getExternal();
|
||||
|
||||
if (external)
|
||||
{
|
||||
@ -861,7 +861,7 @@ void EXE_send(thread_db* tdbb, jrd_req* request, USHORT msg, USHORT length, cons
|
||||
node = request->req_message;
|
||||
|
||||
jrd_tra* transaction = request->req_transaction;
|
||||
const bool external = request->req_procedure && request->req_procedure->prc_external;
|
||||
const bool external = request->req_procedure && request->req_procedure->getExternal();
|
||||
|
||||
if (external)
|
||||
{
|
||||
@ -1453,7 +1453,7 @@ static void execute_procedure(thread_db* tdbb, jrd_nod* node)
|
||||
}
|
||||
}
|
||||
|
||||
jrd_prc* procedure = (jrd_prc*) node->nod_arg[e_esp_procedure];
|
||||
const jrd_prc* procedure = (jrd_prc*) node->nod_arg[e_esp_procedure];
|
||||
|
||||
USHORT in_msg_length = 0;
|
||||
UCHAR* in_msg = NULL;
|
||||
@ -1476,7 +1476,7 @@ static void execute_procedure(thread_db* tdbb, jrd_nod* node)
|
||||
out_msg = (UCHAR*) request + out_message->nod_impure;
|
||||
}
|
||||
|
||||
jrd_req* proc_request = EXE_find_request(tdbb, procedure->prc_request, false);
|
||||
jrd_req* proc_request = EXE_find_request(tdbb, procedure->getRequest(), false);
|
||||
|
||||
// trace procedure execution start
|
||||
TraceProcExecute trace(tdbb, proc_request, request, node->nod_arg[e_esp_inputs]);
|
||||
@ -1822,12 +1822,12 @@ static void stuff_stack_trace(const jrd_req* request)
|
||||
else if (req->req_procedure)
|
||||
{
|
||||
name = "At procedure '";
|
||||
name += req->req_procedure->prc_name.toString().c_str();
|
||||
name += req->req_procedure->getName().toString().c_str();
|
||||
}
|
||||
else if (req->req_function)
|
||||
{
|
||||
name = "At function '";
|
||||
name += req->req_function->fun_name.toString().c_str();
|
||||
name += req->req_function->getName().toString().c_str();
|
||||
}
|
||||
|
||||
if (! name.isEmpty())
|
||||
@ -1922,12 +1922,12 @@ jrd_nod* EXE_looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
|
||||
|
||||
// Execute stuff until we drop
|
||||
|
||||
bool runExternal = request->req_procedure && request->req_procedure->prc_external;
|
||||
bool runExternal = request->req_procedure && request->req_procedure->getExternal();
|
||||
|
||||
while (runExternal || (node && !(request->req_flags & req_stall)))
|
||||
{
|
||||
try {
|
||||
if (request->req_procedure && request->req_procedure->prc_external)
|
||||
if (request->req_procedure && request->req_procedure->getExternal())
|
||||
{
|
||||
if (runExternal)
|
||||
runExternal = false;
|
||||
@ -1985,18 +1985,18 @@ jrd_nod* EXE_looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
|
||||
|
||||
request->inputParams = FB_NEW(*request->req_pool) ValuesImpl(
|
||||
*request->req_pool, format, inMsg,
|
||||
*request->req_procedure->prc_input_fields);
|
||||
request->req_procedure->prc_input_fields);
|
||||
}
|
||||
|
||||
if (!request->outputParams)
|
||||
{
|
||||
request->outputParams = FB_NEW(*request->req_pool) ValuesImpl(
|
||||
*request->req_pool, outFormat, outMsg,
|
||||
*request->req_procedure->prc_output_fields);
|
||||
request->req_procedure->prc_output_fields);
|
||||
request->outputParams->setNull();
|
||||
}
|
||||
|
||||
request->resultSet = request->req_procedure->prc_external->open(tdbb,
|
||||
request->resultSet = request->req_procedure->getExternal()->open(tdbb,
|
||||
request->inputParams, request->outputParams);
|
||||
}
|
||||
|
||||
|
@ -357,20 +357,20 @@ void InternalStatement::doPrepare(thread_db* tdbb, const string& sql)
|
||||
if (request && request->req_trg_name.hasData())
|
||||
tran->tra_caller_name = CallerName(obj_trigger, request->req_trg_name);
|
||||
else if (request && request->req_procedure &&
|
||||
request->req_procedure->prc_name.identifier.hasData())
|
||||
request->req_procedure->getName().identifier.hasData())
|
||||
{
|
||||
if (request->req_procedure->prc_name.qualifier.isEmpty())
|
||||
tran->tra_caller_name = CallerName(obj_procedure, request->req_procedure->prc_name.identifier);
|
||||
if (request->req_procedure->getName().qualifier.isEmpty())
|
||||
tran->tra_caller_name = CallerName(obj_procedure, request->req_procedure->getName().identifier);
|
||||
else
|
||||
tran->tra_caller_name = CallerName(obj_package_header, request->req_procedure->prc_name.qualifier);
|
||||
tran->tra_caller_name = CallerName(obj_package_header, request->req_procedure->getName().qualifier);
|
||||
}
|
||||
else if (request && request->req_function &&
|
||||
request->req_function->fun_name.identifier.hasData())
|
||||
request->req_function->getName().identifier.hasData())
|
||||
{
|
||||
if (request->req_function->fun_name.qualifier.isEmpty())
|
||||
tran->tra_caller_name = CallerName(obj_udf, request->req_function->fun_name.identifier);
|
||||
if (request->req_function->getName().qualifier.isEmpty())
|
||||
tran->tra_caller_name = CallerName(obj_udf, request->req_function->getName().identifier);
|
||||
else
|
||||
tran->tra_caller_name = CallerName(obj_package_header, request->req_function->fun_name.qualifier);
|
||||
tran->tra_caller_name = CallerName(obj_package_header, request->req_function->getName().qualifier);
|
||||
}
|
||||
else
|
||||
tran->tra_caller_name = CallerName();
|
||||
|
@ -689,13 +689,13 @@ void FUN_evaluate(thread_db* tdbb, const Function* function, jrd_nod* node, impu
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_udf_fp_overflow) <<
|
||||
Arg::Str(function->fun_name.toString()));
|
||||
Arg::Str(function->getName().toString()));
|
||||
}
|
||||
else if (isnan(value->vlu_misc.vlu_double))
|
||||
{
|
||||
status_exception::raise(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_udf_fp_nan) <<
|
||||
Arg::Str(function->fun_name.toString()));
|
||||
Arg::Str(function->getName().toString()));
|
||||
}
|
||||
}
|
||||
request->req_flags &= ~req_null;
|
||||
|
@ -24,11 +24,6 @@
|
||||
#ifndef JRD_FUN_PROTO_H
|
||||
#define JRD_FUN_PROTO_H
|
||||
|
||||
namespace Jrd
|
||||
{
|
||||
class CompilerScratch;
|
||||
}
|
||||
|
||||
class IbUtil
|
||||
{
|
||||
public:
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include "../jrd/os/guid.h"
|
||||
#include "../jrd/sbm.h"
|
||||
#include "../jrd/scl.h"
|
||||
|
||||
#include "../jrd/Routine.h"
|
||||
#include "../jrd/ExtEngineManager.h"
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
@ -217,41 +217,53 @@ const int VAL_PAG_WRONG_SCN = 27;
|
||||
const int VAL_MAX_ERROR = 28;
|
||||
|
||||
|
||||
|
||||
|
||||
// Procedure block
|
||||
|
||||
class jrd_prc : public pool_alloc<type_prc>
|
||||
class jrd_prc : public Routine
|
||||
{
|
||||
public:
|
||||
USHORT prc_id;
|
||||
USHORT prc_flags;
|
||||
USHORT prc_inputs;
|
||||
USHORT prc_defaults;
|
||||
USHORT prc_outputs;
|
||||
jrd_nod* prc_output_msg;
|
||||
Format* prc_input_fmt;
|
||||
Format* prc_output_fmt;
|
||||
Format* prc_format;
|
||||
vec<Parameter*>* prc_input_fields; // vector of field blocks
|
||||
vec<Parameter*>* prc_output_fields; // vector of field blocks
|
||||
Firebird::Array<Parameter*> prc_input_fields; // array of field blocks
|
||||
Firebird::Array<Parameter*> prc_output_fields; // array of field blocks
|
||||
prc_t prc_type; // procedure type
|
||||
jrd_req* prc_request; // compiled procedure request
|
||||
USHORT prc_use_count; // requests compiled with procedure
|
||||
SSHORT prc_int_use_count; // number of procedures compiled with procedure, set and
|
||||
// used internally in the MET_clear_cache procedure
|
||||
// no code should rely on value of this field
|
||||
// (it will usually be 0)
|
||||
Lock* prc_existence_lock; // existence lock, if any
|
||||
Firebird::MetaName prc_security_name; // security class name for procedure
|
||||
Firebird::QualifiedName prc_name; // name
|
||||
USHORT prc_alter_count; // No. of times the procedure was altered
|
||||
|
||||
const ExtEngineManager::Procedure* getExternal() const { return prc_external; }
|
||||
void setExternal(ExtEngineManager::Procedure* value) { prc_external = value; }
|
||||
|
||||
private:
|
||||
ExtEngineManager::Procedure* prc_external;
|
||||
|
||||
public:
|
||||
explicit jrd_prc(MemoryPool& p)
|
||||
: prc_security_name(p), prc_name(p)
|
||||
{}
|
||||
: Routine(p),
|
||||
prc_flags(0),
|
||||
prc_defaults(0),
|
||||
prc_output_msg(NULL),
|
||||
prc_input_fmt(NULL),
|
||||
prc_output_fmt(NULL),
|
||||
prc_format(NULL),
|
||||
prc_input_fields(p),
|
||||
prc_output_fields(p),
|
||||
prc_type(prc_legacy),
|
||||
prc_use_count(0),
|
||||
prc_int_use_count(0),
|
||||
prc_existence_lock(NULL),
|
||||
prc_alter_count(0),
|
||||
prc_external(NULL)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// prc_flags
|
||||
|
211
src/jrd/met.epp
211
src/jrd/met.epp
@ -391,10 +391,10 @@ void adjust_dependencies(jrd_prc* procedure)
|
||||
return;
|
||||
}
|
||||
procedure->prc_int_use_count = -1; // Mark as undeletable
|
||||
if (procedure->prc_request)
|
||||
if (procedure->getRequest())
|
||||
{
|
||||
// Loop over procedures from resource list of prc_request
|
||||
ResourceList& list = procedure->prc_request->req_resources;
|
||||
// Loop over procedures from resource list of request
|
||||
ResourceList& list = procedure->getRequest()->req_resources;
|
||||
size_t i;
|
||||
for (list.find(Resource(Resource::rsc_procedure, 0, NULL, NULL, NULL), i);
|
||||
i < list.getCount(); i++)
|
||||
@ -437,7 +437,7 @@ void MET_verify_cache(thread_db* tdbb)
|
||||
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ++ptr)
|
||||
{
|
||||
if ( (procedure = *ptr) && procedure->prc_request /*&&
|
||||
if ( (procedure = *ptr) && procedure->getRequest() /*&&
|
||||
!(procedure->prc_flags & PRC_obsolete)*/ )
|
||||
{
|
||||
fb_assert(procedure->prc_int_use_count == 0);
|
||||
@ -447,32 +447,34 @@ void MET_verify_cache(thread_db* tdbb)
|
||||
// Walk procedures and calculate internal dependencies
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ptr++)
|
||||
{
|
||||
if ( (procedure = *ptr) && procedure->prc_request /*&&
|
||||
if ( (procedure = *ptr) && procedure->getRequest() /*&&
|
||||
!(procedure->prc_flags & PRC_obsolete)*/ )
|
||||
{
|
||||
inc_int_use_count(procedure->prc_request);
|
||||
inc_int_use_count(procedure->getRequest());
|
||||
}
|
||||
}
|
||||
|
||||
// Walk procedures again and check dependencies
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ptr++)
|
||||
{
|
||||
if ( (procedure = *ptr) && procedure->prc_request && /*
|
||||
if ( (procedure = *ptr) && procedure->getRequest() && /*
|
||||
!(procedure->prc_flags & PRC_obsolete) && */
|
||||
procedure->prc_use_count < procedure->prc_int_use_count)
|
||||
{
|
||||
char buffer[1024], *buf = buffer;
|
||||
buf += sprintf(buf, "Procedure %d:%s is not properly counted (use count=%d, prc use=%d). Used by: \n",
|
||||
procedure->prc_id, procedure->prc_name.toString().c_str(), procedure->prc_use_count, procedure->prc_int_use_count);
|
||||
procedure->getId(), procedure->getName().toString().c_str(),
|
||||
procedure->prc_use_count, procedure->prc_int_use_count);
|
||||
|
||||
vec<jrd_prc*>::const_iterator ptr2 = procedures->begin();
|
||||
for (const vec<jrd_prc*>::const_iterator end2 = procedures->end();
|
||||
ptr2 < end2; ++ptr2)
|
||||
{
|
||||
const jrd_prc* prc = *ptr2;
|
||||
if (prc && prc->prc_request /*&& !(prc->prc_flags & PRC_obsolete)*/ )
|
||||
if (prc && prc->getRequest() /*&& !(prc->prc_flags & PRC_obsolete)*/ )
|
||||
{
|
||||
// Loop over procedures from resource list of prc_request
|
||||
const ResourceList& list = prc->prc_request->req_resources;
|
||||
// Loop over procedures from resource list of request
|
||||
const ResourceList& list = prc->getRequest()->req_resources;
|
||||
size_t i;
|
||||
for (list.find(Resource(Resource::rsc_procedure, 0, NULL, NULL, NULL), i);
|
||||
i < list.getCount(); i++)
|
||||
@ -480,8 +482,11 @@ void MET_verify_cache(thread_db* tdbb)
|
||||
const Resource& resource = list[i];
|
||||
if (resource.rsc_type != Resource::rsc_procedure)
|
||||
break;
|
||||
if (resource.rsc_prc == procedure) {
|
||||
buf += sprintf(buf, "%d:%s\n", prc->prc_id, prc->prc_name.toString().c_str());
|
||||
|
||||
if (resource.rsc_prc == procedure)
|
||||
{
|
||||
buf += sprintf(buf, "%d:%s\n", prc->getId(),
|
||||
prc->getName().toString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -554,10 +559,10 @@ void MET_clear_cache(thread_db* tdbb)
|
||||
// Walk procedures and calculate internal dependencies
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ++ptr)
|
||||
{
|
||||
if ( (procedure = *ptr) && procedure->prc_request &&
|
||||
if ( (procedure = *ptr) && procedure->getRequest() &&
|
||||
!(procedure->prc_flags & PRC_obsolete) )
|
||||
{
|
||||
inc_int_use_count(procedure->prc_request);
|
||||
inc_int_use_count(procedure->getRequest());
|
||||
}
|
||||
}
|
||||
|
||||
@ -565,7 +570,7 @@ void MET_clear_cache(thread_db* tdbb)
|
||||
// which will not be removed.
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ptr++)
|
||||
{
|
||||
if ( (procedure = *ptr) && procedure->prc_request &&
|
||||
if ( (procedure = *ptr) && procedure->getRequest() &&
|
||||
!(procedure->prc_flags & PRC_obsolete) &&
|
||||
procedure->prc_use_count != procedure->prc_int_use_count )
|
||||
{
|
||||
@ -579,12 +584,12 @@ void MET_clear_cache(thread_db* tdbb)
|
||||
if ( (procedure = *ptr) )
|
||||
{
|
||||
|
||||
if ( procedure->prc_request && !(procedure->prc_flags & PRC_obsolete) &&
|
||||
if ( procedure->getRequest() && !(procedure->prc_flags & PRC_obsolete) &&
|
||||
procedure->prc_int_use_count >= 0 &&
|
||||
procedure->prc_use_count == procedure->prc_int_use_count )
|
||||
{
|
||||
CMP_release(tdbb, procedure->prc_request);
|
||||
procedure->prc_request = NULL;
|
||||
CMP_release(tdbb, procedure->getRequest());
|
||||
procedure->setRequest(NULL);
|
||||
if (procedure->prc_existence_lock) //// TODO: verify why this IF is necessary now
|
||||
LCK_release(tdbb, procedure->prc_existence_lock);
|
||||
procedure->prc_existence_lock = NULL;
|
||||
@ -602,9 +607,7 @@ void MET_clear_cache(thread_db* tdbb)
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ptr++)
|
||||
{
|
||||
if ( (procedure = *ptr) && (procedure->prc_flags & PRC_obsolete) )
|
||||
{
|
||||
MET_remove_procedure(tdbb, procedure->prc_id, procedure);
|
||||
}
|
||||
MET_remove_procedure(tdbb, procedure->getId(), procedure);
|
||||
}
|
||||
|
||||
}
|
||||
@ -662,9 +665,9 @@ bool MET_procedure_in_use(thread_db* tdbb, jrd_prc* proc)
|
||||
// Walk procedures and calculate internal dependencies
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ++ptr)
|
||||
{
|
||||
if ((procedure = *ptr) && procedure->prc_request && !(procedure->prc_flags & PRC_obsolete))
|
||||
if ((procedure = *ptr) && procedure->getRequest() && !(procedure->prc_flags & PRC_obsolete))
|
||||
{
|
||||
inc_int_use_count(procedure->prc_request);
|
||||
inc_int_use_count(procedure->getRequest());
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,7 +675,7 @@ bool MET_procedure_in_use(thread_db* tdbb, jrd_prc* proc)
|
||||
// which will not be removed.
|
||||
for (ptr = procedures->begin(), end = procedures->end(); ptr < end; ptr++)
|
||||
{
|
||||
if ( (procedure = *ptr) && procedure->prc_request &&
|
||||
if ( (procedure = *ptr) && procedure->getRequest() &&
|
||||
!(procedure->prc_flags & PRC_obsolete) &&
|
||||
procedure->prc_use_count != procedure->prc_int_use_count && procedure != proc )
|
||||
{
|
||||
@ -2587,7 +2590,7 @@ jrd_prc* MET_lookup_procedure(thread_db* tdbb, const QualifiedName& name, bool n
|
||||
!(procedure->prc_flags & PRC_being_scanned) &&
|
||||
!(procedure->prc_flags & PRC_being_altered))
|
||||
{
|
||||
if (procedure->prc_name == name)
|
||||
if (procedure->getName() == name)
|
||||
{
|
||||
if (procedure->prc_flags & PRC_check_existence)
|
||||
{
|
||||
@ -2658,7 +2661,7 @@ jrd_prc* MET_lookup_procedure_id(thread_db* tdbb, SSHORT id,
|
||||
|
||||
vec<jrd_prc*>* procedures = dbb->dbb_procedures;
|
||||
if (procedures && id < (SSHORT) procedures->count() && (procedure = (*procedures)[id]) &&
|
||||
procedure->prc_id == id &&
|
||||
procedure->getId() == id &&
|
||||
!(procedure->prc_flags & PRC_being_scanned) &&
|
||||
((procedure->prc_flags & PRC_scanned) || noscan) &&
|
||||
!(procedure->prc_flags & PRC_being_altered) &&
|
||||
@ -3180,7 +3183,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
procedure->prc_flags |= (PRC_being_scanned | flags);
|
||||
procedure->prc_flags &= ~PRC_obsolete;
|
||||
|
||||
procedure->prc_id = id;
|
||||
procedure->setId(id);
|
||||
(*vector)[id] = procedure;
|
||||
|
||||
if (!procedure->prc_existence_lock)
|
||||
@ -3189,7 +3192,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
procedure->prc_existence_lock = lock;
|
||||
lock->lck_parent = dbb->dbb_lock;
|
||||
lock->lck_dbb = dbb;
|
||||
lock->lck_key.lck_long = procedure->prc_id;
|
||||
lock->lck_key.lck_long = procedure->getId();
|
||||
lock->lck_length = sizeof(lock->lck_key.lck_long);
|
||||
lock->lck_type = LCK_prc_exist;
|
||||
lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
|
||||
@ -3206,24 +3209,22 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
jrd_req* request = CMP_find_request(tdbb, irq_r_procedure, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_ID EQ procedure->prc_id
|
||||
P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_ID EQ procedure->getId()
|
||||
|
||||
if (!REQUEST(irq_r_procedure))
|
||||
{
|
||||
REQUEST(irq_r_procedure) = request;
|
||||
}
|
||||
|
||||
if (procedure->prc_name.toString().length() == 0)
|
||||
if (procedure->getName().toString().length() == 0)
|
||||
{
|
||||
procedure->prc_name = QualifiedName(P.RDB$PROCEDURE_NAME,
|
||||
(P.RDB$PACKAGE_NAME.NULL ? "" : P.RDB$PACKAGE_NAME));
|
||||
procedure->setName(QualifiedName(P.RDB$PROCEDURE_NAME,
|
||||
(P.RDB$PACKAGE_NAME.NULL ? "" : P.RDB$PACKAGE_NAME)));
|
||||
}
|
||||
procedure->prc_id = P.RDB$PROCEDURE_ID;
|
||||
procedure->setId(P.RDB$PROCEDURE_ID);
|
||||
|
||||
if (!P.RDB$SECURITY_CLASS.NULL)
|
||||
{
|
||||
procedure->prc_security_name = P.RDB$SECURITY_CLASS;
|
||||
}
|
||||
procedure->setSecurityName(P.RDB$SECURITY_CLASS);
|
||||
else if (!P.RDB$PACKAGE_NAME.NULL)
|
||||
{
|
||||
AutoCacheRequest requestHandle(tdbb, irq_l_procedure_pkg_class, IRQ_REQUESTS);
|
||||
@ -3233,25 +3234,13 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
WITH PKG.RDB$PACKAGE_NAME EQ P.RDB$PACKAGE_NAME
|
||||
{
|
||||
if (!PKG.RDB$SECURITY_CLASS.NULL)
|
||||
procedure->prc_security_name = PKG.RDB$SECURITY_CLASS;
|
||||
procedure->setSecurityName(PKG.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
|
||||
if ( (procedure->prc_inputs = P.RDB$PROCEDURE_INPUTS) )
|
||||
{
|
||||
procedure->prc_input_fields =
|
||||
vec<Parameter*>::newVector(*dbb->dbb_permanent, procedure->prc_input_fields,
|
||||
P.RDB$PROCEDURE_INPUTS);
|
||||
}
|
||||
if ( (procedure->prc_outputs = P.RDB$PROCEDURE_OUTPUTS) )
|
||||
{
|
||||
procedure->prc_output_fields =
|
||||
vec<Parameter*>::newVector(*dbb->dbb_permanent, procedure->prc_output_fields,
|
||||
P.RDB$PROCEDURE_OUTPUTS);
|
||||
}
|
||||
|
||||
vec<Parameter*>* paramVector = 0;
|
||||
procedure->prc_input_fields.resize(P.RDB$PROCEDURE_INPUTS);
|
||||
procedure->prc_output_fields.resize(P.RDB$PROCEDURE_OUTPUTS);
|
||||
procedure->prc_defaults = 0;
|
||||
|
||||
jrd_req* request2 = CMP_find_request(tdbb, irq_r_params, IRQ_REQUESTS);
|
||||
@ -3273,17 +3262,13 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
const SSHORT pa_default_value_null = PA.RDB$DEFAULT_VALUE.NULL;
|
||||
bid pa_default_value = PA.RDB$DEFAULT_VALUE;
|
||||
|
||||
if (PA.RDB$PARAMETER_TYPE) {
|
||||
paramVector = procedure->prc_output_fields;
|
||||
}
|
||||
else {
|
||||
paramVector = procedure->prc_input_fields;
|
||||
}
|
||||
Array<Parameter*>& paramArray = PA.RDB$PARAMETER_TYPE ?
|
||||
procedure->prc_output_fields : procedure->prc_input_fields;
|
||||
|
||||
// should be error if field already exists
|
||||
Parameter* parameter = FB_NEW(*dbb->dbb_permanent) Parameter(*dbb->dbb_permanent);
|
||||
parameter->prm_number = PA.RDB$PARAMETER_NUMBER;
|
||||
(*paramVector)[parameter->prm_number] = parameter;
|
||||
paramArray[parameter->prm_number] = parameter;
|
||||
parameter->prm_name = PA.RDB$PARAMETER_NAME;
|
||||
parameter->prm_nullable = PA.RDB$NULL_FLAG.NULL || PA.RDB$NULL_FLAG == 0; // ODS_11_1
|
||||
parameter->prm_mechanism = PA.RDB$PARAMETER_MECHANISM.NULL ? // ODS_11_1
|
||||
@ -3325,14 +3310,16 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
if (!REQUEST(irq_r_params))
|
||||
REQUEST(irq_r_params) = request2;
|
||||
|
||||
if ((paramVector = procedure->prc_output_fields) && (*paramVector)[0])
|
||||
Array<Parameter*>& paramArray = procedure->prc_output_fields;
|
||||
|
||||
if (paramArray.hasData() && paramArray[0])
|
||||
{
|
||||
Format* format = procedure->prc_format =
|
||||
Format::newFormat(*dbb->dbb_permanent, procedure->prc_outputs);
|
||||
Format::newFormat(*dbb->dbb_permanent, procedure->prc_output_fields.getCount());
|
||||
ULONG length = FLAG_BYTES(format->fmt_count);
|
||||
Format::fmt_desc_iterator desc = format->fmt_desc.begin();
|
||||
vec<Parameter*>::iterator ptr, end;
|
||||
for (ptr = paramVector->begin(), end = paramVector->end(); ptr < end; ++ptr, ++desc)
|
||||
Array<Parameter*>::iterator ptr, end;
|
||||
for (ptr = paramArray.begin(), end = paramArray.end(); ptr < end; ++ptr, ++desc)
|
||||
{
|
||||
Parameter* parameter = *ptr;
|
||||
// check for parameter to be null, this can only happen if the
|
||||
@ -3362,7 +3349,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
|
||||
FOR(REQUEST_HANDLE request4)
|
||||
PT IN RDB$PROCEDURES
|
||||
WITH PT.RDB$PROCEDURE_ID EQ procedure->prc_id
|
||||
WITH PT.RDB$PROCEDURE_ID EQ procedure->getId()
|
||||
|
||||
if (!REQUEST(irq_p_type))
|
||||
REQUEST(irq_p_type) = request4;
|
||||
@ -3389,19 +3376,19 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
{
|
||||
delete csb;
|
||||
|
||||
if (procedure->prc_request)
|
||||
if (procedure->getRequest())
|
||||
{
|
||||
CMP_release(tdbb, procedure->prc_request);
|
||||
procedure->prc_request = NULL;
|
||||
CMP_release(tdbb, procedure->getRequest());
|
||||
procedure->setRequest(NULL);
|
||||
}
|
||||
else {
|
||||
dbb->deletePool(csb_pool);
|
||||
}
|
||||
|
||||
ERR_post(Arg::Gds(isc_bad_proc_BLR) << Arg::Str(procedure->prc_name.toString()));
|
||||
ERR_post(Arg::Gds(isc_bad_proc_BLR) << Arg::Str(procedure->getName().toString()));
|
||||
}
|
||||
|
||||
procedure->prc_request->req_procedure = procedure;
|
||||
procedure->getRequest()->req_procedure = procedure;
|
||||
for (size_t i = 0; i < csb->csb_rpt.getCount(); i++)
|
||||
{
|
||||
jrd_nod* node = csb->csb_rpt[i].csb_message;
|
||||
@ -3430,15 +3417,13 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
else
|
||||
body.getBuffer(1)[0] = '\0';
|
||||
|
||||
procedure->prc_external = dbb->dbb_extManager.makeProcedure(
|
||||
procedure->setExternal(dbb->dbb_extManager.makeProcedure(
|
||||
tdbb, procedure, P.RDB$ENGINE_NAME,
|
||||
(P.RDB$ENTRYPOINT.NULL ? "" : P.RDB$ENTRYPOINT), body.begin()); // ODS_12_0
|
||||
(P.RDB$ENTRYPOINT.NULL ? "" : P.RDB$ENTRYPOINT), body.begin()));
|
||||
}
|
||||
|
||||
if (P.RDB$VALID_BLR.NULL || P.RDB$VALID_BLR == FALSE)
|
||||
{
|
||||
valid_blr = false;
|
||||
}
|
||||
|
||||
END_FOR;
|
||||
|
||||
@ -3456,7 +3441,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
jrd_req* request5 = NULL;
|
||||
|
||||
FOR(REQUEST_HANDLE request5)
|
||||
P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_ID EQ procedure->prc_id
|
||||
P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_ID EQ procedure->getId()
|
||||
|
||||
MODIFY P USING
|
||||
P.RDB$VALID_BLR = TRUE;
|
||||
@ -3697,37 +3682,27 @@ void MET_remove_procedure(thread_db* tdbb, int id, jrd_prc* procedure)
|
||||
}
|
||||
|
||||
// deallocate input param structures
|
||||
vec<Parameter*>* vector;
|
||||
if ((procedure->prc_inputs) && (vector = procedure->prc_input_fields))
|
||||
|
||||
for (Array<Parameter*>::iterator i = procedure->prc_input_fields.begin();
|
||||
i != procedure->prc_input_fields.end(); ++i)
|
||||
{
|
||||
for (int i = 0; i < procedure->prc_inputs; i++)
|
||||
{
|
||||
if ((*vector)[i])
|
||||
{
|
||||
delete (*vector)[i];
|
||||
}
|
||||
}
|
||||
delete vector;
|
||||
procedure->prc_inputs = 0;
|
||||
procedure->prc_input_fields = NULL;
|
||||
if (*i)
|
||||
delete *i;
|
||||
}
|
||||
|
||||
procedure->prc_input_fields.clear();
|
||||
|
||||
// deallocate output param structures
|
||||
|
||||
if ((procedure->prc_outputs) && (vector = procedure->prc_output_fields))
|
||||
for (Array<Parameter*>::iterator i = procedure->prc_output_fields.begin();
|
||||
i != procedure->prc_output_fields.end(); ++i)
|
||||
{
|
||||
for (int i = 0; i < procedure->prc_outputs; i++)
|
||||
{
|
||||
if ((*vector)[i])
|
||||
{
|
||||
delete (*vector)[i];
|
||||
}
|
||||
}
|
||||
delete vector;
|
||||
procedure->prc_outputs = 0;
|
||||
procedure->prc_output_fields = NULL;
|
||||
if (*i)
|
||||
delete *i;
|
||||
}
|
||||
|
||||
procedure->prc_output_fields.clear();
|
||||
|
||||
if (!procedure->prc_use_count)
|
||||
{
|
||||
if (procedure->prc_format)
|
||||
@ -3745,10 +3720,10 @@ void MET_remove_procedure(thread_db* tdbb, int id, jrd_prc* procedure)
|
||||
{
|
||||
// Fully clear procedure block. Some pieces of code check for empty
|
||||
// procedure name and ID, this is why we do it.
|
||||
procedure->prc_name = QualifiedName();
|
||||
procedure->prc_security_name = "";
|
||||
procedure->setName(QualifiedName());
|
||||
procedure->setSecurityName("");
|
||||
procedure->prc_defaults = 0;
|
||||
procedure->prc_id = 0;
|
||||
procedure->setId(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4667,8 +4642,10 @@ static jrd_nod* parse_param_blr(thread_db* tdbb, jrd_prc* procedure, bid* blob_i
|
||||
|
||||
length = BLB_get_data(tdbb, blob, temp.getBuffer(length), length);
|
||||
|
||||
jrd_req* request = procedure->getRequest();
|
||||
jrd_nod* node = PAR_blr(tdbb, NULL, temp.begin(), length, NULL, &csb,
|
||||
&procedure->prc_request, false, 0);
|
||||
&request, false, 0);
|
||||
procedure->setRequest(request);
|
||||
csb->csb_blr_reader = BlrReader();
|
||||
|
||||
return node;
|
||||
@ -4677,9 +4654,9 @@ static jrd_nod* parse_param_blr(thread_db* tdbb, jrd_prc* procedure, bid* blob_i
|
||||
|
||||
// Generate BLR message for external procedures
|
||||
static void gen_ext_message(Firebird::UCharBuffer& blr, UCHAR message,
|
||||
const vec<Parameter*>* parameters)
|
||||
const Array<Parameter*>& parameters)
|
||||
{
|
||||
size_t count = (parameters ? parameters->count() : 0);
|
||||
size_t count = parameters.getCount();
|
||||
count = count * 2 + message;
|
||||
fb_assert(count < MAX_USHORT);
|
||||
|
||||
@ -4691,10 +4668,7 @@ static void gen_ext_message(Firebird::UCharBuffer& blr, UCHAR message,
|
||||
dsc shortDesc;
|
||||
shortDesc.makeShort(0);
|
||||
|
||||
if (!parameters)
|
||||
return;
|
||||
|
||||
for (Parameter* const* i = parameters->begin(); i != parameters->end(); ++i)
|
||||
for (Parameter* const* i = parameters.begin(); i != parameters.end(); ++i)
|
||||
{
|
||||
const Parameter* parameter = *i;
|
||||
|
||||
@ -4774,8 +4748,8 @@ static void parse_procedure_blr(thread_db* tdbb,
|
||||
|
||||
tmp.add(blr_begin); // e_extproc_input_assign
|
||||
|
||||
fb_assert(procedure->prc_inputs < MAX_USHORT / 2);
|
||||
for (USHORT i = 0; i < procedure->prc_inputs; ++i)
|
||||
fb_assert(procedure->prc_input_fields.getCount() < MAX_USHORT / 2);
|
||||
for (USHORT i = 0; i < procedure->prc_input_fields.getCount(); ++i)
|
||||
{
|
||||
tmp.add(blr_assignment);
|
||||
tmp.add(blr_parameter2);
|
||||
@ -4791,8 +4765,8 @@ static void parse_procedure_blr(thread_db* tdbb,
|
||||
|
||||
tmp.add(blr_begin); // e_extproc_output_assign
|
||||
|
||||
fb_assert(procedure->prc_outputs < MAX_USHORT / 2);
|
||||
for (USHORT i = 0; i < procedure->prc_outputs; ++i)
|
||||
fb_assert(procedure->prc_output_fields.getCount() < MAX_USHORT / 2);
|
||||
for (USHORT i = 0; i < procedure->prc_output_fields.getCount(); ++i)
|
||||
{
|
||||
tmp.add(blr_assignment);
|
||||
tmp.add(blr_parameter2);
|
||||
@ -4821,8 +4795,11 @@ static void parse_procedure_blr(thread_db* tdbb,
|
||||
|
||||
par_messages(tdbb, tmp.begin(), (ULONG) tmp.getCount(), procedure, csb);
|
||||
|
||||
jrd_req* request = procedure->getRequest();
|
||||
PAR_blr(tdbb, NULL, tmp.begin(), (ULONG) tmp.getCount(), NULL, &csb,
|
||||
&procedure->prc_request, false, 0);
|
||||
&request, false, 0);
|
||||
procedure->setRequest(request);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -5290,8 +5267,8 @@ static void store_dependencies(thread_db* tdbb,
|
||||
break;
|
||||
case obj_procedure:
|
||||
procedure = (jrd_prc*) node->nod_arg[e_dep_object];
|
||||
dpdo_name = &procedure->prc_name.identifier;
|
||||
packageName = procedure->prc_name.qualifier;
|
||||
dpdo_name = &procedure->getName().identifier;
|
||||
packageName = procedure->getName().qualifier;
|
||||
break;
|
||||
case obj_collation:
|
||||
{
|
||||
@ -5321,8 +5298,8 @@ static void store_dependencies(thread_db* tdbb,
|
||||
case obj_udf:
|
||||
{
|
||||
Function* const udf = (Function*) node->nod_arg[e_dep_object];
|
||||
dpdo_name = &udf->fun_name.identifier;
|
||||
packageName = udf->fun_name.qualifier;
|
||||
dpdo_name = &udf->getName().identifier;
|
||||
packageName = udf->getName().qualifier;
|
||||
}
|
||||
break;
|
||||
case obj_index:
|
||||
@ -5349,7 +5326,7 @@ static void store_dependencies(thread_db* tdbb,
|
||||
}
|
||||
else if (procedure)
|
||||
{
|
||||
const Parameter* param = (*procedure->prc_output_fields)[fld_id];
|
||||
const Parameter* param = procedure->prc_output_fields[fld_id];
|
||||
// CVC: Setting the field var here didn't make sense alone,
|
||||
// so I thought the missing code was to try to extract
|
||||
// the field name that's in this case an output var from a proc.
|
||||
|
@ -802,12 +802,10 @@ static SSHORT find_proc_field(const jrd_prc* procedure, const Firebird::MetaName
|
||||
* Look for named field in procedure output fields.
|
||||
*
|
||||
**************************************/
|
||||
vec<Parameter*>* list = procedure->prc_output_fields;
|
||||
if (!list)
|
||||
return -1;
|
||||
const Array<Parameter*>& list = procedure->prc_output_fields;
|
||||
|
||||
vec<Parameter*>::const_iterator ptr = list->begin();
|
||||
for (const vec<Parameter*>::const_iterator end = list->end(); ptr < end; ++ptr)
|
||||
Array<Parameter*>::const_iterator ptr = list.begin();
|
||||
for (const vec<Parameter*>::const_iterator end = list.end(); ptr < end; ++ptr)
|
||||
{
|
||||
const Parameter* param = *ptr;
|
||||
if (name == param->prm_name)
|
||||
@ -1328,7 +1326,7 @@ static jrd_nod* par_field(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_oper
|
||||
(procedure->prc_flags & PRC_being_scanned) ||
|
||||
(procedure->prc_flags & PRC_being_altered)))
|
||||
{
|
||||
const jrd_prc* scan_proc = MET_procedure(tdbb, procedure->prc_id, false, 0);
|
||||
const jrd_prc* scan_proc = MET_procedure(tdbb, procedure->getId(), false, 0);
|
||||
if (scan_proc != procedure)
|
||||
procedure = NULL;
|
||||
}
|
||||
@ -1339,7 +1337,7 @@ static jrd_nod* par_field(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_oper
|
||||
if ((id = find_proc_field(procedure, name)) == -1)
|
||||
{
|
||||
error(csb, Arg::Gds(isc_fldnotdef2) << Arg::Str(name) <<
|
||||
Arg::Str(procedure->prc_name.toString()));
|
||||
Arg::Str(procedure->getName().toString()));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1483,7 +1481,7 @@ static jrd_nod* par_function(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_o
|
||||
error(csb, Arg::Gds(isc_funnotdef) << Arg::Str(name.toString()));
|
||||
}
|
||||
|
||||
if (!function->fun_entrypoint && !function->fun_external && !function->fun_request)
|
||||
if (!function->fun_entrypoint && !function->fun_external && !function->getRequest())
|
||||
{
|
||||
if (tdbb->getAttachment()->att_flags & ATT_gbak_attachment)
|
||||
{
|
||||
@ -1508,7 +1506,7 @@ static jrd_nod* par_function(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_o
|
||||
if (node->nod_arg[e_fun_args]->nod_count < function->fun_inputs - function->fun_defaults ||
|
||||
node->nod_arg[e_fun_args]->nod_count > function->fun_inputs)
|
||||
{
|
||||
error(csb, Arg::Gds(isc_funmismat) << Arg::Str(function->fun_name.toString()));
|
||||
error(csb, Arg::Gds(isc_funmismat) << Arg::Str(function->getName().toString()));
|
||||
}
|
||||
|
||||
// CVC: I will track ufds only if a proc is not being dropped.
|
||||
@ -2139,13 +2137,13 @@ static jrd_nod* par_procedure(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_
|
||||
|
||||
if (procedure->prc_type == prc_executable)
|
||||
{
|
||||
error(csb, Arg::Gds(isc_illegal_prc_type) << Arg::Str(procedure->prc_name.toString()));
|
||||
error(csb, Arg::Gds(isc_illegal_prc_type) << Arg::Str(procedure->getName().toString()));
|
||||
}
|
||||
|
||||
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;
|
||||
node->nod_arg[e_prc_procedure] = (jrd_nod*)(IPTR) procedure->getId();
|
||||
|
||||
SSHORT context;
|
||||
const SSHORT stream = par_context(csb, &context);
|
||||
@ -2189,15 +2187,15 @@ static void par_procedure_parms(thread_db* tdbb,
|
||||
|
||||
// Check to see if the parameter count matches
|
||||
if (input_flag ?
|
||||
(count < (procedure->prc_inputs - procedure->prc_defaults) ||
|
||||
(count > procedure->prc_inputs) ) :
|
||||
(count != procedure->prc_outputs))
|
||||
(count < (SLONG(procedure->prc_input_fields.getCount()) - procedure->prc_defaults) ||
|
||||
(count > SLONG(procedure->prc_input_fields.getCount())) ) :
|
||||
(count != SLONG(procedure->prc_output_fields.getCount())))
|
||||
{
|
||||
// They don't match...Hmmm...Its OK if we were dropping the procedure
|
||||
if (!(tdbb->tdbb_flags & TDBB_prc_being_dropped))
|
||||
{
|
||||
error(csb, Arg::Gds(input_flag ? isc_prcmismat : isc_prc_out_param_mismatch) <<
|
||||
Arg::Str(procedure->prc_name.toString()));
|
||||
Arg::Str(procedure->getName().toString()));
|
||||
}
|
||||
else
|
||||
mismatch = true;
|
||||
@ -2272,7 +2270,8 @@ static void par_procedure_parms(thread_db* tdbb,
|
||||
// default value for parameter
|
||||
if ((count <= 0) && input_flag)
|
||||
{
|
||||
Parameter* parameter = (*procedure->prc_input_fields)[procedure->prc_inputs - n];
|
||||
Parameter* parameter = procedure->prc_input_fields[
|
||||
procedure->prc_input_fields.getCount() - n];
|
||||
asgn->nod_arg[asgn_arg1] = CMP_clone_node(tdbb, csb, parameter->prm_default_value);
|
||||
}
|
||||
else {
|
||||
@ -2290,10 +2289,12 @@ static void par_procedure_parms(thread_db* tdbb,
|
||||
prm_f->nod_arg[e_arg_number] = (jrd_nod*)(IPTR) i++;
|
||||
}
|
||||
}
|
||||
else if ((input_flag ? procedure->prc_inputs : procedure->prc_outputs) && !mismatch)
|
||||
else if ((input_flag ?
|
||||
procedure->prc_input_fields.getCount() : procedure->prc_output_fields.getCount()) &&
|
||||
!mismatch)
|
||||
{
|
||||
error(csb, Arg::Gds(input_flag ? isc_prcmismat : isc_prc_out_param_mismatch) <<
|
||||
Arg::Str(procedure->prc_name.toString()));
|
||||
Arg::Str(procedure->getName().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ void ProcedureScan::open(thread_db* tdbb)
|
||||
USHORT iml;
|
||||
const UCHAR* im;
|
||||
|
||||
jrd_req* const proc_request = EXE_find_request(tdbb, m_procedure->prc_request, false);
|
||||
jrd_req* const proc_request = EXE_find_request(tdbb, m_procedure->getRequest(), false);
|
||||
impure->irsb_req_handle = proc_request;
|
||||
|
||||
if (m_inputs)
|
||||
|
@ -233,7 +233,7 @@ public:
|
||||
m_inputs(*getDefaultMemoryPool(), request->req_proc_caller, request->req_proc_inputs)
|
||||
{}
|
||||
|
||||
virtual const char* getProcName() { return m_request->req_procedure->prc_name.identifier.c_str(); }
|
||||
virtual const char* getProcName() { return m_request->req_procedure->getName().identifier.c_str(); }
|
||||
virtual TraceParams* getInputs() { return &m_inputs; }
|
||||
virtual PerformanceInfo* getPerf() { return m_perf; };
|
||||
|
||||
|
@ -1412,11 +1412,11 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
|
||||
if ((procedure = MET_lookup_procedure(tdbb,
|
||||
QualifiedName(procedure_name, package_name), true)))
|
||||
{
|
||||
work = DFW_post_work(transaction, dfw_delete_prm, &desc2, procedure->prc_id,
|
||||
work = DFW_post_work(transaction, dfw_delete_prm, &desc2, procedure->getId(),
|
||||
package_name);
|
||||
|
||||
// procedure name to track parameter dependencies
|
||||
DFW_post_work_arg(transaction, work, &desc, procedure->prc_id, dfw_arg_proc_name);
|
||||
DFW_post_work_arg(transaction, work, &desc, procedure->getId(), dfw_arg_proc_name);
|
||||
}
|
||||
EVL_field(0, rpb->rpb_record, f_prm_sname, &desc2);
|
||||
DFW_post_work(transaction, dfw_delete_global, &desc2, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user