~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/ndbapi/NdbOperationDefine.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include <ndb_global.h>
 
17
#include <NdbOperation.hpp>
 
18
#include "NdbApiSignal.hpp"
 
19
#include <NdbTransaction.hpp>
 
20
#include <Ndb.hpp>
 
21
#include <NdbRecAttr.hpp>
 
22
#include "NdbUtil.hpp"
 
23
#include "NdbOut.hpp"
 
24
#include "NdbImpl.hpp"
 
25
#include <NdbIndexScanOperation.hpp>
 
26
#include <NdbBlob.hpp>
 
27
 
 
28
#include <Interpreter.hpp>
 
29
 
 
30
#include <AttributeHeader.hpp>
 
31
#include <signaldata/TcKeyReq.hpp>
 
32
 
 
33
/*****************************************************************************
 
34
 * int insertTuple();
 
35
 *****************************************************************************/
 
36
int
 
37
NdbOperation::insertTuple()
 
38
{
 
39
  NdbTransaction* tNdbCon = theNdbCon;
 
40
  int tErrorLine = theErrorLine;
 
41
  if (theStatus == Init) {
 
42
    theStatus = OperationDefined;
 
43
    theOperationType = InsertRequest;
 
44
    tNdbCon->theSimpleState = 0;
 
45
    theErrorLine = tErrorLine++;
 
46
    theLockMode = LM_Exclusive;
 
47
    m_abortOption = AbortOnError;
 
48
    return 0; 
 
49
  } else {
 
50
    setErrorCode(4200);
 
51
    return -1;
 
52
  }//if
 
53
}//NdbOperation::insertTuple()
 
54
/******************************************************************************
 
55
 * int updateTuple();
 
56
 *****************************************************************************/
 
57
int
 
58
NdbOperation::updateTuple()
 
59
{  
 
60
  NdbTransaction* tNdbCon = theNdbCon;
 
61
  int tErrorLine = theErrorLine;
 
62
  if (theStatus == Init) {
 
63
    theStatus = OperationDefined;
 
64
    tNdbCon->theSimpleState = 0;
 
65
    theOperationType = UpdateRequest;  
 
66
    theErrorLine = tErrorLine++;
 
67
    theLockMode = LM_Exclusive;
 
68
    m_abortOption = AbortOnError;
 
69
    return 0; 
 
70
  } else {
 
71
    setErrorCode(4200);
 
72
    return -1;
 
73
  }//if
 
74
}//NdbOperation::updateTuple()
 
75
/*****************************************************************************
 
76
 * int writeTuple();
 
77
 *****************************************************************************/
 
78
int
 
79
NdbOperation::writeTuple()
 
80
{  
 
81
  NdbTransaction* tNdbCon = theNdbCon;
 
82
  int tErrorLine = theErrorLine;
 
83
  if (theStatus == Init) {
 
84
    theStatus = OperationDefined;
 
85
    tNdbCon->theSimpleState = 0;
 
86
    theOperationType = WriteRequest;  
 
87
    theErrorLine = tErrorLine++;
 
88
    theLockMode = LM_Exclusive;
 
89
    m_abortOption = AbortOnError;
 
90
    return 0; 
 
91
  } else {
 
92
    setErrorCode(4200);
 
93
    return -1;
 
94
  }//if
 
95
}//NdbOperation::writeTuple()
 
96
/*****************************************************************************
 
97
 * int deleteTuple();
 
98
 *****************************************************************************/
 
99
int
 
100
NdbOperation::deleteTuple()
 
101
{
 
102
  NdbTransaction* tNdbCon = theNdbCon;
 
103
  int tErrorLine = theErrorLine;
 
104
  if (theStatus == Init) {
 
105
    theStatus = OperationDefined;  
 
106
    tNdbCon->theSimpleState = 0;
 
107
    theOperationType = DeleteRequest;
 
108
    theErrorLine = tErrorLine++;
 
109
    theLockMode = LM_Exclusive;
 
110
    m_abortOption = AbortOnError;
 
111
    return 0;
 
112
  } else {
 
113
    setErrorCode(4200);
 
114
    return -1;
 
115
  }//if
 
116
}//NdbOperation::deleteTuple()
 
