MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbOperationInt.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include "API.hpp"
19 #include "Interpreter.hpp"
20 #include <signaldata/AttrInfo.hpp>
21 
22 #ifdef VM_TRACE
23 #include <NdbEnv.h>
24 #define INT_DEBUG(x) \
25  { const char* tmp = NdbEnv_GetEnv("INT_DEBUG", (char*)0, 0); \
26  if (tmp != 0 && strlen(tmp) != 0) { ndbout << "INT:"; ndbout_c x; } }
27 #else
28 #define INT_DEBUG(x)
29 #endif
30 
31 void
32 NdbOperation::initInterpreter(){
33  theFirstLabel = NULL;
34  theLastLabel = NULL;
35  theFirstBranch = NULL;
36  theLastBranch = NULL;
37 
38  theFirstCall = NULL;
39  theLastCall = NULL;
40  theFirstSubroutine = NULL;
41  theLastSubroutine = NULL;
42 
43  theNoOfLabels = 0;
44  theNoOfSubroutines = 0;
45 
46  theSubroutineSize = 0;
47  theInitialReadSize = 0;
48  theInterpretedSize = 0;
49  theFinalUpdateSize = 0;
50  theFinalReadSize = 0;
51  theInterpretIndicator = 1;
52 
53  theTotalCurrAI_Len = AttrInfo::SectionSizeInfoLength;
54 }
55 
56 bool
57 NdbOperation::isNdbRecordOperation()
58 {
59  /* All scans are 'NdbRecord'. For PK and UK access
60  * check if we've got an m_attribute_record set
61  */
62  return !(((m_type == PrimaryKeyAccess) ||
63  (m_type == UniqueIndexAccess)) &&
64  (m_attribute_record == NULL));
65 }
66 
67 int
68 NdbOperation::incCheck(const NdbColumnImpl* tNdbColumnImpl)
69 {
70  if (isNdbRecordOperation()) {
71  /* Wrong API. Use NdbInterpretedCode for NdbRecord operations */
72  setErrorCodeAbort(4537);
73  return -1;
74  }
75 
76  if ((theInterpretIndicator == 1)) {
77  if (tNdbColumnImpl == NULL)
78  goto inc_check_error1;
79  if ((tNdbColumnImpl->getInterpretableType() != true) ||
80  (tNdbColumnImpl->m_pk != false) ||
81  (tNdbColumnImpl->m_nullable))
82  goto inc_check_error2;
83  if (theStatus == ExecInterpretedValue) {
84  ; // Simply continue with interpretation
85  } else if (theStatus == GetValue) {
86  theInitialReadSize = theTotalCurrAI_Len - AttrInfo::SectionSizeInfoLength;
87  theStatus = ExecInterpretedValue;
88  } else if (theStatus == SubroutineExec) {
89  ; // Simply continue with interpretation
90  } else {
91  setErrorCodeAbort(4231);
92  return -1;
93  }
94  if (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK)
95  {
96  m_flags &= ~(Uint8)OF_NO_DISK;
97  }
98  return tNdbColumnImpl->m_attrId;
99  } else {
100  if (theNdbCon->theCommitStatus == NdbTransaction::Started)
101  setErrorCodeAbort(4200);
102  }
103  return -1;
104 
105  inc_check_error1:
106  setErrorCodeAbort(4004);
107  return -1;
108 
109  inc_check_error2:
110  if (tNdbColumnImpl->m_pk){
111  setErrorCodeAbort(4202);
112  return -1;
113  }//if
114  if (!tNdbColumnImpl->getInterpretableType()){
115  setErrorCodeAbort(4217);
116  return -1;
117  }//if
118  if (tNdbColumnImpl->m_nullable){
119  setErrorCodeAbort(4218);
120  return -1;
121  }//if
122  setErrorCodeAbort(4219);
123  return -1;
124 }
125 
126 int
127 NdbOperation::write_attrCheck(const NdbColumnImpl* tNdbColumnImpl)
128 {
129  if (isNdbRecordOperation()) {
130  /* Wrong API. Use NdbInterpretedCode for NdbRecord operations */
131  setErrorCodeAbort(4537);
132  return -1;
133  }
134 
135  if ((theInterpretIndicator == 1)) {
136  if (tNdbColumnImpl == NULL)
137  goto write_attr_check_error1;
138  if ((tNdbColumnImpl->getInterpretableType() == false) ||
139  (tNdbColumnImpl->m_pk))
140  goto write_attr_check_error2;
141  if (theStatus == ExecInterpretedValue) {
142  ; // Simply continue with interpretation
143  } else if (theStatus == SubroutineExec) {
144  ; // Simply continue with interpretation
145  } else {
146  setErrorCodeAbort(4231);
147  return -1;
148  }
149  if (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK)
150  {
151  m_flags &= ~(Uint8)OF_NO_DISK;
152  }
153  return tNdbColumnImpl->m_attrId;
154  } else {
155  if (theNdbCon->theCommitStatus == NdbTransaction::Started)
156  setErrorCodeAbort(4200);
157  }
158  return -1;
159 
160 write_attr_check_error1:
161  setErrorCodeAbort(4004);
162  return -1;
163 
164 write_attr_check_error2:
165  if (tNdbColumnImpl->m_pk) {
166  setErrorCodeAbort(4202);
167  return -1;
168  }//if
169  if (tNdbColumnImpl->getInterpretableType() == false){
170  setErrorCodeAbort(4217);
171  return -1;
172  }//if
173  setErrorCodeAbort(4219);
174  return -1;
175 }
176 
177 int
178 NdbOperation::read_attrCheck(const NdbColumnImpl* tNdbColumnImpl)
179 {
180  if (isNdbRecordOperation()) {
181  /* Wrong API. Use NdbInterpretedCode for NdbRecord operations */
182  setErrorCodeAbort(4537);
183  return -1;
184  }
185 
186  if ((theInterpretIndicator == 1)) {
187  if (tNdbColumnImpl == NULL)
188  goto read_attr_check_error1;
189  if (tNdbColumnImpl->getInterpretableType() == false)
190  goto read_attr_check_error2;
191  if (theStatus == ExecInterpretedValue) {
192  ; // Simply continue with interpretation
193  } else if (theStatus == GetValue) {
194  theInitialReadSize = theTotalCurrAI_Len - AttrInfo::SectionSizeInfoLength;
195  theStatus = ExecInterpretedValue;
196  } else if (theStatus == SubroutineExec) {
197  ; // Simply continue with interpretation
198  } else {
199  setErrorCodeAbort(4231);
200  return -1;
201  }
202  if (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK)
203  {
204  m_flags &= ~(Uint8)OF_NO_DISK;
205  }
206  return tNdbColumnImpl->m_attrId;
207  } else {
208  if (theNdbCon->theCommitStatus == NdbTransaction::Started)
209  setErrorCodeAbort(4200);
210  }
211  return -1;
212 
213  read_attr_check_error1:
214  setErrorCodeAbort(4004);
215  return -1;
216 
217  read_attr_check_error2:
218  if (tNdbColumnImpl->getInterpretableType() == false)
219  setErrorCodeAbort(4217);
220  else
221  setErrorCodeAbort(4219);
222  return -1;
223 
224 }
225 
226 int
227 NdbOperation::initial_interpreterCheck()
228 {
229  if (isNdbRecordOperation()) {
230  /* Wrong API. Use NdbInterpretedCode for NdbRecord operations */
231  setErrorCodeAbort(4537);
232  return -1;
233  }
234 
235  if ((theInterpretIndicator == 1)) {
236  if (theStatus == ExecInterpretedValue) {
237  return 0; // Simply continue with interpretation
238  } else if (theStatus == GetValue) {
239  theInitialReadSize = theTotalCurrAI_Len - AttrInfo::SectionSizeInfoLength;
240  theStatus = ExecInterpretedValue;
241  return 0;
242  } else if (theStatus == SubroutineExec) {
243  return 0; // Simply continue with interpretation
244  } else {
245  setErrorCodeAbort(4231);
246  return -1;
247  }
248  return 0;
249  } else {
250  if (theNdbCon->theCommitStatus == NdbTransaction::Started)
251  setErrorCodeAbort(4200);
252  }
253  return -1;
254 }
255 
256 int
257 NdbOperation::labelCheck()
258 {
259  if (isNdbRecordOperation()) {
260  /* Wrong API. Use NdbInterpretedCode for NdbRecord operations */
261  setErrorCodeAbort(4537);
262  return -1;
263  }
264 
265  if ((theInterpretIndicator == 1)) {
266  if (theStatus == ExecInterpretedValue) {
267  return 0; // Simply continue with interpretation
268  } else if (theStatus == GetValue) {
269  theInitialReadSize = theTotalCurrAI_Len - AttrInfo::SectionSizeInfoLength;
270  theStatus = ExecInterpretedValue;
271  return 0;
272  } else if (theStatus == SubroutineExec) {
273  return 0; // Simply continue with interpretation
274  } else if (theStatus == SubroutineEnd) {
275  theStatus = SubroutineExec;
276  } else {
277  setErrorCodeAbort(4231);
278  return -1;
279  }
280  return 0;
281  } else {
282  if (theNdbCon->theCommitStatus == NdbTransaction::Started)
283  setErrorCodeAbort(4200);
284  }
285  return -1;
286 }
287 
288 int
289 NdbOperation::intermediate_interpreterCheck()
290 {
291  if (isNdbRecordOperation()) {
292  /* Wrong API. Use NdbInterpretedCode for NdbRecord operations */
293  setErrorCodeAbort(4537);
294  return -1;
295  }
296 
297  if ((theInterpretIndicator == 1)) {
298  if (theStatus == ExecInterpretedValue) {
299  return 0; // Simply continue with interpretation
300  } else if (theStatus == SubroutineExec) {
301  return 0; // Simply continue with interpretation
302  } else {
303  setErrorCodeAbort(4231);
304  return -1;
305  }
306  return 0;
307  } else {
308  if (theNdbCon->theCommitStatus == NdbTransaction::Started)
309  setErrorCodeAbort(4200);
310  }
311  return -1;
312 }
313 
314 /*****************************************************************************
315  * int incValue(const char* anAttrName, char* aValue, Uint32 aValue)
316  *
317  * Return Value: Return 0 : incValue was succesful.
318  * Return -1: In all other case.
319  * Parameters: anAttrName : Attribute name where the attribute value
320  * will be save.
321  * aValue : The constant to increment the attribute value with.
322  *****************************************************************************/
323 int
324 NdbOperation::incValue(const NdbColumnImpl* tNdbColumnImpl, Uint32 aValue)
325 {
326  INT_DEBUG(("incValue32 %d %u", tNdbColumnImpl->m_attrId, aValue));
327  int tAttrId;
328 
329  tAttrId = incCheck(tNdbColumnImpl);
330  if (tAttrId == -1)
331  goto incValue_error1;
332 
333 // Load Attribute into register 6
334 
335  if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1)
336  goto incValue_error1;
337 // Load aValue into register 7
338  if (aValue < 65536)
339  {
340  if (insertATTRINFO(Interpreter::LoadConst16(7, aValue)) == -1)
341  goto incValue_error1;
342  } else {
343  if (insertATTRINFO(Interpreter::LoadConst32(7)) == -1)
344  goto incValue_error1;
345  if (insertATTRINFO(aValue) == -1)
346  goto incValue_error1;
347  }
348  // Add register 6 and 7 and put result in register 7
349 
350  if (insertATTRINFO( Interpreter::Add(7, 6, 7)) == -1)
351  goto incValue_error1;
352  if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
353  goto incValue_error1;
354 
355  theErrorLine++;
356  return 0;
357 
358 incValue_error1:
359  return -1;
360 }
361 
362 /*****************************************************************************
363  * int subValue(const char* anAttrName, char* aValue, Uint32 aValue)
364  *
365  * Return Value: Return 0 : incValue was succesful.
366  * Return -1: In all other case.
367  * Parameters: anAttrName : Attribute name where the attribute value
368  * will be save.
369  * aValue : The constant to increment the attribute value with.
370 ******************************************************************************/
371 int
372 NdbOperation::subValue(const NdbColumnImpl* tNdbColumnImpl, Uint32 aValue)
373 {
374  INT_DEBUG(("subValue32 %d %u", tNdbColumnImpl->m_attrId, aValue));
375  int tAttrId;
376 
377  tAttrId = incCheck(tNdbColumnImpl);
378  if (tAttrId == -1)
379  goto subValue_error1;
380 
381 // Load Attribute into register 6
382 
383  if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1)
384  goto subValue_error1;
385 // Load aValue into register 7
386  if (aValue < 65536)
387  {
388  if (insertATTRINFO( Interpreter::LoadConst16(7, aValue)) == -1)
389  goto subValue_error1;
390  } else {
391  if (insertATTRINFO( Interpreter::LoadConst32(7)) == -1)
392  goto subValue_error1;
393  if (insertATTRINFO(aValue) == -1)
394  goto subValue_error1;
395  }
396  // Subtract register 6 and 7 and put result in register 7
397 
398  if (insertATTRINFO( Interpreter::Sub(7, 6, 7)) == -1)
399  goto subValue_error1;
400  if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
401  goto subValue_error1;
402 
403  theErrorLine++;
404  return 0;
405 
406  subValue_error1:
407  return -1;
408 }
409 
410 /******************************************************************************
411  * int incValue(const char* anAttrName, char* aValue, Uint64 aValue)
412  *
413  * Return Value: Return 0 : incValue was succesful.
414  * Return -1: In all other case.
415  * Parameters: anAttrName : Attribute name where the attribute value will
416  * be save.
417  * aValue : The constant to increment the attribute value with.
418  *****************************************************************************/
419 int
420 NdbOperation::incValue(const NdbColumnImpl* tNdbColumnImpl, Uint64 aValue)
421 {
422  INT_DEBUG(("incValue64 %d %llu", tNdbColumnImpl->m_attrId, aValue));
423  int tAttrId;
424 
425  tAttrId = incCheck(tNdbColumnImpl);
426  if (tAttrId == -1)
427  goto incValue_error1;
428 
429 // Load Attribute into register 6
430 
431  if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1)
432  goto incValue_error1;
433 // Load aValue into register 7
434  if (insertATTRINFO( Interpreter::LoadConst64(7)) == -1)
435  goto incValue_error1;
436  if (insertATTRINFOloop((Uint32*)&aValue, 2) == -1)
437  goto incValue_error1;
438  // Add register 6 and 7 and put result in register 7
439  if (insertATTRINFO( Interpreter::Add(7, 6, 7)) == -1)
440  goto incValue_error1;
441  if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
442  goto incValue_error1;
443 
444  theErrorLine++;
445  return 0;
446 
447 incValue_error1:
448  return -1;
449 }
450 
451 /*****************************************************************************
452  * int subValue(const char* anAttrName, char* aValue, Uint64 aValue)
453  *
454  * Return Value: Return 0 : incValue was succesful.
455  * Return -1: In all other case.
456  * Parameters: anAttrName : Attribute name where the attribute value will
457  * be save.
458  * aValue : The constant to increment the attribute value with.
459 ******************************************************************************/
460 int
461 NdbOperation::subValue(const NdbColumnImpl* tNdbColumnImpl, Uint64 aValue)
462 {
463  INT_DEBUG(("subValue64 %d %llu", tNdbColumnImpl->m_attrId, aValue));
464  int tAttrId;
465 
466  tAttrId = incCheck(tNdbColumnImpl);
467  if (tAttrId == -1)
468  goto subValue_error1;
469 
470 // Load Attribute into register 6
471 
472  if (insertATTRINFO( Interpreter::Read(6, tAttrId)) == -1)
473  goto subValue_error1;
474 // Load aValue into register 7
475  if (insertATTRINFO( Interpreter::LoadConst64(7)) == -1)
476  goto subValue_error1;
477  if (insertATTRINFOloop((Uint32*)&aValue, 2) == -1)
478  goto subValue_error1;
479 // Subtract register 6 and 7 and put result in register 7
480  if (insertATTRINFO( Interpreter::Sub(7, 6, 7)) == -1)
481  goto subValue_error1;
482  if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
483  goto subValue_error1;
484 
485  theErrorLine++;
486  return 0;
487 
488 subValue_error1:
489  return -1;
490 }
491 
492 /*****************************************************************************
493  * int NdbOperation::def_label()
494  *****************************************************************************/
495 int
497 {
498  INT_DEBUG(("def_label %d", tLabelNo));
499  Uint32 tLabelIndex;
500  if (labelCheck() == -1)
501  return -1;
502 
503  tLabelIndex = theNoOfLabels - ((theNoOfLabels >> 4) << 4);
504  if (tLabelIndex == 0)
505  {
506  NdbLabel* tNdbLabel = theNdb->getNdbLabel();
507  if (tNdbLabel == NULL)
508  {
509  setErrorCodeAbort(4000);
510  return -1;
511  }
512  if (theFirstLabel == NULL)
513  theFirstLabel = tNdbLabel;
514  else
515  theLastLabel->theNext = tNdbLabel;
516 
517  theLastLabel = tNdbLabel;
518  tNdbLabel->theNext = NULL;
519  }
520 
531  Uint32 initialOffset= theInitialReadSize + AttrInfo::SectionSizeInfoLength;
532 
533  if (theNoOfSubroutines > 0)
534  {
535  /* Label in a sub, needs to be offset from the start of the subroutines
536  * section
537  */
538  initialOffset+= (theInterpretedSize + theFinalUpdateSize + theFinalReadSize);
539 
540  }
541 
542  theLastLabel->theLabelNo[tLabelIndex] = tLabelNo;
543  theLastLabel->theLabelAddress[tLabelIndex] = (theTotalCurrAI_Len + 1) - initialOffset;
544  theLastLabel->theSubroutine[tLabelIndex] = theNoOfSubroutines;
545  theNoOfLabels++;
546  theErrorLine++;
547 
548  return (theNoOfLabels - 1);
549 }
550 
551 /************************************************************************************************
552 int NdbOperation::def_subroutine()
553 
554 ************************************************************************************************/
555 int
557 {
558  INT_DEBUG(("def_subroutine %d", tSubNo));
559  Uint32 tSubroutineIndex;
560 
561  if (theInterpretIndicator != 1)
562  {
563  setErrorCodeAbort(4200);
564  return -1;
565  }
566 
567  if (int(theNoOfSubroutines) != tSubNo)
568  {
569  setErrorCodeAbort(4227);
570  return -1;
571  }
572  if (theStatus == FinalGetValue)
573  {
574  theFinalReadSize = theTotalCurrAI_Len -
575  (theInitialReadSize + theInterpretedSize +
576  theFinalUpdateSize + AttrInfo::SectionSizeInfoLength);
577 
578  } else if (theStatus == SubroutineEnd)
579  {
580  ; // Correct Status, last call was ret_sub()
581  } else if (theStatus == ExecInterpretedValue)
582  {
583  if (insertATTRINFO(Interpreter::EXIT_OK) == -1)
584  return -1;
585  theInterpretedSize = theTotalCurrAI_Len -
586  (theInitialReadSize + AttrInfo::SectionSizeInfoLength);
587  } else if (theStatus == SetValueInterpreted)
588  {
589  theFinalUpdateSize = theTotalCurrAI_Len -
590  (theInitialReadSize + theInterpretedSize +
591  AttrInfo::SectionSizeInfoLength);
592 
593  } else if (theStatus == GetValue)
594  {
595 
596  theInitialReadSize = theTotalCurrAI_Len -
597  AttrInfo::SectionSizeInfoLength;
598 
599  } else
600  {
601  setErrorCodeAbort(4200);
602  return -1;
603  }
604  theStatus = SubroutineExec;
605  tSubroutineIndex = theNoOfSubroutines - ((theNoOfSubroutines >> 4) << 4);
606  if (tSubroutineIndex == 0)
607  {
608  NdbSubroutine* tNdbSubroutine = theNdb->getNdbSubroutine();
609  if (tNdbSubroutine == NULL)
610  {
611  setErrorCodeAbort(4000);
612  return -1;
613  }
614  if (theFirstSubroutine == NULL)
615  theFirstSubroutine = tNdbSubroutine;
616  else
617  theLastSubroutine->theNext = tNdbSubroutine;
618 
619  theLastSubroutine = tNdbSubroutine;
620  tNdbSubroutine->theNext = NULL;
621  }
622  theLastSubroutine->theSubroutineAddress[tSubroutineIndex] = theTotalCurrAI_Len -
623  (AttrInfo::SectionSizeInfoLength + theInitialReadSize + theInterpretedSize +
624  theFinalUpdateSize + theFinalReadSize); // Preceding sections + sizes array
625 
626  theNoOfSubroutines++;
627  theErrorLine++;
628  return (theNoOfSubroutines - 1);
629 }
630 
631 /************************************************************************************************
632 int NdbOperation::add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
633 
634 ************************************************************************************************/
635 int
636 NdbOperation::add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
637 {
638  INT_DEBUG(("add_reg %u %u %u", RegSource1, RegSource2, RegDest));
639  if (intermediate_interpreterCheck() == -1)
640  return -1;
641 
642  if (RegSource1 >= 8)
643  {
644  setErrorCodeAbort(4229);
645  return -1;
646  }
647  if (RegSource2 >= 8)
648  {
649  setErrorCodeAbort(4229);
650  return -1;
651  }
652  if (RegDest >= 8)
653  {
654  setErrorCodeAbort(4229);
655  return -1;
656  }
657  if (insertATTRINFO( Interpreter::Add(RegDest, RegSource1, RegSource2)) == -1)
658  return -1;
659  theErrorLine++;
660  return 0;
661 }
662 
663 /************************************************************************************************
664 int NdbOperation::sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
665 
666 ************************************************************************************************/
667 int
668 NdbOperation::sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
669 {
670  INT_DEBUG(("sub_reg %u %u %u", RegSource1, RegSource2, RegDest));
671  if (intermediate_interpreterCheck() == -1)
672  return -1;
673 
674  if (RegSource1 >= 8)
675  {
676  setErrorCodeAbort(4229);
677  return -1;
678  }
679  if (RegSource2 >= 8)
680  {
681  setErrorCodeAbort(4229);
682  return -1;
683  }
684  if (RegDest >= 8)
685  {
686  setErrorCodeAbort(4229);
687  return -1;
688  }
689  if (insertATTRINFO( Interpreter::Sub(RegDest, RegSource1, RegSource2)) == -1)
690  return -1;
691  theErrorLine++;
692  return 0;
693 }
694 
695 /************************************************************************************************
696 int NdbOperation::load_const_u32(Uint32 RegDest, Uint32 Constant)
697 
698 ************************************************************************************************/
699 int
700 NdbOperation::load_const_u32(Uint32 RegDest, Uint32 Constant)
701 {
702  INT_DEBUG(("load_const_u32 %u %u", RegDest, Constant));
703  if (initial_interpreterCheck() == -1)
704  goto l_u32_error1;
705  if (RegDest >= 8)
706  goto l_u32_error2;
707  if (insertATTRINFO( Interpreter::LoadConst32(RegDest)) == -1)
708  goto l_u32_error1;
709  if (insertATTRINFO(Constant) == -1)
710  goto l_u32_error1;
711  theErrorLine++;
712  return 0;
713 
714  l_u32_error1:
715  return -1;
716 
717  l_u32_error2:
718  setErrorCodeAbort(4229);
719  return -1;
720 }
721 
722 /************************************************************************************************
723 int NdbOperation::load_const_u64(Uint32 RegDest, Uint64 Constant)
724 
725 ************************************************************************************************/
726 int
727 NdbOperation::load_const_u64(Uint32 RegDest, Uint64 Constant)
728 {
729  INT_DEBUG(("load_const_u64 %u %llu", RegDest, Constant));
730  if (initial_interpreterCheck() == -1)
731  return -1;
732  if (RegDest >= 8)
733  {
734  setErrorCodeAbort(4229);
735  return -1;
736  }
737 
738  // 64 bit value
739  if (insertATTRINFO( Interpreter::LoadConst64(RegDest)) == -1)
740  return -1;
741  if (insertATTRINFOloop((Uint32*)&Constant, 2) == -1)
742  return -1;
743  theErrorLine++;
744  return 0;
745 }
746 
747 /************************************************************************************************
748 int NdbOperation::load_const_null(Uint32 RegDest)
749 
750 ************************************************************************************************/
751 int
753 {
754  INT_DEBUG(("load_const_null %u", RegDest));
755  if (initial_interpreterCheck() == -1)
756  return -1;
757  if (RegDest >= 8)
758  {
759  setErrorCodeAbort(4229);
760  return -1;
761  }
762  if (insertATTRINFO( Interpreter::LOAD_CONST_NULL) == -1)
763  return -1;
764  theErrorLine++;
765  return 0;
766 }
767 
768 /************************************************************************************************
769 int NdbOperation::read_attr(const char* anAttrName, Uint32 RegDest)
770 
771 ************************************************************************************************/
772 int
773 NdbOperation::read_attr(const NdbColumnImpl* anAttrObject, Uint32 RegDest)
774 {
775  INT_DEBUG(("read_attr %d %u", anAttrObject->m_attrId, RegDest));
776  if (initial_interpreterCheck() == -1)
777  return -1;
778 
779  int tAttrId = read_attrCheck(anAttrObject);
780  if (tAttrId == -1)
781  goto read_attr_error1;
782  if (RegDest >= 8)
783  goto read_attr_error2;
784  if (insertATTRINFO( Interpreter::Read(tAttrId, RegDest)) != -1) {
785  return 0;
786  theErrorLine++;
787  }//if
788  return -1;
789 
790 read_attr_error1:
791  return -1;
792 
793 read_attr_error2:
794  setErrorCodeAbort(4229);
795  return -1;
796 }
797 
798 /************************************************************************************************
799 int NdbOperation::write_attr(const char* anAttrName, Uint32 RegSource)
800 
801 ************************************************************************************************/
802 int
803 NdbOperation::write_attr(const NdbColumnImpl* anAttrObject, Uint32 RegSource)
804 {
805  INT_DEBUG(("write_attr %d %u", anAttrObject->m_attrId, RegSource));
806  int tAttrId = write_attrCheck(anAttrObject);
807  if (tAttrId == -1)
808  return -1;
809  if (insertATTRINFO( Interpreter::Write(tAttrId, RegSource)) == -1)
810  return -1;
811  theErrorLine++;
812  return 0;
813 }
814 
815 int
816 NdbOperation::branch_reg_reg(Uint32 type,
817  Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
818 {
819  if (intermediate_interpreterCheck() == -1)
820  return -1;
821  if (insertATTRINFO(Interpreter::Branch(type, RegLvalue, RegRvalue)) == -1)
822  return -1;
823  if (insertBranch(Label) == -1)
824  return -1;
825  theErrorLine++;
826  return 0;
827 }
828 
829 int
830 NdbOperation::branch_ge(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
831 {
832  INT_DEBUG(("branch_ge %u %u %u", RegLvalue, RegRvalue, Label));
833  return branch_reg_reg(Interpreter::BRANCH_GE_REG_REG,
834  RegLvalue, RegRvalue, Label);
835 }
836 
837 int
838 NdbOperation::branch_gt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
839 {
840  INT_DEBUG(("branch_gt %u %u %u", RegLvalue, RegRvalue, Label));
841  return branch_reg_reg(Interpreter::BRANCH_GT_REG_REG,
842  RegLvalue, RegRvalue, Label);
843 }
844 
845 int
846 NdbOperation::branch_le(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
847 {
848  INT_DEBUG(("branch_le %u %u %u", RegLvalue, RegRvalue, Label));
849  return branch_reg_reg(Interpreter::BRANCH_LE_REG_REG,
850  RegLvalue, RegRvalue, Label);
851 }
852 
853 int
854 NdbOperation::branch_lt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
855 {
856  INT_DEBUG(("branch_lt %u %u %u", RegLvalue, RegRvalue, Label));
857  return branch_reg_reg(Interpreter::BRANCH_LT_REG_REG,
858  RegLvalue, RegRvalue, Label);
859 }
860 
861 int
862 NdbOperation::branch_eq(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
863 {
864  INT_DEBUG(("branch_eq %u %u %u", RegLvalue, RegRvalue, Label));
865  return branch_reg_reg(Interpreter::BRANCH_EQ_REG_REG,
866  RegLvalue, RegRvalue, Label);
867 }
868 
869 int
870 NdbOperation::branch_ne(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
871 {
872  INT_DEBUG(("branch_ne %u %u %u", RegLvalue, RegRvalue, Label));
873  return branch_reg_reg(Interpreter::BRANCH_NE_REG_REG,
874  RegLvalue, RegRvalue, Label);
875 }
876 
877 int
878 NdbOperation::branch_ne_null(Uint32 RegLvalue, Uint32 Label)
879 {
880  INT_DEBUG(("branch_ne_null %u %u", RegLvalue, Label));
881  if (intermediate_interpreterCheck() == -1)
882  return -1;
883  if (insertATTRINFO((RegLvalue << 6) + Interpreter::BRANCH_REG_NE_NULL) == -1)
884  return -1;
885  if (insertBranch(Label) == -1)
886  return -1;
887  theErrorLine++;
888  return 0;
889 }
890 
891 int
892 NdbOperation::branch_eq_null(Uint32 RegLvalue, Uint32 Label)
893 {
894  INT_DEBUG(("branch_eq_null %u %u", RegLvalue, Label));
895  if (intermediate_interpreterCheck() == -1)
896  return -1;
897  if (insertATTRINFO((RegLvalue << 6) + Interpreter::BRANCH_REG_EQ_NULL) == -1)
898  return -1;
899  if (insertBranch(Label) == -1)
900  return -1;
901  theErrorLine++;
902  return 0;
903 }
904 
905 int
907 {
908  INT_DEBUG(("branch_label %u", Label));
909  if (initial_interpreterCheck() == -1)
910  return -1;
911  if (insertATTRINFO(Interpreter::BRANCH) == -1)
912  return -1;
913  if (insertBranch(Label) == -1)
914  return -1;
915  theErrorLine++;
916  return 0;
917 }
918 
919 /************************************************************************************************
920 int NdbOperation::interpret_exit_ok()
921 
922 ************************************************************************************************/
923 int
925 {
926  INT_DEBUG(("interpret_exit_ok"));
927  if (initial_interpreterCheck() == -1)
928  return -1;
929  if (insertATTRINFO(Interpreter::EXIT_OK) == -1)
930  return -1;
931  theErrorLine++;
932  return 0;
933 }
934 
935 int
937 {
938  INT_DEBUG(("interpret_exit_last_row"));
939  if (initial_interpreterCheck() == -1)
940  return -1;
941  if (insertATTRINFO(Interpreter::EXIT_OK_LAST) == -1)
942  return -1;
943  theErrorLine++;
944  return 0;
945 }
946 
947 /************************************************************************************************
948 int NdbOperation::interpret_exit_nok(Uint32 ErrorCode)
949 
950 ************************************************************************************************/
951 int
953 {
954  INT_DEBUG(("interpret_exit_nok %u", ErrorCode));
955  if (initial_interpreterCheck() == -1)
956  return -1;
957  if (insertATTRINFO( (ErrorCode << 16) + Interpreter::EXIT_REFUSE) == -1)
958  return -1;
959  theErrorLine++;
960  return 0;
961 }
962 
963 int
964 NdbOperation::interpret_exit_nok()
965 {
966  INT_DEBUG(("interpret_exit_nok"));
967  Uint32 ErrorCode = 899;
968 
969  if (initial_interpreterCheck() == -1)
970  return -1;
971  if (insertATTRINFO( (ErrorCode << 16) + Interpreter::EXIT_REFUSE) == -1)
972  return -1;
973  theErrorLine++;
974  return 0;
975 }
976 
977 int
978 NdbOperation::call_sub(Uint32 Subroutine)
979 {
980  INT_DEBUG(("call_sub %u", Subroutine));
981  if (initial_interpreterCheck() == -1)
982  return -1;
983  if (insertATTRINFO( (Subroutine << 16) + Interpreter::CALL) == -1)
984  return -1;
985  if (insertCall(Subroutine) == -1)
986  return -1;
987  theErrorLine++;
988  return 0;
989 }
990 
991 int
993 {
994  INT_DEBUG(("ret_sub"));
995  if (theInterpretIndicator != 1)
996  {
997  setErrorCodeAbort(4200);
998  return -1;
999  }
1000  if (theStatus == SubroutineExec)
1001  {
1002  ; // Simply continue with interpretation
1003  } else
1004  {
1005  setErrorCodeAbort(4200);
1006  return -1;
1007  }
1008  if (insertATTRINFO(Interpreter::RETURN) == -1)
1009  return -1;
1010  theStatus = SubroutineEnd;
1011  theErrorLine++;
1012  return 0;
1013 }
1014 
1015 int
1016 NdbOperation::insertBranch(Uint32 aLabel)
1017 {
1018  Uint32 tAddress;
1019  NdbBranch* tBranch = theNdb->getNdbBranch();
1020  if (tBranch == NULL)
1021  goto insertBranch_error1;
1022  if (theFirstBranch == NULL)
1023  theFirstBranch = tBranch;
1024  else
1025  theLastBranch->theNext = tBranch;
1026  theLastBranch = tBranch;
1027  if (theNoOfSubroutines == 0)
1028  tAddress = theTotalCurrAI_Len -
1029  (theInitialReadSize + AttrInfo::SectionSizeInfoLength);
1030  else
1031  tAddress = theTotalCurrAI_Len -
1032  (theInitialReadSize + theInterpretedSize +
1033  theFinalUpdateSize + theFinalReadSize + AttrInfo::SectionSizeInfoLength);
1034 
1035  tBranch->theBranchAddress = tAddress;
1036  tBranch->theSignal = theCurrentATTRINFO;
1037  tBranch->theSignalAddress = theAI_LenInCurrAI; // + 1; theAI_LenInCurrAI has already been updated in
1038  tBranch->theSubroutine = theNoOfSubroutines; // insertATTRINFO which was done before insertBranch!!
1039  tBranch->theBranchLabel = aLabel;
1040  return 0;
1041 
1042 insertBranch_error1:
1043  setErrorCodeAbort(4000);
1044  return -1;
1045 }
1046 
1047 int
1048 NdbOperation::insertCall(Uint32 aCall)
1049 {
1050  NdbCall* tCall = theNdb->getNdbCall();
1051  if (tCall == NULL)
1052  {
1053  setErrorCodeAbort(4000);
1054  return -1;
1055  }
1056  if (theFirstCall == NULL)
1057  theFirstCall = tCall;
1058  else
1059  theLastCall->theNext = tCall;
1060  theLastCall = tCall;
1061 
1062  tCall->theSignal = theCurrentATTRINFO;
1063  tCall->theSignalAddress = theAI_LenInCurrAI;
1064  tCall->theSubroutine = aCall;
1065  return 0;
1066 }
1067 
1068 int
1069 NdbOperation::branch_col(Uint32 type,
1070  Uint32 ColId, const void * val, Uint32 len,
1071  Uint32 Label){
1072 
1073  DBUG_ENTER("NdbOperation::branch_col");
1074  DBUG_PRINT("enter", ("type: %u col:%u val: 0x%lx len: %u label: %u",
1075  type, ColId, (long) val, len, Label));
1076  if (val != NULL)
1077  DBUG_DUMP("value", (uchar*)val, len);
1078 
1079  if (initial_interpreterCheck() == -1)
1080  DBUG_RETURN(-1);
1081 
1082  Interpreter::BinaryCondition c = (Interpreter::BinaryCondition)type;
1083 
1084  const NdbColumnImpl * col =
1085  m_currentTable->getColumn(ColId);
1086 
1087  if(col == 0){
1088  abort();
1089  }
1090 
1091  Uint32 lastWordMask= ~0;
1092  if (val == NULL)
1093  len = 0;
1094  else {
1095  if (! col->getStringType())
1096  {
1097  /* Fixed size type */
1098  if (col->getType() == NDB_TYPE_BIT)
1099  {
1100  /* We want to zero out insignificant bits in the
1101  * last word of a bit type
1102  */
1103  Uint32 bitLen= col->getLength();
1104  Uint32 lastWordBits= bitLen & 0x1F;
1105  if (lastWordBits)
1106  lastWordMask= (1 << lastWordBits) -1;
1107  }
1108  len= col->m_attrSize * col->m_arraySize;
1109  }
1110  else
1111  {
1112  /* For Like and Not like we must use the passed in
1113  * length. Otherwise we use the length encoded
1114  * in the passed string
1115  */
1116  if ((type != Interpreter::LIKE) &&
1117  (type != Interpreter::NOT_LIKE))
1118  {
1119  if (! col->get_var_length(val, len))
1120  {
1121  setErrorCodeAbort(4209);
1122  DBUG_RETURN(-1);
1123  }
1124  }
1125  }
1126  }
1127 
1128  if (col->m_storageType == NDB_STORAGETYPE_DISK)
1129  {
1130  m_flags &= ~(Uint8)OF_NO_DISK;
1131  }
1132 
1133  Uint32 tempData[ NDB_MAX_TUPLE_SIZE_IN_WORDS ];
1134  if (((UintPtr)val & 3) != 0) {
1135  memcpy(tempData, val, len);
1136  val = tempData;
1137  }
1138 
1139  if (insertATTRINFO(Interpreter::BranchCol(c, 0, 0)) == -1)
1140  DBUG_RETURN(-1);
1141 
1142  if (insertBranch(Label) == -1)
1143  DBUG_RETURN(-1);
1144 
1145  if (insertATTRINFO(Interpreter::BranchCol_2(col->m_attrId, len)))
1146  DBUG_RETURN(-1);
1147 
1148  Uint32 len2 = Interpreter::mod4(len);
1149  if((len2 == len) &&
1150  (lastWordMask == (Uint32)~0)){
1151  insertATTRINFOloop((Uint32*)val, len2 >> 2);
1152  } else {
1153  len2 -= 4;
1154  insertATTRINFOloop((Uint32*)val, len2 >> 2);
1155  Uint32 tmp = 0;
1156  for (Uint32 i = 0; i < len-len2; i++) {
1157  char* p = (char*)&tmp;
1158  p[i] = ((char*)val)[len2+i];
1159  }
1160  insertATTRINFO(tmp & lastWordMask);
1161  }
1162 
1163  theErrorLine++;
1164  DBUG_RETURN(0);
1165 }
1166 
1167 int
1168 NdbOperation::branch_col_eq(Uint32 ColId, const void * val, Uint32 len,
1169  bool nopad, Uint32 Label){
1170  INT_DEBUG(("branch_col_eq %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1171  nopad, Label));
1172  return branch_col(Interpreter::EQ, ColId, val, len, Label);
1173 }
1174 
1175 int
1176 NdbOperation::branch_col_ne(Uint32 ColId, const void * val, Uint32 len,
1177  bool nopad, Uint32 Label){
1178  INT_DEBUG(("branch_col_ne %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1179  nopad, Label));
1180  return branch_col(Interpreter::NE, ColId, val, len, Label);
1181 }
1182 int
1183 NdbOperation::branch_col_lt(Uint32 ColId, const void * val, Uint32 len,
1184  bool nopad, Uint32 Label){
1185  INT_DEBUG(("branch_col_lt %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1186  nopad, Label));
1187  return branch_col(Interpreter::LT, ColId, val, len, Label);
1188 }
1189 int
1190 NdbOperation::branch_col_le(Uint32 ColId, const void * val, Uint32 len,
1191  bool nopad, Uint32 Label){
1192  INT_DEBUG(("branch_col_le %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1193  nopad, Label));
1194  return branch_col(Interpreter::LE, ColId, val, len, Label);
1195 }
1196 int
1197 NdbOperation::branch_col_gt(Uint32 ColId, const void * val, Uint32 len,
1198  bool nopad, Uint32 Label){
1199  INT_DEBUG(("branch_col_gt %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1200  nopad, Label));
1201  return branch_col(Interpreter::GT, ColId, val, len, Label);
1202 }
1203 
1204 int
1205 NdbOperation::branch_col_ge(Uint32 ColId, const void * val, Uint32 len,
1206  bool nopad, Uint32 Label){
1207  INT_DEBUG(("branch_col_ge %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1208  nopad, Label));
1209  return branch_col(Interpreter::GE, ColId, val, len, Label);
1210 }
1211 
1212 int
1213 NdbOperation::branch_col_like(Uint32 ColId, const void * val, Uint32 len,
1214  bool nopad, Uint32 Label){
1215  INT_DEBUG(("branch_col_like %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1216  nopad, Label));
1217  return branch_col(Interpreter::LIKE, ColId, val, len, Label);
1218 }
1219 
1220 int
1221 NdbOperation::branch_col_notlike(Uint32 ColId, const void * val, Uint32 len,
1222  bool nopad, Uint32 Label){
1223  INT_DEBUG(("branch_col_notlike %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
1224  nopad, Label));
1225  return branch_col(Interpreter::NOT_LIKE, ColId, val, len, Label);
1226 }
1227 
1228 int
1229 NdbOperation::branch_col_and_mask_eq_mask(Uint32 ColId, const void * mask,
1230  Uint32 len, bool nopad, Uint32 Label){
1231  INT_DEBUG(("branch_col_and_mask_eq_mask %u %.*s(%u,%d) -> %u", ColId, len, (char*) mask, len,
1232  nopad, Label));
1233  return branch_col(Interpreter::AND_EQ_MASK, ColId, mask, len, Label);
1234 }
1235 
1236 int
1237 NdbOperation::branch_col_and_mask_ne_mask(Uint32 ColId, const void * mask,
1238  Uint32 len, bool nopad, Uint32 Label){
1239  INT_DEBUG(("branch_col_and_mask_ne_mask %u %.*s(%u,%d) -> %u", ColId, len, (char*) mask, len,
1240  nopad, Label));
1241  return branch_col(Interpreter::AND_NE_MASK, ColId, mask, len, Label);
1242 }
1243 
1244 int
1245 NdbOperation::branch_col_and_mask_eq_zero(Uint32 ColId, const void * mask,
1246  Uint32 len, bool nopad, Uint32 Label){
1247  INT_DEBUG(("branch_col_and_mask_eq_zero %u %.*s(%u,%d) -> %u", ColId, len, (char*) mask, len,
1248  nopad, Label));
1249  return branch_col(Interpreter::AND_EQ_ZERO, ColId, mask, len, Label);
1250 }
1251 
1252 int
1253 NdbOperation::branch_col_and_mask_ne_zero(Uint32 ColId, const void * mask,
1254  Uint32 len, bool nopad, Uint32 Label){
1255  INT_DEBUG(("branch_col_and_mask_ne_zero %u %.*s(%u,%d) -> %u", ColId, len, (char*) mask, len,
1256  nopad, Label));
1257  return branch_col(Interpreter::AND_NE_ZERO, ColId, mask, len, Label);
1258 }
1259 
1260 int
1261 NdbOperation::branch_col_null(Uint32 type, Uint32 ColId, Uint32 Label){
1262 
1263  if (initial_interpreterCheck() == -1)
1264  return -1;
1265 
1266  if (insertATTRINFO(type) == -1)
1267  return -1;
1268 
1269  if (insertBranch(Label) == -1)
1270  return -1;
1271 
1272  Uint32 attrId=
1273  NdbColumnImpl::getImpl(* m_currentTable->getColumn(ColId)).m_attrId;
1274 
1275  if (insertATTRINFO(Interpreter::BranchCol_2(attrId)))
1276  return -1;
1277 
1278  theErrorLine++;
1279  return 0;
1280 }
1281 
1282 int
1283 NdbOperation::branch_col_eq_null(Uint32 ColId, Uint32 Label){
1284 
1285  INT_DEBUG(("branch_col_eq_null %u -> %u", ColId, Label));
1286  return branch_col_null(Interpreter::BRANCH_ATTR_EQ_NULL, ColId, Label);
1287 }
1288 
1289 int
1290 NdbOperation::branch_col_ne_null(Uint32 ColId, Uint32 Label){
1291 
1292  INT_DEBUG(("branch_col_ne_null %u -> %u", ColId, Label));
1293  return branch_col_null(Interpreter::BRANCH_ATTR_NE_NULL, ColId, Label);
1294 }
1295