Dbtup.hpp 106 KB
Newer Older
1 2 3 4
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
5
   the Free Software Foundation; version 2 of the License.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef DBTUP_H
#define DBTUP_H

#include <pc.hpp>
#include <SimulatedBlock.hpp>
#include <ndb_limits.h>
#include <trigger_definitions.h>
#include <AttributeHeader.hpp>
#include <Bitmask.hpp>
#include <signaldata/TupKey.hpp>
#include <signaldata/CreateTrig.hpp>
#include <signaldata/DropTrig.hpp>
#include <signaldata/TrigAttrInfo.hpp>
#include <signaldata/BuildIndx.hpp>
unknown's avatar
unknown committed
30 31 32 33
#include "Undo_buffer.hpp"
#include "tuppage.hpp"
#include <../pgman.hpp>
#include <../tsman.hpp>
34

35 36 37 38 39 40 41 42 43
#ifdef VM_TRACE
inline const char* dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS>& bm) {
  static int i=0; static char buf[5][200];
  bm.getText(buf[i%5]); return buf[i++%5]; }
inline const char* dbgmask(const Uint32 bm[2]) {
  static int i=0; static char buf[5][200];
  sprintf(buf[i%5],"%08x%08x",bm[1],bm[0]); return buf[i++%5]; }
#endif

44 45 46 47
#define ZWORDS_ON_PAGE 8192          /* NUMBER OF WORDS ON A PAGE.      */
#define ZATTRBUF_SIZE 32             /* SIZE OF ATTRIBUTE RECORD BUFFER */
#define ZMIN_PAGE_LIMIT_TUPKEYREQ 5
#define ZTUP_VERSION_BITS 15
unknown's avatar
unknown committed
48 49 50 51 52 53 54 55 56 57 58 59
#define ZTUP_VERSION_MASK ((1 << ZTUP_VERSION_BITS) - 1)
#define MAX_FREE_LIST 4

inline Uint32* ALIGN_WORD(void * ptr)
{
  return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
}

inline const Uint32* ALIGN_WORD(const void* ptr)
{
  return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
}
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

#ifdef DBTUP_C
//------------------------------------------------------------------
// Jam Handling:
//
// When DBTUP reports lines through jam in the trace files it has to
// be interpreted. 4024 means as an example line 24 in DbtupCommit.cpp
// Thus 4000 is added to the line number beacuse it is located in the
// file DbtupCommit.cpp. The following is the exhaustive list of the
// added value in the various files. ndbrequire, ptrCheckGuard still
// only reports the line number in the file it currently is located in.
// 
// DbtupExecQuery.cpp         0
// DbtupBuffer.cpp         2000
// DbtupRoutines.cpp       3000
// DbtupCommit.cpp         5000
// DbtupFixAlloc.cpp       6000
// DbtupTrigger.cpp        7000
// DbtupAbort.cpp          9000
// DbtupPageMap.cpp       14000
// DbtupPagMan.cpp        16000
// DbtupStoredProcDef.cpp 18000
// DbtupMeta.cpp          20000
// DbtupTabDesMan.cpp     22000
// DbtupGen.cpp           24000
// DbtupIndex.cpp         28000
// DbtupDebug.cpp         30000
unknown's avatar
unknown committed
87 88
// DbtupVarAlloc.cpp      32000
// DbtupScan.cpp          33000
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//------------------------------------------------------------------

/*
2.2 LOCAL SYMBOLS
-----------------
*/
/* ---------------------------------------------------------------- */
/*       S I Z E              O F               R E C O R D S       */
/* ---------------------------------------------------------------- */
#define ZNO_OF_ATTRBUFREC 10000             /* SIZE   OF ATTRIBUTE INFO FILE   */
#define ZNO_OF_CONCURRENT_OPEN_OP 40        /* NUMBER OF CONCURRENT OPENS      */
#define ZNO_OF_CONCURRENT_WRITE_OP 80       /* NUMBER OF CONCURRENT DISK WRITES*/
#define ZNO_OF_FRAGOPREC 20                 /* NUMBER OF CONCURRENT ADD FRAG.  */
#define TOT_PAGE_RECORD_SPACE 262144        /* SIZE OF PAGE RECORD FILE.       */
#define ZNO_OF_PAGE TOT_PAGE_RECORD_SPACE/ZWORDS_ON_PAGE   
#define ZNO_OF_PAGE_RANGE_REC 128           /* SIZE OF PAGE RANGE FILE         */
// Trigger constants
#define ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE 16

/* ---------------------------------------------------------------- */
/* A ATTRIBUTE MAY BE NULL, DYNAMIC OR NORMAL. A NORMAL ATTRIBUTE   */
/* IS A ATTRIBUTE THAT IS NOT NULL OR DYNAMIC. A NULL ATTRIBUTE     */
/* MAY HAVE NO VALUE. A DYNAMIC ATTRIBUTE IS A NULL ATTRIBUTE THAT  */
/* DOES NOT HAVE TO BE A MEMBER OF EVERY TUPLE I A CERTAIN TABLE.   */
/* ---------------------------------------------------------------- */
/**
 * #defines moved into include/kernel/Interpreter.hpp
 */
#define ZINSERT_DELETE 0
unknown's avatar
unknown committed
118
#define ZUPDATE_ALL 8
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
/* ---------------------------------------------------------------- */
/* THE MINIMUM SIZE OF AN 'EMPTY' TUPLE HEADER IN R-WORDS           */
/* ---------------------------------------------------------------- */
          /* THE TUPLE HEADER FIELD 'SIZE OF NULL ATTR. FIELD' SPECIFYES    */
          /* THE SIZE OF THE TUPLE HEADER FIELD 'NULL ATTR. FIELD'.         */
          /* THE TUPLE HEADER FIELD 'TYPE' SPECIFYES THE TYPE OF THE TUPLE  */
          /* HEADER.                                                        */
                               /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
                               /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER.  */
                               /* IT MAY ALSO CONTAIN SHORT ATTRIBUTES AND  */
                               /* POINTERS TO LONG ATTRIBUTE HEADERS.       */
                               /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
                               /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER.  */

          /* DATA STRUCTURE TYPES */
          /* WHEN ATTRIBUTE INFO IS SENT WITH A ATTRINFO-SIGNAL THE         */
          /* VARIABLE TYPE IS SPECIFYED. THIS MUST BE DONE TO BE ABLE TO    */
          /* NOW HOW MUCH DATA OF A ATTRIBUTE TO READ FROM ATTRINFO.        */

          /* WHEN A REQUEST CAN NOT BE EXECUTED BECAUSE OF A ERROR THE      */
          /* ERROR MUST BE IDENTIFYED BY MEANS OF A ERROR CODE AND SENT TO  */
          /* THE REQUESTER.                                                 */
#define ZGET_OPREC_ERROR 804            // TUP_SEIZEREF

#define ZEXIST_FRAG_ERROR 816           // Add fragment
#define ZFULL_FRAGRECORD_ERROR 817      // Add fragment
#define ZNO_FREE_PAGE_RANGE_ERROR 818   // Add fragment
#define ZNOFREE_FRAGOP_ERROR 830        // Add fragment
#define ZTOO_LARGE_TUPLE_ERROR 851      // Add fragment
#define ZNO_FREE_TAB_ENTRY_ERROR 852    // Add fragment
#define ZNO_PAGES_ALLOCATED_ERROR 881   // Add fragment

#define ZGET_REALPID_ERROR 809
#define ZNOT_IMPLEMENTED_ERROR 812
#define ZSEIZE_ATTRINBUFREC_ERROR 805
#define ZTOO_MUCH_ATTRINFO_ERROR 823
#define ZMEM_NOTABDESCR_ERROR 826
#define ZMEM_NOMEM_ERROR 827
#define ZAI_INCONSISTENCY_ERROR 829
#define ZNO_ILLEGAL_NULL_ATTR 839
#define ZNOT_NULL_ATTR 840
#define ZNO_INSTRUCTION_ERROR 871
#define ZOUTSIDE_OF_PROGRAM_ERROR 876
#define ZSTORED_PROC_ID_ERROR 877
#define ZREGISTER_INIT_ERROR 878
#define ZATTRIBUTE_ID_ERROR 879
#define ZTRY_TO_READ_TOO_MUCH_ERROR 880
#define ZTOTAL_LEN_ERROR 882
#define ZATTR_INTERPRETER_ERROR 883
#define ZSTACK_OVERFLOW_ERROR 884
#define ZSTACK_UNDERFLOW_ERROR 885
#define ZTOO_MANY_INSTRUCTIONS_ERROR 886
#define ZTRY_TO_UPDATE_ERROR 888
#define ZCALL_ERROR 890
#define ZTEMPORARY_RESOURCE_FAILURE 891
unknown's avatar
unknown committed
174
#define ZUNSUPPORTED_BRANCH 892
175 176 177 178 179 180 181 182 183 184 185 186

#define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan

#define ZREAD_ONLY_CONSTRAINT_VIOLATION 893
#define ZVAR_SIZED_NOT_SUPPORTED 894
#define ZINCONSISTENT_NULL_ATTRIBUTE_COUNT 895
#define ZTUPLE_CORRUPTED_ERROR 896
#define ZTRY_UPDATE_PRIMARY_KEY 897
#define ZMUST_BE_ABORTED_ERROR 898
#define ZTUPLE_DELETED_ERROR 626
#define ZINSERT_ERROR 630

unknown's avatar
unknown committed
187
#define ZINVALID_CHAR_FORMAT 744
unknown's avatar
unknown committed
188
#define ZROWID_ALLOCATED 899
189 190

          /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */
unknown's avatar
unknown committed
191

192 193 194 195
#define ZFREE_COMMON 1                    /* PAGE STATE, PAGE IN COMMON AREA                   */
#define ZEMPTY_MM 2                       /* PAGE STATE, PAGE IN EMPTY LIST                    */
#define ZTH_MM_FREE 3                     /* PAGE STATE, TUPLE HEADER PAGE WITH FREE AREA      */
#define ZTH_MM_FULL 4                     /* PAGE STATE, TUPLE HEADER PAGE WHICH IS FULL       */
unknown's avatar
unknown committed
196

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
#define ZTD_HEADER 0                      /* HEADER POSITION                   */
#define ZTD_DATASIZE 1                    /* SIZE OF THE DATA IN THIS CHUNK    */
#define ZTD_SIZE 2                        /* TOTAL SIZE OF TABLE DESCRIPTOR    */

          /* TRAILER POSITIONS FROM END OF TABLE DESCRIPTOR RECORD               */
#define ZTD_TR_SIZE 1                     /* SIZE DESCRIPTOR POS FROM END+1    */
#define ZTD_TR_TYPE 2
#define ZTD_TRAILER_SIZE 2                /* TOTAL SIZE OF TABLE TRAILER       */
#define ZAD_SIZE 2                        /* TOTAL SIZE OF ATTR DESCRIPTOR     */
#define ZAD_LOG_SIZE 1                    /* TWO LOG OF TOTAL SIZE OF ATTR DESCRIPTOR     */

          /* CONSTANTS USED TO HANDLE TABLE DESCRIPTOR AS A FREELIST             */
#define ZTD_FL_HEADER 0                   /* HEADER POSITION                   */
#define ZTD_FL_SIZE 1                     /* TOTAL SIZE OF THIS FREELIST ENTRY */
#define ZTD_FL_PREV 2                     /* PREVIOUS RECORD IN FREELIST       */
#define ZTD_FL_NEXT 3                     /* NEXT RECORD IN FREELIST           */
#define ZTD_FREE_SIZE 16                  /* SIZE NEEDED TO HOLD ONE FL ENTRY  */

          /* CONSTANTS USED IN LSB OF TABLE DESCRIPTOR HEADER DESCRIBING USAGE   */
#define ZTD_TYPE_FREE 0                   /* RECORD LINKED INTO FREELIST       */
#define ZTD_TYPE_NORMAL 1                 /* RECORD USED AS TABLE DESCRIPTOR   */
          /* ATTRIBUTE OPERATION CONSTANTS */
#define ZLEAF 1
#define ZNON_LEAF 2

          /* ATTRINBUFREC VARIABLE POSITIONS. */
#define ZBUF_PREV 29                      /* POSITION OF 'PREV'-VARIABLE (USED BY INTERPRETED EXEC) */
#define ZBUF_DATA_LEN 30                  /* POSITION OF 'DATA LENGTH'-VARIABLE. */
#define ZBUF_NEXT 31                      /* POSITION OF 'NEXT'-VARIABLE.        */
#define ZSAVE_BUF_NEXT 28
#define ZSAVE_BUF_DATA_LEN 27

          /* RETURN POINTS. */
          /* RESTART PHASES */
#define ZSTARTPHASE1 1
#define ZSTARTPHASE2 2
#define ZSTARTPHASE3 3
#define ZSTARTPHASE4 4
#define ZSTARTPHASE6 6

#define ZADDFRAG 0

//------------------------------------------------------------
// TUP_CONTINUEB codes
//------------------------------------------------------------
#define ZINITIALISE_RECORDS 6
#define ZREL_FRAG 7
#define ZREPORT_MEMORY_USAGE 8
#define ZBUILD_INDEX 9
unknown's avatar
unknown committed
246 247 248
#define ZTUP_SCAN 10
#define ZFREE_EXTENT 11
#define ZUNMAP_PAGES 12
unknown's avatar
unknown committed
249
#define ZFREE_VAR_PAGES 13
250 251 252 253 254 255

#define ZSCAN_PROCEDURE 0
#define ZCOPY_PROCEDURE 2
#define ZSTORED_PROCEDURE_DELETE 3
#define ZSTORED_PROCEDURE_FREE 0xffff
#define ZMIN_PAGE_LIMIT_TUP_COMMITREQ 2
unknown's avatar
unknown committed
256

unknown's avatar
unknown committed
257 258
#define ZSKIP_TUX_TRIGGERS 0x1 // flag for TUP_ABORTREQ

259 260 261
#endif

class Dbtup: public SimulatedBlock {
unknown's avatar
unknown committed
262
friend class Suma;
263
public:
unknown's avatar
unknown committed
264
struct KeyReqStruct;
265
friend struct KeyReqStruct; // CC
unknown's avatar
unknown committed
266 267 268 269 270 271
typedef bool (Dbtup::* ReadFunction)(Uint32*,
                                     KeyReqStruct*,
                                     AttributeHeader*,
                                     Uint32);
typedef bool (Dbtup::* UpdateFunction)(Uint32*,
                                       KeyReqStruct*,
unknown's avatar
unknown committed
272
                                       Uint32);
unknown's avatar
unknown committed
273 274 275 276 277 278 279 280 281 282 283
private:
  
