1
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
19
#include <NdbError.hpp>
21
static Ndb_cluster_connection *g_cluster_connection= 0;
22
static Ndb* g_ndb = 0;
23
static const char* g_tablename1 = "T_DEF1"; //The normal table with default values
24
static const char* g_tablename2 = "T_DEF2"; //The table for Test that maximum length defaults work
25
//The table for Test that an attempt to insert to a table containing defaults
26
//without supplying a value for a not-null, non-defaulted column still fails
27
static const char* g_tablename3 = "T_DEF3";
28
static NdbDictionary::Dictionary* g_dict = 0;
29
static const unsigned int column_count_table1 = 8;
30
static const unsigned int column_count_table2 = 2;
31
static const unsigned int column_count_table3 = 2;
33
static struct NdbError g_ndberror;
34
static int create_table();
39
g_cluster_connection = new Ndb_cluster_connection();
40
if(g_cluster_connection->connect(12, 5, 1) != 0)
43
g_ndb = new Ndb(g_cluster_connection, "TEST");
45
if(g_ndb->waitUntilReady(30) != 0)
54
delete g_cluster_connection;
57
g_cluster_connection= 0;
60
#define PRINT_ERROR(error) \
61
ndbout << "Error in " << __FILE__ << ", line: " << __LINE__ \
62
<< ", code: " << error.code \
63
<< ", msg: " << error.message << "." << endl
64
#define FAIL(error_msg) \
65
ndbout << error_msg << " at line " << __LINE__ << endl; \
68
static const int tab1_c1_default= 6;
69
static const float tab1_c2_default= float(1234.56);
70
static const double tab1_c3_default= 4567.89;
71
static const char tab1_c4_default[]= "aaaaaa ";
72
static const unsigned int tab1_c4_default_siglen= 12;
73
static const char tab1_c5_default[]= "\x6" "aaaaaa\0\0\0\0";
74
static const unsigned int tab1_c5_default_siglen= 7;
75
static const char tab1_c6_default[]= "aaaaaa ";
76
static const unsigned int tab1_c6_default_siglen= 0;
77
static const char tab1_c7_default[]= "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
78
static const char tab1_c7_default_siglen= 1;
80
static const int tab2_c1_default_len= 8052 - 4 - 2;
81
/* Max row length minus 4 bytes for key, minus 2 bytes for length info */
82
static const char tab2_c1_default_char= 'V';
87
g_dict = g_ndb->getDictionary();
88
if ((g_dict->getTable(g_tablename1) != 0) &&
89
(g_dict->dropTable(g_tablename1) != 0))
91
PRINT_ERROR(g_dict->getNdbError());
95
if ((g_dict->getTable(g_tablename2) != 0) &&
96
(g_dict->dropTable(g_tablename2) != 0))
98
PRINT_ERROR(g_dict->getNdbError());
102
if ((g_dict->getTable(g_tablename3) != 0) &&
103
(g_dict->dropTable(g_tablename3) != 0))
105
PRINT_ERROR(g_dict->getNdbError());
109
NdbDictionary::Table tab(g_tablename1);
110
tab.setLogging(false);
112
NdbDictionary::Table tab2(g_tablename2);
113
tab2.setLogging(false);
115
NdbDictionary::Table tab3(g_tablename3);
116
tab3.setLogging(false);
119
{ NdbDictionary::Column col("PK");
120
col.setType(NdbDictionary::Column::Unsigned);
121
col.setPrimaryKey(true);
122
col.setNullable(FALSE);
123
col.setAutoIncrement(TRUE);
124
col.setDefaultValue(NULL);
129
NdbDictionary::Column col("C1");
130
col.setType(NdbDictionary::Column::Int);
131
col.setDefaultValue(&tab1_c1_default,sizeof(int));
136
NdbDictionary::Column col("C2");
137
col.setType(NdbDictionary::Column::Float);
138
col.setDefaultValue(&tab1_c2_default, sizeof(float));
143
NdbDictionary::Column col("C3");
144
col.setType(NdbDictionary::Column::Double);
145
col.setDefaultValue(&tab1_c3_default, sizeof(double));
150
NdbDictionary::Column col("C4");
151
col.setType(NdbDictionary::Column::Char);
153
col.setDefaultValue(tab1_c4_default, 12);
158
NdbDictionary::Column col("C5");
159
col.setType(NdbDictionary::Column::Varchar);
161
col.setDefaultValue(tab1_c5_default, tab1_c5_default_siglen);
167
/* Test non-null pointer passed, but with zero length? */
168
NdbDictionary::Column col("C6");
169
col.setType(NdbDictionary::Column::Char);
171
col.setNullable(TRUE);
172
col.setDefaultValue(tab1_c6_default, tab1_c6_default_siglen);
176
//Test that a zero-length VARCHAR default works
178
NdbDictionary::Column col("C7");
179
col.setType(NdbDictionary::Column::Varchar);
181
col.setDefaultValue(tab1_c7_default, tab1_c7_default_siglen);
185
//create table T_DEF2
186
{ NdbDictionary::Column col("PK");
187
col.setType(NdbDictionary::Column::Unsigned);
188
col.setPrimaryKey(true);
189
col.setNullable(FALSE);
190
col.setAutoIncrement(FALSE);
191
col.setDefaultValue(NULL, 0);
195
//Test that maximum length defaults work
197
char default_data[tab2_c1_default_len + 2];
198
default_data[0] = (tab2_c1_default_len >> 0) & 0xff;
199
default_data[1] = (tab2_c1_default_len >> 8) & 0xff;
200
memset(default_data + 2, tab2_c1_default_char, tab2_c1_default_len);
201
NdbDictionary::Column col("C1");
202
col.setType(NdbDictionary::Column::Longvarchar);
203
col.setLength(tab2_c1_default_len);
204
col.setDefaultValue(default_data, tab2_c1_default_len + 2);
208
//Create table T_DEF3
209
{ NdbDictionary::Column col("PK");
210
col.setType(NdbDictionary::Column::Unsigned);
211
col.setPrimaryKey(true);
212
col.setNullable(FALSE);
213
col.setAutoIncrement(FALSE);
214
col.setDefaultValue(NULL, 0);
218
//For column without supplying a value for a not-null, non-defaulted column
219
{ NdbDictionary::Column col("C1");
220
col.setType(NdbDictionary::Column::Unsigned);
221
col.setNullable(FALSE);
222
col.setDefaultValue(NULL, 0);
227
if(g_dict->createTable(tab) != 0)
229
PRINT_ERROR(g_dict->getNdbError());
233
if(g_dict->createTable(tab2) != 0)
235
PRINT_ERROR(g_dict->getNdbError());
239
if(g_dict->createTable(tab3) != 0)
241
PRINT_ERROR(g_dict->getNdbError());
249
ndb_error_check(const struct NdbError& error, unsigned int line)
251
if (error.code != 850)
254
ndbout << " at line " << line << "\n";
260
#define CHECK_ERROR(error) { \
261
if (ndb_error_check(error, __LINE__) == NDBT_FAILED) \
262
return NDBT_FAILED; \
268
g_dict = g_ndb->getDictionary();
271
* 1. The following test case is for fixed columns that
272
* there are too long or too short default values.
274
//for too long default value
275
NdbDictionary::Table tab1("T_DEF_TEST1");
276
tab1.setLogging(false);
278
{ NdbDictionary::Column col("PK");
279
col.setType(NdbDictionary::Column::Unsigned);
280
col.setPrimaryKey(true);
281
col.setNullable(FALSE);
282
col.setDefaultValue(NULL);
286
{ int default_data = 6;
287
NdbDictionary::Column col("C1");
288
col.setType(NdbDictionary::Column::Int);
289
col.setDefaultValue(&default_data, 8);
293
if(g_dict->createTable(tab1) != 0)
295
CHECK_ERROR(g_dict->getNdbError());
299
FAIL("Create table should not have succeeded");
302
//for too short default value
303
NdbDictionary::Table tab2("T_DEF_TEST2");
304
tab2.setLogging(false);
306
{ NdbDictionary::Column col("PK");
307
col.setType(NdbDictionary::Column::Unsigned);
308
col.setPrimaryKey(true);
309
col.setNullable(FALSE);
310
col.setAutoIncrement(TRUE);
311
col.setDefaultValue(NULL);
315
{ const char default_data[] = "aaaaaa";
316
NdbDictionary::Column col("C4");
317
col.setType(NdbDictionary::Column::Char);
319
col.setDefaultValue(default_data, 6);
323
if(g_dict->createTable(tab2) != 0)
325
CHECK_ERROR(g_dict->getNdbError());
329
FAIL("Create table should not have succeeded");
333
* 2. The following test case is for Var-type columns that
334
* there are too long default values.
336
NdbDictionary::Table tab3("T_DEF_TEST3");
337
tab3.setLogging(false);
339
{ NdbDictionary::Column col("PK");
340
col.setType(NdbDictionary::Column::Unsigned);
341
col.setPrimaryKey(true);
342
col.setNullable(FALSE);
343
col.setAutoIncrement(TRUE);
344
col.setDefaultValue(NULL);
348
{ char default_data[20];
349
memset(default_data, 0, 20);
350
Uint8 * p = (Uint8*)default_data;
352
memcpy(default_data + 1, "aaaaaaaaaa", 10);
353
NdbDictionary::Column col("C5");
354
col.setType(NdbDictionary::Column::Varchar);
356
col.setDefaultValue(default_data, 11);
360
if(g_dict->createTable(tab3) != 0)
362
CHECK_ERROR(g_dict->getNdbError());
366
FAIL("Create table should not have succeeded");
371
* 3. Test attempt to set default value for primary key
373
NdbDictionary::Table tab4("T_DEF_TEST4");
374
tab4.setLogging(false);
376
{ NdbDictionary::Column col("PK");
377
unsigned int default_val=22;
378
col.setType(NdbDictionary::Column::Unsigned);
379
col.setPrimaryKey(true);
380
col.setNullable(FALSE);
381
col.setAutoIncrement(TRUE);
382
col.setDefaultValue(&default_val, sizeof(default_val));
386
if(g_dict->createTable(tab4) == 0)
388
FAIL("Create table should not have succeeded");
391
if(g_dict->getNdbError().code != 792)
393
PRINT_ERROR(g_dict->getNdbError());
398
* 4. The following test case is for Var-type columns that
399
* there are too long default values, where the passed
400
* value is short, but the implied value is too long
402
NdbDictionary::Table tab5("T_DEF_TEST5");
403
tab5.setLogging(false);
405
{ NdbDictionary::Column col("PK");
406
col.setType(NdbDictionary::Column::Unsigned);
407
col.setPrimaryKey(true);
408
col.setNullable(FALSE);
409
col.setAutoIncrement(TRUE);
410
col.setDefaultValue(NULL);
414
{ char default_data[20];
415
memset(default_data, 0, 20);
416
Uint8 * p = (Uint8*)default_data;
418
memcpy(default_data + 1, "aaaaaaaaaa", 15);
419
NdbDictionary::Column col("C5");
420
col.setType(NdbDictionary::Column::Varchar);
422
/* Within range, but contained VARCHAR is too long */
423
col.setDefaultValue(default_data, 10);
427
if(g_dict->createTable(tab5) != 0)
429
CHECK_ERROR(g_dict->getNdbError());
433
FAIL("Create table should not have succeeded");
442
if ((g_dict != 0) && ( g_dict->getTable(g_tablename1) != 0))
444
if(g_dict->dropTable(g_tablename1))
445
PRINT_ERROR(g_dict->getNdbError());
448
if ((g_dict != 0) && ( g_dict->getTable(g_tablename2) != 0))
450
if(g_dict->dropTable(g_tablename2))
451
PRINT_ERROR(g_dict->getNdbError());
454
if ((g_dict != 0) && ( g_dict->getTable(g_tablename3) != 0))
456
if(g_dict->dropTable(g_tablename3))
457
PRINT_ERROR(g_dict->getNdbError());
463
static int do_insert()
465
const NdbDictionary::Table *myTable= g_dict->getTable(g_tablename1);
469
PRINT_ERROR(g_dict->getNdbError());
473
NdbTransaction *myTransaction= g_ndb->startTransaction();
474
if (myTransaction == NULL)
476
PRINT_ERROR(g_ndb->getNdbError());
480
NdbOperation *myOperation= myTransaction->getNdbOperation(myTable);
481
NdbOperation *myOperation1= myTransaction->getNdbOperation(myTable);
482
if (myOperation == NULL || myOperation1 == NULL)
484
PRINT_ERROR(myTransaction->getNdbError());
485
g_ndb->closeTransaction(myTransaction);
489
myOperation->insertTuple();
490
myOperation->equal("PK", 1);
491
myOperation1->insertTuple();
492
myOperation1->equal("PK", 2);
494
//insert the second table T_DEF2
495
const NdbDictionary::Table *myTable2= g_dict->getTable(g_tablename2);
499
PRINT_ERROR(g_dict->getNdbError());
502
NdbOperation *myOperation2 = myTransaction->getNdbOperation(myTable2);
503
if (myOperation2 == NULL)
505
PRINT_ERROR(myTransaction->getNdbError());
506
g_ndb->closeTransaction(myTransaction);
510
myOperation2->insertTuple();
511
myOperation2->equal("PK", 1);
514
/* Test insert of max length tuple with max length default
515
* Could theoretically expose kernel overflow with default
518
myOperation2=myTransaction->getNdbOperation(myTable2);
519
if (myOperation2 == NULL)
521
PRINT_ERROR(myTransaction->getNdbError());
522
g_ndb->closeTransaction(myTransaction);
526
myOperation2->insertTuple();
527
myOperation2->equal("PK", 2);
530
char default_data[tab2_c1_default_len + 2];
531
default_data[0] = (tab2_c1_default_len >> 0) & 0xff;
532
default_data[1] = (tab2_c1_default_len >> 8) & 0xff;
533
memset(default_data + 2, tab2_c1_default_char, tab2_c1_default_len);
535
myOperation2->setValue("C1", default_data);
538
if (myTransaction->execute(NdbTransaction::Commit) == -1)
540
PRINT_ERROR(myTransaction->getNdbError());
541
g_ndb->closeTransaction(myTransaction);
545
g_ndb->closeTransaction(myTransaction);
547
//The following insert should fail, and return error code
548
const NdbDictionary::Table *myTable3= g_dict->getTable(g_tablename3);
550
if (myTable3 == NULL)
552
PRINT_ERROR(g_dict->getNdbError());
556
NdbTransaction *myTransaction3 = g_ndb->startTransaction();
557
if (myTransaction3 == NULL)
559
PRINT_ERROR(g_ndb->getNdbError());
563
NdbOperation *myOperation3 = myTransaction3->getNdbOperation(myTable3);
564
if (myOperation3 == NULL)
566
PRINT_ERROR(myTransaction3->getNdbError());
567
g_ndb->closeTransaction(myTransaction3);
570
myOperation3->insertTuple();
571
myOperation3->equal("PK", 1);
573
/* It should return error code 839 ( msg: Illegal null attribute)
574
* for an attempt to insert to a table containing defaults
575
* without supplying a value for a not-null, non-defaulted column
577
if (myTransaction3->execute(NdbTransaction::Commit) == -1)
579
PRINT_ERROR(myTransaction3->getNdbError());
581
if (myTransaction3->getNdbError().code != 839)
583
ndbout << "Expected error 839" << endl;
584
g_ndb->closeTransaction(myTransaction3);
588
g_ndb->closeTransaction(myTransaction3);
593
#define CHECK_VAL_EQ(ref, test) { \
594
if ((ref) != (test)) { \
595
ndbout << "Equality failed at line " << __LINE__ << "\n" \
596
<< test << " != " << ref << "\n"; \
597
return NDBT_FAILED; \
600
#define CHECK_BYTES_EQ(ref, test, len) { \
601
if (memcmp((ref), (test), (len))) { \
602
ndbout << "Bytes differ at line " << __LINE__ << "\n"; \
603
return NDBT_FAILED; \
611
NdbRecAttr *myRecAttr[column_count_table1];
612
NdbRecAttr *myRecAttr2[column_count_table2];
613
NdbRecAttr *myRecAttr3[column_count_table3];
615
const NdbDictionary::Table *myTable= g_dict->getTable(g_tablename1);
616
const NdbDictionary::Table *myTable2 = g_dict->getTable(g_tablename2);
617
const NdbDictionary::Table *myTable3 = g_dict->getTable(g_tablename3);
619
if (myTable == NULL || myTable2 == NULL || myTable3 == NULL)
621
PRINT_ERROR(g_dict->getNdbError());
625
NdbTransaction *myTransaction= g_ndb->startTransaction();
626
if (myTransaction == NULL)
628
PRINT_ERROR(g_ndb->getNdbError());
632
//Define Scan Operation for T_DEF1
633
NdbScanOperation *myScanOp = myTransaction->getNdbScanOperation(myTable);
634
if (myScanOp == NULL)
636
PRINT_ERROR(myTransaction->getNdbError());
637
g_ndb->closeTransaction(myTransaction);
641
if(myScanOp->readTuples(NdbOperation::LM_CommittedRead) == -1)
643
PRINT_ERROR(myTransaction->getNdbError());
644
g_ndb->closeTransaction(myTransaction);
648
myRecAttr[0] = myScanOp->getValue("PK");
649
myRecAttr[1] = myScanOp->getValue("C1");
650
myRecAttr[2] = myScanOp->getValue("C2");
651
myRecAttr[3] = myScanOp->getValue("C3");
652
myRecAttr[4] = myScanOp->getValue("C4");
653
myRecAttr[5] = myScanOp->getValue("C5");
654
myRecAttr[6] = myScanOp->getValue("C6");
655
myRecAttr[7] = myScanOp->getValue("C7");
657
for (unsigned int i = 0; i < column_count_table1; i++)
658
if (myRecAttr[i] == NULL)
660
PRINT_ERROR(myTransaction->getNdbError());
661
g_ndb->closeTransaction(myTransaction);
665
//Define Scan Operation for T_DEF2
666
NdbScanOperation *myScanOp2 = myTransaction->getNdbScanOperation(myTable2);
667
if (myScanOp2 == NULL)
669
PRINT_ERROR(myTransaction->getNdbError());
670
g_ndb->closeTransaction(myTransaction);
674
if(myScanOp2->readTuples(NdbOperation::LM_CommittedRead) == -1)
676
PRINT_ERROR(myTransaction->getNdbError());
677
g_ndb->closeTransaction(myTransaction);
681
myRecAttr2[0] = myScanOp2->getValue("PK");
682
myRecAttr2[1] = myScanOp2->getValue("C1");
683
if (myRecAttr2[0] == NULL || myRecAttr2[1] == NULL)
685
PRINT_ERROR(myTransaction->getNdbError());
686
g_ndb->closeTransaction(myTransaction);
690
//Define Scan Operation for T_DEF3
691
NdbScanOperation *myScanOp3 = myTransaction->getNdbScanOperation(myTable3);
692
if (myScanOp3 == NULL)
694
PRINT_ERROR(myTransaction->getNdbError());
695
g_ndb->closeTransaction(myTransaction);
699
if(myScanOp3->readTuples(NdbOperation::LM_CommittedRead) == -1)
701
PRINT_ERROR(myTransaction->getNdbError());
702
g_ndb->closeTransaction(myTransaction);
706
myRecAttr3[0] = myScanOp3->getValue("PK");
707
myRecAttr3[1] = myScanOp3->getValue("C1");
708
if (myRecAttr3[0] == NULL || myRecAttr3[1] == NULL)
710
PRINT_ERROR(myTransaction->getNdbError());
711
g_ndb->closeTransaction(myTransaction);
715
//Execute the Transcation for the 3 scan operations
716
if(myTransaction->execute(NdbTransaction::NoCommit) != 0)
718
PRINT_ERROR(myTransaction->getNdbError());
719
g_ndb->closeTransaction(myTransaction);
723
//The following print out the result
725
ndbout<< "Table: " << g_tablename1 << endl;
727
// for (unsigned int i = 0; i < column_count_table1; i++)
728
// ndbout << "\tC" << i ;
730
while((check = myScanOp->nextResult(true)) == 0){
732
// for (Uint32 i = 0; i < column_count_table1; i++)
733
// ndbout << *myRecAttr[i] << "\t";
736
for (Uint32 i = 0; i < column_count_table1; i++)
738
/* Check that all columns are non NULL except c6 */
739
CHECK_VAL_EQ((i == 6), myRecAttr[i]->isNULL());
742
CHECK_VAL_EQ(tab1_c1_default, (int) myRecAttr[1]->int32_value());
743
CHECK_VAL_EQ(tab1_c2_default, myRecAttr[2]->float_value());
744
CHECK_VAL_EQ(tab1_c3_default, myRecAttr[3]->double_value());
745
CHECK_BYTES_EQ(tab1_c4_default, (const char*) myRecAttr[4]->aRef(), tab1_c4_default_siglen);
746
CHECK_BYTES_EQ(tab1_c5_default, (const char*) myRecAttr[5]->aRef(), tab1_c5_default_siglen);
747
CHECK_BYTES_EQ(tab1_c6_default, (const char*) myRecAttr[6]->aRef(), tab1_c6_default_siglen);
748
CHECK_BYTES_EQ(tab1_c7_default, (const char*) myRecAttr[7]->aRef(), tab1_c7_default_siglen);
749
} while((check = myScanOp->nextResult(false)) == 0);
753
ndbout << "Error with transaction " << check << " "
754
<< myTransaction->getNdbError().code << "\n";
759
ndbout<< "Table: " << g_tablename2 << endl;
760
// ndbout << "PK\tC1" << endl;
761
while((check = myScanOp2->nextResult(true)) == 0){
763
// for (Uint32 i = 0; i < column_count_table2; i++)
766
// ndbout << myRecAttr2[i]->get_size_in_bytes() << " ";
767
// ndbout << *myRecAttr2[i] << "\t";
770
const char* valPtr= (const char*)myRecAttr2[1]->aRef();
771
char default_data[tab2_c1_default_len + 2];
772
default_data[0] = (tab2_c1_default_len >> 0) & 0xff;
773
default_data[1] = (tab2_c1_default_len >> 8) & 0xff;
774
memset(default_data + 2, tab2_c1_default_char, tab2_c1_default_len);
776
CHECK_BYTES_EQ(default_data, valPtr, tab2_c1_default_len + 2);
778
} while((check = myScanOp2->nextResult(false)) == 0);
785
int main(int argc, char* argv[])
790
ndbout << "testNativeDefault started" << endl;
794
ndbout << "Failed to connect to NDB" << endl;
795
return NDBT_ProgramExit(NDBT_FAILED);
797
ndbout << "connected.." << endl;
799
ndbout << "checking create table errors..." << endl;
800
if ((ret = create_table_error()) != NDBT_OK)
801
return NDBT_ProgramExit(ret);
803
ndbout << "creating table..." << endl;
804
if ((ret = create_table()) != NDBT_OK)
805
return NDBT_ProgramExit(ret);
807
ndbout << "inserting..." << endl;
808
if ((ret = do_insert()) != NDBT_OK)
809
return NDBT_ProgramExit(ret);
811
ndbout << "reading..." << endl;
812
if ((ret = do_read()) != NDBT_OK)
813
return NDBT_ProgramExit(ret);
815
if ((ret = drop_table()) != NDBT_OK)
816
return NDBT_ProgramExit(ret);
818
ndbout << "done!" << endl;
822
ndbout << "All tests successful" << endl;
823
return NDBT_ProgramExit(NDBT_OK);