DbtupStoredProcDef.cpp 8.13 KB
Newer Older
1 2 3 4
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6 7 8 9 10 11 12 13 14 15 16 17

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


#define DBTUP_C
18
#define DBTUP_STORE_PROC_DEF_CPP
19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include "Dbtup.hpp"
#include <RefConvert.hpp>
#include <ndb_limits.h>
#include <pc.hpp>

/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
/* ------------ADD/DROP STORED PROCEDURE MODULE ------------------- */
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
void Dbtup::execSTORED_PROCREQ(Signal* signal) 
{
  OperationrecPtr regOperPtr;
  TablerecPtr regTabPtr;
33
  jamEntry();
34
  regOperPtr.i = signal->theData[0];
35
  c_operation_pool.getPtr(regOperPtr);
36 37 38 39
  regTabPtr.i = signal->theData[1];
  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);

  Uint32 requestInfo = signal->theData[3];
40 41 42
  TransState trans_state= get_trans_state(regOperPtr.p);
  ndbrequire(trans_state == TRANS_IDLE ||
             ((trans_state == TRANS_ERROR_WAIT_STORED_PROCREQ) &&
43 44 45 46
             (requestInfo == ZSTORED_PROCEDURE_DELETE)));
  ndbrequire(regTabPtr.p->tableStatus == DEFINED);
  switch (requestInfo) {
  case ZSCAN_PROCEDURE:
47
    jam();
48 49 50 51 52
    scanProcedure(signal,
                  regOperPtr.p,
                  signal->theData[4]);
    break;
  case ZCOPY_PROCEDURE:
53
    jam();
54 55 56
    copyProcedure(signal, regTabPtr, regOperPtr.p);
    break;
  case ZSTORED_PROCEDURE_DELETE:
57
    jam();
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    deleteScanProcedure(signal, regOperPtr.p);
    break;
  default:
    ndbrequire(false);
  }//switch
}//Dbtup::execSTORED_PROCREQ()

void Dbtup::deleteScanProcedure(Signal* signal,
                                Operationrec* regOperPtr) 
{
  StoredProcPtr storedPtr;
  Uint32 storedProcId = signal->theData[4];
  c_storedProcPool.getPtr(storedPtr, storedProcId);
  ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
  ndbrequire(storedPtr.p->storedCounter == 0);
  Uint32 firstAttrinbuf = storedPtr.p->storedLinkFirst;
  storedPtr.p->storedCode = ZSTORED_PROCEDURE_FREE;
  storedPtr.p->storedLinkFirst = RNIL;
  storedPtr.p->storedLinkLast = RNIL;
  storedPtr.p->storedProcLength = 0;
  c_storedProcPool.release(storedPtr);
  freeAttrinbufrec(firstAttrinbuf);
  regOperPtr->currentAttrinbufLen = 0;
81
  set_trans_state(regOperPtr, TRANS_IDLE);
82 83
  signal->theData[0] = regOperPtr->userpointer;
  signal->theData[1] = storedProcId;
84
  sendSignal(DBLQH_REF, GSN_STORED_PROCCONF, signal, 2, JBB);
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
}//Dbtup::deleteScanProcedure()

void Dbtup::scanProcedure(Signal* signal,
                          Operationrec* regOperPtr,
                          Uint32 lenAttrInfo)
{
//--------------------------------------------------------
// We introduce the maxCheck so that there is always one
// stored procedure entry free for copy procedures. Thus
// no amount of scanning can cause problems for the node
// recovery functionality.
//--------------------------------------------------------
  StoredProcPtr storedPtr;
  c_storedProcPool.seize(storedPtr);
  ndbrequire(storedPtr.i != RNIL);
  storedPtr.p->storedCode = ZSCAN_PROCEDURE;
  storedPtr.p->storedCounter = 0;
  storedPtr.p->storedProcLength = lenAttrInfo;
  storedPtr.p->storedLinkFirst = RNIL;
  storedPtr.p->storedLinkLast = RNIL;
105
  set_trans_state(regOperPtr, TRANS_WAIT_STORED_PROCEDURE_ATTR_INFO);
106 107
  regOperPtr->attrinbufLen = lenAttrInfo;
  regOperPtr->currentAttrinbufLen = 0;
108
  regOperPtr->storedProcPtr = storedPtr.i;
109 110 111 112 113 114
}//Dbtup::scanProcedure()

void Dbtup::copyProcedure(Signal* signal,
                          TablerecPtr regTabPtr,
                          Operationrec* regOperPtr) 
{
115
  Uint32 TnoOfAttributes = regTabPtr.p->m_no_of_attributes;
116 117 118 119 120 121 122 123 124
  scanProcedure(signal,
                regOperPtr,
                TnoOfAttributes);

  Uint32 length = 0;
  for (Uint32 Ti = 0; Ti < TnoOfAttributes; Ti++) {
    AttributeHeader::init(&signal->theData[length + 1], Ti, 0);
    length++;
    if (length == 24) {
125
      jam();
126 127
      ndbrequire(storedProcedureAttrInfo(signal, regOperPtr, 
					 signal->theData+1, length, true));
128 129 130 131
      length = 0;
    }//if
  }//for
  if (length != 0) {
132
    jam();
133 134
    ndbrequire(storedProcedureAttrInfo(signal, regOperPtr, 
				       signal->theData+1, length, true));
135 136 137 138 139 140
  }//if
  ndbrequire(regOperPtr->currentAttrinbufLen == 0);
}//Dbtup::copyProcedure()