  typedef Tup_fixsize_page Fix_page;
  typedef Tup_varsize_page Var_page;

public:
  class Dblqh *c_lqh;
  Tsman* c_tsman;
  Lgman* c_lgman;
  Page_cache_client m_pgman;

284
// State values
unknown's avatar
unknown committed
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
enum ChangeMaskState {
  DELETE_CHANGES = 0,
  SET_ALL_MASK = 1,
  USE_SAVED_CHANGE_MASK = 2,
  RECALCULATE_CHANGE_MASK = 3
};

enum TransState {
  TRANS_IDLE = 0,
  TRANS_STARTED = 1,
  TRANS_WAIT_STORED_PROCEDURE_ATTR_INFO = 2,
  TRANS_ERROR_WAIT_STORED_PROCREQ = 3,
  TRANS_ERROR_WAIT_TUPKEYREQ = 4,
  TRANS_TOO_MUCH_AI = 5,
  TRANS_DISCONNECTED = 6
};

enum TupleState {
  TUPLE_PREPARED = 1,
  TUPLE_ALREADY_ABORTED = 2,
  TUPLE_TO_BE_COMMITTED = 3
};
  
308 309 310 311 312 313 314 315 316
enum State {
  NOT_INITIALIZED = 0,
  IDLE = 17,
  ACTIVE = 18,
  SYSTEM_RESTART = 19,
  DEFINED = 34,
  NOT_DEFINED = 37,
  NORMAL_PAGE = 40,
  DEFINING = 65,
unknown's avatar
unknown committed
317
  DROPPING = 68
318 319 320 321 322 323 324 325 326 327 328 329
};

// Records
/* ************** ATTRIBUTE INFO BUFFER RECORD ****************** */
/* THIS RECORD IS USED AS A BUFFER FOR INCOMING AND OUTGOING DATA */
/* ************************************************************** */
struct Attrbufrec {
  Uint32 attrbuf[ZATTRBUF_SIZE];
}; /* p2c: size = 128 bytes */

typedef Ptr<Attrbufrec> AttrbufrecPtr;

unknown's avatar
unknown committed
330

331 332

struct Fragoperrec {
333 334
  Uint64 minRows;
  Uint64 maxRows;
335 336 337 338 339 340
  Uint32 nextFragoprec;
  Uint32 lqhPtrFrag;
  Uint32 fragidFrag;
  Uint32 tableidFrag;
  Uint32 fragPointer;
  Uint32 attributeCount;
unknown's avatar
unknown committed
341
  Uint32 charsetIndex;
unknown's avatar
unknown committed
342 343 344
  Uint32 m_null_bits[2];
  Uint32 m_fix_attributes_size[2]; // In words
  Uint32 m_var_attributes_size[2]; // In bytes
345
  BlockReference lqhBlockrefFrag;
346
  bool inUse;
347
  bool definingFragment;
348 349 350
};
typedef Ptr<Fragoperrec> FragoperrecPtr;

unknown's avatar
unknown committed
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374

  typedef Tup_page Page;
  typedef Ptr<Page> PagePtr;

  // Scan position
  struct ScanPos {
    enum Get {
      Get_undef = 0,
      Get_next_page,
      Get_page,
      Get_next_page_mm,
      Get_page_mm,
      Get_next_page_dd,
      Get_page_dd,
      Get_next_tuple,
      Get_tuple,
      Get_next_tuple_fs,
      Get_tuple_fs
    };
    Get m_get;                  // entry point in scanNext
    Local_key m_key;            // scan position pointer MM or DD
    Page* m_page;               // scanned MM or DD (cache) page
    Local_key m_key_mm;         // MM local key returned
    Uint32 m_realpid_mm;        // MM real page id
unknown's avatar
unknown committed
375
    Uint32 m_extent_info_ptr_i;
376 377
  };

unknown's avatar
unknown committed
378 379 380 381 382 383 384 385 386 387 388 389 390 391
  // Scan Lock
  struct ScanLock {
    Uint32 m_accLockOp;
    union {
      Uint32 nextPool;
      Uint32 nextList;
    };
    Uint32 prevList;
  };
  typedef Ptr<ScanLock> ScanLockPtr;
  ArrayPool<ScanLock> c_scanLockPool;

  // Tup scan, similar to Tux scan.  Later some of this could
  // be moved to common superclass.
392
  struct ScanOp {
unknown's avatar
unknown committed
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
    ScanOp() :
      m_state(Undef),
      m_bits(0),
      m_userPtr(RNIL),
      m_userRef(RNIL),
      m_tableId(RNIL),
      m_fragId(~(Uint32)0),
      m_fragPtrI(RNIL),
      m_transId1(0),
      m_transId2(0),
      m_savePointId(0),
      m_accLockOp(RNIL)
    {}

    enum State {
408 409
      Undef = 0,
      First = 1,                // before first entry
unknown's avatar
unknown committed
410 411 412
      Current = 2,              // at current before locking
      Blocked = 3,              // at current waiting for ACC lock
      Locked = 4,               // at current and locked or no lock needed
413 414
      Next = 5,                 // looking for next extry
      Last = 6,                 // after last entry
unknown's avatar
unknown committed
415
      Aborting = 7,             // lock wait at scan close
416 417 418
      Invalid = 9               // cannot return REF to LQH currently
    };
    Uint16 m_state;
unknown's avatar
unknown committed
419

unknown's avatar
unknown committed
420 421 422 423 424 425 426 427 428 429 430
    enum Bits {
      SCAN_DD        = 0x01,        // scan disk pages
      SCAN_VS        = 0x02,        // page format is var size
      SCAN_LCP       = 0x04,        // LCP mem page scan
      SCAN_LOCK_SH   = 0x10,        // lock mode shared
      SCAN_LOCK_EX   = 0x20,        // lock mode exclusive
      SCAN_LOCK_WAIT = 0x40,        // lock wait
      // any lock mode
      SCAN_LOCK      = SCAN_LOCK_SH | SCAN_LOCK_EX,
      SCAN_NR        = 0x80        // Node recovery scan
    };
unknown's avatar
unknown committed
431 432
    Uint16 m_bits;
    
433 434 435
    Uint32 m_userPtr;           // scanptr.i in LQH
    Uint32 m_userRef;
    Uint32 m_tableId;
unknown's avatar
unknown committed
436
    Uint32 m_fragId;
unknown's avatar
unknown committed
437
    Uint32 m_fragPtrI;
438 439
    Uint32 m_transId1;
    Uint32 m_transId2;
unknown's avatar
unknown committed
440 441 442 443 444 445 446 447 448 449 450
    union {
      Uint32 m_savePointId;
      Uint32 m_scanGCI;
    };
    // lock waited for or obtained and not yet passed to LQH
    Uint32 m_accLockOp;

    ScanPos m_scanPos;

    DLFifoList<ScanLock>::Head m_accLockOps;

451 452 453 454 455 456 457 458 459
    union {
    Uint32 nextPool;
    Uint32 nextList;
    };
    Uint32 prevList;
  };
  typedef Ptr<ScanOp> ScanOpPtr;
  ArrayPool<ScanOp> c_scanOpPool;

unknown's avatar
unknown committed
460 461 462 463 464 465 466 467 468 469 470 471
  void scanReply(Signal*, ScanOpPtr scanPtr);
  void scanFirst(Signal*, ScanOpPtr scanPtr);
  bool scanNext(Signal*, ScanOpPtr scanPtr);
  void scanCont(Signal*, ScanOpPtr scanPtr);
  void disk_page_tup_scan_callback(Signal*, Uint32 scanPtrI, Uint32 page_i);
  void scanClose(Signal*, ScanOpPtr scanPtr);
  void addAccLockOp(ScanOp& scan, Uint32 accLockOp);
  void removeAccLockOp(ScanOp& scan, Uint32 accLockOp);
  void releaseScanOp(ScanOpPtr& scanPtr);

  // for md5 of key (could maybe reuse existing temp buffer)
  Uint64 c_dataBuffer[ZWORDS_ON_PAGE/2 + 1];
unknown's avatar
unknown committed
472 473 474 475 476 477

  struct Page_request 
  {
    Local_key m_key;
    Uint32 m_frag_ptr_i;
    Uint32 m_extent_info_ptr;
unknown's avatar
unknown committed
478 479 480
    Uint16 m_estimated_free_space; // in bytes/records
    Uint16 m_list_index;           // in Disk_alloc_info.m_page_requests
    Uint16 m_ref_count;            // Waiters for page
unknown's avatar
unknown committed
481
    Uint16 m_uncommitted_used_space;
unknown's avatar
unknown committed
482
    Uint32 nextList;
unknown's avatar
unknown committed
483
    Uint32 prevList;
unknown's avatar
unknown committed
484
    Uint32 m_magic;
unknown's avatar
unknown committed
485
  }; // 32 bytes
unknown's avatar
unknown committed
486 487 488 489
  
  typedef RecordPool<Page_request, WOPool> Page_request_pool;
  typedef DLFifoListImpl<Page_request_pool, Page_request> Page_request_list;
  typedef LocalDLFifoListImpl<Page_request_pool, Page_request> Local_page_request_list;
unknown's avatar
unknown committed
490 491 492 493 494 495 496 497 498 499 500 501

  STATIC_CONST( EXTENT_SEARCH_MATRIX_COLS = 4 ); // Guarantee size
  STATIC_CONST( EXTENT_SEARCH_MATRIX_ROWS = 5 ); // Total size
  STATIC_CONST( EXTENT_SEARCH_MATRIX_SIZE = 20 );
  
  struct Extent_list_t
  {
    Uint32 nextList;
  };

  struct Extent_info : public Extent_list_t
  {
unknown's avatar
unknown committed
502
    Uint32 m_magic;
unknown's avatar
unknown committed
503
    Uint32 m_first_page_no;
unknown's avatar
unknown committed
504 505 506 507 508 509 510 511 512 513 514 515 516 517
    Local_key m_key;
    Uint32 m_free_space;
    Uint32 m_free_matrix_pos;
    Uint16 m_free_page_count[EXTENT_SEARCH_MATRIX_COLS];
    union {
      Uint32 nextList;
      Uint32 nextPool;
    };
    Uint32 prevList;
    Uint32 nextHash, prevHash;

    Uint32 hashValue() const {
      return (m_key.m_file_no << 16) ^ m_key.m_page_idx;
    }
518

unknown's avatar
unknown committed
519 520 521 522 523 524
    bool equal(const Extent_info & rec) const {
      return m_key.m_file_no == rec.m_key.m_file_no &&
	m_key.m_page_idx == rec.m_key.m_page_idx;
    }
  }; // 40 bytes

unknown's avatar
unknown committed
525 526 527 528 529 530
  typedef RecordPool<Extent_info, RWPool> Extent_info_pool;
  typedef DLListImpl<Extent_info_pool, Extent_info> Extent_info_list;
  typedef LocalDLListImpl<Extent_info_pool, Extent_info> Local_extent_info_list;
  typedef DLHashTableImpl<Extent_info_pool, Extent_info> Extent_info_hash;
  typedef SLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Fragment_extent_list;
  typedef LocalSLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Local_fragment_extent_list;
unknown's avatar
unknown committed
531 532 533 534 535 536
  struct Tablerec;
  struct Disk_alloc_info 
  {
    Disk_alloc_info() {}
    Disk_alloc_info(const Tablerec* tabPtrP, 
		    Uint32 extent_size_in_pages);
unknown's avatar
unknown committed
537
    Uint32 m_extent_size;
unknown's avatar
unknown committed
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
    
    /**
     * Disk allocation
     *
     * 1) Allocate space on pages that already are dirty
     *    (4 free lists for different requests)
     * 2) Allocate space on pages waiting to maped that will be dirty
     *    (4 free lists for different requests)
     * 3) Check if "current" extent can accommodate request
     *    If so, allocate page from there
     *    Else put "current" into free matrix
     * 4) Search free matrix for extent with greatest amount of free space
     *    while still accommodating current request
     *    (20 free lists for different requests)
     */
    
    /**
     * Free list of pages in different size
     *   that are dirty
     */
    DLList<Page>::Head m_dirty_pages[MAX_FREE_LIST];   // In real page id's

    /**
     * Requests (for update) that have sufficient space left after request
     *   these are currently being "mapped"
     */
unknown's avatar
unknown committed
564
    Page_request_list::Head m_page_requests[MAX_FREE_LIST];
unknown's avatar
unknown committed
565 566 567 568 569 570 571 572 573 574

    /**
     * Current extent
     */
    Uint32 m_curr_extent_info_ptr_i;
    
    /**
     * 
     */
    STATIC_CONST( SZ = EXTENT_SEARCH_MATRIX_SIZE );
unknown's avatar
unknown committed
575
    Extent_info_list::Head m_free_extents[SZ];
unknown's avatar
unknown committed
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
    Uint32 m_total_extent_free_space_thresholds[EXTENT_SEARCH_MATRIX_ROWS];
    Uint32 m_page_free_bits_map[EXTENT_SEARCH_MATRIX_COLS];

    Uint32 find_extent(Uint32 sz) const;
    Uint32 calc_extent_pos(const Extent_info*) const;

    /**
     * Compute minimum free space on page given bits
     */
    Uint32 calc_page_free_space(Uint32 bits) const {
      return m_page_free_bits_map[bits];
    }
  
    /**
     * Compute page free bits, given free space
     */
    Uint32 calc_page_free_bits(Uint32 free) const {
      for(Uint32 i = 0; i<EXTENT_SEARCH_MATRIX_COLS-1; i++)
	if(free >= m_page_free_bits_map[i])
	  return i;
      return EXTENT_SEARCH_MATRIX_COLS - 1;
    }

unknown's avatar
unknown committed
599
    Fragment_extent_list::Head m_extent_list;
unknown's avatar
unknown committed
600 601
  };
  
602 603
  void dump_disk_alloc(Disk_alloc_info&);

604 605 606 607 608
struct Fragrecord {
  Uint32 nextStartRange;
  Uint32 currentPageRange;
  Uint32 rootPageRange;
  Uint32 noOfPages;
609
  Uint32 noOfVarPages;
610
  Uint32 noOfPagesToGrow;
611

unknown's avatar
unknown committed
612
  DLList<Page>::Head emptyPrimPage; // allocated pages (not init)
613
  DLFifoList<Page>::Head thFreeFirst;   // pages with atleast 1 free record
unknown's avatar
unknown committed
614 615
  SLList<Page>::Head m_empty_pages; // Empty pages not in logical/physical map
  
unknown's avatar
unknown committed
616
  Uint32 m_lcp_scan_op;
617
  Uint32 m_lcp_keep_list;
618 619 620 621 622

  State fragStatus;
  Uint32 fragTableId;
  Uint32 fragmentId;
  Uint32 nextfreefrag;
unknown's avatar
unknown committed
623 624
  DLList<Page>::Head free_var_page_array[MAX_FREE_LIST];
  
unknown's avatar
unknown committed
625
  DLList<ScanOp>::Head m_scanList;
626

unknown's avatar
unknown committed
627 628
  enum { UC_LCP = 1, UC_CREATE = 2 };
  Uint32 m_undo_complete;
unknown's avatar
unknown committed
629 630 631
  Uint32 m_tablespace_id;
  Uint32 m_logfile_group_id;
  Disk_alloc_info m_disk_alloc_info;
unknown's avatar
unknown committed
632
  Uint32 m_var_page_chunks;
633 634 635 636 637
};
typedef Ptr<Fragrecord> FragrecordPtr;


struct Operationrec {
unknown's avatar
unknown committed
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
  /*
   * To handle Attrinfo signals and buffer them up we need to
   * a simple list with first and last and we also need to keep track
   * of how much we received for security check.
   * Will most likely disappear with introduction of long signals.
   * These variables are used before TUPKEYREQ is received and not
   * thereafter and is disposed with after calling copyAttrinfo
   * which is called before putting the operation into its lists.
   * Thus we can use union declarations for these variables.
   */

  /*
   * Used by scans to find the Attrinfo buffers.
   * This is only until returning from copyAttrinfo and
   * can thus reuse the same memory as needed by the
   * active operation list variables.
   */

  /*
   * Doubly linked list with anchor on tuple.
   * This is to handle multiple updates on the same tuple
   * by the same transaction.
   */
  union {
    Uint32 prevActiveOp;
    Uint32 storedProcedureId; //Used until copyAttrinfo
  };
  union {
    Uint32 nextActiveOp;
    Uint32 currentAttrinbufLen; //Used until copyAttrinfo
  };

