MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbTransactionScan.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #include <ndb_global.h>
20 
21 #include "API.hpp"
22 
23 #include <signaldata/ScanTab.hpp>
24 
25 #include <NdbOut.hpp>
26 #include <NdbQueryOperationImpl.hpp>
27 
28 /***************************************************************************
29  * int receiveSCAN_TABREF(NdbApiSignal* aSignal)
30  *
31  * This means the scan could not be started, set status(s) to indicate
32  * the failure
33  *
34  ****************************************************************************/
35 int
36 NdbTransaction::receiveSCAN_TABREF(const NdbApiSignal* aSignal){
37  const ScanTabRef * ref = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr());
38 
39  if (checkState_TransId(&ref->transId1)) {
40  if (theScanningOp) {
41  theScanningOp->execCLOSE_SCAN_REP();
42  theScanningOp->setErrorCode(ref->errorCode);
43  if(!ref->closeNeeded){
44  return 0;
45  }
46 
51  theScanningOp->m_conf_receivers_count++;
52  theScanningOp->m_conf_receivers[0] = theScanningOp->m_receivers[0];
53  theScanningOp->m_conf_receivers[0]->m_tcPtrI = ~0;
54 
55  } else {
56  assert (m_scanningQuery);
57  m_scanningQuery->execCLOSE_SCAN_REP(ref->errorCode, ref->closeNeeded);
58  if(!ref->closeNeeded){
59  return 0;
60  }
61  }
62  return 0;
63  } else {
64 #ifdef NDB_NO_DROPPED_SIGNAL
65  abort();
66 #endif
67  }
68 
69  return -1;
70 }
71 
72 /*****************************************************************************
73  * int receiveSCAN_TABCONF(NdbApiSignal* aSignal)
74  *
75  * Receive SCAN_TABCONF
76  * If scanStatus == 0 there is more records to read. Since signals may be
77  * received in any order we have to go through the lists with saved signals
78  * and check if all expected signals are there so that we can start to
79  * execute them.
80  *
81  * If scanStatus > 0 this indicates that the scan is finished and there are
82  * no more data to be read.
83  *
84  *****************************************************************************/
85 int
86 NdbTransaction::receiveSCAN_TABCONF(const NdbApiSignal* aSignal,
87  const Uint32 * ops, Uint32 len)
88 {
89  const ScanTabConf * conf = CAST_CONSTPTR(ScanTabConf, aSignal->getDataPtr());
90 
91  if (checkState_TransId(&conf->transId1)) {
92 
96  if (conf->requestInfo == ScanTabConf::EndOfData) {
97  if (theScanningOp) {
98  theScanningOp->execCLOSE_SCAN_REP();
99  } else {
100  assert (m_scanningQuery);
101  m_scanningQuery->execCLOSE_SCAN_REP(0, false);
102  }
103  return 1; // -> Finished
104  }
105 
106  int retVal = -1;
107  Uint32 words_per_op = theScanningOp ? 3 : 4;
108  for(Uint32 i = 0; i<len; i += words_per_op)
109  {
110  Uint32 ptrI = * ops++;
111  Uint32 tcPtrI = * ops++;
112  Uint32 opCount;
113  Uint32 totalLen;
114  if (words_per_op == 3)
115  {
116  Uint32 info = * ops++;
117  opCount = ScanTabConf::getRows(info);
118  totalLen = ScanTabConf::getLength(info);
119  }
120  else
121  {
122  opCount = * ops++;
123  totalLen = * ops++;
124  }
125 
126  void * tPtr = theNdb->int2void(ptrI);
127  assert(tPtr); // For now
128  NdbReceiver* tOp = theNdb->void2rec(tPtr);
129  if (tOp && tOp->checkMagicNumber())
130  {
131  // Check if this is a linked operation.
132  if (tOp->getType()==NdbReceiver::NDB_QUERY_OPERATION)
133  {
134  NdbQueryOperationImpl* queryOp = (NdbQueryOperationImpl*)tOp->m_owner;
135  assert (&queryOp->getQuery() == m_scanningQuery);
136 
137  if (queryOp->execSCAN_TABCONF(tcPtrI, opCount, totalLen, tOp))
138  retVal = 0; // We have result data, wakeup receiver
139  }
140  else
141  {
142  if (tcPtrI == RNIL && opCount == 0)
143  {
144  theScanningOp->receiver_completed(tOp);
145  retVal = 0;
146  }
147  else if (tOp->execSCANOPCONF(tcPtrI, totalLen, opCount))
148  {
149  theScanningOp->receiver_delivered(tOp);
150  retVal = 0;
151  }
152  }
153  }
154  } //for
155  return retVal;
156  } else {
157 #ifdef NDB_NO_DROPPED_SIGNAL
158  abort();
159 #endif
160  }
161 
162  return -1;
163 }