20 #include <NdbBlob.hpp>
22 #include <Interpreter.hpp>
23 #include <NdbInterpretedCode.hpp>
24 #include <AttributeHeader.hpp>
25 #include <signaldata/TcKeyReq.hpp>
34 int tErrorLine = theErrorLine;
35 if (theStatus == Init) {
36 theStatus = OperationDefined;
38 tNdbCon->theSimpleState = 0;
39 theErrorLine = tErrorLine++;
55 int tErrorLine = theErrorLine;
56 if (theStatus == Init) {
57 theStatus = OperationDefined;
58 tNdbCon->theSimpleState = 0;
60 theErrorLine = tErrorLine++;
76 int tErrorLine = theErrorLine;
77 if (theStatus == Init) {
78 theStatus = OperationDefined;
79 tNdbCon->theSimpleState = 0;
81 theErrorLine = tErrorLine++;
97 int tErrorLine = theErrorLine;
98 if (theStatus == Init) {
99 theStatus = OperationDefined;
100 tNdbCon->theSimpleState = 0;
102 theErrorLine = tErrorLine++;
141 int tErrorLine = theErrorLine;
142 if (theStatus == Init) {
143 theStatus = OperationDefined;
144 tNdbCon->theSimpleState = 0;
146 theErrorLine = tErrorLine++;
163 int tErrorLine = theErrorLine;
164 if (theStatus == Init) {
165 theStatus = OperationDefined;
166 tNdbCon->theSimpleState = 0;
168 theErrorLine = tErrorLine++;
185 int tErrorLine = theErrorLine;
186 if (theStatus == Init) {
187 theStatus = OperationDefined;
189 theSimpleIndicator = 1;
190 theDirtyIndicator = 0;
191 theErrorLine = tErrorLine++;
194 tNdbCon->theSimpleState = 0;
217 int tErrorLine = theErrorLine;
218 if (theStatus == Init) {
219 theStatus = OperationDefined;
221 theSimpleIndicator = 1;
222 theDirtyIndicator = 1;
223 theErrorLine = tErrorLine++;
240 int tErrorLine = theErrorLine;
241 if (theStatus == Init) {
242 theStatus = OperationDefined;
244 tNdbCon->theSimpleState = 0;
245 theSimpleIndicator = 1;
246 theDirtyIndicator = 1;
247 theErrorLine = tErrorLine++;
264 int tErrorLine = theErrorLine;
265 if (theStatus == Init) {
266 theStatus = OperationDefined;
268 tNdbCon->theSimpleState = 0;
269 theSimpleIndicator = 1;
270 theDirtyIndicator = 1;
271 theErrorLine = tErrorLine++;
288 int tErrorLine = theErrorLine;
289 if (theStatus == Init) {
290 theStatus = OperationDefined;
291 tNdbCon->theSimpleState = 0;
293 theAI_LenInCurrAI = 25;
295 theErrorLine = tErrorLine++;
312 int tErrorLine = theErrorLine;
313 if (theStatus == Init) {
314 theStatus = OperationDefined;
315 tNdbCon->theSimpleState = 0;
318 theErrorLine = tErrorLine++;
319 theAI_LenInCurrAI = 25;
331 NdbOperation::setReadLockMode(LockMode lockMode)
338 theSimpleIndicator= 1;
339 theDirtyIndicator= 1;
343 theSimpleIndicator= 1;
344 theDirtyIndicator= 0;
347 theNdbCon->theSimpleState= 0;
349 theSimpleIndicator= 0;
350 theDirtyIndicator= 0;
353 theNdbCon->theSimpleState= 0;
355 theSimpleIndicator= 0;
356 theDirtyIndicator= 0;
362 theLockMode= lockMode;
376 NdbOperation::getValue_impl(
const NdbColumnImpl* tAttrInfo,
char* aValue)
379 if ((tAttrInfo != NULL) &&
380 (theStatus != Init)){
381 if (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK)
383 m_flags &= ~Uint8(OF_NO_DISK);
385 if (theStatus != GetValue) {
386 if (theStatus == UseNdbRecord)
388 return getValue_NdbRecord(tAttrInfo, aValue);
389 if (theInterpretIndicator == 1) {
390 if (theStatus == FinalGetValue) {
392 }
else if (theStatus == ExecInterpretedValue) {
393 if (insertATTRINFO(Interpreter::EXIT_OK) == -1)
395 theInterpretedSize = theTotalCurrAI_Len -
396 (theInitialReadSize + 5);
397 }
else if (theStatus == SetValueInterpreted) {
398 theFinalUpdateSize = theTotalCurrAI_Len -
399 (theInitialReadSize + theInterpretedSize + 5);
401 setErrorCodeAbort(4230);
405 theStatus = FinalGetValue;
407 setErrorCodeAbort(4230);
412 if (insertATTRINFO(ah.m_value) != -1) {
418 if((tRecAttr = theReceiver.getValue(tAttrInfo, aValue)) != 0){
422 setErrorCodeAbort(4000);
429 if (tAttrInfo == NULL) {
430 setErrorCodeAbort(4004);
434 setErrorCodeAbort(4200);
439 NdbOperation::getValue_NdbRecord(
const NdbColumnImpl* tAttrInfo,
char* aValue)
443 if (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK)
445 m_flags &= ~Uint8(OF_NO_DISK);
452 if((tRecAttr = theReceiver.getValue(tAttrInfo, aValue)) != 0) {
456 setErrorCodeAbort(4000);
474 const char* aValuePassed)
476 DBUG_ENTER(
"NdbOperation::setValue");
477 DBUG_PRINT(
"enter", (
"col: %s op:%d val: 0x%lx",
478 tAttrInfo ? tAttrInfo->m_name.
c_str() :
"NULL",
479 theOperationType, (long) aValuePassed));
484 Uint32 tempData[ NDB_MAX_TUPLE_SIZE_IN_WORDS ];
486 OperationStatus tStatus = theStatus;
491 if (theInterpretIndicator == 0) {
492 if (tStatus == SetValue) {
495 setErrorCodeAbort(4234);
499 if (tStatus == GetValue) {
500 theInitialReadSize = theTotalCurrAI_Len - 5;
501 }
else if (tStatus == ExecInterpretedValue) {
506 if (insertATTRINFO(Interpreter::EXIT_OK) == -1){
509 theInterpretedSize = theTotalCurrAI_Len -
510 (theInitialReadSize + 5);
511 }
else if (tStatus == SetValueInterpreted) {
517 setErrorCodeAbort(4234);
520 theStatus = SetValueInterpreted;
523 if ((theStatus != SetValue) && (theStatus != OperationDefined)) {
524 setErrorCodeAbort(4234);
528 setErrorCodeAbort(4504);
531 setErrorCodeAbort(4504);
534 setErrorCodeAbort(4228);
541 setErrorCodeAbort(4108);
544 if (tAttrInfo == NULL) {
545 setErrorCodeAbort(4004);
548 if (tAttrInfo->m_pk) {
550 DBUG_RETURN(equal_impl(tAttrInfo, aValuePassed));
552 setErrorCodeAbort(4202);
558 tAttrId = tAttrInfo->m_attrId;
559 if (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK)
561 m_flags &= ~Uint8(OF_NO_DISK);
563 const char *aValue = aValuePassed;
564 if (aValue == NULL) {
565 if (tAttrInfo->m_nullable) {
568 insertATTRINFO(ah.m_value);
576 setErrorCodeAbort(4203);
582 if (! tAttrInfo->get_var_length(aValue, len)) {
583 setErrorCodeAbort(4209);
587 const Uint32 sizeInBytes = len;
588 const Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ;
590 const int attributeSize = sizeInBytes;
591 const int slack = sizeInBytes & 3;
593 if (((UintPtr)aValue & 3) != 0 || (slack != 0)){
594 memcpy(&tempData[0], aValue, attributeSize);
595 aValue = (
char*)&tempData[0];
597 char * tmp = (
char*)&tempData[0];
598 memset(&tmp[attributeSize], 0, (4 - slack));
603 const Uint32 sizeInWords = sizeInBytes / 4;
605 insertATTRINFO( ah.m_value );
614 tReturnCode = insertATTRINFOloop((Uint32*)aValue, sizeInWords);
615 if (tReturnCode == -1) {
616 DBUG_RETURN(tReturnCode);
618 if (bitsInLastWord != 0) {
619 tData = *(Uint32*)(aValue + sizeInWords*4);
620 tData = convertEndian(tData);
621 tData = tData & ((1 << bitsInLastWord) - 1);
622 tData = convertEndian(tData);
623 tReturnCode = insertATTRINFO(tData);
624 if (tReturnCode == -1) {
625 DBUG_RETURN(tReturnCode);
634 NdbOperation::setAnyValue(Uint32 any_value)
638 if (theStatus == UseNdbRecord)
642 setErrorCodeAbort(4515);
647 &NdbColumnImpl::getImpl(* NdbDictionary::Column::ANY_VALUE);
653 if (insertATTRINFO(ah) != -1 && insertATTRINFO(any_value) != -1 )
659 return setValue(impl, (
const char *)&any_value);
662 setErrorCodeAbort(4000);
667 NdbOperation::setOptimize(Uint32 options)
669 return setValue(&NdbColumnImpl::getImpl(*NdbDictionary::Column::OPTIMIZE),
670 (
const char*)&options);
681 while (tBlob != NULL) {
682 if (tBlob->theColumn == tAttrInfo)
685 tBlob = tBlob->theNext;
696 if (m_attribute_record)
698 setErrorCodeAbort(4288);
705 case TupleKeyDefined:
709 case ExecInterpretedValue:
710 case SetValueInterpreted:
717 setErrorCodeAbort(4264);
722 tBlob = theNdb->getNdbBlob();
725 if (tBlob->atPrepare(aCon,
this, tAttrInfo) == -1) {
726 theNdb->releaseNdbBlob(tBlob);
729 if (tLastBlob == NULL)
732 tLastBlob->theNext = tBlob;
733 tBlob->theNext = NULL;
734 theNdbCon->theBlobFlag =
true;
743 while (tBlob != NULL) {
744 if (tBlob->theColumn == tAttrInfo)
746 tBlob = tBlob->theNext;
753 setErrorCodeAbort(4288);
779 NdbBlob *bh= theNdb->getNdbBlob();
786 res= bh->atPrepareNdbRecordScan(aCon,
this, column);
788 else if (m_key_record == NULL)
793 res= bh->atPrepareNdbRecordTakeover(aCon,
this, column,
794 m_key_row, m_keyinfo_length*4);
798 res= bh->atPrepareNdbRecord(aCon,
this, column, m_key_record, m_key_row);
802 theNdb->releaseNdbBlob(bh);
806 lastPtr->theNext= bh;
811 theNdbCon->theBlobFlag=
true;
825 const Uint32 * m_read_mask)
829 for (Uint32
i= 0;
i<m_attribute_record->noOfColumns;
i++)
832 if (!(col->flags & NdbRecord::IsBlob))
835 Uint32 attrId= col->attrId;
837 m_read_mask, attrId))
840 const NdbColumnImpl *tableColumn= m_currentTable->getColumn(attrId);
841 assert(tableColumn != NULL);
843 NdbBlob *bh= linkInBlobHandle(aCon, tableColumn, lastBlob);
853 memcpy((
char *)&m_attribute_row[col->offset], &bh,
sizeof(bh));
869 const Uint32 * m_read_mask)
875 for (Uint32
i= 0;
i < m_currentTable->m_columns.size();
i++)
879 if (!c->getBlobType())
884 m_read_mask, c->m_attrId)))
887 setErrorCodeAbort(4511);
891 NdbBlob *bh= linkInBlobHandle(aCon, c, lastBlob);
901 char* aBareValue, Uint16* aLenLoc)
905 assert(aLenLoc != NULL);
906 ra->m_getVarValue = aLenLoc;
913 const char* aBareValue,
const Uint16& aLen)
915 DBUG_ENTER(
"NdbOperation::setVarValue");
916 DBUG_PRINT(
"info", (
"aLen=%u", (Uint32)aLen));
919 const Uint32 MaxTupleSizeInLongWords= (NDB_MAX_TUPLE_SIZE + 7)/ 8;
920 Uint64
buf[ MaxTupleSizeInLongWords ];
921 assert( aLen < (NDB_MAX_TUPLE_SIZE - 2) );
922 unsigned char* p = (
unsigned char*)buf;
923 p[0] = (aLen & 0xff);
925 memcpy(&p[2], aBareValue, aLen);
926 if (
setValue(tAttrInfo, (
char*)buf) == -1)
941 NdbOperation::insertATTRINFO( Uint32 aData )
944 register Uint32 tAI_LenInCurrAI = theAI_LenInCurrAI;
945 register Uint32* tAttrPtr = theATTRINFOptr;
946 register Uint32 tTotCurrAILen = theTotalCurrAI_Len;
948 if (tAI_LenInCurrAI >= 25) {
952 tSignal = tNdb->getSignal();
953 if (tSignal != NULL) {
954 tSignal->setSignal(m_attrInfoGSN, refToBlock(theNdbCon->m_tcRef));
955 tAttrPtr = &tSignal->getDataPtrSend()[3];
956 if (tFirstAttrinfo == NULL) {
958 theFirstATTRINFO = tSignal;
959 theCurrentATTRINFO = tSignal;
961 NdbApiSignal* tCurrentAttrinfoBeforeUpdate = theCurrentATTRINFO;
963 theCurrentATTRINFO = tSignal;
964 tCurrentAttrinfoBeforeUpdate->next(tSignal);
967 goto insertATTRINFO_error1;
974 theTotalCurrAI_Len = tTotCurrAILen;
975 theAI_LenInCurrAI = tAI_LenInCurrAI;
976 theATTRINFOptr = tAttrPtr;
979 insertATTRINFO_error1:
980 setErrorCodeAbort(4000);
996 NdbOperation::insertATTRINFOloop(
register const Uint32* aDataPtr,
997 register Uint32 aLength)
1000 register Uint32 tAI_LenInCurrAI = theAI_LenInCurrAI;
1001 register Uint32 tTotCurrAILen = theTotalCurrAI_Len;
1002 register Uint32* tAttrPtr = theATTRINFOptr;
1005 while (aLength > 0) {
1006 if (tAI_LenInCurrAI >= 25) {
1008 tAI_LenInCurrAI = 3;
1009 tSignal = tNdb->getSignal();
1010 if (tSignal != NULL) {
1011 tSignal->setSignal(m_attrInfoGSN, refToBlock(theNdbCon->m_tcRef));
1012 tAttrPtr = &tSignal->getDataPtrSend()[3];
1013 if (tFirstAttrinfo == NULL) {
1014 tSignal->next(NULL);
1015 theFirstATTRINFO = tSignal;
1016 theCurrentATTRINFO = tSignal;
1018 NdbApiSignal* tCurrentAttrinfoBeforeUpdate = theCurrentATTRINFO;
1019 tSignal->next(NULL);
1020 theCurrentATTRINFO = tSignal;
1021 tCurrentAttrinfoBeforeUpdate->next(tSignal);
1024 goto insertATTRINFO_error1;
1028 register Uint32 tData = *aDataPtr;
1037 theATTRINFOptr = tAttrPtr;
1038 theTotalCurrAI_Len = tTotCurrAILen;
1039 theAI_LenInCurrAI = tAI_LenInCurrAI;
1042 insertATTRINFO_error1:
1043 setErrorCodeAbort(4000);
1055 NdbOperation::setAbortOption(AbortOption ao)
1057 if (theStatus == UseNdbRecord)
1061 setErrorCodeAbort(4515);
1078 NdbOperation::prepareGetLockHandleNdbRecord()
1084 assert(theLockHandle == NULL);
1085 theLockHandle = theNdbCon->getLockHandle();
1091 assert(! theLockHandle->isLockRefValid());
1093 assert(m_attribute_record);
1094 theLockHandle->m_table = m_attribute_record->table;
1095 assert(theLockHandle->m_table);
1098 getValue_NdbRecord(&NdbColumnImpl::getImpl(*NdbDictionary::Column::LOCK_REF),
1099 (
char*) &theLockHandle->m_lockRef);
1104 assert(theError.
code);
1105 return theError.
code;
1108 theLockHandle->m_state = NdbLockHandle::PREPARED;
1120 NdbOperation::handleOperationOptions (
const OperationType
type,
1121 const OperationOptions *opts,
1122 const Uint32 sizeOfOptions,
1126 if (unlikely((sizeOfOptions != 0) &&
1127 (sizeOfOptions !=
sizeof(OperationOptions))))
1137 bool isScanTakeoverOp = (op->m_key_record == NULL);
1139 if (opts->optionsPresent & OperationOptions::OO_ABORTOPTION)
1144 switch (opts->abortOption)
1149 op->m_abortOption=opts->abortOption;
1159 if ((opts->optionsPresent & OperationOptions::OO_GETVALUE) &&
1160 (opts->numExtraGetValues > 0))
1162 if (opts->extraGetValues == NULL)
1178 for (
unsigned int i=0;
i < opts->numExtraGetValues;
i++)
1180 GetValueSpec *pvalSpec
1181 = &(opts->extraGetValues[
i]);
1183 pvalSpec->recAttr=NULL;
1185 if (pvalSpec->column == NULL)
1192 op->getValue_NdbRecord(&NdbColumnImpl::getImpl(*pvalSpec->column),
1193 (
char *) pvalSpec->appStorage);
1200 pvalSpec->recAttr = pra;
1226 if ((opts->optionsPresent & OperationOptions::OO_SETVALUE) &&
1227 (opts->numExtraSetValues > 0))
1229 if (opts->extraSetValues == NULL)
1244 for (Uint32
i=0;
i< opts->numExtraSetValues;
i++)
1247 const void *pvalue=opts->extraSetValues[
i].value;
1283 op->m_extraSetValues = opts->extraSetValues;
1284 op->m_numExtraSetValues = opts->numExtraSetValues;
1293 if (opts->optionsPresent & OperationOptions::OO_PARTITION_ID)
1296 assert(op->theBlobList == NULL);
1299 if (unlikely(isScanTakeoverOp))
1309 if (unlikely( ! (((op->m_attribute_record->flags &
1310 NdbRecord::RecHasUserDefinedPartitioning) &&
1311 (op->m_key_record->table->m_index == NULL)) ||
1317 op->theDistributionKey=opts->partitionId;
1318 op->theDistrKeyIndicator_= 1;
1321 if (opts->optionsPresent & OperationOptions::OO_INTERPRETED)
1336 if (codeTable != NULL)
1338 NdbTableImpl* impl= &NdbTableImpl::getImpl(*codeTable);
1340 if ((impl->m_id != (
int) op->m_attribute_record->tableId) ||
1341 (table_version_major(impl->m_version) !=
1342 table_version_major(op->m_attribute_record->tableVersion)))
1347 if ((opts->interpretedCode->m_flags &
1348 NdbInterpretedCode::Finalised) == 0)
1351 op->m_interpreted_code = opts->interpretedCode;
1354 if (opts->optionsPresent & OperationOptions::OO_ANYVALUE)
1357 op->m_any_value = opts->anyValue;
1358 op->m_flags |= OF_USE_ANY_VALUE;
1361 if (opts->optionsPresent & OperationOptions::OO_CUSTOMDATA)
1364 op->m_customData = opts->customData;
1367 if (opts->optionsPresent & OperationOptions::OO_LOCKHANDLE)
1369 if (unlikely(op->theNdb->getMinDbNodeVersion() <
1370 NDBD_UNLOCK_OP_SUPPORTED))
1382 (op->m_key_record &&
1383 (op->m_key_record->flags & NdbRecord::RecIsIndex)) ||
1384 ((op->theLockMode !=
LM_Read) &&
1390 int prepareRc = op->prepareGetLockHandleNdbRecord();
1397 if (opts->optionsPresent & OperationOptions::OO_QUEUABLE)
1399 op->m_flags |= OF_QUEUEABLE;
1402 if (opts->optionsPresent & OperationOptions::OO_NOT_QUEUABLE)
1404 op->m_flags &= ~Uint8(OF_QUEUEABLE);
1407 if (opts->optionsPresent & OperationOptions::OO_DEFERRED_CONSTAINTS)
1409 op->m_flags |= OF_DEFERRED_CONSTRAINTS;