  bool is_first_operation() const { return prevActiveOp == RNIL;}
  bool is_last_operation() const { return nextActiveOp == RNIL;}

  Uint32 m_undo_buffer_space; // In words
  union {
    Uint32 firstAttrinbufrec; //Used until copyAttrinfo
  };
  union {
    Uint32 lastAttrinbufrec; //Used until copyAttrinfo
    Uint32 nextPool;
  };
  Uint32 attrinbufLen; //only used during STORED_PROCDEF phase
  Uint32 storedProcPtr; //only used during STORED_PROCDEF phase
  
  /*
   * From fragment i-value we can find fragment and table record
   */
687
  Uint32 fragmentPtr;
unknown's avatar
unknown committed
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702

  /*
   * We need references to both the original tuple and the copy tuple.
   * We keep the page's real i-value and its index and from there we
   * can find out about the fragment page id and the page offset.
   */
  Local_key m_tuple_location;
  Local_key m_copy_tuple_location;

  /*
   * We keep the record linked to the operation record in LQH.
   * This is needed due to writing of REDO log must be performed
   * in correct order, which is the same order as the writes
   * occurred. LQH can receive the records in different order.
   */
703 704
  Uint32 userpointer;

unknown's avatar
unknown committed
705 706 707 708 709 710
  /*
   * When responding to queries in the same transaction they will see
   * a result from the save point id the query was started. Again
   * functionality for multi-updates of the same record in one
   * transaction.
   */
711
  union {
unknown's avatar
unknown committed
712 713 714 715 716 717 718
    Uint32 savepointId;
    Uint32 m_commit_disk_callback_page;
  };

  /*
   * We use 64 bits to save change mask for the most common cases.
   */
719
  Uint32 saved_change_mask[2];
720

unknown's avatar
unknown committed
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
  /*
   * State variables on connection.
   * State variable on tuple after multi-updates
   * Is operation undo logged or not
   * Is operation in fragment list
   * Is operation in multi-update list
   * Operation type (READ, UPDATE, etc)
   * Is record primary replica
   * Is delete or insert performed
   */
  struct OpBitFields {
    unsigned int trans_state : 3;
    unsigned int tuple_state : 2;
    unsigned int in_active_list : 1;

    unsigned int op_type : 3;
    unsigned int delete_insert_flag : 1;
    unsigned int primary_replica : 1;
    unsigned int change_mask_state : 2;
    unsigned int m_disk_preallocated : 1;
    unsigned int m_load_diskpage_on_commit : 1;
    unsigned int m_wait_log_buffer : 1;
  };
  union {
    OpBitFields op_struct;
    Uint16 op_bit_fields;
  };

  /*
   * TUX needs to know the tuple version of the tuple since it
   * keeps an entry for both the committed and all versions in
   * a transaction currently. So each update will create a new
   * version even if in the same transaction.
   */
  Uint16 tupVersion;
756
};
unknown's avatar
unknown committed
757
typedef Ptr<Operationrec> OperationrecPtr;
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793

          /* ****************************** PAGE RANGE RECORD ************************** */
          /* PAGE RANGES AND BASE PAGE ID. EACH RANGE HAS A  CORRESPONDING BASE PAGE ID  */
          /* THAT IS USED TO  CALCULATE REAL PAGE ID FROM A FRAGMENT PAGE ID AND A TABLE */
          /* REFERENCE.                                                                  */
          /* THE PAGE RANGES ARE ORGANISED IN A B-TREE FASHION WHERE THE VARIABLE TYPE   */
          /* SPECIFIES IF A LEAF NODE HAS BEEN REACHED. IF A LEAF NODE HAS BEEN REACHED  */
          /* THEN BASE_PAGE_ID IS THE BASE_PAGE_ID OF THE SET OF PAGES THAT WAS          */
          /* ALLOCATED IN THAT RANGE. OTHERWISE BASE_PAGE_ID IS THE POINTER TO THE NEXT  */
          /* PAGE_RANGE RECORD.                                                          */
          /* *************************************************************************** */
struct PageRange {
  Uint32 startRange[4];                                  /* START OF RANGE                                   */
  Uint32 endRange[4];                                    /* END OF THIS RANGE                                */
  Uint32 basePageId[4];                                  /* BASE PAGE ID.                                    */
/*----               VARIABLE BASE_PAGE_ID2 (4) 8 DS NEEDED WHEN SUPPORTING 40 BIT PAGE ID           -------*/
  Uint8 type[4];                                        /* TYPE OF BASE PAGE ID                             */
  Uint32 nextFree;                                       /* NEXT FREE PAGE RANGE RECORD                      */
  Uint32 parentPtr;                                      /* THE PARENT TO THE PAGE RANGE REC IN THE B-TREE   */
  Uint8 currentIndexPos;
};
typedef Ptr<PageRange> PageRangePtr;


  /* ************* TRIGGER DATA ************* */
  /* THIS RECORD FORMS LISTS OF ACTIVE       */
  /* TRIGGERS FOR EACH TABLE.                 */
  /* THE RECORDS ARE MANAGED BY A TRIGGER     */
  /* POOL wHERE A TRIGGER RECORD IS SEIZED    */
  /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
  /* WHEN THE TRIGGER IS DEACTIVATED.         */
  /* **************************************** */
struct TupTriggerData {
  
  /**
   * Trigger id, used by DICT/TRIX to identify the trigger
794 795 796 797
   *
   * trigger Ids are unique per block for SUBSCRIPTION triggers.
   * This is so that BACKUP can use TUP triggers directly and delete them
   * properly.
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
   */
  Uint32 triggerId;

  /**
   * Index id is needed for ordered index.
   */
  Uint32 indexId;

  /**
   * Trigger type etc, defines what the trigger is used for
   */
  TriggerType::Value triggerType;
  TriggerActionTime::Value triggerActionTime;
  TriggerEvent::Value triggerEvent;
  /**
   * Receiver block
   */
  Uint32 m_receiverBlock;
  
  /**
   * Monitor all replicas, i.e. trigger will fire on all nodes where tuples
   * are stored
   */
  bool monitorReplicas;

  /**
   * Monitor all attributes, the trigger monitors all changes to attributes 
   * in the table
   */
  bool monitorAllAttributes;

  /**
   * Send only changed attributes at trigger firing time.
   */
  bool sendOnlyChangedAttributes;

  /**
   * Send also before values at trigger firing time.
   */
  bool sendBeforeValues;

  /**
   * Attribute mask, defines what attributes are to be monitored
   * Can be seen as a compact representation of SQL column name list
   */
  Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
  
  /**
   * Next ptr (used in pool/list)
   */
  union {
    Uint32 nextPool;
    Uint32 nextList;
  };
  
  /**
   * Prev pointer (used in list)
   */
  Uint32 prevList;

  inline void print(NdbOut & s) const { s << "[TriggerData = " << triggerId << "]"; };
};

typedef Ptr<TupTriggerData> TriggerPtr;
  
/**
 * Pool of trigger data record
 */
ArrayPool<TupTriggerData> c_triggerPool;

unknown's avatar
unknown committed
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
  /* ************ TABLE RECORD ************ */
  /* THIS RECORD FORMS A LIST OF TABLE      */
  /* REFERENCE INFORMATION. ONE RECORD      */
  /* PER TABLE REFERENCE.                   */
  /* ************************************** */
  STATIC_CONST( MM = 0 );
  STATIC_CONST( DD = 1 );
  
  struct Tablerec {
    Tablerec(ArrayPool<TupTriggerData> & triggerPool) : 
      afterInsertTriggers(triggerPool),
      afterDeleteTriggers(triggerPool),
      afterUpdateTriggers(triggerPool),
      subscriptionInsertTriggers(triggerPool),
      subscriptionDeleteTriggers(triggerPool),
      subscriptionUpdateTriggers(triggerPool),
      constraintUpdateTriggers(triggerPool),
      tuxCustomTriggers(triggerPool)
      {}
    
    Bitmask<MAXNROFATTRIBUTESINWORDS> notNullAttributeMask;
889
    Bitmask<MAXNROFATTRIBUTESINWORDS> blobAttributeMask;
unknown's avatar
unknown committed
890 891 892 893 894 895 896 897 898
    
    ReadFunction* readFunctionArray;
    UpdateFunction* updateFunctionArray;
    CHARSET_INFO** charsetArray;
    
    Uint32 readKeyArray;
    Uint32 tabDescriptor;
    Uint32 m_real_order_descriptor;
    
unknown's avatar
unknown committed
899 900 901 902 903 904
    enum Bits
    {
      TR_Checksum = 0x1, // Need to be 1
      TR_RowGCI   = 0x2
    };
    Uint16 m_bits;
unknown's avatar
unknown committed
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
    Uint16 total_rec_size; // Max total size for entire tuple in words
    
    /**
     * Aggregates
     */
    Uint16 m_no_of_attributes;
    Uint16 m_no_of_disk_attributes;
    Uint16 noOfKeyAttr;
    Uint16 noOfCharsets;

    bool need_expand() const { 
      return m_no_of_attributes > m_attributes[MM].m_no_of_fixsize;
    }

    bool need_expand(bool disk) const { 
      return m_attributes[MM].m_no_of_varsize > 0 ||
	(disk && m_no_of_disk_attributes > 0);
    }
    
    bool need_shrink() const {
      return 
	m_attributes[MM].m_no_of_varsize > 0 ||
	m_attributes[DD].m_no_of_varsize > 0;
    }
    
    bool need_shrink(bool disk) const {
      return 
	m_attributes[MM].m_no_of_varsize > 0 ||
	(disk && m_attributes[DD].m_no_of_varsize > 0);
    }

    /**
     * Descriptors for MM and DD part
     */
    struct Tuple_offsets {
      Uint8 m_null_words;
      Uint8 m_null_offset;
      Uint16 m_disk_ref_offset; // In words relative m_data
unknown's avatar
ndb -  
unknown committed
943
      Uint16 m_fix_header_size; // For fix size tuples= total rec size(part)
unknown's avatar
unknown committed
944 945 946 947
      Uint16 m_max_var_offset;  // In bytes relative m_var_data.m_data_ptr
    } m_offsets[2];
    
    Uint32 get_check_offset(Uint32 mm) const {
unknown's avatar
ndb -  
unknown committed
948
      return m_offsets[mm].m_fix_header_size;
unknown's avatar
unknown committed
949 950 951 952 953 954 955 956
    }

    struct {
      Uint16 m_no_of_fixsize;
      Uint16 m_no_of_varsize;
    } m_attributes[2];
    
    // Lists of trigger data for active triggers
957 958 959 960 961 962 963
    DLList<TupTriggerData> afterInsertTriggers;
    DLList<TupTriggerData> afterDeleteTriggers;
    DLList<TupTriggerData> afterUpdateTriggers;
    DLList<TupTriggerData> subscriptionInsertTriggers;
    DLList<TupTriggerData> subscriptionDeleteTriggers;
    DLList<TupTriggerData> subscriptionUpdateTriggers;
    DLList<TupTriggerData> constraintUpdateTriggers;
unknown's avatar
unknown committed
964 965
    
    // List of ordered indexes
966
    DLList<TupTriggerData> tuxCustomTriggers;
unknown's avatar
unknown committed
967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985
    
    Uint32 fragid[MAX_FRAG_PER_NODE];
    Uint32 fragrec[MAX_FRAG_PER_NODE];

    struct {
      Uint32 tabUserPtr;
      Uint32 tabUserRef;
    } m_dropTable;
    State tableStatus;
  };  

  struct Disk_undo 
  {
    enum 
    {
      UNDO_ALLOC = File_formats::Undofile::UNDO_TUP_ALLOC
      ,UNDO_UPDATE = File_formats::Undofile::UNDO_TUP_UPDATE
      ,UNDO_FREE = File_formats::Undofile::UNDO_TUP_FREE
      ,UNDO_CREATE = File_formats::Undofile::UNDO_TUP_CREATE
unknown's avatar
unknown committed
986 987 988
      ,UNDO_DROP = File_formats::Undofile::UNDO_TUP_DROP
      ,UNDO_ALLOC_EXTENT = File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT
      ,UNDO_FREE_EXTENT = File_formats::Undofile::UNDO_TUP_FREE_EXTENT
unknown's avatar
unknown committed
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
    };
    
    struct Alloc 
    {
      Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
      Uint32 m_page_no;
      Uint32 m_type_length; // 16 bit type, 16 bit length
    };
    
    struct Update
    {
      Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
      Uint32 m_page_no;
      Uint32 m_gci;
      Uint32 m_data[1];
      Uint32 m_type_length; // 16 bit type, 16 bit length
    };
    
    struct Free
    {
      Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
      Uint32 m_page_no;
      Uint32 m_gci;
      Uint32 m_data[1];
      Uint32 m_type_length; // 16 bit type, 16 bit length
    };
    
    struct Create
    {
      Uint32 m_table;
      Uint32 m_type_length; // 16 bit type, 16 bit length
    };
unknown's avatar
unknown committed
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044

    struct Drop
    {
      Uint32 m_table;
      Uint32 m_type_length; // 16 bit type, 16 bit length
    };

    struct AllocExtent
    {
      Uint32 m_table;
      Uint32 m_fragment;
      Uint32 m_page_no;
      Uint32 m_file_no;
      Uint32 m_type_length;
    };

