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 613 614 615
  DLList<Page>::Head emptyPrimPage; // allocated pages (not init)
  DLList<Page>::Head thFreeFirst;   // pages with atleast 1 free record
  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 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962
    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
      union {
	Uint16 m_varpart_offset;  // In words relative m_data
	Uint16 m_fix_header_size; // For fix size tuples= total rec size(part)
      };
      Uint16 m_max_var_offset;  // In bytes relative m_var_data.m_data_ptr
    } m_offsets[2];
    

    Uint32 get_check_offset(Uint32 mm) const {
      Uint32 cnt= m_attributes[mm].m_no_of_varsize;
      Uint32 off= m_offsets[mm].m_varpart_offset;
      return off - (cnt ? 0 : Tuple_header::HeaderSize);
    }

    struct {
      Uint16 m_no_of_fixsize;
      Uint16 m_no_of_varsize;
    } m_attributes[2];
    
    // Lists of trigger data for active triggers
963 964 965 966 967 968 969
    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
970 971
    
    // List of ordered indexes
972
    DLList<TupTriggerData> tuxCustomTriggers;
unknown's avatar
unknown committed
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991
    
    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
992 993 994
      ,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
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 1021 1022 1023 1024 1025 1026
    };
    
    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
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050

    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
1051 1052
  };
  
unknown's avatar
unknown committed
1053 1054
  Extent_info_pool c_extent_pool;
  Extent_info_hash c_extent_hash;
unknown's avatar
unknown committed
1055
  Page_request_pool c_page_request_pool;
1056

unknown's avatar
unknown committed
1057
  typedef Ptr<Tablerec> TablerecPtr;
1058

unknown's avatar
unknown committed
1059 1060 1061 1062 1063 1064 1065
  struct storedProc {
    Uint32 storedLinkFirst;
    Uint32 storedLinkLast;
    Uint32 storedCounter;
    Uint32 nextPool;
    Uint16 storedCode;
    Uint16 storedProcLength;
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 1180 1181 1182 1183 1184 1185
};

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
1186 1187
    Uint8  m_build_vs;          // varsize pages
    Uint32 m_indexId;           // the index
1188 1189
    Uint32 m_fragNo;            // fragment number under Tablerec
    Uint32 m_pageId;            // logical fragment page id
unknown's avatar
unknown committed
1190 1191
    Uint32 m_tupleNo;           // tuple number on page
    Uint32 m_buildRef;          // Where to send tuples
1192 1193 1194 1195 1196 1197 1198 1199 1200
    BuildIndxRef::ErrorCode m_errorCode;
    union {
      Uint32 nextPool;
      Uint32 nextList;
    };
    Uint32 prevList;
  };
  typedef Ptr<BuildIndexRec> BuildIndexPtr;
  ArrayPool<BuildIndexRec> c_buildIndexPool;
1201
  DLList<BuildIndexRec> c_buildIndexList;
1202 1203
  Uint32 c_noOfBuildIndexRec;

unknown's avatar
unknown committed
1204 1205 1206 1207 1208
  /**
   * Reference to variable part when a tuple is chained
   */
  struct Var_part_ref 
  {
1209
#if NDB_SIZEOF_CHARP == 4
unknown's avatar
unknown committed
1210
    Uint32 m_ref;
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
    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
1225

1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
    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
unknown committed
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
  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
1264
    STATIC_CONST( FREED       = 0x00800000 ); // Is freed
unknown's avatar
unknown committed
1265
    STATIC_CONST( LCP_SKIP    = 0x01000000 ); // Should not be returned in LCP
1266 1267
    STATIC_CONST( LCP_KEEP    = 0x02000000 ); // Should be returned in LCP
    STATIC_CONST( FREE        = 0x02800000 ); // Is free
unknown's avatar
unknown committed
1268
    
unknown's avatar
unknown committed
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300
    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;
    }
    
    Uint32* get_var_part_ptr(const Tablerec* tabPtrP) {
      return m_data + tabPtrP->m_offsets[MM].m_varpart_offset;      
    }

    const Uint32* get_var_part_ptr(const Tablerec* tabPtrP) const {
      return m_data + tabPtrP->m_offsets[MM].m_varpart_offset;      
    }

    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
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310

    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
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 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
  };
  
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
1352 1353
  PagePtr m_page_ptr;
  PagePtr m_varpart_page_ptr;    // could be same as m_page_ptr_p
unknown's avatar
unknown committed
1354
  PagePtr m_disk_page_ptr;       //
unknown's avatar
unknown committed
1355 1356
  Local_key m_row_id;
  
unknown's avatar
unknown committed
1357 1358 1359
  bool            dirty_op;
  bool            interpreted_exec;
  bool            last_row;
unknown's avatar
unknown committed
1360
  bool            m_use_rowid;
unknown's avatar
unknown committed
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373

  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;
1374
  // next 2 apply only to attrids >= 64 (zero otherwise)
unknown's avatar
unknown committed
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 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
  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;

1415
public:
1416
  Dbtup(Block_context&, Pgman*);
1417 1418
  virtual ~Dbtup();

