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. |