    struct FreeExtent
    {
      Uint32 m_table;
      Uint32 m_fragment;
      Uint32 m_page_no;
      Uint32 m_file_no;
      Uint32 m_type_length;
    };
unknown's avatar
unknown committed
1045 1046
  };
  
unknown's avatar
unknown committed
1047 1048
  Extent_info_pool c_extent_pool;
  Extent_info_hash c_extent_hash;
unknown's avatar
unknown committed
1049
  Page_request_pool c_page_request_pool;
1050

unknown's avatar
unknown committed
1051
  typedef Ptr<Tablerec> TablerecPtr;
1052

unknown's avatar
unknown committed
1053 1054 1055 1056 1057 1058 1059
  struct storedProc {
    Uint32 storedLinkFirst;
    Uint32 storedLinkLast;
    Uint32 storedCounter;
    Uint32 nextPool;
    Uint16 storedCode;
    Uint16 storedProcLength;
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179
};

typedef Ptr<storedProc> StoredProcPtr;

ArrayPool<storedProc> c_storedProcPool;

/* **************************** TABLE_DESCRIPTOR RECORD ******************************** */
/* THIS VARIABLE IS USED TO STORE TABLE DESCRIPTIONS. A TABLE DESCRIPTION IS STORED AS A */
/* CONTIGUOS ARRAY IN THIS VARIABLE. WHEN A NEW TABLE IS ADDED A CHUNK IS ALLOCATED IN   */
/* THIS RECORD. WHEN ATTRIBUTES ARE ADDED TO THE TABLE, A NEW CHUNK OF PROPER SIZE IS    */
/* ALLOCATED AND ALL DATA IS COPIED TO THIS NEW CHUNK AND THEN THE OLD CHUNK IS PUT IN   */
/* THE FREE LIST. EACH TABLE IS DESCRIBED BY A NUMBER OF TABLE DESCRIPTIVE ATTRIBUTES    */
/* AND A NUMBER OF ATTRIBUTE DESCRIPTORS AS SHOWN IN FIGURE BELOW                        */
/*                                                                                       */
/* WHEN ALLOCATING A TABLE DESCRIPTOR THE SIZE IS ALWAYS A MULTIPLE OF 16 WORDS.         */
/*                                                                                       */
/*               ----------------------------------------------                          */
/*               |    TRAILER USED FOR ALLOC/DEALLOC          |                          */
/*               ----------------------------------------------                          */
/*               |    TABLE DESCRIPTIVE ATTRIBUTES            |                          */
/*               ----------------------------------------------                          */
/*               |    ATTRIBUTE DESCRIPTION 1                 |                          */
/*               ----------------------------------------------                          */
/*               |    ATTRIBUTE DESCRIPTION 2                 |                          */
/*               ----------------------------------------------                          */
/*               |                                            |                          */
/*               |                                            |                          */
/*               |                                            |                          */
/*               ----------------------------------------------                          */
/*               |    ATTRIBUTE DESCRIPTION N                 |                          */
/*               ----------------------------------------------                          */
/*                                                                                       */
/* THE TABLE DESCRIPTIVE ATTRIBUTES CONTAINS THE FOLLOWING ATTRIBUTES:                   */
/*                                                                                       */
/*               ----------------------------------------------                          */
/*               |    HEADER (TYPE OF INFO)                   |                          */
/*               ----------------------------------------------                          */
/*               |    SIZE OF WHOLE CHUNK (INCL. TRAILER)     |                          */
/*               ----------------------------------------------                          */
/*               |    TABLE IDENTITY                          |                          */
/*               ----------------------------------------------                          */
/*               |    FRAGMENT IDENTITY                       |                          */
/*               ----------------------------------------------                          */
/*               |    NUMBER OF ATTRIBUTES                    |                          */
/*               ----------------------------------------------                          */
/*               |    SIZE OF FIXED ATTRIBUTES                |                          */
/*               ----------------------------------------------                          */
/*               |    NUMBER OF NULL FIELDS                   |                          */
/*               ----------------------------------------------                          */
/*               |    NOT USED                                |                          */
/*               ----------------------------------------------                          */
/*                                                                                       */
/* THESE ATTRIBUTES ARE ALL ONE R-VARIABLE IN THE RECORD.                                */
/* NORMALLY ONLY ONE TABLE DESCRIPTOR IS USED. DURING SCHEMA CHANGES THERE COULD         */
/* HOWEVER EXIST MORE THAN ONE TABLE DESCRIPTION SINCE THE SCHEMA CHANGE OF VARIOUS      */
/* FRAGMENTS ARE NOT SYNCHRONISED. THIS MEANS THAT ALTHOUGH THE SCHEMA HAS CHANGED       */
/* IN ALL FRAGMENTS, BUT THE FRAGMENTS HAVE NOT REMOVED THE ATTRIBUTES IN THE SAME       */
/* TIME-FRAME. THEREBY SOME ATTRIBUTE INFORMATION MIGHT DIFFER BETWEEN FRAGMENTS.        */
/* EXAMPLES OF ATTRIBUTES THAT MIGHT DIFFER ARE SIZE OF FIXED ATTRIBUTES, NUMBER OF      */
/* ATTRIBUTES, FIELD START WORD, START BIT.                                              */
/*                                                                                       */
/* AN ATTRIBUTE DESCRIPTION CONTAINS THE FOLLOWING ATTRIBUTES:                           */
/*                                                                                       */
/*               ----------------------------------------------                          */
/*               |    Field Type, 4 bits (LSB Bits)           |                          */
/*               ----------------------------------------------                          */
/*               |    Attribute Size, 4 bits                  |                          */
/*               ----------------------------------------------                          */
/*               |    NULL indicator 1 bit                    |                          */
/*               ----------------------------------------------                          */
/*               |    Indicator if TUP stores attr. 1 bit     |                          */
/*               ----------------------------------------------                          */
/*               |    Not used 6 bits                         |                          */
/*               ----------------------------------------------                          */
/*               |    No. of elements in fixed array 16 bits  |                          */
/*               ----------------------------------------------                          */
/*               ----------------------------------------------                          */
/*               |    Field Start Word, 21 bits (LSB Bits)    |                          */
/*               ----------------------------------------------                          */
/*               |    NULL Bit, 11 bits                       |                          */
/*               ----------------------------------------------                          */
/*                                                                                       */
/* THE ATTRIBUTE SIZE CAN BE 1,2,4,8,16,32,64 AND 128 BITS.                              */
/*                                                                                       */
/* THE UNUSED PARTS OF THE RECORDS ARE PUT IN A LINKED LIST OF FREE PARTS. EACH OF       */
/* THOSE FREE PARTS HAVE THREE RECORDS ASSIGNED AS SHOWN IN THIS STRUCTURE               */
/* ALL FREE PARTS ARE SET INTO A CHUNK LIST WHERE EACH CHUNK IS AT LEAST 16 WORDS        */
/*                                                                                       */
/*               ----------------------------------------------                          */
/*               |    HEADER = RNIL                           |                          */
/*               ----------------------------------------------                          */
/*               |    SIZE OF FREE AREA                       |                          */
/*               ----------------------------------------------                          */
/*               |    POINTER TO PREVIOUS FREE AREA           |                          */
/*               ----------------------------------------------                          */
/*               |    POINTER TO NEXT FREE AREA               |                          */
/*               ----------------------------------------------                          */
/*                                                                                       */
/* IF THE POINTER TO THE NEXT AREA IS RNIL THEN THIS IS THE LAST FREE AREA.              */
/*                                                                                       */
/*****************************************************************************************/
struct TableDescriptor {
  Uint32 tabDescr;
};
typedef Ptr<TableDescriptor> TableDescriptorPtr;

struct HostBuffer {
  bool  inPackedList;
  Uint32 packetLenTA;
  Uint32 noOfPacketsTA;
  Uint32 packetBufferTA[30];
};
typedef Ptr<HostBuffer> HostBufferPtr;

  /*
   * Build index operation record.
   */
  struct BuildIndexRec {
    // request cannot use signal class due to extra members
    Uint32 m_request[BuildIndxReq::SignalLength];
unknown's avatar
unknown committed
1180 1181
    Uint8  m_build_vs;          // varsize pages
    Uint32 m_indexId;           // the index
1182 1183
    Uint32 m_fragNo;            // fragment number under Tablerec
    Uint32 m_pageId;            // logical fragment page id
unknown's avatar
unknown committed
1184 1185
    Uint32 m_tupleNo;           // tuple number on page
    Uint32 m_buildRef;          // Where to send tuples
1186 1187 1188 1189 1190 1191 1192 1193 1194
    BuildIndxRef::ErrorCode m_errorCode;
    union {
      Uint32 nextPool;
      Uint32 nextList;
    };
    Uint32 prevList;
  };
  typedef Ptr<BuildIndexRec> BuildIndexPtr;
  ArrayPool<BuildIndexRec> c_buildIndexPool;
1195
  DLList<BuildIndexRec> c_buildIndexList;
1196 1197
  Uint32 c_noOfBuildIndexRec;

unknown's avatar
unknown committed
1198 1199 1200 1201 1202
  /**
   * Reference to variable part when a tuple is chained
   */
  struct Var_part_ref 
  {
1203 1204 1205 1206 1207 1208
#ifdef NDB_32BIT_VAR_REF
    /*
      In versions prior to ndb 6.1.6, 6.2.1 and mysql 5.1.17
      Running this code limits DataMemory to 16G, also online
      upgrade not possible between versions
     */
unknown's avatar
unknown committed
1209
    Uint32 m_ref;
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223
    STATIC_CONST( SZ32 = 1 );

    void copyout(Local_key* dst) const {
      dst->m_page_no = m_ref >> MAX_TUPLES_BITS;
      dst->m_page_idx = m_ref & MAX_TUPLES_PER_PAGE;
    }

    void assign(const Local_key* src) {
      m_ref = (src->m_page_no << MAX_TUPLES_BITS) | src->m_page_idx;
    }
#else
    Uint32 m_page_no;
    Uint32 m_page_idx;
    STATIC_CONST( SZ32 = 2 );
unknown's avatar
unknown committed
1224

1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
    void copyout(Local_key* dst) const {
      dst->m_page_no = m_page_no;
      dst->m_page_idx = m_page_idx;
    }

    void assign(const Local_key* src) {
      m_page_no = src->m_page_no;
      m_page_idx = src->m_page_idx;
    }
#endif    
  };
  
unknown's avatar
ndb -  
unknown committed
1237 1238 1239 1240 1241
  struct Disk_part_ref
  {
    STATIC_CONST( SZ32 = 2 );
  };

unknown's avatar
unknown committed
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
  struct Tuple_header
  {
    union {
      Uint32 m_operation_ptr_i;  // OperationPtrI
      Uint32 m_base_record_ref;  // For disk tuple, ref to MM tuple
    };
    Uint32 m_header_bits;      // Header word
    union {
      Uint32 m_checksum;
      Uint32 m_data[1];
      Uint32 m_null_bits[1];
    };

    STATIC_CONST( HeaderSize = 2 );
    
    /**
     * header bits
     */
    STATIC_CONST( TUP_VERSION_MASK = 0xFFFF );
    STATIC_CONST( CHAINED_ROW = 0x00010000 ); // Is var part on different page
    STATIC_CONST( DISK_PART   = 0x00020000 ); // Is there a disk part
    STATIC_CONST( DISK_ALLOC  = 0x00040000 ); // Is disk part allocated
    STATIC_CONST( DISK_INLINE = 0x00080000 ); // Is disk inline
    STATIC_CONST( ALLOC       = 0x00100000 ); // Is record allocated now
    STATIC_CONST( MM_SHRINK   = 0x00200000 ); // Has MM part shrunk
    STATIC_CONST( MM_GROWN    = 0x00400000 ); // Has MM part grown
1268
    STATIC_CONST( FREED       = 0x00800000 ); // Is freed
unknown's avatar
unknown committed
1269
    STATIC_CONST( LCP_SKIP    = 0x01000000 ); // Should not be returned in LCP
1270 1271
    STATIC_CONST( LCP_KEEP    = 0x02000000 ); // Should be returned in LCP
    STATIC_CONST( FREE        = 0x02800000 ); // Is free
unknown's avatar
unknown committed
1272
    
unknown's avatar
unknown committed
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
    Uint32 get_tuple_version() const { 
      return m_header_bits & TUP_VERSION_MASK;
    }
    void set_tuple_version(Uint32 version) { 
      m_header_bits= 
	(m_header_bits & ~(Uint32)TUP_VERSION_MASK) | 
	(version & TUP_VERSION_MASK);
    }

    Uint32* get_null_bits(const Tablerec* tabPtrP) {
      return m_null_bits+tabPtrP->m_offsets[MM].m_null_offset;
    }

    Uint32* get_null_bits(const Tablerec* tabPtrP, Uint32 mm) {
      return m_null_bits+tabPtrP->m_offsets[mm].m_null_offset;
    }
    
unknown's avatar
ndb -  
unknown committed
1290 1291
    Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) {
      return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
unknown's avatar
unknown committed
1292 1293
    }

unknown's avatar
ndb -  
unknown committed
1294 1295
    const Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) const {
      return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
unknown's avatar
unknown committed
1296
    }
unknown's avatar
ndb -  
unknown committed
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307
    
    Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) {
      return m_data + tabPtrP->m_offsets[MM].m_fix_header_size - 
        Tuple_header::HeaderSize;
    }
    
    const Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) const {
      return m_data + tabPtrP->m_offsets[MM].m_fix_header_size - 
        Tuple_header::HeaderSize;
    }
    
unknown's avatar
unknown committed
1308 1309 1310 1311 1312 1313 1314
    Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) {
      return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
    }

    const Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) const {
      return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
    }
unknown's avatar
unknown committed
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324

    Uint32 *get_mm_gci(const Tablerec* tabPtrP){
      assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
      return m_data + (tabPtrP->m_bits & Tablerec::TR_Checksum);
    }

    Uint32 *get_dd_gci(const Tablerec* tabPtrP, Uint32 mm){
      assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
      return m_data;
    }
unknown's avatar
unknown committed
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365
  };
  
struct KeyReqStruct {
/**
 * These variables are used as temporary storage during execution of the
 * TUPKEYREQ signal.
 * The first set of variables defines a number of variables needed for
 * the fix part of the tuple.
 *
 * The second part defines a number of commonly used meta data variables.
 *
 * The third set of variables defines a set of variables needed for the
 * variable part.
 *
 * The fourth part is variables needed only for updates and inserts.
 *
 * The fifth part is a long array of real lengths which is is put last
 * for cache memory reasons. This is part of the variable part and
 * contains the real allocated lengths whereas the tuple contains
 * the length of attribute stored.
 */
  Tuple_header *m_tuple_ptr;

  Uint32 check_offset[2];

  TableDescriptor *attr_descr;
  Uint32          max_read;
  Uint32          out_buf_index;
  Uint32          in_buf_index;
  Uint32          in_buf_len;
  Uint32          attr_descriptor;
  bool            xfrm_flag;

  struct Var_data {
    char *m_data_ptr;
    Uint16 *m_offset_array_ptr;
    Uint16 m_var_len_offset;
    Uint16 m_max_var_offset;
  } m_var_data[2];

  Tuple_header *m_disk_ptr;
unknown's avatar
unknown committed
1366 1367
  PagePtr m_page_ptr;
  PagePtr m_varpart_page_ptr;    // could be same as m_page_ptr_p
unknown's avatar
unknown committed
1368
  PagePtr m_disk_page_ptr;       //
unknown's avatar
unknown committed
1369 1370
  Local_key m_row_id;
  
unknown's avatar
unknown committed
1371 1372 1373
  bool            dirty_op;
  bool            interpreted_exec;
  bool            last_row;
unknown's avatar
unknown committed
1374
  bool            m_use_rowid;
unknown's avatar
unknown committed
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387

  Signal*         signal;
  Uint32 no_fired_triggers;
  Uint32 frag_page_id;
  Uint32 hash_value;
  Uint32 gci;
  Uint32 log_size;
  Uint32 read_length;
  Uint32 attrinfo_len;
  Uint32 tc_operation_ptr;
  Uint32 trans_id1;
  Uint32 trans_id2;
  Uint32 TC_index;
1388
  // next 2 apply only to attrids >= 64 (zero otherwise)
unknown's avatar
unknown committed
1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428
  Uint32 max_attr_id_updated;
  Uint32 no_changed_attrs;
  BlockReference TC_ref;
  BlockReference rec_blockref;
  bool change_mask_calculated;
  /*
   * A bit mask where a bit set means that the update or insert
   * was updating this record.
   */
  Bitmask<MAXNROFATTRIBUTESINWORDS> changeMask;
  Uint16 var_pos_array[2*MAX_ATTRIBUTES_IN_TABLE + 1];
  OperationrecPtr prevOpPtr;
};

  friend class Undo_buffer;
  Undo_buffer c_undo_buffer;
  
/*
 No longer used:
 Implemented by shift instructions in subroutines instead
 
struct TupHeadInfo {
  struct BitPart {
    unsigned int disk_indicator : 1;
    unsigned int var_part_loc_ind : 1;
    unsigned int initialised : 1;
    unsigned int not_used_yet : 5;
    unsigned int no_var_sized : 8;
    unsigned int tuple_version : 16;
  };
  union {
    Uint32 all;
    BitPart bit_part;
  };
};
*/

// updateAttributes module
  Uint32          terrorCode;

1429
public:
1430
  Dbtup(Block_context&, Pgman*);
1431 1432
  virtual ~Dbtup();

1433 1434 1435 1436 1437
  /*
   * TUX uses logical tuple address when talking to ACC and LQH.
   */
  void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32& tupAddr);

1438 1439
  /*
   * TUX index in TUP has single Uint32 array attribute which stores an
1440
   * index node.  TUX reads and writes the node directly via pointer.
1441 1442 1443 1444 1445
   */
  int tuxAllocNode(Signal* signal, Uint32 fragPtrI, Uint32& pageId, Uint32& pageOffset, Uint32*& node);
  void tuxFreeNode(Signal* signal, Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* node);
  void tuxGetNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32*& node);