1419 1420 1421 1422 1423
  /*
   * TUX uses logical tuple address when talking to ACC and LQH.
   */
  void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32& tupAddr);

1424 1425
  /*
   * TUX index in TUP has single Uint32 array attribute which stores an
1426
   * index node.  TUX reads and writes the node directly via pointer.
1427 1428 1429 1430 1431
   */
  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);

1432
  /*
1433 1434 1435 1436 1437
   * 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.
1438
   */
1439
  int tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut);
1440 1441

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

1448 1449 1450 1451 1452
  /*
   * 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
1453
  int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag);
1454

1455 1456 1457 1458
  /*
   * TUX checks if tuple is visible to scan.
   */
  bool tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId);
1459

unknown's avatar
unknown committed
1460 1461 1462 1463 1464 1465
  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
1466 1467
  int alloc_page(Tablerec*, Fragrecord*, PagePtr*,Uint32 page_no);
  
unknown's avatar
unknown committed
1468 1469
  void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
  void complete_restore_lcp(Uint32 tableId, Uint32 fragmentId);
unknown's avatar
unknown committed
1470 1471 1472 1473 1474 1475

  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
1476
  void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page);
1477 1478 1479 1480 1481 1482 1483 1484
private:
  BLOCK_DEFINES(Dbtup);

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

  // Received signals
unknown's avatar
unknown committed
1485
  void execLCP_FRAG_ORD(Signal*signal);
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500
  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);
1501
  void execREAD_CONFIG_REQ(Signal* signal);
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512
  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);

1513 1514 1515 1516
  // Tup scan
  void execACC_SCANREQ(Signal* signal);
  void execNEXT_SCANREQ(Signal* signal);
  void execACC_CHECK_SCAN(Signal* signal);
unknown's avatar
unknown committed
1517 1518 1519
  void execACCKEYCONF(Signal* signal);
  void execACCKEYREF(Signal* signal);
  void execACC_ABORTCONF(Signal* signal);
1520

1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 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
//------------------------------------------------------------------
//------------------------------------------------------------------
// 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
1702 1703
  void disk_page_load_callback(Signal*, Uint32 op, Uint32 page);
  void disk_page_load_scan_callback(Signal*, Uint32 op, Uint32 page);
1704 1705 1706 1707

//------------------------------------------------------------------
//------------------------------------------------------------------
  void execATTRINFO(Signal* signal);
unknown's avatar
unknown committed
1708 1709 1710
public:
  void receive_attrinfo(Signal*, Uint32 op, const Uint32* data, Uint32 len);
private:
1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726

// 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
1727
				  const Uint32* data,
1728
                                  Uint32 length,
unknown's avatar
unknown committed
1729
                                  Operationrec * regOperPtr);
1730 1731 1732 1733 1734 1735 1736

// *****************************************************************
// Setting up the environment for reads, inserts, updates and deletes.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleReadReq(Signal* signal,
unknown's avatar
unknown committed
1737 1738
                    Operationrec* regOperPtr,
                    Tablerec* regTabPtr,
unknown's avatar
unknown committed
1739
                    KeyReqStruct* req_struct);
1740 1741 1742 1743

//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleUpdateReq(Signal* signal,
unknown's avatar
unknown committed
1744 1745 1746
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1747 1748
                      KeyReqStruct* req_struct,
		      bool disk);
1749 1750 1751 1752

//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleInsertReq(Signal* signal,
unknown's avatar
unknown committed
1753 1754
                      Ptr<Operationrec> regOperPtr,
                      Ptr<Fragrecord>,
unknown's avatar
unknown committed
1755
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1756
                      KeyReqStruct* req_struct);
1757 1758 1759 1760

//------------------------------------------------------------------
//------------------------------------------------------------------
  int handleDeleteReq(Signal* signal,
unknown's avatar
unknown committed
1761 1762 1763
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1764
                      KeyReqStruct* req_struct);
1765 1766 1767 1768

//------------------------------------------------------------------
//------------------------------------------------------------------
  int  updateStartLab(Signal* signal,
unknown's avatar
unknown committed
1769 1770 1771
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr,
unknown's avatar
unknown committed
1772
                      KeyReqStruct* req_struct);
1773 1774 1775 1776 1777 1778 1779 1780

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

//------------------------------------------------------------------
//------------------------------------------------------------------
  int interpreterStartLab(Signal* signal,
unknown's avatar
unknown committed
1781
                          KeyReqStruct *req_struct);
1782 1783 1784 1785

//------------------------------------------------------------------
//------------------------------------------------------------------
  int interpreterNextLab(Signal* signal,
unknown's avatar
unknown committed
1786
                         KeyReqStruct *req_struct,
1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800
                         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
1801
                        KeyReqStruct *req_struct,
1802
                        Uint32 TnoOfData,
unknown's avatar
unknown committed
1803
                        const Operationrec * regOperPtr);
1804 1805 1806 1807 1808

//------------------------------------------------------------------
//------------------------------------------------------------------
  void sendLogAttrinfo(Signal* signal,
                       Uint32 TlogSize,
unknown's avatar
unknown committed
1809
                       Operationrec * regOperPtr);
