"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/ExtEngineManager.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

ExtEngineManager.cpp  (Firebird-3.0.2.32703-0.tar.bz2):ExtEngineManager.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 61 skipping to change at line 61
#include "../common/config/config.h" #include "../common/config/config.h"
#include "../common/ScanDir.h" #include "../common/ScanDir.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
#include "../common/classes/GetPlugins.h" #include "../common/classes/GetPlugins.h"
using namespace Firebird; using namespace Firebird;
using namespace Jrd; using namespace Jrd;
namespace namespace
{ {
// External message node. // Internal message node.
class ExtMessageNode : public MessageNode class IntMessageNode : public MessageNode
{ {
public: public:
ExtMessageNode(thread_db* tdbb, MemoryPool& pool, CompilerScratch * csb, USHORT message, IntMessageNode(thread_db* tdbb, MemoryPool& pool, CompilerScratch * csb, USHORT message,
Array<NestConst<Parameter> >& aParameters, const Format* aFormat) Array<NestConst<Parameter> >& aParameters, const Format* aFormat)
: MessageNode(pool), : MessageNode(pool),
parameters(aParameters), parameters(aParameters),
format(aFormat), format(aFormat)
isSpecial(pool)
{ {
setup(tdbb, csb, message, format->fmt_count); setup(tdbb, csb, message, format->fmt_count);
} }
virtual USHORT setupDesc(thread_db* tdbb, CompilerScratch* csb, U SHORT index, virtual USHORT setupDesc(thread_db* tdbb, CompilerScratch* csb, U SHORT index,
dsc* desc, ItemInfo* itemInfo) dsc* desc, ItemInfo* itemInfo)
{ {
*desc = format->fmt_desc[index]; *desc = format->fmt_desc[index];
if (index % 2 == 0 && index / 2u < parameters.getCount()) if (index % 2 == 0 && index / 2u < parameters.getCount())
skipping to change at line 106 skipping to change at line 105
itemInfo->field = namePair; itemInfo->field = namePair;
itemInfo->nullable = fieldInfo.nullable; itemInfo->nullable = fieldInfo.nullable;
itemInfo->fullDomain = true; itemInfo->fullDomain = true;
} }
itemInfo->name = param->prm_name; itemInfo->name = param->prm_name;
if (!param->prm_nullable) if (!param->prm_nullable)
itemInfo->nullable = false; itemInfo->nullable = false;
isSpecial.getBuffer(index / 2 + 1)[index / 2] = i
temInfo->isSpecial();
} }
return type_alignments[desc->dsc_dtype]; return type_alignments[desc->dsc_dtype];
} }
public:
Array<NestConst<Parameter> >& parameters;
const Format* format;
};
// External message node.
class ExtMessageNode : public MessageNode
{
public:
ExtMessageNode(thread_db* tdbb, MemoryPool& pool, CompilerScratch
* csb, USHORT message, const Format* aFormat)
: MessageNode(pool),
format(aFormat)
{
setup(tdbb, csb, message, format->fmt_count);
}
virtual USHORT setupDesc(thread_db* tdbb, CompilerScratch* csb, U
SHORT index,
dsc* desc, ItemInfo* itemInfo)
{
*desc = format->fmt_desc[index];
return type_alignments[desc->dsc_dtype];
}
virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request , ExeState* exeState) const virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request , ExeState* exeState) const
{ {
if (request->req_operation == jrd_req::req_evaluate) if (request->req_operation == jrd_req::req_evaluate)
{ {
// Clear the message. This is important for exter nal routines. // Clear the message. This is important for exter nal routines.
UCHAR* msg = request->getImpure<UCHAR>(impureOffs et); UCHAR* msg = request->getImpure<UCHAR>(impureOffs et);
memset(msg, 0, format->fmt_length); memset(msg, 0, format->fmt_length);
} }
return MessageNode::execute(tdbb, request, exeState); return MessageNode::execute(tdbb, request, exeState);
} }
public: public:
Array<NestConst<Parameter> >& parameters;
const Format* format; const Format* format;
Array<bool> isSpecial;
}; };
// Initialize output parameters with their domains default value or NULL. // Initialize output parameters with their domains default value or NULL.
// Kind of blr_init_variable, but for parameters. // Kind of blr_init_variable, but for parameters.
class ExtInitParameterNode : public TypedNode<StmtNode, StmtNode::TYPE_EX T_INIT_PARAMETER> class InitParameterNode : public TypedNode<StmtNode, StmtNode::TYPE_EXT_I NIT_PARAMETER>
{ {
public: public:
ExtInitParameterNode(thread_db* tdbb, MemoryPool& pool, CompilerS InitParameterNode(thread_db* tdbb, MemoryPool& pool, CompilerScra
cratch* csb, tch* csb,
ExtMessageNode* aMessage, USHORT aArgNumber) Array<NestConst<Parameter> >& parameters, Message
Node* aMessage, USHORT aArgNumber)
: TypedNode<StmtNode, StmtNode::TYPE_EXT_INIT_PARAMETER>( pool), : TypedNode<StmtNode, StmtNode::TYPE_EXT_INIT_PARAMETER>( pool),
message(aMessage), message(aMessage),
argNumber(aArgNumber) argNumber(aArgNumber)
{ {
Parameter* parameter = message->parameters[argNumber / 2] Parameter* parameter = parameters[argNumber / 2];
; defaultValueNode = NULL;
if (parameter->prm_mechanism == prm_mech_type_of || if (parameter->prm_mechanism != prm_mech_type_of &&
fb_utils::implicit_domain(parameter->prm_field_so !fb_utils::implicit_domain(parameter->prm_field_s
urce.c_str()) || ource.c_str()))
!parameter->prm_default_value)
{ {
defaultValueNode = NULL; MetaNamePair namePair(parameter->prm_field_source
, "");
FieldInfo fieldInfo;
bool exist = csb->csb_map_field_info.get(namePair
, fieldInfo);
if (exist && fieldInfo.defaultValue)
defaultValueNode = CMP_clone_node(tdbb, c
sb, fieldInfo.defaultValue);
} }
else
defaultValueNode = CMP_clone_node(tdbb, csb, para
meter->prm_default_value);
} }
string internalPrint(NodePrinter& printer) const string internalPrint(NodePrinter& printer) const
{ {
StmtNode::internalPrint(printer); StmtNode::internalPrint(printer);
NODE_PRINT(printer, message); NODE_PRINT(printer, message);
NODE_PRINT(printer, argNumber); NODE_PRINT(printer, argNumber);
NODE_PRINT(printer, defaultValueNode); NODE_PRINT(printer, defaultValueNode);
return "ExtInitParameterNode"; return "InitParameterNode";
} }
void genBlr(DsqlCompilerScratch* /*dsqlScratch*/) void genBlr(DsqlCompilerScratch* /*dsqlScratch*/)
{ {
} }
ExtInitParameterNode* pass1(thread_db* tdbb, CompilerScratch* csb ) InitParameterNode* pass1(thread_db* tdbb, CompilerScratch* csb)
{ {
doPass1(tdbb, csb, &defaultValueNode); doPass1(tdbb, csb, &defaultValueNode);
return this; return this;
} }
ExtInitParameterNode* pass2(thread_db* tdbb, CompilerScratch* csb ) InitParameterNode* pass2(thread_db* tdbb, CompilerScratch* csb)
{ {
ExprNode::doPass2(tdbb, csb, &defaultValueNode); ExprNode::doPass2(tdbb, csb, &defaultValueNode);
return this; return this;
} }
const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeSta te* /*exeState*/) const const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeSta te* /*exeState*/) const
{ {
if (request->req_operation == jrd_req::req_evaluate) if (request->req_operation == jrd_req::req_evaluate)
{ {
dsc* defaultDesc = NULL; dsc* defaultDesc = NULL;
skipping to change at line 226 skipping to change at line 248
MOV_move(tdbb, &temp, &desc); MOV_move(tdbb, &temp, &desc);
} }
request->req_operation = jrd_req::req_return; request->req_operation = jrd_req::req_return;
} }
return parentStmt; return parentStmt;
} }
private: private:
ExtMessageNode* message; MessageNode* message;
USHORT argNumber; USHORT argNumber;
ValueExprNode* defaultValueNode; ValueExprNode* defaultValueNode;
}; };
// External output parameters initialization. // Output parameters initialization.
class ExtInitOutputNode : public CompoundStmtNode class InitOutputNode : public CompoundStmtNode
{ {
public: public:
ExtInitOutputNode(thread_db* tdbb, MemoryPool& pool, CompilerScra InitOutputNode(thread_db* tdbb, MemoryPool& pool, CompilerScratch
tch* csb, * csb,
ExtMessageNode* message) Array<NestConst<Parameter> >& parameters, Message
Node* message)
: CompoundStmtNode(pool) : CompoundStmtNode(pool)
{ {
// Iterate over the format items, except the EOF item. // Iterate over the format items, except the EOF item.
for (USHORT i = 0; i < (message->format->fmt_count / 2) * 2; i += 2) for (USHORT i = 0; i < (message->format->fmt_count / 2) * 2; i += 2)
{ {
ExtInitParameterNode* init = FB_NEW_POOL(pool) Ex InitParameterNode* init = FB_NEW_POOL(pool) InitP
tInitParameterNode( arameterNode(
tdbb, pool, csb, message, i); tdbb, pool, csb, parameters, message, i);
statements.add(init); statements.add(init);
} }
} }
}; };
// External parameters validation. // Move parameters from a message to another, validating theirs values.
class ExtValidationNode : public CompoundStmtNode class MessageMoverNode : public CompoundStmtNode
{ {
public: public:
ExtValidationNode(MemoryPool& pool, ExtMessageNode* message, bool procedure, bool input) MessageMoverNode(MemoryPool& pool, MessageNode* fromMessage, Mess ageNode* toMessage)
: CompoundStmtNode(pool) : CompoundStmtNode(pool)
{ {
// Iterate over the format items, except the EOF item. // Iterate over the format items, except the EOF item.
for (USHORT i = 0; i < (message->format->fmt_count / 2) * 2; i += 2) for (USHORT i = 0; i < (fromMessage->format->fmt_count / 2) * 2; i += 2)
{ {
if (!message->isSpecial[i / 2])
continue;
ParameterNode* flag = FB_NEW_POOL(pool) Parameter Node(pool); ParameterNode* flag = FB_NEW_POOL(pool) Parameter Node(pool);
flag->message = message; flag->message = fromMessage;
flag->argNumber = i + 1; flag->argNumber = i + 1;
ParameterNode* param = FB_NEW_POOL(pool) Paramete rNode(pool); ParameterNode* param = FB_NEW_POOL(pool) Paramete rNode(pool);
param->message = message; param->message = fromMessage;
param->argNumber = i; param->argNumber = i;
param->argFlag = flag; param->argFlag = flag;
AssignmentNode* assign = FB_NEW_POOL(pool) Assign mentNode(pool); AssignmentNode* assign = FB_NEW_POOL(pool) Assign mentNode(pool);
assign->asgnFrom = param; assign->asgnFrom = param;
statements.add(assign); statements.add(assign);
// It's sufficient to assign input parameters to flag = FB_NEW_POOL(pool) ParameterNode(pool);
NULL, but output parameters flag->message = toMessage;
// need to be assigned to themselves to validate flag->argNumber = i + 1;
correctly.
if (input)
assign->asgnTo = FB_NEW_POOL(pool) NullNo
de(pool);
else
{
flag = FB_NEW_POOL(pool) ParameterNode(po
ol);
flag->message = message;
flag->argNumber = i + 1;
param = FB_NEW_POOL(pool) ParameterNode(p
ool);
param->message = message;
param->argNumber = i;
param->argFlag = flag;
assign->asgnTo = param; param = FB_NEW_POOL(pool) ParameterNode(pool);
} param->message = toMessage;
} param->argNumber = i;
param->argFlag = flag;
// A stall is required to read req_proc_fetch state corre assign->asgnTo = param;
ctly. }
if (procedure)
statements.add(FB_NEW_POOL(pool) StallNode(pool))
;
} }
}; };
// External function node. // External function node.
class ExtFunctionNode : public SuspendNode class ExtFunctionNode : public SuspendNode
{ {
public: public:
ExtFunctionNode(MemoryPool& pool, const ReceiveNode* aReceiveNode , ExtFunctionNode(MemoryPool& pool, const MessageNode* aExtInMessag eNode, const MessageNode* aExtOutMessageNode,
const ExtEngineManager::Function* aFunction) const ExtEngineManager::Function* aFunction)
: SuspendNode(pool), : SuspendNode(pool),
receiveNode(aReceiveNode), extInMessageNode(aExtInMessageNode),
extOutMessageNode(aExtOutMessageNode),
function(aFunction) function(aFunction)
{ {
} }
virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request , ExeState* exeState) const virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request , ExeState* exeState) const
{ {
if (request->req_operation == jrd_req::req_evaluate) if (request->req_operation == jrd_req::req_evaluate)
{ {
UCHAR* inMsg = receiveNode ? UCHAR* inMsg = extInMessageNode ? request->getImp
request->getImpure<UCHAR>(receiveNode->me ure<UCHAR>(extInMessageNode->impureOffset) : NULL;
ssage->impureOffset) : NULL; UCHAR* outMsg = request->getImpure<UCHAR>(extOutM
UCHAR* outMsg = request->getImpure<UCHAR>(message essageNode->impureOffset);
->impureOffset);
function->execute(tdbb, inMsg, outMsg); function->execute(tdbb, inMsg, outMsg);
} }
return SuspendNode::execute(tdbb, request, exeState); return SuspendNode::execute(tdbb, request, exeState);
} }
private: private:
const ReceiveNode* receiveNode; const MessageNode* extInMessageNode;
const MessageNode* extOutMessageNode;
const ExtEngineManager::Function* function; const ExtEngineManager::Function* function;
}; };
// External procedure node. // External procedure node.
class ExtProcedureNode : public SuspendNode class ExtProcedureNode : public CompoundStmtNode
{ {
public: public:
ExtProcedureNode(MemoryPool& pool, const ReceiveNode* aReceiveNod ExtProcedureNode(MemoryPool& pool, MessageNode* aExtInMessageNode
e, , MessageNode* aExtOutMessageNode,
const ExtEngineManager::Procedure* aProcedure) MessageNode* aIntOutMessageNode, const ExtEngineM
: SuspendNode(pool), anager::Procedure* aProcedure)
receiveNode(aReceiveNode), : CompoundStmtNode(pool),
extInMessageNode(aExtInMessageNode),
extOutMessageNode(aExtOutMessageNode),
intOutMessageNode(aIntOutMessageNode),
procedure(aProcedure) procedure(aProcedure)
{ {
SuspendNode* suspend = FB_NEW_POOL(pool) SuspendNode(pool
);
suspend->message = intOutMessageNode;
suspend->statement = FB_NEW_POOL(getPool()) MessageMoverN
ode(pool, extOutMessageNode, intOutMessageNode);
statements.add(suspend);
statements.add(FB_NEW_POOL(getPool()) StallNode(pool));
} }
virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request , ExeState* exeState) const virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request , ExeState* exeState) const
{ {
impure_state* const impure = request->getImpure<impure_st ate>(impureOffset);
ExtEngineManager::ResultSet*& resultSet = request->req_ex t_resultset; ExtEngineManager::ResultSet*& resultSet = request->req_ex t_resultset;
UCHAR* inMsg = receiveNode ? UCHAR* extInMsg = extInMessageNode ? request->getImpure<U
request->getImpure<UCHAR>(receiveNode->message->i CHAR>(extInMessageNode->impureOffset) : NULL;
mpureOffset) : NULL; UCHAR* extOutMsg = extOutMessageNode ? request->getImpure
UCHAR* outMsg = request->getImpure<UCHAR>(message->impure <UCHAR>(extOutMessageNode->impureOffset) : NULL;
Offset); UCHAR* intOutMsg = intOutMessageNode ? request->getImpure
USHORT* eof = (USHORT*) (outMsg + (IPTR) message->format- <UCHAR>(intOutMessageNode->impureOffset) : NULL;
>fmt_desc.back().dsc_address); SSHORT* eof = intOutMsg ?
(SSHORT*) (intOutMsg + (IPTR) intOutMessageNode->
format->fmt_desc.back().dsc_address) : NULL;
switch (request->req_operation) switch (request->req_operation)
{ {
case jrd_req::req_evaluate: case jrd_req::req_evaluate:
fb_assert(!resultSet && *eof == 0); fb_assert(!resultSet);
resultSet = procedure->open(tdbb, inMsg, resultSet = procedure->open(tdbb, extInMs
outMsg); g, extOutMsg);
if (resultSet) if (!resultSet)
*eof = -1;
else
{ {
if (!(request->req_flags & req_pr *eof = 0;
oc_fetch)) break;
{
request->req_operation =
jrd_req::req_evaluate;
return statement;
}
} }
else
request->req_operation = jrd_req::req_ret *eof = -1;
urn;
// fall into // fall into
case jrd_req::req_return: case jrd_req::req_proceed:
if (*eof == 0) case jrd_req::req_sync:
{ if (resultSet)
fb_assert(!resultSet);
return parentStmt;
}
fb_assert(resultSet);
if (!resultSet->fetch(tdbb) || !(request-
>req_flags & req_proc_fetch))
{ {
*eof = 0; if (resultSet->fetch(tdbb) && (re
delete resultSet; quest->req_flags & req_proc_fetch))
resultSet = NULL; *eof = -1;
else
{
*eof = 0;
delete resultSet;
resultSet = NULL;
}
} }
impure->sta_state = 0; // suspend node
request->req_operation = jrd_req::req_syn
c;
break; break;
case jrd_req::req_proceed:
request->req_operation = jrd_req::req_eva
luate;
return statement;
case jrd_req::req_unwind: case jrd_req::req_unwind:
delete resultSet; delete resultSet;
resultSet = NULL; resultSet = NULL;
break; break;
} }
return SuspendNode::execute(tdbb, request, exeState); return CompoundStmtNode::execute(tdbb, request, exeState) ;
} }
private: private:
const ReceiveNode* receiveNode; MessageNode* extInMessageNode;
MessageNode* extOutMessageNode;
MessageNode* intOutMessageNode;
const ExtEngineManager::Procedure* procedure; const ExtEngineManager::Procedure* procedure;
}; };
// External trigger node. // External trigger node.
class ExtTriggerNode : public TypedNode<StmtNode, StmtNode::TYPE_EXT_TRIG GER> class ExtTriggerNode : public TypedNode<StmtNode, StmtNode::TYPE_EXT_TRIG GER>
{ {
public: public:
ExtTriggerNode(MemoryPool& pool, const ExtEngineManager::Trigger* aTrigger) ExtTriggerNode(MemoryPool& pool, const ExtEngineManager::Trigger* aTrigger)
: TypedNode<StmtNode, StmtNode::TYPE_EXT_TRIGGER>(pool), : TypedNode<StmtNode, StmtNode::TYPE_EXT_TRIGGER>(pool),
trigger(aTrigger) trigger(aTrigger)
skipping to change at line 588 skipping to change at line 600
externalAttachment(NULL), externalAttachment(NULL),
externalTransaction(NULL), externalTransaction(NULL),
miscInfo(*internalAttachment->att_pool) miscInfo(*internalAttachment->att_pool)
{ {
//// TODO: admin rights //// TODO: admin rights
clientCharSet = INTL_charset_lookup(tdbb, internalAttachment->att_client_ charset)->getName(); clientCharSet = INTL_charset_lookup(tdbb, internalAttachment->att_client_ charset)->getName();
internalAttachment->getStable()->addRef(); internalAttachment->getStable()->addRef();
externalAttachment = MasterInterfacePtr()->registerAttachment(JProvider:: externalAttachment = MasterInterfacePtr()->registerAttachment
getInstance(), (AutoPlugin<JProvider>(JProvider::getInstance()), internalAttachm
internalAttachment->getInterface()); ent->getInterface());
} }
ExtEngineManager::ExternalContextImpl::~ExternalContextImpl() ExtEngineManager::ExternalContextImpl::~ExternalContextImpl()
{ {
releaseTransaction(); releaseTransaction();
if (externalAttachment) if (externalAttachment)
{ {
externalAttachment->release(); externalAttachment->release();
externalAttachment = NULL; externalAttachment = NULL;
skipping to change at line 616 skipping to change at line 628
{ {
externalTransaction->release(); externalTransaction->release();
externalTransaction = NULL; externalTransaction = NULL;
} }
internalTransaction = NULL; internalTransaction = NULL;
} }
void ExtEngineManager::ExternalContextImpl::setTransaction(thread_db* tdbb) void ExtEngineManager::ExternalContextImpl::setTransaction(thread_db* tdbb)
{ {
jrd_tra* newTransaction = tdbb->getTransaction(); ITransaction* newTransaction = tdbb->getTransaction() ? tdbb->getTransact ion()->getInterface(true) : NULL;
if (newTransaction == internalTransaction) if (newTransaction == internalTransaction)
return; return;
releaseTransaction(); releaseTransaction();
fb_assert(!externalTransaction); fb_assert(!externalTransaction && !internalTransaction);
if ((internalTransaction = newTransaction)) if ((internalTransaction = newTransaction))
{ externalTransaction = MasterInterfacePtr()->registerTransaction(e
internalTransaction->getInterface()->addRef(); xternalAttachment, internalTransaction);
externalTransaction = MasterInterfacePtr()->registerTransaction(e
xternalAttachment,
internalTransaction->getInterface());
}
} }
IMaster* ExtEngineManager::ExternalContextImpl::getMaster() IMaster* ExtEngineManager::ExternalContextImpl::getMaster()
{ {
MasterInterfacePtr master; MasterInterfacePtr master;
return master; return master;
} }
IExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(CheckStatusWra pper* /*status*/) IExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(CheckStatusWra pper* /*status*/)
{ {
skipping to change at line 1047 skipping to change at line 1054
FbLocalStatus status; FbLocalStatus status;
RefPtr<IMetadataBuilder> inBuilder(REF_NO_INCR, metadata->inputParameters ->getBuilder(&status)); RefPtr<IMetadataBuilder> inBuilder(REF_NO_INCR, metadata->inputParameters ->getBuilder(&status));
status.check(); status.check();
RefPtr<IMetadataBuilder> outBuilder(REF_NO_INCR, metadata->outputParamete rs->getBuilder(&status)); RefPtr<IMetadataBuilder> outBuilder(REF_NO_INCR, metadata->outputParamete rs->getBuilder(&status));
status.check(); status.check();
IExternalFunction* externalFunction; IExternalFunction* externalFunction;
RefPtr<IMessageMetadata> extInputParameters, extOutputParameters;
{ // scope { // scope
EngineCheckout cout(tdbb, FB_FUNCTION); EngineCheckout cout(tdbb, FB_FUNCTION);
externalFunction = attInfo->engine->makeFunction(&status, attInfo ->context, metadata, externalFunction = attInfo->engine->makeFunction(&status, attInfo ->context, metadata,
inBuilder, outBuilder); inBuilder, outBuilder);
status.check(); status.check();
if (!externalFunction) if (!externalFunction)
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_eem_func_not_returned) << udf->getNa me().toString() << engine); Arg::Gds(isc_eem_func_not_returned) << udf->getNa me().toString() << engine);
} }
metadata->inputParameters = inBuilder->getMetadata(&status); extInputParameters = inBuilder->getMetadata(&status);
status.check(); status.check();
metadata->outputParameters = outBuilder->getMetadata(&status); extOutputParameters = outBuilder->getMetadata(&status);
status.check(); status.check();
} }
udf->setInputFormat(Routine::createFormat(pool, metadata->inputParameters , false)); udf->setInputFormat(Routine::createFormat(pool, metadata->inputParameters , false));
udf->setOutputFormat(Routine::createFormat(pool, metadata->outputParamete rs, true)); udf->setOutputFormat(Routine::createFormat(pool, metadata->outputParamete rs, true));
const Format* extInputFormat = Routine::createFormat(pool, extInputParame
ters, false);
const Format* extOutputFormat = Routine::createFormat(pool, extOutputPara
meters, true);
try try
{ {
udf->fun_external = FB_NEW_POOL(getPool()) Function(tdbb, this, a ttInfo->engine, udf->fun_external = FB_NEW_POOL(getPool()) Function(tdbb, this, a ttInfo->engine,
metadata.release(), externalFunction, udf); metadata.release(), externalFunction, udf);
CompoundStmtNode* mainNode = FB_NEW_POOL(getPool()) CompoundStmtN ode(getPool()); CompoundStmtNode* mainNode = FB_NEW_POOL(getPool()) CompoundStmtN ode(getPool());
ExtMessageNode* inMessageNode = udf->getInputFields().hasData() ? IntMessageNode* intInMessageNode = udf->getInputFields().hasData(
FB_NEW_POOL(getPool()) ExtMessageNode(tdbb, getPool(), cs ) ?
b, 0, FB_NEW_POOL(getPool()) IntMessageNode(tdbb, getPool(), cs
b, 0,
udf->getInputFields(), udf->getInputFormat()) : udf->getInputFields(), udf->getInputFormat()) :
NULL; NULL;
if (inMessageNode) ExtMessageNode* extInMessageNode = NULL;
mainNode->statements.add(inMessageNode);
if (intInMessageNode)
{
mainNode->statements.add(intInMessageNode);
extInMessageNode = FB_NEW_POOL(getPool()) ExtMessageNode(
tdbb, getPool(), csb, 2, extInputFormat);
mainNode->statements.add(extInMessageNode);
}
ExtMessageNode* outMessageNode = FB_NEW_POOL(getPool()) ExtMessag eNode(tdbb, getPool(), csb, 1, IntMessageNode* intOutMessageNode = FB_NEW_POOL(getPool()) IntMes sageNode(tdbb, getPool(), csb, 1,
udf->getOutputFields(), udf->getOutputFormat()); udf->getOutputFields(), udf->getOutputFormat());
mainNode->statements.add(outMessageNode); mainNode->statements.add(intOutMessageNode);
ExtInitOutputNode* initOutputNode = FB_NEW_POOL(getPool()) ExtIni ExtMessageNode* extOutMessageNode = FB_NEW_POOL(getPool()) ExtMes
tOutputNode( sageNode(tdbb, getPool(), csb, 3,
tdbb, getPool(), csb, outMessageNode); extOutputFormat);
mainNode->statements.add(extOutMessageNode);
// Initialize the output fields into the external message.
InitOutputNode* initOutputNode = FB_NEW_POOL(getPool()) InitOutpu
tNode(
tdbb, getPool(), csb, udf->getOutputFields(), extOutMessa
geNode);
mainNode->statements.add(initOutputNode); mainNode->statements.add(initOutputNode);
ReceiveNode* receiveNode = inMessageNode ? if (intInMessageNode)
FB_NEW_POOL(getPool()) ReceiveNode(getPool()) : NULL;
if (inMessageNode)
{ {
receiveNode->message = inMessageNode; ReceiveNode* receiveNode = intInMessageNode ? FB_NEW_POOL
receiveNode->statement = FB_NEW_POOL(getPool()) ExtValida (getPool()) ReceiveNode(getPool()) : NULL;
tionNode( receiveNode->message = intInMessageNode;
getPool(), inMessageNode, false, true); receiveNode->statement = FB_NEW_POOL(getPool()) MessageMo
verNode(
getPool(), intInMessageNode, extInMessageNode);
mainNode->statements.add(receiveNode); mainNode->statements.add(receiveNode);
} }
ExtFunctionNode* extFunctionNode = FB_NEW_POOL(getPool()) ExtFunc tionNode(getPool(), ExtFunctionNode* extFunctionNode = FB_NEW_POOL(getPool()) ExtFunc tionNode(getPool(),
receiveNode, udf->fun_external); extInMessageNode, extOutMessageNode, udf->fun_external);
mainNode->statements.add(extFunctionNode); mainNode->statements.add(extFunctionNode);
extFunctionNode->message = outMessageNode; extFunctionNode->message = intOutMessageNode;
extFunctionNode->statement = FB_NEW_POOL(getPool()) ExtValidation extFunctionNode->statement = FB_NEW_POOL(getPool()) MessageMoverN
Node( ode(
getPool(), outMessageNode, false, false); getPool(), extOutMessageNode, intOutMessageNode);
JrdStatement* statement = udf->getStatement(); JrdStatement* statement = udf->getStatement();
PAR_preparsed_node(tdbb, NULL, mainNode, NULL, &csb, &statement, false, 0); PAR_preparsed_node(tdbb, NULL, mainNode, NULL, &csb, &statement, false, 0);
udf->setStatement(statement); udf->setStatement(statement);
} }
catch (...) catch (...)
{ {
EngineCheckout cout(tdbb, FB_FUNCTION); EngineCheckout cout(tdbb, FB_FUNCTION);
externalFunction->dispose(); externalFunction->dispose();
throw; throw;
skipping to change at line 1155 skipping to change at line 1176
FbLocalStatus status; FbLocalStatus status;
RefPtr<IMetadataBuilder> inBuilder(REF_NO_INCR, metadata->inputParameters ->getBuilder(&status)); RefPtr<IMetadataBuilder> inBuilder(REF_NO_INCR, metadata->inputParameters ->getBuilder(&status));
status.check(); status.check();
RefPtr<IMetadataBuilder> outBuilder(REF_NO_INCR, metadata->outputParamete rs->getBuilder(&status)); RefPtr<IMetadataBuilder> outBuilder(REF_NO_INCR, metadata->outputParamete rs->getBuilder(&status));
status.check(); status.check();
IExternalProcedure* externalProcedure; IExternalProcedure* externalProcedure;
RefPtr<IMessageMetadata> extInputParameters, extOutputParameters;
{ // scope { // scope
EngineCheckout cout(tdbb, FB_FUNCTION); EngineCheckout cout(tdbb, FB_FUNCTION);
externalProcedure = attInfo->engine->makeProcedure(&status, attIn fo->context, metadata, externalProcedure = attInfo->engine->makeProcedure(&status, attIn fo->context, metadata,
inBuilder, outBuilder); inBuilder, outBuilder);
status.check(); status.check();
if (!externalProcedure) if (!externalProcedure)
{ {
status_exception::raise( status_exception::raise(
Arg::Gds(isc_eem_proc_not_returned) << Arg::Gds(isc_eem_proc_not_returned) <<
prc->getName().toString() << engine); prc->getName().toString() << engine);
} }
metadata->inputParameters = inBuilder->getMetadata(&status); extInputParameters = inBuilder->getMetadata(&status);
status.check(); status.check();
metadata->outputParameters = outBuilder->getMetadata(&status); extOutputParameters = outBuilder->getMetadata(&status);
status.check(); status.check();
} }
prc->setInputFormat(Routine::createFormat(pool, metadata->inputParameters , false)); prc->setInputFormat(Routine::createFormat(pool, metadata->inputParameters , false));
prc->setOutputFormat(Routine::createFormat(pool, metadata->outputParamete rs, true)); prc->setOutputFormat(Routine::createFormat(pool, metadata->outputParamete rs, true));
const Format* extInputFormat = Routine::createFormat(pool, extInputParame
ters, false);
const Format* extOutputFormat = Routine::createFormat(pool, extOutputPara
meters, true);
try try
{ {
prc->setExternal(FB_NEW_POOL(getPool()) Procedure(tdbb, this, att Info->engine, prc->setExternal(FB_NEW_POOL(getPool()) Procedure(tdbb, this, att Info->engine,
metadata.release(), externalProcedure, prc)); metadata.release(), externalProcedure, prc));
CompoundStmtNode* mainNode = FB_NEW_POOL(getPool()) CompoundStmtN ode(getPool()); CompoundStmtNode* mainNode = FB_NEW_POOL(getPool()) CompoundStmtN ode(getPool());
ExtMessageNode* inMessageNode = prc->getInputFields().hasData() ? IntMessageNode* intInMessageNode = prc->getInputFields().hasData(
FB_NEW_POOL(getPool()) ExtMessageNode(tdbb, getPool(), cs ) ?
b, 0, FB_NEW_POOL(getPool()) IntMessageNode(tdbb, getPool(), cs
b, 0,
prc->getInputFields(), prc->getInputFormat()) : prc->getInputFields(), prc->getInputFormat()) :
NULL; NULL;
if (inMessageNode) ExtMessageNode* extInMessageNode = NULL;
mainNode->statements.add(inMessageNode);
if (intInMessageNode)
{
mainNode->statements.add(intInMessageNode);
ExtMessageNode* outMessageNode = FB_NEW_POOL(getPool()) ExtMessag extInMessageNode = FB_NEW_POOL(getPool()) ExtMessageNode(
eNode(tdbb, getPool(), csb, 1, tdbb, getPool(), csb, 2, extInputFormat);
mainNode->statements.add(extInMessageNode);
}
IntMessageNode* intOutMessageNode = FB_NEW_POOL(getPool()) IntMes
sageNode(tdbb, getPool(), csb, 1,
prc->getOutputFields(), prc->getOutputFormat()); prc->getOutputFields(), prc->getOutputFormat());
mainNode->statements.add(outMessageNode); mainNode->statements.add(intOutMessageNode);
ExtInitOutputNode* initOutputNode = FB_NEW_POOL(getPool()) ExtIni ExtMessageNode* extOutMessageNode = FB_NEW_POOL(getPool()) ExtMes
tOutputNode( sageNode(tdbb, getPool(),
tdbb, getPool(), csb, outMessageNode); csb, 3, extOutputFormat);
mainNode->statements.add(extOutMessageNode);
// Initialize the output fields into the external message.
InitOutputNode* initOutputNode = FB_NEW_POOL(getPool()) InitOutpu
tNode(
tdbb, getPool(), csb, prc->getOutputFields(), extOutMessa
geNode);
mainNode->statements.add(initOutputNode); mainNode->statements.add(initOutputNode);
ReceiveNode* receiveNode = inMessageNode ? ReceiveNode* receiveNode = intInMessageNode ?
FB_NEW_POOL(getPool()) ReceiveNode(getPool()) : NULL; FB_NEW_POOL(getPool()) ReceiveNode(getPool()) : NULL;
if (inMessageNode) if (intInMessageNode)
{ {
receiveNode->message = inMessageNode; CompoundStmtNode* receiveSubStatement = FB_NEW_POOL(getPo
receiveNode->statement = FB_NEW_POOL(getPool()) ExtValida ol()) CompoundStmtNode(getPool());
tionNode( receiveSubStatement->statements.add(FB_NEW_POOL(getPool()
getPool(), inMessageNode, true, true); ) MessageMoverNode(
getPool(), intInMessageNode, extInMessageNode));
receiveSubStatement->statements.add(FB_NEW_POOL(getPool()
) StallNode(getPool()));
receiveNode->statement = receiveSubStatement;
receiveNode->message = intInMessageNode;
mainNode->statements.add(receiveNode); mainNode->statements.add(receiveNode);
} }
else
mainNode->statements.add(FB_NEW_POOL(getPool()) StallNode
(getPool()));
ExtProcedureNode* extProcedureNode = FB_NEW_POOL(getPool()) ExtPr ocedureNode(getPool(), ExtProcedureNode* extProcedureNode = FB_NEW_POOL(getPool()) ExtPr ocedureNode(getPool(),
receiveNode, prc->getExternal()); extInMessageNode, extOutMessageNode, intOutMessageNode, p rc->getExternal());
mainNode->statements.add(extProcedureNode); mainNode->statements.add(extProcedureNode);
extProcedureNode->message = outMessageNode;
extProcedureNode->statement = FB_NEW_POOL(getPool()) ExtValidatio
nNode(
getPool(), outMessageNode, true, false);
JrdStatement* statement = prc->getStatement(); JrdStatement* statement = prc->getStatement();
PAR_preparsed_node(tdbb, NULL, mainNode, NULL, &csb, &statement, false, 0); PAR_preparsed_node(tdbb, NULL, mainNode, NULL, &csb, &statement, false, 0);
prc->setStatement(statement); prc->setStatement(statement);
} }
catch (...) catch (...)
{ {
EngineCheckout cout(tdbb, FB_FUNCTION); EngineCheckout cout(tdbb, FB_FUNCTION);
externalProcedure->dispose(); externalProcedure->dispose();
throw; throw;
 End of changes. 80 change blocks. 
191 lines changed or deleted 245 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)