1446
  /*
1447 1448 1449 1450 1451
   * TUX reads primary table attributes for index keys.  Tuple is
   * specified by location of original tuple and version number.  Input
   * is attribute ids in AttributeHeader format.  Output is attribute
   * data with headers.  Uses readAttributes with xfrm option set.
   * Returns number of words or negative (-terrorCode) on error.
1452
   */
1453
  int tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut);
1454 1455

  /*
1456
   * TUX reads primary key without headers into an array of words.  Used
1457 1458
   * for md5 summing and when returning keyinfo.  Returns number of
   * words or negative (-terrorCode) on error.
1459
   */
unknown's avatar
unknown committed
1460
  int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag);
1461

1462 1463 1464 1465 1466
  /*
   * ACC reads primary key without headers into an array of words.  At
   * this point in ACC deconstruction, ACC still uses logical references
   * to fragment and tuple.
   */
unknown's avatar
unknown committed
1467
  int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag);
1468

1469 1470 1471 1472
  /*
   * TUX checks if tuple is visible to scan.
   */
  bool tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId);
1473

unknown's avatar
unknown committed
1474 1475 1476 1477 1478 1479
  int load_diskpage(Signal*, Uint32 opRec, Uint32 fragPtrI, 
		    Uint32 local_key, Uint32 flags);

  int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI, 
			 Uint32 local_key, Uint32 flags);

unknown's avatar
unknown committed
1480 1481
  int alloc_page(Tablerec*, Fragrecord*, PagePtr*,Uint32 page_no);
  
unknown's avatar
unknown committed
1482 1483
  void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
  void complete_restore_lcp(Uint32 tableId, Uint32 fragmentId);
unknown's avatar
unknown committed
1484 1485 1486 1487 1488 1489

  int nr_read_pk(Uint32 fragPtr, const Local_key*, Uint32* dataOut, bool&copy);
  int nr_update_gci(Uint32 fragPtr, const Local_key*, Uint32 gci);
  int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci);

  void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page);
unknown's avatar
unknown committed
1490
  void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page);
1491 1492 1493 1494 1495 1496 1497 1498
private:
  BLOCK_DEFINES(Dbtup);

  // Transit signals
  void execDEBUG_SIG(Signal* signal);
  void execCONTINUEB(Signal* signal);

  // Received signals
unknown's avatar
unknown committed
1499
  void execLCP_FRAG_ORD(Signal*signal);
1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514
  void execDUMP_STATE_ORD(Signal* signal);
  void execSEND_PACKED(Signal* signal);
  void execSTTOR(Signal* signal);
  void execTUP_LCPREQ(Signal* signal);
  void execEND_LCPREQ(Signal* signal);
  void execSTART_RECREQ(Signal* signal);
  void execMEMCHECKREQ(Signal* signal);
  void execTUPSEIZEREQ(Signal* signal);
  void execTUPRELEASEREQ(Signal* signal);
  void execSTORED_PROCREQ(Signal* signal);
  void execTUPFRAGREQ(Signal* signal);
  void execTUP_ADD_ATTRREQ(Signal* signal);
  void execTUP_COMMITREQ(Signal* signal);
  void execTUP_ABORTREQ(Signal* signal);
  void execNDB_STTOR(Signal* signal);
1515
  void execREAD_CONFIG_REQ(Signal* signal);
1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526
  void execSET_VAR_REQ(Signal* signal);
  void execDROP_TAB_REQ(Signal* signal);
  void execALTER_TAB_REQ(Signal* signal);
  void execTUP_DEALLOCREQ(Signal* signal);
  void execTUP_WRITELOG_REQ(Signal* signal);

  // Ordered index related
  void execBUILDINDXREQ(Signal* signal);
  void buildIndex(Signal* signal, Uint32 buildPtrI);
  void buildIndexReply(Signal* signal, const BuildIndexRec* buildRec);

1527 1528 1529 1530
  // Tup scan
  void execACC_SCANREQ(Signal* signal);
  void execNEXT_SCANREQ(Signal* signal);
  void execACC_CHECK_SCAN(Signal* signal);
unknown's avatar
unknown committed
1531 1532 1533
  void execACCKEYCONF(Signal* signal);
  void execACCKEYREF(Signal* signal);
  void execACC_ABORTCONF(Signal* signal);
1534

1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715
//------------------------------------------------------------------
//------------------------------------------------------------------
// Methods to handle execution of TUPKEYREQ + ATTRINFO.
//
// Module Execution Manager
//
// The TUPKEYREQ signal is central to this block. This signal is used
// by everybody that needs to read data residing in DBTUP. The data is
// read using an interpreter approach.
//
// Operations only needing to read execute a simplified version of the
// interpreter where the only instruction is read Attribute to send.
// Operations only needing to update the record (insert or update)
// execute a simplified version of the interpreter where the only
// instruction is write Attribute.
//
// Currently TUPKEYREQ is used in the following situations.
// 1) Normal transaction execution. Can be any of the types described
//    below.
// 2) Execution of fragment redo log during system restart.
//    In this situation there will only be normal updates, inserts
//    and deletes performed.
// 3) A special type of normal transaction execution is to write the
//    records arriving from the primary replica in the node restart
//    processing. This will always be normal write operations which
//    are translated to inserts or updates before arriving to TUP.
// 4) Scan processing. The scan processing will use normal reads or
//    interpreted reads in their execution. There will be one TUPKEYREQ
//    signal for each record processed.
// 5) Copy fragment processing. This is a special type of scan used in the
//    primary replica at system restart. It reads the entire reads and
//    converts those to writes to the starting node. In this special case
//    LQH acts as an API node and receives also the ATTRINFO sent in the
//    TRANSID_AI signals.
//
// Signal Diagram:
//
// In Signals:
// -----------
//
// Logically there is one request TUPKEYREQ which requests to read/write data
// of one tuple in the database. Since the definition of what to read and write
// can be bigger than the maximum signal size we segment the signal. The definition
// of what to read/write/interpreted program is sent before the TUPKEYREQ signal.
//
// ---> ATTRINFO
// ...
// ---> ATTRINFO
// ---> TUPKEYREQ
// The number of ATTRINFO signals can be anything between 0 and upwards.
// The total size of the ATTRINFO is not allowed to be more than 16384 words.
// There is always one and only one TUPKEYREQ.
//
// Response Signals (successful case):
//
// Simple/Dirty Read Operation
// ---------------------------
//
// <---- TRANSID_AI (to API)
// ...
// <---- TRANSID_AI (to API)
// <---- READCONF   (to API)
// <---- TUPKEYCONF (to LQH)
// There is always exactly one READCONF25 sent last. The number of
// TRANSID_AI is dependent on how much that was read. The maximum size
// of the ATTRINFO sent back is 16384 words. The signals are sent
// directly to the application with an address provided by the
// TUPKEYREQ signal.
// A positive response signal is also sent to LQH.
//
// Normal Read Operation
// ---------------------
//
// <---- TRANSID_AI (to API)
// ...
// <---- TRANSID_AI (to API)
// <---- TUPKEYCONF (to LQH)
// The number of TRANSID_AI is dependent on how much that was read.
// The maximum size of the ATTRINFO sent back is 16384 words. The
// signals are sent directly to the application with an address
// provided by the TUPKEYREQ signal.
// A positive response signal is also sent to LQH.
//
// Normal update/insert/delete operation
// -------------------------------------
//
// <---- TUPKEYCONF
// After successful updating of the tuple LQH is informed of this.
//
// Delete with read
// ----------------
//
// Will behave as a normal read although it also prepares the
// deletion of the tuple.
//
// Interpreted Update
// ------------------
//
// <---- TRANSID_AI (to API)
// ...
// <---- TRANSID_AI (to API)
// <---- TUP_ATTRINFO (to LQH)
// ...
// <---- TUP_ATTRINFO (to LQH)
// <---- TUPKEYCONF (to LQH)
//
// The interpreted Update contains five sections:
// The first section performs read Attribute operations
// that send results back to the API.
//
// The second section executes the interpreted program
// where data from attributes can be updated and it
// can also read attribute values into the registers.
//
// The third section performs unconditional updates of
// attributes.
//
// The fourth section can read the attributes to be sent to the
// API after updating the record.
//
// The fifth section contains subroutines used by the interpreter
// in the second section.
//
// All types of interpreted programs contains the same five sections.
// The only difference is that only interpreted updates can update
// attributes. Interpreted inserts are not allowed.
//
// Interpreted Updates have to send back the information about the
// attributes they have updated. This information will be shipped to
// the log and also to any other replicas. Thus interpreted updates
// are only performed in the primary replica. The fragment redo log
// in LQH will contain information so that normal update/inserts/deletes
// can be performed using TUPKEYREQ.
//
// Interpreted Read
// ----------------
//
// From a signalling point of view the Interpreted Read behaves as
// as a Normal Read. The interpreted Read is often used by Scan's.
//
// Interpreted Delete
// ------------------
//
// <---- TUPKEYCONF
// After successful prepartion to delete the tuple LQH is informed
// of this.
//
// Interpreted Delete with Read
// ----------------------------
//
// From a signalling point of view an interpreted delete with read
// behaves as a normal read.
//
// Continuation after successful case:
//
// After a read of any kind the operation record is ready to be used
// again by a new operation.
//
// Any updates, inserts or deletes waits for either of two messages.
// A commit specifying that the operation is to be performed for real
// or an abort specifying that the operation is to be rolled back and
// the record to be restored in its original format.
// 
// This is handled by the module Transaction Manager.
//
// Response Signals (unsuccessful case):
//
// <---- TUPKEYREF (to LQH)
// A signal is sent back to LQH informing about the unsuccessful
// operation. In this case TUP waits for an abort signal to arrive
// before the operation record is ready for the next operation.
// This is handled by the Transaction Manager.
//------------------------------------------------------------------
//------------------------------------------------------------------

// *****************************************************************
// Signal Reception methods.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
  void execTUPKEYREQ(Signal* signal);
unknown's avatar
unknown committed
1716 1717
  void disk_page_load_callback(Signal*, Uint32 op, Uint32 page);
  void disk_page_load_scan_callback(Signal*, Uint32 op, Uint32 page);
1718 1719 1720 1721

//------------------------------------------------------------------
//------------------------------------------------------------------
  void execATTRINFO(Signal* signal);
unknown's avatar
unknown committed
1722 1723 1724
public:
  void receive_attrinfo(Signal*, Uint32 op, const Uint32* data, Uint32 len);
private:
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740

// Trigger signals
//------------------------------------------------------------------
//------------------------------------------------------------------
  void execCREATE_TRIG_REQ(Signal* signal);

//------------------------------------------------------------------
//------------------------------------------------------------------
  void execDROP_TRIG_REQ(Signal* signal);

// *****************************************************************
// Support methods for ATTRINFO.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
  void handleATTRINFOforTUPKEYREQ(Signal* signal,
unknown's avatar
unknown committed
1741
				  const Uint32* data,
1742
                                  Uint32 length,
unknown's avatar
unknown committed
1743
                                  Operationrec * regOperPtr);
1744 1745 1746 1747 1748 1749 1750

// *****************************************************************
// Setting up the environment for reads, inserts, updates and deletes.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleReadReq(Signal* signal,
unknown's avatar
unknown committed
1751 1752
                    Operationrec* regOperPtr,
                    Tablerec* regTabPtr,
unknown's avatar
unknown committed
1753
                    KeyReqStruct* req_struct);
1754 1755 1756 1757

//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleUpdateReq(Signal* signal,
unknown's avatar
unknown committed
1758 1759 1760
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1761 1762
                      KeyReqStruct* req_struct,
		      bool disk);
1763 1764 1765 1766

//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleInsertReq(Signal* signal,
unknown's avatar
unknown committed
1767 1768
                      Ptr<Operationrec> regOperPtr,
                      Ptr<Fragrecord>,
unknown's avatar
unknown committed
1769
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1770
                      KeyReqStruct* req_struct);
1771 1772 1773 1774

//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleDeleteReq(Signal* signal,
unknown's avatar
unknown committed
1775 1776 1777
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1778
                      KeyReqStruct* req_struct);
1779 1780 1781 1782

//------------------------------------------------------------------
//------------------------------------------------------------------
  int  updateStartLab(Signal* signal,
unknown's avatar
unknown committed
1783 1784 1785
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1786
                      KeyReqStruct* req_struct);
1787 1788 1789 1790 1791 1792 1793 1794

// *****************************************************************
// Interpreter Handling methods.
// *****************************************************************

//------------------------------------------------------------------
//------------------------------------------------------------------
  int interpreterStartLab(Signal* signal,
unknown's avatar
unknown committed
1795
                          KeyReqStruct *req_struct);
1796 1797 1798 1799

//------------------------------------------------------------------
//------------------------------------------------------------------
  int interpreterNextLab(Signal* signal,
unknown's avatar
unknown committed
1800
                         KeyReqStruct *req_struct,
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814
                         Uint32* logMemory,
                         Uint32* mainProgram,
                         Uint32 TmainProgLen,
                         Uint32* subroutineProg,
                         Uint32 TsubroutineLen,
			 Uint32 * tmpArea,
			 Uint32 tmpAreaSz);

// *****************************************************************
// Signal Sending methods.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
  void sendReadAttrinfo(Signal* signal,
unknown's avatar
unknown committed
1815
                        KeyReqStruct *req_struct,
1816
                        Uint32 TnoOfData,
unknown's avatar
unknown committed
1817
                        const Operationrec * regOperPtr);
1818 1819 1820 1821 1822

//------------------------------------------------------------------
//------------------------------------------------------------------
  void sendLogAttrinfo(Signal* signal,
                       Uint32 TlogSize,
unknown's avatar
unknown committed
1823
                       Operationrec * regOperPtr);
1824 1825 1826

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1827 1828
  void sendTUPKEYCONF(Signal* signal,
                      KeyReqStruct *req_struct,
unknown's avatar
unknown committed
1829
                      Operationrec * regOperPtr); 
1830 1831 1832 1833 1834 1835 1836 1837 1838

//------------------------------------------------------------------
//------------------------------------------------------------------
// *****************************************************************
// The methods that perform the actual read and update of attributes
// in the tuple.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1839
  int readAttributes(KeyReqStruct* req_struct,
1840
                     const Uint32*  inBuffer,
1841 1842
                     Uint32   inBufLen,
                     Uint32*  outBuffer,
1843 1844
                     Uint32   TmaxRead,
                     bool     xfrmFlag);