117
 
 
118
/******************************************************************************
 
119
 * int readTuple();
 
120
 *****************************************************************************/
 
121
int
 
122
NdbOperation::readTuple(NdbOperation::LockMode lm)
 
123
 
124
  switch(lm) {
 
125
  case LM_Read:
 
126
    return readTuple();
 
127
    break;
 
128
  case LM_Exclusive:
 
129
    return readTupleExclusive();
 
130
    break;
 
131
  case LM_CommittedRead:
 
132
    return committedRead();
 
133
    break;
 
134
  case LM_SimpleRead:
 
135
    return simpleRead();
 
136
  default:
 
137
    return -1;
 
138
  };
 
139
}
 
140
/******************************************************************************
 
141
 * int readTuple();
 
142
 *****************************************************************************/
 
143
int
 
144
NdbOperation::readTuple()
 
145
 
146
  NdbTransaction* tNdbCon = theNdbCon;
 
147
  int tErrorLine = theErrorLine;
 
148
  if (theStatus == Init) {
 
149
    theStatus = OperationDefined;
 
150
    tNdbCon->theSimpleState = 0;
 
151
    theOperationType = ReadRequest;
 
152
    theErrorLine = tErrorLine++;
 
153
    theLockMode = LM_Read;
 
154
    m_abortOption = AO_IgnoreError;
 
155
    return 0;
 
156
  } else {
 
157
    setErrorCode(4200);
 
158
    return -1;
 
159
  }//if
 
160
}//NdbOperation::readTuple()
 
161
 
 
162
/******************************************************************************
 
163
 * int readTupleExclusive();
 
164
 *****************************************************************************/
 
165
int
 
166
NdbOperation::readTupleExclusive()
 
167
 
168
  NdbTransaction* tNdbCon = theNdbCon;
 
169
  int tErrorLine = theErrorLine;
 
170
  if (theStatus == Init) {
 
171
    theStatus = OperationDefined;
 
172
    tNdbCon->theSimpleState = 0;
 
173
    theOperationType = ReadExclusive;
 
174
    theErrorLine = tErrorLine++;
 
175
    theLockMode = LM_Exclusive;
 
176
    m_abortOption = AO_IgnoreError;
 
177
    return 0;
 
178
  } else {
 
179
    setErrorCode(4200);
 
180
    return -1;
 
181
  }//if
 
182
}//NdbOperation::readTupleExclusive()
 
183
 
 
184
/*****************************************************************************
 
185
 * int simpleRead();
 
186
 *****************************************************************************/
 
187
int
 
188
NdbOperation::simpleRead()
 
189
{
 
190
  NdbTransaction* tNdbCon = theNdbCon;
 
191
  int tErrorLine = theErrorLine;
 
192
  if (theStatus == Init) {
 
193
    theStatus = OperationDefined;
 
194
    theOperationType = ReadRequest;
 
195
    theSimpleIndicator = 1;
 
196
    theDirtyIndicator = 0;
 
197
    theErrorLine = tErrorLine++;
 
198
    theLockMode = LM_SimpleRead;
 
199
    m_abortOption = AO_IgnoreError;
 
200
    tNdbCon->theSimpleState = 0;
 
201
    return 0;
 
202
  } else {
 
203
    setErrorCode(4200);
 
204
    return -1;
 
205
  }//if
 
206
}//NdbOperation::simpleRead()
 
207
 
 
208
/*****************************************************************************
 
209
 * int dirtyRead();
 
210
 *****************************************************************************/
 
211
int
 
212
NdbOperation::dirtyRead()
 
213
{
 
214
  return committedRead();
 
215
}//NdbOperation::dirtyRead()
 
216
 
 
217
/*****************************************************************************
 
218
 * int committedRead();
 
219
 *****************************************************************************/
 
220
int
 
221
NdbOperation::committedRead()
 
222
{
 
223
  int tErrorLine = theErrorLine;
 
224
  if (theStatus == Init) {
 
225
    theStatus = OperationDefined;
 
226
    theOperationType = ReadRequest;
 
227
    theSimpleIndicator = 1;
 
228
    theDirtyIndicator = 1;
 
229
    theErrorLine = tErrorLine++;
 
230
    theLockMode = LM_CommittedRead;
 
231
    m_abortOption = AO_IgnoreError;
 
232
    return 0;
 
233
  } else {
 
234
    setErrorCode(4200);
 
235
    return -1;
 
236
  }//if
 
237
}//NdbOperation::committedRead()
 