bool Dbtup::storedProcedureAttrInfo(Signal* signal,
                                    Operationrec* regOperPtr,
141
				    const Uint32 *data,
142 143 144 145 146 147 148 149 150 151 152 153 154 155
                                    Uint32 length,
                                    bool copyProcedure) 
{
  AttrbufrecPtr regAttrPtr;
  Uint32 RnoFree = cnoFreeAttrbufrec;
  if (ERROR_INSERTED(4004) && !copyProcedure) {
    CLEAR_ERROR_INSERT_VALUE;
    storedSeizeAttrinbufrecErrorLab(signal, regOperPtr);
    return false;
  }//if
  regOperPtr->currentAttrinbufLen += length;
  ndbrequire(regOperPtr->currentAttrinbufLen <= regOperPtr->attrinbufLen);
  if ((RnoFree > MIN_ATTRBUF) ||
      (copyProcedure)) {
156
    jam();
157 158 159 160 161 162 163
    regAttrPtr.i = cfirstfreeAttrbufrec;
    ptrCheckGuard(regAttrPtr, cnoOfAttrbufrec, attrbufrec);
    regAttrPtr.p->attrbuf[ZBUF_DATA_LEN] = 0;
    cfirstfreeAttrbufrec = regAttrPtr.p->attrbuf[ZBUF_NEXT];
    cnoFreeAttrbufrec = RnoFree - 1;
    regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
  } else {
164
    jam();
165 166 167 168
    storedSeizeAttrinbufrecErrorLab(signal, regOperPtr);
    return false;
  }//if
  if (regOperPtr->firstAttrinbufrec == RNIL) {
169
    jam();
170 171 172 173 174
    regOperPtr->firstAttrinbufrec = regAttrPtr.i;
  }//if
  regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
  if (regOperPtr->lastAttrinbufrec != RNIL) {
    AttrbufrecPtr tempAttrinbufptr;
175
    jam();
176 177 178 179 180 181 182 183
    tempAttrinbufptr.i = regOperPtr->lastAttrinbufrec;  
    ptrCheckGuard(tempAttrinbufptr, cnoOfAttrbufrec, attrbufrec);
    tempAttrinbufptr.p->attrbuf[ZBUF_NEXT] = regAttrPtr.i;
  }//if
  regOperPtr->lastAttrinbufrec = regAttrPtr.i;

  regAttrPtr.p->attrbuf[ZBUF_DATA_LEN] = length;
  MEMCOPY_NO_WORDS(&regAttrPtr.p->attrbuf[0],
184
                   data,
185 186 187
                   length);

  if (regOperPtr->currentAttrinbufLen < regOperPtr->attrinbufLen) {
188
    jam();
189 190 191 192 193 194 195 196 197
    return true;
  }//if
  if (ERROR_INSERTED(4005) && !copyProcedure) {
    CLEAR_ERROR_INSERT_VALUE;
    storedSeizeAttrinbufrecErrorLab(signal, regOperPtr);
    return false;
  }//if

  StoredProcPtr storedPtr;
198
  c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcPtr);
199 200 201 202 203 204 205
  ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);

  regOperPtr->currentAttrinbufLen = 0;
  storedPtr.p->storedLinkFirst = regOperPtr->firstAttrinbufrec;
  storedPtr.p->storedLinkLast = regOperPtr->lastAttrinbufrec;
  regOperPtr->firstAttrinbufrec = RNIL;
  regOperPtr->lastAttrinbufrec = RNIL;
206
  set_trans_state(regOperPtr, TRANS_IDLE);
207 208
  signal->theData[0] = regOperPtr->userpointer;
  signal->theData[1] = storedPtr.i;
209
  sendSignal(DBLQH_REF, GSN_STORED_PROCCONF, signal, 2, JBB);
210 211 212 213 214 215 216
  return true;
}//Dbtup::storedProcedureAttrInfo()

void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal,
                                            Operationrec* regOperPtr)
{
  StoredProcPtr storedPtr;
217
  c_storedProcPool.getPtr(storedPtr, regOperPtr->storedProcPtr);
218 219 220 221 222
  ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);

  storedPtr.p->storedLinkFirst = regOperPtr->firstAttrinbufrec;
  regOperPtr->firstAttrinbufrec = RNIL;
  regOperPtr->lastAttrinbufrec = RNIL;
223
  set_trans_state(regOperPtr, TRANS_ERROR_WAIT_STORED_PROCREQ);
224 225
  signal->theData[0] = regOperPtr->userpointer;
  signal->theData[1] = ZSTORED_SEIZE_ATTRINBUFREC_ERROR;
226 227
  signal->theData[2] = regOperPtr->storedProcPtr;
  sendSignal(DBLQH_REF, GSN_STORED_PROCREF, signal, 3, JBB);
228 229
}//Dbtup::storedSeizeAttrinbufrecErrorLab()