|
From: <asf...@us...> - 2013-05-22 15:44:09
|
Revision: 58094
http://sourceforge.net/p/firebird/code/58094
Author: asfernandes
Date: 2013-05-22 15:44:05 +0000 (Wed, 22 May 2013)
Log Message:
-----------
Improve external triggers messages to work by field name (instead of field order).
Modified Paths:
--------------
firebird/trunk/examples/udr/UdrCppExample.cpp
firebird/trunk/src/common/MsgMetadata.cpp
firebird/trunk/src/include/firebird/Message.h
firebird/trunk/src/include/firebird/Provider.h
firebird/trunk/src/include/firebird/UdrCppEngine.h
firebird/trunk/src/jrd/ExtEngineManager.cpp
Modified: firebird/trunk/examples/udr/UdrCppExample.cpp
===================================================================
--- firebird/trunk/examples/udr/UdrCppExample.cpp 2013-05-22 12:18:32 UTC (rev 58093)
+++ firebird/trunk/examples/udr/UdrCppExample.cpp 2013-05-22 15:44:05 UTC (rev 58094)
@@ -611,7 +611,7 @@
ITransaction* transaction = context->getTransaction(status);
StatusException::check(status->get());
- stmt = attachment->prepare(status, transaction, 0, buffer, 3, 0);
+ stmt = attachment->prepare(status, transaction, 0, buffer, SQL_DIALECT_CURRENT, 0);
delete [] outSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(outSqlDa);
@@ -625,7 +625,6 @@
FB_UDR_END_TRIGGER
-#if 0 //// FIXME:
FB_UDR_BEGIN_TRIGGER(replicate_persons)
FB_UDR_TRIGGER(replicate_persons)()
: initialized(false)
@@ -637,37 +636,26 @@
if (!initialized)
return;
- delete [] reinterpret_cast<char*>(inSqlDa);
+ StatusImpl status(master);
- ISC_STATUS_ARRAY statusVector = {0};
- isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_drop);
+ triggerMetadata->release();
+ stmt->free(&status);
}
+ // Order of fields does not need to match the fields order in the table, but it should match
+ // the order of fields in the SQL command constructed in the initialization.
FB_UDR_EXECUTE_MESSAGE_TRIGGER(
(FB_INTEGER, id, "ID")
+ (FB_BLOB, info, "INFO")
(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;
+ ITransaction* transaction = context->getTransaction(status);
+ StatusException::check(status->get());
- 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);
-
- StatusException::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
- inSqlDa), statusVector);
+ stmt->execute(status, transaction, triggerMetadata, newFields, NULL, NULL);
+ StatusException::check(status->get());
}
FB_UDR_INITIALIZE
@@ -676,7 +664,7 @@
isc_db_handle dbHandle = getIscDbHandle(context);
isc_tr_handle trHandle = getIscTrHandle(context);
- stmtHandle = 0;
+ isc_stmt_handle stmtHandle = 0;
StatusException::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle), statusVector);
StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
"select data_source from replicate_config where name = ?",
@@ -700,7 +688,7 @@
else
info = "";
- inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
+ XSQLDA* inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = 1;
StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
@@ -723,21 +711,17 @@
delete [] inSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(inSqlDa);
- inSqlDa = NULL;
- const IParametersMetadata* fields = metadata->getTriggerFields(status);
+ triggerMetadata = metadata->getTriggerMetadata(status);
StatusException::check(status->get());
- unsigned count = fields->getCount(status);
- StatusException::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"
+ " info type of column PERSONS.INFO = ?,\n"
" address type of column PERSONS.ADDRESS = ?,\n"
- " info type of column PERSONS.INFO = ?\n"
+ " name type of column PERSONS.NAME = ?\n"
")"
"as\n"
"begin\n"
@@ -747,20 +731,13 @@
strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short));
strcat(buffer, "';\nend");
- StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
- SQL_DIALECT_CURRENT, NULL), statusVector);
+ IAttachment* attachment = context->getAttachment(status);
+ StatusException::check(status->get());
- inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(4))]);
- inSqlDa->version = SQLDA_VERSION1;
- inSqlDa->sqln = 4;
- StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
- statusVector);
+ ITransaction* transaction = context->getTransaction(status);
+ StatusException::check(status->get());
- for (unsigned i = 0; i < 4; ++i)
- {
- XSQLVAR* var = &inSqlDa->sqlvar[i];
- var->sqltype |= 1;
- }
+ stmt = attachment->prepare(status, transaction, 0, buffer, SQL_DIALECT_CURRENT, 0);
delete [] outSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(outSqlDa);
@@ -769,7 +746,6 @@
}
bool initialized;
- XSQLDA* inSqlDa;
- isc_stmt_handle stmtHandle;
+ IMessageMetadata* triggerMetadata;
+ IStatement* stmt;
FB_UDR_END_TRIGGER
-#endif
Modified: firebird/trunk/src/common/MsgMetadata.cpp
===================================================================
--- firebird/trunk/src/common/MsgMetadata.cpp 2013-05-22 12:18:32 UTC (rev 58093)
+++ firebird/trunk/src/common/MsgMetadata.cpp 2013-05-22 15:44:05 UTC (rev 58094)
@@ -53,6 +53,7 @@
}
// IMetadataBuilder implementation
+
virtual void FB_CARG setType(IStatus* status, unsigned index, unsigned type)
{
try
@@ -128,6 +129,35 @@
}
}
+ virtual void FB_CARG moveNameToIndex(IStatus* status, const char* name, unsigned index)
+ {
+ try
+ {
+ MutexLockGuard g(mtx, FB_FUNCTION);
+
+ indexError(index, "moveNameToIndex");
+
+ for (ObjectsArray<MsgMetadata::Item>::iterator i = msgMetadata->items.begin();
+ i != msgMetadata->items.end();
+ ++i)
+ {
+ if (i->field == name)
+ {
+ MsgMetadata::Item copy(getPool(), *i);
+ msgMetadata->items.remove(i);
+ msgMetadata->items.insert(index, copy);
+ return;
+ }
+ }
+
+ (Arg::Gds(isc_random) << (string("Name not found in IMetadataBuilder: ") + name)).raise();
+ }
+ catch (const Exception& ex)
+ {
+ ex.stuffException(status);
+ }
+ }
+
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status)
{
try
@@ -162,7 +192,7 @@
{
if (!msgMetadata)
{
- (Arg::Gds(isc_random) << (string("MetadataBuilder interface is already inactive: "
+ (Arg::Gds(isc_random) << (string("IMetadataBuilder interface is already inactive: "
"IMetadataBuilder::") + functionName)).raise();
}
}
Modified: firebird/trunk/src/include/firebird/Message.h
===================================================================
--- firebird/trunk/src/include/firebird/Message.h 2013-05-22 12:18:32 UTC (rev 58093)
+++ firebird/trunk/src/include/firebird/Message.h 2013-05-22 15:44:05 UTC (rev 58094)
@@ -31,37 +31,36 @@
#include <string.h>
#define FB_MESSAGE(name, fields) \
- FB_MESSAGE_I(name, 2, FB_BOOST_PP_CAT(FB_MESSAGE_X fields, 0))
+ 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_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_TRIGGER_MESSAGE(name, fields) \
- struct name \
- { \
- 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)) \
- }
+ FB__MESSAGE_I(name, 3, FB_BOOST_PP_CAT(FB_TRIGGER_MESSAGE_X fields, 0), \
+ FB_TRIGGER_MESSAGE_MOVE_NAMES(name, fields))
#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) \
+#define FB__MESSAGE_I(name, size, fields, moveNames) \
struct name \
{ \
struct Type \
{ \
- FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_FIELD, size, fields) \
+ FB_BOOST_PP_SEQ_FOR_EACH_I(FB__MESSAGE_FIELD, size, fields) \
}; \
\
static void setup(::Firebird::IStatus* status, ::Firebird::IMetadataBuilder* builder) \
{ \
unsigned index = 0; \
- FB_BOOST_PP_SEQ_FOR_EACH_I(FB_MESSAGE_META, size, fields) \
+ FB_BOOST_PP_SEQ_FOR_EACH_I(FB__MESSAGE_META, size, fields) \
+ \
+ moveNames \
} \
\
name(::Firebird::IMaster* master) \
@@ -103,142 +102,105 @@
::Firebird::MessageDesc desc; \
}
-#define FB_MESSAGE_FIELD(r, _, i, xy) \
- FB_BOOST_PP_CAT(FB_TYPE_, FB_BOOST_PP_TUPLE_ELEM(_, 0, xy)) FB_BOOST_PP_TUPLE_ELEM(_, 1, xy); \
+#define FB__MESSAGE_FIELD(r, _, i, xy) \
+ 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_META(r, _, i, xy) \
- FB_BOOST_PP_CAT(FB_META_, FB_BOOST_PP_TUPLE_ELEM(_, 0, xy)) \
+#define FB__MESSAGE_META(r, _, i, xy) \
+ FB_BOOST_PP_CAT(FB__META_, FB_BOOST_PP_TUPLE_ELEM(_, 0, xy)) \
++index;
// Types - metadata
-#define FB_META_FB_SCALED_SMALLINT(scale) \
+#define FB__META_FB_SCALED_SMALLINT(scale) \
builder->setType(status, index, SQL_SHORT); \
builder->setLength(status, index, sizeof(ISC_SHORT)); \
builder->setScale(status, index, scale);
-#define FB_META_FB_SCALED_INTEGER(scale) \
+#define FB__META_FB_SCALED_INTEGER(scale) \
builder->setType(status, index, SQL_LONG); \
builder->setLength(status, index, sizeof(ISC_LONG)); \
builder->setScale(status, index, scale);
-#define FB_META_FB_SCALED_BIGINT(scale) \
+#define FB__META_FB_SCALED_BIGINT(scale) \
builder->setType(status, index, SQL_INT64); \
builder->setLength(status, index, sizeof(ISC_INT64)); \
builder->setScale(status, index, scale);
-#define FB_META_FB_FLOAT \
+#define FB__META_FB_FLOAT \
builder->setType(status, index, SQL_FLOAT); \
builder->setLength(status, index, sizeof(float));
-#define FB_META_FB_DOUBLE \
+#define FB__META_FB_DOUBLE \
builder->setType(status, index, SQL_DOUBLE); \
builder->setLength(status, index, sizeof(double));
-#define FB_META_FB_BLOB \
+#define FB__META_FB_BLOB \
builder->setType(status, index, SQL_BLOB); \
builder->setLength(status, index, sizeof(ISC_QUAD));
-#define FB_META_FB_BOOLEAN \
+#define FB__META_FB_BOOLEAN \
builder->setType(status, index, SQL_BOOLEAN); \
builder->setLength(status, index, sizeof(ISC_BOOLEAN));
-#define FB_META_FB_DATE \
+#define FB__META_FB_DATE \
builder->setType(status, index, SQL_DATE); \
builder->setLength(status, index, sizeof(FbDate));
-#define FB_META_FB_TIME \
+#define FB__META_FB_TIME \
builder->setType(status, index, SQL_TIME); \
builder->setLength(status, index, sizeof(FbTime));
-#define FB_META_FB_TIMESTAMP \
+#define FB__META_FB_TIMESTAMP \
builder->setType(status, index, SQL_TIMESTAMP); \
builder->setLength(status, index, sizeof(FbTimestamp));
-#define FB_META_FB_CHAR(len) \
+#define FB__META_FB_CHAR(len) \
builder->setType(status, index, SQL_TEXT); \
builder->setLength(status, index, len);
-#define FB_META_FB_VARCHAR(len) \
+#define FB__META_FB_VARCHAR(len) \
builder->setType(status, index, SQL_VARYING); \
builder->setLength(status, index, len);
-#define FB_META_FB_SMALLINT FB_META_FB_SCALED_SMALLINT(0)
-#define FB_META_FB_INTEGER FB_META_FB_SCALED_INTEGER(0)
-#define FB_META_FB_BIGINT FB_META_FB_SCALED_BIGINT(0)
+#define FB__META_FB_SMALLINT FB__META_FB_SCALED_SMALLINT(0)
+#define FB__META_FB_INTEGER FB__META_FB_SCALED_INTEGER(0)
+#define FB__META_FB_BIGINT FB__META_FB_SCALED_BIGINT(0)
// Types - struct
-#define FB_TYPE_FB_SCALED_SMALLINT(x) ISC_SHORT
-#define FB_TYPE_FB_SCALED_INTEGER(x) ISC_LONG
-#define FB_TYPE_FB_SCALED_BIGINT(x) ISC_INT64
-#define FB_TYPE_FB_SMALLINT ISC_SHORT
-#define FB_TYPE_FB_INTEGER ISC_LONG
-#define FB_TYPE_FB_BIGINT ISC_INT64
-#define FB_TYPE_FB_FLOAT float
-#define FB_TYPE_FB_DOUBLE double
-#define FB_TYPE_FB_BLOB ISC_QUAD
-#define FB_TYPE_FB_BOOLEAN ISC_UCHAR
-#define FB_TYPE_FB_DATE ::Firebird::FbDate
-#define FB_TYPE_FB_TIME ::Firebird::FbTime
-#define FB_TYPE_FB_TIMESTAMP ::Firebird::FbTimestamp
-#define FB_TYPE_FB_CHAR(len) ::Firebird::FbChar<(len)>
-#define FB_TYPE_FB_VARCHAR(len) ::Firebird::FbVarChar<(len)>
+#define FB__TYPE_FB_SCALED_SMALLINT(x) ISC_SHORT
+#define FB__TYPE_FB_SCALED_INTEGER(x) ISC_LONG
+#define FB__TYPE_FB_SCALED_BIGINT(x) ISC_INT64
+#define FB__TYPE_FB_SMALLINT ISC_SHORT
+#define FB__TYPE_FB_INTEGER ISC_LONG
+#define FB__TYPE_FB_BIGINT ISC_INT64
+#define FB__TYPE_FB_FLOAT float
+#define FB__TYPE_FB_DOUBLE double
+#define FB__TYPE_FB_BLOB ISC_QUAD
+#define FB__TYPE_FB_BOOLEAN ISC_UCHAR
+#define FB__TYPE_FB_DATE ::Firebird::FbDate
+#define FB__TYPE_FB_TIME ::Firebird::FbTime
+#define FB__TYPE_FB_TIMESTAMP ::Firebird::FbTimestamp
+#define FB__TYPE_FB_CHAR(len) ::Firebird::FbChar<(len)>
+#define FB__TYPE_FB_VARCHAR(len) ::Firebird::FbVarChar<(len)>
-#define FB_MESSAGE_DESC(name, fields) \
- FB_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_MOVE_NAMES(name, fields) \
+ FB_TRIGGER_MESSAGE_MOVE_NAMES_I(name, 3, FB_BOOST_PP_CAT(FB_TRIGGER_MESSAGE_MOVE_NAMES_X fields, 0))
-#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_MOVE_NAMES_X(x, y, z) ((x, y, z)) FB_TRIGGER_MESSAGE_MOVE_NAMES_Y
+#define FB_TRIGGER_MESSAGE_MOVE_NAMES_Y(x, y, z) ((x, y, z)) FB_TRIGGER_MESSAGE_MOVE_NAMES_X
+#define FB_TRIGGER_MESSAGE_MOVE_NAMES_X0
+#define FB_TRIGGER_MESSAGE_MOVE_NAMES_Y0
-#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_MOVE_NAMES_I(name, size, fields) \
+ index = 0; \
+ FB_BOOST_PP_SEQ_FOR_EACH_I(FB_TRIGGER_MESSAGE_MOVE_NAME, size, fields)
-#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_MOVE_NAME(r, _, i, xy) \
+ builder->moveNameToIndex(status, FB_BOOST_PP_TUPLE_ELEM(_, 2, xy), index++);
-#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 {
Modified: firebird/trunk/src/include/firebird/Provider.h
===================================================================
--- firebird/trunk/src/include/firebird/Provider.h 2013-05-22 12:18:32 UTC (rev 58093)
+++ firebird/trunk/src/include/firebird/Provider.h 2013-05-22 15:44:05 UTC (rev 58094)
@@ -120,9 +120,11 @@
virtual void FB_CARG setLength(IStatus* status, unsigned index, unsigned length) = 0;
virtual void FB_CARG setScale(IStatus* status, unsigned index, unsigned scale) = 0;
+ virtual void FB_CARG moveNameToIndex(IStatus* status, const char* name, unsigned index) = 0;
+
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status) = 0;
};
-#define FB_METADATA_BUILDER_VERSION (FB_REFCOUNTED_VERSION + 5)
+#define FB_METADATA_BUILDER_VERSION (FB_REFCOUNTED_VERSION + 6)
class IResultSet : public IRefCounted
{
Modified: firebird/trunk/src/include/firebird/UdrCppEngine.h
===================================================================
--- firebird/trunk/src/include/firebird/UdrCppEngine.h 2013-05-22 12:18:32 UTC (rev 58093)
+++ firebird/trunk/src/include/firebird/UdrCppEngine.h 2013-05-22 15:44:05 UTC (rev 58094)
@@ -61,10 +61,10 @@
};
#define FB_UDR_EXECUTE_DYNAMIC_FUNCTION \
- FB_UDR__DYNAMIC_TYPE(InMessage); \
- FB_UDR__DYNAMIC_TYPE(OutMessage); \
+ FB__UDR_DYNAMIC_TYPE(InMessage); \
+ FB__UDR_DYNAMIC_TYPE(OutMessage); \
\
- FB_UDR__EXECUTE_FUNCTION
+ FB__UDR_EXECUTE_FUNCTION
#define FB_UDR_EXECUTE_MESSAGE_FUNCTION(inputs, output) \
FB_MESSAGE(InMessage, \
@@ -74,17 +74,17 @@
output \
); \
\
- FB_UDR__EXECUTE_FUNCTION
+ FB__UDR_EXECUTE_FUNCTION
#define FB_UDR_EXECUTE_MESSAGE_FUNCTION_OUT(outputs) \
- FB_UDR__DYNAMIC_TYPE(InMessage); \
+ FB__UDR_DYNAMIC_TYPE(InMessage); \
FB_MESSAGE(OutMessage, \
outputs \
); \
\
- FB_UDR__EXECUTE_FUNCTION
+ FB__UDR_EXECUTE_FUNCTION
-#define FB_UDR__EXECUTE_FUNCTION \
+#define FB__UDR_EXECUTE_FUNCTION \
virtual void FB_CARG execute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
void* in, void* out) \
{ \
@@ -92,7 +92,7 @@
{ \
internalExecute(status, context, (InMessage::Type*) in, (OutMessage::Type*) out); \
} \
- FB_UDR__CATCH \
+ FB__UDR_CATCH \
} \
\
void internalExecute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
@@ -118,10 +118,10 @@
};
#define FB_UDR_EXECUTE_DYNAMIC_PROCEDURE \
- FB_UDR__DYNAMIC_TYPE(InMessage); \
- FB_UDR__DYNAMIC_TYPE(OutMessage); \
+ FB__UDR_DYNAMIC_TYPE(InMessage); \
+ FB__UDR_DYNAMIC_TYPE(OutMessage); \
\
- FB_UDR__EXECUTE_PROCEDURE
+ FB__UDR_EXECUTE_PROCEDURE
#define FB_UDR_EXECUTE_MESSAGE_PROCEDURE(inputs, outputs) \
FB_MESSAGE(InMessage, \
@@ -131,25 +131,25 @@
outputs \
); \
\
- FB_UDR__EXECUTE_PROCEDURE
+ FB__UDR_EXECUTE_PROCEDURE
#define FB_UDR_EXECUTE_MESSAGE_PROCEDURE_IN(inputs) \
FB_MESSAGE(InMessage, \
inputs \
); \
- FB_UDR__DYNAMIC_TYPE(OutMessage); \
+ FB__UDR_DYNAMIC_TYPE(OutMessage); \
\
- FB_UDR__EXECUTE_PROCEDURE
+ FB__UDR_EXECUTE_PROCEDURE
#define FB_UDR_EXECUTE_MESSAGE_PROCEDURE_OUT(outputs) \
- FB_UDR__DYNAMIC_TYPE(InMessage); \
+ FB__UDR_DYNAMIC_TYPE(InMessage); \
FB_MESSAGE(OutMessage, \
outputs \
); \
\
- FB_UDR__EXECUTE_PROCEDURE
+ FB__UDR_EXECUTE_PROCEDURE
-#define FB_UDR__EXECUTE_PROCEDURE \
+#define FB__UDR_EXECUTE_PROCEDURE \
virtual ::Firebird::ExternalResultSet* FB_CARG open(::Firebird::IStatus* status, \
::Firebird::ExternalContext* context, void* in, void* out) \
{ \
@@ -157,7 +157,7 @@
{ \
return new ResultSet(status, context, this, (InMessage::Type*) in, (OutMessage::Type*) out); \
} \
- FB_UDR__CATCH \
+ FB__UDR_CATCH \
\
return 0; \
} \
@@ -177,7 +177,7 @@
{ \
return internalFetch(status); \
} \
- FB_UDR__CATCH \
+ FB__UDR_CATCH \
\
return 0; \
} \
@@ -202,18 +202,18 @@
};
#define FB_UDR_EXECUTE_DYNAMIC_TRIGGER \
- FB_UDR__DYNAMIC_TYPE(FieldsMessage); \
+ FB__UDR_DYNAMIC_TYPE(FieldsMessage); \
\
- FB_UDR__EXECUTE_TRIGGER
+ FB__UDR_EXECUTE_TRIGGER
#define FB_UDR_EXECUTE_MESSAGE_TRIGGER(fields) \
FB_TRIGGER_MESSAGE(FieldsMessage, \
fields \
); \
\
- FB_UDR__EXECUTE_TRIGGER
+ FB__UDR_EXECUTE_TRIGGER
-#define FB_UDR__EXECUTE_TRIGGER \
+#define FB__UDR_EXECUTE_TRIGGER \
virtual void FB_CARG execute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
::Firebird::ExternalTrigger::Action action, void* oldFields, void* newFields) \
{ \
@@ -222,7 +222,7 @@
internalExecute(status, context, action, \
(FieldsMessage::Type*) oldFields, (FieldsMessage::Type*) newFields); \
} \
- FB_UDR__CATCH \
+ FB__UDR_CATCH \
} \
\
void internalExecute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
@@ -237,13 +237,13 @@
{ \
internalInitialize(status, context); \
} \
- FB_UDR__CATCH \
+ FB__UDR_CATCH \
} \
\
void internalInitialize(::Firebird::IStatus* status, ::Firebird::ExternalContext* context)
-#define FB_UDR__DYNAMIC_TYPE(name) \
+#define FB__UDR_DYNAMIC_TYPE(name) \
struct name \
{ \
typedef unsigned char Type; \
@@ -251,7 +251,7 @@
}
-#define FB_UDR__CATCH \
+#define FB__UDR_CATCH \
catch (const ::Firebird::Udr::StatusException& e) \
{ \
e.stuff(status); \
Modified: firebird/trunk/src/jrd/ExtEngineManager.cpp
===================================================================
--- firebird/trunk/src/jrd/ExtEngineManager.cpp 2013-05-22 12:18:32 UTC (rev 58093)
+++ firebird/trunk/src/jrd/ExtEngineManager.cpp 2013-05-22 15:44:05 UTC (rev 58094)
@@ -232,11 +232,9 @@
ExtMessageNode* message)
: CompoundStmtNode(pool)
{
- for (USHORT i = 0; i < message->format->fmt_count; i += 2)
+ // Iterate over the format items, except the EOF item.
+ for (USHORT i = 0; i < message->format->fmt_count / 2 * 2; i += 2)
{
- if (i + 1 >= message->format->fmt_count)
- continue;
-
ExtInitParameterNode* init = FB_NEW(pool) ExtInitParameterNode(
tdbb, pool, csb, message, i);
statements.add(init);
@@ -251,9 +249,10 @@
ExtValidationNode(MemoryPool& pool, ExtMessageNode* message, bool procedure, bool input)
: CompoundStmtNode(pool)
{
- for (USHORT i = 0; i < message->format->fmt_count; i += 2)
+ // Iterate over the format items, except the EOF item.
+ for (USHORT i = 0; i < message->format->fmt_count / 2 * 2; i += 2)
{
- if (i + 1 >= message->format->fmt_count || !message->isSpecial[i / 2])
+ if (!message->isSpecial[i / 2])
continue;
ParameterNode* flag = FB_NEW(pool) ParameterNode(pool);
@@ -840,10 +839,31 @@
if (relation)
{
+ 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)
+ fieldsMap.put(field->fld_name, (USHORT) i);
+ }
+
format = Routine::createFormat(pool, metadata->triggerFields, false);
+ LocalStatus status;
+
for (unsigned i = 0; i < format->fmt_count / 2; ++i)
- fieldsPos.add(i);
+ {
+ const char* fieldName = metadata->triggerFields->getField(&status, i);
+ status.check();
+
+ USHORT pos;
+
+ if (!fieldsMap.get(fieldName, pos))
+ fb_assert(false);
+ else
+ fieldsPos.add(pos);
+ }
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|