238
 
 
239
/*****************************************************************************
 
240
 * int dirtyUpdate();
 
241
 ****************************************************************************/
 
242
int
 
243
NdbOperation::dirtyUpdate()
 
244
{
 
245
  NdbTransaction* tNdbCon = theNdbCon;
 
246
  int tErrorLine = theErrorLine;
 
247
  if (theStatus == Init) {
 
248
    theStatus = OperationDefined;
 
249
    theOperationType = UpdateRequest;
 
250
    tNdbCon->theSimpleState = 0;
 
251
    theSimpleIndicator = 1;
 
252
    theDirtyIndicator = 1;
 
253
    theErrorLine = tErrorLine++;
 
254
    theLockMode = LM_CommittedRead;
 
255
    m_abortOption = AbortOnError;
 
256
    return 0;
 
257
  } else {
 
258
    setErrorCode(4200);
 
259
    return -1;
 
260
  }//if
 
261
}//NdbOperation::dirtyUpdate()
 
262
 
 
263
/******************************************************************************
 
264
 * int dirtyWrite();
 
265
 *****************************************************************************/
 
266
int
 
267
NdbOperation::dirtyWrite()
 
268
{
 
269
  NdbTransaction* tNdbCon = theNdbCon;
 
270
  int tErrorLine = theErrorLine;
 
271
  if (theStatus == Init) {
 
272
    theStatus = OperationDefined;
 
273
    theOperationType = WriteRequest;
 
274
    tNdbCon->theSimpleState = 0;
 
275
    theSimpleIndicator = 1;
 
276
    theDirtyIndicator = 1;
 
277
    theErrorLine = tErrorLine++;
 
278
    theLockMode = LM_CommittedRead;
 
279
    m_abortOption = AbortOnError;
 
280
    return 0;
 
281
  } else {
 
282
    setErrorCode(4200);
 
283
    return -1;
 
284
  }//if
 
285
}//NdbOperation::dirtyWrite()
 
286
 
 
287
/******************************************************************************
 
288
 * int interpretedUpdateTuple();
 
289
 ****************************************************************************/
 
290
int
 
291
NdbOperation::interpretedUpdateTuple()
 
292
{
 
293
  NdbTransaction* tNdbCon = theNdbCon;
 
294
  int tErrorLine = theErrorLine;
 
295
  if (theStatus == Init) {
 
296
    theStatus = OperationDefined;
 
297
    tNdbCon->theSimpleState = 0;
 
298
    theOperationType = UpdateRequest;
 
299
    theAI_LenInCurrAI = 25;
 
300
    theLockMode = LM_Exclusive;
 
301
    theErrorLine = tErrorLine++;
 
302
    m_abortOption = AbortOnError;
 
303
    initInterpreter();
 
304
    return 0;
 
305
  } else {
 
306
    setErrorCode(4200);
 
307
    return -1;
 
308
  }//if
 
309
}//NdbOperation::interpretedUpdateTuple()
 
310
 
 
311
/*****************************************************************************
 
312
 * int interpretedDeleteTuple();
 
313
 *****************************************************************************/
 
314
int
 
315
NdbOperation::interpretedDeleteTuple()
 
316
{
 
317
  NdbTransaction* tNdbCon = theNdbCon;
 
318
  int tErrorLine = theErrorLine;
 
319
  if (theStatus == Init) {
 
320
    theStatus = OperationDefined;
 
321
    tNdbCon->theSimpleState = 0;
 
322
    theOperationType = DeleteRequest;
 
323
 
 
324
    theErrorLine = tErrorLine++;
 
325
    theAI_LenInCurrAI = 25;
 
326
    theLockMode = LM_Exclusive;
 
327
    m_abortOption = AbortOnError;
 
328
    initInterpreter();
 
329
    return 0;
 
330
  } else {
 
331
    setErrorCode(4200);
 
332
    return -1;
 
333
  }//if
 
334
}//NdbOperation::interpretedDeleteTuple()
 