1845 1846 1847

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1848
  int updateAttributes(KeyReqStruct *req_struct,
1849 1850 1851 1852 1853 1854
                       Uint32*     inBuffer,
                       Uint32      inBufLen);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHOneWordNotNULL(Uint32* outBuffer,
unknown's avatar
unknown committed
1855
                                     KeyReqStruct *req_struct,
1856 1857 1858 1859 1860 1861
                                     AttributeHeader* ahOut,
                                     Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer,
unknown's avatar
unknown committed
1862
                                       KeyReqStruct *req_struct,
1863 1864 1865 1866 1867
                                       Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHTwoWordNotNULL(Uint32* outBuffer,
unknown's avatar
unknown committed
1868
                                     KeyReqStruct *req_struct,
1869 1870 1871 1872 1873 1874
                                     AttributeHeader* ahOut,
                                     Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHTwoWordNotNULL(Uint32* inBuffer,
unknown's avatar
unknown committed
1875
                                       KeyReqStruct *req_struct,
1876 1877 1878 1879 1880
                                       Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHManyWordNotNULL(Uint32* outBuffer,
unknown's avatar
unknown committed
1881
                                      KeyReqStruct *req_struct,
1882 1883 1884 1885 1886 1887
                                      AttributeHeader* ahOut,
                                      Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
unknown's avatar
unknown committed
1888
                                        KeyReqStruct *req_struct,
1889 1890 1891 1892 1893
                                        Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHOneWordNULLable(Uint32* outBuffer,
unknown's avatar
unknown committed
1894
                                      KeyReqStruct *req_struct,
1895 1896 1897 1898 1899 1900
                                      AttributeHeader* ahOut,
                                      Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHOneWordNULLable(Uint32* inBuffer,
unknown's avatar
unknown committed
1901
                                        KeyReqStruct *req_struct,
1902 1903 1904 1905 1906
                                        Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHTwoWordNULLable(Uint32* outBuffer,
unknown's avatar
unknown committed
1907
                                      KeyReqStruct *req_struct,
1908 1909 1910 1911 1912 1913
                                      AttributeHeader* ahOut,
                                      Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHTwoWordNULLable(Uint32* inBuffer,
unknown's avatar
unknown committed
1914
                                        KeyReqStruct *req_struct,
1915 1916 1917 1918 1919
                                        Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHManyWordNULLable(Uint32* outBuffer,
unknown's avatar
unknown committed
1920
                                       KeyReqStruct *req_struct,
1921 1922 1923 1924 1925 1926
                                       AttributeHeader* ahOut,
                                       Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHZeroWordNULLable(Uint32* outBuffer,
unknown's avatar
unknown committed
1927
                                       KeyReqStruct *req_struct,
1928 1929 1930 1931 1932
                                       AttributeHeader* ahOut,
                                       Uint32  attrDes2);
//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHManyWordNULLable(Uint32* inBuffer,
unknown's avatar
unknown committed
1933
                                         KeyReqStruct *req_struct,
1934 1935 1936 1937
                                         Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1938 1939 1940 1941
  bool readVarSizeNotNULL(Uint32* outBuffer,
                          KeyReqStruct *req_struct,
                          AttributeHeader* ahOut,
                          Uint32  attrDes2);
1942 1943 1944

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1945 1946 1947
  bool updateVarSizeNotNULL(Uint32* inBuffer,
                            KeyReqStruct *req_struct,
                            Uint32  attrDes2);
1948 1949 1950

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1951 1952 1953 1954
  bool readVarSizeNULLable(Uint32* outBuffer,
                           KeyReqStruct *req_struct,
                           AttributeHeader* ahOut,
                           Uint32  attrDes2);
1955 1956 1957

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1958 1959
  bool updateVarSizeNULLable(Uint32* inBuffer,
                             KeyReqStruct *req_struct,
1960 1961 1962 1963 1964
                             Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readDynFixedSize(Uint32* outBuffer,
unknown's avatar
unknown committed
1965
                        KeyReqStruct *req_struct,
1966 1967 1968 1969 1970 1971
                        AttributeHeader* ahOut,
                        Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateDynFixedSize(Uint32* inBuffer,
unknown's avatar
unknown committed
1972
                          KeyReqStruct *req_struct,
1973 1974 1975 1976
                          Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1977 1978 1979 1980
  bool readDynVarSize(Uint32* outBuffer,
                      KeyReqStruct *req_struct,
                      AttributeHeader* ahOut,
                      Uint32  attrDes2);
1981 1982 1983

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1984 1985 1986
  bool updateDynVarSize(Uint32* inBuffer,
                        KeyReqStruct *req_struct,
                        Uint32  attrDes2);
1987

unknown's avatar
unknown committed
1988 1989 1990 1991
  bool readCharNotNULL(Uint32* outBuffer,
                       KeyReqStruct *req_struct,
                       AttributeHeader* ahOut,
                       Uint32  attrDes2);
1992

unknown's avatar
unknown committed
1993 1994 1995 1996
  bool readCharNULLable(Uint32* outBuffer,
                        KeyReqStruct *req_struct,
                        AttributeHeader* ahOut,
                        Uint32  attrDes2);
1997

unknown's avatar
unknown committed
1998 1999 2000 2001
  bool readBitsNULLable(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
  bool updateBitsNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
  bool readBitsNotNULL(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
  bool updateBitsNotNULL(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2002

unknown's avatar
unknown committed
2003 2004
  bool updateFixedNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
  bool updateFixedNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
2005

unknown's avatar
unknown committed
2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
  bool updateVarNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
  bool updateVarNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);


  bool readDiskFixedSizeNotNULL(Uint32* outBuffer,
				KeyReqStruct *req_struct,
				AttributeHeader* ahOut,
				Uint32  attrDes2);
  
  bool readDiskFixedSizeNULLable(Uint32* outBuffer,
				 KeyReqStruct *req_struct,
				 AttributeHeader* ahOut,
				 Uint32  attrDes2);
  bool readDiskVarSizeNULLable(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
  bool readDiskVarSizeNotNULL(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);

  bool updateDiskFixedSizeNULLable(Uint32*, KeyReqStruct*, Uint32);
  bool updateDiskFixedSizeNotNULL(Uint32*, KeyReqStruct*, Uint32);

  bool updateDiskVarSizeNULLable(Uint32*, KeyReqStruct *, Uint32);
  bool updateDiskVarSizeNotNULL(Uint32*, KeyReqStruct *, Uint32);
  
  bool readDiskBitsNULLable(Uint32*, KeyReqStruct*, AttributeHeader*, Uint32);
  bool readDiskBitsNotNULL(Uint32*, KeyReqStruct*, AttributeHeader*, Uint32);
  bool updateDiskBitsNULLable(Uint32*, KeyReqStruct*, Uint32);
  bool updateDiskBitsNotNULL(Uint32*, KeyReqStruct*, Uint32);
2032 2033


2034 2035
//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2036 2037 2038 2039 2040
  bool nullFlagCheck(KeyReqStruct *req_struct, Uint32  attrDes2);
  bool disk_nullFlagCheck(KeyReqStruct *req_struct, Uint32  attrDes2);
  Uint32 read_pseudo(Uint32 attrId,
                     KeyReqStruct *req_struct,
                     Uint32* outBuffer);
2041 2042 2043

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2044
  void setUpQueryRoutines(Tablerec* regTabPtr);
2045 2046 2047 2048

// *****************************************************************
// Service methods.
// *****************************************************************
unknown's avatar
unknown committed
2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061
  TransState get_trans_state(Operationrec * const);
  void set_trans_state(Operationrec * const, TransState);
  TupleState get_tuple_state(Operationrec * const);
  void set_tuple_state(Operationrec * const, TupleState);
  Uint32 get_frag_page_id(Uint32 real_page_id);
  Uint32 get_fix_page_offset(Uint32 page_index, Uint32 tuple_size);

  Uint32 decr_tup_version(Uint32 tuple_version);
  void set_change_mask_state(Operationrec * const, ChangeMaskState);
  ChangeMaskState get_change_mask_state(Operationrec * const);
  void update_change_mask_info(KeyReqStruct * const, Operationrec * const);
  void set_change_mask_info(KeyReqStruct * const, Operationrec * const);

2062 2063
//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2064
  void copyAttrinfo(Operationrec * regOperPtr, Uint32*  inBuffer);
2065 2066 2067

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2068
  void initOpConnection(Operationrec* regOperPtr);
2069 2070 2071 2072 2073 2074 2075

//------------------------------------------------------------------
//------------------------------------------------------------------
  void initOperationrec(Signal* signal);

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2076
  int initStoredOperationrec(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2077
                             KeyReqStruct* req_struct,
2078 2079 2080 2081
                             Uint32 storedId);

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2082
  bool insertActiveOpList(OperationrecPtr, KeyReqStruct* req_struct);
2083 2084 2085 2086 2087 2088

//------------------------------------------------------------------
//------------------------------------------------------------------

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2089
  void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen);
2090 2091 2092 2093

//------------------------------------------------------------------
// Trigger handling routines
//------------------------------------------------------------------
2094
  DLList<TupTriggerData>*
unknown's avatar
unknown committed
2095 2096 2097 2098
  findTriggerList(Tablerec* table,
                  TriggerType::Value ttype,
                  TriggerActionTime::Value ttime,
                  TriggerEvent::Value tevent);
2099 2100 2101

  bool createTrigger(Tablerec* table, const CreateTrigReq* req);

2102 2103 2104
  Uint32 dropTrigger(Tablerec* table,
		     const DropTrigReq* req,
		     BlockNumber sender);
2105

unknown's avatar
unknown committed
2106 2107
  void
  checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2108 2109
                                    Operationrec* regOperPtr, 
                                    Tablerec* tablePtr);
2110

unknown's avatar
unknown committed
2111 2112
  void
  checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2113 2114
                                    Operationrec* regOperPtr, 
                                    Tablerec* tablePtr);
2115

unknown's avatar
unknown committed
2116 2117
  void
  checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2118 2119
                                    Operationrec* regOperPtr, 
                                    Tablerec* tablePtr);
2120 2121 2122

#if 0
  void checkDeferredTriggers(Signal* signal, 
unknown's avatar
unknown committed
2123 2124
                             Operationrec* regOperPtr,
                             Tablerec* regTablePtr);
2125
#endif
unknown's avatar
unknown committed
2126
  void checkDetachedTriggers(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2127 2128
                             Operationrec* regOperPtr,
                             Tablerec* regTablePtr);
2129

unknown's avatar
unknown committed
2130
  void fireImmediateTriggers(KeyReqStruct *req_struct,
2131
                             DLList<TupTriggerData>& triggerList, 
unknown's avatar
unknown committed
2132
                             Operationrec* regOperPtr);
2133

unknown's avatar
unknown committed
2134
  void fireDeferredTriggers(KeyReqStruct *req_struct,
2135
                            DLList<TupTriggerData>& triggerList,
unknown's avatar
unknown committed
2136
                            Operationrec* regOperPtr);
2137

unknown's avatar
unknown committed
2138
  void fireDetachedTriggers(KeyReqStruct *req_struct,
2139
                            DLList<TupTriggerData>& triggerList,
unknown's avatar
unknown committed
2140
                            Operationrec* regOperPtr);
2141

unknown's avatar
unknown committed
2142
  void executeTriggers(KeyReqStruct *req_struct,
2143
                       DLList<TupTriggerData>& triggerList,
unknown's avatar
unknown committed
2144
                       Operationrec* regOperPtr);
2145

unknown's avatar
unknown committed
2146
  void executeTrigger(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2147 2148 2149 2150 2151 2152 2153 2154
                      TupTriggerData* trigPtr, 
                      Operationrec* regOperPtr);

  bool readTriggerInfo(TupTriggerData* trigPtr,
                       Operationrec* regOperPtr,
                       KeyReqStruct * req_struct,
                       Fragrecord* regFragPtr,
                       Uint32* keyBuffer,
2155
                       Uint32& noPrimKey,
unknown's avatar
unknown committed
2156
                       Uint32* afterBuffer,
unknown's avatar
unknown committed
2157
                       Uint32& noAfterWords,
unknown's avatar
unknown committed
2158
                       Uint32* beforeBuffer,
unknown's avatar
unknown committed
2159
                       Uint32& noBeforeWords);
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171

  void sendTrigAttrInfo(Signal*        signal, 
                        Uint32*        data, 
                        Uint32         dataLen,
                        bool           executeDirect,
                        BlockReference receiverReference);

  Uint32 setAttrIds(Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask, 
                    Uint32 noOfAttributes, 
                    Uint32* inBuffer);

  void sendFireTrigOrd(Signal* signal, 
unknown's avatar
unknown committed
2172
                       KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2173 2174
                       Operationrec * regOperPtr,
                       TupTriggerData* trigPtr,
unknown's avatar
unknown committed
2175
		       Uint32 fragmentId,
2176 2177 2178 2179 2180 2181 2182 2183 2184
                       Uint32 noPrimKeySignals, 
                       Uint32 noBeforeSignals, 
                       Uint32 noAfterSignals);

  bool primaryKey(Tablerec* const, Uint32);

  // these set terrorCode and return non-zero on error

  int executeTuxInsertTriggers(Signal* signal, 
unknown's avatar
unknown committed
2185 2186 2187
                               Operationrec* regOperPtr,
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2188 2189

  int executeTuxUpdateTriggers(Signal* signal, 
unknown's avatar
unknown committed
2190 2191 2192
                               Operationrec* regOperPtr,
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2193 2194

  int executeTuxDeleteTriggers(Signal* signal, 
unknown's avatar
unknown committed
2195 2196 2197
                               Operationrec* regOperPtr,
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2198

unknown's avatar
unknown committed
2199 2200 2201 2202
  int addTuxEntries(Signal* signal,
                    Operationrec* regOperPtr,
                    Tablerec* regTabPtr);

2203 2204 2205 2206
  // these crash the node on error

  void executeTuxCommitTriggers(Signal* signal, 
                                Operationrec* regOperPtr,
unknown's avatar
unknown committed
2207 2208
                                Fragrecord* regFragPtr,
                                Tablerec* regTabPtr);
2209 2210 2211

  void executeTuxAbortTriggers(Signal* signal, 
                               Operationrec* regOperPtr,
unknown's avatar
unknown committed
2212 2213
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2214

unknown's avatar
unknown committed
2215 2216 2217
  void removeTuxEntries(Signal* signal,
                        Tablerec* regTabPtr);

2218 2219 2220 2221 2222 2223 2224 2225 2226 2227
// *****************************************************************
// Error Handling routines.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
  int TUPKEY_abort(Signal* signal, int error_type);

//------------------------------------------------------------------
//------------------------------------------------------------------
  void tupkeyErrorLab(Signal* signal);
unknown's avatar
unknown committed
2228
  void do_tup_abortreq(Signal*, Uint32 flags);
2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253

//------------------------------------------------------------------
//------------------------------------------------------------------
// Methods to handle execution of TUP_COMMITREQ + TUP_ABORTREQ.
//
// Module Transaction Manager
//
// The Transaction Manager module is responsible for the commit
// and abort of operations started by the Execution Manager.
//
// Commit Operation:
// ----------------
//
// Failures in commit processing is not allowed since that would
// leave the database in an unreliable state. Thus the only way
// to handle failures in commit processing is to crash the node.
//
// TUP_COMMITREQ can only be received in the wait state after a
// successful TUPKEYREQ which was not a read operation.
// 
// Commit of Delete:
// -----------------
//
// This will actually perform the deletion of the record unless
// other operations also are connected to the record. In this case
unknown's avatar
unknown committed
2254
// we will set the delete state on the record that becomes the ownerd
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293
// of the record.
//
// Commit of Update:
// ----------------
//
// We will release the copy record where the original record was kept.
// Also here we will take special care if more operations are updating
// the record simultaneously.
//
// Commit of Insert:
// -----------------
//
// Will simply reset the state of the operation record.
//
// Signal Diagram:
// --->  TUP_COMMITREQ (from LQH)
// <---- TUP_COMMITCONF (to LQH)
//
//
// Abort Operation:
// ----------------
//
// Signal Diagram:
// --->  TUP_ABORTREQ (from LQH)
// <---- TUP_ABORTCONF (to LQH)
//
// Failures in abort processing is not allowed since that would
// leave the database in an unreliable state. Thus the only way
// to handle failures in abort processing is to crash the node.
//
// Abort messages can arrive at any time. It can arrive even before
// anything at all have arrived of the operation. It can arrive after
// receiving a number of ATTRINFO but before TUPKEYREQ has been received.
// It must arrive after that we sent TUPKEYREF in response to TUPKEYREQ
// and finally it can arrive after successfully performing the TUPKEYREQ
// in all cases including the read case.
//------------------------------------------------------------------
//------------------------------------------------------------------

unknown's avatar
unknown committed
2294
#if 0 
unknown's avatar
unknown committed
2295
  void checkPages(Fragrecord* regFragPtr);
2296
#endif
unknown's avatar
unknown committed
2297 2298 2299 2300 2301 2302 2303 2304 2305 2306
  Uint32 convert_byte_to_word_size(Uint32 byte_size)
  {
    return ((byte_size + 3) >> 2);
  }
  Uint32 convert_bit_to_word_size(Uint32 bit_size)
  {
    return ((bit_size + 31) >> 5);
  }

  void prepare_initial_insert(KeyReqStruct*, Operationrec*, Tablerec*);
2307
  void fix_disk_insert_no_mem_insert(KeyReqStruct*, Operationrec*, Tablerec*);
unknown's avatar
unknown committed
2308
  void setup_fixed_part(KeyReqStruct* req_struct,
unknown's avatar
unknown committed
2309 2310
			Operationrec* regOperPtr,
			Tablerec* regTabPtr);
unknown's avatar
unknown committed
2311 2312
  
  void send_TUPKEYREF(Signal* signal,
unknown's avatar
unknown committed
2313
                      Operationrec* regOperPtr);
unknown's avatar
unknown committed
2314
  void early_tupkey_error(Signal* signal);
2315

unknown's avatar
unknown committed
2316
  void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit);
2317

unknown's avatar
unknown committed
2318 2319
  bool checkUpdateOfPrimaryKey(KeyReqStruct *req_struct,
                               Uint32* updateBuffer,
unknown's avatar
unknown committed
2320
                               Tablerec* regTabPtr);
2321

unknown's avatar
unknown committed
2322
  void setNullBits(Uint32*, Tablerec* regTabPtr);
unknown's avatar
unknown committed
2323 2324
  bool checkNullAttributes(KeyReqStruct * const, Tablerec* const);
  bool setup_read(KeyReqStruct* req_struct,
unknown's avatar
unknown committed
2325 2326 2327
		  Operationrec* regOperPtr,
		  Fragrecord* regFragPtr,
		  Tablerec* regTabPtr,
unknown's avatar
unknown committed
2328 2329
		  bool disk);
  
unknown's avatar
unknown committed
2330 2331
  Uint32 calculateChecksum(Tuple_header*, Tablerec* regTabPtr);
  void setChecksum(Tuple_header*, Tablerec* regTabPtr);
2332

unknown's avatar
unknown committed
2333 2334
  void complexTrigger(Signal* signal,
                      KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2335 2336 2337
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr);
2338

unknown's avatar
unknown committed
2339
  void setTupleStatesSetOpType(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2340
                               KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2341
                               Page* pagePtr,
2342 2343 2344 2345 2346 2347
                               Uint32& opType,
                               OperationrecPtr& firstOpPtr);

  void findBeforeValueOperation(OperationrecPtr& befOpPtr,
                                OperationrecPtr firstOpPtr);

unknown's avatar
unknown committed
2348 2349 2350
  void calculateChangeMask(Page* PagePtr,
                           Tablerec* regTabPtr,
                           KeyReqStruct * req_struct);
2351

unknown's avatar
unknown committed
2352
  void updateGcpId(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2353 2354 2355
                   Operationrec* regOperPtr,
                   Fragrecord* regFragPtr,
                   Tablerec* regTabPtr);
2356 2357 2358 2359 2360 2361

  void setTupleStateOnPreviousOps(Uint32 prevOpIndex);
  void copyMem(Signal* signal, Uint32 sourceIndex, Uint32 destIndex);

  void freeAllAttrBuffers(Operationrec*  const regOperPtr);
  void freeAttrinbufrec(Uint32 anAttrBufRec);
unknown's avatar
unknown committed
2362
  void removeActiveOpList(Operationrec*  const regOperPtr, Tuple_header*);
2363 2364 2365 2366

  void updatePackedList(Signal* signal, Uint16 ahostIndex);

  void setUpDescriptorReferences(Uint32 descriptorReference,
unknown's avatar
unknown committed
2367
                                 Tablerec* regTabPtr,
unknown's avatar
unknown committed
2368
                                 const Uint32* offset);
unknown's avatar
unknown committed
2369 2370 2371
  void setUpKeyArray(Tablerec* regTabPtr);
  bool addfragtotab(Tablerec* regTabPtr, Uint32 fragId, Uint32 fragIndex);
  void deleteFragTab(Tablerec* regTabPtr, Uint32 fragId);
2372
  void abortAddFragOp(Signal* signal);
unknown's avatar
unknown committed
2373 2374
  void releaseTabDescr(Tablerec* regTabPtr);
  void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* regTabPtr);
2375

2376
  void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32);
2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390
  void initializeAttrbufrec();
  void initializeCheckpointInfoRec();
  void initializeDiskBufferSegmentRecord();
  void initializeFragoperrec();
  void initializeFragrecord();
  void initializeHostBuffer();
  void initializeLocalLogInfo();
  void initializeOperationrec();
  void initializePendingFileOpenInfoRecord();
  void initializeRestartInfoRec();
  void initializeTablerec();
  void initializeTabDescr();
  void initializeUndoPage();

unknown's avatar
unknown committed
2391
  void initTab(Tablerec* regTabPtr);
2392 2393 2394 2395 2396 2397 2398 2399 2400

  void startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2);

  void fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr);
  void fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr);
  void fragrefuse2Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr);
  void fragrefuse3Lab(Signal* signal,
                      FragoperrecPtr fragOperPtr,
                      FragrecordPtr regFragPtr,
unknown's avatar
unknown committed
2401
                      Tablerec* regTabPtr,
2402 2403 2404 2405
                      Uint32 fragId);
  void fragrefuse4Lab(Signal* signal,
                      FragoperrecPtr fragOperPtr,
                      FragrecordPtr regFragPtr,
unknown's avatar
unknown committed
2406
                      Tablerec* regTabPtr,
2407 2408 2409 2410
                      Uint32 fragId);
  void addattrrefuseLab(Signal* signal,
                        FragrecordPtr regFragPtr,
                        FragoperrecPtr fragOperPtr,
unknown's avatar
unknown committed
2411
                        Tablerec* regTabPtr,
2412 2413 2414
                        Uint32 fragId);


unknown's avatar
unknown committed
2415
  void releaseFragment(Signal* signal, Uint32 tableId, Uint32);
unknown's avatar
unknown committed
2416
  void drop_fragment_free_var_pages(Signal*);
unknown's avatar
unknown committed
2417 2418
  void drop_fragment_free_extent(Signal*, TablerecPtr, FragrecordPtr, Uint32);
  void drop_fragment_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
unknown's avatar
unknown committed
2419 2420 2421
  void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32);
  void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32);
  
2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436
  // Initialisation
  void initData();
  void initRecords();

  void deleteScanProcedure(Signal* signal, Operationrec* regOperPtr);
  void copyProcedure(Signal* signal,
                     TablerecPtr regTabPtr,
                     Operationrec* regOperPtr);
  void scanProcedure(Signal* signal,
                     Operationrec* regOperPtr,
                     Uint32 lenAttrInfo);
  void storedSeizeAttrinbufrecErrorLab(Signal* signal,
                                       Operationrec* regOperPtr);
  bool storedProcedureAttrInfo(Signal* signal,
                               Operationrec* regOperPtr,
unknown's avatar
unknown committed
2437
			       const Uint32* data,
2438 2439 2440 2441 2442 2443 2444 2445
                               Uint32 length,
                               bool copyProc);

//-----------------------------------------------------------------------------
// Table Descriptor Memory Manager
//-----------------------------------------------------------------------------

// Public methods
unknown's avatar
unknown committed
2446 2447
  Uint32 getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset);
  Uint32 allocTabDescr(const Tablerec* regTabPtr, Uint32* offset);
2448
  void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
2449 2450 2451 2452 2453 2454
  Uint32 getTabDescrWord(Uint32 index);
  void setTabDescrWord(Uint32 index, Uint32 word);

// Private methods
  Uint32 sizeOfReadFunction();
  void   removeTdArea(Uint32 tabDesRef, Uint32 list);
2455 2456 2457 2458 2459
  void   insertTdArea(Uint32 tabDesRef, Uint32 list);
  void   itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
#ifdef VM_TRACE
  void verifytabdes();
#endif
2460

unknown's avatar
unknown committed
2461 2462 2463 2464 2465 2466
  void seizeOpRec(OperationrecPtr& regOperPtr);
  void seizeFragrecord(FragrecordPtr& regFragPtr);
  void seizeFragoperrec(FragoperrecPtr& fragOperPtr);
  void releaseFragoperrec(FragoperrecPtr fragOperPtr);
  void releaseFragrec(FragrecordPtr);
//----------------------------------------------------------------------------
2467
// Page Memory Manager
unknown's avatar
unknown committed
2468 2469
//----------------------------------------------------------------------------
  
2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492
// Public methods
  void allocConsPages(Uint32 noOfPagesToAllocate,
                      Uint32& noOfPagesAllocated,
                      Uint32& allocPageRef);
  void returnCommonArea(Uint32 retPageRef, Uint32 retNo);
  void initializePage();

// Private methods
  void removeCommonArea(Uint32 remPageRef, Uint32 list);
  void insertCommonArea(Uint32 insPageRef, Uint32 list);
  void findFreeLeftNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate);
  void findFreeRightNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate);
  Uint32 nextHigherTwoLog(Uint32 input);

// Private data
  Uint32 cfreepageList[16];

//------------------------------------------------------------------------------------------------------
// Page Mapper, convert logical page id's to physical page id's
// The page mapper also handles the pages allocated to the fragment.
//------------------------------------------------------------------------------------------------------
//
// Public methods
unknown's avatar
unknown committed
2493 2494
  Uint32 getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId);
  Uint32 getNoOfPages(Fragrecord* regFragPtr);
2495
  void initPageRangeSize(Uint32 size);
unknown's avatar
unknown committed
2496
  bool insertPageRangeTab(Fragrecord* regFragPtr,
2497 2498
                          Uint32 startPageId,
                          Uint32 noPages);
unknown's avatar
unknown committed
2499 2500
  void releaseFragPages(Fragrecord* regFragPtr);
  void initFragRange(Fragrecord* regFragPtr);
2501
  void initializePageRange();
unknown's avatar
unknown committed
2502 2503 2504 2505
  Uint32 getEmptyPage(Fragrecord* regFragPtr);
  Uint32 allocFragPages(Fragrecord* regFragPtr, Uint32 noOfPagesAllocated);
  Uint32 get_empty_var_page(Fragrecord* frag_ptr);
  
2506
// Private methods
unknown's avatar
unknown committed
2507
  Uint32 leafPageRangeFull(Fragrecord* regFragPtr, PageRangePtr currPageRangePtr);
2508 2509 2510
  void releasePagerange(PageRangePtr regPRPtr);
  void seizePagerange(PageRangePtr& regPageRangePtr);
  void errorHandler(Uint32 errorCode);
unknown's avatar
unknown committed
2511
  void allocMoreFragPages(Fragrecord* regFragPtr);
2512 2513 2514 2515 2516 2517 2518

// Private data
  Uint32 cfirstfreerange;
  PageRange *pageRange;
  Uint32 c_noOfFreePageRanges;
  Uint32 cnoOfPageRangeRec;

unknown's avatar
unknown committed
2519 2520
//---------------------------------------------------------------
// Variable Allocator
2521
// Allocates and deallocates tuples of fixed size on a fragment.
unknown's avatar
unknown committed
2522
//---------------------------------------------------------------
2523 2524
//
// Public methods
unknown's avatar
unknown committed
2525 2526

  void init_list_sizes(void);
2527 2528 2529

// Private methods

unknown's avatar
unknown committed
2530
  Uint32 get_alloc_page(Fragrecord* const, Uint32);
unknown's avatar
unknown committed
2531
  void update_free_page_list(Fragrecord* const, Ptr<Page>);
2532

unknown's avatar
unknown committed
2533 2534 2535 2536 2537
#if 0  
  Uint32 calc_free_list(const Tablerec* regTabPtr, Uint32 sz) const {
    return regTabPtr->m_disk_alloc_info.calc_page_free_bits(sz);
  }
#endif
2538

unknown's avatar
unknown committed
2539 2540 2541
  Uint32 calculate_free_list_impl(Uint32) const ;
  void remove_free_page(Fragrecord*, Var_page*, Uint32);
  void insert_free_page(Fragrecord*, Var_page*, Uint32);
2542

unknown's avatar
unknown committed
2543 2544 2545 2546 2547 2548
//---------------------------------------------------------------
// Fixed Allocator
// Allocates and deallocates tuples of fixed size on a fragment.
//---------------------------------------------------------------
//
// Public methods
unknown's avatar
unknown committed
2549 2550 2551 2552 2553
  Uint32* alloc_var_rec(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
  void free_var_rec(Fragrecord*, Tablerec*, Local_key*, Ptr<Page>);
  Uint32* alloc_var_part(Fragrecord*, Tablerec*, Uint32, Local_key*);
  int realloc_var_part(Fragrecord*, Tablerec*, 
		       PagePtr, Var_part_ref*, Uint32, Uint32);
unknown's avatar
unknown committed
2554 2555 2556
  
  void validate_page(Tablerec*, Var_page* page);
  
2557 2558
  Uint32* alloc_fix_rec(Fragrecord*const, Tablerec*const, Local_key*,
                        Uint32*);
unknown's avatar
unknown committed
2559 2560
  void free_fix_rec(Fragrecord*, Tablerec*, Local_key*, Fix_page*);
  
unknown's avatar
unknown committed
2561 2562
  Uint32* alloc_fix_rowid(Fragrecord*, Tablerec*, Local_key*, Uint32 *);
  Uint32* alloc_var_rowid(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
unknown's avatar
unknown committed
2563
// Private methods
unknown's avatar
unknown committed
2564 2565 2566
  void convertThPage(Fix_page* regPagePtr,
		     Tablerec*,
		     Uint32 mm);
unknown's avatar
unknown committed
2567 2568 2569 2570

  /**
   * Return offset
   */
unknown's avatar
unknown committed
2571 2572
  Uint32 alloc_tuple_from_page(Fragrecord* regFragPtr,
			       Fix_page* regPagePtr);
unknown's avatar
unknown committed
2573 2574 2575 2576 2577
  
//---------------------------------------------------------------
// Temporary variables used for storing commonly used variables
// in certain modules
//---------------------------------------------------------------
2578

unknown's avatar
unknown committed
2579
  Uint32 c_lcp_scan_op;
2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602
  FragrecordPtr   fragptr;
  OperationrecPtr operPtr;
  TablerecPtr     tabptr;

// readAttributes and updateAttributes module
//------------------------------------------------------------------------------------------------------
// Common stored variables. Variables that have a valid value always.
//------------------------------------------------------------------------------------------------------
  Attrbufrec *attrbufrec;
  Uint32 cfirstfreeAttrbufrec;
  Uint32 cnoOfAttrbufrec;
  Uint32 cnoFreeAttrbufrec;

  Fragoperrec *fragoperrec;
  Uint32 cfirstfreeFragopr;
  Uint32 cnoOfFragoprec;

  Fragrecord *fragrecord;
  Uint32 cfirstfreefrag;
  Uint32 cnoOfFragrec;

  HostBuffer *hostBuffer;

unknown's avatar
unknown committed
2603
  ArrayPool<Operationrec> c_operation_pool;
2604

unknown's avatar
unknown committed
2605
  ArrayPool<Page> c_page_pool;
2606 2607 2608 2609 2610 2611 2612
  Uint32 cnoOfAllocatedPages;
  
  Tablerec *tablerec;
  Uint32 cnoOfTablerec;

  TableDescriptor *tableDescriptor;
  Uint32 cnoOfTabDescrRec;
unknown's avatar
unknown committed
2613
  
2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635
  Uint32 cdata[32];
  Uint32 cdataPages[16];
  Uint32 cpackedListIndex;
  Uint32 cpackedList[MAX_NODES];
  Uint32 cfreeTdList[16];
  Uint32 clastBitMask;
  Uint32 clblPageCounter;
  Uint32 clblPagesPerTick;
  Uint32 clblPagesPerTickAfterSr;
  BlockReference clqhBlockref;
  Uint32 clqhUserpointer;
  Uint32 cminusOne;
  BlockReference cndbcntrRef;
  BlockReference cownref;
  Uint32 cownNodeId;
  Uint32 czero;

 // A little bit bigger to cover overwrites in copy algorithms (16384 real size).
#define ZATTR_BUFFER_SIZE 16384
  Uint32 clogMemBuffer[ZATTR_BUFFER_SIZE + 16];
  Uint32 coutBuffer[ZATTR_BUFFER_SIZE + 16];
  Uint32 cinBuffer[ZATTR_BUFFER_SIZE + 16];
unknown's avatar
unknown committed
2636 2637
  Uint32 ctemp_page[ZWORDS_ON_PAGE];
  Uint32 ctemp_var_record[ZWORDS_ON_PAGE];
2638 2639 2640 2641
  Uint32 totNoOfPagesAllocated;

  // Trigger variables
  Uint32 c_maxTriggersPerTable;
2642
  Uint32 c_memusage_report_frequency;
2643 2644

  Uint32 c_errorInsert4000TableId;
unknown's avatar
unknown committed
2645 2646
  Uint32 c_min_list_size[MAX_FREE_LIST + 1];
  Uint32 c_max_list_size[MAX_FREE_LIST + 1];
2647 2648 2649

  void initGlobalTemporaryVars();
  void reportMemoryUsage(Signal* signal, int incDec);
2650 2651

  
2652 2653 2654 2655 2656 2657 2658
#ifdef VM_TRACE
  struct Th {
    Uint32 data[1];
  };
  friend class NdbOut& operator<<(NdbOut&, const Operationrec&);
  friend class NdbOut& operator<<(NdbOut&, const Th&);
#endif
unknown's avatar
unknown committed
2659 2660 2661 2662 2663 2664 2665

  void expand_tuple(KeyReqStruct*, Uint32 sizes[4], Tuple_header*org, 
		    const Tablerec*, bool disk);
  void shrink_tuple(KeyReqStruct*, Uint32 sizes[2], const Tablerec*,
		    bool disk);
  
  Uint32* get_ptr(Var_part_ref);
unknown's avatar
unknown committed
2666
  Uint32* get_ptr(PagePtr*, Var_part_ref);
unknown's avatar
unknown committed
2667
  Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
unknown's avatar
unknown committed
2668
  Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
unknown's avatar
unknown committed
2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691

  /**
   * prealloc space from disk
   *   key.m_file_no  contains file no
   *   key.m_page_no  contains disk page
   *   key.m_page_idx contains byte preallocated
   */
  int disk_page_prealloc(Signal*, Ptr<Fragrecord>, Local_key*, Uint32);
  void disk_page_prealloc_dirty_page(Disk_alloc_info&, 
				     Ptr<Page>, Uint32, Uint32);
  void disk_page_prealloc_transit_page(Disk_alloc_info&,
				       Ptr<Page_request>, Uint32, Uint32);
  
  void disk_page_abort_prealloc(Signal*, Fragrecord*,Local_key*, Uint32);
  void disk_page_abort_prealloc_callback(Signal*, Uint32, Uint32);
  void disk_page_abort_prealloc_callback_1(Signal*, Fragrecord*,
					   PagePtr, Uint32);
  
  void disk_page_prealloc_callback(Signal*, Uint32, Uint32);
  void disk_page_prealloc_initial_callback(Signal*, Uint32, Uint32);
  void disk_page_prealloc_callback_common(Signal*, 
					  Ptr<Page_request>, 
					  Ptr<Fragrecord>,
unknown's avatar
unknown committed
2692
					  Ptr<Page>);
unknown's avatar
unknown committed
2693 2694 2695 2696 2697 2698 2699 2700 2701
  
  void disk_page_alloc(Signal*, 
		       Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
  void disk_page_free(Signal*, 
		      Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
  
  void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);  
  
  void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32); 
unknown's avatar
unknown committed
2702 2703 2704

  void disk_page_alloc_extent_log_buffer_callback(Signal*, Uint32, Uint32);
  void disk_page_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
unknown's avatar
unknown committed
2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717
  
  Uint64 disk_page_undo_alloc(Page*, const Local_key*,
			      Uint32 sz, Uint32 gci, Uint32 logfile_group_id);

  Uint64 disk_page_undo_update(Page*, const Local_key*,
			       const Uint32*, Uint32,
			       Uint32 gci, Uint32 logfile_group_id);
  
  Uint64 disk_page_undo_free(Page*, const Local_key*,
			     const Uint32*, Uint32 sz,
			     Uint32 gci, Uint32 logfile_group_id);

  void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused);
unknown's avatar
unknown committed
2718
  void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
unknown's avatar
unknown committed
2719

unknown's avatar
unknown committed
2720 2721 2722
  void drop_table_log_buffer_callback(Signal*, Uint32, Uint32);
  void drop_table_logsync_callback(Signal*, Uint32, Uint32);

unknown's avatar
unknown committed
2723
  void disk_page_set_dirty(Ptr<Page>);
unknown's avatar
unknown committed
2724
  void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
unknown's avatar
unknown committed
2725 2726
  void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>);
  
unknown's avatar
unknown committed
2727 2728 2729 2730 2731
  /**
   * Disk restart code
   */
public:
  int disk_page_load_hook(Uint32 page_id);
unknown's avatar
unknown committed
2732 2733
  
  void disk_page_unmap_callback(Uint32 page_id, Uint32 dirty_count);
unknown's avatar
unknown committed
2734 2735 2736 2737
  
  int disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId, 
				const Local_key* key, Uint32 pages);
  void disk_restart_page_bits(Uint32 tableId, Uint32 fragId,
unknown's avatar
unknown committed
2738
			      const Local_key*, Uint32 bits);
unknown's avatar
unknown committed
2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749
  void disk_restart_undo(Signal* signal, Uint64 lsn,
			 Uint32 type, const Uint32 * ptr, Uint32 len);

  struct Apply_undo 
  {
    Uint32 m_type, m_len;
    const Uint32* m_ptr;
    Uint64 m_lsn;
    Ptr<Tablerec> m_table_ptr;
    Ptr<Fragrecord> m_fragment_ptr;
    Ptr<Page> m_page_ptr;
unknown's avatar
unknown committed
2750
    Ptr<Extent_info> m_extent_ptr;
unknown's avatar
unknown committed
2751 2752
    Local_key m_key;
  };
unknown's avatar
unknown committed
2753 2754

  void disk_restart_mark_no_lcp(Uint32 table, Uint32 frag);
unknown's avatar
unknown committed
2755 2756 2757
  
private:
  void disk_restart_undo_next(Signal*);
unknown's avatar
unknown committed
2758
  void disk_restart_undo_lcp(Uint32, Uint32, Uint32 flag);
unknown's avatar
unknown committed
2759 2760 2761 2762
  void disk_restart_undo_callback(Signal* signal, Uint32, Uint32);
  void disk_restart_undo_alloc(Apply_undo*);
  void disk_restart_undo_update(Apply_undo*);
  void disk_restart_undo_free(Apply_undo*);
unknown's avatar
unknown committed
2763
  void disk_restart_undo_page_bits(Signal*, Apply_undo*);
unknown's avatar
unknown committed
2764 2765 2766 2767 2768 2769 2770 2771

#ifdef VM_TRACE
  void verify_page_lists(Disk_alloc_info&);
#else
  void verify_page_lists(Disk_alloc_info&) {}
#endif
  
  void fix_commit_order(OperationrecPtr);
unknown's avatar
unknown committed
2772
  void commit_operation(Signal*, Uint32, Tuple_header*, PagePtr,
unknown's avatar
unknown committed
2773 2774 2775 2776 2777 2778 2779 2780
			Operationrec*, Fragrecord*, Tablerec*);
  
  void dealloc_tuple(Signal* signal, Uint32, Page*, Tuple_header*, 
		     Operationrec*, Fragrecord*, Tablerec*);
  
  int handle_size_change_after_update(KeyReqStruct* req_struct,
				      Tuple_header* org,
				      Operationrec*,
unknown's avatar
unknown committed
2781 2782
				      Fragrecord* regFragPtr,
				      Tablerec* regTabPtr,
unknown's avatar
unknown committed
2783 2784 2785 2786 2787 2788 2789
				      Uint32 sizes[4]);

  /**
   * Setup all pointer on keyreqstruct to prepare for read
   *   req_struct->m_tuple_ptr is set to tuple to read
   */
  void prepare_read(KeyReqStruct*, Tablerec* const, bool disk);
2790 2791
};

