20 #include <dblqh/Dblqh.hpp>
22 #include <RefConvert.hpp>
23 #include <ndb_limits.h>
25 #include <AttributeDescriptor.hpp>
26 #include "AttributeOffset.hpp"
27 #include <AttributeHeader.hpp>
28 #include <Interpreter.hpp>
29 #include <signaldata/TupKey.hpp>
30 #include <signaldata/AttrInfo.hpp>
31 #include <NdbSqlUtil.hpp>
37 dump_hex(
const Uint32 *p, Uint32 len)
46 ndbout_c(
"%8p %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]);
48 ndbout_c(
"%8p %08X %08X %08X", p, p[0], p[1], p[2]);
50 ndbout_c(
"%8p %08X %08X", p, p[0], p[1]);
52 ndbout_c(
"%8p %08X", p, p[0]);
67 int Dbtup::getStoredProcAttrInfo(Uint32 storedId,
68 KeyReqStruct* req_struct,
72 StoredProcPtr storedPtr;
73 c_storedProcPool.
getPtr(storedPtr, storedId);
74 if (storedPtr.i != RNIL) {
75 if ((storedPtr.p->storedCode == ZSCAN_PROCEDURE) ||
76 (storedPtr.p->storedCode == ZCOPY_PROCEDURE)) {
79 getSection(sectionPtr, storedPtr.p->storedProcIVal);
80 Uint32 storedProcLen= sectionPtr.sz;
82 ndbassert( attrInfoIVal == RNIL );
83 attrInfoIVal= storedPtr.p->storedProcIVal;
84 req_struct->attrinfo_len= storedProcLen;
88 terrorCode= ZSTORED_PROC_ID_ERROR;
92 void Dbtup::copyAttrinfo(Operationrec * regOperPtr,
97 ndbassert( expectedLen > 0 || attrInfoIVal == RNIL );
101 ndbassert( attrInfoIVal != RNIL );
105 getSection(sectionPtr, attrInfoIVal);
107 ndbrequire(sectionPtr.sz == expectedLen);
108 ndbrequire(sectionPtr.sz < ZATTR_BUFFER_SIZE);
113 copy(inBuffer, attrInfoIVal);
116 regOperPtr->m_any_value= 0;
122 Dbtup::setChecksum(Tuple_header* tuple_ptr,
125 tuple_ptr->m_checksum= 0;
126 tuple_ptr->m_checksum= calculateChecksum(tuple_ptr, regTabPtr);
130 Dbtup::calculateChecksum(Tuple_header* tuple_ptr,
134 Uint32
i, rec_size, *tuple_header;
135 rec_size= regTabPtr->m_offsets[MM].m_fix_header_size;
136 tuple_header= tuple_ptr->m_data;
141 for (i= 0; i < rec_size-Tuple_header::HeaderSize; i++) {
142 checksum ^= tuple_header[
i];
157 var_data_part= req_struct->var_data_start;
158 vsize_words= calculate_total_var_size(req_struct->var_len_array,
159 regTabPtr->no_var_attr);
160 ndbassert(req_struct->var_data_end >= &var_data_part[vsize_words]);
161 for (i= 0; i < vsize_words; i++) {
162 checksum ^= var_data_part[
i];
173 Dbtup::insertActiveOpList(OperationrecPtr regOperPtr,
174 KeyReqStruct* req_struct)
176 OperationrecPtr prevOpPtr;
177 ndbrequire(!regOperPtr.p->op_struct.in_active_list);
178 regOperPtr.p->op_struct.in_active_list=
true;
179 req_struct->prevOpPtr.i=
180 prevOpPtr.i= req_struct->m_tuple_ptr->m_operation_ptr_i;
181 regOperPtr.p->prevActiveOp= prevOpPtr.i;
182 regOperPtr.p->nextActiveOp= RNIL;
183 regOperPtr.p->m_undo_buffer_space= 0;
184 req_struct->m_tuple_ptr->m_operation_ptr_i= regOperPtr.i;
185 if (prevOpPtr.i == RNIL) {
188 req_struct->prevOpPtr.p= prevOpPtr.p= c_operation_pool.
getPtr(prevOpPtr.i);
189 prevOpPtr.p->nextActiveOp= regOperPtr.i;
191 regOperPtr.p->op_struct.m_wait_log_buffer=
192 prevOpPtr.p->op_struct.m_wait_log_buffer;
193 regOperPtr.p->op_struct.m_load_diskpage_on_commit=
194 prevOpPtr.p->op_struct.m_load_diskpage_on_commit;
195 regOperPtr.p->op_struct.m_gci_written=
196 prevOpPtr.p->op_struct.m_gci_written;
197 regOperPtr.p->m_undo_buffer_space= prevOpPtr.p->m_undo_buffer_space;
200 regOperPtr.p->m_any_value = prevOpPtr.p->m_any_value;
202 prevOpPtr.p->op_struct.m_wait_log_buffer= 0;
203 prevOpPtr.p->op_struct.m_load_diskpage_on_commit= 0;
205 if(prevOpPtr.p->op_struct.tuple_state == TUPLE_PREPARED)
207 Uint32 op= regOperPtr.p->op_struct.op_type;
208 Uint32 prevOp= prevOpPtr.p->op_struct.op_type;
209 if (prevOp == ZDELETE)
214 prevOpPtr.p->op_struct.delete_insert_flag=
true;
215 regOperPtr.p->op_struct.delete_insert_flag=
true;
218 else if (op == ZREFRESH)
225 terrorCode= ZTUPLE_DELETED_ERROR;
229 else if(op == ZINSERT && prevOp != ZDELETE)
231 terrorCode= ZINSERT_ERROR;
234 else if (prevOp == ZREFRESH)
237 terrorCode= ZOP_AFTER_REFRESH_ERROR;
244 terrorCode= ZMUST_BE_ABORTED_ERROR;
251 Dbtup::setup_read(KeyReqStruct *req_struct,
252 Operationrec* regOperPtr,
253 Fragrecord* regFragPtr,
257 OperationrecPtr currOpPtr;
258 currOpPtr.i= req_struct->m_tuple_ptr->m_operation_ptr_i;
259 Uint32 bits = req_struct->m_tuple_ptr->m_header_bits;
261 if (unlikely(req_struct->m_reorg))
263 Uint32 moved = bits & Tuple_header::REORG_MOVE;
264 if (! ((req_struct->m_reorg == 1 && moved == 0) ||
265 (req_struct->m_reorg == 2 && moved != 0)))
267 terrorCode= ZTUPLE_DELETED_ERROR;
271 if (currOpPtr.i == RNIL)
273 if (regTabPtr->need_expand(disk))
274 prepare_read(req_struct, regTabPtr, disk);
279 Uint32 savepointId= regOperPtr->savepointId;
280 bool dirty= req_struct->dirty_op;
282 c_operation_pool.
getPtr(currOpPtr);
283 bool sameTrans= c_lqh->is_same_trans(currOpPtr.p->userpointer,
284 req_struct->trans_id1,
285 req_struct->trans_id2);
289 if(dirty && !sameTrans)
302 bool found= find_savepoint(currOpPtr, savepointId);
304 Uint32 currOp= currOpPtr.p->op_struct.op_type;
309 bool is_insert = (bits & Tuple_header::ALLOC);
321 if((found && currOp == ZDELETE) ||
322 ((dirty || !found) && is_insert))
325 terrorCode= ZTUPLE_DELETED_ERROR;
335 req_struct->m_tuple_ptr=
336 get_copy_tuple(&currOpPtr.p->m_copy_tuple_location);
339 if (regTabPtr->need_expand(disk))
340 prepare_read(req_struct, regTabPtr, disk);
343 ndbout_c(
"reading copy");
344 Uint32 *var_ptr = fixed_ptr+regTabPtr->var_offset;
345 req_struct->m_tuple_ptr= fixed_ptr;
346 req_struct->fix_var_together=
true;
347 req_struct->var_len_array= (Uint16*)var_ptr;
348 req_struct->var_data_start= var_ptr+regTabPtr->var_array_wsize;
349 Uint32 var_sz32= init_var_pos_array((Uint16*)var_ptr,
350 req_struct->var_pos_array,
351 regTabPtr->no_var_attr);
352 req_struct->var_data_end= var_ptr+regTabPtr->var_array_wsize + var_sz32;
361 Dbtup::load_diskpage(
Signal* signal,
362 Uint32 opRec, Uint32 fragPtrI,
363 Uint32 lkey1, Uint32 lkey2, Uint32
flags)
369 c_operation_pool.
getPtr(operPtr, opRec);
371 ptrCheckGuard(fragptr, cnoOfFragrec, fragrecord);
373 Operationrec * regOperPtr= operPtr.p;
374 Fragrecord * regFragPtr= fragptr.p;
376 tabptr.i = regFragPtr->fragTableId;
377 ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
378 Tablerec* regTabPtr = tabptr.p;
380 if (Local_key::ref(lkey1, lkey2) == ~(Uint32)0)
383 regOperPtr->op_struct.m_wait_log_buffer= 1;
384 regOperPtr->op_struct.m_load_diskpage_on_commit= 1;
385 if (unlikely((flags & 7) == ZREFRESH))
391 regOperPtr->op_struct.m_wait_log_buffer= 0;
392 regOperPtr->op_struct.m_load_diskpage_on_commit= 0;
400 Uint32 page_idx= lkey2;
401 Uint32 frag_page_id= lkey1;
402 regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
404 regOperPtr->m_tuple_location.m_page_idx= page_idx;
407 Uint32* tmp= get_ptr(&page_ptr, ®OperPtr->m_tuple_location, regTabPtr);
408 Tuple_header* ptr= (Tuple_header*)tmp;
411 if(ptr->m_header_bits & Tuple_header::DISK_PART)
414 memcpy(&req.m_page, ptr->get_disk_ref_ptr(regTabPtr),
sizeof(
Local_key));
415 req.m_callback.m_callbackData= opRec;
416 req.m_callback.m_callbackFunction=
417 safe_cast(&Dbtup::disk_page_load_callback);
420 if (ERROR_INSERTED(4022))
422 flags |= Page_cache_client::DELAY_REQ;
423 req.m_delay_until_time = NdbTick_CurrentMillisecond()+(Uint64)3000;
428 res= pgman.get_page(signal, req, flags);
429 m_pgman_ptr = pgman.m_ptr;
456 regOperPtr->op_struct.m_wait_log_buffer= 1;
457 regOperPtr->op_struct.m_load_diskpage_on_commit= 1;
463 Dbtup::disk_page_load_callback(
Signal* signal, Uint32 opRec, Uint32 page_id)
466 c_operation_pool.
getPtr(operPtr, opRec);
467 c_lqh->acckeyconf_load_diskpage_callback(signal,
468 operPtr.p->userpointer, page_id);
472 Dbtup::load_diskpage_scan(
Signal* signal,
473 Uint32 opRec, Uint32 fragPtrI,
474 Uint32 lkey1, Uint32 lkey2, Uint32 flags)
480 c_operation_pool.
getPtr(operPtr, opRec);
482 ptrCheckGuard(fragptr, cnoOfFragrec, fragrecord);
484 Operationrec * regOperPtr= operPtr.p;
485 Fragrecord * regFragPtr= fragptr.p;
487 tabptr.i = regFragPtr->fragTableId;
488 ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
489 Tablerec* regTabPtr = tabptr.p;
492 Uint32 page_idx= lkey2;
493 Uint32 frag_page_id= lkey1;
494 regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
496 regOperPtr->m_tuple_location.m_page_idx= page_idx;
497 regOperPtr->op_struct.m_load_diskpage_on_commit= 0;
500 Uint32* tmp= get_ptr(&page_ptr, ®OperPtr->m_tuple_location, regTabPtr);
501 Tuple_header* ptr= (Tuple_header*)tmp;
504 if(ptr->m_header_bits & Tuple_header::DISK_PART)
507 memcpy(&req.m_page, ptr->get_disk_ref_ptr(regTabPtr),
sizeof(
Local_key));
508 req.m_callback.m_callbackData= opRec;
509 req.m_callback.m_callbackFunction=
510 safe_cast(&Dbtup::disk_page_load_scan_callback);
513 res= pgman.get_page(signal, req, flags);
514 m_pgman_ptr = pgman.m_ptr;
534 Dbtup::disk_page_load_scan_callback(
Signal* signal,
535 Uint32 opRec, Uint32 page_id)
538 c_operation_pool.
getPtr(operPtr, opRec);
539 c_lqh->next_scanconf_load_diskpage_callback(signal,
540 operPtr.p->userpointer, page_id);
543 void Dbtup::execTUPKEYREQ(
Signal* signal)
549 KeyReqStruct req_struct(
this);
550 Uint32 sig1, sig2, sig3, sig4;
552 Uint32 RoperPtr= tupKeyReq->connectPtr;
553 Uint32 Rfragptr= tupKeyReq->fragPtr;
555 Uint32 RnoOfFragrec= cnoOfFragrec;
556 Uint32 RnoOfTablerec= cnoOfTablerec;
561 ndbrequire(Rfragptr < RnoOfFragrec);
563 c_operation_pool.
getPtr(operPtr, RoperPtr);
564 ptrAss(fragptr, fragrecord);
566 Uint32 TrequestInfo= tupKeyReq->request;
568 Operationrec * regOperPtr= operPtr.p;
569 Fragrecord * regFragPtr= fragptr.p;
571 tabptr.i = regFragPtr->fragTableId;
572 ptrCheckGuard(tabptr, RnoOfTablerec, tablerec);
573 Tablerec* regTabPtr = tabptr.p;
575 req_struct.tablePtrP = tabptr.p;
576 req_struct.fragPtrP = fragptr.p;
577 req_struct.operPtrP = operPtr.p;
578 req_struct.signal= signal;
579 req_struct.dirty_op= TrequestInfo & 1;
580 req_struct.interpreted_exec= (TrequestInfo >> 10) & 1;
581 req_struct.no_fired_triggers= 0;
582 req_struct.read_length= 0;
583 req_struct.last_row=
false;
584 req_struct.changeMask.clear();
585 req_struct.m_is_lcp =
false;
587 if (unlikely(get_trans_state(regOperPtr) != TRANS_IDLE))
589 TUPKEY_abort(&req_struct, 39);
599 Uint32 Rstoredid= tupKeyReq->storedProcedure;
601 regOperPtr->fragmentPtr= Rfragptr;
602 regOperPtr->op_struct.op_type= (TrequestInfo >> 6) & 0x7;
603 regOperPtr->op_struct.delete_insert_flag =
false;
604 regOperPtr->op_struct.m_reorg = (TrequestInfo >> 12) & 3;
606 regOperPtr->m_copy_tuple_location.setNull();
607 regOperPtr->tupVersion= ZNIL;
609 sig1= tupKeyReq->savePointId;
610 sig2= tupKeyReq->primaryReplica;
611 sig3= tupKeyReq->keyRef2;
613 regOperPtr->savepointId= sig1;
614 regOperPtr->op_struct.primary_replica= sig2;
615 Uint32 pageidx = regOperPtr->m_tuple_location.m_page_idx= sig3;
617 sig1= tupKeyReq->opRef;
618 sig2= tupKeyReq->tcOpIndex;
619 sig3= tupKeyReq->coordinatorTC;
620 sig4= tupKeyReq->keyRef1;
622 req_struct.tc_operation_ptr= sig1;
623 req_struct.TC_index= sig2;
624 req_struct.TC_ref= sig3;
625 Uint32 pageid = req_struct.frag_page_id= sig4;
626 req_struct.m_use_rowid = (TrequestInfo >> 11) & 1;
627 req_struct.m_reorg = (TrequestInfo >> 12) & 3;
629 sig1= tupKeyReq->attrBufLen;
630 sig2= tupKeyReq->applRef;
631 sig3= tupKeyReq->transId1;
632 sig4= tupKeyReq->transId2;
634 Uint32 disk_page= tupKeyReq->disk_page;
636 req_struct.log_size= sig1;
637 req_struct.attrinfo_len= sig1;
638 req_struct.rec_blockref= sig2;
639 req_struct.trans_id1= sig3;
640 req_struct.trans_id2= sig4;
641 req_struct.m_disk_page_ptr.i= disk_page;
643 sig1 = tupKeyReq->m_row_id_page_no;
644 sig2 = tupKeyReq->m_row_id_page_idx;
645 sig3 = tupKeyReq->deferred_constraints;
647 req_struct.m_row_id.m_page_no = sig1;
648 req_struct.m_row_id.m_page_idx = sig2;
649 req_struct.m_deferred_constraints = sig3;
652 Uint32 attrInfoIVal= tupKeyReq->attrInfoIVal;
657 ndbassert( (attrInfoIVal == RNIL) ||
658 (tupKeyReq->attrBufLen > 0));
660 Uint32 Roptype = regOperPtr->op_struct.op_type;
662 if (Rstoredid != ZNIL) {
666 ndbrequire(getStoredProcAttrInfo(Rstoredid,
668 attrInfoIVal) == ZOK);
672 copyAttrinfo(regOperPtr,
674 req_struct.attrinfo_len,
677 regOperPtr->op_struct.m_gci_written = 0;
679 if (Roptype == ZINSERT && Local_key::isInvalid(pageid, pageidx))
685 if (Roptype == ZREFRESH && Local_key::isInvalid(pageid, pageidx))
691 if (unlikely(isCopyTuple(pageid, pageidx)))
696 ndbassert(Roptype == ZREAD);
697 ndbassert(disk_page == RNIL);
698 setup_lcp_read_copy_tuple(&req_struct, regOperPtr, regFragPtr, regTabPtr);
705 regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
706 req_struct.frag_page_id);
708 setup_fixed_part(&req_struct, regOperPtr, regTabPtr);
713 if (Roptype == ZREAD) {
716 if (setup_read(&req_struct, regOperPtr, regFragPtr, regTabPtr,
720 if(handleReadReq(signal, regOperPtr, regTabPtr, &req_struct) != -1)
722 req_struct.log_size= 0;
723 sendTUPKEYCONF(signal, &req_struct, regOperPtr);
732 set_trans_state(regOperPtr, TRANS_IDLE);
736 tupkeyErrorLab(&req_struct);
740 if(insertActiveOpList(operPtr, &req_struct))
742 if(Roptype == ZINSERT)
747 Local_key * accminupdateptr = &accminupdate;
748 if (unlikely(handleInsertReq(signal, operPtr,
749 fragptr, regTabPtr, &req_struct,
750 &accminupdateptr) == -1))
756 checkImmediateTriggersAfterInsert(&req_struct,
761 if (unlikely(terrorCode != 0))
763 tupkeyErrorLab(&req_struct);
767 if (!regTabPtr->tuxCustomTriggers.isEmpty())
770 if (unlikely(executeTuxInsertTriggers(signal,
788 signal->theData[0] = operPtr.i;
789 do_tup_abortreq(signal, ZSKIP_TUX_TRIGGERS);
790 tupkeyErrorLab(&req_struct);
800 c_lqh->accminupdate(signal,
801 regOperPtr->userpointer,
805 sendTUPKEYCONF(signal, &req_struct, regOperPtr);
809 if (Roptype == ZUPDATE) {
811 if (unlikely(handleUpdateReq(signal, regOperPtr,
812 regFragPtr, regTabPtr,
813 &req_struct, disk_page != RNIL) == -1))
819 checkImmediateTriggersAfterUpdate(&req_struct,
824 if (unlikely(terrorCode != 0))
826 tupkeyErrorLab(&req_struct);
830 if (!regTabPtr->tuxCustomTriggers.isEmpty())
833 if (unlikely(executeTuxUpdateTriggers(signal,
842 signal->theData[0] = operPtr.i;
843 do_tup_abortreq(signal, ZSKIP_TUX_TRIGGERS);
844 tupkeyErrorLab(&req_struct);
849 sendTUPKEYCONF(signal, &req_struct, regOperPtr);
852 else if(Roptype == ZDELETE)
855 req_struct.log_size= 0;
856 if (unlikely(handleDeleteReq(signal, regOperPtr,
857 regFragPtr, regTabPtr,
859 disk_page != RNIL) == -1))
865 checkImmediateTriggersAfterDelete(&req_struct,
870 if (unlikely(terrorCode != 0))
872 tupkeyErrorLab(&req_struct);
881 sendTUPKEYCONF(signal, &req_struct, regOperPtr);
884 else if (Roptype == ZREFRESH)
890 if (unlikely(handleRefreshReq(signal, operPtr,
892 &req_struct, disk_page != RNIL) == -1))
897 sendTUPKEYCONF(signal, &req_struct, regOperPtr);
907 tupkeyErrorLab(&req_struct);
911 Dbtup::setup_fixed_part(KeyReqStruct* req_struct,
912 Operationrec* regOperPtr,
916 Uint32* ptr= get_ptr(&page_ptr, ®OperPtr->m_tuple_location, regTabPtr);
917 req_struct->m_page_ptr = page_ptr;
918 req_struct->m_tuple_ptr = (Tuple_header*)ptr;
920 ndbassert(regOperPtr->op_struct.op_type == ZINSERT || (! (req_struct->m_tuple_ptr->m_header_bits & Tuple_header::FREE)));
922 req_struct->check_offset[MM]= regTabPtr->get_check_offset(MM);
923 req_struct->check_offset[DD]= regTabPtr->get_check_offset(DD);
925 Uint32 num_attr= regTabPtr->m_no_of_attributes;
926 Uint32 descr_start= regTabPtr->tabDescriptor;
927 TableDescriptor *tab_descr= &tableDescriptor[descr_start];
928 ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
929 req_struct->attr_descr= tab_descr;
933 Dbtup::setup_lcp_read_copy_tuple(KeyReqStruct* req_struct,
934 Operationrec* regOperPtr,
935 Fragrecord* regFragPtr,
939 tmp.m_page_no = req_struct->frag_page_id;
940 tmp.m_page_idx = regOperPtr->m_tuple_location.m_page_idx;
941 clearCopyTuple(tmp.m_page_no, tmp.m_page_idx);
943 Uint32 * copytuple = get_copy_tuple_raw(&tmp);
945 memcpy(&rowid, copytuple+0,
sizeof(
Local_key));
947 req_struct->frag_page_id = rowid.m_page_no;
948 regOperPtr->m_tuple_location.m_page_idx = rowid.m_page_idx;
950 Tuple_header * th = get_copy_tuple(copytuple);
951 req_struct->m_page_ptr.setNull();
952 req_struct->m_tuple_ptr = (Tuple_header*)th;
953 th->m_operation_ptr_i = RNIL;
954 ndbassert((th->m_header_bits & Tuple_header::COPY_TUPLE) != 0);
956 Uint32 num_attr= regTabPtr->m_no_of_attributes;
957 Uint32 descr_start= regTabPtr->tabDescriptor;
958 TableDescriptor *tab_descr= &tableDescriptor[descr_start];
959 ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
960 req_struct->attr_descr= tab_descr;
963 if (regTabPtr->need_expand(disk))
966 prepare_read(req_struct, regTabPtr, disk);
973 void Dbtup::sendTUPKEYCONF(
Signal* signal,
974 KeyReqStruct *req_struct,
975 Operationrec * regOperPtr)
979 Uint32 Rcreate_rowid = req_struct->m_use_rowid;
980 Uint32 RuserPointer= regOperPtr->userpointer;
981 Uint32 RnoFiredTriggers= req_struct->no_fired_triggers;
982 Uint32 log_size= req_struct->log_size;
983 Uint32 read_length= req_struct->read_length;
984 Uint32 last_row= req_struct->last_row;
986 set_trans_state(regOperPtr, TRANS_STARTED);
987 set_tuple_state(regOperPtr, TUPLE_PREPARED);
988 tupKeyConf->userPtr= RuserPointer;
989 tupKeyConf->readLength= read_length;
990 tupKeyConf->writeLength= log_size;
991 tupKeyConf->noFiredTriggers= RnoFiredTriggers;
992 tupKeyConf->lastRow= last_row;
993 tupKeyConf->rowid = Rcreate_rowid;
996 TupKeyConf::SignalLength);
1001 #define MAX_READ (MIN(sizeof(signal->theData), MAX_SEND_MESSAGE_BYTESIZE))
1006 int Dbtup::handleReadReq(
Signal* signal,
1007 Operationrec* regOperPtr,
1008 Tablerec* regTabPtr,
1009 KeyReqStruct* req_struct)
1012 Uint32 dstLen, start_index;
1013 const BlockReference sendBref= req_struct->rec_blockref;
1014 if ((regTabPtr->m_bits & Tablerec::TR_Checksum) &&
1015 (calculateChecksum(req_struct->m_tuple_ptr, regTabPtr) != 0)) {
1018 terrorCode= ZTUPLE_CORRUPTED_ERROR;
1019 tupkeyErrorLab(req_struct);
1023 const Uint32 node = refToNode(sendBref);
1024 if(node != 0 && node != getOwnNodeId()) {
1033 dst= &signal->theData[start_index];
1034 dstLen= (MAX_READ / 4) - start_index;
1035 if (!req_struct->interpreted_exec) {
1037 int ret = readAttributes(req_struct,
1039 req_struct->attrinfo_len,
1043 if (likely(ret >= 0)) {
1048 Uint32 TnoOfDataRead= (Uint32) ret;
1049 req_struct->read_length += TnoOfDataRead;
1050 sendReadAttrinfo(signal, req_struct, TnoOfDataRead, regOperPtr);
1055 terrorCode = Uint32(-ret);
1059 if (likely(interpreterStartLab(signal, req_struct) != -1)) {
1066 tupkeyErrorLab(req_struct);
1073 Dbtup::Fragrecord::FragState state)
1075 Uint32 reorg = req_struct->m_reorg;
1077 case Dbtup::Fragrecord::FS_FREE:
1078 case Dbtup::Fragrecord::FS_REORG_NEW:
1079 case Dbtup::Fragrecord::FS_REORG_COMMIT_NEW:
1080 case Dbtup::Fragrecord::FS_REORG_COMPLETE_NEW:
1082 case Dbtup::Fragrecord::FS_REORG_COMMIT:
1083 case Dbtup::Fragrecord::FS_REORG_COMPLETE:
1087 case Dbtup::Fragrecord::FS_ONLINE:
1094 req_struct->m_tuple_ptr->m_header_bits |= Dbtup::Tuple_header::REORG_MOVE;
1100 int Dbtup::handleUpdateReq(
Signal* signal,
1101 Operationrec* operPtrP,
1102 Fragrecord* regFragPtr,
1103 Tablerec* regTabPtr,
1104 KeyReqStruct* req_struct,
1108 Tuple_header *base= req_struct->m_tuple_ptr, *org;
1109 ChangeMask * change_mask_ptr;
1110 if ((dst= alloc_copy_tuple(regTabPtr, &operPtrP->m_copy_tuple_location))== 0)
1112 terrorCode= ZMEM_NOMEM_ERROR;
1117 change_mask_ptr = get_change_mask_ptr(regTabPtr, dst);
1118 if(operPtrP->is_first_operation())
1120 org= req_struct->m_tuple_ptr;
1121 tup_version= org->get_tuple_version();
1122 clear_change_mask_info(regTabPtr, change_mask_ptr);
1126 Operationrec* prevOp= req_struct->prevOpPtr.p;
1127 tup_version= prevOp->tupVersion;
1128 Uint32 * rawptr = get_copy_tuple_raw(&prevOp->m_copy_tuple_location);
1129 org= get_copy_tuple(rawptr);
1130 copy_change_mask_info(regTabPtr,
1132 get_change_mask_ptr(rawptr));
1138 req_struct->m_tuple_ptr= org;
1139 if ((regTabPtr->m_bits & Tablerec::TR_Checksum) &&
1140 (calculateChecksum(req_struct->m_tuple_ptr, regTabPtr) != 0))
1142 terrorCode= ZTUPLE_CORRUPTED_ERROR;
1146 req_struct->m_tuple_ptr= dst;
1153 disk = disk || (org->m_header_bits & Tuple_header::DISK_INLINE);
1154 if (regTabPtr->need_expand(disk))
1156 expand_tuple(req_struct, sizes, org, regTabPtr, disk);
1157 if(disk && operPtrP->m_undo_buffer_space == 0)
1159 operPtrP->op_struct.m_wait_log_buffer = 1;
1160 operPtrP->op_struct.m_load_diskpage_on_commit = 1;
1161 Uint32 sz= operPtrP->m_undo_buffer_space=
1164 D(
"Logfile_client - handleUpdateReq");
1165 Logfile_client lgman(
this, c_lgman, regFragPtr->m_logfile_group_id);
1166 terrorCode= lgman.alloc_log_space(sz);
1167 if(unlikely(terrorCode))
1169 operPtrP->m_undo_buffer_space= 0;
1176 memcpy(dst, org, 4*regTabPtr->m_offsets[MM].m_fix_header_size);
1177 req_struct->m_tuple_ptr->m_header_bits |= Tuple_header::COPY_TUPLE;
1180 tup_version= (tup_version + 1) & ZTUP_VERSION_MASK;
1181 operPtrP->tupVersion= tup_version;
1183 req_struct->optimize_options = 0;
1185 if (!req_struct->interpreted_exec) {
1188 if (regTabPtr->m_bits & Tablerec::TR_ExtraRowAuthorBits)
1192 regTabPtr->getExtraAttrId<Tablerec::TR_ExtraRowAuthorBits>();
1194 store_extra_row_bits(attrId, regTabPtr, dst, 0,
false);
1196 int retValue = updateAttributes(req_struct,
1198 req_struct->attrinfo_len);
1199 if (unlikely(retValue < 0))
1201 terrorCode = Uint32(-retValue);
1206 if (unlikely(interpreterStartLab(signal, req_struct) == -1))
1210 update_change_mask_info(regTabPtr,
1212 req_struct->changeMask.rep.data);
1214 switch (req_struct->optimize_options) {
1215 case AttributeHeader::OPTIMIZE_MOVE_VARPART:
1220 if(base->m_header_bits & Tuple_header::VAR_PART)
1221 optimize_var_part(req_struct, base, operPtrP,
1222 regFragPtr, regTabPtr);
1224 case AttributeHeader::OPTIMIZE_MOVE_FIXPART:
1231 if (regTabPtr->need_shrink())
1233 shrink_tuple(req_struct, sizes+2, regTabPtr, disk);
1234 if (cmp[0] != cmp[1] && handle_size_change_after_update(req_struct,
1244 if (req_struct->m_reorg)
1246 handle_reorg(req_struct, regFragPtr->fragStatus);
1249 req_struct->m_tuple_ptr->set_tuple_version(tup_version);
1250 if (regTabPtr->m_bits & Tablerec::TR_Checksum) {
1252 setChecksum(req_struct->m_tuple_ptr, regTabPtr);
1255 set_tuple_state(operPtrP, TUPLE_PREPARED);
1260 tupkeyErrorLab(req_struct);
1284 const Uint32 * tabDesc,
1285 const Uint16* order,
1291 Uint32 *dst_bm_ptr= (Uint32*)dst->m_dyn_data_ptr;
1292 Uint32 bm_len = row_len ? (* src & Dbtup::DYN_BM_LEN_MASK) : 0;
1294 assert(bm_len <= max_bmlen);
1297 memcpy(dst_bm_ptr, src, 4*bm_len);
1298 if(bm_len < max_bmlen)
1299 bzero(dst_bm_ptr + bm_len, 4 * (max_bmlen - bm_len));
1304 Uint32 tmp = (* dst_bm_ptr);
1305 * dst_bm_ptr = (tmp & ~(Uint32)Dbtup::DYN_BM_LEN_MASK) | max_bmlen;
1307 char *src_off_start= (
char*)(src + bm_len);
1308 assert((UintPtr(src_off_start)&3) == 0);
1309 Uint16 *src_off_ptr= (Uint16*)src_off_start;
1315 Uint32 no_attr= dst->m_dyn_len_offset;
1316 Uint16* dst_off_ptr= dst->m_dyn_offset_arr_ptr;
1317 Uint16* dst_len_ptr= dst_off_ptr + no_attr;
1318 Uint16 this_src_off= row_len ? * src_off_ptr++ : 0;
1320 Uint16 dst_off= 4 * (max_bmlen + ((dynvar+2)>>1));
1321 char *dst_ptr= (
char*)dst_bm_ptr + dst_off;
1322 for(Uint32 i= 0; i<dynvar; i++)
1324 Uint16 j= order[dynfix+
i];
1325 Uint32 max_len= 4 *AttributeDescriptor::getSizeInWords(tabDesc[j]);
1327 Uint32 pos = AttributeOffset::getNullFlagPos(tabDesc[j+1]);
1330 Uint16 next_src_off= *src_off_ptr++;
1331 len= next_src_off - this_src_off;
1332 memcpy(dst_ptr, src_off_start+this_src_off, len);
1333 this_src_off= next_src_off;
1339 dst_off_ptr[
i]= dst_off;
1340 dst_len_ptr[
i]= dst_off+len;
1348 char *src_ptr= src_off_start+this_src_off;
1349 src_ptr= (
char *)(ALIGN_WORD(src_ptr));
1358 for(Uint32 i= dynfix; i>0; )
1362 Uint32 fix_size= 4*AttributeDescriptor::getSizeInWords(tabDesc[j]);
1363 dst_off_ptr[dynvar+
i]= dst_off;
1365 Uint32 pos = AttributeOffset::getNullFlagPos(tabDesc[j+1]);
1368 assert((UintPtr(dst_ptr)&3) == 0);
1369 memcpy(dst_ptr, src_ptr, fix_size);
1376 return (Uint32 *)dst_ptr;
1384 const Uint32 * tabDesc,
1385 const Uint16* order,
1395 assert((UintPtr(dst->m_dyn_data_ptr)&3) == 0);
1396 char *dyn_src_ptr= dst->m_dyn_data_ptr;
1397 Uint32 bm_len = tabPtrP->m_offsets[ind].m_dyn_null_words;
1406 * ((Uint32 *)dyn_src_ptr) &= ~Uint32(Dbtup::DYN_BM_LEN_MASK);
1408 Uint32 *bm_ptr= (Uint32 *)dyn_src_ptr + bm_len - 1;
1424 Uint32 *dyn_dst_ptr= dst_ptr;
1425 Uint32 dyn_var_count= 0;
1426 const Uint32 *src_bm_ptr= (Uint32 *)(dyn_src_ptr);
1427 Uint32 *dst_bm_ptr= (Uint32 *)dyn_dst_ptr;
1431 Uint16 dyn_dst_data_offset= 0;
1432 const Uint32 *dyn_bm_var_mask_ptr= tabPtrP->dynVarSizeMask[ind];
1433 for(Uint16 i= 0; i< bm_len; i++)
1435 Uint32 v= src_bm_ptr[
i];
1436 dyn_var_count+= BitmaskImpl::count_bits(v & *dyn_bm_var_mask_ptr++);
1440 Uint32 tmp = *dyn_dst_ptr;
1441 assert(bm_len <= Dbtup::DYN_BM_LEN_MASK);
1442 * dyn_dst_ptr = (tmp & ~(Uint32)Dbtup::DYN_BM_LEN_MASK) | bm_len;
1443 dyn_dst_ptr+= bm_len;
1444 dyn_dst_data_offset= 2*dyn_var_count + 2;
1446 Uint16 *dyn_src_off_array= dst->m_dyn_offset_arr_ptr;
1447 Uint16 *dyn_src_lenoff_array=
1448 dyn_src_off_array + dst->m_dyn_len_offset;
1449 Uint16* dyn_dst_off_array = (Uint16*)dyn_dst_ptr;
1458 for(Uint32 i= 0; i<dynvar; i++)
1465 Uint32 attrDesc2 = tabDesc[order[dynfix+
i]+1];
1466 Uint32 pos = AttributeOffset::getNullFlagPos(attrDesc2);
1469 dyn_dst_off_array[off_idx++]= dyn_dst_data_offset;
1470 Uint32 dyn_src_off= dyn_src_off_array[
i];
1471 Uint32 dyn_len= dyn_src_lenoff_array[
i] - dyn_src_off;
1472 memmove(((
char *)dyn_dst_ptr) + dyn_dst_data_offset,
1473 dyn_src_ptr + dyn_src_off,
1475 dyn_dst_data_offset+= dyn_len;
1479 dyn_dst_off_array[off_idx]= dyn_dst_data_offset;
1480 assert(dyn_dst_off_array + off_idx == (Uint16*)dyn_dst_ptr+dyn_var_count);
1482 char *dynvar_end_ptr= ((
char *)dyn_dst_ptr) + dyn_dst_data_offset;
1483 char *dyn_dst_data_ptr= (
char *)(ALIGN_WORD(dynvar_end_ptr));
1489 bzero(dynvar_end_ptr, dyn_dst_data_ptr-dynvar_end_ptr);
1497 for(Uint32 i= dynfix; i > 0; )
1501 Uint32 attrDesc2 = tabDesc[j+1];
1502 Uint32 pos = AttributeOffset::getNullFlagPos(attrDesc2);
1506 4*AttributeDescriptor::getSizeInWords(tabDesc[j]);
1507 memmove(dyn_dst_data_ptr,
1508 dyn_src_ptr + dyn_src_off_array[dynvar+i],
1510 dyn_dst_data_ptr += fixsize;
1513 dst_ptr = (Uint32*)dyn_dst_data_ptr;
1514 assert((UintPtr(dst_ptr) & 3) == 0);
1516 return (Uint32 *)dst_ptr;
1523 Dbtup::prepare_initial_insert(KeyReqStruct *req_struct,
1524 Operationrec* regOperPtr,
1525 Tablerec* regTabPtr)
1527 Uint32 disk_undo = regTabPtr->m_no_of_disk_attributes ?
1529 regOperPtr->nextActiveOp= RNIL;
1530 regOperPtr->prevActiveOp= RNIL;
1531 regOperPtr->op_struct.in_active_list=
true;
1532 regOperPtr->m_undo_buffer_space= disk_undo;
1534 req_struct->check_offset[MM]= regTabPtr->get_check_offset(MM);
1535 req_struct->check_offset[DD]= regTabPtr->get_check_offset(DD);
1537 Uint32 num_attr= regTabPtr->m_no_of_attributes;
1538 Uint32 descr_start= regTabPtr->tabDescriptor;
1539 Uint32 order_desc= regTabPtr->m_real_order_descriptor;
1540 TableDescriptor *tab_descr= &tableDescriptor[descr_start];
1541 ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
1542 req_struct->attr_descr= tab_descr;
1543 Uint16* order= (Uint16*)&tableDescriptor[order_desc];
1544 order += regTabPtr->m_attributes[MM].m_no_of_fixsize;
1546 Uint32 bits = Tuple_header::COPY_TUPLE;
1547 bits |= disk_undo ? (Tuple_header::DISK_ALLOC|Tuple_header::DISK_INLINE) : 0;
1549 const Uint32 mm_vars= regTabPtr->m_attributes[MM].m_no_of_varsize;
1550 const Uint32 mm_dyns= regTabPtr->m_attributes[MM].m_no_of_dynamic;
1551 const Uint32 mm_dynvar= regTabPtr->m_attributes[MM].m_no_of_dyn_var;
1552 const Uint32 mm_dynfix= regTabPtr->m_attributes[MM].m_no_of_dyn_fix;
1553 const Uint32 dd_vars= regTabPtr->m_attributes[DD].m_no_of_varsize;
1554 Uint32 *ptr= req_struct->m_tuple_ptr->get_end_of_fix_part_ptr(regTabPtr);
1555 Var_part_ref* ref = req_struct->m_tuple_ptr->get_var_part_ref_ptr(regTabPtr);
1557 if (regTabPtr->m_bits & Tablerec::TR_ForceVarPart)
1559 ref->m_page_no = RNIL;
1560 ref->m_page_idx = Tup_varsize_page::END_OF_FREE_LIST;
1563 if(mm_vars || mm_dyns)
1567 Varpart_copy * cp = (Varpart_copy*)ptr;
1569 ptr += Varpart_copy::SZ32;
1572 KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
1576 dst->m_data_ptr= (
char*)(((Uint16*)ptr)+mm_vars+1);
1577 dst->m_offset_array_ptr= req_struct->var_pos_array;
1578 dst->m_var_len_offset= mm_vars;
1579 dst->m_max_var_offset= regTabPtr->m_offsets[MM].m_max_var_offset;
1582 Uint16 *pos_ptr = req_struct->var_pos_array;
1583 Uint16 *len_ptr = pos_ptr + mm_vars;
1584 for(Uint32 i= 0; i<mm_vars; i++)
1588 pos += AttributeDescriptor::getSizeInBytes(tab_descr[*order++].tabDescr);
1592 ptr = ALIGN_WORD(dst->m_data_ptr+pos);
1593 ndbassert(ptr == ALIGN_WORD(dst->m_data_ptr +
1594 regTabPtr->m_offsets[MM].m_max_var_offset));
1601 dst->m_dyn_data_ptr= (
char *)ptr;
1602 dst->m_dyn_offset_arr_ptr= req_struct->var_pos_array+2*mm_vars;
1603 dst->m_dyn_len_offset= mm_dynvar+mm_dynfix;
1604 dst->m_max_dyn_offset= regTabPtr->m_offsets[MM].m_max_dyn_offset;
1606 ptr = expand_dyn_part(dst, 0, 0,
1607 (Uint32*)tab_descr, order,
1608 mm_dynvar, mm_dynfix,
1609 regTabPtr->m_offsets[MM].m_dyn_null_words);
1612 ndbassert((UintPtr(ptr)&3) == 0);
1615 req_struct->m_disk_ptr= (Tuple_header*)ptr;
1617 ndbrequire(dd_vars == 0);
1619 req_struct->m_tuple_ptr->m_header_bits= bits;
1622 memset(req_struct->m_tuple_ptr->m_null_bits+
1623 regTabPtr->m_offsets[MM].m_null_offset, 0xFF,
1624 4*regTabPtr->m_offsets[MM].m_null_words);
1625 memset(req_struct->m_disk_ptr->m_null_bits+
1626 regTabPtr->m_offsets[DD].m_null_offset, 0xFF,
1627 4*regTabPtr->m_offsets[DD].m_null_words);
1630 int Dbtup::handleInsertReq(
Signal* signal,
1633 Tablerec* regTabPtr,
1634 KeyReqStruct *req_struct,
1637 Uint32 tup_version = 1;
1638 Fragrecord* regFragPtr = fragPtr.p;
1641 Tuple_header *base= req_struct->m_tuple_ptr, *org= base;
1642 Tuple_header *tuple_ptr;
1644 bool disk = regTabPtr->m_no_of_disk_attributes > 0;
1645 bool mem_insert = regOperPtr.p->is_first_operation();
1646 bool disk_insert = mem_insert && disk;
1647 bool vardynsize = (regTabPtr->m_attributes[MM].m_no_of_varsize ||
1648 regTabPtr->m_attributes[MM].m_no_of_dynamic);
1649 bool varalloc = vardynsize || regTabPtr->m_bits & Tablerec::TR_ForceVarPart;
1650 bool rowid = req_struct->m_use_rowid;
1651 bool update_acc =
false;
1652 Uint32 real_page_id = regOperPtr.p->m_tuple_location.m_page_no;
1653 Uint32 frag_page_id = req_struct->frag_page_id;
1659 cmp[0] = cmp[1] = 0;
1661 if (ERROR_INSERTED(4014))
1664 goto undo_buffer_error;
1667 dst= alloc_copy_tuple(regTabPtr, ®OperPtr.p->m_copy_tuple_location);
1669 if (unlikely(dst == 0))
1671 goto undo_buffer_error;
1673 tuple_ptr= req_struct->m_tuple_ptr= dst;
1674 set_change_mask_info(regTabPtr, get_change_mask_ptr(regTabPtr, dst));
1679 prepare_initial_insert(req_struct, regOperPtr.p, regTabPtr);
1683 Operationrec* prevOp= req_struct->prevOpPtr.p;
1684 ndbassert(prevOp->op_struct.op_type == ZDELETE);
1685 tup_version= prevOp->tupVersion + 1;
1687 if(!prevOp->is_first_operation())
1688 org= get_copy_tuple(&prevOp->m_copy_tuple_location);
1689 if (regTabPtr->need_expand())
1691 expand_tuple(req_struct, sizes, org, regTabPtr, !disk_insert);
1692 memset(req_struct->m_disk_ptr->m_null_bits+
1693 regTabPtr->m_offsets[DD].m_null_offset, 0xFF,
1694 4*regTabPtr->m_offsets[DD].m_null_words);
1696 Uint32 bm_size_in_bytes= 4*(regTabPtr->m_offsets[MM].m_dyn_null_words);
1697 if (bm_size_in_bytes)
1700 (Uint32*)req_struct->m_var_data[MM].m_dyn_data_ptr;
1701 bzero(ptr, bm_size_in_bytes);
1702 * ptr = bm_size_in_bytes >> 2;
1707 memcpy(dst, org, 4*regTabPtr->m_offsets[MM].m_fix_header_size);
1708 tuple_ptr->m_header_bits |= Tuple_header::COPY_TUPLE;
1710 memset(tuple_ptr->m_null_bits+
1711 regTabPtr->m_offsets[MM].m_null_offset, 0xFF,
1712 4*regTabPtr->m_offsets[MM].m_null_words);
1718 if (ERROR_INSERTED(4015))
1721 goto log_space_error;
1724 D(
"Logfile_client - handleInsertReq");
1725 Logfile_client lgman(
this, c_lgman, regFragPtr->m_logfile_group_id);
1726 res= lgman.alloc_log_space(regOperPtr.p->m_undo_buffer_space);
1730 goto log_space_error;
1734 regOperPtr.p->tupVersion= tup_version & ZTUP_VERSION_MASK;
1735 tuple_ptr->set_tuple_version(tup_version);
1737 if (ERROR_INSERTED(4016))
1739 terrorCode = ZAI_INCONSISTENCY_ERROR;
1743 if (regTabPtr->m_bits & Tablerec::TR_ExtraRowAuthorBits)
1746 regTabPtr->getExtraAttrId<Tablerec::TR_ExtraRowAuthorBits>();
1748 store_extra_row_bits(attrId, regTabPtr, tuple_ptr, 0,
false);
1751 if (!regTabPtr->m_default_value_location.isNull())
1754 Uint32 default_values_len;
1756 Uint32* default_values = get_default_ptr(regTabPtr, default_values_len);
1757 ndbrequire(default_values_len != 0 && default_values != NULL);
1762 if(unlikely((res = updateAttributes(req_struct, default_values,
1763 default_values_len)) < 0))
1766 terrorCode = Uint32(-res);
1771 if(unlikely((res = updateAttributes(req_struct, &cinBuffer[0],
1772 req_struct->attrinfo_len)) < 0))
1774 terrorCode = Uint32(-res);
1778 if (ERROR_INSERTED(4017))
1780 goto null_check_error;
1782 if (unlikely(checkNullAttributes(req_struct, regTabPtr) ==
false))
1784 goto null_check_error;
1787 if (req_struct->m_is_lcp)
1790 sizes[2+MM] = req_struct->m_lcp_varpart_len;
1792 else if (regTabPtr->need_shrink())
1794 shrink_tuple(req_struct, sizes+2, regTabPtr,
true);
1797 if (ERROR_INSERTED(4025))
1802 if (ERROR_INSERTED(4026))
1804 CLEAR_ERROR_INSERT_VALUE;
1808 if (ERROR_INSERTED(4027) && (rand() % 100) > 25)
1813 if (ERROR_INSERTED(4028) && (rand() % 100) > 25)
1815 CLEAR_ERROR_INSERT_VALUE;
1826 if (ERROR_INSERTED(4018))
1834 ptr= alloc_fix_rec(&terrorCode,
1837 ®OperPtr.p->m_tuple_location,
1843 regOperPtr.p->m_tuple_location.m_file_no= sizes[2+MM];
1844 ptr= alloc_var_rec(&terrorCode,
1845 regFragPtr, regTabPtr,
1847 ®OperPtr.p->m_tuple_location,
1850 if (unlikely(ptr == 0))
1854 req_struct->m_use_rowid =
true;
1858 regOperPtr.p->m_tuple_location = req_struct->m_row_id;
1859 if (ERROR_INSERTED(4019))
1861 terrorCode = ZROWID_ALLOCATED;
1862 goto alloc_rowid_error;
1868 ptr= alloc_fix_rowid(&terrorCode,
1871 ®OperPtr.p->m_tuple_location,
1877 regOperPtr.p->m_tuple_location.m_file_no= sizes[2+MM];
1878 ptr= alloc_var_rowid(&terrorCode,
1879 regFragPtr, regTabPtr,
1881 ®OperPtr.p->m_tuple_location,
1884 if (unlikely(ptr == 0))
1887 goto alloc_rowid_error;
1890 real_page_id = regOperPtr.p->m_tuple_location.m_page_no;
1893 base = (Tuple_header*)ptr;
1894 base->m_operation_ptr_i= regOperPtr.i;
1895 base->m_header_bits= Tuple_header::ALLOC |
1896 (sizes[2+MM] > 0 ? Tuple_header::VAR_PART : 0);
1900 if (ERROR_INSERTED(4020))
1902 goto size_change_error;
1905 if (regTabPtr->need_shrink() && cmp[0] != cmp[1] &&
1906 unlikely(handle_size_change_after_update(req_struct,
1913 goto size_change_error;
1915 req_struct->m_use_rowid =
false;
1916 base->m_header_bits &= ~(Uint32)Tuple_header::FREE;
1922 Uint32
size= regTabPtr->m_attributes[DD].m_no_of_varsize == 0 ?
1925 if (ERROR_INSERTED(4021))
1928 goto disk_prealloc_error;
1931 int ret= disk_page_prealloc(signal, fragPtr, &tmp, size);
1932 if (unlikely(ret < 0))
1935 goto disk_prealloc_error;
1938 regOperPtr.p->op_struct.m_disk_preallocated= 1;
1939 tmp.m_page_idx=
size;
1940 memcpy(tuple_ptr->get_disk_ref_ptr(regTabPtr), &tmp,
sizeof(tmp));
1945 Local_key ref = regOperPtr.p->m_tuple_location;
1946 ref.m_page_no = frag_page_id;
1948 Tuple_header* disk_ptr= req_struct->m_disk_ptr;
1949 disk_ptr->m_header_bits = 0;
1950 disk_ptr->m_base_record_ref= ref.ref();
1953 if (req_struct->m_reorg)
1955 handle_reorg(req_struct, regFragPtr->fragStatus);
1967 ndbassert(regOperPtr.p->m_tuple_location.m_page_no == real_page_id);
1969 Local_key accKey = regOperPtr.p->m_tuple_location;
1970 accKey.m_page_no = frag_page_id;
1971 ** accminupdateptr = accKey;
1975 * accminupdateptr = 0;
1978 if (regTabPtr->m_bits & Tablerec::TR_Checksum)
1981 setChecksum(req_struct->m_tuple_ptr, regTabPtr);
1984 set_tuple_state(regOperPtr.p, TUPLE_PREPARED);
1990 terrorCode = ZMEM_NOMEM_ERROR;
1995 terrorCode= ZMEM_NOMEM_ERROR;
1996 regOperPtr.p->m_undo_buffer_space = 0;
1998 regOperPtr.p->m_tuple_location.setNull();
1999 regOperPtr.p->m_copy_tuple_location.setNull();
2000 tupkeyErrorLab(req_struct);
2005 terrorCode= ZNO_ILLEGAL_NULL_ATTR;
2010 terrorCode= ZMEM_NOMEM_ERROR;
2015 regOperPtr.p->m_undo_buffer_space = 0;
2022 regOperPtr.p->op_struct.in_active_list =
false;
2023 regOperPtr.p->m_tuple_location.setNull();
2026 tupkeyErrorLab(req_struct);
2029 disk_prealloc_error:
2030 base->m_header_bits |= Tuple_header::FREED;
2037 int Dbtup::handleDeleteReq(
Signal* signal,
2038 Operationrec* regOperPtr,
2039 Fragrecord* regFragPtr,
2040 Tablerec* regTabPtr,
2041 KeyReqStruct *req_struct,
2044 Tuple_header* dst = alloc_copy_tuple(regTabPtr,
2045 ®OperPtr->m_copy_tuple_location);
2047 terrorCode = ZMEM_NOMEM_ERROR;
2052 if (!regOperPtr->is_first_operation())
2054 Operationrec* prevOp= req_struct->prevOpPtr.p;
2055 regOperPtr->tupVersion= prevOp->tupVersion;
2057 const Tuple_header* org = get_copy_tuple(&prevOp->m_copy_tuple_location);
2058 Uint32 len = regTabPtr->total_rec_size -
2059 Uint32(((Uint32*)dst) -
2060 get_copy_tuple_raw(®OperPtr->m_copy_tuple_location));
2061 memcpy(dst, org, 4 * len);
2062 req_struct->m_tuple_ptr = dst;
2066 regOperPtr->tupVersion= req_struct->m_tuple_ptr->get_tuple_version();
2067 if (regTabPtr->m_no_of_disk_attributes)
2069 dst->m_header_bits = req_struct->m_tuple_ptr->m_header_bits;
2070 memcpy(dst->get_disk_ref_ptr(regTabPtr),
2071 req_struct->m_tuple_ptr->get_disk_ref_ptr(regTabPtr),
2075 req_struct->changeMask.set();
2076 set_change_mask_info(regTabPtr, get_change_mask_ptr(regTabPtr, dst));
2078 if(disk && regOperPtr->m_undo_buffer_space == 0)
2080 regOperPtr->op_struct.m_wait_log_buffer = 1;
2081 regOperPtr->op_struct.m_load_diskpage_on_commit = 1;
2082 Uint32 sz= regOperPtr->m_undo_buffer_space=
2084 regTabPtr->m_offsets[DD].m_fix_header_size - 1;
2086 D(
"Logfile_client - handleDeleteReq");
2087 Logfile_client lgman(
this, c_lgman, regFragPtr->m_logfile_group_id);
2088 terrorCode= lgman.alloc_log_space(sz);
2089 if(unlikely(terrorCode))
2091 regOperPtr->m_undo_buffer_space= 0;
2096 set_tuple_state(regOperPtr, TUPLE_PREPARED);
2098 if (req_struct->attrinfo_len == 0)
2103 if (regTabPtr->need_expand(disk))
2105 prepare_read(req_struct, regTabPtr, disk);
2110 int ret= handleReadReq(signal, regOperPtr, regTabPtr, req_struct);
2111 if (ret == 0 && (RlogSize= req_struct->log_size))
2114 sendLogAttrinfo(signal, req_struct, RlogSize, regOperPtr);
2120 tupkeyErrorLab(req_struct);
2125 Dbtup::handleRefreshReq(
Signal* signal,
2128 Tablerec* regTabPtr,
2129 KeyReqStruct *req_struct,
2146 Uint32 refresh_case;
2147 if (regOperPtr.p->is_first_operation())
2150 if (Local_key::isInvalid(req_struct->frag_page_id,
2151 regOperPtr.p->m_tuple_location.m_page_idx))
2154 refresh_case = Operationrec::RF_SINGLE_NOT_EXIST;
2161 Local_key * accminupdateptr = &accminupdate;
2168 Uint32 save_disk = regTabPtr->m_no_of_disk_attributes;
2169 Local_key save_defaults = regTabPtr->m_default_value_location;
2171 regTabPtr->notNullAttributeMask;
2173 regTabPtr->m_no_of_disk_attributes = 0;
2174 regTabPtr->m_default_value_location.setNull();
2175 regOperPtr.p->op_struct.op_type = ZINSERT;
2180 regTabPtr->notNullAttributeMask.clear();
2181 const Uint32 * primarykeys =
2182 (Uint32*)&tableDescriptor[regTabPtr->readKeyArray].tabDescr;
2183 for (Uint32 i = 0; i<regTabPtr->noOfKeyAttr; i++)
2184 regTabPtr->notNullAttributeMask.set(primarykeys[i] >> 16);
2186 int res = handleInsertReq(signal, regOperPtr,
2187 regFragPtr, regTabPtr, req_struct,
2190 regTabPtr->m_no_of_disk_attributes = save_disk;
2191 regTabPtr->m_default_value_location = save_defaults;
2192 regTabPtr->notNullAttributeMask = save_mask;
2194 if (unlikely(res == -1))
2199 regOperPtr.p->op_struct.op_type = ZREFRESH;
2201 if (accminupdateptr)
2206 c_lqh->accminupdate(signal,
2207 regOperPtr.p->userpointer,
2213 refresh_case = Operationrec::RF_SINGLE_EXIST;
2217 Uint32 tup_version_save = req_struct->m_tuple_ptr->get_tuple_version();
2218 Uint32 new_tup_version = decr_tup_version(tup_version_save);
2219 Tuple_header* origTuple = req_struct->m_tuple_ptr;
2220 origTuple->set_tuple_version(new_tup_version);
2221 int res = handleUpdateReq(signal, regOperPtr.p, regFragPtr.p,
2222 regTabPtr, req_struct, disk);
2232 origTuple->set_tuple_version(tup_version_save);
2242 Uint32 tup_version_save = req_struct->prevOpPtr.p->tupVersion;
2243 Uint32 new_tup_version = decr_tup_version(tup_version_save);
2244 req_struct->prevOpPtr.p->tupVersion = new_tup_version;
2247 if (req_struct->prevOpPtr.p->op_struct.op_type == ZDELETE)
2249 refresh_case = Operationrec::RF_MULTI_NOT_EXIST;
2259 Local_key save_defaults = regTabPtr->m_default_value_location;
2261 regTabPtr->notNullAttributeMask;
2263 regTabPtr->m_default_value_location.setNull();
2264 regOperPtr.p->op_struct.op_type = ZINSERT;
2269 regTabPtr->notNullAttributeMask.clear();
2270 const Uint32 * primarykeys =
2271 (Uint32*)&tableDescriptor[regTabPtr->readKeyArray].tabDescr;
2272 for (Uint32 i = 0; i<regTabPtr->noOfKeyAttr; i++)
2273 regTabPtr->notNullAttributeMask.set(primarykeys[i] >> 16);
2279 res = handleInsertReq(signal, regOperPtr,
2280 regFragPtr, regTabPtr, req_struct,
2283 regTabPtr->m_default_value_location = save_defaults;
2284 regTabPtr->notNullAttributeMask = save_mask;
2286 if (unlikely(res == -1))
2291 regOperPtr.p->op_struct.op_type = ZREFRESH;
2296 refresh_case = Operationrec::RF_MULTI_EXIST;
2301 res = handleUpdateReq(signal, regOperPtr.p, regFragPtr.p,
2302 regTabPtr, req_struct, disk);
2304 req_struct->prevOpPtr.p->tupVersion = tup_version_save;
2311 regOperPtr.p->m_copy_tuple_location.m_file_no = refresh_case;
2316 Dbtup::checkNullAttributes(KeyReqStruct * req_struct,
2317 Tablerec* regTabPtr)
2331 attributeMask.
clear();
2332 attributeMask.
bitOR(req_struct->changeMask);
2333 attributeMask.
bitAND(regTabPtr->notNullAttributeMask);
2334 attributeMask.
bitXOR(regTabPtr->notNullAttributeMask);
2335 if (!attributeMask.
isclear()) {
2386 int Dbtup::interpreterStartLab(
Signal* signal,
2387 KeyReqStruct *req_struct)
2389 Operationrec *
const regOperPtr = req_struct->operPtrP;
2391 Uint32 RtotalLen, start_index, dstLen;
2394 Uint32 RinitReadLen= cinBuffer[0];
2395 Uint32 RexecRegionLen= cinBuffer[1];
2396 Uint32 RfinalUpdateLen= cinBuffer[2];
2397 Uint32 RfinalRLen= cinBuffer[3];
2398 Uint32 RsubLen= cinBuffer[4];
2400 Uint32 RattrinbufLen= req_struct->attrinfo_len;
2401 const BlockReference sendBref= req_struct->rec_blockref;
2403 const Uint32 node = refToNode(sendBref);
2404 if(node != 0 && node != getOwnNodeId()) {
2413 dst= &signal->theData[start_index];
2414 dstLen= (MAX_READ / 4) - start_index;
2416 RtotalLen= RinitReadLen;
2417 RtotalLen += RexecRegionLen;
2418 RtotalLen += RfinalUpdateLen;
2419 RtotalLen += RfinalRLen;
2420 RtotalLen += RsubLen;
2422 Uint32 RattroutCounter= 0;
2423 Uint32 RinstructionCounter= 5;
2428 Uint32 RlogSize= req_struct->log_size= 0;
2429 if (((RtotalLen + 5) == RattrinbufLen) &&
2430 (RattrinbufLen >= 5) &&
2431 (RattrinbufLen < ZATTR_BUFFER_SIZE)) {
2439 if (RinitReadLen > 0) {
2445 TnoDataRW= readAttributes(req_struct,
2451 if (TnoDataRW >= 0) {
2452 RattroutCounter= TnoDataRW;
2453 RinstructionCounter += RinitReadLen;
2456 terrorCode = Uint32(-TnoDataRW);
2457 tupkeyErrorLab(req_struct);
2461 if (RexecRegionLen > 0) {
2468 Uint32 RsubPC= RinstructionCounter + RexecRegionLen
2469 + RfinalUpdateLen + RfinalRLen;
2470 TnoDataRW= interpreterNextLab(signal,
2473 &cinBuffer[RinstructionCounter],
2478 sizeof(coutBuffer) / 4);
2479 if (TnoDataRW != -1) {
2480 RinstructionCounter += RexecRegionLen;
2481 RlogSize= TnoDataRW;
2491 if ((RlogSize > 0) ||
2492 (RfinalUpdateLen > 0))
2500 Tablerec* regTabPtr = req_struct->tablePtrP;
2501 Tuple_header* dst = req_struct->m_tuple_ptr;
2503 if (regTabPtr->m_bits & Tablerec::TR_ExtraRowAuthorBits)
2506 regTabPtr->getExtraAttrId<Tablerec::TR_ExtraRowAuthorBits>();
2508 store_extra_row_bits(attrId, regTabPtr, dst, 0,
false);
2512 if (RfinalUpdateLen > 0) {
2518 if (regOperPtr->op_struct.op_type == ZUPDATE) {
2519 TnoDataRW= updateAttributes(req_struct,
2520 &cinBuffer[RinstructionCounter],
2522 if (TnoDataRW >= 0) {
2523 MEMCOPY_NO_WORDS(&clogMemBuffer[RlogSize],
2524 &cinBuffer[RinstructionCounter],
2526 RinstructionCounter += RfinalUpdateLen;
2527 RlogSize += RfinalUpdateLen;
2530 terrorCode = Uint32(-TnoDataRW);
2531 tupkeyErrorLab(req_struct);
2535 return TUPKEY_abort(req_struct, 19);
2538 if (RfinalRLen > 0) {
2544 TnoDataRW= readAttributes(req_struct,
2545 &cinBuffer[RinstructionCounter],
2547 &dst[RattroutCounter],
2548 (dstLen - RattroutCounter),
2550 if (TnoDataRW >= 0) {
2551 RattroutCounter += TnoDataRW;
2554 terrorCode = Uint32(-TnoDataRW);
2555 tupkeyErrorLab(req_struct);
2564 req_struct->log_size+= RlogSize;
2565 req_struct->read_length += RattroutCounter;
2566 sendReadAttrinfo(signal, req_struct, RattroutCounter, regOperPtr);
2568 return sendLogAttrinfo(signal, req_struct, RlogSize, regOperPtr);
2572 return TUPKEY_abort(req_struct, 22);
2584 int Dbtup::sendLogAttrinfo(
Signal* signal,
2585 KeyReqStruct * req_struct,
2587 Operationrec *
const regOperPtr)
2594 ndbrequire( TlogSize > 0 );
2595 Uint32 longSectionIVal= RNIL;
2596 bool ok= appendToSection(longSectionIVal,
2602 terrorCode = ZSEIZE_ATTRINBUFREC_ERROR;
2603 tupkeyErrorLab(req_struct);
2611 signal->theData[0]= regOperPtr->userpointer;
2612 signal->theData[1]= TlogSize;
2613 signal->theData[2]= longSectionIVal;
2624 Dbtup::brancher(Uint32 TheInstruction, Uint32 TprogramCounter)
2626 Uint32 TbranchDirection= TheInstruction >> 31;
2627 Uint32 TbranchLength= (TheInstruction >> 16) & 0x7fff;
2629 if (TbranchDirection == 1) {
2634 return (TprogramCounter - TbranchLength);
2640 return (TprogramCounter + TbranchLength);
2645 Dbtup::lookupInterpreterParameter(Uint32 paramNo,
2646 const Uint32 * subptr,
2647 Uint32 sublen)
const
2661 const Uint32 * head = subptr + pos;
2662 Uint32 len = AttributeHeader::getDataSize(* head);
2665 if (unlikely(pos >= sublen))
2669 const Uint32 * head = subptr + pos;
2670 Uint32 len = AttributeHeader::getDataSize(* head);
2671 if (unlikely(pos + 1 + len > sublen))
2677 int Dbtup::interpreterNextLab(
Signal* signal,
2678 KeyReqStruct* req_struct,
2680 Uint32* mainProgram,
2681 Uint32 TmainProgLen,
2682 Uint32* subroutineProg,
2683 Uint32 TsubroutineLen,
2687 register Uint32* TcurrentProgram= mainProgram;
2688 register Uint32 TcurrentSize= TmainProgLen;
2689 register Uint32 RnoOfInstructions= 0;
2690 register Uint32 TprogramCounter= 0;
2691 register Uint32 theInstruction;
2692 register Uint32 theRegister;
2693 Uint32 TdataWritten= 0;
2694 Uint32 RstackPtr= 0;
2696 Uint32 TregMemBuffer[32];
2700 Uint32 TstackMemBuffer[32];
2708 TregMemBuffer[0]= 0;
2709 TregMemBuffer[4]= 0;
2710 TregMemBuffer[8]= 0;
2711 TregMemBuffer[12]= 0;
2712 TregMemBuffer[16]= 0;
2713 TregMemBuffer[20]= 0;
2714 TregMemBuffer[24]= 0;
2715 TregMemBuffer[28]= 0;
2716 Uint32 tmpHabitant= ~0;
2718 while (RnoOfInstructions < 8000) {
2722 RnoOfInstructions++;
2723 theInstruction= TcurrentProgram[TprogramCounter];
2724 theRegister= Interpreter::getReg1(theInstruction) << 2;
2725 #ifdef TRACE_INTERPRETER
2726 ndbout_c(
"Interpreter : RnoOfInstructions : %u. TprogramCounter : %u. Opcode : %u",
2729 if (TprogramCounter < TcurrentSize) {
2732 case Interpreter::READ_ATTR_INTO_REG:
2740 Uint32 theAttrinfo= theInstruction;
2741 int TnoDataRW= readAttributes(req_struct,
2744 &TregMemBuffer[theRegister],
2747 if (TnoDataRW == 2) {
2752 TregMemBuffer[theRegister]= 0x50;
2754 * (Int64*)(TregMemBuffer+theRegister+2)= TregMemBuffer[theRegister+1];
2755 }
else if (TnoDataRW == 3) {
2760 TregMemBuffer[theRegister]= 0x60;
2761 TregMemBuffer[theRegister+3]= TregMemBuffer[theRegister+2];
2762 TregMemBuffer[theRegister+2]= TregMemBuffer[theRegister+1];
2763 }
else if (TnoDataRW == 1) {
2768 TregMemBuffer[theRegister]= 0;
2769 TregMemBuffer[theRegister + 2]= 0;
2770 TregMemBuffer[theRegister + 3]= 0;
2771 }
else if (TnoDataRW < 0) {
2773 terrorCode = Uint32(-TnoDataRW);
2774 tupkeyErrorLab(req_struct);
2786 case Interpreter::WRITE_ATTR_FROM_REG:
2789 Uint32 TattrId= theInstruction >> 16;
2790 Uint32 TattrDescrIndex= req_struct->tablePtrP->tabDescriptor +
2791 (TattrId << ZAD_LOG_SIZE);
2792 Uint32 TattrDesc1= tableDescriptor[TattrDescrIndex].tabDescr;
2793 Uint32 TregType= TregMemBuffer[theRegister];
2800 Uint32 TattrNoOfWords = AttributeDescriptor::getSizeInWords(TattrDesc1);
2801 Uint32 Toptype = req_struct->operPtrP->op_struct.op_type;
2802 Uint32 TdataForUpdate[3];
2806 TdataForUpdate[0]= ah.m_value;
2807 TdataForUpdate[1]= TregMemBuffer[theRegister + 2];
2808 TdataForUpdate[2]= TregMemBuffer[theRegister + 3];
2809 Tlen= TattrNoOfWords + 1;
2810 if (Toptype == ZUPDATE) {
2811 if (TattrNoOfWords <= 2) {
2812 if (TattrNoOfWords == 1) {
2814 Int64 * tmp =
new (&TregMemBuffer[theRegister + 2]) Int64;
2815 TdataForUpdate[1] = Uint32(* tmp);
2816 TdataForUpdate[2] = 0;
2818 if (TregType == 0) {
2823 TdataForUpdate[0]= ah.m_value;
2826 int TnoDataRW= updateAttributes(req_struct,
2829 if (TnoDataRW >= 0) {
2834 logMemory[TdataWritten + 0]= TdataForUpdate[0];
2835 logMemory[TdataWritten + 1]= TdataForUpdate[1];
2836 logMemory[TdataWritten + 2]= TdataForUpdate[2];
2837 TdataWritten += Tlen;
2839 terrorCode = Uint32(-TnoDataRW);
2840 tupkeyErrorLab(req_struct);
2844 return TUPKEY_abort(req_struct, 15);
2847 return TUPKEY_abort(req_struct, 16);
2852 case Interpreter::LOAD_CONST_NULL:
2854 TregMemBuffer[theRegister]= 0;
2857 case Interpreter::LOAD_CONST16:
2859 TregMemBuffer[theRegister]= 0x50;
2860 * (Int64*)(TregMemBuffer+theRegister+2)= theInstruction >> 16;
2863 case Interpreter::LOAD_CONST32:
2865 TregMemBuffer[theRegister]= 0x50;
2866 * (Int64*)(TregMemBuffer+theRegister+2)= *
2867 (TcurrentProgram+TprogramCounter);
2871 case Interpreter::LOAD_CONST64:
2873 TregMemBuffer[theRegister]= 0x60;
2874 TregMemBuffer[theRegister + 2 ]= * (TcurrentProgram +
2876 TregMemBuffer[theRegister + 3 ]= * (TcurrentProgram +
2880 case Interpreter::ADD_REG_REG:
2883 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
2884 Uint32 TdestRegister= Interpreter::getReg3(theInstruction) << 2;
2886 Uint32 TrightType= TregMemBuffer[TrightRegister];
2887 Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
2890 Uint32 TleftType= TregMemBuffer[theRegister];
2891 Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
2893 if ((TleftType | TrightType) != 0) {
2894 Uint64 Tdest0= Tleft0 + Tright0;
2895 * (Int64*)(TregMemBuffer+TdestRegister+2)= Tdest0;
2896 TregMemBuffer[TdestRegister]= 0x60;
2898 return TUPKEY_abort(req_struct, 20);
2903 case Interpreter::SUB_REG_REG:
2906 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
2907 Uint32 TdestRegister= Interpreter::getReg3(theInstruction) << 2;
2909 Uint32 TrightType= TregMemBuffer[TrightRegister];
2910 Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
2912 Uint32 TleftType= TregMemBuffer[theRegister];
2913 Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
2915 if ((TleftType | TrightType) != 0) {
2916 Int64 Tdest0= Tleft0 - Tright0;
2917 * (Int64*)(TregMemBuffer+TdestRegister+2)= Tdest0;
2918 TregMemBuffer[TdestRegister]= 0x60;
2920 return TUPKEY_abort(req_struct, 20);
2925 case Interpreter::BRANCH:
2926 TprogramCounter= brancher(theInstruction, TprogramCounter);
2929 case Interpreter::BRANCH_REG_EQ_NULL:
2930 if (TregMemBuffer[theRegister] != 0) {
2935 TprogramCounter= brancher(theInstruction, TprogramCounter);
2939 case Interpreter::BRANCH_REG_NE_NULL:
2940 if (TregMemBuffer[theRegister] == 0) {
2945 TprogramCounter= brancher(theInstruction, TprogramCounter);
2950 case Interpreter::BRANCH_EQ_REG_REG:
2952 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
2954 Uint32 TleftType= TregMemBuffer[theRegister];
2955 Uint32 Tleft0= TregMemBuffer[theRegister + 2];
2956 Uint32 Tleft1= TregMemBuffer[theRegister + 3];
2958 Uint32 TrightType= TregMemBuffer[TrightRegister];
2959 Uint32 Tright0= TregMemBuffer[TrightRegister + 2];
2960 Uint32 Tright1= TregMemBuffer[TrightRegister + 3];
2961 if ((TrightType | TleftType) != 0) {
2963 if ((Tleft0 == Tright0) && (Tleft1 == Tright1)) {
2964 TprogramCounter= brancher(theInstruction, TprogramCounter);
2967 return TUPKEY_abort(req_struct, 23);
2972 case Interpreter::BRANCH_NE_REG_REG:
2974 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
2976 Uint32 TleftType= TregMemBuffer[theRegister];
2977 Uint32 Tleft0= TregMemBuffer[theRegister + 2];
2978 Uint32 Tleft1= TregMemBuffer[theRegister + 3];
2980 Uint32 TrightType= TregMemBuffer[TrightRegister];
2981 Uint32 Tright0= TregMemBuffer[TrightRegister + 2];
2982 Uint32 Tright1= TregMemBuffer[TrightRegister + 3];
2983 if ((TrightType | TleftType) != 0) {
2985 if ((Tleft0 != Tright0) || (Tleft1 != Tright1)) {
2986 TprogramCounter= brancher(theInstruction, TprogramCounter);
2989 return TUPKEY_abort(req_struct, 24);
2994 case Interpreter::BRANCH_LT_REG_REG:
2996 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
2998 Uint32 TrightType= TregMemBuffer[TrightRegister];
2999 Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
3001 Uint32 TleftType= TregMemBuffer[theRegister];
3002 Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
3005 if ((TrightType | TleftType) != 0) {
3007 if (Tleft0 < Tright0) {
3008 TprogramCounter= brancher(theInstruction, TprogramCounter);
3011 return TUPKEY_abort(req_struct, 24);
3016 case Interpreter::BRANCH_LE_REG_REG:
3018 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
3020 Uint32 TrightType= TregMemBuffer[TrightRegister];
3021 Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
3023 Uint32 TleftType= TregMemBuffer[theRegister];
3024 Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
3027 if ((TrightType | TleftType) != 0) {
3029 if (Tleft0 <= Tright0) {
3030 TprogramCounter= brancher(theInstruction, TprogramCounter);
3033 return TUPKEY_abort(req_struct, 26);
3038 case Interpreter::BRANCH_GT_REG_REG:
3040 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
3042 Uint32 TrightType= TregMemBuffer[TrightRegister];
3043 Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
3045 Uint32 TleftType= TregMemBuffer[theRegister];
3046 Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
3049 if ((TrightType | TleftType) != 0) {
3051 if (Tleft0 > Tright0){
3052 TprogramCounter= brancher(theInstruction, TprogramCounter);
3055 return TUPKEY_abort(req_struct, 27);
3060 case Interpreter::BRANCH_GE_REG_REG:
3062 Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
3064 Uint32 TrightType= TregMemBuffer[TrightRegister];
3065 Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
3067 Uint32 TleftType= TregMemBuffer[theRegister];
3068 Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
3071 if ((TrightType | TleftType) != 0) {
3073 if (Tleft0 >= Tright0){
3074 TprogramCounter= brancher(theInstruction, TprogramCounter);
3077 return TUPKEY_abort(req_struct, 28);
3082 case Interpreter::BRANCH_ATTR_OP_ARG_2:
3083 case Interpreter::BRANCH_ATTR_OP_ARG:{
3085 Uint32 cond = Interpreter::getBinaryCondition(theInstruction);
3086 Uint32 ins2 = TcurrentProgram[TprogramCounter];
3087 Uint32 attrId = Interpreter::getBranchCol_AttrId(ins2) << 16;
3088 Uint32 argLen = Interpreter::getBranchCol_Len(ins2);
3089 Uint32 step = argLen;
3091 if(tmpHabitant != attrId){
3092 Int32 TnoDataR = readAttributes(req_struct,
3099 terrorCode = Uint32(-TnoDataR);
3100 tupkeyErrorLab(req_struct);
3103 tmpHabitant= attrId;
3108 Uint32 TattrDescrIndex = req_struct->tablePtrP->tabDescriptor +
3109 (attrId << ZAD_LOG_SIZE);
3110 Uint32 TattrDesc1 = tableDescriptor[TattrDescrIndex].tabDescr;
3111 Uint32 TattrDesc2 = tableDescriptor[TattrDescrIndex+1].tabDescr;
3114 if(AttributeOffset::getCharsetFlag(TattrDesc2))
3116 Uint32 pos = AttributeOffset::getCharsetPos(TattrDesc2);
3117 cs = req_struct->tablePtrP->charsetArray[pos];
3123 const char* s1 = (
char*)&tmpArea[1];
3124 const char* s2 = (
char*)&TcurrentProgram[TprogramCounter+1];
3126 Uint32 attrLen = AttributeDescriptor::getSizeInBytes(TattrDesc1);
3129 Interpreter::BRANCH_ATTR_OP_ARG_2)
3132 Uint32 paramNo = Interpreter::getBranchCol_ParamNo(ins2);
3133 const Uint32 * paramptr = lookupInterpreterParameter(paramNo,
3136 if (unlikely(paramptr == 0))
3140 tupkeyErrorLab(req_struct);
3144 argLen = AttributeHeader::getByteSize(* paramptr);
3146 s2 = (
char*)(paramptr + 1);
3149 if (typeId == NDB_TYPE_BIT)
3154 Uint32 bitFieldAttrLen= (AttributeDescriptor::getArraySize(TattrDesc1)
3156 attrLen= bitFieldAttrLen;
3159 bool r1_null = ah.isNULL();
3160 bool r2_null = argLen == 0;
3162 if (cond <= Interpreter::GE)
3165 if (r1_null || r2_null) {
3167 res1 = r1_null && r2_null ? 0 : r1_null ? -1 : 1;
3170 if (unlikely(sqlType.m_cmp == 0))
3172 return TUPKEY_abort(req_struct, 40);
3174 res1 = (*sqlType.m_cmp)(cs, s1, attrLen, s2, argLen);
3177 if ((cond == Interpreter::LIKE) ||
3178 (cond == Interpreter::NOT_LIKE))
3180 if (r1_null || r2_null) {
3182 res1 = r1_null && r2_null ? 0 : -1;
3185 if (unlikely(sqlType.m_like == 0))
3187 return TUPKEY_abort(req_struct, 40);
3189 res1 = (*sqlType.m_like)(cs, s1, attrLen, s2, argLen);
3195 ndbassert(cond <= Interpreter::AND_NE_ZERO);
3196 if (unlikely(sqlType.m_mask == 0))
3198 return TUPKEY_abort(req_struct,40);
3203 if (r1_null || r2_null) {
3208 (cond == Interpreter::AND_EQ_ZERO) ||
3209 (cond == Interpreter::AND_NE_ZERO);
3211 res1 = (*sqlType.m_mask)(s1, attrLen, s2, argLen, cmpZero);
3217 switch ((Interpreter::BinaryCondition)cond) {
3218 case Interpreter::EQ:
3221 case Interpreter::NE:
3225 case Interpreter::LT:
3228 case Interpreter::LE:
3231 case Interpreter::GT:
3234 case Interpreter::GE:
3237 case Interpreter::LIKE:
3240 case Interpreter::NOT_LIKE:
3243 case Interpreter::AND_EQ_MASK:
3246 case Interpreter::AND_NE_MASK:
3249 case Interpreter::AND_EQ_ZERO:
3252 case Interpreter::AND_NE_ZERO:
3257 #ifdef TRACE_INTERPRETER
3258 ndbout_c(
"cond=%u attr(%d)='%.*s'(%d) str='%.*s'(%d) res1=%d res=%d",
3260 attrLen, s1, attrLen, argLen, s2, argLen, res1, res);
3263 TprogramCounter = brancher(theInstruction, TprogramCounter);
3266 Uint32 tmp = ((step + 3) >> 2) + 1;
3267 TprogramCounter += tmp;
3272 case Interpreter::BRANCH_ATTR_EQ_NULL:{
3274 Uint32 ins2= TcurrentProgram[TprogramCounter];
3275 Uint32 attrId= Interpreter::getBranchCol_AttrId(ins2) << 16;
3277 if (tmpHabitant != attrId){
3278 Int32 TnoDataR= readAttributes(req_struct,
3285 terrorCode = Uint32(-TnoDataR);
3286 tupkeyErrorLab(req_struct);
3289 tmpHabitant= attrId;
3294 TprogramCounter= brancher(theInstruction, TprogramCounter);
3301 case Interpreter::BRANCH_ATTR_NE_NULL:{
3303 Uint32 ins2= TcurrentProgram[TprogramCounter];
3304 Uint32 attrId= Interpreter::getBranchCol_AttrId(ins2) << 16;
3306 if (tmpHabitant != attrId){
3307 Int32 TnoDataR= readAttributes(req_struct,
3314 terrorCode = Uint32(-TnoDataR);
3315 tupkeyErrorLab(req_struct);
3318 tmpHabitant= attrId;
3325 TprogramCounter= brancher(theInstruction, TprogramCounter);
3330 case Interpreter::EXIT_OK:
3332 #ifdef TRACE_INTERPRETER
3333 ndbout_c(
" - exit_ok");
3335 return TdataWritten;
3337 case Interpreter::EXIT_OK_LAST:
3339 #ifdef TRACE_INTERPRETER
3340 ndbout_c(
" - exit_ok_last");
3342 req_struct->last_row=
true;
3343 return TdataWritten;
3345 case Interpreter::EXIT_REFUSE:
3347 #ifdef TRACE_INTERPRETER
3348 ndbout_c(
" - exit_nok");
3350 terrorCode= theInstruction >> 16;
3351 return TUPKEY_abort(req_struct, 29);
3353 case Interpreter::CALL:
3355 #ifdef TRACE_INTERPRETER
3356 ndbout_c(
" - call addr=%u, subroutine len=%u ret addr=%u",
3357 theInstruction >> 16, TsubroutineLen, TprogramCounter);
3360 if (RstackPtr < 32) {
3361 TstackMemBuffer[RstackPtr]= TprogramCounter;
3362 TprogramCounter= theInstruction >> 16;
3363 if (TprogramCounter < TsubroutineLen) {
3364 TcurrentProgram= subroutineProg;
3365 TcurrentSize= TsubroutineLen;
3367 return TUPKEY_abort(req_struct, 30);
3370 return TUPKEY_abort(req_struct, 31);
3374 case Interpreter::RETURN:
3376 #ifdef TRACE_INTERPRETER
3377 ndbout_c(
" - return to %u from stack level %u",
3378 TstackMemBuffer[RstackPtr],
3381 if (RstackPtr > 0) {
3382 TprogramCounter= TstackMemBuffer[RstackPtr];
3384 if (RstackPtr == 0) {
3389 TcurrentProgram= mainProgram;
3390 TcurrentSize= TmainProgLen;
3393 return TUPKEY_abort(req_struct, 32);
3398 return TUPKEY_abort(req_struct, 33);
3401 return TUPKEY_abort(req_struct, 34);
3404 return TUPKEY_abort(req_struct, 35);
3420 const Uint32 * tabDesc,
3421 const Uint16* order)
3423 char* dst_ptr= dst->m_data_ptr;
3424 Uint32 no_attr= dst->m_var_len_offset;
3425 Uint16* dst_off_ptr= dst->m_offset_array_ptr;
3426 Uint16* dst_len_ptr= dst_off_ptr + no_attr;
3427 const Uint16* src_off_ptr= (
const Uint16*)src;
3428 const char* src_ptr= (
const char*)(src_off_ptr + no_attr + 1);
3430 Uint16 tmp= *src_off_ptr++, next_pos, len, max_len, dst_off= 0;
3431 for(Uint32 i = 0; i<no_attr; i++)
3433 next_pos= *src_off_ptr++;
3434 len= next_pos - tmp;
3436 *dst_off_ptr++ = dst_off;
3437 *dst_len_ptr++ = dst_off + len;
3438 memcpy(dst_ptr, src_ptr, len);
3441 max_len= AttributeDescriptor::getSizeInBytes(tabDesc[* order++]);
3448 return ALIGN_WORD(dst_ptr);
3452 Dbtup::expand_tuple(KeyReqStruct* req_struct,
3455 const Tablerec* tabPtrP,
3458 Uint32 bits= src->m_header_bits;
3459 Uint32 extra_bits = bits;
3460 Tuple_header* ptr= req_struct->m_tuple_ptr;
3462 Uint16 dd_tot= tabPtrP->m_no_of_disk_attributes;
3463 Uint16 mm_vars= tabPtrP->m_attributes[MM].m_no_of_varsize;
3464 Uint16 mm_dynvar= tabPtrP->m_attributes[MM].m_no_of_dyn_var;
3465 Uint16 mm_dynfix= tabPtrP->m_attributes[MM].m_no_of_dyn_fix;
3466 Uint16 mm_dyns= tabPtrP->m_attributes[MM].m_no_of_dynamic;
3467 Uint32 fix_size= tabPtrP->m_offsets[MM].m_fix_header_size;
3468 Uint32 order_desc= tabPtrP->m_real_order_descriptor;
3470 Uint32 *dst_ptr= ptr->get_end_of_fix_part_ptr(tabPtrP);
3471 const Uint32 *disk_ref= src->get_disk_ref_ptr(tabPtrP);
3472 const Uint32 *src_ptr= src->get_end_of_fix_part_ptr(tabPtrP);
3473 const Var_part_ref* var_ref = src->get_var_part_ref_ptr(tabPtrP);
3474 const Uint32 *desc= (Uint32*)req_struct->attr_descr;
3475 const Uint16 *order = (Uint16*)(&tableDescriptor[order_desc]);
3476 order += tabPtrP->m_attributes[MM].m_no_of_fixsize;
3480 memcpy(ptr, src, 4*fix_size);
3481 if(mm_vars || mm_dyns)
3487 dst_ptr += Varpart_copy::SZ32;
3489 KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
3492 const Uint32 *src_data;
3493 if (bits & Tuple_header::VAR_PART)
3495 KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
3496 if(! (bits & Tuple_header::COPY_TUPLE))
3500 src_data= get_ptr(&var_page, *var_ref);
3501 src_len= get_len(&var_page, *var_ref);
3504 req_struct->m_varpart_page_ptr = var_page;
3508 ndbassert(! (bits & Tuple_header::MM_GROWN));
3514 Varpart_copy* vp = (Varpart_copy*)src_ptr;
3515 src_len = vp->m_len;
3516 src_data= vp->m_data;
3517 step= (Varpart_copy::SZ32 + src_len);
3518 req_struct->m_varpart_page_ptr = req_struct->m_page_ptr;
3524 dst->m_data_ptr= (
char*)(((Uint16*)dst_ptr)+mm_vars+1);
3525 dst->m_offset_array_ptr= req_struct->var_pos_array;
3526 dst->m_var_len_offset= mm_vars;
3527 dst->m_max_var_offset= tabPtrP->m_offsets[MM].m_max_var_offset;
3529 dst_ptr= expand_var_part(dst, src_data, desc, order);
3530 ndbassert(dst_ptr == ALIGN_WORD(dst->m_data_ptr + dst->m_max_var_offset));
3534 char* varstart = (
char*)(((Uint16*)src_data)+mm_vars+1);
3535 Uint32 varlen = ((Uint16*)src_data)[mm_vars];
3536 Uint32 *dynstart = ALIGN_WORD(varstart + varlen);
3538 ndbassert(src_len >= (dynstart - src_data));
3539 src_len -= Uint32(dynstart - src_data);
3540 src_data = dynstart;
3548 ndbassert(mm_vars == 0);
3549 src_len = step = sizes[MM] = 0;
3558 dst->m_dyn_offset_arr_ptr= req_struct->var_pos_array+2*mm_vars;
3559 dst->m_dyn_len_offset= mm_dynvar+mm_dynfix;
3560 dst->m_max_dyn_offset= tabPtrP->m_offsets[MM].m_max_dyn_offset;
3561 dst->m_dyn_data_ptr= (
char*)dst_ptr;
3562 dst_ptr= expand_dyn_part(dst, src_data,
3564 desc, order + mm_vars,
3565 mm_dynvar, mm_dynfix,
3566 tabPtrP->m_offsets[MM].m_dyn_null_words);
3569 ndbassert((UintPtr(src_ptr) & 3) == 0);
3570 src_ptr = src_ptr + step;
3573 src->m_header_bits= bits &
3574 ~(Uint32)(Tuple_header::MM_SHRINK | Tuple_header::MM_GROWN);
3579 const Uint16 dd_vars= tabPtrP->m_attributes[DD].m_no_of_varsize;
3580 order+= mm_vars+mm_dynvar+mm_dynfix;
3582 if(bits & Tuple_header::DISK_INLINE)
3585 ndbassert(bits & Tuple_header::COPY_TUPLE);
3590 memcpy(&key, disk_ref,
sizeof(key));
3591 key.m_page_no= req_struct->m_disk_page_ptr.i;
3592 src_ptr= get_dd_ptr(&req_struct->m_disk_page_ptr, &key, tabPtrP);
3594 extra_bits |= Tuple_header::DISK_INLINE;
3597 req_struct->m_disk_ptr= (Tuple_header*)dst_ptr;
3598 memcpy(dst_ptr, src_ptr, 4*tabPtrP->m_offsets[DD].m_fix_header_size);
3599 sizes[DD] = tabPtrP->m_offsets[DD].m_fix_header_size;
3601 ndbassert(! (req_struct->m_disk_ptr->m_header_bits & Tuple_header::FREE));
3603 ndbrequire(dd_vars == 0);
3606 ptr->m_header_bits= (extra_bits | Tuple_header::COPY_TUPLE);
3607 req_struct->is_expanded=
true;
3611 Dbtup::dump_tuple(
const KeyReqStruct* req_struct,
const Tablerec* tabPtrP)
3613 Uint16 mm_vars= tabPtrP->m_attributes[MM].m_no_of_varsize;
3614 Uint16 mm_dyns= tabPtrP->m_attributes[MM].m_no_of_dynamic;
3616 const Tuple_header* ptr= req_struct->m_tuple_ptr;
3617 Uint32 bits= ptr->m_header_bits;
3618 const Uint32 *tuple_words= (Uint32 *)ptr;
3619 const Uint32 *fix_p;
3621 const Uint32 *var_p;
3628 fix_len= tabPtrP->m_offsets[MM].m_fix_header_size;
3629 if(req_struct->is_expanded)
3632 var_p= ptr->get_end_of_fix_part_ptr(tabPtrP);
3635 disk_p= (Uint32 *)req_struct->m_disk_ptr;
3636 disk_len= (dd_tot ? tabPtrP->m_offsets[DD].m_fix_header_size : 0);
3639 else if(! (bits & Tuple_header::COPY_TUPLE))
3645 const Var_part_ref *varref= ptr->get_var_part_ref_ptr(tabPtrP);
3647 var_p= get_ptr(&tmp, * varref);
3648 var_len= get_len(&tmp, * varref);
3659 memcpy(&key, ptr->get_disk_ref_ptr(tabPtrP),
sizeof(key));
3660 key.m_page_no= req_struct->m_disk_page_ptr.i;
3661 disk_p= get_dd_ptr(&req_struct->m_disk_page_ptr, &key, tabPtrP);
3662 disk_len= tabPtrP->m_offsets[DD].m_fix_header_size;
3676 var_p= ptr->get_end_of_fix_part_ptr(tabPtrP);
3677 var_len= *((Uint16 *)var_p) + 1;
3685 disk_p= (Uint32 *)(req_struct->m_disk_ptr);
3686 disk_len= (dd_tot ? tabPtrP->m_offsets[DD].m_fix_header_size : 0);
3689 ndbout_c(
"Fixed part[%s](%p len=%u words)",typ, fix_p, fix_len);
3690 dump_hex(fix_p, fix_len);
3691 ndbout_c(
"Varpart part[%s](%p len=%u words)", typ , var_p, var_len);
3692 dump_hex(var_p, var_len);
3694 ndbout_c(
"Disk part[%s](%p len=%u words)", typ, disk_p, disk_len);
3695 dump_hex(disk_p, disk_len);
3700 Dbtup::prepare_read(KeyReqStruct* req_struct,
3701 Tablerec* tabPtrP,
bool disk)
3703 Tuple_header* ptr= req_struct->m_tuple_ptr;
3705 Uint32 bits= ptr->m_header_bits;
3706 Uint16 dd_tot= tabPtrP->m_no_of_disk_attributes;
3707 Uint16 mm_vars= tabPtrP->m_attributes[MM].m_no_of_varsize;
3708 Uint16 mm_dyns= tabPtrP->m_attributes[MM].m_no_of_dynamic;
3710 const Uint32 *src_ptr= ptr->get_end_of_fix_part_ptr(tabPtrP);
3711 const Uint32 *disk_ref= ptr->get_disk_ref_ptr(tabPtrP);
3712 const Var_part_ref* var_ref = ptr->get_var_part_ref_ptr(tabPtrP);
3713 if(mm_vars || mm_dyns)
3715 const Uint32 *src_data= src_ptr;
3717 KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
3718 if (bits & Tuple_header::VAR_PART)
3720 if(! (bits & Tuple_header::COPY_TUPLE))
3723 src_data= get_ptr(&tmp, * var_ref);
3724 src_len= get_len(&tmp, * var_ref);
3728 if(bits & Tuple_header::MM_GROWN)
3734 ndbassert(src_len>0);
3735 src_len= src_data[src_len-1];
3740 Varpart_copy* vp = (Varpart_copy*)src_ptr;
3741 src_len = vp->m_len;
3742 src_data = vp->m_data;
3748 const Uint32* dynstart;
3751 varstart = (
char*)(((Uint16*)src_data)+mm_vars+1);
3752 varlen = ((Uint16*)src_data)[mm_vars];
3753 dynstart = ALIGN_WORD(varstart + varlen);
3759 dynstart = src_data;
3762 dst->m_data_ptr= varstart;
3763 dst->m_offset_array_ptr= (Uint16*)src_data;
3764 dst->m_var_len_offset= 1;
3765 dst->m_max_var_offset= varlen;
3767 Uint32 dynlen = Uint32(src_len - (dynstart - src_data));
3768 ndbassert(src_len >= (dynstart - src_data));
3769 dst->m_dyn_data_ptr= (
char*)dynstart;
3770 dst->m_dyn_part_len= dynlen;
3782 dst->m_max_var_offset = 0;
3783 dst->m_dyn_part_len = 0;
3784 #if defined VM_TRACE || defined ERROR_INSERT
3785 bzero(dst,
sizeof(* dst));
3795 const Uint16 dd_vars= tabPtrP->m_attributes[DD].m_no_of_varsize;
3797 if(bits & Tuple_header::DISK_INLINE)
3800 ndbassert(bits & Tuple_header::COPY_TUPLE);
3806 memcpy(&key, disk_ref,
sizeof(key));
3807 key.m_page_no= req_struct->m_disk_page_ptr.i;
3808 src_ptr= get_dd_ptr(&req_struct->m_disk_page_ptr, &key, tabPtrP);
3811 req_struct->m_disk_ptr= (Tuple_header*)src_ptr;
3812 ndbassert(! (req_struct->m_disk_ptr->m_header_bits & Tuple_header::FREE));
3813 ndbrequire(dd_vars == 0);
3816 req_struct->is_expanded=
false;
3820 Dbtup::shrink_tuple(KeyReqStruct* req_struct, Uint32 sizes[2],
3821 const Tablerec* tabPtrP,
bool disk)
3823 ndbassert(tabPtrP->need_shrink());
3824 Tuple_header* ptr= req_struct->m_tuple_ptr;
3825 ndbassert(ptr->m_header_bits & Tuple_header::COPY_TUPLE);
3827 KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
3828 Uint32 order_desc= tabPtrP->m_real_order_descriptor;
3829 const Uint32 * tabDesc= (Uint32*)req_struct->attr_descr;
3830 const Uint16 *order = (Uint16*)(&tableDescriptor[order_desc]);
3831 Uint16 dd_tot= tabPtrP->m_no_of_disk_attributes;
3832 Uint16 mm_fix= tabPtrP->m_attributes[MM].m_no_of_fixsize;
3833 Uint16 mm_vars= tabPtrP->m_attributes[MM].m_no_of_varsize;
3834 Uint16 mm_dyns= tabPtrP->m_attributes[MM].m_no_of_dynamic;
3835 Uint16 mm_dynvar= tabPtrP->m_attributes[MM].m_no_of_dyn_var;
3836 Uint16 mm_dynfix= tabPtrP->m_attributes[MM].m_no_of_dyn_fix;
3837 Uint16 dd_vars= tabPtrP->m_attributes[DD].m_no_of_varsize;
3839 Uint32 *dst_ptr= ptr->get_end_of_fix_part_ptr(tabPtrP);
3840 Uint16* src_off_ptr= req_struct->var_pos_array;
3845 if(mm_vars || mm_dyns)
3847 Varpart_copy* vp = (Varpart_copy*)dst_ptr;
3848 Uint32* varstart = dst_ptr = vp->m_data;
3852 Uint16* dst_off_ptr= (Uint16*)dst_ptr;
3853 char* dst_data_ptr= (
char*)(dst_off_ptr + mm_vars + 1);
3854 char* src_data_ptr= dst_data_ptr;
3856 for(Uint32 i= 0; i<mm_vars; i++)
3858 const char* data_ptr= src_data_ptr + *src_off_ptr;
3859 Uint32 len= src_off_ptr[mm_vars] - *src_off_ptr;
3860 * dst_off_ptr++= off;
3861 memmove(dst_data_ptr, data_ptr, len);
3864 dst_data_ptr += len;
3867 dst_ptr = ALIGN_WORD(dst_data_ptr);
3873 dst_ptr = shrink_dyn_part(dst, dst_ptr, tabPtrP, tabDesc,
3874 order, mm_dynvar, mm_dynfix, MM);
3875 ndbassert((
char*)dst_ptr <= ((
char*)ptr) + 8192);
3876 order += mm_dynfix + mm_dynvar;
3879 Uint32 varpart_len= Uint32(dst_ptr - varstart);
3880 vp->m_len = varpart_len;
3881 sizes[MM] = varpart_len;
3882 ptr->m_header_bits |= (varpart_len) ? Tuple_header::VAR_PART : 0;
3884 ndbassert((UintPtr(ptr) & 3) == 0);
3885 ndbassert(varpart_len < 0x10000);
3890 Uint32 * src_ptr = (Uint32*)req_struct->m_disk_ptr;
3891 req_struct->m_disk_ptr = (Tuple_header*)dst_ptr;
3892 ndbrequire(dd_vars == 0);
3893 sizes[DD] = tabPtrP->m_offsets[DD].m_fix_header_size;
3894 memmove(dst_ptr, src_ptr, 4*tabPtrP->m_offsets[DD].m_fix_header_size);
3897 req_struct->is_expanded=
false;
3902 Dbtup::validate_page(Tablerec* regTabPtr, Var_page* p)
3905 Uint32 mm_vars= regTabPtr->m_attributes[MM].m_no_of_varsize;
3906 Uint32 fix_sz= regTabPtr->m_offsets[MM].m_fix_header_size +
3907 Tuple_header::HeaderSize;
3912 for(Uint32 F= 0; F<MAX_FRAG_PER_NODE; F++)
3914 FragrecordPtr fragPtr;
3916 if((fragPtr.i = regTabPtr->fragrec[F]) == RNIL)
3919 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
3920 for(Uint32 P= 0; P<fragPtr.p->noOfPages; P++)
3922 Uint32 real= getRealpid(fragPtr.p, P);
3923 Var_page*
page= (Var_page*)c_page_pool.
getPtr(real);
3925 for(Uint32 i=1; i<page->high_index; i++)
3927 Uint32 idx= page->get_index_word(i);
3928 Uint32 len = (idx & Var_page::LEN_MASK) >> Var_page::LEN_SHIFT;
3929 if(!(idx & Var_page::FREE) && !(idx & Var_page::CHAIN))
3931 Tuple_header *ptr= (Tuple_header*)page->get_ptr(i);
3932 Uint32 *part= ptr->get_end_of_fix_part_ptr(regTabPtr);
3933 if(! (ptr->m_header_bits & Tuple_header::COPY_TUPLE))
3935 ndbassert(len == fix_sz + 1);
3938 part= get_ptr(&tmpPage, *(Var_part_ref*)part);
3939 len= ((Var_page*)tmpPage.p)->get_entry_len(tmp.m_page_idx);
3940 Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)part)[mm_vars]);
3941 ndbassert(len >= ((sz + 3) >> 2));
3945 Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)part)[mm_vars]);
3946 ndbassert(len >= ((sz+3)>>2)+fix_sz);
3948 if(ptr->m_operation_ptr_i != RNIL)
3950 c_operation_pool.
getPtr(ptr->m_operation_ptr_i);
3953 else if(!(idx & Var_page::FREE))
3958 Uint32 *part= page->get_ptr(i);
3959 Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)part)[mm_vars]);
3960 ndbassert(len >= ((sz + 3) >> 2));
3967 if(p == 0 && page->high_index > 1)
3968 page->reorg((Var_page*)ctemp_page);
3974 validate_page(regTabPtr, (Var_page*)1);
3979 Dbtup::handle_size_change_after_update(KeyReqStruct* req_struct,
3981 Operationrec* regOperPtr,
3982 Fragrecord* regFragPtr,
3983 Tablerec* regTabPtr,
3986 ndbrequire(sizes[1] == sizes[3]);
3989 printf(
"%p %d %d - handle_size_change_after_update ",
3990 req_struct->m_tuple_ptr,
3991 regOperPtr->m_tuple_location.m_page_no,
3992 regOperPtr->m_tuple_location.m_page_idx);
3994 Uint32 bits= org->m_header_bits;
3995 Uint32 copy_bits= req_struct->m_tuple_ptr->m_header_bits;
3997 if(sizes[2+MM] == sizes[MM])
3999 else if(sizes[2+MM] < sizes[MM])
4001 if(0) ndbout_c(
"shrink");
4002 req_struct->m_tuple_ptr->m_header_bits= copy_bits|Tuple_header::MM_SHRINK;
4006 if(0) printf(
"grow - ");
4007 Ptr<Page> pagePtr = req_struct->m_varpart_page_ptr;
4008 Var_page* pageP= (Var_page*)pagePtr.p;
4009 Var_part_ref *refptr= org->get_var_part_ref_ptr(regTabPtr);
4010 ndbassert(! (bits & Tuple_header::COPY_TUPLE));
4013 refptr->copyout(&ref);
4015 Uint32 idx= ref.m_page_idx;
4016 if (bits & Tuple_header::VAR_PART)
4018 if (copy_bits & Tuple_header::COPY_TUPLE)
4020 c_page_pool.
getPtr(pagePtr, ref.m_page_no);
4021 pageP = (Var_page*)pagePtr.p;
4023 alloc = pageP->get_entry_len(idx);
4029 Uint32 orig_size= alloc;
4030 if(bits & Tuple_header::MM_GROWN)
4033 Uint32 *old_var_part= pageP->get_ptr(idx);
4035 orig_size= old_var_part[alloc-1];
4041 if(!pageP->get_entry_chain(idx))
4042 ndbout << *pageP << endl;
4044 ndbassert(pageP->get_entry_chain(idx));
4047 Uint32 needed= sizes[2+MM];
4052 if (0) ndbout_c(
" no grow");
4055 Uint32 *new_var_part=realloc_var_part(&terrorCode,
4056 regFragPtr, regTabPtr, pagePtr,
4057 refptr, alloc, needed);
4058 if (unlikely(new_var_part==NULL))
4061 org->m_header_bits= bits | Tuple_header::MM_GROWN | Tuple_header::VAR_PART;
4062 new_var_part[needed-1]= orig_size;
4064 if (regTabPtr->m_bits & Tablerec::TR_Checksum)
4067 setChecksum(org, regTabPtr);
4074 Dbtup::optimize_var_part(KeyReqStruct* req_struct,
4076 Operationrec* regOperPtr,
4077 Fragrecord* regFragPtr,
4078 Tablerec* regTabPtr)
4081 Var_part_ref* refptr = org->get_var_part_ref_ptr(regTabPtr);
4084 refptr->copyout(&ref);
4085 Uint32 idx = ref.m_page_idx;
4088 c_page_pool.
getPtr(pagePtr, ref.m_page_no);
4090 Var_page* pageP = (Var_page*)pagePtr.p;
4091 Uint32 var_part_size = pageP->get_entry_len(idx);
4097 if(pageP->list_index != MAX_FREE_LIST)
4104 move_var_part(regFragPtr, regTabPtr, pagePtr,
4105 refptr, var_part_size);
4107 if (regTabPtr->m_bits & Tablerec::TR_Checksum)
4110 setChecksum(org, regTabPtr);
4118 Dbtup::nr_update_gci(Uint32 fragPtrI,
const Local_key* key, Uint32 gci)
4120 FragrecordPtr fragPtr;
4121 fragPtr.i= fragPtrI;
4122 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
4123 TablerecPtr tablePtr;
4124 tablePtr.i= fragPtr.p->fragTableId;
4125 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
4127 if (tablePtr.p->m_bits & Tablerec::TR_RowGCI)
4133 pagePtr.i = allocFragPage(&err, tablePtr.p, fragPtr.p, tmp.m_page_no);
4134 if (unlikely(pagePtr.i == RNIL))
4138 c_page_pool.
getPtr(pagePtr);
4140 Tuple_header* ptr = (Tuple_header*)
4141 ((Fix_page*)pagePtr.p)->get_ptr(tmp.m_page_idx, 0);
4143 ndbrequire(ptr->m_header_bits & Tuple_header::FREE);
4144 *ptr->get_mm_gci(tablePtr.p) = gci;
4150 Dbtup::nr_read_pk(Uint32 fragPtrI,
4151 const Local_key* key, Uint32* dst,
bool& copy)
4154 FragrecordPtr fragPtr;
4155 fragPtr.i= fragPtrI;
4156 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
4157 TablerecPtr tablePtr;
4158 tablePtr.i= fragPtr.p->fragTableId;
4159 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
4165 pagePtr.i = allocFragPage(&err, tablePtr.p, fragPtr.p, tmp.m_page_no);
4166 if (unlikely(pagePtr.i == RNIL))
4169 c_page_pool.
getPtr(pagePtr);
4170 KeyReqStruct req_struct(
this);
4171 Uint32* ptr= ((Fix_page*)pagePtr.p)->get_ptr(key->m_page_idx, 0);
4173 req_struct.m_page_ptr = pagePtr;
4174 req_struct.m_tuple_ptr = (Tuple_header*)ptr;
4175 Uint32 bits = req_struct.m_tuple_ptr->m_header_bits;
4179 if (! (bits & Tuple_header::FREE))
4181 if (bits & Tuple_header::ALLOC)
4183 Uint32 opPtrI= req_struct.m_tuple_ptr->m_operation_ptr_i;
4184 Operationrec* opPtrP= c_operation_pool.
getPtr(opPtrI);
4185 ndbassert(!opPtrP->m_copy_tuple_location.isNull());
4186 req_struct.m_tuple_ptr=
4187 get_copy_tuple(&opPtrP->m_copy_tuple_location);
4190 req_struct.check_offset[MM]= tablePtr.p->get_check_offset(MM);
4191 req_struct.check_offset[DD]= tablePtr.p->get_check_offset(DD);
4193 Uint32 num_attr= tablePtr.p->m_no_of_attributes;
4194 Uint32 descr_start= tablePtr.p->tabDescriptor;
4195 TableDescriptor *tab_descr= &tableDescriptor[descr_start];
4196 ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
4197 req_struct.attr_descr= tab_descr;
4199 if (tablePtr.p->need_expand())
4200 prepare_read(&req_struct, tablePtr.p,
false);
4202 const Uint32* attrIds= &tableDescriptor[tablePtr.p->readKeyArray].tabDescr;
4203 const Uint32 numAttrs= tablePtr.p->noOfKeyAttr;
4206 req_struct.tablePtrP = tablePtr.p;
4207 req_struct.fragPtrP = fragPtr.p;
4210 ret = readAttributes(&req_struct,
4217 if (likely(ret >= 0)) {
4221 while (n < numAttrs) {
4223 Uint32 size= ah.getDataSize();
4224 ndbrequire(size != 0);
4225 for (Uint32 j= 0; j <
size; j++) {
4226 dst[i + j -
n]= dst[i + j + 1];
4231 ndbrequire((
int)i == ret);
4238 if (tablePtr.p->m_bits & Tablerec::TR_RowGCI)
4240 dst[
ret] = *req_struct.m_tuple_ptr->get_mm_gci(tablePtr.p);
4249 #include <signaldata/TuxMaint.hpp>
4253 Uint32 fragPtrI,
const Local_key* key, Uint32 gci)
4256 fragPtr.i= fragPtrI;
4257 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
4259 tablePtr.i= fragPtr.p->fragTableId;
4260 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
4263 tmp.m_page_no= getRealpid(fragPtr.p, tmp.m_page_no);
4268 if (!tablePtr.p->tuxCustomTriggers.isEmpty())
4272 req->tableId = fragPtr.p->fragTableId;
4273 req->fragId = fragPtr.p->fragmentId;
4274 req->pageId = tmp.m_page_no;
4275 req->pageIndex = tmp.m_page_idx;
4276 req->tupVersion = ptr->get_tuple_version();
4277 req->opInfo = TuxMaintReq::OpRemove;
4278 removeTuxEntries(signal, tablePtr.p);
4282 memcpy(&disk, ptr->get_disk_ref_ptr(tablePtr.p),
sizeof(disk));
4284 if (tablePtr.p->m_attributes[MM].m_no_of_varsize +
4285 tablePtr.p->m_attributes[MM].m_no_of_dynamic)
4288 free_var_rec(fragPtr.p, tablePtr.p, &tmp, pagePtr);
4291 free_fix_rec(fragPtr.p, tablePtr.p, &tmp, (
Fix_page*)pagePtr.p);
4294 if (tablePtr.p->m_no_of_disk_attributes)
4299 tablePtr.p->m_offsets[DD].m_fix_header_size - 1;
4301 D(
"Logfile_client - nr_delete");
4302 Logfile_client lgman(
this, c_lgman, fragPtr.p->m_logfile_group_id);
4303 int res = lgman.alloc_log_space(sz);
4304 ndbrequire(res == 0);
4314 preq.m_callback.m_callbackData = senderData;
4315 preq.m_callback.m_callbackFunction =
4316 safe_cast(&Dbtup::nr_delete_page_callback);
4317 int flags = Page_cache_client::COMMIT_REQ;
4320 if (ERROR_INSERTED(4023) || ERROR_INSERTED(4024))
4322 int rnd = rand() % 100;
4324 if (ERROR_INSERTED(4024))
4337 ndbout_c(
"rnd: %d slp: %d", rnd, slp);
4341 flags |= Page_cache_client::DELAY_REQ;
4342 preq.m_delay_until_time = NdbTick_CurrentMillisecond()+(Uint64)slp;
4348 res = pgman.
get_page(signal, preq, flags);
4349 m_pgman_ptr = pgman.m_ptr;
4354 else if (unlikely(res == -1))
4360 disk_page_set_dirty(disk_page);
4363 cptr.m_callbackIndex = NR_DELETE_LOG_BUFFER_CALLBACK;
4364 cptr.m_callbackData = senderData;
4368 signal->theData[2] = disk_page.i;
4371 ndbrequire(
"NOT YET IMPLEMENTED" == 0);
4375 if (0) ndbout <<
"DIRECT DISK DELETE: " << disk << endl;
4376 disk_page_free(signal, tablePtr.p, fragPtr.p,
4377 &disk, *(
PagePtr*)&disk_page, gci);
4384 memcpy(signal->theData, &disk,
sizeof(disk));
4389 Dbtup::nr_delete_page_callback(
Signal* signal,
4390 Uint32 userpointer, Uint32 page_id)
4393 m_global_page_pool.
getPtr(gpage, page_id);
4394 PagePtr pagePtr= { (
Tup_page*)gpage.p, gpage.i };
4395 disk_page_set_dirty(pagePtr);
4397 op.m_ptr_i = userpointer;
4398 op.m_disk_ref.m_page_no = pagePtr.p->m_page_no;
4399 op.m_disk_ref.m_file_no = pagePtr.p->m_file_no;
4400 c_lqh->get_nr_op_info(&op, page_id);
4403 fragPtr.i= op.m_tup_frag_ptr_i;
4404 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
4407 tablePtr.i = fragPtr.p->fragTableId;
4408 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
4411 tablePtr.p->m_offsets[DD].m_fix_header_size - 1;
4414 cb.m_callbackData = userpointer;
4415 cb.m_callbackIndex = NR_DELETE_LOG_BUFFER_CALLBACK;
4416 D(
"Logfile_client - nr_delete_page_callback");
4417 Logfile_client lgman(
this, c_lgman, fragPtr.p->m_logfile_group_id);
4418 int res= lgman.get_log_buffer(signal, sz, &cb);
4423 ndbrequire(
"NOT YET IMPLEMENTED" == 0);
4427 if (0) ndbout <<
"PAGE CALLBACK DISK DELETE: " << op.m_disk_ref << endl;
4428 disk_page_free(signal, tablePtr.p, fragPtr.p,
4429 &op.m_disk_ref, pagePtr, op.m_gci_hi);
4441 op.m_ptr_i = userpointer;
4442 c_lqh->get_nr_op_info(&op, RNIL);
4445 fragPtr.i= op.m_tup_frag_ptr_i;
4446 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
4449 tablePtr.i = fragPtr.p->fragTableId;
4450 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
4453 m_global_page_pool.
getPtr(gpage, op.m_page_id);
4459 if (0) ndbout <<
"LOGBUFFER CALLBACK DISK DELETE: " << op.m_disk_ref << endl;
4461 disk_page_free(signal, tablePtr.p, fragPtr.p,
4462 &op.m_disk_ref, pagePtr, op.m_gci_hi);