335
 
 
336
void
 
337
NdbOperation::setReadLockMode(LockMode lockMode)
 
338
{
 
339
  /* We only support changing lock mode for read operations at this time. */
 
340
  assert(theOperationType == ReadRequest || theOperationType == ReadExclusive);
 
341
  switch (lockMode) {
 
342
  case LM_CommittedRead: /* TODO, check theNdbCon->theSimpleState */
 
343
    theOperationType= ReadRequest;
 
344
    theSimpleIndicator= 1;
 
345
    theDirtyIndicator= 1;
 
346
    break;
 
347
  case LM_SimpleRead: /* TODO, check theNdbCon->theSimpleState */
 
348
    theOperationType= ReadRequest;
 
349
    theSimpleIndicator= 1;
 
350
    theDirtyIndicator= 0;
 
351
    break;
 
352
  case LM_Read:
 
353
    theNdbCon->theSimpleState= 0;
 
354
    theOperationType= ReadRequest;
 
355
    theSimpleIndicator= 0;
 
356
    theDirtyIndicator= 0;
 
357
    break;
 
358
  case LM_Exclusive:
 
359
    theNdbCon->theSimpleState= 0;
 
360
    theOperationType= ReadExclusive;
 
361
    theSimpleIndicator= 0;
 
362
    theDirtyIndicator= 0;
 
363
    break;
 
364
  default:
 
365
    /* Not supported / invalid. */
 
366
    assert(false);
 
367
  }
 
368
  theLockMode= lockMode;
 
369
}
 
370
 
 
371
 
 
372
/******************************************************************************
 
373
 * int getValue(AttrInfo* tAttrInfo, char* aRef )
 
374
 *
 
375
 * Return Value   Return 0 : GetValue was successful.
 
376
 *                Return -1: In all other case. 
 
377
 * Parameters:    tAttrInfo : Attribute object of the retrieved attribute 
 
378
 *                            value.
 
379
 * Remark:        Define an attribute to retrieve in query.
 
380
 *****************************************************************************/
 
381
NdbRecAttr*
 
382
NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue)
 
383
{
 
384
  NdbRecAttr* tRecAttr;
 
385
  if ((tAttrInfo != NULL) &&
 
386
      (theStatus != Init)){
 
387
    m_no_disk_flag &= (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
 
388
    if (theStatus != GetValue) {
 
389
      if (theInterpretIndicator == 1) {
 
390
        if (theStatus == FinalGetValue) {
 
391
          ; // Simply continue with getValue
 
392
        } else if (theStatus == ExecInterpretedValue) {
 
393
          if (insertATTRINFO(Interpreter::EXIT_OK) == -1)
 
394
            return NULL;
 
395
          theInterpretedSize = theTotalCurrAI_Len -
 
396
            (theInitialReadSize + 5);
 
397
        } else if (theStatus == SetValueInterpreted) {
 
398
          theFinalUpdateSize = theTotalCurrAI_Len - 
 
399
            (theInitialReadSize + theInterpretedSize + 5);
 
400
        } else {
 
401
          setErrorCodeAbort(4230);
 
402
          return NULL;
 
403
        }//if
 
404
        // MASV - How would execution come here?
 
405
        theStatus = FinalGetValue;
 
406
      } else {
 
407
        setErrorCodeAbort(4230);
 
408
        return NULL;
 
409
      }//if
 
410
    }//if
 
411
    AttributeHeader ah(tAttrInfo->m_attrId, 0);
 
412
    if (insertATTRINFO(ah.m_value) != -1) {     
 
413
      // Insert Attribute Id into ATTRINFO part. 
 
414
      
 
415
      /************************************************************************
 
416
       * Get a Receive Attribute object and link it into the operation object.
 
417
       ***********************************************************************/
 
418
      if((tRecAttr = theReceiver.getValue(tAttrInfo, aValue)) != 0){
 
419
        theErrorLine++;
 
420
        return tRecAttr;
 
421
      } else {  
 
422
        setErrorCodeAbort(4000);
 
423
        return NULL;
 
424
      }
 
425
    } else {
 
426
      return NULL;
 
427
    }//if insertATTRINFO failure
 
428
  } else {
 
429
    if (tAttrInfo == NULL) {
 
430
      setErrorCodeAbort(4004);      
 
431
      return NULL;
 
432
    }//if
 
433
  }//if
 
434
  setErrorCodeAbort(4200);
 
435
  return NULL;
 
436
}
 
437
 
 
438
/*****************************************************************************
 
439
 * int setValue(AttrInfo* tAttrInfo, char* aValue, Uint32 len)
 
440
 *
 
441
 * Return Value:  Return 0 : SetValue was succesful.
 
442
 *                Return -1: In all other case.   
 
443
 * Parameters:    tAttrInfo : Attribute object where the attribute 
 
444
 *                            info exists.
 
445
 *                aValue : Reference to the variable with the new value.
 
446
 *                len    : Length of the value
 
447
 * Remark:        Define a attribute to set in a query.
 
448
******************************************************************************/
 
449
int
 
450
NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, 
 
451
                        const char* aValuePassed)
 