unknown's avatar
unknown committed
2792
#if 0
2793
inline
unknown's avatar
unknown committed
2794 2795 2796 2797 2798 2799 2800 2801
Uint32
Dbtup::get_frag_page_id(Uint32 real_page_id)
{
  PagePtr real_page_ptr;
  real_page_ptr.i= real_page_id;
  ptrCheckGuard(real_page_ptr, cnoOfPage, cpage);
  return real_page_ptr.p->frag_page_id;
}
unknown's avatar
unknown committed
2802
#endif
unknown's avatar
unknown committed
2803 2804 2805

inline
Dbtup::TransState
unknown's avatar
unknown committed
2806
Dbtup::get_trans_state(Operationrec * regOperPtr)
unknown's avatar
unknown committed
2807 2808 2809 2810 2811 2812
{
  return (Dbtup::TransState)regOperPtr->op_struct.trans_state;
}

inline
void
unknown's avatar
unknown committed
2813
Dbtup::set_trans_state(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2814 2815 2816 2817 2818 2819 2820
                       Dbtup::TransState trans_state)
{
  regOperPtr->op_struct.trans_state= (Uint32)trans_state;
}

inline
Dbtup::TupleState
unknown's avatar
unknown committed
2821
Dbtup::get_tuple_state(Operationrec * regOperPtr)
unknown's avatar
unknown committed
2822 2823 2824 2825 2826 2827
{
  return (Dbtup::TupleState)regOperPtr->op_struct.tuple_state;
}