1810 1811 1812

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1813 1814
  void sendTUPKEYCONF(Signal* signal,
                      KeyReqStruct *req_struct,
unknown's avatar
unknown committed
1815
                      Operationrec * regOperPtr); 
1816 1817 1818 1819 1820 1821 1822 1823 1824

//------------------------------------------------------------------
//------------------------------------------------------------------
// *****************************************************************
// The methods that perform the actual read and update of attributes
// in the tuple.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1825
  int readAttributes(KeyReqStruct* req_struct,
1826
                     const Uint32*  inBuffer,
1827 1828
                     Uint32   inBufLen,
                     Uint32*  outBuffer,
1829 1830
                     Uint32   TmaxRead,
                     bool     xfrmFlag);
1831 1832 1833

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1834
  int updateAttributes(KeyReqStruct *req_struct,
1835 1836 1837 1838 1839 1840
                       Uint32*     inBuffer,
                       Uint32      inBufLen);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHOneWordNotNULL(Uint32* outBuffer,
unknown's avatar
unknown committed
1841
                                     KeyReqStruct *req_struct,
1842 1843 1844 1845 1846 1847
                                     AttributeHeader* ahOut,
                                     Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer,
unknown's avatar
unknown committed
1848
                                       KeyReqStruct *req_struct,
1849 1850 1851 1852 1853
                                       Uint32  attrDes2);

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

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

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

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

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

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

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

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

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

//------------------------------------------------------------------
//------------------------------------------------------------------
  bool readFixedSizeTHZeroWordNULLable(Uint32* outBuffer,
unknown's avatar
unknown committed
1913
                                       KeyReqStruct *req_struct,
1914 1915 1916 1917 1918
                                       AttributeHeader* ahOut,
                                       Uint32  attrDes2);
//------------------------------------------------------------------
//------------------------------------------------------------------
  bool updateFixedSizeTHManyWordNULLable(Uint32* inBuffer,
unknown's avatar
unknown committed
1919
                                         KeyReqStruct *req_struct,
1920 1921 1922 1923
                                         Uint32  attrDes2);

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1924 1925 1926 1927
  bool readVarSizeNotNULL(Uint32* outBuffer,
                          KeyReqStruct *req_struct,
                          AttributeHeader* ahOut,
                          Uint32  attrDes2);
1928 1929 1930

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1931 1932 1933
  bool updateVarSizeNotNULL(Uint32* inBuffer,
                            KeyReqStruct *req_struct,
                            Uint32  attrDes2);
1934 1935 1936

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

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

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

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

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

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
1970 1971 1972
  bool updateDynVarSize(Uint32* inBuffer,
                        KeyReqStruct *req_struct,
                        Uint32  attrDes2);
1973

unknown's avatar
unknown committed
1974 1975 1976 1977
  bool readCharNotNULL(Uint32* outBuffer,
                       KeyReqStruct *req_struct,
                       AttributeHeader* ahOut,
                       Uint32  attrDes2);
1978

unknown's avatar
unknown committed
1979 1980 1981 1982
  bool readCharNULLable(Uint32* outBuffer,
                        KeyReqStruct *req_struct,
                        AttributeHeader* ahOut,
                        Uint32  attrDes2);
1983

unknown's avatar
unknown committed
1984 1985 1986 1987
  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);
1988

unknown's avatar
unknown committed
1989 1990
  bool updateFixedNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
  bool updateFixedNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
1991

unknown's avatar
unknown committed
1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017
  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);
2018 2019


2020 2021
//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2022 2023 2024 2025 2026
  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);
2027 2028 2029

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2030
  void setUpQueryRoutines(Tablerec* regTabPtr);
2031 2032 2033 2034

// *****************************************************************
// Service methods.
// *****************************************************************
unknown's avatar
unknown committed
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047
  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);

2048 2049
//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2050
  void copyAttrinfo(Operationrec * regOperPtr, Uint32*  inBuffer);
2051 2052 2053

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2054
  void initOpConnection(Operationrec* regOperPtr);
2055 2056 2057 2058 2059 2060 2061

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

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2062
  int initStoredOperationrec(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2063
                             KeyReqStruct* req_struct,
2064 2065 2066 2067
                             Uint32 storedId);

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2068
  bool insertActiveOpList(OperationrecPtr, KeyReqStruct* req_struct);
2069 2070 2071 2072 2073 2074

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

//------------------------------------------------------------------
//------------------------------------------------------------------
unknown's avatar
unknown committed
2075
  void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen);
2076 2077 2078 2079

//------------------------------------------------------------------
// Trigger handling routines
//------------------------------------------------------------------
2080
  DLList<TupTriggerData>*
unknown's avatar
unknown committed
2081 2082 2083 2084
  findTriggerList(Tablerec* table,
                  TriggerType::Value ttype,
                  TriggerActionTime::Value ttime,
                  TriggerEvent::Value tevent);
2085 2086 2087

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

