mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / tools / select_all.cpp
bloba91a4d44663051b66936894256717cad334cbc41
1 /* Copyright (c) 2003-2007 MySQL AB
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 */
17 #include <ndb_global.h>
18 #include <ndb_opts.h>
20 #include <NdbOut.hpp>
22 #include <NdbApi.hpp>
23 #include <NdbMain.h>
24 #include <NDBT.hpp>
25 #include <NdbSleep.h>
27 int scanReadRecords(Ndb*,
28 const NdbDictionary::Table*,
29 const NdbDictionary::Index*,
30 int parallel,
31 int lockType,
32 bool headers,
33 bool useHexFormat,
34 char delim,
35 bool orderby,
36 bool descending);
38 NDB_STD_OPTS_VARS;
40 static const char* _dbname = "TEST_DB";
41 static const char* _delimiter = "\t";
42 static int _header, _parallelism, _useHexFormat, _lock,
43 _order, _descending;
45 const char *load_default_groups[]= { "mysql_cluster",0 };
47 static int _tup = 0;
48 static int _dumpDisk = 0;
49 static int use_rowid = 0;
50 static int nodata = 0;
51 static int use_gci = 0;
53 static struct my_option my_long_options[] =
55 NDB_STD_OPTS("ndb_desc"),
56 { "database", 'd', "Name of database table is in",
57 (uchar**) &_dbname, (uchar**) &_dbname, 0,
58 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
59 { "parallelism", 'p', "parallelism",
60 (uchar**) &_parallelism, (uchar**) &_parallelism, 0,
61 GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
62 { "lock", 'l', "Read(0), Read-hold(1), Exclusive(2)",
63 (uchar**) &_lock, (uchar**) &_lock, 0,
64 GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
65 { "order", 'o', "Sort resultset according to index",
66 (uchar**) &_order, (uchar**) &_order, 0,
67 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
68 { "descending", 'z', "Sort descending (requires order flag)",
69 (uchar**) &_descending, (uchar**) &_descending, 0,
70 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
71 { "header", 'h', "Print header",
72 (uchar**) &_header, (uchar**) &_header, 0,
73 GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
74 { "useHexFormat", 'x', "Output numbers in hexadecimal format",
75 (uchar**) &_useHexFormat, (uchar**) &_useHexFormat, 0,
76 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
77 { "delimiter", 'D', "Column delimiter",
78 (uchar**) &_delimiter, (uchar**) &_delimiter, 0,
79 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
80 { "disk", 256, "Dump disk ref",
81 (uchar**) &_dumpDisk, (uchar**) &_dumpDisk, 0,
82 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
83 { "rowid", 256, "Dump rowid",
84 (uchar**) &use_rowid, (uchar**) &use_rowid, 0,
85 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
86 { "gci", 256, "Dump gci",
87 (uchar**) &use_gci, (uchar**) &use_gci, 0,
88 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
89 { "tupscan", 't', "Scan in tup order",
90 (uchar**) &_tup, (uchar**) &_tup, 0,
91 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
92 { "nodata", 256, "Dont print data",
93 (uchar**) &nodata, (uchar**) &nodata, 0,
94 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
95 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
97 static void usage()
99 #ifdef NOT_USED
100 char desc[] =
101 "tabname\n"\
102 "This program reads all records from one table in NDB Cluster\n"\
103 "and print them to stdout. This is performed using a scan read.\n"\
104 "(It only print error messages if it encounters a permanent error.)\n"\
105 "It can also be used to dump the content of a table to file \n"\
106 " ex: select_all --no-header --delimiter=';' T4 > T4.data\n";
107 #endif
108 ndb_std_print_version();
109 print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
110 puts("");
111 my_print_help(my_long_options);
112 my_print_variables(my_long_options);
115 int main(int argc, char** argv){
116 NDB_INIT(argv[0]);
117 load_defaults("my",load_default_groups,&argc,&argv);
118 const char* _tabname;
119 int ho_error;
120 #ifndef DBUG_OFF
121 opt_debug= "d:t:O,/tmp/ndb_select_all.trace";
122 #endif
123 if ((ho_error=handle_options(&argc, &argv, my_long_options,
124 ndb_std_get_one_option)))
125 return NDBT_ProgramExit(NDBT_WRONGARGS);
126 if ((_tabname = argv[0]) == 0) {
127 usage();
128 return NDBT_ProgramExit(NDBT_WRONGARGS);
131 Ndb_cluster_connection con(opt_connect_str);
132 con.set_name("ndb_select_all");
133 if(con.connect(12, 5, 1) != 0)
135 ndbout << "Unable to connect to management server." << endl;
136 return NDBT_ProgramExit(NDBT_FAILED);
138 if (con.wait_until_ready(30,0) < 0)
140 ndbout << "Cluster nodes not ready in 30 seconds." << endl;
141 return NDBT_ProgramExit(NDBT_FAILED);
144 Ndb MyNdb(&con, _dbname );
145 if(MyNdb.init() != 0){
146 ERR(MyNdb.getNdbError());
147 return NDBT_ProgramExit(NDBT_FAILED);
150 // Check if table exists in db
151 const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname);
152 const NdbDictionary::Index * pIdx = 0;
153 if(argc > 1){
154 pIdx = MyNdb.getDictionary()->getIndex(argv[1], _tabname);
157 if(pTab == NULL){
158 ndbout << " Table " << _tabname << " does not exist!" << endl;
159 return NDBT_ProgramExit(NDBT_WRONGARGS);
162 if(argc > 1 && pIdx == 0)
164 ndbout << " Index " << argv[1] << " does not exists" << endl;
167 if(_order && pIdx == NULL){
168 ndbout << " Order flag given without an index" << endl;
169 return NDBT_ProgramExit(NDBT_WRONGARGS);
172 if (_descending && ! _order) {
173 ndbout << " Descending flag given without order flag" << endl;
174 return NDBT_ProgramExit(NDBT_WRONGARGS);
177 if (scanReadRecords(&MyNdb,
178 pTab,
179 pIdx,
180 _parallelism,
181 _lock,
182 _header,
183 _useHexFormat,
184 (char)*_delimiter, _order, _descending) != 0){
185 return NDBT_ProgramExit(NDBT_FAILED);
188 return NDBT_ProgramExit(NDBT_OK);
192 int scanReadRecords(Ndb* pNdb,
193 const NdbDictionary::Table* pTab,
194 const NdbDictionary::Index* pIdx,
195 int parallel,
196 int _lock,
197 bool headers,
198 bool useHexFormat,
199 char delimiter, bool order, bool descending){
201 int retryAttempt = 0;
202 const int retryMax = 100;
203 int check;
204 NdbTransaction *pTrans;
205 NdbScanOperation *pOp;
206 NdbIndexScanOperation * pIOp= 0;
208 NDBT_ResultRow * row = new NDBT_ResultRow(*pTab, delimiter);
210 while (true){
212 if (retryAttempt >= retryMax){
213 ndbout << "ERROR: has retried this operation " << retryAttempt
214 << " times, failing!" << endl;
215 return -1;
218 pTrans = pNdb->startTransaction();
219 if (pTrans == NULL) {
220 const NdbError err = pNdb->getNdbError();
222 if (err.status == NdbError::TemporaryError){
223 NdbSleep_MilliSleep(50);
224 retryAttempt++;
225 continue;
227 ERR(err);
228 return -1;
232 pOp = (!pIdx) ? pTrans->getNdbScanOperation(pTab->getName()) :
233 pIOp=pTrans->getNdbIndexScanOperation(pIdx->getName(), pTab->getName());
235 if (pOp == NULL) {
236 ERR(pTrans->getNdbError());
237 pNdb->closeTransaction(pTrans);
238 return -1;
241 int rs;
242 unsigned scan_flags = 0;
243 if (_tup) scan_flags |= NdbScanOperation::SF_TupScan;
244 switch(_lock + (3 * order)){
245 case 1:
246 rs = pOp->readTuples(NdbScanOperation::LM_Read, scan_flags, parallel);
247 break;
248 case 2:
249 rs = pOp->readTuples(NdbScanOperation::LM_Exclusive, scan_flags, parallel);
250 break;
251 case 3:
252 rs = pIOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallel,
253 true, descending);
254 break;
255 case 4:
256 rs = pIOp->readTuples(NdbScanOperation::LM_Read, 0, parallel, true, descending);
257 break;
258 case 5:
259 rs = pIOp->readTuples(NdbScanOperation::LM_Exclusive, 0, parallel, true, descending);
260 break;
261 case 0:
262 default:
263 rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, scan_flags, parallel);
264 break;
266 if( rs != 0 ){
267 ERR(pTrans->getNdbError());
268 pNdb->closeTransaction(pTrans);
269 return -1;
272 if(0){
273 NdbScanFilter sf(pOp);
274 #if 0
275 sf.begin(NdbScanFilter::AND);
276 sf.le(0, (Uint32)10);
278 sf.end();
279 #elif 0
280 sf.begin(NdbScanFilter::OR);
281 sf.begin(NdbScanFilter::AND);
282 sf.ge(0, (Uint32)10);
283 sf.lt(0, (Uint32)20);
284 sf.end();
285 sf.begin(NdbScanFilter::AND);
286 sf.ge(0, (Uint32)30);
287 sf.lt(0, (Uint32)40);
288 sf.end();
289 sf.end();
290 #elif 1
291 sf.begin(NdbScanFilter::AND);
292 sf.begin(NdbScanFilter::OR);
293 sf.begin(NdbScanFilter::AND);
294 sf.ge(0, (Uint32)10);
295 sf.lt(0, (Uint32)20);
296 sf.end();
297 sf.begin(NdbScanFilter::AND);
298 sf.ge(0, (Uint32)30);
299 sf.lt(0, (Uint32)40);
300 sf.end();
301 sf.end();
302 sf.begin(NdbScanFilter::OR);
303 sf.begin(NdbScanFilter::AND);
304 sf.ge(0, (Uint32)0);
305 sf.lt(0, (Uint32)50);
306 sf.end();
307 sf.begin(NdbScanFilter::AND);
308 sf.ge(0, (Uint32)100);
309 sf.lt(0, (Uint32)200);
310 sf.end();
311 sf.end();
312 sf.end();
313 #endif
314 } else {
315 check = pOp->interpret_exit_ok();
316 if( check == -1 ) {
317 ERR(pTrans->getNdbError());
318 pNdb->closeTransaction(pTrans);
319 return -1;
323 bool disk= false;
324 for(int a = 0; a<pTab->getNoOfColumns(); a++)
326 const NdbDictionary::Column* col = pTab->getColumn(a);
327 if(col->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
328 disk= true;
330 if (!nodata)
331 if((row->attributeStore(a) = pOp->getValue(col)) == 0)
333 ERR(pTrans->getNdbError());
334 pNdb->closeTransaction(pTrans);
335 return -1;
339 NdbRecAttr * disk_ref= 0;
340 if(_dumpDisk && disk)
341 disk_ref = pOp->getValue(NdbDictionary::Column::DISK_REF);
343 NdbRecAttr * rowid= 0, *frag = 0, *gci = 0;
344 if (use_rowid)
346 frag = pOp->getValue(NdbDictionary::Column::FRAGMENT);
347 rowid = pOp->getValue(NdbDictionary::Column::ROWID);
350 if (use_gci)
352 gci = pOp->getValue(NdbDictionary::Column::ROW_GCI);
355 check = pTrans->execute(NdbTransaction::NoCommit);
356 if( check == -1 ) {
357 const NdbError err = pTrans->getNdbError();
359 if (err.status == NdbError::TemporaryError){
360 pNdb->closeTransaction(pTrans);
361 NdbSleep_MilliSleep(50);
362 retryAttempt++;
363 continue;
365 ERR(err);
366 pNdb->closeTransaction(pTrans);
367 return -1;
370 if (rowid)
371 ndbout << "ROWID\t";
373 if (gci)
374 ndbout << "\tGCI";
376 if (headers && !nodata)
377 row->header(ndbout);
379 if (disk_ref)
380 ndbout << "\tDISK_REF";
382 ndbout << endl;
384 int eof;
385 int rows = 0;
386 eof = pOp->nextResult();
388 while(eof == 0){
389 rows++;
391 if (useHexFormat)
392 ndbout.setHexFormat(1);
394 if (rowid)
396 ndbout << "[ fragment: " << frag->u_32_value()
397 << " m_page: " << rowid->u_32_value()
398 << " m_page_idx: " << *(Uint32*)(rowid->aRef() + 4) << " ]";
399 ndbout << "\t";
402 if (gci)
404 if (gci->isNULL())
405 ndbout << "NULL\t";
406 else
407 ndbout << gci->u_64_value() << "\t";
410 if (!nodata)
411 ndbout << (*row);
413 if(disk_ref)
415 ndbout << "\t";
416 ndbout << "[ m_file_no: " << *(Uint16*)(disk_ref->aRef()+6)
417 << " m_page: " << disk_ref->u_32_value()
418 << " m_page_idx: " << *(Uint16*)(disk_ref->aRef() + 4) << " ]";
421 if (rowid || disk_ref || gci || !nodata)
422 ndbout << endl;
423 eof = pOp->nextResult();
425 if (eof == -1) {
426 const NdbError err = pTrans->getNdbError();
428 if (err.status == NdbError::TemporaryError){
429 pNdb->closeTransaction(pTrans);
430 NdbSleep_MilliSleep(50);
431 retryAttempt++;
432 continue;
434 ERR(err);
435 pNdb->closeTransaction(pTrans);
436 return -1;
439 pNdb->closeTransaction(pTrans);
441 ndbout << rows << " rows returned" << endl;
443 return 0;
445 return -1;