MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Dbspj.hpp
1 /*
2  Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef DBSPJ_H
19 #define DBSPJ_H
20 
21 #include <SimulatedBlock.hpp>
22 #include <signaldata/LqhKey.hpp>
23 #include <signaldata/ScanFrag.hpp>
24 #include <AttributeHeader.hpp>
25 #include <SLFifoList.hpp>
26 #include <DLFifoList.hpp>
27 #include <SLList.hpp>
28 #include <ArenaPool.hpp>
29 #include <DataBuffer2.hpp>
30 #include <Bitmask.hpp>
31 #include <signaldata/DbspjErr.hpp>
32 #include "../dbtup/tuppage.hpp"
33 
34 class SectionReader;
35 struct QueryNode;
36 struct QueryNodeParameters;
37 
38 //#define SPJ_TRACE_TIME
39 
40 #ifdef SPJ_TRACE_TIME
41 static
42 inline
43 Uint64 spj_now()
44 {
45  NDB_TICKS sec;
46  Uint32 micro;
47  NdbTick_CurrentMicrosecond(&sec, &micro);
48  return Uint64(sec * 1000000 + micro);
49 }
50 #endif
51 
52 class Dbspj: public SimulatedBlock {
53 public:
54  Dbspj(Block_context& ctx, Uint32 instanceNumber = 0);
55  virtual ~Dbspj();
56 
57 private:
58  BLOCK_DEFINES(Dbspj);
59 
63  void execLQHKEYREQ(Signal* signal);
64  void execSCAN_FRAGREQ(Signal* signal);
65  void execSCAN_NEXTREQ(Signal* signal);
66 
67  void execDIH_SCAN_TAB_REF(Signal*);
68  void execDIH_SCAN_TAB_CONF(Signal*);
69  void execDIH_SCAN_GET_NODES_REF(Signal*);
70  void execDIH_SCAN_GET_NODES_CONF(Signal*);
71 
75  void execLQHKEYREF(Signal* signal);
76  void execLQHKEYCONF(Signal* signal);
77  void execSCAN_FRAGREF(Signal* signal);
78  void execSCAN_FRAGCONF(Signal* signal);
79  void execSCAN_HBREP(Signal* signal);
80  void execTRANSID_AI(Signal*signal);
81 
85  void execDUMP_STATE_ORD(Signal* signal){}
86  void execREAD_NODESCONF(Signal*);
87  void execREAD_CONFIG_REQ(Signal* signal);
88  void execSTTOR(Signal* signal);
89  void execDBINFO_SCANREQ(Signal* signal);
90  void execCONTINUEB(Signal*);
91  void execNODE_FAILREP(Signal*);
92  void execINCL_NODEREQ(Signal*);
93  void execAPI_FAILREQ(Signal*);
94 
95  void sendSTTORRY(Signal* signal);
96 
97 protected:
98  //virtual bool getParam(const char* name, Uint32* count);
99 
100 public:
101  struct Request;
102  struct TreeNode;
103  struct ScanFragHandle;
108  typedef Bitmask<(NDB_SPJ_MAX_TREE_NODES+31)/32> TreeNodeBitMask;
109 
110  struct RowRef
111  {
112  Uint32 m_page_id;
113  Uint16 m_page_pos;
114  union
115  {
116  Uint16 unused;
117  Uint16 m_allocator;
118  };
119 
120  void copyto_link(Uint32 * dst) const {
121  dst[0] = m_page_id; dst[1] = m_page_pos;
122  }
123  void assign_from_link(const Uint32 * src) {
124  m_page_id = src[0];
125  m_page_pos = src[1];
126  }
127 
128  void copyto_map(Uint16 * dst) const {
129  dst[0] = Uint16(m_page_id);
130  dst[1] = Uint16(m_page_id >> 16);
131  dst[2] = m_page_pos;
132  }
133 
134  void assign_from_map(const Uint16 * src) {
135  m_page_id = src[0];
136  m_page_id += Uint32(src[1]) << 16;
137  m_page_pos = src[2];
138  }
139 
140  static bool map_is_null(const Uint16 * src) {
141  return src[2] == 0xFFFF;
142  }
143 
144  void setNull() { m_page_id = RNIL;}
145  bool isNull() const { return m_page_id == RNIL;}
146  };
147 
148  static const RowRef NullRowRef;
149 
153  struct RowPtr
154  {
155  Uint32 m_type;
156  Uint32 m_src_node_no;
157  Uint32 m_src_node_ptrI;
158  Uint32 m_src_correlation;
159 
160  struct Header
161  {
162  Uint32 m_len;
163  Uint32 m_offset[1];
164  };
165 
166  struct Section
167  {
168  const Header * m_header;
169  SegmentedSectionPtrPOD m_dataPtr;
170  };
171 
172  struct Linear
173  {
174  RowRef m_row_ref;
175  const Header * m_header;
176  const Uint32 * m_data;
177  };
178  union
179  {
180  struct Section m_section;
181  struct Linear m_linear;
182  } m_row_data;
183 
184  enum RowType
185  {
186  RT_SECTION = 1,
187  RT_LINEAR = 2,
188  RT_END = 0
189  };
190  };
191 
193  {
198  Uint32 m_last_row_page_id;
199  Uint16 m_first_row_page_pos;
200  Uint16 m_last_row_page_pos;
201 
202  void init() { m_first_row_page_id = RNIL;}
203  bool isNull() const { return m_first_row_page_id == RNIL; }
204  };
205 
206  struct RowMap
207  {
214  Uint16 m_size; // size of array
215  Uint16 m_elements; // #elements in array
216 
217  void init() { m_map_ref.setNull();}
218  bool isNull() const { return m_map_ref.isNull(); }
219 
220  void assign (RowRef ref) {
221  m_map_ref = ref;
222  }
223 
224  void copyto(RowRef& ref) const {
225  ref = m_map_ref;
226  }
227 
231  void clear(Uint32 * ptr) {
232  memset(ptr, 0xFF, MAP_SIZE_PER_REF_16 * m_size * sizeof(Uint16));
233  }
234  void store(Uint32 * _ptr, Uint32 pos, RowRef ref) {
235  Uint16 * ptr = (Uint16*)_ptr;
236  ptr += MAP_SIZE_PER_REF_16 * pos;
237  ref.copyto_map(ptr);
238  m_elements++;
239  }
240  static void load(const Uint32 * _ptr, Uint32 pos, RowRef & ref) {
241  const Uint16 * ptr = (const Uint16*)_ptr;
242  ptr += MAP_SIZE_PER_REF_16 * pos;
243  ref.assign_from_map(ptr);
244  }
245  static bool isNull(const Uint32 * _ptr, Uint32 pos) {
246  const Uint16 * ptr = (const Uint16*)_ptr;
247  ptr += MAP_SIZE_PER_REF_16 * pos;
248  return RowRef::map_is_null(ptr);
249  }
250 
251  STATIC_CONST( MAP_SIZE_PER_REF_16 = 3 );
252  };
253 
255  {
256  RowRef m_ref;
257  Uint32 * m_row_ptr;
258 
259  bool isNull() const { return m_ref.isNull(); }
260  void setNull() { m_ref.setNull(); }
261  };
262 
264  {
265  RowRef m_ref;
266  };
267 
269  {
270  Uint32 * m_row_ptr;
271  Uint32 * m_map_ptr;
272  RowRef m_ref; // position of actual row
273  Uint16 m_size;
274  Uint16 m_element_no;
275  bool isNull() const { return m_ref.isNull(); }
276  void setNull() { m_ref.setNull(); }
277  };
278 
280  {
281  Uint32 m_element_no;
282  };
283 
284 
289  {
290  Uint32 m_cnt;
291  Uint32 m_scanPrio;
292  Uint32 m_savepointId;
293  Uint32 m_batch_size_rows;
294  Uint32 m_resultRef; // API
295  Uint32 m_resultData; // API
296  Uint32 m_senderRef; // TC (used for routing)
297  Uint32 m_scan_cnt;
298  Signal* m_start_signal; // Argument to first node in tree
299  SegmentedSectionPtr m_keyPtr;
300 
301  TreeNodeBitMask m_scans; // TreeNodes doing scans
302 
303  // Used for resolving dependencies
304  Ptr<TreeNode> m_node_list[NDB_SPJ_MAX_TREE_NODES];
305  };
306 
307  struct RowPage
308  {
313  RowPage() {}
314  struct File_formats::Page_header m_page_header;
315  Uint32 unused0;
316  Uint32 unused1;
317  Uint32 nextList;
318  Uint32 prevList;
319  Uint32 m_data[GLOBAL_PAGE_SIZE_WORDS - 7];
320  STATIC_CONST( SIZE = GLOBAL_PAGE_SIZE_WORDS - 7 );
321  };
322 
323  typedef Tup_varsize_page Var_page;
324 
325  struct RowBuffer
326  {
327  RowBuffer() { stack_init(); }
328  DLFifoList<RowPage>::Head m_page_list;
329 
330  void stack_init() { new (&m_page_list) DLFifoList<RowPage>::Head(); m_stack.m_pos = 0xFFFF; }
331  void var_init() { new (&m_page_list) DLFifoList<RowPage>::Head(); m_var.m_free = 0; }
332 
333  struct Stack
334  {
335  Uint32 m_pos; // position on head-page
336  };
337 
338  struct Var
339  {
340  Uint32 m_free; // Free on last page in list
341  };
342 
343  union {
344  struct Stack m_stack;
345  struct Var m_var;
346  };
347  };
348 
353  struct DABuffer
354  {
355  const Uint32 * ptr;
356  const Uint32 * end;
357  };
358 
362  struct OpInfo
363  {
369  const QueryNode*, const QueryNodeParameters*);
370 
377 
382 
387  const RowPtr&);
388 
393 
398 
403 
408 
413  const RowPtr&);
414 
420 
426 
432 
437 
443 
449 
460  }; //struct OpInfo
461 
462  struct LookupData
463  {
464  Uint32 m_api_resultRef;
465  Uint32 m_api_resultData;
477  Uint32 m_lqhKeyReq[LqhKeyReq::FixedSignalLength + 4];
478  };
479 
481  {
482  Uint32 m_rows_received; // #execTRANSID_AI
483  Uint32 m_rows_expecting; // ScanFragConf
484  Uint32 m_scanFragReq[ScanFragReq::SignalLength + 2];
485  Uint32 m_scanFragHandlePtrI;
486  };
487 
489  {
490  enum SFH_State
491  {
492  SFH_NOT_STARTED = 0,
493  SFH_SCANNING = 1, // in LQH
494  SFH_WAIT_NEXTREQ = 2,
495  SFH_COMPLETE = 3,
496  SFH_WAIT_CLOSE = 4
497  };
498 
499  void init(Uint32 fid) {
500  m_ref = 0;
501  m_fragId = fid;
502  m_state = SFH_NOT_STARTED;
503  m_rangePtrI = RNIL;
504  reset_ranges();
505  }
506 
507  Uint32 m_magic;
508  Uint32 m_treeNodePtrI;
509  Uint16 m_fragId;
510  Uint16 m_state;
511  Uint32 m_ref;
512 
513  void reset_ranges() {
514  // m_rangePtrI is explicitly managed...in code
515  m_range_builder.m_range_cnt = m_range_builder.m_range_size = 0;
516  }
518  {
519  Uint16 m_range_size;
520  Uint16 m_range_cnt; // too set bounds info correctly
521  } m_range_builder;
522  Uint32 m_rangePtrI;
523  union {
524  Uint32 nextList;
525  Uint32 nextPool;
526  };
527  };
528 
529  typedef RecordPool<ScanFragHandle, ArenaPool> ScanFragHandle_pool;
530  typedef SLFifoListImpl<ScanFragHandle_pool, ScanFragHandle> ScanFragHandle_list;
531  typedef LocalSLFifoListImpl<ScanFragHandle_pool, ScanFragHandle> Local_ScanFragHandle_list;
532 
538  {
539  public:
544  void init()
545  {
546  m_mean = m_sumSquare = 0.0;
547  m_noOfSamples = 0;
548  }
549 
550  // Add another sample.
551  void update(double sample);
552 
553  double getMean() const { return m_mean; }
554 
555  double getStdDev() const {
556  return m_noOfSamples < 2 ? 0.0 : sqrt(m_sumSquare/(m_noOfSamples - 1));
557  }
558 
559  private:
560  // Mean of all samples
561  double m_mean;
562  //Sum of square of differences from the current mean.
563  double m_sumSquare;
564  Uint32 m_noOfSamples;
565  }; // IncrementalStatistics
566 
568  {
569  Uint16 m_frags_complete;
570  Uint16 m_frags_outstanding;
576  Uint32 m_rows_received; // #execTRANSID_AI
577  Uint32 m_rows_expecting; // Sum(ScanFragConf)
578  Uint32 m_batch_chunks; // #SCAN_FRAGREQ + #SCAN_NEXTREQ to retrieve batch
579  Uint32 m_scanCookie;
580  Uint32 m_fragCount;
581  // The number of fragments that we scan in parallel.
582  Uint32 m_parallelism;
593  // Total number of rows for the current execution of this operation.
594  Uint32 m_totalRows;
595  // Total number of bytes for the current execution of this operation.
596  Uint32 m_totalBytes;
597 
598  ScanFragHandle_list::HeadPOD m_fragments; // ScanFrag states
599  union
600  {
601  PatternStore::HeadPOD m_prunePattern;
602  Uint32 m_constPrunePtrI;
603  };
614  Uint32 m_scanFragReq[ScanFragReq::SignalLength + 2];
615  };
616 
618  {
619  Uint32 nextList;
620  };
621 
628  {
629  STATIC_CONST ( MAGIC = ~RT_SPJ_TREENODE );
630 
631  TreeNode()
632  : m_magic(MAGIC), m_state(TN_END),
633  m_parentPtrI(RNIL), m_requestPtrI(0),
634  m_ancestors()
635  {
636  }
637 
638  TreeNode(Uint32 request)
639  : m_magic(MAGIC),
640  m_info(0), m_bits(T_LEAF), m_state(TN_BUILDING),
641  m_parentPtrI(RNIL), m_requestPtrI(request),
642  m_ancestors(),
643  nextList(RNIL), prevList(RNIL)
644  {
645 // m_send.m_ref = 0;
646  m_send.m_correlation = 0;
647  m_send.m_keyInfoPtrI = RNIL;
648  m_send.m_attrInfoPtrI = RNIL;
649  }
650 
651  const Uint32 m_magic;
652  const struct OpInfo* m_info;
653 
655  {
660 
665 
670 
675 
680 
684  TN_END = 0
685  };
686 
688  {
689  T_ATTR_INTERPRETED = 0x1,
690 
695  T_ONE_SHOT = 0x2,
696 
702 
708 
712  T_LEAF = 0x10,
713 
720 
726 
727  /*
728  * Should this node buffers its rows
729  */
730  T_ROW_BUFFER = 0x80,
731 
739 
744 
749 
753  T_CONST_PRUNE = 0x800,
754 
758  T_PRUNE_PATTERN = 0x1000,
759 
763  T_SCAN_PARALLEL = 0x2000,
764 
769 
770  // End marker...
771  T_END = 0
772  };
773 
774  bool isLeaf() const { return (m_bits & T_LEAF) != 0;}
775 
776  Uint32 m_bits;
777  Uint32 m_state;
778  Uint32 m_node_no;
779  Uint32 m_batch_size;
780  Uint32 m_parentPtrI;
781  const Uint32 m_requestPtrI;
782  TreeNodeBitMask m_ancestors;
783  Dependency_map::Head m_dependent_nodes;
784  PatternStore::Head m_keyPattern;
785  PatternStore::Head m_attrParamPattern;
786 
790  union
791  {
792  RowMap m_row_map;
793  SLFifoRowList m_row_list;
794  };
795 
796  union
797  {
798  LookupData m_lookup_data;
799  ScanFragData m_scanfrag_data;
800  ScanIndexData m_scanindex_data;
801  };
802 
803  struct {
804  Uint32 m_ref; // dst for signal
810  Uint32 m_keyInfoPtrI; // keyInfoSection
811  Uint32 m_attrInfoPtrI; // attrInfoSection
812  } m_send;
813 
814  union {
815  Uint32 nextList;
816  Uint32 nextPool;
817  };
818  Uint32 prevList;
819  }; //struct TreeNode
820 
821  static const Ptr<TreeNode> NullTreeNodePtr;
822 
823  typedef RecordPool<TreeNode, ArenaPool> TreeNode_pool;
824  typedef DLFifoListImpl<TreeNode_pool, TreeNode> TreeNode_list;
825  typedef LocalDLFifoListImpl<TreeNode_pool, TreeNode> Local_TreeNode_list;
826 
828  TreeNodeCursor_list;
830  Local_TreeNodeCursor_list;
831 
835  struct Request
836  {
837  enum RequestBits
838  {
839  RT_SCAN = 0x1 // unbounded result set, scan interface
840  ,RT_ROW_BUFFERS = 0x2 // Do any of the node use row-buffering
841  ,RT_MULTI_SCAN = 0x4 // Is there several scans in request
842  ,RT_VAR_ALLOC = 0x8 // Is var-allocation used for row-buffer
843  ,RT_NEED_PREPARE = 0x10 // Does any node need m_prepare hook
844  ,RT_NEED_COMPLETE = 0x20 // Does any node need m_complete hook
845  ,RT_REPEAT_SCAN_RESULT = 0x40 // Repeat bushy scan result when required
846  };
847 
848  enum RequestState
849  {
850  RS_BUILDING = 0x1,
851  RS_PREPARING = 0x2,
852  RS_RUNNING = 0x3,
853  RS_COMPLETING = 0x4,
854 
855  RS_ABORTING = 0x1000, // Or:ed together with other states
856  RS_WAITING = 0x2000, // Waiting for SCAN_NEXTREQ
857 
858  RS_ABORTED = 0x2008, // Aborted and waiting for SCAN_NEXTREQ
859  RS_END = 0
860  }; //struct Request
861 
862  Request() {}
863  Request(const ArenaHead & arena) : m_arena(arena) {}
864  Uint32 m_magic;
865  Uint32 m_bits;
866  Uint32 m_state;
867  Uint32 m_errCode;
868  Uint32 m_node_cnt;
869  Uint32 m_senderRef;
870  Uint32 m_senderData;
871  Uint32 m_rootResultData;
872  Uint32 m_transId[2];
873  TreeNode_list::Head m_nodes;
874  TreeNodeCursor_list::Head m_cursor_nodes;
875  Uint32 m_cnt_active; // No of "running" nodes
877  m_active_nodes; // Nodes which will return more data in NEXTREQ
878  Uint32 m_rows; // Rows accumulated in current batch
879  Uint32 m_outstanding; // Outstanding signals, when 0, batch is done
880  Uint16 m_lookup_node_data[MAX_NDB_NODES];
881  ArenaHead m_arena;
882  RowBuffer m_rowBuffer;
883 
884 #ifdef SPJ_TRACE_TIME
885  Uint32 m_cnt_batches;
886  Uint32 m_sum_rows;
887  Uint32 m_sum_running;
888  Uint32 m_sum_waiting;
889  Uint64 m_save_time;
890 #endif
891 
892  bool isScan() const { return (m_bits & RT_SCAN) != 0;}
893  bool isLookup() const { return (m_bits & RT_SCAN) == 0;}
894 
895  bool equal(const Request & key) const {
896  return
897  m_senderData == key.m_senderData &&
898  m_transId[0] == key.m_transId[0] &&
899  m_transId[1] == key.m_transId[1];
900  }
901 
902  Uint32 hashValue() const {
903  return m_transId[0] ^ m_senderData;
904  }
905 
906  union {
907  Uint32 nextHash;
908  Uint32 nextPool;
909  };
910  Uint32 prevHash;
911  };
912 
913 private:
918  enum CounterId
919  {
924  CI_READS_RECEIVED = 0,
925 
930  CI_LOCAL_READS_SENT = 1,
931 
936  CI_REMOTE_READS_SENT = 2,
937 
943  CI_READS_NOT_FOUND = 3,
944 
949  CI_TABLE_SCANS_RECEIVED = 4,
950 
955  CI_LOCAL_TABLE_SCANS_SENT = 5,
956 
961  CI_RANGE_SCANS_RECEIVED = 6,
962 
967  CI_LOCAL_RANGE_SCANS_SENT = 7,
968 
973  CI_REMOTE_RANGE_SCANS_SENT = 8,
974 
978  CI_SCAN_BATCHES_RETURNED = 9,
979 
983  CI_SCAN_ROWS_RETURNED = 10,
984 
988  CI_PRUNED_RANGE_SCANS_RECEIVED = 11,
989 
994  CI_CONST_PRUNED_RANGE_SCANS_RECEIVED = 12,
995 
996  CI_END = 13 // End marker - not a valid counter id.
997  };
998 
1003  class MonotonicCounters {
1004  public:
1005 
1006  MonotonicCounters()
1007  {
1008  for(int i = 0; i < CI_END; i++)
1009  {
1010  m_counters[i] = 0;
1011  }
1012  }
1013 
1014  Uint64 get_counter(CounterId id) const
1015  {
1016  return m_counters[id];
1017  }
1018 
1019  void incr_counter(CounterId id, Uint64 delta)
1020  {
1021  m_counters[id] += delta;
1022  }
1023 
1024  private:
1025  Uint64 m_counters[CI_END];
1026 
1027  } c_Counters;
1028 
1029  typedef RecordPool<Request, ArenaPool> Request_pool;
1030  typedef DLListImpl<Request_pool, Request> Request_list;
1031  typedef LocalDLListImpl<Request_pool, Request> Local_Request_list;
1032  typedef DLHashTableImpl<Request_pool, Request> Request_hash;
1033  typedef DLHashTableImpl<Request_pool, Request>::Iterator Request_iterator;
1034 
1035  ArenaAllocator m_arenaAllocator;
1036  Request_pool m_request_pool;
1037  Request_hash m_scan_request_hash;
1038  Request_hash m_lookup_request_hash;
1039  ArenaPool m_dependency_map_pool;
1040  TreeNode_pool m_treenode_pool;
1041  ScanFragHandle_pool m_scanfraghandle_pool;
1042 
1043  NdbNodeBitmask c_alive_nodes;
1044 
1045  void do_init(Request*, const LqhKeyReq*, Uint32 senderRef);
1046  void store_lookup(Ptr<Request>);
1047  void handle_early_lqhkey_ref(Signal*, const LqhKeyReq *, Uint32 err);
1048  void sendTCKEYREF(Signal* signal, Uint32 ref, Uint32 routeRef);
1049  void sendTCKEYCONF(Signal* signal, Uint32 len, Uint32 ref, Uint32 routeRef);
1050 
1051  void do_init(Request*, const ScanFragReq*, Uint32 senderRef);
1052  void store_scan(Ptr<Request>);
1053  void handle_early_scanfrag_ref(Signal*, const ScanFragReq *, Uint32 err);
1054 
1055  struct BuildKeyReq
1056  {
1057  Uint32 hashInfo[4]; // Used for hashing
1058  Uint32 fragId;
1059  Uint32 fragDistKey;
1060  Uint32 receiverRef; // NodeId + InstanceNo
1061  };
1062 
1066  const OpInfo* getOpInfo(Uint32 op);
1067  Uint32 build(Build_context&,Ptr<Request>,SectionReader&,SectionReader&);
1068  void checkPrepareComplete(Signal*, Ptr<Request>, Uint32 cnt);
1069  void start(Signal*, Ptr<Request>);
1070  void checkBatchComplete(Signal*, Ptr<Request>, Uint32 cnt);
1071  void batchComplete(Signal*, Ptr<Request>);
1072  void prepareNextBatch(Signal*, Ptr<Request>);
1073  void sendConf(Signal*, Ptr<Request>, bool is_complete);
1074  void complete(Signal*, Ptr<Request>);
1075  void cleanup(Ptr<Request>);
1076  void abort(Signal*, Ptr<Request>, Uint32 errCode);
1077  Uint32 nodeFail(Signal*, Ptr<Request>, NdbNodeBitmask mask);
1078 
1079  Uint32 createNode(Build_context&, Ptr<Request>, Ptr<TreeNode> &);
1080  void reportBatchComplete(Signal*, Ptr<Request>, Ptr<TreeNode>);
1081  void releaseScanBuffers(Ptr<Request> requestPtr);
1082  void releaseRequestBuffers(Ptr<Request> requestPtr, bool reset);
1083  void releaseNodeRows(Ptr<Request> requestPtr, Ptr<TreeNode>);
1084  void releaseRow(Ptr<Request>, RowRef ref);
1085  void registerActiveCursor(Ptr<Request>, Ptr<TreeNode>);
1086  void nodeFail_checkRequests(Signal*);
1087 
1088  void cleanupChildBranch(Ptr<Request>, Ptr<TreeNode>);
1089  void cleanup_common(Ptr<Request>, Ptr<TreeNode>);
1090 
1094  Uint32 storeRow(Ptr<Request>, Ptr<TreeNode>, RowPtr &row);
1095  Uint32* stackAlloc(RowBuffer& dst, RowRef&, Uint32 len);
1096  Uint32* varAlloc(RowBuffer& dst, RowRef&, Uint32 len);
1097 
1098  void add_to_list(SLFifoRowList & list, RowRef rowref);
1099  Uint32 add_to_map(Ptr<Request> requestPtr, Ptr<TreeNode>, Uint32, RowRef);
1100  Uint32 * get_row_ptr(const RowMap&, RowMapIterator pos);
1101  void setupRowPtr(Ptr<TreeNode>, RowPtr& dst, RowRef, const Uint32 * src);
1102 
1103  // NOTE: ref contains info about it being stack/var
1104  // so adding an inline would be nice...but that remove possibility
1105  // to add jam()'s
1106  Uint32 * get_row_ptr_stack(RowRef pos);
1107  Uint32 * get_row_ptr_var(RowRef pos);
1108 
1112  bool first(Ptr<Request>, Ptr<TreeNode>, SLFifoRowListIterator&);
1113  bool next(SLFifoRowListIterator&);
1114  bool next(Ptr<Request>, Ptr<TreeNode>, SLFifoRowListIterator&, SLFifoRowListIteratorPtr);
1115 
1116  bool first(Ptr<Request>, Ptr<TreeNode>, RowMapIterator&);
1117  bool next(RowMapIterator&);
1118  bool next(Ptr<Request>,Ptr<TreeNode>, RowMapIterator&, RowMapIteratorPtr);
1119 
1123  Uint32 buildRowHeader(RowPtr::Header *, SegmentedSectionPtr);
1124  Uint32 buildRowHeader(RowPtr::Header *, const Uint32 *& src, Uint32 len);
1125  void getCorrelationData(const RowPtr::Section & row, Uint32 col,
1126  Uint32& correlationNumber);
1127  void getCorrelationData(const RowPtr::Linear & row, Uint32 col,
1128  Uint32& correlationNumber);
1129  Uint32 appendToPattern(Local_pattern_store &, DABuffer & tree, Uint32);
1130  Uint32 appendParamToPattern(Local_pattern_store&,const RowPtr::Linear&,
1131  Uint32);
1132  Uint32 appendParamHeadToPattern(Local_pattern_store&,const RowPtr::Linear&,
1133  Uint32);
1134 
1135  Uint32 appendTreeToSection(Uint32 & ptrI, SectionReader &, Uint32);
1136  Uint32 appendColToSection(Uint32 & ptrI, const RowPtr::Linear&, Uint32 col, bool& hasNull);
1137  Uint32 appendColToSection(Uint32 & ptrI, const RowPtr::Section&, Uint32 col, bool& hasNull);
1138  Uint32 appendPkColToSection(Uint32 & ptrI, const RowPtr::Section&,Uint32 col);
1139  Uint32 appendPkColToSection(Uint32 & ptrI, const RowPtr::Linear&, Uint32 col);
1140  Uint32 appendAttrinfoToSection(Uint32 &, const RowPtr::Linear&, Uint32 col, bool& hasNull);
1141  Uint32 appendAttrinfoToSection(Uint32 &, const RowPtr::Section&, Uint32 col, bool& hasNull);
1142  Uint32 appendDataToSection(Uint32 & ptrI, Local_pattern_store&,
1143  Local_pattern_store::ConstDataBufferIterator&,
1144  Uint32 len, bool& hasNull);
1145  Uint32 appendFromParent(Uint32 & ptrI, Local_pattern_store&,
1146  Local_pattern_store::ConstDataBufferIterator&,
1147  Uint32 level, const RowPtr&, bool& hasNull);
1148  Uint32 expand(Uint32 & ptrI, Local_pattern_store& p, const RowPtr& r, bool& hasNull){
1149  switch(r.m_type){
1150  case RowPtr::RT_SECTION:
1151  return expandS(ptrI, p, r, hasNull);
1152  case RowPtr::RT_LINEAR:
1153  return expandL(ptrI, p, r, hasNull);
1154  }
1155  return DbspjErr::InternalError;
1156  }
1157  Uint32 expandS(Uint32 & ptrI, Local_pattern_store&, const RowPtr&, bool& hasNull);
1158  Uint32 expandL(Uint32 & ptrI, Local_pattern_store&, const RowPtr&, bool& hasNull);
1159  Uint32 expand(Uint32 & ptrI, DABuffer& pattern, Uint32 len,
1160  DABuffer & param, Uint32 cnt, bool& hasNull);
1161  Uint32 expand(Local_pattern_store& dst, Ptr<TreeNode> treeNodePtr,
1162  DABuffer & pattern, Uint32 len,
1163  DABuffer & param, Uint32 cnt);
1164  Uint32 parseDA(Build_context&, Ptr<Request>, Ptr<TreeNode>,
1165  DABuffer & tree, Uint32 treeBits,
1166  DABuffer & param, Uint32 paramBits);
1167 
1168  Uint32 createEmptySection(Uint32 & ptrI);
1169 
1170  Uint32 getResultRef(Ptr<Request> requestPtr);
1171 
1175  static const OpInfo g_LookupOpInfo;
1176  Uint32 lookup_build(Build_context&,Ptr<Request>,
1177  const QueryNode*, const QueryNodeParameters*);
1178  void lookup_start(Signal*, Ptr<Request>, Ptr<TreeNode>);
1179  void lookup_send(Signal*, Ptr<Request>, Ptr<TreeNode>);
1180  void lookup_execTRANSID_AI(Signal*, Ptr<Request>, Ptr<TreeNode>,
1181  const RowPtr&);
1182  void lookup_execLQHKEYREF(Signal*, Ptr<Request>, Ptr<TreeNode>);
1183  void lookup_execLQHKEYCONF(Signal*, Ptr<Request>, Ptr<TreeNode>);
1184  void lookup_parent_row(Signal*, Ptr<Request>, Ptr<TreeNode>, const RowPtr &);
1185  void lookup_parent_batch_complete(Signal*, Ptr<Request>, Ptr<TreeNode>);
1186  void lookup_abort(Signal*, Ptr<Request>, Ptr<TreeNode>);
1187  Uint32 lookup_execNODE_FAILREP(Signal*signal, Ptr<Request>, Ptr<TreeNode>,
1188  NdbNodeBitmask);
1189  void lookup_cleanup(Ptr<Request>, Ptr<TreeNode>);
1190 
1191  Uint32 handle_special_hash(Uint32 tableId, Uint32 dstHash[4],
1192  const Uint64* src,
1193  Uint32 srcLen, // Len in #32bit words
1194  const struct KeyDescriptor* desc);
1195 
1196  Uint32 computeHash(Signal*, BuildKeyReq&, Uint32 table, Uint32 keyInfoPtrI);
1197  Uint32 computePartitionHash(Signal*, BuildKeyReq&, Uint32 table, Uint32 keyInfoPtrI);
1198  Uint32 getNodes(Signal*, BuildKeyReq&, Uint32 tableId);
1199 
1203  static const OpInfo g_ScanFragOpInfo;
1204  Uint32 scanFrag_build(Build_context&, Ptr<Request>,
1205  const QueryNode*, const QueryNodeParameters*);
1206  void scanFrag_start(Signal*, Ptr<Request>,Ptr<TreeNode>);
1207  void scanFrag_send(Signal*, Ptr<Request>, Ptr<TreeNode>);
1208  void scanFrag_execTRANSID_AI(Signal*, Ptr<Request>, Ptr<TreeNode>,
1209  const RowPtr &);
1210  void scanFrag_execSCAN_FRAGREF(Signal*, Ptr<Request>, Ptr<TreeNode>, Ptr<ScanFragHandle>);
1211  void scanFrag_execSCAN_FRAGCONF(Signal*, Ptr<Request>, Ptr<TreeNode>, Ptr<ScanFragHandle>);
1212  void scanFrag_execSCAN_NEXTREQ(Signal*, Ptr<Request>,Ptr<TreeNode>);
1213  void scanFrag_abort(Signal*, Ptr<Request>, Ptr<TreeNode>);
1214  void scanFrag_cleanup(Ptr<Request>, Ptr<TreeNode>);
1215 
1219  static const OpInfo g_ScanIndexOpInfo;
1220  Uint32 scanIndex_build(Build_context&, Ptr<Request>,
1221  const QueryNode*, const QueryNodeParameters*);
1222  Uint32 parseScanIndex(Build_context&, Ptr<Request>, Ptr<TreeNode>,
1223  DABuffer tree, Uint32 treeBits,
1224  DABuffer param, Uint32 paramBits);
1225  void scanIndex_prepare(Signal*, Ptr<Request>, Ptr<TreeNode>);
1226  void scanIndex_execTRANSID_AI(Signal*, Ptr<Request>, Ptr<TreeNode>,
1227  const RowPtr &);
1228  void scanIndex_execSCAN_FRAGREF(Signal*, Ptr<Request>, Ptr<TreeNode>, Ptr<ScanFragHandle>);
1229  void scanIndex_execSCAN_FRAGCONF(Signal*, Ptr<Request>, Ptr<TreeNode>, Ptr<ScanFragHandle>);
1230  void scanIndex_parent_row(Signal*,Ptr<Request>,Ptr<TreeNode>, const RowPtr&);
1231  void scanIndex_fixupBound(Ptr<ScanFragHandle> fragPtr, Uint32 ptrI, Uint32);
1232  void scanIndex_send(Signal*,Ptr<Request>,Ptr<TreeNode>);
1233  void scanIndex_send(Signal* signal,
1234  Ptr<Request> requestPtr,
1235  Ptr<TreeNode> treeNodePtr,
1236  Uint32 noOfFrags,
1237  Uint32 bs_bytes,
1238  Uint32 bs_rows,
1239  Uint32& batchRange);
1240  void scanIndex_batchComplete(Signal* signal);
1241  Uint32 scanIndex_findFrag(Local_ScanFragHandle_list &, Ptr<ScanFragHandle>&,
1242  Uint32 fragId);
1243  void scanIndex_parent_batch_complete(Signal*, Ptr<Request>, Ptr<TreeNode>);
1244  void scanIndex_parent_batch_repeat(Signal*, Ptr<Request>, Ptr<TreeNode>);
1245  void scanIndex_execSCAN_NEXTREQ(Signal*, Ptr<Request>,Ptr<TreeNode>);
1246  void scanIndex_complete(Signal*, Ptr<Request>, Ptr<TreeNode>);
1247  void scanIndex_abort(Signal*, Ptr<Request>, Ptr<TreeNode>);
1248  Uint32 scanIndex_execNODE_FAILREP(Signal*signal, Ptr<Request>, Ptr<TreeNode>,
1249  NdbNodeBitmask);
1250  void scanIndex_parent_batch_cleanup(Ptr<Request>, Ptr<TreeNode>);
1251  void scanIndex_cleanup(Ptr<Request>, Ptr<TreeNode>);
1252 
1253  void scanIndex_release_rangekeys(Ptr<Request>, Ptr<TreeNode>);
1254 
1258  bool allocPage(Ptr<RowPage> &);
1259  void releasePage(Ptr<RowPage>);
1260  void releasePages(Uint32 first, Ptr<RowPage> last);
1261  void releaseGlobal(Signal*);
1262  SLList<RowPage>::Head m_free_page_list;
1263  ArrayPool<RowPage> m_page_pool;
1264 
1268  Uint32 m_buffer0[8192]; // 32k
1269  Uint32 m_buffer1[8192]; // 32k
1270 };
1271 
1272 #endif