2088 2089 2090
  Uint32 dropTrigger(Tablerec* table,
		     const DropTrigReq* req,
		     BlockNumber sender);
2091

unknown's avatar
unknown committed
2092 2093
  void
  checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2094 2095
                                    Operationrec* regOperPtr, 
                                    Tablerec* tablePtr);
2096

unknown's avatar
unknown committed
2097 2098
  void
  checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2099 2100
                                    Operationrec* regOperPtr, 
                                    Tablerec* tablePtr);
2101

unknown's avatar
unknown committed
2102 2103
  void
  checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2104 2105
                                    Operationrec* regOperPtr, 
                                    Tablerec* tablePtr);
2106 2107 2108

#if 0
  void checkDeferredTriggers(Signal* signal, 
unknown's avatar
unknown committed
2109 2110
                             Operationrec* regOperPtr,
                             Tablerec* regTablePtr);
2111
#endif
unknown's avatar
unknown committed
2112
  void checkDetachedTriggers(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2113 2114
                             Operationrec* regOperPtr,
                             Tablerec* regTablePtr);
2115

unknown's avatar
unknown committed
2116
  void fireImmediateTriggers(KeyReqStruct *req_struct,
2117
                             DLList<TupTriggerData>& triggerList, 
unknown's avatar
unknown committed
2118
                             Operationrec* regOperPtr);
2119

unknown's avatar
unknown committed
2120
  void fireDeferredTriggers(KeyReqStruct *req_struct,
2121
                            DLList<TupTriggerData>& triggerList,
unknown's avatar
unknown committed
2122
                            Operationrec* regOperPtr);
2123

unknown's avatar
unknown committed
2124
  void fireDetachedTriggers(KeyReqStruct *req_struct,
2125
                            DLList<TupTriggerData>& triggerList,
unknown's avatar
unknown committed
2126
                            Operationrec* regOperPtr);
2127

unknown's avatar
unknown committed
2128
  void executeTriggers(KeyReqStruct *req_struct,
2129
                       DLList<TupTriggerData>& triggerList,
unknown's avatar
unknown committed
2130
                       Operationrec* regOperPtr);
2131

unknown's avatar
unknown committed
2132
  void executeTrigger(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2133 2134 2135 2136 2137 2138 2139 2140
                      TupTriggerData* trigPtr, 
                      Operationrec* regOperPtr);

  bool readTriggerInfo(TupTriggerData* trigPtr,
                       Operationrec* regOperPtr,
                       KeyReqStruct * req_struct,
                       Fragrecord* regFragPtr,
                       Uint32* keyBuffer,
2141
                       Uint32& noPrimKey,
unknown's avatar
unknown committed
2142
                       Uint32* afterBuffer,
unknown's avatar
unknown committed
2143
                       Uint32& noAfterWords,
unknown's avatar
unknown committed
2144
                       Uint32* beforeBuffer,
unknown's avatar
unknown committed
2145
                       Uint32& noBeforeWords);
2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157

  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
2158
                       KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2159 2160
                       Operationrec * regOperPtr,
                       TupTriggerData* trigPtr,
unknown's avatar
unknown committed
2161
		       Uint32 fragmentId,
2162 2163 2164 2165 2166 2167 2168 2169 2170
                       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
2171 2172 2173
                               Operationrec* regOperPtr,
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2174 2175

  int executeTuxUpdateTriggers(Signal* signal, 
unknown's avatar
unknown committed
2176 2177 2178
                               Operationrec* regOperPtr,
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2179 2180

  int executeTuxDeleteTriggers(Signal* signal, 
unknown's avatar
unknown committed
2181 2182 2183
                               Operationrec* regOperPtr,
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2184

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

2189 2190 2191 2192
  // these crash the node on error

  void executeTuxCommitTriggers(Signal* signal, 
                                Operationrec* regOperPtr,
unknown's avatar
unknown committed
2193 2194
                                Fragrecord* regFragPtr,
                                Tablerec* regTabPtr);
2195 2196 2197

  void executeTuxAbortTriggers(Signal* signal, 
                               Operationrec* regOperPtr,
unknown's avatar
unknown committed
2198 2199
                               Fragrecord* regFragPtr,
                               Tablerec* regTabPtr);
2200

unknown's avatar
unknown committed
2201 2202 2203
  void removeTuxEntries(Signal* signal,
                        Tablerec* regTabPtr);

2204 2205 2206 2207 2208 2209 2210 2211 2212 2213
// *****************************************************************
// Error Handling routines.
// *****************************************************************
//------------------------------------------------------------------
//------------------------------------------------------------------
  int TUPKEY_abort(Signal* signal, int error_type);

//------------------------------------------------------------------
//------------------------------------------------------------------
  void tupkeyErrorLab(Signal* signal);
unknown's avatar
unknown committed
2214
  void do_tup_abortreq(Signal*, Uint32 flags);
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239

//------------------------------------------------------------------
//------------------------------------------------------------------
// 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
2240
// we will set the delete state on the record that becomes the ownerd
2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 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
// 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
2280
#if 0 
unknown's avatar
unknown committed
2281
  void checkPages(Fragrecord* regFragPtr);
2282
#endif
unknown's avatar
unknown committed
2283 2284 2285 2286 2287 2288 2289 2290 2291 2292
  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*);
2293
  void fix_disk_insert_no_mem_insert(KeyReqStruct*, Operationrec*, Tablerec*);
unknown's avatar
unknown committed
2294
  void setup_fixed_part(KeyReqStruct* req_struct,
unknown's avatar
unknown committed
2295 2296
			Operationrec* regOperPtr,
			Tablerec* regTabPtr);
unknown's avatar
unknown committed
2297 2298
  
  void send_TUPKEYREF(Signal* signal,
unknown's avatar
unknown committed
2299
                      Operationrec* regOperPtr);
unknown's avatar
unknown committed
2300
  void early_tupkey_error(Signal* signal);
2301

unknown's avatar
unknown committed
2302
  void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit);
