Dbdict.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:368k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1.  *
  2.  * NdbEventOperation, reading systable, creating event in suma
  3.  *
  4.  */
  5. void
  6. Dbdict::createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
  7.   jam();
  8.   EVENT_TRACE;
  9. #ifdef EVENT_PH2_DEBUG
  10.   ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REQ::RT_USER_GET evntRecPtr.i = (%d), ref = %u", evntRecPtr.i, evntRecPtr.p->m_request.getUserRef());
  11. #endif
  12.   SegmentedSectionPtr ssPtr;
  13.   signal->getSection(ssPtr, 0);
  14.   SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
  15. #ifdef EVENT_DEBUG
  16.   r0.printAll(ndbout);
  17. #endif
  18.   if ((!r0.first()) ||
  19.       (r0.getValueType() != SimpleProperties::StringValue) ||
  20.       (r0.getValueLen() <= 0)) {
  21.     jam();
  22.     releaseSections(signal);
  23.     evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  24.     evntRecPtr.p->m_errorLine = __LINE__;
  25.     evntRecPtr.p->m_errorNode = reference();
  26.     createEvent_sendReply(signal, evntRecPtr);
  27.     return;
  28.   }
  29.   r0.getString(evntRecPtr.p->m_eventRec.NAME);
  30.   int len = strlen(evntRecPtr.p->m_eventRec.NAME);
  31.   memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
  32.   
  33.   releaseSections(signal);
  34.   
  35.   Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
  36.   
  37.   prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
  38.   UtilPrepareReq::Read);
  39.   /* 
  40.    * Will read systable and fill an OpCreateEventPtr
  41.    * and return below
  42.    */
  43. }
  44. void
  45. Dbdict::createEventComplete_RT_USER_GET(Signal* signal,
  46. OpCreateEventPtr evntRecPtr){
  47.   jam();
  48.   // Send to oneself and the other DICT's
  49.   CreateEvntReq * req = (CreateEvntReq *)signal->getDataPtrSend();
  50.       
  51.   *req = evntRecPtr.p->m_request;
  52.   req->senderRef = reference();
  53.   req->senderData = evntRecPtr.i;
  54.       
  55.   req->addRequestFlag(CreateEvntReq::RT_DICT_AFTER_GET);
  56.       
  57. #ifdef EVENT_PH2_DEBUG
  58.   ndbout_c("DBDICT(Coordinator) sending GSN_CREATE_EVNT_REQ::RT_DICT_AFTER_GET to DBDICT participants evntRecPtr.i = (%d)", evntRecPtr.i);
  59. #endif
  60.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  61.   RequestTracker & p = evntRecPtr.p->m_reqTracker;
  62.   p.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, evntRecPtr.i);
  63.   sendSignal(rg, GSN_CREATE_EVNT_REQ, signal, CreateEvntReq::SignalLength, JBB);
  64. }
  65. void
  66. Dbdict::createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI,
  67.      Uint32 returnCode){
  68.   OpCreateEventPtr evntRecPtr;
  69.   c_opCreateEvent.getPtr(evntRecPtr, eventRecPtrI);
  70.   createEvent_sendReply(signal, evntRecPtr);
  71. }
  72. void Dbdict::execCREATE_EVNT_REF(Signal* signal) 
  73. {
  74.   jamEntry();      
  75.   EVENT_TRACE;
  76.   CreateEvntRef * const ref = (CreateEvntRef *)signal->getDataPtr();
  77.   OpCreateEventPtr evntRecPtr;
  78.   evntRecPtr.i = ref->getUserData();
  79.   ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  80. #ifdef EVENT_PH2_DEBUG
  81.   ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REF evntRecPtr.i = (%d)", evntRecPtr.i);
  82. #endif
  83.   if (ref->errorCode == CreateEvntRef::NF_FakeErrorREF){
  84.     jam();
  85.     evntRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(ref->senderRef));
  86.   } else {
  87.     jam();
  88.     evntRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(ref->senderRef));
  89.   }
  90.   createEvent_sendReply(signal, evntRecPtr);
  91.   return;
  92. }
  93. void Dbdict::execCREATE_EVNT_CONF(Signal* signal)
  94. {
  95.   jamEntry();
  96.   EVENT_TRACE;
  97.   CreateEvntConf * const conf = (CreateEvntConf *)signal->getDataPtr();
  98.   OpCreateEventPtr evntRecPtr;
  99.   evntRecPtr.i = conf->getUserData();
  100.   ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  101. #ifdef EVENT_PH2_DEBUG
  102.   ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_CONF evntRecPtr.i = (%d)", evntRecPtr.i);
  103. #endif
  104.   evntRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(conf->senderRef));
  105.   // we will only have a valid tablename if it the master DICT sending this
  106.   // but that's ok
  107.   LinearSectionPtr ptr[1];
  108.   ptr[0].p = (Uint32 *)evntRecPtr.p->m_eventRec.TABLE_NAME;
  109.   ptr[0].sz =
  110.     (strlen(evntRecPtr.p->m_eventRec.TABLE_NAME)+4)/4; // to make sure we have a null
  111.   createEvent_sendReply(signal, evntRecPtr, ptr, 1);
  112.     
  113.   return;
  114. }
  115. /************************************************
  116.  *
  117.  * Participant stuff
  118.  *
  119.  */
  120. void
  121. Dbdict::createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
  122.   jam();
  123.   evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
  124.   
  125. #ifdef EVENT_PH2_DEBUG
  126.   ndbout_c("DBDICT(Participant) got CREATE_EVNT_REQ::RT_DICT_AFTER_GET evntRecPtr.i = (%d)", evntRecPtr.i);
  127. #endif
  128.   // the signal comes from the DICT block that got the first user request!
  129.   // This code runs on all DICT nodes, including oneself
  130.   // Seize a Create Event record, the Coordinator will now have two seized
  131.   // but that's ok, it's like a recursion
  132.   SubCreateReq * sumaReq = (SubCreateReq *)signal->getDataPtrSend();
  133.   
  134.   sumaReq->subscriberRef    = reference(); // reference to DICT
  135.   sumaReq->subscriberData   = evntRecPtr.i;
  136.   sumaReq->subscriptionId   = evntRecPtr.p->m_request.getEventId();
  137.   sumaReq->subscriptionKey  = evntRecPtr.p->m_request.getEventKey();
  138.   sumaReq->subscriptionType = SubCreateReq::TableEvent;
  139.   sumaReq->tableId          = evntRecPtr.p->m_request.getTableId();
  140.     
  141. #ifdef EVENT_PH2_DEBUG
  142.   ndbout_c("sending GSN_SUB_CREATE_REQ");
  143. #endif
  144.   sendSignal(SUMA_REF, GSN_SUB_CREATE_REQ, signal,
  145.      SubCreateReq::SignalLength+1 /*to get table Id*/, JBB);
  146. }
  147. void Dbdict::execSUB_CREATE_REF(Signal* signal)
  148. {
  149.   jamEntry();
  150.   EVENT_TRACE;
  151.   SubCreateRef * const ref = (SubCreateRef *)signal->getDataPtr();
  152.   OpCreateEventPtr evntRecPtr;
  153.   evntRecPtr.i = ref->subscriberData;
  154.   ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  155. #ifdef EVENT_PH2_DEBUG
  156.   ndbout_c("DBDICT(Participant) got SUB_CREATE_REF evntRecPtr.i = (%d)", evntRecPtr.i);
  157. #endif
  158.   if (ref->err == GrepError::SUBSCRIPTION_ID_NOT_UNIQUE) {
  159.     jam();
  160. #ifdef EVENT_PH2_DEBUG
  161.     ndbout_c("SUBSCRIPTION_ID_NOT_UNIQUE");
  162. #endif
  163.     createEvent_sendReply(signal, evntRecPtr);
  164.     return;
  165.   }
  166. #ifdef EVENT_PH2_DEBUG
  167.     ndbout_c("Other error");
  168. #endif
  169.   evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  170.   evntRecPtr.p->m_errorLine = __LINE__;
  171.   evntRecPtr.p->m_errorNode = reference();
  172.   createEvent_sendReply(signal, evntRecPtr);
  173. }
  174. void Dbdict::execSUB_CREATE_CONF(Signal* signal)
  175. {
  176.   jamEntry();
  177.   EVENT_TRACE;
  178.   SubCreateConf * const sumaConf = (SubCreateConf *)signal->getDataPtr();
  179.   const Uint32 subscriptionId  = sumaConf->subscriptionId;
  180.   const Uint32 subscriptionKey = sumaConf->subscriptionKey;
  181.   const Uint32 evntRecId       = sumaConf->subscriberData;
  182.   OpCreateEvent *evntRec;
  183.   ndbrequire((evntRec = c_opCreateEvent.getPtr(evntRecId)) != NULL);
  184. #ifdef EVENT_PH2_DEBUG
  185.   ndbout_c("DBDICT(Participant) got SUB_CREATE_CONF evntRecPtr.i = (%d)", evntRecId);
  186. #endif
  187.   SubSyncReq *sumaSync = (SubSyncReq *)signal->getDataPtrSend();
  188.   sumaSync->subscriptionId = subscriptionId;
  189.   sumaSync->subscriptionKey = subscriptionKey;
  190.   sumaSync->part = (Uint32) SubscriptionData::MetaData;
  191.   sumaSync->subscriberData = evntRecId;
  192.   sendSignal(SUMA_REF, GSN_SUB_SYNC_REQ, signal,
  193.      SubSyncReq::SignalLength, JBB);
  194. }
  195. void Dbdict::execSUB_SYNC_REF(Signal* signal)
  196. {
  197.   jamEntry();
  198.   EVENT_TRACE;
  199.   SubSyncRef * const ref = (SubSyncRef *)signal->getDataPtr();
  200.   OpCreateEventPtr evntRecPtr;
  201.   evntRecPtr.i = ref->subscriberData;
  202.   ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  203.   evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  204.   evntRecPtr.p->m_errorLine = __LINE__;
  205.   evntRecPtr.p->m_errorNode = reference();
  206.   createEvent_sendReply(signal, evntRecPtr);
  207. }
  208. void Dbdict::execSUB_SYNC_CONF(Signal* signal) 
  209. {
  210.   jamEntry();
  211.   EVENT_TRACE;
  212.   SubSyncConf * const sumaSyncConf = (SubSyncConf *)signal->getDataPtr();
  213.   //  Uint32 subscriptionId = sumaSyncConf->subscriptionId;
  214.   //  Uint32 subscriptionKey = sumaSyncConf->subscriptionKey;
  215.   OpCreateEventPtr evntRecPtr;
  216.   evntRecPtr.i = sumaSyncConf->subscriberData;
  217.   ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
  218.   ndbrequire(sumaSyncConf->part == (Uint32)SubscriptionData::MetaData);
  219.   createEvent_sendReply(signal, evntRecPtr);
  220. }
  221. /****************************************************
  222.  *
  223.  * common create reply method
  224.  *
  225.  *******************************************************/
  226. void Dbdict::createEvent_sendReply(Signal* signal,
  227.    OpCreateEventPtr evntRecPtr,
  228.    LinearSectionPtr *ptr, int noLSP)
  229. {
  230.   jam();
  231.   EVENT_TRACE;
  232.   // check if we're ready to sent reply
  233.   // if we are the master dict we might be waiting for conf/ref
  234.   if (!evntRecPtr.p->m_reqTracker.done()) {
  235.     jam();
  236.     return; // there's more to come
  237.   }
  238.   if (evntRecPtr.p->m_reqTracker.hasRef()) {
  239.     ptr = NULL; // we don't want to return anything if there's an error
  240.     if (!evntRecPtr.p->hasError()) {
  241.       evntRecPtr.p->m_errorCode = CreateEvntRef::Undefined;
  242.       evntRecPtr.p->m_errorLine = __LINE__;
  243.       evntRecPtr.p->m_errorNode = reference();
  244.       jam();
  245.     } else 
  246.       jam();
  247.   }
  248.   // reference to API if master DICT
  249.   // else reference to master DICT
  250.   Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
  251.   Uint32 signalLength;
  252.   Uint32 gsn;
  253.   if (evntRecPtr.p->hasError()) {
  254.     jam();
  255.     EVENT_TRACE;
  256.     CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
  257.     
  258.     ret->setEventId(evntRecPtr.p->m_request.getEventId());
  259.     ret->setEventKey(evntRecPtr.p->m_request.getEventKey());
  260.     ret->setUserData(evntRecPtr.p->m_request.getUserData());
  261.     ret->senderRef = reference();
  262.     ret->setTableId(evntRecPtr.p->m_request.getTableId());
  263.     ret->setEventType(evntRecPtr.p->m_request.getEventType());
  264.     ret->setRequestType(evntRecPtr.p->m_request.getRequestType());
  265.     ret->setErrorCode(evntRecPtr.p->m_errorCode);
  266.     ret->setErrorLine(evntRecPtr.p->m_errorLine);
  267.     ret->setErrorNode(evntRecPtr.p->m_errorNode);
  268.     signalLength = CreateEvntRef::SignalLength;
  269. #ifdef EVENT_PH2_DEBUG
  270.     ndbout_c("DBDICT sending GSN_CREATE_EVNT_REF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
  271.     ndbout_c("errorCode = %u", evntRecPtr.p->m_errorCode);
  272.     ndbout_c("errorLine = %u", evntRecPtr.p->m_errorLine);
  273. #endif
  274.     gsn = GSN_CREATE_EVNT_REF;
  275.   } else {
  276.     jam();
  277.     EVENT_TRACE;
  278.     CreateEvntConf * evntConf = (CreateEvntConf *)signal->getDataPtrSend();
  279.     
  280.     evntConf->setEventId(evntRecPtr.p->m_request.getEventId());
  281.     evntConf->setEventKey(evntRecPtr.p->m_request.getEventKey());
  282.     evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
  283.     evntConf->senderRef = reference();
  284.     evntConf->setTableId(evntRecPtr.p->m_request.getTableId());
  285.     evntConf->setAttrListBitmask(evntRecPtr.p->m_request.getAttrListBitmask());
  286.     evntConf->setEventType(evntRecPtr.p->m_request.getEventType());
  287.     evntConf->setRequestType(evntRecPtr.p->m_request.getRequestType());
  288.     signalLength = CreateEvntConf::SignalLength;
  289. #ifdef EVENT_PH2_DEBUG
  290.     ndbout_c("DBDICT sending GSN_CREATE_EVNT_CONF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
  291. #endif
  292.     gsn = GSN_CREATE_EVNT_CONF;
  293.   }
  294.   if (ptr) {
  295.     jam();
  296.     sendSignal(senderRef, gsn, signal, signalLength, JBB, ptr, noLSP);
  297.   } else {
  298.     jam();
  299.     sendSignal(senderRef, gsn, signal, signalLength, JBB);
  300.   }
  301.   c_opCreateEvent.release(evntRecPtr);
  302. }
  303. /*************************************************************/
  304. /********************************************************************
  305.  *
  306.  * Start event
  307.  *
  308.  *******************************************************************/
  309. void Dbdict::execSUB_START_REQ(Signal* signal)
  310. {
  311.   jamEntry();
  312.   Uint32 origSenderRef = signal->senderBlockRef();
  313.   OpSubEventPtr subbPtr;
  314.   if (!c_opSubEvent.seize(subbPtr)) {
  315.     SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
  316.     { // fix
  317.       Uint32 subcriberRef = ((SubStartReq*)signal->getDataPtr())->subscriberRef;
  318.       ref->subscriberRef = subcriberRef;
  319.     }
  320.     jam();
  321.     //      ret->setErrorCode(SubStartRef::SeizeError);
  322.     //      ret->setErrorLine(__LINE__);
  323.     //      ret->setErrorNode(reference());
  324.     ref->senderRef = reference();
  325.     ref->setTemporary(SubStartRef::Busy);
  326.     sendSignal(origSenderRef, GSN_SUB_START_REF, signal,
  327.        SubStartRef::SignalLength2, JBB);
  328.     return;
  329.   }
  330.   {
  331.     const SubStartReq* req = (SubStartReq*) signal->getDataPtr();
  332.     subbPtr.p->m_senderRef = req->senderRef;
  333.     subbPtr.p->m_senderData = req->senderData;
  334.     subbPtr.p->m_errorCode = 0;
  335.   }
  336.   
  337.   if (refToBlock(origSenderRef) != DBDICT) {
  338.     /*
  339.      * Coordinator
  340.      */
  341.     jam();
  342.     
  343.     subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
  344.     NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  345.     RequestTracker & p = subbPtr.p->m_reqTracker;
  346.     p.init<SubStartRef>(c_counterMgr, rg, GSN_SUB_START_REF, subbPtr.i);
  347.     
  348.     SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
  349.     
  350.     req->senderRef  = reference();
  351.     req->senderData = subbPtr.i;
  352.     
  353. #ifdef EVENT_PH3_DEBUG
  354.     ndbout_c("DBDICT(Coordinator) sending GSN_SUB_START_REQ to DBDICT participants subbPtr.i = (%d)", subbPtr.i);
  355. #endif
  356.     sendSignal(rg, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
  357.     return;
  358.   }
  359.   /*
  360.    * Participant
  361.    */
  362.   ndbrequire(refToBlock(origSenderRef) == DBDICT);
  363.   
  364.   {
  365.     SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
  366.     
  367.     req->senderRef = reference();
  368.     req->senderData = subbPtr.i;
  369.     
  370. #ifdef EVENT_PH3_DEBUG
  371.     ndbout_c("DBDICT(Participant) sending GSN_SUB_START_REQ to SUMA subbPtr.i = (%d)", subbPtr.i);
  372. #endif
  373.     sendSignal(SUMA_REF, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
  374.   }
  375. }
  376. void Dbdict::execSUB_START_REF(Signal* signal)
  377. {
  378.   jamEntry();
  379.   const SubStartRef* ref = (SubStartRef*) signal->getDataPtr();
  380.   Uint32 senderRef  = ref->senderRef;
  381.   OpSubEventPtr subbPtr;
  382.   c_opSubEvent.getPtr(subbPtr, ref->senderData);
  383.   if (refToBlock(senderRef) == SUMA) {
  384.     /*
  385.      * Participant
  386.      */
  387.     jam();
  388. #ifdef EVENT_PH3_DEBUG
  389.     ndbout_c("DBDICT(Participant) got GSN_SUB_START_REF = (%d)", subbPtr.i);
  390. #endif
  391.     if (ref->isTemporary()){
  392.       jam();
  393.       SubStartReq* req = (SubStartReq*)signal->getDataPtrSend();
  394.       { // fix
  395. Uint32 subscriberRef = ref->subscriberRef;
  396. req->subscriberRef = subscriberRef;
  397.       }
  398.       req->senderRef  = reference();
  399.       req->senderData = subbPtr.i;
  400.       sendSignal(SUMA_REF, GSN_SUB_START_REQ,
  401.  signal, SubStartReq::SignalLength2, JBB);
  402.     } else {
  403.       jam();
  404.       SubStartRef* ref = (SubStartRef*) signal->getDataPtrSend();
  405.       ref->senderRef = reference();
  406.       ref->senderData = subbPtr.p->m_senderData;
  407.       sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
  408.  signal, SubStartRef::SignalLength2, JBB);
  409.       c_opSubEvent.release(subbPtr);
  410.     }
  411.     return;
  412.   }
  413.   /*
  414.    * Coordinator
  415.    */
  416.   ndbrequire(refToBlock(senderRef) == DBDICT);
  417. #ifdef EVENT_PH3_DEBUG
  418.   ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_REF = (%d)", subbPtr.i);
  419. #endif
  420.   if (ref->errorCode == SubStartRef::NF_FakeErrorREF){
  421.     jam();
  422.     subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
  423.   } else {
  424.     jam();
  425.     subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
  426.   }
  427.   completeSubStartReq(signal,subbPtr.i,0);
  428. }
  429. void Dbdict::execSUB_START_CONF(Signal* signal)
  430. {
  431.   jamEntry();
  432.   const SubStartConf* conf = (SubStartConf*) signal->getDataPtr();
  433.   Uint32 senderRef  = conf->senderRef;
  434.   OpSubEventPtr subbPtr;
  435.   c_opSubEvent.getPtr(subbPtr, conf->senderData);
  436.   if (refToBlock(senderRef) == SUMA) {
  437.     /*
  438.      * Participant
  439.      */
  440.     jam();
  441.     SubStartConf* conf = (SubStartConf*) signal->getDataPtrSend();
  442. #ifdef EVENT_PH3_DEBUG
  443.   ndbout_c("DBDICT(Participant) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
  444. #endif
  445.     conf->senderRef = reference();
  446.     conf->senderData = subbPtr.p->m_senderData;
  447.     sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
  448.        signal, SubStartConf::SignalLength2, JBB);
  449.     c_opSubEvent.release(subbPtr);
  450.     return;
  451.   }
  452.   /*
  453.    * Coordinator
  454.    */
  455.   ndbrequire(refToBlock(senderRef) == DBDICT);
  456. #ifdef EVENT_PH3_DEBUG
  457.   ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
  458. #endif
  459.   subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
  460.   completeSubStartReq(signal,subbPtr.i,0);
  461. }
  462. /*
  463.  * Coordinator
  464.  */
  465. void Dbdict::completeSubStartReq(Signal* signal,
  466.  Uint32 ptrI,
  467.  Uint32 returnCode){
  468.   jam();
  469.   OpSubEventPtr subbPtr;
  470.   c_opSubEvent.getPtr(subbPtr, ptrI);
  471.   if (!subbPtr.p->m_reqTracker.done()){
  472.     jam();
  473.     return;
  474.   }
  475.   if (subbPtr.p->m_reqTracker.hasRef()) {
  476.     jam();
  477. #ifdef EVENT_DEBUG
  478.     ndbout_c("SUB_START_REF");
  479. #endif
  480.     sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
  481.        signal, SubStartRef::SignalLength, JBB);
  482.     if (subbPtr.p->m_reqTracker.hasConf()) {
  483.       //  stopStartedNodes(signal);
  484.     }
  485.     c_opSubEvent.release(subbPtr);
  486.     return;
  487.   }
  488. #ifdef EVENT_DEBUG
  489.   ndbout_c("SUB_START_CONF");
  490. #endif
  491.   sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
  492.      signal, SubStartConf::SignalLength, JBB);
  493.   c_opSubEvent.release(subbPtr);
  494. }
  495. /********************************************************************
  496.  *
  497.  * Stop event
  498.  *
  499.  *******************************************************************/
  500. void Dbdict::execSUB_STOP_REQ(Signal* signal)
  501. {
  502.   jamEntry();
  503.   Uint32 origSenderRef = signal->senderBlockRef();
  504.   OpSubEventPtr subbPtr;
  505.   if (!c_opSubEvent.seize(subbPtr)) {
  506.     SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
  507.     jam();
  508.     //      ret->setErrorCode(SubStartRef::SeizeError);
  509.     //      ret->setErrorLine(__LINE__);
  510.     //      ret->setErrorNode(reference());
  511.     ref->senderRef = reference();
  512.     ref->setTemporary(SubStopRef::Busy);
  513.     sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal,
  514.        SubStopRef::SignalLength, JBB);
  515.     return;
  516.   }
  517.   {
  518.     const SubStopReq* req = (SubStopReq*) signal->getDataPtr();
  519.     subbPtr.p->m_senderRef = req->senderRef;
  520.     subbPtr.p->m_senderData = req->senderData;
  521.     subbPtr.p->m_errorCode = 0;
  522.   }
  523.   
  524.   if (refToBlock(origSenderRef) != DBDICT) {
  525.     /*
  526.      * Coordinator
  527.      */
  528.     jam();
  529. #ifdef EVENT_DEBUG
  530.     ndbout_c("SUB_STOP_REQ 1");
  531. #endif
  532.     subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
  533.     NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  534.     RequestTracker & p = subbPtr.p->m_reqTracker;
  535.     p.init<SubStopRef>(c_counterMgr, rg, GSN_SUB_STOP_REF, subbPtr.i);
  536.     SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
  537.     req->senderRef  = reference();
  538.     req->senderData = subbPtr.i;
  539.     
  540.     sendSignal(rg, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
  541.     return;
  542.   }
  543.   /*
  544.    * Participant
  545.    */
  546. #ifdef EVENT_DEBUG
  547.   ndbout_c("SUB_STOP_REQ 2");
  548. #endif
  549.   ndbrequire(refToBlock(origSenderRef) == DBDICT);
  550.   {
  551.     SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
  552.     
  553.     req->senderRef = reference();
  554.     req->senderData = subbPtr.i;
  555.     
  556.     sendSignal(SUMA_REF, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
  557.   }
  558. }
  559. void Dbdict::execSUB_STOP_REF(Signal* signal)
  560. {
  561.   jamEntry();
  562.   const SubStopRef* ref = (SubStopRef*) signal->getDataPtr();
  563.   Uint32 senderRef  = ref->senderRef;
  564.   OpSubEventPtr subbPtr;
  565.   c_opSubEvent.getPtr(subbPtr, ref->senderData);
  566.   if (refToBlock(senderRef) == SUMA) {
  567.     /*
  568.      * Participant
  569.      */
  570.     jam();
  571.     if (ref->isTemporary()){
  572.       jam();
  573.       SubStopReq* req = (SubStopReq*)signal->getDataPtrSend();
  574.       req->senderRef  = reference();
  575.       req->senderData = subbPtr.i;
  576.       sendSignal(SUMA_REF, GSN_SUB_STOP_REQ,
  577.  signal, SubStopReq::SignalLength, JBB);
  578.     } else {
  579.       jam();
  580.       SubStopRef* ref = (SubStopRef*) signal->getDataPtrSend();
  581.       ref->senderRef = reference();
  582.       ref->senderData = subbPtr.p->m_senderData;
  583.       sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
  584.  signal, SubStopRef::SignalLength, JBB);
  585.       c_opSubEvent.release(subbPtr);
  586.     }
  587.     return;
  588.   }
  589.   /*
  590.    * Coordinator
  591.    */
  592.   ndbrequire(refToBlock(senderRef) == DBDICT);
  593.   if (ref->errorCode == SubStopRef::NF_FakeErrorREF){
  594.     jam();
  595.     subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
  596.   } else {
  597.     jam();
  598.     subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
  599.   }
  600.   completeSubStopReq(signal,subbPtr.i,0);
  601. }
  602. void Dbdict::execSUB_STOP_CONF(Signal* signal)
  603. {
  604.   jamEntry();
  605.   const SubStopConf* conf = (SubStopConf*) signal->getDataPtr();
  606.   Uint32 senderRef  = conf->senderRef;
  607.   OpSubEventPtr subbPtr;
  608.   c_opSubEvent.getPtr(subbPtr, conf->senderData);
  609.   if (refToBlock(senderRef) == SUMA) {
  610.     /*
  611.      * Participant
  612.      */
  613.     jam();
  614.     SubStopConf* conf = (SubStopConf*) signal->getDataPtrSend();
  615.     conf->senderRef = reference();
  616.     conf->senderData = subbPtr.p->m_senderData;
  617.     sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
  618.        signal, SubStopConf::SignalLength, JBB);
  619.     c_opSubEvent.release(subbPtr);
  620.     return;
  621.   }
  622.   /*
  623.    * Coordinator
  624.    */
  625.   ndbrequire(refToBlock(senderRef) == DBDICT);
  626.   subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
  627.   completeSubStopReq(signal,subbPtr.i,0);
  628. }
  629. /*
  630.  * Coordinator
  631.  */
  632. void Dbdict::completeSubStopReq(Signal* signal,
  633. Uint32 ptrI,
  634. Uint32 returnCode){
  635.   OpSubEventPtr subbPtr;
  636.   c_opSubEvent.getPtr(subbPtr, ptrI);
  637.   if (!subbPtr.p->m_reqTracker.done()){
  638.     jam();
  639.     return;
  640.   }
  641.   if (subbPtr.p->m_reqTracker.hasRef()) {
  642.     jam();
  643. #ifdef EVENT_DEBUG
  644.     ndbout_c("SUB_STOP_REF");
  645. #endif
  646.     SubStopRef* ref = (SubStopRef*)signal->getDataPtrSend();
  647.     ref->senderRef      = reference();
  648.     ref->senderData     = subbPtr.p->m_senderData;
  649.     /*
  650.     ref->subscriptionId = subbPtr.p->m_senderData;
  651.     ref->subscriptionKey = subbPtr.p->m_senderData;
  652.     ref->part = subbPtr.p->m_part;  // SubscriptionData::Part
  653.     ref->subscriberData = subbPtr.p->m_subscriberData;
  654.     ref->subscriberRef = subbPtr.p->m_subscriberRef;
  655.     */
  656.     ref->errorCode = subbPtr.p->m_errorCode;
  657.     sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
  658.        signal, SubStopRef::SignalLength, JBB);
  659.     if (subbPtr.p->m_reqTracker.hasConf()) {
  660.       //  stopStartedNodes(signal);
  661.     }
  662.     c_opSubEvent.release(subbPtr);
  663.     return;
  664.   }
  665. #ifdef EVENT_DEBUG
  666.   ndbout_c("SUB_STOP_CONF");
  667. #endif
  668.   sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
  669.      signal, SubStopConf::SignalLength, JBB);
  670.   c_opSubEvent.release(subbPtr);
  671. }
  672. /***************************************************************
  673.  * MODULE: Drop event.
  674.  *
  675.  * Drop event.
  676.  * 
  677.  * TODO
  678.  */
  679. void
  680. Dbdict::execDROP_EVNT_REQ(Signal* signal)
  681. {
  682.   jamEntry();
  683.   EVENT_TRACE;
  684.   DropEvntReq *req = (DropEvntReq*)signal->getDataPtr();
  685.   const Uint32 senderRef = signal->senderBlockRef();
  686.   OpDropEventPtr evntRecPtr;
  687.   // Seize a Create Event record
  688.   if (!c_opDropEvent.seize(evntRecPtr)) {
  689.     // Failed to allocate event record
  690.     jam();
  691.     releaseSections(signal);
  692.  
  693.     DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
  694.     ret->setErrorCode(DropEvntRef::SeizeError);
  695.     ret->setErrorLine(__LINE__);
  696.     ret->setErrorNode(reference());
  697.     sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
  698.        DropEvntRef::SignalLength, JBB);
  699.     return;
  700.   }
  701. #ifdef EVENT_DEBUG
  702.   ndbout_c("DBDICT::execDROP_EVNT_REQ evntRecId = (%d)", evntRecPtr.i);
  703. #endif
  704.   OpDropEvent* evntRec = evntRecPtr.p;
  705.   evntRec->init(req);
  706.   SegmentedSectionPtr ssPtr;
  707.   signal->getSection(ssPtr, 0);
  708.   SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
  709. #ifdef EVENT_DEBUG
  710.   r0.printAll(ndbout);
  711. #endif
  712.   // event name
  713.   if ((!r0.first()) ||
  714.       (r0.getValueType() != SimpleProperties::StringValue) ||
  715.       (r0.getValueLen() <= 0)) {
  716.     jam();
  717.     releaseSections(signal);
  718.     evntRecPtr.p->m_errorCode = DropEvntRef::Undefined;
  719.     evntRecPtr.p->m_errorLine = __LINE__;
  720.     evntRecPtr.p->m_errorNode = reference();
  721.     dropEvent_sendReply(signal, evntRecPtr);
  722.     return;
  723.   }
  724.   r0.getString(evntRecPtr.p->m_eventRec.NAME);
  725.   {
  726.     int len = strlen(evntRecPtr.p->m_eventRec.NAME);
  727.     memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
  728. #ifdef EVENT_DEBUG
  729.     printf("DropEvntReq; EventName %s, len %un",
  730.    evntRecPtr.p->m_eventRec.NAME, len);
  731.     for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
  732.       printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
  733.     printf("n");
  734. #endif
  735.   }
  736.   
  737.   releaseSections(signal);
  738.   Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_READ), 0 };
  739.   prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
  740.   UtilPrepareReq::Read);
  741. }
  742. void 
  743. Dbdict::dropEventUTIL_PREPARE_READ(Signal* signal,
  744.    Uint32 callbackData,
  745.    Uint32 returnCode)
  746. {
  747.   jam();
  748.   EVENT_TRACE;
  749.   if (returnCode != 0) {
  750.     EVENT_TRACE;
  751.     dropEventUtilPrepareRef(signal, callbackData, returnCode);
  752.     return;
  753.   }
  754.   UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
  755.   OpDropEventPtr evntRecPtr;
  756.   evntRecPtr.i = req->getSenderData();
  757.   const Uint32 prepareId = req->getPrepareId();
  758.   ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
  759.   Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_READ), 0 };
  760.   executeTransEventSysTable(&c, signal,
  761.     evntRecPtr.i, evntRecPtr.p->m_eventRec,
  762.     prepareId, UtilPrepareReq::Read);
  763. }
  764. void 
  765. Dbdict::dropEventUTIL_EXECUTE_READ(Signal* signal,
  766.    Uint32 callbackData,
  767.    Uint32 returnCode)
  768. {
  769.   jam();
  770.   EVENT_TRACE;
  771.   if (returnCode != 0) {
  772.     EVENT_TRACE;
  773.     dropEventUtilExecuteRef(signal, callbackData, returnCode);
  774.     return;
  775.   }
  776.   OpDropEventPtr evntRecPtr;
  777.   UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
  778.   jam();
  779.   evntRecPtr.i = ref->getSenderData();
  780.   ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
  781.   parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
  782.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  783.   RequestTracker & p = evntRecPtr.p->m_reqTracker;
  784.   p.init<SubRemoveRef>(c_counterMgr, rg, GSN_SUB_REMOVE_REF,
  785. evntRecPtr.i);
  786.   SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
  787.   req->senderRef       = reference();
  788.   req->senderData      = evntRecPtr.i;
  789.   req->subscriptionId  = evntRecPtr.p->m_eventRec.SUBID;
  790.   req->subscriptionKey = evntRecPtr.p->m_eventRec.SUBKEY;
  791.   sendSignal(rg, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
  792. }
  793. /*
  794.  * Participant
  795.  */
  796. void
  797. Dbdict::execSUB_REMOVE_REQ(Signal* signal)
  798. {
  799.   jamEntry();
  800.   Uint32 origSenderRef = signal->senderBlockRef();
  801.   OpSubEventPtr subbPtr;
  802.   if (!c_opSubEvent.seize(subbPtr)) {
  803.     SubRemoveRef * ref = (SubRemoveRef *)signal->getDataPtrSend();
  804.     jam();
  805.     ref->senderRef = reference();
  806.     ref->setTemporary(SubRemoveRef::Busy);
  807.     sendSignal(origSenderRef, GSN_SUB_REMOVE_REF, signal,
  808.        SubRemoveRef::SignalLength, JBB);
  809.     return;
  810.   }
  811.   {
  812.     const SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtr();
  813.     subbPtr.p->m_senderRef = req->senderRef;
  814.     subbPtr.p->m_senderData = req->senderData;
  815.     subbPtr.p->m_errorCode = 0;
  816.   }
  817.   SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
  818.   req->senderRef = reference();
  819.   req->senderData = subbPtr.i;
  820.   sendSignal(SUMA_REF, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
  821. }
  822. /*
  823.  * Coordintor/Participant
  824.  */
  825. void
  826. Dbdict::execSUB_REMOVE_REF(Signal* signal)
  827. {
  828.   jamEntry();
  829.   const SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtr();
  830.   Uint32 senderRef = ref->senderRef;
  831.   if (refToBlock(senderRef) == SUMA) {
  832.     /*
  833.      * Participant
  834.      */
  835.     jam();
  836.     OpSubEventPtr subbPtr;
  837.     c_opSubEvent.getPtr(subbPtr, ref->senderData);
  838.     if (ref->errorCode == (Uint32) GrepError::SUBSCRIPTION_ID_NOT_FOUND) {
  839.       // conf this since this may occur if a nodefailiure has occured
  840.       // earlier so that the systable was not cleared
  841.       SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
  842.       conf->senderRef  = reference();
  843.       conf->senderData = subbPtr.p->m_senderData;
  844.       sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
  845.  signal, SubRemoveConf::SignalLength, JBB);
  846.     } else {
  847.       SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtrSend();
  848.       ref->senderRef = reference();
  849.       ref->senderData = subbPtr.p->m_senderData;
  850.       sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_REF,
  851.  signal, SubRemoveRef::SignalLength, JBB);
  852.     }
  853.     c_opSubEvent.release(subbPtr);
  854.     return;
  855.   }
  856.   /*
  857.    * Coordinator
  858.    */
  859.   ndbrequire(refToBlock(senderRef) == DBDICT);
  860.   OpDropEventPtr eventRecPtr;
  861.   c_opDropEvent.getPtr(eventRecPtr, ref->senderData);
  862.   if (ref->errorCode == SubRemoveRef::NF_FakeErrorREF){
  863.     jam();
  864.     eventRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
  865.   } else {
  866.     jam();
  867.     eventRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
  868.   }
  869.   completeSubRemoveReq(signal,eventRecPtr.i,0);
  870. }
  871. void
  872. Dbdict::execSUB_REMOVE_CONF(Signal* signal)
  873. {
  874.   jamEntry();
  875.   const SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtr();
  876.   Uint32 senderRef = conf->senderRef;
  877.   if (refToBlock(senderRef) == SUMA) {
  878.     /*
  879.      * Participant
  880.      */
  881.     jam();
  882.     OpSubEventPtr subbPtr;
  883.     c_opSubEvent.getPtr(subbPtr, conf->senderData);
  884.     SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
  885.     conf->senderRef = reference();
  886.     conf->senderData = subbPtr.p->m_senderData;
  887.     sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
  888.        signal, SubRemoveConf::SignalLength, JBB);
  889.     c_opSubEvent.release(subbPtr);
  890.     return;
  891.   }
  892.   /*
  893.    * Coordinator
  894.    */
  895.   ndbrequire(refToBlock(senderRef) == DBDICT);
  896.   OpDropEventPtr eventRecPtr;
  897.   c_opDropEvent.getPtr(eventRecPtr, conf->senderData);
  898.   eventRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
  899.   completeSubRemoveReq(signal,eventRecPtr.i,0);
  900. }
  901. void
  902. Dbdict::completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 xxx)
  903. {
  904.   OpDropEventPtr evntRecPtr;
  905.   c_opDropEvent.getPtr(evntRecPtr, ptrI);
  906.   if (!evntRecPtr.p->m_reqTracker.done()){
  907.     jam();
  908.     return;
  909.   }
  910.   if (evntRecPtr.p->m_reqTracker.hasRef()) {
  911.     jam();
  912.     evntRecPtr.p->m_errorNode = reference();
  913.     evntRecPtr.p->m_errorLine = __LINE__;
  914.     evntRecPtr.p->m_errorCode = DropEvntRef::Undefined;
  915.     dropEvent_sendReply(signal, evntRecPtr);
  916.     return;
  917.   }
  918.   Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_DELETE), 0 };
  919.   prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
  920.   UtilPrepareReq::Delete);
  921. }
  922. void 
  923. Dbdict::dropEventUTIL_PREPARE_DELETE(Signal* signal,
  924.      Uint32 callbackData,
  925.      Uint32 returnCode)
  926. {
  927.   jam();
  928.   EVENT_TRACE;
  929.   if (returnCode != 0) {
  930.     EVENT_TRACE;
  931.     dropEventUtilPrepareRef(signal, callbackData, returnCode);
  932.     return;
  933.   }
  934.   UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
  935.   OpDropEventPtr evntRecPtr;
  936.   jam();
  937.   evntRecPtr.i = req->getSenderData();
  938.   const Uint32 prepareId = req->getPrepareId();
  939.   
  940.   ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
  941. #ifdef EVENT_DEBUG
  942.   printf("DropEvntUTIL_PREPARE; evntRecPtr.i len %un",evntRecPtr.i);
  943. #endif    
  944.   Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_DELETE), 0 };
  945.   executeTransEventSysTable(&c, signal,
  946.     evntRecPtr.i, evntRecPtr.p->m_eventRec,
  947.     prepareId, UtilPrepareReq::Delete);
  948. }
  949. void 
  950. Dbdict::dropEventUTIL_EXECUTE_DELETE(Signal* signal,
  951.      Uint32 callbackData,
  952.      Uint32 returnCode)
  953. {
  954.   jam();
  955.   EVENT_TRACE;
  956.   if (returnCode != 0) {
  957.     EVENT_TRACE;
  958.     dropEventUtilExecuteRef(signal, callbackData, returnCode);
  959.     return;
  960.   }
  961.   OpDropEventPtr evntRecPtr;
  962.   UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
  963.   jam();
  964.   evntRecPtr.i = ref->getSenderData();
  965.   ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
  966.   dropEvent_sendReply(signal, evntRecPtr);
  967. }
  968. void
  969. Dbdict::dropEventUtilPrepareRef(Signal* signal,
  970. Uint32 callbackData,
  971. Uint32 returnCode)
  972. {
  973.   jam();
  974.   EVENT_TRACE;
  975.   UtilPrepareRef * const ref = (UtilPrepareRef *)signal->getDataPtr();
  976.   OpDropEventPtr evntRecPtr;
  977.   evntRecPtr.i = ref->getSenderData();
  978.   ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
  979.   bool temporary = false;
  980.   interpretUtilPrepareErrorCode((UtilPrepareRef::ErrorCode)ref->getErrorCode(),
  981. temporary, evntRecPtr.p->m_errorLine);
  982.   if (temporary) {
  983.     evntRecPtr.p->m_errorCode = (DropEvntRef::ErrorCode)
  984.       ((Uint32) DropEvntRef::Undefined | (Uint32) DropEvntRef::Temporary);
  985.   }
  986.   if (evntRecPtr.p->m_errorCode == 0) {
  987.     evntRecPtr.p->m_errorCode = DropEvntRef::Undefined;
  988.     evntRecPtr.p->m_errorLine = __LINE__;
  989.   }
  990.   evntRecPtr.p->m_errorNode = reference();
  991.   dropEvent_sendReply(signal, evntRecPtr);
  992. }
  993. void
  994. Dbdict::dropEventUtilExecuteRef(Signal* signal,
  995. Uint32 callbackData,
  996. Uint32 returnCode)
  997. {
  998.   jam();
  999.   EVENT_TRACE;
  1000.   OpDropEventPtr evntRecPtr;
  1001.   UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
  1002.   jam();
  1003.   evntRecPtr.i = ref->getSenderData();
  1004.   ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
  1005.     
  1006.   evntRecPtr.p->m_errorNode = reference();
  1007.   evntRecPtr.p->m_errorLine = __LINE__;
  1008.   switch (ref->getErrorCode()) {
  1009.   case UtilExecuteRef::TCError:
  1010.     switch (ref->getTCErrorCode()) {
  1011.     case ZNOT_FOUND:
  1012.       jam();
  1013.       evntRecPtr.p->m_errorCode = DropEvntRef::EventNotFound;
  1014.       break;
  1015.     default:
  1016.       jam();
  1017.       evntRecPtr.p->m_errorCode = DropEvntRef::UndefinedTCError;
  1018.       break;
  1019.     }
  1020.     break;
  1021.   default:
  1022.     jam();
  1023.     evntRecPtr.p->m_errorCode = DropEvntRef::Undefined;
  1024.     break;
  1025.   }
  1026.   dropEvent_sendReply(signal, evntRecPtr);
  1027. }
  1028. void Dbdict::dropEvent_sendReply(Signal* signal,
  1029.  OpDropEventPtr evntRecPtr)
  1030. {
  1031.   jam();
  1032.   EVENT_TRACE;
  1033.   Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
  1034.   if (evntRecPtr.p->hasError()) {
  1035.     jam();
  1036.     DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
  1037.     
  1038.     ret->setUserData(evntRecPtr.p->m_request.getUserData());
  1039.     ret->setUserRef(evntRecPtr.p->m_request.getUserRef());
  1040.     ret->setErrorCode(evntRecPtr.p->m_errorCode);
  1041.     ret->setErrorLine(evntRecPtr.p->m_errorLine);
  1042.     ret->setErrorNode(evntRecPtr.p->m_errorNode);
  1043.     sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
  1044.        DropEvntRef::SignalLength, JBB);
  1045.   } else {
  1046.     jam();
  1047.     DropEvntConf * evntConf = (DropEvntConf *)signal->getDataPtrSend();
  1048.     
  1049.     evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
  1050.     evntConf->setUserRef(evntRecPtr.p->m_request.getUserRef());
  1051.     sendSignal(senderRef, GSN_DROP_EVNT_CONF, signal,
  1052.        DropEvntConf::SignalLength, JBB);
  1053.   }
  1054.   c_opDropEvent.release(evntRecPtr);
  1055. }
  1056. /**
  1057.  * MODULE: Alter index
  1058.  *
  1059.  * Alter index state.  Alter online creates the index in each TC and
  1060.  * then invokes create trigger and alter trigger protocols to activate
  1061.  * the 3 triggers.  Alter offline does the opposite.
  1062.  *
  1063.  * Request type received in REQ and returned in CONF/REF:
  1064.  *
  1065.  * RT_USER - from API to DICT master
  1066.  * RT_CREATE_INDEX - part of create index operation
  1067.  * RT_DROP_INDEX - part of drop index operation
  1068.  * RT_NODERESTART - node restart, activate locally only
  1069.  * RT_SYSTEMRESTART - system restart, activate and build if not logged
  1070.  * RT_DICT_PREPARE - prepare participants
  1071.  * RT_DICT_TC - to local TC via each participant
  1072.  * RT_DICT_COMMIT - commit in each participant
  1073.  */
  1074. void
  1075. Dbdict::execALTER_INDX_REQ(Signal* signal)
  1076. {
  1077.   jamEntry();
  1078.   AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
  1079.   OpAlterIndexPtr opPtr;
  1080.   const Uint32 senderRef = signal->senderBlockRef();
  1081.   const AlterIndxReq::RequestType requestType = req->getRequestType();
  1082.   if (requestType == AlterIndxReq::RT_USER ||
  1083.       requestType == AlterIndxReq::RT_CREATE_INDEX ||
  1084.       requestType == AlterIndxReq::RT_DROP_INDEX ||
  1085.       requestType == AlterIndxReq::RT_NODERESTART ||
  1086.       requestType == AlterIndxReq::RT_SYSTEMRESTART) {
  1087.     jam();
  1088.     const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
  1089.     NdbNodeBitmask receiverNodes = c_aliveNodes;
  1090.     if (isLocal) {
  1091.       receiverNodes.clear();
  1092.       receiverNodes.set(getOwnNodeId());
  1093.     }
  1094.     if (signal->getLength() == AlterIndxReq::SignalLength) {
  1095.       jam();
  1096.       if (! isLocal && getOwnNodeId() != c_masterNodeId) {
  1097.         jam();
  1098. releaseSections(signal);
  1099. OpAlterIndex opBad;
  1100. opPtr.p = &opBad;
  1101. opPtr.p->save(req);
  1102. opPtr.p->m_errorCode = AlterIndxRef::NotMaster;
  1103. opPtr.p->m_errorLine = __LINE__;
  1104. opPtr.p->m_errorNode = c_masterNodeId;
  1105. alterIndex_sendReply(signal, opPtr, true);
  1106.         return;
  1107.       }
  1108.       // forward initial request plus operation key to all
  1109.       req->setOpKey(++c_opRecordSequence);
  1110.       NodeReceiverGroup rg(DBDICT, receiverNodes);
  1111.       sendSignal(rg, GSN_ALTER_INDX_REQ,
  1112.           signal, AlterIndxReq::SignalLength + 1, JBB);
  1113.       return;
  1114.     }
  1115.     // seize operation record
  1116.     ndbrequire(signal->getLength() == AlterIndxReq::SignalLength + 1);
  1117.     const Uint32 opKey = req->getOpKey();
  1118.     OpAlterIndex opBusy;
  1119.     if (! c_opAlterIndex.seize(opPtr))
  1120.       opPtr.p = &opBusy;
  1121.     opPtr.p->save(req);
  1122.     opPtr.p->m_coordinatorRef = senderRef;
  1123.     opPtr.p->m_isMaster = (senderRef == reference());
  1124.     opPtr.p->key = opKey;
  1125.     opPtr.p->m_requestType = AlterIndxReq::RT_DICT_PREPARE;
  1126.     if (opPtr.p == &opBusy) {
  1127.       jam();
  1128.       opPtr.p->m_errorCode = AlterIndxRef::Busy;
  1129.       opPtr.p->m_errorLine = __LINE__;
  1130.       alterIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  1131.       return;
  1132.     }
  1133.     c_opAlterIndex.add(opPtr);
  1134.     // master expects to hear from all
  1135.     if (opPtr.p->m_isMaster)
  1136.       opPtr.p->m_signalCounter = receiverNodes;
  1137.     // check request in all participants
  1138.     alterIndex_slavePrepare(signal, opPtr);
  1139.     alterIndex_sendReply(signal, opPtr, false);
  1140.     return;
  1141.   }
  1142.   c_opAlterIndex.find(opPtr, req->getConnectionPtr());
  1143.   if (! opPtr.isNull()) {
  1144.     opPtr.p->m_requestType = requestType;
  1145.     if (requestType == AlterIndxReq::RT_DICT_TC) {
  1146.       jam();
  1147.       if (opPtr.p->m_request.getOnline())
  1148.         alterIndex_toCreateTc(signal, opPtr);
  1149.       else
  1150.         alterIndex_toDropTc(signal, opPtr);
  1151.       return;
  1152.     }
  1153.     if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
  1154.         requestType == AlterIndxReq::RT_DICT_ABORT) {
  1155.       jam();
  1156.       if (requestType == AlterIndxReq::RT_DICT_COMMIT)
  1157.         alterIndex_slaveCommit(signal, opPtr);
  1158.       else
  1159.         alterIndex_slaveAbort(signal, opPtr);
  1160.       alterIndex_sendReply(signal, opPtr, false);
  1161.       // done in slave
  1162.       if (! opPtr.p->m_isMaster)
  1163.         c_opAlterIndex.release(opPtr);
  1164.       return;
  1165.     }
  1166.   }
  1167.   jam();
  1168.   // return to sender
  1169.   OpAlterIndex opBad;
  1170.   opPtr.p = &opBad;
  1171.   opPtr.p->save(req);
  1172.   opPtr.p->m_errorCode = AlterIndxRef::BadRequestType;
  1173.   opPtr.p->m_errorLine = __LINE__;
  1174.   alterIndex_sendReply(signal, opPtr, true);
  1175. }
  1176. void
  1177. Dbdict::execALTER_INDX_CONF(Signal* signal)
  1178. {
  1179.   jamEntry();
  1180.   ndbrequire(signal->getNoOfSections() == 0);
  1181.   AlterIndxConf* conf = (AlterIndxConf*)signal->getDataPtrSend();
  1182.   alterIndex_recvReply(signal, conf, 0);
  1183. }
  1184. void
  1185. Dbdict::execALTER_INDX_REF(Signal* signal)
  1186. {
  1187.   jamEntry();
  1188.   AlterIndxRef* ref = (AlterIndxRef*)signal->getDataPtrSend();
  1189.   alterIndex_recvReply(signal, ref->getConf(), ref);
  1190. }
  1191. void
  1192. Dbdict::alterIndex_recvReply(Signal* signal, const AlterIndxConf* conf,
  1193.     const AlterIndxRef* ref)
  1194. {
  1195.   jam();
  1196.   const Uint32 senderRef = signal->senderBlockRef();
  1197.   const AlterIndxReq::RequestType requestType = conf->getRequestType();
  1198.   const Uint32 key = conf->getConnectionPtr();
  1199.   if (requestType == AlterIndxReq::RT_CREATE_INDEX) {
  1200.     jam();
  1201.     // part of create index operation
  1202.     OpCreateIndexPtr opPtr;
  1203.     c_opCreateIndex.find(opPtr, key);
  1204.     ndbrequire(! opPtr.isNull());
  1205.     opPtr.p->setError(ref);
  1206.     createIndex_fromAlterIndex(signal, opPtr);
  1207.     return;
  1208.   }
  1209.   if (requestType == AlterIndxReq::RT_DROP_INDEX) {
  1210.     jam();
  1211.     // part of drop index operation
  1212.     OpDropIndexPtr opPtr;
  1213.     c_opDropIndex.find(opPtr, key);
  1214.     ndbrequire(! opPtr.isNull());
  1215.     opPtr.p->setError(ref);
  1216.     dropIndex_fromAlterIndex(signal, opPtr);
  1217.     return;
  1218.   }
  1219.   if (requestType == AlterIndxReq::RT_TC ||
  1220.       requestType == AlterIndxReq::RT_TUX) {
  1221.     jam();
  1222.     // part of build index operation
  1223.     OpBuildIndexPtr opPtr;
  1224.     c_opBuildIndex.find(opPtr, key);
  1225.     ndbrequire(! opPtr.isNull());
  1226.     opPtr.p->setError(ref);
  1227.     buildIndex_fromOnline(signal, opPtr);
  1228.     return;
  1229.   }
  1230.   if (requestType == AlterIndxReq::RT_NODERESTART) {
  1231.     jam();
  1232.     if (ref == 0) {
  1233.       infoEvent("DICT: index %u activated", (unsigned)key);
  1234.     } else {
  1235.       warningEvent("DICT: index %u activation failed: code=%d line=%d",
  1236.           (unsigned)key,
  1237.           ref->getErrorCode(), ref->getErrorLine());
  1238.     }
  1239.     activateIndexes(signal, key + 1);
  1240.     return;
  1241.   }
  1242.   if (requestType == AlterIndxReq::RT_SYSTEMRESTART) {
  1243.     jam();
  1244.     if (ref == 0) {
  1245.       infoEvent("DICT: index %u activated done", (unsigned)key);
  1246.     } else {
  1247.       warningEvent("DICT: index %u activated failed: code=%d line=%d node=%d",
  1248.           (unsigned)key,
  1249.           ref->getErrorCode(), ref->getErrorLine(), ref->getErrorNode());
  1250.     }
  1251.     activateIndexes(signal, key + 1);
  1252.     return;
  1253.   }
  1254.   OpAlterIndexPtr opPtr;
  1255.   c_opAlterIndex.find(opPtr, key);
  1256.   ndbrequire(! opPtr.isNull());
  1257.   ndbrequire(opPtr.p->m_isMaster);
  1258.   ndbrequire(opPtr.p->m_requestType == requestType);
  1259.   opPtr.p->setError(ref);
  1260.   opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
  1261.   if (! opPtr.p->m_signalCounter.done()) {
  1262.     jam();
  1263.     return;
  1264.   }
  1265.   if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
  1266.       requestType == AlterIndxReq::RT_DICT_ABORT) {
  1267.     jam();
  1268.     // send reply to user
  1269.     alterIndex_sendReply(signal, opPtr, true);
  1270.     c_opAlterIndex.release(opPtr);
  1271.     return;
  1272.   }
  1273.   if (opPtr.p->hasError()) {
  1274.     jam();
  1275.     opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
  1276.     alterIndex_sendSlaveReq(signal, opPtr);
  1277.     return;
  1278.   }
  1279.   TableRecordPtr indexPtr;
  1280.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1281.   if (indexPtr.p->isHashIndex()) {
  1282.     if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
  1283.       jam();
  1284.       if (opPtr.p->m_request.getOnline()) {
  1285.         opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
  1286.         alterIndex_sendSlaveReq(signal, opPtr);
  1287.       } else {
  1288.         // start drop triggers
  1289.         alterIndex_toDropTrigger(signal, opPtr);
  1290.       }
  1291.       return;
  1292.     }
  1293.     if (requestType == AlterIndxReq::RT_DICT_TC) {
  1294.       jam();
  1295.       if (opPtr.p->m_request.getOnline()) {
  1296.         // start create triggers
  1297.         alterIndex_toCreateTrigger(signal, opPtr);
  1298.       } else {
  1299.         opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
  1300.         alterIndex_sendSlaveReq(signal, opPtr);
  1301.       }
  1302.       return;
  1303.     }
  1304.   }
  1305.   if (indexPtr.p->isOrderedIndex()) {
  1306.     if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
  1307.       jam();
  1308.       if (opPtr.p->m_request.getOnline()) {
  1309.         // start create triggers
  1310.         alterIndex_toCreateTrigger(signal, opPtr);
  1311.       } else {
  1312.         // start drop triggers
  1313.         alterIndex_toDropTrigger(signal, opPtr);
  1314.       }
  1315.       return;
  1316.     }
  1317.   }
  1318.   ndbrequire(false);
  1319. }
  1320. void
  1321. Dbdict::alterIndex_slavePrepare(Signal* signal, OpAlterIndexPtr opPtr)
  1322. {
  1323.   jam();
  1324.   const AlterIndxReq* const req = &opPtr.p->m_request;
  1325.   if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
  1326.     jam();
  1327.     opPtr.p->m_errorCode = AlterIndxRef::Inconsistency;
  1328.     opPtr.p->m_errorLine = __LINE__;
  1329.     return;
  1330.   }
  1331.   TableRecordPtr indexPtr;
  1332.   c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
  1333.   if (indexPtr.p->tabState != TableRecord::DEFINED) {
  1334.     jam();
  1335.     opPtr.p->m_errorCode = AlterIndxRef::IndexNotFound;
  1336.     opPtr.p->m_errorLine = __LINE__;
  1337.     return;
  1338.   }
  1339.   if (! indexPtr.p->isIndex()) {
  1340.     jam();
  1341.     opPtr.p->m_errorCode = AlterIndxRef::NotAnIndex;
  1342.     opPtr.p->m_errorLine = __LINE__;
  1343.     return;
  1344.   }
  1345.   if (req->getOnline())
  1346.     indexPtr.p->indexState = TableRecord::IS_BUILDING;
  1347.   else
  1348.     indexPtr.p->indexState = TableRecord::IS_DROPPING;
  1349. }
  1350. void
  1351. Dbdict::alterIndex_toCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
  1352. {
  1353.   jam();
  1354.   TableRecordPtr indexPtr;
  1355.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1356.   // request to create index in local TC
  1357.   CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
  1358.   req->setUserRef(reference());
  1359.   req->setConnectionPtr(opPtr.p->key);
  1360.   req->setRequestType(CreateIndxReq::RT_TC);
  1361.   req->setIndexType(indexPtr.p->tableType);
  1362.   req->setTableId(indexPtr.p->primaryTableId);
  1363.   req->setIndexId(indexPtr.i);
  1364.   req->setOnline(true);
  1365.   getIndexAttrList(indexPtr, opPtr.p->m_attrList);
  1366.   // send
  1367.   LinearSectionPtr lsPtr[3];
  1368.   lsPtr[0].p = (Uint32*)&opPtr.p->m_attrList;
  1369.   lsPtr[0].sz = 1 + opPtr.p->m_attrList.sz;
  1370.   sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_CREATE_INDX_REQ,
  1371.       signal, CreateIndxReq::SignalLength, JBB, lsPtr, 1);
  1372. }
  1373. void
  1374. Dbdict::alterIndex_fromCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
  1375. {
  1376.   jam();
  1377.   // mark created in local TC
  1378.   if (! opPtr.p->hasLastError()) {
  1379.     TableRecordPtr indexPtr;
  1380.     c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1381.     indexPtr.p->indexLocal |= TableRecord::IL_CREATED_TC;
  1382.   }
  1383.   // forward CONF or REF to master
  1384.   ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
  1385.   alterIndex_sendReply(signal, opPtr, false);
  1386. }
  1387. void
  1388. Dbdict::alterIndex_toDropTc(Signal* signal, OpAlterIndexPtr opPtr)
  1389. {
  1390.   jam();
  1391.   TableRecordPtr indexPtr;
  1392.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1393.   // broken index allowed if force
  1394.   if (! (indexPtr.p->indexLocal & TableRecord::IL_CREATED_TC)) {
  1395.     jam();
  1396.     ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
  1397.     alterIndex_sendReply(signal, opPtr, false);
  1398.     return;
  1399.   }
  1400.   // request to drop in local TC
  1401.   DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
  1402.   req->setUserRef(reference());
  1403.   req->setConnectionPtr(opPtr.p->key);
  1404.   req->setRequestType(DropIndxReq::RT_TC);
  1405.   req->setTableId(indexPtr.p->primaryTableId);
  1406.   req->setIndexId(indexPtr.i);
  1407.   req->setIndexVersion(indexPtr.p->tableVersion);
  1408.   // send
  1409.   sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_DROP_INDX_REQ,
  1410.       signal, DropIndxReq::SignalLength, JBB);
  1411. }
  1412. void
  1413. Dbdict::alterIndex_fromDropTc(Signal* signal, OpAlterIndexPtr opPtr)
  1414. {
  1415.   jam();
  1416.   ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
  1417.   // mark dropped locally
  1418.   if (! opPtr.p->hasLastError()) {
  1419.     TableRecordPtr indexPtr;
  1420.     c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1421.     indexPtr.p->indexLocal &= ~TableRecord::IL_CREATED_TC;
  1422.   }
  1423.   // forward CONF or REF to master
  1424.   alterIndex_sendReply(signal, opPtr, false);
  1425. }
  1426. void
  1427. Dbdict::alterIndex_toCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
  1428. {
  1429.   jam();
  1430.   TableRecordPtr indexPtr;
  1431.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1432.   // start creation of index triggers
  1433.   CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
  1434.   req->setUserRef(reference());
  1435.   req->setConnectionPtr(opPtr.p->key);
  1436.   req->setRequestType(CreateTrigReq::RT_ALTER_INDEX);
  1437.   req->addRequestFlag(opPtr.p->m_requestFlag);
  1438.   req->setTableId(opPtr.p->m_request.getTableId());
  1439.   req->setIndexId(opPtr.p->m_request.getIndexId());
  1440.   req->setTriggerId(RNIL);
  1441.   req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
  1442.   req->setMonitorAllAttributes(false);
  1443.   req->setOnline(true);         // alter online after create
  1444.   req->setReceiverRef(0);       // implicit for index triggers
  1445.   getIndexAttrMask(indexPtr, req->getAttributeMask());
  1446.   // name section
  1447.   char triggerName[MAX_TAB_NAME_SIZE];
  1448.   Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)];    // SP string
  1449.   LinearWriter w(buffer, sizeof(buffer) >> 2);
  1450.   LinearSectionPtr lsPtr[3];
  1451.   if (indexPtr.p->isHashIndex()) {
  1452.     req->setTriggerType(TriggerType::SECONDARY_INDEX);
  1453.     req->setMonitorReplicas(false);
  1454.     // insert
  1455.     if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
  1456.       req->setTriggerId(indexPtr.p->insertTriggerId);
  1457.     req->setTriggerEvent(TriggerEvent::TE_INSERT);
  1458.     sprintf(triggerName, "NDB$INDEX_%u_INSERT", opPtr.p->m_request.getIndexId());
  1459.     w.reset();
  1460.     w.add(CreateTrigReq::TriggerNameKey, triggerName);
  1461.     lsPtr[0].p = buffer;
  1462.     lsPtr[0].sz = w.getWordsUsed();
  1463.     sendSignal(reference(), GSN_CREATE_TRIG_REQ, 
  1464.         signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
  1465.     // update
  1466.     if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
  1467.       req->setTriggerId(indexPtr.p->updateTriggerId);
  1468.     req->setTriggerEvent(TriggerEvent::TE_UPDATE);
  1469.     sprintf(triggerName, "NDB$INDEX_%u_UPDATE", opPtr.p->m_request.getIndexId());
  1470.     w.reset();
  1471.     w.add(CreateTrigReq::TriggerNameKey, triggerName);
  1472.     lsPtr[0].p = buffer;
  1473.     lsPtr[0].sz = w.getWordsUsed();
  1474.     sendSignal(reference(), GSN_CREATE_TRIG_REQ, 
  1475.         signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
  1476.     // delete
  1477.     if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
  1478.       req->setTriggerId(indexPtr.p->deleteTriggerId);
  1479.     req->setTriggerEvent(TriggerEvent::TE_DELETE);
  1480.     sprintf(triggerName, "NDB$INDEX_%u_DELETE", opPtr.p->m_request.getIndexId());
  1481.     w.reset();
  1482.     w.add(CreateTrigReq::TriggerNameKey, triggerName);
  1483.     lsPtr[0].p = buffer;
  1484.     lsPtr[0].sz = w.getWordsUsed();
  1485.     sendSignal(reference(), GSN_CREATE_TRIG_REQ, 
  1486.         signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
  1487.     // triggers left to create
  1488.     opPtr.p->m_triggerCounter = 3;
  1489.     return;
  1490.   }
  1491.   if (indexPtr.p->isOrderedIndex()) {
  1492.     req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
  1493.     req->setTriggerType(TriggerType::ORDERED_INDEX);
  1494.     req->setTriggerActionTime(TriggerActionTime::TA_CUSTOM);
  1495.     req->setMonitorReplicas(true);
  1496.     // one trigger for 5 events (insert, update, delete, commit, abort)
  1497.     if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
  1498.       req->setTriggerId(indexPtr.p->customTriggerId);
  1499.     req->setTriggerEvent(TriggerEvent::TE_CUSTOM);
  1500.     sprintf(triggerName, "NDB$INDEX_%u_CUSTOM", opPtr.p->m_request.getIndexId());
  1501.     w.reset();
  1502.     w.add(CreateTrigReq::TriggerNameKey, triggerName);
  1503.     lsPtr[0].p = buffer;
  1504.     lsPtr[0].sz = w.getWordsUsed();
  1505.     sendSignal(reference(), GSN_CREATE_TRIG_REQ, 
  1506.         signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
  1507.     // triggers left to create
  1508.     opPtr.p->m_triggerCounter = 1;
  1509.     return;
  1510.   }
  1511.   ndbrequire(false);
  1512. }
  1513. void
  1514. Dbdict::alterIndex_fromCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
  1515. {
  1516.   jam();
  1517.   ndbrequire(opPtr.p->m_triggerCounter != 0);
  1518.   if (--opPtr.p->m_triggerCounter != 0) {
  1519.     jam();
  1520.     return;
  1521.   }
  1522.   if (opPtr.p->hasError()) {
  1523.     jam();
  1524.     opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
  1525.     alterIndex_sendSlaveReq(signal, opPtr);
  1526.     return;
  1527.   }
  1528.   if(opPtr.p->m_requestType != AlterIndxReq::RT_SYSTEMRESTART){
  1529.     // send build request
  1530.     alterIndex_toBuildIndex(signal, opPtr);
  1531.     return;
  1532.   }
  1533.   
  1534.   /**
  1535.    * During system restart, 
  1536.    *   leave index in activated but not build state.
  1537.    *
  1538.    * Build a bit later when REDO has been run
  1539.    */
  1540.   alterIndex_sendReply(signal, opPtr, true);
  1541. }
  1542. void
  1543. Dbdict::alterIndex_toDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
  1544. {
  1545.   jam();
  1546.   TableRecordPtr indexPtr;
  1547.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1548.   // start drop of index triggers
  1549.   DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
  1550.   req->setUserRef(reference());
  1551.   req->setConnectionPtr(opPtr.p->key);
  1552.   req->setRequestType(DropTrigReq::RT_ALTER_INDEX);
  1553.   req->addRequestFlag(opPtr.p->m_requestFlag);
  1554.   req->setTableId(opPtr.p->m_request.getTableId());
  1555.   req->setIndexId(opPtr.p->m_request.getIndexId());
  1556.   req->setTriggerInfo(0);       // not used
  1557.   opPtr.p->m_triggerCounter = 0;
  1558.   if (indexPtr.p->isHashIndex()) {
  1559.     // insert
  1560.     req->setTriggerId(indexPtr.p->insertTriggerId);
  1561.     sendSignal(reference(), GSN_DROP_TRIG_REQ, 
  1562.         signal, DropTrigReq::SignalLength, JBB);
  1563.     opPtr.p->m_triggerCounter++;
  1564.     // update
  1565.     req->setTriggerId(indexPtr.p->updateTriggerId);
  1566.     sendSignal(reference(), GSN_DROP_TRIG_REQ, 
  1567.         signal, DropTrigReq::SignalLength, JBB);
  1568.     opPtr.p->m_triggerCounter++;
  1569.     // delete
  1570.     req->setTriggerId(indexPtr.p->deleteTriggerId);
  1571.     sendSignal(reference(), GSN_DROP_TRIG_REQ, 
  1572.         signal, DropTrigReq::SignalLength, JBB);
  1573.     opPtr.p->m_triggerCounter++;
  1574.     // build
  1575.     if (indexPtr.p->buildTriggerId != RNIL) {
  1576.       req->setTriggerId(indexPtr.p->buildTriggerId);
  1577.       sendSignal(reference(), GSN_DROP_TRIG_REQ, 
  1578.           signal, DropTrigReq::SignalLength, JBB);
  1579.       opPtr.p->m_triggerCounter++;
  1580.     }
  1581.     return;
  1582.   }
  1583.   if (indexPtr.p->isOrderedIndex()) {
  1584.     // custom
  1585.     req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
  1586.     req->setTriggerId(indexPtr.p->customTriggerId);
  1587.     sendSignal(reference(), GSN_DROP_TRIG_REQ, 
  1588.         signal, DropTrigReq::SignalLength, JBB);
  1589.     opPtr.p->m_triggerCounter++;
  1590.     return;
  1591.   }
  1592.   ndbrequire(false);
  1593. }
  1594. void
  1595. Dbdict::alterIndex_fromDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
  1596. {
  1597.   jam();
  1598.   ndbrequire(opPtr.p->m_triggerCounter != 0);
  1599.   if (--opPtr.p->m_triggerCounter != 0) {
  1600.     jam();
  1601.     return;
  1602.   }
  1603.   // finally drop index in each TC
  1604.   TableRecordPtr indexPtr;
  1605.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1606.   const bool isHashIndex = indexPtr.p->isHashIndex();
  1607.   const bool isOrderedIndex = indexPtr.p->isOrderedIndex();
  1608.   ndbrequire(isHashIndex != isOrderedIndex);    // xor
  1609.   if (isHashIndex)
  1610.     opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
  1611.   if (isOrderedIndex)
  1612.     opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
  1613.   alterIndex_sendSlaveReq(signal, opPtr);
  1614. }
  1615. void
  1616. Dbdict::alterIndex_toBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
  1617. {
  1618.   jam();
  1619.   // get index and table records
  1620.   TableRecordPtr indexPtr;
  1621.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1622.   TableRecordPtr tablePtr;
  1623.   c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
  1624.   // build request to self (short signal)
  1625.   BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
  1626.   req->setUserRef(reference());
  1627.   req->setConnectionPtr(opPtr.p->key);
  1628.   req->setRequestType(BuildIndxReq::RT_ALTER_INDEX);
  1629.   req->addRequestFlag(opPtr.p->m_requestFlag);
  1630.   req->setBuildId(0);   // not used
  1631.   req->setBuildKey(0);  // not used
  1632.   req->setIndexType(indexPtr.p->tableType);
  1633.   req->setIndexId(indexPtr.i);
  1634.   req->setTableId(indexPtr.p->primaryTableId);
  1635.   req->setParallelism(16);
  1636.   // send
  1637.   sendSignal(reference(), GSN_BUILDINDXREQ,
  1638.       signal, BuildIndxReq::SignalLength, JBB);
  1639. }
  1640. void
  1641. Dbdict::alterIndex_fromBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
  1642. {
  1643.   jam();
  1644.   if (opPtr.p->hasError()) {
  1645.     jam();
  1646.     opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
  1647.     alterIndex_sendSlaveReq(signal, opPtr);
  1648.     return;
  1649.   }
  1650.   opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
  1651.   alterIndex_sendSlaveReq(signal, opPtr);
  1652. }
  1653. void
  1654. Dbdict::alterIndex_slaveCommit(Signal* signal, OpAlterIndexPtr opPtr)
  1655. {
  1656.   jam();
  1657.   // get index record
  1658.   TableRecordPtr indexPtr;
  1659.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1660.   indexPtr.p->indexState = TableRecord::IS_ONLINE;
  1661. }
  1662. void
  1663. Dbdict::alterIndex_slaveAbort(Signal* signal, OpAlterIndexPtr opPtr)
  1664. {
  1665.   jam();
  1666.   // find index record
  1667.   const Uint32 indexId = opPtr.p->m_request.getIndexId();
  1668.   if (indexId >= c_tableRecordPool.getSize())
  1669.     return;
  1670.   TableRecordPtr indexPtr;
  1671.   c_tableRecordPool.getPtr(indexPtr, indexId);
  1672.   if (! indexPtr.p->isIndex())
  1673.     return;
  1674.   // mark broken
  1675.   indexPtr.p->indexState = TableRecord::IS_BROKEN;
  1676. }
  1677. void
  1678. Dbdict::alterIndex_sendSlaveReq(Signal* signal, OpAlterIndexPtr opPtr)
  1679. {
  1680.   AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
  1681.   *req = opPtr.p->m_request;
  1682.   req->setUserRef(opPtr.p->m_coordinatorRef);
  1683.   req->setConnectionPtr(opPtr.p->key);
  1684.   req->setRequestType(opPtr.p->m_requestType);
  1685.   req->addRequestFlag(opPtr.p->m_requestFlag);
  1686.   NdbNodeBitmask receiverNodes = c_aliveNodes;
  1687.   if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
  1688.     receiverNodes.clear();
  1689.     receiverNodes.set(getOwnNodeId());
  1690.   }
  1691.   opPtr.p->m_signalCounter = receiverNodes;
  1692.   NodeReceiverGroup rg(DBDICT, receiverNodes);
  1693.   sendSignal(rg, GSN_ALTER_INDX_REQ,
  1694.       signal, AlterIndxReq::SignalLength, JBB);
  1695. }
  1696. void
  1697. Dbdict::alterIndex_sendReply(Signal* signal, OpAlterIndexPtr opPtr,
  1698.     bool toUser)
  1699. {
  1700.   AlterIndxRef* rep = (AlterIndxRef*)signal->getDataPtrSend();
  1701.   Uint32 gsn = GSN_ALTER_INDX_CONF;
  1702.   Uint32 length = AlterIndxConf::InternalLength;
  1703.   bool sendRef;
  1704.   if (! toUser) {
  1705.     sendRef = opPtr.p->hasLastError();
  1706.     rep->setUserRef(opPtr.p->m_coordinatorRef);
  1707.     rep->setConnectionPtr(opPtr.p->key);
  1708.     rep->setRequestType(opPtr.p->m_requestType);
  1709.     if (opPtr.p->m_requestType == AlterIndxReq::RT_DICT_ABORT)
  1710.       sendRef = false;
  1711.   } else {
  1712.     sendRef = opPtr.p->hasError();
  1713.     rep->setUserRef(opPtr.p->m_request.getUserRef());
  1714.     rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
  1715.     rep->setRequestType(opPtr.p->m_request.getRequestType());
  1716.     length = AlterIndxConf::SignalLength;
  1717.   }
  1718.   rep->setTableId(opPtr.p->m_request.getTableId());
  1719.   rep->setIndexId(opPtr.p->m_request.getIndexId());
  1720.   if (sendRef) {
  1721.     if (opPtr.p->m_errorNode == 0)
  1722.       opPtr.p->m_errorNode = getOwnNodeId();
  1723.     rep->setErrorCode(opPtr.p->m_errorCode);
  1724.     rep->setErrorLine(opPtr.p->m_errorLine);
  1725.     rep->setErrorNode(opPtr.p->m_errorNode);
  1726.     gsn = GSN_ALTER_INDX_REF;
  1727.     length = AlterIndxRef::SignalLength;
  1728.   }
  1729.   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
  1730. }
  1731. /**
  1732.  * MODULE: Build index
  1733.  *
  1734.  * Build index or all indexes on a table.  Request type:
  1735.  *
  1736.  * RT_USER - normal user request, not yet used
  1737.  * RT_ALTER_INDEX - from alter index
  1738.  * RT_SYSTEM_RESTART - 
  1739.  * RT_DICT_PREPARE - prepare participants
  1740.  * RT_DICT_TRIX - to participant on way to local TRIX
  1741.  * RT_DICT_COMMIT - commit in each participant
  1742.  * RT_DICT_ABORT - abort
  1743.  * RT_TRIX - to local TRIX
  1744.  */
  1745. void
  1746. Dbdict::execBUILDINDXREQ(Signal* signal)
  1747. {
  1748.   jamEntry();
  1749.   BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
  1750.   OpBuildIndexPtr opPtr;
  1751.   const Uint32 senderRef = signal->senderBlockRef();
  1752.   const BuildIndxReq::RequestType requestType = req->getRequestType();
  1753.   if (requestType == BuildIndxReq::RT_USER ||
  1754.       requestType == BuildIndxReq::RT_ALTER_INDEX ||
  1755.       requestType == BuildIndxReq::RT_SYSTEMRESTART) {
  1756.     jam();
  1757.     const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
  1758.     NdbNodeBitmask receiverNodes = c_aliveNodes;
  1759.     if (isLocal) {
  1760.       receiverNodes.clear();
  1761.       receiverNodes.set(getOwnNodeId());
  1762.     }
  1763.     
  1764.     if (signal->getLength() == BuildIndxReq::SignalLength) {
  1765.       jam();
  1766.       
  1767.       if (!isLocal && getOwnNodeId() != c_masterNodeId) {
  1768.         jam();
  1769. releaseSections(signal);
  1770. OpBuildIndex opBad;
  1771. opPtr.p = &opBad;
  1772. opPtr.p->save(req);
  1773. opPtr.p->m_errorCode = BuildIndxRef::NotMaster;
  1774. opPtr.p->m_errorLine = __LINE__;
  1775. opPtr.p->m_errorNode = c_masterNodeId;
  1776. buildIndex_sendReply(signal, opPtr, true);
  1777.         return;
  1778.       }
  1779.       // forward initial request plus operation key to all
  1780.       req->setOpKey(++c_opRecordSequence);
  1781.       NodeReceiverGroup rg(DBDICT, receiverNodes);
  1782.       sendSignal(rg, GSN_BUILDINDXREQ,
  1783.  signal, BuildIndxReq::SignalLength + 1, JBB);
  1784.       return;
  1785.     }
  1786.     // seize operation record
  1787.     ndbrequire(signal->getLength() == BuildIndxReq::SignalLength + 1);
  1788.     const Uint32 opKey = req->getOpKey();
  1789.     OpBuildIndex opBusy;
  1790.     if (! c_opBuildIndex.seize(opPtr))
  1791.       opPtr.p = &opBusy;
  1792.     opPtr.p->save(req);
  1793.     opPtr.p->m_coordinatorRef = senderRef;
  1794.     opPtr.p->m_isMaster = (senderRef == reference());
  1795.     opPtr.p->key = opKey;
  1796.     opPtr.p->m_requestType = BuildIndxReq::RT_DICT_PREPARE;
  1797.     if (opPtr.p == &opBusy) {
  1798.       jam();
  1799.       opPtr.p->m_errorCode = BuildIndxRef::Busy;
  1800.       opPtr.p->m_errorLine = __LINE__;
  1801.       buildIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  1802.       return;
  1803.     }
  1804.     c_opBuildIndex.add(opPtr);
  1805.     // master expects to hear from all
  1806.     opPtr.p->m_signalCounter = receiverNodes;
  1807.     buildIndex_sendReply(signal, opPtr, false);
  1808.     return;
  1809.   }
  1810.   c_opBuildIndex.find(opPtr, req->getConnectionPtr());
  1811.   if (! opPtr.isNull()) {
  1812.     opPtr.p->m_requestType = requestType;
  1813.     if (requestType == BuildIndxReq::RT_DICT_TRIX) {
  1814.       jam();
  1815.       buildIndex_buildTrix(signal, opPtr);
  1816.       return;
  1817.     }
  1818.     if (requestType == BuildIndxReq::RT_DICT_TC ||
  1819.         requestType == BuildIndxReq::RT_DICT_TUX) {
  1820.       jam();
  1821.       buildIndex_toOnline(signal, opPtr);
  1822.       return;
  1823.     }
  1824.     if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
  1825.         requestType == BuildIndxReq::RT_DICT_ABORT) {
  1826.       jam();
  1827.       buildIndex_sendReply(signal, opPtr, false);
  1828.       // done in slave
  1829.       if (! opPtr.p->m_isMaster)
  1830.         c_opBuildIndex.release(opPtr);
  1831.       return;
  1832.     }
  1833.   }
  1834.   jam();
  1835.   // return to sender
  1836.   OpBuildIndex opBad;
  1837.   opPtr.p = &opBad;
  1838.   opPtr.p->save(req);
  1839.   opPtr.p->m_errorCode = BuildIndxRef::BadRequestType;
  1840.   opPtr.p->m_errorLine = __LINE__;
  1841.   buildIndex_sendReply(signal, opPtr, true);
  1842. }
  1843. void
  1844. Dbdict::execBUILDINDXCONF(Signal* signal)
  1845. {
  1846.   jamEntry();
  1847.   ndbrequire(signal->getNoOfSections() == 0);
  1848.   BuildIndxConf* conf = (BuildIndxConf*)signal->getDataPtrSend();
  1849.   buildIndex_recvReply(signal, conf, 0);
  1850. }
  1851. void
  1852. Dbdict::execBUILDINDXREF(Signal* signal)
  1853. {
  1854.   jamEntry();
  1855.   BuildIndxRef* ref = (BuildIndxRef*)signal->getDataPtrSend();
  1856.   buildIndex_recvReply(signal, ref->getConf(), ref);
  1857. }
  1858. void
  1859. Dbdict::buildIndex_recvReply(Signal* signal, const BuildIndxConf* conf,
  1860.     const BuildIndxRef* ref)
  1861. {
  1862.   jam();
  1863.   const Uint32 senderRef = signal->senderBlockRef();
  1864.   const BuildIndxReq::RequestType requestType = conf->getRequestType();
  1865.   const Uint32 key = conf->getConnectionPtr();
  1866.   if (requestType == BuildIndxReq::RT_ALTER_INDEX) {
  1867.     jam();
  1868.     // part of alter index operation
  1869.     OpAlterIndexPtr opPtr;
  1870.     c_opAlterIndex.find(opPtr, key);
  1871.     ndbrequire(! opPtr.isNull());
  1872.     opPtr.p->setError(ref);
  1873.     alterIndex_fromBuildIndex(signal, opPtr);
  1874.     return;
  1875.   }
  1876.   if (requestType == BuildIndxReq::RT_SYSTEMRESTART) {
  1877.     jam();
  1878.     if (ref == 0) {
  1879.       infoEvent("DICT: index %u rebuild done", (unsigned)key);
  1880.     } else {
  1881.       warningEvent("DICT: index %u rebuild failed: code=%d line=%d node=%d",
  1882.    (unsigned)key, ref->getErrorCode());
  1883.     }
  1884.     rebuildIndexes(signal, key + 1);
  1885.     return;
  1886.   }
  1887.   OpBuildIndexPtr opPtr;
  1888.   c_opBuildIndex.find(opPtr, key);
  1889.   ndbrequire(! opPtr.isNull());
  1890.   opPtr.p->setError(ref);
  1891.   if (requestType == BuildIndxReq::RT_TRIX) {
  1892.     jam();
  1893.     // forward to master
  1894.     opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
  1895.     buildIndex_sendReply(signal, opPtr, false);
  1896.     return;
  1897.   }
  1898.   ndbrequire(opPtr.p->m_isMaster);
  1899.   ndbrequire(opPtr.p->m_requestType == requestType);
  1900.   opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
  1901.   if (! opPtr.p->m_signalCounter.done()) {
  1902.     jam();
  1903.     return;
  1904.   }
  1905.   if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
  1906.       requestType == BuildIndxReq::RT_DICT_ABORT) {
  1907.     jam();
  1908.     // send reply to user
  1909.     buildIndex_sendReply(signal, opPtr, true);
  1910.     c_opBuildIndex.release(opPtr);
  1911.     return;
  1912.   }
  1913.   if (opPtr.p->hasError()) {
  1914.     jam();
  1915.     opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
  1916.     buildIndex_sendSlaveReq(signal, opPtr);
  1917.     return;
  1918.   }
  1919.   TableRecordPtr indexPtr;
  1920.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1921.   if (indexPtr.p->isHashIndex()) {
  1922.     if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
  1923.       jam();
  1924.       if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
  1925.         buildIndex_toCreateConstr(signal, opPtr);
  1926.       } else {
  1927.         opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
  1928.         buildIndex_sendSlaveReq(signal, opPtr);
  1929.       }
  1930.       return;
  1931.     }
  1932.     if (requestType == BuildIndxReq::RT_DICT_TRIX) {
  1933.       jam();
  1934.       ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
  1935.       buildIndex_toDropConstr(signal, opPtr);
  1936.       return;
  1937.     }
  1938.     if (requestType == BuildIndxReq::RT_DICT_TC) {
  1939.       jam();
  1940.       opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
  1941.       buildIndex_sendSlaveReq(signal, opPtr);
  1942.       return;
  1943.     }
  1944.   }
  1945.   if (indexPtr.p->isOrderedIndex()) {
  1946.     if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
  1947.       jam();
  1948.       if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
  1949.         opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
  1950.         buildIndex_sendSlaveReq(signal, opPtr);
  1951.       } else {
  1952.         opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
  1953.         buildIndex_sendSlaveReq(signal, opPtr);
  1954.       }
  1955.       return;
  1956.     }
  1957.     if (requestType == BuildIndxReq::RT_DICT_TRIX) {
  1958.       jam();
  1959.       ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
  1960.       opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
  1961.       buildIndex_sendSlaveReq(signal, opPtr);
  1962.       return;
  1963.     }
  1964.     if (requestType == BuildIndxReq::RT_DICT_TUX) {
  1965.       jam();
  1966.       opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
  1967.       buildIndex_sendSlaveReq(signal, opPtr);
  1968.       return;
  1969.     }
  1970.   }
  1971.   ndbrequire(false);
  1972. void
  1973. Dbdict::buildIndex_toCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
  1974. {
  1975.   jam();
  1976.   TableRecordPtr indexPtr;
  1977.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  1978.   // request to create constraint trigger
  1979.   CreateTrigReq* req = (CreateTrigReq*)signal->getDataPtrSend();
  1980.   req->setUserRef(reference());
  1981.   req->setConnectionPtr(opPtr.p->key);
  1982.   req->setRequestType(CreateTrigReq::RT_BUILD_INDEX);
  1983.   req->addRequestFlag(0);       // none
  1984.   req->setTableId(indexPtr.i);
  1985.   req->setIndexId(RNIL);
  1986.   req->setTriggerId(RNIL);
  1987.   req->setTriggerType(TriggerType::READ_ONLY_CONSTRAINT);
  1988.   req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
  1989.   req->setTriggerEvent(TriggerEvent::TE_UPDATE);
  1990.   req->setMonitorReplicas(false);
  1991.   req->setMonitorAllAttributes(false);
  1992.   req->setOnline(true);         // alter online after create
  1993.   req->setReceiverRef(0);       // no receiver, REF-ed by TUP
  1994.   req->getAttributeMask().clear();
  1995.   // NDB$PK is last attribute
  1996.   req->getAttributeMask().set(indexPtr.p->noOfAttributes - 1);
  1997.   // name section
  1998.   char triggerName[MAX_TAB_NAME_SIZE];
  1999.   Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)];    // SP string
  2000.   LinearWriter w(buffer, sizeof(buffer) >> 2);
  2001.   LinearSectionPtr lsPtr[3];
  2002.   sprintf(triggerName, "NDB$INDEX_%u_BUILD", indexPtr.i);
  2003.   w.reset();
  2004.   w.add(CreateTrigReq::TriggerNameKey, triggerName);
  2005.   lsPtr[0].p = buffer;
  2006.   lsPtr[0].sz = w.getWordsUsed();
  2007.   sendSignal(reference(), GSN_CREATE_TRIG_REQ,
  2008.       signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
  2009. }
  2010. void
  2011. Dbdict::buildIndex_fromCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
  2012. {
  2013.   jam();
  2014.   if (opPtr.p->hasError()) {
  2015.     jam();
  2016.     opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
  2017.     buildIndex_sendSlaveReq(signal, opPtr);
  2018.     return;
  2019.   }
  2020.   opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
  2021.   buildIndex_sendSlaveReq(signal, opPtr);
  2022. }
  2023. void
  2024. Dbdict::buildIndex_buildTrix(Signal* signal, OpBuildIndexPtr opPtr)
  2025. {
  2026.   jam();
  2027.   TableRecordPtr indexPtr;
  2028.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  2029.   TableRecordPtr tablePtr;
  2030.   c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
  2031.   // build request
  2032.   BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
  2033.   req->setUserRef(reference());
  2034.   req->setConnectionPtr(opPtr.p->key);
  2035.   req->setRequestType(BuildIndxReq::RT_TRIX);
  2036.   req->setBuildId(0);   // not yet..
  2037.   req->setBuildKey(0);  // ..in use
  2038.   req->setIndexType(indexPtr.p->tableType);
  2039.   req->setIndexId(indexPtr.i);
  2040.   req->setTableId(indexPtr.p->primaryTableId);
  2041.   req->setParallelism(16);
  2042.   if (indexPtr.p->isHashIndex()) {
  2043.     jam();
  2044.     getIndexAttrList(indexPtr, opPtr.p->m_attrList);
  2045.     getTableKeyList(tablePtr, opPtr.p->m_tableKeyList);
  2046.     // send
  2047.     LinearSectionPtr lsPtr[3];
  2048.     lsPtr[0].sz = opPtr.p->m_attrList.sz;
  2049.     lsPtr[0].p = opPtr.p->m_attrList.id;
  2050.     lsPtr[1].sz = opPtr.p->m_tableKeyList.sz;
  2051.     lsPtr[1].p = opPtr.p->m_tableKeyList.id;
  2052.     sendSignal(calcTrixBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
  2053.         signal, BuildIndxReq::SignalLength, JBB, lsPtr, 2);
  2054.     return;
  2055.   }
  2056.   if (indexPtr.p->isOrderedIndex()) {
  2057.     jam();
  2058.     sendSignal(calcTupBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
  2059.         signal, BuildIndxReq::SignalLength, JBB);
  2060.     return;
  2061.   }
  2062.   ndbrequire(false);
  2063. }
  2064. void
  2065. Dbdict::buildIndex_toDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
  2066. {
  2067.   jam();
  2068.   TableRecordPtr indexPtr;
  2069.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  2070.   // request to drop constraint trigger
  2071.   DropTrigReq* req = (DropTrigReq*)signal->getDataPtrSend();
  2072.   req->setUserRef(reference());
  2073.   req->setConnectionPtr(opPtr.p->key);
  2074.   req->setRequestType(DropTrigReq::RT_BUILD_INDEX);
  2075.   req->addRequestFlag(0);       // none
  2076.   req->setTableId(indexPtr.i);
  2077.   req->setIndexId(RNIL);
  2078.   req->setTriggerId(opPtr.p->m_constrTriggerId);
  2079.   req->setTriggerInfo(0);       // not used
  2080.   sendSignal(reference(), GSN_DROP_TRIG_REQ,
  2081.       signal, DropTrigReq::SignalLength, JBB);
  2082. }
  2083. void
  2084. Dbdict::buildIndex_fromDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
  2085. {
  2086.   jam();
  2087.   if (opPtr.p->hasError()) {
  2088.     jam();
  2089.     opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
  2090.     buildIndex_sendSlaveReq(signal, opPtr);
  2091.     return;
  2092.   }
  2093.   opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
  2094.   buildIndex_sendSlaveReq(signal, opPtr);
  2095. }
  2096. void
  2097. Dbdict::buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr)
  2098. {
  2099.   jam();
  2100.   TableRecordPtr indexPtr;
  2101.   c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
  2102.   TableRecordPtr tablePtr;
  2103.   c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
  2104.   // request to set index online in TC or TUX
  2105.   AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
  2106.   req->setUserRef(reference());
  2107.   req->setConnectionPtr(opPtr.p->key);
  2108.   if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
  2109.     jam();
  2110.     req->setRequestType(AlterIndxReq::RT_TC);
  2111.   } else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
  2112.     jam();
  2113.     req->setRequestType(AlterIndxReq::RT_TUX);
  2114.   } else {
  2115.     ndbrequire(false);
  2116.   }
  2117.   req->setTableId(tablePtr.i);
  2118.   req->setIndexId(indexPtr.i);
  2119.   req->setIndexVersion(indexPtr.p->tableVersion);
  2120.   req->setOnline(true);
  2121.   BlockReference blockRef = 0;
  2122.   if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
  2123.     jam();
  2124.     blockRef = calcTcBlockRef(getOwnNodeId());
  2125.   } else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
  2126.     jam();
  2127.     blockRef = calcTuxBlockRef(getOwnNodeId());
  2128.   } else {
  2129.     ndbrequire(false);
  2130.   }
  2131.   // send
  2132.   sendSignal(blockRef, GSN_ALTER_INDX_REQ,
  2133.       signal, BuildIndxReq::SignalLength, JBB);
  2134. }
  2135. void
  2136. Dbdict::buildIndex_fromOnline(Signal* signal, OpBuildIndexPtr opPtr)
  2137. {
  2138.   jam();
  2139.   // forward to master
  2140.   buildIndex_sendReply(signal, opPtr, false);
  2141. }
  2142. void
  2143. Dbdict::buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr)
  2144. {
  2145.   BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
  2146.   *req = opPtr.p->m_request;
  2147.   req->setUserRef(opPtr.p->m_coordinatorRef);
  2148.   req->setConnectionPtr(opPtr.p->key);
  2149.   req->setRequestType(opPtr.p->m_requestType);
  2150.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2151.   if(opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
  2152.     jam();
  2153.     opPtr.p->m_signalCounter.clearWaitingFor();
  2154.     opPtr.p->m_signalCounter.setWaitingFor(getOwnNodeId());
  2155.     sendSignal(reference(), GSN_BUILDINDXREQ,
  2156.        signal, BuildIndxReq::SignalLength, JBB);
  2157.   } else {
  2158.     jam();
  2159.     opPtr.p->m_signalCounter = c_aliveNodes;
  2160.     NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2161.     sendSignal(rg, GSN_BUILDINDXREQ,
  2162.        signal, BuildIndxReq::SignalLength, JBB);
  2163.   }
  2164. }
  2165. void
  2166. Dbdict::buildIndex_sendReply(Signal* signal, OpBuildIndexPtr opPtr,
  2167.     bool toUser)
  2168. {
  2169.   BuildIndxRef* rep = (BuildIndxRef*)signal->getDataPtrSend();
  2170.   Uint32 gsn = GSN_BUILDINDXCONF;
  2171.   Uint32 length = BuildIndxConf::InternalLength;
  2172.   bool sendRef;
  2173.   if (! toUser) {
  2174.     sendRef = opPtr.p->hasLastError();
  2175.     rep->setUserRef(opPtr.p->m_coordinatorRef);
  2176.     rep->setConnectionPtr(opPtr.p->key);
  2177.     rep->setRequestType(opPtr.p->m_requestType);
  2178.     if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_ABORT)
  2179.       sendRef = false;
  2180.   } else {
  2181.     sendRef = opPtr.p->hasError();
  2182.     rep->setUserRef(opPtr.p->m_request.getUserRef());
  2183.     rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
  2184.     rep->setRequestType(opPtr.p->m_request.getRequestType());
  2185.     length = BuildIndxConf::SignalLength;
  2186.   }
  2187.   rep->setIndexType(opPtr.p->m_request.getIndexType());
  2188.   rep->setTableId(opPtr.p->m_request.getTableId());
  2189.   rep->setIndexId(opPtr.p->m_request.getIndexId());
  2190.   if (sendRef) {
  2191.     rep->setErrorCode(opPtr.p->m_errorCode);
  2192.     rep->masterNodeId = opPtr.p->m_errorNode;
  2193.     gsn = GSN_BUILDINDXREF;
  2194.     length = BuildIndxRef::SignalLength;
  2195.   }
  2196.   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
  2197. }
  2198. /**
  2199.  * MODULE: Create trigger
  2200.  *
  2201.  * Create trigger in all DICT blocks.  Optionally start alter trigger
  2202.  * operation to set the trigger online.
  2203.  *
  2204.  * Request type received in REQ and returned in CONF/REF:
  2205.  *
  2206.  * RT_USER - normal user e.g. BACKUP
  2207.  * RT_ALTER_INDEX - from alter index online
  2208.  * RT_DICT_PREPARE - seize operation in each DICT
  2209.  * RT_DICT_COMMIT - commit create in each DICT
  2210.  * RT_TC - sending to TC (operation alter trigger)
  2211.  * RT_LQH - sending to LQH (operation alter trigger)
  2212.  */
  2213. void
  2214. Dbdict::execCREATE_TRIG_REQ(Signal* signal) 
  2215. {
  2216.   jamEntry();
  2217.   CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
  2218.   OpCreateTriggerPtr opPtr;
  2219.   const Uint32 senderRef = signal->senderBlockRef();
  2220.   const CreateTrigReq::RequestType requestType = req->getRequestType();
  2221.   if (requestType == CreateTrigReq::RT_USER ||
  2222.       requestType == CreateTrigReq::RT_ALTER_INDEX ||
  2223.       requestType == CreateTrigReq::RT_BUILD_INDEX) {
  2224.     jam();
  2225.     if (! assembleFragments(signal)) {
  2226.       jam();
  2227.       return;
  2228.     }
  2229.     const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
  2230.     NdbNodeBitmask receiverNodes = c_aliveNodes;
  2231.     if (isLocal) {
  2232.       receiverNodes.clear();
  2233.       receiverNodes.set(getOwnNodeId());
  2234.     }
  2235.     if (signal->getLength() == CreateTrigReq::SignalLength) {
  2236.       jam();
  2237.       if (! isLocal && getOwnNodeId() != c_masterNodeId) {
  2238.         jam();
  2239. releaseSections(signal);
  2240. OpCreateTrigger opBad;
  2241. opPtr.p = &opBad;
  2242. opPtr.p->save(req);
  2243. opPtr.p->m_errorCode = CreateTrigRef::NotMaster;
  2244. opPtr.p->m_errorLine = __LINE__;
  2245. opPtr.p->m_errorNode = c_masterNodeId;
  2246. createTrigger_sendReply(signal,  opPtr, true);
  2247.         return;
  2248.       }
  2249.       // forward initial request plus operation key to all
  2250.       req->setOpKey(++c_opRecordSequence);
  2251.       NodeReceiverGroup rg(DBDICT, receiverNodes);
  2252.       sendSignal(rg, GSN_CREATE_TRIG_REQ,
  2253.           signal, CreateTrigReq::SignalLength + 1, JBB);
  2254.       return;
  2255.     }
  2256.     // seize operation record
  2257.     ndbrequire(signal->getLength() == CreateTrigReq::SignalLength + 1);
  2258.     const Uint32 opKey = req->getOpKey();
  2259.     OpCreateTrigger opBusy;
  2260.     if (! c_opCreateTrigger.seize(opPtr))
  2261.       opPtr.p = &opBusy;
  2262.     opPtr.p->save(req);
  2263.     opPtr.p->m_coordinatorRef = senderRef;
  2264.     opPtr.p->m_isMaster = (senderRef == reference());
  2265.     opPtr.p->key = opKey;
  2266.     opPtr.p->m_requestType = CreateTrigReq::RT_DICT_PREPARE;
  2267.     if (opPtr.p == &opBusy) {
  2268.       jam();
  2269.       opPtr.p->m_errorCode = CreateTrigRef::Busy;
  2270.       opPtr.p->m_errorLine = __LINE__;
  2271.       releaseSections(signal);
  2272.       createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2273.       return;
  2274.     }
  2275.     c_opCreateTrigger.add(opPtr);
  2276.     {
  2277.       // save name
  2278.       SegmentedSectionPtr ssPtr;
  2279.       signal->getSection(ssPtr, CreateTrigReq::TRIGGER_NAME_SECTION);
  2280.       SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
  2281.       if (ssReader.getKey() != CreateTrigReq::TriggerNameKey ||
  2282.   ! ssReader.getString(opPtr.p->m_triggerName)) {
  2283. jam();
  2284. opPtr.p->m_errorCode = CreateTrigRef::InvalidName;
  2285. opPtr.p->m_errorLine = __LINE__;
  2286. releaseSections(signal);
  2287. createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2288. return;
  2289.       }
  2290.     }
  2291.     releaseSections(signal);
  2292.     {
  2293.       // check that trigger name is unique
  2294.       TriggerRecordPtr triggerPtr;
  2295.       TriggerRecord keyRecord;
  2296.       strcpy(keyRecord.triggerName, opPtr.p->m_triggerName);
  2297.       c_triggerRecordHash.find(triggerPtr, keyRecord);
  2298.       if (triggerPtr.i != RNIL) {
  2299. jam();
  2300. opPtr.p->m_errorCode = CreateTrigRef::TriggerExists;
  2301. opPtr.p->m_errorLine = __LINE__;
  2302. createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2303. return;
  2304.       }
  2305.     }
  2306.     // master expects to hear from all
  2307.     if (opPtr.p->m_isMaster)
  2308.       opPtr.p->m_signalCounter = receiverNodes;
  2309.     // check request in all participants
  2310.     createTrigger_slavePrepare(signal, opPtr);
  2311.     createTrigger_sendReply(signal, opPtr, false);
  2312.     return;
  2313.   }
  2314.   c_opCreateTrigger.find(opPtr, req->getConnectionPtr());
  2315.   if (! opPtr.isNull()) {
  2316.     opPtr.p->m_requestType = requestType;
  2317.     if (requestType == CreateTrigReq::RT_DICT_CREATE) {
  2318.       jam();
  2319.       // master has set trigger id
  2320.       opPtr.p->m_request.setTriggerId(req->getTriggerId());
  2321.       createTrigger_slaveCreate(signal, opPtr);
  2322.       createTrigger_sendReply(signal, opPtr, false);
  2323.       return;
  2324.     }
  2325.     if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
  2326.         requestType == CreateTrigReq::RT_DICT_ABORT) {
  2327.       jam();
  2328.       if (requestType == CreateTrigReq::RT_DICT_COMMIT)
  2329.         createTrigger_slaveCommit(signal, opPtr);
  2330.       else
  2331.         createTrigger_slaveAbort(signal, opPtr);
  2332.       createTrigger_sendReply(signal, opPtr, false);
  2333.       // done in slave
  2334.       if (! opPtr.p->m_isMaster)
  2335.         c_opCreateTrigger.release(opPtr);
  2336.       return;
  2337.     }
  2338.   }
  2339.   jam();
  2340.   // return to sender
  2341.   releaseSections(signal);
  2342.   OpCreateTrigger opBad;
  2343.   opPtr.p = &opBad;
  2344.   opPtr.p->save(req);
  2345.   opPtr.p->m_errorCode = CreateTrigRef::BadRequestType;
  2346.   opPtr.p->m_errorLine = __LINE__;
  2347.   createTrigger_sendReply(signal,  opPtr, true);
  2348. }
  2349. void
  2350. Dbdict::execCREATE_TRIG_CONF(Signal* signal) 
  2351. {
  2352.   jamEntry();
  2353.   ndbrequire(signal->getNoOfSections() == 0);
  2354.   CreateTrigConf* conf = (CreateTrigConf*)signal->getDataPtrSend();
  2355.   createTrigger_recvReply(signal, conf, 0);
  2356. }
  2357. void
  2358. Dbdict::execCREATE_TRIG_REF(Signal* signal) 
  2359. {
  2360.   jamEntry();
  2361.   CreateTrigRef* ref = (CreateTrigRef*)signal->getDataPtrSend();
  2362.   createTrigger_recvReply(signal, ref->getConf(), ref);
  2363. }
  2364. void
  2365. Dbdict::createTrigger_recvReply(Signal* signal, const CreateTrigConf* conf,
  2366.     const CreateTrigRef* ref)
  2367. {
  2368.   jam();
  2369.   const Uint32 senderRef = signal->senderBlockRef();
  2370.   const CreateTrigReq::RequestType requestType = conf->getRequestType();
  2371.   const Uint32 key = conf->getConnectionPtr();
  2372.   if (requestType == CreateTrigReq::RT_ALTER_INDEX) {
  2373.     jam();
  2374.     // part of alter index operation
  2375.     OpAlterIndexPtr opPtr;
  2376.     c_opAlterIndex.find(opPtr, key);
  2377.     ndbrequire(! opPtr.isNull());
  2378.     opPtr.p->setError(ref);
  2379.     alterIndex_fromCreateTrigger(signal, opPtr);
  2380.     return;
  2381.   }
  2382.   if (requestType == CreateTrigReq::RT_BUILD_INDEX) {
  2383.     jam();
  2384.     // part of build index operation
  2385.     OpBuildIndexPtr opPtr;
  2386.     c_opBuildIndex.find(opPtr, key);
  2387.     ndbrequire(! opPtr.isNull());
  2388.     opPtr.p->setError(ref);
  2389.     // fill in trigger id
  2390.     opPtr.p->m_constrTriggerId = conf->getTriggerId();
  2391.     buildIndex_fromCreateConstr(signal, opPtr);
  2392.     return;
  2393.   }
  2394.   if (requestType == CreateTrigReq::RT_TC ||
  2395.       requestType == CreateTrigReq::RT_LQH) {
  2396.     jam();
  2397.     // part of alter trigger operation
  2398.     OpAlterTriggerPtr opPtr;
  2399.     c_opAlterTrigger.find(opPtr, key);
  2400.     ndbrequire(! opPtr.isNull());
  2401.     opPtr.p->setError(ref);
  2402.     alterTrigger_fromCreateLocal(signal, opPtr);
  2403.     return;
  2404.   }
  2405.   OpCreateTriggerPtr opPtr;
  2406.   c_opCreateTrigger.find(opPtr, key);
  2407.   ndbrequire(! opPtr.isNull());
  2408.   ndbrequire(opPtr.p->m_isMaster);
  2409.   ndbrequire(opPtr.p->m_requestType == requestType);
  2410.   opPtr.p->setError(ref);
  2411.   opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
  2412.   if (! opPtr.p->m_signalCounter.done()) {
  2413.     jam();
  2414.     return;
  2415.   }
  2416.   if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
  2417.       requestType == CreateTrigReq::RT_DICT_ABORT) {
  2418.     jam();
  2419.     // send reply to user
  2420.     createTrigger_sendReply(signal, opPtr, true);
  2421.     c_opCreateTrigger.release(opPtr);
  2422.     return;
  2423.   }
  2424.   if (opPtr.p->hasError()) {
  2425.     jam();
  2426.     opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
  2427.     createTrigger_sendSlaveReq(signal, opPtr);
  2428.     return;
  2429.   }
  2430.   if (requestType == CreateTrigReq::RT_DICT_PREPARE) {
  2431.     jam();
  2432.     // seize trigger id in master
  2433.     createTrigger_masterSeize(signal, opPtr);
  2434.     if (opPtr.p->hasError()) {
  2435.       jam();
  2436.       opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
  2437.       createTrigger_sendSlaveReq(signal, opPtr);
  2438.       return;
  2439.     }
  2440.     opPtr.p->m_requestType = CreateTrigReq::RT_DICT_CREATE;
  2441.     createTrigger_sendSlaveReq(signal, opPtr);
  2442.     return;
  2443.   }
  2444.   if (requestType == CreateTrigReq::RT_DICT_CREATE) {
  2445.     jam();
  2446.     if (opPtr.p->m_request.getOnline()) {
  2447.       jam();
  2448.       // start alter online
  2449.       createTrigger_toAlterTrigger(signal, opPtr);
  2450.       return;
  2451.     }
  2452.     opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
  2453.     createTrigger_sendSlaveReq(signal, opPtr);
  2454.     return;
  2455.   }
  2456.   ndbrequire(false);
  2457. }
  2458. void
  2459. Dbdict::createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr)
  2460. {
  2461.   jam();
  2462.   const CreateTrigReq* const req = &opPtr.p->m_request;
  2463.   // check trigger type
  2464.   if (req->getRequestType() == CreateTrigReq::RT_USER &&
  2465.       req->getTriggerType() == TriggerType::SUBSCRIPTION ||
  2466.       req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
  2467.       req->getTriggerType() == TriggerType::SECONDARY_INDEX ||
  2468.       req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
  2469.       req->getTriggerType() == TriggerType::ORDERED_INDEX ||
  2470.       req->getRequestType() == CreateTrigReq::RT_BUILD_INDEX &&
  2471.       req->getTriggerType() == TriggerType::READ_ONLY_CONSTRAINT) {
  2472.     ;
  2473.   } else {
  2474.     jam();
  2475.     opPtr.p->m_errorCode = CreateTrigRef::UnsupportedTriggerType;
  2476.     opPtr.p->m_errorLine = __LINE__;
  2477.     return;
  2478.   }
  2479.   // check the table
  2480.   const Uint32 tableId = req->getTableId();
  2481.   if (! (tableId < c_tableRecordPool.getSize())) {
  2482.     jam();
  2483.     opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
  2484.     opPtr.p->m_errorLine = __LINE__;
  2485.     return;
  2486.   }
  2487.   TableRecordPtr tablePtr;
  2488.   c_tableRecordPool.getPtr(tablePtr, tableId);
  2489.   if (tablePtr.p->tabState != TableRecord::DEFINED &&
  2490.       tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
  2491.     jam();
  2492.     opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
  2493.     opPtr.p->m_errorLine = __LINE__;
  2494.     return;
  2495.   }
  2496. }
  2497. void
  2498. Dbdict::createTrigger_masterSeize(Signal* signal, OpCreateTriggerPtr opPtr)
  2499. {
  2500.   TriggerRecordPtr triggerPtr;
  2501.   if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
  2502.     triggerPtr.i = opPtr.p->m_request.getTriggerId();
  2503.   } else {
  2504.     triggerPtr.i = getFreeTriggerRecord();
  2505.     if (triggerPtr.i == RNIL) {
  2506.       jam();
  2507.       opPtr.p->m_errorCode = CreateTrigRef::TooManyTriggers;
  2508.       opPtr.p->m_errorLine = __LINE__;
  2509.       return;
  2510.     }
  2511.   }
  2512.   c_triggerRecordPool.getPtr(triggerPtr);
  2513.   initialiseTriggerRecord(triggerPtr);
  2514.   triggerPtr.p->triggerState = TriggerRecord::TS_DEFINING;
  2515.   opPtr.p->m_request.setTriggerId(triggerPtr.i);
  2516. }
  2517. void
  2518. Dbdict::createTrigger_slaveCreate(Signal* signal, OpCreateTriggerPtr opPtr)
  2519. {
  2520.   jam();
  2521.   const CreateTrigReq* const req = &opPtr.p->m_request;
  2522.   // get the trigger record
  2523.   const Uint32 triggerId = req->getTriggerId();
  2524.   TriggerRecordPtr triggerPtr;
  2525.   c_triggerRecordPool.getPtr(triggerPtr, triggerId);
  2526.   initialiseTriggerRecord(triggerPtr);
  2527.   // fill in trigger data
  2528.   strcpy(triggerPtr.p->triggerName, opPtr.p->m_triggerName);
  2529.   triggerPtr.p->triggerId = triggerId;
  2530.   triggerPtr.p->tableId = req->getTableId();
  2531.   triggerPtr.p->indexId = RNIL;
  2532.   triggerPtr.p->triggerType = req->getTriggerType();
  2533.   triggerPtr.p->triggerActionTime = req->getTriggerActionTime();
  2534.   triggerPtr.p->triggerEvent = req->getTriggerEvent();
  2535.   triggerPtr.p->monitorReplicas = req->getMonitorReplicas();
  2536.   triggerPtr.p->monitorAllAttributes = req->getMonitorAllAttributes();
  2537.   triggerPtr.p->attributeMask = req->getAttributeMask();
  2538.   triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
  2539.   // add to hash table
  2540.   //  ndbout_c("++++++++++++ Adding trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
  2541.   c_triggerRecordHash.add(triggerPtr);
  2542.   if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
  2543.       triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
  2544.     jam();
  2545.     // connect to index record  XXX should be done in caller instead
  2546.     triggerPtr.p->indexId = req->getIndexId();
  2547.     TableRecordPtr indexPtr;
  2548.     c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
  2549.     switch (triggerPtr.p->triggerEvent) {
  2550.     case TriggerEvent::TE_INSERT:
  2551.       indexPtr.p->insertTriggerId = triggerPtr.p->triggerId;
  2552.       break;
  2553.     case TriggerEvent::TE_UPDATE:
  2554.       indexPtr.p->updateTriggerId = triggerPtr.p->triggerId;
  2555.       break;
  2556.     case TriggerEvent::TE_DELETE:
  2557.       indexPtr.p->deleteTriggerId = triggerPtr.p->triggerId;
  2558.       break;
  2559.     case TriggerEvent::TE_CUSTOM:
  2560.       indexPtr.p->customTriggerId = triggerPtr.p->triggerId;
  2561.       break;
  2562.     default:
  2563.       ndbrequire(false);
  2564.       break;
  2565.     }
  2566.   }
  2567.   if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
  2568.     jam();
  2569.     // connect to index record  XXX should be done in caller instead
  2570.     triggerPtr.p->indexId = req->getTableId();
  2571.     TableRecordPtr indexPtr;
  2572.     c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
  2573.     indexPtr.p->buildTriggerId = triggerPtr.p->triggerId;
  2574.   }
  2575. }
  2576. void
  2577. Dbdict::createTrigger_toAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
  2578. {
  2579.   jam();
  2580.   AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
  2581.   req->setUserRef(reference());
  2582.   req->setConnectionPtr(opPtr.p->key);
  2583.   req->setRequestType(AlterTrigReq::RT_CREATE_TRIGGER);
  2584.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2585.   req->setTableId(opPtr.p->m_request.getTableId());
  2586.   req->setTriggerId(opPtr.p->m_request.getTriggerId());
  2587.   req->setTriggerInfo(0);       // not used
  2588.   req->setOnline(true);
  2589.   req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
  2590.   sendSignal(reference(), GSN_ALTER_TRIG_REQ,
  2591.       signal, AlterTrigReq::SignalLength, JBB);
  2592. }
  2593. void
  2594. Dbdict::createTrigger_fromAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
  2595. {
  2596.   jam();
  2597.   if (opPtr.p->hasError()) {
  2598.     jam();
  2599.     opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
  2600.     createTrigger_sendSlaveReq(signal, opPtr);
  2601.     return;
  2602.   }
  2603.   opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
  2604.   createTrigger_sendSlaveReq(signal, opPtr);
  2605. }
  2606. void
  2607. Dbdict::createTrigger_slaveCommit(Signal* signal, OpCreateTriggerPtr opPtr)
  2608. {
  2609.   jam();
  2610.   const CreateTrigReq* const req = &opPtr.p->m_request;
  2611.   // get the trigger record
  2612.   const Uint32 triggerId = req->getTriggerId();
  2613.   TriggerRecordPtr triggerPtr;
  2614.   c_triggerRecordPool.getPtr(triggerPtr, triggerId);
  2615.   if (! req->getOnline()) {
  2616.     triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
  2617.   } else {
  2618.     ndbrequire(triggerPtr.p->triggerState == TriggerRecord::TS_ONLINE);
  2619.   }
  2620. }
  2621. void
  2622. Dbdict::createTrigger_slaveAbort(Signal* signal, OpCreateTriggerPtr opPtr)
  2623. {
  2624.   jam();
  2625. }
  2626. void
  2627. Dbdict::createTrigger_sendSlaveReq(Signal* signal, OpCreateTriggerPtr opPtr)
  2628. {
  2629.   CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
  2630.   *req = opPtr.p->m_request;
  2631.   req->setUserRef(opPtr.p->m_coordinatorRef);
  2632.   req->setConnectionPtr(opPtr.p->key);
  2633.   req->setRequestType(opPtr.p->m_requestType);
  2634.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2635.   NdbNodeBitmask receiverNodes = c_aliveNodes;
  2636.   if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
  2637.     receiverNodes.clear();
  2638.     receiverNodes.set(getOwnNodeId());
  2639.   }
  2640.   opPtr.p->m_signalCounter = receiverNodes;
  2641.   NodeReceiverGroup rg(DBDICT, receiverNodes);
  2642.   sendSignal(rg, GSN_CREATE_TRIG_REQ,
  2643.       signal, CreateTrigReq::SignalLength, JBB);
  2644. }
  2645. void
  2646. Dbdict::createTrigger_sendReply(Signal* signal, OpCreateTriggerPtr opPtr,
  2647.     bool toUser)
  2648. {
  2649.   CreateTrigRef* rep = (CreateTrigRef*)signal->getDataPtrSend();
  2650.   Uint32 gsn = GSN_CREATE_TRIG_CONF;
  2651.   Uint32 length = CreateTrigConf::InternalLength;
  2652.   bool sendRef;
  2653.   if (! toUser) {
  2654.     sendRef = opPtr.p->hasLastError();
  2655.     rep->setUserRef(opPtr.p->m_coordinatorRef);
  2656.     rep->setConnectionPtr(opPtr.p->key);
  2657.     rep->setRequestType(opPtr.p->m_requestType);
  2658.     if (opPtr.p->m_requestType == CreateTrigReq::RT_DICT_ABORT)
  2659.       sendRef = false;
  2660.   } else {
  2661.     sendRef = opPtr.p->hasError();
  2662.     rep->setUserRef(opPtr.p->m_request.getUserRef());
  2663.     rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
  2664.     rep->setRequestType(opPtr.p->m_request.getRequestType());
  2665.     length = CreateTrigConf::SignalLength;
  2666.   }
  2667.   rep->setTableId(opPtr.p->m_request.getTableId());
  2668.   rep->setIndexId(opPtr.p->m_request.getIndexId());
  2669.   rep->setTriggerId(opPtr.p->m_request.getTriggerId());
  2670.   rep->setTriggerInfo(opPtr.p->m_request.getTriggerInfo());
  2671.   if (sendRef) {
  2672.     if (opPtr.p->m_errorNode == 0)
  2673.       opPtr.p->m_errorNode = getOwnNodeId();
  2674.     rep->setErrorCode(opPtr.p->m_errorCode);
  2675.     rep->setErrorLine(opPtr.p->m_errorLine);
  2676.     rep->setErrorNode(opPtr.p->m_errorNode);
  2677.     gsn = GSN_CREATE_TRIG_REF;
  2678.     length = CreateTrigRef::SignalLength;
  2679.   }
  2680.   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
  2681. }
  2682. /**
  2683.  * MODULE: Drop trigger.
  2684.  */
  2685. void
  2686. Dbdict::execDROP_TRIG_REQ(Signal* signal) 
  2687. {
  2688.   jamEntry();
  2689.   DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
  2690.   OpDropTriggerPtr opPtr;
  2691.   const Uint32 senderRef = signal->senderBlockRef();
  2692.   const DropTrigReq::RequestType requestType = req->getRequestType();
  2693.   if (signal->getNoOfSections() > 0) {
  2694.     ndbrequire(signal->getNoOfSections() == 1);
  2695.     jam();
  2696.     TriggerRecord keyRecord;
  2697.     OpDropTrigger opTmp;
  2698.     opPtr.p=&opTmp;
  2699.     SegmentedSectionPtr ssPtr;
  2700.     signal->getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
  2701.     SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
  2702.     if (ssReader.getKey() != DropTrigReq::TriggerNameKey ||
  2703. ! ssReader.getString(keyRecord.triggerName)) {
  2704.       jam();
  2705.       opPtr.p->m_errorCode = DropTrigRef::InvalidName;
  2706.       opPtr.p->m_errorLine = __LINE__;
  2707.       releaseSections(signal);
  2708.       dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2709.       return;
  2710.     }
  2711.     releaseSections(signal);
  2712.     TriggerRecordPtr triggerPtr;
  2713.     //    ndbout_c("++++++++++++++ Looking for trigger %s", keyRecord.triggerName);
  2714.     c_triggerRecordHash.find(triggerPtr, keyRecord);
  2715.     if (triggerPtr.i == RNIL) {
  2716.       jam();
  2717.       req->setTriggerId(RNIL);
  2718.     } else {
  2719.       jam();
  2720.       //      ndbout_c("++++++++++ Found trigger %s", triggerPtr.p->triggerName);
  2721.       req->setTriggerId(triggerPtr.p->triggerId);
  2722.       req->setTableId(triggerPtr.p->tableId);
  2723.     }
  2724.   }
  2725.   if (requestType == DropTrigReq::RT_USER ||
  2726.       requestType == DropTrigReq::RT_ALTER_INDEX ||
  2727.       requestType == DropTrigReq::RT_BUILD_INDEX) {
  2728.     jam();
  2729.     if (signal->getLength() == DropTrigReq::SignalLength) {
  2730.       if (getOwnNodeId() != c_masterNodeId) {
  2731. jam();
  2732. // forward to DICT master
  2733. sendSignal(calcDictBlockRef(c_masterNodeId), GSN_DROP_TRIG_REQ,
  2734.    signal, signal->getLength(), JBB);
  2735. return;
  2736.       }
  2737.       if (!c_triggerRecordPool.findId(req->getTriggerId())) {
  2738. jam();
  2739. // return to sender
  2740. OpDropTrigger opBad;
  2741. opPtr.p = &opBad;
  2742. opPtr.p->save(req);
  2743.         if (! (req->getRequestFlag() & RequestFlag::RF_FORCE)) {
  2744.           opPtr.p->m_errorCode = DropTrigRef::TriggerNotFound;
  2745.           opPtr.p->m_errorLine = __LINE__;
  2746.         }
  2747. dropTrigger_sendReply(signal,  opPtr, true);
  2748. return;
  2749.       }
  2750.       // forward initial request plus operation key to all
  2751.       req->setOpKey(++c_opRecordSequence);
  2752.       NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2753.       sendSignal(rg, GSN_DROP_TRIG_REQ,
  2754.  signal, DropTrigReq::SignalLength + 1, JBB);
  2755.       return;
  2756.     }
  2757.     // seize operation record
  2758.     ndbrequire(signal->getLength() == DropTrigReq::SignalLength + 1);
  2759.     const Uint32 opKey = req->getOpKey();
  2760.     OpDropTrigger opBusy;
  2761.     if (! c_opDropTrigger.seize(opPtr))
  2762.       opPtr.p = &opBusy;
  2763.     opPtr.p->save(req);
  2764.     opPtr.p->m_coordinatorRef = senderRef;
  2765.     opPtr.p->m_isMaster = (senderRef == reference());
  2766.     opPtr.p->key = opKey;
  2767.     opPtr.p->m_requestType = DropTrigReq::RT_DICT_PREPARE;
  2768.     if (opPtr.p == &opBusy) {
  2769.       jam();
  2770.       opPtr.p->m_errorCode = DropTrigRef::Busy;
  2771.       opPtr.p->m_errorLine = __LINE__;
  2772.       dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  2773.       return;
  2774.     }
  2775.     c_opDropTrigger.add(opPtr);
  2776.       // master expects to hear from all
  2777.     if (opPtr.p->m_isMaster)
  2778. opPtr.p->m_signalCounter = c_aliveNodes;
  2779.     dropTrigger_slavePrepare(signal, opPtr);
  2780.     dropTrigger_sendReply(signal, opPtr, false);
  2781.     return;
  2782.   }
  2783.   c_opDropTrigger.find(opPtr, req->getConnectionPtr());
  2784.   if (! opPtr.isNull()) {
  2785.     opPtr.p->m_requestType = requestType;
  2786.     if (requestType == DropTrigReq::RT_DICT_COMMIT ||
  2787. requestType == DropTrigReq::RT_DICT_ABORT) {
  2788.       jam();
  2789.       if (requestType == DropTrigReq::RT_DICT_COMMIT)
  2790. dropTrigger_slaveCommit(signal, opPtr);
  2791.       else
  2792. dropTrigger_slaveAbort(signal, opPtr);
  2793.       dropTrigger_sendReply(signal, opPtr, false);
  2794.       // done in slave
  2795.       if (! opPtr.p->m_isMaster)
  2796. c_opDropTrigger.release(opPtr);
  2797.       return;
  2798.     }
  2799.   }
  2800.   jam();
  2801.   // return to sender
  2802.   OpDropTrigger opBad;
  2803.   opPtr.p = &opBad;
  2804.   opPtr.p->save(req);
  2805.   opPtr.p->m_errorCode = DropTrigRef::BadRequestType;
  2806.   opPtr.p->m_errorLine = __LINE__;
  2807.   dropTrigger_sendReply(signal,  opPtr, true);
  2808. }
  2809. void
  2810. Dbdict::execDROP_TRIG_CONF(Signal* signal) 
  2811. {
  2812.   jamEntry();
  2813.   DropTrigConf* conf = (DropTrigConf*)signal->getDataPtrSend();
  2814.   dropTrigger_recvReply(signal, conf, 0);
  2815. }
  2816. void
  2817. Dbdict::execDROP_TRIG_REF(Signal* signal) 
  2818. {
  2819.   jamEntry();
  2820.   DropTrigRef* ref = (DropTrigRef*)signal->getDataPtrSend();
  2821.   dropTrigger_recvReply(signal, ref->getConf(), ref);
  2822. }
  2823. void
  2824. Dbdict::dropTrigger_recvReply(Signal* signal, const DropTrigConf* conf,
  2825.     const DropTrigRef* ref)
  2826. {
  2827.   jam();
  2828.   const Uint32 senderRef = signal->senderBlockRef();
  2829.   const DropTrigReq::RequestType requestType = conf->getRequestType();
  2830.   const Uint32 key = conf->getConnectionPtr();
  2831.   if (requestType == DropTrigReq::RT_ALTER_INDEX) {
  2832.     jam();
  2833.     // part of alter index operation
  2834.     OpAlterIndexPtr opPtr;
  2835.     c_opAlterIndex.find(opPtr, key);
  2836.     ndbrequire(! opPtr.isNull());
  2837.     opPtr.p->setError(ref);
  2838.     alterIndex_fromDropTrigger(signal, opPtr);
  2839.     return;
  2840.   }
  2841.   if (requestType == DropTrigReq::RT_BUILD_INDEX) {
  2842.     jam();
  2843.     // part of build index operation
  2844.     OpBuildIndexPtr opPtr;
  2845.     c_opBuildIndex.find(opPtr, key);
  2846.     ndbrequire(! opPtr.isNull());
  2847.     opPtr.p->setError(ref);
  2848.     buildIndex_fromDropConstr(signal, opPtr);
  2849.     return;
  2850.   }
  2851.   if (requestType == DropTrigReq::RT_TC ||
  2852.       requestType == DropTrigReq::RT_LQH) {
  2853.     jam();
  2854.     // part of alter trigger operation
  2855.     OpAlterTriggerPtr opPtr;
  2856.     c_opAlterTrigger.find(opPtr, key);
  2857.     ndbrequire(! opPtr.isNull());
  2858.     opPtr.p->setError(ref);
  2859.     alterTrigger_fromDropLocal(signal, opPtr);
  2860.     return;
  2861.   }
  2862.   OpDropTriggerPtr opPtr;
  2863.   c_opDropTrigger.find(opPtr, key);
  2864.   ndbrequire(! opPtr.isNull());
  2865.   ndbrequire(opPtr.p->m_isMaster);
  2866.   ndbrequire(opPtr.p->m_requestType == requestType);
  2867.   opPtr.p->setError(ref);
  2868.   opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
  2869.   if (! opPtr.p->m_signalCounter.done()) {
  2870.     jam();
  2871.     return;
  2872.   }
  2873.   if (requestType == DropTrigReq::RT_DICT_COMMIT ||
  2874.       requestType == DropTrigReq::RT_DICT_ABORT) {
  2875.     jam();
  2876.     // send reply to user
  2877.     dropTrigger_sendReply(signal, opPtr, true);
  2878.     c_opDropTrigger.release(opPtr);
  2879.     return;
  2880.   }
  2881.   if (opPtr.p->hasError()) {
  2882.     jam();
  2883.     opPtr.p->m_requestType = DropTrigReq::RT_DICT_ABORT;
  2884.     dropTrigger_sendSlaveReq(signal, opPtr);
  2885.     return;
  2886.   }
  2887.   if (requestType == DropTrigReq::RT_DICT_PREPARE) {
  2888.     jam();
  2889.     // start alter offline
  2890.     dropTrigger_toAlterTrigger(signal, opPtr);
  2891.     return;
  2892.   }
  2893.   ndbrequire(false);
  2894. }
  2895. void
  2896. Dbdict::dropTrigger_slavePrepare(Signal* signal, OpDropTriggerPtr opPtr)
  2897. {
  2898.   jam();
  2899. }
  2900. void
  2901. Dbdict::dropTrigger_toAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
  2902. {
  2903.   jam();
  2904.   AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
  2905.   req->setUserRef(reference());
  2906.   req->setConnectionPtr(opPtr.p->key);
  2907.   req->setRequestType(AlterTrigReq::RT_DROP_TRIGGER);
  2908.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2909.   req->setTableId(opPtr.p->m_request.getTableId());
  2910.   req->setTriggerId(opPtr.p->m_request.getTriggerId());
  2911.   req->setTriggerInfo(0);       // not used
  2912.   req->setOnline(false);
  2913.   req->setReceiverRef(0);
  2914.   sendSignal(reference(), GSN_ALTER_TRIG_REQ,
  2915.       signal, AlterTrigReq::SignalLength, JBB);
  2916. }
  2917. void
  2918. Dbdict::dropTrigger_fromAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
  2919. {
  2920.   jam();
  2921.   // remove in all
  2922.   opPtr.p->m_requestType = DropTrigReq::RT_DICT_COMMIT;
  2923.   dropTrigger_sendSlaveReq(signal, opPtr);
  2924. }
  2925. void
  2926. Dbdict::dropTrigger_sendSlaveReq(Signal* signal, OpDropTriggerPtr opPtr)
  2927. {
  2928.   DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
  2929.   *req = opPtr.p->m_request;
  2930.   req->setUserRef(opPtr.p->m_coordinatorRef);
  2931.   req->setConnectionPtr(opPtr.p->key);
  2932.   req->setRequestType(opPtr.p->m_requestType);
  2933.   req->addRequestFlag(opPtr.p->m_requestFlag);
  2934.   opPtr.p->m_signalCounter = c_aliveNodes;
  2935.   NodeReceiverGroup rg(DBDICT, c_aliveNodes);
  2936.   sendSignal(rg, GSN_DROP_TRIG_REQ,
  2937.       signal, DropTrigReq::SignalLength, JBB);
  2938. }
  2939. void
  2940. Dbdict::dropTrigger_slaveCommit(Signal* signal, OpDropTriggerPtr opPtr)
  2941. {
  2942.   jam();
  2943.   const DropTrigReq* const req = &opPtr.p->m_request;
  2944.   // get trigger record
  2945.   const Uint32 triggerId = req->getTriggerId();
  2946.   TriggerRecordPtr triggerPtr;
  2947.   c_triggerRecordPool.getPtr(triggerPtr, triggerId);
  2948.   if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
  2949.       triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
  2950.     jam();
  2951.     // disconnect from index if index trigger  XXX move to drop index
  2952.     triggerPtr.p->indexId = req->getIndexId();
  2953.     TableRecordPtr indexPtr;
  2954.     c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
  2955.     ndbrequire(! indexPtr.isNull());
  2956.     switch (triggerPtr.p->triggerEvent) {
  2957.     case TriggerEvent::TE_INSERT:
  2958.       indexPtr.p->insertTriggerId = RNIL;
  2959.       break;
  2960.     case TriggerEvent::TE_UPDATE:
  2961.       indexPtr.p->updateTriggerId = RNIL;
  2962.       break;
  2963.     case TriggerEvent::TE_DELETE:
  2964.       indexPtr.p->deleteTriggerId = RNIL;
  2965.       break;
  2966.     case TriggerEvent::TE_CUSTOM:
  2967.       indexPtr.p->customTriggerId = RNIL;
  2968.       break;
  2969.     default:
  2970.       ndbrequire(false);
  2971.       break;
  2972.     }
  2973.   }
  2974.   if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
  2975.     jam();
  2976.     // disconnect from index record  XXX should be done in caller instead
  2977.     triggerPtr.p->indexId = req->getTableId();
  2978.     TableRecordPtr indexPtr;
  2979.     c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
  2980.     indexPtr.p->buildTriggerId = RNIL;
  2981.   }
  2982.   // remove trigger
  2983.   //  ndbout_c("++++++++++++ Removing trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
  2984.   c_triggerRecordHash.remove(triggerPtr);
  2985.   triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
  2986. }
  2987. void
  2988. Dbdict::dropTrigger_slaveAbort(Signal* signal, OpDropTriggerPtr opPtr)
  2989. {
  2990.   jam();
  2991. }
  2992. void
  2993. Dbdict::dropTrigger_sendReply(Signal* signal, OpDropTriggerPtr opPtr,
  2994.     bool toUser)
  2995. {
  2996.   DropTrigRef* rep = (DropTrigRef*)signal->getDataPtrSend();
  2997.   Uint32 gsn = GSN_DROP_TRIG_CONF;
  2998.   Uint32 length = DropTrigConf::InternalLength;
  2999.   bool sendRef;
  3000.   if (! toUser) {
  3001.     sendRef = opPtr.p->hasLastError();
  3002.     rep->setUserRef(opPtr.p->m_coordinatorRef);
  3003.     rep->setConnectionPtr(opPtr.p->key);
  3004.     rep->setRequestType(opPtr.p->m_requestType);
  3005.     if (opPtr.p->m_requestType == DropTrigReq::RT_DICT_ABORT)
  3006.       sendRef = false;
  3007.   } else {
  3008.     sendRef = opPtr.p->hasError();
  3009.     rep->setUserRef(opPtr.p->m_request.getUserRef());
  3010.     rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
  3011.     rep->setRequestType(opPtr.p->m_request.getRequestType());
  3012.     length = DropTrigConf::SignalLength;
  3013.   }
  3014.   rep->setTableId(opPtr.p->m_request.getTableId());
  3015.   rep->setIndexId(opPtr.p->m_request.getIndexId());
  3016.   rep->setTriggerId(opPtr.p->m_request.getTriggerId());
  3017.   if (sendRef) {
  3018.     if (opPtr.p->m_errorNode == 0)
  3019.       opPtr.p->m_errorNode = getOwnNodeId();
  3020.     rep->setErrorCode(opPtr.p->m_errorCode);
  3021.     rep->setErrorLine(opPtr.p->m_errorLine);
  3022.     rep->setErrorNode(opPtr.p->m_errorNode);
  3023.     gsn = GSN_DROP_TRIG_REF;
  3024.     length = CreateTrigRef::SignalLength;
  3025.   }
  3026.   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
  3027. }
  3028. /**
  3029.  * MODULE: Alter trigger.
  3030.  *
  3031.  * Alter trigger state.  Alter online creates the trigger first in all
  3032.  * TC (if index trigger) and then in all LQH-TUP.
  3033.  *
  3034.  * Request type received in REQ and returned in CONF/REF:
  3035.  *
  3036.  * RT_USER - normal user e.g. BACKUP
  3037.  * RT_CREATE_TRIGGER - from create trigger
  3038.  * RT_DROP_TRIGGER - from drop trigger
  3039.  * RT_DICT_PREPARE - seize operations and check request
  3040.  * RT_DICT_TC - master to each DICT on way to TC
  3041.  * RT_DICT_LQH - master to each DICT on way to LQH-TUP
  3042.  * RT_DICT_COMMIT - commit state change in each DICT (no reply)
  3043.  */
  3044. void
  3045. Dbdict::execALTER_TRIG_REQ(Signal* signal) 
  3046. {
  3047.   jamEntry();
  3048.   AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
  3049.   OpAlterTriggerPtr opPtr;
  3050.   const Uint32 senderRef = signal->senderBlockRef();
  3051.   const AlterTrigReq::RequestType requestType = req->getRequestType();
  3052.   if (requestType == AlterTrigReq::RT_USER ||
  3053.       requestType == AlterTrigReq::RT_CREATE_TRIGGER ||
  3054.       requestType == AlterTrigReq::RT_DROP_TRIGGER) {
  3055.     jam();
  3056.     const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
  3057.     NdbNodeBitmask receiverNodes = c_aliveNodes;
  3058.     if (isLocal) {
  3059.       receiverNodes.clear();
  3060.       receiverNodes.set(getOwnNodeId());
  3061.     }
  3062.     if (signal->getLength() == AlterTrigReq::SignalLength) {
  3063.       jam();
  3064.       if (! isLocal && getOwnNodeId() != c_masterNodeId) {
  3065.         jam();
  3066.         // forward to DICT master
  3067.         sendSignal(calcDictBlockRef(c_masterNodeId), GSN_ALTER_TRIG_REQ,
  3068.             signal, AlterTrigReq::SignalLength, JBB);
  3069.         return;
  3070.       }
  3071.       // forward initial request plus operation key to all
  3072.       req->setOpKey(++c_opRecordSequence);
  3073.       NodeReceiverGroup rg(DBDICT, receiverNodes);
  3074.       sendSignal(rg, GSN_ALTER_TRIG_REQ,
  3075.           signal, AlterTrigReq::SignalLength + 1, JBB);
  3076.       return;
  3077.     }
  3078.     // seize operation record
  3079.     ndbrequire(signal->getLength() == AlterTrigReq::SignalLength + 1);
  3080.     const Uint32 opKey = req->getOpKey();
  3081.     OpAlterTrigger opBusy;
  3082.     if (! c_opAlterTrigger.seize(opPtr))
  3083.       opPtr.p = &opBusy;
  3084.     opPtr.p->save(req);
  3085.     opPtr.p->m_coordinatorRef = senderRef;
  3086.     opPtr.p->m_isMaster = (senderRef == reference());
  3087.     opPtr.p->key = opKey;
  3088.     opPtr.p->m_requestType = AlterTrigReq::RT_DICT_PREPARE;
  3089.     if (opPtr.p == &opBusy) {
  3090.       jam();
  3091.       opPtr.p->m_errorCode = AlterTrigRef::Busy;
  3092.       opPtr.p->m_errorLine = __LINE__;
  3093.       alterTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
  3094.       return;
  3095.     }
  3096.     c_opAlterTrigger.add(opPtr);
  3097.     // master expects to hear from all
  3098.     if (opPtr.p->m_isMaster) {
  3099.       opPtr.p->m_nodes = receiverNodes;
  3100.       opPtr.p->m_signalCounter = receiverNodes;
  3101.     }
  3102.     alterTrigger_slavePrepare(signal, opPtr);
  3103.     alterTrigger_sendReply(signal, opPtr, false);
  3104.     return;
  3105.   }
  3106.   c_opAlterTrigger.find(opPtr, req->getConnectionPtr());
  3107.   if (! opPtr.isNull()) {
  3108.     opPtr.p->m_requestType = requestType;
  3109.     if (requestType == AlterTrigReq::RT_DICT_TC ||
  3110.         requestType == AlterTrigReq::RT_DICT_LQH) {
  3111.       jam();
  3112.       if (req->getOnline())
  3113.         alterTrigger_toCreateLocal(signal, opPtr);
  3114.       else
  3115.         alterTrigger_toDropLocal(signal, opPtr);
  3116.       return;
  3117.     }
  3118.     if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
  3119.         requestType == AlterTrigReq::RT_DICT_ABORT) {
  3120.       jam();
  3121.       if (requestType == AlterTrigReq::RT_DICT_COMMIT)
  3122.         alterTrigger_slaveCommit(signal, opPtr);
  3123.       else
  3124.         alterTrigger_slaveAbort(signal, opPtr);
  3125.       alterTrigger_sendReply(signal, opPtr, false);
  3126.       // done in slave
  3127.       if (! opPtr.p->m_isMaster)
  3128.         c_opAlterTrigger.release(opPtr);
  3129.       return;
  3130.     }
  3131.   }
  3132.   jam();
  3133.   // return to sender
  3134.   OpAlterTrigger opBad;
  3135.   opPtr.p = &opBad;
  3136.   opPtr.p->save(req);
  3137.   opPtr.p->m_errorCode = AlterTrigRef::BadRequestType;
  3138.   opPtr.p->m_errorLine = __LINE__;
  3139.   alterTrigger_sendReply(signal, opPtr, true);
  3140.   return;
  3141. }
  3142. void
  3143. Dbdict::execALTER_TRIG_CONF(Signal* signal) 
  3144. {
  3145.   jamEntry();
  3146.   AlterTrigConf* conf = (AlterTrigConf*)signal->getDataPtrSend();
  3147.   alterTrigger_recvReply(signal, conf, 0);
  3148. }
  3149. void
  3150. Dbdict::execALTER_TRIG_REF(Signal* signal) 
  3151. {
  3152.   jamEntry();
  3153.   AlterTrigRef* ref = (AlterTrigRef*)signal->getDataPtrSend();
  3154.   alterTrigger_recvReply(signal, ref->getConf(), ref);
  3155. }
  3156. void
  3157. Dbdict::alterTrigger_recvReply(Signal* signal, const AlterTrigConf* conf,
  3158.     const AlterTrigRef* ref)
  3159. {
  3160.   jam();
  3161.   const Uint32 senderRef = signal->senderBlockRef();
  3162.   const AlterTrigReq::RequestType requestType = conf->getRequestType();
  3163.   const Uint32 key = conf->getConnectionPtr();
  3164.   if (requestType == AlterTrigReq::RT_CREATE_TRIGGER) {
  3165.     jam();
  3166.     // part of create trigger operation
  3167.     OpCreateTriggerPtr opPtr;
  3168.     c_opCreateTrigger.find(opPtr, key);
  3169.     ndbrequire(! opPtr.isNull());
  3170.     opPtr.p->setError(ref);
  3171.     createTrigger_fromAlterTrigger(signal, opPtr);
  3172.     return;
  3173.   }
  3174.   if (requestType == AlterTrigReq::RT_DROP_TRIGGER) {
  3175.     jam();
  3176.     // part of drop trigger operation
  3177.     OpDropTriggerPtr opPtr;
  3178.     c_opDropTrigger.find(opPtr, key);
  3179.     ndbrequire(! opPtr.isNull());
  3180.     opPtr.p->setError(ref);
  3181.     dropTrigger_fromAlterTrigger(signal, opPtr);
  3182.     return;
  3183.   }
  3184.   OpAlterTriggerPtr opPtr;
  3185.   c_opAlterTrigger.find(opPtr, key);
  3186.   ndbrequire(! opPtr.isNull());
  3187.   ndbrequire(opPtr.p->m_isMaster);
  3188.   ndbrequire(opPtr.p->m_requestType == requestType);
  3189.   /* 
  3190.    * If refuse on drop trig, because of non-existent trigger,
  3191.    * comes from anyone but the master node - ignore it and
  3192.    * remove the node from forter ALTER_TRIG communication
  3193.    * This will happen if a new node has started since the
  3194.    * trigger whas created.
  3195.    */
  3196.   if (ref &&
  3197.       refToNode(senderRef) != refToNode(reference()) &&
  3198.       opPtr.p->m_request.getRequestType() == AlterTrigReq::RT_DROP_TRIGGER &&
  3199.       ref->getErrorCode() == AlterTrigRef::TriggerNotFound) {
  3200.     jam();
  3201.     ref = 0;                                      // ignore this error
  3202.     opPtr.p->m_nodes.clear(refToNode(senderRef)); // remove this from group
  3203.   }
  3204.   opPtr.p->setError(ref);
  3205.   opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
  3206.   if (! opPtr.p->m_signalCounter.done()) {
  3207.     jam();
  3208.     return;
  3209.   }
  3210.   if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
  3211.       requestType == AlterTrigReq::RT_DICT_ABORT) {
  3212.     jam();
  3213.     // send reply to user
  3214.     alterTrigger_sendReply(signal, opPtr, true);
  3215.     c_opAlterTrigger.release(opPtr);
  3216.     return;
  3217.   }
  3218.   if (opPtr.p->hasError()) {
  3219.     jam();
  3220.     opPtr.p->m_requestType = AlterTrigReq::RT_DICT_ABORT;
  3221.     alterTrigger_sendSlaveReq(signal, opPtr);
  3222.     return;
  3223.   }
  3224.   if (! (opPtr.p->m_request.getRequestFlag() & RequestFlag::RF_NOTCTRIGGER)) {
  3225.     if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
  3226.       jam();
  3227.       if (opPtr.p->m_request.getOnline()) {
  3228.         jam();
  3229.         opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
  3230.       } else {
  3231.         jam();
  3232.         opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
  3233.       }
  3234.       alterTrigger_sendSlaveReq(signal, opPtr);
  3235.       return;
  3236.     }
  3237.     if (requestType == AlterTrigReq::RT_DICT_TC) {
  3238.       jam();
  3239.       if (opPtr.p->m_request.getOnline()) {
  3240.         jam();
  3241.         opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
  3242.       } else {
  3243.         jam();
  3244.         opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
  3245.       }
  3246.       alterTrigger_sendSlaveReq(signal, opPtr);
  3247.       return;
  3248.     }
  3249.     if (requestType == AlterTrigReq::RT_DICT_LQH) {
  3250.       jam();
  3251.       if (opPtr.p->m_request.getOnline()) {
  3252.         jam();
  3253.         opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
  3254.       } else {
  3255.         jam();
  3256.         opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
  3257.       }
  3258.       alterTrigger_sendSlaveReq(signal, opPtr);
  3259.       return;
  3260.     }
  3261.   } else {
  3262.     if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
  3263.       jam();
  3264.       opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
  3265.       alterTrigger_sendSlaveReq(signal, opPtr);
  3266.       return;
  3267.     }
  3268.     if (requestType == AlterTrigReq::RT_DICT_LQH) {
  3269.       jam();
  3270.       opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
  3271.       alterTrigger_sendSlaveReq(signal, opPtr);
  3272.       return;
  3273.     }
  3274.   }
  3275.   ndbrequire(false);
  3276. }
  3277. void
  3278. Dbdict::alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr)
  3279. {
  3280.   jam();
  3281.   const AlterTrigReq* const req = &opPtr.p->m_request;
  3282.   const Uint32 triggerId = req->getTriggerId();
  3283.   TriggerRecordPtr triggerPtr;
  3284.   if (! (triggerId < c_triggerRecordPool.getSize())) {
  3285.     jam();
  3286.     opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
  3287.     opPtr.p->m_errorLine = __LINE__;
  3288.     return;
  3289.   }
  3290.   c_triggerRecordPool.getPtr(triggerPtr, triggerId);
  3291.   if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
  3292.     jam();
  3293.     opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
  3294.     opPtr.p->m_errorLine = __LINE__;
  3295.     return;
  3296.   }
  3297.   if (triggerPtr.p->triggerType == TriggerType::SUBSCRIPTION)
  3298.   {
  3299.     opPtr.p->m_request.addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
  3300.   }
  3301. }
  3302. void
  3303. Dbdict::alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
  3304. {
  3305.   jam();
  3306.   // find trigger record
  3307.   const Uint32 triggerId = opPtr.p->m_request.getTriggerId();
  3308.   TriggerRecordPtr triggerPtr;
  3309.   c_triggerRecordPool.getPtr(triggerPtr, triggerId);
  3310.   CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
  3311.   req->setUserRef(reference());
  3312.   req->setConnectionPtr(opPtr.p->key);
  3313.   if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
  3314.     jam();
  3315.     req->setRequestType(CreateTrigReq::RT_TC);
  3316.   } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
  3317.     jam();
  3318.     req->setRequestType(CreateTrigReq::RT_LQH);
  3319.   } else {
  3320.     ndbassert(false);
  3321.   }
  3322.   req->setTableId(triggerPtr.p->tableId);
  3323.   req->setIndexId(triggerPtr.p->indexId);
  3324.   req->setTriggerId(triggerPtr.i);
  3325.   req->setTriggerType(triggerPtr.p->triggerType);
  3326.   req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
  3327.   req->setTriggerEvent(triggerPtr.p->triggerEvent);
  3328.   req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
  3329.   req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
  3330.   req->setOnline(true);
  3331.   req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
  3332.   BlockReference blockRef = 0;
  3333.   if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
  3334.     jam();
  3335.     blockRef = calcTcBlockRef(getOwnNodeId());
  3336.   } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
  3337.     jam();
  3338.     blockRef = calcLqhBlockRef(getOwnNodeId());
  3339.   } else {
  3340.     ndbassert(false);
  3341.   }
  3342.   req->setAttributeMask(triggerPtr.p->attributeMask);
  3343.   sendSignal(blockRef, GSN_CREATE_TRIG_REQ,
  3344.       signal, CreateTrigReq::SignalLength, JBB);
  3345. }
  3346. void
  3347. Dbdict::alterTrigger_fromCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
  3348. {
  3349.   jam();
  3350.   if (! opPtr.p->hasLastError()) {
  3351.     // mark created locally
  3352.     TriggerRecordPtr triggerPtr;
  3353.     c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
  3354.     if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
  3355.       jam();
  3356.       triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_TC;
  3357.     } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
  3358.       jam();
  3359.       triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_LQH;
  3360.     } else {
  3361.       ndbrequire(false);
  3362.     }
  3363.   }
  3364.   // forward CONF or REF to master
  3365.   alterTrigger_sendReply(signal, opPtr, false);
  3366. }
  3367. void
  3368. Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
  3369. {
  3370.   jam();
  3371.   TriggerRecordPtr triggerPtr;
  3372.   c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
  3373.   DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
  3374.   req->setUserRef(reference());
  3375.   req->setConnectionPtr(opPtr.p->key);
  3376.   if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
  3377.     jam();
  3378.     // broken trigger allowed if force
  3379.     if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_TC)) {
  3380.       jam();
  3381.       ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
  3382.       alterTrigger_sendReply(signal, opPtr, false);
  3383.       return;
  3384.     }
  3385.     req->setRequestType(DropTrigReq::RT_TC);
  3386.   } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
  3387.     jam();
  3388.     // broken trigger allowed if force
  3389.     if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_LQH)) {
  3390.       jam();
  3391.       ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
  3392.       alterTrigger_sendReply(signal, opPtr, false);
  3393.       return;
  3394.     }
  3395.     req->setRequestType(DropTrigReq::RT_LQH);
  3396.   } else {
  3397.     ndbassert(false);
  3398.   }
  3399.   req->setTableId(triggerPtr.p->tableId);
  3400.   req->setIndexId(triggerPtr.p->indexId);
  3401.   req->setTriggerId(triggerPtr.i);
  3402.   req->setTriggerType(triggerPtr.p->triggerType);
  3403.   req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
  3404.   req->setTriggerEvent(triggerPtr.p->triggerEvent);
  3405.   req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
  3406.   req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
  3407.   BlockReference blockRef = 0;
  3408.   if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
  3409.     jam();
  3410.     blockRef = calcTcBlockRef(getOwnNodeId());
  3411.   } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
  3412.     jam();
  3413.     blockRef = calcLqhBlockRef(getOwnNodeId());
  3414.   } else {
  3415.     ndbassert(false);
  3416.   }
  3417.   sendSignal(blockRef, GSN_DROP_TRIG_REQ,
  3418.       signal, DropTrigReq::SignalLength, JBB);
  3419. }
  3420. void
  3421. Dbdict::alterTrigger_fromDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
  3422. {
  3423.   jam();
  3424.   if (! opPtr.p->hasLastError()) {
  3425.     // mark dropped locally
  3426.     TriggerRecordPtr triggerPtr;
  3427.     c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
  3428.     if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
  3429.       jam();
  3430.       triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_TC;
  3431.     } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
  3432.       jam();
  3433.       triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_LQH;
  3434.     } else {
  3435.       ndbrequire(false);
  3436.     }
  3437.   }
  3438.   // forward CONF or REF to master
  3439.   alterTrigger_sendReply(signal, opPtr, false);
  3440. }
  3441. void
  3442. Dbdict::alterTrigger_slaveCommit(Signal* signal, OpAlterTriggerPtr opPtr)
  3443. {
  3444.   jam();
  3445.   TriggerRecordPtr triggerPtr;
  3446.   c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
  3447.   // set state
  3448.   triggerPtr.p->triggerState = TriggerRecord::TS_ONLINE;
  3449. }
  3450. void
  3451. Dbdict::alterTrigger_slaveAbort(Signal* signal, OpAlterTriggerPtr opPtr)
  3452. {
  3453.   jam();
  3454. }
  3455. void
  3456. Dbdict::alterTrigger_sendSlaveReq(Signal* signal, OpAlterTriggerPtr opPtr)
  3457. {
  3458.   AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
  3459.   *req = opPtr.p->m_request;
  3460.   req->setUserRef(opPtr.p->m_coordinatorRef);
  3461.   req->setConnectionPtr(opPtr.p->key);
  3462.   req->setRequestType(opPtr.p->m_requestType);
  3463.   req->addRequestFlag(opPtr.p->m_requestFlag);
  3464.   NdbNodeBitmask receiverNodes = c_aliveNodes;
  3465.   if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
  3466.     receiverNodes.clear();
  3467.     receiverNodes.set(getOwnNodeId());
  3468.   } else {
  3469.     opPtr.p->m_nodes.bitAND(receiverNodes);
  3470.     receiverNodes = opPtr.p->m_nodes;
  3471.   }
  3472.   opPtr.p->m_signalCounter = receiverNodes;
  3473.   NodeReceiverGroup rg(DBDICT, receiverNodes);
  3474.   sendSignal(rg, GSN_ALTER_TRIG_REQ,
  3475.       signal, AlterTrigReq::SignalLength, JBB);
  3476. }
  3477. void
  3478. Dbdict::alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr,
  3479.     bool toUser)
  3480. {
  3481.   jam();
  3482.   AlterTrigRef* rep = (AlterTrigRef*)signal->getDataPtrSend();
  3483.   Uint32 gsn = GSN_ALTER_TRIG_CONF;
  3484.   Uint32 length = AlterTrigConf::InternalLength;
  3485.   bool sendRef;
  3486.   if (! toUser) {
  3487.     sendRef = opPtr.p->hasLastError();
  3488.     rep->setUserRef(opPtr.p->m_coordinatorRef);
  3489.     rep->setConnectionPtr(opPtr.p->key);
  3490.     rep->setRequestType(opPtr.p->m_requestType);
  3491.     if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_ABORT) {
  3492.       jam();
  3493.       sendRef = false;
  3494.     } else {
  3495.       jam();
  3496.     }
  3497.   } else {
  3498.     sendRef = opPtr.p->hasError();
  3499.     jam();
  3500.     rep->setUserRef(opPtr.p->m_request.getUserRef());
  3501.     rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
  3502.     rep->setRequestType(opPtr.p->m_request.getRequestType());
  3503.     length = AlterTrigConf::SignalLength;
  3504.   }
  3505.   rep->setTableId(opPtr.p->m_request.getTableId());
  3506.   rep->setTriggerId(opPtr.p->m_request.getTriggerId());
  3507.   if (sendRef) {
  3508.     if (opPtr.p->m_errorNode == 0) {
  3509.       jam();
  3510.       opPtr.p->m_errorNode = getOwnNodeId();
  3511.     } else {
  3512.       jam();
  3513.     }
  3514.     rep->setErrorCode(opPtr.p->m_errorCode);
  3515.     rep->setErrorLine(opPtr.p->m_errorLine);
  3516.     rep->setErrorNode(opPtr.p->m_errorNode);
  3517.     gsn = GSN_ALTER_TRIG_REF;
  3518.     length = AlterTrigRef::SignalLength;
  3519.   }
  3520.   sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
  3521. }
  3522. /**
  3523.  * MODULE: Support routines for index and trigger.
  3524.  */
  3525. void
  3526. Dbdict::getTableKeyList(TableRecordPtr tablePtr, AttributeList& list)
  3527. {
  3528.   jam();
  3529.   list.sz = 0;
  3530.   for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
  3531.     AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
  3532.     if (aRec->tupleKey)
  3533.       list.id[list.sz++] = aRec->attributeId;
  3534.     tAttr = aRec->nextAttrInTable;
  3535.   }
  3536. }
  3537. // XXX should store the primary attribute id
  3538. void
  3539. Dbdict::getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id)
  3540. {
  3541.   jam();
  3542.   TableRecordPtr tablePtr;
  3543.   c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
  3544.   AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
  3545.   for (Uint32 tAttr = tablePtr.p->firstAttribute; tAttr != RNIL; ) {
  3546.     AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
  3547.     if (iaRec->equal(*aRec)) {
  3548.       id[0] = aRec->attributeId;
  3549.       return;
  3550.     }
  3551.     tAttr = aRec->nextAttrInTable;
  3552.   }
  3553.   ndbrequire(false);
  3554. }
  3555. void
  3556. Dbdict::getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list)
  3557. {
  3558.   jam();
  3559.   TableRecordPtr tablePtr;
  3560.   c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
  3561.   list.sz = 0;
  3562.   memset(list.id, 0, sizeof(list.id));
  3563.   ndbrequire(indexPtr.p->noOfAttributes >= 2);
  3564.   Uint32 itAttr = indexPtr.p->firstAttribute;
  3565.   for (Uint32 i = 0; i < (Uint32)indexPtr.p->noOfAttributes - 1; i++) {
  3566.     getIndexAttr(indexPtr, itAttr, &list.id[list.sz++]);
  3567.     AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
  3568.     itAttr = iaRec->nextAttrInTable;
  3569.   }
  3570. }
  3571. void
  3572. Dbdict::getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask)
  3573. {
  3574.   jam();
  3575.   TableRecordPtr tablePtr;
  3576.   c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
  3577.   mask.clear();
  3578.   ndbrequire(indexPtr.p->noOfAttributes >= 2);
  3579.   Uint32 itAttr = indexPtr.p->firstAttribute;
  3580.   for (Uint32 i = 0; i < (Uint32)indexPtr.p->noOfAttributes - 1; i++) {
  3581.     Uint32 id;
  3582.     getIndexAttr(indexPtr, itAttr, &id);
  3583.     mask.set(id);
  3584.     AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
  3585.     itAttr = iaRec->nextAttrInTable;
  3586.   }
  3587. }
  3588. /* **************************************************************** */
  3589. /* ---------------------------------------------------------------- */
  3590. /* MODULE:          STORE/RESTORE SCHEMA FILE---------------------- */
  3591. /* ---------------------------------------------------------------- */
  3592. /*                                                                  */
  3593. /* General module used to store the schema file on disk and         */
  3594. /* similar function to restore it from disk.                        */
  3595. /* ---------------------------------------------------------------- */
  3596. /* **************************************************************** */
  3597. void
  3598. Dbdict::initSchemaFile(SchemaFile * sf, Uint32 fileSz){
  3599.   memcpy(sf->Magic, "NDBSCHMA", sizeof(sf->Magic));
  3600.   sf->ByteOrder = 0x12345678;
  3601.   sf->NdbVersion =  NDB_VERSION;
  3602.   sf->FileSize = fileSz;
  3603.   sf->CheckSum = 0;
  3604.   
  3605.   Uint32 headSz = (sizeof(SchemaFile)-sizeof(SchemaFile::TableEntry));
  3606.   Uint32 noEntries = (fileSz - headSz) / sizeof(SchemaFile::TableEntry);
  3607.   Uint32 slack = (fileSz - headSz) - noEntries * sizeof(SchemaFile::TableEntry);
  3608.   
  3609.   ndbrequire(noEntries > MAX_TABLES);
  3610.   sf->NoOfTableEntries = noEntries;
  3611.   memset(sf->TableEntries, 0, noEntries*sizeof(SchemaFile::TableEntry));
  3612.   memset(&(sf->TableEntries[noEntries]), 0, slack);
  3613.   computeChecksum(sf);
  3614. }
  3615. void
  3616. Dbdict::computeChecksum(SchemaFile * sf){ 
  3617.   sf->CheckSum = 0;
  3618.   sf->CheckSum = computeChecksum((const Uint32*)sf, sf->FileSize/4);
  3619. }
  3620. bool 
  3621. Dbdict::validateChecksum(const SchemaFile * sf){
  3622.   
  3623.   Uint32 c = computeChecksum((const Uint32*)sf, sf->FileSize/4);
  3624.   return c == 0;
  3625. }
  3626. Uint32
  3627. Dbdict::computeChecksum(const Uint32 * src, Uint32 len){
  3628.   Uint32 ret = 0;
  3629.   for(Uint32 i = 0; i<len; i++)
  3630.     ret ^= src[i];
  3631.   return ret;
  3632. }
  3633. SchemaFile::TableEntry * 
  3634. Dbdict::getTableEntry(void * p, Uint32 tableId, bool allowTooBig){
  3635.   SchemaFile * sf = (SchemaFile*)p;
  3636.   
  3637.   ndbrequire(allowTooBig || tableId < sf->NoOfTableEntries);
  3638.   return &sf->TableEntries[tableId];
  3639. }
  3640. // global metadata support
  3641. int
  3642. Dbdict::getMetaTablePtr(TableRecordPtr& tablePtr, Uint32 tableId, Uint32 tableVersion)
  3643. {
  3644.   if (tableId >= c_tableRecordPool.getSize()) {
  3645.     return MetaData::InvalidArgument;
  3646.   }
  3647.   c_tableRecordPool.getPtr(tablePtr, tableId);
  3648.   if (tablePtr.p->tabState == TableRecord::NOT_DEFINED) {
  3649.     return MetaData::TableNotFound;
  3650.   }
  3651.   if (tablePtr.p->tableVersion != tableVersion) {
  3652.     return MetaData::InvalidTableVersion;
  3653.   }
  3654.   // online flag is not maintained by DICT
  3655.   tablePtr.p->online =
  3656.     tablePtr.p->isTable() && 
  3657.     (tablePtr.p->tabState == TableRecord::DEFINED ||
  3658.      tablePtr.p->tabState == TableRecord::BACKUP_ONGOING) ||
  3659.     tablePtr.p->isIndex() && tablePtr.p->indexState == TableRecord::IS_ONLINE;
  3660.   return 0;
  3661. }
  3662. int
  3663. Dbdict::getMetaTable(MetaData::Table& table, Uint32 tableId, Uint32 tableVersion)
  3664. {
  3665.   int ret;
  3666.   TableRecordPtr tablePtr;
  3667.   if ((ret = getMetaTablePtr(tablePtr, tableId, tableVersion)) < 0) {
  3668.     return ret;
  3669.   }
  3670.   new (&table) MetaData::Table(*tablePtr.p);
  3671.   return 0;
  3672. }
  3673. int
  3674. Dbdict::getMetaTable(MetaData::Table& table, const char* tableName)
  3675. {
  3676.   int ret;
  3677.   TableRecordPtr tablePtr;
  3678.   if (strlen(tableName) + 1 > MAX_TAB_NAME_SIZE) {
  3679.     return MetaData::InvalidArgument;
  3680.   }
  3681.   TableRecord keyRecord;
  3682.   strcpy(keyRecord.tableName, tableName);
  3683.   c_tableRecordHash.find(tablePtr, keyRecord);
  3684.   if (tablePtr.i == RNIL) {
  3685.     return MetaData::TableNotFound;
  3686.   }
  3687.   if ((ret = getMetaTablePtr(tablePtr, tablePtr.i, tablePtr.p->tableVersion)) < 0) {
  3688.     return ret;
  3689.   }
  3690.   new (&table) MetaData::Table(*tablePtr.p);
  3691.   return 0;
  3692. }
  3693. int
  3694. Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table, Uint32 attributeId)
  3695. {
  3696.   int ret;
  3697.   TableRecordPtr tablePtr;
  3698.   if ((ret = getMetaTablePtr(tablePtr, table.tableId, table.tableVersion)) < 0) {
  3699.     return ret;
  3700.   }
  3701.   AttributeRecordPtr attrPtr;
  3702.   attrPtr.i = tablePtr.p->firstAttribute;
  3703.   while (attrPtr.i != RNIL) {
  3704.     c_attributeRecordPool.getPtr(attrPtr);
  3705.     if (attrPtr.p->attributeId == attributeId)
  3706.       break;
  3707.     attrPtr.i = attrPtr.p->nextAttrInTable;
  3708.   }
  3709.   if (attrPtr.i == RNIL) {
  3710.     return MetaData::AttributeNotFound;
  3711.   }
  3712.   new (&attr) MetaData::Attribute(*attrPtr.p);
  3713.   return 0;
  3714. }
  3715. int
  3716. Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table, const char* attributeName)
  3717. {
  3718.   int ret;
  3719.   TableRecordPtr tablePtr;
  3720.   if ((ret = getMetaTablePtr(tablePtr, table.tableId, table.tableVersion)) < 0) {
  3721.     return ret;
  3722.   }
  3723.   AttributeRecordPtr attrPtr;
  3724.   attrPtr.i = tablePtr.p->firstAttribute;
  3725.   while (attrPtr.i != RNIL) {
  3726.     c_attributeRecordPool.getPtr(attrPtr);
  3727.     if (strcmp(attrPtr.p->attributeName, attributeName) == 0)
  3728.       break;
  3729.     attrPtr.i = attrPtr.p->nextAttrInTable;
  3730.   }
  3731.   if (attrPtr.i == RNIL) {
  3732.     return MetaData::AttributeNotFound;
  3733.   }
  3734.   new (&attr) MetaData::Attribute(*attrPtr.p);
  3735.   return 0;
  3736. }