2
Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
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.
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.
13
You should have received a copy of the GNU General Public License
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <SimpleProperties.hpp>
21
#include <Bitmask.hpp>
22
#include <AttributeList.hpp>
23
#include <AttributeHeader.hpp>
27
#include <util/version.h>
29
#include <signaldata/IndexStatSignal.hpp>
31
#include <signaldata/GetTabInfo.hpp>
32
#include <signaldata/DictTabInfo.hpp>
33
#include <signaldata/CreateTable.hpp>
34
#include <signaldata/CreateIndx.hpp>
35
#include <signaldata/CreateEvnt.hpp>
36
#include <signaldata/SumaImpl.hpp>
37
#include <signaldata/DropTable.hpp>
38
#include <signaldata/AlterTable.hpp>
39
#include <signaldata/DropIndx.hpp>
40
#include <signaldata/ListTables.hpp>
41
#include <signaldata/DropFilegroup.hpp>
42
#include <signaldata/CreateFilegroup.hpp>
43
#include <signaldata/WaitGCP.hpp>
44
#include <signaldata/SchemaTrans.hpp>
45
#include <signaldata/CreateHashMap.hpp>
46
#include <signaldata/ApiRegSignalData.hpp>
47
#include <signaldata/NodeFailRep.hpp>
50
#define INCOMPATIBLE_VERSION -2
52
#define DICT_WAITFOR_TIMEOUT (7*24*60*60*1000)
54
#define ERR_RETURN(a,b) \
56
DBUG_PRINT("exit", ("error %d return %d", (a).code, b));\
60
int ndb_dictionary_is_mysqld = 0;
63
is_ndb_blob_table(const char* name, Uint32* ptab_id, Uint32* pcol_no)
65
return DictTabInfo::isBlobTableName(name, ptab_id, pcol_no);
69
is_ndb_blob_table(const NdbTableImpl* t)
71
return is_ndb_blob_table(t->m_internalName.c_str());
75
ignore_broken_blob_tables()
77
/* To be able to fix broken blob tables, we must be able
78
* to ignore them when getting the table description
81
const char* v = NdbEnv_GetEnv("NDB_FORCE_IGNORE_BROKEN_BLOB",
84
return (v != NULL && *v != 0 && *v != '0' && *v != 'n' && *v != 'N');
92
NdbColumnImpl::NdbColumnImpl()
93
: NdbDictionary::Column(* this), m_attrId(-1), m_facade(this)
95
DBUG_ENTER("NdbColumnImpl::NdbColumnImpl");
96
DBUG_PRINT("info", ("this: %p", this));
101
NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f)
102
: NdbDictionary::Column(* this), m_attrId(-1), m_facade(&f)
104
DBUG_ENTER("NdbColumnImpl::NdbColumnImpl");
105
DBUG_PRINT("info", ("this: %p", this));
111
NdbColumnImpl::operator=(const NdbColumnImpl& col)
113
DBUG_ENTER("NdbColumnImpl::operator=");
114
DBUG_PRINT("info", ("this: %p &col: %p", this, &col));
115
m_attrId = col.m_attrId;
118
m_precision = col.m_precision;
120
m_scale = col.m_scale;
121
m_length = col.m_length;
123
m_distributionKey = col.m_distributionKey;
124
m_nullable = col.m_nullable;
125
m_autoIncrement = col.m_autoIncrement;
126
m_autoIncrementInitialValue = col.m_autoIncrementInitialValue;
127
m_defaultValue.assign(col.m_defaultValue);
128
m_attrSize = col.m_attrSize;
129
m_arraySize = col.m_arraySize;
130
m_arrayType = col.m_arrayType;
131
m_storageType = col.m_storageType;
132
m_blobVersion = col.m_blobVersion;
133
m_dynamic = col.m_dynamic;
134
m_indexSourced = col.m_indexSourced;
135
m_keyInfoPos = col.m_keyInfoPos;
136
if (col.m_blobTable == NULL)
139
if (m_blobTable == NULL)
140
m_blobTable = new NdbTableImpl();
141
m_blobTable->assign(*col.m_blobTable);
143
m_column_no = col.m_column_no;
144
// Do not copy m_facade !!
150
NdbColumnImpl::init(Type t)
152
// do not use default_charset_info as it may not be initialized yet
153
// use binary collation until NDB tests can handle charsets
154
CHARSET_INFO* default_cs = &my_charset_bin;
174
m_arrayType = NDB_ARRAYTYPE_FIXED;
177
case Olddecimalunsigned:
179
case Decimalunsigned:
184
m_arrayType = NDB_ARRAYTYPE_FIXED;
191
m_arrayType = NDB_ARRAYTYPE_FIXED;
198
m_arrayType = NDB_ARRAYTYPE_SHORT_VAR;
205
m_arrayType = NDB_ARRAYTYPE_FIXED;
212
m_arrayType = NDB_ARRAYTYPE_SHORT_VAR;
220
m_arrayType = NDB_ARRAYTYPE_FIXED;
226
m_length = 0; // default no striping
227
m_cs = m_type == Blob ? NULL : default_cs;
228
m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
229
m_blobVersion = NDB_BLOB_V2;
231
if (NdbEnv_GetEnv("NDB_DEFAULT_BLOB_V1", (char *)0, 0)) {
233
m_arrayType = NDB_ARRAYTYPE_FIXED;
234
m_blobVersion = NDB_BLOB_V1;
245
m_arrayType = NDB_ARRAYTYPE_FIXED;
252
m_arrayType = NDB_ARRAYTYPE_FIXED;
257
m_length = 1; // legal
259
m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
264
m_length = 1; // legal
266
m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
275
m_distributionKey = false;
277
// next 2 are set at run time
280
m_autoIncrement = false;
281
m_autoIncrementInitialValue = 1;
283
m_storageType = NDB_STORAGETYPE_MEMORY;
285
m_indexSourced= false;
287
if(NdbEnv_GetEnv("NDB_DEFAULT_DISK", (char *)0, 0))
288
m_storageType = NDB_STORAGETYPE_DISK;
292
NdbColumnImpl::~NdbColumnImpl()
294
DBUG_ENTER("NdbColumnImpl::~NdbColumnImpl");
295
DBUG_PRINT("info", ("this: %p", this));
296
if (m_blobTable != NULL)
303
NdbColumnImpl::equal(const NdbColumnImpl& col) const
305
DBUG_ENTER("NdbColumnImpl::equal");
306
DBUG_PRINT("info", ("this: %p &col: %p", this, &col));
307
/* New member comparisons added here should also be
308
* handled in the BackupRestore::column_compatible_check()
309
* member of tools/restore/consumer_restore.cpp
311
if(strcmp(m_name.c_str(), col.m_name.c_str()) != 0){
314
if(m_type != col.m_type){
317
if(m_pk != col.m_pk){
320
if(m_nullable != col.m_nullable){
324
if (m_distributionKey != col.m_distributionKey) {
328
if (m_precision != col.m_precision ||
329
m_scale != col.m_scale ||
330
m_length != col.m_length ||
334
if (m_autoIncrement != col.m_autoIncrement){
337
if (m_defaultValue.length() != col.m_defaultValue.length())
340
if(memcmp(m_defaultValue.get_data(), col.m_defaultValue.get_data(), m_defaultValue.length()) != 0){
344
if (m_arrayType != col.m_arrayType || m_storageType != col.m_storageType){
347
if (m_blobVersion != col.m_blobVersion) {
350
if(m_dynamic != col.m_dynamic){
358
NdbColumnImpl::create_pseudo_columns()
360
NdbDictionary::Column::FRAGMENT=
361
NdbColumnImpl::create_pseudo("NDB$FRAGMENT");
362
NdbDictionary::Column::FRAGMENT_FIXED_MEMORY=
363
NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FIXED_MEMORY");
364
NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY=
365
NdbColumnImpl::create_pseudo("NDB$FRAGMENT_VARSIZED_MEMORY");
366
NdbDictionary::Column::ROW_COUNT=
367
NdbColumnImpl::create_pseudo("NDB$ROW_COUNT");
368
NdbDictionary::Column::COMMIT_COUNT=
369
NdbColumnImpl::create_pseudo("NDB$COMMIT_COUNT");
370
NdbDictionary::Column::ROW_SIZE=
371
NdbColumnImpl::create_pseudo("NDB$ROW_SIZE");
372
NdbDictionary::Column::RANGE_NO=
373
NdbColumnImpl::create_pseudo("NDB$RANGE_NO");
374
NdbDictionary::Column::DISK_REF=
375
NdbColumnImpl::create_pseudo("NDB$DISK_REF");
376
NdbDictionary::Column::RECORDS_IN_RANGE=
377
NdbColumnImpl::create_pseudo("NDB$RECORDS_IN_RANGE");
378
NdbDictionary::Column::ROWID=
379
NdbColumnImpl::create_pseudo("NDB$ROWID");
380
NdbDictionary::Column::ROW_GCI=
381
NdbColumnImpl::create_pseudo("NDB$ROW_GCI");
382
NdbDictionary::Column::ROW_GCI64 =
383
NdbColumnImpl::create_pseudo("NDB$ROW_GCI64");
384
NdbDictionary::Column::ROW_AUTHOR =
385
NdbColumnImpl::create_pseudo("NDB$ROW_AUTHOR");
386
NdbDictionary::Column::ANY_VALUE=
387
NdbColumnImpl::create_pseudo("NDB$ANY_VALUE");
388
NdbDictionary::Column::COPY_ROWID=
389
NdbColumnImpl::create_pseudo("NDB$COPY_ROWID");
390
NdbDictionary::Column::OPTIMIZE=
391
NdbColumnImpl::create_pseudo("NDB$OPTIMIZE");
392
NdbDictionary::Column::FRAGMENT_EXTENT_SPACE =
393
NdbColumnImpl::create_pseudo("NDB$FRAGMENT_EXTENT_SPACE");
394
NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE =
395
NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FREE_EXTENT_SPACE");
396
NdbDictionary::Column::LOCK_REF =
397
NdbColumnImpl::create_pseudo("NDB$LOCK_REF");
398
NdbDictionary::Column::OP_ID =
399
NdbColumnImpl::create_pseudo("NDB$OP_ID");
403
NdbColumnImpl::destory_pseudo_columns()
405
delete NdbDictionary::Column::FRAGMENT;
406
delete NdbDictionary::Column::FRAGMENT_FIXED_MEMORY;
407
delete NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY;
408
delete NdbDictionary::Column::ROW_COUNT;
409
delete NdbDictionary::Column::COMMIT_COUNT;
410
delete NdbDictionary::Column::ROW_SIZE;
411
delete NdbDictionary::Column::RANGE_NO;
412
delete NdbDictionary::Column::DISK_REF;
413
delete NdbDictionary::Column::RECORDS_IN_RANGE;
414
delete NdbDictionary::Column::ROWID;
415
delete NdbDictionary::Column::ROW_GCI;
416
delete NdbDictionary::Column::ROW_GCI64;
417
delete NdbDictionary::Column::ROW_AUTHOR;
418
delete NdbDictionary::Column::ANY_VALUE;
419
delete NdbDictionary::Column::OPTIMIZE;
420
NdbDictionary::Column::FRAGMENT= 0;
421
NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 0;
422
NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 0;
423
NdbDictionary::Column::ROW_COUNT= 0;
424
NdbDictionary::Column::COMMIT_COUNT= 0;
425
NdbDictionary::Column::ROW_SIZE= 0;
426
NdbDictionary::Column::RANGE_NO= 0;
427
NdbDictionary::Column::DISK_REF= 0;
428
NdbDictionary::Column::RECORDS_IN_RANGE= 0;
429
NdbDictionary::Column::ROWID= 0;
430
NdbDictionary::Column::ROW_GCI= 0;
431
NdbDictionary::Column::ROW_GCI64= 0;
432
NdbDictionary::Column::ROW_AUTHOR= 0;
433
NdbDictionary::Column::ANY_VALUE= 0;
434
NdbDictionary::Column::OPTIMIZE= 0;
436
delete NdbDictionary::Column::COPY_ROWID;
437
NdbDictionary::Column::COPY_ROWID = 0;
439
delete NdbDictionary::Column::FRAGMENT_EXTENT_SPACE;
440
NdbDictionary::Column::FRAGMENT_EXTENT_SPACE = 0;
442
delete NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE;
443
NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE = 0;
445
delete NdbDictionary::Column::LOCK_REF;
446
delete NdbDictionary::Column::OP_ID;
447
NdbDictionary::Column::LOCK_REF = 0;
448
NdbDictionary::Column::OP_ID = 0;
451
NdbDictionary::Column *
452
NdbColumnImpl::create_pseudo(const char * name){
453
NdbDictionary::Column * col = new NdbDictionary::Column();
455
if(!strcmp(name, "NDB$FRAGMENT")){
456
col->setType(NdbDictionary::Column::Unsigned);
457
col->m_impl.m_attrId = AttributeHeader::FRAGMENT;
458
col->m_impl.m_attrSize = 4;
459
col->m_impl.m_arraySize = 1;
460
} else if(!strcmp(name, "NDB$FRAGMENT_FIXED_MEMORY")){
461
col->setType(NdbDictionary::Column::Bigunsigned);
462
col->m_impl.m_attrId = AttributeHeader::FRAGMENT_FIXED_MEMORY;
463
col->m_impl.m_attrSize = 8;
464
col->m_impl.m_arraySize = 1;
465
} else if(!strcmp(name, "NDB$FRAGMENT_VARSIZED_MEMORY")){
466
col->setType(NdbDictionary::Column::Bigunsigned);
467
col->m_impl.m_attrId = AttributeHeader::FRAGMENT_VARSIZED_MEMORY;
468
col->m_impl.m_attrSize = 8;
469
col->m_impl.m_arraySize = 1;
470
} else if(!strcmp(name, "NDB$ROW_COUNT")){
471
col->setType(NdbDictionary::Column::Bigunsigned);
472
col->m_impl.m_attrId = AttributeHeader::ROW_COUNT;
473
col->m_impl.m_attrSize = 8;
474
col->m_impl.m_arraySize = 1;
475
} else if(!strcmp(name, "NDB$COMMIT_COUNT")){
476
col->setType(NdbDictionary::Column::Bigunsigned);
477
col->m_impl.m_attrId = AttributeHeader::COMMIT_COUNT;
478
col->m_impl.m_attrSize = 8;
479
col->m_impl.m_arraySize = 1;
480
} else if(!strcmp(name, "NDB$ROW_SIZE")){
481
col->setType(NdbDictionary::Column::Unsigned);
482
col->m_impl.m_attrId = AttributeHeader::ROW_SIZE;
483
col->m_impl.m_attrSize = 4;
484
col->m_impl.m_arraySize = 1;
485
} else if(!strcmp(name, "NDB$RANGE_NO")){
486
col->setType(NdbDictionary::Column::Unsigned);
487
col->m_impl.m_attrId = AttributeHeader::RANGE_NO;
488
col->m_impl.m_attrSize = 4;
489
col->m_impl.m_arraySize = 1;
490
} else if(!strcmp(name, "NDB$DISK_REF")){
491
col->setType(NdbDictionary::Column::Bigunsigned);
492
col->m_impl.m_attrId = AttributeHeader::DISK_REF;
493
col->m_impl.m_attrSize = 8;
494
col->m_impl.m_arraySize = 1;
495
} else if(!strcmp(name, "NDB$RECORDS_IN_RANGE")){
496
col->setType(NdbDictionary::Column::Unsigned);
497
col->m_impl.m_attrId = AttributeHeader::RECORDS_IN_RANGE;
498
col->m_impl.m_attrSize = 4;
499
col->m_impl.m_arraySize = 4;
500
} else if(!strcmp(name, "NDB$ROWID")){
501
col->setType(NdbDictionary::Column::Bigunsigned);
502
col->m_impl.m_attrId = AttributeHeader::ROWID;
503
col->m_impl.m_attrSize = 4;
504
col->m_impl.m_arraySize = 2;
505
} else if(!strcmp(name, "NDB$ROW_GCI")){
506
col->setType(NdbDictionary::Column::Bigunsigned);
507
col->m_impl.m_attrId = AttributeHeader::ROW_GCI;
508
col->m_impl.m_attrSize = 8;
509
col->m_impl.m_arraySize = 1;
510
col->m_impl.m_nullable = true;
511
} else if(!strcmp(name, "NDB$ROW_GCI64")){
512
col->setType(NdbDictionary::Column::Bigunsigned);
513
col->m_impl.m_attrId = AttributeHeader::ROW_GCI64;
514
col->m_impl.m_attrSize = 8;
515
col->m_impl.m_arraySize = 1;
516
col->m_impl.m_nullable = true;
517
} else if(!strcmp(name, "NDB$ROW_AUTHOR")){
518
col->setType(NdbDictionary::Column::Unsigned);
519
col->m_impl.m_attrId = AttributeHeader::ROW_AUTHOR;
520
col->m_impl.m_attrSize = 4;
521
col->m_impl.m_arraySize = 1;
522
col->m_impl.m_nullable = true;
523
} else if(!strcmp(name, "NDB$ANY_VALUE")){
524
col->setType(NdbDictionary::Column::Unsigned);
525
col->m_impl.m_attrId = AttributeHeader::ANY_VALUE;
526
col->m_impl.m_attrSize = 4;
527
col->m_impl.m_arraySize = 1;
528
} else if(!strcmp(name, "NDB$COPY_ROWID")){
529
col->setType(NdbDictionary::Column::Bigunsigned);
530
col->m_impl.m_attrId = AttributeHeader::COPY_ROWID;
531
col->m_impl.m_attrSize = 4;
532
col->m_impl.m_arraySize = 2;
533
} else if(!strcmp(name, "NDB$OPTIMIZE")){
534
col->setType(NdbDictionary::Column::Unsigned);
535
col->m_impl.m_attrId = AttributeHeader::OPTIMIZE;
536
col->m_impl.m_attrSize = 4;
537
col->m_impl.m_arraySize = 1;
538
} else if(!strcmp(name, "NDB$FRAGMENT_EXTENT_SPACE")){
539
col->setType(NdbDictionary::Column::Bigunsigned);
540
col->m_impl.m_attrId = AttributeHeader::FRAGMENT_EXTENT_SPACE;
541
col->m_impl.m_attrSize = 4;
542
col->m_impl.m_arraySize = 2;
543
} else if(!strcmp(name, "NDB$FRAGMENT_FREE_EXTENT_SPACE")){
544
col->setType(NdbDictionary::Column::Bigunsigned);
545
col->m_impl.m_attrId = AttributeHeader::FRAGMENT_FREE_EXTENT_SPACE;
546
col->m_impl.m_attrSize = 4;
547
col->m_impl.m_arraySize = 2;
548
} else if (!strcmp(name, "NDB$LOCK_REF")){
549
col->setType(NdbDictionary::Column::Unsigned);
550
col->m_impl.m_attrId = AttributeHeader::LOCK_REF;
551
col->m_impl.m_attrSize = 4;
552
col->m_impl.m_arraySize = 3;
553
} else if (!strcmp(name, "NDB$OP_ID")){
554
col->setType(NdbDictionary::Column::Bigunsigned);
555
col->m_impl.m_attrId = AttributeHeader::OP_ID;
556
col->m_impl.m_attrSize = 8;
557
col->m_impl.m_arraySize = 1;
562
col->m_impl.m_storageType = NDB_STORAGETYPE_MEMORY;
570
NdbTableImpl::NdbTableImpl()
571
: NdbDictionary::Table(* this),
572
NdbDictObjectImpl(NdbDictionary::Object::UserTable), m_facade(this)
574
DBUG_ENTER("NdbTableImpl::NdbTableImpl");
575
DBUG_PRINT("info", ("this: %p", this));
580
NdbTableImpl::NdbTableImpl(NdbDictionary::Table & f)
581
: NdbDictionary::Table(* this),
582
NdbDictObjectImpl(NdbDictionary::Object::UserTable), m_facade(&f)
584
DBUG_ENTER("NdbTableImpl::NdbTableImpl");
585
DBUG_PRINT("info", ("this: %p", this));
590
NdbTableImpl::~NdbTableImpl()
592
DBUG_ENTER("NdbTableImpl::~NdbTableImpl");
593
DBUG_PRINT("info", ("this: %p", this));
598
for (unsigned i = 0; i < m_columns.size(); i++)
601
if (m_ndbrecord !=0) {
602
free(m_ndbrecord); // As it was calloc'd
607
free(const_cast<unsigned char *>(m_pkMask));
615
NdbTableImpl::init(){
618
m_status = NdbDictionary::Object::Invalid;
619
m_type = NdbDictionary::Object::TypeUndefined;
620
m_primaryTableId= RNIL;
621
m_internalName.clear();
622
m_externalName.clear();
627
m_fragmentType= NdbDictionary::Object::HashMapPartition;
629
m_hashpointerValue= 0;
631
m_primaryTable.clear();
632
m_default_no_part_flag = 1;
636
m_row_checksum = true;
637
m_force_var_part = false;
638
m_has_default_values = false;
645
m_indexType= NdbDictionary::Object::TypeUndefined;
647
m_noOfDistributionKeys= 0;
650
m_noOfAutoIncColumns = 0;
655
m_tablespace_name.clear();
656
m_tablespace_id = RNIL;
657
m_tablespace_version = ~0;
658
m_single_user_mode = 0;
659
m_hash_map_id = RNIL;
660
m_hash_map_version = ~0;
661
m_storageType = NDB_STORAGETYPE_DEFAULT;
662
m_extra_row_gci_bits = 0;
663
m_extra_row_author_bits = 0;
667
NdbTableImpl::equal(const NdbTableImpl& obj) const
669
DBUG_ENTER("NdbTableImpl::equal");
670
if ((m_internalName.c_str() == NULL) ||
671
(strcmp(m_internalName.c_str(), "") == 0) ||
672
(obj.m_internalName.c_str() == NULL) ||
673
(strcmp(obj.m_internalName.c_str(), "") == 0))
676
if(strcmp(getName(), obj.getName()) != 0)
678
DBUG_PRINT("info",("name %s != %s",getName(),obj.getName()));
685
if(strcmp(m_internalName.c_str(), obj.m_internalName.c_str()) != 0)
687
DBUG_PRINT("info",("m_internalName %s != %s",
688
m_internalName.c_str(),obj.m_internalName.c_str()));
692
if (m_frm.length() != obj.m_frm.length() ||
693
(memcmp(m_frm.get_data(), obj.m_frm.get_data(), m_frm.length())))
695
DBUG_PRINT("info",("m_frm not equal"));
698
if (!m_fd.equal(obj.m_fd))
700
DBUG_PRINT("info",("m_fd not equal"));
703
if (!m_range.equal(obj.m_range))
705
DBUG_PRINT("info",("m_range not equal"));
708
if(m_fragmentType != obj.m_fragmentType)
710
DBUG_PRINT("info",("m_fragmentType %d != %d",m_fragmentType,
711
obj.m_fragmentType));
714
if(m_columns.size() != obj.m_columns.size())
716
DBUG_PRINT("info",("m_columns.size %d != %d",m_columns.size(),
717
obj.m_columns.size()));
721
for(unsigned i = 0; i<obj.m_columns.size(); i++)
723
if(!m_columns[i]->equal(* obj.m_columns[i]))
725
DBUG_PRINT("info",("m_columns [%d] != [%d]",i,i));
730
if(m_linear_flag != obj.m_linear_flag)
732
DBUG_PRINT("info",("m_linear_flag %d != %d",m_linear_flag,
737
if(m_max_rows != obj.m_max_rows)
739
DBUG_PRINT("info",("m_max_rows %d != %d",(int32)m_max_rows,
740
(int32)obj.m_max_rows));
744
if(m_default_no_part_flag != obj.m_default_no_part_flag)
746
DBUG_PRINT("info",("m_default_no_part_flag %d != %d",m_default_no_part_flag,
747
obj.m_default_no_part_flag));
751
if(m_logging != obj.m_logging)
753
DBUG_PRINT("info",("m_logging %d != %d",m_logging,obj.m_logging));
757
if(m_temporary != obj.m_temporary)
759
DBUG_PRINT("info",("m_temporary %d != %d",m_temporary,obj.m_temporary));
763
if(m_row_gci != obj.m_row_gci)
765
DBUG_PRINT("info",("m_row_gci %d != %d",m_row_gci,obj.m_row_gci));
769
if(m_row_checksum != obj.m_row_checksum)
771
DBUG_PRINT("info",("m_row_checksum %d != %d",m_row_checksum,
772
obj.m_row_checksum));
776
if(m_kvalue != obj.m_kvalue)
778
DBUG_PRINT("info",("m_kvalue %d != %d",m_kvalue,obj.m_kvalue));
782
if(m_minLoadFactor != obj.m_minLoadFactor)
784
DBUG_PRINT("info",("m_minLoadFactor %d != %d",m_minLoadFactor,
785
obj.m_minLoadFactor));
789
if(m_maxLoadFactor != obj.m_maxLoadFactor)
791
DBUG_PRINT("info",("m_maxLoadFactor %d != %d",m_maxLoadFactor,
792
obj.m_maxLoadFactor));
796
if(m_tablespace_id != obj.m_tablespace_id)
798
DBUG_PRINT("info",("m_tablespace_id %d != %d",m_tablespace_id,
799
obj.m_tablespace_id));
803
if(m_tablespace_version != obj.m_tablespace_version)
805
DBUG_PRINT("info",("m_tablespace_version %d != %d",m_tablespace_version,
806
obj.m_tablespace_version));
812
DBUG_PRINT("info",("m_id %d != %d",m_id,obj.m_id));
816
if(m_version != obj.m_version)
818
DBUG_PRINT("info",("m_version %d != %d",m_version,obj.m_version));
822
if(m_type != obj.m_type)
824
DBUG_PRINT("info",("m_type %d != %d",m_type,obj.m_type));
828
if (m_type == NdbDictionary::Object::UniqueHashIndex ||
829
m_type == NdbDictionary::Object::OrderedIndex)
831
if(m_primaryTableId != obj.m_primaryTableId)
833
DBUG_PRINT("info",("m_primaryTableId %d != %d",m_primaryTableId,
834
obj.m_primaryTableId));
837
if (m_indexType != obj.m_indexType)
839
DBUG_PRINT("info",("m_indexType %d != %d",m_indexType,obj.m_indexType));
842
if(strcmp(m_primaryTable.c_str(), obj.m_primaryTable.c_str()) != 0)
844
DBUG_PRINT("info",("m_primaryTable %s != %s",
845
m_primaryTable.c_str(),obj.m_primaryTable.c_str()));
850
if(m_single_user_mode != obj.m_single_user_mode)
852
DBUG_PRINT("info",("m_single_user_mode %d != %d",
853
(int32)m_single_user_mode,
854
(int32)obj.m_single_user_mode));
858
if (m_extra_row_gci_bits != obj.m_extra_row_gci_bits)
860
DBUG_PRINT("info",("m_extra_row_gci_bits %d != %d",
861
(int32)m_extra_row_gci_bits,
862
(int32)obj.m_extra_row_gci_bits));
866
if (m_extra_row_author_bits != obj.m_extra_row_author_bits)
868
DBUG_PRINT("info",("m_extra_row_author_bits %d != %d",
869
(int32)m_extra_row_author_bits,
870
(int32)obj.m_extra_row_author_bits));
878
NdbTableImpl::assign(const NdbTableImpl& org)
880
DBUG_ENTER("NdbColumnImpl::assign");
881
DBUG_PRINT("info", ("this: %p &org: %p", this, &org));
882
m_primaryTableId = org.m_primaryTableId;
883
if (!m_internalName.assign(org.m_internalName) ||
888
m_externalName.assign(org.m_externalName);
889
m_frm.assign(org.m_frm.get_data(), org.m_frm.length());
890
m_fd.assign(org.m_fd);
891
m_range.assign(org.m_range);
893
m_fragmentType = org.m_fragmentType;
895
m_columnHashMask, m_columnHash, m_hashValueMask, m_hashpointerValue
896
is state calculated by computeAggregates and buildColumnHash
899
for(i = 0; i < m_columns.size(); i++)
904
for(i = 0; i < org.m_columns.size(); i++)
906
NdbColumnImpl * col = new NdbColumnImpl();
912
const NdbColumnImpl * iorg = org.m_columns[i];
914
if (m_columns.push_back(col))
921
m_fragments = org.m_fragments;
923
m_linear_flag = org.m_linear_flag;
924
m_max_rows = org.m_max_rows;
925
m_default_no_part_flag = org.m_default_no_part_flag;
926
m_logging = org.m_logging;
927
m_temporary = org.m_temporary;
928
m_row_gci = org.m_row_gci;
929
m_row_checksum = org.m_row_checksum;
930
m_force_var_part = org.m_force_var_part;
931
m_has_default_values = org.m_has_default_values;
932
m_kvalue = org.m_kvalue;
933
m_minLoadFactor = org.m_minLoadFactor;
934
m_maxLoadFactor = org.m_maxLoadFactor;
935
m_keyLenInWords = org.m_keyLenInWords;
936
m_fragmentCount = org.m_fragmentCount;
938
m_single_user_mode = org.m_single_user_mode;
939
m_extra_row_gci_bits = org.m_extra_row_gci_bits;
940
m_extra_row_author_bits = org.m_extra_row_author_bits;
944
m_index = org.m_index;
946
m_primaryTable = org.m_primaryTable;
947
m_indexType = org.m_indexType;
949
m_noOfKeys = org.m_noOfKeys;
950
m_noOfDistributionKeys = org.m_noOfDistributionKeys;
951
m_noOfBlobs = org.m_noOfBlobs;
952
m_replicaCount = org.m_replicaCount;
954
m_noOfAutoIncColumns = org.m_noOfAutoIncColumns;
957
m_version = org.m_version;
958
m_status = org.m_status;
960
m_max_rows = org.m_max_rows;
961
m_min_rows = org.m_min_rows;
963
m_tablespace_name = org.m_tablespace_name;
964
m_tablespace_id= org.m_tablespace_id;
965
m_tablespace_version = org.m_tablespace_version;
966
m_storageType = org.m_storageType;
971
int NdbTableImpl::setName(const char * name)
973
return !m_externalName.assign(name);
977
NdbTableImpl::getName() const
979
return m_externalName.c_str();
983
NdbTableImpl::getDbName(char buf[], size_t len) const
989
const char *ptr = m_internalName.c_str();
992
while (ptr[pos] && ptr[pos] != table_name_separator)
1005
NdbTableImpl::getSchemaName(char buf[], size_t len) const
1011
const char *ptr = m_internalName.c_str();
1014
while (*ptr && *ptr != table_name_separator)
1018
if (*ptr == table_name_separator)
1022
while (ptr[pos] && ptr[pos] != table_name_separator)
1024
buf[pos] = ptr[pos];
1037
NdbTableImpl::setDbSchema(const char * db, const char * schema)
1039
m_internalName.assfmt("%s%c%s%c%s",
1041
table_name_separator,
1043
table_name_separator,
1044
m_externalName.c_str());
1049
NdbTableImpl::computeAggregates()
1052
m_keyLenInWords = 0;
1053
m_noOfDistributionKeys = 0;
1055
m_noOfDiskColumns = 0;
1057
for (i = 0; i < m_columns.size(); i++) {
1058
NdbColumnImpl* col = m_columns[i];
1061
m_keyLenInWords += (col->m_attrSize * col->m_arraySize + 3) / 4;
1063
if (col->m_distributionKey)
1064
m_noOfDistributionKeys++; // XXX check PK
1066
if (col->getBlobType())
1069
if (col->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
1070
m_noOfDiskColumns++;
1072
col->m_keyInfoPos = ~0;
1074
if (col->m_autoIncrement)
1075
m_noOfAutoIncColumns++;
1077
if (m_noOfDistributionKeys == m_noOfKeys) {
1079
m_noOfDistributionKeys = 0;
1082
if (m_noOfDistributionKeys == 0)
1085
for (i = 0, n = m_noOfKeys; n != 0; i++) {
1086
NdbColumnImpl* col = m_columns[i];
1088
col->m_distributionKey = true;
1094
Uint32 keyInfoPos = 0;
1095
for (i = 0, n = m_noOfKeys; n != 0; i++) {
1096
NdbColumnImpl* col = m_columns[i];
1098
col->m_keyInfoPos = keyInfoPos++;
1104
// TODO add error checks
1105
// TODO use these internally at create and retrieve
1107
NdbTableImpl::aggregate(NdbError& error)
1109
computeAggregates();
1113
NdbTableImpl::validate(NdbError& error)
1115
if (aggregate(error) == -1)
1121
NdbTableImpl::setFragmentCount(Uint32 count)
1123
m_fragmentCount= count;
1126
Uint32 NdbTableImpl::getFragmentCount() const
1128
return m_fragmentCount;
1131
int NdbTableImpl::setFrm(const void* data, Uint32 len)
1133
return m_frm.assign(data, len);
1137
NdbTableImpl::getFrmData() const
1139
return m_frm.get_data();
1143
NdbTableImpl::getFrmLength() const
1145
return m_frm.length();
1149
NdbTableImpl::setFragmentData(const Uint32* data, Uint32 cnt)
1151
return m_fd.assign(data, cnt);
1155
NdbTableImpl::getFragmentData() const
1157
return m_fd.getBase();
1161
NdbTableImpl::getFragmentDataLen() const
1167
NdbTableImpl::setRangeListData(const Int32* data, Uint32 len)
1169
return m_range.assign(data, len);
1173
NdbTableImpl::getRangeListData() const
1175
return m_range.getBase();
1179
NdbTableImpl::getRangeListDataLen() const
1181
return m_range.size();
1185
NdbTableImpl::getFragmentNodes(Uint32 fragmentId,
1186
Uint32* nodeIdArrayPtr,
1187
Uint32 arraySize) const
1189
const Uint16 *shortNodeIds;
1190
Uint32 nodeCount = get_nodes(fragmentId, &shortNodeIds);
1196
nodeIdArrayPtr[i] = (Uint32) shortNodeIds[i];
1202
NdbTableImpl::updateMysqlName()
1204
Vector<BaseString> v;
1205
if (m_internalName.split(v,"/") == 3)
1207
return !m_mysqlName.assfmt("%s/%s",v[0].c_str(),v[2].c_str());
1209
return !m_mysqlName.assign("");
1213
NdbTableImpl::buildColumnHash(){
1214
const Uint32 size = m_columns.size();
1216
for(i = 31; i >= 0; i--){
1217
if(((1 << i) & size) != 0){
1218
m_columnHashMask = (1 << (i + 1)) - 1;
1223
Vector<Uint32> hashValues;
1224
Vector<Vector<Uint32> > chains;
1225
if (chains.fill(size, hashValues))
1229
for(i = 0; i< (int) size; i++){
1230
Uint32 hv = Hash(m_columns[i]->getName()) & 0xFFFE;
1231
Uint32 bucket = hv & m_columnHashMask;
1232
bucket = (bucket < size ? bucket : bucket - size);
1233
assert(bucket < size);
1234
if (hashValues.push_back(hv) ||
1235
chains[bucket].push_back(i))
1241
m_columnHash.clear();
1243
if (m_columnHash.fill((unsigned)size-1, tmp)) // Default no chaining
1248
Uint32 pos = 0; // In overflow vector
1249
for(i = 0; i< (int) size; i++){
1250
Uint32 sz = chains[i].size();
1252
Uint32 col = chains[i][0];
1253
Uint32 hv = hashValues[col];
1254
Uint32 bucket = hv & m_columnHashMask;
1255
bucket = (bucket < size ? bucket : bucket - size);
1256
m_columnHash[bucket] = (col << 16) | hv | 1;
1258
Uint32 col = chains[i][0];
1259
Uint32 hv = hashValues[col];
1260
Uint32 bucket = hv & m_columnHashMask;
1261
bucket = (bucket < size ? bucket : bucket - size);
1262
m_columnHash[bucket] = (sz << 16) | (((size - bucket) + pos) << 1);
1263
for(size_t j = 0; j<sz; j++, pos++){
1264
Uint32 col = chains[i][j];
1265
Uint32 hv = hashValues[col];
1266
if (m_columnHash.push_back((col << 16) | hv))
1274
if (m_columnHash.push_back(0)) // Overflow when looping in end of array
1280
for(size_t i = 0; i<m_columnHash.size(); i++){
1281
Uint32 tmp = m_columnHash[i];
1283
if(i < size && (tmp & 1) == 1){
1285
} else if(i >= size){
1288
ndbout_c("m_columnHash[%d] %s = %x",
1289
i, col > 0 ? m_columns[col]->getName() : "" , m_columnHash[i]);
1296
NdbTableImpl::get_nodes(Uint32 fragmentId, const Uint16 ** nodes) const
1298
Uint32 pos = fragmentId * m_replicaCount;
1299
if (pos + m_replicaCount <= m_fragments.size())
1301
*nodes = m_fragments.getBase()+pos;
1302
return m_replicaCount;
1308
NdbDictionary::Table::checkColumns(const Uint32* map, Uint32 len) const
1311
Uint32 colCnt = m_impl.m_columns.size();
1315
ret |= (m_impl.m_noOfDiskColumns) ? 2 : 0;
1316
ret |= (colCnt > m_impl.m_noOfDiskColumns) ? 4 : 0;
1320
NdbColumnImpl** cols = m_impl.m_columns.getBase();
1321
const char * ptr = reinterpret_cast<const char*>(map);
1322
const char * end = ptr + len;
1326
Uint32 val = (Uint32)* ptr;
1328
for (Uint32 i = 0; i<8; i++)
1332
if (cols[no]->getPrimaryKey())
1336
if (cols[no]->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
1359
NdbIndexImpl::NdbIndexImpl() :
1360
NdbDictionary::Index(* this),
1361
NdbDictObjectImpl(NdbDictionary::Object::OrderedIndex), m_facade(this)
1366
NdbIndexImpl::NdbIndexImpl(NdbDictionary::Index & f) :
1367
NdbDictionary::Index(* this),
1368
NdbDictObjectImpl(NdbDictionary::Object::OrderedIndex), m_facade(&f)
1373
void NdbIndexImpl::init()
1376
m_type= NdbDictionary::Object::TypeUndefined;
1382
NdbIndexImpl::~NdbIndexImpl(){
1383
for (unsigned i = 0; i < m_columns.size(); i++)
1384
delete m_columns[i];
1387
int NdbIndexImpl::setName(const char * name)
1389
return !m_externalName.assign(name);
1393
NdbIndexImpl::getName() const
1395
return m_externalName.c_str();
1399
NdbIndexImpl::setTable(const char * table)
1401
return !m_tableName.assign(table);
1405
NdbIndexImpl::getTable() const
1407
return m_tableName.c_str();
1410
const NdbTableImpl *
1411
NdbIndexImpl::getIndexTable() const
1417
* NdbOptimizeTableHandleImpl
1420
NdbOptimizeTableHandleImpl::NdbOptimizeTableHandleImpl(NdbDictionary::OptimizeTableHandle &f)
1421
: NdbDictionary::OptimizeTableHandle(* this),
1422
m_state(NdbOptimizeTableHandleImpl::CREATED),
1423
m_ndb(NULL), m_table(NULL),
1424
m_table_queue(NULL), m_table_queue_first(NULL), m_table_queue_end(NULL),
1425
m_trans(NULL), m_scan_op(NULL),
1430
NdbOptimizeTableHandleImpl::~NdbOptimizeTableHandleImpl()
1432
DBUG_ENTER("NdbOptimizeTableHandleImpl::~NdbOptimizeTableHandleImpl");
1437
int NdbOptimizeTableHandleImpl::start()
1439
int noRetries = 100;
1440
DBUG_ENTER("NdbOptimizeTableImpl::start");
1444
const NdbTableImpl * table = m_table_queue->table;
1447
* Start/Restart transaction
1449
while (noRetries-- > 0)
1451
if (m_trans && (m_trans->restart() != 0))
1453
m_ndb->closeTransaction(m_trans);
1457
m_trans = m_ndb->startTransaction();
1466
* Get first scan operation
1468
if ((m_scan_op = m_trans->getNdbScanOperation(table->m_facade))
1471
m_ndb->getNdbError(m_trans->getNdbError().code);
1476
* Define a result set for the scan.
1478
if (m_scan_op->readTuples(NdbOperation::LM_Exclusive)) {
1479
m_ndb->getNdbError(m_trans->getNdbError().code);
1484
* Start scan (NoCommit since we are only reading at this stage);
1486
if (m_trans->execute(NdbTransaction::NoCommit) != 0) {
1487
if (m_trans->getNdbError().status == NdbError::TemporaryError)
1488
continue; /* goto next_retry */
1489
m_ndb->getNdbError(m_trans->getNdbError().code);
1493
} // while (noRetries-- > 0)
1494
m_state = NdbOptimizeTableHandleImpl::INITIALIZED;
1495
} // if (m_table_queue)
1497
m_state = NdbOptimizeTableHandleImpl::FINISHED;
1501
DBUG_PRINT("info", ("NdbOptimizeTableImpl::start aborted"));
1502
m_state = NdbOptimizeTableHandleImpl::ABORTED;
1506
int NdbOptimizeTableHandleImpl::init(Ndb* ndb, const NdbTableImpl &table)
1508
DBUG_ENTER("NdbOptimizeTableHandleImpl::init");
1509
NdbDictionary::Dictionary* dict = ndb->getDictionary();
1510
Uint32 sz = table.m_columns.size();
1511
bool found_varpart = false;
1512
int blob_num = table.m_noOfBlobs;
1518
* search whether there are var size columns in the table,
1519
* in first step, we only optimize var part, then if the
1520
* table has no var size columns, we do not do optimizing
1522
for (Uint32 i = 0; i < sz; i++) {
1523
const NdbColumnImpl *col = m_table->m_columns[i];
1524
if (col != 0 && col->m_storageType == NDB_STORAGETYPE_MEMORY &&
1525
(col->m_dynamic || col->m_arrayType != NDB_ARRAYTYPE_FIXED)) {
1526
found_varpart= true;
1532
m_state = NdbOptimizeTableHandleImpl::FINISHED;
1537
* Add main table to the table queue
1540
m_table_queue_end = new fifo_element_st(m_table, m_table_queue_end);
1541
m_table_queue = m_table_queue_first = m_table_queue_end;
1543
* Add any BLOB tables the table queue
1546
for (int i = m_table->m_columns.size(); i > 0 && blob_num > 0;) {
1548
NdbColumnImpl & c = *m_table->m_columns[i];
1549
if (! c.getBlobType() || c.getPartSize() == 0)
1553
const NdbTableImpl * blob_table =
1554
(const NdbTableImpl *)dict->getBlobTable(m_table, c.m_attrId);
1557
m_table_queue_end = new fifo_element_st(blob_table, m_table_queue_end);
1561
* Initialize transaction
1563
DBUG_RETURN(start());
1566
int NdbOptimizeTableHandleImpl::next()
1568
int noRetries = 100;
1570
DBUG_ENTER("NdbOptimizeTableHandleImpl::next");
1572
if (m_state == NdbOptimizeTableHandleImpl::FINISHED)
1574
else if (m_state != NdbOptimizeTableHandleImpl::INITIALIZED)
1577
while (noRetries-- > 0)
1579
if ((done = check = m_scan_op->nextResult(true)) == 0)
1584
* Get update operation
1586
NdbOperation * myUpdateOp = m_scan_op->updateCurrentTuple();
1587
if (myUpdateOp == 0)
1589
m_ndb->getNdbError(m_trans->getNdbError().code);
1593
* optimize a tuple through doing the update
1594
* first step, move varpart
1596
Uint32 options = 0 | AttributeHeader::OPTIMIZE_MOVE_VARPART;
1597
myUpdateOp->setOptimize(options);
1599
* nextResult(false) means that the records
1600
* cached in the NDBAPI are modified before
1601
* fetching more rows from NDB.
1603
} while ((check = m_scan_op->nextResult(false)) == 0);
1607
* Commit when all cached tuple have been updated
1610
check = m_trans->execute(NdbTransaction::Commit);
1614
DBUG_PRINT("info", ("Done with table %s",
1615
m_table_queue->table->getName()));
1617
* We are done with optimizing current table
1620
fifo_element_st *current = m_table_queue;
1621
m_table_queue = current->next;
1623
* Start scan of next table
1626
m_ndb->getNdbError(m_trans->getNdbError().code);
1633
if (m_trans->getNdbError().status == NdbError::TemporaryError)
1636
* If we encountered temporary error, retry
1638
m_ndb->closeTransaction(m_trans);
1641
m_ndb->getNdbError(m_trans->getNdbError().code);
1646
m_ndb->getNdbError(m_trans->getNdbError().code);
1649
if (m_trans->restart() != 0)
1651
DBUG_PRINT("info", ("Failed to restart transaction"));
1652
m_ndb->closeTransaction(m_trans);
1655
m_ndb->getNdbError(m_trans->getNdbError().code);
1663
DBUG_PRINT("info", ("NdbOptimizeTableHandleImpl::next aborted"));
1664
m_state = NdbOptimizeTableHandleImpl::ABORTED;
1668
int NdbOptimizeTableHandleImpl::close()
1670
DBUG_ENTER("NdbOptimizeTableHandleImpl::close");
1672
* Drop queued tables
1674
while(m_table_queue_first != NULL)
1676
fifo_element_st *next = m_table_queue_first->next;
1677
delete m_table_queue_first;
1678
m_table_queue_first = next;
1680
m_table_queue = m_table_queue_first = m_table_queue_end = NULL;
1683
m_ndb->closeTransaction(m_trans);
1686
m_state = NdbOptimizeTableHandleImpl::CLOSED;
1691
* NdbOptimizeIndexHandleImpl
1694
NdbOptimizeIndexHandleImpl::NdbOptimizeIndexHandleImpl(NdbDictionary::OptimizeIndexHandle &f)
1695
: NdbDictionary::OptimizeIndexHandle(* this),
1696
m_state(NdbOptimizeIndexHandleImpl::CREATED),
1697
m_ndb(NULL), m_index(NULL),
1700
DBUG_ENTER("NdbOptimizeIndexHandleImpl::NdbOptimizeIndexHandleImpl");
1704
NdbOptimizeIndexHandleImpl::~NdbOptimizeIndexHandleImpl()
1706
DBUG_ENTER("NdbOptimizeIndexHandleImpl::~NdbOptimizeIndexHandleImpl");
1710
int NdbOptimizeIndexHandleImpl::init(Ndb *ndb, const NdbIndexImpl &index)
1712
DBUG_ENTER("NdbOptimizeIndexHandleImpl::init");
1714
m_state = NdbOptimizeIndexHandleImpl::INITIALIZED;
1716
* NOTE: we only optimize unique index
1718
if (m_index->m_facade->getType() != NdbDictionary::Index::UniqueHashIndex)
1720
DBUG_RETURN(m_optimize_table_handle.m_impl.init(ndb, *index.getIndexTable()));
1723
int NdbOptimizeIndexHandleImpl::next()
1725
DBUG_ENTER("NdbOptimizeIndexHandleImpl::next");
1726
if (m_state != NdbOptimizeIndexHandleImpl::INITIALIZED)
1728
if (m_index->m_facade->getType() != NdbDictionary::Index::UniqueHashIndex)
1730
DBUG_RETURN(m_optimize_table_handle.m_impl.next());
1733
int NdbOptimizeIndexHandleImpl::close()
1735
DBUG_ENTER("NdbOptimizeIndexHandleImpl::close");
1736
m_state = NdbOptimizeIndexHandleImpl::CLOSED;
1738
m_index->m_facade->getType() == NdbDictionary::Index::UniqueHashIndex)
1739
DBUG_RETURN(m_optimize_table_handle.m_impl.close());
1748
NdbEventImpl::NdbEventImpl() :
1749
NdbDictionary::Event(* this),
1750
NdbDictObjectImpl(NdbDictionary::Object::TypeUndefined), m_facade(this)
1752
DBUG_ENTER("NdbEventImpl::NdbEventImpl");
1753
DBUG_PRINT("info", ("this: %p", this));
1758
NdbEventImpl::NdbEventImpl(NdbDictionary::Event & f) :
1759
NdbDictionary::Event(* this),
1760
NdbDictObjectImpl(NdbDictionary::Object::TypeUndefined), m_facade(&f)
1762
DBUG_ENTER("NdbEventImpl::NdbEventImpl");
1763
DBUG_PRINT("info", ("this: %p", this));
1768
void NdbEventImpl::init()
1773
m_dur= NdbDictionary::Event::ED_UNDEFINED;
1774
m_mergeEvents = false;
1776
m_rep= NdbDictionary::Event::ER_UPDATED;
1779
NdbEventImpl::~NdbEventImpl()
1781
DBUG_ENTER("NdbEventImpl::~NdbEventImpl");
1782
DBUG_PRINT("info", ("this: %p", this));
1783
for (unsigned i = 0; i < m_columns.size(); i++)
1784
delete m_columns[i];
1790
int NdbEventImpl::setName(const char * name)
1792
return !m_name.assign(name);
1795
const char *NdbEventImpl::getName() const
1797
return m_name.c_str();
1801
NdbEventImpl::setTable(const NdbDictionary::Table& table)
1803
setTable(&NdbTableImpl::getImpl(table));
1804
return !m_tableName.assign(m_tableImpl->getName());
1808
NdbEventImpl::setTable(NdbTableImpl *tableImpl)
1810
DBUG_ENTER("NdbEventImpl::setTable");
1811
DBUG_PRINT("info", ("this: %p tableImpl: %p", this, tableImpl));
1814
m_tableImpl = new NdbTableImpl();
1815
// Copy table, since event might be accessed from different threads
1816
m_tableImpl->assign(*tableImpl);
1820
const NdbDictionary::Table *
1821
NdbEventImpl::getTable() const
1824
return m_tableImpl->m_facade;
1830
NdbEventImpl::setTable(const char * table)
1832
return !m_tableName.assign(table);
1836
NdbEventImpl::getTableName() const
1838
return m_tableName.c_str();
1842
NdbEventImpl::addTableEvent(const NdbDictionary::Event::TableEvent t = NdbDictionary::Event::TE_ALL)
1844
mi_type |= (unsigned)t;
1848
NdbEventImpl::getTableEvent(const NdbDictionary::Event::TableEvent t) const
1850
return (mi_type & (unsigned)t) == (unsigned)t;
1854
NdbEventImpl::setDurability(NdbDictionary::Event::EventDurability d)
1859
NdbDictionary::Event::EventDurability
1860
NdbEventImpl::getDurability() const
1866
NdbEventImpl::setReport(NdbDictionary::Event::EventReport r)
1871
NdbDictionary::Event::EventReport
1872
NdbEventImpl::getReport() const
1877
int NdbEventImpl::getNoOfEventColumns() const
1879
return m_attrIds.size() + m_columns.size();
1882
const NdbDictionary::Column *
1883
NdbEventImpl::getEventColumn(unsigned no) const
1885
if (m_columns.size())
1887
if (no < m_columns.size())
1889
return m_columns[no];
1892
else if (m_attrIds.size())
1894
if (no < m_attrIds.size())
1896
NdbTableImpl* tab= m_tableImpl;
1899
return tab->getColumn(m_attrIds[no]);
1909
/* Initialise static */
1911
NdbDictionaryImpl::m_emptyMask[MAXNROFATTRIBUTESINWORDS]= {0,0,0,0};
1913
NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb)
1914
: NdbDictionary::Dictionary(* this),
1916
m_receiver(m_tx, m_error, m_warn),
1920
m_local_table_data_size= 0;
1923
(int)WarnUndobufferRoundUp == (int)CreateFilegroupConf::WarnUndobufferRoundUp &&
1924
(int)WarnUndofileRoundDown == (int)CreateFileConf::WarnUndofileRoundDown &&
1925
(int)WarnExtentRoundUp == (int)CreateFilegroupConf::WarnExtentRoundUp &&
1926
(int)WarnDatafileRoundDown == (int)CreateFileConf::WarnDatafileRoundDown &&
1927
(int)WarnDatafileRoundUp == (int)CreateFileConf::WarnDatafileRoundUp
1932
NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb,
1933
NdbDictionary::Dictionary & f)
1934
: NdbDictionary::Dictionary(* this),
1936
m_receiver(m_tx, m_error, m_warn),
1940
m_local_table_data_size= 0;
1943
NdbDictionaryImpl::~NdbDictionaryImpl()
1945
/* Release local table references back to the global cache */
1946
NdbElement_t<Ndb_local_table_info> * curr = m_localHash.m_tableHash.getNext(0);
1949
m_globalHash->lock();
1950
m_globalHash->release(curr->theData->m_table_impl);
1951
Ndb_local_table_info::destroy(curr->theData);
1952
m_globalHash->unlock();
1954
curr = m_localHash.m_tableHash.getNext(curr);
1962
NdbDictionaryImpl::fetchGlobalTableImplRef(const GlobalCacheInitObject &obj)
1964
DBUG_ENTER("fetchGlobalTableImplRef");
1968
m_globalHash->lock();
1969
impl = m_globalHash->get(obj.m_name.c_str(), &error);
1970
m_globalHash->unlock();
1974
impl = m_receiver.getTable(obj.m_name,
1975
m_ndb.usingFullyQualifiedNames());
1977
m_error.code = 4000;
1978
if (impl != 0 && (obj.init(this, *impl)))
1983
m_globalHash->lock();
1984
m_globalHash->put(obj.m_name.c_str(), impl);
1985
m_globalHash->unlock();
1992
NdbDictionaryImpl::putTable(NdbTableImpl *impl)
1996
int ret = getBlobTables(*impl);
2000
m_globalHash->lock();
2001
if ((old= m_globalHash->get(impl->m_internalName.c_str(), &error)))
2003
m_globalHash->alter_table_rep(old->m_internalName.c_str(),
2008
m_globalHash->put(impl->m_internalName.c_str(), impl);
2009
m_globalHash->unlock();
2010
Ndb_local_table_info *info=
2011
Ndb_local_table_info::create(impl, m_local_table_data_size);
2013
m_localHash.put(impl->m_internalName.c_str(), info);
2017
NdbDictionaryImpl::getBlobTables(NdbTableImpl &t)
2019
unsigned n= t.m_noOfBlobs;
2020
DBUG_ENTER("NdbDictionaryImpl::getBlobTables");
2021
// optimized for blob column being the last one
2022
// and not looking for more than one if not neccessary
2023
for (unsigned i = t.m_columns.size(); i > 0 && n > 0;) {
2025
NdbColumnImpl & c = *t.m_columns[i];
2026
if (! c.getBlobType() || c.getPartSize() == 0)
2029
// retrieve blob table def from DICT - by-pass cache
2030
char btname[NdbBlobImpl::BlobTableNameSize];
2031
NdbBlob::getBlobTableName(btname, &t, &c);
2032
BaseString btname_internal = m_ndb.internalize_table_name(btname);
2034
m_receiver.getTable(btname_internal, m_ndb.usingFullyQualifiedNames());
2037
if (ignore_broken_blob_tables())
2039
DBUG_PRINT("info", ("Blob table %s not found, continuing", btname));
2045
// TODO check primary id/version when returned by DICT
2047
// the blob column owns the blob table
2048
assert(c.m_blobTable == NULL);
2051
// change storage type to that of PART column
2052
const char* colName = c.m_blobVersion == 1 ? "DATA" : "NDB$DATA";
2053
const NdbColumnImpl* bc = bt->getColumn(colName);
2055
assert(c.m_storageType == NDB_STORAGETYPE_MEMORY);
2056
c.m_storageType = bc->m_storageType;
2062
NdbDictionaryImpl::getBlobTable(const NdbTableImpl& tab, uint col_no)
2064
if (col_no < tab.m_columns.size()) {
2065
NdbColumnImpl* col = tab.m_columns[col_no];
2067
NdbTableImpl* bt = col->m_blobTable;
2071
m_error.code = 4273; // No blob table..
2073
m_error.code = 4249; // Invalid table..
2075
m_error.code = 4318; // Invalid attribute..
2080
NdbDictionaryImpl::getBlobTable(uint tab_id, uint col_no)
2082
DBUG_ENTER("NdbDictionaryImpl::getBlobTable");
2083
DBUG_PRINT("enter", ("tab_id: %u col_no %u", tab_id, col_no));
2085
NdbTableImpl* tab = m_receiver.getTable(tab_id,
2086
m_ndb.usingFullyQualifiedNames());
2089
Ndb_local_table_info* info =
2090
get_local_table_info(tab->m_internalName);
2094
NdbTableImpl* bt = getBlobTable(*info->m_table_impl, col_no);
2099
NdbDictionaryImpl::setTransporter(class Ndb* ndb,
2100
class TransporterFacade * tf)
2102
m_globalHash = tf->m_globalDictCache;
2103
if(m_receiver.setTransporter(ndb)){
2110
NdbDictionaryImpl::getIndexTable(NdbIndexImpl * index,
2111
NdbTableImpl * table)
2113
const char *current_db= m_ndb.getDatabaseName();
2114
NdbTableImpl *index_table;
2115
const BaseString internalName(
2116
m_ndb.internalize_index_name(table, index->getName()));
2117
// Get index table in system database
2118
m_ndb.setDatabaseName(NDB_SYSTEM_DATABASE);
2119
index_table= getTable(m_ndb.externalizeTableName(internalName.c_str()));
2120
m_ndb.setDatabaseName(current_db);
2123
// Index table not found
2124
// Try geting index table in current database (old format)
2125
index_table= getTable(m_ndb.externalizeTableName(internalName.c_str()));
2131
NdbDictInterface::setTransporter(class Ndb* ndb)
2133
m_reference = ndb->getReference();
2134
m_impl = ndb->theImpl;
2140
NdbDictInterface::getTransporter() const
2142
return m_impl->m_transporter_facade;
2145
NdbDictInterface::~NdbDictInterface()
2150
NdbDictInterface::execSignal(void* dictImpl,
2151
const class NdbApiSignal* signal,
2152
const struct LinearSectionPtr ptr[3])
2154
NdbDictInterface * tmp = (NdbDictInterface*)dictImpl;
2156
const Uint32 gsn = signal->readSignalNumber();
2158
case GSN_GET_TABINFOREF:
2159
tmp->execGET_TABINFO_REF(signal, ptr);
2161
case GSN_GET_TABINFO_CONF:
2162
tmp->execGET_TABINFO_CONF(signal, ptr);
2164
case GSN_CREATE_TABLE_REF:
2165
tmp->execCREATE_TABLE_REF(signal, ptr);
2167
case GSN_CREATE_TABLE_CONF:
2168
tmp->execCREATE_TABLE_CONF(signal, ptr);
2170
case GSN_DROP_TABLE_REF:
2171
tmp->execDROP_TABLE_REF(signal, ptr);
2173
case GSN_DROP_TABLE_CONF:
2174
tmp->execDROP_TABLE_CONF(signal, ptr);
2176
case GSN_ALTER_TABLE_REF:
2177
tmp->execALTER_TABLE_REF(signal, ptr);
2179
case GSN_ALTER_TABLE_CONF:
2180
tmp->execALTER_TABLE_CONF(signal, ptr);
2182
case GSN_CREATE_INDX_REF:
2183
tmp->execCREATE_INDX_REF(signal, ptr);
2185
case GSN_CREATE_INDX_CONF:
2186
tmp->execCREATE_INDX_CONF(signal, ptr);
2188
case GSN_DROP_INDX_REF:
2189
tmp->execDROP_INDX_REF(signal, ptr);
2191
case GSN_DROP_INDX_CONF:
2192
tmp->execDROP_INDX_CONF(signal, ptr);
2194
case GSN_INDEX_STAT_CONF:
2195
tmp->execINDEX_STAT_CONF(signal, ptr);
2197
case GSN_INDEX_STAT_REF:
2198
tmp->execINDEX_STAT_REF(signal, ptr);
2200
case GSN_CREATE_EVNT_REF:
2201
tmp->execCREATE_EVNT_REF(signal, ptr);
2203
case GSN_CREATE_EVNT_CONF:
2204
tmp->execCREATE_EVNT_CONF(signal, ptr);
2206
case GSN_SUB_START_CONF:
2207
tmp->execSUB_START_CONF(signal, ptr);
2209
case GSN_SUB_START_REF:
2210
tmp->execSUB_START_REF(signal, ptr);
2212
case GSN_SUB_STOP_CONF:
2213
tmp->execSUB_STOP_CONF(signal, ptr);
2215
case GSN_SUB_STOP_REF:
2216
tmp->execSUB_STOP_REF(signal, ptr);
2218
case GSN_DROP_EVNT_REF:
2219
tmp->execDROP_EVNT_REF(signal, ptr);
2221
case GSN_DROP_EVNT_CONF:
2222
tmp->execDROP_EVNT_CONF(signal, ptr);
2224
case GSN_LIST_TABLES_CONF:
2225
tmp->execLIST_TABLES_CONF(signal, ptr);
2227
case GSN_CREATE_FILEGROUP_REF:
2228
tmp->execCREATE_FILEGROUP_REF(signal, ptr);
2230
case GSN_CREATE_FILEGROUP_CONF:
2231
tmp->execCREATE_FILEGROUP_CONF(signal, ptr);
2233
case GSN_CREATE_FILE_REF:
2234
tmp->execCREATE_FILE_REF(signal, ptr);
2236
case GSN_CREATE_FILE_CONF:
2237
tmp->execCREATE_FILE_CONF(signal, ptr);
2239
case GSN_DROP_FILEGROUP_REF:
2240
tmp->execDROP_FILEGROUP_REF(signal, ptr);
2242
case GSN_DROP_FILEGROUP_CONF:
2243
tmp->execDROP_FILEGROUP_CONF(signal, ptr);
2245
case GSN_DROP_FILE_REF:
2246
tmp->execDROP_FILE_REF(signal, ptr);
2248
case GSN_DROP_FILE_CONF:
2249
tmp->execDROP_FILE_CONF(signal, ptr);
2251
case GSN_SCHEMA_TRANS_BEGIN_CONF:
2252
tmp->execSCHEMA_TRANS_BEGIN_CONF(signal, ptr);
2254
case GSN_SCHEMA_TRANS_BEGIN_REF:
2255
tmp->execSCHEMA_TRANS_BEGIN_REF(signal, ptr);
2257
case GSN_SCHEMA_TRANS_END_CONF:
2258
tmp->execSCHEMA_TRANS_END_CONF(signal, ptr);
2260
case GSN_SCHEMA_TRANS_END_REF:
2261
tmp->execSCHEMA_TRANS_END_REF(signal, ptr);
2263
case GSN_SCHEMA_TRANS_END_REP:
2264
tmp->execSCHEMA_TRANS_END_REP(signal, ptr);
2266
case GSN_WAIT_GCP_CONF:
2267
tmp->execWAIT_GCP_CONF(signal, ptr);
2269
case GSN_WAIT_GCP_REF:
2270
tmp->execWAIT_GCP_REF(signal, ptr);
2272
case GSN_CREATE_HASH_MAP_REF:
2273
tmp->execCREATE_HASH_MAP_REF(signal, ptr);
2275
case GSN_CREATE_HASH_MAP_CONF:
2276
tmp->execCREATE_HASH_MAP_CONF(signal, ptr);
2278
case GSN_NODE_FAILREP:
2280
const NodeFailRep *rep = CAST_CONSTPTR(NodeFailRep,
2281
signal->getDataPtr());
2282
for (Uint32 i = NdbNodeBitmask::find_first(rep->theNodes);
2283
i != NdbNodeBitmask::NotFound;
2284
i = NdbNodeBitmask::find_next(rep->theNodes, i + 1))
2286
tmp->m_impl->theWaiter.nodeFail(i);
2296
NdbDictInterface::execNodeStatus(void* dictImpl, Uint32 aNode, Uint32 ns_event)
2301
NdbDictInterface::dictSignal(NdbApiSignal* sig,
2302
LinearSectionPtr ptr[3], int secs,
2303
int node_specification,
2305
int timeout, Uint32 RETRIES,
2306
const int *errcodes, int temporaryMask)
2308
DBUG_ENTER("NdbDictInterface::dictSignal");
2309
DBUG_PRINT("enter", ("useMasterNodeId: %d", node_specification));
2314
for(Uint32 i = 0; i<RETRIES; i++)
2318
Uint32 t = sleep + 10 * (rand() % mod);
2320
ndbout_c("retry sleep %ums on error %u", t, m_error.code);
2322
NdbSleep_MilliSleep(t);
2324
if (i == RETRIES / 2)
2328
if (i == 3*RETRIES/4)
2337
The PollGuard has an implicit call of unlock_and_signal through the
2338
~PollGuard method. This method is called implicitly by the compiler
2339
in all places where the object is out of context due to a return,
2340
break, continue or simply end of statement block
2342
PollGuard poll_guard(* m_impl);
2344
switch(node_specification){
2346
node = (m_impl->get_node_alive(m_masterNodeId) ? m_masterNodeId :
2347
(m_masterNodeId = getTransporter()->get_an_alive_node()));
2350
node = getTransporter()->get_an_alive_node();
2353
node = node_specification;
2355
DBUG_PRINT("info", ("node %d", node));
2361
m_impl->sendFragmentedSignal(sig, node, ptr, secs):
2362
m_impl->sendSignal(sig, node));
2364
DBUG_PRINT("info", ("dictSignal failed to send signal"));
2365
m_error.code = 4007;
2369
m_impl->incClientStat(Ndb::WaitMetaRequestCount,1);
2371
int ret_val= poll_guard.wait_n_unlock(timeout, node, wst, true);
2372
// End of Protected area
2374
if(ret_val == 0 && m_error.code == 0){
2380
* Handle error codes
2382
if(ret_val == -2) //WAIT_NODE_FAILURE
2384
m_error.code = 4013;
2387
if(m_impl->theWaiter.get_state() == WST_WAIT_TIMEOUT)
2389
DBUG_PRINT("info", ("dictSignal caught time-out"));
2390
m_error.code = 4008;
2394
if ( temporaryMask == -1)
2396
const NdbError &error= getNdbError();
2397
if (error.status == NdbError::TemporaryError)
2402
else if ( (temporaryMask & m_error.code) != 0 )
2406
DBUG_PRINT("info", ("dictSignal caught error= %d", m_error.code));
2408
if(m_error.code && errcodes)
2411
for(j = 0; errcodes[j] ; j++){
2412
if(m_error.code == errcodes[j]){
2416
if(errcodes[j]) // Accepted error code
2427
Get dictionary information for a table using table id as reference
2430
Sends a GET_TABINFOREQ signal containing the table id
2433
NdbDictInterface::getTable(int tableId, bool fullyQualifiedNames)
2435
NdbApiSignal tSignal(m_reference);
2436
GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
2438
req->senderRef = m_reference;
2439
req->senderData = 0;
2441
GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
2442
req->tableId = tableId;
2443
req->schemaTransId = m_tx.transId();
2444
tSignal.theReceiversBlockNumber = DBDICT;
2445
tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
2446
tSignal.theLength = GetTabInfoReq::SignalLength;
2448
return getTable(&tSignal, 0, 0, fullyQualifiedNames);
2452
Get dictionary information for a table using table name as the reference
2455
Send GET_TABINFOREQ signal with the table name in the first
2460
NdbDictInterface::getTable(const BaseString& name, bool fullyQualifiedNames)
2462
NdbApiSignal tSignal(m_reference);
2463
GetTabInfoReq* const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
2465
const Uint32 namelen= name.length() + 1; // NULL terminated
2466
const Uint32 namelen_words= (namelen + 3) >> 2; // Size in words
2468
req->senderRef= m_reference;
2471
GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
2472
req->tableNameLen= namelen;
2473
req->schemaTransId = m_tx.transId();
2474
tSignal.theReceiversBlockNumber= DBDICT;
2475
tSignal.theVerId_signalNumber= GSN_GET_TABINFOREQ;
2476
tSignal.theLength= GetTabInfoReq::SignalLength;
2478
// Copy name to m_buffer to get a word sized buffer
2480
if (m_buffer.grow(namelen_words*4+4) ||
2481
m_buffer.append(name.c_str(), namelen))
2487
#ifndef IGNORE_VALGRIND_WARNINGS
2489
if (m_buffer.append(&pad, 4))
2496
LinearSectionPtr ptr[1];
2497
ptr[0].p= (Uint32*)m_buffer.get_data();
2498
ptr[0].sz= namelen_words;
2500
return getTable(&tSignal, ptr, 1, fullyQualifiedNames);
2505
NdbDictInterface::getTable(class NdbApiSignal * signal,
2506
LinearSectionPtr ptr[3],
2507
Uint32 noOfSections, bool fullyQualifiedNames)
2509
int errCodes[] = {GetTabInfoRef::Busy, 0 };
2510
int r = dictSignal(signal, ptr, noOfSections,
2512
WAIT_GET_TAB_INFO_REQ,
2513
DICT_WAITFOR_TIMEOUT, 100, errCodes);
2518
NdbTableImpl * rt = 0;
2519
m_error.code = parseTableInfo(&rt,
2520
(Uint32*)m_buffer.get_data(),
2521
m_buffer.length() / 4,
2522
fullyQualifiedNames);
2525
if (rt->buildColumnHash())
2527
m_error.code = 4000;
2532
if (rt->m_fragmentType == NdbDictionary::Object::HashMapPartition)
2535
if (get_hashmap(tmp, rt->m_hash_map_id))
2540
for (Uint32 i = 0; i<tmp.m_map.size(); i++)
2542
assert(tmp.m_map[i] <= 255);
2543
rt->m_hash_map.push_back(tmp.m_map[i]);
2552
NdbDictInterface::execGET_TABINFO_CONF(const NdbApiSignal * signal,
2553
const LinearSectionPtr ptr[3])
2555
const GetTabInfoConf* conf = CAST_CONSTPTR(GetTabInfoConf, signal->getDataPtr());
2556
const Uint32 i = GetTabInfoConf::DICT_TAB_INFO;
2557
if(signal->isFirstFragment()){
2558
m_fragmentId = signal->getFragmentId();
2559
if (m_buffer.grow(4 * conf->totalLen))
2565
if(m_fragmentId != signal->getFragmentId()){
2570
if (m_buffer.append(ptr[i].p, 4 * ptr[i].sz))
2575
if(!signal->isLastFragment()){
2579
m_impl->theWaiter.signal(NO_WAIT);
2583
NdbDictInterface::execGET_TABINFO_REF(const NdbApiSignal * signal,
2584
const LinearSectionPtr ptr[3])
2586
const GetTabInfoRef* ref = CAST_CONSTPTR(GetTabInfoRef,
2587
signal->getDataPtr());
2589
if (likely(signal->getLength() == GetTabInfoRef::SignalLength))
2591
m_error.code= ref->errorCode;
2595
/* 6.3 <-> 7.0 upgrade only */
2596
assert (signal->getLength() == GetTabInfoRef::OriginalSignalLength);
2597
m_error.code = (*(signal->getDataPtr() +
2598
GetTabInfoRef::OriginalErrorOffset));
2600
m_impl->theWaiter.signal(NO_WAIT);
2603
/*****************************************************************
2604
* Pack/Unpack tables
2606
struct ApiKernelMapping {
2607
Int32 kernelConstant;
2612
getApiConstant(Int32 kernelConstant, const ApiKernelMapping map[], Uint32 def)
2615
while(map[i].kernelConstant != kernelConstant){
2616
if(map[i].kernelConstant == -1 &&
2617
map[i].apiConstant == -1){
2622
return map[i].apiConstant;
2626
getKernelConstant(Int32 apiConstant, const ApiKernelMapping map[], Uint32 def)
2629
while(map[i].apiConstant != apiConstant){
2630
if(map[i].kernelConstant == -1 &&
2631
map[i].apiConstant == -1){
2636
return map[i].kernelConstant;
2641
fragmentTypeMapping[] = {
2642
{ DictTabInfo::AllNodesSmallTable, NdbDictionary::Object::FragAllSmall },
2643
{ DictTabInfo::AllNodesMediumTable, NdbDictionary::Object::FragAllMedium },
2644
{ DictTabInfo::AllNodesLargeTable, NdbDictionary::Object::FragAllLarge },
2645
{ DictTabInfo::SingleFragment, NdbDictionary::Object::FragSingle },
2646
{ DictTabInfo::DistrKeyHash, NdbDictionary::Object::DistrKeyHash },
2647
{ DictTabInfo::DistrKeyLin, NdbDictionary::Object::DistrKeyLin },
2648
{ DictTabInfo::UserDefined, NdbDictionary::Object::UserDefined },
2649
{ DictTabInfo::HashMapPartition, NdbDictionary::Object::HashMapPartition },
2655
objectTypeMapping[] = {
2656
{ DictTabInfo::SystemTable, NdbDictionary::Object::SystemTable },
2657
{ DictTabInfo::UserTable, NdbDictionary::Object::UserTable },
2658
{ DictTabInfo::UniqueHashIndex, NdbDictionary::Object::UniqueHashIndex },
2659
{ DictTabInfo::OrderedIndex, NdbDictionary::Object::OrderedIndex },
2660
{ DictTabInfo::HashIndexTrigger, NdbDictionary::Object::HashIndexTrigger },
2661
{ DictTabInfo::IndexTrigger, NdbDictionary::Object::IndexTrigger },
2662
{ DictTabInfo::SubscriptionTrigger,NdbDictionary::Object::SubscriptionTrigger },
2663
{ DictTabInfo::ReadOnlyConstraint ,NdbDictionary::Object::ReadOnlyConstraint },
2664
{ DictTabInfo::Tablespace, NdbDictionary::Object::Tablespace },
2665
{ DictTabInfo::LogfileGroup, NdbDictionary::Object::LogfileGroup },
2666
{ DictTabInfo::Datafile, NdbDictionary::Object::Datafile },
2667
{ DictTabInfo::Undofile, NdbDictionary::Object::Undofile },
2668
{ DictTabInfo::ReorgTrigger, NdbDictionary::Object::ReorgTrigger },
2674
objectStateMapping[] = {
2675
{ DictTabInfo::StateOffline, NdbDictionary::Object::StateOffline },
2676
{ DictTabInfo::StateBuilding, NdbDictionary::Object::StateBuilding },
2677
{ DictTabInfo::StateDropping, NdbDictionary::Object::StateDropping },
2678
{ DictTabInfo::StateOnline, NdbDictionary::Object::StateOnline },
2679
{ DictTabInfo::StateBackup, NdbDictionary::Object::StateBackup },
2680
{ DictTabInfo::StateBroken, NdbDictionary::Object::StateBroken },
2686
objectStoreMapping[] = {
2687
{ DictTabInfo::StoreNotLogged, NdbDictionary::Object::StoreNotLogged },
2688
{ DictTabInfo::StorePermanent, NdbDictionary::Object::StorePermanent },
2694
indexTypeMapping[] = {
2695
{ DictTabInfo::UniqueHashIndex, NdbDictionary::Index::UniqueHashIndex },
2696
{ DictTabInfo::OrderedIndex, NdbDictionary::Index::OrderedIndex },
2701
NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
2702
const Uint32 * data, Uint32 len,
2703
bool fullyQualifiedNames,
2706
SimplePropertiesLinearReader it(data, len);
2707
DictTabInfo::Table *tableDesc;
2708
SimpleProperties::UnpackStatus s;
2709
DBUG_ENTER("NdbDictInterface::parseTableInfo");
2711
tableDesc = (DictTabInfo::Table*)NdbMem_Allocate(sizeof(DictTabInfo::Table));
2717
s = SimpleProperties::unpack(it, tableDesc,
2718
DictTabInfo::TableMapping,
2719
DictTabInfo::TableMappingSize,
2722
if(s != SimpleProperties::Break){
2723
NdbMem_Free((void*)tableDesc);
2726
const char * internalName = tableDesc->TableName;
2727
const char * externalName = Ndb::externalizeTableName(internalName, fullyQualifiedNames);
2729
NdbTableImpl * impl = new NdbTableImpl();
2730
impl->m_id = tableDesc->TableId;
2731
impl->m_version = tableDesc->TableVersion;
2732
impl->m_status = NdbDictionary::Object::Retrieved;
2733
if (!impl->m_internalName.assign(internalName) ||
2734
impl->updateMysqlName() ||
2735
!impl->m_externalName.assign(externalName) ||
2736
impl->m_frm.assign(tableDesc->FrmData, tableDesc->FrmLen) ||
2737
impl->m_range.assign((Int32*)tableDesc->RangeListData,
2738
/* yuck */tableDesc->RangeListDataLen / 4))
2745
* NOTE: fragment data is currently an array of Uint16
2746
* and len is specified in bytes (yuck)
2747
* please change to Uint32 and len == count
2749
Uint32 cnt = tableDesc->FragmentDataLen / 2;
2750
for (Uint32 i = 0; i<cnt; i++)
2751
if (impl->m_fd.push_back((Uint32)tableDesc->FragmentData[i]))
2755
impl->m_fragmentCount = tableDesc->FragmentCount;
2758
We specifically don't get tablespace data and range/list arrays here
2759
since those are known by the MySQL Server through analysing the
2761
Fragment Data contains the real node group mapping and the fragment
2762
identities used for each fragment. At the moment we have no need for
2764
Frm file is needed for autodiscovery.
2767
impl->m_fragmentType = (NdbDictionary::Object::FragmentType)
2768
getApiConstant(tableDesc->FragmentType,
2769
fragmentTypeMapping,
2770
(Uint32)NdbDictionary::Object::FragUndefined);
2772
if (impl->m_fragmentType == NdbDictionary::Object::HashMapPartition)
2774
impl->m_hash_map_id = tableDesc->HashMapObjectId;
2775
impl->m_hash_map_version = tableDesc->HashMapVersion;
2779
impl->m_hash_map_id = ~0;
2780
impl->m_hash_map_version = ~0;
2783
Uint64 max_rows = ((Uint64)tableDesc->MaxRowsHigh) << 32;
2784
max_rows += tableDesc->MaxRowsLow;
2785
impl->m_max_rows = max_rows;
2786
Uint64 min_rows = ((Uint64)tableDesc->MinRowsHigh) << 32;
2787
min_rows += tableDesc->MinRowsLow;
2788
impl->m_min_rows = min_rows;
2789
impl->m_default_no_part_flag = tableDesc->DefaultNoPartFlag;
2790
impl->m_linear_flag = tableDesc->LinearHashFlag;
2791
impl->m_logging = tableDesc->TableLoggedFlag;
2792
impl->m_temporary = tableDesc->TableTemporaryFlag;
2793
impl->m_row_gci = tableDesc->RowGCIFlag;
2794
impl->m_row_checksum = tableDesc->RowChecksumFlag;
2795
impl->m_force_var_part = tableDesc->ForceVarPartFlag;
2796
impl->m_kvalue = tableDesc->TableKValue;
2797
impl->m_minLoadFactor = tableDesc->MinLoadFactor;
2798
impl->m_maxLoadFactor = tableDesc->MaxLoadFactor;
2799
impl->m_single_user_mode = tableDesc->SingleUserMode;
2800
impl->m_storageType = tableDesc->TableStorageType;
2801
impl->m_extra_row_gci_bits = tableDesc->ExtraRowGCIBits;
2802
impl->m_extra_row_author_bits = tableDesc->ExtraRowAuthorBits;
2804
impl->m_indexType = (NdbDictionary::Object::Type)
2805
getApiConstant(tableDesc->TableType,
2807
NdbDictionary::Object::TypeUndefined);
2809
bool columnsIndexSourced= false;
2811
if(impl->m_indexType == NdbDictionary::Object::TypeUndefined){
2813
const char * externalPrimary =
2814
Ndb::externalizeTableName(tableDesc->PrimaryTable, fullyQualifiedNames);
2815
if (!impl->m_primaryTable.assign(externalPrimary))
2819
columnsIndexSourced= true;
2823
for(i = 0; i < tableDesc->NoOfAttributes; i++) {
2824
DictTabInfo::Attribute attrDesc; attrDesc.init();
2825
s = SimpleProperties::unpack(it,
2827
DictTabInfo::AttributeMapping,
2828
DictTabInfo::AttributeMappingSize,
2830
if(s != SimpleProperties::Break){
2832
NdbMem_Free((void*)tableDesc);
2836
NdbColumnImpl * col = new NdbColumnImpl();
2837
col->m_attrId = attrDesc.AttributeId;
2838
col->setName(attrDesc.AttributeName);
2840
// check type and compute attribute size and array size
2841
if (! attrDesc.translateExtType()) {
2844
NdbMem_Free((void*)tableDesc);
2847
col->m_type = (NdbDictionary::Column::Type)attrDesc.AttributeExtType;
2848
col->m_precision = (attrDesc.AttributeExtPrecision & 0xFFFF);
2849
col->m_scale = attrDesc.AttributeExtScale;
2850
col->m_length = attrDesc.AttributeExtLength;
2851
// charset in upper half of precision
2852
unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16);
2853
// charset is defined exactly for char types
2854
if (col->getCharType() != (cs_number != 0)) {
2857
NdbMem_Free((void*)tableDesc);
2860
if (col->getCharType()) {
2861
col->m_cs = get_charset(cs_number, MYF(0));
2862
if (col->m_cs == NULL) {
2865
NdbMem_Free((void*)tableDesc);
2869
col->m_orgAttrSize = attrDesc.AttributeSize;
2870
col->m_attrSize = (1 << attrDesc.AttributeSize) / 8;
2871
col->m_arraySize = attrDesc.AttributeArraySize;
2872
col->m_arrayType = attrDesc.AttributeArrayType;
2873
if(attrDesc.AttributeSize == 0)
2875
col->m_attrSize = 4;
2876
col->m_arraySize = (attrDesc.AttributeArraySize + 31) >> 5;
2878
col->m_storageType = attrDesc.AttributeStorageType;
2879
col->m_dynamic = (attrDesc.AttributeDynamic != 0);
2880
col->m_indexSourced= columnsIndexSourced;
2882
if (col->getBlobType()) {
2883
if (unlikely(col->m_arrayType) == NDB_ARRAYTYPE_FIXED)
2884
col->m_blobVersion = NDB_BLOB_V1;
2885
else if (col->m_arrayType == NDB_ARRAYTYPE_MEDIUM_VAR)
2886
col->m_blobVersion = NDB_BLOB_V2;
2889
NdbMem_Free((void*)tableDesc);
2894
col->m_pk = attrDesc.AttributeKeyFlag;
2895
col->m_distributionKey = (attrDesc.AttributeDKey != 0);
2896
col->m_nullable = attrDesc.AttributeNullableFlag;
2897
col->m_autoIncrement = (attrDesc.AttributeAutoIncrement != 0);
2898
col->m_autoIncrementInitialValue = ~0;
2900
if (attrDesc.AttributeDefaultValueLen)
2902
assert(attrDesc.AttributeDefaultValueLen >= sizeof(Uint32)); /* AttributeHeader */
2903
const char* defPtr = (const char*) attrDesc.AttributeDefaultValue;
2904
Uint32 a = * (const Uint32*) defPtr;
2905
AttributeHeader ah(ntohl(a));
2906
Uint32 bytesize = ah.getByteSize();
2907
assert(attrDesc.AttributeDefaultValueLen >= sizeof(Uint32) + bytesize);
2911
if (col->m_defaultValue.assign(defPtr + sizeof(Uint32), bytesize))
2918
/* Table meta-info is normally stored in network byte order by
2920
* For the default value 'Blob' we do the work
2922
/* In-place convert network -> host */
2923
NdbSqlUtil::convertByteOrder(attrDesc.AttributeExtType,
2924
attrDesc.AttributeSize,
2925
attrDesc.AttributeArrayType,
2926
attrDesc.AttributeArraySize,
2927
(uchar*) col->m_defaultValue.get_data(),
2930
impl->m_has_default_values = true;
2934
col->m_column_no = impl->m_columns.size();
2935
impl->m_columns.push_back(col);
2939
impl->computeAggregates();
2941
if(tableDesc->ReplicaDataLen > 0)
2943
Uint16 replicaCount = ntohs(tableDesc->ReplicaData[0]);
2944
Uint16 fragCount = ntohs(tableDesc->ReplicaData[1]);
2946
assert(replicaCount <= 256);
2948
impl->m_replicaCount = (Uint8)replicaCount;
2949
impl->m_fragmentCount = fragCount;
2950
DBUG_PRINT("info", ("replicaCount=%x , fragCount=%x",replicaCount,fragCount));
2952
for(i = 0; i < (Uint32) fragCount;i++)
2954
pos++; // skip logpart
2955
for (Uint32 j = 0; j<(Uint32)replicaCount; j++)
2957
if (impl->m_fragments.push_back(ntohs(tableDesc->ReplicaData[pos++])))
2965
Uint32 topBit = (1 << 31);
2966
for(; topBit && !(fragCount & topBit); ){
2969
impl->m_hashValueMask = topBit - 1;
2970
impl->m_hashpointerValue = fragCount - (impl->m_hashValueMask + 1);
2974
impl->m_fragmentCount = tableDesc->FragmentCount;
2975
impl->m_replicaCount = 0;
2976
impl->m_hashValueMask = 0;
2977
impl->m_hashpointerValue = 0;
2980
impl->m_tablespace_id = tableDesc->TablespaceId;
2981
impl->m_tablespace_version = tableDesc->TablespaceVersion;
2985
NdbMem_Free((void*)tableDesc);
2986
if (version < MAKE_VERSION(5,1,3))
2992
DBUG_ASSERT(impl->m_fragmentCount > 0);
2997
/*****************************************************************
2998
* Create table and alter table
3001
NdbDictionaryImpl::createTable(NdbTableImpl &t, NdbDictObjectImpl & objid)
3003
DBUG_ENTER("NdbDictionaryImpl::createTable");
3005
bool autoIncrement = false;
3006
Uint64 initialValue = 0;
3007
for (Uint32 i = 0; i < t.m_columns.size(); i++) {
3008
const NdbColumnImpl* c = t.m_columns[i];
3010
if (c->m_autoIncrement) {
3011
if (autoIncrement) {
3012
m_error.code = 4335;
3015
autoIncrement = true;
3016
initialValue = c->m_autoIncrementInitialValue;
3019
if (c->m_pk && (! c->m_defaultValue.empty())) {
3020
/* Default value for primary key column not supported */
3027
if (m_receiver.createTable(m_ndb, t) != 0)
3029
Uint32* data = (Uint32*)m_receiver.m_buffer.get_data();
3031
t.m_version = data[1];
3032
objid.m_id = data[0];
3033
objid.m_version = data[1];
3035
// update table def from DICT - by-pass cache
3037
m_receiver.getTable(t.m_internalName, m_ndb.usingFullyQualifiedNames());
3039
// check if we got back same table
3041
DBUG_PRINT("info", ("table %s dropped by another thread",
3042
t.m_internalName.c_str()));
3046
if (t.m_id != t2->m_id || t.m_version != t2->m_version) {
3047
DBUG_PRINT("info", ("table %s re-created by another thread",
3048
t.m_internalName.c_str()));
3054
// auto-increment - use "t" because initial value is not in DICT
3056
if (autoIncrement) {
3057
// XXX unlikely race condition - t.m_id may no longer be same table
3058
// the tuple id range is not used on input
3059
Ndb::TupleIdRange range;
3060
if (m_ndb.setTupleIdInNdb(&t, range, initialValue, false) == -1) {
3061
assert(m_ndb.theError.code != 0);
3062
m_error.code = m_ndb.theError.code;
3069
// blob tables - use "t2" to get values set by kernel
3070
if (t.m_noOfBlobs != 0) {
3072
// fix up disk data in t2 columns
3074
for (i = 0; i < t.m_columns.size(); i++) {
3075
const NdbColumnImpl* c = t.m_columns[i];
3076
NdbColumnImpl* c2 = t2->m_columns[i];
3077
if (c->getBlobType()) {
3078
// type was mangled before sending to DICT
3079
assert(c2->m_storageType == NDB_STORAGETYPE_MEMORY);
3080
c2->m_storageType = c->m_storageType;
3084
if (createBlobTables(*t2) != 0) {
3085
int save_code = m_error.code;
3086
(void)dropTableGlobal(*t2);
3087
m_error.code = save_code;
3093
// not entered in cache
3099
NdbDictionaryImpl::optimizeTable(const NdbTableImpl &t,
3100
NdbOptimizeTableHandleImpl &h)
3102
DBUG_ENTER("NdbDictionaryImpl::optimizeTableGlobal(const NdbTableImpl)");
3103
DBUG_RETURN(h.init(&m_ndb, t));
3107
NdbDictionaryImpl::optimizeIndex(const NdbIndexImpl &index,
3108
NdbOptimizeIndexHandleImpl &h)
3110
DBUG_ENTER("NdbDictionaryImpl::optimizeIndexGlobal(const NdbIndexImpl)");
3111
DBUG_RETURN(h.init(&m_ndb, index));
3115
NdbDictionaryImpl::createBlobTables(const NdbTableImpl& t)
3117
DBUG_ENTER("NdbDictionaryImpl::createBlobTables");
3118
for (unsigned i = 0; i < t.m_columns.size(); i++) {
3119
const NdbColumnImpl & c = *t.m_columns[i];
3120
if (! c.getBlobType() || c.getPartSize() == 0)
3122
DBUG_PRINT("info", ("col: %s array type: %u storage type: %u",
3123
c.m_name.c_str(), c.m_arrayType, c.m_storageType));
3126
if (NdbBlob::getBlobTable(bt, &t, &c, error) == -1) {
3127
m_error.code = error.code;
3130
NdbDictionary::Column::StorageType
3131
d = NdbDictionary::Column::StorageTypeDisk;
3132
if (t.m_columns[i]->getStorageType() == d) {
3133
const char* colName = c.m_blobVersion == 1 ? "DATA" : "NDB$DATA";
3134
NdbColumnImpl* bc = bt.getColumn(colName);
3136
bc->setStorageType(d);
3138
NdbDictionary::ObjectId objId; // ignore objid
3139
if (createTable(bt, NdbDictObjectImpl::getImpl(objId)) != 0) {
3147
NdbDictInterface::createTable(Ndb & ndb,
3148
NdbTableImpl & impl)
3152
DBUG_ENTER("NdbDictInterface::createTable");
3154
if (impl.m_fragmentType == NdbDictionary::Object::HashMapPartition)
3156
if (impl.m_hash_map_id == RNIL && impl.m_hash_map_version == ~(Uint32)0)
3159
* Make sure that hashmap exists (i.e after upgrade or similar)
3161
NdbHashMapImpl hashmap;
3162
ret = create_hashmap(hashmap, 0,
3163
CreateHashMapReq::CreateDefault |
3164
CreateHashMapReq::CreateIfNotExists);
3172
syncInternalName(ndb, impl);
3174
UtilBufferWriter w(m_buffer);
3175
ret= serializeTableDesc(ndb, impl, w);
3181
DBUG_RETURN(sendCreateTable(impl, w));
3184
bool NdbDictionaryImpl::supportedAlterTable(NdbTableImpl &old_impl,
3187
return m_receiver.supportedAlterTable(old_impl, impl);
3190
bool NdbDictInterface::supportedAlterTable(const NdbTableImpl &old_impl,
3194
return (compChangeMask(old_impl, impl, change_mask) == 0);
3197
int NdbDictionaryImpl::alterTable(NdbTableImpl &old_impl,
3200
return alterTableGlobal(old_impl, impl);
3203
int NdbDictionaryImpl::alterTableGlobal(NdbTableImpl &old_impl,
3206
DBUG_ENTER("NdbDictionaryImpl::alterTableGlobal");
3208
Uint32 changeMask = 0;
3209
int ret = m_receiver.alterTable(m_ndb, old_impl, impl, changeMask);
3211
old_impl.m_status = NdbDictionary::Object::Invalid;
3214
NdbDictInterface::Tx::Op op;
3215
op.m_gsn = GSN_ALTER_TABLE_REQ;
3216
op.m_impl = &old_impl;
3217
if (m_tx.m_op.push_back(op) == -1) {
3218
m_error.code = 4000;
3221
m_globalHash->lock();
3222
ret = m_globalHash->inc_ref_count(op.m_impl);
3223
m_globalHash->unlock();
3227
if (ret == 0 && AlterTableReq::getNameFlag(changeMask) != 0)
3229
char db0[MAX_TAB_NAME_SIZE];
3230
char db1[MAX_TAB_NAME_SIZE];
3231
if (old_impl.getDbName(db0, sizeof(db0)) != 0)
3236
if (impl.getDbName(db1, sizeof(db0)) != 0)
3242
bool db_change = strcmp(db0, db1) != 0;
3243
if (old_impl.getSchemaName(db0, sizeof(db0)) != 0)
3248
if (impl.getSchemaName(db1, sizeof(db0)) != 0)
3254
bool schema_change = strcmp(db0, db1) != 0;
3255
if (db_change || schema_change)
3257
if (renameBlobTables(old_impl, impl) != 0)
3265
ERR_RETURN(getNdbError(), ret);
3269
NdbDictionaryImpl::renameBlobTables(const NdbTableImpl & old_tab,
3270
const NdbTableImpl & new_tab)
3272
if (old_tab.m_noOfBlobs == 0)
3275
char db[MAX_TAB_NAME_SIZE];
3276
char schema[MAX_TAB_NAME_SIZE];
3277
new_tab.getDbName(db, sizeof(db));
3278
new_tab.getSchemaName(schema, sizeof(schema));
3280
for (unsigned i = 0; i < old_tab.m_columns.size(); i++)
3282
NdbColumnImpl & c = *old_tab.m_columns[i];
3283
if (! c.getBlobType() || c.getPartSize() == 0)
3285
NdbTableImpl* _bt = c.m_blobTable;
3288
continue; // "force" mode on
3291
NdbDictionary::Table& bt = * _bt->m_facade;
3292
NdbDictionary::Table new_bt(bt);
3293
new_bt.m_impl.setDbSchema(db, schema);
3295
Uint32 changeMask = 0;
3296
int ret = m_receiver.alterTable(m_ndb, bt.m_impl, new_bt.m_impl,changeMask);
3301
assert(AlterTableReq::getNameFlag(changeMask) != 0);
3307
NdbDictInterface::alterTable(Ndb & ndb,
3308
const NdbTableImpl &old_impl,
3310
Uint32 & change_mask)
3314
DBUG_ENTER("NdbDictInterface::alterTable");
3316
syncInternalName(ndb, impl);
3318
/* Check that alter request is valid and compute stuff to alter. */
3319
ret= compChangeMask(old_impl, impl, change_mask);
3323
UtilBufferWriter w(m_buffer);
3324
ret= serializeTableDesc(ndb, impl, w);
3328
DBUG_RETURN(sendAlterTable(impl, change_mask, w));
3332
NdbDictInterface::syncInternalName(Ndb & ndb, NdbTableImpl &impl)
3334
const BaseString internalName(
3335
ndb.internalize_table_name(impl.m_externalName.c_str()));
3336
impl.m_internalName.assign(internalName);
3337
impl.updateMysqlName();
3341
Compare old and new Table descriptors.
3342
Set the corresponding flag for any (supported) difference.
3343
Error on any difference not supported for alter table.
3346
NdbDictInterface::compChangeMask(const NdbTableImpl &old_impl,
3347
const NdbTableImpl &impl,
3348
Uint32 &change_mask)
3350
DBUG_ENTER("compChangeMask");
3353
Uint32 old_sz= old_impl.m_columns.size();
3354
Uint32 sz= impl.m_columns.size();
3356
/* These are the supported properties that may be altered. */
3357
DBUG_PRINT("info", ("old_impl.m_internalName='%s' impl.m_internalName='%s'",
3358
old_impl.m_internalName.c_str(),
3359
impl.m_internalName.c_str()));
3360
if(impl.m_internalName != old_impl.m_internalName)
3362
bool old_blob = is_ndb_blob_table(old_impl.m_externalName.c_str());
3363
bool new_blob = is_ndb_blob_table(impl.m_externalName.c_str());
3364
if (unlikely(old_blob != new_blob))
3366
/* Attempt to alter to/from Blob part table name */
3367
DBUG_PRINT("info", ("Attempt to alter to/from Blob part table name"));
3368
goto invalid_alter_table;
3370
AlterTableReq::setNameFlag(change_mask, true);
3372
if(!impl.m_frm.equal(old_impl.m_frm))
3373
AlterTableReq::setFrmFlag(change_mask, true);
3374
if(!impl.m_fd.equal(old_impl.m_fd))
3375
AlterTableReq::setFragDataFlag(change_mask, true);
3376
if(!impl.m_range.equal(old_impl.m_range))
3377
AlterTableReq::setRangeListFlag(change_mask, true);
3379
/* No other property can be changed in alter table. */
3380
if(impl.m_logging != old_impl.m_logging ||
3381
impl.m_temporary != old_impl.m_temporary ||
3382
impl.m_row_gci != old_impl.m_row_gci ||
3383
impl.m_row_checksum != old_impl.m_row_checksum ||
3384
impl.m_kvalue != old_impl.m_kvalue ||
3385
impl.m_minLoadFactor != old_impl.m_minLoadFactor ||
3386
impl.m_maxLoadFactor != old_impl.m_maxLoadFactor ||
3387
impl.m_primaryTableId != old_impl.m_primaryTableId ||
3388
impl.m_max_rows != old_impl.m_max_rows ||
3389
impl.m_min_rows != old_impl.m_min_rows ||
3390
impl.m_default_no_part_flag != old_impl.m_default_no_part_flag ||
3391
impl.m_linear_flag != old_impl.m_linear_flag ||
3392
impl.m_fragmentType != old_impl.m_fragmentType ||
3393
impl.m_tablespace_name != old_impl.m_tablespace_name ||
3394
impl.m_tablespace_id != old_impl.m_tablespace_id ||
3395
impl.m_tablespace_version != old_impl.m_tablespace_version ||
3396
impl.m_id != old_impl.m_id ||
3397
impl.m_version != old_impl.m_version ||
3399
impl.m_extra_row_gci_bits != old_impl.m_extra_row_gci_bits ||
3400
impl.m_extra_row_author_bits != old_impl.m_extra_row_author_bits)
3402
DBUG_PRINT("info", ("Old and new table not compatible"));
3403
goto invalid_alter_table;
3406
if (impl.m_fragmentCount != old_impl.m_fragmentCount)
3408
if (impl.m_fragmentType != NdbDictionary::Object::HashMapPartition)
3409
goto invalid_alter_table;
3410
AlterTableReq::setAddFragFlag(change_mask, true);
3414
Check for new columns.
3415
We can add one or more new columns at the end, with some restrictions:
3416
- All existing columns must be unchanged.
3417
- The new column must be dynamic.
3418
- The new column must be nullable.
3419
- The new column must be memory based.
3420
- The new column can not be a primary key or distribution key.
3421
- There must already be at least one existing memory-stored dynamic or
3422
variable-sized column (so that the varpart is already allocated) or
3423
varPart must be forced
3425
found_varpart= old_impl.getForceVarPart();
3426
for(Uint32 i= 0; i<old_sz; i++)
3428
const NdbColumnImpl *col= impl.m_columns[i];
3429
if(!col->equal(*(old_impl.m_columns[i])))
3431
DBUG_PRINT("info", ("Old and new column not equal"));
3432
goto invalid_alter_table;
3434
if(col->m_storageType == NDB_STORAGETYPE_MEMORY &&
3435
(col->m_dynamic || col->m_arrayType != NDB_ARRAYTYPE_FIXED))
3436
found_varpart= true;
3443
DBUG_PRINT("info", ("No old dynamic column found"));
3444
goto invalid_alter_table;
3447
for(Uint32 i=old_sz; i<sz; i++)
3449
const NdbColumnImpl *col= impl.m_columns[i];
3450
if(!col->m_dynamic || !col->m_nullable ||
3451
col->m_storageType == NDB_STORAGETYPE_DISK ||
3453
col->m_distributionKey ||
3454
col->m_autoIncrement || // ToDo: allow this?
3455
(col->getBlobType() && col->getPartSize())
3458
goto invalid_alter_table;
3461
AlterTableReq::setAddAttrFlag(change_mask, true);
3466
invalid_alter_table:
3467
m_error.code = 741; // "Unsupported alter table"
3472
NdbDictInterface::serializeTableDesc(Ndb & ndb,
3473
NdbTableImpl & impl,
3474
UtilBufferWriter & w)
3477
DBUG_ENTER("NdbDictInterface::serializeTableDesc");
3479
impl.computeAggregates();
3481
if((unsigned)impl.getNoOfPrimaryKeys() > NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY){
3485
unsigned sz = impl.m_columns.size();
3486
if (sz > NDB_MAX_ATTRIBUTES_IN_TABLE){
3492
TODO RONM: Here I need to insert checks for fragment array and
3499
DictTabInfo::Table *tmpTab;
3501
tmpTab = (DictTabInfo::Table*)NdbMem_Allocate(sizeof(DictTabInfo::Table));
3504
m_error.code = 4000;
3508
BaseString::snprintf(tmpTab->TableName, sizeof(tmpTab->TableName),
3509
"%s", impl.m_internalName.c_str());
3512
for(i = 0; i<sz; i++) {
3513
const NdbColumnImpl * col = impl.m_columns[i];
3515
m_error.code = 4272;
3516
NdbMem_Free((void*)tmpTab);
3519
if (col->m_distributionKey)
3524
m_error.code = 4327;
3525
NdbMem_Free((void*)tmpTab);
3530
if (distKeys == impl.m_noOfKeys)
3532
impl.m_noOfDistributionKeys= distKeys;
3535
// Check max length of frm data
3536
if (impl.m_frm.length() > MAX_FRM_DATA_SIZE){
3538
NdbMem_Free((void*)tmpTab);
3542
TODO RONM: This needs to change to dynamic arrays instead
3543
Frm Data, FragmentData, TablespaceData, RangeListData, TsNameData
3545
tmpTab->FrmLen = impl.m_frm.length();
3546
memcpy(tmpTab->FrmData, impl.m_frm.get_data(), impl.m_frm.length());
3550
* NOTE: fragment data is currently an array of Uint16
3551
* and len is specified in bytes (yuck)
3552
* please change to Uint32 and len == count
3554
const Uint32* src = impl.m_fd.getBase();
3555
tmpTab->FragmentDataLen = 2*impl.m_fd.size();
3556
for (Uint32 i = 0; i<impl.m_fd.size(); i++)
3557
tmpTab->FragmentData[i] = (Uint16)src[i];
3562
* NOTE: len is specified in bytes (yuck)
3563
* please change to len == count
3565
tmpTab->RangeListDataLen = 4*impl.m_range.size();
3566
memcpy(tmpTab->RangeListData, impl.m_range.getBase(),4*impl.m_range.size());
3569
tmpTab->FragmentCount= impl.m_fragmentCount;
3570
tmpTab->TableLoggedFlag = impl.m_logging;
3571
tmpTab->TableTemporaryFlag = impl.m_temporary;
3572
tmpTab->RowGCIFlag = impl.m_row_gci;
3573
tmpTab->RowChecksumFlag = impl.m_row_checksum;
3574
tmpTab->TableKValue = impl.m_kvalue;
3575
tmpTab->MinLoadFactor = impl.m_minLoadFactor;
3576
tmpTab->MaxLoadFactor = impl.m_maxLoadFactor;
3577
tmpTab->TableType = DictTabInfo::UserTable;
3578
tmpTab->PrimaryTableId = impl.m_primaryTableId;
3579
tmpTab->NoOfAttributes = sz;
3580
tmpTab->MaxRowsHigh = (Uint32)(impl.m_max_rows >> 32);
3581
tmpTab->MaxRowsLow = (Uint32)(impl.m_max_rows & 0xFFFFFFFF);
3582
tmpTab->MinRowsHigh = (Uint32)(impl.m_min_rows >> 32);
3583
tmpTab->MinRowsLow = (Uint32)(impl.m_min_rows & 0xFFFFFFFF);
3584
tmpTab->DefaultNoPartFlag = impl.m_default_no_part_flag;
3585
tmpTab->LinearHashFlag = impl.m_linear_flag;
3586
tmpTab->SingleUserMode = impl.m_single_user_mode;
3587
tmpTab->ForceVarPartFlag = impl.m_force_var_part;
3588
tmpTab->ExtraRowGCIBits = impl.m_extra_row_gci_bits;
3589
tmpTab->ExtraRowAuthorBits = impl.m_extra_row_author_bits;
3591
tmpTab->FragmentType = getKernelConstant(impl.m_fragmentType,
3592
fragmentTypeMapping,
3593
DictTabInfo::AllNodesSmallTable);
3594
tmpTab->TableVersion = rand();
3596
tmpTab->HashMapObjectId = impl.m_hash_map_id;
3597
tmpTab->HashMapVersion = impl.m_hash_map_version;
3598
tmpTab->TableStorageType = impl.m_storageType;
3600
const char *tablespace_name= impl.m_tablespace_name.c_str();
3602
if(impl.m_tablespace_version != ~(Uint32)0)
3604
tmpTab->TablespaceId = impl.m_tablespace_id;
3605
tmpTab->TablespaceVersion = impl.m_tablespace_version;
3607
else if(strlen(tablespace_name))
3609
NdbTablespaceImpl tmp;
3610
if(get_filegroup(tmp, NdbDictionary::Object::Tablespace,
3611
tablespace_name) == 0)
3613
tmpTab->TablespaceId = tmp.m_id;
3614
tmpTab->TablespaceVersion = tmp.m_version;
3618
// error set by get filegroup
3619
if (m_error.code == 723)
3622
NdbMem_Free((void*)tmpTab);
3628
for(i = 0; i<sz; i++)
3630
if(impl.m_columns[i]->m_storageType == NDB_STORAGETYPE_DISK)
3632
tablespace_name = "DEFAULT-TS";
3638
SimpleProperties::UnpackStatus s;
3640
s = SimpleProperties::pack(w,
3642
DictTabInfo::TableMapping,
3643
DictTabInfo::TableMappingSize, true);
3645
if(s != SimpleProperties::Eof){
3648
NdbMem_Free((void*)tmpTab);
3650
DBUG_PRINT("info",("impl.m_noOfDistributionKeys: %d impl.m_noOfKeys: %d distKeys: %d",
3651
impl.m_noOfDistributionKeys, impl.m_noOfKeys, distKeys));
3652
if (distKeys == impl.m_noOfKeys)
3654
impl.m_noOfDistributionKeys= distKeys;
3656
for(i = 0; i<sz; i++){
3657
const NdbColumnImpl * col = impl.m_columns[i];
3661
DBUG_PRINT("info",("column: %s(%d) col->m_distributionKey: %d"
3662
" array type: %u storage type: %u",
3663
col->m_name.c_str(), i, col->m_distributionKey,
3664
col->m_arrayType, col->m_storageType));
3665
DictTabInfo::Attribute tmpAttr; tmpAttr.init();
3666
BaseString::snprintf(tmpAttr.AttributeName, sizeof(tmpAttr.AttributeName),
3667
"%s", col->m_name.c_str());
3668
tmpAttr.AttributeId = col->m_attrId;
3669
tmpAttr.AttributeKeyFlag = col->m_pk;
3670
tmpAttr.AttributeNullableFlag = col->m_nullable;
3671
tmpAttr.AttributeDKey = distKeys ? col->m_distributionKey : 0;
3673
tmpAttr.AttributeExtType = (Uint32)col->m_type;
3674
tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF);
3675
tmpAttr.AttributeExtScale = col->m_scale;
3676
tmpAttr.AttributeExtLength = col->m_length;
3677
tmpAttr.AttributeArrayType = col->m_arrayType;
3680
tmpAttr.AttributeStorageType = NDB_STORAGETYPE_MEMORY;
3682
tmpAttr.AttributeStorageType = col->m_storageType;
3683
tmpAttr.AttributeDynamic = (col->m_dynamic ? 1 : 0);
3685
if (col->getBlobType()) {
3686
tmpAttr.AttributeArrayType = col->m_arrayType;
3687
tmpAttr.AttributeStorageType = NDB_STORAGETYPE_MEMORY;
3690
// check type and compute attribute size and array size
3691
if (! tmpAttr.translateExtType()) {
3695
// charset is defined exactly for char types
3696
if (col->getCharType() != (col->m_cs != NULL)) {
3700
// primary key type check
3702
(err = NdbSqlUtil::check_column_for_pk(col->m_type, col->m_cs)))
3707
// all PK types now allowed as dist key
3708
// charset in upper half of precision
3709
if (col->getCharType()) {
3710
tmpAttr.AttributeExtPrecision |= (col->m_cs->number << 16);
3713
tmpAttr.AttributeAutoIncrement = col->m_autoIncrement;
3716
Uint32 byteSize = col->m_defaultValue.length();
3717
assert(byteSize <= NDB_MAX_TUPLE_SIZE);
3721
if (unlikely(! ndb_native_default_support(ndb.getMinDbNodeVersion())))
3723
/* We can't create a table with native defaults with
3724
* this kernel version
3725
* Schema feature requires data node upgrade
3732
//The AttributeId of a column isn't decided now, so 0 is used.
3733
AttributeHeader::init(&ah, 0, byteSize);
3735
/* Table meta-info is normally stored in network byte order
3736
* by SimpleProperties
3737
* For the default value 'Blob' we do the work
3739
Uint32 a = htonl(ah);
3740
memcpy(tmpAttr.AttributeDefaultValue, &a, sizeof(Uint32));
3741
memcpy(tmpAttr.AttributeDefaultValue + sizeof(Uint32),
3742
col->m_defaultValue.get_data(), byteSize);
3743
Uint32 defValByteLen = ((col->m_defaultValue.length() + 3) / 4) * 4;
3744
tmpAttr.AttributeDefaultValueLen = defValByteLen + sizeof(Uint32);
3748
/* In-place host->network conversion */
3749
NdbSqlUtil::convertByteOrder(tmpAttr.AttributeExtType,
3750
tmpAttr.AttributeSize,
3751
tmpAttr.AttributeArrayType,
3752
tmpAttr.AttributeArraySize,
3753
tmpAttr.AttributeDefaultValue +
3758
s = SimpleProperties::pack(w,
3760
DictTabInfo::AttributeMapping,
3761
DictTabInfo::AttributeMappingSize, true);
3762
w.add(DictTabInfo::AttributeEnd, 1);
3769
NdbDictInterface::sendAlterTable(const NdbTableImpl &impl,
3771
UtilBufferWriter &w)
3773
LinearSectionPtr ptr[1];
3774
ptr[0].p = (Uint32*)m_buffer.get_data();
3775
ptr[0].sz = m_buffer.length() / 4;
3776
NdbApiSignal tSignal(m_reference);
3777
tSignal.theReceiversBlockNumber = DBDICT;
3778
tSignal.theVerId_signalNumber = GSN_ALTER_TABLE_REQ;
3779
tSignal.theLength = AlterTableReq::SignalLength;
3781
AlterTableReq * req = CAST_PTR(AlterTableReq, tSignal.getDataPtrSend());
3783
req->clientRef = m_reference;
3784
req->clientData = 0;
3785
req->transId = m_tx.transId();
3786
req->transKey = m_tx.transKey();
3787
req->requestInfo = 0;
3788
req->requestInfo |= m_tx.requestFlags();
3789
req->tableId = impl.m_id;
3790
req->tableVersion = impl.m_version;
3791
req->changeMask = change_mask;
3793
int errCodes[] = { AlterTableRef::NotMaster, AlterTableRef::Busy, 0 };
3794
int ret= dictSignal(&tSignal, ptr, 1,
3797
DICT_WAITFOR_TIMEOUT, 100,
3800
if(m_error.code == AlterTableRef::InvalidTableVersion) {
3801
// Clear caches and try again
3802
return(INCOMPATIBLE_VERSION);
3809
NdbDictInterface::sendCreateTable(const NdbTableImpl &impl,
3810
UtilBufferWriter &w)
3812
LinearSectionPtr ptr[1];
3813
ptr[0].p = (Uint32*)m_buffer.get_data();
3814
ptr[0].sz = m_buffer.length() / 4;
3815
NdbApiSignal tSignal(m_reference);
3816
tSignal.theReceiversBlockNumber = DBDICT;
3817
tSignal.theVerId_signalNumber = GSN_CREATE_TABLE_REQ;
3818
tSignal.theLength = CreateTableReq::SignalLength;
3820
CreateTableReq * req = CAST_PTR(CreateTableReq, tSignal.getDataPtrSend());
3821
req->clientRef = m_reference;
3822
req->clientData = 0;
3823
req->requestInfo = 0;
3824
req->requestInfo |= m_tx.requestFlags();
3825
req->transId = m_tx.transId();
3826
req->transKey = m_tx.transKey();
3828
int errCodes[]= { CreateTableRef::Busy, CreateTableRef::NotMaster, 0 };
3829
int ret= dictSignal(&tSignal, ptr, 1,
3831
WAIT_CREATE_INDX_REQ,
3832
DICT_WAITFOR_TIMEOUT, 100,
3839
NdbDictInterface::execCREATE_TABLE_CONF(const NdbApiSignal * signal,
3840
const LinearSectionPtr ptr[3])
3842
const CreateTableConf* const conf=
3843
CAST_CONSTPTR(CreateTableConf, signal->getDataPtr());
3844
m_buffer.grow(4 * 2); // 2 words
3845
Uint32* data = (Uint32*)m_buffer.get_data();
3846
data[0] = conf->tableId;
3847
data[1] = conf->tableVersion;
3848
m_impl->theWaiter.signal(NO_WAIT);
3852
NdbDictInterface::execCREATE_TABLE_REF(const NdbApiSignal * sig,
3853
const LinearSectionPtr ptr[3])
3855
const CreateTableRef* ref = CAST_CONSTPTR(CreateTableRef, sig->getDataPtr());
3856
m_error.code= ref->errorCode;
3857
m_masterNodeId = ref->masterNodeId;
3858
m_impl->theWaiter.signal(NO_WAIT);
3862
NdbDictInterface::execALTER_TABLE_CONF(const NdbApiSignal * signal,
3863
const LinearSectionPtr ptr[3])
3865
m_impl->theWaiter.signal(NO_WAIT);
3869
NdbDictInterface::execALTER_TABLE_REF(const NdbApiSignal * sig,
3870
const LinearSectionPtr ptr[3])
3872
const AlterTableRef * ref = CAST_CONSTPTR(AlterTableRef, sig->getDataPtr());
3873
m_error.code= ref->errorCode;
3874
m_masterNodeId = ref->masterNodeId;
3875
m_impl->theWaiter.signal(NO_WAIT);
3878
/*****************************************************************
3882
NdbDictionaryImpl::dropTable(const char * name)
3884
DBUG_ENTER("NdbDictionaryImpl::dropTable");
3885
DBUG_PRINT("enter",("name: %s", name));
3887
NdbTableImpl * tab = getTable(name);
3891
int ret = dropTable(* tab);
3892
// If table stored in cache is incompatible with the one in the kernel
3893
// we must clear the cache and try again
3894
if (ret == INCOMPATIBLE_VERSION) {
3895
const BaseString internalTableName(m_ndb.internalize_table_name(name));
3896
DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName.c_str()));
3897
m_localHash.drop(internalTableName.c_str());
3898
m_globalHash->lock();
3899
m_globalHash->release(tab, 1);
3900
m_globalHash->unlock();
3901
DBUG_RETURN(dropTable(name));
3908
NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
3911
const char * name = impl.getName();
3912
if(impl.m_status == NdbDictionary::Object::New){
3913
return dropTable(name);
3916
if (impl.m_indexType != NdbDictionary::Object::TypeUndefined)
3918
m_receiver.m_error.code= 1228;
3923
if ((res = listIndexes(list, impl.m_id)) == -1){
3926
for (unsigned i = 0; i < list.count; i++) {
3927
const List::Element& element = list.elements[i];
3928
// note can also return -2 in error case(INCOMPATIBLE_VERSION),
3929
// hence compare with != 0
3930
if ((res = dropIndex(element.name, name)) != 0)
3936
if (impl.m_noOfBlobs != 0) {
3937
if (dropBlobTables(impl) != 0){
3942
int ret = m_receiver.dropTable(impl);
3943
if(ret == 0 || m_error.code == 709 || m_error.code == 723){
3944
const char * internalTableName = impl.m_internalName.c_str();
3947
m_localHash.drop(internalTableName);
3948
m_globalHash->lock();
3949
m_globalHash->release(&impl, 1);
3950
m_globalHash->unlock();
3959
NdbDictionaryImpl::dropTableGlobal(NdbTableImpl & impl)
3962
DBUG_ENTER("NdbDictionaryImpl::dropTableGlobal");
3963
DBUG_ASSERT(impl.m_status != NdbDictionary::Object::New);
3964
DBUG_ASSERT(impl.m_indexType == NdbDictionary::Object::TypeUndefined);
3967
if ((res = listIndexes(list, impl.m_id)) == -1){
3968
ERR_RETURN(getNdbError(), -1);
3970
for (unsigned i = 0; i < list.count; i++) {
3971
const List::Element& element = list.elements[i];
3972
NdbIndexImpl *idx= getIndexGlobal(element.name, impl);
3975
ERR_RETURN(getNdbError(), -1);
3977
// note can also return -2 in error case(INCOMPATIBLE_VERSION),
3978
// hence compare with != 0
3979
if ((res = dropIndexGlobal(*idx)) != 0)
3981
releaseIndexGlobal(*idx, 1);
3982
ERR_RETURN(getNdbError(), -1);
3984
releaseIndexGlobal(*idx, 1);
3987
if (impl.m_noOfBlobs != 0) {
3988
if (dropBlobTables(impl) != 0){
3989
ERR_RETURN(getNdbError(), -1);
3993
int ret = m_receiver.dropTable(impl);
3994
impl.m_status = NdbDictionary::Object::Invalid;
3995
if(ret == 0 || m_error.code == 709 || m_error.code == 723)
4000
ERR_RETURN(getNdbError(), ret);
4004
NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
4006
DBUG_ENTER("NdbDictionaryImpl::dropBlobTables");
4007
for (unsigned i = 0; i < t.m_columns.size(); i++) {
4008
NdbColumnImpl & c = *t.m_columns[i];
4009
if (! c.getBlobType() || c.getPartSize() == 0)
4011
NdbTableImpl* bt = c.m_blobTable;
4013
DBUG_PRINT("info", ("col %s: blob table pointer is NULL",
4015
continue; // "force" mode on
4017
// drop directly - by-pass cache
4018
int ret = m_receiver.dropTable(*c.m_blobTable);
4020
DBUG_PRINT("info", ("col %s: blob table %s: error %d",
4021
c.m_name.c_str(), bt->m_internalName.c_str(), m_error.code));
4022
if (! (ret == 709 || ret == 723)) // "force" mode on
4023
ERR_RETURN(getNdbError(), -1);
4025
// leave c.m_blobTable defined
4031
NdbDictInterface::dropTable(const NdbTableImpl & impl)
4033
NdbApiSignal tSignal(m_reference);
4034
tSignal.theReceiversBlockNumber = DBDICT;
4035
tSignal.theVerId_signalNumber = GSN_DROP_TABLE_REQ;
4036
tSignal.theLength = DropTableReq::SignalLength;
4038
DropTableReq * req = CAST_PTR(DropTableReq, tSignal.getDataPtrSend());
4039
req->clientRef = m_reference;
4040
req->clientData = 0;
4041
req->transId = m_tx.transId();
4042
req->transKey = m_tx.transKey();
4043
req->requestInfo = 0;
4044
req->requestInfo |= m_tx.requestFlags();
4045
req->tableId = impl.m_id;
4046
req->tableVersion = impl.m_version;
4049
{ DropTableRef::NoDropTableRecordAvailable,
4050
DropTableRef::NotMaster,
4051
DropTableRef::Busy, 0 };
4052
int r = dictSignal(&tSignal, 0, 0,
4055
DICT_WAITFOR_TIMEOUT, 100,
4057
if(m_error.code == DropTableRef::InvalidTableVersion) {
4058
// Clear caches and try again
4059
return INCOMPATIBLE_VERSION;
4065
NdbDictInterface::execDROP_TABLE_CONF(const NdbApiSignal * signal,
4066
const LinearSectionPtr ptr[3])
4068
DBUG_ENTER("NdbDictInterface::execDROP_TABLE_CONF");
4069
//DropTableConf* const conf = CAST_CONSTPTR(DropTableConf, signal->getDataPtr());
4071
m_impl->theWaiter.signal(NO_WAIT);
4076
NdbDictInterface::execDROP_TABLE_REF(const NdbApiSignal * signal,
4077
const LinearSectionPtr ptr[3])
4079
DBUG_ENTER("NdbDictInterface::execDROP_TABLE_REF");
4080
const DropTableRef* ref = CAST_CONSTPTR(DropTableRef, signal->getDataPtr());
4081
m_error.code= ref->errorCode;
4082
m_masterNodeId = ref->masterNodeId;
4083
m_impl->theWaiter.signal(NO_WAIT);
4088
NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
4090
const char * internalTableName = impl.m_internalName.c_str();
4091
DBUG_ENTER("NdbDictionaryImpl::invalidateObject");
4092
DBUG_PRINT("enter", ("internal_name: %s", internalTableName));
4094
m_localHash.drop(internalTableName);
4095
m_globalHash->lock();
4096
m_globalHash->release(&impl, 1);
4097
m_globalHash->unlock();
4102
NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl)
4104
const char * internalTableName = impl.m_internalName.c_str();
4105
DBUG_ENTER("NdbDictionaryImpl::removeCachedObject");
4106
DBUG_PRINT("enter", ("internal_name: %s", internalTableName));
4108
m_localHash.drop(internalTableName);
4109
m_globalHash->lock();
4110
m_globalHash->release(&impl);
4111
m_globalHash->unlock();
4116
NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
4118
const NdbTableImpl* prim)
4120
DBUG_ENTER("NdbDictInterface::create_index_obj_from_table");
4121
NdbIndexImpl *idx = new NdbIndexImpl();
4127
idx->m_version = tab->m_version;
4128
idx->m_status = tab->m_status;
4129
idx->m_id = tab->m_id;
4130
if (!idx->m_externalName.assign(tab->getName()) ||
4131
!idx->m_tableName.assign(prim->m_externalName))
4137
NdbDictionary::Object::Type type = idx->m_type = tab->m_indexType;
4138
idx->m_logging = tab->m_logging;
4139
idx->m_temporary = tab->m_temporary;
4141
const Uint32 distKeys = prim->m_noOfDistributionKeys;
4143
(type == NdbDictionary::Object::UniqueHashIndex) ?
4144
tab->m_noOfKeys : (distKeys ? distKeys : prim->m_noOfKeys);
4145
const Uint32 fullKeyCount = keyCount;
4148
// skip last attribute (NDB$PK or NDB$TNODE)
4149
for(i = 0; i+1<tab->m_columns.size(); i++){
4150
NdbColumnImpl* org = tab->m_columns[i];
4152
NdbColumnImpl* col = new NdbColumnImpl;
4159
// Copy column definition
4161
if (idx->m_columns.push_back(col))
4171
const NdbColumnImpl* primCol = prim->getColumn(col->getName());
4178
int key_id = primCol->getColumnNo();
4180
idx->m_key_ids.fill(key_id, fill);
4181
idx->m_key_ids[key_id] = i;
4182
col->m_keyInfoPos = key_id;
4184
if(type == NdbDictionary::Object::OrderedIndex &&
4185
(primCol->m_distributionKey ||
4186
(distKeys == 0 && primCol->getPrimaryKey())))
4189
org->m_distributionKey = 1;
4191
else if (type == NdbDictionary::Object::UniqueHashIndex)
4194
org->m_distributionKey = 1;
4200
tab->m_noOfDistributionKeys = fullKeyCount;
4204
for(i = 0; i+1<tab->m_columns.size(); i++)
4205
tab->m_columns[i]->m_distributionKey = 0;
4208
idx->m_table_id = prim->getObjectId();
4209
idx->m_table_version = prim->getObjectVersion();
4212
DBUG_PRINT("exit", ("m_id: %d m_version: %d", idx->m_id, idx->m_version));
4216
/*****************************************************************
4220
NdbDictionaryImpl::createIndex(NdbIndexImpl &ix, bool offline)
4223
NdbTableImpl* tab = getTable(ix.getTable());
4225
m_error.code = 4249;
4229
return m_receiver.createIndex(m_ndb, ix, * tab, offline);
4233
NdbDictionaryImpl::createIndex(NdbIndexImpl &ix, NdbTableImpl &tab,
4236
return m_receiver.createIndex(m_ndb, ix, tab, offline);
4240
NdbDictInterface::createIndex(Ndb & ndb,
4241
const NdbIndexImpl & impl,
4242
const NdbTableImpl & table,
4248
UtilBufferWriter w(m_buffer);
4249
const size_t len = strlen(impl.m_externalName.c_str()) + 1;
4250
if(len > MAX_TAB_NAME_SIZE) {
4251
m_error.code = 4241;
4254
const BaseString internalName(
4255
ndb.internalize_index_name(&table, impl.getName()));
4256
w.add(DictTabInfo::TableName, internalName.c_str());
4257
w.add(DictTabInfo::TableLoggedFlag, impl.m_logging);
4258
w.add(DictTabInfo::TableTemporaryFlag, impl.m_temporary);
4260
NdbApiSignal tSignal(m_reference);
4261
tSignal.theReceiversBlockNumber = DBDICT;
4262
tSignal.theVerId_signalNumber = GSN_CREATE_INDX_REQ;
4263
tSignal.theLength = CreateIndxReq::SignalLength;
4265
CreateIndxReq * const req = CAST_PTR(CreateIndxReq, tSignal.getDataPtrSend());
4266
req->clientRef = m_reference;
4267
req->clientData = 0;
4268
req->transId = m_tx.transId();
4269
req->transKey = m_tx.transKey();
4270
req->requestInfo = offline ? CreateIndxReq::RF_BUILD_OFFLINE : 0;
4271
req->requestInfo |= m_tx.requestFlags();
4273
Uint32 it = getKernelConstant(impl.m_type,
4275
DictTabInfo::UndefTableType);
4277
if(it == DictTabInfo::UndefTableType){
4278
m_error.code = 4250;
4281
req->indexType = it;
4283
req->tableId = table.m_id;
4284
req->tableVersion = table.m_version;
4286
IndexAttributeList attributeList;
4287
attributeList.sz = impl.m_columns.size();
4288
for(i = 0; i<attributeList.sz; i++){
4289
const NdbColumnImpl* col =
4290
table.getColumn(impl.m_columns[i]->m_name.c_str());
4292
m_error.code = 4247;
4295
// Copy column definition XXX must be wrong, overwrites
4296
*impl.m_columns[i] = *col;
4298
// index key type check
4299
if ((it == DictTabInfo::UniqueHashIndex &&
4300
(err = NdbSqlUtil::check_column_for_hash_index(col->m_type, col->m_cs)))
4302
(it == DictTabInfo::OrderedIndex &&
4303
(err = NdbSqlUtil::check_column_for_ordered_index(col->m_type, col->m_cs))))
4308
// API uses external column number to talk to DICT
4309
attributeList.id[i] = col->m_column_no;
4311
LinearSectionPtr ptr[2];
4312
ptr[0].p = (Uint32*)&attributeList;
4313
ptr[0].sz = 1 + attributeList.sz;
4314
ptr[1].p = (Uint32*)m_buffer.get_data();
4315
ptr[1].sz = m_buffer.length() >> 2; //BUG?
4317
int errCodes[] = { CreateIndxRef::Busy, CreateIndxRef::NotMaster, 0 };
4318
return dictSignal(&tSignal, ptr, 2,
4320
WAIT_CREATE_INDX_REQ,
4321
DICT_WAITFOR_TIMEOUT, 100,
4326
NdbDictInterface::execCREATE_INDX_CONF(const NdbApiSignal * signal,
4327
const LinearSectionPtr ptr[3])
4329
m_impl->theWaiter.signal(NO_WAIT);
4333
NdbDictInterface::execCREATE_INDX_REF(const NdbApiSignal * sig,
4334
const LinearSectionPtr ptr[3])
4336
const CreateIndxRef* ref = CAST_CONSTPTR(CreateIndxRef, sig->getDataPtr());
4337
m_error.code = ref->errorCode;
4338
if (m_error.code == ref->NotMaster)
4339
m_masterNodeId = ref->masterNodeId;
4340
m_impl->theWaiter.signal(NO_WAIT);
4346
NdbDictionaryImpl::updateIndexStat(const NdbIndexImpl& index,
4347
const NdbTableImpl& table)
4349
Uint32 rt = IndexStatReq::RT_UPDATE_STAT;
4350
return m_receiver.doIndexStatReq(m_ndb, index, table, rt);
4354
NdbDictionaryImpl::updateIndexStat(Uint32 indexId,
4355
Uint32 indexVersion,
4358
Uint32 rt = IndexStatReq::RT_UPDATE_STAT;
4359
return m_receiver.doIndexStatReq(m_ndb, indexId, indexVersion, tableId, rt);
4363
NdbDictionaryImpl::deleteIndexStat(const NdbIndexImpl& index,
4364
const NdbTableImpl& table)
4366
Uint32 rt = IndexStatReq::RT_DELETE_STAT;
4367
return m_receiver.doIndexStatReq(m_ndb, index, table, rt);
4371
NdbDictionaryImpl::deleteIndexStat(Uint32 indexId,
4372
Uint32 indexVersion,
4375
Uint32 rt = IndexStatReq::RT_DELETE_STAT;
4376
return m_receiver.doIndexStatReq(m_ndb, indexId, indexVersion, tableId, rt);
4380
NdbDictInterface::doIndexStatReq(Ndb& ndb,
4381
const NdbIndexImpl& index,
4382
const NdbTableImpl& table,
4385
return doIndexStatReq(ndb, index.m_id, index.m_version, table.m_id, rt);
4389
NdbDictInterface::doIndexStatReq(Ndb& ndb,
4391
Uint32 indexVersion,
4395
NdbApiSignal tSignal(m_reference);
4396
tSignal.theReceiversBlockNumber = DBDICT;
4397
tSignal.theVerId_signalNumber = GSN_INDEX_STAT_REQ;
4398
tSignal.theLength = IndexStatReq::SignalLength;
4400
IndexStatReq* req = CAST_PTR(IndexStatReq, tSignal.getDataPtrSend());
4401
req->clientRef = m_reference;
4402
req->clientData = 0;
4403
req->transId = m_tx.transId();
4404
req->transKey = m_tx.transKey();
4405
req->requestInfo = requestType;
4406
req->requestFlag = 0;
4407
req->indexId = indexId;
4408
req->indexVersion = indexVersion;
4409
req->tableId = tableId;
4411
int errCodes[] = { IndexStatRef::Busy, IndexStatRef::NotMaster, 0 };
4412
return dictSignal(&tSignal, 0, 0,
4414
WAIT_CREATE_INDX_REQ,
4415
DICT_WAITFOR_TIMEOUT, 100,
4420
NdbDictInterface::execINDEX_STAT_CONF(const NdbApiSignal * signal,
4421
const LinearSectionPtr ptr[3])
4423
m_impl->theWaiter.signal(NO_WAIT);
4427
NdbDictInterface::execINDEX_STAT_REF(const NdbApiSignal * signal,
4428
const LinearSectionPtr ptr[3])
4430
const IndexStatRef* ref = CAST_CONSTPTR(IndexStatRef, signal->getDataPtr());
4431
m_error.code = ref->errorCode;
4432
if (m_error.code == ref->NotMaster)
4433
m_masterNodeId = ref->masterNodeId;
4434
m_impl->theWaiter.signal(NO_WAIT);
4437
/*****************************************************************
4441
NdbDictionaryImpl::dropIndex(const char * indexName,
4442
const char * tableName)
4445
NdbIndexImpl * idx = getIndex(indexName, tableName);
4447
m_error.code = 4243;
4450
int ret = dropIndex(*idx, tableName);
4451
// If index stored in cache is incompatible with the one in the kernel
4452
// we must clear the cache and try again
4453
if (ret == INCOMPATIBLE_VERSION) {
4454
const BaseString internalIndexName((tableName)
4456
m_ndb.internalize_index_name(getTable(tableName), indexName)
4458
m_ndb.internalize_table_name(indexName)); // Index is also a table
4460
m_localHash.drop(internalIndexName.c_str());
4461
m_globalHash->lock();
4462
m_globalHash->release(idx->m_table, 1);
4463
m_globalHash->unlock();
4464
return dropIndex(indexName, tableName);
4471
NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
4473
const char * indexName = impl.getName();
4474
if (tableName || m_ndb.usingFullyQualifiedNames()) {
4475
NdbTableImpl * timpl = impl.m_table;
4482
const BaseString internalIndexName((tableName)
4484
m_ndb.internalize_index_name(getTable(tableName), indexName)
4486
m_ndb.internalize_table_name(indexName)); // Index is also a table
4488
if(impl.m_status == NdbDictionary::Object::New){
4489
return dropIndex(indexName, tableName);
4492
int ret= dropIndexGlobal(impl);
4495
m_globalHash->lock();
4496
m_globalHash->release(impl.m_table, 1);
4497
m_globalHash->unlock();
4498
m_localHash.drop(internalIndexName.c_str());
4503
m_error.code = 4243;
4508
NdbDictionaryImpl::dropIndexGlobal(NdbIndexImpl & impl)
4510
DBUG_ENTER("NdbDictionaryImpl::dropIndexGlobal");
4511
int ret = m_receiver.dropIndex(impl, *impl.m_table);
4512
impl.m_status = NdbDictionary::Object::Invalid;
4517
ERR_RETURN(getNdbError(), ret);
4521
NdbDictInterface::dropIndex(const NdbIndexImpl & impl,
4522
const NdbTableImpl & timpl)
4524
DBUG_ENTER("NdbDictInterface::dropIndex");
4525
DBUG_PRINT("enter", ("indexId: %d indexVersion: %d",
4526
timpl.m_id, timpl.m_version));
4527
NdbApiSignal tSignal(m_reference);
4528
tSignal.theReceiversBlockNumber = DBDICT;
4529
tSignal.theVerId_signalNumber = GSN_DROP_INDX_REQ;
4530
tSignal.theLength = DropIndxReq::SignalLength;
4532
DropIndxReq * const req = CAST_PTR(DropIndxReq, tSignal.getDataPtrSend());
4533
req->clientRef = m_reference;
4534
req->clientData = 0;
4535
req->transId = m_tx.transId();
4536
req->transKey = m_tx.transKey();
4537
req->requestInfo = 0;
4538
req->requestInfo |= m_tx.requestFlags();
4539
req->indexId = timpl.m_id;
4540
req->indexVersion = timpl.m_version;
4542
int errCodes[] = { DropIndxRef::Busy, DropIndxRef::NotMaster, 0 };
4543
int r = dictSignal(&tSignal, 0, 0,
4546
DICT_WAITFOR_TIMEOUT, 100,
4548
if(m_error.code == DropIndxRef::InvalidIndexVersion) {
4549
// Clear caches and try again
4550
ERR_RETURN(m_error, INCOMPATIBLE_VERSION);
4552
ERR_RETURN(m_error, r);
4556
NdbDictInterface::execDROP_INDX_CONF(const NdbApiSignal * signal,
4557
const LinearSectionPtr ptr[3])
4559
m_impl->theWaiter.signal(NO_WAIT);
4563
NdbDictInterface::execDROP_INDX_REF(const NdbApiSignal * signal,
4564
const LinearSectionPtr ptr[3])
4566
const DropIndxRef* ref = CAST_CONSTPTR(DropIndxRef, signal->getDataPtr());
4567
m_error.code = ref->errorCode;
4568
if (m_error.code == ref->NotMaster)
4569
m_masterNodeId = ref->masterNodeId;
4570
m_impl->theWaiter.signal(NO_WAIT);
4573
/*****************************************************************
4578
NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
4580
DBUG_ENTER("NdbDictionaryImpl::createEvent");
4582
NdbTableImpl* tab= evnt.m_tableImpl;
4585
tab= getTable(evnt.getTableName());
4587
DBUG_PRINT("info",("NdbDictionaryImpl::createEvent: table not found: %s",
4588
evnt.getTableName()));
4589
ERR_RETURN(getNdbError(), -1);
4594
DBUG_PRINT("info",("Table: id: %d version: %d", tab->m_id, tab->m_version));
4596
NdbTableImpl &table = *evnt.m_tableImpl;
4598
int attributeList_sz = evnt.m_attrIds.size();
4600
for (i = 0; i < attributeList_sz; i++) {
4601
NdbColumnImpl *col_impl = table.getColumn(evnt.m_attrIds[i]);
4603
evnt.m_facade->addColumn(*(col_impl->m_facade));
4605
ndbout_c("Attr id %u in table %s not found", evnt.m_attrIds[i],
4606
evnt.getTableName());
4608
ERR_RETURN(getNdbError(), -1);
4612
evnt.m_attrIds.clear();
4614
attributeList_sz = evnt.m_columns.size();
4616
DBUG_PRINT("info",("Event on tableId=%d, tableVersion=%d, event name %s, no of columns %d",
4617
table.m_id, table.m_version,
4618
evnt.m_name.c_str(),
4619
evnt.m_columns.size()));
4622
evnt.m_attrListBitmask.clear();
4624
for(i = 0; i<attributeList_sz; i++){
4625
const NdbColumnImpl* col =
4626
table.getColumn(evnt.m_columns[i]->m_name.c_str());
4629
ERR_RETURN(getNdbError(), -1);
4631
// Copy column definition
4632
*evnt.m_columns[i] = *col;
4638
evnt.m_attrListBitmask.set(col->m_attrId);
4641
// Sort index attributes according to primary table (using insertion sort)
4642
for(i = 1; i < attributeList_sz; i++) {
4643
NdbColumnImpl* temp = evnt.m_columns[i];
4645
while((j > 0) && (evnt.m_columns[j - 1]->m_attrId > temp->m_attrId)) {
4646
evnt.m_columns[j] = evnt.m_columns[j - 1];
4649
evnt.m_columns[j] = temp;
4651
// Check for illegal duplicate attributes
4652
for(i = 1; i<attributeList_sz; i++) {
4653
if (evnt.m_columns[i-1]->m_attrId == evnt.m_columns[i]->m_attrId) {
4655
ERR_RETURN(getNdbError(), -1);
4659
// NdbDictInterface m_receiver;
4660
if (m_receiver.createEvent(m_ndb, evnt, 0 /* getFlag unset */) != 0)
4661
ERR_RETURN(getNdbError(), -1);
4663
// Create blob events
4664
if (evnt.m_mergeEvents && createBlobEvents(evnt) != 0) {
4665
int save_code = m_error.code;
4666
(void)dropEvent(evnt.m_name.c_str(), 0);
4667
m_error.code = save_code;
4668
ERR_RETURN(getNdbError(), -1);
4674
NdbDictionaryImpl::createBlobEvents(NdbEventImpl& evnt)
4676
DBUG_ENTER("NdbDictionaryImpl::createBlobEvents");
4677
NdbTableImpl& t = *evnt.m_tableImpl;
4678
Uint32 n = t.m_noOfBlobs;
4680
for (i = 0; i < evnt.m_columns.size() && n > 0; i++) {
4681
NdbColumnImpl & c = *evnt.m_columns[i];
4682
if (! c.getBlobType() || c.getPartSize() == 0)
4685
NdbEventImpl blob_evnt;
4686
NdbBlob::getBlobEvent(blob_evnt, &evnt, &c);
4687
if (createEvent(blob_evnt) != 0)
4688
ERR_RETURN(getNdbError(), -1);
4694
NdbDictInterface::createEvent(class Ndb & ndb,
4695
NdbEventImpl & evnt,
4698
DBUG_ENTER("NdbDictInterface::createEvent");
4699
DBUG_PRINT("enter",("getFlag=%d",getFlag));
4701
NdbApiSignal tSignal(m_reference);
4702
tSignal.theReceiversBlockNumber = DBDICT;
4703
tSignal.theVerId_signalNumber = GSN_CREATE_EVNT_REQ;
4705
tSignal.theLength = CreateEvntReq::SignalLengthGet;
4707
tSignal.theLength = CreateEvntReq::SignalLengthCreate;
4709
CreateEvntReq * const req = CAST_PTR(CreateEvntReq, tSignal.getDataPtrSend());
4711
req->setUserRef(m_reference);
4712
req->setUserData(0);
4715
LinearSectionPtr ptr[2];
4718
// getting event from Dictionary
4719
req->setRequestType(CreateEvntReq::RT_USER_GET);
4721
DBUG_PRINT("info",("tableId: %u tableVersion: %u",
4722
evnt.m_tableImpl->m_id,
4723
evnt.m_tableImpl->m_version));
4724
// creating event in Dictionary
4725
req->setRequestType(CreateEvntReq::RT_USER_CREATE);
4726
req->setTableId(evnt.m_tableImpl->m_id);
4727
req->setTableVersion(evnt.m_tableImpl->m_version);
4728
req->setAttrListBitmask(evnt.m_attrListBitmask);
4729
req->setEventType(evnt.mi_type);
4731
if (evnt.m_rep & NdbDictionary::Event::ER_ALL)
4732
req->setReportAll();
4733
if (evnt.m_rep & NdbDictionary::Event::ER_SUBSCRIBE)
4734
req->setReportSubscribe();
4735
if (evnt.m_rep & NdbDictionary::Event::ER_DDL)
4737
req->setReportDDL();
4741
req->clearReportDDL();
4743
ptr[1].p = evnt.m_attrListBitmask.rep.data;
4744
ptr[1].sz = evnt.m_attrListBitmask.getSizeInWords();
4748
UtilBufferWriter w(m_buffer);
4750
const size_t len = strlen(evnt.m_name.c_str()) + 1;
4751
if(len > MAX_TAB_NAME_SIZE) {
4753
ERR_RETURN(getNdbError(), -1);
4756
w.add(SimpleProperties::StringValue, evnt.m_name.c_str());
4760
const BaseString internal_tabname(
4761
ndb.internalize_table_name(evnt.m_tableName.c_str()));
4762
w.add(SimpleProperties::StringValue,
4763
internal_tabname.c_str());
4766
ptr[0].p = (Uint32*)m_buffer.get_data();
4767
ptr[0].sz = (m_buffer.length()+3) >> 2;
4769
int ret = dictSignal(&tSignal,ptr, seccnt,
4771
WAIT_CREATE_INDX_REQ,
4772
DICT_WAITFOR_TIMEOUT, 100,
4776
ERR_RETURN(getNdbError(), ret);
4779
char *dataPtr = (char *)m_buffer.get_data();
4780
unsigned int lenCreateEvntConf = *((unsigned int *)dataPtr);
4781
dataPtr += sizeof(lenCreateEvntConf);
4782
CreateEvntConf const * evntConf = (CreateEvntConf *)dataPtr;
4783
dataPtr += lenCreateEvntConf;
4785
// NdbEventImpl *evntImpl = (NdbEventImpl *)evntConf->getUserData();
4787
evnt.m_eventId = evntConf->getEventId();
4788
evnt.m_eventKey = evntConf->getEventKey();
4789
evnt.m_table_id = evntConf->getTableId();
4790
evnt.m_table_version = evntConf->getTableVersion();
4793
evnt.m_attrListBitmask = evntConf->getAttrListBitmask();
4794
evnt.mi_type = evntConf->getEventType();
4795
evnt.setTable(dataPtr);
4796
if (!m_tableData.empty())
4798
Uint32 len = m_tableData.length();
4799
assert((len & 3) == 0);
4801
if (len <= evnt.m_attrListBitmask.getSizeInWords())
4803
evnt.m_attrListBitmask.clear();
4804
memcpy(evnt.m_attrListBitmask.rep.data, m_tableData.get_data(), 4*len);
4808
memcpy(evnt.m_attrListBitmask.rep.data, m_tableData.get_data(),
4809
4*evnt.m_attrListBitmask.getSizeInWords());
4813
if ((Uint32) evnt.m_tableImpl->m_id != evntConf->getTableId() ||
4814
evnt.m_tableImpl->m_version != evntConf->getTableVersion() ||
4815
//evnt.m_attrListBitmask != evntConf->getAttrListBitmask() ||
4816
evnt.mi_type != evntConf->getEventType()) {
4817
ndbout_c("ERROR*************");
4819
m_tableData.clear();
4820
ERR_RETURN(getNdbError(), 1);
4825
m_tableData.clear();
4831
NdbDictionaryImpl::executeSubscribeEvent(NdbEventOperationImpl & ev_op,
4834
// NdbDictInterface m_receiver;
4835
return m_receiver.executeSubscribeEvent(m_ndb, ev_op, buckets);
4839
NdbDictInterface::executeSubscribeEvent(class Ndb & ndb,
4840
NdbEventOperationImpl & ev_op,
4843
DBUG_ENTER("NdbDictInterface::executeSubscribeEvent");
4844
NdbApiSignal tSignal(m_reference);
4845
tSignal.theReceiversBlockNumber = DBDICT;
4846
tSignal.theVerId_signalNumber = GSN_SUB_START_REQ;
4847
tSignal.theLength = SubStartReq::SignalLength;
4849
SubStartReq * req = CAST_PTR(SubStartReq, tSignal.getDataPtrSend());
4851
req->subscriptionId = ev_op.m_eventImpl->m_eventId;
4852
req->subscriptionKey = ev_op.m_eventImpl->m_eventKey;
4853
req->part = SubscriptionData::TableData;
4854
req->subscriberData = ev_op.m_oid;
4855
req->subscriberRef = m_reference;
4857
DBUG_PRINT("info",("GSN_SUB_START_REQ subscriptionId=%d,subscriptionKey=%d,"
4858
"subscriberData=%d",req->subscriptionId,
4859
req->subscriptionKey,req->subscriberData));
4861
int errCodes[] = { SubStartRef::Busy,
4862
SubStartRef::BusyWithNR,
4863
SubStartRef::NotMaster,
4865
int ret = dictSignal(&tSignal,NULL,0,
4866
0 /*use masternode id*/,
4867
WAIT_CREATE_INDX_REQ /*WAIT_CREATE_EVNT_REQ*/,
4872
buckets = m_data.m_sub_start_conf.m_buckets;
4879
NdbDictionaryImpl::stopSubscribeEvent(NdbEventOperationImpl & ev_op)
4881
// NdbDictInterface m_receiver;
4882
return m_receiver.stopSubscribeEvent(m_ndb, ev_op);
4886
NdbDictInterface::stopSubscribeEvent(class Ndb & ndb,
4887
NdbEventOperationImpl & ev_op)
4889
DBUG_ENTER("NdbDictInterface::stopSubscribeEvent");
4891
NdbApiSignal tSignal(m_reference);
4892
// tSignal.theReceiversBlockNumber = SUMA;
4893
tSignal.theReceiversBlockNumber = DBDICT;
4894
tSignal.theVerId_signalNumber = GSN_SUB_STOP_REQ;
4895
tSignal.theLength = SubStopReq::SignalLength;
4897
SubStopReq * req = CAST_PTR(SubStopReq, tSignal.getDataPtrSend());
4899
req->subscriptionId = ev_op.m_eventImpl->m_eventId;
4900
req->subscriptionKey = ev_op.m_eventImpl->m_eventKey;
4901
req->subscriberData = ev_op.m_oid;
4902
req->part = (Uint32) SubscriptionData::TableData;
4903
req->subscriberRef = m_reference;
4904
req->requestInfo = 0;
4906
DBUG_PRINT("info",("GSN_SUB_STOP_REQ subscriptionId=%d,subscriptionKey=%d,"
4907
"subscriberData=%d",req->subscriptionId,
4908
req->subscriptionKey,req->subscriberData));
4910
int errCodes[] = { SubStartRef::Busy,
4911
SubStartRef::BusyWithNR,
4912
SubStartRef::NotMaster,
4914
int ret= dictSignal(&tSignal,NULL,0,
4915
0 /*use masternode id*/,
4916
WAIT_CREATE_INDX_REQ /*WAIT_SUB_STOP__REQ*/,
4921
Uint32 *data = (Uint32*)m_buffer.get_data();
4922
ev_op.m_stop_gci = data[1] | (Uint64(data[0]) << 32);
4928
NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab)
4930
DBUG_ENTER("NdbDictionaryImpl::getEvent");
4931
DBUG_PRINT("enter",("eventName= %s", eventName));
4933
NdbEventImpl *ev = new NdbEventImpl();
4938
ev->setName(eventName);
4940
int ret = m_receiver.createEvent(m_ndb, *ev, 1 /* getFlag set */);
4947
// We only have the table name with internal name
4948
DBUG_PRINT("info",("table %s", ev->getTableName()));
4951
tab= fetchGlobalTableImplRef(InitTable(ev->getTableName()));
4954
DBUG_PRINT("error",("unable to find table %s", ev->getTableName()));
4958
if ((tab->m_status != NdbDictionary::Object::Retrieved) ||
4959
((Uint32) tab->m_id != ev->m_table_id) ||
4960
(table_version_major(tab->m_version) !=
4961
table_version_major(ev->m_table_version)))
4963
DBUG_PRINT("info", ("mismatch on verison in cache"));
4964
releaseTableGlobal(*tab, 1);
4965
tab= fetchGlobalTableImplRef(InitTable(ev->getTableName()));
4968
DBUG_PRINT("error",("unable to find table %s", ev->getTableName()));
4974
releaseTableGlobal(*tab, 0);
4980
ev->setTable(m_ndb.externalizeTableName(ev->getTableName()));
4981
// get the columns from the attrListBitmask
4982
NdbTableImpl &table = *ev->m_tableImpl;
4983
AttributeMask & mask = ev->m_attrListBitmask;
4984
unsigned attributeList_sz = mask.count();
4986
DBUG_PRINT("info",("Table: id: %d version: %d",
4987
table.m_id, table.m_version));
4989
if ((Uint32) table.m_id != ev->m_table_id ||
4990
table_version_major(table.m_version) !=
4991
table_version_major(ev->m_table_version))
4998
if ( attributeList_sz > (uint) table.getNoOfColumns() )
5001
DBUG_PRINT("error",("Invalid version, too many columns"));
5006
assert( (int)attributeList_sz <= table.getNoOfColumns() );
5007
for(unsigned id= 0; ev->m_columns.size() < attributeList_sz; id++) {
5008
if ( id >= (uint) table.getNoOfColumns())
5011
DBUG_PRINT("error",("Invalid version, column %d out of range", id));
5018
const NdbColumnImpl* col = table.getColumn(id);
5019
DBUG_PRINT("info",("column %d %s", id, col->getName()));
5020
NdbColumnImpl* new_col = new NdbColumnImpl;
5021
// Copy column definition
5023
ev->m_columns.push_back(new_col);
5028
// ev is main event and has been retrieved previously
5030
NdbDictionaryImpl::getBlobEvent(const NdbEventImpl& ev, uint col_no)
5032
DBUG_ENTER("NdbDictionaryImpl::getBlobEvent");
5033
DBUG_PRINT("enter", ("ev=%s col=%u", ev.m_name.c_str(), col_no));
5035
NdbTableImpl* tab = ev.m_tableImpl;
5036
assert(tab != NULL && col_no < tab->m_columns.size());
5037
NdbColumnImpl* col = tab->m_columns[col_no];
5038
assert(col != NULL && col->getBlobType() && col->getPartSize() != 0);
5039
NdbTableImpl* blob_tab = col->m_blobTable;
5040
assert(blob_tab != NULL);
5041
char bename[MAX_TAB_NAME_SIZE];
5042
NdbBlob::getBlobEventName(bename, &ev, col);
5044
NdbEventImpl* blob_ev = getEvent(bename, blob_tab);
5045
DBUG_RETURN(blob_ev);
5049
NdbDictInterface::execCREATE_EVNT_CONF(const NdbApiSignal * signal,
5050
const LinearSectionPtr ptr[3])
5052
DBUG_ENTER("NdbDictInterface::execCREATE_EVNT_CONF");
5055
m_tableData.clear();
5056
unsigned int len = signal->getLength() << 2;
5057
m_buffer.append((char *)&len, sizeof(len));
5058
m_buffer.append(signal->getDataPtr(), len);
5060
if (signal->m_noOfSections > 0) {
5061
m_buffer.append((char *)ptr[0].p, strlen((char *)ptr[0].p)+1);
5063
if (signal->m_noOfSections > 1)
5065
m_tableData.append(ptr[1].p, 4 * ptr[1].sz);
5068
const CreateEvntConf * const createEvntConf=
5069
CAST_CONSTPTR(CreateEvntConf, signal->getDataPtr());
5071
Uint32 subscriptionId = createEvntConf->getEventId();
5072
Uint32 subscriptionKey = createEvntConf->getEventKey();
5074
DBUG_PRINT("info",("nodeid=%d,subscriptionId=%d,subscriptionKey=%d",
5075
refToNode(signal->theSendersBlockRef),
5076
subscriptionId,subscriptionKey));
5077
m_impl->theWaiter.signal(NO_WAIT);
5082
NdbDictInterface::execCREATE_EVNT_REF(const NdbApiSignal * signal,
5083
const LinearSectionPtr ptr[3])
5085
DBUG_ENTER("NdbDictInterface::execCREATE_EVNT_REF");
5087
const CreateEvntRef* const ref=
5088
CAST_CONSTPTR(CreateEvntRef, signal->getDataPtr());
5089
m_error.code= ref->getErrorCode();
5090
DBUG_PRINT("error",("error=%d,line=%d,node=%d",ref->getErrorCode(),
5091
ref->getErrorLine(),ref->getErrorNode()));
5092
if (m_error.code == CreateEvntRef::NotMaster)
5093
m_masterNodeId = ref->getMasterNode();
5094
m_impl->theWaiter.signal(NO_WAIT);
5099
NdbDictInterface::execSUB_STOP_CONF(const NdbApiSignal * signal,
5100
const LinearSectionPtr ptr[3])
5102
DBUG_ENTER("NdbDictInterface::execSUB_STOP_CONF");
5103
const SubStopConf * const subStopConf=
5104
CAST_CONSTPTR(SubStopConf, signal->getDataPtr());
5106
Uint32 subscriptionId = subStopConf->subscriptionId;
5107
Uint32 subscriptionKey = subStopConf->subscriptionKey;
5108
Uint32 subscriberData = subStopConf->subscriberData;
5110
DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d",
5111
subscriptionId,subscriptionKey,subscriberData));
5115
if (SubStopConf::SignalLength >= SubStopConf::SignalLengthWithGci)
5117
gci_hi= subStopConf->gci_hi;
5118
gci_lo= subStopConf->gci_lo;
5121
m_buffer.grow(4 * 2); // 2 words
5122
Uint32* data = (Uint32*)m_buffer.get_data();
5126
m_impl->theWaiter.signal(NO_WAIT);
5131
NdbDictInterface::execSUB_STOP_REF(const NdbApiSignal * signal,
5132
const LinearSectionPtr ptr[3])
5134
DBUG_ENTER("NdbDictInterface::execSUB_STOP_REF");
5135
const SubStopRef * const subStopRef=
5136
CAST_CONSTPTR(SubStopRef, signal->getDataPtr());
5138
Uint32 subscriptionId = subStopRef->subscriptionId;
5139
Uint32 subscriptionKey = subStopRef->subscriptionKey;
5140
Uint32 subscriberData = subStopRef->subscriberData;
5141
m_error.code= subStopRef->errorCode;
5143
DBUG_PRINT("error",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d,error=%d",
5144
subscriptionId,subscriptionKey,subscriberData,m_error.code));
5145
if (m_error.code == SubStopRef::NotMaster &&
5146
signal->getLength() >= SubStopRef::SL_MasterNode)
5148
m_masterNodeId = subStopRef->m_masterNodeId;
5150
m_impl->theWaiter.signal(NO_WAIT);
5155
NdbDictInterface::execSUB_START_CONF(const NdbApiSignal * signal,
5156
const LinearSectionPtr ptr[3])
5158
DBUG_ENTER("NdbDictInterface::execSUB_START_CONF");
5159
const SubStartConf * const subStartConf=
5160
CAST_CONSTPTR(SubStartConf, signal->getDataPtr());
5162
Uint32 subscriptionId = subStartConf->subscriptionId;
5163
Uint32 subscriptionKey = subStartConf->subscriptionKey;
5164
SubscriptionData::Part part =
5165
(SubscriptionData::Part)subStartConf->part;
5166
Uint32 subscriberData = subStartConf->subscriberData;
5169
case SubscriptionData::MetaData: {
5170
DBUG_PRINT("error",("SubscriptionData::MetaData"));
5174
case SubscriptionData::TableData: {
5175
DBUG_PRINT("info",("SubscriptionData::TableData"));
5179
DBUG_PRINT("error",("wrong data"));
5185
if (signal->getLength() == SubStartConf::SignalLength)
5187
m_data.m_sub_start_conf.m_buckets = subStartConf->bucketCount;
5191
/* 6.3 <-> 7.0 upgrade
5192
* 6.3 doesn't send required bucketCount.
5193
* ~0 indicates no bucketCount received
5195
m_data.m_sub_start_conf.m_buckets = ~0;
5197
DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d",
5198
subscriptionId,subscriptionKey,subscriberData));
5199
m_impl->theWaiter.signal(NO_WAIT);
5204
NdbDictInterface::execSUB_START_REF(const NdbApiSignal * signal,
5205
const LinearSectionPtr ptr[3])
5207
DBUG_ENTER("NdbDictInterface::execSUB_START_REF");
5208
const SubStartRef * const subStartRef=
5209
CAST_CONSTPTR(SubStartRef, signal->getDataPtr());
5210
m_error.code= subStartRef->errorCode;
5211
if (m_error.code == SubStartRef::NotMaster)
5212
m_masterNodeId = subStartRef->m_masterNodeId;
5213
m_impl->theWaiter.signal(NO_WAIT);
5217
/*****************************************************************
5221
NdbDictionaryImpl::dropEvent(const char * eventName, int force)
5223
DBUG_ENTER("NdbDictionaryImpl::dropEvent");
5224
DBUG_PRINT("enter", ("name:%s force: %d", eventName, force));
5226
NdbEventImpl *evnt = NULL;
5229
evnt = getEvent(eventName); // allocated
5232
if (m_error.code != 723 && // no such table
5233
m_error.code != 241) // invalid table
5235
DBUG_PRINT("info", ("no table err=%d", m_error.code));
5238
DBUG_PRINT("info", ("no table err=%d, drop by name alone", m_error.code));
5243
evnt = new NdbEventImpl();
5244
evnt->setName(eventName);
5246
int ret = dropEvent(*evnt);
5252
NdbDictionaryImpl::dropEvent(const NdbEventImpl& evnt)
5254
if (dropBlobEvents(evnt) != 0)
5256
if (m_receiver.dropEvent(evnt) != 0)
5262
NdbDictionaryImpl::dropBlobEvents(const NdbEventImpl& evnt)
5264
DBUG_ENTER("NdbDictionaryImpl::dropBlobEvents");
5265
if (evnt.m_tableImpl != 0) {
5266
const NdbTableImpl& t = *evnt.m_tableImpl;
5267
Uint32 n = t.m_noOfBlobs;
5269
for (i = 0; i < evnt.m_columns.size() && n > 0; i++) {
5270
const NdbColumnImpl& c = *evnt.m_columns[i];
5271
if (! c.getBlobType() || c.getPartSize() == 0)
5274
NdbEventImpl* blob_evnt = getBlobEvent(evnt, i);
5275
if (blob_evnt == NULL)
5277
(void)dropEvent(*blob_evnt);
5283
DBUG_PRINT("info", ("no table definition, listing events"));
5284
char bename[MAX_TAB_NAME_SIZE];
5286
// XXX should get name from NdbBlob
5287
sprintf(bename, "NDB$BLOBEVENT_%s_%s", evnt.getName(), "%d");
5289
if (listEvents(list))
5291
for (unsigned i = 0; i < list.count; i++)
5293
NdbDictionary::Dictionary::List::Element& elt = list.elements[i];
5296
case NdbDictionary::Object::TableEvent:
5297
if (sscanf(elt.name, bename, &val) == 1)
5299
DBUG_PRINT("info", ("found blob event %s, removing...", elt.name));
5300
NdbEventImpl* bevnt = new NdbEventImpl();
5301
bevnt->setName(elt.name);
5302
(void)m_receiver.dropEvent(*bevnt);
5306
DBUG_PRINT("info", ("found event %s, skipping...", elt.name));
5317
NdbDictInterface::dropEvent(const NdbEventImpl &evnt)
5319
NdbApiSignal tSignal(m_reference);
5320
tSignal.theReceiversBlockNumber = DBDICT;
5321
tSignal.theVerId_signalNumber = GSN_DROP_EVNT_REQ;
5322
tSignal.theLength = DropEvntReq::SignalLength;
5324
DropEvntReq * const req = CAST_PTR(DropEvntReq, tSignal.getDataPtrSend());
5326
req->setUserRef(m_reference);
5327
req->setUserData(0);
5329
UtilBufferWriter w(m_buffer);
5331
w.add(SimpleProperties::StringValue, evnt.m_name.c_str());
5333
LinearSectionPtr ptr[1];
5334
ptr[0].p = (Uint32*)m_buffer.get_data();
5335
ptr[0].sz = (m_buffer.length()+3) >> 2;
5337
return dictSignal(&tSignal,ptr, 1,
5338
0 /*use masternode id*/,
5339
WAIT_CREATE_INDX_REQ,
5345
NdbDictInterface::execDROP_EVNT_CONF(const NdbApiSignal * signal,
5346
const LinearSectionPtr ptr[3])
5348
DBUG_ENTER("NdbDictInterface::execDROP_EVNT_CONF");
5349
m_impl->theWaiter.signal(NO_WAIT);
5354
NdbDictInterface::execDROP_EVNT_REF(const NdbApiSignal * signal,
5355
const LinearSectionPtr ptr[3])
5357
DBUG_ENTER("NdbDictInterface::execDROP_EVNT_REF");
5358
const DropEvntRef* const ref=
5359
CAST_CONSTPTR(DropEvntRef, signal->getDataPtr());
5360
m_error.code= ref->getErrorCode();
5362
DBUG_PRINT("info",("ErrorCode=%u Errorline=%u ErrorNode=%u",
5363
ref->getErrorCode(), ref->getErrorLine(), ref->getErrorNode()));
5364
if (m_error.code == DropEvntRef::NotMaster)
5365
m_masterNodeId = ref->getMasterNode();
5366
m_impl->theWaiter.signal(NO_WAIT);
5370
static int scanEventTable(Ndb* pNdb,
5371
const NdbDictionary::Table* pTab,
5372
NdbDictionary::Dictionary::List &list)
5374
int retryAttempt = 0;
5375
const int retryMax = 100;
5376
NdbTransaction *pTrans = NULL;
5377
NdbScanOperation *pOp = NULL;
5378
NdbRecAttr *event_name, *event_id;
5380
const Uint32 codeWords= 1;
5381
Uint32 codeSpace[ codeWords ];
5382
NdbInterpretedCode code(pTab,
5385
if ((code.interpret_exit_last_row() != 0) ||
5386
(code.finalise() != 0))
5388
return code.getNdbError().code;
5393
NdbDictionary::Dictionary::List tmp_list;
5397
if (retryAttempt >= retryMax)
5399
ndbout << "ERROR: has retried this operation " << retryAttempt
5400
<< " times, failing!" << endl;
5404
pNdb->closeTransaction(pTrans);
5405
NdbSleep_MilliSleep(50);
5408
pTrans = pNdb->startTransaction();
5411
if (pNdb->getNdbError().status == NdbError::TemporaryError)
5416
Uint64 row_count = 0;
5418
if ((pOp = pTrans->getNdbScanOperation(pTab)) == NULL)
5420
if (pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 1) != 0)
5422
if (pOp->setInterpretedCode(&code) != 0)
5426
pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&tmp);
5427
if (pTrans->execute(NdbTransaction::NoCommit) == -1)
5431
while ((eof = pOp->nextResult(true)) == 0)
5436
if (pTrans->getNdbError().status == NdbError::TemporaryError)
5442
if ((pOp = pTrans->getNdbScanOperation(pTab)) == NULL)
5445
if (pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 1) != 0)
5448
if ((event_id = pOp->getValue(6)) == 0 ||
5449
(event_name = pOp->getValue(0u)) == 0)
5452
if (pTrans->execute(NdbTransaction::NoCommit) == -1)
5454
const NdbError err = pTrans->getNdbError();
5455
if (err.status == NdbError::TemporaryError)
5460
/* Cannot handle > 2^32 yet (limit on tmp_list.count is unsigned int) */
5461
assert((row_count & 0xffffffff) == row_count);
5463
tmp_list.count = (unsigned int)row_count;
5465
new NdbDictionary::Dictionary::List::Element[(unsigned int)row_count];
5469
while((eof = pOp->nextResult()) == 0)
5471
if (rows < tmp_list.count)
5473
NdbDictionary::Dictionary::List::Element &el = tmp_list.elements[rows];
5474
el.id = event_id->u_32_value();
5475
el.type = NdbDictionary::Object::TableEvent;
5476
el.state = NdbDictionary::Object::StateOnline;
5477
el.store = NdbDictionary::Object::StorePermanent;
5478
Uint32 len = (Uint32)strlen(event_name->aRef());
5479
el.name = new char[len+1];
5480
memcpy(el.name, event_name->aRef(), len);
5487
if (pTrans->getNdbError().status == NdbError::TemporaryError)
5492
pNdb->closeTransaction(pTrans);
5494
if (rows < tmp_list.count)
5495
tmp_list.count = rows;
5499
tmp_list.elements = NULL;
5507
error_code = pTrans->getNdbError().code;
5508
pNdb->closeTransaction(pTrans);
5511
error_code = pNdb->getNdbError().code;
5517
NdbDictionaryImpl::listEvents(List& list)
5521
BaseString currentDb(m_ndb.getDatabaseName());
5522
BaseString currentSchema(m_ndb.getDatabaseSchemaName());
5524
m_ndb.setDatabaseName("sys");
5525
m_ndb.setDatabaseSchemaName("def");
5527
const NdbDictionary::Table* pTab =
5528
m_facade->getTableGlobal("NDB$EVENTS_0");
5531
error_code = m_facade->getNdbError().code;
5534
error_code = scanEventTable(&m_ndb, pTab, list);
5535
m_facade->removeTableGlobal(*pTab, 0);
5539
m_ndb.setDatabaseName(currentDb.c_str());
5540
m_ndb.setDatabaseSchemaName(currentSchema.c_str());
5543
m_error.code = error_code;
5549
/*****************************************************************
5550
* List objects or indexes
5553
NdbDictionaryImpl::listObjects(List& list,
5554
NdbDictionary::Object::Type type,
5555
bool fullyQualified)
5559
if (type == NdbDictionary::Object::TableEvent)
5560
return listEvents(list);
5562
if (type == NdbDictionary::Object::TypeUndefined)
5564
ret = listEvents(list2);
5572
req.setTableType(getKernelConstant(type, objectTypeMapping, 0));
5573
req.setListNames(true);
5575
return m_receiver.listObjects(list, req, fullyQualified);
5576
ret = m_receiver.listObjects(list1, req, fullyQualified);
5579
list.count = list1.count + list2.count;
5580
list.elements = new NdbDictionary::Dictionary::List::Element[list.count];
5582
const NdbDictionary::Dictionary::List::Element null_el;
5583
for (i = 0; i < list1.count; i++)
5585
NdbDictionary::Dictionary::List::Element &el = list1.elements[i];
5586
list.elements[i] = el;
5589
for (i = 0; i < list2.count; i++)
5591
NdbDictionary::Dictionary::List::Element &el = list2.elements[i];
5592
list.elements[i + list1.count] = el;
5599
NdbDictionaryImpl::listIndexes(List& list, Uint32 indexId)
5603
req.setTableId(indexId);
5604
req.setTableType(0);
5605
req.setListNames(true);
5606
req.setListIndexes(true);
5607
return m_receiver.listObjects(list, req, m_ndb.usingFullyQualifiedNames());
5611
NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list,
5612
ListTablesReq& ltreq, bool fullyQualifiedNames)
5614
bool listTablesLongSignal = false;
5615
NdbApiSignal tSignal(m_reference);
5616
ListTablesReq* const req = CAST_PTR(ListTablesReq, tSignal.getDataPtrSend());
5617
memcpy(req, <req, sizeof(ListTablesReq));
5618
req->senderRef = m_reference;
5619
req->senderData = 0;
5620
if (ltreq.getTableId() > 4096)
5623
Enforce new long signal format,
5624
if this is not supported by the
5625
called node the request will fail
5627
listTablesLongSignal = true;
5631
Set table id and type according to old format
5632
in case sent to old nodes (during upgrade).
5634
req->oldSetTableId(ltreq.getTableId());
5635
req->oldSetTableType(ltreq.getTableType());
5637
tSignal.theReceiversBlockNumber = DBDICT;
5638
tSignal.theVerId_signalNumber = GSN_LIST_TABLES_REQ;
5639
tSignal.theLength = ListTablesReq::SignalLength;
5640
if (listObjects(&tSignal, listTablesLongSignal) != 0)
5643
if (listTablesLongSignal)
5645
return unpackListTables(list, fullyQualifiedNames);
5649
return unpackOldListTables(list, fullyQualifiedNames);
5654
NdbDictInterface::unpackListTables(NdbDictionary::Dictionary::List& list,
5655
bool fullyQualifiedNames)
5658
Uint32* tableData = (Uint32*)m_tableData.get_data();
5659
Uint32* tableNames = (Uint32*)m_tableNames.get_data();
5660
const Uint32 listTablesDataSizeInWords = (sizeof(ListTablesData) + 3) / 4;
5661
list.count = m_noOfTables;
5662
list.elements = new NdbDictionary::Dictionary::List::Element[m_noOfTables];
5664
while (count < m_noOfTables)
5666
NdbDictionary::Dictionary::List::Element& element = list.elements[count];
5667
ListTablesData _ltd;
5668
ListTablesData * ltd = &_ltd;
5669
memcpy(ltd, tableData, 4 * listTablesDataSizeInWords);
5670
tableData += listTablesDataSizeInWords;
5671
element.id = ltd->getTableId();
5672
element.type = (NdbDictionary::Object::Type)
5673
getApiConstant(ltd->getTableType(), objectTypeMapping, 0);
5674
element.state = (NdbDictionary::Object::State)
5675
getApiConstant(ltd->getTableState(), objectStateMapping, 0);
5676
element.store = (NdbDictionary::Object::Store)
5677
getApiConstant(ltd->getTableStore(), objectStoreMapping, 0);
5678
element.temp = ltd->getTableTemp();
5679
// table or index name
5680
BaseString databaseName;
5681
BaseString schemaName;
5682
BaseString objectName;
5683
if (!databaseName || !schemaName || !objectName)
5688
Uint32 size = tableNames[0];
5689
Uint32 wsize = (size + 3) / 4;
5691
if ((element.type == NdbDictionary::Object::UniqueHashIndex) ||
5692
(element.type == NdbDictionary::Object::OrderedIndex)) {
5693
char * indexName = new char[size];
5694
if (indexName == NULL)
5699
memcpy(indexName, (char *) tableNames, size);
5700
if (!(databaseName = Ndb::getDatabaseFromInternalName(indexName)) ||
5701
!(schemaName = Ndb::getSchemaFromInternalName(indexName)))
5703
delete [] indexName;
5707
objectName = BaseString(Ndb::externalizeIndexName(indexName,
5708
fullyQualifiedNames));
5709
delete [] indexName;
5710
} else if ((element.type == NdbDictionary::Object::SystemTable) ||
5711
(element.type == NdbDictionary::Object::UserTable)) {
5712
char * tableName = new char[size];
5713
if (tableName == NULL)
5718
memcpy(tableName, (char *) tableNames, size);
5719
if (!(databaseName = Ndb::getDatabaseFromInternalName(tableName)) ||
5720
!(schemaName = Ndb::getSchemaFromInternalName(tableName)))
5722
delete [] tableName;
5726
objectName = BaseString(Ndb::externalizeTableName(tableName,
5727
fullyQualifiedNames));
5728
delete [] tableName;
5731
char * otherName = new char[size];
5732
if (otherName == NULL)
5737
memcpy(otherName, (char *) tableNames, size);
5738
if (!(objectName = BaseString(otherName)))
5743
delete [] otherName;
5745
if (!(element.database = new char[databaseName.length() + 1]) ||
5746
!(element.schema = new char[schemaName.length() + 1]) ||
5747
!(element.name = new char[objectName.length() + 1]))
5752
strcpy(element.database, databaseName.c_str());
5753
strcpy(element.schema, schemaName.c_str());
5754
strcpy(element.name, objectName.c_str());
5756
tableNames += wsize;
5763
NdbDictInterface::unpackOldListTables(NdbDictionary::Dictionary::List& list,
5764
bool fullyQualifiedNames)
5767
const Uint32* data = (const Uint32*)m_buffer.get_data();
5768
const unsigned length = m_buffer.length() / 4;
5771
unsigned pos, count;
5773
while (pos < length) {
5774
// table id - name length - name
5776
if (pos >= length) {
5780
Uint32 n = (data[pos++] + 3) >> 2;
5794
list.elements = new NdbDictionary::Dictionary::List::Element[count];
5796
while (pos < length) {
5797
NdbDictionary::Dictionary::List::Element& element = list.elements[count];
5798
Uint32 d = data[pos++];
5799
element.id = OldListTablesConf::getTableId(d);
5800
element.type = (NdbDictionary::Object::Type)
5801
getApiConstant(OldListTablesConf::getTableType(d), objectTypeMapping, 0);
5802
element.state = (NdbDictionary::Object::State)
5803
getApiConstant(OldListTablesConf::getTableState(d), objectStateMapping, 0);
5804
element.store = (NdbDictionary::Object::Store)
5805
getApiConstant(OldListTablesConf::getTableStore(d), objectStoreMapping, 0);
5806
element.temp = OldListTablesConf::getTableTemp(d);
5807
// table or index name
5808
Uint32 n = (data[pos++] + 3) >> 2;
5809
BaseString databaseName;
5810
BaseString schemaName;
5811
BaseString objectName;
5812
if (!databaseName || !schemaName || !objectName)
5817
if ((element.type == NdbDictionary::Object::UniqueHashIndex) ||
5818
(element.type == NdbDictionary::Object::OrderedIndex)) {
5819
char * indexName = new char[n << 2];
5820
if (indexName == NULL)
5825
memcpy(indexName, &data[pos], n << 2);
5826
if (!(databaseName = Ndb::getDatabaseFromInternalName(indexName)) ||
5827
!(schemaName = Ndb::getSchemaFromInternalName(indexName)))
5829
delete [] indexName;
5833
objectName = BaseString(Ndb::externalizeIndexName(indexName, fullyQualifiedNames));
5834
delete [] indexName;
5835
} else if ((element.type == NdbDictionary::Object::SystemTable) ||
5836
(element.type == NdbDictionary::Object::UserTable)) {
5837
char * tableName = new char[n << 2];
5838
if (tableName == NULL)
5843
memcpy(tableName, &data[pos], n << 2);
5844
if (!(databaseName = Ndb::getDatabaseFromInternalName(tableName)) ||
5845
!(schemaName = Ndb::getSchemaFromInternalName(tableName)))
5847
delete [] tableName;
5851
objectName = BaseString(Ndb::externalizeTableName(tableName, fullyQualifiedNames));
5852
delete [] tableName;
5855
char * otherName = new char[n << 2];
5856
if (otherName == NULL)
5861
memcpy(otherName, &data[pos], n << 2);
5862
if (!(objectName = BaseString(otherName)))
5867
delete [] otherName;
5869
if (!(element.database = new char[databaseName.length() + 1]) ||
5870
!(element.schema = new char[schemaName.length() + 1]) ||
5871
!(element.name = new char[objectName.length() + 1]))
5876
strcpy(element.database, databaseName.c_str());
5877
strcpy(element.schema, schemaName.c_str());
5878
strcpy(element.name, objectName.c_str());
5886
NdbDictInterface::listObjects(NdbApiSignal* signal,
5887
bool& listTablesLongSignal)
5889
const Uint32 RETRIES = 100;
5890
for (Uint32 i = 0; i < RETRIES; i++) {
5894
The PollGuard has an implicit call of unlock_and_signal through the
5895
~PollGuard method. This method is called implicitly by the compiler
5896
in all places where the object is out of context due to a return,
5897
break, continue or simply end of statement block
5899
PollGuard poll_guard(* m_impl);
5900
Uint16 aNodeId = getTransporter()->get_an_alive_node();
5905
NodeInfo info = m_impl->getNodeInfo(aNodeId).m_info;
5906
if (ndbd_LIST_TABLES_CONF_long_signal(info.m_version))
5909
Called node will return a long signal
5911
listTablesLongSignal = true;
5913
else if (listTablesLongSignal)
5916
We are requesting info from a table with table id > 4096
5917
and older versions don't support that, bug#36044
5923
if (m_impl->sendSignal(signal, aNodeId) != 0) {
5926
m_impl->incClientStat(Ndb::WaitMetaRequestCount, 1);
5928
int ret_val= poll_guard.wait_n_unlock(DICT_WAITFOR_TIMEOUT,
5929
aNodeId, WAIT_LIST_TABLES_CONF,
5932
if (ret_val == 0 && m_error.code == 0)
5934
if (ret_val == -2) //WAIT_NODE_FAILURE
5942
NdbDictInterface::execLIST_TABLES_CONF(const NdbApiSignal* signal,
5943
const LinearSectionPtr ptr[3])
5945
Uint16 nodeId = refToNode(signal->theSendersBlockRef);
5946
NodeInfo info = m_impl->getNodeInfo(nodeId).m_info;
5947
if (!ndbd_LIST_TABLES_CONF_long_signal(info.m_version))
5950
Sender doesn't support new signal format
5952
NdbDictInterface::execOLD_LIST_TABLES_CONF(signal, ptr);
5956
if (signal->isFirstFragment())
5958
m_fragmentId = signal->getFragmentId();
5960
m_tableData.clear();
5961
m_tableNames.clear();
5965
if (m_fragmentId != signal->getFragmentId())
5974
const ListTablesConf* const conf=
5975
CAST_CONSTPTR(ListTablesConf, signal->getDataPtr());
5976
m_noOfTables+= conf->noOfTables;
5978
bool fragmented = signal->isFragmented();
5979
Uint32 sigLen = signal->getLength() - 1;
5980
const Uint32 secs = signal->m_noOfSections;
5981
const Uint32 directMap[3] = {0,1,2};
5982
const Uint32 * const secNos =
5984
&signal->getDataPtr()[sigLen - secs]
5985
: (const Uint32 *) &directMap;
5987
for(Uint32 i = 0; i<secs; i++)
5989
Uint32 sectionNo = secNos[i];
5990
switch (sectionNo) {
5991
case(ListTablesConf::TABLE_DATA):
5992
if (m_tableData.append(ptr[i].p, 4 * ptr[i].sz))
5998
case(ListTablesConf::TABLE_NAMES):
5999
if (m_tableNames.append(ptr[i].p, 4 * ptr[i].sz))
6011
if(!signal->isLastFragment()){
6015
m_impl->theWaiter.signal(NO_WAIT);
6020
NdbDictInterface::execOLD_LIST_TABLES_CONF(const NdbApiSignal* signal,
6021
const LinearSectionPtr ptr[3])
6023
const unsigned off = OldListTablesConf::HeaderLength;
6024
const unsigned len = (signal->getLength() - off);
6025
if (m_buffer.append(signal->getDataPtr() + off, len << 2))
6029
if (signal->getLength() < OldListTablesConf::SignalLength) {
6030
// last signal has less than full length
6031
m_impl->theWaiter.signal(NO_WAIT);
6036
NdbDictionaryImpl::forceGCPWait(int type)
6038
return m_receiver.forceGCPWait(type);
6042
NdbDictInterface::forceGCPWait(int type)
6044
NdbApiSignal tSignal(m_reference);
6045
if (type == 0 || type == 2)
6047
WaitGCPReq* const req = CAST_PTR(WaitGCPReq, tSignal.getDataPtrSend());
6048
req->senderRef = m_reference;
6049
req->senderData = 0;
6052
WaitGCPReq::CompleteForceStart : WaitGCPReq::RestartGCI;
6054
tSignal.theReceiversBlockNumber = DBDIH;
6055
tSignal.theVerId_signalNumber = GSN_WAIT_GCP_REQ;
6056
tSignal.theLength = WaitGCPReq::SignalLength;
6058
const Uint32 RETRIES = 100;
6059
for (Uint32 i = 0; i < RETRIES; i++)
6061
PollGuard pg(* m_impl);
6062
Uint16 aNodeId = getTransporter()->get_an_alive_node();
6067
if (m_impl->sendSignal(&tSignal, aNodeId) != 0)
6074
m_impl->incClientStat(Ndb::WaitMetaRequestCount, 1);
6075
int ret_val= pg.wait_n_unlock(DICT_WAITFOR_TIMEOUT,
6076
aNodeId, WAIT_LIST_TABLES_CONF);
6078
if (ret_val == 0 && m_error.code == 0)
6080
if (ret_val == -2) //WAIT_NODE_FAILURE
6088
tSignal.getDataPtrSend()[0] = 6099;
6089
tSignal.theReceiversBlockNumber = DBDIH;
6090
tSignal.theVerId_signalNumber = GSN_DUMP_STATE_ORD;
6091
tSignal.theLength = 1;
6093
const Uint32 RETRIES = 100;
6094
for (Uint32 i = 0; i < RETRIES; i++)
6097
Uint16 aNodeId = getTransporter()->get_an_alive_node();
6103
if (m_impl->sendSignal(&tSignal, aNodeId) != 0) {
6108
m_impl->do_forceSend();
6111
return m_error.code == 0 ? 0 : -1;
6115
m_error.code = 4003;
6121
NdbDictionaryImpl::getRestartGCI(Uint32 * gci)
6123
int res = m_receiver.forceGCPWait(2);
6124
if (res == 0 && gci != 0)
6126
* gci = m_receiver.m_data.m_wait_gcp_conf.gci_hi;
6132
NdbDictInterface::execWAIT_GCP_CONF(const NdbApiSignal* signal,
6133
const LinearSectionPtr ptr[3])
6135
const WaitGCPConf* conf = CAST_CONSTPTR(WaitGCPConf, signal->getDataPtr());
6137
m_data.m_wait_gcp_conf.gci_lo = conf->gci_lo;
6138
m_data.m_wait_gcp_conf.gci_hi = conf->gci_hi;
6139
m_impl->theWaiter.signal(NO_WAIT);
6143
NdbDictInterface::execWAIT_GCP_REF(const NdbApiSignal* signal,
6144
const LinearSectionPtr ptr[3])
6146
const WaitGCPRef* ref = CAST_CONSTPTR(WaitGCPRef, signal->getDataPtr());
6147
m_error.code = ref->errorCode;
6149
m_impl->theWaiter.signal(NO_WAIT);
6152
NdbFilegroupImpl::NdbFilegroupImpl(NdbDictionary::Object::Type t)
6153
: NdbDictObjectImpl(t)
6156
m_undo_buffer_size = 0;
6157
m_logfile_group_id = RNIL;
6158
m_logfile_group_version = ~0;
6161
NdbTablespaceImpl::NdbTablespaceImpl() :
6162
NdbDictionary::Tablespace(* this),
6163
NdbFilegroupImpl(NdbDictionary::Object::Tablespace), m_facade(this)
6167
NdbTablespaceImpl::NdbTablespaceImpl(NdbDictionary::Tablespace & f) :
6168
NdbDictionary::Tablespace(* this),
6169
NdbFilegroupImpl(NdbDictionary::Object::Tablespace), m_facade(&f)
6173
NdbTablespaceImpl::~NdbTablespaceImpl(){
6177
NdbTablespaceImpl::assign(const NdbTablespaceImpl& org)
6180
m_version = org.m_version;
6181
m_status = org.m_status;
6182
m_type = org.m_type;
6184
if (!m_name.assign(org.m_name))
6186
m_grow_spec = org.m_grow_spec;
6187
m_extent_size = org.m_extent_size;
6188
m_undo_free_words = org.m_undo_free_words;
6189
m_logfile_group_id = org.m_logfile_group_id;
6190
m_logfile_group_version = org.m_logfile_group_version;
6191
if (!m_logfile_group_name.assign(org.m_logfile_group_name))
6193
m_undo_free_words = org.m_undo_free_words;
6197
NdbLogfileGroupImpl::NdbLogfileGroupImpl() :
6198
NdbDictionary::LogfileGroup(* this),
6199
NdbFilegroupImpl(NdbDictionary::Object::LogfileGroup), m_facade(this)
6203
NdbLogfileGroupImpl::NdbLogfileGroupImpl(NdbDictionary::LogfileGroup & f) :
6204
NdbDictionary::LogfileGroup(* this),
6205
NdbFilegroupImpl(NdbDictionary::Object::LogfileGroup), m_facade(&f)
6209
NdbLogfileGroupImpl::~NdbLogfileGroupImpl(){
6213
NdbLogfileGroupImpl::assign(const NdbLogfileGroupImpl& org)
6216
m_version = org.m_version;
6217
m_status = org.m_status;
6218
m_type = org.m_type;
6220
if (!m_name.assign(org.m_name))
6222
m_grow_spec = org.m_grow_spec;
6223
m_extent_size = org.m_extent_size;
6224
m_undo_free_words = org.m_undo_free_words;
6225
m_logfile_group_id = org.m_logfile_group_id;
6226
m_logfile_group_version = org.m_logfile_group_version;
6227
if (!m_logfile_group_name.assign(org.m_logfile_group_name))
6229
m_undo_free_words = org.m_undo_free_words;
6233
NdbFileImpl::NdbFileImpl(NdbDictionary::Object::Type t)
6234
: NdbDictObjectImpl(t)
6238
m_filegroup_id = RNIL;
6239
m_filegroup_version = ~0;
6242
NdbDatafileImpl::NdbDatafileImpl() :
6243
NdbDictionary::Datafile(* this),
6244
NdbFileImpl(NdbDictionary::Object::Datafile), m_facade(this)
6248
NdbDatafileImpl::NdbDatafileImpl(NdbDictionary::Datafile & f) :
6249
NdbDictionary::Datafile(* this),
6250
NdbFileImpl(NdbDictionary::Object::Datafile), m_facade(&f)
6254
NdbDatafileImpl::~NdbDatafileImpl(){
6258
NdbDatafileImpl::assign(const NdbDatafileImpl& org)
6261
m_version = org.m_version;
6262
m_status = org.m_status;
6263
m_type = org.m_type;
6265
m_size = org.m_size;
6266
m_free = org.m_free;
6267
m_filegroup_id = org.m_filegroup_id;
6268
m_filegroup_version = org.m_filegroup_version;
6269
if (!m_path.assign(org.m_path) ||
6270
!m_filegroup_name.assign(org.m_filegroup_name))
6275
NdbUndofileImpl::NdbUndofileImpl() :
6276
NdbDictionary::Undofile(* this),
6277
NdbFileImpl(NdbDictionary::Object::Undofile), m_facade(this)
6281
NdbUndofileImpl::NdbUndofileImpl(NdbDictionary::Undofile & f) :
6282
NdbDictionary::Undofile(* this),
6283
NdbFileImpl(NdbDictionary::Object::Undofile), m_facade(&f)
6287
NdbUndofileImpl::~NdbUndofileImpl(){
6291
NdbUndofileImpl::assign(const NdbUndofileImpl& org)
6294
m_version = org.m_version;
6295
m_status = org.m_status;
6296
m_type = org.m_type;
6298
m_size = org.m_size;
6299
m_free = org.m_free;
6300
m_filegroup_id = org.m_filegroup_id;
6301
m_filegroup_version = org.m_filegroup_version;
6302
if (!m_path.assign(org.m_path) ||
6303
!m_filegroup_name.assign(org.m_filegroup_name))
6309
NdbDictionaryImpl::createDatafile(const NdbDatafileImpl & file,
6311
NdbDictObjectImpl* obj)
6314
DBUG_ENTER("NdbDictionaryImpl::createDatafile");
6315
NdbFilegroupImpl tmp(NdbDictionary::Object::Tablespace);
6316
if(file.m_filegroup_version != ~(Uint32)0){
6317
tmp.m_id = file.m_filegroup_id;
6318
tmp.m_version = file.m_filegroup_version;
6319
DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
6323
if(m_receiver.get_filegroup(tmp, NdbDictionary::Object::Tablespace,
6324
file.m_filegroup_name.c_str()) == 0){
6325
DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
6331
NdbDictionaryImpl::dropDatafile(const NdbDatafileImpl & file){
6332
return m_receiver.drop_file(file);
6336
NdbDictionaryImpl::createUndofile(const NdbUndofileImpl & file,
6338
NdbDictObjectImpl* obj)
6340
DBUG_ENTER("NdbDictionaryImpl::createUndofile");
6341
NdbFilegroupImpl tmp(NdbDictionary::Object::LogfileGroup);
6342
if(file.m_filegroup_version != ~(Uint32)0){
6343
tmp.m_id = file.m_filegroup_id;
6344
tmp.m_version = file.m_filegroup_version;
6345
DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
6349
if(m_receiver.get_filegroup(tmp, NdbDictionary::Object::LogfileGroup,
6350
file.m_filegroup_name.c_str()) == 0){
6351
DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
6353
DBUG_PRINT("info", ("Failed to find filegroup"));
6359
NdbDictionaryImpl::dropUndofile(const NdbUndofileImpl & file)
6361
return m_receiver.drop_file(file);
6365
NdbDictionaryImpl::createTablespace(const NdbTablespaceImpl & fg,
6366
NdbDictObjectImpl* obj)
6368
return m_receiver.create_filegroup(fg, obj);
6372
NdbDictionaryImpl::dropTablespace(const NdbTablespaceImpl & fg)
6374
return m_receiver.drop_filegroup(fg);
6378
NdbDictionaryImpl::createLogfileGroup(const NdbLogfileGroupImpl & fg,
6379
NdbDictObjectImpl* obj)
6381
return m_receiver.create_filegroup(fg, obj);
6385
NdbDictionaryImpl::dropLogfileGroup(const NdbLogfileGroupImpl & fg)
6387
return m_receiver.drop_filegroup(fg);
6391
cmp_ndbrec_attr(const void *a, const void *b)
6393
const NdbRecord::Attr *r1= (const NdbRecord::Attr *)a;
6394
const NdbRecord::Attr *r2= (const NdbRecord::Attr *)b;
6395
if(r1->attrId < r2->attrId)
6397
else if(r1->attrId == r2->attrId)
6404
Uint64 start; /* First occupied bit */
6405
Uint64 end; /* Last occupied bit */
6409
cmp_bitrange(const void* a, const void* b)
6411
/* Sort them by start bit */
6412
const BitRange& brA= *(const BitRange*)a;
6413
const BitRange& brB= *(const BitRange*)b;
6415
if (brA.start < brB.start)
6417
else if (brA.start == brB.start)
6424
NdbDictionaryImpl::validateRecordSpec(const NdbDictionary::RecordSpecification *recSpec,
6428
/* We check that there's no overlap between any of the data values
6432
/* Column data + NULL bits with at least 1 non nullable PK */
6433
const Uint32 MaxRecordElements= (2* NDB_MAX_ATTRIBUTES_IN_TABLE) - 1;
6434
Uint32 numElements= 0;
6435
BitRange bitRanges[ MaxRecordElements ];
6437
if (length > NDB_MAX_ATTRIBUTES_IN_TABLE)
6443
/* Populate bitRanges array with ranges of bits occupied by
6444
* data values and null bits
6446
for (Uint32 rs=0; rs < length; rs++)
6448
const NdbDictionary::Column* col= recSpec[rs].column;
6449
Uint64 elementByteOffset= recSpec[rs].offset;
6450
Uint64 elementByteLength= col->getSizeInBytes();
6451
Uint64 nullLength= col->getNullable() ? 1 : 0;
6453
/* Blobs 'data' just occupies the size of an NdbBlob ptr */
6454
const NdbDictionary::Column::Type type= col->getType();
6456
(type == NdbDictionary::Column::Blob) ||
6457
(type == NdbDictionary::Column::Text);
6461
elementByteLength= sizeof(NdbBlob*);
6464
if ((type == NdbDictionary::Column::Bit) &&
6465
(flags & NdbDictionary::RecMysqldBitfield))
6467
/* MySQLD Bit format puts 'fractional' part of bit types
6468
* in with the null bits - so there's 1 optional Null
6469
* bit followed by n (max 7) databits, at position
6470
* given by the nullbit offsets. Then the rest of
6471
* the bytes go at the normal offset position.
6473
Uint32 bitLength= col->getLength();
6474
Uint32 fractionalBits= bitLength % 8;
6475
nullLength+= fractionalBits;
6476
elementByteLength= bitLength / 8;
6479
/* Does the element itself have any bytes?
6480
* (MySQLD bit format may have all data as 'null bits'
6482
if (elementByteLength)
6484
bitRanges[numElements].start= 8 * elementByteOffset;
6485
bitRanges[numElements].end= (8 * (elementByteOffset + elementByteLength)) - 1;
6492
bitRanges[numElements].start=
6493
(8* recSpec[rs].nullbit_byte_offset) +
6494
recSpec[rs].nullbit_bit_in_byte;
6495
bitRanges[numElements].end= bitRanges[numElements].start +
6502
/* Now sort the 'elements' by start bit */
6508
Uint64 endOfPreviousRange= bitRanges[0].end;
6510
/* Now check that there's no overlaps */
6511
for (Uint32 rangeNum= 1; rangeNum < numElements; rangeNum++)
6513
if (unlikely((bitRanges[rangeNum].start <= endOfPreviousRange)))
6515
/* Oops, this range overlaps with previous one */
6519
endOfPreviousRange= bitRanges[rangeNum].end;
6522
/* All relevant ranges are distinct */
6527
/* ndb_set_record_specification
6528
* This procedure sets the contents of the passed RecordSpecification
6529
* for the given column in the given table.
6530
* The column is placed at the storageOffset given, and a new
6531
* storageOffset, beyond the end of this column, is returned.
6532
* Null bits are stored at the start of the row in consecutive positions.
6533
* The caller must ensure that enough space exists for all of the nullable
6534
* columns, before the first bit of data.
6535
* The new storageOffset is returned.
6538
ndb_set_record_specification(Uint32 storageOffset,
6540
Uint32& nullableColNum,
6541
NdbDictionary::RecordSpecification *spec,
6544
spec->column= col->m_facade;
6546
spec->offset= storageOffset;
6547
/* For Blobs we just need the NdbBlob* */
6548
const Uint32 sizeOfElement= col->getBlobType() ?
6550
spec->column->getSizeInBytes();
6552
if (spec->column->getNullable())
6554
spec->nullbit_byte_offset= (nullableColNum >> 3);
6555
spec->nullbit_bit_in_byte= (nullableColNum & 7);
6560
/* For non-nullable columns, use visibly bad offsets */
6561
spec->nullbit_byte_offset= ~0;
6562
spec->nullbit_bit_in_byte= ~0;
6565
return storageOffset + sizeOfElement;
6569
/* This method creates an NdbRecord for the given table or index which
6570
* contains all columns (except pseudo columns).
6571
* For a table, only the tableOrIndex parameter should be supplied.
6572
* For an index, the index 'table object' should be supplied as the
6573
* tableOrIndex parameter, and the underlying indexed table object
6574
* should be supplied as the baseTableForIndex parameter.
6575
* The underlying table object is required to get the correct column
6576
* objects to build the NdbRecord object.
6577
* The record is created with all null bits packed together starting
6578
* from the first word, in attrId order, followed by all attributes
6579
* in attribute order.
6582
NdbDictionaryImpl::createDefaultNdbRecord(NdbTableImpl *tableOrIndex,
6583
const NdbTableImpl *baseTableForIndex)
6585
/* We create a full NdbRecord for the columns in the table
6587
DBUG_ENTER("NdbDictionaryImpl::createNdbRecords()");
6588
NdbDictionary::RecordSpecification spec[NDB_MAX_ATTRIBUTES_IN_TABLE];
6591
Uint32 numCols= tableOrIndex->m_columns.size();
6592
// Reserve space for Null bits at the start
6593
Uint32 baseTabCols= numCols;
6594
unsigned char* pkMask= NULL;
6595
bool isIndex= false;
6597
if (baseTableForIndex != NULL)
6599
/* Check we've really got an index */
6600
assert((tableOrIndex->m_indexType == NdbDictionary::Object::OrderedIndex ||
6601
tableOrIndex->m_indexType == NdbDictionary::Object::UniqueHashIndex));
6603
/* Update baseTabCols to real number of cols in indexed table */
6604
baseTabCols= baseTableForIndex->m_columns.size();
6606
/* Ignore extra info column at end of index table */
6611
// Could do further string checks to make sure the base table and
6612
// index are related
6616
/* Check we've not got an index */
6617
assert((tableOrIndex->m_indexType != NdbDictionary::Object::OrderedIndex &&
6618
tableOrIndex->m_indexType != NdbDictionary::Object::UniqueHashIndex));
6621
Uint32 nullableCols= 0;
6622
/* Determine number of nullable columns */
6623
for (i=0; i<numCols; i++)
6625
/* As the Index NdbRecord is built using Columns from the base table,
6626
* it will get/set Null according to their Nullability.
6627
* If this is an index, then we need to take the 'Nullability' from
6628
* the base table column objects - unique index table column objects
6629
* will not be nullable as they are part of the key.
6631
const NdbColumnImpl* col= NULL;
6635
Uint32 baseTableColNum=
6636
tableOrIndex->m_index->m_columns[i]->m_keyInfoPos;
6637
col= baseTableForIndex->m_columns[baseTableColNum];
6641
col= tableOrIndex->m_columns[i];
6644
if (col->m_nullable)
6648
/* Offset of first byte of data in the NdbRecord */
6649
Uint32 offset= (nullableCols+7) / 8;
6651
/* Allocate and zero column presence bitmasks */
6652
Uint32 bitMaskBytes= (baseTabCols + 7) / 8;
6653
pkMask= (unsigned char*) calloc(1, bitMaskBytes);
6657
/* Memory allocation problem */
6662
Uint32 nullableColNum= 0;
6664
/* Build record specification array for this table. */
6665
for (i= 0; i < numCols; i++)
6667
/* Have to use columns from 'real' table for indexes as described
6668
* in NdbRecord documentation
6670
NdbColumnImpl *col= NULL;
6674
/* From index table, get m_index pointer to NdbIndexImpl object.
6675
* m_index has m_key_ids[] array mapping index column numbers to
6676
* real table column numbers.
6677
* Use this number to get the correct column object from the
6678
* base table structure
6679
* No need to worry about Blobs here as Blob columns can't be
6682
Uint32 baseTableColNum=
6683
tableOrIndex->m_index->m_columns[i]->m_keyInfoPos;
6684
col= baseTableForIndex->m_columns[baseTableColNum];
6686
/* Set pk bitmask bit based on the base-table col number of this
6689
assert( baseTableColNum < baseTabCols);
6690
pkMask[ baseTableColNum >> 3 ] |= ( 1 << ( baseTableColNum & 7 ));
6694
col= tableOrIndex->m_columns[i];
6698
/* Set pk bitmask bit based on the col number of this column */
6699
pkMask[ i >> 3 ] |= ( 1 << (i & 7));
6702
/* If this column's a Blob then we need to create
6703
* a default NdbRecord for the Blob table too
6704
* (unless it's a really small one with no parts table).
6706
if (col->getBlobType() && col->getPartSize() != 0)
6708
if (likely(col->m_blobTable != NULL))
6710
int res= createDefaultNdbRecord(col->m_blobTable, NULL);
6719
if (!ignore_broken_blob_tables())
6722
/* 4263 - Invalid blob attributes or invalid blob parts table */
6723
m_error.code = 4263;
6731
offset= ndb_set_record_specification(offset,
6738
rec= createRecord(tableOrIndex,
6742
0, // No special flags
6743
true); // default record
6750
/* Store in the table definition */
6751
tableOrIndex->m_ndbrecord= rec;
6752
tableOrIndex->m_pkMask= pkMask;
6757
/* This method initialises the data for a single
6758
* column in the passed NdbRecord structure
6761
NdbDictionaryImpl::initialiseColumnData(bool isIndex,
6763
const NdbDictionary::RecordSpecification *recSpec,
6767
const NdbColumnImpl *col= &NdbColumnImpl::getImpl(*(recSpec->column));
6770
// Missing column specification in NdbDictionary::RecordSpecification
6775
if (col->m_attrId & AttributeHeader::PSEUDO)
6777
/* Pseudo columns not supported by NdbRecord */
6782
if (col->m_indexSourced)
6784
// Attempt to pass an index column to createRecord...
6789
NdbRecord::Attr *recCol= &rec->columns[colNum];
6790
recCol->attrId= col->m_attrId;
6791
recCol->column_no= col->m_column_no;
6792
recCol->index_attrId= ~0;
6793
recCol->offset= recSpec->offset;
6794
recCol->maxSize= col->m_attrSize*col->m_arraySize;
6795
recCol->orgAttrSize= col->m_orgAttrSize;
6796
if (recCol->offset+recCol->maxSize > rec->m_row_size)
6797
rec->m_row_size= recCol->offset+recCol->maxSize;
6798
/* Round data size to whole words + 4 bytes of AttributeHeader. */
6799
rec->m_max_transid_ai_bytes+= (recCol->maxSize+7) & ~3;
6800
recCol->charset_info= col->m_cs;
6801
recCol->compare_function= NdbSqlUtil::getType(col->m_type).m_cmp;
6803
if (!isIndex && col->m_pk)
6804
recCol->flags|= NdbRecord::IsKey;
6805
/* For indexes, we set key membership below. */
6806
if (col->m_storageType == NDB_STORAGETYPE_DISK)
6807
recCol->flags|= NdbRecord::IsDisk;
6808
if (col->m_nullable)
6810
recCol->flags|= NdbRecord::IsNullable;
6811
recCol->nullbit_byte_offset= recSpec->nullbit_byte_offset;
6812
recCol->nullbit_bit_in_byte= recSpec->nullbit_bit_in_byte;
6814
const Uint32 nullbit_byte= recSpec->nullbit_byte_offset +
6815
(recSpec->nullbit_bit_in_byte >> 3);
6816
if (nullbit_byte >= rec->m_row_size)
6817
rec->m_row_size= nullbit_byte + 1;
6819
if (col->m_arrayType==NDB_ARRAYTYPE_SHORT_VAR)
6821
recCol->flags|= NdbRecord::IsVar1ByteLen;
6822
if (flags & NdbDictionary::RecMysqldShrinkVarchar)
6823
recCol->flags|= NdbRecord::IsMysqldShrinkVarchar;
6825
else if (col->m_arrayType==NDB_ARRAYTYPE_MEDIUM_VAR)
6827
recCol->flags|= NdbRecord::IsVar2ByteLen;
6829
if (col->m_type == NdbDictionary::Column::Bit)
6831
recCol->bitCount= col->m_length;
6832
if (flags & NdbDictionary::RecMysqldBitfield)
6834
recCol->flags|= NdbRecord::IsMysqldBitfield;
6835
if (!(col->m_nullable))
6838
We need these to access the overflow bits stored within
6841
recCol->nullbit_byte_offset= recSpec->nullbit_byte_offset;
6842
recCol->nullbit_bit_in_byte= recSpec->nullbit_bit_in_byte;
6847
recCol->bitCount= 0;
6848
if (col->m_distributionKey)
6849
recCol->flags|= NdbRecord::IsDistributionKey;
6850
if (col->getBlobType())
6852
recCol->flags|= NdbRecord::IsBlob;
6853
rec->flags|= NdbRecord::RecHasBlob;
6860
* Create an NdbRecord object using the table implementation and
6861
* RecordSpecification array passed.
6862
* The table pointer may be a proper table, or the underlying
6863
* table of an Index. In any case, it is assumed that is is a
6864
* global table object, which may be safely shared between
6865
* multiple threads. The responsibility for ensuring that it is
6866
* a global object rests with the caller
6869
NdbDictionaryImpl::createRecord(const NdbTableImpl *table,
6870
const NdbDictionary::RecordSpecification *recSpec,
6876
NdbRecord *rec= NULL;
6877
Uint32 numKeys, tableNumKeys, numIndexDistrKeys, min_distkey_prefix_length;
6883
In later versions we can use elemSize to provide backwards
6884
compatibility if we extend the RecordSpecification structure.
6886
if (elemSize != sizeof(NdbDictionary::RecordSpecification))
6892
if (!validateRecordSpec(recSpec, length, flags))
6894
/* Error set in call */
6898
isIndex= (table->m_indexType==NdbDictionary::Object::OrderedIndex ||
6899
table->m_indexType==NdbDictionary::Object::UniqueHashIndex);
6901
/* Count the number of key columns in the table or index. */
6904
assert(table->m_index);
6905
/* Ignore the extra NDB$TNODE column at the end. */
6906
tableNumKeys= table->m_columns.size() - 1;
6911
for (i= 0; i<table->m_columns.size(); i++)
6913
if (table->m_columns[i]->m_pk)
6917
Uint32 tableNumDistKeys;
6918
if (isIndex || table->m_noOfDistributionKeys != 0)
6919
tableNumDistKeys= table->m_noOfDistributionKeys;
6921
tableNumDistKeys= table->m_noOfKeys;
6923
int max_attrId = -1;
6924
for (i = 0; i < length; i++)
6926
Uint32 attrId = recSpec[i].column->getAttrId();
6927
if ((int)attrId > max_attrId)
6928
max_attrId = (int)attrId;
6930
Uint32 attrId_indexes_length = (Uint32)(max_attrId + 1);
6933
We need to allocate space for
6934
1. The struct itself.
6935
2. The columns[] array at the end of struct (length #columns).
6936
3. An extra Uint32 array key_indexes (length #key columns).
6937
4. An extra Uint32 array distkey_indexes (length #distribution keys).
6938
5. An extra int array attrId_indexes (length max attrId)
6940
const Uint32 ndbRecBytes= sizeof(NdbRecord);
6941
const Uint32 colArrayBytes= (length-1)*sizeof(NdbRecord::Attr);
6942
const Uint32 tableKeyMapBytes= tableNumKeys*sizeof(Uint32);
6943
const Uint32 tableDistKeyMapBytes= tableNumDistKeys*sizeof(Uint32);
6944
const Uint32 attrIdMapBytes= attrId_indexes_length*sizeof(int);
6945
rec= (NdbRecord *)calloc(1, ndbRecBytes +
6948
tableDistKeyMapBytes +
6955
Uint32 *key_indexes= (Uint32 *)((unsigned char *)rec +
6958
Uint32 *distkey_indexes= (Uint32 *)((unsigned char *)rec +
6962
int *attrId_indexes = (int *)((unsigned char *)rec +
6966
tableDistKeyMapBytes);
6967
for (i = 0; i < attrId_indexes_length; i++)
6968
attrId_indexes[i] = -1;
6971
rec->tableId= table->m_id;
6972
rec->tableVersion= table->m_version;
6974
rec->noOfColumns= length;
6975
rec->m_no_of_distribution_keys= tableNumDistKeys;
6977
/* Check for any blobs in the base table. */
6978
for (i= 0; i<table->m_columns.size(); i++)
6980
if (table->m_columns[i]->getBlobType())
6982
rec->flags|= NdbRecord::RecTableHasBlob;
6988
rec->m_max_transid_ai_bytes= 0;
6989
for (i= 0; i<length; i++)
6991
const NdbDictionary::RecordSpecification *rs= &recSpec[i];
6993
/* Initialise this column in NdbRecord from column
6996
if (initialiseColumnData(isIndex,
7004
Distibution key flag for unique index needs to be corrected
7005
to reflect the keys in the index base table
7007
if (table->m_indexType == NdbDictionary::Object::UniqueHashIndex)
7009
NdbRecord::Attr *recCol= &rec->columns[i];
7010
if (table->m_columns[i]->m_distributionKey)
7011
recCol->flags|= NdbRecord::IsDistributionKey;
7013
recCol->flags&= ~NdbRecord::IsDistributionKey;
7017
/* Now we sort the array in attrId order. */
7020
sizeof(rec->columns[0]),
7024
Now check for the presence of primary keys, and set flags for whether
7025
this NdbRecord can be used for insert and/or for specifying keys for
7028
Also test for duplicate columns, easy now that they are sorted.
7029
Also set up key_indexes array.
7030
Also compute if an index includes all of the distribution key.
7031
Also set up distkey_indexes array.
7036
min_distkey_prefix_length= 0;
7037
numIndexDistrKeys= 0;
7038
for (i= 0; i<rec->noOfColumns; i++)
7040
NdbRecord::Attr *recCol= &rec->columns[i];
7041
if (i > 0 && oldAttrId==recCol->attrId)
7046
oldAttrId= recCol->attrId;
7048
assert(recCol->attrId < attrId_indexes_length);
7049
attrId_indexes[recCol->attrId] = i;
7053
Uint32 colNo= recCol->column_no;
7055
if (colNo < table->m_index->m_key_ids.size() &&
7056
(key_idx= table->m_index->m_key_ids[colNo]) != -1)
7058
assert((Uint32)key_idx < tableNumKeys);
7059
recCol->flags|= NdbRecord::IsKey;
7060
key_indexes[key_idx]= i;
7061
recCol->index_attrId= table->m_columns[key_idx]->m_attrId;
7064
if (recCol->flags & NdbRecord::IsDistributionKey)
7066
if (min_distkey_prefix_length <= (Uint32)key_idx)
7067
min_distkey_prefix_length= key_idx+1;
7068
if (numIndexDistrKeys < tableNumDistKeys)
7069
distkey_indexes[numIndexDistrKeys++]= i;
7075
if (recCol->flags & NdbRecord::IsKey)
7077
key_indexes[numKeys]= i;
7080
if (recCol->flags & NdbRecord::IsDistributionKey)
7082
if (numIndexDistrKeys < tableNumDistKeys)
7083
distkey_indexes[numIndexDistrKeys++]= i;
7088
rec->flags|= NdbRecord::RecIsDefaultRec;
7090
rec->key_indexes= key_indexes;
7091
rec->key_index_length= tableNumKeys;
7092
rec->m_min_distkey_prefix_length= min_distkey_prefix_length;
7093
rec->distkey_indexes= distkey_indexes;
7094
rec->distkey_index_length= numIndexDistrKeys;
7095
rec->m_attrId_indexes = attrId_indexes;
7096
rec->m_attrId_indexes_length = attrId_indexes_length;
7099
Since we checked for duplicates, we can check for primary key completeness
7102
if (numKeys == tableNumKeys)
7104
rec->flags|= NdbRecord::RecHasAllKeys;
7105
if (rec->noOfColumns == tableNumKeys)
7106
rec->flags|= NdbRecord::RecIsKeyRecord;
7109
rec->flags|= NdbRecord::RecIsIndex;
7110
rec->m_keyLenInWords= table->m_keyLenInWords;
7112
if (table->m_fragmentType == NdbDictionary::Object::UserDefined)
7113
rec->flags |= NdbRecord::RecHasUserDefinedPartitioning;
7124
NdbRecord::copyMask(Uint32 *dst, const unsigned char *src) const
7128
BitmaskImpl::clear((NDB_MAX_ATTRIBUTES_IN_TABLE+31)>>5, dst);
7131
for (i= 0; i<noOfColumns; i++)
7133
Uint32 attrId= columns[i].attrId;
7135
assert(!(attrId & AttributeHeader::PSEUDO));
7137
if (src[attrId>>3] & (1 << (attrId&7)))
7138
BitmaskImpl::set((NDB_MAX_ATTRIBUTES_IN_TABLE+31)>>5, dst, attrId);
7143
for (i= 0; i<noOfColumns; i++)
7145
Uint32 attrId= columns[i].attrId;
7147
assert(!(attrId & AttributeHeader::PSEUDO));
7149
BitmaskImpl::set((NDB_MAX_ATTRIBUTES_IN_TABLE+31)>>5, dst, attrId);
7155
NdbRecord::Attr::get_mysqld_bitfield(const char *src_row, char *dst_buffer) const
7157
assert(flags & IsMysqldBitfield);
7159
Uint32 remaining_bits= bitCount;
7160
Uint32 fractional_bitcount= remaining_bits % 8;
7162
/* Copy fractional bits, if any. */
7163
if (fractional_bitcount > 0)
7165
Uint32 fractional_shift= nullbit_bit_in_byte + ((flags & IsNullable) != 0);
7166
Uint32 fractional_bits= (unsigned char)(src_row[nullbit_byte_offset]);
7167
if (fractional_shift + fractional_bitcount > 8)
7168
fractional_bits|= (unsigned char)(src_row[nullbit_byte_offset+1]) << 8;
7170
(fractional_bits >> fractional_shift) & ((1 << fractional_bitcount) - 1);
7171
bits= fractional_bits;
7176
/* Copy whole bytes. The mysqld format stored bit fields big-endian. */
7177
assert(remaining_bits <= 64);
7178
const unsigned char *src_ptr= (const unsigned char *)&src_row[offset];
7179
while (remaining_bits >= 8)
7181
bits= (bits << 8) | (*src_ptr++);
7185
Uint32 small_bits= (Uint32)bits;
7186
memcpy(dst_buffer, &small_bits, 4);
7189
small_bits= (Uint32)(bits >> 32);
7190
memcpy(dst_buffer+4, &small_bits, 4);
7195
NdbRecord::Attr::put_mysqld_bitfield(char *dst_row, const char *src_buffer) const
7197
assert(flags & IsMysqldBitfield);
7198
char *dst_ptr= &dst_row[offset];
7201
memcpy(&small_bits, src_buffer, 4);
7205
memcpy(&small_bits, src_buffer+4, 4);
7206
bits|= ((Uint64)small_bits) << 32;
7209
/* Copy whole bytes. The mysqld format stores bitfields big-endian. */
7210
Uint32 remaining_bits= bitCount;
7211
assert(remaining_bits <= 64);
7212
dst_ptr+= remaining_bits/8;
7213
while (remaining_bits >= 8)
7215
*--dst_ptr= (char)(bits & 0xff);
7220
/* Copy fractional bits, if any. */
7221
if (remaining_bits > 0)
7223
Uint32 shift= nullbit_bit_in_byte + ((flags & IsNullable) != 0);
7224
Uint32 mask= ((1 << remaining_bits) - 1) << shift;
7225
bits= (bits << shift) & mask;
7226
dst_row[nullbit_byte_offset]=
7227
Uint8((dst_row[nullbit_byte_offset] & ~mask) | bits);
7228
if (shift + remaining_bits > 8)
7232
dst_row[nullbit_byte_offset+1]=
7233
Uint8((dst_row[nullbit_byte_offset+1] & ~mask) | bits);
7238
void NdbDictionaryImpl::releaseRecord_impl(NdbRecord *rec)
7242
/* Silently do nothing if they've passed the default
7243
* record in (similar to null handling behaviour)
7245
if (!(rec->flags & NdbRecord::RecIsDefaultRec))
7247
/* For non-default records, we need to release the
7248
* global table / index reference
7250
if (rec->flags & NdbRecord::RecIsIndex)
7251
releaseIndexGlobal(*rec->table->m_index,
7252
false); // Don't invalidate
7254
releaseTableGlobal(*rec->table,
7255
false); // Don't invalidate
7262
NdbDictionary::RecordType
7263
NdbDictionaryImpl::getRecordType(const NdbRecord* record)
7265
if (record->flags & NdbRecord::RecIsIndex)
7266
return NdbDictionary::IndexAccess;
7268
return NdbDictionary::TableAccess;
7272
NdbDictionaryImpl::getRecordTableName(const NdbRecord* record)
7274
if (!(record->flags & NdbRecord::RecIsIndex))
7276
return record->table->m_externalName.c_str();
7283
NdbDictionaryImpl::getRecordIndexName(const NdbRecord* record)
7285
if (record->flags & NdbRecord::RecIsIndex)
7287
assert(record->table->m_index != NULL);
7288
assert(record->table->m_index->m_facade != NULL);
7290
return record->table->m_index->m_externalName.c_str();
7297
NdbDictionaryImpl::getNextAttrIdFrom(const NdbRecord* record,
7301
for (Uint32 i= startAttrId; i < record->m_attrId_indexes_length; i++)
7303
if (record->m_attrId_indexes[i] != -1)
7313
NdbDictionaryImpl::getOffset(const NdbRecord* record,
7317
if (attrId < record->m_attrId_indexes_length)
7319
int attrIdIndex= record->m_attrId_indexes[attrId];
7321
if (attrIdIndex != -1)
7323
assert(attrIdIndex < (int) record->noOfColumns);
7325
offset= record->columns[attrIdIndex].offset;
7330
/* AttrId not part of this NdbRecord */
7335
NdbDictionaryImpl::getNullBitOffset(const NdbRecord* record,
7337
Uint32& nullbit_byte_offset,
7338
Uint32& nullbit_bit_in_byte)
7340
if (attrId < record->m_attrId_indexes_length)
7342
int attrIdIndex= record->m_attrId_indexes[attrId];
7344
if (attrIdIndex != -1)
7346
assert(attrIdIndex < (int) record->noOfColumns);
7348
NdbRecord::Attr attr= record->columns[attrIdIndex];
7350
nullbit_byte_offset= attr.nullbit_byte_offset;
7351
nullbit_bit_in_byte= attr.nullbit_bit_in_byte;
7356
/* AttrId not part of this NdbRecord */
7361
NdbDictionaryImpl::getValuePtr(const NdbRecord* record,
7365
if (attrId < record->m_attrId_indexes_length)
7367
int attrIdIndex= record->m_attrId_indexes[attrId];
7369
if (attrIdIndex != -1)
7371
assert(attrIdIndex < (int) record->noOfColumns);
7373
return row + (record->columns[attrIdIndex].offset);
7377
/* AttrId not part of this NdbRecord */
7382
NdbDictionaryImpl::getValuePtr(const NdbRecord* record,
7386
if (attrId < record->m_attrId_indexes_length)
7388
int attrIdIndex= record->m_attrId_indexes[attrId];
7390
if (attrIdIndex != -1)
7392
assert(attrIdIndex < (int)record->noOfColumns);
7394
return row + (record->columns[attrIdIndex].offset);
7398
/* AttrId not part of this NdbRecord */
7403
NdbDictionaryImpl::isNull(const NdbRecord* record,
7407
if (attrId < record->m_attrId_indexes_length)
7409
int attrIdIndex= record->m_attrId_indexes[attrId];
7411
if (attrIdIndex != -1)
7413
assert(attrIdIndex < (int)record->noOfColumns);
7414
return record->columns[attrIdIndex].is_null(row);
7418
/* AttrId not part of this NdbRecord or is not nullable */
7423
NdbDictionaryImpl::setNull(const NdbRecord* record,
7428
if (attrId < record->m_attrId_indexes_length)
7430
int attrIdIndex= record->m_attrId_indexes[attrId];
7432
if (attrIdIndex != -1)
7434
assert(attrIdIndex < (int)record->noOfColumns);
7435
NdbRecord::Attr attr= record->columns[attrIdIndex];
7437
if (attr.flags & NdbRecord::IsNullable)
7440
*(row + attr.nullbit_byte_offset) |=
7441
(1 << attr.nullbit_bit_in_byte);
7443
*(row + attr.nullbit_byte_offset) &=
7444
~(1 << attr.nullbit_bit_in_byte);
7451
/* AttrId not part of this NdbRecord or is not nullable */
7456
NdbDictionaryImpl::getRecordRowLength(const NdbRecord* record)
7458
return record->m_row_size;
7464
NdbDictInterface::create_file(const NdbFileImpl & file,
7465
const NdbFilegroupImpl & group,
7467
NdbDictObjectImpl* obj)
7469
DBUG_ENTER("NdbDictInterface::create_file");
7470
UtilBufferWriter w(m_buffer);
7471
DictFilegroupInfo::File f; f.init();
7472
BaseString::snprintf(f.FileName, sizeof(f.FileName), "%s", file.m_path.c_str());
7473
f.FileType = file.m_type;
7474
f.FilegroupId = group.m_id;
7475
f.FilegroupVersion = group.m_version;
7476
f.FileSizeHi = (Uint32)(file.m_size >> 32);
7477
f.FileSizeLo = (Uint32)(file.m_size & 0xFFFFFFFF);
7479
SimpleProperties::UnpackStatus s;
7480
s = SimpleProperties::pack(w,
7482
DictFilegroupInfo::FileMapping,
7483
DictFilegroupInfo::FileMappingSize, true);
7485
if(s != SimpleProperties::Eof){
7489
NdbApiSignal tSignal(m_reference);
7490
tSignal.theReceiversBlockNumber = DBDICT;
7491
tSignal.theVerId_signalNumber = GSN_CREATE_FILE_REQ;
7492
tSignal.theLength = CreateFileReq::SignalLength;
7494
CreateFileReq* req = CAST_PTR(CreateFileReq, tSignal.getDataPtrSend());
7495
req->senderRef = m_reference;
7496
req->senderData = 0;
7497
req->objType = file.m_type;
7498
req->requestInfo = 0;
7500
req->requestInfo |= CreateFileReq::ForceCreateFile;
7501
req->requestInfo |= m_tx.requestFlags();
7502
req->transId = m_tx.transId();
7503
req->transKey = m_tx.transKey();
7505
LinearSectionPtr ptr[3];
7506
ptr[0].p = (Uint32*)m_buffer.get_data();
7507
ptr[0].sz = m_buffer.length() / 4;
7509
int err[] = { CreateFileRef::Busy, CreateFileRef::NotMaster, 0};
7511
Send signal without time-out since creating files can take a very long
7512
time if the file is very big.
7514
int ret = dictSignal(&tSignal, ptr, 1,
7516
WAIT_CREATE_INDX_REQ,
7522
Uint32* data = (Uint32*)m_buffer.get_data();
7525
obj->m_id = data[0];
7526
obj->m_version = data[1];
7529
DBUG_PRINT("info", ("warning flags: 0x%x", m_warn));
7536
NdbDictInterface::execCREATE_FILE_CONF(const NdbApiSignal * signal,
7537
const LinearSectionPtr ptr[3])
7539
const CreateFileConf* conf=
7540
CAST_CONSTPTR(CreateFileConf, signal->getDataPtr());
7541
m_buffer.grow(4 * 3); // 3 words
7542
Uint32* data = (Uint32*)m_buffer.get_data();
7543
data[0] = conf->fileId;
7544
data[1] = conf->fileVersion;
7545
data[2] = conf->warningFlags;
7547
m_impl->theWaiter.signal(NO_WAIT);
7551
NdbDictInterface::execCREATE_FILE_REF(const NdbApiSignal * signal,
7552
const LinearSectionPtr ptr[3])
7554
const CreateFileRef* ref =
7555
CAST_CONSTPTR(CreateFileRef, signal->getDataPtr());
7556
m_error.code = ref->errorCode;
7557
m_masterNodeId = ref->masterNodeId;
7558
m_impl->theWaiter.signal(NO_WAIT);
7562
NdbDictInterface::drop_file(const NdbFileImpl & file)
7564
DBUG_ENTER("NdbDictInterface::drop_file");
7565
NdbApiSignal tSignal(m_reference);
7566
tSignal.theReceiversBlockNumber = DBDICT;
7567
tSignal.theVerId_signalNumber = GSN_DROP_FILE_REQ;
7568
tSignal.theLength = DropFileReq::SignalLength;
7570
DropFileReq* req = CAST_PTR(DropFileReq, tSignal.getDataPtrSend());
7571
req->senderRef = m_reference;
7572
req->senderData = 0;
7573
req->file_id = file.m_id;
7574
req->file_version = file.m_version;
7575
req->requestInfo = 0;
7576
req->requestInfo |= m_tx.requestFlags();
7577
req->transId = m_tx.transId();
7578
req->transKey = m_tx.transKey();
7580
int err[] = { DropFileRef::Busy, DropFileRef::NotMaster, 0};
7581
DBUG_RETURN(dictSignal(&tSignal, 0, 0,
7583
WAIT_CREATE_INDX_REQ,
7584
DICT_WAITFOR_TIMEOUT, 100,
7589
NdbDictInterface::execDROP_FILE_CONF(const NdbApiSignal * signal,
7590
const LinearSectionPtr ptr[3])
7592
m_impl->theWaiter.signal(NO_WAIT);
7596
NdbDictInterface::execDROP_FILE_REF(const NdbApiSignal * signal,
7597
const LinearSectionPtr ptr[3])
7599
const DropFileRef* ref =
7600
CAST_CONSTPTR(DropFileRef, signal->getDataPtr());
7601
m_error.code = ref->errorCode;
7602
m_masterNodeId = ref->masterNodeId;
7603
m_impl->theWaiter.signal(NO_WAIT);
7607
NdbDictInterface::create_filegroup(const NdbFilegroupImpl & group,
7608
NdbDictObjectImpl* obj)
7610
DBUG_ENTER("NdbDictInterface::create_filegroup");
7611
UtilBufferWriter w(m_buffer);
7612
DictFilegroupInfo::Filegroup fg; fg.init();
7613
BaseString::snprintf(fg.FilegroupName, sizeof(fg.FilegroupName),
7614
"%s", group.m_name.c_str());
7615
switch(group.m_type){
7616
case NdbDictionary::Object::Tablespace:
7618
fg.FilegroupType = DictTabInfo::Tablespace;
7619
//fg.TS_DataGrow = group.m_grow_spec;
7620
fg.TS_ExtentSize = group.m_extent_size;
7622
if(group.m_logfile_group_version != ~(Uint32)0)
7624
fg.TS_LogfileGroupId = group.m_logfile_group_id;
7625
fg.TS_LogfileGroupVersion = group.m_logfile_group_version;
7629
NdbLogfileGroupImpl tmp;
7630
if(get_filegroup(tmp, NdbDictionary::Object::LogfileGroup,
7631
group.m_logfile_group_name.c_str()) == 0)
7633
fg.TS_LogfileGroupId = tmp.m_id;
7634
fg.TS_LogfileGroupVersion = tmp.m_version;
7636
else // error set by get filegroup
7643
case NdbDictionary::Object::LogfileGroup:
7644
fg.LF_UndoBufferSize = group.m_undo_buffer_size;
7645
fg.FilegroupType = DictTabInfo::LogfileGroup;
7646
//fg.LF_UndoGrow = group.m_grow_spec;
7653
SimpleProperties::UnpackStatus s;
7654
s = SimpleProperties::pack(w,
7656
DictFilegroupInfo::Mapping,
7657
DictFilegroupInfo::MappingSize, true);
7659
if(s != SimpleProperties::Eof){
7663
NdbApiSignal tSignal(m_reference);
7664
tSignal.theReceiversBlockNumber = DBDICT;
7665
tSignal.theVerId_signalNumber = GSN_CREATE_FILEGROUP_REQ;
7666
tSignal.theLength = CreateFilegroupReq::SignalLength;
7668
CreateFilegroupReq* req =
7669
CAST_PTR(CreateFilegroupReq, tSignal.getDataPtrSend());
7670
req->senderRef = m_reference;
7671
req->senderData = 0;
7672
req->objType = fg.FilegroupType;
7673
req->requestInfo = 0;
7674
req->requestInfo |= m_tx.requestFlags();
7675
req->transId = m_tx.transId();
7676
req->transKey = m_tx.transKey();
7678
LinearSectionPtr ptr[3];
7679
ptr[0].p = (Uint32*)m_buffer.get_data();
7680
ptr[0].sz = m_buffer.length() / 4;
7682
int err[] = { CreateFilegroupRef::Busy, CreateFilegroupRef::NotMaster, 0};
7683
int ret = dictSignal(&tSignal, ptr, 1,
7685
WAIT_CREATE_INDX_REQ,
7686
DICT_WAITFOR_TIMEOUT, 100,
7691
Uint32* data = (Uint32*)m_buffer.get_data();
7694
obj->m_id = data[0];
7695
obj->m_version = data[1];
7698
DBUG_PRINT("info", ("warning flags: 0x%x", m_warn));
7705
NdbDictInterface::execCREATE_FILEGROUP_CONF(const NdbApiSignal * signal,
7706
const LinearSectionPtr ptr[3])
7708
const CreateFilegroupConf* conf=
7709
CAST_CONSTPTR(CreateFilegroupConf, signal->getDataPtr());
7710
m_buffer.grow(4 * 3); // 3 words
7711
Uint32* data = (Uint32*)m_buffer.get_data();
7712
data[0] = conf->filegroupId;
7713
data[1] = conf->filegroupVersion;
7714
data[2] = conf->warningFlags;
7715
m_impl->theWaiter.signal(NO_WAIT);
7719
NdbDictInterface::execCREATE_FILEGROUP_REF(const NdbApiSignal * signal,
7720
const LinearSectionPtr ptr[3])
7722
const CreateFilegroupRef* ref =
7723
CAST_CONSTPTR(CreateFilegroupRef, signal->getDataPtr());
7724
m_error.code = ref->errorCode;
7725
m_masterNodeId = ref->masterNodeId;
7726
m_impl->theWaiter.signal(NO_WAIT);
7730
NdbDictInterface::drop_filegroup(const NdbFilegroupImpl & group)
7732
DBUG_ENTER("NdbDictInterface::drop_filegroup");
7733
NdbApiSignal tSignal(m_reference);
7734
tSignal.theReceiversBlockNumber = DBDICT;
7735
tSignal.theVerId_signalNumber = GSN_DROP_FILEGROUP_REQ;
7736
tSignal.theLength = DropFilegroupReq::SignalLength;
7738
DropFilegroupReq* req = CAST_PTR(DropFilegroupReq, tSignal.getDataPtrSend());
7739
req->senderRef = m_reference;
7740
req->senderData = 0;
7741
req->filegroup_id = group.m_id;
7742
req->filegroup_version = group.m_version;
7743
req->requestInfo = 0;
7744
req->requestInfo |= m_tx.requestFlags();
7745
req->transId = m_tx.transId();
7746
req->transKey = m_tx.transKey();
7748
int err[] = { DropFilegroupRef::Busy, DropFilegroupRef::NotMaster, 0};
7749
DBUG_RETURN(dictSignal(&tSignal, 0, 0,
7751
WAIT_CREATE_INDX_REQ,
7752
DICT_WAITFOR_TIMEOUT, 100,
7757
NdbDictInterface::execDROP_FILEGROUP_CONF(const NdbApiSignal * signal,
7758
const LinearSectionPtr ptr[3])
7760
m_impl->theWaiter.signal(NO_WAIT);
7764
NdbDictInterface::execDROP_FILEGROUP_REF(const NdbApiSignal * signal,
7765
const LinearSectionPtr ptr[3])
7767
const DropFilegroupRef* ref =
7768
CAST_CONSTPTR(DropFilegroupRef, signal->getDataPtr());
7769
m_error.code = ref->errorCode;
7770
m_masterNodeId = ref->masterNodeId;
7771
m_impl->theWaiter.signal(NO_WAIT);
7776
NdbDictInterface::get_filegroup(NdbFilegroupImpl & dst,
7777
NdbDictionary::Object::Type type,
7779
DBUG_ENTER("NdbDictInterface::get_filegroup");
7780
NdbApiSignal tSignal(m_reference);
7781
GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
7783
Uint32 strLen = (Uint32)strlen(name) + 1;
7785
req->senderRef = m_reference;
7786
req->senderData = 0;
7788
GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
7789
req->tableNameLen = strLen;
7790
req->schemaTransId = m_tx.transId();
7791
tSignal.theReceiversBlockNumber = DBDICT;
7792
tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
7793
tSignal.theLength = GetTabInfoReq::SignalLength;
7795
LinearSectionPtr ptr[1];
7796
ptr[0].p = (Uint32*)name;
7797
ptr[0].sz = (strLen + 3)/4;
7799
#ifndef IGNORE_VALGRIND_WARNINGS
7804
m_buffer.append(name, strLen);
7805
m_buffer.append(&pad, 4);
7806
ptr[0].p = (Uint32*)m_buffer.get_data();
7810
int r = dictSignal(&tSignal, ptr, 1,
7812
WAIT_GET_TAB_INFO_REQ,
7813
DICT_WAITFOR_TIMEOUT, 100);
7819
DBUG_PRINT("info", ("get_filegroup failed dictSignal"));
7823
m_error.code = parseFilegroupInfo(dst,
7824
(Uint32*)m_buffer.get_data(),
7825
m_buffer.length() / 4);
7829
DBUG_PRINT("info", ("get_filegroup failed parseFilegroupInfo %d",
7831
DBUG_RETURN(m_error.code);
7834
if(dst.m_type == NdbDictionary::Object::Tablespace)
7836
NdbDictionary::LogfileGroup tmp;
7837
get_filegroup(NdbLogfileGroupImpl::getImpl(tmp),
7838
NdbDictionary::Object::LogfileGroup,
7839
dst.m_logfile_group_id);
7840
if (!dst.m_logfile_group_name.assign(tmp.getName()))
7841
DBUG_RETURN(m_error.code = 4000);
7844
if(dst.m_type == type)
7848
DBUG_PRINT("info", ("get_filegroup failed no such filegroup"));
7849
DBUG_RETURN(m_error.code = GetTabInfoRef::TableNotDefined);
7853
NdbDictInterface::parseFilegroupInfo(NdbFilegroupImpl &dst,
7854
const Uint32 * data, Uint32 len)
7857
SimplePropertiesLinearReader it(data, len);
7859
SimpleProperties::UnpackStatus status;
7860
DictFilegroupInfo::Filegroup fg; fg.init();
7861
status = SimpleProperties::unpack(it, &fg,
7862
DictFilegroupInfo::Mapping,
7863
DictFilegroupInfo::MappingSize,
7866
if(status != SimpleProperties::Eof){
7867
return CreateFilegroupRef::InvalidFormat;
7870
dst.m_id = fg.FilegroupId;
7871
dst.m_version = fg.FilegroupVersion;
7872
dst.m_type = (NdbDictionary::Object::Type)fg.FilegroupType;
7873
dst.m_status = NdbDictionary::Object::Retrieved;
7875
if (!dst.m_name.assign(fg.FilegroupName))
7877
dst.m_extent_size = fg.TS_ExtentSize;
7878
dst.m_undo_buffer_size = fg.LF_UndoBufferSize;
7879
dst.m_logfile_group_id = fg.TS_LogfileGroupId;
7880
dst.m_logfile_group_version = fg.TS_LogfileGroupVersion;
7881
dst.m_undo_free_words= ((Uint64)fg.LF_UndoFreeWordsHi << 32)
7882
| (fg.LF_UndoFreeWordsLo);
7888
NdbDictInterface::get_filegroup(NdbFilegroupImpl & dst,
7889
NdbDictionary::Object::Type type,
7891
DBUG_ENTER("NdbDictInterface::get_filegroup");
7892
NdbApiSignal tSignal(m_reference);
7893
GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
7895
req->senderRef = m_reference;
7896
req->senderData = 0;
7898
GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
7900
req->schemaTransId = m_tx.transId();
7901
tSignal.theReceiversBlockNumber = DBDICT;
7902
tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
7903
tSignal.theLength = GetTabInfoReq::SignalLength;
7905
int r = dictSignal(&tSignal, NULL, 1,
7907
WAIT_GET_TAB_INFO_REQ,
7908
DICT_WAITFOR_TIMEOUT, 100);
7911
DBUG_PRINT("info", ("get_filegroup failed dictSignal"));
7915
m_error.code = parseFilegroupInfo(dst,
7916
(Uint32*)m_buffer.get_data(),
7917
m_buffer.length() / 4);
7921
DBUG_PRINT("info", ("get_filegroup failed parseFilegroupInfo %d",
7923
DBUG_RETURN(m_error.code);
7926
if(dst.m_type == type)
7930
DBUG_PRINT("info", ("get_filegroup failed no such filegroup"));
7931
DBUG_RETURN(m_error.code = GetTabInfoRef::TableNotDefined);
7935
NdbDictInterface::get_file(NdbFileImpl & dst,
7936
NdbDictionary::Object::Type type,
7939
DBUG_ENTER("NdbDictInterface::get_file");
7940
NdbApiSignal tSignal(m_reference);
7941
GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
7943
Uint32 strLen = (Uint32)strlen(name) + 1;
7945
req->senderRef = m_reference;
7946
req->senderData = 0;
7948
GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
7949
req->tableNameLen = strLen;
7950
req->schemaTransId = m_tx.transId();
7951
tSignal.theReceiversBlockNumber = DBDICT;
7952
tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
7953
tSignal.theLength = GetTabInfoReq::SignalLength;
7955
LinearSectionPtr ptr[1];
7956
ptr[0].p = (Uint32*)name;
7957
ptr[0].sz = (strLen + 3)/4;
7959
#ifndef IGNORE_VALGRIND_WARNINGS
7964
m_buffer.append(name, strLen);
7965
m_buffer.append(&pad, 4);
7966
ptr[0].p = (Uint32*)m_buffer.get_data();
7970
int r = dictSignal(&tSignal, ptr, 1,
7972
WAIT_GET_TAB_INFO_REQ,
7973
DICT_WAITFOR_TIMEOUT, 100);
7976
DBUG_PRINT("info", ("get_file failed dictSignal"));
7980
m_error.code = parseFileInfo(dst,
7981
(Uint32*)m_buffer.get_data(),
7982
m_buffer.length() / 4);
7986
DBUG_PRINT("info", ("get_file failed parseFileInfo %d",
7988
DBUG_RETURN(m_error.code);
7991
if(dst.m_type == NdbDictionary::Object::Undofile)
7993
NdbDictionary::LogfileGroup tmp;
7994
get_filegroup(NdbLogfileGroupImpl::getImpl(tmp),
7995
NdbDictionary::Object::LogfileGroup,
7996
dst.m_filegroup_id);
7997
if (!dst.m_filegroup_name.assign(tmp.getName()))
7998
DBUG_RETURN(m_error.code = 4000);
8000
else if(dst.m_type == NdbDictionary::Object::Datafile)
8002
NdbDictionary::Tablespace tmp;
8003
get_filegroup(NdbTablespaceImpl::getImpl(tmp),
8004
NdbDictionary::Object::Tablespace,
8005
dst.m_filegroup_id);
8006
if (!dst.m_filegroup_name.assign(tmp.getName()))
8007
DBUG_RETURN(m_error.code = 4000);
8008
dst.m_free *= tmp.getExtentSize();
8011
dst.m_filegroup_name.assign("Not Yet Implemented");
8013
if(dst.m_type == type)
8017
DBUG_PRINT("info", ("get_file failed no such file"));
8018
DBUG_RETURN(m_error.code = GetTabInfoRef::TableNotDefined);
8022
NdbDictInterface::parseFileInfo(NdbFileImpl &dst,
8023
const Uint32 * data, Uint32 len)
8025
SimplePropertiesLinearReader it(data, len);
8027
SimpleProperties::UnpackStatus status;
8028
DictFilegroupInfo::File f; f.init();
8029
status = SimpleProperties::unpack(it, &f,
8030
DictFilegroupInfo::FileMapping,
8031
DictFilegroupInfo::FileMappingSize,
8034
if(status != SimpleProperties::Eof){
8035
return CreateFilegroupRef::InvalidFormat;
8038
dst.m_type= (NdbDictionary::Object::Type)f.FileType;
8040
dst.m_version = f.FileVersion;
8042
dst.m_size= ((Uint64)f.FileSizeHi << 32) | (f.FileSizeLo);
8043
if (!dst.m_path.assign(f.FileName))
8046
dst.m_filegroup_id= f.FilegroupId;
8047
dst.m_filegroup_version= f.FilegroupVersion;
8048
dst.m_free= f.FileFreeExtents;
8056
NdbHashMapImpl::NdbHashMapImpl()
8057
: NdbDictionary::HashMap(* this),
8058
NdbDictObjectImpl(NdbDictionary::Object::HashMap), m_facade(this)
8062
NdbHashMapImpl::NdbHashMapImpl(NdbDictionary::HashMap & f)
8063
: NdbDictionary::HashMap(* this),
8064
NdbDictObjectImpl(NdbDictionary::Object::HashMap), m_facade(&f)
8068
NdbHashMapImpl::~NdbHashMapImpl()
8073
NdbHashMapImpl::assign(const NdbHashMapImpl& org)
8076
m_version = org.m_version;
8077
m_status = org.m_status;
8079
m_name.assign(org.m_name);
8080
m_map.assign(org.m_map);
8086
NdbDictInterface::get_hashmap(NdbHashMapImpl & dst,
8089
NdbApiSignal tSignal(m_reference);
8090
GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
8092
Uint32 strLen = (Uint32)strlen(name) + 1;
8094
req->senderRef = m_reference;
8095
req->senderData = 0;
8097
GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
8098
req->tableNameLen = strLen;
8099
req->schemaTransId = m_tx.transId();
8100
tSignal.theReceiversBlockNumber = DBDICT;
8101
tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
8102
tSignal.theLength = GetTabInfoReq::SignalLength;
8104
LinearSectionPtr ptr[1];
8105
ptr[0].p = (Uint32*)name;
8106
ptr[0].sz = (strLen + 3)/4;
8108
#ifndef IGNORE_VALGRIND_WARNINGS
8113
m_buffer.append(name, strLen);
8114
m_buffer.append(&pad, 4);
8115
ptr[0].p = (Uint32*)m_buffer.get_data();
8119
int r = dictSignal(&tSignal, ptr, 1,
8121
WAIT_GET_TAB_INFO_REQ,
8122
DICT_WAITFOR_TIMEOUT, 100);
8131
m_error.code = parseHashMapInfo(dst,
8132
(Uint32*)m_buffer.get_data(),
8133
m_buffer.length() / 4);
8135
return m_error.code;
8139
NdbDictInterface::get_hashmap(NdbHashMapImpl & dst,
8142
NdbApiSignal tSignal(m_reference);
8143
GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
8145
req->senderRef = m_reference;
8146
req->senderData = 0;
8148
GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
8150
req->schemaTransId = m_tx.transId();
8151
tSignal.theReceiversBlockNumber = DBDICT;
8152
tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
8153
tSignal.theLength = GetTabInfoReq::SignalLength;
8155
int r = dictSignal(&tSignal, 0, 0,
8157
WAIT_GET_TAB_INFO_REQ,
8158
DICT_WAITFOR_TIMEOUT, 100);
8167
m_error.code = parseHashMapInfo(dst,
8168
(Uint32*)m_buffer.get_data(),
8169
m_buffer.length() / 4);
8171
return m_error.code;
8175
NdbDictInterface::parseHashMapInfo(NdbHashMapImpl &dst,
8176
const Uint32 * data, Uint32 len)
8178
SimplePropertiesLinearReader it(data, len);
8180
SimpleProperties::UnpackStatus status;
8181
DictHashMapInfo::HashMap hm; hm.init();
8182
status = SimpleProperties::unpack(it, &hm,
8183
DictHashMapInfo::Mapping,
8184
DictHashMapInfo::MappingSize,
8187
if(status != SimpleProperties::Eof){
8188
return CreateFilegroupRef::InvalidFormat;
8191
dst.m_name.assign(hm.HashMapName);
8192
dst.m_id= hm.HashMapObjectId;
8193
dst.m_version = hm.HashMapVersion;
8196
* pack is stupid...and requires bytes!
8197
* we store shorts...so divide by 2
8199
hm.HashMapBuckets /= sizeof(Uint16);
8202
for (Uint32 i = 0; i<hm.HashMapBuckets; i++)
8204
dst.m_map.push_back(hm.HashMapValues[i]);
8211
NdbDictInterface::create_hashmap(const NdbHashMapImpl& src,
8212
NdbDictObjectImpl* obj,
8215
DictHashMapInfo::HashMap hm; hm.init();
8216
BaseString::snprintf(hm.HashMapName, sizeof(hm.HashMapName),
8217
"%s", src.getName());
8218
hm.HashMapBuckets = src.getMapLen();
8219
for (Uint32 i = 0; i<hm.HashMapBuckets; i++)
8221
hm.HashMapValues[i] = NdbHashMapImpl::getImpl(src).m_map[i];
8225
* pack is stupid...and requires bytes!
8226
* we store shorts...so multiply by 2
8228
hm.HashMapBuckets *= sizeof(Uint16);
8229
SimpleProperties::UnpackStatus s;
8230
UtilBufferWriter w(m_buffer);
8231
s = SimpleProperties::pack(w,
8233
DictHashMapInfo::Mapping,
8234
DictHashMapInfo::MappingSize, true);
8236
if(s != SimpleProperties::Eof)
8241
NdbApiSignal tSignal(m_reference);
8242
tSignal.theReceiversBlockNumber = DBDICT;
8243
tSignal.theVerId_signalNumber = GSN_CREATE_HASH_MAP_REQ;
8244
tSignal.theLength = CreateHashMapReq::SignalLength;
8246
CreateHashMapReq* req = CAST_PTR(CreateHashMapReq, tSignal.getDataPtrSend());
8247
req->clientRef = m_reference;
8248
req->clientData = 0;
8249
req->requestInfo = flags;
8250
req->requestInfo |= m_tx.requestFlags();
8251
req->transId = m_tx.transId();
8252
req->transKey = m_tx.transKey();
8253
req->fragments = 0; // not used from here
8254
req->buckets = 0; // not used from here
8256
LinearSectionPtr ptr[3];
8257
ptr[0].p = (Uint32*)m_buffer.get_data();
8258
ptr[0].sz = m_buffer.length() / 4;
8260
int err[]= { CreateTableRef::Busy, CreateTableRef::NotMaster, 0 };
8263
Send signal without time-out since creating files can take a very long
8264
time if the file is very big.
8267
if (flags & CreateHashMapReq::CreateDefault)
8271
int ret = dictSignal(&tSignal, ptr, seccnt,
8273
WAIT_CREATE_INDX_REQ,
8277
if (ret == 0 && obj)
8279
Uint32* data = (Uint32*)m_buffer.get_data();
8280
obj->m_id = data[0];
8281
obj->m_version = data[1];
8288
NdbDictInterface::execCREATE_HASH_MAP_REF(const NdbApiSignal * signal,
8289
const LinearSectionPtr ptr[3])
8291
const CreateHashMapRef* ref =
8292
CAST_CONSTPTR(CreateHashMapRef, signal->getDataPtr());
8293
m_error.code = ref->errorCode;
8294
m_masterNodeId = ref->masterNodeId;
8295
m_impl->theWaiter.signal(NO_WAIT);
8300
NdbDictInterface::execCREATE_HASH_MAP_CONF(const NdbApiSignal * signal,
8301
const LinearSectionPtr ptr[3])
8303
const CreateHashMapConf* conf=
8304
CAST_CONSTPTR(CreateHashMapConf, signal->getDataPtr());
8305
m_buffer.grow(4 * 2); // 2 words
8306
Uint32* data = (Uint32*)m_buffer.get_data();
8307
data[0] = conf->objectId;
8308
data[1] = conf->objectVersion;
8310
m_impl->theWaiter.signal(NO_WAIT);
8313
template class Vector<NdbTableImpl*>;
8314
template class Vector<NdbColumnImpl*>;
8317
NdbDictionaryImpl::beginSchemaTrans(bool retry711)
8319
DBUG_ENTER("beginSchemaTrans");
8320
if (m_tx.m_state == NdbDictInterface::Tx::Started) {
8321
m_error.code = 4410;
8324
if (!m_receiver.checkAllNodeVersionsMin(NDBD_SCHEMA_TRANS_VERSION))
8326
/* Upgrade 6.3 -> 7.0 path */
8327
/* Schema transaction not possible until upgrade complete */
8328
m_error.code = 4411;
8331
// TODO real transId
8332
m_tx.m_transId = rand();
8333
m_tx.m_state = NdbDictInterface::Tx::Started;
8334
m_tx.m_error.code = 0;
8335
if (m_tx.m_transId == 0)
8337
int ret = m_receiver.beginSchemaTrans(retry711);
8339
m_tx.m_state = NdbDictInterface::Tx::NotStarted;
8342
DBUG_PRINT("info", ("transId: %x transKey: %x",
8343
m_tx.m_transId, m_tx.m_transKey));
8348
NdbDictionaryImpl::endSchemaTrans(Uint32 flags)
8350
DBUG_ENTER("endSchemaTrans");
8351
if (m_tx.m_state == NdbDictInterface::Tx::NotStarted) {
8355
Check if schema transaction has been aborted
8356
already, for example because of master node failure.
8358
if (m_tx.m_state != NdbDictInterface::Tx::Started)
8361
DBUG_PRINT("info", ("endSchemaTrans: state %u, flags 0x%x\n", m_tx.m_state, flags));
8362
if (m_tx.m_state == NdbDictInterface::Tx::Aborted && // rollback at master takeover
8363
flags & NdbDictionary::Dictionary::SchemaTransAbort)
8365
m_tx.m_error.code = 0;
8368
m_error.code = m_tx.m_error.code;
8371
DBUG_PRINT("info", ("transId: %x transKey: %x",
8372
m_tx.m_transId, m_tx.m_transKey));
8373
int ret = m_receiver.endSchemaTrans(flags);
8374
if (ret == -1 || m_tx.m_error.code != 0) {
8375
DBUG_PRINT("info", ("endSchemaTrans: state %u, flags 0x%x\n", m_tx.m_state, flags));
8376
if (m_tx.m_state == NdbDictInterface::Tx::Committed && // rollforward at master takeover
8377
!(flags & NdbDictionary::Dictionary::SchemaTransAbort))
8380
if (m_tx.m_state == NdbDictInterface::Tx::Aborted && // rollback at master takeover
8381
flags & NdbDictionary::Dictionary::SchemaTransAbort)
8383
m_error.code = m_tx.m_error.code = 0;
8384
m_tx.m_state = NdbDictInterface::Tx::NotStarted;
8387
if (m_tx.m_error.code != 0)
8388
m_error.code = m_tx.m_error.code;
8389
m_tx.m_state = NdbDictInterface::Tx::NotStarted;
8393
// invalidate old version of altered table
8395
for (i = 0; i < m_tx.m_op.size(); i++) {
8396
NdbDictInterface::Tx::Op& op = m_tx.m_op[i];
8397
if (op.m_gsn == GSN_ALTER_TABLE_REQ)
8399
op.m_impl->m_status = NdbDictionary::Object::Invalid;
8400
m_globalHash->lock();
8401
int ret = m_globalHash->dec_ref_count(op.m_impl);
8402
m_globalHash->unlock();
8407
m_tx.m_state = NdbDictInterface::Tx::NotStarted;
8413
NdbDictInterface::checkAllNodeVersionsMin(Uint32 minNdbVersion) const
8415
for (Uint32 nodeId = 1; nodeId < MAX_NODES; nodeId++)
8417
if (m_impl->getIsDbNode(nodeId) &&
8418
m_impl->getIsNodeSendable(nodeId) &&
8419
(m_impl->getNodeNdbVersion(nodeId) <
8422
/* At least 1 sendable data node has lower-than-min
8434
NdbDictInterface::beginSchemaTrans(bool retry711)
8436
assert(m_tx.m_op.size() == 0);
8437
NdbApiSignal tSignal(m_reference);
8438
SchemaTransBeginReq* req =
8439
CAST_PTR(SchemaTransBeginReq, tSignal.getDataPtrSend());
8441
tSignal.theReceiversBlockNumber = DBDICT;
8442
tSignal.theVerId_signalNumber = GSN_SCHEMA_TRANS_BEGIN_REQ;
8443
tSignal.theLength = SchemaTransBeginReq::SignalLength;
8445
req->clientRef = m_reference;
8446
req->transId = m_tx.m_transId;
8447
req->requestInfo = 0;
8450
SchemaTransBeginRef::NotMaster,
8451
SchemaTransBeginRef::Busy,
8452
retry711 ? SchemaTransBeginRef::BusyWithNR : 0,
8456
int ret = dictSignal(
8462
DICT_WAITFOR_TIMEOUT,
8471
NdbDictInterface::endSchemaTrans(Uint32 flags)
8473
NdbApiSignal tSignal(m_reference);
8474
SchemaTransEndReq* req =
8475
CAST_PTR(SchemaTransEndReq, tSignal.getDataPtrSend());
8477
tSignal.theReceiversBlockNumber = DBDICT;
8478
tSignal.theVerId_signalNumber = GSN_SCHEMA_TRANS_END_REQ;
8479
tSignal.theLength = SchemaTransEndReq::SignalLength;
8481
req->clientRef = m_reference;
8482
req->transId = m_tx.m_transId;
8483
req->requestInfo = 0;
8484
req->transKey = m_tx.m_transKey;
8488
SchemaTransBeginRef::NotMaster,
8491
int ret = dictSignal(
8497
DICT_WAITFOR_TIMEOUT,
8506
NdbDictInterface::execSCHEMA_TRANS_BEGIN_CONF(const NdbApiSignal * signal,
8507
const LinearSectionPtr ptr[3])
8509
const SchemaTransBeginConf* conf=
8510
CAST_CONSTPTR(SchemaTransBeginConf, signal->getDataPtr());
8511
assert(m_tx.m_transId == conf->transId);
8512
m_tx.m_transKey = conf->transKey;
8513
m_impl->theWaiter.signal(NO_WAIT);
8517
NdbDictInterface::execSCHEMA_TRANS_BEGIN_REF(const NdbApiSignal * signal,
8518
const LinearSectionPtr ptr[3])
8520
const SchemaTransBeginRef* ref =
8521
CAST_CONSTPTR(SchemaTransBeginRef, signal->getDataPtr());
8522
m_error.code = ref->errorCode;
8523
m_masterNodeId = ref->masterNodeId;
8524
m_impl->theWaiter.signal(NO_WAIT);
8528
NdbDictInterface::execSCHEMA_TRANS_END_CONF(const NdbApiSignal * signal,
8529
const LinearSectionPtr ptr[3])
8531
const SchemaTransEndConf* conf=
8532
CAST_CONSTPTR(SchemaTransEndConf, signal->getDataPtr());
8533
assert(m_tx.m_transId == conf->transId);
8534
m_impl->theWaiter.signal(NO_WAIT);
8538
NdbDictInterface::execSCHEMA_TRANS_END_REF(const NdbApiSignal * signal,
8539
const LinearSectionPtr ptr[3])
8541
const SchemaTransEndRef* ref =
8542
CAST_CONSTPTR(SchemaTransEndRef, signal->getDataPtr());
8543
m_error.code = ref->errorCode;
8544
m_tx.m_error.code = ref->errorCode;
8545
m_masterNodeId = ref->masterNodeId;
8546
m_impl->theWaiter.signal(NO_WAIT);
8550
NdbDictInterface::execSCHEMA_TRANS_END_REP(const NdbApiSignal * signal,
8551
const LinearSectionPtr ptr[3])
8553
const SchemaTransEndRep* rep =
8554
CAST_CONSTPTR(SchemaTransEndRep, signal->getDataPtr());
8555
(rep->errorCode == 0) ?
8556
m_tx.m_state = Tx::Committed
8558
m_tx.m_state = Tx::Aborted;
8559
m_tx.m_error.code = rep->errorCode;
8560
m_masterNodeId = rep->masterNodeId;
8561
m_impl->theWaiter.signal(NO_WAIT);
8564
const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT = 0;
8565
const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_FIXED_MEMORY = 0;
8566
const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY = 0;
8567
const NdbDictionary::Column * NdbDictionary::Column::ROW_COUNT = 0;
8568
const NdbDictionary::Column * NdbDictionary::Column::COMMIT_COUNT = 0;
8569
const NdbDictionary::Column * NdbDictionary::Column::ROW_SIZE = 0;
8570
const NdbDictionary::Column * NdbDictionary::Column::RANGE_NO = 0;
8571
const NdbDictionary::Column * NdbDictionary::Column::DISK_REF = 0;
8572
const NdbDictionary::Column * NdbDictionary::Column::RECORDS_IN_RANGE = 0;
8573
const NdbDictionary::Column * NdbDictionary::Column::ROWID = 0;
8574
const NdbDictionary::Column * NdbDictionary::Column::ROW_GCI = 0;
8575
const NdbDictionary::Column * NdbDictionary::Column::ROW_GCI64 = 0;
8576
const NdbDictionary::Column * NdbDictionary::Column::ROW_AUTHOR = 0;
8577
const NdbDictionary::Column * NdbDictionary::Column::ANY_VALUE = 0;
8578
const NdbDictionary::Column * NdbDictionary::Column::COPY_ROWID = 0;
8579
const NdbDictionary::Column * NdbDictionary::Column::OPTIMIZE = 0;
8580
const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_EXTENT_SPACE = 0;
8581
const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE = 0;
8582
const NdbDictionary::Column * NdbDictionary::Column::LOCK_REF = 0;
8583
const NdbDictionary::Column * NdbDictionary::Column::OP_ID = 0;
8585
template class Vector<NdbDictInterface::Tx::Op>;