2303

unknown's avatar
unknown committed
2304 2305
  bool checkUpdateOfPrimaryKey(KeyReqStruct *req_struct,
                               Uint32* updateBuffer,
unknown's avatar
unknown committed
2306
                               Tablerec* regTabPtr);
2307

unknown's avatar
unknown committed
2308
  void setNullBits(Uint32*, Tablerec* regTabPtr);
unknown's avatar
unknown committed
2309 2310
  bool checkNullAttributes(KeyReqStruct * const, Tablerec* const);
  bool setup_read(KeyReqStruct* req_struct,
unknown's avatar
unknown committed
2311 2312 2313
		  Operationrec* regOperPtr,
		  Fragrecord* regFragPtr,
		  Tablerec* regTabPtr,
unknown's avatar
unknown committed
2314 2315
		  bool disk);
  
unknown's avatar
unknown committed
2316 2317
  Uint32 calculateChecksum(Tuple_header*, Tablerec* regTabPtr);
  void setChecksum(Tuple_header*, Tablerec* regTabPtr);
2318

unknown's avatar
unknown committed
2319 2320
  void complexTrigger(Signal* signal,
                      KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2321 2322 2323
                      Operationrec* regOperPtr,
                      Fragrecord* regFragPtr,
                      Tablerec* regTabPtr);
2324

unknown's avatar
unknown committed
2325
  void setTupleStatesSetOpType(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2326
                               KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2327
                               Page* pagePtr,
2328 2329 2330 2331 2332 2333
                               Uint32& opType,
                               OperationrecPtr& firstOpPtr);

  void findBeforeValueOperation(OperationrecPtr& befOpPtr,
                                OperationrecPtr firstOpPtr);

unknown's avatar
unknown committed
2334 2335 2336
  void calculateChangeMask(Page* PagePtr,
                           Tablerec* regTabPtr,
                           KeyReqStruct * req_struct);
2337

unknown's avatar
unknown committed
2338
  void updateGcpId(KeyReqStruct *req_struct,
unknown's avatar
unknown committed
2339 2340 2341
                   Operationrec* regOperPtr,
                   Fragrecord* regFragPtr,
                   Tablerec* regTabPtr);
2342 2343 2344 2345 2346 2347

  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
2348
  void removeActiveOpList(Operationrec*  const regOperPtr, Tuple_header*);
2349 2350 2351 2352

  void updatePackedList(Signal* signal, Uint16 ahostIndex);

  void setUpDescriptorReferences(Uint32 descriptorReference,
unknown's avatar
unknown committed
2353
                                 Tablerec* regTabPtr,
unknown's avatar
unknown committed
2354
                                 const Uint32* offset);
unknown's avatar
unknown committed
2355 2356 2357
  void setUpKeyArray(Tablerec* regTabPtr);
  bool addfragtotab(Tablerec* regTabPtr, Uint32 fragId, Uint32 fragIndex);
  void deleteFragTab(Tablerec* regTabPtr, Uint32 fragId);
2358
  void abortAddFragOp(Signal* signal);
unknown's avatar
unknown committed
2359 2360
  void releaseTabDescr(Tablerec* regTabPtr);
  void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* regTabPtr);
2361

2362
  void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32);
2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
  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
2377
  void initTab(Tablerec* regTabPtr);
2378 2379 2380 2381 2382 2383 2384 2385 2386

  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
2387
                      Tablerec* regTabPtr,
2388 2389 2390 2391
                      Uint32 fragId);
  void fragrefuse4Lab(Signal* signal,
                      FragoperrecPtr fragOperPtr,
                      FragrecordPtr regFragPtr,
unknown's avatar
unknown committed
2392
                      Tablerec* regTabPtr,
2393 2394 2395 2396
                      Uint32 fragId);
  void addattrrefuseLab(Signal* signal,
                        FragrecordPtr regFragPtr,
                        FragoperrecPtr fragOperPtr,
unknown's avatar
unknown committed
2397
                        Tablerec* regTabPtr,
2398 2399 2400
                        Uint32 fragId);


unknown's avatar
unknown committed
2401
  void releaseFragment(Signal* signal, Uint32 tableId, Uint32);
