1 /* Copyright (c) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
2 Use is subject to license terms
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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17 #include <ndb_global.h>
18 #include <my_sys.h>
19
20 #define DBDICT_C
21 #include "Dbdict.hpp"
22 #include "diskpage.hpp"
23
24 #include <ndb_limits.h>
25 #include <NdbOut.hpp>
26 #include <Properties.hpp>
27 #include <Configuration.hpp>
28 #include <SectionReader.hpp>
29 #include <SimpleProperties.hpp>
30 #include <AttributeHeader.hpp>
31 #include <KeyDescriptor.hpp>
32 #include <signaldata/DictSchemaInfo.hpp>
33 #include <signaldata/DictTabInfo.hpp>
34 #include <signaldata/DropTabFile.hpp>
35
36 #include <signaldata/EventReport.hpp>
37 #include <signaldata/FsCloseReq.hpp>
38 #include <signaldata/FsConf.hpp>
39 #include <signaldata/FsOpenReq.hpp>
40 #include <signaldata/FsReadWriteReq.hpp>
41 #include <signaldata/FsRef.hpp>
42 #include <signaldata/GetTabInfo.hpp>
43 #include <signaldata/GetTableId.hpp>
44 #include <signaldata/HotSpareRep.hpp>
45 #include <signaldata/NFCompleteRep.hpp>
46 #include <signaldata/NodeFailRep.hpp>
47 #include <signaldata/ReadNodesConf.hpp>
48 #include <signaldata/RelTabMem.hpp>
49 #include <signaldata/WaitGCP.hpp>
50 #include <signaldata/ListTables.hpp>
51
52 #include <signaldata/CreateTrig.hpp>
53 #include <signaldata/AlterTrig.hpp>
54 #include <signaldata/DropTrig.hpp>
55 #include <signaldata/CreateIndx.hpp>
56 #include <signaldata/DropIndx.hpp>
57 #include <signaldata/BuildIndx.hpp>
58
59 #include <signaldata/DropFilegroup.hpp>
60 #include <signaldata/CreateFilegroup.hpp>
61 #include <signaldata/CreateFilegroupImpl.hpp>
62
63 #include <signaldata/CreateEvnt.hpp>
64 #include <signaldata/UtilPrepare.hpp>
65 #include <signaldata/UtilExecute.hpp>
66 #include <signaldata/UtilRelease.hpp>
67 #include <signaldata/SumaImpl.hpp>
68
69 #include <signaldata/LqhFrag.hpp>
70
71 #include <signaldata/DiAddTab.hpp>
72 #include <signaldata/DihStartTab.hpp>
73
74 #include <signaldata/DropTable.hpp>
75 #include <signaldata/DropTab.hpp>
76 #include <signaldata/PrepDropTab.hpp>
77
78 #include <signaldata/CreateTable.hpp>
79 #include <signaldata/AlterTable.hpp>
80 #include <signaldata/AlterTab.hpp>
81 #include <signaldata/CreateFragmentation.hpp>
82 #include <signaldata/CreateTab.hpp>
83 #include <NdbSleep.h>
84 #include <signaldata/ApiBroadcast.hpp>
85
86 #include <signaldata/DropObj.hpp>
87 #include <signaldata/CreateObj.hpp>
88 #include <SLList.hpp>
89
90 #include <EventLogger.hpp>
91 extern EventLogger g_eventLogger;
92
93 #define ZNOT_FOUND 626
94 #define ZALREADYEXIST 630
95
96 //#define EVENT_PH2_DEBUG
97 //#define EVENT_PH3_DEBUG
98 //#define EVENT_DEBUG
99
100 static const char EVENT_SYSTEM_TABLE_NAME[] = "sys/def/NDB$EVENTS_0";
101
102 #define EVENT_TRACE \
103 // ndbout_c("Event debug trace: File: %s Line: %u", __FILE__, __LINE__)
104
105 #define DIV(x,y) (((x)+(y)-1)/(y))
106 #define WORDS2PAGES(x) DIV(x, (ZSIZE_OF_PAGES_IN_WORDS - ZPAGE_HEADER_SIZE))
107 #include <ndb_version.h>
108
109 static
110 struct {
111 Uint32 m_gsn_user_req;
112 Uint32 m_gsn_req;
113 Uint32 m_gsn_ref;
114 Uint32 m_gsn_conf;
115 void (Dbdict::* m_trans_commit_start)(Signal*, Dbdict::SchemaTransaction*);
116 void (Dbdict::* m_trans_commit_complete)(Signal*,Dbdict::SchemaTransaction*);
117 void (Dbdict::* m_trans_abort_start)(Signal*, Dbdict::SchemaTransaction*);
118 void (Dbdict::* m_trans_abort_complete)(Signal*, Dbdict::SchemaTransaction*);
119
120 void (Dbdict::* m_prepare_start)(Signal*, Dbdict::SchemaOp*);
121 void (Dbdict::* m_prepare_complete)(Signal*, Dbdict::SchemaOp*);
122 void (Dbdict::* m_commit)(Signal*, Dbdict::SchemaOp*);
123 void (Dbdict::* m_commit_start)(Signal*, Dbdict::SchemaOp*);
124 void (Dbdict::* m_commit_complete)(Signal*, Dbdict::SchemaOp*);
125 void (Dbdict::* m_abort)(Signal*, Dbdict::SchemaOp*);
126 void (Dbdict::* m_abort_start)(Signal*, Dbdict::SchemaOp*);
127 void (Dbdict::* m_abort_complete)(Signal*, Dbdict::SchemaOp*);
128
129 } f_dict_op[] = {
130 /**
131 * Create filegroup
132 */
133 {
134 GSN_CREATE_FILEGROUP_REQ,
135 GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
136 0, 0, 0, 0,
137 &Dbdict::create_fg_prepare_start, &Dbdict::create_fg_prepare_complete,
138 &Dbdict::createObj_commit,
139 0, 0,
140 &Dbdict::createObj_abort,
141 &Dbdict::create_fg_abort_start, &Dbdict::create_fg_abort_complete,
142 }
143
144 /**
145 * Create file
146 */
147 ,{
148 GSN_CREATE_FILE_REQ,
149 GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
150 0, 0, 0, 0,
151 &Dbdict::create_file_prepare_start, &Dbdict::create_file_prepare_complete,
152 &Dbdict::createObj_commit,
153 &Dbdict::create_file_commit_start, 0,
154 &Dbdict::createObj_abort,
155 &Dbdict::create_file_abort_start, &Dbdict::create_file_abort_complete,
156 }
157
158 /**
159 * Drop file
160 */
161 ,{
162 GSN_DROP_FILE_REQ,
163 GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
164 0, 0, 0, 0,
165 &Dbdict::drop_file_prepare_start, 0,
166 &Dbdict::dropObj_commit,
167 &Dbdict::drop_file_commit_start, &Dbdict::drop_file_commit_complete,
168 &Dbdict::dropObj_abort,
169 &Dbdict::drop_file_abort_start, 0
170 }
171
172 /**
173 * Drop filegroup
174 */
175 ,{
176 GSN_DROP_FILEGROUP_REQ,
177 GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
178 0, 0, 0, 0,
179 &Dbdict::drop_fg_prepare_start, 0,
180 &Dbdict::dropObj_commit,
181 &Dbdict::drop_fg_commit_start, &Dbdict::drop_fg_commit_complete,
182 &Dbdict::dropObj_abort,
183 &Dbdict::drop_fg_abort_start, 0
184 }
185
186 /**
187 * Drop undofile
188 */
189 ,{
190 GSN_DROP_FILE_REQ,
191 GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
192 0, 0, 0, 0,
193 &Dbdict::drop_undofile_prepare_start, 0,
194 0,
195 0, &Dbdict::drop_undofile_commit_complete,
196 0, 0, 0
197 }
198 };
199
200 Uint32
alter_obj_inc_schema_version(Uint32 old)201 alter_obj_inc_schema_version(Uint32 old)
202 {
203 return (old & 0x00FFFFFF) + ((old + 0x1000000) & 0xFF000000);
204 }
205
206 static
207 Uint32
alter_obj_dec_schema_version(Uint32 old)208 alter_obj_dec_schema_version(Uint32 old)
209 {
210 return (old & 0x00FFFFFF) + ((old - 0x1000000) & 0xFF000000);
211 }
212
213 static
214 Uint32
create_obj_inc_schema_version(Uint32 old)215 create_obj_inc_schema_version(Uint32 old)
216 {
217 return (old + 0x00000001) & 0x00FFFFFF;
218 }
219
220 /* **************************************************************** */
221 /* ---------------------------------------------------------------- */
222 /* MODULE: GENERAL MODULE -------------------------------- */
223 /* ---------------------------------------------------------------- */
224 /* */
225 /* This module contains general stuff. Mostly debug signals and */
226 /* general signals that go into a specific module after checking a */
227 /* state variable. Also general subroutines used by many. */
228 /* ---------------------------------------------------------------- */
229 /* **************************************************************** */
230
231 /* ---------------------------------------------------------------- */
232 // This signal is used to dump states of various variables in the
233 // block by command.
234 /* ---------------------------------------------------------------- */
235 void
execDUMP_STATE_ORD(Signal * signal)236 Dbdict::execDUMP_STATE_ORD(Signal* signal)
237 {
238 jamEntry();
239
240 #ifdef VM_TRACE
241 if(signal->theData[0] == 1222){
242 const Uint32 tab = signal->theData[1];
243 PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
244 req->senderRef = reference();
245 req->senderData = 1222;
246 req->tableId = tab;
247 sendSignal(DBLQH_REF, GSN_PREP_DROP_TAB_REQ, signal,
248 PrepDropTabReq::SignalLength, JBB);
249 }
250
251 if(signal->theData[0] == 1223){
252 const Uint32 tab = signal->theData[1];
253 PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
254 req->senderRef = reference();
255 req->senderData = 1222;
256 req->tableId = tab;
257 sendSignal(DBTC_REF, GSN_PREP_DROP_TAB_REQ, signal,
258 PrepDropTabReq::SignalLength, JBB);
259 }
260
261 if(signal->theData[0] == 1224){
262 const Uint32 tab = signal->theData[1];
263 PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
264 req->senderRef = reference();
265 req->senderData = 1222;
266 req->tableId = tab;
267 sendSignal(DBDIH_REF, GSN_PREP_DROP_TAB_REQ, signal,
268 PrepDropTabReq::SignalLength, JBB);
269 }
270
271 if(signal->theData[0] == 1225){
272 const Uint32 tab = signal->theData[1];
273 const Uint32 ver = signal->theData[2];
274 TableRecordPtr tabRecPtr;
275 c_tableRecordPool.getPtr(tabRecPtr, tab);
276 DropTableReq * req = (DropTableReq*)signal->getDataPtr();
277 req->senderData = 1225;
278 req->senderRef = numberToRef(1,1);
279 req->tableId = tab;
280 req->tableVersion = tabRecPtr.p->tableVersion + ver;
281 sendSignal(DBDICT_REF, GSN_DROP_TABLE_REQ, signal,
282 DropTableReq::SignalLength, JBB);
283 }
284 #endif
285 #define MEMINFO(x, y) infoEvent(x ": %d %d", y.getSize(), y.getNoOfFree())
286 if(signal->theData[0] == 1226){
287 MEMINFO("c_obj_pool", c_obj_pool);
288 MEMINFO("c_opRecordPool", c_opRecordPool);
289 MEMINFO("c_rope_pool", c_rope_pool);
290 }
291
292 if (signal->theData[0] == 1227)
293 {
294 DLHashTable<DictObject>::Iterator iter;
295 bool ok = c_obj_hash.first(iter);
296 for(; ok; ok = c_obj_hash.next(iter))
297 {
298 Rope name(c_rope_pool, iter.curr.p->m_name);
299 char buf[1024];
300 name.copy(buf);
301 ndbout_c("%s m_ref_count: %d", buf, iter.curr.p->m_ref_count);
302 }
303 }
304
305 return;
306 }//Dbdict::execDUMP_STATE_ORD()
307
308 /* ---------------------------------------------------------------- */
309 /* ---------------------------------------------------------------- */
310 // CONTINUEB is used when a real-time break is needed for long
311 // processes.
312 /* ---------------------------------------------------------------- */
313 /* ---------------------------------------------------------------- */
execCONTINUEB(Signal * signal)314 void Dbdict::execCONTINUEB(Signal* signal)
315 {
316 jamEntry();
317 switch (signal->theData[0]) {
318 case ZPACK_TABLE_INTO_PAGES :
319 jam();
320 packTableIntoPages(signal);
321 break;
322
323 case ZSEND_GET_TAB_RESPONSE :
324 jam();
325 sendGetTabResponse(signal);
326 break;
327
328 case ZDICT_LOCK_POLL:
329 jam();
330 checkDictLockQueue(signal, true);
331 break;
332
333 default :
334 ndbrequire(false);
335 break;
336 }//switch
337 return;
338 }//execCONTINUEB()
339
340 /* ---------------------------------------------------------------- */
341 /* ---------------------------------------------------------------- */
342 // Routine to handle pack table into pages.
343 /* ---------------------------------------------------------------- */
344 /* ---------------------------------------------------------------- */
345
packTableIntoPages(Signal * signal)346 void Dbdict::packTableIntoPages(Signal* signal)
347 {
348 const Uint32 tableId= signal->theData[1];
349 const Uint32 type= signal->theData[2];
350 const Uint32 pageId= signal->theData[3];
351
352 PageRecordPtr pagePtr;
353 c_pageRecordArray.getPtr(pagePtr, pageId);
354
355 memset(&pagePtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
356 LinearWriter w(&pagePtr.p->word[ZPAGE_HEADER_SIZE],
357 ZMAX_PAGES_OF_TABLE_DEFINITION * ZSIZE_OF_PAGES_IN_WORDS);
358 w.first();
359 switch((DictTabInfo::TableType)type) {
360 case DictTabInfo::SystemTable:
361 case DictTabInfo::UserTable:
362 case DictTabInfo::UniqueHashIndex:
363 case DictTabInfo::HashIndex:
364 case DictTabInfo::UniqueOrderedIndex:
365 case DictTabInfo::OrderedIndex:{
366 jam();
367 TableRecordPtr tablePtr;
368 c_tableRecordPool.getPtr(tablePtr, tableId);
369 packTableIntoPages(w, tablePtr, signal);
370 break;
371 }
372 case DictTabInfo::Tablespace:
373 case DictTabInfo::LogfileGroup:{
374 FilegroupPtr fg_ptr;
375 ndbrequire(c_filegroup_hash.find(fg_ptr, tableId));
376 const Uint32 free_hi= signal->theData[4];
377 const Uint32 free_lo= signal->theData[5];
378 packFilegroupIntoPages(w, fg_ptr, free_hi, free_lo);
379 break;
380 }
381 case DictTabInfo::Datafile:{
382 FilePtr fg_ptr;
383 ndbrequire(c_file_hash.find(fg_ptr, tableId));
384 const Uint32 free_extents= signal->theData[4];
385 packFileIntoPages(w, fg_ptr, free_extents);
386 break;
387 }
388 case DictTabInfo::Undofile:{
389 FilePtr fg_ptr;
390 ndbrequire(c_file_hash.find(fg_ptr, tableId));
391 packFileIntoPages(w, fg_ptr, 0);
392 break;
393 }
394 case DictTabInfo::UndefTableType:
395 case DictTabInfo::HashIndexTrigger:
396 case DictTabInfo::SubscriptionTrigger:
397 case DictTabInfo::ReadOnlyConstraint:
398 case DictTabInfo::IndexTrigger:
399 ndbrequire(false);
400 }
401
402 Uint32 wordsOfTable = w.getWordsUsed();
403 Uint32 pagesUsed = WORDS2PAGES(wordsOfTable);
404 pagePtr.p->word[ZPOS_CHECKSUM] =
405 computeChecksum(&pagePtr.p->word[0], pagesUsed * ZSIZE_OF_PAGES_IN_WORDS);
406
407 switch (c_packTable.m_state) {
408 case PackTable::PTS_IDLE:
409 ndbrequire(false);
410 break;
411 case PackTable::PTS_GET_TAB:
412 jam();
413 c_retrieveRecord.retrievedNoOfPages = pagesUsed;
414 c_retrieveRecord.retrievedNoOfWords = wordsOfTable;
415 sendGetTabResponse(signal);
416 return;
417 break;
418 }//switch
419 ndbrequire(false);
420 return;
421 }//packTableIntoPages()
422
423 void
packTableIntoPages(SimpleProperties::Writer & w,TableRecordPtr tablePtr,Signal * signal)424 Dbdict::packTableIntoPages(SimpleProperties::Writer & w,
425 TableRecordPtr tablePtr,
426 Signal* signal){
427
428 union {
429 char tableName[MAX_TAB_NAME_SIZE];
430 char frmData[MAX_FRM_DATA_SIZE];
431 char rangeData[16*MAX_NDB_PARTITIONS];
432 char ngData[2*MAX_NDB_PARTITIONS];
433 char tsData[2*2*MAX_NDB_PARTITIONS];
434 char defaultValue[MAX_ATTR_DEFAULT_VALUE_SIZE];
435 char attributeName[MAX_ATTR_NAME_SIZE];
436 };
437 ConstRope r(c_rope_pool, tablePtr.p->tableName);
438 r.copy(tableName);
439 w.add(DictTabInfo::TableName, tableName);
440 w.add(DictTabInfo::TableId, tablePtr.i);
441 w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion);
442 w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey);
443 w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes);
444 w.add(DictTabInfo::NoOfNullable, tablePtr.p->noOfNullAttr);
445 w.add(DictTabInfo::NoOfVariable, (Uint32)0);
446 w.add(DictTabInfo::KeyLength, tablePtr.p->tupKeyLength);
447
448 w.add(DictTabInfo::TableLoggedFlag,
449 !!(tablePtr.p->m_bits & TableRecord::TR_Logged));
450 w.add(DictTabInfo::RowGCIFlag,
451 !!(tablePtr.p->m_bits & TableRecord::TR_RowGCI));
452 w.add(DictTabInfo::RowChecksumFlag,
453 !!(tablePtr.p->m_bits & TableRecord::TR_RowChecksum));
454 w.add(DictTabInfo::TableTemporaryFlag,
455 !!(tablePtr.p->m_bits & TableRecord::TR_Temporary));
456 w.add(DictTabInfo::ForceVarPartFlag,
457 !!(tablePtr.p->m_bits & TableRecord::TR_ForceVarPart));
458
459 w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor);
460 w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor);
461 w.add(DictTabInfo::TableKValue, tablePtr.p->kValue);
462 w.add(DictTabInfo::FragmentTypeVal, tablePtr.p->fragmentType);
463 w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType);
464 w.add(DictTabInfo::MaxRowsLow, tablePtr.p->maxRowsLow);
465 w.add(DictTabInfo::MaxRowsHigh, tablePtr.p->maxRowsHigh);
466 w.add(DictTabInfo::DefaultNoPartFlag, tablePtr.p->defaultNoPartFlag);
467 w.add(DictTabInfo::LinearHashFlag, tablePtr.p->linearHashFlag);
468 w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount);
469 w.add(DictTabInfo::MinRowsLow, tablePtr.p->minRowsLow);
470 w.add(DictTabInfo::MinRowsHigh, tablePtr.p->minRowsHigh);
471 w.add(DictTabInfo::SingleUserMode, tablePtr.p->singleUserMode);
472
473 if(signal)
474 {
475 /* Denna branch k�rs vid GET_TABINFOREQ */
476
477 Uint32 * theData = signal->getDataPtrSend();
478 CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
479 req->senderRef = 0;
480 req->senderData = RNIL;
481 req->fragmentationType = tablePtr.p->fragmentType;
482 req->noOfFragments = 0;
483 req->primaryTableId = tablePtr.i;
484 EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
485 CreateFragmentationReq::SignalLength);
486 ndbrequire(signal->theData[0] == 0);
487 Uint16 *data = (Uint16*)&signal->theData[25];
488 Uint32 count = 2 + (1 + data[0]) * data[1];
489 w.add(DictTabInfo::ReplicaDataLen, 2*count);
490 for (Uint32 i = 0; i < count; i++)
491 data[i] = htons(data[i]);
492 w.add(DictTabInfo::ReplicaData, data, 2*count);
493 }
494 else
495 {
496 /* Denna del k�rs vid CREATE_TABLEREQ, ALTER_TABLEREQ */
497 ;
498 }
499
500 if (tablePtr.p->primaryTableId != RNIL){
501 TableRecordPtr primTab;
502 c_tableRecordPool.getPtr(primTab, tablePtr.p->primaryTableId);
503 ConstRope r2(c_rope_pool, primTab.p->tableName);
504 r2.copy(tableName);
505 w.add(DictTabInfo::PrimaryTable, tableName);
506 w.add(DictTabInfo::PrimaryTableId, tablePtr.p->primaryTableId);
507 w.add(DictTabInfo::IndexState, tablePtr.p->indexState);
508 w.add(DictTabInfo::InsertTriggerId, tablePtr.p->insertTriggerId);
509 w.add(DictTabInfo::UpdateTriggerId, tablePtr.p->updateTriggerId);
510 w.add(DictTabInfo::DeleteTriggerId, tablePtr.p->deleteTriggerId);
511 w.add(DictTabInfo::CustomTriggerId, tablePtr.p->customTriggerId);
512 }
513
514 ConstRope frm(c_rope_pool, tablePtr.p->frmData);
515 frm.copy(frmData);
516 w.add(DictTabInfo::FrmLen, frm.size());
517 w.add(DictTabInfo::FrmData, frmData, frm.size());
518
519 {
520 jam();
521 ConstRope ts(c_rope_pool, tablePtr.p->tsData);
522 ts.copy(tsData);
523 w.add(DictTabInfo::TablespaceDataLen, ts.size());
524 w.add(DictTabInfo::TablespaceData, tsData, ts.size());
525
526 ConstRope ng(c_rope_pool, tablePtr.p->ngData);
527 ng.copy(ngData);
528 w.add(DictTabInfo::FragmentDataLen, ng.size());
529 w.add(DictTabInfo::FragmentData, ngData, ng.size());
530
531 ConstRope range(c_rope_pool, tablePtr.p->rangeData);
532 range.copy(rangeData);
533 w.add(DictTabInfo::RangeListDataLen, range.size());
534 w.add(DictTabInfo::RangeListData, rangeData, range.size());
535 }
536
537 if(tablePtr.p->m_tablespace_id != RNIL)
538 {
539 w.add(DictTabInfo::TablespaceId, tablePtr.p->m_tablespace_id);
540 FilegroupPtr tsPtr;
541 ndbrequire(c_filegroup_hash.find(tsPtr, tablePtr.p->m_tablespace_id));
542 w.add(DictTabInfo::TablespaceVersion, tsPtr.p->m_version);
543 }
544
545 AttributeRecordPtr attrPtr;
546 LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
547 tablePtr.p->m_attributes);
548 for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)){
549 jam();
550
551 ConstRope name(c_rope_pool, attrPtr.p->attributeName);
552 name.copy(attributeName);
553
554 w.add(DictTabInfo::AttributeName, attributeName);
555 w.add(DictTabInfo::AttributeId, attrPtr.p->attributeId);
556 w.add(DictTabInfo::AttributeKeyFlag, attrPtr.p->tupleKey > 0);
557
558 const Uint32 desc = attrPtr.p->attributeDescriptor;
559 const Uint32 attrType = AttributeDescriptor::getType(desc);
560 const Uint32 attrSize = AttributeDescriptor::getSize(desc);
561 const Uint32 arraySize = AttributeDescriptor::getArraySize(desc);
562 const Uint32 arrayType = AttributeDescriptor::getArrayType(desc);
563 const Uint32 nullable = AttributeDescriptor::getNullable(desc);
564 const Uint32 DKey = AttributeDescriptor::getDKey(desc);
565 const Uint32 disk= AttributeDescriptor::getDiskBased(desc);
566
567
568 // AttributeType deprecated
569 w.add(DictTabInfo::AttributeSize, attrSize);
570 w.add(DictTabInfo::AttributeArraySize, arraySize);
571 w.add(DictTabInfo::AttributeArrayType, arrayType);
572 w.add(DictTabInfo::AttributeNullableFlag, nullable);
573 w.add(DictTabInfo::AttributeDKey, DKey);
574 w.add(DictTabInfo::AttributeExtType, attrType);
575 w.add(DictTabInfo::AttributeExtPrecision, attrPtr.p->extPrecision);
576 w.add(DictTabInfo::AttributeExtScale, attrPtr.p->extScale);
577 w.add(DictTabInfo::AttributeExtLength, attrPtr.p->extLength);
578 w.add(DictTabInfo::AttributeAutoIncrement,
579 (Uint32)attrPtr.p->autoIncrement);
580
581 if(disk)
582 w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_DISK);
583 else
584 w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_MEMORY);
585
586 ConstRope def(c_rope_pool, attrPtr.p->defaultValue);
587 def.copy(defaultValue);
588 w.add(DictTabInfo::AttributeDefaultValue, defaultValue);
589
590 w.add(DictTabInfo::AttributeEnd, 1);
591 }
592
593 w.add(DictTabInfo::TableEnd, 1);
594 }
595
596 void
packFilegroupIntoPages(SimpleProperties::Writer & w,FilegroupPtr fg_ptr,const Uint32 undo_free_hi,const Uint32 undo_free_lo)597 Dbdict::packFilegroupIntoPages(SimpleProperties::Writer & w,
598 FilegroupPtr fg_ptr,
599 const Uint32 undo_free_hi,
600 const Uint32 undo_free_lo){
601
602 DictFilegroupInfo::Filegroup fg; fg.init();
603 ConstRope r(c_rope_pool, fg_ptr.p->m_name);
604 r.copy(fg.FilegroupName);
605
606 fg.FilegroupId = fg_ptr.p->key;
607 fg.FilegroupType = fg_ptr.p->m_type;
608 fg.FilegroupVersion = fg_ptr.p->m_version;
609
610 switch(fg.FilegroupType){
611 case DictTabInfo::Tablespace:
612 //fg.TS_DataGrow = group.m_grow_spec;
613 fg.TS_ExtentSize = fg_ptr.p->m_tablespace.m_extent_size;
614 fg.TS_LogfileGroupId = fg_ptr.p->m_tablespace.m_default_logfile_group_id;
615 FilegroupPtr lfg_ptr;
616 ndbrequire(c_filegroup_hash.find(lfg_ptr, fg.TS_LogfileGroupId));
617 fg.TS_LogfileGroupVersion = lfg_ptr.p->m_version;
618 break;
619 case DictTabInfo::LogfileGroup:
620 fg.LF_UndoBufferSize = fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
621 fg.LF_UndoFreeWordsHi= undo_free_hi;
622 fg.LF_UndoFreeWordsLo= undo_free_lo;
623 //fg.LF_UndoGrow = ;
624 break;
625 default:
626 ndbrequire(false);
627 }
628
629 SimpleProperties::UnpackStatus s;
630 s = SimpleProperties::pack(w,
631 &fg,
632 DictFilegroupInfo::Mapping,
633 DictFilegroupInfo::MappingSize, true);
634
635 ndbrequire(s == SimpleProperties::Eof);
636 }
637
638 void
packFileIntoPages(SimpleProperties::Writer & w,FilePtr f_ptr,const Uint32 free_extents)639 Dbdict::packFileIntoPages(SimpleProperties::Writer & w,
640 FilePtr f_ptr, const Uint32 free_extents){
641
642 DictFilegroupInfo::File f; f.init();
643 ConstRope r(c_rope_pool, f_ptr.p->m_path);
644 r.copy(f.FileName);
645
646 f.FileType = f_ptr.p->m_type;
647 f.FilegroupId = f_ptr.p->m_filegroup_id;; //group.m_id;
648 f.FileSizeHi = (f_ptr.p->m_file_size >> 32);
649 f.FileSizeLo = (f_ptr.p->m_file_size & 0xFFFFFFFF);
650 f.FileFreeExtents= free_extents;
651 f.FileId = f_ptr.p->key;
652 f.FileVersion = f_ptr.p->m_version;
653
654 FilegroupPtr lfg_ptr;
655 ndbrequire(c_filegroup_hash.find(lfg_ptr, f.FilegroupId));
656 f.FilegroupVersion = lfg_ptr.p->m_version;
657
658 SimpleProperties::UnpackStatus s;
659 s = SimpleProperties::pack(w,
660 &f,
661 DictFilegroupInfo::FileMapping,
662 DictFilegroupInfo::FileMappingSize, true);
663
664 ndbrequire(s == SimpleProperties::Eof);
665 }
666
667 /* ---------------------------------------------------------------- */
668 /* ---------------------------------------------------------------- */
669 // The routines to handle responses from file system.
670 /* ---------------------------------------------------------------- */
671 /* ---------------------------------------------------------------- */
672
673 /* ---------------------------------------------------------------- */
674 // A file was successfully closed.
675 /* ---------------------------------------------------------------- */
execFSCLOSECONF(Signal * signal)676 void Dbdict::execFSCLOSECONF(Signal* signal)
677 {
678 FsConnectRecordPtr fsPtr;
679 FsConf * const fsConf = (FsConf *)&signal->theData[0];
680 jamEntry();
681 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
682 switch (fsPtr.p->fsState) {
683 case FsConnectRecord::CLOSE_WRITE_SCHEMA:
684 jam();
685 closeWriteSchemaConf(signal, fsPtr);
686 break;
687 case FsConnectRecord::CLOSE_READ_SCHEMA:
688 jam();
689 closeReadSchemaConf(signal, fsPtr);
690 break;
691 case FsConnectRecord::CLOSE_READ_TAB_FILE:
692 jam();
693 closeReadTableConf(signal, fsPtr);
694 break;
695 case FsConnectRecord::CLOSE_WRITE_TAB_FILE:
696 jam();
697 closeWriteTableConf(signal, fsPtr);
698 break;
699 case FsConnectRecord::OPEN_READ_SCHEMA2:
700 openSchemaFile(signal, 1, fsPtr.i, false, false);
701 break;
702 case FsConnectRecord::OPEN_READ_TAB_FILE2:
703 openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
704 break;
705 default:
706 jamLine((fsPtr.p->fsState & 0xFFF));
707 ndbrequire(false);
708 break;
709 }//switch
710 }//execFSCLOSECONF()
711
712
713 /* ---------------------------------------------------------------- */
714 // A file was successfully opened.
715 /* ---------------------------------------------------------------- */
execFSOPENCONF(Signal * signal)716 void Dbdict::execFSOPENCONF(Signal* signal)
717 {
718 FsConnectRecordPtr fsPtr;
719 jamEntry();
720 FsConf * const fsConf = (FsConf *)&signal->theData[0];
721 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
722
723 Uint32 filePointer = fsConf->filePointer;
724 fsPtr.p->filePtr = filePointer;
725 switch (fsPtr.p->fsState) {
726 case FsConnectRecord::OPEN_WRITE_SCHEMA:
727 jam();
728 fsPtr.p->fsState = FsConnectRecord::WRITE_SCHEMA;
729 writeSchemaFile(signal, filePointer, fsPtr.i);
730 break;
731 case FsConnectRecord::OPEN_READ_SCHEMA1:
732 jam();
733 fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA1;
734 readSchemaFile(signal, filePointer, fsPtr.i);
735 break;
736 case FsConnectRecord::OPEN_READ_SCHEMA2:
737 jam();
738 fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA2;
739 readSchemaFile(signal, filePointer, fsPtr.i);
740 break;
741 case FsConnectRecord::OPEN_READ_TAB_FILE1:
742 jam();
743 fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE1;
744 readTableFile(signal, filePointer, fsPtr.i);
745 break;
746 case FsConnectRecord::OPEN_READ_TAB_FILE2:
747 jam();
748 fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE2;
749 readTableFile(signal, filePointer, fsPtr.i);
750 break;
751 case FsConnectRecord::OPEN_WRITE_TAB_FILE:
752 jam();
753 fsPtr.p->fsState = FsConnectRecord::WRITE_TAB_FILE;
754 writeTableFile(signal, filePointer, fsPtr.i);
755 break;
756 default:
757 jamLine((fsPtr.p->fsState & 0xFFF));
758 ndbrequire(false);
759 break;
760 }//switch
761 }//execFSOPENCONF()
762
763 /* ---------------------------------------------------------------- */
764 // An open file was refused.
765 /* ---------------------------------------------------------------- */
execFSOPENREF(Signal * signal)766 void Dbdict::execFSOPENREF(Signal* signal)
767 {
768 jamEntry();
769 FsRef * const fsRef = (FsRef *)&signal->theData[0];
770 FsConnectRecordPtr fsPtr;
771 c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
772 switch (fsPtr.p->fsState) {
773 case FsConnectRecord::OPEN_READ_SCHEMA1:
774 jam();
775 openReadSchemaRef(signal, fsPtr);
776 return;
777 case FsConnectRecord::OPEN_READ_TAB_FILE1:
778 jam();
779 openReadTableRef(signal, fsPtr);
780 return;
781 default:
782 break;
783 }//switch
784 {
785 char msg[100];
786 sprintf(msg, "File system open failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
787 fsRefError(signal,__LINE__,msg);
788 }
789 }//execFSOPENREF()
790
791 /* ---------------------------------------------------------------- */
792 // A file was successfully read.
793 /* ---------------------------------------------------------------- */
execFSREADCONF(Signal * signal)794 void Dbdict::execFSREADCONF(Signal* signal)
795 {
796 jamEntry();
797 FsConf * const fsConf = (FsConf *)&signal->theData[0];
798 FsConnectRecordPtr fsPtr;
799 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
800 switch (fsPtr.p->fsState) {
801 case FsConnectRecord::READ_SCHEMA1:
802 case FsConnectRecord::READ_SCHEMA2:
803 readSchemaConf(signal ,fsPtr);
804 break;
805 case FsConnectRecord::READ_TAB_FILE1:
806 if(ERROR_INSERTED(6007)){
807 jam();
808 FsRef * const fsRef = (FsRef *)&signal->theData[0];
809 fsRef->userPointer = fsConf->userPointer;
810 fsRef->setErrorCode(fsRef->errorCode, NDBD_EXIT_AFS_UNKNOWN);
811 fsRef->osErrorCode = ~0; // Indicate local error
812 execFSREADREF(signal);
813 return;
814 }//Testing how DICT behave if read of file 1 fails (Bug#28770)
815 case FsConnectRecord::READ_TAB_FILE2:
816 jam();
817 readTableConf(signal ,fsPtr);
818 break;
819 default:
820 jamLine((fsPtr.p->fsState & 0xFFF));
821 ndbrequire(false);
822 break;
823 }//switch
824 }//execFSREADCONF()
825
826 /* ---------------------------------------------------------------- */
827 // A read file was refused.
828 /* ---------------------------------------------------------------- */
execFSREADREF(Signal * signal)829 void Dbdict::execFSREADREF(Signal* signal)
830 {
831 jamEntry();
832 FsRef * const fsRef = (FsRef *)&signal->theData[0];
833 FsConnectRecordPtr fsPtr;
834 c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
835 switch (fsPtr.p->fsState) {
836 case FsConnectRecord::READ_SCHEMA1:
837 jam();
838 readSchemaRef(signal, fsPtr);
839 return;
840 case FsConnectRecord::READ_TAB_FILE1:
841 jam();
842 readTableRef(signal, fsPtr);
843 return;
844 default:
845 break;
846 }//switch
847 {
848 char msg[100];
849 sprintf(msg, "File system read failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
850 fsRefError(signal,__LINE__,msg);
851 }
852 }//execFSREADREF()
853
854 /* ---------------------------------------------------------------- */
855 // A file was successfully written.
856 /* ---------------------------------------------------------------- */
execFSWRITECONF(Signal * signal)857 void Dbdict::execFSWRITECONF(Signal* signal)
858 {
859 FsConf * const fsConf = (FsConf *)&signal->theData[0];
860 FsConnectRecordPtr fsPtr;
861 jamEntry();
862 c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
863 switch (fsPtr.p->fsState) {
864 case FsConnectRecord::WRITE_TAB_FILE:
865 writeTableConf(signal, fsPtr);
866 break;
867 case FsConnectRecord::WRITE_SCHEMA:
868 jam();
869 writeSchemaConf(signal, fsPtr);
870 break;
871 default:
872 jamLine((fsPtr.p->fsState & 0xFFF));
873 ndbrequire(false);
874 break;
875 }//switch
876 }//execFSWRITECONF()
877
878
879 /* ---------------------------------------------------------------- */
880 // Routines to handle Read/Write of Table Files
881 /* ---------------------------------------------------------------- */
882 void
writeTableFile(Signal * signal,Uint32 tableId,SegmentedSectionPtr tabInfoPtr,Callback * callback)883 Dbdict::writeTableFile(Signal* signal, Uint32 tableId,
884 SegmentedSectionPtr tabInfoPtr, Callback* callback){
885
886 ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
887
888 Uint32 pages = WORDS2PAGES(tabInfoPtr.sz);
889 c_writeTableRecord.no_of_words = tabInfoPtr.sz;
890 c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
891 c_writeTableRecord.m_callback = * callback;
892
893 c_writeTableRecord.pageId = 0;
894 ndbrequire(pages == 1);
895
896 PageRecordPtr pageRecPtr;
897 c_pageRecordArray.getPtr(pageRecPtr, c_writeTableRecord.pageId);
898 copy(&pageRecPtr.p->word[ZPAGE_HEADER_SIZE], tabInfoPtr);
899
900 memset(&pageRecPtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
901 pageRecPtr.p->word[ZPOS_CHECKSUM] =
902 computeChecksum(&pageRecPtr.p->word[0],
903 pages * ZSIZE_OF_PAGES_IN_WORDS);
904
905 startWriteTableFile(signal, tableId);
906 }
907
startWriteTableFile(Signal * signal,Uint32 tableId)908 void Dbdict::startWriteTableFile(Signal* signal, Uint32 tableId)
909 {
910 FsConnectRecordPtr fsPtr;
911 c_writeTableRecord.tableId = tableId;
912 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
913 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
914 openTableFile(signal, 0, fsPtr.i, tableId, true);
915 c_writeTableRecord.noOfTableFilesHandled = 0;
916 }//Dbdict::startWriteTableFile()
917
openTableFile(Signal * signal,Uint32 fileNo,Uint32 fsConPtr,Uint32 tableId,bool writeFlag)918 void Dbdict::openTableFile(Signal* signal,
919 Uint32 fileNo,
920 Uint32 fsConPtr,
921 Uint32 tableId,
922 bool writeFlag)
923 {
924 FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
925
926 fsOpenReq->userReference = reference();
927 fsOpenReq->userPointer = fsConPtr;
928 if (writeFlag) {
929 jam();
930 fsOpenReq->fileFlags =
931 FsOpenReq::OM_WRITEONLY |
932 FsOpenReq::OM_TRUNCATE |
933 FsOpenReq::OM_CREATE |
934 FsOpenReq::OM_SYNC;
935 } else {
936 jam();
937 fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
938 }//if
939 fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
940 FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
941 FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_TABLELIST);
942 FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
943 FsOpenReq::v1_setTable(fsOpenReq->fileNumber, tableId);
944 FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
945 FsOpenReq::v1_setS(fsOpenReq->fileNumber, 0);
946 FsOpenReq::v1_setP(fsOpenReq->fileNumber, 255);
947 /* ---------------------------------------------------------------- */
948 // File name : D1/DBDICT/T0/S1.TableList
949 // D1 means Disk 1 (set by fileNo + 1)
950 // T0 means table id = 0
951 // S1 means tableVersion 1
952 // TableList indicates that this is a file for a table description.
953 /* ---------------------------------------------------------------- */
954 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
955 }//openTableFile()
956
writeTableFile(Signal * signal,Uint32 filePtr,Uint32 fsConPtr)957 void Dbdict::writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
958 {
959 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
960
961 fsRWReq->filePointer = filePtr;
962 fsRWReq->userReference = reference();
963 fsRWReq->userPointer = fsConPtr;
964 fsRWReq->operationFlag = 0; // Initialise before bit changes
965 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
966 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
967 FsReadWriteReq::fsFormatArrayOfPages);
968 fsRWReq->varIndex = ZBAT_TABLE_FILE;
969 fsRWReq->numberOfPages = WORDS2PAGES(c_writeTableRecord.no_of_words);
970 fsRWReq->data.arrayOfPages.varIndex = c_writeTableRecord.pageId;
971 fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
972 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
973 }//writeTableFile()
974
writeTableConf(Signal * signal,FsConnectRecordPtr fsPtr)975 void Dbdict::writeTableConf(Signal* signal,
976 FsConnectRecordPtr fsPtr)
977 {
978 fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_TAB_FILE;
979 closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
980 return;
981 }//Dbdict::writeTableConf()
982
closeWriteTableConf(Signal * signal,FsConnectRecordPtr fsPtr)983 void Dbdict::closeWriteTableConf(Signal* signal,
984 FsConnectRecordPtr fsPtr)
985 {
986 c_writeTableRecord.noOfTableFilesHandled++;
987 if (c_writeTableRecord.noOfTableFilesHandled < 2) {
988 jam();
989 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
990 openTableFile(signal, 1, fsPtr.i, c_writeTableRecord.tableId, true);
991 return;
992 }
993 ndbrequire(c_writeTableRecord.noOfTableFilesHandled == 2);
994 c_fsConnectRecordPool.release(fsPtr);
995 WriteTableRecord::TableWriteState state = c_writeTableRecord.tableWriteState;
996 c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
997 switch (state) {
998 case WriteTableRecord::IDLE:
999 case WriteTableRecord::WRITE_ADD_TABLE_MASTER :
1000 case WriteTableRecord::WRITE_ADD_TABLE_SLAVE :
1001 case WriteTableRecord::WRITE_RESTART_FROM_MASTER :
1002 case WriteTableRecord::WRITE_RESTART_FROM_OWN :
1003 ndbrequire(false);
1004 break;
1005 case WriteTableRecord::TWR_CALLBACK:
1006 jam();
1007 execute(signal, c_writeTableRecord.m_callback, 0);
1008 return;
1009 }
1010 ndbrequire(false);
1011 }//Dbdict::closeWriteTableConf()
1012
startReadTableFile(Signal * signal,Uint32 tableId)1013 void Dbdict::startReadTableFile(Signal* signal, Uint32 tableId)
1014 {
1015 //globalSignalLoggers.log(number(), "startReadTableFile");
1016 ndbrequire(!c_readTableRecord.inUse);
1017
1018 FsConnectRecordPtr fsPtr;
1019 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
1020 c_readTableRecord.inUse = true;
1021 c_readTableRecord.tableId = tableId;
1022 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE1;
1023 openTableFile(signal, 0, fsPtr.i, tableId, false);
1024 }//Dbdict::startReadTableFile()
1025
openReadTableRef(Signal * signal,FsConnectRecordPtr fsPtr)1026 void Dbdict::openReadTableRef(Signal* signal,
1027 FsConnectRecordPtr fsPtr)
1028 {
1029 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
1030 openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
1031 return;
1032 }//Dbdict::openReadTableConf()
1033
readTableFile(Signal * signal,Uint32 filePtr,Uint32 fsConPtr)1034 void Dbdict::readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
1035 {
1036 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
1037
1038 fsRWReq->filePointer = filePtr;
1039 fsRWReq->userReference = reference();
1040 fsRWReq->userPointer = fsConPtr;
1041 fsRWReq->operationFlag = 0; // Initialise before bit changes
1042 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
1043 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
1044 FsReadWriteReq::fsFormatArrayOfPages);
1045 fsRWReq->varIndex = ZBAT_TABLE_FILE;
1046 fsRWReq->numberOfPages = WORDS2PAGES(c_readTableRecord.no_of_words);
1047 fsRWReq->data.arrayOfPages.varIndex = c_readTableRecord.pageId;
1048 fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
1049 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
1050 }//readTableFile()
1051
readTableConf(Signal * signal,FsConnectRecordPtr fsPtr)1052 void Dbdict::readTableConf(Signal* signal,
1053 FsConnectRecordPtr fsPtr)
1054 {
1055 /* ---------------------------------------------------------------- */
1056 // Verify the data read from disk
1057 /* ---------------------------------------------------------------- */
1058 bool crashInd;
1059 if (fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1) {
1060 jam();
1061 crashInd = false;
1062 } else {
1063 jam();
1064 crashInd = true;
1065 }//if
1066
1067 PageRecordPtr tmpPagePtr;
1068 c_pageRecordArray.getPtr(tmpPagePtr, c_readTableRecord.pageId);
1069 Uint32 sz =
1070 WORDS2PAGES(c_readTableRecord.no_of_words)*ZSIZE_OF_PAGES_IN_WORDS;
1071 Uint32 chk = computeChecksum((const Uint32*)tmpPagePtr.p, sz);
1072
1073 ndbrequire((chk == 0) || !crashInd);
1074 if(chk != 0){
1075 jam();
1076 ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1);
1077 readTableRef(signal, fsPtr);
1078 return;
1079 }//if
1080
1081 fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_TAB_FILE;
1082 closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
1083 return;
1084 }//Dbdict::readTableConf()
1085
readTableRef(Signal * signal,FsConnectRecordPtr fsPtr)1086 void Dbdict::readTableRef(Signal* signal,
1087 FsConnectRecordPtr fsPtr)
1088 {
1089 /**
1090 * First close corrupt file
1091 */
1092 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
1093 closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
1094 return;
1095 }//Dbdict::readTableRef()
1096
closeReadTableConf(Signal * signal,FsConnectRecordPtr fsPtr)1097 void Dbdict::closeReadTableConf(Signal* signal,
1098 FsConnectRecordPtr fsPtr)
1099 {
1100 c_fsConnectRecordPool.release(fsPtr);
1101 c_readTableRecord.inUse = false;
1102
1103 execute(signal, c_readTableRecord.m_callback, 0);
1104 return;
1105 }//Dbdict::closeReadTableConf()
1106
1107 /* ---------------------------------------------------------------- */
1108 // Routines to handle Read/Write of Schema Files
1109 /* ---------------------------------------------------------------- */
1110 void
updateSchemaState(Signal * signal,Uint32 tableId,SchemaFile::TableEntry * te,Callback * callback,bool savetodisk)1111 Dbdict::updateSchemaState(Signal* signal, Uint32 tableId,
1112 SchemaFile::TableEntry* te, Callback* callback,
1113 bool savetodisk){
1114 jam();
1115 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
1116 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
1117
1118 SchemaFile::TableState newState =
1119 (SchemaFile::TableState)te->m_tableState;
1120 SchemaFile::TableState oldState =
1121 (SchemaFile::TableState)tableEntry->m_tableState;
1122
1123 Uint32 newVersion = te->m_tableVersion;
1124 Uint32 oldVersion = tableEntry->m_tableVersion;
1125
1126 bool ok = false;
1127 switch(newState){
1128 case SchemaFile::ADD_STARTED:
1129 jam();
1130 ok = true;
1131 ndbrequire(create_obj_inc_schema_version(oldVersion) == newVersion);
1132 ndbrequire(oldState == SchemaFile::INIT ||
1133 oldState == SchemaFile::DROP_TABLE_COMMITTED);
1134 break;
1135 case SchemaFile::TABLE_ADD_COMMITTED:
1136 jam();
1137 ok = true;
1138 ndbrequire(newVersion == oldVersion);
1139 ndbrequire(oldState == SchemaFile::ADD_STARTED ||
1140 oldState == SchemaFile::DROP_TABLE_STARTED);
1141 break;
1142 case SchemaFile::ALTER_TABLE_COMMITTED:
1143 jam();
1144 ok = true;
1145 ndbrequire(alter_obj_inc_schema_version(oldVersion) == newVersion);
1146 ndbrequire(oldState == SchemaFile::TABLE_ADD_COMMITTED ||
1147 oldState == SchemaFile::ALTER_TABLE_COMMITTED);
1148 break;
1149 case SchemaFile::DROP_TABLE_STARTED:
1150 jam();
1151 case SchemaFile::DROP_TABLE_COMMITTED:
1152 jam();
1153 ok = true;
1154 break;
1155 case SchemaFile::TEMPORARY_TABLE_COMMITTED:
1156 jam();
1157 ndbrequire(oldState == SchemaFile::ADD_STARTED ||
1158 oldState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
1159 ok = true;
1160 break;
1161 case SchemaFile::INIT:
1162 jam();
1163 ok = true;
1164 ndbrequire((oldState == SchemaFile::ADD_STARTED));
1165 }//if
1166 ndbrequire(ok);
1167
1168 * tableEntry = * te;
1169 computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
1170
1171 if (savetodisk)
1172 {
1173 ndbrequire(c_writeSchemaRecord.inUse == false);
1174 c_writeSchemaRecord.inUse = true;
1175
1176 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
1177 c_writeSchemaRecord.newFile = false;
1178 c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
1179 c_writeSchemaRecord.noOfPages = 1;
1180 c_writeSchemaRecord.m_callback = * callback;
1181
1182 startWriteSchemaFile(signal);
1183 }
1184 else
1185 {
1186 execute(signal, *callback, 0);
1187 }
1188 }
1189
startWriteSchemaFile(Signal * signal)1190 void Dbdict::startWriteSchemaFile(Signal* signal)
1191 {
1192 FsConnectRecordPtr fsPtr;
1193 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
1194 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
1195 openSchemaFile(signal, 0, fsPtr.i, true, c_writeSchemaRecord.newFile);
1196 c_writeSchemaRecord.noOfSchemaFilesHandled = 0;
1197 }//Dbdict::startWriteSchemaFile()
1198
openSchemaFile(Signal * signal,Uint32 fileNo,Uint32 fsConPtr,bool writeFlag,bool newFile)1199 void Dbdict::openSchemaFile(Signal* signal,
1200 Uint32 fileNo,
1201 Uint32 fsConPtr,
1202 bool writeFlag,
1203 bool newFile)
1204 {
1205 FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
1206 fsOpenReq->userReference = reference();
1207 fsOpenReq->userPointer = fsConPtr;
1208 if (writeFlag) {
1209 jam();
1210 fsOpenReq->fileFlags =
1211 FsOpenReq::OM_WRITEONLY |
1212 FsOpenReq::OM_SYNC;
1213 if (newFile)
1214 fsOpenReq->fileFlags |=
1215 FsOpenReq::OM_TRUNCATE |
1216 FsOpenReq::OM_CREATE;
1217 } else {
1218 jam();
1219 fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
1220 }//if
1221 fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
1222 FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
1223 FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_SCHEMALOG);
1224 FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
1225 FsOpenReq::v1_setTable(fsOpenReq->fileNumber, (Uint32)-1);
1226 FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
1227 FsOpenReq::v1_setS(fsOpenReq->fileNumber, (Uint32)-1);
1228 FsOpenReq::v1_setP(fsOpenReq->fileNumber, 0);
1229 /* ---------------------------------------------------------------- */
1230 // File name : D1/DBDICT/P0.SchemaLog
1231 // D1 means Disk 1 (set by fileNo + 1). Writes to both D1 and D2
1232 // SchemaLog indicates that this is a file giving a list of current tables.
1233 /* ---------------------------------------------------------------- */
1234 sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
1235 }//openSchemaFile()
1236
writeSchemaFile(Signal * signal,Uint32 filePtr,Uint32 fsConPtr)1237 void Dbdict::writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
1238 {
1239 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
1240
1241 // check write record
1242 WriteSchemaRecord & wr = c_writeSchemaRecord;
1243 ndbrequire(wr.pageId == (wr.pageId != 0) * NDB_SF_MAX_PAGES);
1244 ndbrequire(wr.noOfPages != 0);
1245 ndbrequire(wr.firstPage + wr.noOfPages <= NDB_SF_MAX_PAGES);
1246
1247 fsRWReq->filePointer = filePtr;
1248 fsRWReq->userReference = reference();
1249 fsRWReq->userPointer = fsConPtr;
1250 fsRWReq->operationFlag = 0; // Initialise before bit changes
1251 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
1252 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
1253 FsReadWriteReq::fsFormatArrayOfPages);
1254 fsRWReq->varIndex = ZBAT_SCHEMA_FILE;
1255 fsRWReq->numberOfPages = wr.noOfPages;
1256 // Write from memory page
1257 fsRWReq->data.arrayOfPages.varIndex = wr.pageId + wr.firstPage;
1258 fsRWReq->data.arrayOfPages.fileOffset = wr.firstPage;
1259 sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
1260 }//writeSchemaFile()
1261
writeSchemaConf(Signal * signal,FsConnectRecordPtr fsPtr)1262 void Dbdict::writeSchemaConf(Signal* signal,
1263 FsConnectRecordPtr fsPtr)
1264 {
1265 fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_SCHEMA;
1266 closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
1267 return;
1268 }//Dbdict::writeSchemaConf()
1269
closeFile(Signal * signal,Uint32 filePtr,Uint32 fsConPtr)1270 void Dbdict::closeFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
1271 {
1272 FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0];
1273 fsCloseReq->filePointer = filePtr;
1274 fsCloseReq->userReference = reference();
1275 fsCloseReq->userPointer = fsConPtr;
1276 FsCloseReq::setRemoveFileFlag(fsCloseReq->fileFlag, false);
1277 sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
1278 return;
1279 }//closeFile()
1280
closeWriteSchemaConf(Signal * signal,FsConnectRecordPtr fsPtr)1281 void Dbdict::closeWriteSchemaConf(Signal* signal,
1282 FsConnectRecordPtr fsPtr)
1283 {
1284 c_writeSchemaRecord.noOfSchemaFilesHandled++;
1285 if (c_writeSchemaRecord.noOfSchemaFilesHandled < 2) {
1286 jam();
1287 fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
1288 openSchemaFile(signal, 1, fsPtr.i, true, c_writeSchemaRecord.newFile);
1289 return;
1290 }
1291 ndbrequire(c_writeSchemaRecord.noOfSchemaFilesHandled == 2);
1292
1293 c_fsConnectRecordPool.release(fsPtr);
1294
1295 c_writeSchemaRecord.inUse = false;
1296 execute(signal, c_writeSchemaRecord.m_callback, 0);
1297 return;
1298 }//Dbdict::closeWriteSchemaConf()
1299
startReadSchemaFile(Signal * signal)1300 void Dbdict::startReadSchemaFile(Signal* signal)
1301 {
1302 //globalSignalLoggers.log(number(), "startReadSchemaFile");
1303 FsConnectRecordPtr fsPtr;
1304 c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
1305 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA1;
1306 openSchemaFile(signal, 0, fsPtr.i, false, false);
1307 }//Dbdict::startReadSchemaFile()
1308
openReadSchemaRef(Signal * signal,FsConnectRecordPtr fsPtr)1309 void Dbdict::openReadSchemaRef(Signal* signal,
1310 FsConnectRecordPtr fsPtr)
1311 {
1312 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
1313 openSchemaFile(signal, 1, fsPtr.i, false, false);
1314 }//Dbdict::openReadSchemaRef()
1315
readSchemaFile(Signal * signal,Uint32 filePtr,Uint32 fsConPtr)1316 void Dbdict::readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
1317 {
1318 FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
1319
1320 // check read record
1321 ReadSchemaRecord & rr = c_readSchemaRecord;
1322 ndbrequire(rr.pageId == (rr.pageId != 0) * NDB_SF_MAX_PAGES);
1323 ndbrequire(rr.noOfPages != 0);
1324 ndbrequire(rr.firstPage + rr.noOfPages <= NDB_SF_MAX_PAGES);
1325
1326 fsRWReq->filePointer = filePtr;
1327 fsRWReq->userReference = reference();
1328 fsRWReq->userPointer = fsConPtr;
1329 fsRWReq->operationFlag = 0; // Initialise before bit changes
1330 FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
1331 FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
1332 FsReadWriteReq::fsFormatArrayOfPages);
1333 fsRWReq->varIndex = ZBAT_SCHEMA_FILE;
1334 fsRWReq->numberOfPages = rr.noOfPages;
1335 fsRWReq->data.arrayOfPages.varIndex = rr.pageId + rr.firstPage;
1336 fsRWReq->data.arrayOfPages.fileOffset = rr.firstPage;
1337 sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
1338 }//readSchemaFile()
1339
readSchemaConf(Signal * signal,FsConnectRecordPtr fsPtr)1340 void Dbdict::readSchemaConf(Signal* signal,
1341 FsConnectRecordPtr fsPtr)
1342 {
1343 /* ---------------------------------------------------------------- */
1344 // Verify the data read from disk
1345 /* ---------------------------------------------------------------- */
1346 bool crashInd;
1347 if (fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1) {
1348 jam();
1349 crashInd = false;
1350 } else {
1351 jam();
1352 crashInd = true;
1353 }//if
1354
1355 ReadSchemaRecord & rr = c_readSchemaRecord;
1356 XSchemaFile * xsf = &c_schemaFile[rr.pageId != 0];
1357
1358 if (rr.schemaReadState == ReadSchemaRecord::INITIAL_READ_HEAD) {
1359 jam();
1360 ndbrequire(rr.firstPage == 0);
1361 SchemaFile * sf = &xsf->schemaPage[0];
1362 Uint32 noOfPages;
1363 if (sf->NdbVersion < NDB_SF_VERSION_5_0_6) {
1364 jam();
1365 const Uint32 pageSize_old = 32 * 1024;
1366 noOfPages = pageSize_old / NDB_SF_PAGE_SIZE - 1;
1367 } else {
1368 noOfPages = sf->FileSize / NDB_SF_PAGE_SIZE - 1;
1369 }
1370 rr.schemaReadState = ReadSchemaRecord::INITIAL_READ;
1371 if (noOfPages != 0) {
1372 rr.firstPage = 1;
1373 rr.noOfPages = noOfPages;
1374 readSchemaFile(signal, fsPtr.p->filePtr, fsPtr.i);
1375 return;
1376 }
1377 }
1378
1379 SchemaFile * sf0 = &xsf->schemaPage[0];
1380 xsf->noOfPages = sf0->FileSize / NDB_SF_PAGE_SIZE;
1381
1382 if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6 &&
1383 ! convertSchemaFileTo_5_0_6(xsf)) {
1384 jam();
1385 ndbrequire(! crashInd);
1386 ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1);
1387 readSchemaRef(signal, fsPtr);
1388 return;
1389 }
1390
1391 for (Uint32 n = 0; n < xsf->noOfPages; n++) {
1392 SchemaFile * sf = &xsf->schemaPage[n];
1393 bool ok = false;
1394 const char *reason;
1395 if (memcmp(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic)) != 0)
1396 { jam(); reason = "magic code"; }
1397 else if (sf->FileSize == 0)
1398 { jam(); reason = "file size == 0"; }
1399 else if (sf->FileSize % NDB_SF_PAGE_SIZE != 0)
1400 { jam(); reason = "invalid size multiple"; }
1401 else if (sf->FileSize != sf0->FileSize)
1402 { jam(); reason = "invalid size"; }
1403 else if (sf->PageNumber != n)
1404 { jam(); reason = "invalid page number"; }
1405 else if (computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS) != 0)
1406 { jam(); reason = "invalid checksum"; }
1407 else
1408 ok = true;
1409
1410 if (!ok)
1411 {
1412 char reason_msg[128];
1413 snprintf(reason_msg, sizeof(reason_msg),
1414 "schema file corrupt, page %u (%s, "
1415 "sz=%u sz0=%u pn=%u)",
1416 n, reason, sf->FileSize, sf0->FileSize, sf->PageNumber);
1417 if (crashInd)
1418 progError(__LINE__, NDBD_EXIT_SR_SCHEMAFILE, reason_msg);
1419 ndbrequireErr(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1,
1420 NDBD_EXIT_SR_SCHEMAFILE);
1421 jam();
1422 infoEvent("primary %s, trying backup", reason_msg);
1423 readSchemaRef(signal, fsPtr);
1424 return;
1425 }
1426 }
1427
1428 fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_SCHEMA;
1429 closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
1430 return;
1431 }//Dbdict::readSchemaConf()
1432
readSchemaRef(Signal * signal,FsConnectRecordPtr fsPtr)1433 void Dbdict::readSchemaRef(Signal* signal,
1434 FsConnectRecordPtr fsPtr)
1435 {
1436 /**
1437 * First close corrupt file
1438 */
1439 fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
1440 closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
1441 return;
1442 }
1443
closeReadSchemaConf(Signal * signal,FsConnectRecordPtr fsPtr)1444 void Dbdict::closeReadSchemaConf(Signal* signal,
1445 FsConnectRecordPtr fsPtr)
1446 {
1447 c_fsConnectRecordPool.release(fsPtr);
1448 ReadSchemaRecord::SchemaReadState state = c_readSchemaRecord.schemaReadState;
1449 c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
1450
1451 switch(state) {
1452 case ReadSchemaRecord::INITIAL_READ :
1453 jam();
1454 {
1455 // write back both copies
1456
1457 ndbrequire(c_writeSchemaRecord.inUse == false);
1458 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0 ];
1459 Uint32 noOfPages =
1460 (c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1) /
1461 NDB_SF_PAGE_ENTRIES;
1462 resizeSchemaFile(xsf, noOfPages);
1463
1464 c_writeSchemaRecord.inUse = true;
1465 c_writeSchemaRecord.pageId = c_schemaRecord.oldSchemaPage;
1466 c_writeSchemaRecord.newFile = true;
1467 c_writeSchemaRecord.firstPage = 0;
1468 c_writeSchemaRecord.noOfPages = xsf->noOfPages;
1469
1470 c_writeSchemaRecord.m_callback.m_callbackFunction =
1471 safe_cast(&Dbdict::initSchemaFile_conf);
1472
1473 startWriteSchemaFile(signal);
1474 }
1475 break;
1476
1477 default :
1478 ndbrequire(false);
1479 break;
1480
1481 }//switch
1482 }//Dbdict::closeReadSchemaConf()
1483
1484 bool
convertSchemaFileTo_5_0_6(XSchemaFile * xsf)1485 Dbdict::convertSchemaFileTo_5_0_6(XSchemaFile * xsf)
1486 {
1487 const Uint32 pageSize_old = 32 * 1024;
1488 Uint32 page_old[pageSize_old >> 2];
1489 SchemaFile * sf_old = (SchemaFile *)page_old;
1490
1491 if (xsf->noOfPages * NDB_SF_PAGE_SIZE != pageSize_old)
1492 return false;
1493 SchemaFile * sf0 = &xsf->schemaPage[0];
1494 memcpy(sf_old, sf0, pageSize_old);
1495
1496 // init max number new pages needed
1497 xsf->noOfPages = (sf_old->NoOfTableEntries + NDB_SF_PAGE_ENTRIES - 1) /
1498 NDB_SF_PAGE_ENTRIES;
1499 initSchemaFile(xsf, 0, xsf->noOfPages, true);
1500
1501 Uint32 noOfPages = 1;
1502 Uint32 n, i, j;
1503 for (n = 0; n < xsf->noOfPages; n++) {
1504 jam();
1505 for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
1506 j = n * NDB_SF_PAGE_ENTRIES + i;
1507 if (j >= sf_old->NoOfTableEntries)
1508 continue;
1509 const SchemaFile::TableEntry_old & te_old = sf_old->TableEntries_old[j];
1510 if (te_old.m_tableState == SchemaFile::INIT ||
1511 te_old.m_tableState == SchemaFile::DROP_TABLE_COMMITTED ||
1512 te_old.m_noOfPages == 0)
1513 continue;
1514 SchemaFile * sf = &xsf->schemaPage[n];
1515 SchemaFile::TableEntry & te = sf->TableEntries[i];
1516 te.m_tableState = te_old.m_tableState;
1517 te.m_tableVersion = te_old.m_tableVersion;
1518 te.m_tableType = te_old.m_tableType;
1519 te.m_info_words = te_old.m_noOfPages * ZSIZE_OF_PAGES_IN_WORDS -
1520 ZPAGE_HEADER_SIZE;
1521 te.m_gcp = te_old.m_gcp;
1522 if (noOfPages < n)
1523 noOfPages = n;
1524 }
1525 }
1526 xsf->noOfPages = noOfPages;
1527 initSchemaFile(xsf, 0, xsf->noOfPages, false);
1528
1529 return true;
1530 }
1531
1532 /* **************************************************************** */
1533 /* ---------------------------------------------------------------- */
1534 /* MODULE: INITIALISATION MODULE ------------------------- */
1535 /* ---------------------------------------------------------------- */
1536 /* */
1537 /* This module contains initialisation of data at start/restart. */
1538 /* ---------------------------------------------------------------- */
1539 /* **************************************************************** */
1540
Dbdict(Block_context & ctx)1541 Dbdict::Dbdict(Block_context& ctx):
1542 SimulatedBlock(DBDICT, ctx),
1543 c_attributeRecordHash(c_attributeRecordPool),
1544 c_file_hash(c_file_pool),
1545 c_filegroup_hash(c_filegroup_pool),
1546 c_obj_hash(c_obj_pool),
1547 c_opCreateTable(c_opRecordPool),
1548 c_opDropTable(c_opRecordPool),
1549 c_opCreateIndex(c_opRecordPool),
1550 c_opDropIndex(c_opRecordPool),
1551 c_opAlterIndex(c_opRecordPool),
1552 c_opBuildIndex(c_opRecordPool),
1553 c_opCreateEvent(c_opRecordPool),
1554 c_opSubEvent(c_opRecordPool),
1555 c_opDropEvent(c_opRecordPool),
1556 c_opSignalUtil(c_opRecordPool),
1557 c_opCreateTrigger(c_opRecordPool),
1558 c_opDropTrigger(c_opRecordPool),
1559 c_opAlterTrigger(c_opRecordPool),
1560 c_schemaOp(c_opRecordPool),
1561 c_Trans(c_opRecordPool),
1562 c_opCreateObj(c_schemaOp),
1563 c_opDropObj(c_schemaOp),
1564 c_opRecordSequence(0),
1565 c_dictLockQueue(c_dictLockPool),
1566 c_dictLockPoll(false)
1567 {
1568 BLOCK_CONSTRUCTOR(Dbdict);
1569
1570 // Transit signals
1571 addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD);
1572 addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ);
1573 addRecSignal(GSN_GET_TABLEID_REQ, &Dbdict::execGET_TABLEDID_REQ);
1574 addRecSignal(GSN_GET_TABINFO_CONF, &Dbdict::execGET_TABINFO_CONF);
1575 addRecSignal(GSN_CONTINUEB, &Dbdict::execCONTINUEB);
1576
1577 addRecSignal(GSN_CREATE_TABLE_REQ, &Dbdict::execCREATE_TABLE_REQ);
1578 addRecSignal(GSN_CREATE_TAB_REQ, &Dbdict::execCREATE_TAB_REQ);
1579 addRecSignal(GSN_CREATE_TAB_REF, &Dbdict::execCREATE_TAB_REF);
1580 addRecSignal(GSN_CREATE_TAB_CONF, &Dbdict::execCREATE_TAB_CONF);
1581 addRecSignal(GSN_CREATE_FRAGMENTATION_REF, &Dbdict::execCREATE_FRAGMENTATION_REF);
1582 addRecSignal(GSN_CREATE_FRAGMENTATION_CONF, &Dbdict::execCREATE_FRAGMENTATION_CONF);
1583 addRecSignal(GSN_DIADDTABCONF, &Dbdict::execDIADDTABCONF);
1584 addRecSignal(GSN_DIADDTABREF, &Dbdict::execDIADDTABREF);
1585 addRecSignal(GSN_ADD_FRAGREQ, &Dbdict::execADD_FRAGREQ);
1586 addRecSignal(GSN_TAB_COMMITCONF, &Dbdict::execTAB_COMMITCONF);
1587 addRecSignal(GSN_TAB_COMMITREF, &Dbdict::execTAB_COMMITREF);
1588 addRecSignal(GSN_ALTER_TABLE_REQ, &Dbdict::execALTER_TABLE_REQ);
1589 addRecSignal(GSN_ALTER_TAB_REQ, &Dbdict::execALTER_TAB_REQ);
1590 addRecSignal(GSN_ALTER_TAB_REF, &Dbdict::execALTER_TAB_REF);
1591 addRecSignal(GSN_ALTER_TAB_CONF, &Dbdict::execALTER_TAB_CONF);
1592
1593 // Index signals
1594 addRecSignal(GSN_CREATE_INDX_REQ, &Dbdict::execCREATE_INDX_REQ);
1595 addRecSignal(GSN_CREATE_INDX_CONF, &Dbdict::execCREATE_INDX_CONF);
1596 addRecSignal(GSN_CREATE_INDX_REF, &Dbdict::execCREATE_INDX_REF);
1597
1598 addRecSignal(GSN_ALTER_INDX_REQ, &Dbdict::execALTER_INDX_REQ);
1599 addRecSignal(GSN_ALTER_INDX_CONF, &Dbdict::execALTER_INDX_CONF);
1600 addRecSignal(GSN_ALTER_INDX_REF, &Dbdict::execALTER_INDX_REF);
1601
1602 addRecSignal(GSN_CREATE_TABLE_CONF, &Dbdict::execCREATE_TABLE_CONF);
1603 addRecSignal(GSN_CREATE_TABLE_REF, &Dbdict::execCREATE_TABLE_REF);
1604
1605 addRecSignal(GSN_DROP_INDX_REQ, &Dbdict::execDROP_INDX_REQ);
1606 addRecSignal(GSN_DROP_INDX_CONF, &Dbdict::execDROP_INDX_CONF);
1607 addRecSignal(GSN_DROP_INDX_REF, &Dbdict::execDROP_INDX_REF);
1608
1609 addRecSignal(GSN_DROP_TABLE_CONF, &Dbdict::execDROP_TABLE_CONF);
1610 addRecSignal(GSN_DROP_TABLE_REF, &Dbdict::execDROP_TABLE_REF);
1611
1612 addRecSignal(GSN_BUILDINDXREQ, &Dbdict::execBUILDINDXREQ);
1613 addRecSignal(GSN_BUILDINDXCONF, &Dbdict::execBUILDINDXCONF);
1614 addRecSignal(GSN_BUILDINDXREF, &Dbdict::execBUILDINDXREF);
1615
1616 // Util signals
1617 addRecSignal(GSN_UTIL_PREPARE_CONF, &Dbdict::execUTIL_PREPARE_CONF);
1618 addRecSignal(GSN_UTIL_PREPARE_REF, &Dbdict::execUTIL_PREPARE_REF);
1619
1620 addRecSignal(GSN_UTIL_EXECUTE_CONF, &Dbdict::execUTIL_EXECUTE_CONF);
1621 addRecSignal(GSN_UTIL_EXECUTE_REF, &Dbdict::execUTIL_EXECUTE_REF);
1622
1623 addRecSignal(GSN_UTIL_RELEASE_CONF, &Dbdict::execUTIL_RELEASE_CONF);
1624 addRecSignal(GSN_UTIL_RELEASE_REF, &Dbdict::execUTIL_RELEASE_REF);
1625
1626 // Event signals
1627 addRecSignal(GSN_CREATE_EVNT_REQ, &Dbdict::execCREATE_EVNT_REQ);
1628 addRecSignal(GSN_CREATE_EVNT_CONF, &Dbdict::execCREATE_EVNT_CONF);
1629 addRecSignal(GSN_CREATE_EVNT_REF, &Dbdict::execCREATE_EVNT_REF);
1630
1631 addRecSignal(GSN_CREATE_SUBID_CONF, &Dbdict::execCREATE_SUBID_CONF);
1632 addRecSignal(GSN_CREATE_SUBID_REF, &Dbdict::execCREATE_SUBID_REF);
1633
1634 addRecSignal(GSN_SUB_CREATE_CONF, &Dbdict::execSUB_CREATE_CONF);
1635 addRecSignal(GSN_SUB_CREATE_REF, &Dbdict::execSUB_CREATE_REF);
1636
1637 addRecSignal(GSN_SUB_START_REQ, &Dbdict::execSUB_START_REQ);
1638 addRecSignal(GSN_SUB_START_CONF, &Dbdict::execSUB_START_CONF);
1639 addRecSignal(GSN_SUB_START_REF, &Dbdict::execSUB_START_REF);
1640
1641 addRecSignal(GSN_SUB_STOP_REQ, &Dbdict::execSUB_STOP_REQ);
1642 addRecSignal(GSN_SUB_STOP_CONF, &Dbdict::execSUB_STOP_CONF);
1643 addRecSignal(GSN_SUB_STOP_REF, &Dbdict::execSUB_STOP_REF);
1644
1645 addRecSignal(GSN_DROP_EVNT_REQ, &Dbdict::execDROP_EVNT_REQ);
1646
1647 addRecSignal(GSN_SUB_REMOVE_REQ, &Dbdict::execSUB_REMOVE_REQ);
1648 addRecSignal(GSN_SUB_REMOVE_CONF, &Dbdict::execSUB_REMOVE_CONF);
1649 addRecSignal(GSN_SUB_REMOVE_REF, &Dbdict::execSUB_REMOVE_REF);
1650
1651 // Trigger signals
1652 addRecSignal(GSN_CREATE_TRIG_REQ, &Dbdict::execCREATE_TRIG_REQ);
1653 addRecSignal(GSN_CREATE_TRIG_CONF, &Dbdict::execCREATE_TRIG_CONF);
1654 addRecSignal(GSN_CREATE_TRIG_REF, &Dbdict::execCREATE_TRIG_REF);
1655 addRecSignal(GSN_ALTER_TRIG_REQ, &Dbdict::execALTER_TRIG_REQ);
1656 addRecSignal(GSN_ALTER_TRIG_CONF, &Dbdict::execALTER_TRIG_CONF);
1657 addRecSignal(GSN_ALTER_TRIG_REF, &Dbdict::execALTER_TRIG_REF);
1658 addRecSignal(GSN_DROP_TRIG_REQ, &Dbdict::execDROP_TRIG_REQ);
1659 addRecSignal(GSN_DROP_TRIG_CONF, &Dbdict::execDROP_TRIG_CONF);
1660 addRecSignal(GSN_DROP_TRIG_REF, &Dbdict::execDROP_TRIG_REF);
1661
1662 // Received signals
1663 addRecSignal(GSN_HOT_SPAREREP, &Dbdict::execHOT_SPAREREP);
1664 addRecSignal(GSN_GET_SCHEMA_INFOREQ, &Dbdict::execGET_SCHEMA_INFOREQ);
1665 addRecSignal(GSN_SCHEMA_INFO, &Dbdict::execSCHEMA_INFO);
1666 addRecSignal(GSN_SCHEMA_INFOCONF, &Dbdict::execSCHEMA_INFOCONF);
1667 addRecSignal(GSN_DICTSTARTREQ, &Dbdict::execDICTSTARTREQ);
1668 addRecSignal(GSN_READ_NODESCONF, &Dbdict::execREAD_NODESCONF);
1669 addRecSignal(GSN_FSOPENCONF, &Dbdict::execFSOPENCONF);
1670 addRecSignal(GSN_FSOPENREF, &Dbdict::execFSOPENREF, true);
1671 addRecSignal(GSN_FSCLOSECONF, &Dbdict::execFSCLOSECONF);
1672 addRecSignal(GSN_FSWRITECONF, &Dbdict::execFSWRITECONF);
1673 addRecSignal(GSN_FSREADCONF, &Dbdict::execFSREADCONF);
1674 addRecSignal(GSN_FSREADREF, &Dbdict::execFSREADREF, true);
1675 addRecSignal(GSN_LQHFRAGCONF, &Dbdict::execLQHFRAGCONF);
1676 addRecSignal(GSN_LQHADDATTCONF, &Dbdict::execLQHADDATTCONF);
1677 addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF);
1678 addRecSignal(GSN_LQHFRAGREF, &Dbdict::execLQHFRAGREF);
1679 addRecSignal(GSN_NDB_STTOR, &Dbdict::execNDB_STTOR);
1680 addRecSignal(GSN_READ_CONFIG_REQ, &Dbdict::execREAD_CONFIG_REQ, true);
1681 addRecSignal(GSN_STTOR, &Dbdict::execSTTOR);
1682 addRecSignal(GSN_TC_SCHVERCONF, &Dbdict::execTC_SCHVERCONF);
1683 addRecSignal(GSN_NODE_FAILREP, &Dbdict::execNODE_FAILREP);
1684 addRecSignal(GSN_INCL_NODEREQ, &Dbdict::execINCL_NODEREQ);
1685 addRecSignal(GSN_API_FAILREQ, &Dbdict::execAPI_FAILREQ);
1686
1687 addRecSignal(GSN_WAIT_GCP_REF, &Dbdict::execWAIT_GCP_REF);
1688 addRecSignal(GSN_WAIT_GCP_CONF, &Dbdict::execWAIT_GCP_CONF);
1689
1690 addRecSignal(GSN_LIST_TABLES_REQ, &Dbdict::execLIST_TABLES_REQ);
1691
1692 addRecSignal(GSN_DROP_TABLE_REQ, &Dbdict::execDROP_TABLE_REQ);
1693
1694 addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbdict::execPREP_DROP_TAB_REQ);
1695 addRecSignal(GSN_PREP_DROP_TAB_REF, &Dbdict::execPREP_DROP_TAB_REF);
1696 addRecSignal(GSN_PREP_DROP_TAB_CONF, &Dbdict::execPREP_DROP_TAB_CONF);
1697
1698 addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ);
1699 addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF);
1700 addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF);
1701
1702 addRecSignal(GSN_CREATE_FILE_REQ, &Dbdict::execCREATE_FILE_REQ);
1703 addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Dbdict::execCREATE_FILEGROUP_REQ);
1704
1705 addRecSignal(GSN_DROP_FILE_REQ, &Dbdict::execDROP_FILE_REQ);
1706 addRecSignal(GSN_DROP_FILE_REF, &Dbdict::execDROP_FILE_REF);
1707 addRecSignal(GSN_DROP_FILE_CONF, &Dbdict::execDROP_FILE_CONF);
1708
1709 addRecSignal(GSN_DROP_FILEGROUP_REQ, &Dbdict::execDROP_FILEGROUP_REQ);
1710 addRecSignal(GSN_DROP_FILEGROUP_REF, &Dbdict::execDROP_FILEGROUP_REF);
1711 addRecSignal(GSN_DROP_FILEGROUP_CONF, &Dbdict::execDROP_FILEGROUP_CONF);
1712
1713 addRecSignal(GSN_CREATE_OBJ_REQ, &Dbdict::execCREATE_OBJ_REQ);
1714 addRecSignal(GSN_CREATE_OBJ_REF, &Dbdict::execCREATE_OBJ_REF);
1715 addRecSignal(GSN_CREATE_OBJ_CONF, &Dbdict::execCREATE_OBJ_CONF);
1716 addRecSignal(GSN_DROP_OBJ_REQ, &Dbdict::execDROP_OBJ_REQ);
1717 addRecSignal(GSN_DROP_OBJ_REF, &Dbdict::execDROP_OBJ_REF);
1718 addRecSignal(GSN_DROP_OBJ_CONF, &Dbdict::execDROP_OBJ_CONF);
1719
1720 addRecSignal(GSN_CREATE_FILE_REF, &Dbdict::execCREATE_FILE_REF);
1721 addRecSignal(GSN_CREATE_FILE_CONF, &Dbdict::execCREATE_FILE_CONF);
1722 addRecSignal(GSN_CREATE_FILEGROUP_REF, &Dbdict::execCREATE_FILEGROUP_REF);
1723 addRecSignal(GSN_CREATE_FILEGROUP_CONF, &Dbdict::execCREATE_FILEGROUP_CONF);
1724
1725 addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ);
1726
1727 addRecSignal(GSN_DICT_COMMIT_REQ, &Dbdict::execDICT_COMMIT_REQ);
1728 addRecSignal(GSN_DICT_COMMIT_REF, &Dbdict::execDICT_COMMIT_REF);
1729 addRecSignal(GSN_DICT_COMMIT_CONF, &Dbdict::execDICT_COMMIT_CONF);
1730
1731 addRecSignal(GSN_DICT_ABORT_REQ, &Dbdict::execDICT_ABORT_REQ);
1732 addRecSignal(GSN_DICT_ABORT_REF, &Dbdict::execDICT_ABORT_REF);
1733 addRecSignal(GSN_DICT_ABORT_CONF, &Dbdict::execDICT_ABORT_CONF);
1734
1735 addRecSignal(GSN_DICT_LOCK_REQ, &Dbdict::execDICT_LOCK_REQ);
1736 addRecSignal(GSN_DICT_UNLOCK_ORD, &Dbdict::execDICT_UNLOCK_ORD);
1737 }//Dbdict::Dbdict()
1738
~Dbdict()1739 Dbdict::~Dbdict()
1740 {
1741 }//Dbdict::~Dbdict()
1742
BLOCK_FUNCTIONS(Dbdict)1743 BLOCK_FUNCTIONS(Dbdict)
1744
1745 void Dbdict::initCommonData()
1746 {
1747 /* ---------------------------------------------------------------- */
1748 // Initialise all common variables.
1749 /* ---------------------------------------------------------------- */
1750 initRetrieveRecord(0, 0, 0);
1751 initSchemaRecord();
1752 initRestartRecord();
1753 initSendSchemaRecord();
1754 initReadTableRecord();
1755 initWriteTableRecord();
1756 initReadSchemaRecord();
1757 initWriteSchemaRecord();
1758
1759 c_masterNodeId = ZNIL;
1760 c_numberNode = 0;
1761 c_noNodesFailed = 0;
1762 c_failureNr = 0;
1763 c_blockState = BS_IDLE;
1764 c_packTable.m_state = PackTable::PTS_IDLE;
1765 c_startPhase = 0;
1766 c_restartType = 255; //Ensure not used restartType
1767 c_tabinfoReceived = 0;
1768 c_initialStart = false;
1769 c_systemRestart = false;
1770 c_initialNodeRestart = false;
1771 c_nodeRestart = false;
1772 }//Dbdict::initCommonData()
1773
initRecords()1774 void Dbdict::initRecords()
1775 {
1776 initNodeRecords();
1777 initPageRecords();
1778 initTableRecords();
1779 initTriggerRecords();
1780 }//Dbdict::initRecords()
1781
initSendSchemaRecord()1782 void Dbdict::initSendSchemaRecord()
1783 {
1784 c_sendSchemaRecord.noOfWords = (Uint32)-1;
1785 c_sendSchemaRecord.pageId = RNIL;
1786 c_sendSchemaRecord.noOfWordsCurrentlySent = 0;
1787 c_sendSchemaRecord.noOfSignalsSentSinceDelay = 0;
1788 c_sendSchemaRecord.inUse = false;
1789 //c_sendSchemaRecord.sendSchemaState = SendSchemaRecord::IDLE;
1790 }//initSendSchemaRecord()
1791
initReadTableRecord()1792 void Dbdict::initReadTableRecord()
1793 {
1794 c_readTableRecord.no_of_words= 0;
1795 c_readTableRecord.pageId = RNIL;
1796 c_readTableRecord.tableId = ZNIL;
1797 c_readTableRecord.inUse = false;
1798 }//initReadTableRecord()
1799
initWriteTableRecord()1800 void Dbdict::initWriteTableRecord()
1801 {
1802 c_writeTableRecord.no_of_words= 0;
1803 c_writeTableRecord.pageId = RNIL;
1804 c_writeTableRecord.noOfTableFilesHandled = 3;
1805 c_writeTableRecord.tableId = ZNIL;
1806 c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
1807 }//initWriteTableRecord()
1808
initReadSchemaRecord()1809 void Dbdict::initReadSchemaRecord()
1810 {
1811 c_readSchemaRecord.pageId = RNIL;
1812 c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
1813 }//initReadSchemaRecord()
1814
initWriteSchemaRecord()1815 void Dbdict::initWriteSchemaRecord()
1816 {
1817 c_writeSchemaRecord.inUse = false;
1818 c_writeSchemaRecord.pageId = RNIL;
1819 c_writeSchemaRecord.noOfSchemaFilesHandled = 3;
1820 }//initWriteSchemaRecord()
1821
initRetrieveRecord(Signal * signal,Uint32 i,Uint32 returnCode)1822 void Dbdict::initRetrieveRecord(Signal* signal, Uint32 i, Uint32 returnCode)
1823 {
1824 c_retrieveRecord.busyState = false;
1825 c_retrieveRecord.blockRef = 0;
1826 c_retrieveRecord.m_senderData = RNIL;
1827 c_retrieveRecord.tableId = RNIL;
1828 c_retrieveRecord.currentSent = 0;
1829 c_retrieveRecord.retrievedNoOfPages = 0;
1830 c_retrieveRecord.retrievedNoOfWords = 0;
1831 c_retrieveRecord.m_useLongSig = false;
1832 }//initRetrieveRecord()
1833
initSchemaRecord()1834 void Dbdict::initSchemaRecord()
1835 {
1836 c_schemaRecord.schemaPage = RNIL;
1837 c_schemaRecord.oldSchemaPage = RNIL;
1838 }//Dbdict::initSchemaRecord()
1839
initRestartRecord()1840 void Dbdict::initRestartRecord()
1841 {
1842 c_restartRecord.gciToRestart = 0;
1843 c_restartRecord.activeTable = ZNIL;
1844 c_restartRecord.m_pass = 0;
1845 }//Dbdict::initRestartRecord()
1846
initNodeRecords()1847 void Dbdict::initNodeRecords()
1848 {
1849 jam();
1850 for (unsigned i = 1; i < MAX_NODES; i++) {
1851 NodeRecordPtr nodePtr;
1852 c_nodes.getPtr(nodePtr, i);
1853 nodePtr.p->hotSpare = false;
1854 nodePtr.p->nodeState = NodeRecord::API_NODE;
1855 }//for
1856 }//Dbdict::initNodeRecords()
1857
initPageRecords()1858 void Dbdict::initPageRecords()
1859 {
1860 c_retrieveRecord.retrievePage = ZMAX_PAGES_OF_TABLE_DEFINITION;
1861 ndbrequire(ZNUMBER_OF_PAGES >= (ZMAX_PAGES_OF_TABLE_DEFINITION + 1));
1862 c_schemaRecord.schemaPage = 0;
1863 c_schemaRecord.oldSchemaPage = NDB_SF_MAX_PAGES;
1864 }//Dbdict::initPageRecords()
1865
initTableRecords()1866 void Dbdict::initTableRecords()
1867 {
1868 TableRecordPtr tablePtr;
1869 while (1) {
1870 jam();
1871 refresh_watch_dog();
1872 c_tableRecordPool.seize(tablePtr);
1873 if (tablePtr.i == RNIL) {
1874 jam();
1875 break;
1876 }//if
1877 initialiseTableRecord(tablePtr);
1878 }//while
1879 }//Dbdict::initTableRecords()
1880
initialiseTableRecord(TableRecordPtr tablePtr)1881 void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr)
1882 {
1883 new (tablePtr.p) TableRecord();
1884 tablePtr.p->activePage = RNIL;
1885 tablePtr.p->filePtr[0] = RNIL;
1886 tablePtr.p->filePtr[1] = RNIL;
1887 tablePtr.p->firstPage = RNIL;
1888 tablePtr.p->tableId = tablePtr.i;
1889 tablePtr.p->tableVersion = (Uint32)-1;
1890 tablePtr.p->tabState = TableRecord::NOT_DEFINED;
1891 tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
1892 tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
1893 tablePtr.p->gciTableCreated = 0;
1894 tablePtr.p->noOfAttributes = ZNIL;
1895 tablePtr.p->noOfNullAttr = 0;
1896 tablePtr.p->fragmentCount = 0;
1897 /*
1898 tablePtr.p->lh3PageIndexBits = 0;
1899 tablePtr.p->lh3DistrBits = 0;
1900 tablePtr.p->lh3PageBits = 6;
1901 */
1902 tablePtr.p->kValue = 6;
1903 tablePtr.p->localKeyLen = 1;
1904 tablePtr.p->maxLoadFactor = 80;
1905 tablePtr.p->minLoadFactor = 70;
1906 tablePtr.p->noOfPrimkey = 1;
1907 tablePtr.p->tupKeyLength = 1;
1908 tablePtr.p->maxRowsLow = 0;
1909 tablePtr.p->maxRowsHigh = 0;
1910 tablePtr.p->defaultNoPartFlag = true;
1911 tablePtr.p->linearHashFlag = true;
1912 tablePtr.p->m_bits = 0;
1913 tablePtr.p->minRowsLow = 0;
1914 tablePtr.p->minRowsHigh = 0;
1915 tablePtr.p->singleUserMode = 0;
1916 tablePtr.p->tableType = DictTabInfo::UserTable;
1917 tablePtr.p->primaryTableId = RNIL;
1918 // volatile elements
1919 tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
1920 tablePtr.p->insertTriggerId = RNIL;
1921 tablePtr.p->updateTriggerId = RNIL;
1922 tablePtr.p->deleteTriggerId = RNIL;
1923 tablePtr.p->customTriggerId = RNIL;
1924 tablePtr.p->buildTriggerId = RNIL;
1925 tablePtr.p->indexLocal = 0;
1926 }//Dbdict::initialiseTableRecord()
1927
initTriggerRecords()1928 void Dbdict::initTriggerRecords()
1929 {
1930 TriggerRecordPtr triggerPtr;
1931 while (1) {
1932 jam();
1933 refresh_watch_dog();
1934 c_triggerRecordPool.seize(triggerPtr);
1935 if (triggerPtr.i == RNIL) {
1936 jam();
1937 break;
1938 }//if
1939 initialiseTriggerRecord(triggerPtr);
1940 }//while
1941 }
1942
initialiseTriggerRecord(TriggerRecordPtr triggerPtr)1943 void Dbdict::initialiseTriggerRecord(TriggerRecordPtr triggerPtr)
1944 {
1945 new (triggerPtr.p) TriggerRecord();
1946 triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
1947 triggerPtr.p->triggerLocal = 0;
1948 triggerPtr.p->triggerId = RNIL;
1949 triggerPtr.p->tableId = RNIL;
1950 triggerPtr.p->triggerType = (TriggerType::Value)~0;
1951 triggerPtr.p->triggerActionTime = (TriggerActionTime::Value)~0;
1952 triggerPtr.p->triggerEvent = (TriggerEvent::Value)~0;
1953 triggerPtr.p->monitorReplicas = false;
1954 triggerPtr.p->monitorAllAttributes = false;
1955 triggerPtr.p->attributeMask.clear();
1956 triggerPtr.p->indexId = RNIL;
1957 }
1958
getFsConnRecord()1959 Uint32 Dbdict::getFsConnRecord()
1960 {
1961 FsConnectRecordPtr fsPtr;
1962 c_fsConnectRecordPool.seize(fsPtr);
1963 ndbrequire(fsPtr.i != RNIL);
1964 fsPtr.p->filePtr = (Uint32)-1;
1965 fsPtr.p->ownerPtr = RNIL;
1966 fsPtr.p->fsState = FsConnectRecord::IDLE;
1967 return fsPtr.i;
1968 }//Dbdict::getFsConnRecord()
1969
1970 /*
1971 * Search schemafile for free entry. Its index is used as 'logical id'
1972 * of new disk-stored object.
1973 */
getFreeObjId(Uint32 minId)1974 Uint32 Dbdict::getFreeObjId(Uint32 minId)
1975 {
1976 const XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
1977 Uint32 noOfPages = xsf->noOfPages;
1978 Uint32 n, i;
1979 for (n = 0; n < noOfPages; n++) {
1980 jam();
1981 const SchemaFile * sf = &xsf->schemaPage[n];
1982 for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
1983 const SchemaFile::TableEntry& te = sf->TableEntries[i];
1984 if (te.m_tableState == (Uint32)SchemaFile::INIT ||
1985 te.m_tableState == (Uint32)SchemaFile::DROP_TABLE_COMMITTED) {
1986 // minId is obsolete anyway
1987 if (minId <= n * NDB_SF_PAGE_ENTRIES + i)
1988 return n * NDB_SF_PAGE_ENTRIES + i;
1989 }
1990 }
1991 }
1992 return RNIL;
1993 }
1994
getFreeTableRecord(Uint32 primaryTableId)1995 Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId)
1996 {
1997 Uint32 minId = (primaryTableId == RNIL ? 0 : primaryTableId + 1);
1998 Uint32 i = getFreeObjId(minId);
1999 if (i == RNIL) {
2000 jam();
2001 return RNIL;
2002 }
2003 if (i >= c_tableRecordPool.getSize()) {
2004 jam();
2005 return RNIL;
2006 }
2007 TableRecordPtr tablePtr;
2008 c_tableRecordPool.getPtr(tablePtr, i);
2009 ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
2010 initialiseTableRecord(tablePtr);
2011 tablePtr.p->tabState = TableRecord::DEFINING;
2012 return i;
2013 }
2014
getFreeTriggerRecord()2015 Uint32 Dbdict::getFreeTriggerRecord()
2016 {
2017 const Uint32 size = c_triggerRecordPool.getSize();
2018 TriggerRecordPtr triggerPtr;
2019 for (triggerPtr.i = 0; triggerPtr.i < size; triggerPtr.i++) {
2020 jam();
2021 c_triggerRecordPool.getPtr(triggerPtr);
2022 if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
2023 jam();
2024 initialiseTriggerRecord(triggerPtr);
2025 return triggerPtr.i;
2026 }
2027 }
2028 return RNIL;
2029 }
2030
2031 /* **************************************************************** */
2032 /* ---------------------------------------------------------------- */
2033 /* MODULE: START/RESTART HANDLING ------------------------ */
2034 /* ---------------------------------------------------------------- */
2035 /* */
2036 /* This module contains the code that is common for all */
2037 /* start/restart types. */
2038 /* ---------------------------------------------------------------- */
2039 /* **************************************************************** */
2040
2041 /* ---------------------------------------------------------------- */
2042 // This is sent as the first signal during start/restart.
2043 /* ---------------------------------------------------------------- */
execSTTOR(Signal * signal)2044 void Dbdict::execSTTOR(Signal* signal)
2045 {
2046 jamEntry();
2047 c_startPhase = signal->theData[1];
2048 switch (c_startPhase) {
2049 case 1:
2050 break;
2051 case 3:
2052 c_restartType = signal->theData[7]; /* valid if 3 */
2053 ndbrequire(c_restartType == NodeState::ST_INITIAL_START ||
2054 c_restartType == NodeState::ST_SYSTEM_RESTART ||
2055 c_restartType == NodeState::ST_INITIAL_NODE_RESTART ||
2056 c_restartType == NodeState::ST_NODE_RESTART);
2057 break;
2058 }
2059 sendSTTORRY(signal);
2060 }//execSTTOR()
2061
sendSTTORRY(Signal * signal)2062 void Dbdict::sendSTTORRY(Signal* signal)
2063 {
2064 signal->theData[0] = 0; /* garbage SIGNAL KEY */
2065 signal->theData[1] = 0; /* garbage SIGNAL VERSION NUMBER */
2066 signal->theData[2] = 0; /* garbage */
2067 signal->theData[3] = 1; /* first wanted start phase */
2068 signal->theData[4] = 3; /* get type of start */
2069 signal->theData[5] = ZNOMOREPHASES;
2070 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
2071 }
2072
2073 /* ---------------------------------------------------------------- */
2074 // We receive information about sizes of records.
2075 /* ---------------------------------------------------------------- */
execREAD_CONFIG_REQ(Signal * signal)2076 void Dbdict::execREAD_CONFIG_REQ(Signal* signal)
2077 {
2078 const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
2079 Uint32 ref = req->senderRef;
2080 Uint32 senderData = req->senderData;
2081 ndbrequire(req->noOfParameters == 0);
2082
2083 jamEntry();
2084
2085 const ndb_mgm_configuration_iterator * p =
2086 m_ctx.m_config.getOwnConfigIterator();
2087 ndbrequire(p != 0);
2088
2089 Uint32 attributesize, tablerecSize;
2090 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS,
2091 &c_maxNoOfTriggers));
2092 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_ATTRIBUTE,&attributesize));
2093 ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &tablerecSize));
2094
2095 c_attributeRecordPool.setSize(attributesize);
2096 c_attributeRecordHash.setSize(64);
2097 c_fsConnectRecordPool.setSize(ZFS_CONNECT_SIZE);
2098 c_nodes.setSize(MAX_NODES);
2099 c_pageRecordArray.setSize(ZNUMBER_OF_PAGES);
2100 c_schemaPageRecordArray.setSize(2 * NDB_SF_MAX_PAGES);
2101 c_tableRecordPool.setSize(tablerecSize);
2102 g_key_descriptor_pool.setSize(tablerecSize);
2103 c_triggerRecordPool.setSize(c_maxNoOfTriggers);
2104
2105 c_obj_pool.setSize(tablerecSize+c_maxNoOfTriggers);
2106 c_obj_hash.setSize((tablerecSize+c_maxNoOfTriggers+1)/2);
2107
2108 Pool_context pc;
2109 pc.m_block = this;
2110
2111 c_file_hash.setSize(16);
2112 c_filegroup_hash.setSize(16);
2113
2114 c_file_pool.init(RT_DBDICT_FILE, pc);
2115 c_filegroup_pool.init(RT_DBDICT_FILEGROUP, pc);
2116
2117 c_opRecordPool.setSize(256); // XXX need config params
2118 c_opCreateTable.setSize(8);
2119 c_opDropTable.setSize(8);
2120 c_opCreateIndex.setSize(8);
2121 c_opCreateEvent.setSize(2);
2122 c_opSubEvent.setSize(2);
2123 c_opDropEvent.setSize(2);
2124 c_opSignalUtil.setSize(8);
2125 c_opDropIndex.setSize(8);
2126 c_opAlterIndex.setSize(8);
2127 c_opBuildIndex.setSize(8);
2128 c_opCreateTrigger.setSize(8);
2129 c_opDropTrigger.setSize(8);
2130 c_opAlterTrigger.setSize(8);
2131
2132 c_dictLockPool.setSize(32);
2133
2134 // Initialize schema file copies
2135 c_schemaFile[0].schemaPage =
2136 (SchemaFile*)c_schemaPageRecordArray.getPtr(0 * NDB_SF_MAX_PAGES);
2137 c_schemaFile[0].noOfPages = 0;
2138 c_schemaFile[1].schemaPage =
2139 (SchemaFile*)c_schemaPageRecordArray.getPtr(1 * NDB_SF_MAX_PAGES);
2140 c_schemaFile[1].noOfPages = 0;
2141
2142 c_schemaOp.setSize(8);
2143 //c_opDropObj.setSize(8);
2144 c_Trans.setSize(8);
2145
2146 Uint32 rps = 0;
2147 rps += tablerecSize * (MAX_TAB_NAME_SIZE + MAX_FRM_DATA_SIZE);
2148 rps += attributesize * (MAX_ATTR_NAME_SIZE + MAX_ATTR_DEFAULT_VALUE_SIZE);
2149 rps += c_maxNoOfTriggers * MAX_TAB_NAME_SIZE;
2150 rps += (10 + 10) * MAX_TAB_NAME_SIZE;
2151
2152 Uint32 sm = 5;
2153 ndb_mgm_get_int_parameter(p, CFG_DB_STRING_MEMORY, &sm);
2154 if (sm == 0)
2155 sm = 5;
2156
2157 Uint32 sb = 0;
2158 if (sm < 100)
2159 {
2160 sb = (rps * sm) / 100;
2161 }
2162 else
2163 {
2164 sb = sm;
2165 }
2166
2167 c_rope_pool.setSize(sb/28 + 100);
2168
2169 // Initialize BAT for interface to file system
2170 NewVARIABLE* bat = allocateBat(2);
2171 bat[0].WA = &c_schemaPageRecordArray.getPtr(0)->word[0];
2172 bat[0].nrr = 2 * NDB_SF_MAX_PAGES;
2173 bat[0].ClusterSize = NDB_SF_PAGE_SIZE;
2174 bat[0].bits.q = NDB_SF_PAGE_SIZE_IN_WORDS_LOG2;
2175 bat[0].bits.v = 5; // 32 bits per element
2176 bat[1].WA = &c_pageRecordArray.getPtr(0)->word[0];
2177 bat[1].nrr = ZNUMBER_OF_PAGES;
2178 bat[1].ClusterSize = ZSIZE_OF_PAGES_IN_WORDS * 4;
2179 bat[1].bits.q = ZLOG_SIZE_OF_PAGES_IN_WORDS; // 2**13 = 8192 elements
2180 bat[1].bits.v = 5; // 32 bits per element
2181
2182 initCommonData();
2183 initRecords();
2184
2185 ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
2186 conf->senderRef = reference();
2187 conf->senderData = senderData;
2188 sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
2189 ReadConfigConf::SignalLength, JBB);
2190
2191 {
2192 Ptr<DictObject> ptr;
2193 SLList<DictObject> objs(c_obj_pool);
2194 while(objs.seize(ptr))
2195 new (ptr.p) DictObject();
2196 objs.release();
2197 }
2198 }//execSIZEALT_REP()
2199
2200 /* ---------------------------------------------------------------- */
2201 // Start phase signals sent by CNTR. We reply with NDB_STTORRY when
2202 // we completed this phase.
2203 /* ---------------------------------------------------------------- */
execNDB_STTOR(Signal * signal)2204 void Dbdict::execNDB_STTOR(Signal* signal)
2205 {
2206 jamEntry();
2207 c_startPhase = signal->theData[2];
2208 const Uint32 restartType = signal->theData[3];
2209 if (restartType == NodeState::ST_INITIAL_START) {
2210 jam();
2211 c_initialStart = true;
2212 } else if (restartType == NodeState::ST_SYSTEM_RESTART) {
2213 jam();
2214 c_systemRestart = true;
2215 } else if (restartType == NodeState::ST_INITIAL_NODE_RESTART) {
2216 jam();
2217 c_initialNodeRestart = true;
2218 } else if (restartType == NodeState::ST_NODE_RESTART) {
2219 jam();
2220 c_nodeRestart = true;
2221 } else {
2222 ndbrequire(false);
2223 }//if
2224 switch (c_startPhase) {
2225 case 1:
2226 jam();
2227 initSchemaFile(signal);
2228 break;
2229 case 3:
2230 jam();
2231 signal->theData[0] = reference();
2232 sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
2233 break;
2234 case 6:
2235 jam();
2236 c_initialStart = false;
2237 c_systemRestart = false;
2238 c_initialNodeRestart = false;
2239 c_nodeRestart = false;
2240 sendNDB_STTORRY(signal);
2241 break;
2242 case 7:
2243 // uses c_restartType
2244 if(restartType == NodeState::ST_SYSTEM_RESTART &&
2245 c_masterNodeId == getOwnNodeId()){
2246 rebuildIndexes(signal, 0);
2247 return;
2248 }
2249 sendNDB_STTORRY(signal);
2250 break;
2251 default:
2252 jam();
2253 sendNDB_STTORRY(signal);
2254 break;
2255 }//switch
2256 }//execNDB_STTOR()
2257
sendNDB_STTORRY(Signal * signal)2258 void Dbdict::sendNDB_STTORRY(Signal* signal)
2259 {
2260 signal->theData[0] = reference();
2261 sendSignal(NDBCNTR_REF, GSN_NDB_STTORRY, signal, 1, JBB);
2262 return;
2263 }//sendNDB_STTORRY()
2264
2265 /* ---------------------------------------------------------------- */
2266 // We receive the information about which nodes that are up and down.
2267 /* ---------------------------------------------------------------- */
execREAD_NODESCONF(Signal * signal)2268 void Dbdict::execREAD_NODESCONF(Signal* signal)
2269 {
2270 jamEntry();
2271
2272 ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
2273 c_numberNode = readNodes->noOfNodes;
2274 c_masterNodeId = readNodes->masterNodeId;
2275
2276 c_noNodesFailed = 0;
2277 c_aliveNodes.clear();
2278 for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
2279 jam();
2280 NodeRecordPtr nodePtr;
2281 c_nodes.getPtr(nodePtr, i);
2282
2283 if (NodeBitmask::get(readNodes->allNodes, i)) {
2284 jam();
2285 nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
2286 if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
2287 jam();
2288 /**-------------------------------------------------------------------
2289 *
2290 * THIS NODE IS DEFINED IN THE CLUSTER BUT IS NOT ALIVE CURRENTLY.
2291 * WE ADD THE NODE TO THE SET OF FAILED NODES AND ALSO SET THE
2292 * BLOCKSTATE TO BUSY TO AVOID ADDING TABLES WHILE NOT ALL NODES ARE
2293 * ALIVE.
2294 *------------------------------------------------------------------*/
2295 nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
2296 c_noNodesFailed++;
2297 } else {
2298 c_aliveNodes.set(i);
2299 }
2300 }//if
2301 }//for
2302 sendNDB_STTORRY(signal);
2303 }//execREAD_NODESCONF()
2304
2305 /* ---------------------------------------------------------------- */
2306 // HOT_SPAREREP informs DBDICT about which nodes that have become
2307 // hot spare nodes.
2308 /* ---------------------------------------------------------------- */
execHOT_SPAREREP(Signal * signal)2309 void Dbdict::execHOT_SPAREREP(Signal* signal)
2310 {
2311 Uint32 hotSpareNodes = 0;
2312 jamEntry();
2313 HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
2314 for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
2315 if (NodeBitmask::get(hotSpare->theHotSpareNodes, i)) {
2316 NodeRecordPtr nodePtr;
2317 c_nodes.getPtr(nodePtr, i);
2318 nodePtr.p->hotSpare = true;
2319 hotSpareNodes++;
2320 }//if
2321 }//for
2322 ndbrequire(hotSpareNodes == hotSpare->noHotSpareNodes);
2323 c_noHotSpareNodes = hotSpareNodes;
2324 return;
2325 }//execHOT_SPAREREP()
2326
initSchemaFile(Signal * signal)2327 void Dbdict::initSchemaFile(Signal* signal)
2328 {
2329 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2330 xsf->noOfPages = (c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1)
2331 / NDB_SF_PAGE_ENTRIES;
2332 initSchemaFile(xsf, 0, xsf->noOfPages, true);
2333 // init alt copy too for INR
2334 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
2335 oldxsf->noOfPages = xsf->noOfPages;
2336 memcpy(&oldxsf->schemaPage[0], &xsf->schemaPage[0], xsf->schemaPage[0].FileSize);
2337
2338 if (c_initialStart || c_initialNodeRestart) {
2339 jam();
2340 ndbrequire(c_writeSchemaRecord.inUse == false);
2341 c_writeSchemaRecord.inUse = true;
2342 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
2343 c_writeSchemaRecord.newFile = true;
2344 c_writeSchemaRecord.firstPage = 0;
2345 c_writeSchemaRecord.noOfPages = xsf->noOfPages;
2346
2347 c_writeSchemaRecord.m_callback.m_callbackFunction =
2348 safe_cast(&Dbdict::initSchemaFile_conf);
2349
2350 startWriteSchemaFile(signal);
2351 } else if (c_systemRestart || c_nodeRestart) {
2352 jam();
2353 ndbrequire(c_readSchemaRecord.schemaReadState == ReadSchemaRecord::IDLE);
2354 c_readSchemaRecord.pageId = c_schemaRecord.oldSchemaPage;
2355 c_readSchemaRecord.firstPage = 0;
2356 c_readSchemaRecord.noOfPages = 1;
2357 c_readSchemaRecord.schemaReadState = ReadSchemaRecord::INITIAL_READ_HEAD;
2358 startReadSchemaFile(signal);
2359 } else {
2360 ndbrequire(false);
2361 }//if
2362 }//Dbdict::initSchemaFile()
2363
2364 void
initSchemaFile_conf(Signal * signal,Uint32 callbackData,Uint32 rv)2365 Dbdict::initSchemaFile_conf(Signal* signal, Uint32 callbackData, Uint32 rv){
2366 jam();
2367 sendNDB_STTORRY(signal);
2368 }
2369
2370 void
activateIndexes(Signal * signal,Uint32 i)2371 Dbdict::activateIndexes(Signal* signal, Uint32 i)
2372 {
2373 AlterIndxReq* req = (AlterIndxReq*)signal->getDataPtrSend();
2374 TableRecordPtr tablePtr;
2375 for (; i < c_tableRecordPool.getSize(); i++) {
2376 tablePtr.i = i;
2377 c_tableRecordPool.getPtr(tablePtr);
2378 if (tablePtr.p->tabState != TableRecord::DEFINED)
2379 continue;
2380 if (! tablePtr.p->isIndex())
2381 continue;
2382 jam();
2383 req->setUserRef(reference());
2384 req->setConnectionPtr(i);
2385 req->setTableId(tablePtr.p->primaryTableId);
2386 req->setIndexId(tablePtr.i);
2387 req->setIndexVersion(tablePtr.p->tableVersion);
2388 req->setOnline(true);
2389 if (c_restartType == NodeState::ST_SYSTEM_RESTART) {
2390 if (c_masterNodeId != getOwnNodeId())
2391 continue;
2392 // from file index state is not defined currently
2393 req->setRequestType(AlterIndxReq::RT_SYSTEMRESTART);
2394 req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
2395 }
2396 else if (
2397 c_restartType == NodeState::ST_NODE_RESTART ||
2398 c_restartType == NodeState::ST_INITIAL_NODE_RESTART) {
2399 // from master index must be online
2400 if (tablePtr.p->indexState != TableRecord::IS_ONLINE)
2401 continue;
2402 req->setRequestType(AlterIndxReq::RT_NODERESTART);
2403 // activate locally, rebuild not needed
2404 req->addRequestFlag((Uint32)RequestFlag::RF_LOCAL);
2405 req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
2406 } else {
2407 ndbrequire(false);
2408 }
2409 sendSignal(reference(), GSN_ALTER_INDX_REQ,
2410 signal, AlterIndxReq::SignalLength, JBB);
2411 return;
2412 }
2413 signal->theData[0] = reference();
2414 sendSignal(c_restartRecord.returnBlockRef, GSN_DICTSTARTCONF,
2415 signal, 1, JBB);
2416 }
2417
2418 void
rebuildIndexes(Signal * signal,Uint32 i)2419 Dbdict::rebuildIndexes(Signal* signal, Uint32 i){
2420 BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
2421
2422 TableRecordPtr indexPtr;
2423 for (; i < c_tableRecordPool.getSize(); i++) {
2424 indexPtr.i = i;
2425 c_tableRecordPool.getPtr(indexPtr);
2426 if (indexPtr.p->tabState != TableRecord::DEFINED)
2427 continue;
2428 if (! indexPtr.p->isIndex())
2429 continue;
2430
2431 jam();
2432
2433 req->setUserRef(reference());
2434 req->setConnectionPtr(i);
2435 req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART);
2436 req->setBuildId(0); // not used
2437 req->setBuildKey(0); // not used
2438 req->setIndexType(indexPtr.p->tableType);
2439 req->setIndexId(indexPtr.i);
2440 req->setTableId(indexPtr.p->primaryTableId);
2441 req->setParallelism(16);
2442
2443 // from file index state is not defined currently
2444 if (indexPtr.p->m_bits & TableRecord::TR_Logged) {
2445 // rebuild not needed
2446 req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
2447 }
2448
2449 // send
2450 sendSignal(reference(), GSN_BUILDINDXREQ,
2451 signal, BuildIndxReq::SignalLength, JBB);
2452 return;
2453 }
2454 sendNDB_STTORRY(signal);
2455 }
2456
2457
2458 /* **************************************************************** */
2459 /* ---------------------------------------------------------------- */
2460 /* MODULE: SYSTEM RESTART MODULE ------------------------- */
2461 /* ---------------------------------------------------------------- */
2462 /* */
2463 /* This module contains code specific for system restart */
2464 /* ---------------------------------------------------------------- */
2465 /* **************************************************************** */
2466
2467 /* ---------------------------------------------------------------- */
2468 // DIH asks DICT to read in table data from disk during system
2469 // restart. DIH also asks DICT to send information about which
2470 // tables that should be started as part of this system restart.
2471 // DICT will also activate the tables in TC as part of this process.
2472 /* ---------------------------------------------------------------- */
execDICTSTARTREQ(Signal * signal)2473 void Dbdict::execDICTSTARTREQ(Signal* signal)
2474 {
2475 jamEntry();
2476 c_restartRecord.gciToRestart = signal->theData[0];
2477 c_restartRecord.returnBlockRef = signal->theData[1];
2478 if (c_nodeRestart || c_initialNodeRestart) {
2479 jam();
2480
2481 CRASH_INSERTION(6000);
2482
2483 BlockReference dictRef = calcDictBlockRef(c_masterNodeId);
2484 signal->theData[0] = getOwnNodeId();
2485 sendSignal(dictRef, GSN_GET_SCHEMA_INFOREQ, signal, 1, JBB);
2486 return;
2487 }
2488 ndbrequire(c_systemRestart);
2489 ndbrequire(c_masterNodeId == getOwnNodeId());
2490
2491 c_schemaRecord.m_callback.m_callbackData = 0;
2492 c_schemaRecord.m_callback.m_callbackFunction =
2493 safe_cast(&Dbdict::masterRestart_checkSchemaStatusComplete);
2494
2495 c_restartRecord.m_pass = 0;
2496 c_restartRecord.activeTable = 0;
2497 c_schemaRecord.schemaPage = c_schemaRecord.oldSchemaPage; // ugly
2498 checkSchemaStatus(signal);
2499 }//execDICTSTARTREQ()
2500
2501 void
masterRestart_checkSchemaStatusComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)2502 Dbdict::masterRestart_checkSchemaStatusComplete(Signal* signal,
2503 Uint32 callbackData,
2504 Uint32 returnCode){
2505
2506 c_schemaRecord.schemaPage = 0; // ugly
2507 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
2508 ndbrequire(oldxsf->noOfPages != 0);
2509
2510 LinearSectionPtr ptr[3];
2511 ptr[0].p = (Uint32*)&oldxsf->schemaPage[0];
2512 ptr[0].sz = oldxsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS;
2513
2514 c_sendSchemaRecord.m_SCHEMAINFO_Counter = c_aliveNodes;
2515 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
2516
2517 rg.m_nodes.clear(getOwnNodeId());
2518 Callback c = { 0, 0 };
2519 sendFragmentedSignal(rg,
2520 GSN_SCHEMA_INFO,
2521 signal,
2522 1, //SchemaInfo::SignalLength,
2523 JBB,
2524 ptr,
2525 1,
2526 c);
2527
2528 XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2529 newxsf->noOfPages = oldxsf->noOfPages;
2530 memcpy(&newxsf->schemaPage[0], &oldxsf->schemaPage[0],
2531 oldxsf->noOfPages * NDB_SF_PAGE_SIZE);
2532
2533 signal->theData[0] = getOwnNodeId();
2534 sendSignal(reference(), GSN_SCHEMA_INFOCONF, signal, 1, JBB);
2535 }
2536
2537 void
execGET_SCHEMA_INFOREQ(Signal * signal)2538 Dbdict::execGET_SCHEMA_INFOREQ(Signal* signal){
2539
2540 const Uint32 ref = signal->getSendersBlockRef();
2541 //const Uint32 senderData = signal->theData[0];
2542
2543 ndbrequire(c_sendSchemaRecord.inUse == false);
2544 c_sendSchemaRecord.inUse = true;
2545
2546 LinearSectionPtr ptr[3];
2547
2548 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2549 ndbrequire(xsf->noOfPages != 0);
2550
2551 ptr[0].p = (Uint32*)&xsf->schemaPage[0];
2552 ptr[0].sz = xsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS;
2553
2554 Callback c = { safe_cast(&Dbdict::sendSchemaComplete), 0 };
2555 sendFragmentedSignal(ref,
2556 GSN_SCHEMA_INFO,
2557 signal,
2558 1, //GetSchemaInfoConf::SignalLength,
2559 JBB,
2560 ptr,
2561 1,
2562 c);
2563 }//Dbdict::execGET_SCHEMA_INFOREQ()
2564
2565 void
sendSchemaComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)2566 Dbdict::sendSchemaComplete(Signal * signal,
2567 Uint32 callbackData,
2568 Uint32 returnCode){
2569 ndbrequire(c_sendSchemaRecord.inUse == true);
2570 c_sendSchemaRecord.inUse = false;
2571
2572 }
2573
2574
2575 /* ---------------------------------------------------------------- */
2576 // We receive the schema info from master as part of all restarts
2577 // except the initial start where no tables exists.
2578 /* ---------------------------------------------------------------- */
execSCHEMA_INFO(Signal * signal)2579 void Dbdict::execSCHEMA_INFO(Signal* signal)
2580 {
2581 jamEntry();
2582 if(!assembleFragments(signal)){
2583 jam();
2584 return;
2585 }
2586
2587 if(getNodeState().getNodeRestartInProgress()){
2588 CRASH_INSERTION(6001);
2589 }
2590
2591 SegmentedSectionPtr schemaDataPtr;
2592 signal->getSection(schemaDataPtr, 0);
2593
2594 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2595 ndbrequire(schemaDataPtr.sz % NDB_SF_PAGE_SIZE_IN_WORDS == 0);
2596 xsf->noOfPages = schemaDataPtr.sz / NDB_SF_PAGE_SIZE_IN_WORDS;
2597 copy((Uint32*)&xsf->schemaPage[0], schemaDataPtr);
2598 releaseSections(signal);
2599
2600 SchemaFile * sf0 = &xsf->schemaPage[0];
2601 if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6) {
2602 bool ok = convertSchemaFileTo_5_0_6(xsf);
2603 ndbrequire(ok);
2604 }
2605
2606 validateChecksum(xsf);
2607
2608 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
2609 resizeSchemaFile(xsf, oldxsf->noOfPages);
2610
2611 ndbrequire(signal->getSendersBlockRef() != reference());
2612
2613 /* ---------------------------------------------------------------- */
2614 // Synchronise our view on data with other nodes in the cluster.
2615 // This is an important part of restart handling where we will handle
2616 // cases where the table have been added but only partially, where
2617 // tables have been deleted but not completed the deletion yet and
2618 // other scenarios needing synchronisation.
2619 /* ---------------------------------------------------------------- */
2620 c_schemaRecord.m_callback.m_callbackData = 0;
2621 c_schemaRecord.m_callback.m_callbackFunction =
2622 safe_cast(&Dbdict::restart_checkSchemaStatusComplete);
2623
2624 c_restartRecord.m_pass= 0;
2625 c_restartRecord.activeTable = 0;
2626 checkSchemaStatus(signal);
2627 }//execSCHEMA_INFO()
2628
2629 void
restart_checkSchemaStatusComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)2630 Dbdict::restart_checkSchemaStatusComplete(Signal * signal,
2631 Uint32 callbackData,
2632 Uint32 returnCode){
2633
2634 ndbrequire(c_writeSchemaRecord.inUse == false);
2635 c_writeSchemaRecord.inUse = true;
2636 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2637 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
2638 c_writeSchemaRecord.newFile = true;
2639 c_writeSchemaRecord.firstPage = 0;
2640 c_writeSchemaRecord.noOfPages = xsf->noOfPages;
2641 c_writeSchemaRecord.m_callback.m_callbackData = 0;
2642 c_writeSchemaRecord.m_callback.m_callbackFunction =
2643 safe_cast(&Dbdict::restart_writeSchemaConf);
2644
2645 for(Uint32 i = 0; i<xsf->noOfPages; i++)
2646 computeChecksum(xsf, i);
2647
2648 startWriteSchemaFile(signal);
2649 }
2650
2651 void
restart_writeSchemaConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)2652 Dbdict::restart_writeSchemaConf(Signal * signal,
2653 Uint32 callbackData,
2654 Uint32 returnCode){
2655
2656 if(c_systemRestart){
2657 jam();
2658 signal->theData[0] = getOwnNodeId();
2659 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_SCHEMA_INFOCONF,
2660 signal, 1, JBB);
2661 return;
2662 }
2663
2664 ndbrequire(c_nodeRestart || c_initialNodeRestart);
2665 c_blockState = BS_IDLE;
2666 activateIndexes(signal, 0);
2667 return;
2668 }
2669
execSCHEMA_INFOCONF(Signal * signal)2670 void Dbdict::execSCHEMA_INFOCONF(Signal* signal)
2671 {
2672 jamEntry();
2673 ndbrequire(signal->getNoOfSections() == 0);
2674
2675 /* ---------------------------------------------------------------- */
2676 // This signal is received in the master as part of system restart
2677 // from all nodes (including the master) after they have synchronised
2678 // their data with the master node's schema information.
2679 /* ---------------------------------------------------------------- */
2680 const Uint32 nodeId = signal->theData[0];
2681 c_sendSchemaRecord.m_SCHEMAINFO_Counter.clearWaitingFor(nodeId);
2682
2683 if (!c_sendSchemaRecord.m_SCHEMAINFO_Counter.done()){
2684 jam();
2685 return;
2686 }//if
2687 activateIndexes(signal, 0);
2688 }//execSCHEMA_INFOCONF()
2689
2690 static bool
checkSchemaStatus(Uint32 tableType,Uint32 pass)2691 checkSchemaStatus(Uint32 tableType, Uint32 pass)
2692 {
2693 switch(tableType){
2694 case DictTabInfo::UndefTableType:
2695 return true;
2696 case DictTabInfo::HashIndexTrigger:
2697 case DictTabInfo::SubscriptionTrigger:
2698 case DictTabInfo::ReadOnlyConstraint:
2699 case DictTabInfo::IndexTrigger:
2700 return false;
2701 case DictTabInfo::LogfileGroup:
2702 return pass == 0 || pass == 9 || pass == 10;
2703 case DictTabInfo::Tablespace:
2704 return pass == 1 || pass == 8 || pass == 11;
2705 case DictTabInfo::Datafile:
2706 case DictTabInfo::Undofile:
2707 return pass == 2 || pass == 7 || pass == 12;
2708 case DictTabInfo::SystemTable:
2709 case DictTabInfo::UserTable:
2710 return /* pass == 3 || pass == 6 || */ pass == 13;
2711 case DictTabInfo::UniqueHashIndex:
2712 case DictTabInfo::HashIndex:
2713 case DictTabInfo::UniqueOrderedIndex:
2714 case DictTabInfo::OrderedIndex:
2715 return /* pass == 4 || pass == 5 || */ pass == 14;
2716 }
2717
2718 return false;
2719 }
2720
2721 static const Uint32 CREATE_OLD_PASS = 4;
2722 static const Uint32 DROP_OLD_PASS = 9;
2723 static const Uint32 CREATE_NEW_PASS = 14;
2724 static const Uint32 LAST_PASS = 14;
2725
2726 NdbOut&
operator <<(NdbOut & out,const SchemaFile::TableEntry entry)2727 operator<<(NdbOut& out, const SchemaFile::TableEntry entry)
2728 {
2729 out << "[";
2730 out << " state: " << entry.m_tableState;
2731 out << " version: " << hex << entry.m_tableVersion << dec;
2732 out << " type: " << entry.m_tableType;
2733 out << " words: " << entry.m_info_words;
2734 out << " gcp: " << entry.m_gcp;
2735 out << " ]";
2736 return out;
2737 }
2738
2739 /**
2740 * Pass 0 Create old LogfileGroup
2741 * Pass 1 Create old Tablespace
2742 * Pass 2 Create old Datafile/Undofile
2743 * Pass 3 Create old Table // NOT DONE DUE TO DIH
2744 * Pass 4 Create old Index // NOT DONE DUE TO DIH
2745
2746 * Pass 5 Drop old Index // NOT DONE DUE TO DIH
2747 * Pass 6 Drop old Table // NOT DONE DUE TO DIH
2748 * Pass 7 Drop old Datafile/Undofile
2749 * Pass 8 Drop old Tablespace
2750 * Pass 9 Drop old Logfilegroup
2751
2752 * Pass 10 Create new LogfileGroup
2753 * Pass 11 Create new Tablespace
2754 * Pass 12 Create new Datafile/Undofile
2755 * Pass 13 Create new Table
2756 * Pass 14 Create new Index
2757 */
2758
checkSchemaStatus(Signal * signal)2759 void Dbdict::checkSchemaStatus(Signal* signal)
2760 {
2761 XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
2762 XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
2763 ndbrequire(newxsf->noOfPages == oldxsf->noOfPages);
2764 const Uint32 noOfEntries = newxsf->noOfPages * NDB_SF_PAGE_ENTRIES;
2765
2766 for (; c_restartRecord.activeTable < noOfEntries;
2767 c_restartRecord.activeTable++) {
2768 jam();
2769
2770 Uint32 tableId = c_restartRecord.activeTable;
2771 SchemaFile::TableEntry *newEntry = getTableEntry(newxsf, tableId);
2772 SchemaFile::TableEntry *oldEntry = getTableEntry(oldxsf, tableId);
2773 SchemaFile::TableState newSchemaState =
2774 (SchemaFile::TableState)newEntry->m_tableState;
2775 SchemaFile::TableState oldSchemaState =
2776 (SchemaFile::TableState)oldEntry->m_tableState;
2777
2778 if (c_restartRecord.activeTable >= c_tableRecordPool.getSize()) {
2779 jam();
2780 ndbrequire(newSchemaState == SchemaFile::INIT);
2781 ndbrequire(oldSchemaState == SchemaFile::INIT);
2782 continue;
2783 }//if
2784
2785 //#define PRINT_SCHEMA_RESTART
2786 #ifdef PRINT_SCHEMA_RESTART
2787 char buf[100];
2788 snprintf(buf, sizeof(buf), "checkSchemaStatus: pass: %d table: %d",
2789 c_restartRecord.m_pass, tableId);
2790 #endif
2791
2792 if (c_restartRecord.m_pass <= CREATE_OLD_PASS)
2793 {
2794 if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
2795 continue;
2796
2797 switch(oldSchemaState){
2798 case SchemaFile::INIT: jam();
2799 case SchemaFile::DROP_TABLE_COMMITTED: jam();
2800 case SchemaFile::ADD_STARTED: jam();
2801 case SchemaFile::DROP_TABLE_STARTED: jam();
2802 case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
2803 continue;
2804 case SchemaFile::TABLE_ADD_COMMITTED: jam();
2805 case SchemaFile::ALTER_TABLE_COMMITTED: jam();
2806 jam();
2807 #ifdef PRINT_SCHEMA_RESTART
2808 ndbout_c("%s -> restartCreateTab", buf);
2809 ndbout << *newEntry << " " << *oldEntry << endl;
2810 #endif
2811 restartCreateTab(signal, tableId, oldEntry, oldEntry, true);
2812 return;
2813 }
2814 }
2815
2816 if (c_restartRecord.m_pass <= DROP_OLD_PASS)
2817 {
2818 if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
2819 continue;
2820
2821 switch(oldSchemaState){
2822 case SchemaFile::INIT: jam();
2823 case SchemaFile::DROP_TABLE_COMMITTED: jam();
2824 case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
2825 continue;
2826 case SchemaFile::ADD_STARTED: jam();
2827 case SchemaFile::DROP_TABLE_STARTED: jam();
2828 #ifdef PRINT_SCHEMA_RESTART
2829 ndbout_c("%s -> restartDropTab", buf);
2830 ndbout << *newEntry << " " << *oldEntry << endl;
2831 #endif
2832 restartDropTab(signal, tableId, oldEntry, newEntry);
2833 return;
2834 case SchemaFile::TABLE_ADD_COMMITTED: jam();
2835 case SchemaFile::ALTER_TABLE_COMMITTED: jam();
2836 if (! (* oldEntry == * newEntry))
2837 {
2838 #ifdef PRINT_SCHEMA_RESTART
2839 ndbout_c("%s -> restartDropTab", buf);
2840 ndbout << *newEntry << " " << *oldEntry << endl;
2841 #endif
2842 restartDropTab(signal, tableId, oldEntry, newEntry);
2843 return;
2844 }
2845 continue;
2846 }
2847 }
2848
2849 if (c_restartRecord.m_pass <= CREATE_NEW_PASS)
2850 {
2851 if (!::checkSchemaStatus(newEntry->m_tableType, c_restartRecord.m_pass))
2852 continue;
2853
2854 switch(newSchemaState){
2855 case SchemaFile::INIT: jam();
2856 case SchemaFile::DROP_TABLE_COMMITTED: jam();
2857 case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
2858 * oldEntry = * newEntry;
2859 continue;
2860 case SchemaFile::ADD_STARTED: jam();
2861 case SchemaFile::DROP_TABLE_STARTED: jam();
2862 ndbrequire(DictTabInfo::isTable(newEntry->m_tableType) ||
2863 DictTabInfo::isIndex(newEntry->m_tableType));
2864 newEntry->m_tableState = SchemaFile::INIT;
2865 continue;
2866 case SchemaFile::TABLE_ADD_COMMITTED: jam();
2867 case SchemaFile::ALTER_TABLE_COMMITTED: jam();
2868 if (DictTabInfo::isIndex(newEntry->m_tableType) ||
2869 DictTabInfo::isTable(newEntry->m_tableType))
2870 {
2871 bool file = * oldEntry == *newEntry &&
2872 (!DictTabInfo::isIndex(newEntry->m_tableType) || c_systemRestart);
2873
2874 #ifdef PRINT_SCHEMA_RESTART
2875 ndbout_c("%s -> restartCreateTab (file: %d)", buf, file);
2876 ndbout << *newEntry << " " << *oldEntry << endl;
2877 #endif
2878 restartCreateTab(signal, tableId, newEntry, newEntry, file);
2879 * oldEntry = * newEntry;
2880 return;
2881 }
2882 else if (! (* oldEntry == *newEntry))
2883 {
2884 #ifdef PRINT_SCHEMA_RESTART
2885 ndbout_c("%s -> restartCreateTab", buf);
2886 ndbout << *newEntry << " " << *oldEntry << endl;
2887 #endif
2888 restartCreateTab(signal, tableId, oldEntry, newEntry, false);
2889 * oldEntry = * newEntry;
2890 return;
2891 }
2892 * oldEntry = * newEntry;
2893 continue;
2894 }
2895 }
2896 }
2897
2898 c_restartRecord.m_pass++;
2899 c_restartRecord.activeTable= 0;
2900 if(c_restartRecord.m_pass <= LAST_PASS)
2901 {
2902 checkSchemaStatus(signal);
2903 }
2904 else
2905 {
2906 execute(signal, c_schemaRecord.m_callback, 0);
2907 }
2908 }//checkSchemaStatus()
2909
2910 void
restartCreateTab(Signal * signal,Uint32 tableId,const SchemaFile::TableEntry * old_entry,const SchemaFile::TableEntry * new_entry,bool file)2911 Dbdict::restartCreateTab(Signal* signal, Uint32 tableId,
2912 const SchemaFile::TableEntry * old_entry,
2913 const SchemaFile::TableEntry * new_entry,
2914 bool file){
2915 jam();
2916
2917 switch(new_entry->m_tableType){
2918 case DictTabInfo::UndefTableType:
2919 case DictTabInfo::HashIndexTrigger:
2920 case DictTabInfo::SubscriptionTrigger:
2921 case DictTabInfo::ReadOnlyConstraint:
2922 case DictTabInfo::IndexTrigger:
2923 ndbrequire(false);
2924 case DictTabInfo::SystemTable:
2925 case DictTabInfo::UserTable:
2926 case DictTabInfo::UniqueHashIndex:
2927 case DictTabInfo::HashIndex:
2928 case DictTabInfo::UniqueOrderedIndex:
2929 case DictTabInfo::OrderedIndex:
2930 break;
2931 case DictTabInfo::Tablespace:
2932 case DictTabInfo::LogfileGroup:
2933 case DictTabInfo::Datafile:
2934 case DictTabInfo::Undofile:
2935 restartCreateObj(signal, tableId, old_entry, new_entry, file);
2936 return;
2937 }
2938
2939 CreateTableRecordPtr createTabPtr;
2940 c_opCreateTable.seize(createTabPtr);
2941 ndbrequire(!createTabPtr.isNull());
2942
2943 createTabPtr.p->key = ++c_opRecordSequence;
2944 c_opCreateTable.add(createTabPtr);
2945
2946 createTabPtr.p->m_errorCode = 0;
2947 createTabPtr.p->m_tablePtrI = tableId;
2948 createTabPtr.p->m_coordinatorRef = reference();
2949 createTabPtr.p->m_senderRef = 0;
2950 createTabPtr.p->m_senderData = RNIL;
2951 createTabPtr.p->m_tabInfoPtrI = RNIL;
2952 createTabPtr.p->m_dihAddFragPtr = RNIL;
2953
2954 if(file && !ERROR_INSERTED(6002)){
2955 jam();
2956
2957 c_readTableRecord.no_of_words = old_entry->m_info_words;
2958 c_readTableRecord.pageId = 0;
2959 c_readTableRecord.m_callback.m_callbackData = createTabPtr.p->key;
2960 c_readTableRecord.m_callback.m_callbackFunction =
2961 safe_cast(&Dbdict::restartCreateTab_readTableConf);
2962
2963 startReadTableFile(signal, tableId);
2964 return;
2965 } else {
2966
2967 ndbrequire(c_masterNodeId != getOwnNodeId());
2968
2969 /**
2970 * Get from master
2971 */
2972 GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
2973 req->senderRef = reference();
2974 req->senderData = createTabPtr.p->key;
2975 req->requestType = GetTabInfoReq::RequestById |
2976 GetTabInfoReq::LongSignalConf;
2977 req->tableId = tableId;
2978 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
2979 GetTabInfoReq::SignalLength, JBB);
2980
2981 if(ERROR_INSERTED(6002)){
2982 NdbSleep_MilliSleep(10);
2983 CRASH_INSERTION(6002);
2984 }
2985 }
2986 }
2987
2988 void
restartCreateTab_readTableConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)2989 Dbdict::restartCreateTab_readTableConf(Signal* signal,
2990 Uint32 callbackData,
2991 Uint32 returnCode){
2992 jam();
2993
2994 PageRecordPtr pageRecPtr;
2995 c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
2996
2997 ParseDictTabInfoRecord parseRecord;
2998 parseRecord.requestType = DictTabInfo::GetTabInfoConf;
2999 parseRecord.errorCode = 0;
3000
3001 Uint32 sz = c_readTableRecord.no_of_words;
3002 SimplePropertiesLinearReader r(pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz);
3003 handleTabInfoInit(r, &parseRecord);
3004 if (parseRecord.errorCode != 0)
3005 {
3006 char buf[255];
3007 BaseString::snprintf(buf, sizeof(buf),
3008 "Unable to restart, fail while creating table %d"
3009 " error: %d. Most likely change of configuration",
3010 c_readTableRecord.tableId,
3011 parseRecord.errorCode);
3012 progError(__LINE__,
3013 NDBD_EXIT_INVALID_CONFIG,
3014 buf);
3015 ndbrequire(parseRecord.errorCode == 0);
3016 }
3017
3018 /* ---------------------------------------------------------------- */
3019 // We have read the table description from disk as part of system restart.
3020 // We will also write it back again to ensure that both copies are ok.
3021 /* ---------------------------------------------------------------- */
3022 ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
3023 c_writeTableRecord.no_of_words = c_readTableRecord.no_of_words;
3024 c_writeTableRecord.pageId = c_readTableRecord.pageId;
3025 c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
3026 c_writeTableRecord.m_callback.m_callbackData = callbackData;
3027 c_writeTableRecord.m_callback.m_callbackFunction =
3028 safe_cast(&Dbdict::restartCreateTab_writeTableConf);
3029 startWriteTableFile(signal, c_readTableRecord.tableId);
3030 }
3031
3032 void
execGET_TABINFO_CONF(Signal * signal)3033 Dbdict::execGET_TABINFO_CONF(Signal* signal){
3034 jamEntry();
3035
3036 if(!assembleFragments(signal)){
3037 jam();
3038 return;
3039 }
3040
3041 GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
3042
3043 switch(conf->tableType){
3044 case DictTabInfo::UndefTableType:
3045 case DictTabInfo::HashIndexTrigger:
3046 case DictTabInfo::SubscriptionTrigger:
3047 case DictTabInfo::ReadOnlyConstraint:
3048 case DictTabInfo::IndexTrigger:
3049 ndbrequire(false);
3050 case DictTabInfo::SystemTable:
3051 case DictTabInfo::UserTable:
3052 case DictTabInfo::UniqueHashIndex:
3053 case DictTabInfo::HashIndex:
3054 case DictTabInfo::UniqueOrderedIndex:
3055 case DictTabInfo::OrderedIndex:
3056 break;
3057 case DictTabInfo::Tablespace:
3058 case DictTabInfo::LogfileGroup:
3059 case DictTabInfo::Datafile:
3060 case DictTabInfo::Undofile:
3061 if(refToBlock(conf->senderRef) == TSMAN
3062 && (refToNode(conf->senderRef) == 0
3063 || refToNode(conf->senderRef) == getOwnNodeId()))
3064 {
3065 jam();
3066 FilePtr fg_ptr;
3067 ndbrequire(c_file_hash.find(fg_ptr, conf->tableId));
3068 const Uint32 free_extents= conf->freeExtents;
3069 const Uint32 id= conf->tableId;
3070 const Uint32 type= conf->tableType;
3071 const Uint32 data= conf->senderData;
3072 signal->theData[0]= ZPACK_TABLE_INTO_PAGES;
3073 signal->theData[1]= id;
3074 signal->theData[2]= type;
3075 signal->theData[3]= data;
3076 signal->theData[4]= free_extents;
3077 sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
3078 }
3079 else if(refToBlock(conf->senderRef) == LGMAN
3080 && (refToNode(conf->senderRef) == 0
3081 || refToNode(conf->senderRef) == getOwnNodeId()))
3082 {
3083 jam();
3084 FilegroupPtr fg_ptr;
3085 ndbrequire(c_filegroup_hash.find(fg_ptr, conf->tableId));
3086 const Uint32 free_hi= conf->freeWordsHi;
3087 const Uint32 free_lo= conf->freeWordsLo;
3088 const Uint32 id= conf->tableId;
3089 const Uint32 type= conf->tableType;
3090 const Uint32 data= conf->senderData;
3091 signal->theData[0]= ZPACK_TABLE_INTO_PAGES;
3092 signal->theData[1]= id;
3093 signal->theData[2]= type;
3094 signal->theData[3]= data;
3095 signal->theData[4]= free_hi;
3096 signal->theData[5]= free_lo;
3097 sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
3098 }
3099 else
3100 {
3101 jam();
3102 restartCreateObj_getTabInfoConf(signal);
3103 }
3104 return;
3105 }
3106
3107 const Uint32 tableId = conf->tableId;
3108 const Uint32 senderData = conf->senderData;
3109
3110 SegmentedSectionPtr tabInfoPtr;
3111 signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
3112
3113 CreateTableRecordPtr createTabPtr;
3114 ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
3115 ndbrequire(!createTabPtr.isNull());
3116 ndbrequire(createTabPtr.p->m_tablePtrI == tableId);
3117
3118 /**
3119 * Put data into table record
3120 */
3121 ParseDictTabInfoRecord parseRecord;
3122 parseRecord.requestType = DictTabInfo::GetTabInfoConf;
3123 parseRecord.errorCode = 0;
3124
3125 SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
3126 handleTabInfoInit(r, &parseRecord);
3127 ndbrequire(parseRecord.errorCode == 0);
3128
3129 // save to disk
3130
3131 ndbrequire(tableId < c_tableRecordPool.getSize());
3132 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
3133 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
3134 tableEntry->m_info_words= tabInfoPtr.sz;
3135
3136 Callback callback;
3137 callback.m_callbackData = createTabPtr.p->key;
3138 callback.m_callbackFunction =
3139 safe_cast(&Dbdict::restartCreateTab_writeTableConf);
3140
3141 signal->header.m_noOfSections = 0;
3142 writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
3143 signal->setSection(tabInfoPtr, 0);
3144 releaseSections(signal);
3145 }
3146
3147 void
restartCreateTab_writeTableConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)3148 Dbdict::restartCreateTab_writeTableConf(Signal* signal,
3149 Uint32 callbackData,
3150 Uint32 returnCode){
3151 jam();
3152
3153 CreateTableRecordPtr createTabPtr;
3154 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
3155
3156 Callback callback;
3157 callback.m_callbackData = callbackData;
3158 callback.m_callbackFunction =
3159 safe_cast(&Dbdict::restartCreateTab_dihComplete);
3160
3161 SegmentedSectionPtr fragDataPtr;
3162 fragDataPtr.sz = 0;
3163 fragDataPtr.setNull();
3164 createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
3165 }
3166
3167 void
restartCreateTab_dihComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)3168 Dbdict::restartCreateTab_dihComplete(Signal* signal,
3169 Uint32 callbackData,
3170 Uint32 returnCode){
3171 jam();
3172
3173 CreateTableRecordPtr createTabPtr;
3174 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
3175
3176 if(createTabPtr.p->m_errorCode)
3177 {
3178 char buf[100];
3179 BaseString::snprintf(buf, sizeof(buf), "Failed to create table during"
3180 " restart, Error: %u",
3181 createTabPtr.p->m_errorCode);
3182 progError(__LINE__, NDBD_EXIT_RESOURCE_ALLOC_ERROR, buf);
3183 }
3184
3185 Callback callback;
3186 callback.m_callbackData = callbackData;
3187 callback.m_callbackFunction =
3188 safe_cast(&Dbdict::restartCreateTab_activateComplete);
3189
3190 alterTab_activate(signal, createTabPtr, &callback);
3191 }
3192
3193 void
restartCreateTab_activateComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)3194 Dbdict::restartCreateTab_activateComplete(Signal* signal,
3195 Uint32 callbackData,
3196 Uint32 returnCode){
3197 jam();
3198
3199 CreateTableRecordPtr createTabPtr;
3200 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
3201
3202 TableRecordPtr tabPtr;
3203 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
3204 tabPtr.p->tabState = TableRecord::DEFINED;
3205
3206 releaseCreateTableOp(signal,createTabPtr);
3207
3208 c_restartRecord.activeTable++;
3209 checkSchemaStatus(signal);
3210 }
3211
3212 void
releaseCreateTableOp(Signal * signal,CreateTableRecordPtr createTabPtr)3213 Dbdict::releaseCreateTableOp(Signal* signal, CreateTableRecordPtr createTabPtr)
3214 {
3215 if (createTabPtr.p->m_tabInfoPtrI != RNIL)
3216 {
3217 jam();
3218 SegmentedSectionPtr tabInfoPtr;
3219 getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
3220 signal->setSection(tabInfoPtr, 0);
3221 releaseSections(signal);
3222 }
3223 c_opCreateTable.release(createTabPtr);
3224 }
3225
3226 void
restartDropTab(Signal * signal,Uint32 tableId,const SchemaFile::TableEntry * old_entry,const SchemaFile::TableEntry * new_entry)3227 Dbdict::restartDropTab(Signal* signal, Uint32 tableId,
3228 const SchemaFile::TableEntry * old_entry,
3229 const SchemaFile::TableEntry * new_entry)
3230 {
3231 switch(old_entry->m_tableType){
3232 case DictTabInfo::UndefTableType:
3233 case DictTabInfo::HashIndexTrigger:
3234 case DictTabInfo::SubscriptionTrigger:
3235 case DictTabInfo::ReadOnlyConstraint:
3236 case DictTabInfo::IndexTrigger:
3237 ndbrequire(false);
3238 case DictTabInfo::SystemTable:
3239 case DictTabInfo::UserTable:
3240 case DictTabInfo::UniqueHashIndex:
3241 case DictTabInfo::HashIndex:
3242 case DictTabInfo::UniqueOrderedIndex:
3243 case DictTabInfo::OrderedIndex:
3244 break;
3245 case DictTabInfo::Tablespace:
3246 case DictTabInfo::LogfileGroup:
3247 case DictTabInfo::Datafile:
3248 case DictTabInfo::Undofile:
3249 restartDropObj(signal, tableId, old_entry);
3250 return;
3251 }
3252
3253 const Uint32 key = ++c_opRecordSequence;
3254
3255 DropTableRecordPtr dropTabPtr;
3256 ndbrequire(c_opDropTable.seize(dropTabPtr));
3257
3258 dropTabPtr.p->key = key;
3259 c_opDropTable.add(dropTabPtr);
3260
3261 dropTabPtr.p->m_errorCode = 0;
3262 dropTabPtr.p->m_request.tableId = tableId;
3263 dropTabPtr.p->m_coordinatorRef = 0;
3264 dropTabPtr.p->m_requestType = DropTabReq::RestartDropTab;
3265 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
3266
3267 dropTabPtr.p->m_participantData.m_block = 0;
3268 dropTabPtr.p->m_participantData.m_callback.m_callbackData = key;
3269 dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
3270 safe_cast(&Dbdict::restartDropTab_complete);
3271 dropTab_nextStep(signal, dropTabPtr);
3272 }
3273
3274 void
restartDropTab_complete(Signal * signal,Uint32 callbackData,Uint32 returnCode)3275 Dbdict::restartDropTab_complete(Signal* signal,
3276 Uint32 callbackData,
3277 Uint32 returnCode){
3278 jam();
3279
3280 DropTableRecordPtr dropTabPtr;
3281 ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
3282
3283 //@todo check error
3284
3285 releaseTableObject(c_restartRecord.activeTable);
3286 c_opDropTable.release(dropTabPtr);
3287
3288 c_restartRecord.activeTable++;
3289 checkSchemaStatus(signal);
3290 }
3291
3292 /**
3293 * Create Obj during NR/SR
3294 */
3295 void
restartCreateObj(Signal * signal,Uint32 tableId,const SchemaFile::TableEntry * old_entry,const SchemaFile::TableEntry * new_entry,bool file)3296 Dbdict::restartCreateObj(Signal* signal,
3297 Uint32 tableId,
3298 const SchemaFile::TableEntry * old_entry,
3299 const SchemaFile::TableEntry * new_entry,
3300 bool file){
3301 jam();
3302
3303 CreateObjRecordPtr createObjPtr;
3304 ndbrequire(c_opCreateObj.seize(createObjPtr));
3305
3306 const Uint32 key = ++c_opRecordSequence;
3307 createObjPtr.p->key = key;
3308 c_opCreateObj.add(createObjPtr);
3309 createObjPtr.p->m_errorCode = 0;
3310 createObjPtr.p->m_senderRef = reference();
3311 createObjPtr.p->m_senderData = tableId;
3312 createObjPtr.p->m_clientRef = reference();
3313 createObjPtr.p->m_clientData = tableId;
3314
3315 createObjPtr.p->m_obj_id = tableId;
3316 createObjPtr.p->m_obj_type = new_entry->m_tableType;
3317 createObjPtr.p->m_obj_version = new_entry->m_tableVersion;
3318
3319 createObjPtr.p->m_callback.m_callbackData = key;
3320 createObjPtr.p->m_callback.m_callbackFunction=
3321 safe_cast(&Dbdict::restartCreateObj_prepare_start_done);
3322
3323 createObjPtr.p->m_restart= file ? 1 : 2;
3324 switch(new_entry->m_tableType){
3325 case DictTabInfo::Tablespace:
3326 case DictTabInfo::LogfileGroup:
3327 createObjPtr.p->m_vt_index = 0;
3328 break;
3329 case DictTabInfo::Datafile:
3330 case DictTabInfo::Undofile:
3331 createObjPtr.p->m_vt_index = 1;
3332 break;
3333 default:
3334 ndbrequire(false);
3335 }
3336
3337 createObjPtr.p->m_obj_info_ptr_i = RNIL;
3338 if(file)
3339 {
3340 c_readTableRecord.no_of_words = old_entry->m_info_words;
3341 c_readTableRecord.pageId = 0;
3342 c_readTableRecord.m_callback.m_callbackData = key;
3343 c_readTableRecord.m_callback.m_callbackFunction =
3344 safe_cast(&Dbdict::restartCreateObj_readConf);
3345
3346 startReadTableFile(signal, tableId);
3347 }
3348 else
3349 {
3350 /**
3351 * Get from master
3352 */
3353 GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
3354 req->senderRef = reference();
3355 req->senderData = key;
3356 req->requestType = GetTabInfoReq::RequestById |
3357 GetTabInfoReq::LongSignalConf;
3358 req->tableId = tableId;
3359 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
3360 GetTabInfoReq::SignalLength, JBB);
3361 }
3362 }
3363
3364 void
restartCreateObj_getTabInfoConf(Signal * signal)3365 Dbdict::restartCreateObj_getTabInfoConf(Signal* signal)
3366 {
3367 jam();
3368
3369 GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
3370
3371 const Uint32 objId = conf->tableId;
3372 const Uint32 senderData = conf->senderData;
3373
3374 SegmentedSectionPtr objInfoPtr;
3375 signal->getSection(objInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
3376
3377 CreateObjRecordPtr createObjPtr;
3378 ndbrequire(c_opCreateObj.find(createObjPtr, senderData));
3379 ndbrequire(createObjPtr.p->m_obj_id == objId);
3380
3381 createObjPtr.p->m_obj_info_ptr_i= objInfoPtr.i;
3382 signal->header.m_noOfSections = 0;
3383
3384 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
3385 (signal, createObjPtr.p);
3386 }
3387
3388 void
restartCreateObj_readConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)3389 Dbdict::restartCreateObj_readConf(Signal* signal,
3390 Uint32 callbackData,
3391 Uint32 returnCode)
3392 {
3393 jam();
3394 ndbrequire(returnCode == 0);
3395 CreateObjRecordPtr createObjPtr;
3396 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
3397 ndbrequire(createObjPtr.p->m_errorCode == 0);
3398
3399 PageRecordPtr pageRecPtr;
3400 c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
3401
3402 Uint32 sz = c_readTableRecord.no_of_words;
3403
3404 Ptr<SectionSegment> ptr;
3405 ndbrequire(import(ptr, pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz));
3406 createObjPtr.p->m_obj_info_ptr_i= ptr.i;
3407
3408 if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
3409 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
3410 (signal, createObjPtr.p);
3411 else
3412 execute(signal, createObjPtr.p->m_callback, 0);
3413 }
3414
3415 void
restartCreateObj_prepare_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3416 Dbdict::restartCreateObj_prepare_start_done(Signal* signal,
3417 Uint32 callbackData,
3418 Uint32 returnCode)
3419 {
3420 jam();
3421 ndbrequire(returnCode == 0);
3422 CreateObjRecordPtr createObjPtr;
3423 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
3424 ndbrequire(createObjPtr.p->m_errorCode == 0);
3425
3426 Callback callback;
3427 callback.m_callbackData = callbackData;
3428 callback.m_callbackFunction =
3429 safe_cast(&Dbdict::restartCreateObj_write_complete);
3430
3431 SegmentedSectionPtr objInfoPtr;
3432 getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
3433
3434 writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
3435 }
3436
3437 void
restartCreateObj_write_complete(Signal * signal,Uint32 callbackData,Uint32 returnCode)3438 Dbdict::restartCreateObj_write_complete(Signal* signal,
3439 Uint32 callbackData,
3440 Uint32 returnCode)
3441 {
3442 ndbrequire(returnCode == 0);
3443 CreateObjRecordPtr createObjPtr;
3444 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
3445 ndbrequire(createObjPtr.p->m_errorCode == 0);
3446
3447 SegmentedSectionPtr objInfoPtr;
3448 getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
3449 signal->setSection(objInfoPtr, 0);
3450 releaseSections(signal);
3451 createObjPtr.p->m_obj_info_ptr_i = RNIL;
3452
3453 createObjPtr.p->m_callback.m_callbackFunction =
3454 safe_cast(&Dbdict::restartCreateObj_prepare_complete_done);
3455
3456 if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
3457 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
3458 (signal, createObjPtr.p);
3459 else
3460 execute(signal, createObjPtr.p->m_callback, 0);
3461 }
3462
3463 void
restartCreateObj_prepare_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3464 Dbdict::restartCreateObj_prepare_complete_done(Signal* signal,
3465 Uint32 callbackData,
3466 Uint32 returnCode)
3467 {
3468 jam();
3469 ndbrequire(returnCode == 0);
3470 CreateObjRecordPtr createObjPtr;
3471 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
3472 ndbrequire(createObjPtr.p->m_errorCode == 0);
3473
3474 createObjPtr.p->m_callback.m_callbackFunction =
3475 safe_cast(&Dbdict::restartCreateObj_commit_start_done);
3476
3477 if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
3478 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
3479 (signal, createObjPtr.p);
3480 else
3481 execute(signal, createObjPtr.p->m_callback, 0);
3482 }
3483
3484 void
restartCreateObj_commit_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3485 Dbdict::restartCreateObj_commit_start_done(Signal* signal,
3486 Uint32 callbackData,
3487 Uint32 returnCode)
3488 {
3489 jam();
3490 ndbrequire(returnCode == 0);
3491 CreateObjRecordPtr createObjPtr;
3492 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
3493 ndbrequire(createObjPtr.p->m_errorCode == 0);
3494
3495 createObjPtr.p->m_callback.m_callbackFunction =
3496 safe_cast(&Dbdict::restartCreateObj_commit_complete_done);
3497
3498 if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
3499 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
3500 (signal, createObjPtr.p);
3501 else
3502 execute(signal, createObjPtr.p->m_callback, 0);
3503 }
3504
3505
3506 void
restartCreateObj_commit_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3507 Dbdict::restartCreateObj_commit_complete_done(Signal* signal,
3508 Uint32 callbackData,
3509 Uint32 returnCode)
3510 {
3511 jam();
3512 ndbrequire(returnCode == 0);
3513 CreateObjRecordPtr createObjPtr;
3514 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
3515 ndbrequire(createObjPtr.p->m_errorCode == 0);
3516
3517 c_opCreateObj.release(createObjPtr);
3518
3519 c_restartRecord.activeTable++;
3520 checkSchemaStatus(signal);
3521 }
3522
3523 /**
3524 * Drop object during NR/SR
3525 */
3526 void
restartDropObj(Signal * signal,Uint32 tableId,const SchemaFile::TableEntry * entry)3527 Dbdict::restartDropObj(Signal* signal,
3528 Uint32 tableId,
3529 const SchemaFile::TableEntry * entry)
3530 {
3531 jam();
3532
3533 DropObjRecordPtr dropObjPtr;
3534 ndbrequire(c_opDropObj.seize(dropObjPtr));
3535
3536 const Uint32 key = ++c_opRecordSequence;
3537 dropObjPtr.p->key = key;
3538 c_opDropObj.add(dropObjPtr);
3539 dropObjPtr.p->m_errorCode = 0;
3540 dropObjPtr.p->m_senderRef = reference();
3541 dropObjPtr.p->m_senderData = tableId;
3542 dropObjPtr.p->m_clientRef = reference();
3543 dropObjPtr.p->m_clientData = tableId;
3544
3545 dropObjPtr.p->m_obj_id = tableId;
3546 dropObjPtr.p->m_obj_type = entry->m_tableType;
3547 dropObjPtr.p->m_obj_version = entry->m_tableVersion;
3548
3549 dropObjPtr.p->m_callback.m_callbackData = key;
3550 dropObjPtr.p->m_callback.m_callbackFunction=
3551 safe_cast(&Dbdict::restartDropObj_prepare_start_done);
3552
3553 ndbout_c("Dropping %d %d", tableId, entry->m_tableType);
3554 switch(entry->m_tableType){
3555 case DictTabInfo::Tablespace:
3556 case DictTabInfo::LogfileGroup:{
3557 jam();
3558 Ptr<Filegroup> fg_ptr;
3559 ndbrequire(c_filegroup_hash.find(fg_ptr, tableId));
3560 dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
3561 dropObjPtr.p->m_vt_index = 3;
3562 break;
3563 }
3564 case DictTabInfo::Datafile:{
3565 jam();
3566 Ptr<File> file_ptr;
3567 dropObjPtr.p->m_vt_index = 2;
3568 ndbrequire(c_file_hash.find(file_ptr, tableId));
3569 dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
3570 break;
3571 }
3572 case DictTabInfo::Undofile:{
3573 jam();
3574 Ptr<File> file_ptr;
3575 dropObjPtr.p->m_vt_index = 4;
3576 ndbrequire(c_file_hash.find(file_ptr, tableId));
3577 dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
3578
3579 /**
3580 * Undofiles are only removed from logfile groups file list
3581 * as drop undofile is currently not supported...
3582 * file will be dropped by lgman when dropping filegroup
3583 */
3584 dropObjPtr.p->m_callback.m_callbackFunction=
3585 safe_cast(&Dbdict::restartDropObj_commit_complete_done);
3586
3587 if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
3588 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
3589 (signal, dropObjPtr.p);
3590 else
3591 execute(signal, dropObjPtr.p->m_callback, 0);
3592 return;
3593 }
3594 default:
3595 jamLine(entry->m_tableType);
3596 ndbrequire(false);
3597 }
3598
3599 if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
3600 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
3601 (signal, dropObjPtr.p);
3602 else
3603 execute(signal, dropObjPtr.p->m_callback, 0);
3604 }
3605
3606 void
restartDropObj_prepare_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3607 Dbdict::restartDropObj_prepare_start_done(Signal* signal,
3608 Uint32 callbackData,
3609 Uint32 returnCode)
3610 {
3611 jam();
3612 ndbrequire(returnCode == 0);
3613 DropObjRecordPtr dropObjPtr;
3614 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
3615 ndbrequire(dropObjPtr.p->m_errorCode == 0);
3616
3617 dropObjPtr.p->m_callback.m_callbackFunction =
3618 safe_cast(&Dbdict::restartDropObj_prepare_complete_done);
3619
3620 if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
3621 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
3622 (signal, dropObjPtr.p);
3623 else
3624 execute(signal, dropObjPtr.p->m_callback, 0);
3625 }
3626
3627 void
restartDropObj_prepare_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3628 Dbdict::restartDropObj_prepare_complete_done(Signal* signal,
3629 Uint32 callbackData,
3630 Uint32 returnCode)
3631 {
3632 jam();
3633 ndbrequire(returnCode == 0);
3634 DropObjRecordPtr dropObjPtr;
3635 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
3636 ndbrequire(dropObjPtr.p->m_errorCode == 0);
3637
3638 dropObjPtr.p->m_callback.m_callbackFunction =
3639 safe_cast(&Dbdict::restartDropObj_commit_start_done);
3640
3641 if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start)
3642 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start)
3643 (signal, dropObjPtr.p);
3644 else
3645 execute(signal, dropObjPtr.p->m_callback, 0);
3646 }
3647
3648 void
restartDropObj_commit_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3649 Dbdict::restartDropObj_commit_start_done(Signal* signal,
3650 Uint32 callbackData,
3651 Uint32 returnCode)
3652 {
3653 jam();
3654 ndbrequire(returnCode == 0);
3655 DropObjRecordPtr dropObjPtr;
3656 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
3657 ndbrequire(dropObjPtr.p->m_errorCode == 0);
3658
3659 dropObjPtr.p->m_callback.m_callbackFunction =
3660 safe_cast(&Dbdict::restartDropObj_commit_complete_done);
3661
3662 if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
3663 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
3664 (signal, dropObjPtr.p);
3665 else
3666 execute(signal, dropObjPtr.p->m_callback, 0);
3667 }
3668
3669
3670 void
restartDropObj_commit_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)3671 Dbdict::restartDropObj_commit_complete_done(Signal* signal,
3672 Uint32 callbackData,
3673 Uint32 returnCode)
3674 {
3675 jam();
3676 ndbrequire(returnCode == 0);
3677 DropObjRecordPtr dropObjPtr;
3678 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
3679 ndbrequire(dropObjPtr.p->m_errorCode == 0);
3680
3681 c_opDropObj.release(dropObjPtr);
3682
3683 c_restartRecord.activeTable++;
3684 checkSchemaStatus(signal);
3685 }
3686
3687 /* **************************************************************** */
3688 /* ---------------------------------------------------------------- */
3689 /* MODULE: NODE FAILURE HANDLING ------------------------- */
3690 /* ---------------------------------------------------------------- */
3691 /* */
3692 /* This module contains the code that is used when nodes */
3693 /* (kernel/api) fails. */
3694 /* ---------------------------------------------------------------- */
3695 /* **************************************************************** */
3696
3697 /* ---------------------------------------------------------------- */
3698 // We receive a report of an API that failed.
3699 /* ---------------------------------------------------------------- */
execAPI_FAILREQ(Signal * signal)3700 void Dbdict::execAPI_FAILREQ(Signal* signal)
3701 {
3702 jamEntry();
3703 Uint32 failedApiNode = signal->theData[0];
3704 BlockReference retRef = signal->theData[1];
3705
3706 #if 0
3707 Uint32 userNode = refToNode(c_connRecord.userBlockRef);
3708 if (userNode == failedApiNode) {
3709 jam();
3710 c_connRecord.userBlockRef = (Uint32)-1;
3711 }//if
3712 #endif
3713
3714 signal->theData[0] = failedApiNode;
3715 signal->theData[1] = reference();
3716 sendSignal(retRef, GSN_API_FAILCONF, signal, 2, JBB);
3717 }//execAPI_FAILREQ()
3718
3719 /* ---------------------------------------------------------------- */
3720 // We receive a report of one or more node failures of kernel nodes.
3721 /* ---------------------------------------------------------------- */
execNODE_FAILREP(Signal * signal)3722 void Dbdict::execNODE_FAILREP(Signal* signal)
3723 {
3724 jamEntry();
3725 NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
3726
3727 c_failureNr = nodeFail->failNo;
3728 const Uint32 numberOfFailedNodes = nodeFail->noOfNodes;
3729 const bool masterFailed = (c_masterNodeId != nodeFail->masterNodeId);
3730 c_masterNodeId = nodeFail->masterNodeId;
3731
3732 c_noNodesFailed += numberOfFailedNodes;
3733 Uint32 theFailedNodes[NodeBitmask::Size];
3734 memcpy(theFailedNodes, nodeFail->theNodes, sizeof(theFailedNodes));
3735
3736 c_counterMgr.execNODE_FAILREP(signal);
3737
3738 bool ok = false;
3739 switch(c_blockState){
3740 case BS_IDLE:
3741 jam();
3742 ok = true;
3743 if(c_opRecordPool.getSize() !=
3744 (c_opRecordPool.getNoOfFree() +
3745 c_opSubEvent.get_count() + c_opCreateEvent.get_count() +
3746 c_opDropEvent.get_count() + c_opSignalUtil.get_count()))
3747 {
3748 jam();
3749 c_blockState = BS_NODE_FAILURE;
3750 }
3751 break;
3752 case BS_CREATE_TAB:
3753 jam();
3754 ok = true;
3755 if(!masterFailed)
3756 break;
3757 // fall through
3758 case BS_BUSY:
3759 case BS_NODE_FAILURE:
3760 jam();
3761 c_blockState = BS_NODE_FAILURE;
3762 ok = true;
3763 break;
3764 case BS_NODE_RESTART:
3765 jam();
3766 ok = true;
3767 break;
3768 }
3769 ndbrequire(ok);
3770
3771 for(unsigned i = 1; i < MAX_NDB_NODES; i++) {
3772 jam();
3773 if(NodeBitmask::get(theFailedNodes, i)) {
3774 jam();
3775 NodeRecordPtr nodePtr;
3776 c_nodes.getPtr(nodePtr, i);
3777
3778 nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
3779 NFCompleteRep * const nfCompRep = (NFCompleteRep *)&signal->theData[0];
3780 nfCompRep->blockNo = DBDICT;
3781 nfCompRep->nodeId = getOwnNodeId();
3782 nfCompRep->failedNodeId = nodePtr.i;
3783 sendSignal(DBDIH_REF, GSN_NF_COMPLETEREP, signal,
3784 NFCompleteRep::SignalLength, JBB);
3785
3786 c_aliveNodes.clear(i);
3787 }//if
3788 }//for
3789
3790 /*
3791 * NODE_FAILREP guarantees that no "in flight" signal from
3792 * a dead node is accepted, and also that the job buffer contains
3793 * no such (un-executed) signals. Therefore no DICT_UNLOCK_ORD
3794 * from a dead node (leading to master crash) is possible after
3795 * this clean-up removes the lock record.
3796 */
3797 removeStaleDictLocks(signal, theFailedNodes);
3798
3799 }//execNODE_FAILREP()
3800
3801
3802 /* **************************************************************** */
3803 /* ---------------------------------------------------------------- */
3804 /* MODULE: NODE START HANDLING --------------------------- */
3805 /* ---------------------------------------------------------------- */
3806 /* */
3807 /* This module contains the code that is used when kernel nodes */
3808 /* starts. */
3809 /* ---------------------------------------------------------------- */
3810 /* **************************************************************** */
3811
3812 /* ---------------------------------------------------------------- */
3813 // Include a starting node in list of nodes to be part of adding
3814 // and dropping tables.
3815 /* ---------------------------------------------------------------- */
execINCL_NODEREQ(Signal * signal)3816 void Dbdict::execINCL_NODEREQ(Signal* signal)
3817 {
3818 jamEntry();
3819 NodeRecordPtr nodePtr;
3820 BlockReference retRef = signal->theData[0];
3821 nodePtr.i = signal->theData[1];
3822
3823 ndbrequire(c_noNodesFailed > 0);
3824 c_noNodesFailed--;
3825
3826 c_nodes.getPtr(nodePtr);
3827 ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD);
3828 nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
3829 signal->theData[0] = nodePtr.i;
3830 signal->theData[1] = reference();
3831 sendSignal(retRef, GSN_INCL_NODECONF, signal, 2, JBB);
3832
3833 c_aliveNodes.set(nodePtr.i);
3834 }//execINCL_NODEREQ()
3835
3836 /* **************************************************************** */
3837 /* ---------------------------------------------------------------- */
3838 /* MODULE: ADD TABLE HANDLING ---------------------------- */
3839 /* ---------------------------------------------------------------- */
3840 /* */
3841 /* This module contains the code that is used when adding a table. */
3842 /* ---------------------------------------------------------------- */
3843 /* **************************************************************** */
3844
3845 /* ---------------------------------------------------------------- */
3846 // This signal receives information about a table from either:
3847 // API, Ndbcntr or from other DICT.
3848 /* ---------------------------------------------------------------- */
3849 void
execCREATE_TABLE_REQ(Signal * signal)3850 Dbdict::execCREATE_TABLE_REQ(Signal* signal){
3851 jamEntry();
3852 if(!assembleFragments(signal)){
3853 return;
3854 }
3855
3856 CreateTableReq* const req = (CreateTableReq*)signal->getDataPtr();
3857 const Uint32 senderRef = req->senderRef;
3858 const Uint32 senderData = req->senderData;
3859
3860 ParseDictTabInfoRecord parseRecord;
3861 do {
3862 if(getOwnNodeId() != c_masterNodeId){
3863 jam();
3864 parseRecord.errorCode = CreateTableRef::NotMaster;
3865 break;
3866 }
3867
3868 if (c_blockState == BS_NODE_RESTART){
3869 jam();
3870 parseRecord.errorCode = CreateTableRef::BusyWithNR;
3871 break;
3872 }
3873
3874 if (c_blockState != BS_IDLE){
3875 jam();
3876 parseRecord.errorCode = CreateTableRef::Busy;
3877 break;
3878 }
3879
3880 if (checkSingleUserMode(signal->getSendersBlockRef()))
3881 {
3882 jam();
3883 parseRecord.errorCode = CreateTableRef::SingleUser;
3884 break;
3885 }
3886
3887 CreateTableRecordPtr createTabPtr;
3888 c_opCreateTable.seize(createTabPtr);
3889
3890 if(createTabPtr.isNull()){
3891 jam();
3892 parseRecord.errorCode = CreateTableRef::Busy;
3893 break;
3894 }
3895
3896 parseRecord.requestType = DictTabInfo::CreateTableFromAPI;
3897 parseRecord.errorCode = 0;
3898
3899 SegmentedSectionPtr ptr;
3900 signal->getSection(ptr, CreateTableReq::DICT_TAB_INFO);
3901 SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
3902
3903 handleTabInfoInit(r, &parseRecord);
3904 releaseSections(signal);
3905
3906 if(parseRecord.errorCode != 0){
3907 jam();
3908 c_opCreateTable.release(createTabPtr);
3909 break;
3910 }
3911
3912 createTabPtr.p->m_errorCode = 0;
3913 createTabPtr.p->m_senderRef = senderRef;
3914 createTabPtr.p->m_senderData = senderData;
3915 createTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
3916 createTabPtr.p->m_coordinatorRef = reference();
3917 createTabPtr.p->m_fragmentsPtrI = RNIL;
3918 createTabPtr.p->m_dihAddFragPtr = RNIL;
3919
3920 Uint32 key = c_opRecordSequence + 1;
3921 Uint32 *theData = signal->getDataPtrSend();
3922 Uint16 *frag_data= (Uint16*)&signal->theData[25];
3923 CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
3924 req->senderRef = reference();
3925 req->senderData = key;
3926 req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
3927 req->noOfFragments = parseRecord.tablePtr.p->fragmentCount;
3928 req->fragmentationType = parseRecord.tablePtr.p->fragmentType;
3929 MEMCOPY_NO_WORDS(frag_data, c_fragData, c_fragDataLen);
3930
3931 if (parseRecord.tablePtr.p->isOrderedIndex()) {
3932 jam();
3933 // ordered index has same fragmentation as the table
3934 req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
3935 req->fragmentationType = DictTabInfo::DistrKeyOrderedIndex;
3936 }
3937 else if (parseRecord.tablePtr.p->isHashIndex())
3938 {
3939 jam();
3940 /*
3941 Unique hash indexes has same amount of fragments as primary table
3942 and distributed in the same manner but has always a normal hash
3943 fragmentation.
3944 */
3945 req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
3946 req->fragmentationType = DictTabInfo::DistrKeyUniqueHashIndex;
3947 }
3948 else
3949 {
3950 jam();
3951 /*
3952 Blob tables come here with primaryTableId != RNIL but we only need
3953 it for creating the fragments so we set it to RNIL now that we got
3954 what we wanted from it to avoid other side effects.
3955 */
3956 parseRecord.tablePtr.p->primaryTableId = RNIL;
3957 }
3958 EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
3959 CreateFragmentationReq::SignalLength);
3960 jamEntry();
3961 if (signal->theData[0] != 0)
3962 {
3963 jam();
3964 parseRecord.errorCode= signal->theData[0];
3965 c_opCreateTable.release(createTabPtr);
3966 releaseTableObject(parseRecord.tablePtr.i, true);
3967 break;
3968 }
3969 createTabPtr.p->key = key;
3970 c_opRecordSequence++;
3971 c_opCreateTable.add(createTabPtr);
3972 c_blockState = BS_CREATE_TAB;
3973 return;
3974 } while(0);
3975
3976 /**
3977 * Something went wrong
3978 */
3979
3980 releaseSections(signal);
3981 CreateTableRef * ref = (CreateTableRef*)signal->getDataPtrSend();
3982 ref->senderData = senderData;
3983 ref->senderRef = reference();
3984 ref->masterNodeId = c_masterNodeId;
3985 ref->errorCode = parseRecord.errorCode;
3986 ref->errorLine = parseRecord.errorLine;
3987 ref->errorKey = parseRecord.errorKey;
3988 ref->status = parseRecord.status;
3989 sendSignal(senderRef, GSN_CREATE_TABLE_REF, signal,
3990 CreateTableRef::SignalLength, JBB);
3991 }
3992
3993 void
execBACKUP_FRAGMENT_REQ(Signal * signal)3994 Dbdict::execBACKUP_FRAGMENT_REQ(Signal* signal)
3995 {
3996 jamEntry();
3997 Uint32 tableId = signal->theData[0];
3998 Uint32 lock = signal->theData[1];
3999
4000 TableRecordPtr tablePtr;
4001 c_tableRecordPool.getPtr(tablePtr, tableId, true);
4002
4003 if(lock)
4004 {
4005 ndbrequire(tablePtr.p->tabState == TableRecord::DEFINED);
4006 tablePtr.p->tabState = TableRecord::BACKUP_ONGOING;
4007 }
4008 else if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
4009 {
4010 tablePtr.p->tabState = TableRecord::DEFINED;
4011 }
4012 }
4013
4014 bool
check_ndb_versions() const4015 Dbdict::check_ndb_versions() const
4016 {
4017 Uint32 node = 0;
4018 Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
4019 while((node = c_aliveNodes.find(node + 1)) != BitmaskImpl::NotFound)
4020 {
4021 if(getNodeInfo(node).m_version != version)
4022 {
4023 return false;
4024 }
4025 }
4026 return true;
4027 }
4028
4029 void
execALTER_TABLE_REQ(Signal * signal)4030 Dbdict::execALTER_TABLE_REQ(Signal* signal)
4031 {
4032 // Received by master
4033 jamEntry();
4034 if(!assembleFragments(signal)){
4035 return;
4036 }
4037 AlterTableReq* const req = (AlterTableReq*)signal->getDataPtr();
4038 const Uint32 senderRef = req->senderRef;
4039 const Uint32 senderData = req->senderData;
4040 const Uint32 changeMask = req->changeMask;
4041 const Uint32 tableId = req->tableId;
4042 const Uint32 tableVersion = req->tableVersion;
4043 ParseDictTabInfoRecord* aParseRecord;
4044
4045 // Get table definition
4046 TableRecordPtr tablePtr;
4047 c_tableRecordPool.getPtr(tablePtr, tableId, false);
4048 if(tablePtr.isNull()){
4049 jam();
4050 alterTableRef(signal, req, AlterTableRef::NoSuchTable);
4051 return;
4052 }
4053
4054 if(getOwnNodeId() != c_masterNodeId){
4055 jam();
4056 alterTableRef(signal, req, AlterTableRef::NotMaster);
4057 return;
4058 }
4059
4060 if(c_blockState == BS_NODE_RESTART){
4061 jam();
4062 alterTableRef(signal, req, AlterTableRef::BusyWithNR);
4063 return;
4064 }
4065
4066 if(c_blockState != BS_IDLE){
4067 jam();
4068 alterTableRef(signal, req, AlterTableRef::Busy);
4069 return;
4070 }
4071
4072 if (!check_ndb_versions())
4073 {
4074 jam();
4075 alterTableRef(signal, req, AlterTableRef::IncompatibleVersions);
4076 return;
4077 }
4078
4079 if (checkSingleUserMode(signal->getSendersBlockRef()))
4080 {
4081 jam();
4082 alterTableRef(signal, req, AlterTableRef::SingleUser);
4083 return;
4084 }
4085
4086 const TableRecord::TabState tabState = tablePtr.p->tabState;
4087 bool ok = false;
4088 switch(tabState){
4089 case TableRecord::NOT_DEFINED:
4090 case TableRecord::DEFINING:
4091 jam();
4092 alterTableRef(signal, req, AlterTableRef::NoSuchTable);
4093 return;
4094 case TableRecord::DEFINED:
4095 ok = true;
4096 jam();
4097 break;
4098 case TableRecord::BACKUP_ONGOING:
4099 jam();
4100 alterTableRef(signal, req, AlterTableRef::BackupInProgress);
4101 return;
4102 case TableRecord::PREPARE_DROPPING:
4103 case TableRecord::DROPPING:
4104 jam();
4105 alterTableRef(signal, req, AlterTableRef::DropInProgress);
4106 return;
4107 }
4108 ndbrequire(ok);
4109
4110 if(tablePtr.p->tableVersion != tableVersion){
4111 jam();
4112 alterTableRef(signal, req, AlterTableRef::InvalidTableVersion);
4113 return;
4114 }
4115 // Parse new table defintion
4116 ParseDictTabInfoRecord parseRecord;
4117 aParseRecord = &parseRecord;
4118
4119 CreateTableRecordPtr alterTabPtr; // Reuse create table records
4120 c_opCreateTable.seize(alterTabPtr);
4121
4122 if(alterTabPtr.isNull()){
4123 jam();
4124 alterTableRef(signal, req, AlterTableRef::Busy);
4125 return;
4126 }
4127
4128 alterTabPtr.p->m_changeMask = changeMask;
4129 parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
4130 parseRecord.errorCode = 0;
4131
4132 SegmentedSectionPtr ptr;
4133 signal->getSection(ptr, AlterTableReq::DICT_TAB_INFO);
4134 SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
4135
4136 handleTabInfoInit(r, &parseRecord, false); // Will not save info
4137
4138 if(parseRecord.errorCode != 0){
4139 jam();
4140 c_opCreateTable.release(alterTabPtr);
4141 alterTableRef(signal, req,
4142 (AlterTableRef::ErrorCode) parseRecord.errorCode,
4143 aParseRecord);
4144 return;
4145 }
4146
4147 releaseSections(signal);
4148 alterTabPtr.p->key = ++c_opRecordSequence;
4149 c_opCreateTable.add(alterTabPtr);
4150 ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
4151 alterTabPtr.p->m_errorCode = 0;
4152 alterTabPtr.p->m_senderRef = senderRef;
4153 alterTabPtr.p->m_senderData = senderData;
4154 alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
4155 alterTabPtr.p->m_alterTableFailed = false;
4156 alterTabPtr.p->m_coordinatorRef = reference();
4157 alterTabPtr.p->m_fragmentsPtrI = RNIL;
4158 alterTabPtr.p->m_dihAddFragPtr = RNIL;
4159 alterTabPtr.p->m_alterTableId = tablePtr.p->tableId;
4160
4161 // Send prepare request to all alive nodes
4162 SimplePropertiesSectionWriter w(getSectionSegmentPool());
4163 packTableIntoPages(w, parseRecord.tablePtr);
4164
4165 SegmentedSectionPtr tabInfoPtr;
4166 w.getPtr(tabInfoPtr);
4167
4168 alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
4169
4170 // Alter table on all nodes
4171 c_blockState = BS_BUSY;
4172
4173 Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
4174 Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked),
4175 alterTabPtr.p->key };
4176
4177 ndbrequire(mutex.lock(c));
4178 }
4179
4180 void
alterTable_backup_mutex_locked(Signal * signal,Uint32 callbackData,Uint32 retValue)4181 Dbdict::alterTable_backup_mutex_locked(Signal* signal,
4182 Uint32 callbackData,
4183 Uint32 retValue)
4184 {
4185 jamEntry();
4186
4187 ndbrequire(retValue == 0);
4188
4189 CreateTableRecordPtr alterTabPtr;
4190 ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
4191
4192 TableRecordPtr tablePtr;
4193 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId, true);
4194
4195 Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
4196 mutex.unlock(); // ignore response
4197
4198 SegmentedSectionPtr tabInfoPtr;
4199 getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
4200 signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
4201
4202 alterTabPtr.p->m_tabInfoPtrI = RNIL;
4203
4204 if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
4205 {
4206 jam();
4207 AlterTableReq* req = (AlterTableReq*)signal->getDataPtr();
4208 req->senderData = alterTabPtr.p->m_senderData;
4209 req->senderRef = alterTabPtr.p->m_senderRef;
4210 alterTableRef(signal, req, AlterTableRef::BackupInProgress);
4211
4212 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_tablePtrI);
4213 releaseTableObject(tablePtr.i, false);
4214
4215 c_opCreateTable.release(alterTabPtr);
4216 c_blockState = BS_IDLE;
4217 return;
4218 }
4219
4220 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
4221 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
4222 SafeCounter safeCounter(c_counterMgr,
4223 alterTabPtr.p->m_coordinatorData.m_counter);
4224 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
4225
4226 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
4227 lreq->senderRef = reference();
4228 lreq->senderData = alterTabPtr.p->key;
4229 lreq->clientRef = alterTabPtr.p->m_senderRef;
4230 lreq->clientData = alterTabPtr.p->m_senderData;
4231 lreq->changeMask = alterTabPtr.p->m_changeMask;
4232 lreq->tableId = tablePtr.p->tableId;
4233 lreq->tableVersion = alter_obj_inc_schema_version(tablePtr.p->tableVersion);
4234 lreq->gci = tablePtr.p->gciTableCreated;
4235 lreq->requestType = AlterTabReq::AlterTablePrepare;
4236
4237 sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
4238 AlterTabReq::SignalLength, JBB);
4239 }
4240
alterTableRef(Signal * signal,AlterTableReq * req,AlterTableRef::ErrorCode errCode,ParseDictTabInfoRecord * parseRecord)4241 void Dbdict::alterTableRef(Signal * signal,
4242 AlterTableReq * req,
4243 AlterTableRef::ErrorCode errCode,
4244 ParseDictTabInfoRecord* parseRecord)
4245 {
4246 jam();
4247 releaseSections(signal);
4248 AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend();
4249 Uint32 senderRef = req->senderRef;
4250 ref->senderData = req->senderData;
4251 ref->senderRef = reference();
4252 ref->masterNodeId = c_masterNodeId;
4253 if (parseRecord) {
4254 ref->errorCode = parseRecord->errorCode;
4255 ref->errorLine = parseRecord->errorLine;
4256 ref->errorKey = parseRecord->errorKey;
4257 ref->status = parseRecord->status;
4258 }
4259 else {
4260 ref->errorCode = errCode;
4261 ref->errorLine = 0;
4262 ref->errorKey = 0;
4263 ref->status = 0;
4264 }
4265 sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal,
4266 AlterTableRef::SignalLength, JBB);
4267 }
4268
4269 void
execALTER_TAB_REQ(Signal * signal)4270 Dbdict::execALTER_TAB_REQ(Signal * signal)
4271 {
4272 // Received in all nodes to handle change locally
4273 jamEntry();
4274
4275 if(!assembleFragments(signal)){
4276 return;
4277 }
4278 AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
4279 const Uint32 senderRef = req->senderRef;
4280 const Uint32 senderData = req->senderData;
4281 const Uint32 changeMask = req->changeMask;
4282 const Uint32 tableId = req->tableId;
4283 const Uint32 tableVersion = req->tableVersion;
4284 const Uint32 gci = req->gci;
4285 AlterTabReq::RequestType requestType =
4286 (AlterTabReq::RequestType) req->requestType;
4287
4288 SegmentedSectionPtr tabInfoPtr;
4289 signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
4290
4291 CreateTableRecordPtr alterTabPtr; // Reuse create table records
4292
4293 if (senderRef != reference()) {
4294 jam();
4295 c_blockState = BS_BUSY;
4296 }
4297 if ((requestType == AlterTabReq::AlterTablePrepare)
4298 && (senderRef != reference())) {
4299 jam();
4300 c_opCreateTable.seize(alterTabPtr);
4301 if(!alterTabPtr.isNull())
4302 alterTabPtr.p->m_changeMask = changeMask;
4303 }
4304 else {
4305 jam();
4306 ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
4307 }
4308 if(alterTabPtr.isNull()){
4309 jam();
4310 alterTabRef(signal, req, AlterTableRef::Busy);
4311 return;
4312 }
4313
4314 if (!check_ndb_versions())
4315 {
4316 jam();
4317 alterTabRef(signal, req, AlterTableRef::IncompatibleVersions);
4318 return;
4319 }
4320
4321 alterTabPtr.p->m_alterTableId = tableId;
4322 alterTabPtr.p->m_coordinatorRef = senderRef;
4323
4324 // Get table definition
4325 TableRecordPtr tablePtr;
4326 c_tableRecordPool.getPtr(tablePtr, tableId, false);
4327 if(tablePtr.isNull()){
4328 jam();
4329 alterTabRef(signal, req, AlterTableRef::NoSuchTable);
4330 return;
4331 }
4332
4333 switch(requestType) {
4334 case(AlterTabReq::AlterTablePrepare): {
4335 ParseDictTabInfoRecord* aParseRecord;
4336
4337 const TableRecord::TabState tabState = tablePtr.p->tabState;
4338 bool ok = false;
4339 switch(tabState){
4340 case TableRecord::NOT_DEFINED:
4341 case TableRecord::DEFINING:
4342 jam();
4343 alterTabRef(signal, req, AlterTableRef::NoSuchTable);
4344 return;
4345 case TableRecord::DEFINED:
4346 ok = true;
4347 jam();
4348 break;
4349 case TableRecord::PREPARE_DROPPING:
4350 case TableRecord::DROPPING:
4351 jam();
4352 alterTabRef(signal, req, AlterTableRef::DropInProgress);
4353 return;
4354 case TableRecord::BACKUP_ONGOING:
4355 jam();
4356 alterTabRef(signal, req, AlterTableRef::BackupInProgress);
4357 return;
4358 }
4359 ndbrequire(ok);
4360
4361 if(alter_obj_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){
4362 jam();
4363 alterTabRef(signal, req, AlterTableRef::InvalidTableVersion);
4364 return;
4365 }
4366 TableRecordPtr newTablePtr;
4367 if (senderRef != reference()) {
4368 jam();
4369 // Parse altered table defintion
4370 ParseDictTabInfoRecord parseRecord;
4371 aParseRecord = &parseRecord;
4372
4373 parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
4374 parseRecord.errorCode = 0;
4375
4376 SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
4377
4378 handleTabInfoInit(r, &parseRecord, false); // Will not save info
4379
4380 if(parseRecord.errorCode != 0){
4381 jam();
4382 c_opCreateTable.release(alterTabPtr);
4383 alterTabRef(signal, req,
4384 (AlterTableRef::ErrorCode) parseRecord.errorCode,
4385 aParseRecord);
4386 return;
4387 }
4388 alterTabPtr.p->key = senderData;
4389 c_opCreateTable.add(alterTabPtr);
4390 alterTabPtr.p->m_errorCode = 0;
4391 alterTabPtr.p->m_senderRef = senderRef;
4392 alterTabPtr.p->m_senderData = senderData;
4393 alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
4394 alterTabPtr.p->m_fragmentsPtrI = RNIL;
4395 alterTabPtr.p->m_dihAddFragPtr = RNIL;
4396 newTablePtr = parseRecord.tablePtr;
4397 newTablePtr.p->tableVersion = tableVersion;
4398 }
4399 else { // (req->senderRef == reference())
4400 jam();
4401 c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
4402 newTablePtr.p->tableVersion = tableVersion;
4403 }
4404 if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) {
4405 jam();
4406 c_opCreateTable.release(alterTabPtr);
4407 alterTabRef(signal, req, AlterTableRef::UnsupportedChange);
4408 return;
4409 }
4410 releaseSections(signal);
4411 // Propagate alter table to other local blocks
4412 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
4413 req->senderRef = reference();
4414 req->senderData = senderData;
4415 req->changeMask = changeMask;
4416 req->tableId = tableId;
4417 req->tableVersion = tableVersion;
4418 req->gci = gci;
4419 req->requestType = requestType;
4420 sendSignal(DBLQH_REF, GSN_ALTER_TAB_REQ, signal,
4421 AlterTabReq::SignalLength, JBB);
4422 return;
4423 }
4424 case(AlterTabReq::AlterTableCommit): {
4425 jam();
4426 // Write schema for altered table to disk
4427 SegmentedSectionPtr tabInfoPtr;
4428 signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
4429 alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
4430 bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
4431
4432 signal->header.m_noOfSections = 0;
4433
4434 // Update table record
4435 tablePtr.p->packedSize = tabInfoPtr.sz;
4436 tablePtr.p->tableVersion = tableVersion;
4437 tablePtr.p->gciTableCreated = gci;
4438
4439 SchemaFile::TableEntry tabEntry;
4440 tabEntry.m_tableVersion = tableVersion;
4441 tabEntry.m_tableType = tablePtr.p->tableType;
4442 if (savetodisk)
4443 tabEntry.m_tableState = SchemaFile::ALTER_TABLE_COMMITTED;
4444 else
4445 tabEntry.m_tableState = SchemaFile::TEMPORARY_TABLE_COMMITTED;
4446 tabEntry.m_gcp = gci;
4447 tabEntry.m_info_words = tabInfoPtr.sz;
4448 memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
4449
4450 Callback callback;
4451 callback.m_callbackData = senderData;
4452 callback.m_callbackFunction =
4453 safe_cast(&Dbdict::alterTab_writeSchemaConf);
4454
4455 updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
4456 break;
4457 }
4458 case(AlterTabReq::AlterTableRevert): {
4459 jam();
4460 // Revert failed alter table
4461 revertAlterTable(signal, changeMask, tableId, alterTabPtr.p);
4462 // Acknowledge the reverted alter table
4463 AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
4464 conf->senderRef = reference();
4465 conf->senderData = senderData;
4466 conf->changeMask = changeMask;
4467 conf->tableId = tableId;
4468 conf->tableVersion = tableVersion;
4469 conf->gci = gci;
4470 conf->requestType = requestType;
4471 sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
4472 AlterTabConf::SignalLength, JBB);
4473 break;
4474 }
4475 default: ndbrequire(false);
4476 }
4477 }
4478
alterTabRef(Signal * signal,AlterTabReq * req,AlterTableRef::ErrorCode errCode,ParseDictTabInfoRecord * parseRecord)4479 void Dbdict::alterTabRef(Signal * signal,
4480 AlterTabReq * req,
4481 AlterTableRef::ErrorCode errCode,
4482 ParseDictTabInfoRecord* parseRecord)
4483 {
4484 jam();
4485 releaseSections(signal);
4486 AlterTabRef * ref = (AlterTabRef*)signal->getDataPtrSend();
4487 Uint32 senderRef = req->senderRef;
4488 ref->senderData = req->senderData;
4489 ref->senderRef = reference();
4490 if (parseRecord) {
4491 jam();
4492 ref->errorCode = parseRecord->errorCode;
4493 ref->errorLine = parseRecord->errorLine;
4494 ref->errorKey = parseRecord->errorKey;
4495 ref->errorStatus = parseRecord->status;
4496 }
4497 else {
4498 jam();
4499 ref->errorCode = errCode;
4500 ref->errorLine = 0;
4501 ref->errorKey = 0;
4502 ref->errorStatus = 0;
4503 }
4504 sendSignal(senderRef, GSN_ALTER_TAB_REF, signal,
4505 AlterTabRef::SignalLength, JBB);
4506
4507 c_blockState = BS_IDLE;
4508 }
4509
execALTER_TAB_REF(Signal * signal)4510 void Dbdict::execALTER_TAB_REF(Signal * signal){
4511 jamEntry();
4512
4513 AlterTabRef * ref = (AlterTabRef*)signal->getDataPtr();
4514
4515 Uint32 senderRef = ref->senderRef;
4516 Uint32 senderData = ref->senderData;
4517 Uint32 errorCode = ref->errorCode;
4518 Uint32 errorLine = ref->errorLine;
4519 Uint32 errorKey = ref->errorKey;
4520 Uint32 errorStatus = ref->errorStatus;
4521 AlterTabReq::RequestType requestType =
4522 (AlterTabReq::RequestType) ref->requestType;
4523 CreateTableRecordPtr alterTabPtr;
4524 ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
4525 Uint32 changeMask = alterTabPtr.p->m_changeMask;
4526 SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
4527 safeCounter.clearWaitingFor(refToNode(senderRef));
4528 switch (requestType) {
4529 case(AlterTabReq::AlterTablePrepare): {
4530 if (safeCounter.done()) {
4531 jam();
4532 // Send revert request to all alive nodes
4533 TableRecordPtr tablePtr;
4534 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
4535 Uint32 tableId = tablePtr.p->tableId;
4536 Uint32 tableVersion = tablePtr.p->tableVersion;
4537 Uint32 gci = tablePtr.p->gciTableCreated;
4538 SimplePropertiesSectionWriter w(getSectionSegmentPool());
4539 packTableIntoPages(w, tablePtr);
4540 SegmentedSectionPtr spDataPtr;
4541 w.getPtr(spDataPtr);
4542 signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
4543
4544 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
4545 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
4546 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
4547
4548 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
4549 lreq->senderRef = reference();
4550 lreq->senderData = alterTabPtr.p->key;
4551 lreq->clientRef = alterTabPtr.p->m_senderRef;
4552 lreq->clientData = alterTabPtr.p->m_senderData;
4553 lreq->changeMask = changeMask;
4554 lreq->tableId = tableId;
4555 lreq->tableVersion = tableVersion;
4556 lreq->gci = gci;
4557 lreq->requestType = AlterTabReq::AlterTableRevert;
4558
4559 sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
4560 AlterTabReq::SignalLength, JBB);
4561 }
4562 else {
4563 jam();
4564 alterTabPtr.p->m_alterTableFailed = true;
4565 }
4566 break;
4567 }
4568 case(AlterTabReq::AlterTableCommit):
4569 jam();
4570 case(AlterTabReq::AlterTableRevert): {
4571 AlterTableRef * apiRef = (AlterTableRef*)signal->getDataPtrSend();
4572
4573 apiRef->senderData = senderData;
4574 apiRef->senderRef = reference();
4575 apiRef->masterNodeId = c_masterNodeId;
4576 apiRef->errorCode = errorCode;
4577 apiRef->errorLine = errorLine;
4578 apiRef->errorKey = errorKey;
4579 apiRef->status = errorStatus;
4580 if (safeCounter.done()) {
4581 jam();
4582 sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal,
4583 AlterTableRef::SignalLength, JBB);
4584 c_blockState = BS_IDLE;
4585 }
4586 else {
4587 jam();
4588 alterTabPtr.p->m_alterTableFailed = true;
4589 alterTabPtr.p->m_alterTableRef = *apiRef;
4590 }
4591 break;
4592 }
4593 default: ndbrequire(false);
4594 }
4595 }
4596
4597 void
execALTER_TAB_CONF(Signal * signal)4598 Dbdict::execALTER_TAB_CONF(Signal * signal){
4599 jamEntry();
4600 AlterTabConf * const conf = (AlterTabConf*)signal->getDataPtr();
4601 Uint32 senderRef = conf->senderRef;
4602 Uint32 senderData = conf->senderData;
4603 Uint32 changeMask = conf->changeMask;
4604 Uint32 tableId = conf->tableId;
4605 Uint32 tableVersion = conf->tableVersion;
4606 Uint32 gci = conf->gci;
4607 AlterTabReq::RequestType requestType =
4608 (AlterTabReq::RequestType) conf->requestType;
4609 CreateTableRecordPtr alterTabPtr;
4610 ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
4611
4612 switch (requestType) {
4613 case(AlterTabReq::AlterTablePrepare): {
4614 switch(refToBlock(signal->getSendersBlockRef())) {
4615 case DBLQH: {
4616 jam();
4617 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
4618 req->senderRef = reference();
4619 req->senderData = senderData;
4620 req->changeMask = changeMask;
4621 req->tableId = tableId;
4622 req->tableVersion = tableVersion;
4623 req->gci = gci;
4624 req->requestType = requestType;
4625 sendSignal(DBDIH_REF, GSN_ALTER_TAB_REQ, signal,
4626 AlterTabReq::SignalLength, JBB);
4627 return;
4628 }
4629 case DBDIH: {
4630 jam();
4631 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
4632 req->senderRef = reference();
4633 req->senderData = senderData;
4634 req->changeMask = changeMask;
4635 req->tableId = tableId;
4636 req->tableVersion = tableVersion;
4637 req->gci = gci;
4638 req->requestType = requestType;
4639 sendSignal(DBTC_REF, GSN_ALTER_TAB_REQ, signal,
4640 AlterTabReq::SignalLength, JBB);
4641 return;
4642 }
4643 case DBTC: {
4644 jam();
4645 // Participant is done with prepare phase, send conf to coordinator
4646 AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
4647 conf->senderRef = reference();
4648 conf->senderData = senderData;
4649 conf->changeMask = changeMask;
4650 conf->tableId = tableId;
4651 conf->tableVersion = tableVersion;
4652 conf->gci = gci;
4653 conf->requestType = requestType;
4654 sendSignal(alterTabPtr.p->m_coordinatorRef, GSN_ALTER_TAB_CONF, signal,
4655 AlterTabConf::SignalLength, JBB);
4656 return;
4657 }
4658 default :break;
4659 }
4660 // Coordinator only
4661 SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
4662 safeCounter.clearWaitingFor(refToNode(senderRef));
4663 if (safeCounter.done()) {
4664 jam();
4665 // We have received all local confirmations
4666 if (alterTabPtr.p->m_alterTableFailed) {
4667 jam();
4668 // Send revert request to all alive nodes
4669 TableRecordPtr tablePtr;
4670 c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
4671 Uint32 tableId = tablePtr.p->tableId;
4672 Uint32 tableVersion = tablePtr.p->tableVersion;
4673 Uint32 gci = tablePtr.p->gciTableCreated;
4674 SimplePropertiesSectionWriter w(getSectionSegmentPool());
4675 packTableIntoPages(w, tablePtr);
4676 SegmentedSectionPtr spDataPtr;
4677 w.getPtr(spDataPtr);
4678 signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
4679
4680 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
4681 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
4682 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
4683
4684 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
4685 lreq->senderRef = reference();
4686 lreq->senderData = alterTabPtr.p->key;
4687 lreq->clientRef = alterTabPtr.p->m_senderRef;
4688 lreq->clientData = alterTabPtr.p->m_senderData;
4689 lreq->changeMask = changeMask;
4690 lreq->tableId = tableId;
4691 lreq->tableVersion = tableVersion;
4692 lreq->gci = gci;
4693 lreq->requestType = AlterTabReq::AlterTableRevert;
4694
4695 sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
4696 AlterTabReq::SignalLength, JBB);
4697 }
4698 else {
4699 jam();
4700 // Send commit request to all alive nodes
4701 TableRecordPtr tablePtr;
4702 c_tableRecordPool.getPtr(tablePtr, tableId);
4703 SimplePropertiesSectionWriter w(getSectionSegmentPool());
4704 packTableIntoPages(w, tablePtr);
4705 SegmentedSectionPtr spDataPtr;
4706 w.getPtr(spDataPtr);
4707 signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
4708
4709 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
4710 alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
4711 safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
4712
4713 AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
4714 lreq->senderRef = reference();
4715 lreq->senderData = alterTabPtr.p->key;
4716 lreq->clientRef = alterTabPtr.p->m_senderRef;
4717 lreq->clientData = alterTabPtr.p->m_senderData;
4718 lreq->changeMask = changeMask;
4719 lreq->tableId = tableId;
4720 lreq->tableVersion = tableVersion;
4721 lreq->gci = gci;
4722 lreq->requestType = AlterTabReq::AlterTableCommit;
4723
4724 sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
4725 AlterTabReq::SignalLength, JBB);
4726 }
4727 }
4728 else {
4729 // (!safeCounter.done())
4730 jam();
4731 }
4732 break;
4733 }
4734 case(AlterTabReq::AlterTableRevert):
4735 jam();
4736 case(AlterTabReq::AlterTableCommit): {
4737 SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
4738 safeCounter.clearWaitingFor(refToNode(senderRef));
4739 if (safeCounter.done()) {
4740 jam();
4741 // We have received all local confirmations
4742 releaseSections(signal);
4743 if (alterTabPtr.p->m_alterTableFailed) {
4744 jam();
4745 AlterTableRef * apiRef =
4746 (AlterTableRef*)signal->getDataPtrSend();
4747 *apiRef = alterTabPtr.p->m_alterTableRef;
4748 sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal,
4749 AlterTableRef::SignalLength, JBB);
4750 }
4751 else {
4752 jam();
4753 // Alter table completed, inform API
4754 AlterTableConf * const apiConf =
4755 (AlterTableConf*)signal->getDataPtrSend();
4756 apiConf->senderRef = reference();
4757 apiConf->senderData = alterTabPtr.p->m_senderData;
4758 apiConf->tableId = tableId;
4759 apiConf->tableVersion = tableVersion;
4760
4761 //@todo check api failed
4762 sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_CONF, signal,
4763 AlterTableConf::SignalLength, JBB);
4764 }
4765
4766 // Release resources
4767 TableRecordPtr tabPtr;
4768 c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
4769 releaseTableObject(tabPtr.i, false);
4770 releaseCreateTableOp(signal,alterTabPtr);
4771 c_blockState = BS_IDLE;
4772 }
4773 else {
4774 // (!safeCounter.done())
4775 jam();
4776 }
4777 break;
4778 }
4779 default: ndbrequire(false);
4780 }
4781 }
4782
4783 // For debugging
4784 inline
printTables()4785 void Dbdict::printTables()
4786 {
4787 DLHashTable<DictObject>::Iterator iter;
4788 bool moreTables = c_obj_hash.first(iter);
4789 printf("OBJECTS IN DICT:\n");
4790 char name[MAX_TAB_NAME_SIZE];
4791 while (moreTables) {
4792 Ptr<DictObject> tablePtr = iter.curr;
4793 ConstRope r(c_rope_pool, tablePtr.p->m_name);
4794 r.copy(name);
4795 printf("%s ", name);
4796 moreTables = c_obj_hash.next(iter);
4797 }
4798 printf("\n");
4799 }
4800
handleAlterTab(AlterTabReq * req,CreateTableRecord * alterTabPtrP,TableRecordPtr origTablePtr,TableRecordPtr newTablePtr)4801 int Dbdict::handleAlterTab(AlterTabReq * req,
4802 CreateTableRecord * alterTabPtrP,
4803 TableRecordPtr origTablePtr,
4804 TableRecordPtr newTablePtr)
4805 {
4806 bool supportedAlteration = false;
4807 Uint32 changeMask = req->changeMask;
4808
4809 if (AlterTableReq::getNameFlag(changeMask)) {
4810 jam();
4811 // Table rename
4812 supportedAlteration = true;
4813 // Remove from hashtable
4814 Ptr<DictObject> obj_ptr;
4815 c_obj_pool.getPtr(obj_ptr, origTablePtr.p->m_obj_ptr_i);
4816 c_obj_hash.remove(obj_ptr);
4817 {
4818 Rope org(c_rope_pool, origTablePtr.p->tableName);
4819 org.copy(alterTabPtrP->previousTableName);
4820
4821 ConstRope src(c_rope_pool, newTablePtr.p->tableName);
4822 char tmp[MAX_TAB_NAME_SIZE];
4823 const int len = src.size();
4824 src.copy(tmp);
4825 ndbrequire(org.assign(tmp, len));
4826 }
4827 obj_ptr.p->m_name = origTablePtr.p->tableName;
4828 // Put it back
4829 c_obj_hash.add(obj_ptr);
4830 }
4831
4832 if (AlterTableReq::getFrmFlag(changeMask)) {
4833 // Table definition changed (new frm)
4834 supportedAlteration = true;
4835 // Save old definition
4836 Rope org(c_rope_pool, origTablePtr.p->frmData);
4837 org.copy(alterTabPtrP->previousFrmData);
4838 alterTabPtrP->previousFrmLen = org.size();
4839
4840 // Set new definition
4841 ConstRope src(c_rope_pool, newTablePtr.p->frmData);
4842 char tmp[MAX_FRM_DATA_SIZE];
4843 src.copy(tmp);
4844 ndbrequire(org.assign(tmp, src.size()));
4845 }
4846
4847 /*
4848 TODO RONM: Lite ny kod f�r FragmentData och RangeOrListData
4849 */
4850 if (supportedAlteration)
4851 {
4852 // Set new schema version
4853 origTablePtr.p->tableVersion = newTablePtr.p->tableVersion;
4854 return 0;
4855 }
4856 else
4857 {
4858 jam();
4859 return -1;
4860 }
4861 }
4862
revertAlterTable(Signal * signal,Uint32 changeMask,Uint32 tableId,CreateTableRecord * alterTabPtrP)4863 void Dbdict::revertAlterTable(Signal * signal,
4864 Uint32 changeMask,
4865 Uint32 tableId,
4866 CreateTableRecord * alterTabPtrP)
4867 {
4868 bool supportedAlteration = false;
4869
4870 TableRecordPtr tablePtr;
4871 c_tableRecordPool.getPtr(tablePtr, tableId);
4872
4873 if (AlterTableReq::getNameFlag(changeMask)) {
4874 jam();
4875 // Table rename
4876 supportedAlteration = true;
4877 // Restore previous name
4878
4879 Ptr<DictObject> obj_ptr;
4880 c_obj_pool.getPtr(obj_ptr, tablePtr.p->m_obj_ptr_i);
4881 c_obj_hash.remove(obj_ptr);
4882
4883 {
4884 // Restore name
4885 Rope org(c_rope_pool, tablePtr.p->tableName);
4886 ndbrequire(org.assign(alterTabPtrP->previousTableName));
4887 }
4888 obj_ptr.p->m_name = tablePtr.p->tableName;
4889 // Put it back
4890 c_obj_hash.add(obj_ptr);
4891 }
4892
4893 if (AlterTableReq::getFrmFlag(changeMask))
4894 {
4895 jam();
4896 // Table redefinition
4897 supportedAlteration = true;
4898 // Restore previous frm
4899 Rope org(c_rope_pool, tablePtr.p->tableName);
4900 ndbrequire(org.assign(alterTabPtrP->previousFrmData,
4901 alterTabPtrP->previousFrmLen));
4902
4903 }
4904
4905
4906 if (supportedAlteration)
4907 {
4908 tablePtr.p->tableVersion =
4909 alter_obj_dec_schema_version(tablePtr.p->tableVersion);
4910 return;
4911 }
4912
4913 ndbrequire(false);
4914 }
4915
4916 void
alterTab_writeSchemaConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)4917 Dbdict::alterTab_writeSchemaConf(Signal* signal,
4918 Uint32 callbackData,
4919 Uint32 returnCode)
4920 {
4921 jam();
4922 Uint32 key = callbackData;
4923 CreateTableRecordPtr alterTabPtr;
4924 ndbrequire(c_opCreateTable.find(alterTabPtr, key));
4925 Uint32 tableId = alterTabPtr.p->m_alterTableId;
4926
4927 Callback callback;
4928 callback.m_callbackData = alterTabPtr.p->key;
4929 callback.m_callbackFunction =
4930 safe_cast(&Dbdict::alterTab_writeTableConf);
4931
4932 TableRecordPtr tablePtr;
4933 c_tableRecordPool.getPtr(tablePtr, tableId);
4934 bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
4935 if (savetodisk)
4936 {
4937 SegmentedSectionPtr tabInfoPtr;
4938 getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
4939 writeTableFile(signal, tableId, tabInfoPtr, &callback);
4940 }
4941 else
4942 {
4943 execute(signal, callback, 0);
4944 }
4945 }
4946
4947 void
alterTab_writeTableConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)4948 Dbdict::alterTab_writeTableConf(Signal* signal,
4949 Uint32 callbackData,
4950 Uint32 returnCode)
4951 {
4952 jam();
4953 CreateTableRecordPtr alterTabPtr;
4954 ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
4955 Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef;
4956 TableRecordPtr tabPtr;
4957 c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId);
4958 // Alter table commit request handled successfully
4959 // Inform Suma so it can send events to any subscribers of the table
4960 AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
4961 if (coordinatorRef == reference())
4962 req->senderRef = alterTabPtr.p->m_senderRef;
4963 else
4964 req->senderRef = 0;
4965 req->senderData = callbackData;
4966 req->tableId = tabPtr.p->tableId;
4967 req->tableVersion = tabPtr.p->tableVersion;
4968 req->gci = tabPtr.p->gciTableCreated;
4969 req->requestType = AlterTabReq::AlterTableCommit;
4970 req->changeMask = alterTabPtr.p->m_changeMask;
4971 SegmentedSectionPtr tabInfoPtr;
4972 getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
4973 signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
4974 EXECUTE_DIRECT(SUMA, GSN_ALTER_TAB_REQ, signal,
4975 AlterTabReq::SignalLength);
4976 releaseSections(signal);
4977 alterTabPtr.p->m_tabInfoPtrI = RNIL;
4978 jamEntry();
4979 AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
4980 conf->senderRef = reference();
4981 conf->senderData = callbackData;
4982 conf->tableId = tabPtr.p->tableId;
4983 conf->tableVersion = tabPtr.p->tableVersion;
4984 conf->gci = tabPtr.p->gciTableCreated;
4985 conf->requestType = AlterTabReq::AlterTableCommit;
4986 conf->changeMask = alterTabPtr.p->m_changeMask;
4987 sendSignal(coordinatorRef, GSN_ALTER_TAB_CONF, signal,
4988 AlterTabConf::SignalLength, JBB);
4989
4990
4991 {
4992 ApiBroadcastRep* api= (ApiBroadcastRep*)signal->getDataPtrSend();
4993 api->gsn = GSN_ALTER_TABLE_REP;
4994 api->minVersion = MAKE_VERSION(4,1,15);
4995
4996 AlterTableRep* rep = (AlterTableRep*)api->theData;
4997 rep->tableId = tabPtr.p->tableId;
4998 rep->tableVersion = alter_obj_dec_schema_version(tabPtr.p->tableVersion);
4999 rep->changeType = AlterTableRep::CT_ALTERED;
5000
5001 LinearSectionPtr ptr[3];
5002 ptr[0].p = (Uint32*)alterTabPtr.p->previousTableName;
5003 ptr[0].sz = (sizeof(alterTabPtr.p->previousTableName) + 3) >> 2;
5004
5005 sendSignal(QMGR_REF, GSN_API_BROADCAST_REP, signal,
5006 ApiBroadcastRep::SignalLength + AlterTableRep::SignalLength,
5007 JBB, ptr,1);
5008 }
5009
5010 if(coordinatorRef != reference()) {
5011 jam();
5012 // Release resources
5013 c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
5014 releaseTableObject(tabPtr.i, false);
5015 releaseCreateTableOp(signal,alterTabPtr);
5016 c_blockState = BS_IDLE;
5017 }
5018 }
5019
5020 void
execCREATE_FRAGMENTATION_REF(Signal * signal)5021 Dbdict::execCREATE_FRAGMENTATION_REF(Signal * signal){
5022 jamEntry();
5023 const Uint32 * theData = signal->getDataPtr();
5024 CreateFragmentationRef * const ref = (CreateFragmentationRef*)theData;
5025 (void)ref;
5026 ndbrequire(false);
5027 }
5028
5029 void
execCREATE_FRAGMENTATION_CONF(Signal * signal)5030 Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){
5031 jamEntry();
5032 const Uint32 * theData = signal->getDataPtr();
5033 CreateFragmentationConf * const conf = (CreateFragmentationConf*)theData;
5034
5035 CreateTableRecordPtr createTabPtr;
5036 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
5037
5038 ndbrequire(signal->getNoOfSections() == 1);
5039
5040 SegmentedSectionPtr fragDataPtr;
5041 signal->getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS);
5042 signal->header.m_noOfSections = 0;
5043
5044 /**
5045 * Get table
5046 */
5047 TableRecordPtr tabPtr;
5048 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5049
5050 /**
5051 * Save fragment count
5052 */
5053 tabPtr.p->fragmentCount = conf->noOfFragments;
5054
5055 /**
5056 * Update table version
5057 */
5058 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
5059 SchemaFile::TableEntry * tabEntry = getTableEntry(xsf, tabPtr.i);
5060
5061 tabPtr.p->tableVersion =
5062 create_obj_inc_schema_version(tabEntry->m_tableVersion);
5063
5064 /**
5065 * Pack
5066 */
5067 SimplePropertiesSectionWriter w(getSectionSegmentPool());
5068 packTableIntoPages(w, tabPtr);
5069
5070 SegmentedSectionPtr spDataPtr;
5071 w.getPtr(spDataPtr);
5072
5073 signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO);
5074 signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION);
5075
5076 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
5077 SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
5078 createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
5079 createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTablePrepare;
5080 tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
5081
5082 CreateTabReq * const req = (CreateTabReq*)theData;
5083 req->senderRef = reference();
5084 req->senderData = createTabPtr.p->key;
5085 req->clientRef = createTabPtr.p->m_senderRef;
5086 req->clientData = createTabPtr.p->m_senderData;
5087 req->requestType = CreateTabReq::CreateTablePrepare;
5088
5089 req->gci = 0;
5090 req->tableId = tabPtr.i;
5091 req->tableVersion = create_obj_inc_schema_version(tabEntry->m_tableVersion);
5092
5093 sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal,
5094 CreateTabReq::SignalLength, JBB);
5095
5096 return;
5097 }
5098
5099 void
execCREATE_TAB_REF(Signal * signal)5100 Dbdict::execCREATE_TAB_REF(Signal* signal){
5101 jamEntry();
5102
5103 CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
5104
5105 CreateTableRecordPtr createTabPtr;
5106 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
5107
5108 ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
5109 ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
5110
5111 if(ref->errorCode != CreateTabRef::NF_FakeErrorREF){
5112 createTabPtr.p->setErrorCode(ref->errorCode);
5113 }
5114 createTab_reply(signal, createTabPtr, refToNode(ref->senderRef));
5115 }
5116
5117 void
execCREATE_TAB_CONF(Signal * signal)5118 Dbdict::execCREATE_TAB_CONF(Signal* signal){
5119 jamEntry();
5120
5121 ndbrequire(signal->getNoOfSections() == 0);
5122
5123 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
5124
5125 CreateTableRecordPtr createTabPtr;
5126 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
5127
5128 ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
5129 ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
5130
5131 createTab_reply(signal, createTabPtr, refToNode(conf->senderRef));
5132 }
5133
5134 void
createTab_reply(Signal * signal,CreateTableRecordPtr createTabPtr,Uint32 nodeId)5135 Dbdict::createTab_reply(Signal* signal,
5136 CreateTableRecordPtr createTabPtr,
5137 Uint32 nodeId)
5138 {
5139
5140 SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
5141 if(!tmp.clearWaitingFor(nodeId)){
5142 jam();
5143 return;
5144 }
5145
5146 switch(createTabPtr.p->m_coordinatorData.m_requestType){
5147 case CreateTabReq::CreateTablePrepare:{
5148
5149 if(createTabPtr.p->m_errorCode != 0){
5150 jam();
5151 /**
5152 * Failed to prepare on atleast one node -> abort on all
5153 */
5154 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
5155 createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
5156 createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableDrop;
5157 ndbrequire(tmp.init<CreateTabRef>(rg, createTabPtr.p->key));
5158
5159 CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
5160 req->senderRef = reference();
5161 req->senderData = createTabPtr.p->key;
5162 req->requestType = CreateTabReq::CreateTableDrop;
5163
5164 sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
5165 CreateTabReq::SignalLength, JBB);
5166 return;
5167 }
5168
5169 /**
5170 * Lock mutex before commiting table
5171 */
5172 Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
5173 Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_locked),
5174 createTabPtr.p->key};
5175
5176 ndbrequire(mutex.lock(c));
5177 return;
5178 }
5179 case CreateTabReq::CreateTableCommit:{
5180 jam();
5181 ndbrequire(createTabPtr.p->m_errorCode == 0);
5182
5183 /**
5184 * Unlock mutex before commiting table
5185 */
5186 Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
5187 Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_unlocked),
5188 createTabPtr.p->key};
5189 mutex.unlock(c);
5190 return;
5191 }
5192 case CreateTabReq::CreateTableDrop:{
5193 jam();
5194 CreateTableRef * const ref = (CreateTableRef*)signal->getDataPtr();
5195 ref->senderRef = reference();
5196 ref->senderData = createTabPtr.p->m_senderData;
5197 ref->errorCode = createTabPtr.p->m_errorCode;
5198 ref->masterNodeId = c_masterNodeId;
5199 ref->status = 0;
5200 ref->errorKey = 0;
5201 ref->errorLine = 0;
5202
5203 //@todo check api failed
5204 sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_REF, signal,
5205 CreateTableRef::SignalLength, JBB);
5206 releaseCreateTableOp(signal,createTabPtr);
5207 c_blockState = BS_IDLE;
5208 return;
5209 }
5210 }
5211 ndbrequire(false);
5212 }
5213
5214 void
createTab_startLcpMutex_locked(Signal * signal,Uint32 callbackData,Uint32 retValue)5215 Dbdict::createTab_startLcpMutex_locked(Signal* signal,
5216 Uint32 callbackData,
5217 Uint32 retValue){
5218 jamEntry();
5219
5220 ndbrequire(retValue == 0);
5221
5222 CreateTableRecordPtr createTabPtr;
5223 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5224
5225 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
5226 createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
5227 createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableCommit;
5228 SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
5229 tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
5230
5231 CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
5232 req->senderRef = reference();
5233 req->senderData = createTabPtr.p->key;
5234 req->requestType = CreateTabReq::CreateTableCommit;
5235
5236 sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
5237 CreateTabReq::SignalLength, JBB);
5238 }
5239
5240 void
createTab_startLcpMutex_unlocked(Signal * signal,Uint32 callbackData,Uint32 retValue)5241 Dbdict::createTab_startLcpMutex_unlocked(Signal* signal,
5242 Uint32 callbackData,
5243 Uint32 retValue){
5244 jamEntry();
5245
5246 ndbrequire(retValue == 0);
5247
5248 CreateTableRecordPtr createTabPtr;
5249 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5250
5251 createTabPtr.p->m_startLcpMutex.release(c_mutexMgr);
5252
5253 TableRecordPtr tabPtr;
5254 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5255
5256 CreateTableConf * const conf = (CreateTableConf*)signal->getDataPtr();
5257 conf->senderRef = reference();
5258 conf->senderData = createTabPtr.p->m_senderData;
5259 conf->tableId = createTabPtr.p->m_tablePtrI;
5260 conf->tableVersion = tabPtr.p->tableVersion;
5261
5262 //@todo check api failed
5263 sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_CONF, signal,
5264 CreateTableConf::SignalLength, JBB);
5265 releaseCreateTableOp(signal,createTabPtr);
5266 c_blockState = BS_IDLE;
5267 return;
5268 }
5269
5270 /***********************************************************
5271 * CreateTable participant code
5272 **********************************************************/
5273 void
execCREATE_TAB_REQ(Signal * signal)5274 Dbdict::execCREATE_TAB_REQ(Signal* signal){
5275 jamEntry();
5276
5277 if(!assembleFragments(signal)){
5278 jam();
5279 return;
5280 }
5281
5282 CreateTabReq * const req = (CreateTabReq*)signal->getDataPtr();
5283
5284 CreateTabReq::RequestType rt = (CreateTabReq::RequestType)req->requestType;
5285 switch(rt){
5286 case CreateTabReq::CreateTablePrepare:
5287 CRASH_INSERTION2(6003, getOwnNodeId() != c_masterNodeId);
5288 createTab_prepare(signal, req);
5289 return;
5290 case CreateTabReq::CreateTableCommit:
5291 CRASH_INSERTION2(6004, getOwnNodeId() != c_masterNodeId);
5292 createTab_commit(signal, req);
5293 return;
5294 case CreateTabReq::CreateTableDrop:
5295 CRASH_INSERTION2(6005, getOwnNodeId() != c_masterNodeId);
5296 createTab_drop(signal, req);
5297 return;
5298 }
5299 ndbrequire(false);
5300 }
5301
5302 void
createTab_prepare(Signal * signal,CreateTabReq * req)5303 Dbdict::createTab_prepare(Signal* signal, CreateTabReq * req){
5304
5305 const Uint32 gci = req->gci;
5306 const Uint32 tableId = req->tableId;
5307 const Uint32 tableVersion = req->tableVersion;
5308
5309 SegmentedSectionPtr tabInfoPtr;
5310 signal->getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO);
5311
5312 CreateTableRecordPtr createTabPtr;
5313 if(req->senderRef == reference()){
5314 jam();
5315 ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
5316 } else {
5317 jam();
5318 c_opCreateTable.seize(createTabPtr);
5319
5320 ndbrequire(!createTabPtr.isNull());
5321
5322 createTabPtr.p->key = req->senderData;
5323 c_opCreateTable.add(createTabPtr);
5324 createTabPtr.p->m_errorCode = 0;
5325 createTabPtr.p->m_tablePtrI = tableId;
5326 createTabPtr.p->m_coordinatorRef = req->senderRef;
5327 createTabPtr.p->m_senderRef = req->clientRef;
5328 createTabPtr.p->m_senderData = req->clientData;
5329 createTabPtr.p->m_dihAddFragPtr = RNIL;
5330
5331 /**
5332 * Put data into table record
5333 */
5334 ParseDictTabInfoRecord parseRecord;
5335 parseRecord.requestType = DictTabInfo::AddTableFromDict;
5336 parseRecord.errorCode = 0;
5337
5338 SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
5339
5340 handleTabInfoInit(r, &parseRecord);
5341
5342 ndbrequire(parseRecord.errorCode == 0);
5343 }
5344
5345 ndbrequire(!createTabPtr.isNull());
5346
5347 SegmentedSectionPtr fragPtr;
5348 signal->getSection(fragPtr, CreateTabReq::FRAGMENTATION);
5349
5350 createTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
5351 createTabPtr.p->m_fragmentsPtrI = fragPtr.i;
5352
5353 signal->header.m_noOfSections = 0;
5354
5355 TableRecordPtr tabPtr;
5356 c_tableRecordPool.getPtr(tabPtr, tableId);
5357 tabPtr.p->packedSize = tabInfoPtr.sz;
5358 tabPtr.p->tableVersion = tableVersion;
5359 tabPtr.p->gciTableCreated = gci;
5360
5361 SchemaFile::TableEntry tabEntry;
5362 tabEntry.m_tableVersion = tableVersion;
5363 tabEntry.m_tableType = tabPtr.p->tableType;
5364 tabEntry.m_tableState = SchemaFile::ADD_STARTED;
5365 tabEntry.m_gcp = gci;
5366 tabEntry.m_info_words = tabInfoPtr.sz;
5367 memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
5368
5369 Callback callback;
5370 callback.m_callbackData = createTabPtr.p->key;
5371 callback.m_callbackFunction =
5372 safe_cast(&Dbdict::createTab_writeSchemaConf1);
5373
5374 bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
5375 updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
5376 }
5377
5378 void getSection(SegmentedSectionPtr & ptr, Uint32 i);
5379
5380 void
createTab_writeSchemaConf1(Signal * signal,Uint32 callbackData,Uint32 returnCode)5381 Dbdict::createTab_writeSchemaConf1(Signal* signal,
5382 Uint32 callbackData,
5383 Uint32 returnCode){
5384 jam();
5385
5386 CreateTableRecordPtr createTabPtr;
5387 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5388
5389 Callback callback;
5390 callback.m_callbackData = createTabPtr.p->key;
5391 callback.m_callbackFunction =
5392 safe_cast(&Dbdict::createTab_writeTableConf);
5393
5394 TableRecordPtr tabPtr;
5395 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5396 bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
5397 if (savetodisk)
5398 {
5399 SegmentedSectionPtr tabInfoPtr;
5400 getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
5401 writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
5402 }
5403 else
5404 {
5405 execute(signal, callback, 0);
5406 }
5407 #if 0
5408 createTabPtr.p->m_tabInfoPtrI = RNIL;
5409 signal->setSection(tabInfoPtr, 0);
5410 releaseSections(signal);
5411 #endif
5412 }
5413
5414 void
createTab_writeTableConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)5415 Dbdict::createTab_writeTableConf(Signal* signal,
5416 Uint32 callbackData,
5417 Uint32 returnCode){
5418 jam();
5419
5420 CreateTableRecordPtr createTabPtr;
5421 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5422
5423 SegmentedSectionPtr fragDataPtr;
5424 getSection(fragDataPtr, createTabPtr.p->m_fragmentsPtrI);
5425
5426 Callback callback;
5427 callback.m_callbackData = callbackData;
5428 callback.m_callbackFunction =
5429 safe_cast(&Dbdict::createTab_dihComplete);
5430
5431 createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
5432 }
5433
5434 void
createTab_dih(Signal * signal,CreateTableRecordPtr createTabPtr,SegmentedSectionPtr fragDataPtr,Callback * c)5435 Dbdict::createTab_dih(Signal* signal,
5436 CreateTableRecordPtr createTabPtr,
5437 SegmentedSectionPtr fragDataPtr,
5438 Callback * c){
5439 jam();
5440
5441 createTabPtr.p->m_callback = * c;
5442
5443 TableRecordPtr tabPtr;
5444 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5445
5446 DiAddTabReq * req = (DiAddTabReq*)signal->getDataPtrSend();
5447 req->connectPtr = createTabPtr.p->key;
5448 req->tableId = tabPtr.i;
5449 req->fragType = tabPtr.p->fragmentType;
5450 req->kValue = tabPtr.p->kValue;
5451 req->noOfReplicas = 0;
5452 req->loggedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged);
5453 req->tableType = tabPtr.p->tableType;
5454 req->schemaVersion = tabPtr.p->tableVersion;
5455 req->primaryTableId = tabPtr.p->primaryTableId;
5456 req->temporaryTable = !!(tabPtr.p->m_bits & TableRecord::TR_Temporary);
5457
5458 /*
5459 Beh�ver fiska upp fragDataPtr fr�n table object ist�llet
5460 */
5461 if(!fragDataPtr.isNull()){
5462 signal->setSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
5463 }
5464
5465 sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal,
5466 DiAddTabReq::SignalLength, JBB);
5467
5468 /**
5469 * Create KeyDescriptor
5470 */
5471 KeyDescriptor* desc= g_key_descriptor_pool.getPtr(tabPtr.i);
5472 new (desc) KeyDescriptor();
5473
5474 Uint32 key = 0;
5475 Ptr<AttributeRecord> attrPtr;
5476 LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
5477 tabPtr.p->m_attributes);
5478 for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr))
5479 {
5480 AttributeRecord* aRec = attrPtr.p;
5481 if (aRec->tupleKey)
5482 {
5483 Uint32 attr = aRec->attributeDescriptor;
5484
5485 desc->noOfKeyAttr ++;
5486 desc->keyAttr[key].attributeDescriptor = attr;
5487 Uint32 csNumber = (aRec->extPrecision >> 16);
5488 if (csNumber)
5489 {
5490 desc->keyAttr[key].charsetInfo = all_charsets[csNumber];
5491 ndbrequire(all_charsets[csNumber] != 0);
5492 desc->hasCharAttr = 1;
5493 }
5494 else
5495 {
5496 desc->keyAttr[key].charsetInfo = 0;
5497 }
5498 if (AttributeDescriptor::getDKey(attr))
5499 {
5500 desc->noOfDistrKeys ++;
5501 }
5502 if (AttributeDescriptor::getArrayType(attr) != NDB_ARRAYTYPE_FIXED)
5503 {
5504 desc->noOfVarKeys ++;
5505 }
5506 key++;
5507 }
5508 }
5509 ndbrequire(key == tabPtr.p->noOfPrimkey);
5510 }
5511
5512 static
5513 void
calcLHbits(Uint32 * lhPageBits,Uint32 * lhDistrBits,Uint32 fid,Uint32 totalFragments)5514 calcLHbits(Uint32 * lhPageBits, Uint32 * lhDistrBits,
5515 Uint32 fid, Uint32 totalFragments)
5516 {
5517 Uint32 distrBits = 0;
5518 Uint32 pageBits = 0;
5519
5520 Uint32 tmp = 1;
5521 while (tmp < totalFragments) {
5522 jam();
5523 tmp <<= 1;
5524 distrBits++;
5525 }//while
5526 #ifdef ndb_classical_lhdistrbits
5527 if (tmp != totalFragments) {
5528 tmp >>= 1;
5529 if ((fid >= (totalFragments - tmp)) && (fid < (tmp - 1))) {
5530 distrBits--;
5531 }//if
5532 }//if
5533 #endif
5534 * lhPageBits = pageBits;
5535 * lhDistrBits = distrBits;
5536
5537 }//calcLHbits()
5538
5539
5540 void
execADD_FRAGREQ(Signal * signal)5541 Dbdict::execADD_FRAGREQ(Signal* signal) {
5542 jamEntry();
5543
5544 AddFragReq * const req = (AddFragReq*)signal->getDataPtr();
5545
5546 Uint32 dihPtr = req->dihPtr;
5547 Uint32 senderData = req->senderData;
5548 Uint32 tableId = req->tableId;
5549 Uint32 fragId = req->fragmentId;
5550 Uint32 node = req->nodeId;
5551 Uint32 lcpNo = req->nextLCP;
5552 Uint32 fragCount = req->totalFragments;
5553 Uint32 requestInfo = req->requestInfo;
5554 Uint32 startGci = req->startGci;
5555 Uint32 logPart = req->logPartId;
5556
5557 ndbrequire(node == getOwnNodeId());
5558
5559 CreateTableRecordPtr createTabPtr;
5560 ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
5561
5562 createTabPtr.p->m_dihAddFragPtr = dihPtr;
5563
5564 TableRecordPtr tabPtr;
5565 c_tableRecordPool.getPtr(tabPtr, tableId);
5566
5567 #if 0
5568 tabPtr.p->gciTableCreated = (startGci > tabPtr.p->gciTableCreated ? startGci:
5569 startGci > tabPtr.p->gciTableCreated);
5570 #endif
5571
5572 /**
5573 * Calc lh3PageBits
5574 */
5575 Uint32 lhDistrBits = 0;
5576 Uint32 lhPageBits = 0;
5577 ::calcLHbits(&lhPageBits, &lhDistrBits, fragId, fragCount);
5578
5579 Uint64 maxRows = tabPtr.p->maxRowsLow +
5580 (((Uint64)tabPtr.p->maxRowsHigh) << 32);
5581 Uint64 minRows = tabPtr.p->minRowsLow +
5582 (((Uint64)tabPtr.p->minRowsHigh) << 32);
5583 maxRows = (maxRows + fragCount - 1) / fragCount;
5584 minRows = (minRows + fragCount - 1) / fragCount;
5585
5586 {
5587 LqhFragReq* req = (LqhFragReq*)signal->getDataPtrSend();
5588 req->senderData = senderData;
5589 req->senderRef = reference();
5590 req->fragmentId = fragId;
5591 req->requestInfo = requestInfo;
5592 req->tableId = tableId;
5593 req->localKeyLength = tabPtr.p->localKeyLen;
5594 req->maxLoadFactor = tabPtr.p->maxLoadFactor;
5595 req->minLoadFactor = tabPtr.p->minLoadFactor;
5596 req->kValue = tabPtr.p->kValue;
5597 req->lh3DistrBits = 0; //lhDistrBits;
5598 req->lh3PageBits = 0; //lhPageBits;
5599 req->noOfAttributes = tabPtr.p->noOfAttributes;
5600 req->noOfNullAttributes = tabPtr.p->noOfNullBits;
5601 req->maxRowsLow = maxRows & 0xFFFFFFFF;
5602 req->maxRowsHigh = maxRows >> 32;
5603 req->minRowsLow = minRows & 0xFFFFFFFF;
5604 req->minRowsHigh = minRows >> 32;
5605 req->schemaVersion = tabPtr.p->tableVersion;
5606 Uint32 keyLen = tabPtr.p->tupKeyLength;
5607 req->keyLength = keyLen; // wl-2066 no more "long keys"
5608 req->nextLCP = lcpNo;
5609
5610 req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
5611 req->noOfCharsets = tabPtr.p->noOfCharsets;
5612 req->checksumIndicator = 1;
5613 req->GCPIndicator = 1;
5614 req->startGci = startGci;
5615 req->tableType = tabPtr.p->tableType;
5616 req->primaryTableId = tabPtr.p->primaryTableId;
5617 req->tablespace_id= tabPtr.p->m_tablespace_id;
5618 req->logPartId = logPart;
5619 req->forceVarPartFlag = !!(tabPtr.p->m_bits& TableRecord::TR_ForceVarPart);
5620 sendSignal(DBLQH_REF, GSN_LQHFRAGREQ, signal,
5621 LqhFragReq::SignalLength, JBB);
5622 }
5623 }
5624
5625 void
execLQHFRAGREF(Signal * signal)5626 Dbdict::execLQHFRAGREF(Signal * signal){
5627 jamEntry();
5628 LqhFragRef * const ref = (LqhFragRef*)signal->getDataPtr();
5629
5630 CreateTableRecordPtr createTabPtr;
5631 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
5632
5633 createTabPtr.p->setErrorCode(ref->errorCode);
5634
5635 {
5636 AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
5637 ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
5638 sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal,
5639 AddFragRef::SignalLength, JBB);
5640 }
5641 }
5642
5643 void
execLQHFRAGCONF(Signal * signal)5644 Dbdict::execLQHFRAGCONF(Signal * signal){
5645 jamEntry();
5646 LqhFragConf * const conf = (LqhFragConf*)signal->getDataPtr();
5647
5648 CreateTableRecordPtr createTabPtr;
5649 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
5650
5651 createTabPtr.p->m_lqhFragPtr = conf->lqhFragPtr;
5652
5653 TableRecordPtr tabPtr;
5654 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5655 sendLQHADDATTRREQ(signal, createTabPtr, tabPtr.p->m_attributes.firstItem);
5656 }
5657
5658 void
sendLQHADDATTRREQ(Signal * signal,CreateTableRecordPtr createTabPtr,Uint32 attributePtrI)5659 Dbdict::sendLQHADDATTRREQ(Signal* signal,
5660 CreateTableRecordPtr createTabPtr,
5661 Uint32 attributePtrI){
5662 jam();
5663 TableRecordPtr tabPtr;
5664 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5665 LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend();
5666 Uint32 i = 0;
5667 for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){
5668 jam();
5669 AttributeRecordPtr attrPtr;
5670 c_attributeRecordPool.getPtr(attrPtr, attributePtrI);
5671 LqhAddAttrReq::Entry& entry = req->attributes[i];
5672 entry.attrId = attrPtr.p->attributeId;
5673 entry.attrDescriptor = attrPtr.p->attributeDescriptor;
5674 entry.extTypeInfo = 0;
5675 // charset number passed to TUP, TUX in upper half
5676 entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
5677 if (tabPtr.p->isIndex()) {
5678 Uint32 primaryAttrId;
5679 if (attrPtr.p->nextList != RNIL) {
5680 getIndexAttr(tabPtr, attributePtrI, &primaryAttrId);
5681 } else {
5682 primaryAttrId = ZNIL;
5683 if (tabPtr.p->isOrderedIndex())
5684 entry.attrId = 0; // attribute goes to TUP
5685 }
5686 entry.attrId |= (primaryAttrId << 16);
5687 }
5688 attributePtrI = attrPtr.p->nextList;
5689 }
5690 req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr;
5691 req->senderData = createTabPtr.p->key;
5692 req->senderAttrPtr = attributePtrI;
5693 req->noOfAttributes = i;
5694
5695 sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
5696 LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
5697 }
5698
5699 void
execLQHADDATTREF(Signal * signal)5700 Dbdict::execLQHADDATTREF(Signal * signal){
5701 jamEntry();
5702 LqhAddAttrRef * const ref = (LqhAddAttrRef*)signal->getDataPtr();
5703
5704 CreateTableRecordPtr createTabPtr;
5705 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
5706
5707 createTabPtr.p->setErrorCode(ref->errorCode);
5708
5709 {
5710 AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
5711 ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
5712 sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal,
5713 AddFragRef::SignalLength, JBB);
5714 }
5715
5716 }
5717
5718 void
execLQHADDATTCONF(Signal * signal)5719 Dbdict::execLQHADDATTCONF(Signal * signal){
5720 jamEntry();
5721 LqhAddAttrConf * const conf = (LqhAddAttrConf*)signal->getDataPtr();
5722
5723 CreateTableRecordPtr createTabPtr;
5724 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
5725
5726 const Uint32 fragId = conf->fragId;
5727 const Uint32 nextAttrPtr = conf->senderAttrPtr;
5728 if(nextAttrPtr != RNIL){
5729 jam();
5730 sendLQHADDATTRREQ(signal, createTabPtr, nextAttrPtr);
5731 return;
5732 }
5733
5734 {
5735 AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
5736 conf->dihPtr = createTabPtr.p->m_dihAddFragPtr;
5737 conf->fragId = fragId;
5738 sendSignal(DBDIH_REF, GSN_ADD_FRAGCONF, signal,
5739 AddFragConf::SignalLength, JBB);
5740 }
5741 }
5742
5743 void
execDIADDTABREF(Signal * signal)5744 Dbdict::execDIADDTABREF(Signal* signal){
5745 jam();
5746
5747 DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
5748
5749 CreateTableRecordPtr createTabPtr;
5750 ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
5751
5752 createTabPtr.p->setErrorCode(ref->errorCode);
5753 execute(signal, createTabPtr.p->m_callback, 0);
5754 }
5755
5756 void
execDIADDTABCONF(Signal * signal)5757 Dbdict::execDIADDTABCONF(Signal* signal){
5758 jam();
5759
5760 DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
5761
5762 CreateTableRecordPtr createTabPtr;
5763 ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
5764
5765 signal->theData[0] = createTabPtr.p->key;
5766 signal->theData[1] = reference();
5767 signal->theData[2] = createTabPtr.p->m_tablePtrI;
5768
5769 if(createTabPtr.p->m_dihAddFragPtr != RNIL){
5770 jam();
5771
5772 /**
5773 * We did perform at least one LQHFRAGREQ
5774 */
5775 sendSignal(DBLQH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
5776 return;
5777 } else {
5778 /**
5779 * No local fragment (i.e. no LQHFRAGREQ)
5780 */
5781 execute(signal, createTabPtr.p->m_callback, 0);
5782 return;
5783 //sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
5784 }
5785 }
5786
5787 void
execTAB_COMMITREF(Signal * signal)5788 Dbdict::execTAB_COMMITREF(Signal* signal) {
5789 jamEntry();
5790 ndbrequire(false);
5791 }//execTAB_COMMITREF()
5792
5793 void
execTAB_COMMITCONF(Signal * signal)5794 Dbdict::execTAB_COMMITCONF(Signal* signal){
5795 jamEntry();
5796
5797 CreateTableRecordPtr createTabPtr;
5798 ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[0]));
5799
5800 if(refToBlock(signal->getSendersBlockRef()) == DBLQH){
5801
5802 execute(signal, createTabPtr.p->m_callback, 0);
5803 return;
5804 }
5805
5806 if(refToBlock(signal->getSendersBlockRef()) == DBDIH){
5807 TableRecordPtr tabPtr;
5808 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5809
5810 signal->theData[0] = tabPtr.i;
5811 signal->theData[1] = tabPtr.p->tableVersion;
5812 signal->theData[2] = (Uint32)!!(tabPtr.p->m_bits & TableRecord::TR_Logged);
5813 signal->theData[3] = reference();
5814 signal->theData[4] = (Uint32)tabPtr.p->tableType;
5815 signal->theData[5] = createTabPtr.p->key;
5816 signal->theData[6] = (Uint32)tabPtr.p->noOfPrimkey;
5817 signal->theData[7] = (Uint32)tabPtr.p->singleUserMode;
5818
5819 sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 8, JBB);
5820 return;
5821 }
5822
5823 ndbrequire(false);
5824 }
5825
5826 void
createTab_dihComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)5827 Dbdict::createTab_dihComplete(Signal* signal,
5828 Uint32 callbackData,
5829 Uint32 returnCode){
5830 jam();
5831
5832 CreateTableRecordPtr createTabPtr;
5833 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5834
5835 //@todo check for master failed
5836
5837 if(createTabPtr.p->m_errorCode == 0){
5838 jam();
5839
5840 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
5841 conf->senderRef = reference();
5842 conf->senderData = createTabPtr.p->key;
5843 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
5844 signal, CreateTabConf::SignalLength, JBB);
5845 return;
5846 }
5847
5848 CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
5849 ref->senderRef = reference();
5850 ref->senderData = createTabPtr.p->key;
5851 ref->errorCode = createTabPtr.p->m_errorCode;
5852 ref->errorLine = 0;
5853 ref->errorKey = 0;
5854 ref->errorStatus = 0;
5855
5856 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_REF,
5857 signal, CreateTabRef::SignalLength, JBB);
5858 }
5859
5860 void
createTab_commit(Signal * signal,CreateTabReq * req)5861 Dbdict::createTab_commit(Signal * signal, CreateTabReq * req){
5862 jam();
5863
5864 CreateTableRecordPtr createTabPtr;
5865 ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
5866
5867 TableRecordPtr tabPtr;
5868 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5869 bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
5870
5871 SchemaFile::TableEntry tabEntry;
5872 tabEntry.m_tableVersion = tabPtr.p->tableVersion;
5873 tabEntry.m_tableType = tabPtr.p->tableType;
5874 if (savetodisk)
5875 tabEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
5876 else
5877 tabEntry.m_tableState = SchemaFile::TEMPORARY_TABLE_COMMITTED;
5878
5879 tabEntry.m_gcp = tabPtr.p->gciTableCreated;
5880 tabEntry.m_info_words = tabPtr.p->packedSize;
5881 memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
5882
5883 Callback callback;
5884 callback.m_callbackData = createTabPtr.p->key;
5885 callback.m_callbackFunction =
5886 safe_cast(&Dbdict::createTab_writeSchemaConf2);
5887
5888 updateSchemaState(signal, tabPtr.i, &tabEntry, &callback, savetodisk);
5889 }
5890
5891 void
createTab_writeSchemaConf2(Signal * signal,Uint32 callbackData,Uint32 returnCode)5892 Dbdict::createTab_writeSchemaConf2(Signal* signal,
5893 Uint32 callbackData,
5894 Uint32 returnCode){
5895 jam();
5896
5897 CreateTableRecordPtr createTabPtr;
5898 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5899
5900 Callback c;
5901 c.m_callbackData = callbackData;
5902 c.m_callbackFunction = safe_cast(&Dbdict::createTab_alterComplete);
5903 alterTab_activate(signal, createTabPtr, &c);
5904 }
5905
5906 void
createTab_alterComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)5907 Dbdict::createTab_alterComplete(Signal* signal,
5908 Uint32 callbackData,
5909 Uint32 returnCode){
5910 jam();
5911
5912 CreateTableRecordPtr createTabPtr;
5913 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5914
5915 TableRecordPtr tabPtr;
5916 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5917 tabPtr.p->tabState = TableRecord::DEFINED;
5918
5919 //@todo check error
5920 //@todo check master failed
5921
5922 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
5923 conf->senderRef = reference();
5924 conf->senderData = createTabPtr.p->key;
5925 {
5926 CreateTabConf tmp= *conf;
5927 conf->senderData = createTabPtr.p->m_tablePtrI;
5928 #if 0
5929 signal->header.m_noOfSections = 1;
5930 SegmentedSectionPtr tabInfoPtr;
5931 getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
5932 signal->setSection(tabInfoPtr, 0);
5933 #endif
5934 sendSignal(SUMA_REF, GSN_CREATE_TAB_CONF, signal,
5935 CreateTabConf::SignalLength, JBB);
5936 *conf= tmp;
5937 #if 0
5938 signal->header.m_noOfSections = 0;
5939 #endif
5940 }
5941 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
5942 signal, CreateTabConf::SignalLength, JBB);
5943
5944 if(createTabPtr.p->m_coordinatorRef != reference()){
5945 jam();
5946 releaseCreateTableOp(signal,createTabPtr);
5947 }
5948 }
5949
5950 void
createTab_drop(Signal * signal,CreateTabReq * req)5951 Dbdict::createTab_drop(Signal* signal, CreateTabReq * req){
5952 jam();
5953
5954 const Uint32 key = req->senderData;
5955
5956 CreateTableRecordPtr createTabPtr;
5957 ndbrequire(c_opCreateTable.find(createTabPtr, key));
5958
5959 TableRecordPtr tabPtr;
5960 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
5961 tabPtr.p->tabState = TableRecord::DROPPING;
5962
5963 DropTableRecordPtr dropTabPtr;
5964 ndbrequire(c_opDropTable.seize(dropTabPtr));
5965
5966 dropTabPtr.p->key = key;
5967 c_opDropTable.add(dropTabPtr);
5968
5969 dropTabPtr.p->m_errorCode = 0;
5970 dropTabPtr.p->m_request.tableId = createTabPtr.p->m_tablePtrI;
5971 dropTabPtr.p->m_requestType = DropTabReq::CreateTabDrop;
5972 dropTabPtr.p->m_coordinatorRef = createTabPtr.p->m_coordinatorRef;
5973 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
5974
5975 dropTabPtr.p->m_participantData.m_block = 0;
5976 dropTabPtr.p->m_participantData.m_callback.m_callbackData = req->senderData;
5977 dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
5978 safe_cast(&Dbdict::createTab_dropComplete);
5979 dropTab_nextStep(signal, dropTabPtr);
5980
5981 if (tabPtr.p->m_tablespace_id != RNIL)
5982 {
5983 FilegroupPtr ptr;
5984 ndbrequire(c_filegroup_hash.find(ptr, tabPtr.p->m_tablespace_id));
5985 decrease_ref_count(ptr.p->m_obj_ptr_i);
5986 }
5987 }
5988
5989 void
createTab_dropComplete(Signal * signal,Uint32 callbackData,Uint32 returnCode)5990 Dbdict::createTab_dropComplete(Signal* signal,
5991 Uint32 callbackData,
5992 Uint32 returnCode){
5993 jam();
5994
5995 CreateTableRecordPtr createTabPtr;
5996 ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
5997
5998 DropTableRecordPtr dropTabPtr;
5999 ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
6000
6001 TableRecordPtr tabPtr;
6002 c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
6003
6004 releaseTableObject(tabPtr.i);
6005
6006 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
6007 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tabPtr.i);
6008 tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
6009
6010 //@todo check error
6011 //@todo check master failed
6012
6013 CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
6014 conf->senderRef = reference();
6015 conf->senderData = createTabPtr.p->key;
6016 sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
6017 signal, CreateTabConf::SignalLength, JBB);
6018
6019 if(createTabPtr.p->m_coordinatorRef != reference()){
6020 jam();
6021 releaseCreateTableOp(signal,createTabPtr);
6022 }
6023
6024 c_opDropTable.release(dropTabPtr);
6025 }
6026
6027 void
alterTab_activate(Signal * signal,CreateTableRecordPtr createTabPtr,Callback * c)6028 Dbdict::alterTab_activate(Signal* signal, CreateTableRecordPtr createTabPtr,
6029 Callback * c){
6030
6031 createTabPtr.p->m_callback = * c;
6032
6033 signal->theData[0] = createTabPtr.p->key;
6034 signal->theData[1] = reference();
6035 signal->theData[2] = createTabPtr.p->m_tablePtrI;
6036 sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
6037 }
6038
6039 void
execTC_SCHVERCONF(Signal * signal)6040 Dbdict::execTC_SCHVERCONF(Signal* signal){
6041 jamEntry();
6042
6043 CreateTableRecordPtr createTabPtr;
6044 ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[1]));
6045
6046 execute(signal, createTabPtr.p->m_callback, 0);
6047 }
6048
6049 #define tabRequire(cond, error) \
6050 if (!(cond)) { \
6051 jam(); \
6052 parseP->errorCode = error; parseP->errorLine = __LINE__; \
6053 parseP->errorKey = it.getKey(); \
6054 return; \
6055 }//if
6056
6057 // handleAddTableFailure(signal, __LINE__, allocatedTable);
6058
6059 Dbdict::DictObject *
get_object(const char * name,Uint32 len,Uint32 hash)6060 Dbdict::get_object(const char * name, Uint32 len, Uint32 hash){
6061 DictObject key;
6062 key.m_key.m_name_ptr = name;
6063 key.m_key.m_name_len = len;
6064 key.m_key.m_pool = &c_rope_pool;
6065 key.m_name.m_hash = hash;
6066 Ptr<DictObject> old_ptr;
6067 c_obj_hash.find(old_ptr, key);
6068 return old_ptr.p;
6069 }
6070
6071 void
release_object(Uint32 obj_ptr_i,DictObject * obj_ptr_p)6072 Dbdict::release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p){
6073 Rope name(c_rope_pool, obj_ptr_p->m_name);
6074 name.erase();
6075
6076 Ptr<DictObject> ptr = { obj_ptr_p, obj_ptr_i };
6077 c_obj_hash.release(ptr);
6078 }
6079
6080 void
increase_ref_count(Uint32 obj_ptr_i)6081 Dbdict::increase_ref_count(Uint32 obj_ptr_i)
6082 {
6083 DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i);
6084 ptr->m_ref_count++;
6085 }
6086
6087 void
decrease_ref_count(Uint32 obj_ptr_i)6088 Dbdict::decrease_ref_count(Uint32 obj_ptr_i)
6089 {
6090 DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i);
6091 ndbrequire(ptr->m_ref_count);
6092 ptr->m_ref_count--;
6093 }
6094
handleTabInfoInit(SimpleProperties::Reader & it,ParseDictTabInfoRecord * parseP,bool checkExist)6095 void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
6096 ParseDictTabInfoRecord * parseP,
6097 bool checkExist)
6098 {
6099 /* ---------------------------------------------------------------- */
6100 // We always start by handling table name since this must be the first
6101 // item in the list. Through the table name we can derive if it is a
6102 // correct name, a new name or an already existing table.
6103 /* ---------------------------------------------------------------- */
6104
6105 it.first();
6106
6107 SimpleProperties::UnpackStatus status;
6108 c_tableDesc.init();
6109 status = SimpleProperties::unpack(it, &c_tableDesc,
6110 DictTabInfo::TableMapping,
6111 DictTabInfo::TableMappingSize,
6112 true, true);
6113
6114 if(status != SimpleProperties::Break){
6115 parseP->errorCode = CreateTableRef::InvalidFormat;
6116 parseP->status = status;
6117 parseP->errorKey = it.getKey();
6118 parseP->errorLine = __LINE__;
6119 return;
6120 }
6121
6122 if(parseP->requestType == DictTabInfo::AlterTableFromAPI)
6123 {
6124 ndbrequire(!checkExist);
6125 }
6126 if(!checkExist)
6127 {
6128 ndbrequire(parseP->requestType == DictTabInfo::AlterTableFromAPI);
6129 }
6130
6131 /* ---------------------------------------------------------------- */
6132 // Verify that table name is an allowed table name.
6133 // TODO
6134 /* ---------------------------------------------------------------- */
6135 const Uint32 tableNameLength = strlen(c_tableDesc.TableName) + 1;
6136 const Uint32 name_hash = Rope::hash(c_tableDesc.TableName, tableNameLength);
6137
6138 if(checkExist){
6139 jam();
6140 tabRequire(get_object(c_tableDesc.TableName, tableNameLength) == 0,
6141 CreateTableRef::TableAlreadyExist);
6142 }
6143
6144 TableRecordPtr tablePtr;
6145 switch (parseP->requestType) {
6146 case DictTabInfo::CreateTableFromAPI: {
6147 jam();
6148 }
6149 case DictTabInfo::AlterTableFromAPI:{
6150 jam();
6151 tablePtr.i = getFreeTableRecord(c_tableDesc.PrimaryTableId);
6152 /* ---------------------------------------------------------------- */
6153 // Check if no free tables existed.
6154 /* ---------------------------------------------------------------- */
6155 tabRequire(tablePtr.i != RNIL, CreateTableRef::NoMoreTableRecords);
6156
6157 c_tableRecordPool.getPtr(tablePtr);
6158 break;
6159 }
6160 case DictTabInfo::AddTableFromDict:
6161 case DictTabInfo::ReadTableFromDiskSR:
6162 case DictTabInfo::GetTabInfoConf:
6163 {
6164 /* ---------------------------------------------------------------- */
6165 // Get table id and check that table doesn't already exist
6166 /* ---------------------------------------------------------------- */
6167 tablePtr.i = c_tableDesc.TableId;
6168
6169 if (parseP->requestType == DictTabInfo::ReadTableFromDiskSR) {
6170 ndbrequire(tablePtr.i == c_restartRecord.activeTable);
6171 }//if
6172 if (parseP->requestType == DictTabInfo::GetTabInfoConf) {
6173 ndbrequire(tablePtr.i == c_restartRecord.activeTable);
6174 }//if
6175
6176 c_tableRecordPool.getPtr(tablePtr);
6177 ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
6178
6179 //Uint32 oldTableVersion = tablePtr.p->tableVersion;
6180 initialiseTableRecord(tablePtr);
6181 if (parseP->requestType == DictTabInfo::AddTableFromDict) {
6182 jam();
6183 tablePtr.p->tabState = TableRecord::DEFINING;
6184 }//if
6185
6186 /* ---------------------------------------------------------------- */
6187 // Set table version
6188 /* ---------------------------------------------------------------- */
6189 Uint32 tableVersion = c_tableDesc.TableVersion;
6190 tablePtr.p->tableVersion = tableVersion;
6191
6192 break;
6193 }
6194 default:
6195 ndbrequire(false);
6196 break;
6197 }//switch
6198 parseP->tablePtr = tablePtr;
6199
6200 {
6201 Rope name(c_rope_pool, tablePtr.p->tableName);
6202 tabRequire(name.assign(c_tableDesc.TableName, tableNameLength, name_hash),
6203 CreateTableRef::OutOfStringBuffer);
6204 }
6205
6206 Ptr<DictObject> obj_ptr;
6207 if (parseP->requestType != DictTabInfo::AlterTableFromAPI) {
6208 jam();
6209 ndbrequire(c_obj_hash.seize(obj_ptr));
6210 obj_ptr.p->m_id = tablePtr.i;
6211 obj_ptr.p->m_type = c_tableDesc.TableType;
6212 obj_ptr.p->m_name = tablePtr.p->tableName;
6213 obj_ptr.p->m_ref_count = 0;
6214 c_obj_hash.add(obj_ptr);
6215 tablePtr.p->m_obj_ptr_i = obj_ptr.i;
6216
6217 #ifdef VM_TRACE
6218 ndbout_c("Dbdict: name=%s,id=%u,obj_ptr_i=%d",
6219 c_tableDesc.TableName, tablePtr.i, tablePtr.p->m_obj_ptr_i);
6220 #endif
6221 }
6222
6223 // Disallow logging of a temporary table.
6224 tabRequire(!(c_tableDesc.TableTemporaryFlag && c_tableDesc.TableLoggedFlag),
6225 CreateTableRef::NoLoggingTemporaryTable);
6226
6227 tablePtr.p->noOfAttributes = c_tableDesc.NoOfAttributes;
6228 tablePtr.p->m_bits |=
6229 (c_tableDesc.TableLoggedFlag ? TableRecord::TR_Logged : 0);
6230 tablePtr.p->m_bits |=
6231 (c_tableDesc.RowChecksumFlag ? TableRecord::TR_RowChecksum : 0);
6232 tablePtr.p->m_bits |=
6233 (c_tableDesc.RowGCIFlag ? TableRecord::TR_RowGCI : 0);
6234 tablePtr.p->m_bits |=
6235 (c_tableDesc.TableTemporaryFlag ? TableRecord::TR_Temporary : 0);
6236 tablePtr.p->m_bits |=
6237 (c_tableDesc.ForceVarPartFlag ? TableRecord::TR_ForceVarPart : 0);
6238 tablePtr.p->minLoadFactor = c_tableDesc.MinLoadFactor;
6239 tablePtr.p->maxLoadFactor = c_tableDesc.MaxLoadFactor;
6240 tablePtr.p->fragmentType = (DictTabInfo::FragmentType)c_tableDesc.FragmentType;
6241 tablePtr.p->tableType = (DictTabInfo::TableType)c_tableDesc.TableType;
6242 tablePtr.p->kValue = c_tableDesc.TableKValue;
6243 tablePtr.p->fragmentCount = c_tableDesc.FragmentCount;
6244 tablePtr.p->m_tablespace_id = c_tableDesc.TablespaceId;
6245 tablePtr.p->maxRowsLow = c_tableDesc.MaxRowsLow;
6246 tablePtr.p->maxRowsHigh = c_tableDesc.MaxRowsHigh;
6247 tablePtr.p->minRowsLow = c_tableDesc.MinRowsLow;
6248 tablePtr.p->minRowsHigh = c_tableDesc.MinRowsHigh;
6249 tablePtr.p->defaultNoPartFlag = c_tableDesc.DefaultNoPartFlag;
6250 tablePtr.p->linearHashFlag = c_tableDesc.LinearHashFlag;
6251 tablePtr.p->singleUserMode = c_tableDesc.SingleUserMode;
6252
6253 {
6254 Rope frm(c_rope_pool, tablePtr.p->frmData);
6255 tabRequire(frm.assign(c_tableDesc.FrmData, c_tableDesc.FrmLen),
6256 CreateTableRef::OutOfStringBuffer);
6257 Rope range(c_rope_pool, tablePtr.p->rangeData);
6258 tabRequire(range.assign(c_tableDesc.RangeListData,
6259 c_tableDesc.RangeListDataLen),
6260 CreateTableRef::OutOfStringBuffer);
6261 Rope fd(c_rope_pool, tablePtr.p->ngData);
6262 tabRequire(fd.assign((const char*)c_tableDesc.FragmentData,
6263 c_tableDesc.FragmentDataLen),
6264 CreateTableRef::OutOfStringBuffer);
6265 Rope ts(c_rope_pool, tablePtr.p->tsData);
6266 tabRequire(ts.assign((const char*)c_tableDesc.TablespaceData,
6267 c_tableDesc.TablespaceDataLen),
6268 CreateTableRef::OutOfStringBuffer);
6269 }
6270
6271 c_fragDataLen = c_tableDesc.FragmentDataLen;
6272 memcpy(c_fragData, c_tableDesc.FragmentData,
6273 c_tableDesc.FragmentDataLen);
6274
6275 if(c_tableDesc.PrimaryTableId != RNIL) {
6276
6277 tablePtr.p->primaryTableId = c_tableDesc.PrimaryTableId;
6278 tablePtr.p->indexState = (TableRecord::IndexState)c_tableDesc.IndexState;
6279 tablePtr.p->insertTriggerId = c_tableDesc.InsertTriggerId;
6280 tablePtr.p->updateTriggerId = c_tableDesc.UpdateTriggerId;
6281 tablePtr.p->deleteTriggerId = c_tableDesc.DeleteTriggerId;
6282 tablePtr.p->customTriggerId = c_tableDesc.CustomTriggerId;
6283 } else {
6284 tablePtr.p->primaryTableId = RNIL;
6285 tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
6286 tablePtr.p->insertTriggerId = RNIL;
6287 tablePtr.p->updateTriggerId = RNIL;
6288 tablePtr.p->deleteTriggerId = RNIL;
6289 tablePtr.p->customTriggerId = RNIL;
6290 }
6291 tablePtr.p->buildTriggerId = RNIL;
6292 tablePtr.p->indexLocal = 0;
6293
6294 handleTabInfo(it, parseP, c_tableDesc);
6295
6296 if(parseP->errorCode != 0)
6297 {
6298 /**
6299 * Release table
6300 */
6301 releaseTableObject(tablePtr.i, checkExist);
6302 return;
6303 }
6304
6305 if (checkExist && tablePtr.p->m_tablespace_id != RNIL)
6306 {
6307 /**
6308 * Increase ref count
6309 */
6310 FilegroupPtr ptr;
6311 ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
6312 increase_ref_count(ptr.p->m_obj_ptr_i);
6313 }
6314 }//handleTabInfoInit()
6315
handleTabInfo(SimpleProperties::Reader & it,ParseDictTabInfoRecord * parseP,DictTabInfo::Table & tableDesc)6316 void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
6317 ParseDictTabInfoRecord * parseP,
6318 DictTabInfo::Table &tableDesc)
6319 {
6320 TableRecordPtr tablePtr = parseP->tablePtr;
6321
6322 SimpleProperties::UnpackStatus status;
6323
6324 Uint32 keyCount = 0;
6325 Uint32 keyLength = 0;
6326 Uint32 attrCount = tablePtr.p->noOfAttributes;
6327 Uint32 nullCount = 0;
6328 Uint32 nullBits = 0;
6329 Uint32 noOfCharsets = 0;
6330 Uint16 charsets[128];
6331 Uint32 recordLength = 0;
6332 AttributeRecordPtr attrPtr;
6333 c_attributeRecordHash.removeAll();
6334
6335 LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
6336 tablePtr.p->m_attributes);
6337
6338 Uint32 counts[] = {0,0,0,0,0};
6339
6340 for(Uint32 i = 0; i<attrCount; i++){
6341 /**
6342 * Attribute Name
6343 */
6344 DictTabInfo::Attribute attrDesc; attrDesc.init();
6345 status = SimpleProperties::unpack(it, &attrDesc,
6346 DictTabInfo::AttributeMapping,
6347 DictTabInfo::AttributeMappingSize,
6348 true, true);
6349
6350 if(status != SimpleProperties::Break){
6351 parseP->errorCode = CreateTableRef::InvalidFormat;
6352 parseP->status = status;
6353 parseP->errorKey = it.getKey();
6354 parseP->errorLine = __LINE__;
6355 return;
6356 }
6357
6358 /**
6359 * Check that attribute is not defined twice
6360 */
6361 const size_t len = strlen(attrDesc.AttributeName)+1;
6362 const Uint32 name_hash = Rope::hash(attrDesc.AttributeName, len);
6363 {
6364 AttributeRecord key;
6365 key.m_key.m_name_ptr = attrDesc.AttributeName;
6366 key.m_key.m_name_len = len;
6367 key.attributeName.m_hash = name_hash;
6368 key.m_key.m_pool = &c_rope_pool;
6369 Ptr<AttributeRecord> old_ptr;
6370 c_attributeRecordHash.find(old_ptr, key);
6371
6372 if(old_ptr.i != RNIL){
6373 parseP->errorCode = CreateTableRef::AttributeNameTwice;
6374 return;
6375 }
6376 }
6377
6378 list.seize(attrPtr);
6379 if(attrPtr.i == RNIL){
6380 jam();
6381 parseP->errorCode = CreateTableRef::NoMoreAttributeRecords;
6382 return;
6383 }
6384
6385 new (attrPtr.p) AttributeRecord();
6386 attrPtr.p->attributeDescriptor = 0x00012255; //Default value
6387 attrPtr.p->tupleKey = 0;
6388
6389 /**
6390 * TmpAttrib to Attribute mapping
6391 */
6392 {
6393 Rope name(c_rope_pool, attrPtr.p->attributeName);
6394 if (!name.assign(attrDesc.AttributeName, len, name_hash))
6395 {
6396 jam();
6397 parseP->errorCode = CreateTableRef::OutOfStringBuffer;
6398 parseP->errorLine = __LINE__;
6399 return;
6400 }
6401 }
6402 attrPtr.p->attributeId = i;
6403 //attrPtr.p->attributeId = attrDesc.AttributeId;
6404 attrPtr.p->tupleKey = (keyCount + 1) * attrDesc.AttributeKeyFlag;
6405
6406 attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision;
6407 attrPtr.p->extScale = attrDesc.AttributeExtScale;
6408 attrPtr.p->extLength = attrDesc.AttributeExtLength;
6409 // charset in upper half of precision
6410 unsigned csNumber = (attrPtr.p->extPrecision >> 16);
6411 if (csNumber != 0) {
6412 /*
6413 * A new charset is first accessed here on this node.
6414 * TODO use separate thread (e.g. via NDBFS) if need to load from file
6415 */
6416 CHARSET_INFO* cs = get_charset(csNumber, MYF(0));
6417 if (cs == NULL) {
6418 parseP->errorCode = CreateTableRef::InvalidCharset;
6419 parseP->errorLine = __LINE__;
6420 return;
6421 }
6422 // XXX should be done somewhere in mysql
6423 all_charsets[cs->number] = cs;
6424 unsigned i = 0;
6425 while (i < noOfCharsets) {
6426 if (charsets[i] == csNumber)
6427 break;
6428 i++;
6429 }
6430 if (i == noOfCharsets) {
6431 noOfCharsets++;
6432 if (noOfCharsets > sizeof(charsets)/sizeof(charsets[0])) {
6433 parseP->errorCode = CreateTableRef::InvalidFormat;
6434 parseP->errorLine = __LINE__;
6435 return;
6436 }
6437 charsets[i] = csNumber;
6438 }
6439 }
6440
6441 // compute attribute size and array size
6442 bool translateOk = attrDesc.translateExtType();
6443 tabRequire(translateOk, CreateTableRef::Inconsistency);
6444
6445 if(attrDesc.AttributeArraySize > 65535){
6446 parseP->errorCode = CreateTableRef::ArraySizeTooBig;
6447 parseP->status = status;
6448 parseP->errorKey = it.getKey();
6449 parseP->errorLine = __LINE__;
6450 return;
6451 }
6452
6453 // XXX old test option, remove
6454 if(!attrDesc.AttributeKeyFlag &&
6455 tablePtr.i > 1 &&
6456 !tablePtr.p->isIndex())
6457 {
6458 //attrDesc.AttributeStorageType= NDB_STORAGETYPE_DISK;
6459 }
6460
6461 Uint32 desc = 0;
6462 AttributeDescriptor::setType(desc, attrDesc.AttributeExtType);
6463 AttributeDescriptor::setSize(desc, attrDesc.AttributeSize);
6464 AttributeDescriptor::setArraySize(desc, attrDesc.AttributeArraySize);
6465 AttributeDescriptor::setArrayType(desc, attrDesc.AttributeArrayType);
6466 AttributeDescriptor::setNullable(desc, attrDesc.AttributeNullableFlag);
6467 AttributeDescriptor::setDKey(desc, attrDesc.AttributeDKey);
6468 AttributeDescriptor::setPrimaryKey(desc, attrDesc.AttributeKeyFlag);
6469 AttributeDescriptor::setDiskBased(desc, attrDesc.AttributeStorageType == NDB_STORAGETYPE_DISK);
6470 attrPtr.p->attributeDescriptor = desc;
6471 attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement;
6472 {
6473 Rope defaultValue(c_rope_pool, attrPtr.p->defaultValue);
6474 defaultValue.assign(attrDesc.AttributeDefaultValue);
6475 }
6476
6477 keyCount += attrDesc.AttributeKeyFlag;
6478 nullCount += attrDesc.AttributeNullableFlag;
6479
6480 const Uint32 aSz = (1 << attrDesc.AttributeSize);
6481 Uint32 sz;
6482 if(aSz != 1)
6483 {
6484 sz = ((aSz * attrDesc.AttributeArraySize) + 31) >> 5;
6485 }
6486 else
6487 {
6488 sz = 0;
6489 nullBits += attrDesc.AttributeArraySize;
6490 }
6491
6492 if(attrDesc.AttributeArraySize == 0)
6493 {
6494 parseP->errorCode = CreateTableRef::InvalidArraySize;
6495 parseP->status = status;
6496 parseP->errorKey = it.getKey();
6497 parseP->errorLine = __LINE__;
6498 return;
6499 }
6500
6501 recordLength += sz;
6502 if(attrDesc.AttributeKeyFlag){
6503 keyLength += sz;
6504
6505 if(attrDesc.AttributeNullableFlag){
6506 parseP->errorCode = CreateTableRef::NullablePrimaryKey;
6507 parseP->status = status;
6508 parseP->errorKey = it.getKey();
6509 parseP->errorLine = __LINE__;
6510 return;
6511 }
6512 }
6513
6514 c_attributeRecordHash.add(attrPtr);
6515
6516 int a= AttributeDescriptor::getDiskBased(desc);
6517 int b= AttributeDescriptor::getArrayType(desc);
6518 Uint32 pos= 2*(a ? 1 : 0) + (b == NDB_ARRAYTYPE_FIXED ? 0 : 1);
6519 counts[pos+1]++;
6520
6521 if(b != NDB_ARRAYTYPE_FIXED && sz == 0)
6522 {
6523 parseP->errorCode = CreateTableRef::VarsizeBitfieldNotSupported;
6524 parseP->status = status;
6525 parseP->errorKey = it.getKey();
6526 parseP->errorLine = __LINE__;
6527 return;
6528 }
6529
6530 if(!it.next())
6531 break;
6532
6533 if(it.getKey() != DictTabInfo::AttributeName)
6534 break;
6535 }//while
6536
6537 tablePtr.p->noOfPrimkey = keyCount;
6538 tablePtr.p->noOfNullAttr = nullCount;
6539 tablePtr.p->noOfCharsets = noOfCharsets;
6540 tablePtr.p->tupKeyLength = keyLength;
6541 tablePtr.p->noOfNullBits = nullCount + nullBits;
6542
6543 tabRequire(recordLength<= MAX_TUPLE_SIZE_IN_WORDS,
6544 CreateTableRef::RecordTooBig);
6545 tabRequire(keyLength <= MAX_KEY_SIZE_IN_WORDS,
6546 CreateTableRef::InvalidPrimaryKeySize);
6547 tabRequire(keyLength > 0,
6548 CreateTableRef::InvalidPrimaryKeySize);
6549
6550 if(tablePtr.p->m_tablespace_id != RNIL || counts[3] || counts[4])
6551 {
6552 FilegroupPtr tablespacePtr;
6553 if(!c_filegroup_hash.find(tablespacePtr, tablePtr.p->m_tablespace_id))
6554 {
6555 tabRequire(false, CreateTableRef::InvalidTablespace);
6556 }
6557
6558 if(tablespacePtr.p->m_type != DictTabInfo::Tablespace)
6559 {
6560 tabRequire(false, CreateTableRef::NotATablespace);
6561 }
6562
6563 if(tablespacePtr.p->m_version != tableDesc.TablespaceVersion)
6564 {
6565 tabRequire(false, CreateTableRef::InvalidTablespaceVersion);
6566 }
6567 }
6568 }//handleTabInfo()
6569
6570
6571 /* ---------------------------------------------------------------- */
6572 // DICTTABCONF is sent when participants have received all DICTTABINFO
6573 // and successfully handled it.
6574 // Also sent to self (DICT master) when index table creation ready.
6575 /* ---------------------------------------------------------------- */
execCREATE_TABLE_CONF(Signal * signal)6576 void Dbdict::execCREATE_TABLE_CONF(Signal* signal)
6577 {
6578 jamEntry();
6579 ndbrequire(signal->getNoOfSections() == 0);
6580
6581 CreateTableConf * const conf = (CreateTableConf *)signal->getDataPtr();
6582 // assume part of create index operation
6583 OpCreateIndexPtr opPtr;
6584 c_opCreateIndex.find(opPtr, conf->senderData);
6585 ndbrequire(! opPtr.isNull());
6586 opPtr.p->m_request.setIndexId(conf->tableId);
6587 opPtr.p->m_request.setIndexVersion(conf->tableVersion);
6588 createIndex_fromCreateTable(signal, opPtr);
6589 }//execCREATE_TABLE_CONF()
6590
execCREATE_TABLE_REF(Signal * signal)6591 void Dbdict::execCREATE_TABLE_REF(Signal* signal)
6592 {
6593 jamEntry();
6594
6595 CreateTableRef * const ref = (CreateTableRef *)signal->getDataPtr();
6596 // assume part of create index operation
6597 OpCreateIndexPtr opPtr;
6598 c_opCreateIndex.find(opPtr, ref->senderData);
6599 ndbrequire(! opPtr.isNull());
6600 opPtr.p->setError(ref);
6601 createIndex_fromCreateTable(signal, opPtr);
6602 }//execCREATE_TABLE_REF()
6603
6604 /* ---------------------------------------------------------------- */
6605 // New global checkpoint created.
6606 /* ---------------------------------------------------------------- */
execWAIT_GCP_CONF(Signal * signal)6607 void Dbdict::execWAIT_GCP_CONF(Signal* signal)
6608 {
6609 #if 0
6610 TableRecordPtr tablePtr;
6611 jamEntry();
6612 WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
6613 c_tableRecordPool.getPtr(tablePtr, c_connRecord.connTableId);
6614 tablePtr.p->gciTableCreated = conf->gcp;
6615 sendUpdateSchemaState(signal,
6616 tablePtr.i,
6617 SchemaFile::TABLE_ADD_COMMITTED,
6618 c_connRecord.noOfPagesForTable,
6619 conf->gcp);
6620 #endif
6621 }//execWAIT_GCP_CONF()
6622
6623 /* ---------------------------------------------------------------- */
6624 // Refused new global checkpoint.
6625 /* ---------------------------------------------------------------- */
execWAIT_GCP_REF(Signal * signal)6626 void Dbdict::execWAIT_GCP_REF(Signal* signal)
6627 {
6628 jamEntry();
6629 WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
6630 /* ---------------------------------------------------------------- */
6631 // Error Handling code needed
6632 /* ---------------------------------------------------------------- */
6633 char buf[32];
6634 BaseString::snprintf(buf, sizeof(buf), "WAIT_GCP_REF ErrorCode=%d",
6635 ref->errorCode);
6636 progError(__LINE__, NDBD_EXIT_NDBREQUIRE, buf);
6637 }//execWAIT_GCP_REF()
6638
6639
6640 /* **************************************************************** */
6641 /* ---------------------------------------------------------------- */
6642 /* MODULE: DROP TABLE -------------------- */
6643 /* ---------------------------------------------------------------- */
6644 /* */
6645 /* This module contains the code used to drop a table. */
6646 /* ---------------------------------------------------------------- */
6647 /* **************************************************************** */
6648 void
execDROP_TABLE_REQ(Signal * signal)6649 Dbdict::execDROP_TABLE_REQ(Signal* signal){
6650 jamEntry();
6651 DropTableReq* req = (DropTableReq*)signal->getDataPtr();
6652
6653 TableRecordPtr tablePtr;
6654 c_tableRecordPool.getPtr(tablePtr, req->tableId, false);
6655 if(tablePtr.isNull()){
6656 jam();
6657 dropTableRef(signal, req, DropTableRef::NoSuchTable);
6658 return;
6659 }
6660
6661 if(getOwnNodeId() != c_masterNodeId){
6662 jam();
6663 dropTableRef(signal, req, DropTableRef::NotMaster);
6664 return;
6665 }
6666
6667 if(c_blockState == BS_NODE_RESTART){
6668 jam();
6669 dropTableRef(signal, req, DropTableRef::BusyWithNR);
6670 return;
6671 }
6672
6673 if(c_blockState != BS_IDLE){
6674 jam();
6675 dropTableRef(signal, req, DropTableRef::Busy);
6676 return;
6677 }
6678
6679 if (checkSingleUserMode(signal->getSendersBlockRef()))
6680 {
6681 jam();
6682 dropTableRef(signal, req, DropTableRef::SingleUser);
6683 return;
6684 }
6685
6686 const TableRecord::TabState tabState = tablePtr.p->tabState;
6687 bool ok = false;
6688 switch(tabState){
6689 case TableRecord::NOT_DEFINED:
6690 case TableRecord::DEFINING:
6691 jam();
6692 dropTableRef(signal, req, DropTableRef::NoSuchTable);
6693 return;
6694 case TableRecord::DEFINED:
6695 ok = true;
6696 jam();
6697 break;
6698 case TableRecord::PREPARE_DROPPING:
6699 case TableRecord::DROPPING:
6700 jam();
6701 dropTableRef(signal, req, DropTableRef::DropInProgress);
6702 return;
6703 case TableRecord::BACKUP_ONGOING:
6704 jam();
6705 dropTableRef(signal, req, DropTableRef::BackupInProgress);
6706 return;
6707 }
6708 ndbrequire(ok);
6709
6710 if(tablePtr.p->tableVersion != req->tableVersion){
6711 jam();
6712 dropTableRef(signal, req, DropTableRef::InvalidTableVersion);
6713 return;
6714 }
6715
6716 /**
6717 * Seems ok
6718 */
6719 DropTableRecordPtr dropTabPtr;
6720 c_opDropTable.seize(dropTabPtr);
6721
6722 if(dropTabPtr.isNull()){
6723 jam();
6724 dropTableRef(signal, req, DropTableRef::NoDropTableRecordAvailable);
6725 return;
6726 }
6727
6728 c_blockState = BS_BUSY;
6729
6730 dropTabPtr.p->key = ++c_opRecordSequence;
6731 c_opDropTable.add(dropTabPtr);
6732
6733 dropTabPtr.p->m_request = * req;
6734 dropTabPtr.p->m_errorCode = 0;
6735 dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab;
6736 dropTabPtr.p->m_coordinatorRef = reference();
6737 dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ;
6738 dropTabPtr.p->m_coordinatorData.m_block = 0;
6739
6740 Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
6741 Callback c = { safe_cast(&Dbdict::dropTable_backup_mutex_locked),
6742 dropTabPtr.p->key};
6743
6744 ndbrequire(mutex.lock(c));
6745
6746 }
6747
6748 void
dropTable_backup_mutex_locked(Signal * signal,Uint32 callbackData,Uint32 retValue)6749 Dbdict::dropTable_backup_mutex_locked(Signal* signal,
6750 Uint32 callbackData,
6751 Uint32 retValue){
6752 jamEntry();
6753
6754 ndbrequire(retValue == 0);
6755
6756 DropTableRecordPtr dropTabPtr;
6757 ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
6758
6759 TableRecordPtr tablePtr;
6760 c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId, true);
6761
6762 Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
6763 mutex.unlock(); // ignore response
6764
6765 if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
6766 {
6767 jam();
6768 dropTableRef(signal, &dropTabPtr.p->m_request,
6769 DropTableRef::BackupInProgress);
6770
6771 c_blockState = BS_IDLE;
6772 c_opDropTable.release(dropTabPtr);
6773 }
6774 else
6775 {
6776 jam();
6777 tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
6778 prepDropTab_nextStep(signal, dropTabPtr);
6779 }
6780 }
6781
6782 void
dropTableRef(Signal * signal,DropTableReq * req,DropTableRef::ErrorCode errCode)6783 Dbdict::dropTableRef(Signal * signal,
6784 DropTableReq * req, DropTableRef::ErrorCode errCode){
6785
6786 Uint32 tableId = req->tableId;
6787 Uint32 tabVersion = req->tableVersion;
6788 Uint32 senderData = req->senderData;
6789 Uint32 senderRef = req->senderRef;
6790
6791 DropTableRef * ref = (DropTableRef*)signal->getDataPtrSend();
6792 ref->tableId = tableId;
6793 ref->tableVersion = tabVersion;
6794 ref->senderData = senderData;
6795 ref->senderRef = reference();
6796 ref->errorCode = errCode;
6797 ref->masterNodeId = c_masterNodeId;
6798 sendSignal(senderRef, GSN_DROP_TABLE_REF, signal,
6799 DropTableRef::SignalLength, JBB);
6800 }
6801
6802 void
prepDropTab_nextStep(Signal * signal,DropTableRecordPtr dropTabPtr)6803 Dbdict::prepDropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
6804
6805 /**
6806 * No errors currently allowed
6807 */
6808 ndbrequire(dropTabPtr.p->m_errorCode == 0);
6809
6810 Uint32 block = 0;
6811 switch(dropTabPtr.p->m_coordinatorData.m_block){
6812 case 0:
6813 jam();
6814 block = dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
6815 break;
6816 case DBDICT:
6817 jam();
6818 block = dropTabPtr.p->m_coordinatorData.m_block = DBLQH;
6819 break;
6820 case DBLQH:
6821 jam();
6822 block = dropTabPtr.p->m_coordinatorData.m_block = DBTC;
6823 break;
6824 case DBTC:
6825 jam();
6826 block = dropTabPtr.p->m_coordinatorData.m_block = DBDIH;
6827 break;
6828 case DBDIH:
6829 jam();
6830 prepDropTab_complete(signal, dropTabPtr);
6831 return;
6832 default:
6833 ndbrequire(false);
6834 }
6835
6836 PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
6837 prep->senderRef = reference();
6838 prep->senderData = dropTabPtr.p->key;
6839 prep->tableId = dropTabPtr.p->m_request.tableId;
6840 prep->requestType = dropTabPtr.p->m_requestType;
6841
6842 dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
6843 NodeReceiverGroup rg(block, c_aliveNodes);
6844 sendSignal(rg, GSN_PREP_DROP_TAB_REQ, signal,
6845 PrepDropTabReq::SignalLength, JBB);
6846
6847 #if 0
6848 for (Uint32 i = 1; i < MAX_NDB_NODES; i++){
6849 if(c_aliveNodes.get(i)){
6850 jam();
6851 BlockReference ref = numberToRef(block, i);
6852
6853 dropTabPtr.p->m_coordinatorData.m_signalCounter.setWaitingFor(i);
6854 }
6855 }
6856 #endif
6857 }
6858
6859 void
execPREP_DROP_TAB_CONF(Signal * signal)6860 Dbdict::execPREP_DROP_TAB_CONF(Signal * signal){
6861 jamEntry();
6862
6863 PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();
6864
6865 DropTableRecordPtr dropTabPtr;
6866 ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
6867
6868 ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
6869 ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
6870 ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
6871
6872 Uint32 nodeId = refToNode(prep->senderRef);
6873 dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
6874
6875 if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
6876 jam();
6877 return;
6878 }
6879 prepDropTab_nextStep(signal, dropTabPtr);
6880 }
6881
6882 void
execPREP_DROP_TAB_REF(Signal * signal)6883 Dbdict::execPREP_DROP_TAB_REF(Signal* signal){
6884 jamEntry();
6885
6886 PrepDropTabRef * prep = (PrepDropTabRef*)signal->getDataPtr();
6887
6888 DropTableRecordPtr dropTabPtr;
6889 ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
6890
6891 ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
6892 ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
6893 ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
6894
6895 Uint32 nodeId = refToNode(prep->senderRef);
6896 dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
6897
6898 Uint32 block = refToBlock(prep->senderRef);
6899 if((prep->errorCode == PrepDropTabRef::NoSuchTable && block == DBLQH) ||
6900 (prep->errorCode == PrepDropTabRef::NF_FakeErrorREF)){
6901 jam();
6902 /**
6903 * Ignore errors:
6904 * 1) no such table and LQH, it might not exists in different LQH's
6905 * 2) node failure...
6906 */
6907 } else {
6908 dropTabPtr.p->setErrorCode((Uint32)prep->errorCode);
6909 }
6910
6911 if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
6912 jam();
6913 return;
6914 }
6915 prepDropTab_nextStep(signal, dropTabPtr);
6916 }
6917
6918 void
prepDropTab_complete(Signal * signal,DropTableRecordPtr dropTabPtr)6919 Dbdict::prepDropTab_complete(Signal* signal, DropTableRecordPtr dropTabPtr){
6920 jam();
6921
6922 dropTabPtr.p->m_coordinatorData.m_gsn = GSN_DROP_TAB_REQ;
6923 dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
6924
6925 DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
6926 req->senderRef = reference();
6927 req->senderData = dropTabPtr.p->key;
6928 req->tableId = dropTabPtr.p->m_request.tableId;
6929 req->requestType = dropTabPtr.p->m_requestType;
6930
6931 dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
6932 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
6933 sendSignal(rg, GSN_DROP_TAB_REQ, signal,
6934 DropTabReq::SignalLength, JBB);
6935 }
6936
6937 void
execDROP_TAB_REF(Signal * signal)6938 Dbdict::execDROP_TAB_REF(Signal* signal){
6939 jamEntry();
6940
6941 DropTabRef * const req = (DropTabRef*)signal->getDataPtr();
6942
6943 Uint32 block = refToBlock(req->senderRef);
6944 ndbrequire(req->errorCode == DropTabRef::NF_FakeErrorREF ||
6945 (req->errorCode == DropTabRef::NoSuchTable &&
6946 (block == DBTUP || block == DBACC || block == DBLQH)));
6947
6948 if(block != DBDICT){
6949 jam();
6950 ndbrequire(refToNode(req->senderRef) == getOwnNodeId());
6951 dropTab_localDROP_TAB_CONF(signal);
6952 return;
6953 }
6954 ndbrequire(false);
6955 }
6956
6957 void
execDROP_TAB_CONF(Signal * signal)6958 Dbdict::execDROP_TAB_CONF(Signal* signal){
6959 jamEntry();
6960
6961 DropTabConf * const req = (DropTabConf*)signal->getDataPtr();
6962
6963 if(refToBlock(req->senderRef) != DBDICT){
6964 jam();
6965 ndbrequire(refToNode(req->senderRef) == getOwnNodeId());
6966 dropTab_localDROP_TAB_CONF(signal);
6967 return;
6968 }
6969
6970 DropTableRecordPtr dropTabPtr;
6971 ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
6972
6973 ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
6974 ndbrequire(dropTabPtr.p->m_request.tableId == req->tableId);
6975 ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_DROP_TAB_REQ);
6976
6977 Uint32 nodeId = refToNode(req->senderRef);
6978 dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
6979
6980 if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
6981 jam();
6982 return;
6983 }
6984
6985 DropTableConf* conf = (DropTableConf*)signal->getDataPtrSend();
6986 conf->senderRef = reference();
6987 conf->senderData = dropTabPtr.p->m_request.senderData;
6988 conf->tableId = dropTabPtr.p->m_request.tableId;
6989 conf->tableVersion = dropTabPtr.p->m_request.tableVersion;
6990 Uint32 ref = dropTabPtr.p->m_request.senderRef;
6991 sendSignal(ref, GSN_DROP_TABLE_CONF, signal,
6992 DropTableConf::SignalLength, JBB);
6993
6994 c_opDropTable.release(dropTabPtr);
6995 c_blockState = BS_IDLE;
6996 }
6997
6998 /**
6999 * DROP TABLE PARTICIPANT CODE
7000 */
7001 void
execPREP_DROP_TAB_REQ(Signal * signal)7002 Dbdict::execPREP_DROP_TAB_REQ(Signal* signal){
7003 jamEntry();
7004 PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
7005
7006 DropTableRecordPtr dropTabPtr;
7007 if(prep->senderRef == reference()){
7008 jam();
7009 ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
7010 ndbrequire(dropTabPtr.p->m_requestType == prep->requestType);
7011 } else {
7012 jam();
7013 c_opDropTable.seize(dropTabPtr);
7014 if(!dropTabPtr.isNull()){
7015 dropTabPtr.p->key = prep->senderData;
7016 c_opDropTable.add(dropTabPtr);
7017 }
7018 }
7019
7020 ndbrequire(!dropTabPtr.isNull());
7021
7022 dropTabPtr.p->m_errorCode = 0;
7023 dropTabPtr.p->m_request.tableId = prep->tableId;
7024 dropTabPtr.p->m_requestType = prep->requestType;
7025 dropTabPtr.p->m_coordinatorRef = prep->senderRef;
7026 dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_REQ;
7027
7028 TableRecordPtr tablePtr;
7029 c_tableRecordPool.getPtr(tablePtr, prep->tableId);
7030 tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
7031
7032 /**
7033 * Modify schema
7034 */
7035 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
7036 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tablePtr.i);
7037 SchemaFile::TableState tabState =
7038 (SchemaFile::TableState)tableEntry->m_tableState;
7039 ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED ||
7040 tabState == SchemaFile::ALTER_TABLE_COMMITTED ||
7041 tabState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
7042 tableEntry->m_tableState = SchemaFile::DROP_TABLE_STARTED;
7043 computeChecksum(xsf, tablePtr.i / NDB_SF_PAGE_ENTRIES);
7044
7045 bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
7046 Callback callback;
7047 callback.m_callbackData = dropTabPtr.p->key;
7048 callback.m_callbackFunction = safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
7049 if (savetodisk)
7050 {
7051 ndbrequire(c_writeSchemaRecord.inUse == false);
7052 c_writeSchemaRecord.inUse = true;
7053
7054 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
7055 c_writeSchemaRecord.newFile = false;
7056 c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES;
7057 c_writeSchemaRecord.noOfPages = 1;
7058 c_writeSchemaRecord.m_callback = callback;
7059 startWriteSchemaFile(signal);
7060 }
7061 else
7062 {
7063 execute(signal, callback, 0);
7064 }
7065 }
7066
7067 void
prepDropTab_writeSchemaConf(Signal * signal,Uint32 dropTabPtrI,Uint32 returnCode)7068 Dbdict::prepDropTab_writeSchemaConf(Signal* signal,
7069 Uint32 dropTabPtrI,
7070 Uint32 returnCode){
7071 jam();
7072
7073 DropTableRecordPtr dropTabPtr;
7074 ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
7075
7076 ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_REQ);
7077
7078 /**
7079 * There probably should be node fail handlign here
7080 *
7081 * To check that coordinator hasn't died
7082 */
7083
7084 PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();
7085 prep->senderRef = reference();
7086 prep->senderData = dropTabPtrI;
7087 prep->tableId = dropTabPtr.p->m_request.tableId;
7088
7089 dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_CONF;
7090 sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_PREP_DROP_TAB_CONF, signal,
7091 PrepDropTabConf::SignalLength, JBB);
7092 }
7093
7094 void
execDROP_TAB_REQ(Signal * signal)7095 Dbdict::execDROP_TAB_REQ(Signal* signal){
7096 jamEntry();
7097 DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
7098
7099 DropTableRecordPtr dropTabPtr;
7100 ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
7101
7102 ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_CONF);
7103 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
7104
7105 ndbrequire(dropTabPtr.p->m_requestType == req->requestType);
7106
7107 TableRecordPtr tablePtr;
7108 c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
7109 tablePtr.p->tabState = TableRecord::DROPPING;
7110
7111 dropTabPtr.p->m_participantData.m_block = 0;
7112 dropTabPtr.p->m_participantData.m_callback.m_callbackData = dropTabPtr.p->key;
7113 dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
7114 safe_cast(&Dbdict::dropTab_complete);
7115 dropTab_nextStep(signal, dropTabPtr);
7116
7117 if (tablePtr.p->m_tablespace_id != RNIL)
7118 {
7119 FilegroupPtr ptr;
7120 ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
7121 decrease_ref_count(ptr.p->m_obj_ptr_i);
7122 }
7123 }
7124
7125 #include <DebuggerNames.hpp>
7126
7127 void
dropTab_nextStep(Signal * signal,DropTableRecordPtr dropTabPtr)7128 Dbdict::dropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
7129
7130 /**
7131 * No errors currently allowed
7132 */
7133 ndbrequire(dropTabPtr.p->m_errorCode == 0);
7134
7135 TableRecordPtr tablePtr;
7136 c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
7137
7138 Uint32 block = 0;
7139 switch(dropTabPtr.p->m_participantData.m_block){
7140 case 0:
7141 jam();
7142 block = DBTC;
7143 break;
7144 case DBTC:
7145 jam();
7146 if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
7147 block = DBACC;
7148 if (tablePtr.p->isOrderedIndex())
7149 block = DBTUP;
7150 break;
7151 case DBACC:
7152 jam();
7153 block = DBTUP;
7154 break;
7155 case DBTUP:
7156 jam();
7157 if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
7158 block = DBLQH;
7159 if (tablePtr.p->isOrderedIndex())
7160 block = DBTUX;
7161 break;
7162 case DBTUX:
7163 jam();
7164 block = DBLQH;
7165 break;
7166 case DBLQH:
7167 jam();
7168 block = DBDIH;
7169 break;
7170 case DBDIH:
7171 jam();
7172 execute(signal, dropTabPtr.p->m_participantData.m_callback, 0);
7173 return;
7174 }
7175 ndbrequire(block != 0);
7176 dropTabPtr.p->m_participantData.m_block = block;
7177
7178 DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
7179 req->senderRef = reference();
7180 req->senderData = dropTabPtr.p->key;
7181 req->tableId = dropTabPtr.p->m_request.tableId;
7182 req->requestType = dropTabPtr.p->m_requestType;
7183
7184 const Uint32 nodeId = getOwnNodeId();
7185 dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor();
7186 dropTabPtr.p->m_participantData.m_signalCounter.setWaitingFor(nodeId);
7187 BlockReference ref = numberToRef(block, 0);
7188 sendSignal(ref, GSN_DROP_TAB_REQ, signal, DropTabReq::SignalLength, JBB);
7189 }
7190
7191 void
dropTab_localDROP_TAB_CONF(Signal * signal)7192 Dbdict::dropTab_localDROP_TAB_CONF(Signal* signal){
7193 jamEntry();
7194
7195 DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
7196
7197 DropTableRecordPtr dropTabPtr;
7198 ndbrequire(c_opDropTable.find(dropTabPtr, conf->senderData));
7199
7200 ndbrequire(dropTabPtr.p->m_request.tableId == conf->tableId);
7201 ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
7202
7203 Uint32 nodeId = refToNode(conf->senderRef);
7204 dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor(nodeId);
7205
7206 if(!dropTabPtr.p->m_participantData.m_signalCounter.done()){
7207 jam();
7208 ndbrequire(false);
7209 return;
7210 }
7211 dropTab_nextStep(signal, dropTabPtr);
7212 }
7213
7214 void
dropTab_complete(Signal * signal,Uint32 dropTabPtrI,Uint32 returnCode)7215 Dbdict::dropTab_complete(Signal* signal,
7216 Uint32 dropTabPtrI,
7217 Uint32 returnCode){
7218 jam();
7219
7220 DropTableRecordPtr dropTabPtr;
7221 ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
7222
7223 Uint32 tableId = dropTabPtr.p->m_request.tableId;
7224
7225 /**
7226 * Write to schema file
7227 */
7228 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
7229 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
7230 SchemaFile::TableState tabState =
7231 (SchemaFile::TableState)tableEntry->m_tableState;
7232 ndbrequire(tabState == SchemaFile::DROP_TABLE_STARTED);
7233 tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
7234 computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
7235
7236 TableRecordPtr tablePtr;
7237 c_tableRecordPool.getPtr(tablePtr, tableId);
7238 bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
7239 Callback callback;
7240 callback.m_callbackData = dropTabPtr.p->key;
7241 callback.m_callbackFunction = safe_cast(&Dbdict::dropTab_writeSchemaConf);
7242 if (savetodisk)
7243 {
7244 ndbrequire(c_writeSchemaRecord.inUse == false);
7245 c_writeSchemaRecord.inUse = true;
7246
7247 c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
7248 c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
7249 c_writeSchemaRecord.noOfPages = 1;
7250 c_writeSchemaRecord.m_callback = callback;
7251 startWriteSchemaFile(signal);
7252 }
7253 else
7254 {
7255 execute(signal, callback, 0);
7256 }
7257 }
7258
7259 void
dropTab_writeSchemaConf(Signal * signal,Uint32 dropTabPtrI,Uint32 returnCode)7260 Dbdict::dropTab_writeSchemaConf(Signal* signal,
7261 Uint32 dropTabPtrI,
7262 Uint32 returnCode){
7263 jam();
7264
7265 DropTableRecordPtr dropTabPtr;
7266 ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
7267
7268 ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
7269
7270 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
7271
7272 releaseTableObject(dropTabPtr.p->m_request.tableId);
7273
7274 DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
7275 conf->senderRef = reference();
7276 conf->senderData = dropTabPtrI;
7277 conf->tableId = dropTabPtr.p->m_request.tableId;
7278 {
7279 DropTabConf tmp= *conf;
7280 if (dropTabPtr.p->m_coordinatorRef == reference())
7281 conf->senderRef = dropTabPtr.p->m_request.senderRef;
7282 else
7283 conf->senderRef = 0;
7284 EXECUTE_DIRECT(SUMA, GSN_DROP_TAB_CONF, signal,
7285 DropTabConf::SignalLength);
7286 jamEntry();
7287 *conf= tmp;
7288 }
7289 dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
7290 sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_DROP_TAB_CONF, signal,
7291 DropTabConf::SignalLength, JBB);
7292
7293 if(dropTabPtr.p->m_coordinatorRef != reference()){
7294 c_opDropTable.release(dropTabPtr);
7295 }
7296 }
7297
releaseTableObject(Uint32 tableId,bool removeFromHash)7298 void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash)
7299 {
7300 TableRecordPtr tablePtr;
7301 c_tableRecordPool.getPtr(tablePtr, tableId);
7302 if (removeFromHash)
7303 {
7304 jam();
7305 release_object(tablePtr.p->m_obj_ptr_i);
7306 }
7307 else
7308 {
7309 Rope tmp(c_rope_pool, tablePtr.p->tableName);
7310 tmp.erase();
7311 }
7312
7313 {
7314 Rope tmp(c_rope_pool, tablePtr.p->frmData);
7315 tmp.erase();
7316 }
7317
7318 {
7319 Rope tmp(c_rope_pool, tablePtr.p->tsData);
7320 tmp.erase();
7321 }
7322
7323 {
7324 Rope tmp(c_rope_pool, tablePtr.p->ngData);
7325 tmp.erase();
7326 }
7327
7328 {
7329 Rope tmp(c_rope_pool, tablePtr.p->rangeData);
7330 tmp.erase();
7331 }
7332
7333 tablePtr.p->tabState = TableRecord::NOT_DEFINED;
7334
7335 LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
7336 tablePtr.p->m_attributes);
7337 AttributeRecordPtr attrPtr;
7338 for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)){
7339 Rope name(c_rope_pool, attrPtr.p->attributeName);
7340 Rope def(c_rope_pool, attrPtr.p->defaultValue);
7341 name.erase();
7342 def.erase();
7343 }
7344 list.release();
7345 }//releaseTableObject()
7346
7347 /**
7348 * DICT receives these on index create and drop.
7349 */
execDROP_TABLE_CONF(Signal * signal)7350 void Dbdict::execDROP_TABLE_CONF(Signal* signal)
7351 {
7352 jamEntry();
7353 ndbrequire(signal->getNoOfSections() == 0);
7354
7355 DropTableConf * const conf = (DropTableConf *)signal->getDataPtr();
7356 // assume part of drop index operation
7357 OpDropIndexPtr opPtr;
7358 c_opDropIndex.find(opPtr, conf->senderData);
7359 ndbrequire(! opPtr.isNull());
7360 ndbrequire(opPtr.p->m_request.getIndexId() == conf->tableId);
7361 ndbrequire(opPtr.p->m_request.getIndexVersion() == conf->tableVersion);
7362 dropIndex_fromDropTable(signal, opPtr);
7363 }
7364
execDROP_TABLE_REF(Signal * signal)7365 void Dbdict::execDROP_TABLE_REF(Signal* signal)
7366 {
7367 jamEntry();
7368
7369 DropTableRef * const ref = (DropTableRef *)signal->getDataPtr();
7370 // assume part of drop index operation
7371 OpDropIndexPtr opPtr;
7372 c_opDropIndex.find(opPtr, ref->senderData);
7373 ndbrequire(! opPtr.isNull());
7374 opPtr.p->setError(ref);
7375 opPtr.p->m_errorLine = __LINE__;
7376 dropIndex_fromDropTable(signal, opPtr);
7377 }
7378
7379 /* **************************************************************** */
7380 /* ---------------------------------------------------------------- */
7381 /* MODULE: EXTERNAL INTERFACE TO DATA -------------------- */
7382 /* ---------------------------------------------------------------- */
7383 /* */
7384 /* This module contains the code that is used by other modules to. */
7385 /* access the data within DBDICT. */
7386 /* ---------------------------------------------------------------- */
7387 /* **************************************************************** */
7388
execGET_TABLEDID_REQ(Signal * signal)7389 void Dbdict::execGET_TABLEDID_REQ(Signal * signal)
7390 {
7391 jamEntry();
7392 ndbrequire(signal->getNoOfSections() == 1);
7393 GetTableIdReq const * req = (GetTableIdReq *)signal->getDataPtr();
7394 Uint32 senderData = req->senderData;
7395 Uint32 senderRef = req->senderRef;
7396 Uint32 len = req->len;
7397
7398 if(len>MAX_TAB_NAME_SIZE)
7399 {
7400 jam();
7401 sendGET_TABLEID_REF((Signal*)signal,
7402 (GetTableIdReq *)req,
7403 GetTableIdRef::TableNameTooLong);
7404 return;
7405 }
7406
7407 char tableName[MAX_TAB_NAME_SIZE];
7408 SegmentedSectionPtr ssPtr;
7409 signal->getSection(ssPtr,GetTableIdReq::TABLE_NAME);
7410 copy((Uint32*)tableName, ssPtr);
7411 releaseSections(signal);
7412
7413 DictObject * obj_ptr_p = get_object(tableName, len);
7414 if(obj_ptr_p == 0 || !DictTabInfo::isTable(obj_ptr_p->m_type)){
7415 jam();
7416 sendGET_TABLEID_REF(signal,
7417 (GetTableIdReq *)req,
7418 GetTableIdRef::TableNotDefined);
7419 return;
7420 }
7421
7422 TableRecordPtr tablePtr;
7423 c_tableRecordPool.getPtr(tablePtr, obj_ptr_p->m_id);
7424
7425 GetTableIdConf * conf = (GetTableIdConf *)req;
7426 conf->tableId = tablePtr.p->tableId;
7427 conf->schemaVersion = tablePtr.p->tableVersion;
7428 conf->senderData = senderData;
7429 sendSignal(senderRef, GSN_GET_TABLEID_CONF, signal,
7430 GetTableIdConf::SignalLength, JBB);
7431 }
7432
7433
sendGET_TABLEID_REF(Signal * signal,GetTableIdReq * req,GetTableIdRef::ErrorCode errorCode)7434 void Dbdict::sendGET_TABLEID_REF(Signal* signal,
7435 GetTableIdReq * req,
7436 GetTableIdRef::ErrorCode errorCode)
7437 {
7438 GetTableIdRef * const ref = (GetTableIdRef *)req;
7439 /**
7440 * The format of GetTabInfo Req/Ref is the same
7441 */
7442 BlockReference retRef = req->senderRef;
7443 ref->err = errorCode;
7444 sendSignal(retRef, GSN_GET_TABLEID_REF, signal,
7445 GetTableIdRef::SignalLength, JBB);
7446 }//sendGET_TABINFOREF()
7447
7448 /* ---------------------------------------------------------------- */
7449 // Get a full table description.
7450 /* ---------------------------------------------------------------- */
execGET_TABINFOREQ(Signal * signal)7451 void Dbdict::execGET_TABINFOREQ(Signal* signal)
7452 {
7453 jamEntry();
7454 if(!assembleFragments(signal))
7455 {
7456 return;
7457 }
7458
7459 GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
7460
7461 /**
7462 * If I get a GET_TABINFO_REQ from myself
7463 * it's is a one from the time queue
7464 */
7465 bool fromTimeQueue = (signal->senderBlockRef() == reference());
7466
7467 if (c_retrieveRecord.busyState && fromTimeQueue == true) {
7468 jam();
7469
7470 sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
7471 signal->length());
7472 return;
7473 }//if
7474
7475 const Uint32 MAX_WAITERS = 5;
7476
7477 if(c_retrieveRecord.busyState && fromTimeQueue == false){
7478 jam();
7479 if(c_retrieveRecord.noOfWaiters < MAX_WAITERS){
7480 jam();
7481 c_retrieveRecord.noOfWaiters++;
7482
7483 sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
7484 signal->length());
7485 return;
7486 }
7487
7488 sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy);
7489 return;
7490 }
7491
7492 if(fromTimeQueue){
7493 jam();
7494 c_retrieveRecord.noOfWaiters--;
7495 }
7496
7497 const bool useLongSig = (req->requestType & GetTabInfoReq::LongSignalConf);
7498 const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
7499
7500 Uint32 obj_id = RNIL;
7501 if(reqType == GetTabInfoReq::RequestByName){
7502 jam();
7503 ndbrequire(signal->getNoOfSections() == 1);
7504 const Uint32 len = req->tableNameLen;
7505
7506 if(len > MAX_TAB_NAME_SIZE){
7507 jam();
7508 releaseSections(signal);
7509 sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNameTooLong);
7510 return;
7511 }
7512
7513 char tableName[MAX_TAB_NAME_SIZE];
7514 SegmentedSectionPtr ssPtr;
7515 signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
7516 SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
7517 r0.reset(); // undo implicit first()
7518 if(!r0.getWords((Uint32*)tableName, (len+3)/4)){
7519 jam();
7520 releaseSections(signal);
7521 sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
7522 return;
7523 }
7524 releaseSections(signal);
7525
7526 DictObject * old_ptr_p = get_object(tableName, len);
7527 if(old_ptr_p)
7528 obj_id = old_ptr_p->m_id;
7529 } else {
7530 jam();
7531 obj_id = req->tableId;
7532 }
7533
7534 SchemaFile::TableEntry *objEntry = 0;
7535 if(obj_id != RNIL){
7536 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
7537 objEntry = getTableEntry(xsf, obj_id);
7538 }
7539
7540 // The table seached for was not found
7541 if(objEntry == 0){
7542 jam();
7543 sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
7544 return;
7545 }//if
7546
7547 // If istable/index, allow ADD_STARTED (not to ref)
7548
7549 if (objEntry->m_tableState != SchemaFile::TABLE_ADD_COMMITTED &&
7550 objEntry->m_tableState != SchemaFile::ALTER_TABLE_COMMITTED &&
7551 objEntry->m_tableState != SchemaFile::TEMPORARY_TABLE_COMMITTED){
7552 jam();
7553 sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
7554 return;
7555 }//if
7556
7557 if (DictTabInfo::isTable(objEntry->m_tableType) ||
7558 DictTabInfo::isIndex(objEntry->m_tableType))
7559 {
7560 jam();
7561 TableRecordPtr tabPtr;
7562 c_tableRecordPool.getPtr(tabPtr, obj_id);
7563 if (tabPtr.p->tabState != TableRecord::DEFINED &&
7564 tabPtr.p->tabState != TableRecord::BACKUP_ONGOING)
7565 {
7566 jam();
7567 sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
7568 return;
7569 }
7570 ndbrequire(objEntry->m_tableState == SchemaFile::TEMPORARY_TABLE_COMMITTED ||
7571 !(tabPtr.p->m_bits & TableRecord::TR_Temporary));
7572 }
7573
7574 c_retrieveRecord.busyState = true;
7575 c_retrieveRecord.blockRef = req->senderRef;
7576 c_retrieveRecord.m_senderData = req->senderData;
7577 c_retrieveRecord.tableId = obj_id;
7578 c_retrieveRecord.currentSent = 0;
7579 c_retrieveRecord.m_useLongSig = useLongSig;
7580 c_retrieveRecord.m_table_type = objEntry->m_tableType;
7581 c_packTable.m_state = PackTable::PTS_GET_TAB;
7582
7583 if(objEntry->m_tableType==DictTabInfo::Datafile)
7584 {
7585 jam();
7586 GetTabInfoReq *req= (GetTabInfoReq*)signal->getDataPtrSend();
7587 req->senderData= c_retrieveRecord.retrievePage;
7588 req->senderRef= reference();
7589 req->requestType= GetTabInfoReq::RequestById;
7590 req->tableId= obj_id;
7591
7592 sendSignal(TSMAN_REF, GSN_GET_TABINFOREQ, signal,
7593 GetTabInfoReq::SignalLength, JBB);
7594 }
7595 else if(objEntry->m_tableType==DictTabInfo::LogfileGroup)
7596 {
7597 jam();
7598 GetTabInfoReq *req= (GetTabInfoReq*)signal->getDataPtrSend();
7599 req->senderData= c_retrieveRecord.retrievePage;
7600 req->senderRef= reference();
7601 req->requestType= GetTabInfoReq::RequestById;
7602 req->tableId= obj_id;
7603
7604 sendSignal(LGMAN_REF, GSN_GET_TABINFOREQ, signal,
7605 GetTabInfoReq::SignalLength, JBB);
7606 }
7607 else
7608 {
7609 jam();
7610 signal->theData[0] = ZPACK_TABLE_INTO_PAGES;
7611 signal->theData[1] = obj_id;
7612 signal->theData[2] = objEntry->m_tableType;
7613 signal->theData[3] = c_retrieveRecord.retrievePage;
7614 sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
7615 }
7616 jam();
7617 }//execGET_TABINFOREQ()
7618
sendGetTabResponse(Signal * signal)7619 void Dbdict::sendGetTabResponse(Signal* signal)
7620 {
7621 PageRecordPtr pagePtr;
7622 DictTabInfo * const conf = (DictTabInfo *)&signal->theData[0];
7623 conf->senderRef = reference();
7624 conf->senderData = c_retrieveRecord.m_senderData;
7625 conf->requestType = DictTabInfo::GetTabInfoConf;
7626 conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
7627
7628 c_pageRecordArray.getPtr(pagePtr, c_retrieveRecord.retrievePage);
7629 Uint32* pagePointer = (Uint32*)&pagePtr.p->word[0] + ZPAGE_HEADER_SIZE;
7630
7631 if(c_retrieveRecord.m_useLongSig){
7632 jam();
7633 GetTabInfoConf* conf = (GetTabInfoConf*)signal->getDataPtr();
7634 conf->gci = 0;
7635 conf->tableId = c_retrieveRecord.tableId;
7636 conf->senderData = c_retrieveRecord.m_senderData;
7637 conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
7638 conf->tableType = c_retrieveRecord.m_table_type;
7639
7640 Callback c = { safe_cast(&Dbdict::initRetrieveRecord), 0 };
7641 LinearSectionPtr ptr[3];
7642 ptr[0].p = pagePointer;
7643 ptr[0].sz = c_retrieveRecord.retrievedNoOfWords;
7644 sendFragmentedSignal(c_retrieveRecord.blockRef,
7645 GSN_GET_TABINFO_CONF,
7646 signal,
7647 GetTabInfoConf::SignalLength,
7648 JBB,
7649 ptr,
7650 1,
7651 c);
7652 return;
7653 }
7654
7655 ndbrequire(false);
7656 }//sendGetTabResponse()
7657
sendGET_TABINFOREF(Signal * signal,GetTabInfoReq * req,GetTabInfoRef::ErrorCode errorCode)7658 void Dbdict::sendGET_TABINFOREF(Signal* signal,
7659 GetTabInfoReq * req,
7660 GetTabInfoRef::ErrorCode errorCode)
7661 {
7662 jamEntry();
7663 GetTabInfoRef * const ref = (GetTabInfoRef *)&signal->theData[0];
7664 /**
7665 * The format of GetTabInfo Req/Ref is the same
7666 */
7667 BlockReference retRef = req->senderRef;
7668 ref->errorCode = errorCode;
7669
7670 sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
7671 }//sendGET_TABINFOREF()
7672
7673 void
execLIST_TABLES_REQ(Signal * signal)7674 Dbdict::execLIST_TABLES_REQ(Signal* signal)
7675 {
7676 jamEntry();
7677 ListTablesReq * req = (ListTablesReq*)signal->getDataPtr();
7678 Uint32 senderRef = req->senderRef;
7679 Uint32 senderData = req->senderData;
7680 // save req flags
7681 const Uint32 reqTableId = req->getTableId();
7682 const Uint32 reqTableType = req->getTableType();
7683 const bool reqListNames = req->getListNames();
7684 const bool reqListIndexes = req->getListIndexes();
7685 // init the confs
7686 ListTablesConf * conf = (ListTablesConf *)signal->getDataPtrSend();
7687 conf->senderData = senderData;
7688 conf->counter = 0;
7689 Uint32 pos = 0;
7690
7691 DLHashTable<DictObject>::Iterator iter;
7692 bool ok = c_obj_hash.first(iter);
7693 for(; ok; ok = c_obj_hash.next(iter)){
7694 Uint32 type = iter.curr.p->m_type;
7695 if ((reqTableType != (Uint32)0) && (reqTableType != type))
7696 continue;
7697
7698 if (reqListIndexes && !DictTabInfo::isIndex(type))
7699 continue;
7700
7701 TableRecordPtr tablePtr;
7702 if (DictTabInfo::isTable(type) || DictTabInfo::isIndex(type)){
7703 c_tableRecordPool.getPtr(tablePtr, iter.curr.p->m_id);
7704
7705 if(reqListIndexes && (reqTableId != tablePtr.p->primaryTableId))
7706 continue;
7707
7708 conf->tableData[pos] = 0;
7709 conf->setTableId(pos, tablePtr.i); // id
7710 conf->setTableType(pos, type); // type
7711 // state
7712
7713 if(DictTabInfo::isTable(type)){
7714 switch (tablePtr.p->tabState) {
7715 case TableRecord::DEFINING:
7716 conf->setTableState(pos, DictTabInfo::StateBuilding);
7717 break;
7718 case TableRecord::PREPARE_DROPPING:
7719 case TableRecord::DROPPING:
7720 conf->setTableState(pos, DictTabInfo::StateDropping);
7721 break;
7722 case TableRecord::DEFINED:
7723 conf->setTableState(pos, DictTabInfo::StateOnline);
7724 break;
7725 case TableRecord::BACKUP_ONGOING:
7726 conf->setTableState(pos, DictTabInfo::StateBackup);
7727 break;
7728 default:
7729 conf->setTableState(pos, DictTabInfo::StateBroken);
7730 break;
7731 }
7732 }
7733 if (tablePtr.p->isIndex()) {
7734 switch (tablePtr.p->indexState) {
7735 case TableRecord::IS_OFFLINE:
7736 conf->setTableState(pos, DictTabInfo::StateOffline);
7737 break;
7738 case TableRecord::IS_BUILDING:
7739 conf->setTableState(pos, DictTabInfo::StateBuilding);
7740 break;
7741 case TableRecord::IS_DROPPING:
7742 conf->setTableState(pos, DictTabInfo::StateDropping);
7743 break;
7744 case TableRecord::IS_ONLINE:
7745 conf->setTableState(pos, DictTabInfo::StateOnline);
7746 break;
7747 default:
7748 conf->setTableState(pos, DictTabInfo::StateBroken);
7749 break;
7750 }
7751 }
7752 // Logging status
7753 if (! (tablePtr.p->m_bits & TableRecord::TR_Logged)) {
7754 conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
7755 } else {
7756 conf->setTableStore(pos, DictTabInfo::StorePermanent);
7757 }
7758 // Temporary status
7759 if (tablePtr.p->m_bits & TableRecord::TR_Temporary) {
7760 conf->setTableTemp(pos, NDB_TEMP_TAB_TEMPORARY);
7761 } else {
7762 conf->setTableTemp(pos, NDB_TEMP_TAB_PERMANENT);
7763 }
7764 pos++;
7765 }
7766 if(DictTabInfo::isTrigger(type)){
7767 TriggerRecordPtr triggerPtr;
7768 c_triggerRecordPool.getPtr(triggerPtr, iter.curr.p->m_id);
7769
7770 conf->tableData[pos] = 0;
7771 conf->setTableId(pos, triggerPtr.i);
7772 conf->setTableType(pos, type);
7773 switch (triggerPtr.p->triggerState) {
7774 case TriggerRecord::TS_OFFLINE:
7775 conf->setTableState(pos, DictTabInfo::StateOffline);
7776 break;
7777 case TriggerRecord::TS_ONLINE:
7778 conf->setTableState(pos, DictTabInfo::StateOnline);
7779 break;
7780 default:
7781 conf->setTableState(pos, DictTabInfo::StateBroken);
7782 break;
7783 }
7784 conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
7785 pos++;
7786 }
7787 if (DictTabInfo::isFilegroup(type)){
7788 jam();
7789 conf->tableData[pos] = 0;
7790 conf->setTableId(pos, iter.curr.p->m_id);
7791 conf->setTableType(pos, type); // type
7792 conf->setTableState(pos, DictTabInfo::StateOnline); // XXX todo
7793 pos++;
7794 }
7795 if (DictTabInfo::isFile(type)){
7796 jam();
7797 conf->tableData[pos] = 0;
7798 conf->setTableId(pos, iter.curr.p->m_id);
7799 conf->setTableType(pos, type); // type
7800 conf->setTableState(pos, DictTabInfo::StateOnline); // XXX todo
7801 pos++;
7802 }
7803
7804 if (pos >= ListTablesConf::DataLength) {
7805 sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
7806 ListTablesConf::SignalLength, JBB);
7807 conf->counter++;
7808 pos = 0;
7809 }
7810
7811 if (! reqListNames)
7812 continue;
7813
7814 Rope name(c_rope_pool, iter.curr.p->m_name);
7815 const Uint32 size = name.size();
7816 conf->tableData[pos] = size;
7817 pos++;
7818 if (pos >= ListTablesConf::DataLength) {
7819 sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
7820 ListTablesConf::SignalLength, JBB);
7821 conf->counter++;
7822 pos = 0;
7823 }
7824 Uint32 i = 0;
7825 char tmp[MAX_TAB_NAME_SIZE];
7826 name.copy(tmp);
7827 while (i < size) {
7828 char* p = (char*)&conf->tableData[pos];
7829 for (Uint32 j = 0; j < 4; j++) {
7830 if (i < size)
7831 *p++ = tmp[i++];
7832 else
7833 *p++ = 0;
7834 }
7835 pos++;
7836 if (pos >= ListTablesConf::DataLength) {
7837 sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
7838 ListTablesConf::SignalLength, JBB);
7839 conf->counter++;
7840 pos = 0;
7841 }
7842 }
7843 }
7844 // last signal must have less than max length
7845 sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
7846 ListTablesConf::HeaderLength + pos, JBB);
7847 }
7848
7849 /**
7850 * MODULE: Create index
7851 *
7852 * Create index in DICT via create table operation. Then invoke alter
7853 * index opearation to online the index.
7854 *
7855 * Request type in CREATE_INDX signals:
7856 *
7857 * RT_USER - from API to DICT master
7858 * RT_DICT_PREPARE - prepare participants
7859 * RT_DICT_COMMIT - commit participants
7860 * RT_TC - create index in TC (part of alter index operation)
7861 */
7862
7863 void
execCREATE_INDX_REQ(Signal * signal)7864 Dbdict::execCREATE_INDX_REQ(Signal* signal)
7865 {
7866 jamEntry();
7867 CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
7868 OpCreateIndexPtr opPtr;
7869 const Uint32 senderRef = signal->senderBlockRef();
7870 const CreateIndxReq::RequestType requestType = req->getRequestType();
7871 if (requestType == CreateIndxReq::RT_USER) {
7872 jam();
7873 if (! assembleFragments(signal)) {
7874 jam();
7875 return;
7876 }
7877 if (signal->getLength() == CreateIndxReq::SignalLength) {
7878 jam();
7879 CreateIndxRef::ErrorCode tmperr = CreateIndxRef::NoError;
7880 if (getOwnNodeId() != c_masterNodeId) {
7881 jam();
7882 tmperr = CreateIndxRef::NotMaster;
7883 } else if (c_blockState == BS_NODE_RESTART) {
7884 jam();
7885 tmperr = CreateIndxRef::BusyWithNR;
7886 } else if (c_blockState != BS_IDLE) {
7887 jam();
7888 tmperr = CreateIndxRef::Busy;
7889 }
7890 else if (checkSingleUserMode(senderRef))
7891 {
7892 jam();
7893 tmperr = CreateIndxRef::SingleUser;
7894 }
7895 if (tmperr != CreateIndxRef::NoError) {
7896 releaseSections(signal);
7897 OpCreateIndex opBusy;
7898 opPtr.p = &opBusy;
7899 opPtr.p->save(req);
7900 opPtr.p->m_isMaster = (senderRef == reference());
7901 opPtr.p->key = 0;
7902 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
7903 opPtr.p->m_errorCode = tmperr;
7904 opPtr.p->m_errorLine = __LINE__;
7905 opPtr.p->m_errorNode = c_masterNodeId;
7906 createIndex_sendReply(signal, opPtr, true);
7907 return;
7908 }
7909 // forward initial request plus operation key to all
7910 req->setOpKey(++c_opRecordSequence);
7911 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
7912 sendSignal(rg, GSN_CREATE_INDX_REQ,
7913 signal, CreateIndxReq::SignalLength + 1, JBB);
7914 return;
7915 }
7916 // seize operation record
7917 ndbrequire(signal->getLength() == CreateIndxReq::SignalLength + 1);
7918 const Uint32 opKey = req->getOpKey();
7919 OpCreateIndex opBusy;
7920 if (! c_opCreateIndex.seize(opPtr))
7921 opPtr.p = &opBusy;
7922 opPtr.p->save(req);
7923 opPtr.p->m_coordinatorRef = senderRef;
7924 opPtr.p->m_isMaster = (senderRef == reference());
7925 opPtr.p->key = opKey;
7926 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
7927 if (opPtr.p == &opBusy) {
7928 jam();
7929 opPtr.p->m_errorCode = CreateIndxRef::Busy;
7930 opPtr.p->m_errorLine = __LINE__;
7931 releaseSections(signal);
7932 createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
7933 return;
7934 }
7935 c_opCreateIndex.add(opPtr);
7936 // save attribute list
7937 SegmentedSectionPtr ssPtr;
7938 signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
7939 SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
7940 r0.reset(); // undo implicit first()
7941 if (! r0.getWord(&opPtr.p->m_attrList.sz) ||
7942 ! r0.getWords(opPtr.p->m_attrList.id, opPtr.p->m_attrList.sz)) {
7943 jam();
7944 opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
7945 opPtr.p->m_errorLine = __LINE__;
7946 releaseSections(signal);
7947 createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
7948 return;
7949 }
7950 // save name and index table properties
7951 signal->getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
7952 SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool());
7953 c_tableDesc.init();
7954 SimpleProperties::UnpackStatus status = SimpleProperties::unpack(
7955 r1, &c_tableDesc,
7956 DictTabInfo::TableMapping, DictTabInfo::TableMappingSize,
7957 true, true);
7958 if (status != SimpleProperties::Eof) {
7959 opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
7960 opPtr.p->m_errorLine = __LINE__;
7961 releaseSections(signal);
7962 createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
7963 return;
7964 }
7965 memcpy(opPtr.p->m_indexName, c_tableDesc.TableName, MAX_TAB_NAME_SIZE);
7966 opPtr.p->m_loggedIndex = c_tableDesc.TableLoggedFlag;
7967 opPtr.p->m_temporaryIndex = c_tableDesc.TableTemporaryFlag;
7968 releaseSections(signal);
7969 // master expects to hear from all
7970 if (opPtr.p->m_isMaster)
7971 opPtr.p->m_signalCounter = c_aliveNodes;
7972 createIndex_slavePrepare(signal, opPtr);
7973 createIndex_sendReply(signal, opPtr, false);
7974 return;
7975 }
7976 c_opCreateIndex.find(opPtr, req->getConnectionPtr());
7977 if (! opPtr.isNull()) {
7978 opPtr.p->m_requestType = requestType;
7979 if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
7980 requestType == CreateIndxReq::RT_DICT_ABORT) {
7981 jam();
7982 if (requestType == CreateIndxReq::RT_DICT_COMMIT) {
7983 opPtr.p->m_request.setIndexId(req->getIndexId());
7984 opPtr.p->m_request.setIndexVersion(req->getIndexVersion());
7985 createIndex_slaveCommit(signal, opPtr);
7986 } else {
7987 createIndex_slaveAbort(signal, opPtr);
7988 }
7989 createIndex_sendReply(signal, opPtr, false);
7990 // done in slave
7991 if (! opPtr.p->m_isMaster)
7992 c_opCreateIndex.release(opPtr);
7993 return;
7994 }
7995 }
7996 jam();
7997 // return to sender
7998 releaseSections(signal);
7999 OpCreateIndex opBad;
8000 opPtr.p = &opBad;
8001 opPtr.p->save(req);
8002 opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
8003 opPtr.p->m_errorLine = __LINE__;
8004 createIndex_sendReply(signal, opPtr, true);
8005 }
8006
8007 void
execCREATE_INDX_CONF(Signal * signal)8008 Dbdict::execCREATE_INDX_CONF(Signal* signal)
8009 {
8010 jamEntry();
8011 ndbrequire(signal->getNoOfSections() == 0);
8012 CreateIndxConf* conf = (CreateIndxConf*)signal->getDataPtrSend();
8013 createIndex_recvReply(signal, conf, 0);
8014 }
8015
8016 void
execCREATE_INDX_REF(Signal * signal)8017 Dbdict::execCREATE_INDX_REF(Signal* signal)
8018 {
8019 jamEntry();
8020 CreateIndxRef* ref = (CreateIndxRef*)signal->getDataPtrSend();
8021 createIndex_recvReply(signal, ref->getConf(), ref);
8022 }
8023
8024 void
createIndex_recvReply(Signal * signal,const CreateIndxConf * conf,const CreateIndxRef * ref)8025 Dbdict::createIndex_recvReply(Signal* signal, const CreateIndxConf* conf,
8026 const CreateIndxRef* ref)
8027 {
8028 jam();
8029 const Uint32 senderRef = signal->senderBlockRef();
8030 const CreateIndxReq::RequestType requestType = conf->getRequestType();
8031 const Uint32 key = conf->getConnectionPtr();
8032 if (requestType == CreateIndxReq::RT_TC) {
8033 jam();
8034 // part of alter index operation
8035 OpAlterIndexPtr opPtr;
8036 c_opAlterIndex.find(opPtr, key);
8037 ndbrequire(! opPtr.isNull());
8038 opPtr.p->setError(ref);
8039 alterIndex_fromCreateTc(signal, opPtr);
8040 return;
8041 }
8042 OpCreateIndexPtr opPtr;
8043 c_opCreateIndex.find(opPtr, key);
8044 ndbrequire(! opPtr.isNull());
8045 ndbrequire(opPtr.p->m_isMaster);
8046 ndbrequire(opPtr.p->m_requestType == requestType);
8047 opPtr.p->setError(ref);
8048 opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
8049 if (! opPtr.p->m_signalCounter.done()) {
8050 jam();
8051 return;
8052 }
8053 if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
8054 requestType == CreateIndxReq::RT_DICT_ABORT) {
8055 jam();
8056 // send reply to user
8057 createIndex_sendReply(signal, opPtr, true);
8058 c_opCreateIndex.release(opPtr);
8059 return;
8060 }
8061 if (opPtr.p->hasError()) {
8062 jam();
8063 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
8064 createIndex_sendSlaveReq(signal, opPtr);
8065 return;
8066 }
8067 if (requestType == CreateIndxReq::RT_DICT_PREPARE) {
8068 jam();
8069 // start index table create
8070 createIndex_toCreateTable(signal, opPtr);
8071 if (opPtr.p->hasError()) {
8072 jam();
8073 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
8074 createIndex_sendSlaveReq(signal, opPtr);
8075 return;
8076 }
8077 return;
8078 }
8079 ndbrequire(false);
8080 }
8081
8082 void
createIndex_slavePrepare(Signal * signal,OpCreateIndexPtr opPtr)8083 Dbdict::createIndex_slavePrepare(Signal* signal, OpCreateIndexPtr opPtr)
8084 {
8085 jam();
8086 if (ERROR_INSERTED(6006) && ! opPtr.p->m_isMaster) {
8087 ndbrequire(false);
8088 }
8089 }
8090
8091 void
createIndex_toCreateTable(Signal * signal,OpCreateIndexPtr opPtr)8092 Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
8093 {
8094 union {
8095 char tableName[MAX_TAB_NAME_SIZE];
8096 char attributeName[MAX_ATTR_NAME_SIZE];
8097 };
8098 Uint32 k;
8099 Uint32 attrid_map[MAX_ATTRIBUTES_IN_INDEX];
8100
8101 jam();
8102 const CreateIndxReq* const req = &opPtr.p->m_request;
8103 // signal data writer
8104 Uint32* wbuffer = &c_indexPage.word[0];
8105 LinearWriter w(wbuffer, sizeof(c_indexPage) >> 2);
8106 w.first();
8107 // get table being indexed
8108 if (! (req->getTableId() < c_tableRecordPool.getSize())) {
8109 jam();
8110 opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
8111 opPtr.p->m_errorLine = __LINE__;
8112 return;
8113 }
8114 TableRecordPtr tablePtr;
8115 c_tableRecordPool.getPtr(tablePtr, req->getTableId());
8116 if (tablePtr.p->tabState != TableRecord::DEFINED &&
8117 tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
8118 jam();
8119 opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
8120 opPtr.p->m_errorLine = __LINE__;
8121 return;
8122 }
8123 if (! tablePtr.p->isTable()) {
8124 jam();
8125 opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
8126 opPtr.p->m_errorLine = __LINE__;
8127 return;
8128 }
8129
8130 // Check that the temporary status of index is compatible with table.
8131 if (!opPtr.p->m_temporaryIndex &&
8132 tablePtr.p->m_bits & TableRecord::TR_Temporary)
8133 {
8134 jam();
8135 opPtr.p->m_errorCode= CreateIndxRef::TableIsTemporary;
8136 opPtr.p->m_errorLine= __LINE__;
8137 return;
8138 }
8139 if (opPtr.p->m_temporaryIndex &&
8140 !(tablePtr.p->m_bits & TableRecord::TR_Temporary))
8141 {
8142 // This could be implemented later, but mysqld does currently not detect
8143 // that the index disappears after SR, and it appears not too useful.
8144 jam();
8145 opPtr.p->m_errorCode= CreateIndxRef::TableIsNotTemporary;
8146 opPtr.p->m_errorLine= __LINE__;
8147 return;
8148 }
8149 if (opPtr.p->m_temporaryIndex && opPtr.p->m_loggedIndex)
8150 {
8151 jam();
8152 opPtr.p->m_errorCode= CreateIndxRef::NoLoggingTemporaryIndex;
8153 opPtr.p->m_errorLine= __LINE__;
8154 return;
8155 }
8156
8157 // compute index table record
8158 TableRecord indexRec;
8159 TableRecordPtr indexPtr;
8160 indexPtr.i = RNIL; // invalid
8161 indexPtr.p = &indexRec;
8162 initialiseTableRecord(indexPtr);
8163 indexPtr.p->m_bits = TableRecord::TR_RowChecksum;
8164 if (req->getIndexType() == DictTabInfo::UniqueHashIndex) {
8165 indexPtr.p->m_bits |= (opPtr.p->m_loggedIndex ? TableRecord::TR_Logged:0);
8166 indexPtr.p->m_bits |=
8167 (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
8168 indexPtr.p->fragmentType = DictTabInfo::DistrKeyUniqueHashIndex;
8169 } else if (req->getIndexType() == DictTabInfo::OrderedIndex) {
8170 // first version will not supported logging
8171 if (opPtr.p->m_loggedIndex) {
8172 jam();
8173 opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
8174 opPtr.p->m_errorLine = __LINE__;
8175 return;
8176 }
8177 indexPtr.p->m_bits |=
8178 (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
8179 indexPtr.p->fragmentType = DictTabInfo::DistrKeyOrderedIndex;
8180 } else {
8181 jam();
8182 opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
8183 opPtr.p->m_errorLine = __LINE__;
8184 return;
8185 }
8186 indexPtr.p->tableType = (DictTabInfo::TableType)req->getIndexType();
8187 indexPtr.p->primaryTableId = req->getTableId();
8188 indexPtr.p->noOfAttributes = opPtr.p->m_attrList.sz;
8189 indexPtr.p->tupKeyLength = 0;
8190 if (indexPtr.p->noOfAttributes == 0) {
8191 jam();
8192 opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
8193 opPtr.p->m_errorLine = __LINE__;
8194 return;
8195 }
8196
8197 if (indexPtr.p->isOrderedIndex()) {
8198 // tree node size in words (make configurable later)
8199 indexPtr.p->tupKeyLength = MAX_TTREE_NODE_SIZE;
8200 }
8201
8202 AttributeMask mask;
8203 mask.clear();
8204 for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
8205 jam();
8206 unsigned current_id= opPtr.p->m_attrList.id[k];
8207 Uint32 tAttr = tablePtr.p->m_attributes.firstItem;
8208 AttributeRecord* aRec = NULL;
8209 for (; tAttr != RNIL; )
8210 {
8211 aRec = c_attributeRecordPool.getPtr(tAttr);
8212 if (aRec->attributeId != current_id)
8213 {
8214 tAttr= aRec->nextList;
8215 continue;
8216 }
8217 jam();
8218 break;
8219 }
8220 if (tAttr == RNIL) {
8221 jam();
8222 opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
8223 opPtr.p->m_errorLine = __LINE__;
8224 return;
8225 }
8226 if (mask.get(current_id))
8227 {
8228 jam();
8229 opPtr.p->m_errorCode = CreateIndxRef::DuplicateAttributes;
8230 opPtr.p->m_errorLine = __LINE__;
8231 return;
8232 }
8233 const Uint32 a = aRec->attributeDescriptor;
8234
8235 if (AttributeDescriptor::getDiskBased(a))
8236 {
8237 jam();
8238 opPtr.p->m_errorCode = CreateIndxRef::IndexOnDiskAttributeError;
8239 opPtr.p->m_errorLine = __LINE__;
8240 return;
8241 }
8242
8243 mask.set(current_id);
8244 unsigned kk= k;
8245 if (indexPtr.p->isHashIndex()) {
8246 const Uint32 s1 = AttributeDescriptor::getSize(a);
8247 const Uint32 s2 = AttributeDescriptor::getArraySize(a);
8248 indexPtr.p->tupKeyLength += ((1 << s1) * s2 + 31) >> 5;
8249
8250 for (; kk > 0 && current_id < attrid_map[kk-1]>>16; kk--)
8251 attrid_map[kk]= attrid_map[kk-1];
8252 }
8253 attrid_map[kk]= k | (current_id << 16);
8254 }
8255
8256 indexPtr.p->noOfPrimkey = indexPtr.p->noOfAttributes;
8257 // plus concatenated primary table key attribute
8258 indexPtr.p->noOfAttributes += 1;
8259 indexPtr.p->noOfNullAttr = 0;
8260 // write index table
8261 w.add(DictTabInfo::TableName, opPtr.p->m_indexName);
8262 w.add(DictTabInfo::TableLoggedFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Logged));
8263 w.add(DictTabInfo::TableTemporaryFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Temporary));
8264 w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType);
8265 w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType);
8266 Rope name(c_rope_pool, tablePtr.p->tableName);
8267 name.copy(tableName);
8268 w.add(DictTabInfo::PrimaryTable, tableName);
8269 w.add(DictTabInfo::PrimaryTableId, tablePtr.i);
8270 w.add(DictTabInfo::NoOfAttributes, indexPtr.p->noOfAttributes);
8271 w.add(DictTabInfo::NoOfKeyAttr, indexPtr.p->noOfPrimkey);
8272 w.add(DictTabInfo::NoOfNullable, indexPtr.p->noOfNullAttr);
8273 w.add(DictTabInfo::KeyLength, indexPtr.p->tupKeyLength);
8274 w.add(DictTabInfo::SingleUserMode, (Uint32)NDB_SUM_READ_WRITE);
8275 // write index key attributes
8276 for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
8277 // insert the attributes in the order decided above in attrid_map
8278 // k is new order, current_id is in previous order
8279 // ToDo: make sure "current_id" is stored with the table and
8280 // passed up to NdbDictionary
8281 unsigned current_id= opPtr.p->m_attrList.id[attrid_map[k] & 0xffff];
8282 jam();
8283 for (Uint32 tAttr = tablePtr.p->m_attributes.firstItem; tAttr != RNIL; ) {
8284 AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
8285 tAttr = aRec->nextList;
8286 if (aRec->attributeId != current_id)
8287 continue;
8288 jam();
8289 const Uint32 a = aRec->attributeDescriptor;
8290 bool isNullable = AttributeDescriptor::getNullable(a);
8291 Uint32 arrayType = AttributeDescriptor::getArrayType(a);
8292 Rope attrName(c_rope_pool, aRec->attributeName);
8293 attrName.copy(attributeName);
8294 w.add(DictTabInfo::AttributeName, attributeName);
8295 Uint32 attrType = AttributeDescriptor::getType(a);
8296 // computed
8297 w.add(DictTabInfo::AttributeId, k);
8298 if (indexPtr.p->isHashIndex()) {
8299 w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
8300 w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
8301 }
8302 if (indexPtr.p->isOrderedIndex()) {
8303 w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
8304 w.add(DictTabInfo::AttributeNullableFlag, (Uint32)isNullable);
8305 }
8306 w.add(DictTabInfo::AttributeArrayType, arrayType);
8307 w.add(DictTabInfo::AttributeExtType, attrType);
8308 w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision);
8309 w.add(DictTabInfo::AttributeExtScale, aRec->extScale);
8310 w.add(DictTabInfo::AttributeExtLength, aRec->extLength);
8311 w.add(DictTabInfo::AttributeEnd, (Uint32)true);
8312 }
8313 }
8314 if (indexPtr.p->isHashIndex()) {
8315 jam();
8316
8317 Uint32 key_type = NDB_ARRAYTYPE_FIXED;
8318 AttributeRecordPtr attrPtr;
8319 LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
8320 tablePtr.p->m_attributes);
8321 for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr))
8322 {
8323 const Uint32 desc = attrPtr.p->attributeDescriptor;
8324 if (AttributeDescriptor::getPrimaryKey(desc) &&
8325 AttributeDescriptor::getArrayType(desc) != NDB_ARRAYTYPE_FIXED)
8326 {
8327 key_type = NDB_ARRAYTYPE_MEDIUM_VAR;
8328 break;
8329 }
8330 }
8331
8332 // write concatenated primary table key attribute i.e. keyinfo
8333 w.add(DictTabInfo::AttributeName, "NDB$PK");
8334 w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
8335 w.add(DictTabInfo::AttributeArrayType, key_type);
8336 w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
8337 w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
8338 w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
8339 w.add(DictTabInfo::AttributeExtLength, tablePtr.p->tupKeyLength+1);
8340 w.add(DictTabInfo::AttributeEnd, (Uint32)true);
8341 }
8342 if (indexPtr.p->isOrderedIndex()) {
8343 jam();
8344 // write index tree node as Uint32 array attribute
8345 w.add(DictTabInfo::AttributeName, "NDB$TNODE");
8346 w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
8347 // should not matter but VAR crashes in TUP
8348 w.add(DictTabInfo::AttributeArrayType, (Uint32)NDB_ARRAYTYPE_FIXED);
8349 w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
8350 w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
8351 w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
8352 w.add(DictTabInfo::AttributeExtLength, indexPtr.p->tupKeyLength);
8353 w.add(DictTabInfo::AttributeEnd, (Uint32)true);
8354 }
8355 // finish
8356 w.add(DictTabInfo::TableEnd, (Uint32)true);
8357 // remember to...
8358 releaseSections(signal);
8359 // send create index table request
8360 CreateTableReq * const cre = (CreateTableReq*)signal->getDataPtrSend();
8361 cre->senderRef = reference();
8362 cre->senderData = opPtr.p->key;
8363 LinearSectionPtr lsPtr[3];
8364 lsPtr[0].p = wbuffer;
8365 lsPtr[0].sz = w.getWordsUsed();
8366 sendSignal(DBDICT_REF, GSN_CREATE_TABLE_REQ,
8367 signal, CreateTableReq::SignalLength, JBB, lsPtr, 1);
8368 }
8369
8370 void
createIndex_fromCreateTable(Signal * signal,OpCreateIndexPtr opPtr)8371 Dbdict::createIndex_fromCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
8372 {
8373 jam();
8374 if (opPtr.p->hasError()) {
8375 jam();
8376 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
8377 createIndex_sendSlaveReq(signal, opPtr);
8378 return;
8379 }
8380 if (! opPtr.p->m_request.getOnline()) {
8381 jam();
8382 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
8383 createIndex_sendSlaveReq(signal, opPtr);
8384 return;
8385 }
8386 createIndex_toAlterIndex(signal, opPtr);
8387 }
8388
8389 void
createIndex_toAlterIndex(Signal * signal,OpCreateIndexPtr opPtr)8390 Dbdict::createIndex_toAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
8391 {
8392 jam();
8393 AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
8394 req->setUserRef(reference());
8395 req->setConnectionPtr(opPtr.p->key);
8396 req->setRequestType(AlterIndxReq::RT_CREATE_INDEX);
8397 req->addRequestFlag(opPtr.p->m_requestFlag);
8398 req->setTableId(opPtr.p->m_request.getTableId());
8399 req->setIndexId(opPtr.p->m_request.getIndexId());
8400 req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
8401 req->setOnline(true);
8402 sendSignal(reference(), GSN_ALTER_INDX_REQ,
8403 signal, AlterIndxReq::SignalLength, JBB);
8404 }
8405
8406 void
createIndex_fromAlterIndex(Signal * signal,OpCreateIndexPtr opPtr)8407 Dbdict::createIndex_fromAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
8408 {
8409 jam();
8410 if (opPtr.p->hasError()) {
8411 jam();
8412 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
8413 createIndex_sendSlaveReq(signal, opPtr);
8414 return;
8415 }
8416 opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
8417 createIndex_sendSlaveReq(signal, opPtr);
8418 }
8419
8420 void
createIndex_slaveCommit(Signal * signal,OpCreateIndexPtr opPtr)8421 Dbdict::createIndex_slaveCommit(Signal* signal, OpCreateIndexPtr opPtr)
8422 {
8423 jam();
8424 const Uint32 indexId = opPtr.p->m_request.getIndexId();
8425 TableRecordPtr indexPtr;
8426 c_tableRecordPool.getPtr(indexPtr, indexId);
8427 if (! opPtr.p->m_request.getOnline()) {
8428 ndbrequire(indexPtr.p->indexState == TableRecord::IS_UNDEFINED);
8429 indexPtr.p->indexState = TableRecord::IS_OFFLINE;
8430 } else {
8431 ndbrequire(indexPtr.p->indexState == TableRecord::IS_ONLINE);
8432 }
8433 }
8434
8435 void
createIndex_slaveAbort(Signal * signal,OpCreateIndexPtr opPtr)8436 Dbdict::createIndex_slaveAbort(Signal* signal, OpCreateIndexPtr opPtr)
8437 {
8438 jam();
8439 CreateIndxReq* const req = &opPtr.p->m_request;
8440 const Uint32 indexId = req->getIndexId();
8441 if (indexId >= c_tableRecordPool.getSize()) {
8442 jam();
8443 return;
8444 }
8445 TableRecordPtr indexPtr;
8446 c_tableRecordPool.getPtr(indexPtr, indexId);
8447 if (! indexPtr.p->isIndex()) {
8448 jam();
8449 return;
8450 }
8451 indexPtr.p->indexState = TableRecord::IS_BROKEN;
8452 }
8453
8454 void
createIndex_sendSlaveReq(Signal * signal,OpCreateIndexPtr opPtr)8455 Dbdict::createIndex_sendSlaveReq(Signal* signal, OpCreateIndexPtr opPtr)
8456 {
8457 jam();
8458 CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
8459 *req = opPtr.p->m_request;
8460 req->setUserRef(opPtr.p->m_coordinatorRef);
8461 req->setConnectionPtr(opPtr.p->key);
8462 req->setRequestType(opPtr.p->m_requestType);
8463 req->addRequestFlag(opPtr.p->m_requestFlag);
8464 opPtr.p->m_signalCounter = c_aliveNodes;
8465 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
8466 sendSignal(rg, GSN_CREATE_INDX_REQ,
8467 signal, CreateIndxReq::SignalLength, JBB);
8468 }
8469
8470 void
createIndex_sendReply(Signal * signal,OpCreateIndexPtr opPtr,bool toUser)8471 Dbdict::createIndex_sendReply(Signal* signal, OpCreateIndexPtr opPtr,
8472 bool toUser)
8473 {
8474 CreateIndxRef* rep = (CreateIndxRef*)signal->getDataPtrSend();
8475 Uint32 gsn = GSN_CREATE_INDX_CONF;
8476 Uint32 length = CreateIndxConf::InternalLength;
8477 bool sendRef;
8478 if (! toUser) {
8479 sendRef = opPtr.p->hasLastError();
8480 rep->setUserRef(opPtr.p->m_coordinatorRef);
8481 rep->setConnectionPtr(opPtr.p->key);
8482 rep->setRequestType(opPtr.p->m_requestType);
8483 if (opPtr.p->m_requestType == CreateIndxReq::RT_DICT_ABORT)
8484 sendRef = false;
8485 } else {
8486 sendRef = opPtr.p->hasError();
8487 rep->setUserRef(opPtr.p->m_request.getUserRef());
8488 rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
8489 rep->setRequestType(opPtr.p->m_request.getRequestType());
8490 length = CreateIndxConf::SignalLength;
8491 }
8492 rep->setTableId(opPtr.p->m_request.getTableId());
8493 rep->setIndexId(opPtr.p->m_request.getIndexId());
8494 rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
8495 if (sendRef) {
8496 if (opPtr.p->m_errorNode == 0)
8497 opPtr.p->m_errorNode = getOwnNodeId();
8498 rep->setErrorCode(opPtr.p->m_errorCode);
8499 rep->setErrorLine(opPtr.p->m_errorLine);
8500 rep->setErrorNode(opPtr.p->m_errorNode);
8501 gsn = GSN_CREATE_INDX_REF;
8502 length = CreateIndxRef::SignalLength;
8503 }
8504 sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
8505 }
8506
8507 /**
8508 * MODULE: Drop index.
8509 *
8510 * Drop index. First alters the index offline (i.e. drops metadata in
8511 * other blocks) and then drops the index table.
8512 */
8513
8514 void
execDROP_INDX_REQ(Signal * signal)8515 Dbdict::execDROP_INDX_REQ(Signal* signal)
8516 {
8517 jamEntry();
8518 DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
8519 OpDropIndexPtr opPtr;
8520
8521 int err = DropIndxRef::BadRequestType;
8522 const Uint32 senderRef = signal->senderBlockRef();
8523 const DropIndxReq::RequestType requestType = req->getRequestType();
8524 if (requestType == DropIndxReq::RT_USER) {
8525 jam();
8526 if (signal->getLength() == DropIndxReq::SignalLength) {
8527 jam();
8528 DropIndxRef::ErrorCode tmperr = DropIndxRef::NoError;
8529 if (getOwnNodeId() != c_masterNodeId) {
8530 jam();
8531 tmperr = DropIndxRef::NotMaster;
8532 } else if (c_blockState == BS_NODE_RESTART) {
8533 jam();
8534 tmperr = DropIndxRef::BusyWithNR;
8535 } else if (c_blockState != BS_IDLE) {
8536 jam();
8537 tmperr = DropIndxRef::Busy;
8538 }
8539 else if (checkSingleUserMode(senderRef))
8540 {
8541 jam();
8542 tmperr = DropIndxRef::SingleUser;
8543 }
8544 if (tmperr != DropIndxRef::NoError) {
8545 err = tmperr;
8546 goto error;
8547 }
8548 // forward initial request plus operation key to all
8549 Uint32 indexId= req->getIndexId();
8550 Uint32 indexVersion= req->getIndexVersion();
8551
8552 if(indexId >= c_tableRecordPool.getSize())
8553 {
8554 err = DropIndxRef::IndexNotFound;
8555 goto error;
8556 }
8557
8558 TableRecordPtr tmp;
8559 c_tableRecordPool.getPtr(tmp, indexId);
8560 if(tmp.p->tabState == TableRecord::NOT_DEFINED ||
8561 tmp.p->tableVersion != indexVersion)
8562 {
8563 err = DropIndxRef::InvalidIndexVersion;
8564 goto error;
8565 }
8566
8567 if (! tmp.p->isIndex()) {
8568 jam();
8569 err = DropIndxRef::NotAnIndex;
8570 goto error;
8571 }
8572
8573 if (tmp.p->indexState != TableRecord::IS_ONLINE)
8574 req->addRequestFlag(RequestFlag::RF_FORCE);
8575
8576 tmp.p->indexState = TableRecord::IS_DROPPING;
8577
8578 req->setOpKey(++c_opRecordSequence);
8579 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
8580 sendSignal(rg, GSN_DROP_INDX_REQ,
8581 signal, DropIndxReq::SignalLength + 1, JBB);
8582 return;
8583 }
8584 // seize operation record
8585 ndbrequire(signal->getLength() == DropIndxReq::SignalLength + 1);
8586 const Uint32 opKey = req->getOpKey();
8587 OpDropIndex opBusy;
8588 if (! c_opDropIndex.seize(opPtr))
8589 opPtr.p = &opBusy;
8590 opPtr.p->save(req);
8591 opPtr.p->m_coordinatorRef = senderRef;
8592 opPtr.p->m_isMaster = (senderRef == reference());
8593 opPtr.p->key = opKey;
8594 opPtr.p->m_requestType = DropIndxReq::RT_DICT_PREPARE;
8595 if (opPtr.p == &opBusy) {
8596 jam();
8597 opPtr.p->m_errorCode = DropIndxRef::Busy;
8598 opPtr.p->m_errorLine = __LINE__;
8599 dropIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
8600 return;
8601 }
8602 c_opDropIndex.add(opPtr);
8603 // master expects to hear from all
8604 if (opPtr.p->m_isMaster)
8605 opPtr.p->m_signalCounter = c_aliveNodes;
8606 dropIndex_slavePrepare(signal, opPtr);
8607 dropIndex_sendReply(signal, opPtr, false);
8608 return;
8609 }
8610 c_opDropIndex.find(opPtr, req->getConnectionPtr());
8611 if (! opPtr.isNull()) {
8612 opPtr.p->m_requestType = requestType;
8613 if (requestType == DropIndxReq::RT_DICT_COMMIT ||
8614 requestType == DropIndxReq::RT_DICT_ABORT) {
8615 jam();
8616 if (requestType == DropIndxReq::RT_DICT_COMMIT)
8617 dropIndex_slaveCommit(signal, opPtr);
8618 else
8619 dropIndex_slaveAbort(signal, opPtr);
8620 dropIndex_sendReply(signal, opPtr, false);
8621 // done in slave
8622 if (! opPtr.p->m_isMaster)
8623 c_opDropIndex.release(opPtr);
8624 return;
8625 }
8626 }
8627 error:
8628 jam();
8629 // return to sender
8630 OpDropIndex opBad;
8631 opPtr.p = &opBad;
8632 opPtr.p->save(req);
8633 opPtr.p->m_errorCode = (DropIndxRef::ErrorCode)err;
8634 opPtr.p->m_errorLine = __LINE__;
8635 opPtr.p->m_errorNode = c_masterNodeId;
8636 dropIndex_sendReply(signal, opPtr, true);
8637 }
8638
8639 void
execDROP_INDX_CONF(Signal * signal)8640 Dbdict::execDROP_INDX_CONF(Signal* signal)
8641 {
8642 jamEntry();
8643 DropIndxConf* conf = (DropIndxConf*)signal->getDataPtrSend();
8644 dropIndex_recvReply(signal, conf, 0);
8645 }
8646
8647 void
execDROP_INDX_REF(Signal * signal)8648 Dbdict::execDROP_INDX_REF(Signal* signal)
8649 {
8650 jamEntry();
8651 DropIndxRef* ref = (DropIndxRef*)signal->getDataPtrSend();
8652 dropIndex_recvReply(signal, ref->getConf(), ref);
8653 }
8654
8655 void
dropIndex_recvReply(Signal * signal,const DropIndxConf * conf,const DropIndxRef * ref)8656 Dbdict::dropIndex_recvReply(Signal* signal, const DropIndxConf* conf,
8657 const DropIndxRef* ref)
8658 {
8659 jam();
8660 const Uint32 senderRef = signal->senderBlockRef();
8661 const DropIndxReq::RequestType requestType = conf->getRequestType();
8662 const Uint32 key = conf->getConnectionPtr();
8663 if (requestType == DropIndxReq::RT_TC) {
8664 jam();
8665 // part of alter index operation
8666 OpAlterIndexPtr opPtr;
8667 c_opAlterIndex.find(opPtr, key);
8668 ndbrequire(! opPtr.isNull());
8669 opPtr.p->setError(ref);
8670 alterIndex_fromDropTc(signal, opPtr);
8671 return;
8672 }
8673 OpDropIndexPtr opPtr;
8674 c_opDropIndex.find(opPtr, key);
8675 ndbrequire(! opPtr.isNull());
8676 ndbrequire(opPtr.p->m_isMaster);
8677 ndbrequire(opPtr.p->m_requestType == requestType);
8678 opPtr.p->setError(ref);
8679 opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
8680 if (! opPtr.p->m_signalCounter.done()) {
8681 jam();
8682 return;
8683 }
8684 if (requestType == DropIndxReq::RT_DICT_COMMIT ||
8685 requestType == DropIndxReq::RT_DICT_ABORT) {
8686 jam();
8687 // send reply to user
8688 dropIndex_sendReply(signal, opPtr, true);
8689 c_opDropIndex.release(opPtr);
8690 return;
8691 }
8692 if (opPtr.p->hasError()) {
8693 jam();
8694 opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
8695 dropIndex_sendSlaveReq(signal, opPtr);
8696 return;
8697 }
8698 if (requestType == DropIndxReq::RT_DICT_PREPARE) {
8699 jam();
8700 // start alter offline
8701 dropIndex_toAlterIndex(signal, opPtr);
8702 return;
8703 }
8704 ndbrequire(false);
8705 }
8706
8707 void
dropIndex_slavePrepare(Signal * signal,OpDropIndexPtr opPtr)8708 Dbdict::dropIndex_slavePrepare(Signal* signal, OpDropIndexPtr opPtr)
8709 {
8710 jam();
8711 DropIndxReq* const req = &opPtr.p->m_request;
8712 // check index exists
8713 TableRecordPtr indexPtr;
8714 if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
8715 jam();
8716 opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
8717 opPtr.p->m_errorLine = __LINE__;
8718 return;
8719 }
8720 c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
8721 if (indexPtr.p->tabState != TableRecord::DEFINED) {
8722 jam();
8723 opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
8724 opPtr.p->m_errorLine = __LINE__;
8725 return;
8726 }
8727 if (! indexPtr.p->isIndex()) {
8728 jam();
8729 opPtr.p->m_errorCode = DropIndxRef::NotAnIndex;
8730 opPtr.p->m_errorLine = __LINE__;
8731 return;
8732 }
8733 // ignore incoming primary table id
8734 req->setTableId(indexPtr.p->primaryTableId);
8735 }
8736
8737 void
dropIndex_toAlterIndex(Signal * signal,OpDropIndexPtr opPtr)8738 Dbdict::dropIndex_toAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
8739 {
8740 jam();
8741 AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
8742 req->setUserRef(reference());
8743 req->setConnectionPtr(opPtr.p->key);
8744 req->setRequestType(AlterIndxReq::RT_DROP_INDEX);
8745 req->addRequestFlag(opPtr.p->m_requestFlag);
8746 req->setTableId(opPtr.p->m_request.getTableId());
8747 req->setIndexId(opPtr.p->m_request.getIndexId());
8748 req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
8749 req->setOnline(false);
8750 sendSignal(reference(), GSN_ALTER_INDX_REQ,
8751 signal, AlterIndxReq::SignalLength, JBB);
8752 }
8753
8754 void
dropIndex_fromAlterIndex(Signal * signal,OpDropIndexPtr opPtr)8755 Dbdict::dropIndex_fromAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
8756 {
8757 jam();
8758 if (opPtr.p->hasError()) {
8759 jam();
8760 opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
8761 dropIndex_sendSlaveReq(signal, opPtr);
8762 return;
8763 }
8764 dropIndex_toDropTable(signal, opPtr);
8765 }
8766
8767 void
dropIndex_toDropTable(Signal * signal,OpDropIndexPtr opPtr)8768 Dbdict::dropIndex_toDropTable(Signal* signal, OpDropIndexPtr opPtr)
8769 {
8770 jam();
8771 DropTableReq* const req = (DropTableReq*)signal->getDataPtrSend();
8772 req->senderRef = reference();
8773 req->senderData = opPtr.p->key;
8774 req->tableId = opPtr.p->m_request.getIndexId();
8775 req->tableVersion = opPtr.p->m_request.getIndexVersion();
8776 sendSignal(reference(), GSN_DROP_TABLE_REQ,
8777 signal,DropTableReq::SignalLength, JBB);
8778 }
8779
8780 void
dropIndex_fromDropTable(Signal * signal,OpDropIndexPtr opPtr)8781 Dbdict::dropIndex_fromDropTable(Signal* signal, OpDropIndexPtr opPtr)
8782 {
8783 jam();
8784 if (opPtr.p->hasError()) {
8785 jam();
8786 opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
8787 dropIndex_sendSlaveReq(signal, opPtr);
8788 return;
8789 }
8790 opPtr.p->m_requestType = DropIndxReq::RT_DICT_COMMIT;
8791 dropIndex_sendSlaveReq(signal, opPtr);
8792 }
8793
8794 void
dropIndex_slaveCommit(Signal * signal,OpDropIndexPtr opPtr)8795 Dbdict::dropIndex_slaveCommit(Signal* signal, OpDropIndexPtr opPtr)
8796 {
8797 jam();
8798 }
8799
8800 void
dropIndex_slaveAbort(Signal * signal,OpDropIndexPtr opPtr)8801 Dbdict::dropIndex_slaveAbort(Signal* signal, OpDropIndexPtr opPtr)
8802 {
8803 jam();
8804 DropIndxReq* const req = &opPtr.p->m_request;
8805 const Uint32 indexId = req->getIndexId();
8806 if (indexId >= c_tableRecordPool.getSize()) {
8807 jam();
8808 return;
8809 }
8810 TableRecordPtr indexPtr;
8811 c_tableRecordPool.getPtr(indexPtr, indexId);
8812 indexPtr.p->indexState = TableRecord::IS_BROKEN;
8813 }
8814
8815 void
dropIndex_sendSlaveReq(Signal * signal,OpDropIndexPtr opPtr)8816 Dbdict::dropIndex_sendSlaveReq(Signal* signal, OpDropIndexPtr opPtr)
8817 {
8818 DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
8819 *req = opPtr.p->m_request;
8820 req->setUserRef(opPtr.p->m_coordinatorRef);
8821 req->setConnectionPtr(opPtr.p->key);
8822 req->setRequestType(opPtr.p->m_requestType);
8823 req->addRequestFlag(opPtr.p->m_requestFlag);
8824 opPtr.p->m_signalCounter = c_aliveNodes;
8825 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
8826 sendSignal(rg, GSN_DROP_INDX_REQ,
8827 signal, DropIndxReq::SignalLength, JBB);
8828 }
8829
8830 void
dropIndex_sendReply(Signal * signal,OpDropIndexPtr opPtr,bool toUser)8831 Dbdict::dropIndex_sendReply(Signal* signal, OpDropIndexPtr opPtr,
8832 bool toUser)
8833 {
8834 DropIndxRef* rep = (DropIndxRef*)signal->getDataPtrSend();
8835 Uint32 gsn = GSN_DROP_INDX_CONF;
8836 Uint32 length = DropIndxConf::InternalLength;
8837 bool sendRef;
8838 if (! toUser) {
8839 sendRef = opPtr.p->hasLastError();
8840 rep->setUserRef(opPtr.p->m_coordinatorRef);
8841 rep->setConnectionPtr(opPtr.p->key);
8842 rep->setRequestType(opPtr.p->m_requestType);
8843 if (opPtr.p->m_requestType == DropIndxReq::RT_DICT_ABORT)
8844 sendRef = false;
8845 } else {
8846 sendRef = opPtr.p->hasError();
8847 rep->setUserRef(opPtr.p->m_request.getUserRef());
8848 rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
8849 rep->setRequestType(opPtr.p->m_request.getRequestType());
8850 length = DropIndxConf::SignalLength;
8851 }
8852 rep->setTableId(opPtr.p->m_request.getTableId());
8853 rep->setIndexId(opPtr.p->m_request.getIndexId());
8854 rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
8855 if (sendRef) {
8856 if (opPtr.p->m_errorNode == 0)
8857 opPtr.p->m_errorNode = getOwnNodeId();
8858 rep->setErrorCode(opPtr.p->m_errorCode);
8859 rep->setErrorLine(opPtr.p->m_errorLine);
8860 rep->setErrorNode(opPtr.p->m_errorNode);
8861 gsn = GSN_DROP_INDX_REF;
8862 length = DropIndxRef::SignalLength;
8863 }
8864 sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
8865 }
8866
8867 /*****************************************************
8868 *
8869 * Util signalling
8870 *
8871 *****************************************************/
8872
8873 int
sendSignalUtilReq(Callback * pcallback,BlockReference ref,GlobalSignalNumber gsn,Signal * signal,Uint32 length,JobBufferLevel jbuf,LinearSectionPtr ptr[3],Uint32 noOfSections)8874 Dbdict::sendSignalUtilReq(Callback *pcallback,
8875 BlockReference ref,
8876 GlobalSignalNumber gsn,
8877 Signal* signal,
8878 Uint32 length,
8879 JobBufferLevel jbuf,
8880 LinearSectionPtr ptr[3],
8881 Uint32 noOfSections)
8882 {
8883 jam();
8884 EVENT_TRACE;
8885 OpSignalUtilPtr utilRecPtr;
8886
8887 // Seize a Util Send record
8888 if (!c_opSignalUtil.seize(utilRecPtr)) {
8889 // Failed to allocate util record
8890 return -1;
8891 }
8892 utilRecPtr.p->m_callback = *pcallback;
8893
8894 // should work for all util signal classes
8895 UtilPrepareReq *req = (UtilPrepareReq*)signal->getDataPtrSend();
8896 utilRecPtr.p->m_userData = req->getSenderData();
8897 req->setSenderData(utilRecPtr.i);
8898
8899 if (ptr) {
8900 jam();
8901 sendSignal(ref, gsn, signal, length, jbuf, ptr, noOfSections);
8902 } else {
8903 jam();
8904 sendSignal(ref, gsn, signal, length, jbuf);
8905 }
8906
8907 return 0;
8908 }
8909
8910 int
recvSignalUtilReq(Signal * signal,Uint32 returnCode)8911 Dbdict::recvSignalUtilReq(Signal* signal, Uint32 returnCode)
8912 {
8913 jam();
8914 EVENT_TRACE;
8915 UtilPrepareConf * const req = (UtilPrepareConf*)signal->getDataPtr();
8916 OpSignalUtilPtr utilRecPtr;
8917 utilRecPtr.i = req->getSenderData();
8918 if ((utilRecPtr.p = c_opSignalUtil.getPtr(utilRecPtr.i)) == NULL) {
8919 jam();
8920 return -1;
8921 }
8922
8923 req->setSenderData(utilRecPtr.p->m_userData);
8924 Callback c = utilRecPtr.p->m_callback;
8925 c_opSignalUtil.release(utilRecPtr);
8926
8927 execute(signal, c, returnCode);
8928 return 0;
8929 }
8930
execUTIL_PREPARE_CONF(Signal * signal)8931 void Dbdict::execUTIL_PREPARE_CONF(Signal *signal)
8932 {
8933 jamEntry();
8934 EVENT_TRACE;
8935 ndbrequire(recvSignalUtilReq(signal, 0) == 0);
8936 }
8937
8938 void
execUTIL_PREPARE_REF(Signal * signal)8939 Dbdict::execUTIL_PREPARE_REF(Signal *signal)
8940 {
8941 jamEntry();
8942 EVENT_TRACE;
8943 ndbrequire(recvSignalUtilReq(signal, 1) == 0);
8944 }
8945
execUTIL_EXECUTE_CONF(Signal * signal)8946 void Dbdict::execUTIL_EXECUTE_CONF(Signal *signal)
8947 {
8948 jamEntry();
8949 EVENT_TRACE;
8950 ndbrequire(recvSignalUtilReq(signal, 0) == 0);
8951 }
8952
execUTIL_EXECUTE_REF(Signal * signal)8953 void Dbdict::execUTIL_EXECUTE_REF(Signal *signal)
8954 {
8955 jamEntry();
8956 EVENT_TRACE;
8957
8958 #ifdef EVENT_DEBUG
8959 UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend();
8960
8961 ndbout_c("execUTIL_EXECUTE_REF");
8962 ndbout_c("senderData %u",ref->getSenderData());
8963 ndbout_c("errorCode %u",ref->getErrorCode());
8964 ndbout_c("TCErrorCode %u",ref->getTCErrorCode());
8965 #endif
8966
8967 ndbrequire(recvSignalUtilReq(signal, 1) == 0);
8968 }
execUTIL_RELEASE_CONF(Signal * signal)8969 void Dbdict::execUTIL_RELEASE_CONF(Signal *signal)
8970 {
8971 jamEntry();
8972 EVENT_TRACE;
8973 ndbrequire(false);
8974 ndbrequire(recvSignalUtilReq(signal, 0) == 0);
8975 }
execUTIL_RELEASE_REF(Signal * signal)8976 void Dbdict::execUTIL_RELEASE_REF(Signal *signal)
8977 {
8978 jamEntry();
8979 EVENT_TRACE;
8980 ndbrequire(false);
8981 ndbrequire(recvSignalUtilReq(signal, 1) == 0);
8982 }
8983
8984 /**
8985 * MODULE: Create event
8986 *
8987 * Create event in DICT.
8988 *
8989 *
8990 * Request type in CREATE_EVNT signals:
8991 *
8992 * Signalflow see Dbdict.txt
8993 *
8994 */
8995
8996 /*****************************************************************
8997 *
8998 * Systable stuff
8999 *
9000 */
9001
9002 const Uint32 Dbdict::sysTab_NDBEVENTS_0_szs[EVENT_SYSTEM_TABLE_LENGTH] = {
9003 sizeof(((sysTab_NDBEVENTS_0*)0)->NAME),
9004 sizeof(((sysTab_NDBEVENTS_0*)0)->EVENT_TYPE),
9005 sizeof(((sysTab_NDBEVENTS_0*)0)->TABLEID),
9006 sizeof(((sysTab_NDBEVENTS_0*)0)->TABLEVERSION),
9007 sizeof(((sysTab_NDBEVENTS_0*)0)->TABLE_NAME),
9008 sizeof(((sysTab_NDBEVENTS_0*)0)->ATTRIBUTE_MASK),
9009 sizeof(((sysTab_NDBEVENTS_0*)0)->SUBID),
9010 sizeof(((sysTab_NDBEVENTS_0*)0)->SUBKEY)
9011 };
9012
9013 void
prepareTransactionEventSysTable(Callback * pcallback,Signal * signal,Uint32 senderData,UtilPrepareReq::OperationTypeValue prepReq)9014 Dbdict::prepareTransactionEventSysTable (Callback *pcallback,
9015 Signal* signal,
9016 Uint32 senderData,
9017 UtilPrepareReq::OperationTypeValue prepReq)
9018 {
9019 // find table id for event system table
9020 DictObject * opj_ptr_p = get_object(EVENT_SYSTEM_TABLE_NAME,
9021 sizeof(EVENT_SYSTEM_TABLE_NAME));
9022
9023 ndbrequire(opj_ptr_p != 0);
9024 TableRecordPtr tablePtr;
9025 c_tableRecordPool.getPtr(tablePtr, opj_ptr_p->m_id);
9026 ndbrequire(tablePtr.i != RNIL); // system table must exist
9027
9028 Uint32 tableId = tablePtr.p->tableId; /* System table */
9029 Uint32 noAttr = tablePtr.p->noOfAttributes;
9030 ndbrequire(noAttr == EVENT_SYSTEM_TABLE_LENGTH);
9031
9032 switch (prepReq) {
9033 case UtilPrepareReq::Update:
9034 case UtilPrepareReq::Insert:
9035 case UtilPrepareReq::Write:
9036 case UtilPrepareReq::Read:
9037 jam();
9038 break;
9039 case UtilPrepareReq::Delete:
9040 jam();
9041 noAttr = 1; // only involves Primary key which should be the first
9042 break;
9043 }
9044 prepareUtilTransaction(pcallback, signal, senderData, tableId, NULL,
9045 prepReq, noAttr, NULL, NULL);
9046 }
9047
9048 void
prepareUtilTransaction(Callback * pcallback,Signal * signal,Uint32 senderData,Uint32 tableId,const char * tableName,UtilPrepareReq::OperationTypeValue prepReq,Uint32 noAttr,Uint32 attrIds[],const char * attrNames[])9049 Dbdict::prepareUtilTransaction(Callback *pcallback,
9050 Signal* signal,
9051 Uint32 senderData,
9052 Uint32 tableId,
9053 const char* tableName,
9054 UtilPrepareReq::OperationTypeValue prepReq,
9055 Uint32 noAttr,
9056 Uint32 attrIds[],
9057 const char *attrNames[])
9058 {
9059 jam();
9060 EVENT_TRACE;
9061
9062 UtilPrepareReq * utilPrepareReq =
9063 (UtilPrepareReq *)signal->getDataPtrSend();
9064
9065 utilPrepareReq->setSenderRef(reference());
9066 utilPrepareReq->setSenderData(senderData);
9067
9068 const Uint32 pageSizeInWords = 128;
9069 Uint32 propPage[pageSizeInWords];
9070 LinearWriter w(&propPage[0],128);
9071 w.first();
9072 w.add(UtilPrepareReq::NoOfOperations, 1);
9073 w.add(UtilPrepareReq::OperationType, prepReq);
9074 if (tableName) {
9075 jam();
9076 w.add(UtilPrepareReq::TableName, tableName);
9077 } else {
9078 jam();
9079 w.add(UtilPrepareReq::TableId, tableId);
9080 }
9081 for(Uint32 i = 0; i < noAttr; i++)
9082 if (tableName) {
9083 jam();
9084 w.add(UtilPrepareReq::AttributeName, attrNames[i]);
9085 } else {
9086 if (attrIds) {
9087 jam();
9088 w.add(UtilPrepareReq::AttributeId, attrIds[i]);
9089 } else {
9090 jam();
9091 w.add(UtilPrepareReq::AttributeId, i);
9092 }
9093 }
9094 #ifdef EVENT_DEBUG
9095 // Debugging
9096 SimplePropertiesLinearReader reader(propPage, w.getWordsUsed());
9097 printf("Dict::prepareInsertTransactions: Sent SimpleProperties:\n");
9098 reader.printAll(ndbout);
9099 #endif
9100
9101 struct LinearSectionPtr sectionsPtr[UtilPrepareReq::NoOfSections];
9102 sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].p = propPage;
9103 sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].sz = w.getWordsUsed();
9104
9105 sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_PREPARE_REQ, signal,
9106 UtilPrepareReq::SignalLength, JBB,
9107 sectionsPtr, UtilPrepareReq::NoOfSections);
9108 }
9109
9110 /*****************************************************************
9111 *
9112 * CREATE_EVNT_REQ has three types RT_CREATE, RT_GET (from user)
9113 * and RT_DICT_AFTER_GET send from master DICT to slaves
9114 *
9115 * This function just dscpaches these to
9116 *
9117 * createEvent_RT_USER_CREATE
9118 * createEvent_RT_USER_GET
9119 * createEvent_RT_DICT_AFTER_GET
9120 *
9121 * repectively
9122 *
9123 */
9124
9125 void
execCREATE_EVNT_REQ(Signal * signal)9126 Dbdict::execCREATE_EVNT_REQ(Signal* signal)
9127 {
9128 jamEntry();
9129
9130 #if 0
9131 {
9132 SafeCounterHandle handle;
9133 {
9134 SafeCounter tmp(c_counterMgr, handle);
9135 tmp.init<CreateEvntRef>(CMVMI, GSN_DUMP_STATE_ORD, /* senderData */ 13);
9136 tmp.clearWaitingFor();
9137 tmp.setWaitingFor(3);
9138 ndbrequire(!tmp.done());
9139 ndbout_c("Allocted");
9140 }
9141 ndbrequire(!handle.done());
9142 {
9143 SafeCounter tmp(c_counterMgr, handle);
9144 tmp.clearWaitingFor(3);
9145 ndbrequire(tmp.done());
9146 ndbout_c("Deallocted");
9147 }
9148 ndbrequire(handle.done());
9149 }
9150 {
9151 NodeBitmask nodes;
9152 nodes.clear();
9153
9154 nodes.set(2);
9155 nodes.set(3);
9156 nodes.set(4);
9157 nodes.set(5);
9158
9159 {
9160 Uint32 i = 0;
9161 while((i = nodes.find(i)) != NodeBitmask::NotFound){
9162 ndbout_c("1 Node id = %u", i);
9163 i++;
9164 }
9165 }
9166
9167 NodeReceiverGroup rg(DBDICT, nodes);
9168 RequestTracker rt2;
9169 ndbrequire(rt2.done());
9170 ndbrequire(!rt2.hasRef());
9171 ndbrequire(!rt2.hasConf());
9172 rt2.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
9173
9174 RequestTracker rt3;
9175 rt3.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
9176
9177 ndbrequire(!rt2.done());
9178 ndbrequire(!rt3.done());
9179
9180 rt2.reportRef(c_counterMgr, 2);
9181 rt3.reportConf(c_counterMgr, 2);
9182
9183 ndbrequire(!rt2.done());
9184 ndbrequire(!rt3.done());
9185
9186 rt2.reportConf(c_counterMgr, 3);
9187 rt3.reportConf(c_counterMgr, 3);
9188
9189 ndbrequire(!rt2.done());
9190 ndbrequire(!rt3.done());
9191
9192 rt2.reportConf(c_counterMgr, 4);
9193 rt3.reportConf(c_counterMgr, 4);
9194
9195 ndbrequire(!rt2.done());
9196 ndbrequire(!rt3.done());
9197
9198 rt2.reportConf(c_counterMgr, 5);
9199 rt3.reportConf(c_counterMgr, 5);
9200
9201 ndbrequire(rt2.done());
9202 ndbrequire(rt3.done());
9203 }
9204 #endif
9205
9206 if (! assembleFragments(signal)) {
9207 jam();
9208 return;
9209 }
9210
9211 CreateEvntReq *req = (CreateEvntReq*)signal->getDataPtr();
9212 const CreateEvntReq::RequestType requestType = req->getRequestType();
9213 const Uint32 requestFlag = req->getRequestFlag();
9214
9215 if (refToBlock(signal->senderBlockRef()) != DBDICT &&
9216 getOwnNodeId() != c_masterNodeId)
9217 {
9218 jam();
9219 releaseSections(signal);
9220
9221 CreateEvntRef * ref = (CreateEvntRef *)signal->getDataPtrSend();
9222 ref->setUserRef(reference());
9223 ref->setErrorCode(CreateEvntRef::NotMaster);
9224 ref->setErrorLine(__LINE__);
9225 ref->setErrorNode(reference());
9226 ref->setMasterNode(c_masterNodeId);
9227 sendSignal(signal->senderBlockRef(), GSN_CREATE_EVNT_REF, signal,
9228 CreateEvntRef::SignalLength2, JBB);
9229 return;
9230 }
9231
9232 OpCreateEventPtr evntRecPtr;
9233 // Seize a Create Event record
9234 if (!c_opCreateEvent.seize(evntRecPtr)) {
9235 // Failed to allocate event record
9236 jam();
9237 releaseSections(signal);
9238
9239 CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
9240 ret->senderRef = reference();
9241 ret->setErrorCode(747);
9242 ret->setErrorLine(__LINE__);
9243 ret->setErrorNode(reference());
9244 sendSignal(signal->senderBlockRef(), GSN_CREATE_EVNT_REF, signal,
9245 CreateEvntRef::SignalLength, JBB);
9246 return;
9247 }
9248
9249 #ifdef EVENT_DEBUG
9250 ndbout_c("DBDICT::execCREATE_EVNT_REQ from %u evntRecId = (%d)", refToNode(signal->getSendersBlockRef()), evntRecPtr.i);
9251 #endif
9252
9253 ndbrequire(req->getUserRef() == signal->getSendersBlockRef());
9254
9255 evntRecPtr.p->init(req,this);
9256
9257 if (requestFlag & (Uint32)CreateEvntReq::RT_DICT_AFTER_GET) {
9258 jam();
9259 EVENT_TRACE;
9260 createEvent_RT_DICT_AFTER_GET(signal, evntRecPtr);
9261 return;
9262 }
9263 if (requestType == CreateEvntReq::RT_USER_GET) {
9264 jam();
9265 EVENT_TRACE;
9266 createEvent_RT_USER_GET(signal, evntRecPtr);
9267 return;
9268 }
9269 if (requestType == CreateEvntReq::RT_USER_CREATE) {
9270 jam();
9271 EVENT_TRACE;
9272 createEvent_RT_USER_CREATE(signal, evntRecPtr);
9273 return;
9274 }
9275
9276 #ifdef EVENT_DEBUG
9277 ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ other" << endl;
9278 #endif
9279 jam();
9280 releaseSections(signal);
9281
9282 evntRecPtr.p->m_errorCode = 1;
9283 evntRecPtr.p->m_errorLine = __LINE__;
9284 evntRecPtr.p->m_errorNode = reference();
9285
9286 createEvent_sendReply(signal, evntRecPtr);
9287 }
9288
9289 /********************************************************************
9290 *
9291 * Event creation
9292 *
9293 *****************************************************************/
9294
9295 void
createEvent_RT_USER_CREATE(Signal * signal,OpCreateEventPtr evntRecPtr)9296 Dbdict::createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr)
9297 {
9298 jam();
9299 DBUG_ENTER("Dbdict::createEvent_RT_USER_CREATE");
9300 evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
9301
9302 #ifdef EVENT_DEBUG
9303 ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ RT_USER" << endl;
9304 char buf[128] = {0};
9305 AttributeMask mask = evntRecPtr.p->m_request.getAttrListBitmask();
9306 mask.getText(buf);
9307 ndbout_c("mask = %s", buf);
9308 #endif
9309
9310 // Interpret the long signal
9311
9312 SegmentedSectionPtr ssPtr;
9313 // save name and event properties
9314 signal->getSection(ssPtr, CreateEvntReq::EVENT_NAME_SECTION);
9315
9316 SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
9317 #ifdef EVENT_DEBUG
9318 r0.printAll(ndbout);
9319 #endif
9320 // event name
9321 if ((!r0.first()) ||
9322 (r0.getValueType() != SimpleProperties::StringValue) ||
9323 (r0.getValueLen() <= 0)) {
9324 jam();
9325 releaseSections(signal);
9326
9327 evntRecPtr.p->m_errorCode = 1;
9328 evntRecPtr.p->m_errorLine = __LINE__;
9329 evntRecPtr.p->m_errorNode = reference();
9330
9331 createEvent_sendReply(signal, evntRecPtr);
9332 DBUG_VOID_RETURN;
9333 }
9334 r0.getString(evntRecPtr.p->m_eventRec.NAME);
9335 {
9336 int len = strlen(evntRecPtr.p->m_eventRec.NAME);
9337 memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
9338 #ifdef EVENT_DEBUG
9339 printf("CreateEvntReq::RT_USER_CREATE; EventName %s, len %u\n",
9340 evntRecPtr.p->m_eventRec.NAME, len);
9341 for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
9342 printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
9343 printf("\n");
9344 #endif
9345 }
9346 // table name
9347 if ((!r0.next()) ||
9348 (r0.getValueType() != SimpleProperties::StringValue) ||
9349 (r0.getValueLen() <= 0)) {
9350 jam();
9351 releaseSections(signal);
9352
9353 evntRecPtr.p->m_errorCode = 1;
9354 evntRecPtr.p->m_errorLine = __LINE__;
9355 evntRecPtr.p->m_errorNode = reference();
9356
9357 createEvent_sendReply(signal, evntRecPtr);
9358 DBUG_VOID_RETURN;
9359 }
9360 r0.getString(evntRecPtr.p->m_eventRec.TABLE_NAME);
9361 {
9362 int len = strlen(evntRecPtr.p->m_eventRec.TABLE_NAME);
9363 memset(evntRecPtr.p->m_eventRec.TABLE_NAME+len, 0, MAX_TAB_NAME_SIZE-len);
9364 }
9365
9366 releaseSections(signal);
9367
9368 // Send request to SUMA
9369
9370 CreateSubscriptionIdReq * sumaIdReq =
9371 (CreateSubscriptionIdReq *)signal->getDataPtrSend();
9372
9373 // make sure we save the original sender for later
9374 sumaIdReq->senderRef = reference();
9375 sumaIdReq->senderData = evntRecPtr.i;
9376 #ifdef EVENT_DEBUG
9377 ndbout << "sumaIdReq->senderData = " << sumaIdReq->senderData << endl;
9378 #endif
9379 sendSignal(SUMA_REF, GSN_CREATE_SUBID_REQ, signal,
9380 CreateSubscriptionIdReq::SignalLength, JBB);
9381 // we should now return in either execCREATE_SUBID_CONF
9382 // or execCREATE_SUBID_REF
9383 DBUG_VOID_RETURN;
9384 }
9385
execCREATE_SUBID_REF(Signal * signal)9386 void Dbdict::execCREATE_SUBID_REF(Signal* signal)
9387 {
9388 jamEntry();
9389 DBUG_ENTER("Dbdict::execCREATE_SUBID_REF");
9390 CreateSubscriptionIdRef * const ref =
9391 (CreateSubscriptionIdRef *)signal->getDataPtr();
9392 OpCreateEventPtr evntRecPtr;
9393
9394 evntRecPtr.i = ref->senderData;
9395 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
9396
9397 if (ref->errorCode)
9398 {
9399 evntRecPtr.p->m_errorCode = ref->errorCode;
9400 evntRecPtr.p->m_errorLine = __LINE__;
9401 }
9402 else
9403 {
9404 evntRecPtr.p->m_errorCode = 1;
9405 evntRecPtr.p->m_errorLine = __LINE__;
9406 }
9407 evntRecPtr.p->m_errorNode = reference();
9408
9409 createEvent_sendReply(signal, evntRecPtr);
9410 DBUG_VOID_RETURN;
9411 }
9412
execCREATE_SUBID_CONF(Signal * signal)9413 void Dbdict::execCREATE_SUBID_CONF(Signal* signal)
9414 {
9415 jamEntry();
9416 DBUG_ENTER("Dbdict::execCREATE_SUBID_CONF");
9417
9418 CreateSubscriptionIdConf const * sumaIdConf =
9419 (CreateSubscriptionIdConf *)signal->getDataPtr();
9420
9421 Uint32 evntRecId = sumaIdConf->senderData;
9422 OpCreateEvent *evntRec;
9423
9424 ndbrequire((evntRec = c_opCreateEvent.getPtr(evntRecId)) != NULL);
9425
9426 evntRec->m_request.setEventId(sumaIdConf->subscriptionId);
9427 evntRec->m_request.setEventKey(sumaIdConf->subscriptionKey);
9428
9429 releaseSections(signal);
9430
9431 Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
9432
9433 prepareTransactionEventSysTable(&c, signal, evntRecId,
9434 UtilPrepareReq::Insert);
9435 DBUG_VOID_RETURN;
9436 }
9437
9438 void
createEventComplete_RT_USER_CREATE(Signal * signal,OpCreateEventPtr evntRecPtr)9439 Dbdict::createEventComplete_RT_USER_CREATE(Signal* signal,
9440 OpCreateEventPtr evntRecPtr){
9441 jam();
9442 createEvent_sendReply(signal, evntRecPtr);
9443 }
9444
9445 /*********************************************************************
9446 *
9447 * UTIL_PREPARE, UTIL_EXECUTE
9448 *
9449 * insert or read systable NDB$EVENTS_0
9450 */
9451
interpretUtilPrepareErrorCode(UtilPrepareRef::ErrorCode errorCode,Uint32 & error,Uint32 & line)9452 void interpretUtilPrepareErrorCode(UtilPrepareRef::ErrorCode errorCode,
9453 Uint32& error, Uint32& line)
9454 {
9455 DBUG_ENTER("interpretUtilPrepareErrorCode");
9456 switch (errorCode) {
9457 case UtilPrepareRef::NO_ERROR:
9458 jam();
9459 error = 1;
9460 line = __LINE__;
9461 DBUG_VOID_RETURN;
9462 case UtilPrepareRef::PREPARE_SEIZE_ERROR:
9463 jam();
9464 error = 748;
9465 line = __LINE__;
9466 DBUG_VOID_RETURN;
9467 case UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR:
9468 jam();
9469 error = 1;
9470 line = __LINE__;
9471 DBUG_VOID_RETURN;
9472 case UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR:
9473 jam();
9474 error = 1;
9475 line = __LINE__;
9476 DBUG_VOID_RETURN;
9477 case UtilPrepareRef::DICT_TAB_INFO_ERROR:
9478 jam();
9479 error = 1;
9480 line = __LINE__;
9481 DBUG_VOID_RETURN;
9482 case UtilPrepareRef::MISSING_PROPERTIES_SECTION:
9483 jam();
9484 error = 1;
9485 line = __LINE__;
9486 DBUG_VOID_RETURN;
9487 default:
9488 jam();
9489 error = 1;
9490 line = __LINE__;
9491 DBUG_VOID_RETURN;
9492 }
9493 DBUG_VOID_RETURN;
9494 }
9495
9496 void
createEventUTIL_PREPARE(Signal * signal,Uint32 callbackData,Uint32 returnCode)9497 Dbdict::createEventUTIL_PREPARE(Signal* signal,
9498 Uint32 callbackData,
9499 Uint32 returnCode)
9500 {
9501 jam();
9502 EVENT_TRACE;
9503 if (returnCode == 0) {
9504 UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
9505 OpCreateEventPtr evntRecPtr;
9506 jam();
9507 evntRecPtr.i = req->getSenderData();
9508 const Uint32 prepareId = req->getPrepareId();
9509
9510 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
9511
9512 Callback c = { safe_cast(&Dbdict::createEventUTIL_EXECUTE), 0 };
9513
9514 switch (evntRecPtr.p->m_requestType) {
9515 case CreateEvntReq::RT_USER_GET:
9516 jam();
9517 executeTransEventSysTable(&c, signal,
9518 evntRecPtr.i, evntRecPtr.p->m_eventRec,
9519 prepareId, UtilPrepareReq::Read);
9520 break;
9521 case CreateEvntReq::RT_USER_CREATE:
9522 {
9523 evntRecPtr.p->m_eventRec.EVENT_TYPE =
9524 evntRecPtr.p->m_request.getEventType() | evntRecPtr.p->m_request.getReportFlags();
9525 evntRecPtr.p->m_eventRec.TABLEID = evntRecPtr.p->m_request.getTableId();
9526 evntRecPtr.p->m_eventRec.TABLEVERSION=evntRecPtr.p->m_request.getTableVersion();
9527 AttributeMask m = evntRecPtr.p->m_request.getAttrListBitmask();
9528 memcpy(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK, &m,
9529 sizeof(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK));
9530 evntRecPtr.p->m_eventRec.SUBID = evntRecPtr.p->m_request.getEventId();
9531 evntRecPtr.p->m_eventRec.SUBKEY = evntRecPtr.p->m_request.getEventKey();
9532 DBUG_PRINT("info",
9533 ("CREATE: event name: %s table name: %s table id: %u table version: %u",
9534 evntRecPtr.p->m_eventRec.NAME,
9535 evntRecPtr.p->m_eventRec.TABLE_NAME,
9536 evntRecPtr.p->m_eventRec.TABLEID,
9537 evntRecPtr.p->m_eventRec.TABLEVERSION));
9538
9539 }
9540 jam();
9541 executeTransEventSysTable(&c, signal,
9542 evntRecPtr.i, evntRecPtr.p->m_eventRec,
9543 prepareId, UtilPrepareReq::Insert);
9544 break;
9545 default:
9546 #ifdef EVENT_DEBUG
9547 printf("type = %d\n", evntRecPtr.p->m_requestType);
9548 printf("bet type = %d\n", CreateEvntReq::RT_USER_GET);
9549 printf("create type = %d\n", CreateEvntReq::RT_USER_CREATE);
9550 #endif
9551 ndbrequire(false);
9552 }
9553 } else { // returnCode != 0
9554 UtilPrepareRef* const ref = (UtilPrepareRef*)signal->getDataPtr();
9555
9556 const UtilPrepareRef::ErrorCode errorCode =
9557 (UtilPrepareRef::ErrorCode)ref->getErrorCode();
9558
9559 OpCreateEventPtr evntRecPtr;
9560 evntRecPtr.i = ref->getSenderData();
9561 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
9562
9563 interpretUtilPrepareErrorCode(errorCode, evntRecPtr.p->m_errorCode,
9564 evntRecPtr.p->m_errorLine);
9565 evntRecPtr.p->m_errorNode = reference();
9566
9567 createEvent_sendReply(signal, evntRecPtr);
9568 }
9569 }
9570
executeTransEventSysTable(Callback * pcallback,Signal * signal,const Uint32 ptrI,sysTab_NDBEVENTS_0 & m_eventRec,const Uint32 prepareId,UtilPrepareReq::OperationTypeValue prepReq)9571 void Dbdict::executeTransEventSysTable(Callback *pcallback, Signal *signal,
9572 const Uint32 ptrI,
9573 sysTab_NDBEVENTS_0& m_eventRec,
9574 const Uint32 prepareId,
9575 UtilPrepareReq::OperationTypeValue prepReq)
9576 {
9577 jam();
9578 const Uint32 noAttr = EVENT_SYSTEM_TABLE_LENGTH;
9579 Uint32 total_len = 0;
9580
9581 Uint32* attrHdr = signal->theData + 25;
9582 Uint32* attrPtr = attrHdr;
9583
9584 Uint32 id=0;
9585 // attribute 0 event name: Primary Key
9586 {
9587 AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]);
9588 total_len += sysTab_NDBEVENTS_0_szs[id];
9589 attrPtr++; id++;
9590 }
9591
9592 switch (prepReq) {
9593 case UtilPrepareReq::Read:
9594 jam();
9595 EVENT_TRACE;
9596 // no more
9597 while ( id < noAttr )
9598 AttributeHeader::init(attrPtr++, id++, 0);
9599 ndbrequire(id == (Uint32) noAttr);
9600 break;
9601 case UtilPrepareReq::Insert:
9602 jam();
9603 EVENT_TRACE;
9604 while ( id < noAttr ) {
9605 AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]);
9606 total_len += sysTab_NDBEVENTS_0_szs[id];
9607 attrPtr++; id++;
9608 }
9609 ndbrequire(id == (Uint32) noAttr);
9610 break;
9611 case UtilPrepareReq::Delete:
9612 ndbrequire(id == 1);
9613 break;
9614 default:
9615 ndbrequire(false);
9616 }
9617
9618 LinearSectionPtr headerPtr;
9619 LinearSectionPtr dataPtr;
9620
9621 headerPtr.p = attrHdr;
9622 headerPtr.sz = noAttr;
9623
9624 dataPtr.p = (Uint32*)&m_eventRec;
9625 dataPtr.sz = total_len/4;
9626
9627 ndbrequire((total_len == sysTab_NDBEVENTS_0_szs[0]) ||
9628 (total_len == sizeof(sysTab_NDBEVENTS_0)));
9629
9630 #if 0
9631 printf("Header size %u\n", headerPtr.sz);
9632 for(int i = 0; i < (int)headerPtr.sz; i++)
9633 printf("H'%.8x ", attrHdr[i]);
9634 printf("\n");
9635
9636 printf("Data size %u\n", dataPtr.sz);
9637 for(int i = 0; i < (int)dataPtr.sz; i++)
9638 printf("H'%.8x ", dataPage[i]);
9639 printf("\n");
9640 #endif
9641
9642 executeTransaction(pcallback, signal,
9643 ptrI,
9644 prepareId,
9645 id,
9646 headerPtr,
9647 dataPtr);
9648 }
9649
executeTransaction(Callback * pcallback,Signal * signal,Uint32 senderData,Uint32 prepareId,Uint32 noAttr,LinearSectionPtr headerPtr,LinearSectionPtr dataPtr)9650 void Dbdict::executeTransaction(Callback *pcallback,
9651 Signal* signal,
9652 Uint32 senderData,
9653 Uint32 prepareId,
9654 Uint32 noAttr,
9655 LinearSectionPtr headerPtr,
9656 LinearSectionPtr dataPtr)
9657 {
9658 jam();
9659 EVENT_TRACE;
9660
9661 UtilExecuteReq * utilExecuteReq =
9662 (UtilExecuteReq *)signal->getDataPtrSend();
9663
9664 utilExecuteReq->setSenderRef(reference());
9665 utilExecuteReq->setSenderData(senderData);
9666 utilExecuteReq->setPrepareId(prepareId);
9667 utilExecuteReq->setReleaseFlag(); // must be done after setting prepareId
9668
9669 #if 0
9670 printf("Header size %u\n", headerPtr.sz);
9671 for(int i = 0; i < (int)headerPtr.sz; i++)
9672 printf("H'%.8x ", headerBuffer[i]);
9673 printf("\n");
9674
9675 printf("Data size %u\n", dataPtr.sz);
9676 for(int i = 0; i < (int)dataPtr.sz; i++)
9677 printf("H'%.8x ", dataBuffer[i]);
9678 printf("\n");
9679 #endif
9680
9681 struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections];
9682 sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = headerPtr.p;
9683 sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr;
9684 sectionsPtr[UtilExecuteReq::DATA_SECTION].p = dataPtr.p;
9685 sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataPtr.sz;
9686
9687 sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal,
9688 UtilExecuteReq::SignalLength, JBB,
9689 sectionsPtr, UtilExecuteReq::NoOfSections);
9690 }
9691
parseReadEventSys(Signal * signal,sysTab_NDBEVENTS_0 & m_eventRec)9692 void Dbdict::parseReadEventSys(Signal* signal, sysTab_NDBEVENTS_0& m_eventRec)
9693 {
9694 SegmentedSectionPtr headerPtr, dataPtr;
9695 jam();
9696 signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
9697 SectionReader headerReader(headerPtr, getSectionSegmentPool());
9698
9699 signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
9700 SectionReader dataReader(dataPtr, getSectionSegmentPool());
9701
9702 AttributeHeader header;
9703 Uint32 *dst = (Uint32*)&m_eventRec;
9704
9705 for (int i = 0; i < EVENT_SYSTEM_TABLE_LENGTH; i++) {
9706 headerReader.getWord((Uint32 *)&header);
9707 int sz = header.getDataSize();
9708 for (int i=0; i < sz; i++)
9709 dataReader.getWord(dst++);
9710 }
9711
9712 ndbrequire( ((char*)dst-(char*)&m_eventRec) == sizeof(m_eventRec) );
9713
9714 releaseSections(signal);
9715 }
9716
createEventUTIL_EXECUTE(Signal * signal,Uint32 callbackData,Uint32 returnCode)9717 void Dbdict::createEventUTIL_EXECUTE(Signal *signal,
9718 Uint32 callbackData,
9719 Uint32 returnCode)
9720 {
9721 jam();
9722 EVENT_TRACE;
9723 if (returnCode == 0) {
9724 // Entry into system table all set
9725 UtilExecuteConf* const conf = (UtilExecuteConf*)signal->getDataPtr();
9726 jam();
9727 OpCreateEventPtr evntRecPtr;
9728 evntRecPtr.i = conf->getSenderData();
9729
9730 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
9731 OpCreateEvent *evntRec = evntRecPtr.p;
9732
9733 switch (evntRec->m_requestType) {
9734 case CreateEvntReq::RT_USER_GET: {
9735 parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
9736
9737 evntRec->m_request.setEventType(evntRecPtr.p->m_eventRec.EVENT_TYPE);
9738 evntRec->m_request.setReportFlags(evntRecPtr.p->m_eventRec.EVENT_TYPE);
9739 evntRec->m_request.setTableId(evntRecPtr.p->m_eventRec.TABLEID);
9740 evntRec->m_request.setTableVersion(evntRecPtr.p->m_eventRec.TABLEVERSION);
9741 evntRec->m_request.setAttrListBitmask(*(AttributeMask*)
9742 evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK);
9743 evntRec->m_request.setEventId(evntRecPtr.p->m_eventRec.SUBID);
9744 evntRec->m_request.setEventKey(evntRecPtr.p->m_eventRec.SUBKEY);
9745
9746 DBUG_PRINT("info",
9747 ("GET: event name: %s table name: %s table id: %u table version: %u",
9748 evntRecPtr.p->m_eventRec.NAME,
9749 evntRecPtr.p->m_eventRec.TABLE_NAME,
9750 evntRecPtr.p->m_eventRec.TABLEID,
9751 evntRecPtr.p->m_eventRec.TABLEVERSION));
9752
9753 // find table id for event table
9754 DictObject* obj_ptr_p = get_object(evntRecPtr.p->m_eventRec.TABLE_NAME);
9755 if(!obj_ptr_p){
9756 jam();
9757 evntRecPtr.p->m_errorCode = 723;
9758 evntRecPtr.p->m_errorLine = __LINE__;
9759 evntRecPtr.p->m_errorNode = reference();
9760
9761 createEvent_sendReply(signal, evntRecPtr);
9762 return;
9763 }
9764
9765 TableRecordPtr tablePtr;
9766 c_tableRecordPool.getPtr(tablePtr, obj_ptr_p->m_id);
9767 evntRec->m_request.setTableId(tablePtr.p->tableId);
9768 evntRec->m_request.setTableVersion(tablePtr.p->tableVersion);
9769
9770 createEventComplete_RT_USER_GET(signal, evntRecPtr);
9771 return;
9772 }
9773 case CreateEvntReq::RT_USER_CREATE: {
9774 #ifdef EVENT_DEBUG
9775 printf("create type = %d\n", CreateEvntReq::RT_USER_CREATE);
9776 #endif
9777 jam();
9778 createEventComplete_RT_USER_CREATE(signal, evntRecPtr);
9779 return;
9780 }
9781 break;
9782 default:
9783 ndbrequire(false);
9784 }
9785 } else { // returnCode != 0
9786 UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
9787 OpCreateEventPtr evntRecPtr;
9788 evntRecPtr.i = ref->getSenderData();
9789 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
9790 jam();
9791 evntRecPtr.p->m_errorNode = reference();
9792 evntRecPtr.p->m_errorLine = __LINE__;
9793
9794 switch (ref->getErrorCode()) {
9795 case UtilExecuteRef::TCError:
9796 switch (ref->getTCErrorCode()) {
9797 case ZNOT_FOUND:
9798 jam();
9799 evntRecPtr.p->m_errorCode = 4710;
9800 break;
9801 case ZALREADYEXIST:
9802 jam();
9803 evntRecPtr.p->m_errorCode = 746;
9804 break;
9805 default:
9806 jam();
9807 evntRecPtr.p->m_errorCode = ref->getTCErrorCode();
9808 break;
9809 }
9810 break;
9811 default:
9812 jam();
9813 evntRecPtr.p->m_errorCode = ref->getErrorCode();
9814 break;
9815 }
9816
9817 createEvent_sendReply(signal, evntRecPtr);
9818 }
9819 }
9820
9821 /***********************************************************************
9822 *
9823 * NdbEventOperation, reading systable, creating event in suma
9824 *
9825 */
9826
9827 void
createEvent_RT_USER_GET(Signal * signal,OpCreateEventPtr evntRecPtr)9828 Dbdict::createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
9829 jam();
9830 EVENT_TRACE;
9831 #ifdef EVENT_PH2_DEBUG
9832 ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REQ::RT_USER_GET evntRecPtr.i = (%d), ref = %u", evntRecPtr.i, evntRecPtr.p->m_request.getUserRef());
9833 #endif
9834
9835 SegmentedSectionPtr ssPtr;
9836
9837 signal->getSection(ssPtr, 0);
9838
9839 SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
9840 #ifdef EVENT_DEBUG
9841 r0.printAll(ndbout);
9842 #endif
9843 if ((!r0.first()) ||
9844 (r0.getValueType() != SimpleProperties::StringValue) ||
9845 (r0.getValueLen() <= 0)) {
9846 jam();
9847 releaseSections(signal);
9848
9849 evntRecPtr.p->m_errorCode = 1;
9850 evntRecPtr.p->m_errorLine = __LINE__;
9851 evntRecPtr.p->m_errorNode = reference();
9852
9853 createEvent_sendReply(signal, evntRecPtr);
9854 return;
9855 }
9856
9857 r0.getString(evntRecPtr.p->m_eventRec.NAME);
9858 int len = strlen(evntRecPtr.p->m_eventRec.NAME);
9859 memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
9860
9861 releaseSections(signal);
9862
9863 Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
9864
9865 prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
9866 UtilPrepareReq::Read);
9867 /*
9868 * Will read systable and fill an OpCreateEventPtr
9869 * and return below
9870 */
9871 }
9872
9873 void
createEventComplete_RT_USER_GET(Signal * signal,OpCreateEventPtr evntRecPtr)9874 Dbdict::createEventComplete_RT_USER_GET(Signal* signal,
9875 OpCreateEventPtr evntRecPtr){
9876 jam();
9877
9878 // Send to oneself and the other DICT's
9879 CreateEvntReq * req = (CreateEvntReq *)signal->getDataPtrSend();
9880
9881 *req = evntRecPtr.p->m_request;
9882 req->senderRef = reference();
9883 req->senderData = evntRecPtr.i;
9884
9885 req->addRequestFlag(CreateEvntReq::RT_DICT_AFTER_GET);
9886
9887 #ifdef EVENT_PH2_DEBUG
9888 ndbout_c("DBDICT(Coordinator) sending GSN_CREATE_EVNT_REQ::RT_DICT_AFTER_GET to DBDICT participants evntRecPtr.i = (%d)", evntRecPtr.i);
9889 #endif
9890
9891 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
9892 RequestTracker & p = evntRecPtr.p->m_reqTracker;
9893 if (!p.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF,
9894 evntRecPtr.i))
9895 {
9896 jam();
9897 evntRecPtr.p->m_errorCode = 701;
9898 createEvent_sendReply(signal, evntRecPtr);
9899 return;
9900 }
9901
9902 sendSignal(rg, GSN_CREATE_EVNT_REQ, signal, CreateEvntReq::SignalLength, JBB);
9903 }
9904
9905 void
createEvent_nodeFailCallback(Signal * signal,Uint32 eventRecPtrI,Uint32 returnCode)9906 Dbdict::createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI,
9907 Uint32 returnCode){
9908 OpCreateEventPtr evntRecPtr;
9909 c_opCreateEvent.getPtr(evntRecPtr, eventRecPtrI);
9910 createEvent_sendReply(signal, evntRecPtr);
9911 }
9912
execCREATE_EVNT_REF(Signal * signal)9913 void Dbdict::execCREATE_EVNT_REF(Signal* signal)
9914 {
9915 jamEntry();
9916 EVENT_TRACE;
9917 CreateEvntRef * const ref = (CreateEvntRef *)signal->getDataPtr();
9918 OpCreateEventPtr evntRecPtr;
9919
9920 evntRecPtr.i = ref->getUserData();
9921
9922 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
9923
9924 #ifdef EVENT_PH2_DEBUG
9925 ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REF evntRecPtr.i = (%d)", evntRecPtr.i);
9926 #endif
9927
9928 if (ref->errorCode == CreateEvntRef::NF_FakeErrorREF){
9929 jam();
9930 evntRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(ref->senderRef));
9931 } else {
9932 jam();
9933 evntRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(ref->senderRef));
9934 }
9935 createEvent_sendReply(signal, evntRecPtr);
9936
9937 return;
9938 }
9939
execCREATE_EVNT_CONF(Signal * signal)9940 void Dbdict::execCREATE_EVNT_CONF(Signal* signal)
9941 {
9942 jamEntry();
9943 EVENT_TRACE;
9944 CreateEvntConf * const conf = (CreateEvntConf *)signal->getDataPtr();
9945 OpCreateEventPtr evntRecPtr;
9946
9947 evntRecPtr.i = conf->getUserData();
9948
9949 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
9950
9951 #ifdef EVENT_PH2_DEBUG
9952 ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_CONF evntRecPtr.i = (%d)", evntRecPtr.i);
9953 #endif
9954
9955 evntRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(conf->senderRef));
9956
9957 // we will only have a valid tablename if it the master DICT sending this
9958 // but that's ok
9959 LinearSectionPtr ptr[1];
9960 ptr[0].p = (Uint32 *)evntRecPtr.p->m_eventRec.TABLE_NAME;
9961 ptr[0].sz =
9962 (strlen(evntRecPtr.p->m_eventRec.TABLE_NAME)+4)/4; // to make sure we have a null
9963
9964 createEvent_sendReply(signal, evntRecPtr, ptr, 1);
9965
9966 return;
9967 }
9968
9969 /************************************************
9970 *
9971 * Participant stuff
9972 *
9973 */
9974
9975 void
createEvent_RT_DICT_AFTER_GET(Signal * signal,OpCreateEventPtr evntRecPtr)9976 Dbdict::createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
9977 DBUG_ENTER("Dbdict::createEvent_RT_DICT_AFTER_GET");
9978 jam();
9979 evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
9980
9981 #ifdef EVENT_PH2_DEBUG
9982 ndbout_c("DBDICT(Participant) got CREATE_EVNT_REQ::RT_DICT_AFTER_GET evntRecPtr.i = (%d)", evntRecPtr.i);
9983 #endif
9984
9985 // the signal comes from the DICT block that got the first user request!
9986 // This code runs on all DICT nodes, including oneself
9987
9988 // Seize a Create Event record, the Coordinator will now have two seized
9989 // but that's ok, it's like a recursion
9990
9991 CRASH_INSERTION2(6009, getOwnNodeId() != c_masterNodeId);
9992
9993 SubCreateReq * sumaReq = (SubCreateReq *)signal->getDataPtrSend();
9994
9995 sumaReq->senderRef = reference(); // reference to DICT
9996 sumaReq->senderData = evntRecPtr.i;
9997 sumaReq->subscriptionId = evntRecPtr.p->m_request.getEventId();
9998 sumaReq->subscriptionKey = evntRecPtr.p->m_request.getEventKey();
9999 sumaReq->subscriptionType = SubCreateReq::TableEvent;
10000 if (evntRecPtr.p->m_request.getReportAll())
10001 sumaReq->subscriptionType|= SubCreateReq::ReportAll;
10002 if (evntRecPtr.p->m_request.getReportSubscribe())
10003 sumaReq->subscriptionType|= SubCreateReq::ReportSubscribe;
10004 sumaReq->tableId = evntRecPtr.p->m_request.getTableId();
10005
10006 #ifdef EVENT_PH2_DEBUG
10007 ndbout_c("sending GSN_SUB_CREATE_REQ");
10008 #endif
10009
10010 sendSignal(SUMA_REF, GSN_SUB_CREATE_REQ, signal,
10011 SubCreateReq::SignalLength, JBB);
10012 DBUG_VOID_RETURN;
10013 }
10014
execSUB_CREATE_REF(Signal * signal)10015 void Dbdict::execSUB_CREATE_REF(Signal* signal)
10016 {
10017 jamEntry();
10018 DBUG_ENTER("Dbdict::execSUB_CREATE_REF");
10019
10020 SubCreateRef * const ref = (SubCreateRef *)signal->getDataPtr();
10021 OpCreateEventPtr evntRecPtr;
10022
10023 evntRecPtr.i = ref->senderData;
10024 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
10025
10026 if (ref->errorCode == 1415) {
10027 jam();
10028 createEvent_sendReply(signal, evntRecPtr);
10029 DBUG_VOID_RETURN;
10030 }
10031
10032 if (ref->errorCode)
10033 {
10034 evntRecPtr.p->m_errorCode = ref->errorCode;
10035 evntRecPtr.p->m_errorLine = __LINE__;
10036 }
10037 else
10038 {
10039 evntRecPtr.p->m_errorCode = 1;
10040 evntRecPtr.p->m_errorLine = __LINE__;
10041 }
10042 evntRecPtr.p->m_errorNode = reference();
10043
10044 createEvent_sendReply(signal, evntRecPtr);
10045 DBUG_VOID_RETURN;
10046 }
10047
execSUB_CREATE_CONF(Signal * signal)10048 void Dbdict::execSUB_CREATE_CONF(Signal* signal)
10049 {
10050 jamEntry();
10051 DBUG_ENTER("Dbdict::execSUB_CREATE_CONF");
10052 EVENT_TRACE;
10053
10054 SubCreateConf * const sumaConf = (SubCreateConf *)signal->getDataPtr();
10055 OpCreateEventPtr evntRecPtr;
10056 evntRecPtr.i = sumaConf->senderData;
10057 ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
10058
10059 createEvent_sendReply(signal, evntRecPtr);
10060
10061 DBUG_VOID_RETURN;
10062 }
10063
10064 /****************************************************
10065 *
10066 * common create reply method
10067 *
10068 *******************************************************/
10069
createEvent_sendReply(Signal * signal,OpCreateEventPtr evntRecPtr,LinearSectionPtr * ptr,int noLSP)10070 void Dbdict::createEvent_sendReply(Signal* signal,
10071 OpCreateEventPtr evntRecPtr,
10072 LinearSectionPtr *ptr, int noLSP)
10073 {
10074 jam();
10075 EVENT_TRACE;
10076
10077 // check if we're ready to sent reply
10078 // if we are the master dict we might be waiting for conf/ref
10079
10080 if (!evntRecPtr.p->m_reqTracker.done()) {
10081 jam();
10082 return; // there's more to come
10083 }
10084
10085 if (evntRecPtr.p->m_reqTracker.hasRef()) {
10086 ptr = NULL; // we don't want to return anything if there's an error
10087 if (!evntRecPtr.p->hasError()) {
10088 evntRecPtr.p->m_errorCode = 1;
10089 evntRecPtr.p->m_errorLine = __LINE__;
10090 evntRecPtr.p->m_errorNode = reference();
10091 jam();
10092 } else
10093 jam();
10094 }
10095
10096 // reference to API if master DICT
10097 // else reference to master DICT
10098 Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
10099 Uint32 signalLength;
10100 Uint32 gsn;
10101
10102 if (evntRecPtr.p->hasError()) {
10103 jam();
10104 EVENT_TRACE;
10105 CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
10106
10107 ret->setEventId(evntRecPtr.p->m_request.getEventId());
10108 ret->setEventKey(evntRecPtr.p->m_request.getEventKey());
10109 ret->setUserData(evntRecPtr.p->m_request.getUserData());
10110 ret->senderRef = reference();
10111 ret->setTableId(evntRecPtr.p->m_request.getTableId());
10112 ret->setTableVersion(evntRecPtr.p->m_request.getTableVersion());
10113 ret->setEventType(evntRecPtr.p->m_request.getEventType());
10114 ret->setRequestType(evntRecPtr.p->m_request.getRequestType());
10115
10116 ret->setErrorCode(evntRecPtr.p->m_errorCode);
10117 ret->setErrorLine(evntRecPtr.p->m_errorLine);
10118 ret->setErrorNode(evntRecPtr.p->m_errorNode);
10119
10120 signalLength = CreateEvntRef::SignalLength;
10121 #ifdef EVENT_PH2_DEBUG
10122 ndbout_c("DBDICT sending GSN_CREATE_EVNT_REF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
10123 ndbout_c("errorCode = %u", evntRecPtr.p->m_errorCode);
10124 ndbout_c("errorLine = %u", evntRecPtr.p->m_errorLine);
10125 #endif
10126 gsn = GSN_CREATE_EVNT_REF;
10127
10128 } else {
10129 jam();
10130 EVENT_TRACE;
10131 CreateEvntConf * evntConf = (CreateEvntConf *)signal->getDataPtrSend();
10132
10133 evntConf->setEventId(evntRecPtr.p->m_request.getEventId());
10134 evntConf->setEventKey(evntRecPtr.p->m_request.getEventKey());
10135 evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
10136 evntConf->senderRef = reference();
10137 evntConf->setTableId(evntRecPtr.p->m_request.getTableId());
10138 evntConf->setTableVersion(evntRecPtr.p->m_request.getTableVersion());
10139 evntConf->setAttrListBitmask(evntRecPtr.p->m_request.getAttrListBitmask());
10140 evntConf->setEventType(evntRecPtr.p->m_request.getEventType());
10141 evntConf->setRequestType(evntRecPtr.p->m_request.getRequestType());
10142
10143 signalLength = CreateEvntConf::SignalLength;
10144 #ifdef EVENT_PH2_DEBUG
10145 ndbout_c("DBDICT sending GSN_CREATE_EVNT_CONF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
10146 #endif
10147 gsn = GSN_CREATE_EVNT_CONF;
10148 }
10149
10150 if (ptr) {
10151 jam();
10152 sendSignal(senderRef, gsn, signal, signalLength, JBB, ptr, noLSP);
10153 } else {
10154 jam();
10155 sendSignal(senderRef, gsn, signal, signalLength, JBB);
10156 }
10157
10158 c_opCreateEvent.release(evntRecPtr);
10159 }
10160
10161 /*************************************************************/
10162
10163 /********************************************************************
10164 *
10165 * Start event
10166 *
10167 *******************************************************************/
10168
execSUB_START_REQ(Signal * signal)10169 void Dbdict::execSUB_START_REQ(Signal* signal)
10170 {
10171 jamEntry();
10172
10173 Uint32 origSenderRef = signal->senderBlockRef();
10174
10175 if (refToBlock(origSenderRef) != DBDICT &&
10176 getOwnNodeId() != c_masterNodeId)
10177 {
10178 /*
10179 * Coordinator but not master
10180 */
10181 SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
10182 ref->senderRef = reference();
10183 ref->errorCode = SubStartRef::NotMaster;
10184 ref->m_masterNodeId = c_masterNodeId;
10185 sendSignal(origSenderRef, GSN_SUB_START_REF, signal,
10186 SubStartRef::SignalLength2, JBB);
10187 return;
10188 }
10189 OpSubEventPtr subbPtr;
10190 Uint32 errCode = 0;
10191
10192 DictLockPtr loopPtr;
10193 if (c_dictLockQueue.first(loopPtr) &&
10194 loopPtr.p->lt->lockType == DictLockReq::NodeRestartLock)
10195 {
10196 jam();
10197 errCode = 1405;
10198 goto busy;
10199 }
10200
10201 if (!c_opSubEvent.seize(subbPtr)) {
10202 errCode = SubStartRef::Busy;
10203 busy:
10204 jam();
10205 SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
10206
10207 { // fix
10208 Uint32 subcriberRef = ((SubStartReq*)signal->getDataPtr())->subscriberRef;
10209 ref->subscriberRef = subcriberRef;
10210 }
10211 jam();
10212 // ret->setErrorCode(SubStartRef::SeizeError);
10213 // ret->setErrorLine(__LINE__);
10214 // ret->setErrorNode(reference());
10215 ref->senderRef = reference();
10216 ref->errorCode = errCode;
10217
10218 sendSignal(origSenderRef, GSN_SUB_START_REF, signal,
10219 SubStartRef::SignalLength2, JBB);
10220 return;
10221 }
10222
10223 {
10224 const SubStartReq* req = (SubStartReq*) signal->getDataPtr();
10225 subbPtr.p->m_senderRef = req->senderRef;
10226 subbPtr.p->m_senderData = req->senderData;
10227 subbPtr.p->m_errorCode = 0;
10228 }
10229
10230 if (refToBlock(origSenderRef) != DBDICT) {
10231 /*
10232 * Coordinator
10233 */
10234 jam();
10235
10236 subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
10237 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
10238 RequestTracker & p = subbPtr.p->m_reqTracker;
10239 if (!p.init<SubStartRef>(c_counterMgr, rg, GSN_SUB_START_REF, subbPtr.i))
10240 {
10241 c_opSubEvent.release(subbPtr);
10242 errCode = SubStartRef::Busy;
10243 goto busy;
10244 }
10245
10246 SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
10247
10248 req->senderRef = reference();
10249 req->senderData = subbPtr.i;
10250
10251 #ifdef EVENT_PH3_DEBUG
10252 ndbout_c("DBDICT(Coordinator) sending GSN_SUB_START_REQ to DBDICT participants subbPtr.i = (%d)", subbPtr.i);
10253 #endif
10254
10255 sendSignal(rg, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
10256 return;
10257 }
10258 /*
10259 * Participant
10260 */
10261 ndbrequire(refToBlock(origSenderRef) == DBDICT);
10262
10263 CRASH_INSERTION(6007);
10264
10265 {
10266 SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
10267
10268 req->senderRef = reference();
10269 req->senderData = subbPtr.i;
10270
10271 #ifdef EVENT_PH3_DEBUG
10272 ndbout_c("DBDICT(Participant) sending GSN_SUB_START_REQ to SUMA subbPtr.i = (%d)", subbPtr.i);
10273 #endif
10274 sendSignal(SUMA_REF, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
10275 }
10276 }
10277
execSUB_START_REF(Signal * signal)10278 void Dbdict::execSUB_START_REF(Signal* signal)
10279 {
10280 jamEntry();
10281
10282 const SubStartRef* ref = (SubStartRef*) signal->getDataPtr();
10283 Uint32 senderRef = ref->senderRef;
10284 Uint32 err = ref->errorCode;
10285
10286 OpSubEventPtr subbPtr;
10287 c_opSubEvent.getPtr(subbPtr, ref->senderData);
10288
10289 if (refToBlock(senderRef) == SUMA) {
10290 /*
10291 * Participant
10292 */
10293 jam();
10294
10295 #ifdef EVENT_PH3_DEBUG
10296 ndbout_c("DBDICT(Participant) got GSN_SUB_START_REF = (%d)", subbPtr.i);
10297 #endif
10298
10299 jam();
10300 SubStartRef* ref = (SubStartRef*) signal->getDataPtrSend();
10301 ref->senderRef = reference();
10302 ref->senderData = subbPtr.p->m_senderData;
10303 ref->errorCode = err;
10304 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
10305 signal, SubStartRef::SignalLength2, JBB);
10306 c_opSubEvent.release(subbPtr);
10307 return;
10308 }
10309 /*
10310 * Coordinator
10311 */
10312 ndbrequire(refToBlock(senderRef) == DBDICT);
10313 #ifdef EVENT_PH3_DEBUG
10314 ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_REF = (%d)", subbPtr.i);
10315 #endif
10316 if (err == SubStartRef::NF_FakeErrorREF){
10317 jam();
10318 subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
10319 } else {
10320 jam();
10321 if (subbPtr.p->m_errorCode == 0)
10322 {
10323 subbPtr.p->m_errorCode= err ? err : 1;
10324 }
10325 subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
10326 }
10327 completeSubStartReq(signal,subbPtr.i,0);
10328 }
10329
execSUB_START_CONF(Signal * signal)10330 void Dbdict::execSUB_START_CONF(Signal* signal)
10331 {
10332 jamEntry();
10333
10334 const SubStartConf* conf = (SubStartConf*) signal->getDataPtr();
10335 Uint32 senderRef = conf->senderRef;
10336
10337 OpSubEventPtr subbPtr;
10338 c_opSubEvent.getPtr(subbPtr, conf->senderData);
10339
10340 if (refToBlock(senderRef) == SUMA) {
10341 /*
10342 * Participant
10343 */
10344 jam();
10345 SubStartConf* conf = (SubStartConf*) signal->getDataPtrSend();
10346
10347 #ifdef EVENT_PH3_DEBUG
10348 ndbout_c("DBDICT(Participant) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
10349 #endif
10350
10351 conf->senderRef = reference();
10352 conf->senderData = subbPtr.p->m_senderData;
10353
10354 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
10355 signal, SubStartConf::SignalLength2, JBB);
10356 c_opSubEvent.release(subbPtr);
10357 return;
10358 }
10359 /*
10360 * Coordinator
10361 */
10362 ndbrequire(refToBlock(senderRef) == DBDICT);
10363 #ifdef EVENT_PH3_DEBUG
10364 ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
10365 #endif
10366 subbPtr.p->m_sub_start_conf = *conf;
10367 subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
10368 completeSubStartReq(signal,subbPtr.i,0);
10369 }
10370
10371 /*
10372 * Coordinator
10373 */
completeSubStartReq(Signal * signal,Uint32 ptrI,Uint32 returnCode)10374 void Dbdict::completeSubStartReq(Signal* signal,
10375 Uint32 ptrI,
10376 Uint32 returnCode){
10377 jam();
10378
10379 OpSubEventPtr subbPtr;
10380 c_opSubEvent.getPtr(subbPtr, ptrI);
10381
10382 if (!subbPtr.p->m_reqTracker.done()){
10383 jam();
10384 return;
10385 }
10386
10387 if (subbPtr.p->m_reqTracker.hasRef()) {
10388 jam();
10389 #ifdef EVENT_DEBUG
10390 ndbout_c("SUB_START_REF");
10391 #endif
10392 SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
10393 ref->senderRef = reference();
10394 ref->errorCode = subbPtr.p->m_errorCode;
10395 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
10396 signal, SubStartRef::SignalLength, JBB);
10397 if (subbPtr.p->m_reqTracker.hasConf()) {
10398 // stopStartedNodes(signal);
10399 }
10400 c_opSubEvent.release(subbPtr);
10401 return;
10402 }
10403 #ifdef EVENT_DEBUG
10404 ndbout_c("SUB_START_CONF");
10405 #endif
10406
10407 SubStartConf* conf = (SubStartConf*)signal->getDataPtrSend();
10408 * conf = subbPtr.p->m_sub_start_conf;
10409 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
10410 signal, SubStartConf::SignalLength, JBB);
10411 c_opSubEvent.release(subbPtr);
10412 }
10413
10414 /********************************************************************
10415 *
10416 * Stop event
10417 *
10418 *******************************************************************/
10419
execSUB_STOP_REQ(Signal * signal)10420 void Dbdict::execSUB_STOP_REQ(Signal* signal)
10421 {
10422 jamEntry();
10423
10424 Uint32 origSenderRef = signal->senderBlockRef();
10425
10426 if (refToBlock(origSenderRef) != DBDICT &&
10427 getOwnNodeId() != c_masterNodeId)
10428 {
10429 /*
10430 * Coordinator but not master
10431 */
10432 SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
10433 ref->senderRef = reference();
10434 ref->errorCode = SubStopRef::NotMaster;
10435 ref->m_masterNodeId = c_masterNodeId;
10436 sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal,
10437 SubStopRef::SignalLength2, JBB);
10438 return;
10439 }
10440 OpSubEventPtr subbPtr;
10441 Uint32 errCode = 0;
10442 if (!c_opSubEvent.seize(subbPtr)) {
10443 errCode = SubStopRef::Busy;
10444 busy:
10445 SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
10446 jam();
10447 // ret->setErrorCode(SubStartRef::SeizeError);
10448 // ret->setErrorLine(__LINE__);
10449 // ret->setErrorNode(reference());
10450 ref->senderRef = reference();
10451 ref->errorCode = errCode;
10452
10453 sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal,
10454 SubStopRef::SignalLength, JBB);
10455 return;
10456 }
10457
10458 {
10459 const SubStopReq* req = (SubStopReq*) signal->getDataPtr();
10460 subbPtr.p->m_senderRef = req->senderRef;
10461 subbPtr.p->m_senderData = req->senderData;
10462 subbPtr.p->m_errorCode = 0;
10463 }
10464
10465 if (refToBlock(origSenderRef) != DBDICT) {
10466 /*
10467 * Coordinator
10468 */
10469 jam();
10470 #ifdef EVENT_DEBUG
10471 ndbout_c("SUB_STOP_REQ 1");
10472 #endif
10473 subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
10474 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
10475 RequestTracker & p = subbPtr.p->m_reqTracker;
10476 if (!p.init<SubStopRef>(c_counterMgr, rg, GSN_SUB_STOP_REF, subbPtr.i))
10477 {
10478 jam();
10479 c_opSubEvent.release(subbPtr);
10480 errCode = SubStopRef::Busy;
10481 goto busy;
10482 }
10483
10484 SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
10485
10486 req->senderRef = reference();
10487 req->senderData = subbPtr.i;
10488
10489 sendSignal(rg, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
10490 return;
10491 }
10492 /*
10493 * Participant
10494 */
10495 #ifdef EVENT_DEBUG
10496 ndbout_c("SUB_STOP_REQ 2");
10497 #endif
10498 ndbrequire(refToBlock(origSenderRef) == DBDICT);
10499
10500 CRASH_INSERTION(6008);
10501
10502 {
10503 SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
10504
10505 req->senderRef = reference();
10506 req->senderData = subbPtr.i;
10507
10508 sendSignal(SUMA_REF, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
10509 }
10510 }
10511
execSUB_STOP_REF(Signal * signal)10512 void Dbdict::execSUB_STOP_REF(Signal* signal)
10513 {
10514 jamEntry();
10515 const SubStopRef* ref = (SubStopRef*) signal->getDataPtr();
10516 Uint32 senderRef = ref->senderRef;
10517 Uint32 err = ref->errorCode;
10518
10519 OpSubEventPtr subbPtr;
10520 c_opSubEvent.getPtr(subbPtr, ref->senderData);
10521
10522 if (refToBlock(senderRef) == SUMA) {
10523 /*
10524 * Participant
10525 */
10526 jam();
10527 SubStopRef* ref = (SubStopRef*) signal->getDataPtrSend();
10528 ref->senderRef = reference();
10529 ref->senderData = subbPtr.p->m_senderData;
10530 ref->errorCode = err;
10531 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
10532 signal, SubStopRef::SignalLength, JBB);
10533 c_opSubEvent.release(subbPtr);
10534 return;
10535 }
10536 /*
10537 * Coordinator
10538 */
10539 ndbrequire(refToBlock(senderRef) == DBDICT);
10540 if (err == SubStopRef::NF_FakeErrorREF){
10541 jam();
10542 subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
10543 } else {
10544 jam();
10545 if (subbPtr.p->m_errorCode == 0)
10546 {
10547 subbPtr.p->m_errorCode= err ? err : 1;
10548 }
10549 subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
10550 }
10551 completeSubStopReq(signal,subbPtr.i,0);
10552 }
10553
execSUB_STOP_CONF(Signal * signal)10554 void Dbdict::execSUB_STOP_CONF(Signal* signal)
10555 {
10556 jamEntry();
10557
10558 const SubStopConf* conf = (SubStopConf*) signal->getDataPtr();
10559 Uint32 senderRef = conf->senderRef;
10560
10561 OpSubEventPtr subbPtr;
10562 c_opSubEvent.getPtr(subbPtr, conf->senderData);
10563
10564 if (refToBlock(senderRef) == SUMA) {
10565 /*
10566 * Participant
10567 */
10568 jam();
10569 SubStopConf* conf = (SubStopConf*) signal->getDataPtrSend();
10570
10571 conf->senderRef = reference();
10572 conf->senderData = subbPtr.p->m_senderData;
10573
10574 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
10575 signal, SubStopConf::SignalLength, JBB);
10576 c_opSubEvent.release(subbPtr);
10577 return;
10578 }
10579 /*
10580 * Coordinator
10581 */
10582 ndbrequire(refToBlock(senderRef) == DBDICT);
10583 subbPtr.p->m_sub_stop_conf = *conf;
10584 subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
10585 completeSubStopReq(signal,subbPtr.i,0);
10586 }
10587
10588 /*
10589 * Coordinator
10590 */
completeSubStopReq(Signal * signal,Uint32 ptrI,Uint32 returnCode)10591 void Dbdict::completeSubStopReq(Signal* signal,
10592 Uint32 ptrI,
10593 Uint32 returnCode){
10594 OpSubEventPtr subbPtr;
10595 c_opSubEvent.getPtr(subbPtr, ptrI);
10596
10597 if (!subbPtr.p->m_reqTracker.done()){
10598 jam();
10599 return;
10600 }
10601
10602 if (subbPtr.p->m_reqTracker.hasRef()) {
10603 jam();
10604 #ifdef EVENT_DEBUG
10605 ndbout_c("SUB_STOP_REF");
10606 #endif
10607 SubStopRef* ref = (SubStopRef*)signal->getDataPtrSend();
10608
10609 ref->senderRef = reference();
10610 ref->senderData = subbPtr.p->m_senderData;
10611 ref->errorCode = subbPtr.p->m_errorCode;
10612
10613 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
10614 signal, SubStopRef::SignalLength, JBB);
10615 if (subbPtr.p->m_reqTracker.hasConf()) {
10616 // stopStartedNodes(signal);
10617 }
10618 c_opSubEvent.release(subbPtr);
10619 return;
10620 }
10621 #ifdef EVENT_DEBUG
10622 ndbout_c("SUB_STOP_CONF");
10623 #endif
10624 SubStopConf* conf = (SubStopConf*)signal->getDataPtrSend();
10625 * conf = subbPtr.p->m_sub_stop_conf;
10626 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
10627 signal, SubStopConf::SignalLength, JBB);
10628 c_opSubEvent.release(subbPtr);
10629 }
10630
10631 /***************************************************************
10632 * MODULE: Drop event.
10633 *
10634 * Drop event.
10635 *
10636 * TODO
10637 */
10638
10639 void
execDROP_EVNT_REQ(Signal * signal)10640 Dbdict::execDROP_EVNT_REQ(Signal* signal)
10641 {
10642 jamEntry();
10643 DBUG_ENTER("Dbdict::execDROP_EVNT_REQ");
10644
10645 DropEvntReq *req = (DropEvntReq*)signal->getDataPtr();
10646 const Uint32 senderRef = signal->senderBlockRef();
10647 OpDropEventPtr evntRecPtr;
10648
10649 if (refToBlock(senderRef) != DBDICT &&
10650 getOwnNodeId() != c_masterNodeId)
10651 {
10652 jam();
10653 releaseSections(signal);
10654
10655 DropEvntRef * ref = (DropEvntRef *)signal->getDataPtrSend();
10656 ref->setUserRef(reference());
10657 ref->setErrorCode(DropEvntRef::NotMaster);
10658 ref->setErrorLine(__LINE__);
10659 ref->setErrorNode(reference());
10660 ref->setMasterNode(c_masterNodeId);
10661 sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
10662 DropEvntRef::SignalLength2, JBB);
10663 return;
10664 }
10665
10666 // Seize a Create Event record
10667 if (!c_opDropEvent.seize(evntRecPtr)) {
10668 // Failed to allocate event record
10669 jam();
10670 releaseSections(signal);
10671
10672 DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
10673 ret->setErrorCode(747);
10674 ret->setErrorLine(__LINE__);
10675 ret->setErrorNode(reference());
10676 sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
10677 DropEvntRef::SignalLength, JBB);
10678 DBUG_VOID_RETURN;
10679 }
10680
10681 #ifdef EVENT_DEBUG
10682 ndbout_c("DBDICT::execDROP_EVNT_REQ evntRecId = (%d)", evntRecPtr.i);
10683 #endif
10684
10685 OpDropEvent* evntRec = evntRecPtr.p;
10686 evntRec->init(req);
10687
10688 SegmentedSectionPtr ssPtr;
10689
10690 signal->getSection(ssPtr, 0);
10691
10692 SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
10693 #ifdef EVENT_DEBUG
10694 r0.printAll(ndbout);
10695 #endif
10696 // event name
10697 if ((!r0.first()) ||
10698 (r0.getValueType() != SimpleProperties::StringValue) ||
10699 (r0.getValueLen() <= 0)) {
10700 jam();
10701 releaseSections(signal);
10702
10703 evntRecPtr.p->m_errorCode = 1;
10704 evntRecPtr.p->m_errorLine = __LINE__;
10705 evntRecPtr.p->m_errorNode = reference();
10706
10707 dropEvent_sendReply(signal, evntRecPtr);
10708 DBUG_VOID_RETURN;
10709 }
10710 r0.getString(evntRecPtr.p->m_eventRec.NAME);
10711 {
10712 int len = strlen(evntRecPtr.p->m_eventRec.NAME);
10713 memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
10714 #ifdef EVENT_DEBUG
10715 printf("DropEvntReq; EventName %s, len %u\n",
10716 evntRecPtr.p->m_eventRec.NAME, len);
10717 for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
10718 printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
10719 printf("\n");
10720 #endif
10721 }
10722
10723 releaseSections(signal);
10724
10725 Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_READ), 0 };
10726
10727 prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
10728 UtilPrepareReq::Read);
10729 DBUG_VOID_RETURN;
10730 }
10731
10732 void
dropEventUTIL_PREPARE_READ(Signal * signal,Uint32 callbackData,Uint32 returnCode)10733 Dbdict::dropEventUTIL_PREPARE_READ(Signal* signal,
10734 Uint32 callbackData,
10735 Uint32 returnCode)
10736 {
10737 jam();
10738 EVENT_TRACE;
10739 if (returnCode != 0) {
10740 EVENT_TRACE;
10741 dropEventUtilPrepareRef(signal, callbackData, returnCode);
10742 return;
10743 }
10744
10745 UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
10746 OpDropEventPtr evntRecPtr;
10747 evntRecPtr.i = req->getSenderData();
10748 const Uint32 prepareId = req->getPrepareId();
10749
10750 ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
10751
10752 Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_READ), 0 };
10753
10754 executeTransEventSysTable(&c, signal,
10755 evntRecPtr.i, evntRecPtr.p->m_eventRec,
10756 prepareId, UtilPrepareReq::Read);
10757 }
10758
10759 void
dropEventUTIL_EXECUTE_READ(Signal * signal,Uint32 callbackData,Uint32 returnCode)10760 Dbdict::dropEventUTIL_EXECUTE_READ(Signal* signal,
10761 Uint32 callbackData,
10762 Uint32 returnCode)
10763 {
10764 jam();
10765 EVENT_TRACE;
10766 if (returnCode != 0) {
10767 EVENT_TRACE;
10768 dropEventUtilExecuteRef(signal, callbackData, returnCode);
10769 return;
10770 }
10771
10772 OpDropEventPtr evntRecPtr;
10773 UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
10774 jam();
10775 evntRecPtr.i = ref->getSenderData();
10776 ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
10777
10778 parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
10779
10780 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
10781 RequestTracker & p = evntRecPtr.p->m_reqTracker;
10782 if (!p.init<SubRemoveRef>(c_counterMgr, rg, GSN_SUB_REMOVE_REF,
10783 evntRecPtr.i))
10784 {
10785 evntRecPtr.p->m_errorCode = 701;
10786 dropEvent_sendReply(signal, evntRecPtr);
10787 return;
10788 }
10789
10790 SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
10791
10792 req->senderRef = reference();
10793 req->senderData = evntRecPtr.i;
10794 req->subscriptionId = evntRecPtr.p->m_eventRec.SUBID;
10795 req->subscriptionKey = evntRecPtr.p->m_eventRec.SUBKEY;
10796
10797 sendSignal(rg, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
10798 }
10799
10800 /*
10801 * Participant
10802 */
10803
10804 void
execSUB_REMOVE_REQ(Signal * signal)10805 Dbdict::execSUB_REMOVE_REQ(Signal* signal)
10806 {
10807 jamEntry();
10808 DBUG_ENTER("Dbdict::execSUB_REMOVE_REQ");
10809
10810 Uint32 origSenderRef = signal->senderBlockRef();
10811
10812 OpSubEventPtr subbPtr;
10813 if (!c_opSubEvent.seize(subbPtr)) {
10814 SubRemoveRef * ref = (SubRemoveRef *)signal->getDataPtrSend();
10815 jam();
10816 ref->senderRef = reference();
10817 ref->errorCode = SubRemoveRef::Busy;
10818
10819 sendSignal(origSenderRef, GSN_SUB_REMOVE_REF, signal,
10820 SubRemoveRef::SignalLength, JBB);
10821 DBUG_VOID_RETURN;
10822 }
10823
10824 {
10825 const SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtr();
10826 subbPtr.p->m_senderRef = req->senderRef;
10827 subbPtr.p->m_senderData = req->senderData;
10828 subbPtr.p->m_errorCode = 0;
10829 }
10830
10831 CRASH_INSERTION2(6010, getOwnNodeId() != c_masterNodeId);
10832
10833 SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
10834 req->senderRef = reference();
10835 req->senderData = subbPtr.i;
10836
10837 sendSignal(SUMA_REF, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
10838 DBUG_VOID_RETURN;
10839 }
10840
10841 /*
10842 * Coordintor/Participant
10843 */
10844
10845 void
execSUB_REMOVE_REF(Signal * signal)10846 Dbdict::execSUB_REMOVE_REF(Signal* signal)
10847 {
10848 jamEntry();
10849 DBUG_ENTER("Dbdict::execSUB_REMOVE_REF");
10850
10851 const SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtr();
10852 Uint32 senderRef = ref->senderRef;
10853 Uint32 err= ref->errorCode;
10854
10855 if (refToBlock(senderRef) == SUMA) {
10856 /*
10857 * Participant
10858 */
10859 jam();
10860 OpSubEventPtr subbPtr;
10861 c_opSubEvent.getPtr(subbPtr, ref->senderData);
10862 if (err == 1407) {
10863 // conf this since this may occur if a nodefailure has occured
10864 // earlier so that the systable was not cleared
10865 SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
10866 conf->senderRef = reference();
10867 conf->senderData = subbPtr.p->m_senderData;
10868 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
10869 signal, SubRemoveConf::SignalLength, JBB);
10870 } else {
10871 SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtrSend();
10872 ref->senderRef = reference();
10873 ref->senderData = subbPtr.p->m_senderData;
10874 ref->errorCode = err;
10875 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_REF,
10876 signal, SubRemoveRef::SignalLength, JBB);
10877 }
10878 c_opSubEvent.release(subbPtr);
10879 DBUG_VOID_RETURN;
10880 }
10881 /*
10882 * Coordinator
10883 */
10884 ndbrequire(refToBlock(senderRef) == DBDICT);
10885 OpDropEventPtr eventRecPtr;
10886 c_opDropEvent.getPtr(eventRecPtr, ref->senderData);
10887 if (err == SubRemoveRef::NF_FakeErrorREF){
10888 jam();
10889 eventRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
10890 } else {
10891 jam();
10892 if (eventRecPtr.p->m_errorCode == 0)
10893 {
10894 eventRecPtr.p->m_errorCode= err ? err : 1;
10895 eventRecPtr.p->m_errorLine= __LINE__;
10896 eventRecPtr.p->m_errorNode= reference();
10897 }
10898 eventRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
10899 }
10900 completeSubRemoveReq(signal,eventRecPtr.i,0);
10901 DBUG_VOID_RETURN;
10902 }
10903
10904 void
execSUB_REMOVE_CONF(Signal * signal)10905 Dbdict::execSUB_REMOVE_CONF(Signal* signal)
10906 {
10907 jamEntry();
10908 const SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtr();
10909 Uint32 senderRef = conf->senderRef;
10910
10911 if (refToBlock(senderRef) == SUMA) {
10912 /*
10913 * Participant
10914 */
10915 jam();
10916 OpSubEventPtr subbPtr;
10917 c_opSubEvent.getPtr(subbPtr, conf->senderData);
10918 SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
10919 conf->senderRef = reference();
10920 conf->senderData = subbPtr.p->m_senderData;
10921 sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
10922 signal, SubRemoveConf::SignalLength, JBB);
10923 c_opSubEvent.release(subbPtr);
10924 return;
10925 }
10926 /*
10927 * Coordinator
10928 */
10929 ndbrequire(refToBlock(senderRef) == DBDICT);
10930 OpDropEventPtr eventRecPtr;
10931 c_opDropEvent.getPtr(eventRecPtr, conf->senderData);
10932 eventRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
10933 completeSubRemoveReq(signal,eventRecPtr.i,0);
10934 }
10935
10936 void
completeSubRemoveReq(Signal * signal,Uint32 ptrI,Uint32 xxx)10937 Dbdict::completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 xxx)
10938 {
10939 OpDropEventPtr evntRecPtr;
10940 c_opDropEvent.getPtr(evntRecPtr, ptrI);
10941
10942 if (!evntRecPtr.p->m_reqTracker.done()){
10943 jam();
10944 return;
10945 }
10946
10947 if (evntRecPtr.p->m_reqTracker.hasRef()) {
10948 jam();
10949 if ( evntRecPtr.p->m_errorCode == 0 )
10950 {
10951 evntRecPtr.p->m_errorNode = reference();
10952 evntRecPtr.p->m_errorLine = __LINE__;
10953 evntRecPtr.p->m_errorCode = 1;
10954 }
10955 dropEvent_sendReply(signal, evntRecPtr);
10956 return;
10957 }
10958
10959 Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_DELETE), 0 };
10960
10961 prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
10962 UtilPrepareReq::Delete);
10963 }
10964
10965 void
dropEventUTIL_PREPARE_DELETE(Signal * signal,Uint32 callbackData,Uint32 returnCode)10966 Dbdict::dropEventUTIL_PREPARE_DELETE(Signal* signal,
10967 Uint32 callbackData,
10968 Uint32 returnCode)
10969 {
10970 jam();
10971 EVENT_TRACE;
10972 if (returnCode != 0) {
10973 EVENT_TRACE;
10974 dropEventUtilPrepareRef(signal, callbackData, returnCode);
10975 return;
10976 }
10977
10978 UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
10979 OpDropEventPtr evntRecPtr;
10980 jam();
10981 evntRecPtr.i = req->getSenderData();
10982 const Uint32 prepareId = req->getPrepareId();
10983
10984 ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
10985 #ifdef EVENT_DEBUG
10986 printf("DropEvntUTIL_PREPARE; evntRecPtr.i len %u\n",evntRecPtr.i);
10987 #endif
10988
10989 Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_DELETE), 0 };
10990
10991 executeTransEventSysTable(&c, signal,
10992 evntRecPtr.i, evntRecPtr.p->m_eventRec,
10993 prepareId, UtilPrepareReq::Delete);
10994 }
10995
10996 void
dropEventUTIL_EXECUTE_DELETE(Signal * signal,Uint32 callbackData,Uint32 returnCode)10997 Dbdict::dropEventUTIL_EXECUTE_DELETE(Signal* signal,
10998 Uint32 callbackData,
10999 Uint32 returnCode)
11000 {
11001 jam();
11002 EVENT_TRACE;
11003 if (returnCode != 0) {
11004 EVENT_TRACE;
11005 dropEventUtilExecuteRef(signal, callbackData, returnCode);
11006 return;
11007 }
11008
11009 OpDropEventPtr evntRecPtr;
11010 UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
11011 jam();
11012 evntRecPtr.i = ref->getSenderData();
11013 ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
11014
11015 dropEvent_sendReply(signal, evntRecPtr);
11016 }
11017
11018 void
dropEventUtilPrepareRef(Signal * signal,Uint32 callbackData,Uint32 returnCode)11019 Dbdict::dropEventUtilPrepareRef(Signal* signal,
11020 Uint32 callbackData,
11021 Uint32 returnCode)
11022 {
11023 jam();
11024 EVENT_TRACE;
11025 UtilPrepareRef * const ref = (UtilPrepareRef *)signal->getDataPtr();
11026 OpDropEventPtr evntRecPtr;
11027 evntRecPtr.i = ref->getSenderData();
11028 ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
11029
11030 interpretUtilPrepareErrorCode((UtilPrepareRef::ErrorCode)ref->getErrorCode(),
11031 evntRecPtr.p->m_errorCode, evntRecPtr.p->m_errorLine);
11032 evntRecPtr.p->m_errorNode = reference();
11033
11034 dropEvent_sendReply(signal, evntRecPtr);
11035 }
11036
11037 void
dropEventUtilExecuteRef(Signal * signal,Uint32 callbackData,Uint32 returnCode)11038 Dbdict::dropEventUtilExecuteRef(Signal* signal,
11039 Uint32 callbackData,
11040 Uint32 returnCode)
11041 {
11042 jam();
11043 EVENT_TRACE;
11044 OpDropEventPtr evntRecPtr;
11045 UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
11046 jam();
11047 evntRecPtr.i = ref->getSenderData();
11048 ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
11049
11050 evntRecPtr.p->m_errorNode = reference();
11051 evntRecPtr.p->m_errorLine = __LINE__;
11052
11053 switch (ref->getErrorCode()) {
11054 case UtilExecuteRef::TCError:
11055 switch (ref->getTCErrorCode()) {
11056 case ZNOT_FOUND:
11057 jam();
11058 evntRecPtr.p->m_errorCode = 4710;
11059 break;
11060 default:
11061 jam();
11062 evntRecPtr.p->m_errorCode = ref->getTCErrorCode();
11063 break;
11064 }
11065 break;
11066 default:
11067 jam();
11068 evntRecPtr.p->m_errorCode = ref->getErrorCode();
11069 break;
11070 }
11071 dropEvent_sendReply(signal, evntRecPtr);
11072 }
11073
dropEvent_sendReply(Signal * signal,OpDropEventPtr evntRecPtr)11074 void Dbdict::dropEvent_sendReply(Signal* signal,
11075 OpDropEventPtr evntRecPtr)
11076 {
11077 jam();
11078 EVENT_TRACE;
11079 Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
11080
11081 if (evntRecPtr.p->hasError()) {
11082 jam();
11083 DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
11084
11085 ret->setUserData(evntRecPtr.p->m_request.getUserData());
11086 ret->setUserRef(evntRecPtr.p->m_request.getUserRef());
11087
11088 ret->setErrorCode(evntRecPtr.p->m_errorCode);
11089 ret->setErrorLine(evntRecPtr.p->m_errorLine);
11090 ret->setErrorNode(evntRecPtr.p->m_errorNode);
11091
11092 sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
11093 DropEvntRef::SignalLength, JBB);
11094 } else {
11095 jam();
11096 DropEvntConf * evntConf = (DropEvntConf *)signal->getDataPtrSend();
11097
11098 evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
11099 evntConf->setUserRef(evntRecPtr.p->m_request.getUserRef());
11100
11101 sendSignal(senderRef, GSN_DROP_EVNT_CONF, signal,
11102 DropEvntConf::SignalLength, JBB);
11103 }
11104
11105 c_opDropEvent.release(evntRecPtr);
11106 }
11107
11108 /**
11109 * MODULE: Alter index
11110 *
11111 * Alter index state. Alter online creates the index in each TC and
11112 * then invokes create trigger and alter trigger protocols to activate
11113 * the 3 triggers. Alter offline does the opposite.
11114 *
11115 * Request type received in REQ and returned in CONF/REF:
11116 *
11117 * RT_USER - from API to DICT master
11118 * RT_CREATE_INDEX - part of create index operation
11119 * RT_DROP_INDEX - part of drop index operation
11120 * RT_NODERESTART - node restart, activate locally only
11121 * RT_SYSTEMRESTART - system restart, activate and build if not logged
11122 * RT_DICT_PREPARE - prepare participants
11123 * RT_DICT_TC - to local TC via each participant
11124 * RT_DICT_COMMIT - commit in each participant
11125 */
11126
11127 void
execALTER_INDX_REQ(Signal * signal)11128 Dbdict::execALTER_INDX_REQ(Signal* signal)
11129 {
11130 jamEntry();
11131 AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
11132 OpAlterIndexPtr opPtr;
11133 const Uint32 senderRef = signal->senderBlockRef();
11134 const AlterIndxReq::RequestType requestType = req->getRequestType();
11135 if (requestType == AlterIndxReq::RT_USER ||
11136 requestType == AlterIndxReq::RT_CREATE_INDEX ||
11137 requestType == AlterIndxReq::RT_DROP_INDEX ||
11138 requestType == AlterIndxReq::RT_NODERESTART ||
11139 requestType == AlterIndxReq::RT_SYSTEMRESTART) {
11140 jam();
11141 const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
11142 NdbNodeBitmask receiverNodes = c_aliveNodes;
11143 if (isLocal) {
11144 receiverNodes.clear();
11145 receiverNodes.set(getOwnNodeId());
11146 }
11147 if (signal->getLength() == AlterIndxReq::SignalLength) {
11148 jam();
11149 if (! isLocal && getOwnNodeId() != c_masterNodeId) {
11150 jam();
11151
11152 releaseSections(signal);
11153 OpAlterIndex opBad;
11154 opPtr.p = &opBad;
11155 opPtr.p->save(req);
11156 opPtr.p->m_errorCode = AlterIndxRef::NotMaster;
11157 opPtr.p->m_errorLine = __LINE__;
11158 opPtr.p->m_errorNode = c_masterNodeId;
11159 alterIndex_sendReply(signal, opPtr, true);
11160 return;
11161 }
11162 // forward initial request plus operation key to all
11163 req->setOpKey(++c_opRecordSequence);
11164 NodeReceiverGroup rg(DBDICT, receiverNodes);
11165 sendSignal(rg, GSN_ALTER_INDX_REQ,
11166 signal, AlterIndxReq::SignalLength + 1, JBB);
11167 return;
11168 }
11169 // seize operation record
11170 ndbrequire(signal->getLength() == AlterIndxReq::SignalLength + 1);
11171 const Uint32 opKey = req->getOpKey();
11172 OpAlterIndex opBusy;
11173 if (! c_opAlterIndex.seize(opPtr))
11174 opPtr.p = &opBusy;
11175 opPtr.p->save(req);
11176 opPtr.p->m_coordinatorRef = senderRef;
11177 opPtr.p->m_isMaster = (senderRef == reference());
11178 opPtr.p->key = opKey;
11179 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_PREPARE;
11180 if (opPtr.p == &opBusy) {
11181 jam();
11182 opPtr.p->m_errorCode = AlterIndxRef::Busy;
11183 opPtr.p->m_errorLine = __LINE__;
11184 alterIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
11185 return;
11186 }
11187 c_opAlterIndex.add(opPtr);
11188 // master expects to hear from all
11189 if (opPtr.p->m_isMaster)
11190 opPtr.p->m_signalCounter = receiverNodes;
11191 // check request in all participants
11192 alterIndex_slavePrepare(signal, opPtr);
11193 alterIndex_sendReply(signal, opPtr, false);
11194 return;
11195 }
11196 c_opAlterIndex.find(opPtr, req->getConnectionPtr());
11197 if (! opPtr.isNull()) {
11198 opPtr.p->m_requestType = requestType;
11199 if (requestType == AlterIndxReq::RT_DICT_TC) {
11200 jam();
11201 if (opPtr.p->m_request.getOnline())
11202 alterIndex_toCreateTc(signal, opPtr);
11203 else
11204 alterIndex_toDropTc(signal, opPtr);
11205 return;
11206 }
11207 if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
11208 requestType == AlterIndxReq::RT_DICT_ABORT) {
11209 jam();
11210 if (requestType == AlterIndxReq::RT_DICT_COMMIT)
11211 alterIndex_slaveCommit(signal, opPtr);
11212 else
11213 alterIndex_slaveAbort(signal, opPtr);
11214 alterIndex_sendReply(signal, opPtr, false);
11215 // done in slave
11216 if (! opPtr.p->m_isMaster)
11217 c_opAlterIndex.release(opPtr);
11218 return;
11219 }
11220 }
11221 jam();
11222 // return to sender
11223 OpAlterIndex opBad;
11224 opPtr.p = &opBad;
11225 opPtr.p->save(req);
11226 opPtr.p->m_errorCode = AlterIndxRef::BadRequestType;
11227 opPtr.p->m_errorLine = __LINE__;
11228 alterIndex_sendReply(signal, opPtr, true);
11229 }
11230
11231 void
execALTER_INDX_CONF(Signal * signal)11232 Dbdict::execALTER_INDX_CONF(Signal* signal)
11233 {
11234 jamEntry();
11235 ndbrequire(signal->getNoOfSections() == 0);
11236 AlterIndxConf* conf = (AlterIndxConf*)signal->getDataPtrSend();
11237 alterIndex_recvReply(signal, conf, 0);
11238 }
11239
11240 void
execALTER_INDX_REF(Signal * signal)11241 Dbdict::execALTER_INDX_REF(Signal* signal)
11242 {
11243 jamEntry();
11244 AlterIndxRef* ref = (AlterIndxRef*)signal->getDataPtrSend();
11245 alterIndex_recvReply(signal, ref->getConf(), ref);
11246 }
11247
11248 void
alterIndex_recvReply(Signal * signal,const AlterIndxConf * conf,const AlterIndxRef * ref)11249 Dbdict::alterIndex_recvReply(Signal* signal, const AlterIndxConf* conf,
11250 const AlterIndxRef* ref)
11251 {
11252 jam();
11253 const Uint32 senderRef = signal->senderBlockRef();
11254 const AlterIndxReq::RequestType requestType = conf->getRequestType();
11255 const Uint32 key = conf->getConnectionPtr();
11256 if (requestType == AlterIndxReq::RT_CREATE_INDEX) {
11257 jam();
11258 // part of create index operation
11259 OpCreateIndexPtr opPtr;
11260 c_opCreateIndex.find(opPtr, key);
11261 ndbrequire(! opPtr.isNull());
11262 opPtr.p->setError(ref);
11263 createIndex_fromAlterIndex(signal, opPtr);
11264 return;
11265 }
11266 if (requestType == AlterIndxReq::RT_DROP_INDEX) {
11267 jam();
11268 // part of drop index operation
11269 OpDropIndexPtr opPtr;
11270 c_opDropIndex.find(opPtr, key);
11271 ndbrequire(! opPtr.isNull());
11272 opPtr.p->setError(ref);
11273 dropIndex_fromAlterIndex(signal, opPtr);
11274 return;
11275 }
11276 if (requestType == AlterIndxReq::RT_TC ||
11277 requestType == AlterIndxReq::RT_TUX) {
11278 jam();
11279 // part of build index operation
11280 OpBuildIndexPtr opPtr;
11281 c_opBuildIndex.find(opPtr, key);
11282 ndbrequire(! opPtr.isNull());
11283 opPtr.p->setError(ref);
11284 buildIndex_fromOnline(signal, opPtr);
11285 return;
11286 }
11287 if (requestType == AlterIndxReq::RT_NODERESTART) {
11288 jam();
11289 if (ref == 0) {
11290 infoEvent("DICT: index %u activated", (unsigned)key);
11291 } else {
11292 warningEvent("DICT: index %u activation failed: code=%d line=%d",
11293 (unsigned)key,
11294 ref->getErrorCode(), ref->getErrorLine());
11295 }
11296 activateIndexes(signal, key + 1);
11297 return;
11298 }
11299 if (requestType == AlterIndxReq::RT_SYSTEMRESTART) {
11300 jam();
11301 if (ref == 0) {
11302 infoEvent("DICT: index %u activated done", (unsigned)key);
11303 } else {
11304 warningEvent("DICT: index %u activated failed: code=%d line=%d node=%d",
11305 (unsigned)key,
11306 ref->getErrorCode(), ref->getErrorLine(), ref->getErrorNode());
11307 }
11308 activateIndexes(signal, key + 1);
11309 return;
11310 }
11311 OpAlterIndexPtr opPtr;
11312 c_opAlterIndex.find(opPtr, key);
11313 ndbrequire(! opPtr.isNull());
11314 ndbrequire(opPtr.p->m_isMaster);
11315 ndbrequire(opPtr.p->m_requestType == requestType);
11316 opPtr.p->setError(ref);
11317 opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
11318 if (! opPtr.p->m_signalCounter.done()) {
11319 jam();
11320 return;
11321 }
11322 if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
11323 requestType == AlterIndxReq::RT_DICT_ABORT) {
11324 jam();
11325 // send reply to user
11326 alterIndex_sendReply(signal, opPtr, true);
11327 c_opAlterIndex.release(opPtr);
11328 return;
11329 }
11330 if (opPtr.p->hasError()) {
11331 jam();
11332 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
11333 alterIndex_sendSlaveReq(signal, opPtr);
11334 return;
11335 }
11336 TableRecordPtr indexPtr;
11337 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11338 if (indexPtr.p->isHashIndex()) {
11339 if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
11340 jam();
11341 if (opPtr.p->m_request.getOnline()) {
11342 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
11343 alterIndex_sendSlaveReq(signal, opPtr);
11344 } else {
11345 // start drop triggers
11346 alterIndex_toDropTrigger(signal, opPtr);
11347 }
11348 return;
11349 }
11350 if (requestType == AlterIndxReq::RT_DICT_TC) {
11351 jam();
11352 if (opPtr.p->m_request.getOnline()) {
11353 // start create triggers
11354 alterIndex_toCreateTrigger(signal, opPtr);
11355 } else {
11356 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
11357 alterIndex_sendSlaveReq(signal, opPtr);
11358 }
11359 return;
11360 }
11361 }
11362 if (indexPtr.p->isOrderedIndex()) {
11363 if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
11364 jam();
11365 if (opPtr.p->m_request.getOnline()) {
11366 // start create triggers
11367 alterIndex_toCreateTrigger(signal, opPtr);
11368 } else {
11369 // start drop triggers
11370 alterIndex_toDropTrigger(signal, opPtr);
11371 }
11372 return;
11373 }
11374 }
11375 ndbrequire(false);
11376 }
11377
11378 void
alterIndex_slavePrepare(Signal * signal,OpAlterIndexPtr opPtr)11379 Dbdict::alterIndex_slavePrepare(Signal* signal, OpAlterIndexPtr opPtr)
11380 {
11381 jam();
11382 const AlterIndxReq* const req = &opPtr.p->m_request;
11383 if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
11384 jam();
11385 opPtr.p->m_errorCode = AlterIndxRef::Inconsistency;
11386 opPtr.p->m_errorLine = __LINE__;
11387 return;
11388 }
11389 TableRecordPtr indexPtr;
11390 c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
11391 if (indexPtr.p->tabState != TableRecord::DEFINED) {
11392 jam();
11393 opPtr.p->m_errorCode = AlterIndxRef::IndexNotFound;
11394 opPtr.p->m_errorLine = __LINE__;
11395 return;
11396 }
11397 if (! indexPtr.p->isIndex()) {
11398 jam();
11399 opPtr.p->m_errorCode = AlterIndxRef::NotAnIndex;
11400 opPtr.p->m_errorLine = __LINE__;
11401 return;
11402 }
11403 if (req->getOnline())
11404 indexPtr.p->indexState = TableRecord::IS_BUILDING;
11405 else
11406 indexPtr.p->indexState = TableRecord::IS_DROPPING;
11407 }
11408
11409 void
alterIndex_toCreateTc(Signal * signal,OpAlterIndexPtr opPtr)11410 Dbdict::alterIndex_toCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
11411 {
11412 jam();
11413 TableRecordPtr indexPtr;
11414 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11415 // request to create index in local TC
11416 CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
11417 req->setUserRef(reference());
11418 req->setConnectionPtr(opPtr.p->key);
11419 req->setRequestType(CreateIndxReq::RT_TC);
11420 req->setIndexType(indexPtr.p->tableType);
11421 req->setTableId(indexPtr.p->primaryTableId);
11422 req->setIndexId(indexPtr.i);
11423 req->setOnline(true);
11424 getIndexAttrList(indexPtr, opPtr.p->m_attrList);
11425 // send
11426 LinearSectionPtr lsPtr[3];
11427 lsPtr[0].p = (Uint32*)&opPtr.p->m_attrList;
11428 lsPtr[0].sz = 1 + opPtr.p->m_attrList.sz;
11429 sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_CREATE_INDX_REQ,
11430 signal, CreateIndxReq::SignalLength, JBB, lsPtr, 1);
11431 }
11432
11433 void
alterIndex_fromCreateTc(Signal * signal,OpAlterIndexPtr opPtr)11434 Dbdict::alterIndex_fromCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
11435 {
11436 jam();
11437 // mark created in local TC
11438 if (! opPtr.p->hasLastError()) {
11439 TableRecordPtr indexPtr;
11440 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11441 indexPtr.p->indexLocal |= TableRecord::IL_CREATED_TC;
11442 }
11443 // forward CONF or REF to master
11444 ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
11445 alterIndex_sendReply(signal, opPtr, false);
11446 }
11447
11448 void
alterIndex_toDropTc(Signal * signal,OpAlterIndexPtr opPtr)11449 Dbdict::alterIndex_toDropTc(Signal* signal, OpAlterIndexPtr opPtr)
11450 {
11451 jam();
11452 TableRecordPtr indexPtr;
11453 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11454 // broken index allowed if force
11455 if (! (indexPtr.p->indexLocal & TableRecord::IL_CREATED_TC)) {
11456 jam();
11457 ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
11458 alterIndex_sendReply(signal, opPtr, false);
11459 return;
11460 }
11461 // request to drop in local TC
11462 DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
11463 req->setUserRef(reference());
11464 req->setConnectionPtr(opPtr.p->key);
11465 req->setRequestType(DropIndxReq::RT_TC);
11466 req->setTableId(indexPtr.p->primaryTableId);
11467 req->setIndexId(indexPtr.i);
11468 req->setIndexVersion(indexPtr.p->tableVersion);
11469 // send
11470 sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_DROP_INDX_REQ,
11471 signal, DropIndxReq::SignalLength, JBB);
11472 }
11473
11474 void
alterIndex_fromDropTc(Signal * signal,OpAlterIndexPtr opPtr)11475 Dbdict::alterIndex_fromDropTc(Signal* signal, OpAlterIndexPtr opPtr)
11476 {
11477 jam();
11478 ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
11479 // mark dropped locally
11480 if (! opPtr.p->hasLastError()) {
11481 TableRecordPtr indexPtr;
11482 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11483 indexPtr.p->indexLocal &= ~TableRecord::IL_CREATED_TC;
11484 }
11485 // forward CONF or REF to master
11486 alterIndex_sendReply(signal, opPtr, false);
11487 }
11488
11489 void
alterIndex_toCreateTrigger(Signal * signal,OpAlterIndexPtr opPtr)11490 Dbdict::alterIndex_toCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
11491 {
11492 jam();
11493 TableRecordPtr indexPtr;
11494 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11495 // start creation of index triggers
11496 CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
11497 req->setUserRef(reference());
11498 req->setConnectionPtr(opPtr.p->key);
11499 req->setRequestType(CreateTrigReq::RT_ALTER_INDEX);
11500 req->addRequestFlag(opPtr.p->m_requestFlag);
11501 req->setTableId(opPtr.p->m_request.getTableId());
11502 req->setIndexId(opPtr.p->m_request.getIndexId());
11503 req->setTriggerId(RNIL);
11504 req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
11505 req->setMonitorAllAttributes(false);
11506 req->setOnline(true); // alter online after create
11507 req->setReceiverRef(0); // implicit for index triggers
11508 getIndexAttrMask(indexPtr, req->getAttributeMask());
11509 // name section
11510 char triggerName[MAX_TAB_NAME_SIZE];
11511 Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)]; // SP string
11512 LinearWriter w(buffer, sizeof(buffer) >> 2);
11513 LinearSectionPtr lsPtr[3];
11514 if (indexPtr.p->isHashIndex()) {
11515 req->setTriggerType(TriggerType::SECONDARY_INDEX);
11516 req->setMonitorReplicas(false);
11517 req->setReportAllMonitoredAttributes(true);
11518 // insert
11519 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
11520 req->setTriggerId(indexPtr.p->insertTriggerId);
11521 req->setTriggerEvent(TriggerEvent::TE_INSERT);
11522 sprintf(triggerName, "NDB$INDEX_%u_INSERT", opPtr.p->m_request.getIndexId());
11523 w.reset();
11524 w.add(CreateTrigReq::TriggerNameKey, triggerName);
11525 lsPtr[0].p = buffer;
11526 lsPtr[0].sz = w.getWordsUsed();
11527 sendSignal(reference(), GSN_CREATE_TRIG_REQ,
11528 signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
11529 // update
11530 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
11531 req->setTriggerId(indexPtr.p->updateTriggerId);
11532 req->setTriggerEvent(TriggerEvent::TE_UPDATE);
11533 sprintf(triggerName, "NDB$INDEX_%u_UPDATE", opPtr.p->m_request.getIndexId());
11534 w.reset();
11535 w.add(CreateTrigReq::TriggerNameKey, triggerName);
11536 lsPtr[0].p = buffer;
11537 lsPtr[0].sz = w.getWordsUsed();
11538 sendSignal(reference(), GSN_CREATE_TRIG_REQ,
11539 signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
11540 // delete
11541 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
11542 req->setTriggerId(indexPtr.p->deleteTriggerId);
11543 req->setTriggerEvent(TriggerEvent::TE_DELETE);
11544 sprintf(triggerName, "NDB$INDEX_%u_DELETE", opPtr.p->m_request.getIndexId());
11545 w.reset();
11546 w.add(CreateTrigReq::TriggerNameKey, triggerName);
11547 lsPtr[0].p = buffer;
11548 lsPtr[0].sz = w.getWordsUsed();
11549 sendSignal(reference(), GSN_CREATE_TRIG_REQ,
11550 signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
11551 // triggers left to create
11552 opPtr.p->m_triggerCounter = 3;
11553 return;
11554 }
11555 if (indexPtr.p->isOrderedIndex()) {
11556 req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
11557 req->setTriggerType(TriggerType::ORDERED_INDEX);
11558 req->setTriggerActionTime(TriggerActionTime::TA_CUSTOM);
11559 req->setMonitorReplicas(true);
11560 req->setReportAllMonitoredAttributes(true);
11561 // one trigger for 5 events (insert, update, delete, commit, abort)
11562 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
11563 req->setTriggerId(indexPtr.p->customTriggerId);
11564 req->setTriggerEvent(TriggerEvent::TE_CUSTOM);
11565 sprintf(triggerName, "NDB$INDEX_%u_CUSTOM", opPtr.p->m_request.getIndexId());
11566 w.reset();
11567 w.add(CreateTrigReq::TriggerNameKey, triggerName);
11568 lsPtr[0].p = buffer;
11569 lsPtr[0].sz = w.getWordsUsed();
11570 sendSignal(reference(), GSN_CREATE_TRIG_REQ,
11571 signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
11572 // triggers left to create
11573 opPtr.p->m_triggerCounter = 1;
11574 return;
11575 }
11576 ndbrequire(false);
11577 }
11578
11579 void
alterIndex_fromCreateTrigger(Signal * signal,OpAlterIndexPtr opPtr)11580 Dbdict::alterIndex_fromCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
11581 {
11582 jam();
11583 ndbrequire(opPtr.p->m_triggerCounter != 0);
11584 if (--opPtr.p->m_triggerCounter != 0) {
11585 jam();
11586 return;
11587 }
11588 if (opPtr.p->hasError()) {
11589 jam();
11590 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
11591 alterIndex_sendSlaveReq(signal, opPtr);
11592 return;
11593 }
11594 if(opPtr.p->m_requestType != AlterIndxReq::RT_SYSTEMRESTART){
11595 // send build request
11596 alterIndex_toBuildIndex(signal, opPtr);
11597 return;
11598 }
11599
11600 /**
11601 * During system restart,
11602 * leave index in activated but not build state.
11603 *
11604 * Build a bit later when REDO has been run
11605 */
11606 alterIndex_sendReply(signal, opPtr, true);
11607 }
11608
11609 void
alterIndex_toDropTrigger(Signal * signal,OpAlterIndexPtr opPtr)11610 Dbdict::alterIndex_toDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
11611 {
11612 jam();
11613 TableRecordPtr indexPtr;
11614 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11615 // start drop of index triggers
11616 DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
11617 req->setUserRef(reference());
11618 req->setConnectionPtr(opPtr.p->key);
11619 req->setRequestType(DropTrigReq::RT_ALTER_INDEX);
11620 req->addRequestFlag(opPtr.p->m_requestFlag);
11621 req->setTableId(opPtr.p->m_request.getTableId());
11622 req->setIndexId(opPtr.p->m_request.getIndexId());
11623 req->setTriggerInfo(0); // not used
11624 opPtr.p->m_triggerCounter = 0;
11625 if (indexPtr.p->isHashIndex()) {
11626 // insert
11627 req->setTriggerId(indexPtr.p->insertTriggerId);
11628 sendSignal(reference(), GSN_DROP_TRIG_REQ,
11629 signal, DropTrigReq::SignalLength, JBB);
11630 opPtr.p->m_triggerCounter++;
11631 // update
11632 req->setTriggerId(indexPtr.p->updateTriggerId);
11633 sendSignal(reference(), GSN_DROP_TRIG_REQ,
11634 signal, DropTrigReq::SignalLength, JBB);
11635 opPtr.p->m_triggerCounter++;
11636 // delete
11637 req->setTriggerId(indexPtr.p->deleteTriggerId);
11638 sendSignal(reference(), GSN_DROP_TRIG_REQ,
11639 signal, DropTrigReq::SignalLength, JBB);
11640 opPtr.p->m_triggerCounter++;
11641 // build
11642 if (indexPtr.p->buildTriggerId != RNIL) {
11643 req->setTriggerId(indexPtr.p->buildTriggerId);
11644 sendSignal(reference(), GSN_DROP_TRIG_REQ,
11645 signal, DropTrigReq::SignalLength, JBB);
11646 opPtr.p->m_triggerCounter++;
11647 }
11648 return;
11649 }
11650 if (indexPtr.p->isOrderedIndex()) {
11651 // custom
11652 req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
11653 req->setTriggerId(indexPtr.p->customTriggerId);
11654 sendSignal(reference(), GSN_DROP_TRIG_REQ,
11655 signal, DropTrigReq::SignalLength, JBB);
11656 opPtr.p->m_triggerCounter++;
11657 return;
11658 }
11659 ndbrequire(false);
11660 }
11661
11662 void
alterIndex_fromDropTrigger(Signal * signal,OpAlterIndexPtr opPtr)11663 Dbdict::alterIndex_fromDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
11664 {
11665 jam();
11666 ndbrequire(opPtr.p->m_triggerCounter != 0);
11667 if (--opPtr.p->m_triggerCounter != 0) {
11668 jam();
11669 return;
11670 }
11671 // finally drop index in each TC
11672 TableRecordPtr indexPtr;
11673 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11674 const bool isHashIndex = indexPtr.p->isHashIndex();
11675 const bool isOrderedIndex = indexPtr.p->isOrderedIndex();
11676 ndbrequire(isHashIndex != isOrderedIndex); // xor
11677 if (isHashIndex)
11678 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
11679 if (isOrderedIndex)
11680 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
11681 alterIndex_sendSlaveReq(signal, opPtr);
11682 }
11683
11684 void
alterIndex_toBuildIndex(Signal * signal,OpAlterIndexPtr opPtr)11685 Dbdict::alterIndex_toBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
11686 {
11687 jam();
11688 // get index and table records
11689 TableRecordPtr indexPtr;
11690 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11691 TableRecordPtr tablePtr;
11692 c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
11693 // build request to self (short signal)
11694 BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
11695 req->setUserRef(reference());
11696 req->setConnectionPtr(opPtr.p->key);
11697 req->setRequestType(BuildIndxReq::RT_ALTER_INDEX);
11698 req->addRequestFlag(opPtr.p->m_requestFlag);
11699 req->setBuildId(0); // not used
11700 req->setBuildKey(0); // not used
11701 req->setIndexType(indexPtr.p->tableType);
11702 req->setIndexId(indexPtr.i);
11703 req->setTableId(indexPtr.p->primaryTableId);
11704 req->setParallelism(16);
11705 // send
11706 sendSignal(reference(), GSN_BUILDINDXREQ,
11707 signal, BuildIndxReq::SignalLength, JBB);
11708 }
11709
11710 void
alterIndex_fromBuildIndex(Signal * signal,OpAlterIndexPtr opPtr)11711 Dbdict::alterIndex_fromBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
11712 {
11713 jam();
11714 if (opPtr.p->hasError()) {
11715 jam();
11716 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
11717 alterIndex_sendSlaveReq(signal, opPtr);
11718 return;
11719 }
11720 opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
11721 alterIndex_sendSlaveReq(signal, opPtr);
11722 }
11723
11724 void
alterIndex_slaveCommit(Signal * signal,OpAlterIndexPtr opPtr)11725 Dbdict::alterIndex_slaveCommit(Signal* signal, OpAlterIndexPtr opPtr)
11726 {
11727 jam();
11728 // get index record
11729 TableRecordPtr indexPtr;
11730 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
11731 indexPtr.p->indexState = TableRecord::IS_ONLINE;
11732 }
11733
11734 void
alterIndex_slaveAbort(Signal * signal,OpAlterIndexPtr opPtr)11735 Dbdict::alterIndex_slaveAbort(Signal* signal, OpAlterIndexPtr opPtr)
11736 {
11737 jam();
11738 // find index record
11739 const Uint32 indexId = opPtr.p->m_request.getIndexId();
11740 if (indexId >= c_tableRecordPool.getSize())
11741 return;
11742 TableRecordPtr indexPtr;
11743 c_tableRecordPool.getPtr(indexPtr, indexId);
11744 if (! indexPtr.p->isIndex())
11745 return;
11746 // mark broken
11747 indexPtr.p->indexState = TableRecord::IS_BROKEN;
11748 }
11749
11750 void
alterIndex_sendSlaveReq(Signal * signal,OpAlterIndexPtr opPtr)11751 Dbdict::alterIndex_sendSlaveReq(Signal* signal, OpAlterIndexPtr opPtr)
11752 {
11753 AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
11754 *req = opPtr.p->m_request;
11755 req->setUserRef(opPtr.p->m_coordinatorRef);
11756 req->setConnectionPtr(opPtr.p->key);
11757 req->setRequestType(opPtr.p->m_requestType);
11758 req->addRequestFlag(opPtr.p->m_requestFlag);
11759 NdbNodeBitmask receiverNodes = c_aliveNodes;
11760 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
11761 receiverNodes.clear();
11762 receiverNodes.set(getOwnNodeId());
11763 }
11764 opPtr.p->m_signalCounter = receiverNodes;
11765 NodeReceiverGroup rg(DBDICT, receiverNodes);
11766 sendSignal(rg, GSN_ALTER_INDX_REQ,
11767 signal, AlterIndxReq::SignalLength, JBB);
11768 }
11769
11770 void
alterIndex_sendReply(Signal * signal,OpAlterIndexPtr opPtr,bool toUser)11771 Dbdict::alterIndex_sendReply(Signal* signal, OpAlterIndexPtr opPtr,
11772 bool toUser)
11773 {
11774 AlterIndxRef* rep = (AlterIndxRef*)signal->getDataPtrSend();
11775 Uint32 gsn = GSN_ALTER_INDX_CONF;
11776 Uint32 length = AlterIndxConf::InternalLength;
11777 bool sendRef;
11778 if (! toUser) {
11779 sendRef = opPtr.p->hasLastError();
11780 rep->setUserRef(opPtr.p->m_coordinatorRef);
11781 rep->setConnectionPtr(opPtr.p->key);
11782 rep->setRequestType(opPtr.p->m_requestType);
11783 if (opPtr.p->m_requestType == AlterIndxReq::RT_DICT_ABORT)
11784 sendRef = false;
11785 } else {
11786 sendRef = opPtr.p->hasError();
11787 rep->setUserRef(opPtr.p->m_request.getUserRef());
11788 rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
11789 rep->setRequestType(opPtr.p->m_request.getRequestType());
11790 length = AlterIndxConf::SignalLength;
11791 }
11792 rep->setTableId(opPtr.p->m_request.getTableId());
11793 rep->setIndexId(opPtr.p->m_request.getIndexId());
11794 if (sendRef) {
11795 if (opPtr.p->m_errorNode == 0)
11796 opPtr.p->m_errorNode = getOwnNodeId();
11797 rep->setErrorCode(opPtr.p->m_errorCode);
11798 rep->setErrorLine(opPtr.p->m_errorLine);
11799 rep->setErrorNode(opPtr.p->m_errorNode);
11800 gsn = GSN_ALTER_INDX_REF;
11801 length = AlterIndxRef::SignalLength;
11802 }
11803 sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
11804 }
11805
11806 /**
11807 * MODULE: Build index
11808 *
11809 * Build index or all indexes on a table. Request type:
11810 *
11811 * RT_USER - normal user request, not yet used
11812 * RT_ALTER_INDEX - from alter index
11813 * RT_SYSTEM_RESTART -
11814 * RT_DICT_PREPARE - prepare participants
11815 * RT_DICT_TRIX - to participant on way to local TRIX
11816 * RT_DICT_COMMIT - commit in each participant
11817 * RT_DICT_ABORT - abort
11818 * RT_TRIX - to local TRIX
11819 */
11820
11821 void
execBUILDINDXREQ(Signal * signal)11822 Dbdict::execBUILDINDXREQ(Signal* signal)
11823 {
11824 jamEntry();
11825 BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
11826 OpBuildIndexPtr opPtr;
11827 const Uint32 senderRef = signal->senderBlockRef();
11828 const BuildIndxReq::RequestType requestType = req->getRequestType();
11829 if (requestType == BuildIndxReq::RT_USER ||
11830 requestType == BuildIndxReq::RT_ALTER_INDEX ||
11831 requestType == BuildIndxReq::RT_SYSTEMRESTART) {
11832 jam();
11833
11834 const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
11835 NdbNodeBitmask receiverNodes = c_aliveNodes;
11836 if (isLocal) {
11837 receiverNodes.clear();
11838 receiverNodes.set(getOwnNodeId());
11839 }
11840
11841 if (signal->getLength() == BuildIndxReq::SignalLength) {
11842 jam();
11843
11844 if (!isLocal && getOwnNodeId() != c_masterNodeId) {
11845 jam();
11846
11847 releaseSections(signal);
11848 OpBuildIndex opBad;
11849 opPtr.p = &opBad;
11850 opPtr.p->save(req);
11851 opPtr.p->m_errorCode = BuildIndxRef::NotMaster;
11852 opPtr.p->m_errorLine = __LINE__;
11853 opPtr.p->m_errorNode = c_masterNodeId;
11854 buildIndex_sendReply(signal, opPtr, true);
11855 return;
11856 }
11857 // forward initial request plus operation key to all
11858 req->setOpKey(++c_opRecordSequence);
11859 NodeReceiverGroup rg(DBDICT, receiverNodes);
11860 sendSignal(rg, GSN_BUILDINDXREQ,
11861 signal, BuildIndxReq::SignalLength + 1, JBB);
11862 return;
11863 }
11864 // seize operation record
11865 ndbrequire(signal->getLength() == BuildIndxReq::SignalLength + 1);
11866 const Uint32 opKey = req->getOpKey();
11867 OpBuildIndex opBusy;
11868 if (! c_opBuildIndex.seize(opPtr))
11869 opPtr.p = &opBusy;
11870 opPtr.p->save(req);
11871 opPtr.p->m_coordinatorRef = senderRef;
11872 opPtr.p->m_isMaster = (senderRef == reference());
11873 opPtr.p->key = opKey;
11874 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_PREPARE;
11875 if (opPtr.p == &opBusy) {
11876 jam();
11877 opPtr.p->m_errorCode = BuildIndxRef::Busy;
11878 opPtr.p->m_errorLine = __LINE__;
11879 buildIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
11880 return;
11881 }
11882 c_opBuildIndex.add(opPtr);
11883 // master expects to hear from all
11884 opPtr.p->m_signalCounter = receiverNodes;
11885 buildIndex_sendReply(signal, opPtr, false);
11886 return;
11887 }
11888 c_opBuildIndex.find(opPtr, req->getConnectionPtr());
11889 if (! opPtr.isNull()) {
11890 opPtr.p->m_requestType = requestType;
11891 if (requestType == BuildIndxReq::RT_DICT_TRIX) {
11892 jam();
11893 buildIndex_buildTrix(signal, opPtr);
11894 return;
11895 }
11896 if (requestType == BuildIndxReq::RT_DICT_TC ||
11897 requestType == BuildIndxReq::RT_DICT_TUX) {
11898 jam();
11899 buildIndex_toOnline(signal, opPtr);
11900 return;
11901 }
11902 if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
11903 requestType == BuildIndxReq::RT_DICT_ABORT) {
11904 jam();
11905 buildIndex_sendReply(signal, opPtr, false);
11906 // done in slave
11907 if (! opPtr.p->m_isMaster)
11908 c_opBuildIndex.release(opPtr);
11909 return;
11910 }
11911 }
11912 jam();
11913 // return to sender
11914 OpBuildIndex opBad;
11915 opPtr.p = &opBad;
11916 opPtr.p->save(req);
11917 opPtr.p->m_errorCode = BuildIndxRef::BadRequestType;
11918 opPtr.p->m_errorLine = __LINE__;
11919 buildIndex_sendReply(signal, opPtr, true);
11920 }
11921
11922 void
execBUILDINDXCONF(Signal * signal)11923 Dbdict::execBUILDINDXCONF(Signal* signal)
11924 {
11925 jamEntry();
11926 ndbrequire(signal->getNoOfSections() == 0);
11927 BuildIndxConf* conf = (BuildIndxConf*)signal->getDataPtrSend();
11928 buildIndex_recvReply(signal, conf, 0);
11929 }
11930
11931 void
execBUILDINDXREF(Signal * signal)11932 Dbdict::execBUILDINDXREF(Signal* signal)
11933 {
11934 jamEntry();
11935 BuildIndxRef* ref = (BuildIndxRef*)signal->getDataPtrSend();
11936 buildIndex_recvReply(signal, ref->getConf(), ref);
11937 }
11938
11939 void
buildIndex_recvReply(Signal * signal,const BuildIndxConf * conf,const BuildIndxRef * ref)11940 Dbdict::buildIndex_recvReply(Signal* signal, const BuildIndxConf* conf,
11941 const BuildIndxRef* ref)
11942 {
11943 jam();
11944 const Uint32 senderRef = signal->senderBlockRef();
11945 const BuildIndxReq::RequestType requestType = conf->getRequestType();
11946 const Uint32 key = conf->getConnectionPtr();
11947 if (requestType == BuildIndxReq::RT_ALTER_INDEX) {
11948 jam();
11949 // part of alter index operation
11950 OpAlterIndexPtr opPtr;
11951 c_opAlterIndex.find(opPtr, key);
11952 ndbrequire(! opPtr.isNull());
11953 opPtr.p->setError(ref);
11954 alterIndex_fromBuildIndex(signal, opPtr);
11955 return;
11956 }
11957
11958 if (requestType == BuildIndxReq::RT_SYSTEMRESTART) {
11959 jam();
11960 if (ref == 0) {
11961 infoEvent("DICT: index %u rebuild done", (unsigned)key);
11962 } else {
11963 warningEvent("DICT: index %u rebuild failed: code=%d line=%d node=%d",
11964 (unsigned)key, ref->getErrorCode());
11965 }
11966 rebuildIndexes(signal, key + 1);
11967 return;
11968 }
11969
11970 OpBuildIndexPtr opPtr;
11971 c_opBuildIndex.find(opPtr, key);
11972 ndbrequire(! opPtr.isNull());
11973 opPtr.p->setError(ref);
11974 if (requestType == BuildIndxReq::RT_TRIX) {
11975 jam();
11976 // forward to master
11977 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
11978 buildIndex_sendReply(signal, opPtr, false);
11979 return;
11980 }
11981 ndbrequire(opPtr.p->m_isMaster);
11982 ndbrequire(opPtr.p->m_requestType == requestType);
11983 opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
11984 if (! opPtr.p->m_signalCounter.done()) {
11985 jam();
11986 return;
11987 }
11988 if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
11989 requestType == BuildIndxReq::RT_DICT_ABORT) {
11990 jam();
11991 // send reply to user
11992 buildIndex_sendReply(signal, opPtr, true);
11993 c_opBuildIndex.release(opPtr);
11994 return;
11995 }
11996 if (opPtr.p->hasError()) {
11997 jam();
11998 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
11999 buildIndex_sendSlaveReq(signal, opPtr);
12000 return;
12001 }
12002 TableRecordPtr indexPtr;
12003 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
12004 if (indexPtr.p->isHashIndex()) {
12005 if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
12006 jam();
12007 if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
12008 buildIndex_toCreateConstr(signal, opPtr);
12009 } else {
12010 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
12011 buildIndex_sendSlaveReq(signal, opPtr);
12012 }
12013 return;
12014 }
12015 if (requestType == BuildIndxReq::RT_DICT_TRIX) {
12016 jam();
12017 ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
12018 buildIndex_toDropConstr(signal, opPtr);
12019 return;
12020 }
12021 if (requestType == BuildIndxReq::RT_DICT_TC) {
12022 jam();
12023 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
12024 buildIndex_sendSlaveReq(signal, opPtr);
12025 return;
12026 }
12027 }
12028 if (indexPtr.p->isOrderedIndex()) {
12029 if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
12030 jam();
12031 if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
12032 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
12033 buildIndex_sendSlaveReq(signal, opPtr);
12034 } else {
12035 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
12036 buildIndex_sendSlaveReq(signal, opPtr);
12037 }
12038 return;
12039 }
12040 if (requestType == BuildIndxReq::RT_DICT_TRIX) {
12041 jam();
12042 ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
12043 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
12044 buildIndex_sendSlaveReq(signal, opPtr);
12045 return;
12046 }
12047 if (requestType == BuildIndxReq::RT_DICT_TUX) {
12048 jam();
12049 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
12050 buildIndex_sendSlaveReq(signal, opPtr);
12051 return;
12052 }
12053 }
12054 ndbrequire(false);
12055 }
12056
12057 void
buildIndex_toCreateConstr(Signal * signal,OpBuildIndexPtr opPtr)12058 Dbdict::buildIndex_toCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
12059 {
12060 jam();
12061 TableRecordPtr indexPtr;
12062 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
12063 // request to create constraint trigger
12064 CreateTrigReq* req = (CreateTrigReq*)signal->getDataPtrSend();
12065 req->setUserRef(reference());
12066 req->setConnectionPtr(opPtr.p->key);
12067 req->setRequestType(CreateTrigReq::RT_BUILD_INDEX);
12068 req->addRequestFlag(0); // none
12069 req->setTableId(indexPtr.i);
12070 req->setIndexId(RNIL);
12071 req->setTriggerId(RNIL);
12072 req->setTriggerType(TriggerType::READ_ONLY_CONSTRAINT);
12073 req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
12074 req->setTriggerEvent(TriggerEvent::TE_UPDATE);
12075 req->setMonitorReplicas(false);
12076 req->setMonitorAllAttributes(false);
12077 req->setReportAllMonitoredAttributes(true);
12078 req->setOnline(true); // alter online after create
12079 req->setReceiverRef(0); // no receiver, REF-ed by TUP
12080 req->getAttributeMask().clear();
12081 // NDB$PK is last attribute
12082 req->getAttributeMask().set(indexPtr.p->noOfAttributes - 1);
12083 // name section
12084 char triggerName[MAX_TAB_NAME_SIZE];
12085 Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)]; // SP string
12086 LinearWriter w(buffer, sizeof(buffer) >> 2);
12087 LinearSectionPtr lsPtr[3];
12088 sprintf(triggerName, "NDB$INDEX_%u_BUILD", indexPtr.i);
12089 w.reset();
12090 w.add(CreateTrigReq::TriggerNameKey, triggerName);
12091 lsPtr[0].p = buffer;
12092 lsPtr[0].sz = w.getWordsUsed();
12093 sendSignal(reference(), GSN_CREATE_TRIG_REQ,
12094 signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
12095 }
12096
12097 void
buildIndex_fromCreateConstr(Signal * signal,OpBuildIndexPtr opPtr)12098 Dbdict::buildIndex_fromCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
12099 {
12100 jam();
12101 if (opPtr.p->hasError()) {
12102 jam();
12103 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
12104 buildIndex_sendSlaveReq(signal, opPtr);
12105 return;
12106 }
12107 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
12108 buildIndex_sendSlaveReq(signal, opPtr);
12109 }
12110
12111 void
buildIndex_buildTrix(Signal * signal,OpBuildIndexPtr opPtr)12112 Dbdict::buildIndex_buildTrix(Signal* signal, OpBuildIndexPtr opPtr)
12113 {
12114 jam();
12115 TableRecordPtr indexPtr;
12116 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
12117 TableRecordPtr tablePtr;
12118 c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
12119 // build request
12120 BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
12121 req->setUserRef(reference());
12122 req->setConnectionPtr(opPtr.p->key);
12123 req->setRequestType(BuildIndxReq::RT_TRIX);
12124 req->setBuildId(0); // not yet..
12125 req->setBuildKey(0); // ..in use
12126 req->setIndexType(indexPtr.p->tableType);
12127 req->setIndexId(indexPtr.i);
12128 req->setTableId(indexPtr.p->primaryTableId);
12129 req->setParallelism(16);
12130 if (indexPtr.p->isHashIndex()) {
12131 jam();
12132 getIndexAttrList(indexPtr, opPtr.p->m_attrList);
12133 getTableKeyList(tablePtr, opPtr.p->m_tableKeyList);
12134 // send
12135 LinearSectionPtr lsPtr[3];
12136 lsPtr[0].sz = opPtr.p->m_attrList.sz;
12137 lsPtr[0].p = opPtr.p->m_attrList.id;
12138 lsPtr[1].sz = opPtr.p->m_tableKeyList.sz;
12139 lsPtr[1].p = opPtr.p->m_tableKeyList.id;
12140 sendSignal(calcTrixBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
12141 signal, BuildIndxReq::SignalLength, JBB, lsPtr, 2);
12142 return;
12143 }
12144 if (indexPtr.p->isOrderedIndex()) {
12145 jam();
12146 sendSignal(calcTupBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
12147 signal, BuildIndxReq::SignalLength, JBB);
12148 return;
12149 }
12150 ndbrequire(false);
12151 }
12152
12153 void
buildIndex_toDropConstr(Signal * signal,OpBuildIndexPtr opPtr)12154 Dbdict::buildIndex_toDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
12155 {
12156 jam();
12157 TableRecordPtr indexPtr;
12158 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
12159 // request to drop constraint trigger
12160 DropTrigReq* req = (DropTrigReq*)signal->getDataPtrSend();
12161 req->setUserRef(reference());
12162 req->setConnectionPtr(opPtr.p->key);
12163 req->setRequestType(DropTrigReq::RT_BUILD_INDEX);
12164 req->addRequestFlag(0); // none
12165 req->setTableId(indexPtr.i);
12166 req->setIndexId(RNIL);
12167 req->setTriggerId(opPtr.p->m_constrTriggerId);
12168 req->setTriggerInfo(0); // not used
12169 sendSignal(reference(), GSN_DROP_TRIG_REQ,
12170 signal, DropTrigReq::SignalLength, JBB);
12171 }
12172
12173 void
buildIndex_fromDropConstr(Signal * signal,OpBuildIndexPtr opPtr)12174 Dbdict::buildIndex_fromDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
12175 {
12176 jam();
12177 if (opPtr.p->hasError()) {
12178 jam();
12179 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
12180 buildIndex_sendSlaveReq(signal, opPtr);
12181 return;
12182 }
12183 opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
12184 buildIndex_sendSlaveReq(signal, opPtr);
12185 }
12186
12187 void
buildIndex_toOnline(Signal * signal,OpBuildIndexPtr opPtr)12188 Dbdict::buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr)
12189 {
12190 jam();
12191 TableRecordPtr indexPtr;
12192 c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
12193 TableRecordPtr tablePtr;
12194 c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
12195 // request to set index online in TC or TUX
12196 AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
12197 req->setUserRef(reference());
12198 req->setConnectionPtr(opPtr.p->key);
12199 if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
12200 jam();
12201 req->setRequestType(AlterIndxReq::RT_TC);
12202 } else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
12203 jam();
12204 req->setRequestType(AlterIndxReq::RT_TUX);
12205 } else {
12206 ndbrequire(false);
12207 }
12208 req->setTableId(tablePtr.i);
12209 req->setIndexId(indexPtr.i);
12210 req->setIndexVersion(indexPtr.p->tableVersion);
12211 req->setOnline(true);
12212 BlockReference blockRef = 0;
12213 if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
12214 jam();
12215 blockRef = calcTcBlockRef(getOwnNodeId());
12216 } else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
12217 jam();
12218 blockRef = calcTuxBlockRef(getOwnNodeId());
12219 } else {
12220 ndbrequire(false);
12221 }
12222 // send
12223 sendSignal(blockRef, GSN_ALTER_INDX_REQ,
12224 signal, BuildIndxReq::SignalLength, JBB);
12225 }
12226
12227 void
buildIndex_fromOnline(Signal * signal,OpBuildIndexPtr opPtr)12228 Dbdict::buildIndex_fromOnline(Signal* signal, OpBuildIndexPtr opPtr)
12229 {
12230 jam();
12231 // forward to master
12232 buildIndex_sendReply(signal, opPtr, false);
12233 }
12234
12235 void
buildIndex_sendSlaveReq(Signal * signal,OpBuildIndexPtr opPtr)12236 Dbdict::buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr)
12237 {
12238 BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
12239 *req = opPtr.p->m_request;
12240 req->setUserRef(opPtr.p->m_coordinatorRef);
12241 req->setConnectionPtr(opPtr.p->key);
12242 req->setRequestType(opPtr.p->m_requestType);
12243 req->addRequestFlag(opPtr.p->m_requestFlag);
12244 if(opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
12245 jam();
12246 opPtr.p->m_signalCounter.clearWaitingFor();
12247 opPtr.p->m_signalCounter.setWaitingFor(getOwnNodeId());
12248 sendSignal(reference(), GSN_BUILDINDXREQ,
12249 signal, BuildIndxReq::SignalLength, JBB);
12250 } else {
12251 jam();
12252 opPtr.p->m_signalCounter = c_aliveNodes;
12253 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
12254 sendSignal(rg, GSN_BUILDINDXREQ,
12255 signal, BuildIndxReq::SignalLength, JBB);
12256 }
12257 }
12258
12259 void
buildIndex_sendReply(Signal * signal,OpBuildIndexPtr opPtr,bool toUser)12260 Dbdict::buildIndex_sendReply(Signal* signal, OpBuildIndexPtr opPtr,
12261 bool toUser)
12262 {
12263 BuildIndxRef* rep = (BuildIndxRef*)signal->getDataPtrSend();
12264 Uint32 gsn = GSN_BUILDINDXCONF;
12265 Uint32 length = BuildIndxConf::InternalLength;
12266 bool sendRef;
12267 if (! toUser) {
12268 sendRef = opPtr.p->hasLastError();
12269 rep->setUserRef(opPtr.p->m_coordinatorRef);
12270 rep->setConnectionPtr(opPtr.p->key);
12271 rep->setRequestType(opPtr.p->m_requestType);
12272 if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_ABORT)
12273 sendRef = false;
12274 } else {
12275 sendRef = opPtr.p->hasError();
12276 rep->setUserRef(opPtr.p->m_request.getUserRef());
12277 rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
12278 rep->setRequestType(opPtr.p->m_request.getRequestType());
12279 length = BuildIndxConf::SignalLength;
12280 }
12281 rep->setIndexType(opPtr.p->m_request.getIndexType());
12282 rep->setTableId(opPtr.p->m_request.getTableId());
12283 rep->setIndexId(opPtr.p->m_request.getIndexId());
12284 if (sendRef) {
12285 rep->setErrorCode(opPtr.p->m_errorCode);
12286 rep->masterNodeId = opPtr.p->m_errorNode;
12287 gsn = GSN_BUILDINDXREF;
12288 length = BuildIndxRef::SignalLength;
12289 }
12290 sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
12291 }
12292
12293 /**
12294 * MODULE: Create trigger
12295 *
12296 * Create trigger in all DICT blocks. Optionally start alter trigger
12297 * operation to set the trigger online.
12298 *
12299 * Request type received in REQ and returned in CONF/REF:
12300 *
12301 * RT_USER - normal user e.g. BACKUP
12302 * RT_ALTER_INDEX - from alter index online
12303 * RT_DICT_PREPARE - seize operation in each DICT
12304 * RT_DICT_COMMIT - commit create in each DICT
12305 * RT_TC - sending to TC (operation alter trigger)
12306 * RT_LQH - sending to LQH (operation alter trigger)
12307 */
12308
12309 void
execCREATE_TRIG_REQ(Signal * signal)12310 Dbdict::execCREATE_TRIG_REQ(Signal* signal)
12311 {
12312 jamEntry();
12313 CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
12314 OpCreateTriggerPtr opPtr;
12315 const Uint32 senderRef = signal->senderBlockRef();
12316 const CreateTrigReq::RequestType requestType = req->getRequestType();
12317 if (requestType == CreateTrigReq::RT_USER ||
12318 requestType == CreateTrigReq::RT_ALTER_INDEX ||
12319 requestType == CreateTrigReq::RT_BUILD_INDEX) {
12320 jam();
12321 if (! assembleFragments(signal)) {
12322 jam();
12323 return;
12324 }
12325 const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
12326 NdbNodeBitmask receiverNodes = c_aliveNodes;
12327 if (isLocal) {
12328 receiverNodes.clear();
12329 receiverNodes.set(getOwnNodeId());
12330 }
12331 if (signal->getLength() == CreateTrigReq::SignalLength) {
12332 jam();
12333 if (! isLocal && getOwnNodeId() != c_masterNodeId) {
12334 jam();
12335
12336 releaseSections(signal);
12337 OpCreateTrigger opBad;
12338 opPtr.p = &opBad;
12339 opPtr.p->save(req);
12340 opPtr.p->m_errorCode = CreateTrigRef::NotMaster;
12341 opPtr.p->m_errorLine = __LINE__;
12342 opPtr.p->m_errorNode = c_masterNodeId;
12343 createTrigger_sendReply(signal, opPtr, true);
12344 return;
12345 }
12346 // forward initial request plus operation key to all
12347 req->setOpKey(++c_opRecordSequence);
12348 NodeReceiverGroup rg(DBDICT, receiverNodes);
12349 sendSignal(rg, GSN_CREATE_TRIG_REQ,
12350 signal, CreateTrigReq::SignalLength + 1, JBB);
12351 return;
12352 }
12353 // seize operation record
12354 ndbrequire(signal->getLength() == CreateTrigReq::SignalLength + 1);
12355 const Uint32 opKey = req->getOpKey();
12356 OpCreateTrigger opBusy;
12357 if (! c_opCreateTrigger.seize(opPtr))
12358 opPtr.p = &opBusy;
12359 opPtr.p->save(req);
12360 opPtr.p->m_coordinatorRef = senderRef;
12361 opPtr.p->m_isMaster = (senderRef == reference());
12362 opPtr.p->key = opKey;
12363 opPtr.p->m_requestType = CreateTrigReq::RT_DICT_PREPARE;
12364 if (opPtr.p == &opBusy) {
12365 jam();
12366 opPtr.p->m_errorCode = CreateTrigRef::Busy;
12367 opPtr.p->m_errorLine = __LINE__;
12368 releaseSections(signal);
12369 createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
12370 return;
12371 }
12372 c_opCreateTrigger.add(opPtr);
12373 {
12374 // save name
12375 SegmentedSectionPtr ssPtr;
12376 signal->getSection(ssPtr, CreateTrigReq::TRIGGER_NAME_SECTION);
12377 SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
12378 if (ssReader.getKey() != CreateTrigReq::TriggerNameKey ||
12379 ! ssReader.getString(opPtr.p->m_triggerName)) {
12380 jam();
12381 opPtr.p->m_errorCode = CreateTrigRef::InvalidName;
12382 opPtr.p->m_errorLine = __LINE__;
12383 releaseSections(signal);
12384 createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
12385 return;
12386 }
12387 }
12388 releaseSections(signal);
12389 if(get_object(opPtr.p->m_triggerName) != 0){
12390 jam();
12391 opPtr.p->m_errorCode = CreateTrigRef::TriggerExists;
12392 opPtr.p->m_errorLine = __LINE__;
12393 createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
12394 return;
12395 }
12396
12397 // master expects to hear from all
12398 if (opPtr.p->m_isMaster)
12399 opPtr.p->m_signalCounter = receiverNodes;
12400 // check request in all participants
12401 createTrigger_slavePrepare(signal, opPtr);
12402 createTrigger_sendReply(signal, opPtr, false);
12403 return;
12404 }
12405 c_opCreateTrigger.find(opPtr, req->getConnectionPtr());
12406 if (! opPtr.isNull()) {
12407 opPtr.p->m_requestType = requestType;
12408 if (requestType == CreateTrigReq::RT_DICT_CREATE) {
12409 jam();
12410 // master has set trigger id
12411 opPtr.p->m_request.setTriggerId(req->getTriggerId());
12412 createTrigger_slaveCreate(signal, opPtr);
12413 createTrigger_sendReply(signal, opPtr, false);
12414 return;
12415 }
12416 if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
12417 requestType == CreateTrigReq::RT_DICT_ABORT) {
12418 jam();
12419 if (requestType == CreateTrigReq::RT_DICT_COMMIT)
12420 createTrigger_slaveCommit(signal, opPtr);
12421 else
12422 createTrigger_slaveAbort(signal, opPtr);
12423 createTrigger_sendReply(signal, opPtr, false);
12424 // done in slave
12425 if (! opPtr.p->m_isMaster)
12426 c_opCreateTrigger.release(opPtr);
12427 return;
12428 }
12429 }
12430 jam();
12431 // return to sender
12432 releaseSections(signal);
12433 OpCreateTrigger opBad;
12434 opPtr.p = &opBad;
12435 opPtr.p->save(req);
12436 opPtr.p->m_errorCode = CreateTrigRef::BadRequestType;
12437 opPtr.p->m_errorLine = __LINE__;
12438 createTrigger_sendReply(signal, opPtr, true);
12439 }
12440
12441 void
execCREATE_TRIG_CONF(Signal * signal)12442 Dbdict::execCREATE_TRIG_CONF(Signal* signal)
12443 {
12444 jamEntry();
12445 ndbrequire(signal->getNoOfSections() == 0);
12446 CreateTrigConf* conf = (CreateTrigConf*)signal->getDataPtrSend();
12447 createTrigger_recvReply(signal, conf, 0);
12448 }
12449
12450 void
execCREATE_TRIG_REF(Signal * signal)12451 Dbdict::execCREATE_TRIG_REF(Signal* signal)
12452 {
12453 jamEntry();
12454 CreateTrigRef* ref = (CreateTrigRef*)signal->getDataPtrSend();
12455 createTrigger_recvReply(signal, ref->getConf(), ref);
12456 }
12457
12458 void
createTrigger_recvReply(Signal * signal,const CreateTrigConf * conf,const CreateTrigRef * ref)12459 Dbdict::createTrigger_recvReply(Signal* signal, const CreateTrigConf* conf,
12460 const CreateTrigRef* ref)
12461 {
12462 jam();
12463 const Uint32 senderRef = signal->senderBlockRef();
12464 const CreateTrigReq::RequestType requestType = conf->getRequestType();
12465 const Uint32 key = conf->getConnectionPtr();
12466 if (requestType == CreateTrigReq::RT_ALTER_INDEX) {
12467 jam();
12468 // part of alter index operation
12469 OpAlterIndexPtr opPtr;
12470 c_opAlterIndex.find(opPtr, key);
12471 ndbrequire(! opPtr.isNull());
12472 opPtr.p->setError(ref);
12473 alterIndex_fromCreateTrigger(signal, opPtr);
12474 return;
12475 }
12476 if (requestType == CreateTrigReq::RT_BUILD_INDEX) {
12477 jam();
12478 // part of build index operation
12479 OpBuildIndexPtr opPtr;
12480 c_opBuildIndex.find(opPtr, key);
12481 ndbrequire(! opPtr.isNull());
12482 opPtr.p->setError(ref);
12483 // fill in trigger id
12484 opPtr.p->m_constrTriggerId = conf->getTriggerId();
12485 buildIndex_fromCreateConstr(signal, opPtr);
12486 return;
12487 }
12488 if (requestType == CreateTrigReq::RT_TC ||
12489 requestType == CreateTrigReq::RT_LQH) {
12490 jam();
12491 // part of alter trigger operation
12492 OpAlterTriggerPtr opPtr;
12493 c_opAlterTrigger.find(opPtr, key);
12494 ndbrequire(! opPtr.isNull());
12495 opPtr.p->setError(ref);
12496 alterTrigger_fromCreateLocal(signal, opPtr);
12497 return;
12498 }
12499 OpCreateTriggerPtr opPtr;
12500 c_opCreateTrigger.find(opPtr, key);
12501 ndbrequire(! opPtr.isNull());
12502 ndbrequire(opPtr.p->m_isMaster);
12503 ndbrequire(opPtr.p->m_requestType == requestType);
12504 opPtr.p->setError(ref);
12505 opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
12506 if (! opPtr.p->m_signalCounter.done()) {
12507 jam();
12508 return;
12509 }
12510 if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
12511 requestType == CreateTrigReq::RT_DICT_ABORT) {
12512 jam();
12513 // send reply to user
12514 createTrigger_sendReply(signal, opPtr, true);
12515 c_opCreateTrigger.release(opPtr);
12516 return;
12517 }
12518 if (opPtr.p->hasError()) {
12519 jam();
12520 opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
12521 createTrigger_sendSlaveReq(signal, opPtr);
12522 return;
12523 }
12524 if (requestType == CreateTrigReq::RT_DICT_PREPARE) {
12525 jam();
12526 // seize trigger id in master
12527 createTrigger_masterSeize(signal, opPtr);
12528 if (opPtr.p->hasError()) {
12529 jam();
12530 opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
12531 createTrigger_sendSlaveReq(signal, opPtr);
12532 return;
12533 }
12534 opPtr.p->m_requestType = CreateTrigReq::RT_DICT_CREATE;
12535 createTrigger_sendSlaveReq(signal, opPtr);
12536 return;
12537 }
12538 if (requestType == CreateTrigReq::RT_DICT_CREATE) {
12539 jam();
12540 if (opPtr.p->m_request.getOnline()) {
12541 jam();
12542 // start alter online
12543 createTrigger_toAlterTrigger(signal, opPtr);
12544 return;
12545 }
12546 opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
12547 createTrigger_sendSlaveReq(signal, opPtr);
12548 return;
12549 }
12550 ndbrequire(false);
12551 }
12552
12553 void
createTrigger_slavePrepare(Signal * signal,OpCreateTriggerPtr opPtr)12554 Dbdict::createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr)
12555 {
12556 jam();
12557 const CreateTrigReq* const req = &opPtr.p->m_request;
12558 // check trigger type
12559 if (req->getRequestType() == CreateTrigReq::RT_USER &&
12560 req->getTriggerType() == TriggerType::SUBSCRIPTION ||
12561 req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
12562 req->getTriggerType() == TriggerType::SECONDARY_INDEX ||
12563 req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
12564 req->getTriggerType() == TriggerType::ORDERED_INDEX ||
12565 req->getRequestType() == CreateTrigReq::RT_BUILD_INDEX &&
12566 req->getTriggerType() == TriggerType::READ_ONLY_CONSTRAINT) {
12567 ;
12568 } else {
12569 jam();
12570 opPtr.p->m_errorCode = CreateTrigRef::UnsupportedTriggerType;
12571 opPtr.p->m_errorLine = __LINE__;
12572 return;
12573 }
12574 // check the table
12575 const Uint32 tableId = req->getTableId();
12576 if (! (tableId < c_tableRecordPool.getSize())) {
12577 jam();
12578 opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
12579 opPtr.p->m_errorLine = __LINE__;
12580 return;
12581 }
12582 TableRecordPtr tablePtr;
12583 c_tableRecordPool.getPtr(tablePtr, tableId);
12584 if (tablePtr.p->tabState != TableRecord::DEFINED &&
12585 tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
12586 jam();
12587 opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
12588 opPtr.p->m_errorLine = __LINE__;
12589 return;
12590 }
12591 }
12592
12593 void
createTrigger_masterSeize(Signal * signal,OpCreateTriggerPtr opPtr)12594 Dbdict::createTrigger_masterSeize(Signal* signal, OpCreateTriggerPtr opPtr)
12595 {
12596 TriggerRecordPtr triggerPtr;
12597 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
12598 triggerPtr.i = opPtr.p->m_request.getTriggerId();
12599 } else {
12600 triggerPtr.i = getFreeTriggerRecord();
12601 if (triggerPtr.i == RNIL) {
12602 jam();
12603 opPtr.p->m_errorCode = CreateTrigRef::TooManyTriggers;
12604 opPtr.p->m_errorLine = __LINE__;
12605 return;
12606 }
12607 }
12608 c_triggerRecordPool.getPtr(triggerPtr);
12609 initialiseTriggerRecord(triggerPtr);
12610 triggerPtr.p->triggerState = TriggerRecord::TS_DEFINING;
12611 opPtr.p->m_request.setTriggerId(triggerPtr.i);
12612 }
12613
12614 void
createTrigger_slaveCreate(Signal * signal,OpCreateTriggerPtr opPtr)12615 Dbdict::createTrigger_slaveCreate(Signal* signal, OpCreateTriggerPtr opPtr)
12616 {
12617 jam();
12618 const CreateTrigReq* const req = &opPtr.p->m_request;
12619 // get the trigger record
12620 const Uint32 triggerId = req->getTriggerId();
12621 TriggerRecordPtr triggerPtr;
12622 c_triggerRecordPool.getPtr(triggerPtr, triggerId);
12623 initialiseTriggerRecord(triggerPtr);
12624 // fill in trigger data
12625 {
12626 Rope name(c_rope_pool, triggerPtr.p->triggerName);
12627 if(!name.assign(opPtr.p->m_triggerName))
12628 {
12629 opPtr.p->m_errorCode = (CreateTrigRef::ErrorCode)CreateTableRef::OutOfStringBuffer;
12630 return;
12631 }
12632 }
12633 triggerPtr.p->triggerId = triggerId;
12634 triggerPtr.p->tableId = req->getTableId();
12635 triggerPtr.p->indexId = RNIL;
12636 triggerPtr.p->triggerType = req->getTriggerType();
12637 triggerPtr.p->triggerActionTime = req->getTriggerActionTime();
12638 triggerPtr.p->triggerEvent = req->getTriggerEvent();
12639 triggerPtr.p->monitorReplicas = req->getMonitorReplicas();
12640 triggerPtr.p->monitorAllAttributes = req->getMonitorAllAttributes();
12641 triggerPtr.p->reportAllMonitoredAttributes = req->getReportAllMonitoredAttributes();
12642 triggerPtr.p->attributeMask = req->getAttributeMask();
12643 triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
12644 // add to hash table
12645 // ndbout_c("++++++++++++ Adding trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
12646 {
12647 Ptr<DictObject> obj_ptr;
12648 ndbrequire(c_obj_hash.seize(obj_ptr));
12649 obj_ptr.p->m_name = triggerPtr.p->triggerName;
12650 obj_ptr.p->m_id = triggerId;
12651 obj_ptr.p->m_type = triggerPtr.p->triggerType;
12652 obj_ptr.p->m_ref_count = 0;
12653 c_obj_hash.add(obj_ptr);
12654 triggerPtr.p->m_obj_ptr_i = obj_ptr.i;
12655 }
12656 if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
12657 triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
12658 jam();
12659 // connect to index record XXX should be done in caller instead
12660 triggerPtr.p->indexId = req->getIndexId();
12661 TableRecordPtr indexPtr;
12662 c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
12663 switch (triggerPtr.p->triggerEvent) {
12664 case TriggerEvent::TE_INSERT:
12665 indexPtr.p->insertTriggerId = triggerPtr.p->triggerId;
12666 break;
12667 case TriggerEvent::TE_UPDATE:
12668 indexPtr.p->updateTriggerId = triggerPtr.p->triggerId;
12669 break;
12670 case TriggerEvent::TE_DELETE:
12671 indexPtr.p->deleteTriggerId = triggerPtr.p->triggerId;
12672 break;
12673 case TriggerEvent::TE_CUSTOM:
12674 indexPtr.p->customTriggerId = triggerPtr.p->triggerId;
12675 break;
12676 default:
12677 ndbrequire(false);
12678 break;
12679 }
12680 }
12681 if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
12682 jam();
12683 // connect to index record XXX should be done in caller instead
12684 triggerPtr.p->indexId = req->getTableId();
12685 TableRecordPtr indexPtr;
12686 c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
12687 indexPtr.p->buildTriggerId = triggerPtr.p->triggerId;
12688 }
12689 }
12690
12691 void
createTrigger_toAlterTrigger(Signal * signal,OpCreateTriggerPtr opPtr)12692 Dbdict::createTrigger_toAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
12693 {
12694 jam();
12695 AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
12696 req->setUserRef(reference());
12697 req->setConnectionPtr(opPtr.p->key);
12698 req->setRequestType(AlterTrigReq::RT_CREATE_TRIGGER);
12699 req->addRequestFlag(opPtr.p->m_requestFlag);
12700 req->setTableId(opPtr.p->m_request.getTableId());
12701 req->setTriggerId(opPtr.p->m_request.getTriggerId());
12702 req->setTriggerInfo(0); // not used
12703 req->setOnline(true);
12704 req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
12705 sendSignal(reference(), GSN_ALTER_TRIG_REQ,
12706 signal, AlterTrigReq::SignalLength, JBB);
12707 }
12708
12709 void
createTrigger_fromAlterTrigger(Signal * signal,OpCreateTriggerPtr opPtr)12710 Dbdict::createTrigger_fromAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
12711 {
12712 jam();
12713 if (opPtr.p->hasError()) {
12714 jam();
12715 opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
12716 createTrigger_sendSlaveReq(signal, opPtr);
12717 return;
12718 }
12719 opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
12720 createTrigger_sendSlaveReq(signal, opPtr);
12721 }
12722
12723 void
createTrigger_slaveCommit(Signal * signal,OpCreateTriggerPtr opPtr)12724 Dbdict::createTrigger_slaveCommit(Signal* signal, OpCreateTriggerPtr opPtr)
12725 {
12726 jam();
12727 const CreateTrigReq* const req = &opPtr.p->m_request;
12728 // get the trigger record
12729 const Uint32 triggerId = req->getTriggerId();
12730 TriggerRecordPtr triggerPtr;
12731 c_triggerRecordPool.getPtr(triggerPtr, triggerId);
12732 if (! req->getOnline()) {
12733 triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
12734 } else {
12735 ndbrequire(triggerPtr.p->triggerState == TriggerRecord::TS_ONLINE);
12736 }
12737 }
12738
12739 void
createTrigger_slaveAbort(Signal * signal,OpCreateTriggerPtr opPtr)12740 Dbdict::createTrigger_slaveAbort(Signal* signal, OpCreateTriggerPtr opPtr)
12741 {
12742 jam();
12743 }
12744
12745 void
createTrigger_sendSlaveReq(Signal * signal,OpCreateTriggerPtr opPtr)12746 Dbdict::createTrigger_sendSlaveReq(Signal* signal, OpCreateTriggerPtr opPtr)
12747 {
12748 CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
12749 *req = opPtr.p->m_request;
12750 req->setUserRef(opPtr.p->m_coordinatorRef);
12751 req->setConnectionPtr(opPtr.p->key);
12752 req->setRequestType(opPtr.p->m_requestType);
12753 req->addRequestFlag(opPtr.p->m_requestFlag);
12754 NdbNodeBitmask receiverNodes = c_aliveNodes;
12755 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
12756 receiverNodes.clear();
12757 receiverNodes.set(getOwnNodeId());
12758 }
12759 opPtr.p->m_signalCounter = receiverNodes;
12760 NodeReceiverGroup rg(DBDICT, receiverNodes);
12761 sendSignal(rg, GSN_CREATE_TRIG_REQ,
12762 signal, CreateTrigReq::SignalLength, JBB);
12763 }
12764
12765 void
createTrigger_sendReply(Signal * signal,OpCreateTriggerPtr opPtr,bool toUser)12766 Dbdict::createTrigger_sendReply(Signal* signal, OpCreateTriggerPtr opPtr,
12767 bool toUser)
12768 {
12769 CreateTrigRef* rep = (CreateTrigRef*)signal->getDataPtrSend();
12770 Uint32 gsn = GSN_CREATE_TRIG_CONF;
12771 Uint32 length = CreateTrigConf::InternalLength;
12772 bool sendRef;
12773 if (! toUser) {
12774 sendRef = opPtr.p->hasLastError();
12775 rep->setUserRef(opPtr.p->m_coordinatorRef);
12776 rep->setConnectionPtr(opPtr.p->key);
12777 rep->setRequestType(opPtr.p->m_requestType);
12778 if (opPtr.p->m_requestType == CreateTrigReq::RT_DICT_ABORT)
12779 sendRef = false;
12780 } else {
12781 sendRef = opPtr.p->hasError();
12782 rep->setUserRef(opPtr.p->m_request.getUserRef());
12783 rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
12784 rep->setRequestType(opPtr.p->m_request.getRequestType());
12785 length = CreateTrigConf::SignalLength;
12786 }
12787 rep->setTableId(opPtr.p->m_request.getTableId());
12788 rep->setIndexId(opPtr.p->m_request.getIndexId());
12789 rep->setTriggerId(opPtr.p->m_request.getTriggerId());
12790 rep->setTriggerInfo(opPtr.p->m_request.getTriggerInfo());
12791 if (sendRef) {
12792 if (opPtr.p->m_errorNode == 0)
12793 opPtr.p->m_errorNode = getOwnNodeId();
12794 rep->setErrorCode(opPtr.p->m_errorCode);
12795 rep->setErrorLine(opPtr.p->m_errorLine);
12796 rep->setErrorNode(opPtr.p->m_errorNode);
12797 gsn = GSN_CREATE_TRIG_REF;
12798 length = CreateTrigRef::SignalLength;
12799 }
12800 sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
12801 }
12802
12803 /**
12804 * MODULE: Drop trigger.
12805 */
12806
12807 void
execDROP_TRIG_REQ(Signal * signal)12808 Dbdict::execDROP_TRIG_REQ(Signal* signal)
12809 {
12810 jamEntry();
12811 DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
12812 OpDropTriggerPtr opPtr;
12813 const Uint32 senderRef = signal->senderBlockRef();
12814 const DropTrigReq::RequestType requestType = req->getRequestType();
12815
12816 if (signal->getNoOfSections() > 0) {
12817 ndbrequire(signal->getNoOfSections() == 1);
12818 jam();
12819 char triggerName[MAX_TAB_NAME_SIZE];
12820 OpDropTrigger opTmp;
12821 opPtr.p=&opTmp;
12822
12823 SegmentedSectionPtr ssPtr;
12824 signal->getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
12825 SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
12826 if (ssReader.getKey() != DropTrigReq::TriggerNameKey ||
12827 ! ssReader.getString(triggerName)) {
12828 jam();
12829 opPtr.p->m_errorCode = DropTrigRef::InvalidName;
12830 opPtr.p->m_errorLine = __LINE__;
12831 releaseSections(signal);
12832 dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
12833 return;
12834 }
12835 releaseSections(signal);
12836
12837 //ndbout_c("++++++++++++++ Looking for trigger %s", keyRecord.triggerName);
12838 DictObject * obj_ptr_p = get_object(triggerName);
12839 if (obj_ptr_p == 0){
12840 jam();
12841 req->setTriggerId(RNIL);
12842 } else {
12843 jam();
12844 //ndbout_c("++++++++++ Found trigger %s", triggerPtr.p->triggerName);
12845 TriggerRecordPtr triggerPtr;
12846 c_triggerRecordPool.getPtr(triggerPtr, obj_ptr_p->m_id);
12847 req->setTriggerId(triggerPtr.p->triggerId);
12848 req->setTableId(triggerPtr.p->tableId);
12849 }
12850 }
12851 if (requestType == DropTrigReq::RT_USER ||
12852 requestType == DropTrigReq::RT_ALTER_INDEX ||
12853 requestType == DropTrigReq::RT_BUILD_INDEX) {
12854 jam();
12855 if (signal->getLength() == DropTrigReq::SignalLength) {
12856 if (getOwnNodeId() != c_masterNodeId) {
12857 jam();
12858 // forward to DICT master
12859 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_DROP_TRIG_REQ,
12860 signal, signal->getLength(), JBB);
12861 return;
12862 }
12863 if (!c_triggerRecordPool.findId(req->getTriggerId())) {
12864 jam();
12865 // return to sender
12866 OpDropTrigger opBad;
12867 opPtr.p = &opBad;
12868 opPtr.p->save(req);
12869 if (! (req->getRequestFlag() & RequestFlag::RF_FORCE)) {
12870 opPtr.p->m_errorCode = DropTrigRef::TriggerNotFound;
12871 opPtr.p->m_errorLine = __LINE__;
12872 }
12873 dropTrigger_sendReply(signal, opPtr, true);
12874 return;
12875 }
12876 // forward initial request plus operation key to all
12877 req->setOpKey(++c_opRecordSequence);
12878 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
12879 sendSignal(rg, GSN_DROP_TRIG_REQ,
12880 signal, DropTrigReq::SignalLength + 1, JBB);
12881 return;
12882 }
12883 // seize operation record
12884 ndbrequire(signal->getLength() == DropTrigReq::SignalLength + 1);
12885 const Uint32 opKey = req->getOpKey();
12886 OpDropTrigger opBusy;
12887 if (! c_opDropTrigger.seize(opPtr))
12888 opPtr.p = &opBusy;
12889 opPtr.p->save(req);
12890 opPtr.p->m_coordinatorRef = senderRef;
12891 opPtr.p->m_isMaster = (senderRef == reference());
12892 opPtr.p->key = opKey;
12893 opPtr.p->m_requestType = DropTrigReq::RT_DICT_PREPARE;
12894 if (opPtr.p == &opBusy) {
12895 jam();
12896 opPtr.p->m_errorCode = DropTrigRef::Busy;
12897 opPtr.p->m_errorLine = __LINE__;
12898 dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
12899 return;
12900 }
12901 c_opDropTrigger.add(opPtr);
12902 // master expects to hear from all
12903 if (opPtr.p->m_isMaster)
12904 opPtr.p->m_signalCounter = c_aliveNodes;
12905 dropTrigger_slavePrepare(signal, opPtr);
12906 dropTrigger_sendReply(signal, opPtr, false);
12907 return;
12908 }
12909 c_opDropTrigger.find(opPtr, req->getConnectionPtr());
12910 if (! opPtr.isNull()) {
12911 opPtr.p->m_requestType = requestType;
12912 if (requestType == DropTrigReq::RT_DICT_COMMIT ||
12913 requestType == DropTrigReq::RT_DICT_ABORT) {
12914 jam();
12915 if (requestType == DropTrigReq::RT_DICT_COMMIT)
12916 dropTrigger_slaveCommit(signal, opPtr);
12917 else
12918 dropTrigger_slaveAbort(signal, opPtr);
12919 dropTrigger_sendReply(signal, opPtr, false);
12920 // done in slave
12921 if (! opPtr.p->m_isMaster)
12922 c_opDropTrigger.release(opPtr);
12923 return;
12924 }
12925 }
12926 jam();
12927 // return to sender
12928 OpDropTrigger opBad;
12929 opPtr.p = &opBad;
12930 opPtr.p->save(req);
12931 opPtr.p->m_errorCode = DropTrigRef::BadRequestType;
12932 opPtr.p->m_errorLine = __LINE__;
12933 dropTrigger_sendReply(signal, opPtr, true);
12934 }
12935
12936 void
execDROP_TRIG_CONF(Signal * signal)12937 Dbdict::execDROP_TRIG_CONF(Signal* signal)
12938 {
12939 jamEntry();
12940 DropTrigConf* conf = (DropTrigConf*)signal->getDataPtrSend();
12941 dropTrigger_recvReply(signal, conf, 0);
12942 }
12943
12944 void
execDROP_TRIG_REF(Signal * signal)12945 Dbdict::execDROP_TRIG_REF(Signal* signal)
12946 {
12947 jamEntry();
12948 DropTrigRef* ref = (DropTrigRef*)signal->getDataPtrSend();
12949 dropTrigger_recvReply(signal, ref->getConf(), ref);
12950 }
12951
12952 void
dropTrigger_recvReply(Signal * signal,const DropTrigConf * conf,const DropTrigRef * ref)12953 Dbdict::dropTrigger_recvReply(Signal* signal, const DropTrigConf* conf,
12954 const DropTrigRef* ref)
12955 {
12956 jam();
12957 const Uint32 senderRef = signal->senderBlockRef();
12958 const DropTrigReq::RequestType requestType = conf->getRequestType();
12959 const Uint32 key = conf->getConnectionPtr();
12960 if (requestType == DropTrigReq::RT_ALTER_INDEX) {
12961 jam();
12962 // part of alter index operation
12963 OpAlterIndexPtr opPtr;
12964 c_opAlterIndex.find(opPtr, key);
12965 ndbrequire(! opPtr.isNull());
12966 opPtr.p->setError(ref);
12967 alterIndex_fromDropTrigger(signal, opPtr);
12968 return;
12969 }
12970 if (requestType == DropTrigReq::RT_BUILD_INDEX) {
12971 jam();
12972 // part of build index operation
12973 OpBuildIndexPtr opPtr;
12974 c_opBuildIndex.find(opPtr, key);
12975 ndbrequire(! opPtr.isNull());
12976 opPtr.p->setError(ref);
12977 buildIndex_fromDropConstr(signal, opPtr);
12978 return;
12979 }
12980 if (requestType == DropTrigReq::RT_TC ||
12981 requestType == DropTrigReq::RT_LQH) {
12982 jam();
12983 // part of alter trigger operation
12984 OpAlterTriggerPtr opPtr;
12985 c_opAlterTrigger.find(opPtr, key);
12986 ndbrequire(! opPtr.isNull());
12987 opPtr.p->setError(ref);
12988 alterTrigger_fromDropLocal(signal, opPtr);
12989 return;
12990 }
12991 OpDropTriggerPtr opPtr;
12992 c_opDropTrigger.find(opPtr, key);
12993 ndbrequire(! opPtr.isNull());
12994 ndbrequire(opPtr.p->m_isMaster);
12995 ndbrequire(opPtr.p->m_requestType == requestType);
12996 opPtr.p->setError(ref);
12997 opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
12998 if (! opPtr.p->m_signalCounter.done()) {
12999 jam();
13000 return;
13001 }
13002 if (requestType == DropTrigReq::RT_DICT_COMMIT ||
13003 requestType == DropTrigReq::RT_DICT_ABORT) {
13004 jam();
13005 // send reply to user
13006 dropTrigger_sendReply(signal, opPtr, true);
13007 c_opDropTrigger.release(opPtr);
13008 return;
13009 }
13010 if (opPtr.p->hasError()) {
13011 jam();
13012 opPtr.p->m_requestType = DropTrigReq::RT_DICT_ABORT;
13013 dropTrigger_sendSlaveReq(signal, opPtr);
13014 return;
13015 }
13016 if (requestType == DropTrigReq::RT_DICT_PREPARE) {
13017 jam();
13018 // start alter offline
13019 dropTrigger_toAlterTrigger(signal, opPtr);
13020 return;
13021 }
13022 ndbrequire(false);
13023 }
13024
13025 void
dropTrigger_slavePrepare(Signal * signal,OpDropTriggerPtr opPtr)13026 Dbdict::dropTrigger_slavePrepare(Signal* signal, OpDropTriggerPtr opPtr)
13027 {
13028 jam();
13029 }
13030
13031 void
dropTrigger_toAlterTrigger(Signal * signal,OpDropTriggerPtr opPtr)13032 Dbdict::dropTrigger_toAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
13033 {
13034 jam();
13035 AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
13036 req->setUserRef(reference());
13037 req->setConnectionPtr(opPtr.p->key);
13038 req->setRequestType(AlterTrigReq::RT_DROP_TRIGGER);
13039 req->addRequestFlag(opPtr.p->m_requestFlag);
13040 req->setTableId(opPtr.p->m_request.getTableId());
13041 req->setTriggerId(opPtr.p->m_request.getTriggerId());
13042 req->setTriggerInfo(0); // not used
13043 req->setOnline(false);
13044 req->setReceiverRef(0);
13045 sendSignal(reference(), GSN_ALTER_TRIG_REQ,
13046 signal, AlterTrigReq::SignalLength, JBB);
13047 }
13048
13049 void
dropTrigger_fromAlterTrigger(Signal * signal,OpDropTriggerPtr opPtr)13050 Dbdict::dropTrigger_fromAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
13051 {
13052 jam();
13053 // remove in all
13054 opPtr.p->m_requestType = DropTrigReq::RT_DICT_COMMIT;
13055 dropTrigger_sendSlaveReq(signal, opPtr);
13056 }
13057
13058 void
dropTrigger_sendSlaveReq(Signal * signal,OpDropTriggerPtr opPtr)13059 Dbdict::dropTrigger_sendSlaveReq(Signal* signal, OpDropTriggerPtr opPtr)
13060 {
13061 DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
13062 *req = opPtr.p->m_request;
13063 req->setUserRef(opPtr.p->m_coordinatorRef);
13064 req->setConnectionPtr(opPtr.p->key);
13065 req->setRequestType(opPtr.p->m_requestType);
13066 req->addRequestFlag(opPtr.p->m_requestFlag);
13067 opPtr.p->m_signalCounter = c_aliveNodes;
13068 NodeReceiverGroup rg(DBDICT, c_aliveNodes);
13069 sendSignal(rg, GSN_DROP_TRIG_REQ,
13070 signal, DropTrigReq::SignalLength, JBB);
13071 }
13072
13073 void
dropTrigger_slaveCommit(Signal * signal,OpDropTriggerPtr opPtr)13074 Dbdict::dropTrigger_slaveCommit(Signal* signal, OpDropTriggerPtr opPtr)
13075 {
13076 jam();
13077 const DropTrigReq* const req = &opPtr.p->m_request;
13078 // get trigger record
13079 const Uint32 triggerId = req->getTriggerId();
13080 TriggerRecordPtr triggerPtr;
13081 c_triggerRecordPool.getPtr(triggerPtr, triggerId);
13082 if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
13083 triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
13084 jam();
13085 // disconnect from index if index trigger XXX move to drop index
13086 triggerPtr.p->indexId = req->getIndexId();
13087 TableRecordPtr indexPtr;
13088 c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
13089 ndbrequire(! indexPtr.isNull());
13090 switch (triggerPtr.p->triggerEvent) {
13091 case TriggerEvent::TE_INSERT:
13092 indexPtr.p->insertTriggerId = RNIL;
13093 break;
13094 case TriggerEvent::TE_UPDATE:
13095 indexPtr.p->updateTriggerId = RNIL;
13096 break;
13097 case TriggerEvent::TE_DELETE:
13098 indexPtr.p->deleteTriggerId = RNIL;
13099 break;
13100 case TriggerEvent::TE_CUSTOM:
13101 indexPtr.p->customTriggerId = RNIL;
13102 break;
13103 default:
13104 ndbrequire(false);
13105 break;
13106 }
13107 }
13108 if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
13109 jam();
13110 // disconnect from index record XXX should be done in caller instead
13111 triggerPtr.p->indexId = req->getTableId();
13112 TableRecordPtr indexPtr;
13113 c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
13114 indexPtr.p->buildTriggerId = RNIL;
13115 }
13116 //remove trigger
13117 //ndbout_c("++++++++++++ Removing trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
13118 release_object(triggerPtr.p->m_obj_ptr_i);
13119 triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
13120 }
13121
13122 void
dropTrigger_slaveAbort(Signal * signal,OpDropTriggerPtr opPtr)13123 Dbdict::dropTrigger_slaveAbort(Signal* signal, OpDropTriggerPtr opPtr)
13124 {
13125 jam();
13126 }
13127
13128 void
dropTrigger_sendReply(Signal * signal,OpDropTriggerPtr opPtr,bool toUser)13129 Dbdict::dropTrigger_sendReply(Signal* signal, OpDropTriggerPtr opPtr,
13130 bool toUser)
13131 {
13132 DropTrigRef* rep = (DropTrigRef*)signal->getDataPtrSend();
13133 Uint32 gsn = GSN_DROP_TRIG_CONF;
13134 Uint32 length = DropTrigConf::InternalLength;
13135 bool sendRef;
13136 if (! toUser) {
13137 sendRef = opPtr.p->hasLastError();
13138 rep->setUserRef(opPtr.p->m_coordinatorRef);
13139 rep->setConnectionPtr(opPtr.p->key);
13140 rep->setRequestType(opPtr.p->m_requestType);
13141 if (opPtr.p->m_requestType == DropTrigReq::RT_DICT_ABORT)
13142 sendRef = false;
13143 } else {
13144 sendRef = opPtr.p->hasError();
13145 rep->setUserRef(opPtr.p->m_request.getUserRef());
13146 rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
13147 rep->setRequestType(opPtr.p->m_request.getRequestType());
13148 length = DropTrigConf::SignalLength;
13149 }
13150 rep->setTableId(opPtr.p->m_request.getTableId());
13151 rep->setIndexId(opPtr.p->m_request.getIndexId());
13152 rep->setTriggerId(opPtr.p->m_request.getTriggerId());
13153 if (sendRef) {
13154 if (opPtr.p->m_errorNode == 0)
13155 opPtr.p->m_errorNode = getOwnNodeId();
13156 rep->setErrorCode(opPtr.p->m_errorCode);
13157 rep->setErrorLine(opPtr.p->m_errorLine);
13158 rep->setErrorNode(opPtr.p->m_errorNode);
13159 gsn = GSN_DROP_TRIG_REF;
13160 length = CreateTrigRef::SignalLength;
13161 }
13162 sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
13163 }
13164
13165 /**
13166 * MODULE: Alter trigger.
13167 *
13168 * Alter trigger state. Alter online creates the trigger first in all
13169 * TC (if index trigger) and then in all LQH-TUP.
13170 *
13171 * Request type received in REQ and returned in CONF/REF:
13172 *
13173 * RT_USER - normal user e.g. BACKUP
13174 * RT_CREATE_TRIGGER - from create trigger
13175 * RT_DROP_TRIGGER - from drop trigger
13176 * RT_DICT_PREPARE - seize operations and check request
13177 * RT_DICT_TC - master to each DICT on way to TC
13178 * RT_DICT_LQH - master to each DICT on way to LQH-TUP
13179 * RT_DICT_COMMIT - commit state change in each DICT (no reply)
13180 */
13181
13182 void
execALTER_TRIG_REQ(Signal * signal)13183 Dbdict::execALTER_TRIG_REQ(Signal* signal)
13184 {
13185 jamEntry();
13186 AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
13187 OpAlterTriggerPtr opPtr;
13188 const Uint32 senderRef = signal->senderBlockRef();
13189 const AlterTrigReq::RequestType requestType = req->getRequestType();
13190 if (requestType == AlterTrigReq::RT_USER ||
13191 requestType == AlterTrigReq::RT_CREATE_TRIGGER ||
13192 requestType == AlterTrigReq::RT_DROP_TRIGGER) {
13193 jam();
13194 const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
13195 NdbNodeBitmask receiverNodes = c_aliveNodes;
13196 if (isLocal) {
13197 receiverNodes.clear();
13198 receiverNodes.set(getOwnNodeId());
13199 }
13200 if (signal->getLength() == AlterTrigReq::SignalLength) {
13201 jam();
13202 if (! isLocal && getOwnNodeId() != c_masterNodeId) {
13203 jam();
13204 // forward to DICT master
13205 sendSignal(calcDictBlockRef(c_masterNodeId), GSN_ALTER_TRIG_REQ,
13206 signal, AlterTrigReq::SignalLength, JBB);
13207 return;
13208 }
13209 // forward initial request plus operation key to all
13210 req->setOpKey(++c_opRecordSequence);
13211 NodeReceiverGroup rg(DBDICT, receiverNodes);
13212 sendSignal(rg, GSN_ALTER_TRIG_REQ,
13213 signal, AlterTrigReq::SignalLength + 1, JBB);
13214 return;
13215 }
13216 // seize operation record
13217 ndbrequire(signal->getLength() == AlterTrigReq::SignalLength + 1);
13218 const Uint32 opKey = req->getOpKey();
13219 OpAlterTrigger opBusy;
13220 if (! c_opAlterTrigger.seize(opPtr))
13221 opPtr.p = &opBusy;
13222 opPtr.p->save(req);
13223 opPtr.p->m_coordinatorRef = senderRef;
13224 opPtr.p->m_isMaster = (senderRef == reference());
13225 opPtr.p->key = opKey;
13226 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_PREPARE;
13227 if (opPtr.p == &opBusy) {
13228 jam();
13229 opPtr.p->m_errorCode = AlterTrigRef::Busy;
13230 opPtr.p->m_errorLine = __LINE__;
13231 alterTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
13232 return;
13233 }
13234 c_opAlterTrigger.add(opPtr);
13235 // master expects to hear from all
13236 if (opPtr.p->m_isMaster) {
13237 opPtr.p->m_nodes = receiverNodes;
13238 opPtr.p->m_signalCounter = receiverNodes;
13239 }
13240 alterTrigger_slavePrepare(signal, opPtr);
13241 alterTrigger_sendReply(signal, opPtr, false);
13242 return;
13243 }
13244 c_opAlterTrigger.find(opPtr, req->getConnectionPtr());
13245 if (! opPtr.isNull()) {
13246 opPtr.p->m_requestType = requestType;
13247 if (requestType == AlterTrigReq::RT_DICT_TC ||
13248 requestType == AlterTrigReq::RT_DICT_LQH) {
13249 jam();
13250 if (req->getOnline())
13251 alterTrigger_toCreateLocal(signal, opPtr);
13252 else
13253 alterTrigger_toDropLocal(signal, opPtr);
13254 return;
13255 }
13256 if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
13257 requestType == AlterTrigReq::RT_DICT_ABORT) {
13258 jam();
13259 if (requestType == AlterTrigReq::RT_DICT_COMMIT)
13260 alterTrigger_slaveCommit(signal, opPtr);
13261 else
13262 alterTrigger_slaveAbort(signal, opPtr);
13263 alterTrigger_sendReply(signal, opPtr, false);
13264 // done in slave
13265 if (! opPtr.p->m_isMaster)
13266 c_opAlterTrigger.release(opPtr);
13267 return;
13268 }
13269 }
13270 jam();
13271 // return to sender
13272 OpAlterTrigger opBad;
13273 opPtr.p = &opBad;
13274 opPtr.p->save(req);
13275 opPtr.p->m_errorCode = AlterTrigRef::BadRequestType;
13276 opPtr.p->m_errorLine = __LINE__;
13277 alterTrigger_sendReply(signal, opPtr, true);
13278 return;
13279 }
13280
13281 void
execALTER_TRIG_CONF(Signal * signal)13282 Dbdict::execALTER_TRIG_CONF(Signal* signal)
13283 {
13284 jamEntry();
13285 AlterTrigConf* conf = (AlterTrigConf*)signal->getDataPtrSend();
13286 alterTrigger_recvReply(signal, conf, 0);
13287 }
13288
13289 void
execALTER_TRIG_REF(Signal * signal)13290 Dbdict::execALTER_TRIG_REF(Signal* signal)
13291 {
13292 jamEntry();
13293 AlterTrigRef* ref = (AlterTrigRef*)signal->getDataPtrSend();
13294 alterTrigger_recvReply(signal, ref->getConf(), ref);
13295 }
13296
13297 void
alterTrigger_recvReply(Signal * signal,const AlterTrigConf * conf,const AlterTrigRef * ref)13298 Dbdict::alterTrigger_recvReply(Signal* signal, const AlterTrigConf* conf,
13299 const AlterTrigRef* ref)
13300 {
13301 jam();
13302 const Uint32 senderRef = signal->senderBlockRef();
13303 const AlterTrigReq::RequestType requestType = conf->getRequestType();
13304 const Uint32 key = conf->getConnectionPtr();
13305 if (requestType == AlterTrigReq::RT_CREATE_TRIGGER) {
13306 jam();
13307 // part of create trigger operation
13308 OpCreateTriggerPtr opPtr;
13309 c_opCreateTrigger.find(opPtr, key);
13310 ndbrequire(! opPtr.isNull());
13311 opPtr.p->setError(ref);
13312 createTrigger_fromAlterTrigger(signal, opPtr);
13313 return;
13314 }
13315 if (requestType == AlterTrigReq::RT_DROP_TRIGGER) {
13316 jam();
13317 // part of drop trigger operation
13318 OpDropTriggerPtr opPtr;
13319 c_opDropTrigger.find(opPtr, key);
13320 ndbrequire(! opPtr.isNull());
13321 opPtr.p->setError(ref);
13322 dropTrigger_fromAlterTrigger(signal, opPtr);
13323 return;
13324 }
13325 OpAlterTriggerPtr opPtr;
13326 c_opAlterTrigger.find(opPtr, key);
13327 ndbrequire(! opPtr.isNull());
13328 ndbrequire(opPtr.p->m_isMaster);
13329 ndbrequire(opPtr.p->m_requestType == requestType);
13330 /*
13331 * If refuse on drop trig, because of non-existent trigger,
13332 * comes from anyone but the master node - ignore it and
13333 * remove the node from forter ALTER_TRIG communication
13334 * This will happen if a new node has started since the
13335 * trigger whas created.
13336 */
13337 if (ref &&
13338 refToNode(senderRef) != refToNode(reference()) &&
13339 opPtr.p->m_request.getRequestType() == AlterTrigReq::RT_DROP_TRIGGER &&
13340 ref->getErrorCode() == AlterTrigRef::TriggerNotFound) {
13341 jam();
13342 ref = 0; // ignore this error
13343 opPtr.p->m_nodes.clear(refToNode(senderRef)); // remove this from group
13344 }
13345 opPtr.p->setError(ref);
13346 opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
13347 if (! opPtr.p->m_signalCounter.done()) {
13348 jam();
13349 return;
13350 }
13351 if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
13352 requestType == AlterTrigReq::RT_DICT_ABORT) {
13353 jam();
13354 // send reply to user
13355 alterTrigger_sendReply(signal, opPtr, true);
13356 c_opAlterTrigger.release(opPtr);
13357 return;
13358 }
13359 if (opPtr.p->hasError()) {
13360 jam();
13361 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_ABORT;
13362 alterTrigger_sendSlaveReq(signal, opPtr);
13363 return;
13364 }
13365 if (! (opPtr.p->m_request.getRequestFlag() & RequestFlag::RF_NOTCTRIGGER)) {
13366 if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
13367 jam();
13368 if (opPtr.p->m_request.getOnline()) {
13369 jam();
13370 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
13371 } else {
13372 jam();
13373 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
13374 }
13375 alterTrigger_sendSlaveReq(signal, opPtr);
13376 return;
13377 }
13378 if (requestType == AlterTrigReq::RT_DICT_TC) {
13379 jam();
13380 if (opPtr.p->m_request.getOnline()) {
13381 jam();
13382 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
13383 } else {
13384 jam();
13385 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
13386 }
13387 alterTrigger_sendSlaveReq(signal, opPtr);
13388 return;
13389 }
13390 if (requestType == AlterTrigReq::RT_DICT_LQH) {
13391 jam();
13392 if (opPtr.p->m_request.getOnline()) {
13393 jam();
13394 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
13395 } else {
13396 jam();
13397 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
13398 }
13399 alterTrigger_sendSlaveReq(signal, opPtr);
13400 return;
13401 }
13402 } else {
13403 if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
13404 jam();
13405 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
13406 alterTrigger_sendSlaveReq(signal, opPtr);
13407 return;
13408 }
13409 if (requestType == AlterTrigReq::RT_DICT_LQH) {
13410 jam();
13411 opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
13412 alterTrigger_sendSlaveReq(signal, opPtr);
13413 return;
13414 }
13415 }
13416 ndbrequire(false);
13417 }
13418
13419 void
alterTrigger_slavePrepare(Signal * signal,OpAlterTriggerPtr opPtr)13420 Dbdict::alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr)
13421 {
13422 jam();
13423 const AlterTrigReq* const req = &opPtr.p->m_request;
13424 const Uint32 triggerId = req->getTriggerId();
13425 TriggerRecordPtr triggerPtr;
13426 if (! (triggerId < c_triggerRecordPool.getSize())) {
13427 jam();
13428 opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
13429 opPtr.p->m_errorLine = __LINE__;
13430 return;
13431 }
13432 c_triggerRecordPool.getPtr(triggerPtr, triggerId);
13433 if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
13434 jam();
13435 opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
13436 opPtr.p->m_errorLine = __LINE__;
13437 return;
13438 }
13439
13440 if (triggerPtr.p->triggerType == TriggerType::SUBSCRIPTION)
13441 {
13442 opPtr.p->m_request.addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
13443 }
13444 }
13445
13446 void
alterTrigger_toCreateLocal(Signal * signal,OpAlterTriggerPtr opPtr)13447 Dbdict::alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
13448 {
13449 jam();
13450 // find trigger record
13451 const Uint32 triggerId = opPtr.p->m_request.getTriggerId();
13452 TriggerRecordPtr triggerPtr;
13453 c_triggerRecordPool.getPtr(triggerPtr, triggerId);
13454 CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
13455 req->setUserRef(reference());
13456 req->setConnectionPtr(opPtr.p->key);
13457 if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
13458 jam();
13459 req->setRequestType(CreateTrigReq::RT_TC);
13460 } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
13461 jam();
13462 req->setRequestType(CreateTrigReq::RT_LQH);
13463 } else {
13464 ndbassert(false);
13465 }
13466 req->setTableId(triggerPtr.p->tableId);
13467 req->setIndexId(triggerPtr.p->indexId);
13468 req->setTriggerId(triggerPtr.i);
13469 req->setTriggerType(triggerPtr.p->triggerType);
13470 req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
13471 req->setTriggerEvent(triggerPtr.p->triggerEvent);
13472 req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
13473 req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
13474 req->setReportAllMonitoredAttributes(triggerPtr.p->reportAllMonitoredAttributes);
13475 req->setOnline(true);
13476 req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
13477 BlockReference blockRef = 0;
13478 if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
13479 jam();
13480 blockRef = calcTcBlockRef(getOwnNodeId());
13481 } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
13482 jam();
13483 blockRef = calcLqhBlockRef(getOwnNodeId());
13484 } else {
13485 ndbassert(false);
13486 }
13487 req->setAttributeMask(triggerPtr.p->attributeMask);
13488 sendSignal(blockRef, GSN_CREATE_TRIG_REQ,
13489 signal, CreateTrigReq::SignalLength, JBB);
13490 }
13491
13492 void
alterTrigger_fromCreateLocal(Signal * signal,OpAlterTriggerPtr opPtr)13493 Dbdict::alterTrigger_fromCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
13494 {
13495 jam();
13496 if (! opPtr.p->hasLastError()) {
13497 // mark created locally
13498 TriggerRecordPtr triggerPtr;
13499 c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
13500 if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
13501 jam();
13502 triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_TC;
13503 } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
13504 jam();
13505 triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_LQH;
13506 } else {
13507 ndbrequire(false);
13508 }
13509 }
13510 // forward CONF or REF to master
13511 alterTrigger_sendReply(signal, opPtr, false);
13512 }
13513
13514 void
alterTrigger_toDropLocal(Signal * signal,OpAlterTriggerPtr opPtr)13515 Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
13516 {
13517 jam();
13518 TriggerRecordPtr triggerPtr;
13519 c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
13520 DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
13521 req->setUserRef(reference());
13522 req->setConnectionPtr(opPtr.p->key);
13523 if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
13524 jam();
13525 // broken trigger allowed if force
13526 if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_TC)) {
13527 jam();
13528 ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
13529 alterTrigger_sendReply(signal, opPtr, false);
13530 return;
13531 }
13532 req->setRequestType(DropTrigReq::RT_TC);
13533 } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
13534 jam();
13535 // broken trigger allowed if force
13536 if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_LQH)) {
13537 jam();
13538 ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
13539 alterTrigger_sendReply(signal, opPtr, false);
13540 return;
13541 }
13542 req->setRequestType(DropTrigReq::RT_LQH);
13543 } else {
13544 ndbassert(false);
13545 }
13546 req->setTableId(triggerPtr.p->tableId);
13547 req->setIndexId(triggerPtr.p->indexId);
13548 req->setTriggerId(triggerPtr.i);
13549 req->setTriggerType(triggerPtr.p->triggerType);
13550 req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
13551 req->setTriggerEvent(triggerPtr.p->triggerEvent);
13552 req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
13553 req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
13554 BlockReference blockRef = 0;
13555 if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
13556 jam();
13557 blockRef = calcTcBlockRef(getOwnNodeId());
13558 } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
13559 jam();
13560 blockRef = calcLqhBlockRef(getOwnNodeId());
13561 } else {
13562 ndbassert(false);
13563 }
13564 sendSignal(blockRef, GSN_DROP_TRIG_REQ,
13565 signal, DropTrigReq::SignalLength, JBB);
13566 }
13567
13568 void
alterTrigger_fromDropLocal(Signal * signal,OpAlterTriggerPtr opPtr)13569 Dbdict::alterTrigger_fromDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
13570 {
13571 jam();
13572 if (! opPtr.p->hasLastError()) {
13573 // mark dropped locally
13574 TriggerRecordPtr triggerPtr;
13575 c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
13576 if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
13577 jam();
13578 triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_TC;
13579 } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
13580 jam();
13581 triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_LQH;
13582 } else {
13583 ndbrequire(false);
13584 }
13585 }
13586 // forward CONF or REF to master
13587 alterTrigger_sendReply(signal, opPtr, false);
13588 }
13589
13590 void
alterTrigger_slaveCommit(Signal * signal,OpAlterTriggerPtr opPtr)13591 Dbdict::alterTrigger_slaveCommit(Signal* signal, OpAlterTriggerPtr opPtr)
13592 {
13593 jam();
13594 TriggerRecordPtr triggerPtr;
13595 c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
13596 // set state
13597 triggerPtr.p->triggerState = TriggerRecord::TS_ONLINE;
13598 }
13599
13600 void
alterTrigger_slaveAbort(Signal * signal,OpAlterTriggerPtr opPtr)13601 Dbdict::alterTrigger_slaveAbort(Signal* signal, OpAlterTriggerPtr opPtr)
13602 {
13603 jam();
13604 }
13605
13606 void
alterTrigger_sendSlaveReq(Signal * signal,OpAlterTriggerPtr opPtr)13607 Dbdict::alterTrigger_sendSlaveReq(Signal* signal, OpAlterTriggerPtr opPtr)
13608 {
13609 AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
13610 *req = opPtr.p->m_request;
13611 req->setUserRef(opPtr.p->m_coordinatorRef);
13612 req->setConnectionPtr(opPtr.p->key);
13613 req->setRequestType(opPtr.p->m_requestType);
13614 req->addRequestFlag(opPtr.p->m_requestFlag);
13615 NdbNodeBitmask receiverNodes = c_aliveNodes;
13616 if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
13617 receiverNodes.clear();
13618 receiverNodes.set(getOwnNodeId());
13619 } else {
13620 opPtr.p->m_nodes.bitAND(receiverNodes);
13621 receiverNodes = opPtr.p->m_nodes;
13622 }
13623 opPtr.p->m_signalCounter = receiverNodes;
13624 NodeReceiverGroup rg(DBDICT, receiverNodes);
13625 sendSignal(rg, GSN_ALTER_TRIG_REQ,
13626 signal, AlterTrigReq::SignalLength, JBB);
13627 }
13628
13629 void
alterTrigger_sendReply(Signal * signal,OpAlterTriggerPtr opPtr,bool toUser)13630 Dbdict::alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr,
13631 bool toUser)
13632 {
13633 jam();
13634 AlterTrigRef* rep = (AlterTrigRef*)signal->getDataPtrSend();
13635 Uint32 gsn = GSN_ALTER_TRIG_CONF;
13636 Uint32 length = AlterTrigConf::InternalLength;
13637 bool sendRef;
13638 if (! toUser) {
13639 sendRef = opPtr.p->hasLastError();
13640 rep->setUserRef(opPtr.p->m_coordinatorRef);
13641 rep->setConnectionPtr(opPtr.p->key);
13642 rep->setRequestType(opPtr.p->m_requestType);
13643 if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_ABORT) {
13644 jam();
13645 sendRef = false;
13646 } else {
13647 jam();
13648 }
13649 } else {
13650 sendRef = opPtr.p->hasError();
13651 jam();
13652 rep->setUserRef(opPtr.p->m_request.getUserRef());
13653 rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
13654 rep->setRequestType(opPtr.p->m_request.getRequestType());
13655 length = AlterTrigConf::SignalLength;
13656 }
13657 rep->setTableId(opPtr.p->m_request.getTableId());
13658 rep->setTriggerId(opPtr.p->m_request.getTriggerId());
13659 if (sendRef) {
13660 if (opPtr.p->m_errorNode == 0) {
13661 jam();
13662 opPtr.p->m_errorNode = getOwnNodeId();
13663 } else {
13664 jam();
13665 }
13666 rep->setErrorCode(opPtr.p->m_errorCode);
13667 rep->setErrorLine(opPtr.p->m_errorLine);
13668 rep->setErrorNode(opPtr.p->m_errorNode);
13669 gsn = GSN_ALTER_TRIG_REF;
13670 length = AlterTrigRef::SignalLength;
13671 }
13672 sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
13673 }
13674
13675 /**
13676 * MODULE: Support routines for index and trigger.
13677 */
13678
13679 /*
13680 This routine is used to set-up the primary key attributes of the unique
13681 hash index. Since we store fragment id as part of the primary key here
13682 we insert the pseudo column for getting fragment id first in the array.
13683 This routine is used as part of the building of the index.
13684 */
13685
13686 void
getTableKeyList(TableRecordPtr tablePtr,Id_array<MAX_ATTRIBUTES_IN_INDEX+1> & list)13687 Dbdict::getTableKeyList(TableRecordPtr tablePtr,
13688 Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list)
13689 {
13690 jam();
13691 list.sz = 0;
13692 list.id[list.sz++] = AttributeHeader::FRAGMENT;
13693 LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
13694 tablePtr.p->m_attributes);
13695 AttributeRecordPtr attrPtr;
13696 for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)) {
13697 if (attrPtr.p->tupleKey) {
13698 list.id[list.sz++] = attrPtr.p->attributeId;
13699 }
13700 }
13701 ndbrequire(list.sz == (uint)(tablePtr.p->noOfPrimkey + 1));
13702 ndbrequire(list.sz <= MAX_ATTRIBUTES_IN_INDEX + 1);
13703 }
13704
13705 // XXX should store the primary attribute id
13706 void
getIndexAttr(TableRecordPtr indexPtr,Uint32 itAttr,Uint32 * id)13707 Dbdict::getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id)
13708 {
13709 jam();
13710
13711 Uint32 len;
13712 char name[MAX_ATTR_NAME_SIZE];
13713 TableRecordPtr tablePtr;
13714 AttributeRecordPtr attrPtr;
13715
13716 c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
13717 AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
13718 {
13719 ConstRope tmp(c_rope_pool, iaRec->attributeName);
13720 tmp.copy(name);
13721 len = tmp.size();
13722 }
13723 LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
13724 tablePtr.p->m_attributes);
13725 for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)){
13726 ConstRope tmp(c_rope_pool, attrPtr.p->attributeName);
13727 if(tmp.compare(name, len) == 0){
13728 id[0] = attrPtr.p->attributeId;
13729 return;
13730 }
13731 }
13732 ndbrequire(false);
13733 }
13734
13735 void
getIndexAttrList(TableRecordPtr indexPtr,AttributeList & list)13736 Dbdict::getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list)
13737 {
13738 jam();
13739 list.sz = 0;
13740 memset(list.id, 0, sizeof(list.id));
13741 ndbrequire(indexPtr.p->noOfAttributes >= 2);
13742
13743 LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
13744 indexPtr.p->m_attributes);
13745 AttributeRecordPtr attrPtr;
13746 for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)) {
13747 // skip last
13748 AttributeRecordPtr tempPtr = attrPtr;
13749 if (! alist.next(tempPtr))
13750 break;
13751 getIndexAttr(indexPtr, attrPtr.i, &list.id[list.sz++]);
13752 }
13753 ndbrequire(indexPtr.p->noOfAttributes == list.sz + 1);
13754 }
13755
13756 void
getIndexAttrMask(TableRecordPtr indexPtr,AttributeMask & mask)13757 Dbdict::getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask)
13758 {
13759 jam();
13760 mask.clear();
13761 ndbrequire(indexPtr.p->noOfAttributes >= 2);
13762
13763 AttributeRecordPtr attrPtr, currPtr;
13764 LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
13765 indexPtr.p->m_attributes);
13766
13767
13768 for (alist.first(attrPtr); currPtr = attrPtr, alist.next(attrPtr); ){
13769 Uint32 id;
13770 getIndexAttr(indexPtr, currPtr.i, &id);
13771 mask.set(id);
13772 }
13773 }
13774
13775 // DICT lock master
13776
13777 const Dbdict::DictLockType*
getDictLockType(Uint32 lockType)13778 Dbdict::getDictLockType(Uint32 lockType)
13779 {
13780 static const DictLockType lt[] = {
13781 { DictLockReq::NodeRestartLock, BS_NODE_RESTART, "NodeRestart" }
13782 };
13783 for (unsigned int i = 0; i < sizeof(lt)/sizeof(lt[0]); i++) {
13784 if ((Uint32) lt[i].lockType == lockType)
13785 return <[i];
13786 }
13787 return NULL;
13788 }
13789
13790 void
sendDictLockInfoEvent(Uint32 pollCount)13791 Dbdict::sendDictLockInfoEvent(Uint32 pollCount)
13792 {
13793 DictLockPtr loopPtr;
13794 c_dictLockQueue.first(loopPtr);
13795 unsigned count = 0;
13796
13797 char queue_buf[100];
13798 char *p = &queue_buf[0];
13799 const char *const q = &queue_buf[sizeof(queue_buf)];
13800 *p = 0;
13801
13802 while (loopPtr.i != RNIL) {
13803 jam();
13804 my_snprintf(p, q-p, "%s%u%s",
13805 ++count == 1 ? "" : " ",
13806 (unsigned)refToNode(loopPtr.p->req.userRef),
13807 loopPtr.p->locked ? "L" : "");
13808 p += strlen(p);
13809 c_dictLockQueue.next(loopPtr);
13810 }
13811
13812 infoEvent("DICT: lock bs: %d ops: %d poll: %d cnt: %d queue: %s",
13813 (int)c_blockState,
13814 c_opRecordPool.getSize() - c_opRecordPool.getNoOfFree(),
13815 c_dictLockPoll, (int)pollCount, queue_buf);
13816 }
13817
13818 void
sendDictLockInfoEvent(DictLockPtr lockPtr,const char * text)13819 Dbdict::sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text)
13820 {
13821 infoEvent("DICT: %s %u for %s",
13822 text,
13823 (unsigned)refToNode(lockPtr.p->req.userRef), lockPtr.p->lt->text);
13824 }
13825
13826 void
execDICT_LOCK_REQ(Signal * signal)13827 Dbdict::execDICT_LOCK_REQ(Signal* signal)
13828 {
13829 jamEntry();
13830 const DictLockReq* req = (const DictLockReq*)&signal->theData[0];
13831
13832 // make sure bad request crashes slave, not master (us)
13833
13834 if (getOwnNodeId() != c_masterNodeId) {
13835 jam();
13836 sendDictLockRef(signal, *req, DictLockRef::NotMaster);
13837 return;
13838 }
13839
13840 const DictLockType* lt = getDictLockType(req->lockType);
13841 if (lt == NULL) {
13842 jam();
13843 sendDictLockRef(signal, *req, DictLockRef::InvalidLockType);
13844 return;
13845 }
13846
13847 if (req->userRef != signal->getSendersBlockRef() ||
13848 getNodeInfo(refToNode(req->userRef)).m_type != NodeInfo::DB) {
13849 jam();
13850 sendDictLockRef(signal, *req, DictLockRef::BadUserRef);
13851 return;
13852 }
13853
13854 if (c_aliveNodes.get(refToNode(req->userRef))) {
13855 jam();
13856 sendDictLockRef(signal, *req, DictLockRef::TooLate);
13857 return;
13858 }
13859
13860 DictLockPtr lockPtr;
13861 if (! c_dictLockQueue.seize(lockPtr)) {
13862 jam();
13863 sendDictLockRef(signal, *req, DictLockRef::TooManyRequests);
13864 return;
13865 }
13866
13867 lockPtr.p->req = *req;
13868 lockPtr.p->locked = false;
13869 lockPtr.p->lt = lt;
13870
13871 checkDictLockQueue(signal, false);
13872
13873 if (! lockPtr.p->locked)
13874 sendDictLockInfoEvent(lockPtr, "lock request by node");
13875 }
13876
13877 // only table and index ops are checked
13878 bool
hasDictLockSchemaOp()13879 Dbdict::hasDictLockSchemaOp()
13880 {
13881 return
13882 ! c_opCreateTable.isEmpty() ||
13883 ! c_opDropTable.isEmpty() ||
13884 ! c_opCreateIndex.isEmpty() ||
13885 ! c_opDropIndex.isEmpty();
13886 }
13887
13888 void
checkDictLockQueue(Signal * signal,bool poll)13889 Dbdict::checkDictLockQueue(Signal* signal, bool poll)
13890 {
13891 Uint32 pollCount = ! poll ? 0 : signal->theData[1];
13892
13893 DictLockPtr lockPtr;
13894
13895 do {
13896 if (! c_dictLockQueue.first(lockPtr)) {
13897 jam();
13898 setDictLockPoll(signal, false, pollCount);
13899 return;
13900 }
13901
13902 if (lockPtr.p->locked) {
13903 jam();
13904 ndbrequire(c_blockState == lockPtr.p->lt->blockState);
13905 break;
13906 }
13907
13908 if (hasDictLockSchemaOp()) {
13909 jam();
13910 break;
13911 }
13912
13913 if (c_blockState != BS_IDLE)
13914 {
13915 /**
13916 * If state is BS_NODE_FAILURE, it might be that no op is running
13917 */
13918 jam();
13919 break;
13920 }
13921
13922 ndbrequire(c_blockState == BS_IDLE);
13923 lockPtr.p->locked = true;
13924 c_blockState = lockPtr.p->lt->blockState;
13925 sendDictLockConf(signal, lockPtr);
13926
13927 sendDictLockInfoEvent(lockPtr, "locked by node");
13928 } while (0);
13929
13930 // poll while first request is open
13931 // this routine is called again when it is removed for any reason
13932
13933 bool on = ! lockPtr.p->locked;
13934 setDictLockPoll(signal, on, pollCount);
13935 }
13936
13937 void
execDICT_UNLOCK_ORD(Signal * signal)13938 Dbdict::execDICT_UNLOCK_ORD(Signal* signal)
13939 {
13940 jamEntry();
13941 const DictUnlockOrd* ord = (const DictUnlockOrd*)&signal->theData[0];
13942
13943 DictLockPtr lockPtr;
13944 c_dictLockQueue.getPtr(lockPtr, ord->lockPtr);
13945 ndbrequire((Uint32) lockPtr.p->lt->lockType == ord->lockType);
13946
13947 if (lockPtr.p->locked) {
13948 jam();
13949 ndbrequire(c_blockState == lockPtr.p->lt->blockState);
13950 ndbrequire(! hasDictLockSchemaOp());
13951 ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
13952
13953 c_blockState = BS_IDLE;
13954 sendDictLockInfoEvent(lockPtr, "unlocked by node");
13955 } else {
13956 sendDictLockInfoEvent(lockPtr, "lock request removed by node");
13957 }
13958
13959 c_dictLockQueue.release(lockPtr);
13960
13961 checkDictLockQueue(signal, false);
13962 }
13963
13964 void
sendDictLockConf(Signal * signal,DictLockPtr lockPtr)13965 Dbdict::sendDictLockConf(Signal* signal, DictLockPtr lockPtr)
13966 {
13967 DictLockConf* conf = (DictLockConf*)&signal->theData[0];
13968 const DictLockReq& req = lockPtr.p->req;
13969
13970 conf->userPtr = req.userPtr;
13971 conf->lockType = req.lockType;
13972 conf->lockPtr = lockPtr.i;
13973
13974 sendSignal(req.userRef, GSN_DICT_LOCK_CONF, signal,
13975 DictLockConf::SignalLength, JBB);
13976 }
13977
13978 void
sendDictLockRef(Signal * signal,DictLockReq req,Uint32 errorCode)13979 Dbdict::sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode)
13980 {
13981 DictLockRef* ref = (DictLockRef*)&signal->theData[0];
13982
13983 ref->userPtr = req.userPtr;
13984 ref->lockType = req.lockType;
13985 ref->errorCode = errorCode;
13986
13987 sendSignal(req.userRef, GSN_DICT_LOCK_REF, signal,
13988 DictLockRef::SignalLength, JBB);
13989 }
13990
13991 // control polling
13992
13993 void
setDictLockPoll(Signal * signal,bool on,Uint32 pollCount)13994 Dbdict::setDictLockPoll(Signal* signal, bool on, Uint32 pollCount)
13995 {
13996 if (on) {
13997 jam();
13998 signal->theData[0] = ZDICT_LOCK_POLL;
13999 signal->theData[1] = pollCount + 1;
14000 sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
14001 }
14002
14003 bool change = (c_dictLockPoll != on);
14004
14005 if (change) {
14006 jam();
14007 c_dictLockPoll = on;
14008 }
14009
14010 // avoid too many messages if master is stuck busy (BS_NODE_FAILURE)
14011 bool periodic =
14012 pollCount < 8 ||
14013 pollCount < 64 && pollCount % 8 == 0 ||
14014 pollCount < 512 && pollCount % 64 == 0 ||
14015 pollCount < 4096 && pollCount % 512 == 0 ||
14016 pollCount % 4096 == 0; // about every 6 minutes
14017
14018 if (change || periodic)
14019 sendDictLockInfoEvent(pollCount);
14020 }
14021
14022 // NF handling
14023
14024 void
removeStaleDictLocks(Signal * signal,const Uint32 * theFailedNodes)14025 Dbdict::removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes)
14026 {
14027 DictLockPtr loopPtr;
14028 c_dictLockQueue.first(loopPtr);
14029
14030 if (getOwnNodeId() != c_masterNodeId) {
14031 ndbrequire(loopPtr.i == RNIL);
14032 return;
14033 }
14034
14035 while (loopPtr.i != RNIL) {
14036 jam();
14037 DictLockPtr lockPtr = loopPtr;
14038 c_dictLockQueue.next(loopPtr);
14039
14040 Uint32 nodeId = refToNode(lockPtr.p->req.userRef);
14041
14042 if (NodeBitmask::get(theFailedNodes, nodeId)) {
14043 if (lockPtr.p->locked) {
14044 jam();
14045 ndbrequire(c_blockState == lockPtr.p->lt->blockState);
14046 ndbrequire(! hasDictLockSchemaOp());
14047 ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
14048
14049 c_blockState = BS_IDLE;
14050
14051 sendDictLockInfoEvent(lockPtr, "remove lock by failed node");
14052 } else {
14053 sendDictLockInfoEvent(lockPtr, "remove lock request by failed node");
14054 }
14055
14056 c_dictLockQueue.release(lockPtr);
14057 }
14058 }
14059
14060 checkDictLockQueue(signal, false);
14061 }
14062
14063
14064 /* **************************************************************** */
14065 /* ---------------------------------------------------------------- */
14066 /* MODULE: STORE/RESTORE SCHEMA FILE---------------------- */
14067 /* ---------------------------------------------------------------- */
14068 /* */
14069 /* General module used to store the schema file on disk and */
14070 /* similar function to restore it from disk. */
14071 /* ---------------------------------------------------------------- */
14072 /* **************************************************************** */
14073
14074 void
initSchemaFile(XSchemaFile * xsf,Uint32 firstPage,Uint32 lastPage,bool initEntries)14075 Dbdict::initSchemaFile(XSchemaFile * xsf, Uint32 firstPage, Uint32 lastPage,
14076 bool initEntries)
14077 {
14078 ndbrequire(lastPage <= xsf->noOfPages);
14079 for (Uint32 n = firstPage; n < lastPage; n++) {
14080 SchemaFile * sf = &xsf->schemaPage[n];
14081 if (initEntries)
14082 memset(sf, 0, NDB_SF_PAGE_SIZE);
14083
14084 Uint32 ndb_version = NDB_VERSION;
14085 if (ndb_version < NDB_SF_VERSION_5_0_6)
14086 ndb_version = NDB_SF_VERSION_5_0_6;
14087
14088 memcpy(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic));
14089 sf->ByteOrder = 0x12345678;
14090 sf->NdbVersion = ndb_version;
14091 sf->FileSize = xsf->noOfPages * NDB_SF_PAGE_SIZE;
14092 sf->PageNumber = n;
14093 sf->CheckSum = 0;
14094 sf->NoOfTableEntries = NDB_SF_PAGE_ENTRIES;
14095
14096 computeChecksum(xsf, n);
14097 }
14098 }
14099
14100 void
resizeSchemaFile(XSchemaFile * xsf,Uint32 noOfPages)14101 Dbdict::resizeSchemaFile(XSchemaFile * xsf, Uint32 noOfPages)
14102 {
14103 ndbrequire(noOfPages <= NDB_SF_MAX_PAGES);
14104 if (xsf->noOfPages < noOfPages) {
14105 jam();
14106 Uint32 firstPage = xsf->noOfPages;
14107 xsf->noOfPages = noOfPages;
14108 initSchemaFile(xsf, 0, firstPage, false);
14109 initSchemaFile(xsf, firstPage, xsf->noOfPages, true);
14110 }
14111 if (xsf->noOfPages > noOfPages) {
14112 jam();
14113 Uint32 tableId = noOfPages * NDB_SF_PAGE_ENTRIES;
14114 while (tableId < xsf->noOfPages * NDB_SF_PAGE_ENTRIES) {
14115 SchemaFile::TableEntry * te = getTableEntry(xsf, tableId);
14116 if (te->m_tableState != SchemaFile::INIT &&
14117 te->m_tableState != SchemaFile::DROP_TABLE_COMMITTED) {
14118 ndbrequire(false);
14119 }
14120 tableId++;
14121 }
14122 xsf->noOfPages = noOfPages;
14123 initSchemaFile(xsf, 0, xsf->noOfPages, false);
14124 }
14125 }
14126
14127 void
computeChecksum(XSchemaFile * xsf,Uint32 pageNo)14128 Dbdict::computeChecksum(XSchemaFile * xsf, Uint32 pageNo){
14129 SchemaFile * sf = &xsf->schemaPage[pageNo];
14130 sf->CheckSum = 0;
14131 sf->CheckSum = computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS);
14132 }
14133
14134 bool
validateChecksum(const XSchemaFile * xsf)14135 Dbdict::validateChecksum(const XSchemaFile * xsf){
14136
14137 for (Uint32 n = 0; n < xsf->noOfPages; n++) {
14138 SchemaFile * sf = &xsf->schemaPage[n];
14139 Uint32 c = computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS);
14140 if ( c != 0)
14141 return false;
14142 }
14143 return true;
14144 }
14145
14146 Uint32
computeChecksum(const Uint32 * src,Uint32 len)14147 Dbdict::computeChecksum(const Uint32 * src, Uint32 len){
14148 Uint32 ret = 0;
14149 for(Uint32 i = 0; i<len; i++)
14150 ret ^= src[i];
14151 return ret;
14152 }
14153
14154 SchemaFile::TableEntry *
getTableEntry(XSchemaFile * xsf,Uint32 tableId)14155 Dbdict::getTableEntry(XSchemaFile * xsf, Uint32 tableId)
14156 {
14157 Uint32 n = tableId / NDB_SF_PAGE_ENTRIES;
14158 Uint32 i = tableId % NDB_SF_PAGE_ENTRIES;
14159 ndbrequire(n < xsf->noOfPages);
14160
14161 SchemaFile * sf = &xsf->schemaPage[n];
14162 return &sf->TableEntries[i];
14163 }
14164
14165 //******************************************
14166 void
execCREATE_FILE_REQ(Signal * signal)14167 Dbdict::execCREATE_FILE_REQ(Signal* signal)
14168 {
14169 jamEntry();
14170
14171 if(!assembleFragments(signal)){
14172 jam();
14173 return;
14174 }
14175
14176 CreateFileReq * req = (CreateFileReq*)signal->getDataPtr();
14177 CreateFileRef * ref = (CreateFileRef*)signal->getDataPtrSend();
14178 Uint32 senderRef = req->senderRef;
14179 Uint32 senderData = req->senderData;
14180 Uint32 type = req->objType;
14181 Uint32 requestInfo = req->requestInfo;
14182
14183 do {
14184 if(getOwnNodeId() != c_masterNodeId){
14185 jam();
14186 ref->errorCode = CreateFileRef::NotMaster;
14187 ref->status = 0;
14188 ref->errorKey = 0;
14189 ref->errorLine = __LINE__;
14190 break;
14191 }
14192
14193 if (c_blockState != BS_IDLE){
14194 jam();
14195 ref->errorCode = CreateFileRef::Busy;
14196 ref->status = 0;
14197 ref->errorKey = 0;
14198 ref->errorLine = __LINE__;
14199 break;
14200 }
14201
14202 if (checkSingleUserMode(senderRef))
14203 {
14204 ref->errorCode = CreateFileRef::SingleUser;
14205 ref->status = 0;
14206 ref->errorKey = 0;
14207 ref->errorLine = __LINE__;
14208 break;
14209 }
14210
14211 Ptr<SchemaTransaction> trans_ptr;
14212 if (! c_Trans.seize(trans_ptr)){
14213 jam();
14214 ref->errorCode = CreateFileRef::Busy;
14215 ref->status = 0;
14216 ref->errorKey = 0;
14217 ref->errorLine = __LINE__;
14218 break;
14219 }
14220 jam();
14221 const Uint32 trans_key = ++c_opRecordSequence;
14222 trans_ptr.p->key = trans_key;
14223 trans_ptr.p->m_senderRef = senderRef;
14224 trans_ptr.p->m_senderData = senderData;
14225 trans_ptr.p->m_nodes = c_aliveNodes;
14226 trans_ptr.p->m_errorCode = 0;
14227 // trans_ptr.p->m_nodes.clear();
14228 // trans_ptr.p->m_nodes.set(getOwnNodeId());
14229 c_Trans.add(trans_ptr);
14230
14231 const Uint32 op_key = ++c_opRecordSequence;
14232 trans_ptr.p->m_op.m_key = op_key;
14233 trans_ptr.p->m_op.m_vt_index = 1;
14234 trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
14235
14236 CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
14237 create_obj->op_key = op_key;
14238 create_obj->senderRef = reference();
14239 create_obj->senderData = trans_key;
14240 create_obj->clientRef = senderRef;
14241 create_obj->clientData = senderData;
14242
14243 create_obj->objType = type;
14244 create_obj->requestInfo = requestInfo;
14245
14246 {
14247 Uint32 objId = getFreeObjId(0);
14248 if (objId == RNIL) {
14249 jam();
14250 ref->errorCode = CreateFileRef::NoMoreObjectRecords;
14251 ref->status = 0;
14252 ref->errorKey = 0;
14253 ref->errorLine = __LINE__;
14254 break;
14255 }
14256
14257 create_obj->objId = objId;
14258 trans_ptr.p->m_op.m_obj_id = objId;
14259 create_obj->gci = 0;
14260
14261 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
14262 SchemaFile::TableEntry *objEntry = getTableEntry(xsf, objId);
14263 create_obj->objVersion =
14264 create_obj_inc_schema_version(objEntry->m_tableVersion);
14265 }
14266
14267 NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
14268 SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
14269 tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
14270 sendSignal(rg, GSN_CREATE_OBJ_REQ, signal,
14271 CreateObjReq::SignalLength, JBB);
14272
14273 c_blockState = BS_CREATE_TAB;
14274 return;
14275 } while(0);
14276
14277 ref->senderData = senderData;
14278 ref->masterNodeId = c_masterNodeId;
14279 sendSignal(senderRef, GSN_CREATE_FILE_REF,signal,
14280 CreateFileRef::SignalLength, JBB);
14281 }
14282
14283 void
execCREATE_FILEGROUP_REQ(Signal * signal)14284 Dbdict::execCREATE_FILEGROUP_REQ(Signal* signal)
14285 {
14286 jamEntry();
14287
14288 if(!assembleFragments(signal)){
14289 jam();
14290 return;
14291 }
14292
14293 CreateFilegroupReq * req = (CreateFilegroupReq*)signal->getDataPtr();
14294 CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtrSend();
14295 Uint32 senderRef = req->senderRef;
14296 Uint32 senderData = req->senderData;
14297 Uint32 type = req->objType;
14298
14299 do {
14300 if(getOwnNodeId() != c_masterNodeId){
14301 jam();
14302 ref->errorCode = CreateFilegroupRef::NotMaster;
14303 ref->status = 0;
14304 ref->errorKey = 0;
14305 ref->errorLine = __LINE__;
14306 break;
14307 }
14308
14309 if (c_blockState != BS_IDLE){
14310 jam();
14311 ref->errorCode = CreateFilegroupRef::Busy;
14312 ref->status = 0;
14313 ref->errorKey = 0;
14314 ref->errorLine = __LINE__;
14315 break;
14316 }
14317
14318 if (checkSingleUserMode(senderRef))
14319 {
14320 ref->errorCode = CreateFilegroupRef::SingleUser;
14321 ref->status = 0;
14322 ref->errorKey = 0;
14323 ref->errorLine = __LINE__;
14324 break;
14325 }
14326
14327 Ptr<SchemaTransaction> trans_ptr;
14328 if (! c_Trans.seize(trans_ptr)){
14329 jam();
14330 ref->errorCode = CreateFilegroupRef::Busy;
14331 ref->status = 0;
14332 ref->errorKey = 0;
14333 ref->errorLine = __LINE__;
14334 break;
14335 }
14336 jam();
14337 const Uint32 trans_key = ++c_opRecordSequence;
14338 trans_ptr.p->key = trans_key;
14339 trans_ptr.p->m_senderRef = senderRef;
14340 trans_ptr.p->m_senderData = senderData;
14341 trans_ptr.p->m_nodes = c_aliveNodes;
14342 trans_ptr.p->m_errorCode = 0;
14343 c_Trans.add(trans_ptr);
14344
14345 const Uint32 op_key = ++c_opRecordSequence;
14346 trans_ptr.p->m_op.m_key = op_key;
14347 trans_ptr.p->m_op.m_vt_index = 0;
14348 trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
14349
14350 CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
14351 create_obj->op_key = op_key;
14352 create_obj->senderRef = reference();
14353 create_obj->senderData = trans_key;
14354 create_obj->clientRef = senderRef;
14355 create_obj->clientData = senderData;
14356
14357 create_obj->objType = type;
14358
14359 {
14360 Uint32 objId = getFreeObjId(0);
14361 if (objId == RNIL) {
14362 jam();
14363 ref->errorCode = CreateFilegroupRef::NoMoreObjectRecords;
14364 ref->status = 0;
14365 ref->errorKey = 0;
14366 ref->errorLine = __LINE__;
14367 break;
14368 }
14369
14370 create_obj->objId = objId;
14371 trans_ptr.p->m_op.m_obj_id = objId;
14372 create_obj->gci = 0;
14373
14374 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
14375 SchemaFile::TableEntry *objEntry = getTableEntry(xsf, objId);
14376 create_obj->objVersion =
14377 create_obj_inc_schema_version(objEntry->m_tableVersion);
14378 }
14379
14380 NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
14381 SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
14382 tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
14383 sendSignal(rg, GSN_CREATE_OBJ_REQ, signal,
14384 CreateObjReq::SignalLength, JBB);
14385
14386 c_blockState = BS_CREATE_TAB;
14387 return;
14388 } while(0);
14389
14390 ref->senderData = senderData;
14391 ref->masterNodeId = c_masterNodeId;
14392 sendSignal(senderRef, GSN_CREATE_FILEGROUP_REF,signal,
14393 CreateFilegroupRef::SignalLength, JBB);
14394 }
14395
14396 void
execDROP_FILE_REQ(Signal * signal)14397 Dbdict::execDROP_FILE_REQ(Signal* signal)
14398 {
14399 jamEntry();
14400
14401 if(!assembleFragments(signal)){
14402 jam();
14403 return;
14404 }
14405
14406 DropFileReq * req = (DropFileReq*)signal->getDataPtr();
14407 DropFileRef * ref = (DropFileRef*)signal->getDataPtrSend();
14408 Uint32 senderRef = req->senderRef;
14409 Uint32 senderData = req->senderData;
14410 Uint32 objId = req->file_id;
14411 Uint32 version = req->file_version;
14412
14413 do {
14414 if(getOwnNodeId() != c_masterNodeId){
14415 jam();
14416 ref->errorCode = DropFileRef::NotMaster;
14417 ref->errorKey = 0;
14418 ref->errorLine = __LINE__;
14419 break;
14420 }
14421
14422 if (c_blockState != BS_IDLE)
14423 {
14424 jam();
14425 ref->errorCode = DropFileRef::Busy;
14426 ref->errorKey = 0;
14427 ref->errorLine = __LINE__;
14428 break;
14429 }
14430
14431 if (checkSingleUserMode(senderRef))
14432 {
14433 jam();
14434 ref->errorCode = DropFileRef::SingleUser;
14435 ref->errorKey = 0;
14436 ref->errorLine = __LINE__;
14437 break;
14438 }
14439
14440 Ptr<File> file_ptr;
14441 if (!c_file_hash.find(file_ptr, objId))
14442 {
14443 jam();
14444 ref->errorCode = DropFileRef::NoSuchFile;
14445 ref->errorLine = __LINE__;
14446 break;
14447 }
14448
14449 if (file_ptr.p->m_version != version)
14450 {
14451 jam();
14452 ref->errorCode = DropFileRef::InvalidSchemaObjectVersion;
14453 ref->errorLine = __LINE__;
14454 break;
14455 }
14456
14457 Ptr<SchemaTransaction> trans_ptr;
14458 if (! c_Trans.seize(trans_ptr))
14459 {
14460 jam();
14461 ref->errorCode = DropFileRef::Busy;
14462 ref->errorLine = __LINE__;
14463 break;
14464 }
14465 jam();
14466
14467 const Uint32 trans_key = ++c_opRecordSequence;
14468 trans_ptr.p->key = trans_key;
14469 trans_ptr.p->m_senderRef = senderRef;
14470 trans_ptr.p->m_senderData = senderData;
14471 trans_ptr.p->m_nodes = c_aliveNodes;
14472 trans_ptr.p->m_errorCode = 0;
14473 c_Trans.add(trans_ptr);
14474
14475 const Uint32 op_key = ++c_opRecordSequence;
14476 trans_ptr.p->m_op.m_key = op_key;
14477 trans_ptr.p->m_op.m_vt_index = 2;
14478 trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
14479
14480 DropObjReq* drop_obj = (DropObjReq*)signal->getDataPtrSend();
14481 drop_obj->op_key = op_key;
14482 drop_obj->objVersion = version;
14483 drop_obj->objId = objId;
14484 drop_obj->objType = file_ptr.p->m_type;
14485 trans_ptr.p->m_op.m_obj_id = objId;
14486
14487 drop_obj->senderRef = reference();
14488 drop_obj->senderData = trans_key;
14489 drop_obj->clientRef = senderRef;
14490 drop_obj->clientData = senderData;
14491
14492 drop_obj->requestInfo = 0;
14493
14494 NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
14495 SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
14496 tmp.init<CreateObjRef>(rg, GSN_DROP_OBJ_REF, trans_key);
14497 sendSignal(rg, GSN_DROP_OBJ_REQ, signal,
14498 DropObjReq::SignalLength, JBB);
14499
14500 c_blockState = BS_CREATE_TAB;
14501 return;
14502 } while(0);
14503
14504 ref->senderData = senderData;
14505 ref->masterNodeId = c_masterNodeId;
14506 sendSignal(senderRef, GSN_DROP_FILE_REF,signal,
14507 DropFileRef::SignalLength, JBB);
14508 }
14509
14510 void
execDROP_FILEGROUP_REQ(Signal * signal)14511 Dbdict::execDROP_FILEGROUP_REQ(Signal* signal)
14512 {
14513 jamEntry();
14514
14515 if(!assembleFragments(signal)){
14516 jam();
14517 return;
14518 }
14519
14520 DropFilegroupReq * req = (DropFilegroupReq*)signal->getDataPtr();
14521 DropFilegroupRef * ref = (DropFilegroupRef*)signal->getDataPtrSend();
14522 Uint32 senderRef = req->senderRef;
14523 Uint32 senderData = req->senderData;
14524 Uint32 objId = req->filegroup_id;
14525 Uint32 version = req->filegroup_version;
14526
14527 do {
14528 if(getOwnNodeId() != c_masterNodeId)
14529 {
14530 jam();
14531 ref->errorCode = DropFilegroupRef::NotMaster;
14532 ref->errorKey = 0;
14533 ref->errorLine = __LINE__;
14534 break;
14535 }
14536
14537 if (c_blockState != BS_IDLE)
14538 {
14539 jam();
14540 ref->errorCode = DropFilegroupRef::Busy;
14541 ref->errorKey = 0;
14542 ref->errorLine = __LINE__;
14543 break;
14544 }
14545
14546 if (checkSingleUserMode(senderRef))
14547 {
14548 jam();
14549 ref->errorCode = DropFilegroupRef::SingleUser;
14550 ref->errorKey = 0;
14551 ref->errorLine = __LINE__;
14552 break;
14553 }
14554
14555 Ptr<Filegroup> filegroup_ptr;
14556 if (!c_filegroup_hash.find(filegroup_ptr, objId))
14557 {
14558 jam();
14559 ref->errorCode = DropFilegroupRef::NoSuchFilegroup;
14560 ref->errorLine = __LINE__;
14561 break;
14562 }
14563
14564 if (filegroup_ptr.p->m_version != version)
14565 {
14566 jam();
14567 ref->errorCode = DropFilegroupRef::InvalidSchemaObjectVersion;
14568 ref->errorLine = __LINE__;
14569 break;
14570 }
14571
14572 Ptr<SchemaTransaction> trans_ptr;
14573 if (! c_Trans.seize(trans_ptr))
14574 {
14575 jam();
14576 ref->errorCode = DropFilegroupRef::Busy;
14577 ref->errorLine = __LINE__;
14578 break;
14579 }
14580 jam();
14581
14582 const Uint32 trans_key = ++c_opRecordSequence;
14583 trans_ptr.p->key = trans_key;
14584 trans_ptr.p->m_senderRef = senderRef;
14585 trans_ptr.p->m_senderData = senderData;
14586 trans_ptr.p->m_nodes = c_aliveNodes;
14587 trans_ptr.p->m_errorCode = 0;
14588 c_Trans.add(trans_ptr);
14589
14590 const Uint32 op_key = ++c_opRecordSequence;
14591 trans_ptr.p->m_op.m_key = op_key;
14592 trans_ptr.p->m_op.m_vt_index = 3;
14593 trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
14594
14595 DropObjReq* drop_obj = (DropObjReq*)signal->getDataPtrSend();
14596 drop_obj->op_key = op_key;
14597 drop_obj->objVersion = version;
14598 drop_obj->objId = objId;
14599 drop_obj->objType = filegroup_ptr.p->m_type;
14600 trans_ptr.p->m_op.m_obj_id = objId;
14601
14602 drop_obj->senderRef = reference();
14603 drop_obj->senderData = trans_key;
14604 drop_obj->clientRef = senderRef;
14605 drop_obj->clientData = senderData;
14606
14607 drop_obj->requestInfo = 0;
14608
14609 NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
14610 SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
14611 tmp.init<CreateObjRef>(rg, GSN_DROP_OBJ_REF, trans_key);
14612 sendSignal(rg, GSN_DROP_OBJ_REQ, signal,
14613 DropObjReq::SignalLength, JBB);
14614
14615 c_blockState = BS_CREATE_TAB;
14616 return;
14617 } while(0);
14618
14619 ref->senderData = senderData;
14620 ref->masterNodeId = c_masterNodeId;
14621 sendSignal(senderRef, GSN_DROP_FILEGROUP_REF,signal,
14622 DropFilegroupRef::SignalLength, JBB);
14623 }
14624
14625 void
execCREATE_OBJ_REF(Signal * signal)14626 Dbdict::execCREATE_OBJ_REF(Signal* signal)
14627 {
14628 CreateObjRef * const ref = (CreateObjRef*)signal->getDataPtr();
14629 Ptr<SchemaTransaction> trans_ptr;
14630
14631 jamEntry();
14632 ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
14633 if(ref->errorCode != CreateObjRef::NF_FakeErrorREF){
14634 jam();
14635 trans_ptr.p->setErrorCode(ref->errorCode);
14636 }
14637 Uint32 node = refToNode(ref->senderRef);
14638 schemaOp_reply(signal, trans_ptr.p, node);
14639 }
14640
14641 void
execCREATE_OBJ_CONF(Signal * signal)14642 Dbdict::execCREATE_OBJ_CONF(Signal* signal)
14643 {
14644 Ptr<SchemaTransaction> trans_ptr;
14645 CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
14646
14647 jamEntry();
14648 ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
14649 schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
14650 }
14651
14652 void
schemaOp_reply(Signal * signal,SchemaTransaction * trans_ptr_p,Uint32 nodeId)14653 Dbdict::schemaOp_reply(Signal* signal,
14654 SchemaTransaction * trans_ptr_p,
14655 Uint32 nodeId)
14656 {
14657 jam();
14658 {
14659 SafeCounter tmp(c_counterMgr, trans_ptr_p->m_counter);
14660 if(!tmp.clearWaitingFor(nodeId)){
14661 jam();
14662 return;
14663 }
14664 }
14665
14666 switch(trans_ptr_p->m_op.m_state){
14667 case DictObjOp::Preparing:{
14668 if(trans_ptr_p->m_errorCode != 0)
14669 {
14670 /**
14671 * Failed to prepare on atleast one node -> abort on all
14672 */
14673 trans_ptr_p->m_op.m_state = DictObjOp::Aborting;
14674 trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
14675 trans_ptr_p->m_callback.m_callbackFunction=
14676 safe_cast(&Dbdict::trans_abort_start_done);
14677
14678 if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
14679 {
14680 jam();
14681 (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
14682 (signal, trans_ptr_p);
14683 }
14684 else
14685 {
14686 jam();
14687 execute(signal, trans_ptr_p->m_callback, 0);
14688 }
14689 return;
14690 }
14691
14692 trans_ptr_p->m_op.m_state = DictObjOp::Prepared;
14693 trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
14694 trans_ptr_p->m_callback.m_callbackFunction=
14695 safe_cast(&Dbdict::trans_commit_start_done);
14696
14697 if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
14698 {
14699 jam();
14700 (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
14701 (signal, trans_ptr_p);
14702 }
14703 else
14704 {
14705 jam();
14706 execute(signal, trans_ptr_p->m_callback, 0);
14707 }
14708 return;
14709 }
14710 case DictObjOp::Committing: {
14711 ndbrequire(trans_ptr_p->m_errorCode == 0);
14712
14713 trans_ptr_p->m_op.m_state = DictObjOp::Committed;
14714 trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
14715 trans_ptr_p->m_callback.m_callbackFunction=
14716 safe_cast(&Dbdict::trans_commit_complete_done);
14717
14718 if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
14719 {
14720 jam();
14721 (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
14722 (signal, trans_ptr_p);
14723 }
14724 else
14725 {
14726 jam();
14727 execute(signal, trans_ptr_p->m_callback, 0);
14728 }
14729 return;
14730 }
14731 case DictObjOp::Aborting:{
14732 trans_ptr_p->m_op.m_state = DictObjOp::Committed;
14733 trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
14734 trans_ptr_p->m_callback.m_callbackFunction=
14735 safe_cast(&Dbdict::trans_abort_complete_done);
14736
14737 if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
14738 {
14739 jam();
14740 (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
14741 (signal, trans_ptr_p);
14742 }
14743 else
14744 {
14745 jam();
14746 execute(signal, trans_ptr_p->m_callback, 0);
14747 }
14748 return;
14749 }
14750 case DictObjOp::Defined:
14751 case DictObjOp::Prepared:
14752 case DictObjOp::Committed:
14753 case DictObjOp::Aborted:
14754 jam();
14755 break;
14756 }
14757 ndbrequire(false);
14758 }
14759
14760 void
trans_commit_start_done(Signal * signal,Uint32 callbackData,Uint32 retValue)14761 Dbdict::trans_commit_start_done(Signal* signal,
14762 Uint32 callbackData,
14763 Uint32 retValue)
14764 {
14765 Ptr<SchemaTransaction> trans_ptr;
14766
14767 jam();
14768 ndbrequire(retValue == 0);
14769 ndbrequire(c_Trans.find(trans_ptr, callbackData));
14770 NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
14771 SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
14772 tmp.init<DictCommitRef>(rg, GSN_DICT_COMMIT_REF, trans_ptr.p->key);
14773
14774 DictCommitReq * const req = (DictCommitReq*)signal->getDataPtrSend();
14775 req->senderRef = reference();
14776 req->senderData = trans_ptr.p->key;
14777 req->op_key = trans_ptr.p->m_op.m_key;
14778 sendSignal(rg, GSN_DICT_COMMIT_REQ, signal, DictCommitReq::SignalLength,
14779 JBB);
14780 trans_ptr.p->m_op.m_state = DictObjOp::Committing;
14781 }
14782
14783 void
trans_commit_complete_done(Signal * signal,Uint32 callbackData,Uint32 retValue)14784 Dbdict::trans_commit_complete_done(Signal* signal,
14785 Uint32 callbackData,
14786 Uint32 retValue)
14787 {
14788 Ptr<SchemaTransaction> trans_ptr;
14789
14790 jam();
14791 ndbrequire(retValue == 0);
14792 ndbrequire(c_Trans.find(trans_ptr, callbackData));
14793
14794 switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
14795 case GSN_CREATE_FILEGROUP_REQ:{
14796 FilegroupPtr fg_ptr;
14797 jam();
14798 ndbrequire(c_filegroup_hash.find(fg_ptr, trans_ptr.p->m_op.m_obj_id));
14799
14800 CreateFilegroupConf * conf = (CreateFilegroupConf*)signal->getDataPtr();
14801 conf->senderRef = reference();
14802 conf->senderData = trans_ptr.p->m_senderData;
14803 conf->filegroupId = fg_ptr.p->key;
14804 conf->filegroupVersion = fg_ptr.p->m_version;
14805
14806 //@todo check api failed
14807 sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_CONF, signal,
14808 CreateFilegroupConf::SignalLength, JBB);
14809 break;
14810 }
14811 case GSN_CREATE_FILE_REQ:{
14812 FilePtr f_ptr;
14813 jam();
14814 ndbrequire(c_file_hash.find(f_ptr, trans_ptr.p->m_op.m_obj_id));
14815 CreateFileConf * conf = (CreateFileConf*)signal->getDataPtr();
14816 conf->senderRef = reference();
14817 conf->senderData = trans_ptr.p->m_senderData;
14818 conf->fileId = f_ptr.p->key;
14819 conf->fileVersion = f_ptr.p->m_version;
14820
14821 //@todo check api failed
14822 sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_CONF, signal,
14823 CreateFileConf::SignalLength, JBB);
14824 break;
14825 }
14826 case GSN_DROP_FILE_REQ:{
14827 DropFileConf * conf = (DropFileConf*)signal->getDataPtr();
14828 jam();
14829 conf->senderRef = reference();
14830 conf->senderData = trans_ptr.p->m_senderData;
14831 conf->fileId = trans_ptr.p->m_op.m_obj_id;
14832
14833 //@todo check api failed
14834 sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILE_CONF, signal,
14835 DropFileConf::SignalLength, JBB);
14836 break;
14837 }
14838 case GSN_DROP_FILEGROUP_REQ:{
14839 DropFilegroupConf * conf = (DropFilegroupConf*)signal->getDataPtr();
14840 jam();
14841 conf->senderRef = reference();
14842 conf->senderData = trans_ptr.p->m_senderData;
14843 conf->filegroupId = trans_ptr.p->m_op.m_obj_id;
14844
14845 //@todo check api failed
14846 sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILEGROUP_CONF, signal,
14847 DropFilegroupConf::SignalLength, JBB);
14848 break;
14849 }
14850 default:
14851 ndbrequire(false);
14852 }
14853
14854 c_Trans.release(trans_ptr);
14855 ndbrequire(c_blockState == BS_CREATE_TAB);
14856 c_blockState = BS_IDLE;
14857 return;
14858 }
14859
14860 void
trans_abort_start_done(Signal * signal,Uint32 callbackData,Uint32 retValue)14861 Dbdict::trans_abort_start_done(Signal* signal,
14862 Uint32 callbackData,
14863 Uint32 retValue)
14864 {
14865 Ptr<SchemaTransaction> trans_ptr;
14866
14867 jam();
14868 ndbrequire(retValue == 0);
14869 ndbrequire(c_Trans.find(trans_ptr, callbackData));
14870
14871 NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
14872 SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
14873 ndbrequire(tmp.init<DictAbortRef>(rg, trans_ptr.p->key));
14874
14875 DictAbortReq * const req = (DictAbortReq*)signal->getDataPtrSend();
14876 req->senderRef = reference();
14877 req->senderData = trans_ptr.p->key;
14878 req->op_key = trans_ptr.p->m_op.m_key;
14879
14880 sendSignal(rg, GSN_DICT_ABORT_REQ, signal, DictAbortReq::SignalLength, JBB);
14881 }
14882
14883 void
trans_abort_complete_done(Signal * signal,Uint32 callbackData,Uint32 retValue)14884 Dbdict::trans_abort_complete_done(Signal* signal,
14885 Uint32 callbackData,
14886 Uint32 retValue)
14887 {
14888 Ptr<SchemaTransaction> trans_ptr;
14889
14890 jam();
14891 ndbrequire(retValue == 0);
14892 ndbrequire(c_Trans.find(trans_ptr, callbackData));
14893
14894 switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
14895 case GSN_CREATE_FILEGROUP_REQ:
14896 {
14897 //
14898 CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtr();
14899 jam();
14900 ref->senderRef = reference();
14901 ref->senderData = trans_ptr.p->m_senderData;
14902 ref->masterNodeId = c_masterNodeId;
14903 ref->errorCode = trans_ptr.p->m_errorCode;
14904 ref->errorLine = 0;
14905 ref->errorKey = 0;
14906 ref->status = 0;
14907
14908 //@todo check api failed
14909 sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_REF, signal,
14910 CreateFilegroupRef::SignalLength, JBB);
14911 break;
14912 }
14913 case GSN_CREATE_FILE_REQ:
14914 {
14915 CreateFileRef * ref = (CreateFileRef*)signal->getDataPtr();
14916 jam();
14917 ref->senderRef = reference();
14918 ref->senderData = trans_ptr.p->m_senderData;
14919 ref->masterNodeId = c_masterNodeId;
14920 ref->errorCode = trans_ptr.p->m_errorCode;
14921 ref->errorLine = 0;
14922 ref->errorKey = 0;
14923 ref->status = 0;
14924
14925 //@todo check api failed
14926 sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_REF, signal,
14927 CreateFileRef::SignalLength, JBB);
14928 break;
14929 }
14930 case GSN_DROP_FILE_REQ:
14931 {
14932 DropFileRef * ref = (DropFileRef*)signal->getDataPtr();
14933 jam();
14934 ref->senderRef = reference();
14935 ref->senderData = trans_ptr.p->m_senderData;
14936 ref->masterNodeId = c_masterNodeId;
14937 ref->errorCode = trans_ptr.p->m_errorCode;
14938 ref->errorLine = 0;
14939 ref->errorKey = 0;
14940
14941 //@todo check api failed
14942 sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILE_REF, signal,
14943 DropFileRef::SignalLength, JBB);
14944 break;
14945 }
14946 case GSN_DROP_FILEGROUP_REQ:
14947 {
14948 //
14949 DropFilegroupRef * ref = (DropFilegroupRef*)signal->getDataPtr();
14950 jam();
14951 ref->senderRef = reference();
14952 ref->senderData = trans_ptr.p->m_senderData;
14953 ref->masterNodeId = c_masterNodeId;
14954 ref->errorCode = trans_ptr.p->m_errorCode;
14955 ref->errorLine = 0;
14956 ref->errorKey = 0;
14957
14958 //@todo check api failed
14959 sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILEGROUP_REF, signal,
14960 DropFilegroupRef::SignalLength, JBB);
14961 break;
14962 }
14963 default:
14964 ndbrequire(false);
14965 }
14966
14967 c_Trans.release(trans_ptr);
14968 ndbrequire(c_blockState == BS_CREATE_TAB);
14969 c_blockState = BS_IDLE;
14970 return;
14971 }
14972
14973 void
execCREATE_OBJ_REQ(Signal * signal)14974 Dbdict::execCREATE_OBJ_REQ(Signal* signal)
14975 {
14976 jamEntry();
14977
14978 if(!assembleFragments(signal)){
14979 jam();
14980 return;
14981 }
14982
14983 CreateObjReq * const req = (CreateObjReq*)signal->getDataPtr();
14984 const Uint32 gci = req->gci;
14985 const Uint32 objId = req->objId;
14986 const Uint32 objVersion = req->objVersion;
14987 const Uint32 objType = req->objType;
14988 const Uint32 requestInfo = req->requestInfo;
14989
14990 SegmentedSectionPtr objInfoPtr;
14991 signal->getSection(objInfoPtr, CreateObjReq::DICT_OBJ_INFO);
14992
14993 CreateObjRecordPtr createObjPtr;
14994 ndbrequire(c_opCreateObj.seize(createObjPtr));
14995
14996 const Uint32 key = req->op_key;
14997 createObjPtr.p->key = key;
14998 c_opCreateObj.add(createObjPtr);
14999 createObjPtr.p->m_errorCode = 0;
15000 createObjPtr.p->m_senderRef = req->senderRef;
15001 createObjPtr.p->m_senderData = req->senderData;
15002 createObjPtr.p->m_clientRef = req->clientRef;
15003 createObjPtr.p->m_clientData = req->clientData;
15004
15005 createObjPtr.p->m_gci = gci;
15006 createObjPtr.p->m_obj_id = objId;
15007 createObjPtr.p->m_obj_type = objType;
15008 createObjPtr.p->m_obj_version = objVersion;
15009 createObjPtr.p->m_obj_info_ptr_i = objInfoPtr.i;
15010 createObjPtr.p->m_obj_ptr_i = RNIL;
15011
15012 createObjPtr.p->m_callback.m_callbackData = key;
15013 createObjPtr.p->m_callback.m_callbackFunction=
15014 safe_cast(&Dbdict::createObj_prepare_start_done);
15015
15016 createObjPtr.p->m_restart= 0;
15017 switch(objType){
15018 case DictTabInfo::Tablespace:
15019 case DictTabInfo::LogfileGroup:
15020 jam();
15021 createObjPtr.p->m_vt_index = 0;
15022 break;
15023 case DictTabInfo::Datafile:
15024 case DictTabInfo::Undofile:
15025 /**
15026 * Use restart code to impl. ForceCreateFile
15027 */
15028 if (requestInfo & CreateFileReq::ForceCreateFile)
15029 {
15030 jam();
15031 createObjPtr.p->m_restart= 2;
15032 }
15033 jam();
15034 createObjPtr.p->m_vt_index = 1;
15035 break;
15036 default:
15037 ndbrequire(false);
15038 }
15039
15040 signal->header.m_noOfSections = 0;
15041 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
15042 (signal, createObjPtr.p);
15043 }
15044
15045 void
execDICT_COMMIT_REQ(Signal * signal)15046 Dbdict::execDICT_COMMIT_REQ(Signal* signal)
15047 {
15048 DictCommitReq* req = (DictCommitReq*)signal->getDataPtr();
15049 Ptr<SchemaOp> op;
15050
15051 jamEntry();
15052 ndbrequire(c_schemaOp.find(op, req->op_key));
15053 (this->*f_dict_op[op.p->m_vt_index].m_commit)(signal, op.p);
15054 }
15055
15056 void
execDICT_ABORT_REQ(Signal * signal)15057 Dbdict::execDICT_ABORT_REQ(Signal* signal)
15058 {
15059 DictAbortReq* req = (DictAbortReq*)signal->getDataPtr();
15060 Ptr<SchemaOp> op;
15061
15062 jamEntry();
15063 ndbrequire(c_schemaOp.find(op, req->op_key));
15064 (this->*f_dict_op[op.p->m_vt_index].m_abort)(signal, op.p);
15065 }
15066
15067 void
execDICT_COMMIT_REF(Signal * signal)15068 Dbdict::execDICT_COMMIT_REF(Signal* signal)
15069 {
15070 DictCommitRef * const ref = (DictCommitRef*)signal->getDataPtr();
15071 Ptr<SchemaTransaction> trans_ptr;
15072
15073 jamEntry();
15074 ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
15075 if(ref->errorCode != DictCommitRef::NF_FakeErrorREF){
15076 jam();
15077 trans_ptr.p->setErrorCode(ref->errorCode);
15078 }
15079 Uint32 node = refToNode(ref->senderRef);
15080 schemaOp_reply(signal, trans_ptr.p, node);
15081 }
15082
15083 void
execDICT_COMMIT_CONF(Signal * signal)15084 Dbdict::execDICT_COMMIT_CONF(Signal* signal)
15085 {
15086 Ptr<SchemaTransaction> trans_ptr;
15087 DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
15088
15089 jamEntry();
15090 ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
15091 schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
15092 }
15093
15094 void
execDICT_ABORT_REF(Signal * signal)15095 Dbdict::execDICT_ABORT_REF(Signal* signal)
15096 {
15097 DictAbortRef * const ref = (DictAbortRef*)signal->getDataPtr();
15098 Ptr<SchemaTransaction> trans_ptr;
15099
15100 jamEntry();
15101 ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
15102 if(ref->errorCode != DictAbortRef::NF_FakeErrorREF){
15103 jam();
15104 trans_ptr.p->setErrorCode(ref->errorCode);
15105 }
15106 Uint32 node = refToNode(ref->senderRef);
15107 schemaOp_reply(signal, trans_ptr.p, node);
15108 }
15109
15110 void
execDICT_ABORT_CONF(Signal * signal)15111 Dbdict::execDICT_ABORT_CONF(Signal* signal)
15112 {
15113 DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
15114 Ptr<SchemaTransaction> trans_ptr;
15115
15116 jamEntry();
15117 ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
15118 schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
15119 }
15120
15121 void
createObj_prepare_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15122 Dbdict::createObj_prepare_start_done(Signal* signal,
15123 Uint32 callbackData,
15124 Uint32 returnCode)
15125 {
15126 CreateObjRecordPtr createObjPtr;
15127 SegmentedSectionPtr objInfoPtr;
15128
15129 ndbrequire(returnCode == 0);
15130 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15131 jam();
15132 getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
15133 if(createObjPtr.p->m_errorCode != 0){
15134 jam();
15135 createObjPtr.p->m_obj_info_ptr_i= RNIL;
15136 signal->setSection(objInfoPtr, 0);
15137 releaseSections(signal);
15138 createObj_prepare_complete_done(signal, callbackData, 0);
15139 return;
15140 }
15141
15142 SchemaFile::TableEntry tabEntry;
15143 bzero(&tabEntry, sizeof(tabEntry));
15144 tabEntry.m_tableVersion = createObjPtr.p->m_obj_version;
15145 tabEntry.m_tableType = createObjPtr.p->m_obj_type;
15146 tabEntry.m_tableState = SchemaFile::ADD_STARTED;
15147 tabEntry.m_gcp = createObjPtr.p->m_gci;
15148 tabEntry.m_info_words = objInfoPtr.sz;
15149
15150 Callback cb;
15151 cb.m_callbackData = createObjPtr.p->key;
15152 cb.m_callbackFunction = safe_cast(&Dbdict::createObj_writeSchemaConf1);
15153
15154 updateSchemaState(signal, createObjPtr.p->m_obj_id, &tabEntry, &cb);
15155 }
15156
15157 void
createObj_writeSchemaConf1(Signal * signal,Uint32 callbackData,Uint32 returnCode)15158 Dbdict::createObj_writeSchemaConf1(Signal* signal,
15159 Uint32 callbackData,
15160 Uint32 returnCode)
15161 {
15162 CreateObjRecordPtr createObjPtr;
15163 Callback callback;
15164 SegmentedSectionPtr objInfoPtr;
15165
15166 jam();
15167 ndbrequire(returnCode == 0);
15168 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15169
15170 callback.m_callbackData = createObjPtr.p->key;
15171 callback.m_callbackFunction = safe_cast(&Dbdict::createObj_writeObjConf);
15172
15173 getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
15174 writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
15175
15176 signal->setSection(objInfoPtr, 0);
15177 releaseSections(signal);
15178 createObjPtr.p->m_obj_info_ptr_i = RNIL;
15179 }
15180
15181 void
createObj_writeObjConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)15182 Dbdict::createObj_writeObjConf(Signal* signal,
15183 Uint32 callbackData,
15184 Uint32 returnCode)
15185 {
15186 CreateObjRecordPtr createObjPtr;
15187
15188 jam();
15189 ndbrequire(returnCode == 0);
15190 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15191 createObjPtr.p->m_callback.m_callbackFunction =
15192 safe_cast(&Dbdict::createObj_prepare_complete_done);
15193 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
15194 (signal, createObjPtr.p);
15195 }
15196
15197 void
createObj_prepare_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15198 Dbdict::createObj_prepare_complete_done(Signal* signal,
15199 Uint32 callbackData,
15200 Uint32 returnCode)
15201 {
15202 CreateObjRecordPtr createObjPtr;
15203
15204 jam();
15205 ndbrequire(returnCode == 0);
15206 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15207
15208 //@todo check for master failed
15209
15210 if(createObjPtr.p->m_errorCode == 0){
15211 jam();
15212
15213 CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
15214 conf->senderRef = reference();
15215 conf->senderData = createObjPtr.p->m_senderData;
15216 sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_CONF,
15217 signal, CreateObjConf::SignalLength, JBB);
15218 return;
15219 }
15220
15221 CreateObjRef * const ref = (CreateObjRef*)signal->getDataPtr();
15222 ref->senderRef = reference();
15223 ref->senderData = createObjPtr.p->m_senderData;
15224 ref->errorCode = createObjPtr.p->m_errorCode;
15225 ref->errorLine = 0;
15226 ref->errorKey = 0;
15227 ref->errorStatus = 0;
15228
15229 sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_REF,
15230 signal, CreateObjRef::SignalLength, JBB);
15231 }
15232
15233 void
createObj_commit(Signal * signal,SchemaOp * op)15234 Dbdict::createObj_commit(Signal * signal, SchemaOp * op)
15235 {
15236 OpCreateObj * createObj = (OpCreateObj*)op;
15237
15238 createObj->m_callback.m_callbackFunction =
15239 safe_cast(&Dbdict::createObj_commit_start_done);
15240 if (f_dict_op[createObj->m_vt_index].m_commit_start)
15241 {
15242 jam();
15243 (this->*f_dict_op[createObj->m_vt_index].m_commit_start)(signal, createObj);
15244 }
15245 else
15246 {
15247 jam();
15248 execute(signal, createObj->m_callback, 0);
15249 }
15250 }
15251
15252 void
createObj_commit_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15253 Dbdict::createObj_commit_start_done(Signal* signal,
15254 Uint32 callbackData,
15255 Uint32 returnCode)
15256 {
15257 CreateObjRecordPtr createObjPtr;
15258
15259 jam();
15260 ndbrequire(returnCode == 0);
15261 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15262
15263 Uint32 objId = createObjPtr.p->m_obj_id;
15264 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
15265 SchemaFile::TableEntry objEntry = * getTableEntry(xsf, objId);
15266 objEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
15267
15268 Callback callback;
15269 callback.m_callbackData = createObjPtr.p->key;
15270 callback.m_callbackFunction =
15271 safe_cast(&Dbdict::createObj_writeSchemaConf2);
15272
15273 updateSchemaState(signal, createObjPtr.p->m_obj_id, &objEntry, &callback);
15274
15275 }
15276
15277 void
createObj_writeSchemaConf2(Signal * signal,Uint32 callbackData,Uint32 returnCode)15278 Dbdict::createObj_writeSchemaConf2(Signal* signal,
15279 Uint32 callbackData,
15280 Uint32 returnCode)
15281 {
15282 CreateObjRecordPtr createObjPtr;
15283
15284 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15285 createObjPtr.p->m_callback.m_callbackFunction =
15286 safe_cast(&Dbdict::createObj_commit_complete_done);
15287 if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
15288 {
15289 jam();
15290 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
15291 (signal, createObjPtr.p);
15292 }
15293 else
15294 {
15295 jam();
15296 execute(signal, createObjPtr.p->m_callback, 0);
15297 }
15298
15299 }
15300
15301 void
createObj_commit_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15302 Dbdict::createObj_commit_complete_done(Signal* signal,
15303 Uint32 callbackData,
15304 Uint32 returnCode)
15305 {
15306 CreateObjRecordPtr createObjPtr;
15307
15308 jam();
15309 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15310
15311 //@todo check error
15312 //@todo check master failed
15313
15314 DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
15315 conf->senderRef = reference();
15316 conf->senderData = createObjPtr.p->m_senderData;
15317 sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
15318 signal, DictCommitConf::SignalLength, JBB);
15319
15320 c_opCreateObj.release(createObjPtr);
15321 }
15322
15323 void
createObj_abort(Signal * signal,SchemaOp * op)15324 Dbdict::createObj_abort(Signal* signal, SchemaOp* op)
15325 {
15326 OpCreateObj * createObj = (OpCreateObj*)op;
15327
15328 createObj->m_callback.m_callbackFunction =
15329 safe_cast(&Dbdict::createObj_abort_start_done);
15330 if (f_dict_op[createObj->m_vt_index].m_abort_start)
15331 {
15332 jam();
15333 (this->*f_dict_op[createObj->m_vt_index].m_abort_start)(signal, createObj);
15334 }
15335 else
15336 {
15337 jam();
15338 execute(signal, createObj->m_callback, 0);
15339 }
15340 }
15341
15342 void
createObj_abort_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15343 Dbdict::createObj_abort_start_done(Signal* signal,
15344 Uint32 callbackData,
15345 Uint32 returnCode)
15346 {
15347 CreateObjRecordPtr createObjPtr;
15348
15349 jam();
15350 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15351 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
15352 SchemaFile::TableEntry objEntry = * getTableEntry(xsf,
15353 createObjPtr.p->m_obj_id);
15354 objEntry.m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
15355
15356 Callback callback;
15357 callback.m_callbackData = createObjPtr.p->key;
15358 callback.m_callbackFunction =
15359 safe_cast(&Dbdict::createObj_abort_writeSchemaConf);
15360
15361 updateSchemaState(signal, createObjPtr.p->m_obj_id, &objEntry, &callback);
15362 }
15363
15364 void
createObj_abort_writeSchemaConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)15365 Dbdict::createObj_abort_writeSchemaConf(Signal* signal,
15366 Uint32 callbackData,
15367 Uint32 returnCode)
15368 {
15369 CreateObjRecordPtr createObjPtr;
15370
15371 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15372 createObjPtr.p->m_callback.m_callbackFunction =
15373 safe_cast(&Dbdict::createObj_abort_complete_done);
15374
15375 if (f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
15376 {
15377 jam();
15378 (this->*f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
15379 (signal, createObjPtr.p);
15380 }
15381 else
15382 {
15383 jam();
15384 execute(signal, createObjPtr.p->m_callback, 0);
15385 }
15386 }
15387
15388 void
createObj_abort_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15389 Dbdict::createObj_abort_complete_done(Signal* signal,
15390 Uint32 callbackData,
15391 Uint32 returnCode)
15392 {
15393 CreateObjRecordPtr createObjPtr;
15394
15395 jam();
15396 ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
15397
15398 DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
15399 conf->senderRef = reference();
15400 conf->senderData = createObjPtr.p->m_senderData;
15401 sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
15402 signal, DictAbortConf::SignalLength, JBB);
15403
15404 c_opCreateObj.release(createObjPtr);
15405 }
15406
15407 void
execDROP_OBJ_REQ(Signal * signal)15408 Dbdict::execDROP_OBJ_REQ(Signal* signal)
15409 {
15410 jamEntry();
15411
15412 if(!assembleFragments(signal)){
15413 jam();
15414 return;
15415 }
15416
15417 DropObjReq * const req = (DropObjReq*)signal->getDataPtr();
15418
15419 const Uint32 objId = req->objId;
15420 const Uint32 objVersion = req->objVersion;
15421 const Uint32 objType = req->objType;
15422
15423 DropObjRecordPtr dropObjPtr;
15424 ndbrequire(c_opDropObj.seize(dropObjPtr));
15425
15426 const Uint32 key = req->op_key;
15427 dropObjPtr.p->key = key;
15428 c_opDropObj.add(dropObjPtr);
15429 dropObjPtr.p->m_errorCode = 0;
15430 dropObjPtr.p->m_senderRef = req->senderRef;
15431 dropObjPtr.p->m_senderData = req->senderData;
15432 dropObjPtr.p->m_clientRef = req->clientRef;
15433 dropObjPtr.p->m_clientData = req->clientData;
15434
15435 dropObjPtr.p->m_obj_id = objId;
15436 dropObjPtr.p->m_obj_type = objType;
15437 dropObjPtr.p->m_obj_version = objVersion;
15438
15439 dropObjPtr.p->m_callback.m_callbackData = key;
15440 dropObjPtr.p->m_callback.m_callbackFunction=
15441 safe_cast(&Dbdict::dropObj_prepare_start_done);
15442
15443 switch(objType){
15444 case DictTabInfo::Tablespace:
15445 case DictTabInfo::LogfileGroup:
15446 {
15447 Ptr<Filegroup> fg_ptr;
15448 jam();
15449 dropObjPtr.p->m_vt_index = 3;
15450 ndbrequire(c_filegroup_hash.find(fg_ptr, objId));
15451 dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
15452 break;
15453
15454 }
15455 case DictTabInfo::Datafile:
15456 {
15457 Ptr<File> file_ptr;
15458 jam();
15459 dropObjPtr.p->m_vt_index = 2;
15460 ndbrequire(c_file_hash.find(file_ptr, objId));
15461 dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
15462 break;
15463 }
15464 case DictTabInfo::Undofile:
15465 {
15466 jam();
15467 dropObjPtr.p->m_vt_index = 4;
15468 return;
15469 }
15470 default:
15471 ndbrequire(false);
15472 }
15473
15474 signal->header.m_noOfSections = 0;
15475 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
15476 (signal, dropObjPtr.p);
15477 }
15478
15479 void
dropObj_prepare_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15480 Dbdict::dropObj_prepare_start_done(Signal* signal,
15481 Uint32 callbackData,
15482 Uint32 returnCode)
15483 {
15484 DropObjRecordPtr dropObjPtr;
15485 Callback cb;
15486
15487 ndbrequire(returnCode == 0);
15488 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15489
15490 cb.m_callbackData = callbackData;
15491 cb.m_callbackFunction =
15492 safe_cast(&Dbdict::dropObj_prepare_writeSchemaConf);
15493
15494 if(dropObjPtr.p->m_errorCode != 0)
15495 {
15496 jam();
15497 dropObj_prepare_complete_done(signal, callbackData, 0);
15498 return;
15499 }
15500 jam();
15501 Uint32 objId = dropObjPtr.p->m_obj_id;
15502 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
15503 SchemaFile::TableEntry objEntry = *getTableEntry(xsf, objId);
15504 objEntry.m_tableState = SchemaFile::DROP_TABLE_STARTED;
15505 updateSchemaState(signal, objId, &objEntry, &cb);
15506 }
15507
15508 void
dropObj_prepare_writeSchemaConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)15509 Dbdict::dropObj_prepare_writeSchemaConf(Signal* signal,
15510 Uint32 callbackData,
15511 Uint32 returnCode)
15512 {
15513 DropObjRecordPtr dropObjPtr;
15514
15515 ndbrequire(returnCode == 0);
15516 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15517 dropObjPtr.p->m_callback.m_callbackFunction =
15518 safe_cast(&Dbdict::dropObj_prepare_complete_done);
15519 if(f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
15520 {
15521 jam();
15522 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
15523 (signal, dropObjPtr.p);
15524 }
15525 else
15526 {
15527 jam();
15528 execute(signal, dropObjPtr.p->m_callback, 0);
15529 }
15530 }
15531
15532 void
dropObj_prepare_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15533 Dbdict::dropObj_prepare_complete_done(Signal* signal,
15534 Uint32 callbackData,
15535 Uint32 returnCode)
15536 {
15537 DropObjRecordPtr dropObjPtr;
15538
15539 ndbrequire(returnCode == 0);
15540 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15541 jam();
15542
15543 //@todo check for master failed
15544
15545 if(dropObjPtr.p->m_errorCode == 0){
15546 jam();
15547
15548 DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
15549 conf->senderRef = reference();
15550 conf->senderData = dropObjPtr.p->m_senderData;
15551 sendSignal(dropObjPtr.p->m_senderRef, GSN_DROP_OBJ_CONF,
15552 signal, DropObjConf::SignalLength, JBB);
15553 return;
15554 }
15555
15556 DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
15557 ref->senderRef = reference();
15558 ref->senderData = dropObjPtr.p->m_senderData;
15559 ref->errorCode = dropObjPtr.p->m_errorCode;
15560
15561 sendSignal(dropObjPtr.p->m_senderRef, GSN_DROP_OBJ_REF,
15562 signal, DropObjRef::SignalLength, JBB);
15563
15564 }
15565
15566 void
dropObj_commit(Signal * signal,SchemaOp * op)15567 Dbdict::dropObj_commit(Signal * signal, SchemaOp * op)
15568 {
15569 OpDropObj * dropObj = (OpDropObj*)op;
15570
15571 dropObj->m_callback.m_callbackFunction =
15572 safe_cast(&Dbdict::dropObj_commit_start_done);
15573 if (f_dict_op[dropObj->m_vt_index].m_commit_start)
15574 {
15575 jam();
15576 (this->*f_dict_op[dropObj->m_vt_index].m_commit_start)(signal, dropObj);
15577 }
15578 else
15579 {
15580 jam();
15581 execute(signal, dropObj->m_callback, 0);
15582 }
15583 }
15584
15585 void
dropObj_commit_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15586 Dbdict::dropObj_commit_start_done(Signal* signal,
15587 Uint32 callbackData,
15588 Uint32 returnCode)
15589 {
15590 DropObjRecordPtr dropObjPtr;
15591
15592 jam();
15593 ndbrequire(returnCode == 0);
15594 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15595
15596 Uint32 objId = dropObjPtr.p->m_obj_id;
15597 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
15598 SchemaFile::TableEntry objEntry = * getTableEntry(xsf, objId);
15599 objEntry.m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
15600
15601 Callback callback;
15602 callback.m_callbackData = dropObjPtr.p->key;
15603 callback.m_callbackFunction =
15604 safe_cast(&Dbdict::dropObj_commit_writeSchemaConf);
15605
15606 updateSchemaState(signal, objId, &objEntry, &callback);
15607 }
15608
15609 void
dropObj_commit_writeSchemaConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)15610 Dbdict::dropObj_commit_writeSchemaConf(Signal* signal,
15611 Uint32 callbackData,
15612 Uint32 returnCode)
15613 {
15614 DropObjRecordPtr dropObjPtr;
15615
15616 jam();
15617 ndbrequire(returnCode == 0);
15618 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15619 dropObjPtr.p->m_callback.m_callbackFunction =
15620 safe_cast(&Dbdict::dropObj_commit_complete_done);
15621
15622 if(f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
15623 {
15624 jam();
15625 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
15626 (signal, dropObjPtr.p);
15627 }
15628 else
15629 {
15630 jam();
15631 execute(signal, dropObjPtr.p->m_callback, 0);
15632 }
15633 }
15634
15635 void
dropObj_commit_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15636 Dbdict::dropObj_commit_complete_done(Signal* signal,
15637 Uint32 callbackData,
15638 Uint32 returnCode)
15639 {
15640 DropObjRecordPtr dropObjPtr;
15641
15642 jam();
15643 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15644
15645 //@todo check error
15646 //@todo check master failed
15647
15648 DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
15649 conf->senderRef = reference();
15650 conf->senderData = dropObjPtr.p->m_senderData;
15651 sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
15652 signal, DictCommitConf::SignalLength, JBB);
15653 c_opDropObj.release(dropObjPtr);
15654 }
15655
15656 void
dropObj_abort(Signal * signal,SchemaOp * op)15657 Dbdict::dropObj_abort(Signal * signal, SchemaOp * op)
15658 {
15659 OpDropObj * dropObj = (OpDropObj*)op;
15660
15661 dropObj->m_callback.m_callbackFunction =
15662 safe_cast(&Dbdict::dropObj_abort_start_done);
15663 if (f_dict_op[dropObj->m_vt_index].m_abort_start)
15664 {
15665 jam();
15666 (this->*f_dict_op[dropObj->m_vt_index].m_abort_start)(signal, dropObj);
15667 }
15668 else
15669 {
15670 jam();
15671 execute(signal, dropObj->m_callback, 0);
15672 }
15673 }
15674
15675 void
dropObj_abort_start_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15676 Dbdict::dropObj_abort_start_done(Signal* signal,
15677 Uint32 callbackData,
15678 Uint32 returnCode)
15679 {
15680 DropObjRecordPtr dropObjPtr;
15681
15682 jam();
15683 ndbrequire(returnCode == 0);
15684 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15685
15686 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
15687 SchemaFile::TableEntry objEntry = * getTableEntry(xsf,
15688 dropObjPtr.p->m_obj_id);
15689
15690 Callback callback;
15691 callback.m_callbackData = dropObjPtr.p->key;
15692 callback.m_callbackFunction =
15693 safe_cast(&Dbdict::dropObj_abort_writeSchemaConf);
15694
15695 if (objEntry.m_tableState == SchemaFile::DROP_TABLE_STARTED)
15696 {
15697 jam();
15698 objEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
15699
15700 updateSchemaState(signal, dropObjPtr.p->m_obj_id, &objEntry, &callback);
15701 }
15702 else
15703 {
15704 jam();
15705 execute(signal, callback, 0);
15706 }
15707 }
15708
15709 void
dropObj_abort_writeSchemaConf(Signal * signal,Uint32 callbackData,Uint32 returnCode)15710 Dbdict::dropObj_abort_writeSchemaConf(Signal* signal,
15711 Uint32 callbackData,
15712 Uint32 returnCode)
15713 {
15714 DropObjRecordPtr dropObjPtr;
15715
15716 ndbrequire(returnCode == 0);
15717 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15718 dropObjPtr.p->m_callback.m_callbackFunction =
15719 safe_cast(&Dbdict::dropObj_abort_complete_done);
15720
15721 if(f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
15722 {
15723 jam();
15724 (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
15725 (signal, dropObjPtr.p);
15726 }
15727 else
15728 {
15729 jam();
15730 execute(signal, dropObjPtr.p->m_callback, 0);
15731 }
15732 }
15733
15734 void
dropObj_abort_complete_done(Signal * signal,Uint32 callbackData,Uint32 returnCode)15735 Dbdict::dropObj_abort_complete_done(Signal* signal,
15736 Uint32 callbackData,
15737 Uint32 returnCode)
15738 {
15739 DropObjRecordPtr dropObjPtr;
15740 DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
15741
15742 ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
15743 jam();
15744 conf->senderRef = reference();
15745 conf->senderData = dropObjPtr.p->m_senderData;
15746 sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
15747 signal, DictAbortConf::SignalLength, JBB);
15748 c_opDropObj.release(dropObjPtr);
15749 }
15750
15751 void
create_fg_prepare_start(Signal * signal,SchemaOp * op)15752 Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op)
15753 {
15754 /**
15755 * Put data into table record
15756 */
15757 SegmentedSectionPtr objInfoPtr;
15758 jam();
15759 getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
15760 SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
15761
15762 Ptr<DictObject> obj_ptr; obj_ptr.setNull();
15763 FilegroupPtr fg_ptr; fg_ptr.setNull();
15764
15765 SimpleProperties::UnpackStatus status;
15766 DictFilegroupInfo::Filegroup fg; fg.init();
15767 do {
15768 status = SimpleProperties::unpack(it, &fg,
15769 DictFilegroupInfo::Mapping,
15770 DictFilegroupInfo::MappingSize,
15771 true, true);
15772
15773 if(status != SimpleProperties::Eof)
15774 {
15775 jam();
15776 op->m_errorCode = CreateTableRef::InvalidFormat;
15777 break;
15778 }
15779
15780 if(fg.FilegroupType == DictTabInfo::Tablespace)
15781 {
15782 if(!fg.TS_ExtentSize)
15783 {
15784 jam();
15785 op->m_errorCode = CreateFilegroupRef::InvalidExtentSize;
15786 break;
15787 }
15788 }
15789 else if(fg.FilegroupType == DictTabInfo::LogfileGroup)
15790 {
15791 /**
15792 * undo_buffer_size can't be less than 96KB in LGMAN block
15793 */
15794 if(fg.LF_UndoBufferSize < 3 * File_formats::NDB_PAGE_SIZE)
15795 {
15796 jam();
15797 op->m_errorCode = CreateFilegroupRef::InvalidUndoBufferSize;
15798 break;
15799 }
15800 }
15801
15802 Uint32 len = strlen(fg.FilegroupName) + 1;
15803 Uint32 hash = Rope::hash(fg.FilegroupName, len);
15804 if(get_object(fg.FilegroupName, len, hash) != 0){
15805 jam();
15806 op->m_errorCode = CreateTableRef::TableAlreadyExist;
15807 break;
15808 }
15809
15810 if(!c_obj_pool.seize(obj_ptr)){
15811 jam();
15812 op->m_errorCode = CreateTableRef::NoMoreTableRecords;
15813 break;
15814 }
15815
15816 if(!c_filegroup_pool.seize(fg_ptr)){
15817 jam();
15818 op->m_errorCode = CreateTableRef::NoMoreTableRecords;
15819 break;
15820 }
15821
15822 new (fg_ptr.p) Filegroup();
15823
15824 {
15825 Rope name(c_rope_pool, obj_ptr.p->m_name);
15826 if(!name.assign(fg.FilegroupName, len, hash)){
15827 jam();
15828 op->m_errorCode = CreateTableRef::OutOfStringBuffer;
15829 break;
15830 }
15831 }
15832
15833 fg_ptr.p->key = op->m_obj_id;
15834 fg_ptr.p->m_obj_ptr_i = obj_ptr.i;
15835 fg_ptr.p->m_type = fg.FilegroupType;
15836 fg_ptr.p->m_version = op->m_obj_version;
15837 fg_ptr.p->m_name = obj_ptr.p->m_name;
15838
15839 switch(fg.FilegroupType){
15840 case DictTabInfo::Tablespace:
15841 {
15842 //fg.TS_DataGrow = group.m_grow_spec;
15843 fg_ptr.p->m_tablespace.m_extent_size = fg.TS_ExtentSize;
15844 fg_ptr.p->m_tablespace.m_default_logfile_group_id = fg.TS_LogfileGroupId;
15845
15846 Ptr<Filegroup> lg_ptr;
15847 if (!c_filegroup_hash.find(lg_ptr, fg.TS_LogfileGroupId))
15848 {
15849 jam();
15850 op->m_errorCode = CreateFilegroupRef::NoSuchLogfileGroup;
15851 goto error;
15852 }
15853
15854 if (lg_ptr.p->m_version != fg.TS_LogfileGroupVersion)
15855 {
15856 jam();
15857 op->m_errorCode = CreateFilegroupRef::InvalidFilegroupVersion;
15858 goto error;
15859 }
15860 increase_ref_count(lg_ptr.p->m_obj_ptr_i);
15861 break;
15862 }
15863 case DictTabInfo::LogfileGroup:
15864 {
15865 jam();
15866 fg_ptr.p->m_logfilegroup.m_undo_buffer_size = fg.LF_UndoBufferSize;
15867 fg_ptr.p->m_logfilegroup.m_files.init();
15868 //fg.LF_UndoGrow = ;
15869 break;
15870 }
15871 default:
15872 ndbrequire(false);
15873 }
15874
15875 obj_ptr.p->m_id = op->m_obj_id;
15876 obj_ptr.p->m_type = fg.FilegroupType;
15877 obj_ptr.p->m_ref_count = 0;
15878 c_obj_hash.add(obj_ptr);
15879 c_filegroup_hash.add(fg_ptr);
15880
15881 op->m_obj_ptr_i = fg_ptr.i;
15882 } while(0);
15883
15884 error:
15885 if (op->m_errorCode)
15886 {
15887 jam();
15888 if (!fg_ptr.isNull())
15889 {
15890 jam();
15891 c_filegroup_pool.release(fg_ptr);
15892 }
15893
15894 if (!obj_ptr.isNull())
15895 {
15896 jam();
15897 c_obj_pool.release(obj_ptr);
15898 }
15899 }
15900
15901 execute(signal, op->m_callback, 0);
15902 }
15903
15904 void
create_fg_prepare_complete(Signal * signal,SchemaOp * op)15905 Dbdict::create_fg_prepare_complete(Signal* signal, SchemaOp* op)
15906 {
15907 /**
15908 * CONTACT TSMAN LGMAN PGMAN
15909 */
15910 CreateFilegroupImplReq* req =
15911 (CreateFilegroupImplReq*)signal->getDataPtrSend();
15912 jam();
15913 req->senderData = op->key;
15914 req->senderRef = reference();
15915 req->filegroup_id = op->m_obj_id;
15916 req->filegroup_version = op->m_obj_version;
15917
15918 FilegroupPtr fg_ptr;
15919 c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
15920
15921 Uint32 ref= 0;
15922 Uint32 len= 0;
15923 switch(op->m_obj_type){
15924 case DictTabInfo::Tablespace:
15925 {
15926 jam();
15927 ref = TSMAN_REF;
15928 len = CreateFilegroupImplReq::TablespaceLength;
15929 req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
15930 req->tablespace.logfile_group_id =
15931 fg_ptr.p->m_tablespace.m_default_logfile_group_id;
15932 break;
15933 }
15934 case DictTabInfo::LogfileGroup:
15935 {
15936 jam();
15937 ref = LGMAN_REF;
15938 len = CreateFilegroupImplReq::LogfileGroupLength;
15939 req->logfile_group.buffer_size =
15940 fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
15941 break;
15942 }
15943 default:
15944 ndbrequire(false);
15945 }
15946
15947 sendSignal(ref, GSN_CREATE_FILEGROUP_REQ, signal, len, JBB);
15948 }
15949
15950 void
execCREATE_FILEGROUP_REF(Signal * signal)15951 Dbdict::execCREATE_FILEGROUP_REF(Signal* signal)
15952 {
15953 CreateFilegroupImplRef * ref = (CreateFilegroupImplRef*)signal->getDataPtr();
15954 CreateObjRecordPtr op_ptr;
15955 jamEntry();
15956 ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
15957 op_ptr.p->m_errorCode = ref->errorCode;
15958
15959 execute(signal, op_ptr.p->m_callback, 0);
15960 }
15961
15962 void
execCREATE_FILEGROUP_CONF(Signal * signal)15963 Dbdict::execCREATE_FILEGROUP_CONF(Signal* signal)
15964 {
15965 CreateFilegroupImplConf * rep =
15966 (CreateFilegroupImplConf*)signal->getDataPtr();
15967 CreateObjRecordPtr op_ptr;
15968 jamEntry();
15969 ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
15970
15971 execute(signal, op_ptr.p->m_callback, 0);
15972 }
15973
15974 void
create_fg_abort_start(Signal * signal,SchemaOp * op)15975 Dbdict::create_fg_abort_start(Signal* signal, SchemaOp* op){
15976 (void) signal->getDataPtrSend();
15977
15978 if (op->m_obj_ptr_i != RNIL)
15979 {
15980 jam();
15981 send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
15982 return;
15983 }
15984 jam();
15985 execute(signal, op->m_callback, 0);
15986 }
15987
15988 void
create_fg_abort_complete(Signal * signal,SchemaOp * op)15989 Dbdict::create_fg_abort_complete(Signal* signal, SchemaOp* op)
15990 {
15991 if (op->m_obj_ptr_i != RNIL)
15992 {
15993 jam();
15994 FilegroupPtr fg_ptr;
15995 c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
15996
15997 release_object(fg_ptr.p->m_obj_ptr_i);
15998 c_filegroup_hash.release(fg_ptr);
15999 }
16000 jam();
16001 execute(signal, op->m_callback, 0);
16002 }
16003
16004 void
create_file_prepare_start(Signal * signal,SchemaOp * op)16005 Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op)
16006 {
16007 /**
16008 * Put data into table record
16009 */
16010 SegmentedSectionPtr objInfoPtr;
16011 getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
16012 SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
16013
16014 Ptr<DictObject> obj_ptr; obj_ptr.setNull();
16015 FilePtr filePtr; filePtr.setNull();
16016
16017 DictFilegroupInfo::File f; f.init();
16018 SimpleProperties::UnpackStatus status;
16019 status = SimpleProperties::unpack(it, &f,
16020 DictFilegroupInfo::FileMapping,
16021 DictFilegroupInfo::FileMappingSize,
16022 true, true);
16023
16024 do {
16025 if(status != SimpleProperties::Eof){
16026 jam();
16027 op->m_errorCode = CreateFileRef::InvalidFormat;
16028 break;
16029 }
16030
16031 // Get Filegroup
16032 FilegroupPtr fg_ptr;
16033 if(!c_filegroup_hash.find(fg_ptr, f.FilegroupId)){
16034 jam();
16035 op->m_errorCode = CreateFileRef::NoSuchFilegroup;
16036 break;
16037 }
16038
16039 if(fg_ptr.p->m_version != f.FilegroupVersion){
16040 jam();
16041 op->m_errorCode = CreateFileRef::InvalidFilegroupVersion;
16042 break;
16043 }
16044
16045 switch(f.FileType){
16046 case DictTabInfo::Datafile:
16047 {
16048 if(fg_ptr.p->m_type != DictTabInfo::Tablespace)
16049 {
16050 jam();
16051 op->m_errorCode = CreateFileRef::InvalidFileType;
16052 }
16053 jam();
16054 break;
16055 }
16056 case DictTabInfo::Undofile:
16057 {
16058 if(fg_ptr.p->m_type != DictTabInfo::LogfileGroup)
16059 {
16060 jam();
16061 op->m_errorCode = CreateFileRef::InvalidFileType;
16062 }
16063 jam();
16064 break;
16065 }
16066 default:
16067 jam();
16068 op->m_errorCode = CreateFileRef::InvalidFileType;
16069 }
16070
16071 if(op->m_errorCode)
16072 {
16073 jam();
16074 break;
16075 }
16076
16077 Uint32 len = strlen(f.FileName) + 1;
16078 Uint32 hash = Rope::hash(f.FileName, len);
16079 if(get_object(f.FileName, len, hash) != 0){
16080 jam();
16081 op->m_errorCode = CreateFileRef::FilenameAlreadyExists;
16082 break;
16083 }
16084
16085 {
16086 Uint32 dl;
16087 const ndb_mgm_configuration_iterator * p =
16088 m_ctx.m_config.getOwnConfigIterator();
16089 if(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl)
16090 {
16091 jam();
16092 op->m_errorCode = CreateFileRef::NotSupportedWhenDiskless;
16093 break;
16094 }
16095 }
16096
16097 // Loop through all filenames...
16098 if(!c_obj_pool.seize(obj_ptr)){
16099 jam();
16100 op->m_errorCode = CreateTableRef::NoMoreTableRecords;
16101 break;
16102 }
16103
16104 if (! c_file_pool.seize(filePtr)){
16105 jam();
16106 op->m_errorCode = CreateFileRef::OutOfFileRecords;
16107 break;
16108 }
16109
16110 new (filePtr.p) File();
16111
16112 {
16113 Rope name(c_rope_pool, obj_ptr.p->m_name);
16114 if(!name.assign(f.FileName, len, hash)){
16115 jam();
16116 op->m_errorCode = CreateTableRef::OutOfStringBuffer;
16117 break;
16118 }
16119 }
16120
16121 switch(fg_ptr.p->m_type){
16122 case DictTabInfo::Tablespace:
16123 {
16124 jam();
16125 increase_ref_count(fg_ptr.p->m_obj_ptr_i);
16126 break;
16127 }
16128 case DictTabInfo::LogfileGroup:
16129 {
16130 jam();
16131 Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
16132 list.add(filePtr);
16133 break;
16134 }
16135 default:
16136 ndbrequire(false);
16137 }
16138
16139 /**
16140 * Init file
16141 */
16142 filePtr.p->key = op->m_obj_id;
16143 filePtr.p->m_file_size = ((Uint64)f.FileSizeHi) << 32 | f.FileSizeLo;
16144 filePtr.p->m_path = obj_ptr.p->m_name;
16145 filePtr.p->m_obj_ptr_i = obj_ptr.i;
16146 filePtr.p->m_filegroup_id = f.FilegroupId;
16147 filePtr.p->m_type = f.FileType;
16148 filePtr.p->m_version = op->m_obj_version;
16149
16150 obj_ptr.p->m_id = op->m_obj_id;
16151 obj_ptr.p->m_type = f.FileType;
16152 obj_ptr.p->m_ref_count = 0;
16153 c_obj_hash.add(obj_ptr);
16154 c_file_hash.add(filePtr);
16155
16156 op->m_obj_ptr_i = filePtr.i;
16157 } while(0);
16158
16159 if (op->m_errorCode)
16160 {
16161 jam();
16162 if (!filePtr.isNull())
16163 {
16164 jam();
16165 c_file_pool.release(filePtr);
16166 }
16167
16168 if (!obj_ptr.isNull())
16169 {
16170 jam();
16171 c_obj_pool.release(obj_ptr);
16172 }
16173 }
16174 execute(signal, op->m_callback, 0);
16175 }
16176
16177
16178 void
create_file_prepare_complete(Signal * signal,SchemaOp * op)16179 Dbdict::create_file_prepare_complete(Signal* signal, SchemaOp* op)
16180 {
16181 /**
16182 * CONTACT TSMAN LGMAN PGMAN
16183 */
16184 CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
16185 FilePtr f_ptr;
16186 FilegroupPtr fg_ptr;
16187
16188 jam();
16189 c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
16190 ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
16191
16192 req->senderData = op->key;
16193 req->senderRef = reference();
16194 switch(((OpCreateObj*)op)->m_restart){
16195 case 0:
16196 {
16197 jam();
16198 req->requestInfo = CreateFileImplReq::Create;
16199 break;
16200 }
16201 case 1:
16202 {
16203 jam();
16204 req->requestInfo = CreateFileImplReq::Open;
16205 break;
16206 }
16207 case 2:
16208 {
16209 jam();
16210 req->requestInfo = CreateFileImplReq::CreateForce;
16211 break;
16212 }
16213 }
16214
16215 req->file_id = f_ptr.p->key;
16216 req->filegroup_id = f_ptr.p->m_filegroup_id;
16217 req->filegroup_version = fg_ptr.p->m_version;
16218 req->file_size_hi = f_ptr.p->m_file_size >> 32;
16219 req->file_size_lo = f_ptr.p->m_file_size & 0xFFFFFFFF;
16220
16221 Uint32 ref= 0;
16222 Uint32 len= 0;
16223 switch(op->m_obj_type){
16224 case DictTabInfo::Datafile:
16225 {
16226 jam();
16227 ref = TSMAN_REF;
16228 len = CreateFileImplReq::DatafileLength;
16229 req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
16230 break;
16231 }
16232 case DictTabInfo::Undofile:
16233 {
16234 jam();
16235 ref = LGMAN_REF;
16236 len = CreateFileImplReq::UndofileLength;
16237 break;
16238 }
16239 default:
16240 ndbrequire(false);
16241 }
16242
16243 char name[MAX_TAB_NAME_SIZE];
16244 ConstRope tmp(c_rope_pool, f_ptr.p->m_path);
16245 tmp.copy(name);
16246 LinearSectionPtr ptr[3];
16247 ptr[0].p = (Uint32*)&name[0];
16248 ptr[0].sz = (strlen(name)+1+3)/4;
16249 sendSignal(ref, GSN_CREATE_FILE_REQ, signal, len, JBB, ptr, 1);
16250 }
16251
16252 void
execCREATE_FILE_REF(Signal * signal)16253 Dbdict::execCREATE_FILE_REF(Signal* signal)
16254 {
16255 CreateFileImplRef * ref = (CreateFileImplRef*)signal->getDataPtr();
16256 CreateObjRecordPtr op_ptr;
16257
16258 jamEntry();
16259 ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
16260 op_ptr.p->m_errorCode = ref->errorCode;
16261 execute(signal, op_ptr.p->m_callback, 0);
16262 }
16263
16264 void
execCREATE_FILE_CONF(Signal * signal)16265 Dbdict::execCREATE_FILE_CONF(Signal* signal)
16266 {
16267 CreateFileImplConf * rep =
16268 (CreateFileImplConf*)signal->getDataPtr();
16269 CreateObjRecordPtr op_ptr;
16270
16271 jamEntry();
16272 ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
16273 execute(signal, op_ptr.p->m_callback, 0);
16274 }
16275
16276 void
create_file_commit_start(Signal * signal,SchemaOp * op)16277 Dbdict::create_file_commit_start(Signal* signal, SchemaOp* op)
16278 {
16279 /**
16280 * CONTACT TSMAN LGMAN PGMAN
16281 */
16282 CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
16283 FilePtr f_ptr;
16284 FilegroupPtr fg_ptr;
16285
16286 jam();
16287 c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
16288 ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
16289
16290 req->senderData = op->key;
16291 req->senderRef = reference();
16292 req->requestInfo = CreateFileImplReq::Commit;
16293
16294 req->file_id = f_ptr.p->key;
16295 req->filegroup_id = f_ptr.p->m_filegroup_id;
16296 req->filegroup_version = fg_ptr.p->m_version;
16297
16298 Uint32 ref= 0;
16299 switch(op->m_obj_type){
16300 case DictTabInfo::Datafile:
16301 {
16302 jam();
16303 ref = TSMAN_REF;
16304 break;
16305 }
16306 case DictTabInfo::Undofile:
16307 {
16308 jam();
16309 ref = LGMAN_REF;
16310 break;
16311 }
16312 default:
16313 ndbrequire(false);
16314 }
16315 sendSignal(ref, GSN_CREATE_FILE_REQ, signal,
16316 CreateFileImplReq::CommitLength, JBB);
16317 }
16318
16319 void
create_file_abort_start(Signal * signal,SchemaOp * op)16320 Dbdict::create_file_abort_start(Signal* signal, SchemaOp* op)
16321 {
16322 CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
16323
16324 if (op->m_obj_ptr_i != RNIL)
16325 {
16326 FilePtr f_ptr;
16327 FilegroupPtr fg_ptr;
16328
16329 jam();
16330 c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
16331
16332 ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
16333
16334 req->senderData = op->key;
16335 req->senderRef = reference();
16336 req->requestInfo = CreateFileImplReq::Abort;
16337
16338 req->file_id = f_ptr.p->key;
16339 req->filegroup_id = f_ptr.p->m_filegroup_id;
16340 req->filegroup_version = fg_ptr.p->m_version;
16341
16342 Uint32 ref= 0;
16343 switch(op->m_obj_type){
16344 case DictTabInfo::Datafile:
16345 {
16346 jam();
16347 ref = TSMAN_REF;
16348 break;
16349 }
16350 case DictTabInfo::Undofile:
16351 {
16352 jam();
16353 ref = LGMAN_REF;
16354 break;
16355 }
16356 default:
16357 ndbrequire(false);
16358 }
16359 sendSignal(ref, GSN_CREATE_FILE_REQ, signal,
16360 CreateFileImplReq::AbortLength, JBB);
16361 return;
16362 }
16363 execute(signal, op->m_callback, 0);
16364 }
16365
16366 void
create_file_abort_complete(Signal * signal,SchemaOp * op)16367 Dbdict::create_file_abort_complete(Signal* signal, SchemaOp* op)
16368 {
16369 if (op->m_obj_ptr_i != RNIL)
16370 {
16371 FilePtr f_ptr;
16372 FilegroupPtr fg_ptr;
16373
16374 jam();
16375 c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
16376 ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
16377 switch(fg_ptr.p->m_type){
16378 case DictTabInfo::Tablespace:
16379 {
16380 jam();
16381 decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
16382 break;
16383 }
16384 case DictTabInfo::LogfileGroup:
16385 {
16386 jam();
16387 Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
16388 list.remove(f_ptr);
16389 break;
16390 }
16391 default:
16392 ndbrequire(false);
16393 }
16394
16395 release_object(f_ptr.p->m_obj_ptr_i);
16396 c_file_hash.release(f_ptr);
16397 }
16398 execute(signal, op->m_callback, 0);
16399 }
16400
16401 void
drop_file_prepare_start(Signal * signal,SchemaOp * op)16402 Dbdict::drop_file_prepare_start(Signal* signal, SchemaOp* op)
16403 {
16404 jam();
16405 send_drop_file(signal, op, DropFileImplReq::Prepare);
16406 }
16407
16408 void
drop_undofile_prepare_start(Signal * signal,SchemaOp * op)16409 Dbdict::drop_undofile_prepare_start(Signal* signal, SchemaOp* op)
16410 {
16411 jam();
16412 op->m_errorCode = DropFileRef::DropUndoFileNotSupported;
16413 execute(signal, op->m_callback, 0);
16414 }
16415
16416 void
drop_file_commit_start(Signal * signal,SchemaOp * op)16417 Dbdict::drop_file_commit_start(Signal* signal, SchemaOp* op)
16418 {
16419 jam();
16420 send_drop_file(signal, op, DropFileImplReq::Commit);
16421 }
16422
16423 void
drop_file_commit_complete(Signal * signal,SchemaOp * op)16424 Dbdict::drop_file_commit_complete(Signal* signal, SchemaOp* op)
16425 {
16426 FilePtr f_ptr;
16427 FilegroupPtr fg_ptr;
16428
16429 jam();
16430 c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
16431 ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
16432 decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
16433 release_object(f_ptr.p->m_obj_ptr_i);
16434 c_file_hash.release(f_ptr);
16435 execute(signal, op->m_callback, 0);
16436 }
16437
16438 void
drop_undofile_commit_complete(Signal * signal,SchemaOp * op)16439 Dbdict::drop_undofile_commit_complete(Signal* signal, SchemaOp* op)
16440 {
16441 FilePtr f_ptr;
16442 FilegroupPtr fg_ptr;
16443
16444 jam();
16445 c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
16446 ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
16447 Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
16448 list.remove(f_ptr);
16449 release_object(f_ptr.p->m_obj_ptr_i);
16450 c_file_hash.release(f_ptr);
16451 execute(signal, op->m_callback, 0);
16452 }
16453
16454 void
drop_file_abort_start(Signal * signal,SchemaOp * op)16455 Dbdict::drop_file_abort_start(Signal* signal, SchemaOp* op)
16456 {
16457 jam();
16458 send_drop_file(signal, op, DropFileImplReq::Abort);
16459 }
16460
16461 void
send_drop_file(Signal * signal,SchemaOp * op,DropFileImplReq::RequestInfo type)16462 Dbdict::send_drop_file(Signal* signal, SchemaOp* op,
16463 DropFileImplReq::RequestInfo type)
16464 {
16465 DropFileImplReq* req = (DropFileImplReq*)signal->getDataPtrSend();
16466 FilePtr f_ptr;
16467 FilegroupPtr fg_ptr;
16468
16469 jam();
16470 c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
16471 ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
16472
16473 req->senderData = op->key;
16474 req->senderRef = reference();
16475 req->requestInfo = type;
16476
16477 req->file_id = f_ptr.p->key;
16478 req->filegroup_id = f_ptr.p->m_filegroup_id;
16479 req->filegroup_version = fg_ptr.p->m_version;
16480
16481 Uint32 ref= 0;
16482 switch(op->m_obj_type){
16483 case DictTabInfo::Datafile:
16484 {
16485 jam();
16486 ref = TSMAN_REF;
16487 break;
16488 }
16489 case DictTabInfo::Undofile:
16490 {
16491 jam();
16492 ref = LGMAN_REF;
16493 break;
16494 }
16495 default:
16496 ndbrequire(false);
16497 }
16498 sendSignal(ref, GSN_DROP_FILE_REQ, signal,
16499 DropFileImplReq::SignalLength, JBB);
16500 }
16501
16502 void
execDROP_OBJ_REF(Signal * signal)16503 Dbdict::execDROP_OBJ_REF(Signal* signal)
16504 {
16505 DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
16506 Ptr<SchemaTransaction> trans_ptr;
16507
16508 jamEntry();
16509 ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
16510 if(ref->errorCode != DropObjRef::NF_FakeErrorREF){
16511 jam();
16512 trans_ptr.p->setErrorCode(ref->errorCode);
16513 }
16514 Uint32 node = refToNode(ref->senderRef);
16515 schemaOp_reply(signal, trans_ptr.p, node);
16516 }
16517
16518 void
execDROP_OBJ_CONF(Signal * signal)16519 Dbdict::execDROP_OBJ_CONF(Signal* signal)
16520 {
16521 DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
16522 Ptr<SchemaTransaction> trans_ptr;
16523
16524 jamEntry();
16525 ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
16526 schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
16527 }
16528
16529 void
execDROP_FILE_REF(Signal * signal)16530 Dbdict::execDROP_FILE_REF(Signal* signal)
16531 {
16532 DropFileImplRef * ref = (DropFileImplRef*)signal->getDataPtr();
16533 DropObjRecordPtr op_ptr;
16534
16535 jamEntry();
16536 ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
16537 op_ptr.p->m_errorCode = ref->errorCode;
16538 execute(signal, op_ptr.p->m_callback, 0);
16539 }
16540
16541 void
execDROP_FILE_CONF(Signal * signal)16542 Dbdict::execDROP_FILE_CONF(Signal* signal)
16543 {
16544 DropFileImplConf * rep =
16545 (DropFileImplConf*)signal->getDataPtr();
16546 DropObjRecordPtr op_ptr;
16547
16548 jamEntry();
16549 ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
16550 execute(signal, op_ptr.p->m_callback, 0);
16551 }
16552
16553 void
execDROP_FILEGROUP_REF(Signal * signal)16554 Dbdict::execDROP_FILEGROUP_REF(Signal* signal)
16555 {
16556 DropFilegroupImplRef * ref = (DropFilegroupImplRef*)signal->getDataPtr();
16557 DropObjRecordPtr op_ptr;
16558
16559 jamEntry();
16560 ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
16561 op_ptr.p->m_errorCode = ref->errorCode;
16562 execute(signal, op_ptr.p->m_callback, 0);
16563 }
16564
16565 void
execDROP_FILEGROUP_CONF(Signal * signal)16566 Dbdict::execDROP_FILEGROUP_CONF(Signal* signal)
16567 {
16568 DropFilegroupImplConf * rep =
16569 (DropFilegroupImplConf*)signal->getDataPtr();
16570 DropObjRecordPtr op_ptr;
16571
16572 jamEntry();
16573 ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
16574 execute(signal, op_ptr.p->m_callback, 0);
16575 }
16576
16577 void
drop_fg_prepare_start(Signal * signal,SchemaOp * op)16578 Dbdict::drop_fg_prepare_start(Signal* signal, SchemaOp* op)
16579 {
16580 FilegroupPtr fg_ptr;
16581 c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
16582
16583 DictObject * obj = c_obj_pool.getPtr(fg_ptr.p->m_obj_ptr_i);
16584 if (obj->m_ref_count)
16585 {
16586 jam();
16587 op->m_errorCode = DropFilegroupRef::FilegroupInUse;
16588 execute(signal, op->m_callback, 0);
16589 }
16590 else
16591 {
16592 jam();
16593 send_drop_fg(signal, op, DropFilegroupImplReq::Prepare);
16594 }
16595 }
16596
16597 void
drop_fg_commit_start(Signal * signal,SchemaOp * op)16598 Dbdict::drop_fg_commit_start(Signal* signal, SchemaOp* op)
16599 {
16600 FilegroupPtr fg_ptr;
16601 c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
16602 if (op->m_obj_type == DictTabInfo::LogfileGroup)
16603 {
16604 jam();
16605 /**
16606 * Mark all undofiles as dropped
16607 */
16608 Ptr<File> filePtr;
16609 Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
16610 XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
16611 for(list.first(filePtr); !filePtr.isNull(); list.next(filePtr))
16612 {
16613 jam();
16614 Uint32 objId = filePtr.p->key;
16615 SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, objId);
16616 tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
16617 computeChecksum(xsf, objId / NDB_SF_PAGE_ENTRIES);
16618 release_object(filePtr.p->m_obj_ptr_i);
16619 c_file_hash.remove(filePtr);
16620 }
16621 list.release();
16622 }
16623 else if(op->m_obj_type == DictTabInfo::Tablespace)
16624 {
16625 FilegroupPtr lg_ptr;
16626 jam();
16627 ndbrequire(c_filegroup_hash.
16628 find(lg_ptr,
16629 fg_ptr.p->m_tablespace.m_default_logfile_group_id));
16630
16631 decrease_ref_count(lg_ptr.p->m_obj_ptr_i);
16632 }
16633 jam();
16634 send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
16635 }
16636
16637 void
drop_fg_commit_complete(Signal * signal,SchemaOp * op)16638 Dbdict::drop_fg_commit_complete(Signal* signal, SchemaOp* op)
16639 {
16640 FilegroupPtr fg_ptr;
16641 c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
16642
16643 jam();
16644 release_object(fg_ptr.p->m_obj_ptr_i);
16645 c_filegroup_hash.release(fg_ptr);
16646 execute(signal, op->m_callback, 0);
16647 }
16648
16649 void
drop_fg_abort_start(Signal * signal,SchemaOp * op)16650 Dbdict::drop_fg_abort_start(Signal* signal, SchemaOp* op)
16651 {
16652 jam();
16653 send_drop_fg(signal, op, DropFilegroupImplReq::Abort);
16654 }
16655
16656 void
send_drop_fg(Signal * signal,SchemaOp * op,DropFilegroupImplReq::RequestInfo type)16657 Dbdict::send_drop_fg(Signal* signal, SchemaOp* op,
16658 DropFilegroupImplReq::RequestInfo type)
16659 {
16660 DropFilegroupImplReq* req = (DropFilegroupImplReq*)signal->getDataPtrSend();
16661
16662 FilegroupPtr fg_ptr;
16663 c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
16664
16665 req->senderData = op->key;
16666 req->senderRef = reference();
16667 req->requestInfo = type;
16668
16669 req->filegroup_id = fg_ptr.p->key;
16670 req->filegroup_version = fg_ptr.p->m_version;
16671
16672 Uint32 ref= 0;
16673 switch(op->m_obj_type){
16674 case DictTabInfo::Tablespace:
16675 ref = TSMAN_REF;
16676 break;
16677 case DictTabInfo::LogfileGroup:
16678 ref = LGMAN_REF;
16679 break;
16680 default:
16681 ndbrequire(false);
16682 }
16683
16684 sendSignal(ref, GSN_DROP_FILEGROUP_REQ, signal,
16685 DropFilegroupImplReq::SignalLength, JBB);
16686 }
16687
16688 /*
16689 return 1 if all of the below is true
16690 a) node in single user mode
16691 b) senderRef is not a db node
16692 c) senderRef nodeid is not the singleUserApi
16693 */
checkSingleUserMode(Uint32 senderRef)16694 int Dbdict::checkSingleUserMode(Uint32 senderRef)
16695 {
16696 Uint32 nodeId = refToNode(senderRef);
16697 return
16698 getNodeState().getSingleUserMode() &&
16699 (getNodeInfo(nodeId).m_type != NodeInfo::DB) &&
16700 (nodeId != getNodeState().getSingleUserApi());
16701 }
16702
16703