452
{
 
453
  DBUG_ENTER("NdbOperation::setValue");
 
454
  DBUG_PRINT("enter", ("col: %s  op:%d  val: 0x%lx",
 
455
                       tAttrInfo->m_name.c_str(), theOperationType,
 
456
                       (long) aValuePassed));
 
457
 
 
458
  int tReturnCode;
 
459
  Uint32 tAttrId;
 
460
  Uint32 tData;
 
461
  Uint32 tempData[2000];
 
462
  OperationType tOpType = theOperationType;
 
463
  OperationStatus tStatus = theStatus;
 
464
 
 
465
  
 
466
  if ((tOpType == UpdateRequest) ||
 
467
      (tOpType == WriteRequest)) {
 
468
    if (theInterpretIndicator == 0) {
 
469
      if (tStatus == SetValue) {
 
470
        ;
 
471
      } else {
 
472
        setErrorCodeAbort(4234);
 
473
        DBUG_RETURN(-1);
 
474
      }//if
 
475
    } else {
 
476
      if (tStatus == GetValue) {
 
477
        theInitialReadSize = theTotalCurrAI_Len - 5;
 
478
      } else if (tStatus == ExecInterpretedValue) {
 
479
        //--------------------------------------------------------------------
 
480
        // We insert an exit from interpretation since we are now starting 
 
481
        // to set values in the tuple by setValue.
 
482
        //--------------------------------------------------------------------
 
483
        if (insertATTRINFO(Interpreter::EXIT_OK) == -1){
 
484
          DBUG_RETURN(-1);
 
485
        }
 
486
        theInterpretedSize = theTotalCurrAI_Len - 
 
487
          (theInitialReadSize + 5);
 
488
      } else if (tStatus == SetValueInterpreted) {
 
489
        ; // Simply continue adding new setValue
 
490
      } else {
 
491
        //--------------------------------------------------------------------
 
492
        // setValue used in the wrong context. Application coding error.
 
493
        //-------------------------------------------------------------------
 
494
        setErrorCodeAbort(4234); //Wrong error code
 
495
        DBUG_RETURN(-1);
 
496
      }//if
 
497
      theStatus = SetValueInterpreted;
 
498
    }//if
 
499
  } else if (tOpType == InsertRequest) {
 
500
    if ((theStatus != SetValue) && (theStatus != OperationDefined)) {
 
501
      setErrorCodeAbort(4234);
 
502
      DBUG_RETURN(-1);
 
503
    }//if
 
504
  } else if (tOpType == ReadRequest || tOpType == ReadExclusive) {
 
505
    setErrorCodeAbort(4504);
 
506
    DBUG_RETURN(-1);
 
507
  } else if (tOpType == DeleteRequest) {
 
508
    setErrorCodeAbort(4504);
 
509
    DBUG_RETURN(-1);
 
510
  } else if (tOpType == OpenScanRequest || tOpType == OpenRangeScanRequest) {
 
511
    setErrorCodeAbort(4228);
 
512
    DBUG_RETURN(-1);
 
513
  } else {
 
514
    //---------------------------------------------------------------------
 
515
    // setValue with undefined operation type. 
 
516
    // Probably application coding error.
 
517
    //---------------------------------------------------------------------
 
518
    setErrorCodeAbort(4108);
 
519
    DBUG_RETURN(-1);
 
520
  }//if
 
521
  if (tAttrInfo == NULL) {
 
522
    setErrorCodeAbort(4004);      
 
523
    DBUG_RETURN(-1);
 
524
  }//if
 
525
  if (tAttrInfo->m_pk) {
 
526
    if (theOperationType == InsertRequest) {
 
527
      DBUG_RETURN(equal_impl(tAttrInfo, aValuePassed));
 
528
    } else {
 
529
      setErrorCodeAbort(4202);      
 
530
      DBUG_RETURN(-1);
 
531
    }//if
 
532
  }//if
 
533
  
 
534
  // Insert Attribute Id into ATTRINFO part. 
 
535
  tAttrId = tAttrInfo->m_attrId;
 
536
  m_no_disk_flag &= (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
 
537
  const char *aValue = aValuePassed; 
 
538
  if (aValue == NULL) {
 
539
    if (tAttrInfo->m_nullable) {
 
540
      AttributeHeader ah(tAttrId, 0);
 
541
      ah.setNULL();
 
542
      insertATTRINFO(ah.m_value);
 
543
      // Insert Attribute Id with the value
 
544
      // NULL into ATTRINFO part. 
 
545
      DBUG_RETURN(0);
 
546
    } else {
 
547
      /***********************************************************************
 
548
       * Setting a NULL value on a NOT NULL attribute is not allowed.
 
549
       **********************************************************************/
 
550
      setErrorCodeAbort(4203);      
 
551
      DBUG_RETURN(-1);
 
552
    }//if
 
553
  }//if
 
554
  
 
555
  Uint32 len;
 
556
  if (! tAttrInfo->get_var_length(aValue, len)) {
 
557
    setErrorCodeAbort(4209);
 
558
    DBUG_RETURN(-1);
 
559
  }
 
560
 
 
561
  const Uint32 sizeInBytes = len;
 
562
  const Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ;
 
563
  
 
564
  const int attributeSize = sizeInBytes;
 
565
  const int slack = sizeInBytes & 3;
 
566
  
 
567
  if (((UintPtr)aValue & 3) != 0 || (slack != 0)){
 
568
    memcpy(&tempData[0], aValue, attributeSize);
 
569
    aValue = (char*)&tempData[0];
 
570
    if(slack != 0) {
 
571
      char * tmp = (char*)&tempData[0];
 
572
      memset(&tmp[attributeSize], 0, (4 - slack));
 
573
    }//if
 
574
  }//if
 
575
  
 
576
  // Excluding bits in last word
 
577
  const Uint32 sizeInWords = sizeInBytes / 4;          
 
578
  AttributeHeader ah(tAttrId, sizeInBytes);
 
579
  insertATTRINFO( ah.m_value );
 
580
 
 
581
  /***********************************************************************
 
582
   * Check if the pointer of the value passed is aligned on a 4 byte boundary.
 
583
   * If so only assign the pointer to the internal variable aValue. 
 
584
   * If it is not aligned then we start by copying the value to tempData and 
 
585
   * use this as aValue instead.
 
586
   *************************************************************************/
 
587
  
 
588
  tReturnCode = insertATTRINFOloop((Uint32*)aValue, sizeInWords);
 
589
  if (tReturnCode == -1) {
 
590
    DBUG_RETURN(tReturnCode);
 
591
  }//if
 
592
  if (bitsInLastWord != 0) {
 
593
    tData = *(Uint32*)(aValue + sizeInWords*4);
 
594
    tData = convertEndian(tData);
 
595
    tData = tData & ((1 << bitsInLastWord) - 1);
 
596
    tData = convertEndian(tData);
 
597
    tReturnCode = insertATTRINFO(tData);
 
598
    if (tReturnCode == -1) {
 
599
      DBUG_RETURN(tReturnCode);
 
600
    }//if
 
601
  }//if
 
602
  theErrorLine++;  
 
603
  DBUG_RETURN(0);
 
604
}//NdbOperation::setValue()
 
605
 
 
606
 
 
607
int
 
608
NdbOperation::setAnyValue(Uint32 any_value)
 
609
{
 
610
  const NdbColumnImpl* impl =
 
611
    &NdbColumnImpl::getImpl(* NdbDictionary::Column::ANY_VALUE);
 
612
  OperationType tOpType = theOperationType;
 
613
 
 
614
  switch(tOpType){
 
615
  case DeleteRequest:{
 
616
    Uint32 ah;
 
617
    AttributeHeader::init(&ah, AttributeHeader::ANY_VALUE, 4);
 
618
    if (insertATTRINFO(ah) != -1 && insertATTRINFO(any_value) != -1 ) 
 
619
    {
 
620
      return 0;
 
621
    }
 
622
  }
 
623
  default:
 
624
    return setValue(impl, (const char *)&any_value);
 
625
  }
 
626
 
 
627
  setErrorCodeAbort(4000);
 
628
  return -1;
 
629
}
 
630
 
 
631
 
 
632
NdbBlob*
 
633
NdbOperation::getBlobHandle(NdbTransaction* aCon, const NdbColumnImpl* tAttrInfo)
 
634
{
 
635
  NdbBlob* tBlob = theBlobList;
 
636
  NdbBlob* tLastBlob = NULL;
 
637
  while (tBlob != NULL) {
 
638
    if (tBlob->theColumn == tAttrInfo)
 
639
      return tBlob;
 
640
    tLastBlob = tBlob;
 
641
    tBlob = tBlob->theNext;
 
642
  }
 
643
  tBlob = theNdb->getNdbBlob();
 
644
  if (tBlob == NULL)
 
645
    return NULL;
 
646
  if (tBlob->atPrepare(aCon, this, tAttrInfo) == -1) {
 
647
    theNdb->releaseNdbBlob(tBlob);
 
648
    return NULL;
 
649
  }
 
650
  if (tLastBlob == NULL)
 
651
    theBlobList = tBlob;
 
652
  else
 
653
    tLastBlob->theNext = tBlob;
 
654
  tBlob->theNext = NULL;
 
655
  theNdbCon->theBlobFlag = true;
 
656
  return tBlob;
 
657
}
 
658
 
 
659
/****************************************************************************
 
660
 * int insertATTRINFO( Uint32 aData );
 
661
 *
 
662
 * Return Value:   Return 0 : insertATTRINFO was succesful.
 
663
 *                 Return -1: In all other case.   
 
664
 * Parameters:     aData: the data to insert into ATTRINFO.
 
665
 * Remark:         Puts the the data into either TCKEYREQ signal or 
 
666
 *                 ATTRINFO signal.
 
667
 *****************************************************************************/
 
668
int
 
669
NdbOperation::insertATTRINFO( Uint32 aData )
 
670
{
 
671
  NdbApiSignal* tSignal;
 
672
  register Uint32 tAI_LenInCurrAI = theAI_LenInCurrAI;
 
673
  register Uint32* tAttrPtr = theATTRINFOptr;
 
674
  register Uint32 tTotCurrAILen = theTotalCurrAI_Len;
 
675
 
 
676
  if (tAI_LenInCurrAI >= 25) {
 
677
    Ndb* tNdb = theNdb;
 
678
    NdbApiSignal* tFirstAttrinfo = theFirstATTRINFO;
 
679
    tAI_LenInCurrAI = 3;
 
680
    tSignal = tNdb->getSignal();
 
681
    if (tSignal != NULL) {
 
682
      tSignal->setSignal(m_attrInfoGSN);
 
683
      tAttrPtr = &tSignal->getDataPtrSend()[3];
 
684
      if (tFirstAttrinfo == NULL) {
 
685
        tSignal->next(NULL);
 
686
        theFirstATTRINFO = tSignal;
 
687
        theCurrentATTRINFO = tSignal;
 
688
      } else {
 
689
        NdbApiSignal* tCurrentAttrinfoBeforeUpdate = theCurrentATTRINFO;
 
690
        tSignal->next(NULL);
 
691
        theCurrentATTRINFO = tSignal;
 
692
        tCurrentAttrinfoBeforeUpdate->next(tSignal);
 
693
      }//if
 
694
    } else {
 
695
      goto insertATTRINFO_error1;
 
696
    }//if
 
697
  }//if
 
698
  *tAttrPtr = aData;
 
699
  tAttrPtr++;
 
700
  tTotCurrAILen++;
 
701
  tAI_LenInCurrAI++;
 
702
  theTotalCurrAI_Len = tTotCurrAILen;
 
703
  theAI_LenInCurrAI = tAI_LenInCurrAI;
 
704
  theATTRINFOptr = tAttrPtr;
 
705
  return 0;
 
706
 
 
707
insertATTRINFO_error1:
 
708
  setErrorCodeAbort(4000);
 
709
  return -1;
 
710
 
 
711
}//NdbOperation::insertATTRINFO()
 
712
 
 
713
/*****************************************************************************
 
714
 * int insertATTRINFOloop(Uint32* aDataPtr, Uint32 aLength );
 
715
 *
 
716
 * Return Value:  Return 0 : insertATTRINFO was succesful.
 
717
 *                Return -1: In all other case.   
 
718
 * Parameters:    aDataPtr: Pointer to the data to insert into ATTRINFO.
 
719
 *                aLength: Length of data to be copied
 
720
 * Remark:        Puts the the data into either TCKEYREQ signal or 
 
721
 *                ATTRINFO signal.
 
722
 *****************************************************************************/
 
723
int
 
724
NdbOperation::insertATTRINFOloop(register const Uint32* aDataPtr, 
 
725
                                 register Uint32 aLength)
 
726
{
 
727
  NdbApiSignal* tSignal;
 
728
  register Uint32 tAI_LenInCurrAI = theAI_LenInCurrAI;
 
729
  register Uint32 tTotCurrAILen = theTotalCurrAI_Len;
 
730
  register Uint32* tAttrPtr = theATTRINFOptr;  
 
731
  Ndb* tNdb = theNdb;
 
732
 
 
733
  while (aLength > 0) {
 
734
    if (tAI_LenInCurrAI >= 25) {
 
735
      NdbApiSignal* tFirstAttrinfo = theFirstATTRINFO;
 
736
      tAI_LenInCurrAI = 3;
 
737
      tSignal = tNdb->getSignal();
 
738
      if (tSignal != NULL) {
 
739
        tSignal->setSignal(m_attrInfoGSN);
 
740
        tAttrPtr = &tSignal->getDataPtrSend()[3];
 
741
        if (tFirstAttrinfo == NULL) {
 
742
          tSignal->next(NULL);
 
743
          theFirstATTRINFO = tSignal;
 
744
          theCurrentATTRINFO = tSignal;
 
745
        } else {
 
746
          NdbApiSignal* tCurrentAttrinfoBeforeUpdate = theCurrentATTRINFO;
 
747
          tSignal->next(NULL);
 
748
          theCurrentATTRINFO = tSignal;
 
749
          tCurrentAttrinfoBeforeUpdate->next(tSignal);
 
750
        }//if
 
751
      } else {
 
752
        goto insertATTRINFO_error1;
 
753
      }//if
 
754
    }//if
 
755
    {
 
756
      register Uint32 tData = *aDataPtr;
 
757
      aDataPtr++;
 
758
      aLength--;
 
759
      tAI_LenInCurrAI++;
 
760
      *tAttrPtr = tData;
 
761
      tAttrPtr++;
 
762
      tTotCurrAILen++;
 
763
    }
 
764
  }//while
 
765
  theATTRINFOptr = tAttrPtr;
 
766
  theTotalCurrAI_Len = tTotCurrAILen;
 
767
  theAI_LenInCurrAI = tAI_LenInCurrAI;
 
768
  return 0;
 
769
 
 
770
insertATTRINFO_error1:
 
771
  setErrorCodeAbort(4000);
 
772
  return -1;
 
773
 
 
774
}//NdbOperation::insertATTRINFOloop()
 
775
 
 
776
NdbOperation::AbortOption
 
777
NdbOperation::getAbortOption() const
 
778
{
 
779
  return (AbortOption)m_abortOption;
 
780
}
 
781
 
 
782
int
 
783
NdbOperation::setAbortOption(AbortOption ao)
 
784
{
 
785
  switch(ao)
 
786
  {
 
787
    case AO_IgnoreError:
 
788
    case AbortOnError:
 
789
      m_abortOption= ao;
 
790
      return 0;
 
791
    default:
 
792
      return -1;
 
793
  }
 
794
}