unknown's avatar
unknown committed
2402
  void drop_fragment_free_var_pages(Signal*);
unknown's avatar
unknown committed
2403 2404
  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
2405 2406 2407
  void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32);
  void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32);
  
2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422
  // 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
2423
			       const Uint32* data,
2424 2425 2426 2427 2428 2429 2430 2431
                               Uint32 length,
                               bool copyProc);

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

// Public methods
unknown's avatar
unknown committed
2432 2433
  Uint32 getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset);
  Uint32 allocTabDescr(const Tablerec* regTabPtr, Uint32* offset);
2434
  void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
2435 2436 2437 2438 2439 2440
  Uint32 getTabDescrWord(Uint32 index);
  void setTabDescrWord(Uint32 index, Uint32 word);

// Private methods
  Uint32 sizeOfReadFunction();
  void   removeTdArea(Uint32 tabDesRef, Uint32 list);
2441 2442 2443 2444 2445
  void   insertTdArea(Uint32 tabDesRef, Uint32 list);
  void   itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
#ifdef VM_TRACE
  void verifytabdes();
#endif
2446

unknown's avatar
unknown committed
2447 2448 2449 2450 2451 2452
  void seizeOpRec(OperationrecPtr& regOperPtr);
  void seizeFragrecord(FragrecordPtr& regFragPtr);
  void seizeFragoperrec(FragoperrecPtr& fragOperPtr);
  void releaseFragoperrec(FragoperrecPtr fragOperPtr);
  void releaseFragrec(FragrecordPtr);
//----------------------------------------------------------------------------
2453
// Page Memory Manager
unknown's avatar
unknown committed
2454 2455
//----------------------------------------------------------------------------
  
2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478
// 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
2479 2480
  Uint32 getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId);
  Uint32 getNoOfPages(Fragrecord* regFragPtr);
2481
  void initPageRangeSize(Uint32 size);
unknown's avatar
unknown committed
2482
  bool insertPageRangeTab(Fragrecord* regFragPtr,
2483 2484
                          Uint32 startPageId,
                          Uint32 noPages);
unknown's avatar
unknown committed
2485 2486
  void releaseFragPages(Fragrecord* regFragPtr);
  void initFragRange(Fragrecord* regFragPtr);
2487
  void initializePageRange();
unknown's avatar
unknown committed
2488 2489 2490 2491
  Uint32 getEmptyPage(Fragrecord* regFragPtr);
  Uint32 allocFragPages(Fragrecord* regFragPtr, Uint32 noOfPagesAllocated);
  Uint32 get_empty_var_page(Fragrecord* frag_ptr);
  
2492
// Private methods
unknown's avatar
unknown committed
2493
  Uint32 leafPageRangeFull(Fragrecord* regFragPtr, PageRangePtr currPageRangePtr);
2494 2495 2496
  void releasePagerange(PageRangePtr regPRPtr);
  void seizePagerange(PageRangePtr& regPageRangePtr);
  void errorHandler(Uint32 errorCode);
unknown's avatar
unknown committed
2497
  void allocMoreFragPages(Fragrecord* regFragPtr);
2498 2499 2500 2501 2502 2503 2504

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

unknown's avatar
unknown committed
2505 2506
//---------------------------------------------------------------
// Variable Allocator
2507
// Allocates and deallocates tuples of fixed size on a fragment.
unknown's avatar
unknown committed
2508
//---------------------------------------------------------------
2509 2510
//
// Public methods
unknown's avatar
unknown committed
2511 2512

  void init_list_sizes(void);
2513 2514 2515

// Private methods

unknown's avatar
unknown committed
2516
  Uint32 get_alloc_page(Fragrecord* const, Uint32);
unknown's avatar
unknown committed
2517
  void update_free_page_list(Fragrecord* const, Ptr<Page>);
2518

unknown's avatar
unknown committed
2519 2520 2521 2522 2523
#if 0  
  Uint32 calc_free_list(const Tablerec* regTabPtr, Uint32 sz) const {
    return regTabPtr->m_disk_alloc_info.calc_page_free_bits(sz);
  }
#endif
2524

unknown's avatar
unknown committed
2525 2526 2527
  Uint32 calculate_free_list_impl(Uint32) const ;
  void remove_free_page(Fragrecord*, Var_page*, Uint32);
  void insert_free_page(Fragrecord*, Var_page*, Uint32);
2528

unknown's avatar
unknown committed
2529 2530 2531 2532 2533 2534
//---------------------------------------------------------------
// Fixed Allocator
// Allocates and deallocates tuples of fixed size on a fragment.
//---------------------------------------------------------------
//
// Public methods
unknown's avatar
unknown committed
2535 2536 2537 2538 2539
  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
2540 2541 2542
  
  void validate_page(Tablerec*, Var_page* page);
  
2543 2544
  Uint32* alloc_fix_rec(Fragrecord*const, Tablerec*const, Local_key*,
                        Uint32*);
unknown's avatar
unknown committed
2545 2546
  void free_fix_rec(Fragrecord*, Tablerec*, Local_key*, Fix_page*);
  
