mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:00:38 +01:00
Migrate external triggers to the new message-based style.
This commit is contained in:
parent
cdc7e4cd64
commit
dc8e42e9bb
@ -662,7 +662,7 @@ create procedure gen_rows (
|
||||
FB_UDR_BEGIN_PROCEDURE(gen_rows)
|
||||
FB_UDR_EXECUTE_DYNAMIC_PROCEDURE
|
||||
{
|
||||
MessageImpl inMessage(2, inMsg);
|
||||
MessageImpl inMessage(2, in);
|
||||
ParamDesc<ISC_LONG> startDesc(inMessage);
|
||||
ParamDesc<ISC_LONG> endDesc(inMessage);
|
||||
|
||||
@ -795,7 +795,6 @@ FB_UDR_BEGIN_PROCEDURE(inc)
|
||||
FB_UDR_END_PROCEDURE
|
||||
|
||||
|
||||
//// TODO: Rework triggers.
|
||||
/***
|
||||
Sample usage:
|
||||
|
||||
@ -828,6 +827,11 @@ create trigger persons_replicate
|
||||
after insert on persons
|
||||
external name 'udrcpp_example!replicate!ds1'
|
||||
engine udr;
|
||||
|
||||
create trigger persons_replicate2
|
||||
after insert on persons
|
||||
external name 'udrcpp_example!replicate_persons!ds1'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_TRIGGER(replicate)
|
||||
FB_UDR_TRIGGER(replicate)()
|
||||
@ -863,7 +867,7 @@ FB_UDR_BEGIN_TRIGGER(replicate)
|
||||
unsigned fieldsCount = fields->getCount(status);
|
||||
ThrowError::check(status->get());
|
||||
|
||||
MessageImpl message(fieldsCount, newMsg);
|
||||
MessageImpl message(fieldsCount, newFields);
|
||||
|
||||
ISC_STATUS_ARRAY statusVector = {0};
|
||||
isc_db_handle dbHandle = getIscDbHandle(context);
|
||||
@ -905,11 +909,11 @@ FB_UDR_BEGIN_TRIGGER(replicate)
|
||||
const char* table = metadata->getTriggerTable(status);
|
||||
ThrowError::check(status->get());
|
||||
|
||||
// Skip the first exclamation point, separing the module name and entry point.
|
||||
// Skip the first exclamation point, separating the module name and entry point.
|
||||
const char* info = strchr(metadata->getEntryPoint(status), '!');
|
||||
ThrowError::check(status->get());
|
||||
|
||||
// Skip the second exclamation point, separing the entry point and the misc info (config).
|
||||
// Skip the second exclamation point, separating the entry point and the misc info (config).
|
||||
if (info)
|
||||
info = strchr(info + 1, '!');
|
||||
|
||||
@ -1046,7 +1050,7 @@ FB_UDR_BEGIN_TRIGGER(replicate)
|
||||
break;
|
||||
|
||||
case SQL_FLOAT:
|
||||
var->sqltype = SQL_DOUBLE | (var->sqltype & 1);
|
||||
var->sqltype = SQL_DOUBLE;
|
||||
var->sqllen = sizeof(double);
|
||||
// fall into
|
||||
|
||||
@ -1069,8 +1073,155 @@ FB_UDR_BEGIN_TRIGGER(replicate)
|
||||
}
|
||||
|
||||
var->sqltype |= 1;
|
||||
var->sqlind = new short;
|
||||
*reinterpret_cast<short*>(var->sqlind) = -1;
|
||||
var->sqlind = new short(-1);
|
||||
}
|
||||
|
||||
delete [] outSqlDa->sqlvar[0].sqldata;
|
||||
delete [] reinterpret_cast<char*>(outSqlDa);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
bool initialized;
|
||||
XSQLDA* inSqlDa;
|
||||
isc_stmt_handle stmtHandle;
|
||||
FB_UDR_END_TRIGGER
|
||||
|
||||
|
||||
FB_UDR_BEGIN_TRIGGER(replicate_persons)
|
||||
FB_UDR_TRIGGER(replicate_persons)()
|
||||
: initialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
~FB_UDR_TRIGGER(replicate_persons)()
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
delete [] reinterpret_cast<char*>(inSqlDa);
|
||||
|
||||
ISC_STATUS_ARRAY statusVector = {0};
|
||||
isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_drop);
|
||||
}
|
||||
|
||||
FB_UDR_EXECUTE_MESSAGE_TRIGGER(
|
||||
(FB_INTEGER, id, "ID")
|
||||
(FB_VARCHAR(60 * 4), address, "ADDRESS")
|
||||
(FB_VARCHAR(60 * 4), name, "NAME")
|
||||
(FB_BLOB, info, "INFO")
|
||||
)
|
||||
{
|
||||
inSqlDa->sqlvar[0].sqldata = reinterpret_cast<char*>(&newFields->id);
|
||||
inSqlDa->sqlvar[0].sqlind = &newFields->idNull;
|
||||
|
||||
inSqlDa->sqlvar[1].sqldata = reinterpret_cast<char*>(&newFields->name.length);
|
||||
inSqlDa->sqlvar[1].sqlind = &newFields->nameNull;
|
||||
|
||||
inSqlDa->sqlvar[2].sqldata = reinterpret_cast<char*>(&newFields->address.length);
|
||||
inSqlDa->sqlvar[2].sqlind = &newFields->addressNull;
|
||||
|
||||
inSqlDa->sqlvar[3].sqldata = reinterpret_cast<char*>(&newFields->info);
|
||||
inSqlDa->sqlvar[3].sqlind = &newFields->infoNull;
|
||||
|
||||
ISC_STATUS_ARRAY statusVector = {0};
|
||||
isc_db_handle dbHandle = getIscDbHandle(context);
|
||||
isc_tr_handle trHandle = getIscTrHandle(context);
|
||||
|
||||
ThrowError::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
|
||||
inSqlDa), statusVector);
|
||||
}
|
||||
|
||||
FB_UDR_INITIALIZE
|
||||
{
|
||||
ISC_STATUS_ARRAY statusVector = {0};
|
||||
isc_db_handle dbHandle = getIscDbHandle(context);
|
||||
isc_tr_handle trHandle = getIscTrHandle(context);
|
||||
|
||||
stmtHandle = 0;
|
||||
ThrowError::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle), statusVector);
|
||||
ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
|
||||
"select data_source from replicate_config where name = ?",
|
||||
SQL_DIALECT_CURRENT, NULL), statusVector);
|
||||
|
||||
AutoDispose<IStatus> status(master->getStatus());
|
||||
|
||||
const char* table = metadata->getTriggerTable(status);
|
||||
ThrowError::check(status->get());
|
||||
|
||||
// Skip the first exclamation point, separating the module name and entry point.
|
||||
const char* info = strchr(metadata->getEntryPoint(status), '!');
|
||||
ThrowError::check(status->get());
|
||||
|
||||
// Skip the second exclamation point, separating the entry point and the misc info (config).
|
||||
if (info)
|
||||
info = strchr(info + 1, '!');
|
||||
|
||||
if (info)
|
||||
++info;
|
||||
else
|
||||
info = "";
|
||||
|
||||
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
|
||||
inSqlDa->version = SQLDA_VERSION1;
|
||||
inSqlDa->sqln = 1;
|
||||
ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
|
||||
statusVector);
|
||||
inSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + inSqlDa->sqlvar[0].sqllen];
|
||||
strncpy(inSqlDa->sqlvar[0].sqldata + sizeof(short), info, inSqlDa->sqlvar[0].sqllen);
|
||||
*reinterpret_cast<short*>(inSqlDa->sqlvar[0].sqldata) = strlen(info);
|
||||
|
||||
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
|
||||
outSqlDa->version = SQLDA_VERSION1;
|
||||
outSqlDa->sqln = 1;
|
||||
ThrowError::check(isc_dsql_describe(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, outSqlDa),
|
||||
statusVector);
|
||||
outSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + outSqlDa->sqlvar[0].sqllen + 1];
|
||||
outSqlDa->sqlvar[0].sqldata[sizeof(short) + outSqlDa->sqlvar[0].sqllen] = '\0';
|
||||
|
||||
ThrowError::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
|
||||
inSqlDa, outSqlDa), statusVector);
|
||||
ThrowError::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector);
|
||||
|
||||
delete [] inSqlDa->sqlvar[0].sqldata;
|
||||
delete [] reinterpret_cast<char*>(inSqlDa);
|
||||
inSqlDa = NULL;
|
||||
|
||||
const IParametersMetadata* fields = metadata->getTriggerFields(status);
|
||||
ThrowError::check(status->get());
|
||||
|
||||
unsigned count = fields->getCount(status);
|
||||
ThrowError::check(status->get());
|
||||
|
||||
char buffer[65536];
|
||||
strcpy(buffer,
|
||||
"execute block (\n"
|
||||
" id type of column PERSONS.ID = ?,\n"
|
||||
" name type of column PERSONS.NAME = ?,\n"
|
||||
" address type of column PERSONS.ADDRESS = ?,\n"
|
||||
" info type of column PERSONS.INFO = ?\n"
|
||||
")"
|
||||
"as\n"
|
||||
"begin\n"
|
||||
" execute statement ('insert into persons (id, name, address, info)\n"
|
||||
" values (?, ?, ?, ?)') (:id, :name, :address, :info)\n"
|
||||
" on external data source '");
|
||||
strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short));
|
||||
strcat(buffer, "';\nend");
|
||||
|
||||
ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
|
||||
SQL_DIALECT_CURRENT, NULL), statusVector);
|
||||
|
||||
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(4))]);
|
||||
inSqlDa->version = SQLDA_VERSION1;
|
||||
inSqlDa->sqln = 4;
|
||||
ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
|
||||
statusVector);
|
||||
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
{
|
||||
XSQLVAR* var = &inSqlDa->sqlvar[i];
|
||||
var->sqltype |= 1;
|
||||
}
|
||||
|
||||
delete [] outSqlDa->sqlvar[0].sqldata;
|
||||
|
@ -1504,6 +1504,10 @@ C --
|
||||
PARAMETER (GDS__null_spb = 335545045)
|
||||
INTEGER*4 GDS__max_args_exceeded
|
||||
PARAMETER (GDS__max_args_exceeded = 335545046)
|
||||
INTEGER*4 GDS__ee_blr_mismatch_names_count
|
||||
PARAMETER (GDS__ee_blr_mismatch_names_count = 335545047)
|
||||
INTEGER*4 GDS__ee_blr_mismatch_name_not_found
|
||||
PARAMETER (GDS__ee_blr_mismatch_name_not_found = 335545048)
|
||||
INTEGER*4 GDS__gfix_db_name
|
||||
PARAMETER (GDS__gfix_db_name = 335740929)
|
||||
INTEGER*4 GDS__gfix_invalid_sw
|
||||
|
@ -759,6 +759,8 @@ const
|
||||
gds_no_providers = 335545044;
|
||||
gds_null_spb = 335545045;
|
||||
gds_max_args_exceeded = 335545046;
|
||||
gds_ee_blr_mismatch_names_count = 335545047;
|
||||
gds_ee_blr_mismatch_name_not_found = 335545048;
|
||||
gds_gfix_db_name = 335740929;
|
||||
gds_gfix_invalid_sw = 335740930;
|
||||
gds_gfix_incmp_sw = 335740932;
|
||||
|
@ -10764,11 +10764,11 @@ dsc* UdfCallNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* const srcDesc = EVL_expr(tdbb, request, *sourcePtr);
|
||||
if (srcDesc && !(request->req_flags & req_null))
|
||||
{
|
||||
*nullPtr = FALSE;
|
||||
*nullPtr = 0;
|
||||
MOV_move(tdbb, srcDesc, &argDesc);
|
||||
}
|
||||
else
|
||||
*nullPtr = TRUE;
|
||||
*nullPtr = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,12 +38,21 @@ namespace Firebird {
|
||||
class ExternalEngine;
|
||||
|
||||
|
||||
struct BlrMessage
|
||||
class IRoutineMessage : public IVersioned
|
||||
{
|
||||
const unsigned char* blr;
|
||||
unsigned int blrLength;
|
||||
unsigned int bufferLength;
|
||||
public:
|
||||
virtual void FB_CARG set(const unsigned char* blr, unsigned blrLength, unsigned bufferLength) = 0;
|
||||
};
|
||||
#define FB_ROUTINE_MESSAGE_VERSION (FB_VERSIONED_VERSION + 1)
|
||||
|
||||
|
||||
class ITriggerMessage : public IVersioned
|
||||
{
|
||||
public:
|
||||
virtual void FB_CARG set(const unsigned char* blr, unsigned blrLength, unsigned bufferLength,
|
||||
const char** names, unsigned count) = 0;
|
||||
};
|
||||
#define FB_TRIGGER_MESSAGE_VERSION (FB_VERSIONED_VERSION + 1)
|
||||
|
||||
|
||||
// Connection to current database in external engine.
|
||||
@ -193,11 +202,11 @@ public:
|
||||
// Called when engine wants to load object in the cache. Objects are disposed when
|
||||
// going out of the cache.
|
||||
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata, BlrMessage* inBlr, BlrMessage* outBlr) = 0;
|
||||
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg) = 0;
|
||||
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata, BlrMessage* inBlr, BlrMessage* outBlr) = 0;
|
||||
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg) = 0;
|
||||
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata) = 0;
|
||||
const IRoutineMetadata* metadata, ITriggerMessage* triggerMsg) = 0;
|
||||
};
|
||||
#define FB_EXTERNAL_ENGINE_VERSION (FB_PLUGIN_VERSION + 6)
|
||||
|
||||
|
@ -30,54 +30,66 @@
|
||||
#include <string.h>
|
||||
|
||||
#define FB_MESSAGE(name, fields) \
|
||||
FB_MESSAGE_I(name, FB_BOOST_PP_CAT(FB_MESSAGE_X fields, 0))
|
||||
struct name \
|
||||
{ \
|
||||
FB_MESSAGE_I(name, 2, FB_BOOST_PP_CAT(FB_MESSAGE_X fields, 0)) \
|
||||
}
|
||||
|
||||
#define FB_MESSAGE_X(x, y) ((x, y)) FB_MESSAGE_Y
|
||||
#define FB_MESSAGE_Y(x, y) ((x, y)) FB_MESSAGE_X
|
||||
#define FB_MESSAGE_X0
|
||||
#define FB_MESSAGE_Y0
|
||||
|
||||
#define FB_MESSAGE_I(name, fields) \
|
||||
#define FB_TRIGGER_MESSAGE(name, fields) \
|
||||
struct name \
|
||||
{ \
|
||||
static const unsigned char* getBlr(unsigned* length) \
|
||||
{ \
|
||||
static const unsigned char blr[] = { \
|
||||
blr_version5, \
|
||||
blr_begin, \
|
||||
blr_message, 0, \
|
||||
(2 * (FB_BOOST_PP_SEQ_SIZE(fields))) & 0xFF, \
|
||||
(2 * (FB_BOOST_PP_SEQ_SIZE(fields))) >> 8, \
|
||||
FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_BLR, _, fields) \
|
||||
blr_end, \
|
||||
blr_eoc \
|
||||
}; \
|
||||
*length = sizeof(blr); \
|
||||
return blr; \
|
||||
} \
|
||||
\
|
||||
static unsigned getSize() \
|
||||
{ \
|
||||
return (unsigned)(size_t) (&((name*) 0)->FB_BOOST_PP_CAT( \
|
||||
FB_BOOST_PP_TUPLE_ELEM(2, 1, \
|
||||
FB_BOOST_PP_SEQ_ELEM(FB_BOOST_PP_DEC(FB_BOOST_PP_SEQ_SIZE(fields)), fields)), \
|
||||
Null) - 0) + sizeof(ISC_SHORT); \
|
||||
} \
|
||||
\
|
||||
void clear() \
|
||||
{ \
|
||||
memset(this, 0, sizeof(*this)); \
|
||||
} \
|
||||
\
|
||||
FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_FIELD, _, fields) \
|
||||
FB_MESSAGE_I(name, 3, FB_BOOST_PP_CAT(FB_TRIGGER_MESSAGE_X fields, 0)) \
|
||||
FB_TRIGGER_MESSAGE_NAMES_I(name, 3, FB_BOOST_PP_CAT(FB_TRIGGER_MESSAGE_NAMES_X fields, 0)) \
|
||||
}
|
||||
|
||||
#define FB_TRIGGER_MESSAGE_X(x, y, z) ((x, y, z)) FB_TRIGGER_MESSAGE_Y
|
||||
#define FB_TRIGGER_MESSAGE_Y(x, y, z) ((x, y, z)) FB_TRIGGER_MESSAGE_X
|
||||
#define FB_TRIGGER_MESSAGE_X0
|
||||
#define FB_TRIGGER_MESSAGE_Y0
|
||||
|
||||
#define FB_MESSAGE_I(name, size, fields) \
|
||||
static const unsigned char* getBlr(unsigned* length) \
|
||||
{ \
|
||||
static const unsigned char blr[] = { \
|
||||
blr_version5, \
|
||||
blr_begin, \
|
||||
blr_message, 0, \
|
||||
(2 * (FB_BOOST_PP_SEQ_SIZE(fields))) & 0xFF, \
|
||||
(2 * (FB_BOOST_PP_SEQ_SIZE(fields))) >> 8, \
|
||||
FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_BLR, size, fields) \
|
||||
blr_end, \
|
||||
blr_eoc \
|
||||
}; \
|
||||
*length = sizeof(blr); \
|
||||
return blr; \
|
||||
} \
|
||||
\
|
||||
static unsigned getSize() \
|
||||
{ \
|
||||
return (unsigned)(size_t) (&((name*) 0)->FB_BOOST_PP_CAT( \
|
||||
FB_BOOST_PP_TUPLE_ELEM(size, 1, \
|
||||
FB_BOOST_PP_SEQ_ELEM(FB_BOOST_PP_DEC(FB_BOOST_PP_SEQ_SIZE(fields)), fields)), \
|
||||
Null) - 0) + sizeof(ISC_SHORT); \
|
||||
} \
|
||||
\
|
||||
void clear() \
|
||||
{ \
|
||||
memset(this, 0, sizeof(*this)); \
|
||||
} \
|
||||
\
|
||||
FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_FIELD, size, fields)
|
||||
|
||||
#define FB_MESSAGE_FIELD(r, _, i, xy) \
|
||||
FB_BOOST_PP_CAT(FB_TYPE_, FB_BOOST_PP_TUPLE_ELEM(2, 0, xy)) FB_BOOST_PP_TUPLE_ELEM(2, 1, xy); \
|
||||
ISC_SHORT FB_BOOST_PP_CAT(FB_BOOST_PP_TUPLE_ELEM(2, 1, xy), Null);
|
||||
FB_BOOST_PP_CAT(FB_TYPE_, FB_BOOST_PP_TUPLE_ELEM(_, 0, xy)) FB_BOOST_PP_TUPLE_ELEM(_, 1, xy); \
|
||||
ISC_SHORT FB_BOOST_PP_CAT(FB_BOOST_PP_TUPLE_ELEM(_, 1, xy), Null);
|
||||
|
||||
#define FB_MESSAGE_BLR(r, _, i, xy) \
|
||||
FB_BOOST_PP_CAT(FB_BLR_, FB_BOOST_PP_TUPLE_ELEM(2, 0, xy)), \
|
||||
FB_BOOST_PP_CAT(FB_BLR_, FB_BOOST_PP_TUPLE_ELEM(_, 0, xy)), \
|
||||
FB_BLR_FB_SMALLINT,
|
||||
|
||||
#define FB_BLR_FB_SCALED_SMALLINT(scale) blr_short, (scale)
|
||||
@ -126,6 +138,44 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#define FB_TRIGGER_MESSAGE_DESC(name, fields) \
|
||||
FB_TRIGGER_MESSAGE(name, fields); \
|
||||
struct name##Desc : public name \
|
||||
{ \
|
||||
::Firebird::FbMessage desc; \
|
||||
\
|
||||
name##Desc() \
|
||||
{ \
|
||||
desc.blr = getBlr(&desc.blrLength); \
|
||||
desc.buffer = (unsigned char*) this; \
|
||||
desc.bufferLength = getSize(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FB_TRIGGER_MESSAGE_NAMES(name, fields) \
|
||||
FB_TRIGGER_MESSAGE_NAMES_I(name, 3, FB_BOOST_PP_CAT(FB_TRIGGER_MESSAGE_NAMES_X fields, 0))
|
||||
|
||||
#define FB_TRIGGER_MESSAGE_NAMES_X(x, y, z) ((x, y, z)) FB_TRIGGER_MESSAGE_NAMES_Y
|
||||
#define FB_TRIGGER_MESSAGE_NAMES_Y(x, y, z) ((x, y, z)) FB_TRIGGER_MESSAGE_NAMES_X
|
||||
#define FB_TRIGGER_MESSAGE_NAMES_X0
|
||||
#define FB_TRIGGER_MESSAGE_NAMES_Y0
|
||||
|
||||
#define FB_TRIGGER_MESSAGE_NAMES_I(name, size, fields) \
|
||||
static const char** getNames(unsigned* count) \
|
||||
{ \
|
||||
*count = FB_BOOST_PP_SEQ_SIZE(fields); \
|
||||
\
|
||||
static const char* names[] = { \
|
||||
FB_BOOST_PP_SEQ_FOR_EACH_I(FB_TRIGGER_MESSAGE_NAME, size, fields) \
|
||||
NULL \
|
||||
}; \
|
||||
\
|
||||
return names; \
|
||||
}
|
||||
|
||||
#define FB_TRIGGER_MESSAGE_NAME(r, _, i, xy) \
|
||||
FB_BOOST_PP_TUPLE_ELEM(_, 2, xy),
|
||||
|
||||
|
||||
namespace Firebird {
|
||||
|
||||
|
@ -86,11 +86,11 @@ namespace Firebird
|
||||
|
||||
#define FB_UDR_EXECUTE__FUNCTION \
|
||||
virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
|
||||
void* inMsg, void* outMsg) \
|
||||
void* in, void* out) \
|
||||
{ \
|
||||
try \
|
||||
{ \
|
||||
internalExecute(error, context, (InMessage*) inMsg, (OutMessage*) outMsg); \
|
||||
internalExecute(error, context, (InMessage*) in, (OutMessage*) out); \
|
||||
} \
|
||||
FB_UDR__CATCH \
|
||||
} \
|
||||
@ -151,11 +151,11 @@ namespace Firebird
|
||||
|
||||
#define FB_UDR_EXECUTE__PROCEDURE \
|
||||
virtual ::Firebird::ExternalResultSet* FB_CALL open(::Firebird::Error* error, \
|
||||
::Firebird::ExternalContext* context, void* inMsg, void* outMsg) \
|
||||
::Firebird::ExternalContext* context, void* in, void* out) \
|
||||
{ \
|
||||
try \
|
||||
{ \
|
||||
return new ResultSet(error, context, this, (InMessage*) inMsg, (OutMessage*) outMsg); \
|
||||
return new ResultSet(error, context, this, (InMessage*) in, (OutMessage*) out); \
|
||||
} \
|
||||
FB_UDR__CATCH \
|
||||
\
|
||||
@ -166,9 +166,9 @@ namespace Firebird
|
||||
{ \
|
||||
public: \
|
||||
ResultSet(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
|
||||
This* procedure, InMessage* inMsg, OutMessage* outMsg) \
|
||||
This* const procedure, InMessage* const in, OutMessage* const out) \
|
||||
: ::Firebird::Udr::ResultSet<ResultSet, This, InMessage, OutMessage>( \
|
||||
context, procedure, inMsg, outMsg)
|
||||
context, procedure, in, out)
|
||||
|
||||
#define FB_UDR_FETCH_PROCEDURE \
|
||||
virtual bool FB_CALL fetch(::Firebird::Error* error) \
|
||||
@ -202,21 +202,30 @@ namespace Firebird
|
||||
};
|
||||
|
||||
#define FB_UDR_EXECUTE_DYNAMIC_TRIGGER \
|
||||
typedef void* FieldsMessage; \
|
||||
\
|
||||
FB_UDR_EXECUTE__TRIGGER
|
||||
|
||||
#define FB_UDR_EXECUTE_MESSAGE_TRIGGER(fields) \
|
||||
FB_TRIGGER_MESSAGE(FieldsMessage, \
|
||||
fields \
|
||||
); \
|
||||
\
|
||||
FB_UDR_EXECUTE__TRIGGER
|
||||
|
||||
#define FB_UDR_EXECUTE__TRIGGER \
|
||||
virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
|
||||
::Firebird::ExternalTrigger::Action action, void* oldMsg, void* newMsg) \
|
||||
::Firebird::ExternalTrigger::Action action, void* oldFields, void* newFields) \
|
||||
{ \
|
||||
try \
|
||||
{ \
|
||||
internalExecute(error, context, action, oldMsg, newMsg); \
|
||||
internalExecute(error, context, action, (FieldsMessage*) oldFields, (FieldsMessage*) newFields); \
|
||||
} \
|
||||
FB_UDR__CATCH \
|
||||
} \
|
||||
\
|
||||
void internalExecute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
|
||||
::Firebird::ExternalTrigger::Action action, void* oldMsg, void* newMsg)
|
||||
::Firebird::ExternalTrigger::Action action, FieldsMessage* oldFields, FieldsMessage* newFields)
|
||||
|
||||
|
||||
#define FB_UDR_INITIALIZE \
|
||||
@ -499,10 +508,10 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
Firebird::ExternalContext* context;
|
||||
Procedure* procedure;
|
||||
InMessage* in;
|
||||
OutMessage* out;
|
||||
Firebird::ExternalContext* const context;
|
||||
Procedure* const procedure;
|
||||
InMessage* const in;
|
||||
OutMessage* const out;
|
||||
};
|
||||
|
||||
|
||||
@ -620,10 +629,10 @@ public:
|
||||
}
|
||||
|
||||
virtual void setup(Error* /*error*/, ExternalContext* /*context*/,
|
||||
const IRoutineMetadata* /*metadata*/, BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
const IRoutineMetadata* /*metadata*/, IRoutineMessage* in, IRoutineMessage* out)
|
||||
{
|
||||
setBlr(inBlr, (typename T::InMessage*) 0);
|
||||
setBlr(outBlr, (typename T::OutMessage*) 0);
|
||||
setBlr(in, (typename T::InMessage*) 0);
|
||||
setBlr(out, (typename T::OutMessage*) 0);
|
||||
}
|
||||
|
||||
virtual ExternalFunction* FB_CALL newItem(Error* error, ExternalContext* context,
|
||||
@ -635,13 +644,14 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename MessageType> void setBlr(BlrMessage* blrMessage, MessageType*)
|
||||
template <typename MessageType> void setBlr(IRoutineMessage* blrMessage, MessageType*)
|
||||
{
|
||||
blrMessage->blr = MessageType::getBlr(&blrMessage->blrLength);
|
||||
blrMessage->bufferLength = MessageType::getSize();
|
||||
unsigned blrLength;
|
||||
const unsigned char* blr = MessageType::getBlr(&blrLength);
|
||||
blrMessage->set(blr, blrLength, MessageType::getSize());
|
||||
}
|
||||
|
||||
void setBlr(BlrMessage* blrMessage, void**)
|
||||
void setBlr(IRoutineMessage* /*blrMessage*/, void**)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -656,10 +666,10 @@ public:
|
||||
}
|
||||
|
||||
virtual void setup(Error* /*error*/, ExternalContext* /*context*/,
|
||||
const IRoutineMetadata* /*metadata*/, BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
const IRoutineMetadata* /*metadata*/, IRoutineMessage* in, IRoutineMessage* out)
|
||||
{
|
||||
setBlr(inBlr, (typename T::InMessage*) 0);
|
||||
setBlr(outBlr, (typename T::OutMessage*) 0);
|
||||
setBlr(in, (typename T::InMessage*) 0);
|
||||
setBlr(out, (typename T::OutMessage*) 0);
|
||||
}
|
||||
|
||||
virtual ExternalProcedure* FB_CALL newItem(Error* error, ExternalContext* context,
|
||||
@ -671,13 +681,14 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename MessageType> void setBlr(BlrMessage* blrMessage, MessageType*)
|
||||
template <typename MessageType> void setBlr(IRoutineMessage* blrMessage, MessageType*)
|
||||
{
|
||||
blrMessage->blr = MessageType::getBlr(&blrMessage->blrLength);
|
||||
blrMessage->bufferLength = MessageType::getSize();
|
||||
unsigned blrLength;
|
||||
const unsigned char* blr = MessageType::getBlr(&blrLength);
|
||||
blrMessage->set(blr, blrLength, MessageType::getSize());
|
||||
}
|
||||
|
||||
void setBlr(BlrMessage* blrMessage, void**)
|
||||
void setBlr(IRoutineMessage* /*blrMessage*/, void**)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -692,8 +703,9 @@ public:
|
||||
}
|
||||
|
||||
virtual void setup(Error* /*error*/, ExternalContext* /*context*/,
|
||||
const IRoutineMetadata* /*metadata*/)
|
||||
const IRoutineMetadata* /*metadata*/, ITriggerMessage* fields)
|
||||
{
|
||||
setBlr(fields, (typename T::FieldsMessage*) 0);
|
||||
}
|
||||
|
||||
virtual ExternalTrigger* FB_CALL newItem(Error* error, ExternalContext* context,
|
||||
@ -703,6 +715,20 @@ public:
|
||||
obj->initialize(error, context);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename MessageType> void setBlr(ITriggerMessage* blrMessage, MessageType*)
|
||||
{
|
||||
unsigned blrLength, namesCount;
|
||||
const unsigned char* blr = MessageType::getBlr(&blrLength);
|
||||
const char** names = MessageType::getNames(&namesCount);
|
||||
|
||||
blrMessage->set(blr, blrLength, MessageType::getSize(), names, namesCount);
|
||||
}
|
||||
|
||||
void setBlr(ITriggerMessage* /*blrMessage*/, void**)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ class FunctionFactory
|
||||
{
|
||||
public:
|
||||
virtual void setup(Error* error, ExternalContext* context, const IRoutineMetadata* metadata,
|
||||
BlrMessage* inBlr, BlrMessage* outBlr) = 0;
|
||||
IRoutineMessage* in, IRoutineMessage* out) = 0;
|
||||
virtual ExternalFunction* FB_CALL newItem(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata) = 0;
|
||||
};
|
||||
@ -49,7 +49,7 @@ class ProcedureFactory
|
||||
{
|
||||
public:
|
||||
virtual void setup(Error* error, ExternalContext* context, const IRoutineMetadata* metadata,
|
||||
BlrMessage* inBlr, BlrMessage* outBlr) = 0;
|
||||
IRoutineMessage* in, IRoutineMessage* out) = 0;
|
||||
virtual ExternalProcedure* FB_CALL newItem(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata) = 0;
|
||||
};
|
||||
@ -57,7 +57,8 @@ public:
|
||||
class TriggerFactory
|
||||
{
|
||||
public:
|
||||
virtual void setup(Error* error, ExternalContext* context, const IRoutineMetadata* metadata) = 0;
|
||||
virtual void setup(Error* error, ExternalContext* context, const IRoutineMetadata* metadata,
|
||||
ITriggerMessage* fields) = 0;
|
||||
virtual ExternalTrigger* FB_CALL newItem(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata) = 0;
|
||||
};
|
||||
|
@ -748,6 +748,8 @@ static const struct {
|
||||
{"no_providers", 335545044},
|
||||
{"null_spb", 335545045},
|
||||
{"max_args_exceeded", 335545046},
|
||||
{"ee_blr_mismatch_names_count", 335545047},
|
||||
{"ee_blr_mismatch_name_not_found", 335545048},
|
||||
{"gfix_db_name", 335740929},
|
||||
{"gfix_invalid_sw", 335740930},
|
||||
{"gfix_incmp_sw", 335740932},
|
||||
|
@ -782,6 +782,8 @@ const ISC_STATUS isc_decrypt_error = 335545043L;
|
||||
const ISC_STATUS isc_no_providers = 335545044L;
|
||||
const ISC_STATUS isc_null_spb = 335545045L;
|
||||
const ISC_STATUS isc_max_args_exceeded = 335545046L;
|
||||
const ISC_STATUS isc_ee_blr_mismatch_names_count = 335545047L;
|
||||
const ISC_STATUS isc_ee_blr_mismatch_name_not_found = 335545048L;
|
||||
const ISC_STATUS isc_gfix_db_name = 335740929L;
|
||||
const ISC_STATUS isc_gfix_invalid_sw = 335740930L;
|
||||
const ISC_STATUS isc_gfix_incmp_sw = 335740932L;
|
||||
@ -1226,7 +1228,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L;
|
||||
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
|
||||
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
|
||||
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
|
||||
const ISC_STATUS isc_err_max = 1170;
|
||||
const ISC_STATUS isc_err_max = 1172;
|
||||
|
||||
#else /* c definitions */
|
||||
|
||||
@ -1978,6 +1980,8 @@ const ISC_STATUS isc_err_max = 1170;
|
||||
#define isc_no_providers 335545044L
|
||||
#define isc_null_spb 335545045L
|
||||
#define isc_max_args_exceeded 335545046L
|
||||
#define isc_ee_blr_mismatch_names_count 335545047L
|
||||
#define isc_ee_blr_mismatch_name_not_found 335545048L
|
||||
#define isc_gfix_db_name 335740929L
|
||||
#define isc_gfix_invalid_sw 335740930L
|
||||
#define isc_gfix_incmp_sw 335740932L
|
||||
@ -2422,7 +2426,7 @@ const ISC_STATUS isc_err_max = 1170;
|
||||
#define isc_trace_switch_param_miss 337182758L
|
||||
#define isc_trace_param_act_notcompat 337182759L
|
||||
#define isc_trace_mandatory_switch_miss 337182760L
|
||||
#define isc_err_max 1170
|
||||
#define isc_err_max 1172
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -751,6 +751,8 @@ Data source : @4"}, /* eds_statement */
|
||||
{335545044, "No providers loaded"}, /* no_providers */
|
||||
{335545045, "NULL data with non-zero SPB length"}, /* null_spb */
|
||||
{335545046, "Maximum (@1) number of arguments exceeded for function @2"}, /* max_args_exceeded */
|
||||
{335545047, "External BLR message mismatch: names count = @1, blr count = @2"}, /* ee_blr_mismatch_names_count */
|
||||
{335545048, "External BLR message mismatch: name @1 not found"}, /* ee_blr_mismatch_name_not_found */
|
||||
{335740929, "data base file name (@1) already given"}, /* gfix_db_name */
|
||||
{335740930, "invalid switch @1"}, /* gfix_invalid_sw */
|
||||
{335740932, "incompatible switch combination"}, /* gfix_incmp_sw */
|
||||
|
@ -747,6 +747,8 @@ static const struct {
|
||||
{335545044, -902}, /* 724 no_providers */
|
||||
{335545045, -104}, /* 725 null_spb */
|
||||
{335545046, -833}, /* 726 max_args_exceeded */
|
||||
{335545047, -901}, /* 727 ee_blr_mismatch_names_count */
|
||||
{335545048, -901}, /* 728 ee_blr_mismatch_name_not_found */
|
||||
{335740929, -901}, /* 1 gfix_db_name */
|
||||
{335740930, -901}, /* 2 gfix_invalid_sw */
|
||||
{335740932, -901}, /* 4 gfix_incmp_sw */
|
||||
|
@ -747,6 +747,8 @@ static const struct {
|
||||
{335545044, "39000"}, // 724 no_providers
|
||||
{335545045, "42818"}, // 725 null_spb
|
||||
{335545046, "42000"}, // 726 max_args_exceeded
|
||||
{335545047, "42000"}, // 727 ee_blr_mismatch_names_count
|
||||
{335545048, "42000"}, // 728 ee_blr_mismatch_name_not_found
|
||||
{335740929, "00000"}, // 1 gfix_db_name
|
||||
{335740930, "00000"}, // 2 gfix_invalid_sw
|
||||
{335740932, "00000"}, // 4 gfix_incmp_sw
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "../jrd/intl_proto.h"
|
||||
#include "../jrd/met_proto.h"
|
||||
#include "../jrd/mov_proto.h"
|
||||
#include "../jrd/par_proto.h"
|
||||
#include "../jrd/thread_proto.h"
|
||||
#include "../jrd/Function.h"
|
||||
#include "../common/isc_proto.h"
|
||||
@ -408,16 +409,140 @@ bool ExtEngineManager::ResultSet::fetch(thread_db* tdbb)
|
||||
//---------------------
|
||||
|
||||
|
||||
ExtEngineManager::Trigger::Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||
ExternalEngine* aEngine, RoutineMetadata* aMetadata, ExternalTrigger* aTrigger,
|
||||
const Jrd::Trigger* aTrg)
|
||||
ExtEngineManager::Trigger::Trigger(thread_db* tdbb, MemoryPool& pool, ExtEngineManager* aExtManager,
|
||||
ExternalEngine* aEngine, RoutineMetadata* aMetadata, TriggerMessage& fieldsMsg,
|
||||
ExternalTrigger* aTrigger, const Jrd::Trigger* aTrg)
|
||||
: extManager(aExtManager),
|
||||
engine(aEngine),
|
||||
metadata(aMetadata),
|
||||
trigger(aTrigger),
|
||||
trg(aTrg),
|
||||
fieldsPos(pool),
|
||||
database(tdbb->getDatabase())
|
||||
{
|
||||
dsc shortDesc;
|
||||
shortDesc.makeShort(0);
|
||||
|
||||
jrd_rel* relation = trg->relation;
|
||||
|
||||
if (relation)
|
||||
{
|
||||
bool blrPresent = fieldsMsg.blr.hasData();
|
||||
Format* relFormat = relation->rel_current_format;
|
||||
GenericMap<Left<MetaName, USHORT> > fieldsMap;
|
||||
|
||||
for (size_t i = 0; i < relation->rel_fields->count(); ++i)
|
||||
{
|
||||
jrd_fld* field = (*relation->rel_fields)[i];
|
||||
if (!field)
|
||||
continue;
|
||||
|
||||
fieldsMap.put(field->fld_name, (USHORT) i);
|
||||
}
|
||||
|
||||
BlrReader reader(fieldsMsg.blr.begin(), fieldsMsg.blr.getCount());
|
||||
ULONG offset = 0;
|
||||
USHORT maxAlignment = 0;
|
||||
USHORT count;
|
||||
|
||||
if (blrPresent)
|
||||
{
|
||||
reader.checkByte(blr_version5);
|
||||
reader.checkByte(blr_begin);
|
||||
reader.checkByte(blr_message);
|
||||
reader.getByte(); // message number: ignore it
|
||||
count = reader.getWord();
|
||||
|
||||
if (count != 2 * fieldsMsg.names.getCount())
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_ee_blr_mismatch_names_count) <<
|
||||
Arg::Num(fieldsMsg.names.getCount()) <<
|
||||
Arg::Num(count));
|
||||
}
|
||||
}
|
||||
else
|
||||
count = fieldsMap.count() * 2;
|
||||
|
||||
format.reset(Format::newFormat(pool, count));
|
||||
|
||||
for (unsigned i = 0; i < count / 2; ++i)
|
||||
{
|
||||
dsc* desc = &format->fmt_desc[i * 2];
|
||||
|
||||
if (blrPresent)
|
||||
{
|
||||
USHORT pos;
|
||||
|
||||
if (!fieldsMap.get(fieldsMsg.names[i], pos))
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_ee_blr_mismatch_name_not_found) <<
|
||||
Arg::Str(fieldsMsg.names[i]));
|
||||
}
|
||||
|
||||
fieldsPos.add(pos);
|
||||
PAR_datatype(tdbb, reader, desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldsPos.add(i);
|
||||
*desc = relFormat->fmt_desc[i];
|
||||
}
|
||||
|
||||
USHORT align = type_alignments[desc->dsc_dtype];
|
||||
maxAlignment = MAX(maxAlignment, align);
|
||||
|
||||
offset = FB_ALIGN(offset, align);
|
||||
desc->dsc_address = (UCHAR*) offset;
|
||||
offset += desc->dsc_length;
|
||||
|
||||
const dsc* fieldDesc = &relFormat->fmt_desc[i];
|
||||
|
||||
if (desc->isText() && desc->getCharSet() == CS_NONE)
|
||||
desc->setTextType(fieldDesc->getTextType());
|
||||
desc->setNullable(fieldDesc->isNullable());
|
||||
|
||||
++desc;
|
||||
|
||||
if (blrPresent)
|
||||
{
|
||||
PAR_datatype(tdbb, reader, desc);
|
||||
|
||||
if (!DSC_EQUIV(desc, &shortDesc, false))
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_ee_blr_mismatch_null) <<
|
||||
Arg::Num(i * 2 + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
*desc = shortDesc;
|
||||
|
||||
align = type_alignments[desc->dsc_dtype];
|
||||
maxAlignment = MAX(maxAlignment, align);
|
||||
|
||||
offset = FB_ALIGN(offset, align);
|
||||
desc->dsc_address = (UCHAR*) offset;
|
||||
offset += desc->dsc_length;
|
||||
}
|
||||
|
||||
if (blrPresent)
|
||||
{
|
||||
reader.checkByte(blr_end);
|
||||
reader.checkByte(blr_eoc);
|
||||
|
||||
if (offset != fieldsMsg.bufferLength)
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_ee_blr_mismatch_length) <<
|
||||
Arg::Num(fieldsMsg.bufferLength) <<
|
||||
Arg::Num(offset));
|
||||
}
|
||||
}
|
||||
|
||||
format->fmt_length = FB_ALIGN(offset, maxAlignment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -444,85 +569,73 @@ void ExtEngineManager::Trigger::execute(thread_db* tdbb, ExternalTrigger::Action
|
||||
if (newRpb)
|
||||
setValues(tdbb, newMsg, newRpb);
|
||||
|
||||
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
|
||||
{ // scope
|
||||
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
|
||||
|
||||
trigger->execute(RaiseError(), attInfo->context, action,
|
||||
(oldRpb ? oldMsg.begin() : NULL), (newRpb ? newMsg.begin() : NULL));
|
||||
trigger->execute(RaiseError(), attInfo->context, action,
|
||||
(oldRpb ? oldMsg.begin() : NULL), (newRpb ? newMsg.begin() : NULL));
|
||||
}
|
||||
|
||||
if (newRpb)
|
||||
{
|
||||
// Move data back from the message to the record.
|
||||
|
||||
Record* record = newRpb->rpb_record;
|
||||
const Format* format = record->rec_format;
|
||||
const UCHAR* msg = newMsg.begin();
|
||||
unsigned pos = 0;
|
||||
UCHAR* p = newMsg.begin();
|
||||
|
||||
for (unsigned i = 0; i < format->fmt_count; ++i)
|
||||
for (unsigned i = 0; i < format->fmt_count / 2; ++i)
|
||||
{
|
||||
if (format->fmt_desc[i].dsc_dtype == dtype_unknown)
|
||||
continue;
|
||||
USHORT fieldPos = fieldsPos[i];
|
||||
|
||||
dsc desc;
|
||||
bool readonly = !EVL_field(newRpb->rpb_relation, record, i, &desc) &&
|
||||
desc.dsc_address && !(desc.dsc_flags & DSC_null);
|
||||
|
||||
unsigned align = type_alignments[desc.dsc_dtype];
|
||||
if (align)
|
||||
pos = FB_ALIGN(pos, align);
|
||||
|
||||
const unsigned dataPos = pos;
|
||||
pos += desc.dsc_length;
|
||||
|
||||
align = type_alignments[dtype_short];
|
||||
if (align)
|
||||
pos = FB_ALIGN(pos, align);
|
||||
dsc target;
|
||||
bool readonly = !EVL_field(newRpb->rpb_relation, record, fieldPos, &target) &&
|
||||
target.dsc_address && !(target.dsc_flags & DSC_null);
|
||||
|
||||
if (!readonly)
|
||||
{
|
||||
if (*(USHORT*) &msg[pos])
|
||||
SET_NULL(record, i);
|
||||
else
|
||||
{
|
||||
memcpy(desc.dsc_address, msg + dataPos, desc.dsc_length);
|
||||
CLEAR_NULL(record, i);
|
||||
}
|
||||
}
|
||||
SSHORT* nullSource = (SSHORT*) (p + (IPTR) format->fmt_desc[i * 2 + 1].dsc_address);
|
||||
|
||||
pos += sizeof(USHORT);
|
||||
if (*nullSource == 0)
|
||||
{
|
||||
dsc source = format->fmt_desc[i * 2];
|
||||
source.dsc_address += (IPTR) p;
|
||||
MOV_move(tdbb, &source, &target);
|
||||
CLEAR_NULL(record, fieldPos);
|
||||
}
|
||||
else
|
||||
SET_NULL(record, fieldPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ExtEngineManager::Trigger::setValues(thread_db* /*tdbb*/, Array<UCHAR>& msgBuffer,
|
||||
void ExtEngineManager::Trigger::setValues(thread_db* tdbb, Array<UCHAR>& msgBuffer,
|
||||
record_param* rpb) const
|
||||
{
|
||||
if (!rpb || !rpb->rpb_record)
|
||||
return;
|
||||
|
||||
Record* record = rpb->rpb_record;
|
||||
const Format* format = record->rec_format;
|
||||
UCHAR* p = msgBuffer.getBuffer(format->fmt_length);
|
||||
///memset(p, 0, format->fmt_length);
|
||||
|
||||
for (unsigned i = 0; i < format->fmt_count; ++i)
|
||||
for (unsigned i = 0; i < format->fmt_count / 2; ++i)
|
||||
{
|
||||
if (format->fmt_desc[i].dsc_dtype == dtype_unknown)
|
||||
continue;
|
||||
USHORT fieldPos = fieldsPos[i];
|
||||
|
||||
dsc desc;
|
||||
EVL_field(rpb->rpb_relation, record, i, &desc);
|
||||
dsc source;
|
||||
EVL_field(rpb->rpb_relation, rpb->rpb_record, fieldPos, &source);
|
||||
// CVC: I'm not sure why it's not important to check EVL_field's result.
|
||||
|
||||
unsigned align = type_alignments[desc.dsc_dtype];
|
||||
if (align)
|
||||
msgBuffer.resize(FB_ALIGN(msgBuffer.getCount(), align));
|
||||
SSHORT* nullTarget = (SSHORT*) (p + (IPTR) format->fmt_desc[i * 2 + 1].dsc_address);
|
||||
*nullTarget = (source.dsc_flags & DSC_null) != 0 ? -1 : 0;
|
||||
|
||||
msgBuffer.add(desc.dsc_address, desc.dsc_length);
|
||||
|
||||
align = type_alignments[dtype_short];
|
||||
if (align)
|
||||
msgBuffer.resize(FB_ALIGN(msgBuffer.getCount(), align));
|
||||
|
||||
USHORT nullFlag = (desc.dsc_flags & DSC_null) != 0;
|
||||
msgBuffer.add((UCHAR*) &nullFlag, sizeof(nullFlag));
|
||||
if (*nullTarget == 0)
|
||||
{
|
||||
dsc target = format->fmt_desc[i * 2];
|
||||
target.dsc_address += (IPTR) p;
|
||||
MOV_move(tdbb, &source, &target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -598,7 +711,7 @@ void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* attachment)
|
||||
|
||||
ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, const Jrd::Function* udf,
|
||||
const MetaName& engine, const string& entryPoint, const string& body,
|
||||
BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
RoutineMessage* inMsg, RoutineMessage* outMsg)
|
||||
{
|
||||
string entryPointTrimmed = entryPoint;
|
||||
entryPointTrimmed.trim();
|
||||
@ -657,7 +770,7 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
|
||||
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
|
||||
|
||||
externalFunction = attInfo->engine->makeFunction(RaiseError(), attInfo->context, metadata,
|
||||
inBlr, outBlr);
|
||||
inMsg, outMsg);
|
||||
|
||||
if (!externalFunction)
|
||||
{
|
||||
@ -683,7 +796,7 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
|
||||
|
||||
ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, const jrd_prc* prc,
|
||||
const MetaName& engine, const string& entryPoint, const string& body,
|
||||
BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
RoutineMessage* inMsg, RoutineMessage* outMsg)
|
||||
{
|
||||
string entryPointTrimmed = entryPoint;
|
||||
entryPointTrimmed.trim();
|
||||
@ -736,7 +849,7 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
|
||||
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
|
||||
|
||||
externalProcedure = attInfo->engine->makeProcedure(RaiseError(), attInfo->context, metadata,
|
||||
inBlr, outBlr);
|
||||
inMsg, outMsg);
|
||||
|
||||
if (!externalProcedure)
|
||||
{
|
||||
@ -761,7 +874,8 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
|
||||
|
||||
|
||||
ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const Jrd::Trigger* trg,
|
||||
const MetaName& engine, const string& entryPoint, const string& body, ExternalTrigger::Type type)
|
||||
const MetaName& engine, const string& entryPoint, const string& body,
|
||||
ExternalTrigger::Type type)
|
||||
{
|
||||
string entryPointTrimmed = entryPoint;
|
||||
entryPointTrimmed.trim();
|
||||
@ -807,12 +921,14 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
|
||||
}
|
||||
}
|
||||
|
||||
TriggerMessage fieldsMsg(pool);
|
||||
ExternalTrigger* externalTrigger;
|
||||
|
||||
{ // scope
|
||||
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
|
||||
|
||||
externalTrigger = attInfo->engine->makeTrigger(RaiseError(), attInfo->context, metadata);
|
||||
externalTrigger = attInfo->engine->makeTrigger(RaiseError(), attInfo->context, metadata,
|
||||
&fieldsMsg);
|
||||
|
||||
if (!externalTrigger)
|
||||
{
|
||||
@ -823,8 +939,8 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
|
||||
|
||||
try
|
||||
{
|
||||
return FB_NEW(getPool()) Trigger(tdbb, this, attInfo->engine, metadata.release(),
|
||||
externalTrigger, trg);
|
||||
return FB_NEW(getPool()) Trigger(tdbb, pool, this, attInfo->engine, metadata.release(),
|
||||
fieldsMsg, externalTrigger, trg);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -52,6 +52,58 @@ struct impure_value;
|
||||
struct record_param;
|
||||
|
||||
|
||||
class RoutineMessage :
|
||||
public Firebird::VersionedIface<Firebird::IRoutineMessage, FB_ROUTINE_MESSAGE_VERSION>,
|
||||
public Firebird::PermanentStorage
|
||||
{
|
||||
public:
|
||||
explicit RoutineMessage(MemoryPool& pool)
|
||||
: PermanentStorage(pool),
|
||||
blr(pool),
|
||||
bufferLength(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void FB_CARG set(const unsigned char* aBlr, unsigned aBlrLength, unsigned aBufferLength)
|
||||
{
|
||||
blr.assign(aBlr, aBlrLength);
|
||||
bufferLength = aBufferLength;
|
||||
}
|
||||
|
||||
public:
|
||||
Firebird::Array<UCHAR> blr;
|
||||
unsigned bufferLength;
|
||||
};
|
||||
|
||||
class TriggerMessage :
|
||||
public Firebird::VersionedIface<Firebird::ITriggerMessage, FB_TRIGGER_MESSAGE_VERSION>,
|
||||
public Firebird::PermanentStorage
|
||||
{
|
||||
public:
|
||||
explicit TriggerMessage(MemoryPool& pool)
|
||||
: PermanentStorage(pool),
|
||||
names(pool),
|
||||
blr(pool),
|
||||
bufferLength(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void FB_CARG set(const unsigned char* aBlr, unsigned aBlrLength, unsigned aBufferLength,
|
||||
const char** aNames, unsigned aCount)
|
||||
{
|
||||
blr.assign(aBlr, aBlrLength);
|
||||
bufferLength = aBufferLength;
|
||||
|
||||
for (unsigned i = 0; i < aCount; ++i)
|
||||
names.add(aNames[i]);
|
||||
}
|
||||
|
||||
public:
|
||||
Firebird::ObjectsArray<Firebird::string> names;
|
||||
Firebird::Array<UCHAR> blr;
|
||||
unsigned bufferLength;
|
||||
};
|
||||
|
||||
class ExtEngineManager : public Firebird::PermanentStorage
|
||||
{
|
||||
private:
|
||||
@ -59,8 +111,9 @@ private:
|
||||
template <typename T> class ContextManager;
|
||||
class TransactionImpl;
|
||||
|
||||
class RoutineMetadata : public Firebird::VersionedIface<Firebird::IRoutineMetadata, FB_ROUTINE_METADATA_VERSION>,
|
||||
public Firebird::PermanentStorage
|
||||
class RoutineMetadata :
|
||||
public Firebird::VersionedIface<Firebird::IRoutineMetadata, FB_ROUTINE_METADATA_VERSION>,
|
||||
public Firebird::PermanentStorage
|
||||
{
|
||||
public:
|
||||
explicit RoutineMetadata(MemoryPool& pool)
|
||||
@ -264,11 +317,9 @@ public:
|
||||
class Trigger
|
||||
{
|
||||
public:
|
||||
Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||
Firebird::ExternalEngine* aEngine,
|
||||
RoutineMetadata* aMetadata,
|
||||
Firebird::ExternalTrigger* aTrigger,
|
||||
const Jrd::Trigger* aTrg);
|
||||
Trigger(thread_db* tdbb, MemoryPool& pool, ExtEngineManager* aExtManager,
|
||||
Firebird::ExternalEngine* aEngine, RoutineMetadata* aMetadata, TriggerMessage& fieldsMsg,
|
||||
Firebird::ExternalTrigger* aTrigger, const Jrd::Trigger* aTrg);
|
||||
~Trigger();
|
||||
|
||||
void execute(thread_db* tdbb, Firebird::ExternalTrigger::Action action,
|
||||
@ -280,8 +331,10 @@ public:
|
||||
ExtEngineManager* extManager;
|
||||
Firebird::ExternalEngine* engine;
|
||||
Firebird::AutoPtr<RoutineMetadata> metadata;
|
||||
Firebird::AutoPtr<Format> format;
|
||||
Firebird::ExternalTrigger* trigger;
|
||||
const Jrd::Trigger* trg;
|
||||
Firebird::Array<USHORT> fieldsPos;
|
||||
Database* database;
|
||||
};
|
||||
|
||||
@ -303,10 +356,10 @@ public:
|
||||
|
||||
Function* makeFunction(thread_db* tdbb, const Jrd::Function* udf,
|
||||
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
|
||||
const Firebird::string& body, Firebird::BlrMessage* inBlr, Firebird::BlrMessage* outBlr);
|
||||
const Firebird::string& body, RoutineMessage* inMsg, RoutineMessage* outMsg);
|
||||
Procedure* makeProcedure(thread_db* tdbb, const jrd_prc* prc,
|
||||
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
|
||||
const Firebird::string& body, Firebird::BlrMessage* inBlr, Firebird::BlrMessage* outBlr);
|
||||
const Firebird::string& body, RoutineMessage* inMsg, RoutineMessage* outMsg);
|
||||
Trigger* makeTrigger(thread_db* tdbb, const Jrd::Trigger* trg,
|
||||
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
|
||||
const Firebird::string& body, Firebird::ExternalTrigger::Type type);
|
||||
|
@ -374,15 +374,8 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
function->fun_external = NULL;
|
||||
function->setStatement(NULL);
|
||||
|
||||
BlrMessage inBlr;
|
||||
inBlr.blr = NULL;
|
||||
inBlr.blrLength = 0;
|
||||
inBlr.bufferLength = 0;
|
||||
|
||||
BlrMessage outBlr;
|
||||
outBlr.blr = NULL;
|
||||
outBlr.blrLength = 0;
|
||||
outBlr.bufferLength = 0;
|
||||
RoutineMessage inMsg(*attachment->att_pool);
|
||||
RoutineMessage outMsg(*attachment->att_pool);
|
||||
|
||||
if (!X.RDB$ENGINE_NAME.NULL || !X.RDB$FUNCTION_BLR.NULL)
|
||||
{
|
||||
@ -403,7 +396,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
function->fun_external =
|
||||
dbb->dbb_extManager.makeFunction(tdbb, function, X.RDB$ENGINE_NAME,
|
||||
(X.RDB$ENTRYPOINT.NULL ? "" : X.RDB$ENTRYPOINT), (char*) body.begin(),
|
||||
&inBlr, &outBlr);
|
||||
&inMsg, &outMsg);
|
||||
|
||||
if (!function->fun_external)
|
||||
function->setDefined(false);
|
||||
@ -422,7 +415,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
|
||||
try
|
||||
{
|
||||
MET_parse_routine_blr(tdbb, function, &X.RDB$FUNCTION_BLR, csb,
|
||||
!X.RDB$ENGINE_NAME.NULL, inBlr, outBlr);
|
||||
!X.RDB$ENGINE_NAME.NULL, inMsg, outMsg);
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
|
@ -5651,7 +5651,7 @@ static bool modify_function(thread_db* tdbb, SSHORT phase, DeferredWork* work, j
|
||||
|
||||
try
|
||||
{
|
||||
BlrMessage dummy;
|
||||
RoutineMessage dummy(*csb_pool);
|
||||
MET_parse_routine_blr(tdbb, function, &FUN.RDB$FUNCTION_BLR, csb, false,
|
||||
dummy, dummy);
|
||||
|
||||
|
@ -642,10 +642,9 @@ void Trigger::compile(thread_db* tdbb)
|
||||
return;
|
||||
|
||||
extTrigger = dbb->dbb_extManager.makeTrigger(tdbb, this, engine, entryPoint, extBody.c_str(),
|
||||
(relation ? (type & 1 ?
|
||||
Firebird::ExternalTrigger::TYPE_BEFORE :
|
||||
Firebird::ExternalTrigger::TYPE_AFTER) :
|
||||
Firebird::ExternalTrigger::TYPE_DATABASE));
|
||||
(relation ?
|
||||
(type & 1 ? ExternalTrigger::TYPE_BEFORE : ExternalTrigger::TYPE_AFTER) :
|
||||
Firebird::ExternalTrigger::TYPE_DATABASE));
|
||||
}
|
||||
|
||||
void Trigger::release(thread_db* tdbb)
|
||||
|
@ -2975,15 +2975,8 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
}
|
||||
END_FOR
|
||||
|
||||
BlrMessage inBlr;
|
||||
inBlr.blr = NULL;
|
||||
inBlr.blrLength = 0;
|
||||
inBlr.bufferLength = 0;
|
||||
|
||||
BlrMessage outBlr;
|
||||
outBlr.blr = NULL;
|
||||
outBlr.blrLength = 0;
|
||||
outBlr.bufferLength = 0;
|
||||
RoutineMessage inMsg(*tdbb->getDefaultPool());
|
||||
RoutineMessage outMsg(*tdbb->getDefaultPool());
|
||||
|
||||
const bool external = !P.RDB$ENGINE_NAME.NULL; // ODS_12_0
|
||||
|
||||
@ -3004,7 +2997,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
|
||||
procedure->setExternal(dbb->dbb_extManager.makeProcedure(
|
||||
tdbb, procedure, P.RDB$ENGINE_NAME,
|
||||
(P.RDB$ENTRYPOINT.NULL ? "" : P.RDB$ENTRYPOINT), body.begin(), &inBlr, &outBlr));
|
||||
(P.RDB$ENTRYPOINT.NULL ? "" : P.RDB$ENTRYPOINT), body.begin(), &inMsg, &outMsg));
|
||||
}
|
||||
|
||||
Array<NestConst<Parameter> >& paramArray = procedure->getOutputFields();
|
||||
@ -3055,7 +3048,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, int id, bool noscan, USHORT flags)
|
||||
{
|
||||
MET_parse_routine_blr(tdbb, procedure,
|
||||
(P.RDB$PROCEDURE_BLR.NULL ? NULL : &P.RDB$PROCEDURE_BLR), csb, external,
|
||||
inBlr, outBlr);
|
||||
inMsg, outMsg);
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
@ -4304,7 +4297,7 @@ static void parse_field_validation_blr(thread_db* tdbb, bid* blob_id, const Meta
|
||||
|
||||
// Generate BLR message for external procedures
|
||||
static bool gen_ext_message(thread_db* tdbb, CompilerScratch* csb, UCharBuffer& blr, UCHAR message,
|
||||
UCHAR message2, const Array<NestConst<Parameter> >& parameters, const BlrMessage& extBlr,
|
||||
UCHAR message2, const Array<NestConst<Parameter> >& parameters, const RoutineMessage& extMsg,
|
||||
UCharBuffer& appendBlr)
|
||||
{
|
||||
const size_t prevAppendBlrSize = appendBlr.getCount();
|
||||
@ -4315,9 +4308,9 @@ static bool gen_ext_message(thread_db* tdbb, CompilerScratch* csb, UCharBuffer&
|
||||
dsc shortDesc;
|
||||
shortDesc.makeShort(0);
|
||||
|
||||
if (extBlr.blr)
|
||||
if (extMsg.blr.hasData())
|
||||
{
|
||||
BlrReader reader(extBlr.blr, extBlr.blrLength);
|
||||
BlrReader reader(extMsg.blr.begin(), extMsg.blr.getCount());
|
||||
|
||||
reader.checkByte(blr_version5);
|
||||
reader.checkByte(blr_begin);
|
||||
@ -4372,11 +4365,11 @@ static bool gen_ext_message(thread_db* tdbb, CompilerScratch* csb, UCharBuffer&
|
||||
reader.checkByte(blr_end);
|
||||
reader.checkByte(blr_eoc);
|
||||
|
||||
if (offset != extBlr.bufferLength)
|
||||
if (offset != extMsg.bufferLength)
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_ee_blr_mismatch_length) <<
|
||||
Arg::Num(extBlr.bufferLength) <<
|
||||
Arg::Num(extMsg.bufferLength) <<
|
||||
Arg::Num(offset));
|
||||
}
|
||||
}
|
||||
@ -4458,8 +4451,8 @@ static bool gen_ext_message(thread_db* tdbb, CompilerScratch* csb, UCharBuffer&
|
||||
|
||||
|
||||
// Parse routine BLR.
|
||||
void MET_parse_routine_blr(thread_db* tdbb, Routine* routine, bid* blob_id,
|
||||
CompilerScratch* csb, bool external, const BlrMessage& extInBlr, const BlrMessage& extOutBlr)
|
||||
void MET_parse_routine_blr(thread_db* tdbb, Routine* routine, bid* blob_id, CompilerScratch* csb,
|
||||
bool external, const RoutineMessage& extInMsg, const RoutineMessage& extOutMsg)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
@ -4477,9 +4470,9 @@ void MET_parse_routine_blr(thread_db* tdbb, Routine* routine, bid* blob_id,
|
||||
UCharBuffer appendBlr;
|
||||
|
||||
bool genExtIn = gen_ext_message(tdbb, csb, tmp, e_extrout_input_message,
|
||||
e_extrout_input_message2, routine->getInputFields(), extInBlr, appendBlr);
|
||||
e_extrout_input_message2, routine->getInputFields(), extInMsg, appendBlr);
|
||||
bool genExtOut = gen_ext_message(tdbb, csb, tmp, e_extrout_output_message,
|
||||
e_extrout_output_message2, routine->getOutputFields(), extOutBlr, appendBlr);
|
||||
e_extrout_output_message2, routine->getOutputFields(), extOutMsg, appendBlr);
|
||||
|
||||
dsc shortDesc;
|
||||
shortDesc.makeShort(0);
|
||||
|
@ -104,8 +104,8 @@ void MET_par_messages(Jrd::thread_db*, const UCHAR* const, ULONG,
|
||||
Jrd::DmlNode* MET_parse_blob(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::bid*, Jrd::CompilerScratch**,
|
||||
Jrd::JrdStatement**, bool, bool);
|
||||
void MET_parse_routine_blr(Jrd::thread_db*, Jrd::Routine*, Jrd::bid*, Jrd::CompilerScratch*,
|
||||
bool, const Firebird::BlrMessage& extInBlr,
|
||||
const Firebird::BlrMessage& extOutBlr);
|
||||
bool, const Jrd::RoutineMessage& extInMsg,
|
||||
const Jrd::RoutineMessage& extOutMsg);
|
||||
void MET_parse_sys_trigger(Jrd::thread_db*, Jrd::jrd_rel*);
|
||||
void MET_post_existence(Jrd::thread_db*, Jrd::jrd_rel*);
|
||||
void MET_prepare(Jrd::thread_db*, Jrd::jrd_tra*, USHORT, const UCHAR*);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* MAX_NUMBER is the next number to be used, always one more than the highest message number. */
|
||||
set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?);
|
||||
--
|
||||
('2012-09-20 12:25:00', 'JRD', 0, 727)
|
||||
('2013-01-27 13:00:00', 'JRD', 0, 729)
|
||||
('2012-01-23 20:10:30', 'QLI', 1, 532)
|
||||
('2009-07-16 05:26:11', 'GFIX', 3, 121)
|
||||
('1996-11-07 13:39:40', 'GPRE', 4, 1)
|
||||
|
@ -834,6 +834,8 @@ Data source : @4', NULL, NULL)
|
||||
('no_providers', NULL, 'why.cpp', NULL, 0, 724, NULL, 'No providers loaded', NULL, NULL);
|
||||
('null_spb', NULL, 'why.cpp', NULL, 0, 725, NULL, 'NULL data with non-zero SPB length', NULL, NULL);
|
||||
('max_args_exceeded', NULL, 'ExprNodes.cpp', NULL, 0, 726, NULL, 'Maximum (@1) number of arguments exceeded for function @2', NULL, NULL)
|
||||
('ee_blr_mismatch_names_count', NULL, 'ExtEngineManager.cpp', NULL, 0, 727, NULL, 'External BLR message mismatch: names count = @1, blr count = @2', NULL, NULL)
|
||||
('ee_blr_mismatch_name_not_found', NULL, 'ExtEngineManager.cpp', NULL, 0, 728, NULL, 'External BLR message mismatch: name @1 not found', NULL, NULL)
|
||||
-- QLI
|
||||
(NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL);
|
||||
(NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL);
|
||||
|
@ -733,6 +733,8 @@ set bulk_insert INSERT INTO SYSTEM_ERRORS (SQL_CODE, SQL_CLASS, SQL_SUBCLASS, FA
|
||||
(-902, '39', '000', 0, 724, 'no_providers', NULL, NULL)
|
||||
(-104, '42', '818', 0, 725, 'null_spb', NULL, NULL)
|
||||
(-833, '42', '000', 0, 726, 'max_args_exceeded', NULL, NULL)
|
||||
(-901, '42', '000', 0, 727, 'ee_blr_mismatch_names_count', NULL, NULL)
|
||||
(-901, '42', '000', 0, 728, 'ee_blr_mismatch_name_not_found', NULL, NULL)
|
||||
-- GFIX
|
||||
(-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL)
|
||||
(-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL)
|
||||
|
@ -153,11 +153,11 @@ public:
|
||||
virtual void FB_CALL openAttachment(Error* error, ExternalContext* context);
|
||||
virtual void FB_CALL closeAttachment(Error* error, ExternalContext* context);
|
||||
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata, BlrMessage* inBlr, BlrMessage* outBlr);
|
||||
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg);
|
||||
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata, BlrMessage* inBlr, BlrMessage* outBlr);
|
||||
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg);
|
||||
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata);
|
||||
const IRoutineMetadata* metadata, ITriggerMessage* fieldsMsg);
|
||||
|
||||
public:
|
||||
virtual void FB_CALL dispose(Error* error);
|
||||
@ -207,7 +207,7 @@ class SharedFunction : public ExternalFunction
|
||||
{
|
||||
public:
|
||||
SharedFunction(Error* error, Engine* aEngine, ExternalContext* context,
|
||||
const IRoutineMetadata* aMetadata, BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
const IRoutineMetadata* aMetadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
|
||||
: engine(aEngine),
|
||||
metadata(aMetadata),
|
||||
moduleName(*getDefaultMemoryPool()),
|
||||
@ -217,7 +217,7 @@ public:
|
||||
{
|
||||
engine->loadModule(metadata, &moduleName, &entryPoint);
|
||||
FunctionNode* node = engine->findNode<FunctionNode>(registeredFunctions, moduleName, entryPoint);
|
||||
node->factory->setup(error, context, metadata, inBlr, outBlr);
|
||||
node->factory->setup(error, context, metadata, inMsg, outMsg);
|
||||
}
|
||||
|
||||
virtual ~SharedFunction()
|
||||
@ -275,7 +275,7 @@ class SharedProcedure : public ExternalProcedure
|
||||
{
|
||||
public:
|
||||
SharedProcedure(Error* error, Engine* aEngine, ExternalContext* context,
|
||||
const IRoutineMetadata* aMetadata, BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
const IRoutineMetadata* aMetadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
|
||||
: engine(aEngine),
|
||||
metadata(aMetadata),
|
||||
moduleName(*getDefaultMemoryPool()),
|
||||
@ -285,7 +285,7 @@ public:
|
||||
{
|
||||
engine->loadModule(metadata, &moduleName, &entryPoint);
|
||||
ProcedureNode* node = engine->findNode<ProcedureNode>(registeredProcedures, moduleName, entryPoint);
|
||||
node->factory->setup(error, context, metadata, inBlr, outBlr);
|
||||
node->factory->setup(error, context, metadata, inMsg, outMsg);
|
||||
}
|
||||
|
||||
virtual ~SharedProcedure()
|
||||
@ -351,7 +351,7 @@ class SharedTrigger : public ExternalTrigger
|
||||
{
|
||||
public:
|
||||
SharedTrigger(Error* error, Engine* aEngine, ExternalContext* context,
|
||||
const IRoutineMetadata* aMetadata)
|
||||
const IRoutineMetadata* aMetadata, ITriggerMessage* fieldsMsg)
|
||||
: engine(aEngine),
|
||||
metadata(aMetadata),
|
||||
moduleName(*getDefaultMemoryPool()),
|
||||
@ -361,7 +361,7 @@ public:
|
||||
{
|
||||
engine->loadModule(metadata, &moduleName, &entryPoint);
|
||||
TriggerNode* node = engine->findNode<TriggerNode>(registeredTriggers, moduleName, entryPoint);
|
||||
node->factory->setup(error, context, metadata);
|
||||
node->factory->setup(error, context, metadata, fieldsMsg);
|
||||
}
|
||||
|
||||
virtual ~SharedTrigger()
|
||||
@ -681,11 +681,11 @@ void FB_CALL Engine::closeAttachment(Error* error, ExternalContext* context)
|
||||
|
||||
|
||||
ExternalFunction* FB_CALL Engine::makeFunction(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata, BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new SharedFunction(error, this, context, metadata, inBlr, outBlr);
|
||||
return new SharedFunction(error, this, context, metadata, inMsg, outMsg);
|
||||
}
|
||||
catch (const ThrowError::Exception& e)
|
||||
{
|
||||
@ -696,11 +696,11 @@ ExternalFunction* FB_CALL Engine::makeFunction(Error* error, ExternalContext* co
|
||||
|
||||
|
||||
ExternalProcedure* FB_CALL Engine::makeProcedure(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata, BlrMessage* inBlr, BlrMessage* outBlr)
|
||||
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new SharedProcedure(error, this, context, metadata, inBlr, outBlr);
|
||||
return new SharedProcedure(error, this, context, metadata, inMsg, outMsg);
|
||||
}
|
||||
catch (const ThrowError::Exception& e)
|
||||
{
|
||||
@ -711,11 +711,11 @@ ExternalProcedure* FB_CALL Engine::makeProcedure(Error* error, ExternalContext*
|
||||
|
||||
|
||||
ExternalTrigger* FB_CALL Engine::makeTrigger(Error* error, ExternalContext* context,
|
||||
const IRoutineMetadata* metadata)
|
||||
const IRoutineMetadata* metadata, ITriggerMessage* fieldsMsg)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new SharedTrigger(error, this, context, metadata);
|
||||
return new SharedTrigger(error, this, context, metadata, fieldsMsg);
|
||||
}
|
||||
catch (const ThrowError::Exception& e)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user