20 #define DBTUP_TRIGGER_CPP
22 #include <RefConvert.hpp>
23 #include <ndb_limits.h>
25 #include <AttributeDescriptor.hpp>
26 #include "AttributeOffset.hpp"
27 #include <AttributeHeader.hpp>
28 #include <signaldata/FireTrigOrd.hpp>
29 #include <signaldata/CreateTrig.hpp>
30 #include <signaldata/CreateTrigImpl.hpp>
31 #include <signaldata/DropTrig.hpp>
32 #include <signaldata/DropTrigImpl.hpp>
33 #include <signaldata/TuxMaint.hpp>
34 #include <signaldata/AlterIndxImpl.hpp>
35 #include "../dblqh/Dblqh.hpp"
44 Dbtup::findTriggerList(Tablerec*
table,
45 TriggerType::Value ttype,
46 TriggerActionTime::Value ttime,
51 case TriggerType::SUBSCRIPTION:
52 case TriggerType::SUBSCRIPTION_BEFORE:
54 case TriggerEvent::TE_INSERT:
56 if (ttime == TriggerActionTime::TA_DETACHED)
57 tlist = &table->subscriptionInsertTriggers;
59 case TriggerEvent::TE_UPDATE:
61 if (ttime == TriggerActionTime::TA_DETACHED)
62 tlist = &table->subscriptionUpdateTriggers;
64 case TriggerEvent::TE_DELETE:
66 if (ttime == TriggerActionTime::TA_DETACHED)
67 tlist = &table->subscriptionDeleteTriggers;
73 case TriggerType::SECONDARY_INDEX:
74 case TriggerType::REORG_TRIGGER:
76 case TriggerEvent::TE_INSERT:
78 if (ttime == TriggerActionTime::TA_AFTER)
79 tlist = &table->afterInsertTriggers;
81 case TriggerEvent::TE_UPDATE:
83 if (ttime == TriggerActionTime::TA_AFTER)
84 tlist = &table->afterUpdateTriggers;
86 case TriggerEvent::TE_DELETE:
88 if (ttime == TriggerActionTime::TA_AFTER)
89 tlist = &table->afterDeleteTriggers;
95 case TriggerType::ORDERED_INDEX:
97 case TriggerEvent::TE_CUSTOM:
99 if (ttime == TriggerActionTime::TA_CUSTOM)
100 tlist = &table->tuxCustomTriggers;
106 case TriggerType::READ_ONLY_CONSTRAINT:
108 case TriggerEvent::TE_UPDATE:
110 if (ttime == TriggerActionTime::TA_AFTER)
111 tlist = &table->constraintUpdateTriggers;
125 Dbtup::execCREATE_TRIG_IMPL_REQ(
Signal* signal)
135 const Uint32 senderRef = req->senderRef;
136 const Uint32 senderData = req->senderData;
137 const Uint32 tableId = req->tableId;
138 const Uint32 triggerId = req->triggerId;
139 const Uint32 triggerInfo = req->triggerInfo;
141 CreateTrigRef::ErrorCode error = CreateTrigRef::NoError;
145 if (handle.m_cnt <= CreateTrigImplReq::ATTRIBUTE_MASK_SECTION)
149 error = CreateTrigRef::BadRequestType;
154 handle.getSection(ptr, CreateTrigImplReq::ATTRIBUTE_MASK_SECTION);
155 ndbrequire(ptr.sz == mask.getSizeInWords());
156 ::copy(mask.rep.data, ptr);
159 releaseSections(handle);
161 if (error != CreateTrigRef::NoError)
169 tabPtr.i = req->tableId;
170 ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
172 if (tabPtr.p->tableStatus != DEFINED )
175 error = CreateTrigRef::InvalidTable;
178 else if (createTrigger(tabPtr.p, req, mask))
183 conf->senderRef = reference();
184 conf->senderData = senderData;
185 conf->tableId = tableId;
186 conf->triggerId = triggerId;
187 conf->triggerInfo = triggerInfo;
189 sendSignal(senderRef, GSN_CREATE_TRIG_IMPL_CONF,
190 signal, CreateTrigImplConf::SignalLength, JBB);
196 error = CreateTrigRef::TooManyTriggers;
201 ndbassert(error != CreateTrigRef::NoError);
204 ref->senderRef = reference();
205 ref->senderData = senderData;
206 ref->tableId = tableId;
207 ref->triggerId = triggerId;
208 ref->triggerInfo = triggerInfo;
209 ref->errorCode = error;
211 sendSignal(senderRef, GSN_CREATE_TRIG_IMPL_REF,
212 signal, CreateTrigImplRef::SignalLength, JBB);
216 Dbtup::execDROP_TRIG_IMPL_REQ(
Signal* signal)
220 const Uint32 senderRef = req->senderRef;
221 const Uint32 senderData = req->senderData;
222 const Uint32 tableId = req->tableId;
223 const Uint32 indexId = req->indexId;
224 const Uint32 triggerId = req->triggerId;
225 const Uint32 triggerInfo = req->triggerInfo;
226 const Uint32 receiverRef = req->receiverRef;
230 tabPtr.i = req->tableId;
231 ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
234 Uint32 r = dropTrigger(tabPtr.p, req, refToBlock(receiverRef));
243 flush_ndbmtd_suma_buffer(signal);
247 conf->senderRef = reference();
248 conf->senderData = senderData;
249 conf->tableId = tableId;
250 conf->triggerId = triggerId;
252 sendSignal(senderRef, GSN_DROP_TRIG_IMPL_CONF,
253 signal, DropTrigImplConf::SignalLength, JBB);
256 TriggerType::Value ttype = TriggerInfo::getTriggerType(triggerInfo);
257 if (ttype == TriggerType::ORDERED_INDEX)
262 areq->senderData = 0;
263 areq->requestType = AlterIndxImplReq::AlterIndexOffline;
264 areq->tableId = tableId;
265 areq->tableVersion = 0;
266 areq->indexId = indexId;
267 areq->indexVersion = 0;
268 areq->indexType = DictTabInfo::OrderedIndex;
270 signal, AlterIndxImplReq::SignalLength);
275 ref->senderRef = reference();
276 ref->senderData = senderData;
277 ref->tableId = tableId;
278 ref->triggerId = triggerId;
280 sendSignal(senderRef, GSN_DROP_TRIG_IMPL_REF,
281 signal, DropTrigImplRef::SignalLength, JBB);
299 Dbtup::createTrigger(Tablerec* table,
303 if (ERROR_INSERTED(4003)) {
304 CLEAR_ERROR_INSERT_VALUE;
308 const Uint32 tinfo = req->triggerInfo;
309 TriggerType::Value ttype = TriggerInfo::getTriggerType(tinfo);
310 TriggerActionTime::Value ttime = TriggerInfo::getTriggerActionTime(tinfo);
320 if (ttype == TriggerType::SECONDARY_INDEX ||
321 ttype == TriggerType::REORG_TRIGGER)
325 tmp[0].event = TriggerEvent::TE_INSERT;
326 tmp[1].event = TriggerEvent::TE_UPDATE;
327 tmp[2].event = TriggerEvent::TE_DELETE;
333 tmp[0].event = tevent;
337 for (i = 0; i<cnt; i++)
339 tmp[
i].list = findTriggerList(table, ttype, ttime, tmp[i].
event);
340 ndbrequire(tmp[i].list != NULL);
343 if (!tmp[i].list->seize(tptr))
352 tptr.p->triggerId = req->triggerId;
353 tptr.p->oldTriggerIds[0] = req->upgradeExtra[0];
354 tptr.p->oldTriggerIds[1] = req->upgradeExtra[1];
355 tptr.p->oldTriggerIds[2] = req->upgradeExtra[2];
358 tptr.p->indexId = req->indexId;
361 tptr.p->triggerType = ttype;
362 tptr.p->triggerActionTime = ttime;
363 tptr.p->triggerEvent = tevent;
365 tptr.p->sendBeforeValues =
true;
366 if ((tptr.p->triggerType == TriggerType::SUBSCRIPTION) &&
367 ((tptr.p->triggerEvent == TriggerEvent::TE_UPDATE) ||
368 (tptr.p->triggerEvent == TriggerEvent::TE_DELETE))) {
370 tptr.p->sendBeforeValues =
false;
373 if (ttype == TriggerType::REORG_TRIGGER)
376 tptr.p->sendBeforeValues =
false;
388 tptr.p->sendOnlyChangedAttributes =
389 !TriggerInfo::getReportAllMonitoredAttributes(tinfo);
391 tptr.p->monitorAllAttributes = TriggerInfo::getMonitorAllAttributes(tinfo);
392 tptr.p->monitorReplicas = TriggerInfo::getMonitorReplicas(tinfo);
393 tptr.p->m_receiverRef = req->receiverRef;
395 if (tptr.p->monitorAllAttributes)
399 tptr.p->attributeMask.set();
400 for(Uint32 i = 0; i < table->m_no_of_attributes; i++) {
401 if (primaryKey(table, i))
402 tptr.p->attributeMask.clear(i);
409 tptr.p->attributeMask = mask;
415 for (--i; i >= 0; i--)
418 tmp[
i].list->release(tmp[i].ptr);
424 Dbtup::primaryKey(Tablerec*
const regTabPtr, Uint32 attrId)
426 Uint32 attrDescriptorStart = regTabPtr->tabDescriptor;
427 Uint32 attrDescriptor = getTabDescrWord(attrDescriptorStart +
428 (attrId * ZAD_SIZE));
429 return (
bool)AttributeDescriptor::getPrimaryKey(attrDescriptor);
443 Dbtup::dropTrigger(Tablerec* table,
const DropTrigImplReq* req, BlockNumber receiver)
445 if (ERROR_INSERTED(4004)) {
446 CLEAR_ERROR_INSERT_VALUE;
449 Uint32 triggerId = req->triggerId;
451 const Uint32 tinfo = req->triggerInfo;
452 TriggerType::Value ttype = TriggerInfo::getTriggerType(tinfo);
453 TriggerActionTime::Value ttime = TriggerInfo::getTriggerActionTime(tinfo);
465 if (ttype == TriggerType::SECONDARY_INDEX ||
466 ttype == TriggerType::REORG_TRIGGER)
470 tmp[0].event = TriggerEvent::TE_INSERT;
471 tmp[1].event = TriggerEvent::TE_UPDATE;
472 tmp[2].event = TriggerEvent::TE_DELETE;
478 tmp[0].event = tevent;
482 for (i = 0; i<cnt; i++)
484 tmp[
i].list = findTriggerList(table, ttype, ttime, tmp[i].
event);
485 ndbrequire(tmp[i].list != NULL);
488 tmp[
i].ptr.setNull();
489 for (tmp[i].list->first(ptr); !ptr.isNull(); tmp[
i].list->next(ptr))
494 if(ttype==TriggerType::SUBSCRIPTION &&
512 if (tmp[i].ptr.isNull())
515 return DropTrigRef::TriggerNotFound;
519 for (i = 0; i<cnt; i++)
522 tmp[
i].list->release(tmp[i].ptr);
528 Dbtup::execFIRE_TRIG_REQ(
Signal* signal)
531 Uint32 opPtrI = signal->theData[0];
532 Uint32 pass = signal->theData[5];
534 FragrecordPtr regFragPtr;
535 OperationrecPtr regOperPtr;
536 TablerecPtr regTabPtr;
537 KeyReqStruct req_struct(
this, (When)(KRS_PRE_COMMIT0 + pass));
539 regOperPtr.i = opPtrI;
543 c_operation_pool.
getPtr(regOperPtr);
545 regFragPtr.i = regOperPtr.p->fragmentPtr;
546 Uint32 no_of_fragrec = cnoOfFragrec;
547 ptrCheckGuard(regFragPtr, no_of_fragrec, fragrecord);
549 TransState trans_state = get_trans_state(regOperPtr.p);
550 ndbrequire(trans_state == TRANS_STARTED);
552 Uint32 no_of_tablerec = cnoOfTablerec;
553 regTabPtr.i = regFragPtr.p->fragTableId;
554 ptrCheckGuard(regTabPtr, no_of_tablerec, tablerec);
556 req_struct.signal = signal;
557 req_struct.TC_ref = signal->theData[1];
558 req_struct.TC_index = signal->theData[2];
559 req_struct.trans_id1 = signal->theData[3];
560 req_struct.trans_id2 = signal->theData[4];
563 Tuple_header* tuple_ptr = (Tuple_header*)
564 get_ptr(&page, ®OperPtr.p->m_tuple_location, regTabPtr.p);
565 req_struct.m_tuple_ptr = tuple_ptr;
567 OperationrecPtr lastOperPtr;
568 lastOperPtr.i = tuple_ptr->m_operation_ptr_i;
569 c_operation_pool.
getPtr(lastOperPtr);
582 signal->theData[0] = 0;
583 signal->theData[1] = 0;
596 req_struct.no_fired_triggers = 0;
601 Uint32 save[2] = { lastOperPtr.p->nextActiveOp, lastOperPtr.p->prevActiveOp };
602 lastOperPtr.p->nextActiveOp = RNIL;
603 lastOperPtr.p->prevActiveOp = RNIL;
605 checkDeferredTriggers(&req_struct, lastOperPtr.p, regTabPtr.p,
false);
607 lastOperPtr.p->nextActiveOp = save[0];
608 lastOperPtr.p->prevActiveOp = save[1];
610 signal->theData[0] = 0;
611 signal->theData[1] = req_struct.no_fired_triggers;
624 Dbtup::checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
625 Operationrec *regOperPtr,
626 Tablerec *regTablePtr,
629 if (refToMain(req_struct->TC_ref) != DBTC) {
633 if (regOperPtr->op_struct.primary_replica)
635 if (! regTablePtr->afterInsertTriggers.isEmpty())
638 fireImmediateTriggers(req_struct,
639 regTablePtr->afterInsertTriggers,
644 if (! regTablePtr->deferredInsertTriggers.isEmpty())
646 checkDeferredTriggersDuringPrepare(req_struct,
647 regTablePtr->deferredInsertTriggers,
655 Dbtup::checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
656 Operationrec* regOperPtr,
657 Tablerec* regTablePtr,
660 if (refToMain(req_struct->TC_ref) != DBTC) {
664 if (regOperPtr->op_struct.primary_replica)
666 if (! regTablePtr->afterUpdateTriggers.isEmpty())
669 fireImmediateTriggers(req_struct,
670 regTablePtr->afterUpdateTriggers,
675 if (! regTablePtr->constraintUpdateTriggers.isEmpty())
678 fireImmediateTriggers(req_struct,
679 regTablePtr->constraintUpdateTriggers,
684 if (! regTablePtr->deferredUpdateTriggers.isEmpty())
687 checkDeferredTriggersDuringPrepare(req_struct,
688 regTablePtr->deferredUpdateTriggers,
696 Dbtup::checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
697 Operationrec* regOperPtr,
698 Tablerec* regTablePtr,
701 if (refToMain(req_struct->TC_ref) != DBTC) {
705 if (regOperPtr->op_struct.primary_replica)
707 if (! regTablePtr->afterDeleteTriggers.isEmpty())
709 fireImmediateTriggers(req_struct,
710 regTablePtr->afterDeleteTriggers,
715 if (! regTablePtr->deferredDeleteTriggers.isEmpty())
717 checkDeferredTriggersDuringPrepare(req_struct,
718 regTablePtr->deferredDeleteTriggers,
726 Dbtup::checkDeferredTriggersDuringPrepare(KeyReqStruct *req_struct,
728 Operationrec*
const regOperPtr,
733 triggerList.
first(trigPtr);
734 while (trigPtr.i != RNIL)
737 if (trigPtr.p->monitorAllAttributes ||
738 trigPtr.p->attributeMask.overlaps(req_struct->changeMask))
741 NoOfFiredTriggers::setDeferredBit(req_struct->no_fired_triggers);
756 void Dbtup::checkDeferredTriggers(KeyReqStruct *req_struct,
757 Operationrec* regOperPtr,
758 Tablerec* regTablePtr,
762 Uint32 save_type = regOperPtr->op_struct.op_type;
763 Tuple_header *save_ptr = req_struct->m_tuple_ptr;
770 req_struct->m_tuple_ptr =get_copy_tuple(®OperPtr->m_copy_tuple_location);
778 if (save_ptr->m_header_bits & Tuple_header::ALLOC) {
779 if (save_type == ZDELETE) {
785 regOperPtr->op_struct.op_type = ZINSERT;
787 else if (save_type == ZINSERT) {
792 regOperPtr->op_struct.op_type = ZUPDATE;
795 switch(regOperPtr->op_struct.op_type) {
798 deferred_list = ®TablePtr->deferredInsertTriggers;
799 constraint_list = ®TablePtr->afterInsertTriggers;
803 deferred_list = ®TablePtr->deferredDeleteTriggers;
804 constraint_list = ®TablePtr->afterDeleteTriggers;
808 deferred_list = ®TablePtr->deferredUpdateTriggers;
809 constraint_list = ®TablePtr->afterUpdateTriggers;
816 if (req_struct->m_deferred_constraints ==
false)
821 if (deferred_list->isEmpty() &&
822 (constraint_list == 0 || constraint_list->isEmpty()))
830 set_commit_change_mask_info(regTablePtr, req_struct, regOperPtr);
831 if (!deferred_list->isEmpty())
833 fireDeferredTriggers(req_struct, * deferred_list, regOperPtr, disk);
836 if (constraint_list && !constraint_list->isEmpty())
838 fireDeferredConstraints(req_struct, * constraint_list, regOperPtr, disk);
842 regOperPtr->op_struct.op_type = save_type;
843 req_struct->m_tuple_ptr = save_ptr;
855 void Dbtup::checkDetachedTriggers(KeyReqStruct *req_struct,
856 Operationrec* regOperPtr,
857 Tablerec* regTablePtr,
860 Uint32 save_type = regOperPtr->op_struct.op_type;
861 Tuple_header *save_ptr = req_struct->m_tuple_ptr;
867 req_struct->m_tuple_ptr =get_copy_tuple(®OperPtr->m_copy_tuple_location);
875 if (save_ptr->m_header_bits & Tuple_header::ALLOC) {
876 if (save_type == ZDELETE) {
882 else if (save_type != ZREFRESH)
884 regOperPtr->op_struct.op_type = ZINSERT;
887 else if (save_type == ZINSERT) {
892 regOperPtr->op_struct.op_type = ZUPDATE;
895 switch(regOperPtr->op_struct.op_type) {
898 if (regTablePtr->subscriptionInsertTriggers.isEmpty()) {
905 fireDetachedTriggers(req_struct,
906 regTablePtr->subscriptionInsertTriggers,
911 if (regTablePtr->subscriptionDeleteTriggers.isEmpty()) {
919 fireDetachedTriggers(req_struct,
920 regTablePtr->subscriptionDeleteTriggers,
925 if (regTablePtr->subscriptionUpdateTriggers.isEmpty()) {
933 fireDetachedTriggers(req_struct,
934 regTablePtr->subscriptionUpdateTriggers,
943 switch(regOperPtr->m_copy_tuple_location.m_file_no){
944 case Operationrec::RF_SINGLE_NOT_EXIST:
945 case Operationrec::RF_MULTI_NOT_EXIST:
946 fireDetachedTriggers(req_struct,
947 regTablePtr->subscriptionDeleteTriggers,
950 case Operationrec::RF_SINGLE_EXIST:
951 case Operationrec::RF_MULTI_EXIST:
952 fireDetachedTriggers(req_struct,
953 regTablePtr->subscriptionInsertTriggers,
966 regOperPtr->op_struct.op_type = save_type;
967 req_struct->m_tuple_ptr = save_ptr;
974 return trigPtr->
triggerType == TriggerType::SECONDARY_INDEX;
978 Dbtup::fireImmediateTriggers(KeyReqStruct *req_struct,
980 Operationrec*
const regOperPtr,
984 triggerList.
first(trigPtr);
985 while (trigPtr.i != RNIL) {
987 if (trigPtr.p->monitorAllAttributes ||
988 trigPtr.p->attributeMask.overlaps(req_struct->changeMask)) {
991 if (req_struct->m_when == KRS_PREPARE &&
992 req_struct->m_deferred_constraints &&
993 is_constraint(trigPtr.p))
995 NoOfFiredTriggers::setDeferredBit(req_struct->no_fired_triggers);
999 executeTrigger(req_struct,
1005 triggerList.
next(trigPtr);
1010 Dbtup::fireDeferredConstraints(KeyReqStruct *req_struct,
1012 Operationrec*
const regOperPtr,
1016 triggerList.
first(trigPtr);
1017 while (trigPtr.i != RNIL) {
1019 if (trigPtr.p->monitorAllAttributes ||
1020 trigPtr.p->attributeMask.overlaps(req_struct->changeMask)) {
1022 executeTrigger(req_struct,
1027 triggerList.
next(trigPtr);
1032 Dbtup::fireDeferredTriggers(KeyReqStruct *req_struct,
1034 Operationrec*
const regOperPtr,
1038 triggerList.
first(trigPtr);
1039 while (trigPtr.i != RNIL) {
1041 if (trigPtr.p->monitorAllAttributes ||
1042 trigPtr.p->attributeMask.overlaps(req_struct->changeMask)) {
1044 executeTrigger(req_struct,
1049 triggerList.
next(trigPtr);
1054 Dbtup::fireDetachedTriggers(KeyReqStruct *req_struct,
1056 Operationrec*
const regOperPtr,
1065 req_struct->m_disk_page_ptr.i = m_pgman_ptr.i;
1067 ndbrequire(regOperPtr->is_first_operation());
1068 triggerList.
first(trigPtr);
1069 while (trigPtr.i != RNIL) {
1071 if ((trigPtr.p->monitorReplicas ||
1072 regOperPtr->op_struct.primary_replica) &&
1073 (trigPtr.p->monitorAllAttributes ||
1074 trigPtr.p->attributeMask.overlaps(req_struct->changeMask))) {
1076 executeTrigger(req_struct,
1081 triggerList.
next(trigPtr);
1085 void Dbtup::executeTriggers(KeyReqStruct *req_struct,
1087 Operationrec* regOperPtr,
1091 triggerList.
first(trigPtr);
1092 while (trigPtr.i != RNIL) {
1094 executeTrigger(req_struct,
1098 triggerList.
next(trigPtr);
1104 Dbtup::check_fire_trigger(
const Fragrecord * fragPtrP,
1105 const TupTriggerData* trigPtrP,
1106 const KeyReqStruct * req_struct,
1107 const Operationrec * regOperPtr)
const
1111 if (trigPtrP->triggerType == TriggerType::SUBSCRIPTION_BEFORE)
1113 if (!check_fire_suma(req_struct, regOperPtr, fragPtrP))
1118 switch(fragPtrP->fragStatus){
1119 case Fragrecord::FS_REORG_NEW:
1122 case Fragrecord::FS_REORG_COMMIT:
1123 case Fragrecord::FS_REORG_COMPLETE:
1124 return req_struct->m_reorg == 0;
1131 Dbtup::check_fire_reorg(
const KeyReqStruct *req_struct,
1132 Fragrecord::FragState state)
const
1134 Uint32 flag = req_struct->m_reorg;
1136 case Fragrecord::FS_ONLINE:
1137 case Fragrecord::FS_REORG_COMMIT_NEW:
1138 case Fragrecord::FS_REORG_COMPLETE_NEW:
1146 case Fragrecord::FS_REORG_NEW:
1147 case Fragrecord::FS_REORG_COMMIT:
1148 case Fragrecord::FS_REORG_COMPLETE:
1156 Dbtup::check_fire_suma(
const KeyReqStruct *req_struct,
1157 const Operationrec* opPtrP,
1158 const Fragrecord* regFragPtrP)
const
1161 tablePtr.i = regFragPtrP->fragTableId;
1162 Fragrecord::FragState state = regFragPtrP->fragStatus;
1163 Uint32 gci_hi = req_struct->gci_hi;
1164 Uint32 flag = opPtrP->op_struct.m_reorg;
1167 case Fragrecord::FS_FREE:
1170 case Fragrecord::FS_ONLINE:
1173 case Fragrecord::FS_REORG_NEW:
1176 case Fragrecord::FS_REORG_COMMIT_NEW:
1179 case Fragrecord::FS_REORG_COMPLETE_NEW:
1182 case Fragrecord::FS_REORG_COMMIT:
1185 case Fragrecord::FS_REORG_COMPLETE:
1195 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
1196 if (gci_hi < tablePtr.p->m_reorg_suma_filter.m_gci_hi)
1206 Dbtup::getOldTriggerId(
const TupTriggerData* trigPtrP,
1211 return trigPtrP->oldTriggerIds[0];
1213 return trigPtrP->oldTriggerIds[1];
1215 return trigPtrP->oldTriggerIds[2];
1221 void Dbtup::executeTrigger(KeyReqStruct *req_struct,
1222 TupTriggerData*
const trigPtr,
1223 Operationrec*
const regOperPtr,
1226 Signal* signal= req_struct->signal;
1227 BlockReference ref = trigPtr->m_receiverRef;
1228 Uint32*
const keyBuffer = &cinBuffer[0];
1229 Uint32*
const afterBuffer = &coutBuffer[0];
1230 Uint32*
const beforeBuffer = &clogMemBuffer[0];
1231 Uint32 triggerType = trigPtr->triggerType;
1233 Uint32 noPrimKey, noAfterWords, noBeforeWords;
1234 FragrecordPtr regFragPtr;
1235 regFragPtr.i= regOperPtr->fragmentPtr;
1236 ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
1237 Fragrecord::FragState fragstatus = regFragPtr.p->fragStatus;
1239 if (refToMain(ref) == BACKUP)
1256 signal->theData[0] = trigPtr->triggerId;
1257 signal->theData[1] = regFragPtr.p->fragmentId;
1260 if (signal->theData[0] == 0) {
1267 else if (unlikely(triggerType == TriggerType::REORG_TRIGGER))
1269 if (!check_fire_reorg(req_struct, fragstatus))
1272 else if (unlikely(regFragPtr.p->fragStatus != Fragrecord::FS_ONLINE))
1274 if (!check_fire_trigger(regFragPtr.p, trigPtr, req_struct, regOperPtr))
1278 if (!readTriggerInfo(trigPtr,
1300 bool longsignal =
false;
1301 Uint32 triggerId = trigPtr->triggerId;
1303 trigAttrInfo->setConnectionPtr(req_struct->TC_index);
1304 trigAttrInfo->setTriggerId(trigPtr->triggerId);
1306 switch(triggerType) {
1307 case (TriggerType::SECONDARY_INDEX):
1313 Uint32 node = refToNode(req_struct->TC_ref);
1314 if (unlikely(node &&
getNodeInfo(node).m_version < MAKE_VERSION(6,4,0)))
1317 triggerId = getOldTriggerId(trigPtr, regOperPtr->op_struct.op_type);
1318 trigAttrInfo->setTriggerId(triggerId);
1322 case (TriggerType::REORG_TRIGGER):
1324 ref = req_struct->TC_ref;
1325 executeDirect =
false;
1327 case (TriggerType::SUBSCRIPTION):
1328 case (TriggerType::SUBSCRIPTION_BEFORE):
1331 ref = trigPtr->m_receiverRef;
1333 executeDirect = refToInstance(ref) == instance();
1336 longsignal = !executeDirect;
1337 ndbassert(refToNode(ref) == 0 || refToNode(ref) == getOwnNodeId());
1339 case (TriggerType::READ_ONLY_CONSTRAINT):
1340 terrorCode = ZREAD_ONLY_CONSTRAINT_VIOLATION;
1345 executeDirect=
false;
1349 if (ERROR_INSERTED(4030))
1351 terrorCode = ZREAD_ONLY_CONSTRAINT_VIOLATION;
1356 if (triggerType == TriggerType::SECONDARY_INDEX &&
1357 req_struct->m_when != KRS_PREPARE)
1359 ndbrequire(req_struct->m_deferred_constraints);
1360 if (req_struct->m_when == KRS_PRE_COMMIT0)
1362 switch(regOperPtr->op_struct.op_type){
1364 NoOfFiredTriggers::setDeferredBit(req_struct->no_fired_triggers);
1368 NoOfFiredTriggers::setDeferredBit(req_struct->no_fired_triggers);
1379 ndbrequire(req_struct->m_when == KRS_PRE_COMMIT1);
1380 switch(regOperPtr->op_struct.op_type){
1394 req_struct->no_fired_triggers++;
1396 if (longsignal ==
false)
1400 trigAttrInfo->setAttrInfoType(TrigAttrInfo::PRIMARY_KEY);
1401 sendTrigAttrInfo(signal, keyBuffer, noPrimKey, executeDirect, ref);
1403 switch(regOperPtr->op_struct.op_type) {
1408 trigAttrInfo->setAttrInfoType(TrigAttrInfo::AFTER_VALUES);
1409 sendTrigAttrInfo(signal, afterBuffer, noAfterWords, executeDirect, ref);
1413 if (trigPtr->sendBeforeValues) {
1415 trigAttrInfo->setAttrInfoType(TrigAttrInfo::BEFORE_VALUES);
1416 sendTrigAttrInfo(signal, beforeBuffer, noBeforeWords, executeDirect,ref);
1421 if (trigPtr->sendBeforeValues) {
1423 trigAttrInfo->setAttrInfoType(TrigAttrInfo::BEFORE_VALUES);
1424 sendTrigAttrInfo(signal, beforeBuffer, noBeforeWords, executeDirect,ref);
1426 trigAttrInfo->setAttrInfoType(TrigAttrInfo::AFTER_VALUES);
1427 sendTrigAttrInfo(signal, afterBuffer, noAfterWords, executeDirect, ref);
1432 switch(regOperPtr->m_copy_tuple_location.m_file_no){
1433 case Operationrec::RF_SINGLE_NOT_EXIST:
1435 case Operationrec::RF_MULTI_NOT_EXIST:
1438 case Operationrec::RF_SINGLE_EXIST:
1440 case Operationrec::RF_MULTI_EXIST:
1456 fireTrigOrd->setConnectionPtr(req_struct->TC_index);
1457 fireTrigOrd->setTriggerId(triggerId);
1458 fireTrigOrd->fragId= regFragPtr.p->fragmentId;
1460 switch(regOperPtr->op_struct.op_type) {
1463 fireTrigOrd->m_triggerEvent = TriggerEvent::TE_INSERT;
1467 fireTrigOrd->m_triggerEvent = TriggerEvent::TE_UPDATE;
1471 fireTrigOrd->m_triggerEvent = TriggerEvent::TE_DELETE;
1475 switch(regOperPtr->m_copy_tuple_location.m_file_no){
1476 case Operationrec::RF_SINGLE_NOT_EXIST:
1478 case Operationrec::RF_MULTI_NOT_EXIST:
1480 fireTrigOrd->m_triggerEvent = TriggerEvent::TE_DELETE;
1482 case Operationrec::RF_SINGLE_EXIST:
1484 case Operationrec::RF_MULTI_EXIST:
1486 fireTrigOrd->m_triggerEvent = TriggerEvent::TE_INSERT;
1497 fireTrigOrd->setNoOfPrimaryKeyWords(noPrimKey);
1498 fireTrigOrd->setNoOfBeforeValueWords(noBeforeWords);
1499 fireTrigOrd->setNoOfAfterValueWords(noAfterWords);
1501 switch(trigPtr->triggerType) {
1502 case (TriggerType::SECONDARY_INDEX):
1503 case (TriggerType::REORG_TRIGGER):
1505 fireTrigOrd->m_triggerType = trigPtr->triggerType;
1506 fireTrigOrd->m_transId1 = req_struct->trans_id1;
1507 fireTrigOrd->m_transId2 = req_struct->trans_id2;
1508 sendSignal(req_struct->TC_ref, GSN_FIRE_TRIG_ORD,
1509 signal, FireTrigOrd::SignalLength, JBB);
1511 case (TriggerType::SUBSCRIPTION_BEFORE):
1513 fireTrigOrd->m_transId1 = req_struct->trans_id1;
1514 fireTrigOrd->m_transId2 = req_struct->trans_id2;
1515 fireTrigOrd->setGCI(req_struct->gci_hi);
1516 fireTrigOrd->setHashValue(req_struct->hash_value);
1517 fireTrigOrd->m_any_value = regOperPtr->m_any_value;
1518 fireTrigOrd->m_gci_lo = req_struct->gci_lo;
1525 FireTrigOrd::SignalLengthSuma);
1530 ndbassert(longsignal);
1532 ptr[0].p = keyBuffer;
1533 ptr[0].sz = noPrimKey;
1534 ptr[1].p = beforeBuffer;
1535 ptr[1].sz = noBeforeWords;
1536 ptr[2].p = afterBuffer;
1537 ptr[2].sz = noAfterWords;
1538 if (refToMain(ref) == SUMA && (refToInstance(ref) != instance()))
1541 ndbmtd_buffer_suma_trigger(signal, FireTrigOrd::SignalLengthSuma, ptr);
1546 sendSignal(ref, GSN_FIRE_TRIG_ORD,
1547 signal, FireTrigOrd::SignalLengthSuma, JBB, ptr, 3);
1551 case (TriggerType::SUBSCRIPTION):
1555 fireTrigOrd->setGCI(req_struct->gci_hi);
1563 FireTrigOrd::SignalWithGCILength);
1570 ndbassert(longsignal);
1572 ptr[0].p = keyBuffer;
1573 ptr[0].sz = noPrimKey;
1574 ptr[1].p = beforeBuffer;
1575 ptr[1].sz = noBeforeWords;
1576 ptr[2].p = afterBuffer;
1577 ptr[2].sz = noAfterWords;
1578 sendSignal(ref, GSN_FIRE_TRIG_ORD,
1579 signal, FireTrigOrd::SignalWithGCILength, JBB, ptr, 3);
1589 Uint32 m_no_of_attributesibutes,
1593 for (Uint32 i = 0; i < m_no_of_attributesibutes; i++) {
1595 if (attributeMask.
get(i)) {
1603 bool Dbtup::readTriggerInfo(TupTriggerData*
const trigPtr,
1604 Operationrec*
const regOperPtr,
1605 KeyReqStruct *req_struct,
1606 Fragrecord*
const regFragPtr,
1607 Uint32*
const keyBuffer,
1609 Uint32*
const afterBuffer,
1610 Uint32& noAfterWords,
1611 Uint32*
const beforeBuffer,
1612 Uint32& noBeforeWords,
1617 Uint32 readBuffer[MAX_ATTRIBUTES_IN_TABLE];
1624 operPtr.p = regOperPtr;
1625 tabptr.i = regFragPtr->fragTableId;
1626 ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
1628 Tablerec*
const regTabPtr = tabptr.p;
1630 Uint32 descr_start= regTabPtr->tabDescriptor;
1631 ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
1633 req_struct->tablePtrP = regTabPtr;
1634 req_struct->operPtrP = regOperPtr;
1635 req_struct->check_offset[MM]= regTabPtr->get_check_offset(MM);
1636 req_struct->check_offset[DD]= regTabPtr->get_check_offset(DD);
1637 req_struct->attr_descr= &tableDescriptor[descr_start];
1642 Tuple_header *save0= req_struct->m_tuple_ptr;
1643 if (regOperPtr->op_struct.op_type == ZDELETE &&
1644 !regOperPtr->is_first_operation())
1647 req_struct->m_tuple_ptr=
1648 get_copy_tuple(&req_struct->prevOpPtr.p->m_copy_tuple_location);
1651 if (regTabPtr->need_expand(disk))
1652 prepare_read(req_struct, regTabPtr, disk);
1654 int ret = readAttributes(req_struct,
1655 &tableDescriptor[regTabPtr->readKeyArray].tabDescr,
1656 regTabPtr->noOfKeyAttr,
1660 ndbrequire(ret >= 0);
1663 req_struct->m_tuple_ptr = save0;
1665 Uint32 numAttrsToRead;
1666 if ((regOperPtr->op_struct.op_type == ZUPDATE) &&
1667 (trigPtr->sendOnlyChangedAttributes)) {
1673 attributeMask = trigPtr->attributeMask;
1674 attributeMask.
bitAND(req_struct->changeMask);
1675 numAttrsToRead = setAttrIds(attributeMask, regTabPtr->m_no_of_attributes,
1678 }
else if ((regOperPtr->op_struct.op_type == ZDELETE) &&
1679 (!trigPtr->sendBeforeValues)) {
1685 }
else if (regOperPtr->op_struct.op_type != ZREFRESH){
1693 attributeMask = trigPtr->attributeMask;
1694 if (regOperPtr->op_struct.op_type == ZUPDATE) {
1696 tmpMask.
bitANDC(req_struct->changeMask);
1697 attributeMask.
bitANDC(tmpMask);
1699 numAttrsToRead = setAttrIds(attributeMask, regTabPtr->m_no_of_attributes,
1705 ndbassert(regOperPtr->op_struct.op_type == ZREFRESH);
1707 switch(regOperPtr->m_copy_tuple_location.m_file_no){
1708 case Operationrec::RF_SINGLE_NOT_EXIST:
1709 case Operationrec::RF_MULTI_NOT_EXIST:
1711 case Operationrec::RF_SINGLE_EXIST:
1712 case Operationrec::RF_MULTI_EXIST:
1714 numAttrsToRead = setAttrIds(trigPtr->attributeMask,
1715 regTabPtr->m_no_of_attributes,
1723 ndbrequire(numAttrsToRead <= MAX_ATTRIBUTES_IN_TABLE);
1727 if (regOperPtr->op_struct.op_type != ZDELETE)
1730 int ret = readAttributes(req_struct,
1736 ndbrequire(ret >= 0);
1748 if ((regOperPtr->op_struct.op_type == ZUPDATE ||
1749 regOperPtr->op_struct.op_type == ZDELETE) &&
1750 (trigPtr->sendBeforeValues)) {
1753 Tuple_header *save= req_struct->m_tuple_ptr;
1755 if(regOperPtr->is_first_operation())
1757 Uint32 *ptr= get_ptr(&tmp, ®OperPtr->m_tuple_location, regTabPtr);
1758 req_struct->m_tuple_ptr= (Tuple_header*)ptr;
1762 req_struct->m_tuple_ptr =
1763 get_copy_tuple(&req_struct->prevOpPtr.p->m_copy_tuple_location);
1766 if (regTabPtr->need_expand(disk))
1767 prepare_read(req_struct, regTabPtr, disk);
1769 int ret = readAttributes(req_struct,
1775 req_struct->m_tuple_ptr= save;
1776 ndbrequire(ret >= 0);
1777 noBeforeWords =
ret;
1778 if (refToMain(trigPtr->m_receiverRef) != SUMA &&
1779 (noAfterWords == noBeforeWords) &&
1780 (memcmp(afterBuffer, beforeBuffer, noAfterWords << 2) == 0)) {
1793 void Dbtup::sendTrigAttrInfo(
Signal* signal,
1797 BlockReference receiverReference)
1801 Uint32 dataIndex = 0;
1803 sigLen = dataLen - dataIndex;
1804 if (sigLen > TrigAttrInfo::DataLength) {
1806 sigLen = TrigAttrInfo::DataLength;
1808 MEMCOPY_NO_WORDS(trigAttrInfo->getData(),
1811 if (executeDirect) {
1816 TrigAttrInfo::StaticLength + sigLen);
1820 sendSignal(receiverReference,
1823 TrigAttrInfo::StaticLength + sigLen,
1826 dataIndex += sigLen;
1827 }
while (dataLen != dataIndex);
1843 Dbtup::executeTuxInsertTriggers(
Signal* signal,
1844 Operationrec* regOperPtr,
1845 Fragrecord* regFragPtr,
1846 Tablerec* regTabPtr)
1850 req->tableId = regFragPtr->fragTableId;
1851 req->fragId = regFragPtr->fragmentId;
1852 req->pageId = regOperPtr->m_tuple_location.m_page_no;
1853 req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
1854 req->tupVersion = regOperPtr->tupVersion;
1855 req->opInfo = TuxMaintReq::OpAdd;
1856 return addTuxEntries(signal, regOperPtr, regTabPtr);
1860 Dbtup::executeTuxUpdateTriggers(
Signal* signal,
1861 Operationrec* regOperPtr,
1862 Fragrecord* regFragPtr,
1863 Tablerec* regTabPtr)
1867 req->tableId = regFragPtr->fragTableId;
1868 req->fragId = regFragPtr->fragmentId;
1869 req->pageId = regOperPtr->m_tuple_location.m_page_no;
1870 req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
1871 req->tupVersion = regOperPtr->tupVersion;
1872 req->opInfo = TuxMaintReq::OpAdd;
1873 return addTuxEntries(signal, regOperPtr, regTabPtr);
1877 Dbtup::addTuxEntries(
Signal* signal,
1878 Operationrec* regOperPtr,
1879 Tablerec* regTabPtr)
1881 if (ERROR_INSERTED(4022)) {
1883 CLEAR_ERROR_INSERT_VALUE;
1889 TriggerPtr triggerPtr;
1891 triggerList.
first(triggerPtr);
1892 while (triggerPtr.i != RNIL) {
1894 req->indexId = triggerPtr.p->indexId;
1895 req->errorCode = RNIL;
1896 if (ERROR_INSERTED(4023) &&
1897 ! triggerList.
hasNext(triggerPtr)) {
1899 CLEAR_ERROR_INSERT_VALUE;
1901 failPtrI = triggerPtr.i;
1905 signal, TuxMaintReq::SignalLength);
1907 if (req->errorCode != 0) {
1909 terrorCode = req->errorCode;
1910 failPtrI = triggerPtr.i;
1913 triggerList.
next(triggerPtr);
1917 req->opInfo = TuxMaintReq::OpRemove;
1918 triggerList.
first(triggerPtr);
1919 while (triggerPtr.i != failPtrI) {
1921 req->indexId = triggerPtr.p->indexId;
1922 req->errorCode = RNIL;
1924 signal, TuxMaintReq::SignalLength);
1926 ndbrequire(req->errorCode == 0);
1927 triggerList.
next(triggerPtr);
1930 ndbout <<
"aborted partial tux update: op " << hex << regOperPtr << endl;
1936 Dbtup::executeTuxDeleteTriggers(
Signal* signal,
1937 Operationrec*
const regOperPtr,
1938 Fragrecord*
const regFragPtr,
1939 Tablerec*
const regTabPtr)
1946 Dbtup::executeTuxCommitTriggers(
Signal* signal,
1947 Operationrec* regOperPtr,
1948 Fragrecord* regFragPtr,
1949 Tablerec* regTabPtr)
1953 if (regOperPtr->op_struct.op_type == ZINSERT) {
1954 if (! regOperPtr->op_struct.delete_insert_flag)
1957 tupVersion= decr_tup_version(regOperPtr->tupVersion);
1958 }
else if (regOperPtr->op_struct.op_type == ZUPDATE) {
1960 tupVersion= decr_tup_version(regOperPtr->tupVersion);
1961 }
else if (regOperPtr->op_struct.op_type == ZDELETE) {
1962 if (regOperPtr->op_struct.delete_insert_flag)
1965 tupVersion= regOperPtr->tupVersion;
1966 }
else if (regOperPtr->op_struct.op_type == ZREFRESH) {
1974 req->tableId = regFragPtr->fragTableId;
1975 req->fragId = regFragPtr->fragmentId;
1976 req->pageId = regOperPtr->m_tuple_location.m_page_no;
1977 req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
1978 req->tupVersion = tupVersion;
1979 req->opInfo = TuxMaintReq::OpRemove;
1980 removeTuxEntries(signal, regTabPtr);
1984 Dbtup::executeTuxAbortTriggers(
Signal* signal,
1985 Operationrec* regOperPtr,
1986 Fragrecord* regFragPtr,
1987 Tablerec* regTabPtr)
1992 if (regOperPtr->op_struct.op_type == ZINSERT) {
1994 tupVersion = regOperPtr->tupVersion;
1995 }
else if (regOperPtr->op_struct.op_type == ZUPDATE) {
1997 tupVersion = regOperPtr->tupVersion;
1998 }
else if (regOperPtr->op_struct.op_type == ZDELETE) {
2001 }
else if (regOperPtr->op_struct.op_type == ZREFRESH) {
2010 req->tableId = regFragPtr->fragTableId;
2011 req->fragId = regFragPtr->fragmentId;
2012 req->pageId = regOperPtr->m_tuple_location.m_page_no;
2013 req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
2014 req->tupVersion = tupVersion;
2015 req->opInfo = TuxMaintReq::OpRemove;
2016 removeTuxEntries(signal, regTabPtr);
2020 Dbtup::removeTuxEntries(
Signal* signal,
2021 Tablerec* regTabPtr)
2025 TriggerPtr triggerPtr;
2026 triggerList.
first(triggerPtr);
2027 while (triggerPtr.i != RNIL) {
2029 req->indexId = triggerPtr.p->indexId;
2030 req->errorCode = RNIL,
2032 signal, TuxMaintReq::SignalLength);
2035 ndbrequire(req->errorCode == 0);
2036 triggerList.
next(triggerPtr);
2041 Dbtup::ndbmtd_buffer_suma_trigger(
Signal * signal,
2046 Uint32 tot = len + 5;
2047 for (Uint32 i = 0; i<3; i++)
2051 Uint32 free = m_suma_trigger_buffer.m_freeWords;
2052 Uint32 pageId = m_suma_trigger_buffer.m_pageId;
2053 Uint32 oom = m_suma_trigger_buffer.m_out_of_memory;
2059 flush_ndbmtd_suma_buffer(signal);
2064 ndbassert(m_suma_trigger_buffer.m_pageId == RNIL);
2065 void * vptr = m_ctx.m_mm.alloc_page(RT_DBTUP_PAGE,
2066 &m_suma_trigger_buffer.m_pageId,
2067 Ndbd_mem_manager::NDB_ZONE_ANY);
2068 ptr =
reinterpret_cast<Uint32*
>(vptr);
2069 free = GLOBAL_PAGE_SIZE_WORDS - tot;
2075 ptr =
reinterpret_cast<Uint32*
>(c_page_pool.
getPtr(pageId));
2076 ptr += (GLOBAL_PAGE_SIZE_WORDS - free);
2080 if (likely(ptr != 0))
2085 * ptr++ = sec[0].sz;
2086 * ptr++ = sec[1].sz;
2087 * ptr++ = sec[2].sz;
2088 memcpy(ptr, signal->getDataPtrSend(), 4 * len);
2090 for (Uint32 i = 0; i<3; i++)
2092 memcpy(ptr, sec[i].p, 4 * sec[i].sz);
2096 m_suma_trigger_buffer.m_freeWords = free;
2097 if (free < (len + 5))
2099 flush_ndbmtd_suma_buffer(signal);
2105 m_suma_trigger_buffer.m_out_of_memory = 1;
2110 Dbtup::flush_ndbmtd_suma_buffer(
Signal* signal)
2114 Uint32 pageId = m_suma_trigger_buffer.m_pageId;
2115 Uint32 free = m_suma_trigger_buffer.m_freeWords;
2116 Uint32 oom = m_suma_trigger_buffer.m_out_of_memory;
2122 save[0] = signal->theData[0];
2123 save[1] = signal->theData[1];
2124 signal->theData[0] = pageId;
2125 signal->theData[1] = GLOBAL_PAGE_SIZE_WORDS - free;
2126 sendSignal(SUMA_REF, GSN_FIRE_TRIG_ORD_L, signal, 2, JBB);
2128 signal->theData[0] = save[0];
2129 signal->theData[1] = save[1];
2135 save[0] = signal->theData[0];
2136 save[1] = signal->theData[1];
2137 signal->theData[0] = RNIL;
2138 signal->theData[1] = 0;
2139 sendSignal(SUMA_REF, GSN_FIRE_TRIG_ORD_L, signal, 2, JBB);
2141 signal->theData[0] = save[0];
2142 signal->theData[1] = save[1];
2145 m_suma_trigger_buffer.m_pageId = RNIL;
2146 m_suma_trigger_buffer.m_freeWords = 0;
2147 m_suma_trigger_buffer.m_out_of_memory = 0;
2151 Dbtup::execSUB_GCP_COMPLETE_REP(
Signal* signal)
2153 flush_ndbmtd_suma_buffer(signal);