unknown's avatar
unknown committed
2547 2548
  Uint32* alloc_fix_rowid(Fragrecord*, Tablerec*, Local_key*, Uint32 *);
  Uint32* alloc_var_rowid(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
unknown's avatar
unknown committed
2549
// Private methods
unknown's avatar
unknown committed
2550 2551 2552
  void convertThPage(Fix_page* regPagePtr,
		     Tablerec*,
		     Uint32 mm);
unknown's avatar
unknown committed
2553 2554 2555 2556

  /**
   * Return offset
   */
unknown's avatar
unknown committed
2557 2558
  Uint32 alloc_tuple_from_page(Fragrecord* regFragPtr,
			       Fix_page* regPagePtr);
unknown's avatar
unknown committed
2559 2560 2561 2562 2563
  
//---------------------------------------------------------------
// Temporary variables used for storing commonly used variables
// in certain modules
//---------------------------------------------------------------
2564

unknown's avatar
unknown committed
2565
  Uint32 c_lcp_scan_op;
2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588
  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
2589
  ArrayPool<Operationrec> c_operation_pool;
2590

unknown's avatar
unknown committed
2591
  ArrayPool<Page> c_page_pool;
2592 2593 2594 2595 2596 2597 2598
  Uint32 cnoOfAllocatedPages;
  
  Tablerec *tablerec;
  Uint32 cnoOfTablerec;

  TableDescriptor *tableDescriptor;
  Uint32 cnoOfTabDescrRec;
unknown's avatar
unknown committed
2599
  
2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621
  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
2622 2623
  Uint32 ctemp_page[ZWORDS_ON_PAGE];
  Uint32 ctemp_var_record[ZWORDS_ON_PAGE];
2624 2625 2626 2627
  Uint32 totNoOfPagesAllocated;

  // Trigger variables
  Uint32 c_maxTriggersPerTable;
2628
  Uint32 c_memusage_report_frequency;
2629 2630

  Uint32 c_errorInsert4000TableId;
unknown's avatar
unknown committed
2631 2632
  Uint32 c_min_list_size[MAX_FREE_LIST + 1];
  Uint32 c_max_list_size[MAX_FREE_LIST + 1];
2633 2634 2635

  void initGlobalTemporaryVars();
  void reportMemoryUsage(Signal* signal, int incDec);
2636 2637

  
2638 2639 2640 2641 2642 2643 2644
#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
2645 2646 2647 2648 2649 2650 2651

  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
2652
  Uint32* get_ptr(PagePtr*, Var_part_ref);
unknown's avatar
unknown committed
2653
  Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
unknown's avatar
unknown committed
2654
  Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
unknown's avatar
unknown committed
2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677

  /**
   * 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
2678
					  Ptr<Page>);
unknown's avatar
unknown committed
2679 2680 2681 2682 2683 2684 2685 2686 2687
  
  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
2688 2689 2690

  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
2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703
  
  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
2704
  void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
unknown's avatar
unknown committed
2705

unknown's avatar
unknown committed
2706 2707 2708
  void drop_table_log_buffer_callback(Signal*, Uint32, Uint32);
  void drop_table_logsync_callback(Signal*, Uint32, Uint32);

unknown's avatar
unknown committed
2709
  void disk_page_set_dirty(Ptr<Page>);
unknown's avatar
unknown committed
2710
  void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
unknown's avatar
unknown committed
2711 2712
  void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>);
  
unknown's avatar
unknown committed
2713 2714 2715 2716 2717
  /**
   * Disk restart code
   */
public:
  int disk_page_load_hook(Uint32 page_id);
unknown's avatar
unknown committed
2718 2719
  
  void disk_page_unmap_callback(Uint32 page_id, Uint32 dirty_count);
unknown's avatar
unknown committed
2720 2721 2722 2723
  
  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
2724
			      const Local_key*, Uint32 bits);
unknown's avatar
unknown committed
2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735
  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
2736
    Ptr<Extent_info> m_extent_ptr;
unknown's avatar
unknown committed
2737 2738
    Local_key m_key;
  };
unknown's avatar
unknown committed
2739 2740

  void disk_restart_mark_no_lcp(Uint32 table, Uint32 frag);
unknown's avatar
unknown committed
2741 2742 2743
  
private:
  void disk_restart_undo_next(Signal*);
unknown's avatar
unknown committed
2744
  void disk_restart_undo_lcp(Uint32, Uint32, Uint32 flag);
unknown's avatar
unknown committed
2745 2746 2747 2748
  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
2749
  void disk_restart_undo_page_bits(Signal*, Apply_undo*);
unknown's avatar
unknown committed
2750 2751 2752 2753 2754 2755 2756 2757

#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
2758
  void commit_operation(Signal*, Uint32, Tuple_header*, PagePtr,
unknown's avatar
unknown committed
2759 2760 2761 2762 2763 2764 2765 2766
			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
2767 2768
				      Fragrecord* regFragPtr,
				      Tablerec* regTabPtr,
unknown's avatar
unknown committed
2769 2770 2771 2772 2773 2774 2775
				      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);
2776 2777
};

