1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
#define DBTUP_ABORT_CPP
19
#include <RefConvert.hpp>
20
#include <ndb_limits.h>
23
void Dbtup::freeAllAttrBuffers(Operationrec* const regOperPtr)
25
if (regOperPtr->storedProcedureId == RNIL) {
27
freeAttrinbufrec(regOperPtr->firstAttrinbufrec);
30
StoredProcPtr storedPtr;
31
c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcedureId);
32
ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
33
storedPtr.p->storedCounter--;
34
regOperPtr->storedProcedureId = ZNIL;
36
regOperPtr->firstAttrinbufrec = RNIL;
37
regOperPtr->lastAttrinbufrec = RNIL;
38
regOperPtr->m_any_value = 0;
39
}//Dbtup::freeAllAttrBuffers()
41
void Dbtup::freeAttrinbufrec(Uint32 anAttrBuf)
44
AttrbufrecPtr localAttrBufPtr;
45
Uint32 RnoFree = cnoFreeAttrbufrec;
46
localAttrBufPtr.i = anAttrBuf;
47
while (localAttrBufPtr.i != RNIL) {
49
ptrCheckGuard(localAttrBufPtr, cnoOfAttrbufrec, attrbufrec);
50
Ttemp = localAttrBufPtr.p->attrbuf[ZBUF_NEXT];
51
localAttrBufPtr.p->attrbuf[ZBUF_NEXT] = cfirstfreeAttrbufrec;
52
cfirstfreeAttrbufrec = localAttrBufPtr.i;
53
localAttrBufPtr.i = Ttemp;
56
cnoFreeAttrbufrec = RnoFree;
57
}//Dbtup::freeAttrinbufrec()
60
* Abort abort this operation and all after (nextActiveOp's)
62
void Dbtup::execTUP_ABORTREQ(Signal* signal)
65
do_tup_abortreq(signal, 0);
68
void Dbtup::do_tup_abortreq(Signal* signal, Uint32 flags)
70
OperationrecPtr regOperPtr;
71
FragrecordPtr regFragPtr;
72
TablerecPtr regTabPtr;
74
regOperPtr.i = signal->theData[0];
75
c_operation_pool.getPtr(regOperPtr);
76
TransState trans_state= get_trans_state(regOperPtr.p);
77
ndbrequire((trans_state == TRANS_STARTED) ||
78
(trans_state == TRANS_TOO_MUCH_AI) ||
79
(trans_state == TRANS_ERROR_WAIT_TUPKEYREQ) ||
80
(trans_state == TRANS_IDLE));
81
if (regOperPtr.p->op_struct.op_type == ZREAD) {
83
freeAllAttrBuffers(regOperPtr.p);
84
initOpConnection(regOperPtr.p);
88
regFragPtr.i = regOperPtr.p->fragmentPtr;
89
ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
91
regTabPtr.i = regFragPtr.p->fragTableId;
92
ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
94
if (get_tuple_state(regOperPtr.p) == TUPLE_PREPARED)
97
if (!regTabPtr.p->tuxCustomTriggers.isEmpty() &&
98
(flags & ZSKIP_TUX_TRIGGERS) == 0)
99
executeTuxAbortTriggers(signal,
104
OperationrecPtr loopOpPtr;
105
loopOpPtr.i = regOperPtr.p->nextActiveOp;
106
while (loopOpPtr.i != RNIL) {
108
c_operation_pool.getPtr(loopOpPtr);
109
if (get_tuple_state(loopOpPtr.p) != TUPLE_ALREADY_ABORTED &&
110
!regTabPtr.p->tuxCustomTriggers.isEmpty() &&
111
(flags & ZSKIP_TUX_TRIGGERS) == 0) {
113
executeTuxAbortTriggers(signal,
118
set_tuple_state(loopOpPtr.p, TUPLE_ALREADY_ABORTED);
119
loopOpPtr.i = loopOpPtr.p->nextActiveOp;
124
Tuple_header *tuple_ptr= (Tuple_header*)
125
get_ptr(&page, ®OperPtr.p->m_tuple_location, regTabPtr.p);
127
Uint32 bits= tuple_ptr->m_header_bits;
128
if(regOperPtr.p->op_struct.op_type != ZDELETE)
130
Tuple_header *copy= (Tuple_header*)
131
c_undo_buffer.get_ptr(®OperPtr.p->m_copy_tuple_location);
133
if(regOperPtr.p->op_struct.m_disk_preallocated)
137
memcpy(&key, copy->get_disk_ref_ptr(regTabPtr.p), sizeof(key));
138
disk_page_abort_prealloc(signal, regFragPtr.p, &key, key.m_page_idx);
142
Uint32 copy_bits= copy->m_header_bits;
143
if(! (bits & Tuple_header::ALLOC))
145
if(copy_bits & Tuple_header::MM_GROWN)
147
if (0) ndbout_c("abort grow");
149
Uint32 idx= regOperPtr.p->m_tuple_location.m_page_idx;
150
Uint32 mm_vars= regTabPtr.p->m_attributes[MM].m_no_of_varsize;
153
ndbassert(tuple_ptr->m_header_bits & Tuple_header::CHAINED_ROW);
155
Var_part_ref *ref = tuple_ptr->get_var_part_ref_ptr(regTabPtr.p);
161
var_part= get_ptr(&vpage, *ref);
162
Var_page* pageP = (Var_page*)vpage.p;
163
Uint32 len= pageP->get_entry_len(idx) & ~Var_page::CHAIN;
164
Uint32 sz = ((((mm_vars + 1) << 1) + (((Uint16*)var_part)[mm_vars]) + 3)>> 2);
165
ndbassert(sz <= len);
166
pageP->shrink_entry(idx, sz);
167
update_free_page_list(regFragPtr.p, vpage);
169
else if(bits & Tuple_header::MM_SHRINK)
171
if (0) ndbout_c("abort shrink");
174
else if (regOperPtr.p->is_first_operation() &&
175
regOperPtr.p->is_last_operation())
178
* Aborting last operation that performed ALLOC
180
tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
181
tuple_ptr->m_header_bits |= Tuple_header::FREED;
184
else if (regOperPtr.p->is_first_operation() &&
185
regOperPtr.p->is_last_operation())
187
if (bits & Tuple_header::ALLOC)
189
tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
190
tuple_ptr->m_header_bits |= Tuple_header::FREED;
194
if(regOperPtr.p->is_first_operation() && regOperPtr.p->is_last_operation())
196
if (regOperPtr.p->m_undo_buffer_space)
197
c_lgman->free_log_space(regFragPtr.p->m_logfile_group_id,
198
regOperPtr.p->m_undo_buffer_space);
201
removeActiveOpList(regOperPtr.p, tuple_ptr);
202
initOpConnection(regOperPtr.p);
205
/* **************************************************************** */
206
/* ********************** TRANSACTION ERROR MODULE **************** */
207
/* **************************************************************** */
208
int Dbtup::TUPKEY_abort(Signal* signal, int error_type)
212
//tmupdate_alloc_error:
213
terrorCode= ZMEM_NOMEM_ERROR;
219
terrorCode = ZREGISTER_INIT_ERROR;
224
terrorCode = ZTRY_TO_UPDATE_ERROR;
229
terrorCode = ZNO_ILLEGAL_NULL_ATTR;
234
terrorCode = ZTRY_TO_UPDATE_ERROR;
239
terrorCode = ZREGISTER_INIT_ERROR;
244
terrorCode = ZTOTAL_LEN_ERROR;
249
terrorCode = ZREGISTER_INIT_ERROR;
254
terrorCode = ZREGISTER_INIT_ERROR;
259
terrorCode = ZREGISTER_INIT_ERROR;
264
terrorCode = ZREGISTER_INIT_ERROR;
269
terrorCode = ZREGISTER_INIT_ERROR;
278
terrorCode = ZCALL_ERROR;
283
terrorCode = ZSTACK_OVERFLOW_ERROR;
288
terrorCode = ZSTACK_UNDERFLOW_ERROR;
293
terrorCode = ZNO_INSTRUCTION_ERROR;
298
terrorCode = ZOUTSIDE_OF_PROGRAM_ERROR;
303
terrorCode = ZTOO_MANY_INSTRUCTIONS_ERROR;
308
terrorCode = ZTEMPORARY_RESOURCE_FAILURE;
312
if (get_trans_state(operPtr.p) == TRANS_TOO_MUCH_AI) {
314
terrorCode = ZTOO_MUCH_ATTRINFO_ERROR;
315
} else if (get_trans_state(operPtr.p) == TRANS_ERROR_WAIT_TUPKEYREQ) {
317
terrorCode = ZSEIZE_ATTRINBUFREC_ERROR;
324
terrorCode = ZUNSUPPORTED_BRANCH;
330
tupkeyErrorLab(signal);
334
void Dbtup::early_tupkey_error(Signal* signal)
336
Operationrec * const regOperPtr = operPtr.p;
337
ndbrequire(!regOperPtr->op_struct.in_active_list);
338
set_trans_state(regOperPtr, TRANS_IDLE);
339
set_tuple_state(regOperPtr, TUPLE_PREPARED);
340
initOpConnection(regOperPtr);
341
send_TUPKEYREF(signal, regOperPtr);
344
void Dbtup::tupkeyErrorLab(Signal* signal)
346
Operationrec * const regOperPtr = operPtr.p;
347
set_trans_state(regOperPtr, TRANS_IDLE);
348
set_tuple_state(regOperPtr, TUPLE_PREPARED);
350
FragrecordPtr fragPtr;
351
fragPtr.i= regOperPtr->fragmentPtr;
352
ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
355
tabPtr.i= fragPtr.p->fragTableId;
356
ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
358
if (regOperPtr->m_undo_buffer_space &&
359
(regOperPtr->is_first_operation() && regOperPtr->is_last_operation()))
361
c_lgman->free_log_space(fragPtr.p->m_logfile_group_id,
362
regOperPtr->m_undo_buffer_space);
366
if (!regOperPtr->m_tuple_location.isNull())
369
ptr= get_ptr(&tmp, ®OperPtr->m_tuple_location, tabPtr.p);
373
removeActiveOpList(regOperPtr, (Tuple_header*)ptr);
374
initOpConnection(regOperPtr);
375
send_TUPKEYREF(signal, regOperPtr);
378
void Dbtup::send_TUPKEYREF(Signal* signal,
379
Operationrec* const regOperPtr)
381
TupKeyRef * const tupKeyRef = (TupKeyRef *)signal->getDataPtrSend();
382
tupKeyRef->userRef = regOperPtr->userpointer;
383
tupKeyRef->errorCode = terrorCode;
384
sendSignal(DBLQH_REF, GSN_TUPKEYREF, signal,
385
TupKeyRef::SignalLength, JBB);
389
* Unlink one operation from the m_operation_ptr_i list in the tuple.
391
void Dbtup::removeActiveOpList(Operationrec* const regOperPtr,
392
Tuple_header *tuple_ptr)
394
OperationrecPtr raoOperPtr;
396
if(!regOperPtr->m_copy_tuple_location.isNull())
399
c_undo_buffer.free_copy_tuple(®OperPtr->m_copy_tuple_location);
402
if (regOperPtr->op_struct.in_active_list) {
403
regOperPtr->op_struct.in_active_list= false;
404
if (regOperPtr->nextActiveOp != RNIL) {
406
raoOperPtr.i= regOperPtr->nextActiveOp;
407
c_operation_pool.getPtr(raoOperPtr);
408
raoOperPtr.p->prevActiveOp= regOperPtr->prevActiveOp;
411
tuple_ptr->m_operation_ptr_i = regOperPtr->prevActiveOp;
413
if (regOperPtr->prevActiveOp != RNIL) {
415
raoOperPtr.i= regOperPtr->prevActiveOp;
416
c_operation_pool.getPtr(raoOperPtr);
417
raoOperPtr.p->nextActiveOp= regOperPtr->nextActiveOp;
419
regOperPtr->prevActiveOp= RNIL;
420
regOperPtr->nextActiveOp= RNIL;