inline
void
unknown's avatar
unknown committed
2828
Dbtup::set_tuple_state(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843
                       Dbtup::TupleState tuple_state)
{
  regOperPtr->op_struct.tuple_state= (Uint32)tuple_state;
}


inline
Uint32
Dbtup::decr_tup_version(Uint32 tup_version)
{
  return (tup_version - 1) & ZTUP_VERSION_MASK;
}

inline
Dbtup::ChangeMaskState
unknown's avatar
unknown committed
2844
Dbtup::get_change_mask_state(Operationrec * regOperPtr)
2845
{
unknown's avatar
unknown committed
2846 2847
  return (Dbtup::ChangeMaskState)regOperPtr->op_struct.change_mask_state;
}
2848 2849

inline
unknown's avatar
unknown committed
2850
void
unknown's avatar
unknown committed
2851
Dbtup::set_change_mask_state(Operationrec * regOperPtr,
unknown's avatar
unknown committed
2852
                             ChangeMaskState new_state)
2853
{
unknown's avatar
unknown committed
2854 2855
  regOperPtr->op_struct.change_mask_state= (Uint32)new_state;
}
2856 2857

inline
unknown's avatar
unknown committed
2858
void
unknown's avatar
unknown committed
2859 2860
Dbtup::update_change_mask_info(KeyReqStruct * req_struct,
                               Operationrec * regOperPtr)
2861
{
unknown's avatar
unknown committed
2862
  if (req_struct->max_attr_id_updated == 0) {
2863 2864 2865 2866 2867
    if (get_change_mask_state(regOperPtr) == USE_SAVED_CHANGE_MASK) {
      // add new changes
      regOperPtr->saved_change_mask[0] |= req_struct->changeMask.getWord(0);
      regOperPtr->saved_change_mask[1] |= req_struct->changeMask.getWord(1);
    }
unknown's avatar
unknown committed
2868 2869 2870 2871 2872 2873 2874 2875
  } else {
    if (req_struct->no_changed_attrs < 16) {
      set_change_mask_state(regOperPtr, RECALCULATE_CHANGE_MASK);
    } else {
      set_change_mask_state(regOperPtr, SET_ALL_MASK);
    }
  }
}
2876 2877

inline
unknown's avatar
unknown committed
2878 2879
Uint32*
Dbtup::get_ptr(Var_part_ref ref)
2880
{
unknown's avatar
unknown committed
2881
  Ptr<Page> tmp;
unknown's avatar
unknown committed
2882 2883 2884 2885 2886
  return get_ptr(&tmp, ref);
}

inline
Uint32*
unknown's avatar
unknown committed
2887
Dbtup::get_ptr(Ptr<Page>* pagePtr, Var_part_ref ref)
unknown's avatar
unknown committed
2888 2889
{
  PagePtr tmp;
2890 2891 2892
  Local_key key;
  ref.copyout(&key);
  tmp.i = key.m_page_no;
unknown's avatar
unknown committed
2893
  
unknown's avatar
unknown committed
2894
  c_page_pool.getPtr(tmp);
unknown's avatar
unknown committed
2895
  memcpy(pagePtr, &tmp, sizeof(tmp));
2896
  return ((Var_page*)tmp.p)->get_ptr(key.m_page_idx);
unknown's avatar
unknown committed
2897 2898 2899 2900 2901 2902 2903 2904 2905
}

inline
Uint32*
Dbtup::get_ptr(PagePtr* pagePtr, 
	       const Local_key* key, const Tablerec* regTabPtr)
{
  PagePtr tmp;
  tmp.i= key->m_page_no;
unknown's avatar
unknown committed
2906
  c_page_pool.getPtr(tmp);
unknown's avatar
unknown committed
2907 2908
  memcpy(pagePtr, &tmp, sizeof(tmp));

unknown's avatar
unknown committed
2909 2910
  return ((Fix_page*)tmp.p)->
    get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
unknown's avatar
unknown committed
2911 2912 2913 2914
}

inline
Uint32*
unknown's avatar
unknown committed
2915 2916
Dbtup::get_dd_ptr(PagePtr* pagePtr, 
		  const Local_key* key, const Tablerec* regTabPtr)
unknown's avatar
unknown committed
2917 2918 2919
{
  PagePtr tmp;
  tmp.i= key->m_page_no;
unknown's avatar
unknown committed
2920
  tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
unknown's avatar
unknown committed
2921 2922
  memcpy(pagePtr, &tmp, sizeof(tmp));
  
unknown's avatar
unknown committed
2923
  if(regTabPtr->m_attributes[DD].m_no_of_varsize)
unknown's avatar
unknown committed
2924 2925 2926
    return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
  else
    return ((Fix_page*)tmp.p)->
unknown's avatar
unknown committed
2927
      get_ptr(key->m_page_idx, regTabPtr->m_offsets[DD].m_fix_header_size);
unknown's avatar
unknown committed
2928 2929 2930 2931
}

NdbOut&
operator<<(NdbOut&, const Dbtup::Tablerec&);
2932 2933

#endif