unknown's avatar
unknown committed
2778
#if 0
2779
inline
unknown's avatar
unknown committed
2780 2781 2782 2783 2784 2785 2786 2787
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
2788
#endif
unknown's avatar
unknown committed
2789 2790 2791

inline
Dbtup::TransState
unknown's avatar
unknown committed
2792
Dbtup::get_trans_state(Operationrec * regOperPtr)
unknown's avatar
unknown committed
2793 2794 2795 2796 2797 2798
{
  return (Dbtup::TransState)regOperPtr->op_struct.trans_state;
}

inline
void
unknown's avatar
unknown committed
2799
Dbtup::set_trans_state(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2800 2801 2802 2803 2804 2805 2806
                       Dbtup::TransState trans_state)
{
  regOperPtr->op_struct.trans_state= (Uint32)trans_state;
}

inline
Dbtup::TupleState
unknown's avatar
unknown committed
2807
Dbtup::get_tuple_state(Operationrec * regOperPtr)
unknown's avatar
unknown committed
2808 2809 2810 2811 2812 2813
{
  return (Dbtup::TupleState)regOperPtr->op_struct.tuple_state;
}

inline
void
unknown's avatar
unknown committed
2814
Dbtup::set_tuple_state(Operationrec* regOperPtr,
unknown's avatar
unknown committed
2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829
                       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
2830
Dbtup::get_change_mask_state(Operationrec * regOperPtr)
2831
{
unknown's avatar
unknown committed
2832 2833
  return (Dbtup::ChangeMaskState)regOperPtr->op_struct.change_mask_state;
}
2834 2835

inline
unknown's avatar
unknown committed
2836
void
unknown's avatar
unknown committed
2837
Dbtup::set_change_mask_state(Operationrec * regOperPtr,
unknown's avatar
unknown committed
2838
                             ChangeMaskState new_state)
2839
{
unknown's avatar
unknown committed
2840 2841
  regOperPtr->op_struct.change_mask_state= (Uint32)new_state;
}
2842 2843

inline
unknown's avatar
unknown committed
2844
void
unknown's avatar
unknown committed
2845 2846
Dbtup::update_change_mask_info(KeyReqStruct * req_struct,
                               Operationrec * regOperPtr)
2847
{
unknown's avatar
unknown committed
2848
  if (req_struct->max_attr_id_updated == 0) {
2849 2850 2851 2852 2853
    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
2854 2855 2856 2857 2858 2859 2860 2861
  } 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);
    }
  }
}
2862 2863

inline
unknown's avatar
unknown committed
2864 2865
Uint32*
Dbtup::get_ptr(Var_part_ref ref)
2866
{
unknown's avatar
unknown committed
2867
  Ptr<Page> tmp;
unknown's avatar
unknown committed
2868 2869 2870 2871 2872
  return get_ptr(&tmp, ref);
}

inline
Uint32*
unknown's avatar
unknown committed
2873
Dbtup::get_ptr(Ptr<Page>* pagePtr, Var_part_ref ref)
unknown's avatar
unknown committed
2874 2875
{
  PagePtr tmp;
2876 2877 2878
  Local_key key;
  ref.copyout(&key);
  tmp.i = key.m_page_no;
unknown's avatar
unknown committed
2879
  
unknown's avatar
unknown committed
2880
  c_page_pool.getPtr(tmp);
unknown's avatar
unknown committed
2881
  memcpy(pagePtr, &tmp, sizeof(tmp));
2882
  return ((Var_page*)tmp.p)->get_ptr(key.m_page_idx);
unknown's avatar
unknown committed
2883 2884 2885 2886 2887 2888 2889 2890 2891
}

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
2892
  c_page_pool.getPtr(tmp);
unknown's avatar
unknown committed
2893 2894
  memcpy(pagePtr, &tmp, sizeof(tmp));

unknown's avatar
unknown committed
2895 2896
  return ((Fix_page*)tmp.p)->
    get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
unknown's avatar
unknown committed
2897 2898 2899 2900
}

inline
Uint32*
unknown's avatar
unknown committed
2901 2902
Dbtup::get_dd_ptr(PagePtr* pagePtr, 
		  const Local_key* key, const Tablerec* regTabPtr)
unknown's avatar
unknown committed
2903 2904 2905
{
  PagePtr tmp;
  tmp.i= key->m_page_no;
unknown's avatar
unknown committed
2906
  tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
unknown's avatar
unknown committed
2907 2908
  memcpy(pagePtr, &tmp, sizeof(tmp));
  
unknown's avatar
unknown committed
2909
  if(regTabPtr->m_attributes[DD].m_no_of_varsize)
unknown's avatar
unknown committed
2910 2911 2912
    return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
  else
    return ((Fix_page*)tmp.p)->
unknown's avatar
unknown committed
2913
      get_ptr(key->m_page_idx, regTabPtr->m_offsets[DD].m_fix_header_size);
unknown's avatar
unknown committed
2914 2915 2916 2917
}

NdbOut&
operator<<(NdbOut&, const Dbtup::Tablerec&);
2918 2919

#endif