Loading storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -1933,15 +1933,16 @@ static struct Ev_t { enum_DEL = NdbDictionary::Event::_TE_DELETE, enum_UPD = NdbDictionary::Event::_TE_UPDATE, enum_NUL = NdbDictionary::Event::_TE_NUL, enum_ERR = 255 enum_IDM = 254, // idempotent op possibly allowed on NF enum_ERR = 255 // always impossible }; int t1, t2, t3; } ev_t[] = { { Ev_t::enum_INS, Ev_t::enum_INS, Ev_t::enum_ERR }, { Ev_t::enum_INS, Ev_t::enum_INS, Ev_t::enum_IDM }, { Ev_t::enum_INS, Ev_t::enum_DEL, Ev_t::enum_NUL }, //ok { Ev_t::enum_INS, Ev_t::enum_UPD, Ev_t::enum_INS }, //ok { Ev_t::enum_DEL, Ev_t::enum_INS, Ev_t::enum_UPD }, //ok { Ev_t::enum_DEL, Ev_t::enum_DEL, Ev_t::enum_ERR }, { Ev_t::enum_DEL, Ev_t::enum_DEL, Ev_t::enum_IDM }, { Ev_t::enum_DEL, Ev_t::enum_UPD, Ev_t::enum_ERR }, { Ev_t::enum_UPD, Ev_t::enum_INS, Ev_t::enum_ERR }, { Ev_t::enum_UPD, Ev_t::enum_DEL, Ev_t::enum_DEL }, //ok Loading Loading @@ -2010,6 +2011,34 @@ NdbEventBuffer::merge_data(const SubTableData * const sdata, } assert(tp != 0 && tp->t3 != Ev_t::enum_ERR); if (tp->t3 == Ev_t::enum_IDM) { LinearSectionPtr (&ptr1)[3] = data->ptr; /* * TODO * - can get data in INS ptr2[2] which is supposed to be empty * - can get extra data in DEL ptr2[2] * - why does DBUG_PRINT not work in this file ??? * * replication + bug#19872 can ignore this since merge is on * only for tables with explicit PK and before data is not used */ const int maxsec = 1; // ignore section 2 int i; for (i = 0; i <= maxsec; i++) { if (ptr1[i].sz != ptr2[i].sz || memcmp(ptr1[i].p, ptr2[i].p, ptr1[i].sz << 2) != 0) { DBUG_PRINT("info", ("idempotent op %d*%d data differs in sec %d", tp->t1, tp->t2, i)); assert(false); DBUG_RETURN_EVENT(-1); } } DBUG_PRINT("info", ("idempotent op %d*%d data ok", tp->t1, tp->t2)); DBUG_RETURN_EVENT(0); } // save old data EventBufData olddata = *data; data->memory = 0; Loading storage/ndb/test/ndbapi/test_event.cpp +40 −3 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ #define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab) static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab, bool merge_events = false) { char eventName[1024]; sprintf(eventName,"%s_EVENT",tab.getName()); Loading @@ -45,6 +46,7 @@ static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab) for(int a = 0; a < tab.getNoOfColumns(); a++){ myEvent.addEventColumn(a); } myEvent.mergeEvents(merge_events); int res = myDict->createEvent(myEvent); // Add event to database Loading Loading @@ -137,7 +139,8 @@ NdbEventOperation *createEventOperation(Ndb *ndb, static int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step) { if (createEvent(GETNDB(step),* ctx->getTab()) != 0){ bool merge_events = ctx->getProperty("MergeEvents"); if (createEvent(GETNDB(step),* ctx->getTab(), merge_events) != 0){ return NDBT_FAILED; } return NDBT_OK; Loading Loading @@ -584,6 +587,8 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step) g_err << "Event operation creation failed on %s" << buf << endl; DBUG_RETURN(NDBT_FAILED); } bool merge_events = ctx->getProperty("MergeEvents"); pOp->mergeEvents(merge_events); int i; int n_columns= table->getNoOfColumns(); Loading Loading @@ -616,6 +621,11 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step) while ((pOp= ndb->nextEvent()) != 0) { assert(pOp == pCreate); if (pOp->getEventType() >= NdbDictionary::Event::TE_FIRST_NON_DATA_EVENT) continue; int noRetries= 0; do { Loading Loading @@ -1607,6 +1617,33 @@ TESTCASE("EventOperationApplier_NR", FINALIZER(runVerify); FINALIZER(runDropShadowTable); } TESTCASE("MergeEventOperationApplier", "Verify that if we apply the data we get from merged event " "operation is the same as the original table" "NOTE! No errors are allowed!" ){ TC_PROPERTY("MergeEvents", 1); INITIALIZER(runCreateEvent); INITIALIZER(runCreateShadowTable); STEP(runEventApplier); STEP(runEventMixedLoad); FINALIZER(runDropEvent); FINALIZER(runVerify); FINALIZER(runDropShadowTable); } TESTCASE("MergeEventOperationApplier_NR", "Verify that if we apply the data we get from merged event " "operation is the same as the original table" "NOTE! No errors are allowed!" ){ TC_PROPERTY("MergeEvents", 1); INITIALIZER(runCreateEvent); INITIALIZER(runCreateShadowTable); STEP(runEventApplier); STEP(runEventMixedLoad); STEP(runRestarter); FINALIZER(runDropEvent); FINALIZER(runVerify); FINALIZER(runDropShadowTable); } TESTCASE("Multi", "Verify that we can work with all tables in parallell" "NOTE! HugoOperations::startTransaction, pTrans != NULL errors, " Loading storage/ndb/test/run-test/daily-devel-tests.txt +5 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,11 @@ max-time: 2500 cmd: test_event args: -n EventOperationApplier_NR -l 2 # max-time: 2500 cmd: test_event args: -n MergeEventOperationApplier_NR -l 2 # max-time: 2500 cmd: test_event Loading Loading
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -1933,15 +1933,16 @@ static struct Ev_t { enum_DEL = NdbDictionary::Event::_TE_DELETE, enum_UPD = NdbDictionary::Event::_TE_UPDATE, enum_NUL = NdbDictionary::Event::_TE_NUL, enum_ERR = 255 enum_IDM = 254, // idempotent op possibly allowed on NF enum_ERR = 255 // always impossible }; int t1, t2, t3; } ev_t[] = { { Ev_t::enum_INS, Ev_t::enum_INS, Ev_t::enum_ERR }, { Ev_t::enum_INS, Ev_t::enum_INS, Ev_t::enum_IDM }, { Ev_t::enum_INS, Ev_t::enum_DEL, Ev_t::enum_NUL }, //ok { Ev_t::enum_INS, Ev_t::enum_UPD, Ev_t::enum_INS }, //ok { Ev_t::enum_DEL, Ev_t::enum_INS, Ev_t::enum_UPD }, //ok { Ev_t::enum_DEL, Ev_t::enum_DEL, Ev_t::enum_ERR }, { Ev_t::enum_DEL, Ev_t::enum_DEL, Ev_t::enum_IDM }, { Ev_t::enum_DEL, Ev_t::enum_UPD, Ev_t::enum_ERR }, { Ev_t::enum_UPD, Ev_t::enum_INS, Ev_t::enum_ERR }, { Ev_t::enum_UPD, Ev_t::enum_DEL, Ev_t::enum_DEL }, //ok Loading Loading @@ -2010,6 +2011,34 @@ NdbEventBuffer::merge_data(const SubTableData * const sdata, } assert(tp != 0 && tp->t3 != Ev_t::enum_ERR); if (tp->t3 == Ev_t::enum_IDM) { LinearSectionPtr (&ptr1)[3] = data->ptr; /* * TODO * - can get data in INS ptr2[2] which is supposed to be empty * - can get extra data in DEL ptr2[2] * - why does DBUG_PRINT not work in this file ??? * * replication + bug#19872 can ignore this since merge is on * only for tables with explicit PK and before data is not used */ const int maxsec = 1; // ignore section 2 int i; for (i = 0; i <= maxsec; i++) { if (ptr1[i].sz != ptr2[i].sz || memcmp(ptr1[i].p, ptr2[i].p, ptr1[i].sz << 2) != 0) { DBUG_PRINT("info", ("idempotent op %d*%d data differs in sec %d", tp->t1, tp->t2, i)); assert(false); DBUG_RETURN_EVENT(-1); } } DBUG_PRINT("info", ("idempotent op %d*%d data ok", tp->t1, tp->t2)); DBUG_RETURN_EVENT(0); } // save old data EventBufData olddata = *data; data->memory = 0; Loading
storage/ndb/test/ndbapi/test_event.cpp +40 −3 Original line number Diff line number Diff line Loading @@ -25,7 +25,8 @@ #define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab) static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab, bool merge_events = false) { char eventName[1024]; sprintf(eventName,"%s_EVENT",tab.getName()); Loading @@ -45,6 +46,7 @@ static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab) for(int a = 0; a < tab.getNoOfColumns(); a++){ myEvent.addEventColumn(a); } myEvent.mergeEvents(merge_events); int res = myDict->createEvent(myEvent); // Add event to database Loading Loading @@ -137,7 +139,8 @@ NdbEventOperation *createEventOperation(Ndb *ndb, static int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step) { if (createEvent(GETNDB(step),* ctx->getTab()) != 0){ bool merge_events = ctx->getProperty("MergeEvents"); if (createEvent(GETNDB(step),* ctx->getTab(), merge_events) != 0){ return NDBT_FAILED; } return NDBT_OK; Loading Loading @@ -584,6 +587,8 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step) g_err << "Event operation creation failed on %s" << buf << endl; DBUG_RETURN(NDBT_FAILED); } bool merge_events = ctx->getProperty("MergeEvents"); pOp->mergeEvents(merge_events); int i; int n_columns= table->getNoOfColumns(); Loading Loading @@ -616,6 +621,11 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step) while ((pOp= ndb->nextEvent()) != 0) { assert(pOp == pCreate); if (pOp->getEventType() >= NdbDictionary::Event::TE_FIRST_NON_DATA_EVENT) continue; int noRetries= 0; do { Loading Loading @@ -1607,6 +1617,33 @@ TESTCASE("EventOperationApplier_NR", FINALIZER(runVerify); FINALIZER(runDropShadowTable); } TESTCASE("MergeEventOperationApplier", "Verify that if we apply the data we get from merged event " "operation is the same as the original table" "NOTE! No errors are allowed!" ){ TC_PROPERTY("MergeEvents", 1); INITIALIZER(runCreateEvent); INITIALIZER(runCreateShadowTable); STEP(runEventApplier); STEP(runEventMixedLoad); FINALIZER(runDropEvent); FINALIZER(runVerify); FINALIZER(runDropShadowTable); } TESTCASE("MergeEventOperationApplier_NR", "Verify that if we apply the data we get from merged event " "operation is the same as the original table" "NOTE! No errors are allowed!" ){ TC_PROPERTY("MergeEvents", 1); INITIALIZER(runCreateEvent); INITIALIZER(runCreateShadowTable); STEP(runEventApplier); STEP(runEventMixedLoad); STEP(runRestarter); FINALIZER(runDropEvent); FINALIZER(runVerify); FINALIZER(runDropShadowTable); } TESTCASE("Multi", "Verify that we can work with all tables in parallell" "NOTE! HugoOperations::startTransaction, pTrans != NULL errors, " Loading
storage/ndb/test/run-test/daily-devel-tests.txt +5 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,11 @@ max-time: 2500 cmd: test_event args: -n EventOperationApplier_NR -l 2 # max-time: 2500 cmd: test_event args: -n MergeEventOperationApplier_NR -l 2 # max-time: 2500 cmd: test_event Loading