~mysql/mysql-server/mysql-6.0

« back to all changes in this revision

Viewing changes to storage/falcon/ha_falcon.cpp.bck

  • Committer: antony at xiphis
  • Date: 2007-12-21 22:49:56 UTC
  • mto: (2476.1304.3)
  • mto: This revision was merged to the branch mainline in revision 2573.
  • Revision ID: sp1r-antony@pcg5ppc.xiphis.org-20071221224956-18150
Fix Sparc build, don't build if compiler doesn't support assembler

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2006 MySQL AB
2
 
 
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.
6
 
 
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.
11
 
 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
16
 
/* XXX correct? */
17
 
 
18
 
#ifndef MYSQL_SERVER
19
 
#define MYSQL_SERVER
20
 
#endif
21
 
 
22
 
#include "mysql_priv.h"
23
 
#include "ha_falcon.h"
24
 
#include "StorageConnection.h"
25
 
#include "StorageTable.h"
26
 
#include "StorageTableShare.h"
27
 
#include "StorageHandler.h"
28
 
#include "CmdGen.h"
29
 
#include "InfoTable.h"
30
 
//#include "TimeTest.h"
31
 
#ifdef _WIN32
32
 
#define I64FORMAT                       "%I64d"
33
 
#else
34
 
#define I64FORMAT                       "%lld"
35
 
#endif
36
 
 
37
 
#include "ScaledBinary.h"
38
 
#include "BigInt.h"
39
 
 
40
 
//#define NO_OPTIMIZE
41
 
 
42
 
#ifndef MIN
43
 
#define MIN(a,b)                        ((a <= b) ? (a) : (b))
44
 
#define MAX(a,b)                        ((a >= b) ? (a) : (b))
45
 
#endif
46
 
 
47
 
static const uint LOAD_AUTOCOMMIT_RECORDS = 10000;
48
 
static const char falcon_hton_name[] = "Falcon";
49
 
 
50
 
static const char *falcon_extensions[] = {
51
 
        ".fts",
52
 
        ".fl1",
53
 
        ".fl2",
54
 
        NullS
55
 
};
56
 
 
57
 
static StorageHandler   *storageHandler;
58
 
 
59
 
unsigned long long              falcon_record_memory_max;
60
 
int                                             falcon_record_scavenge_threshold;
61
 
int                                             falcon_record_scavenge_floor;
62
 
unsigned long long              falcon_initial_allocation;
63
 
uint                                    falcon_allocation_extent;
64
 
my_bool                                 falcon_disable_fsync;
65
 
unsigned long long              falcon_page_cache_size;
66
 
uint                                    falcon_page_size;
67
 
uint                                    falcon_serial_log_buffers;
68
 
char*                                   falcon_serial_log_dir;
69
 
char*                                   falcon_checkpoint_schedule;
70
 
char*                                   falcon_scavenge_schedule;
71
 
int                                             falcon_debug_mask;
72
 
my_bool                                 falcon_debug_server;
73
 
FILE                                    *falcon_log_file;
74
 
uint                                    falcon_index_chill_threshold;
75
 
uint                                    falcon_record_chill_threshold;
76
 
uint                                    falcon_tablespace_mode;
77
 
uint                                    falcon_max_transaction_backlog;
78
 
 
79
 
 
80
 
static struct st_mysql_show_var falconStatus[]=
81
 
{
82
 
  //{"static",     (char*)"just a static text",     SHOW_CHAR},
83
 
  //{"called",     (char*)&number_of_calls, SHOW_LONG},
84
 
  {0,0,SHOW_UNDEF}
85
 
};
86
 
 
87
 
extern THD*             current_thd;
88
 
 
89
 
static handler *falcon_create_handler(handlerton *hton,
90
 
                                      TABLE_SHARE *table, MEM_ROOT *mem_root)
91
 
{
92
 
        return new (mem_root) StorageInterface(hton, table);
93
 
}
94
 
 
95
 
handlerton *falcon_hton;
96
 
 
97
 
void openFalconLogFile(const char *file)
98
 
{
99
 
        if (falcon_log_file)
100
 
                fclose(falcon_log_file);
101
 
        falcon_log_file = fopen(file, "a");
102
 
}
103
 
 
104
 
void closeFalconLogFile()
105
 
{
106
 
        if (falcon_log_file)
107
 
                {
108
 
                fclose(falcon_log_file);
109
 
                falcon_log_file = NULL;
110
 
                }
111
 
}
112
 
 
113
 
void flushFalconLogFile()
114
 
{
115
 
        if (falcon_log_file)
116
 
                fflush(falcon_log_file);
117
 
}
118
 
 
119
 
int StorageInterface::falcon_init(void *p)
120
 
{
121
 
        DBUG_ENTER("falcon_init");
122
 
        falcon_hton = (handlerton *)p;
123
 
 
124
 
        if (!storageHandler)
125
 
                storageHandler = getFalconStorageHandler(sizeof(THR_LOCK));
126
 
                
127
 
        falcon_hton->state = SHOW_OPTION_YES;
128
 
        falcon_hton->db_type = DB_TYPE_FALCON;
129
 
        falcon_hton->savepoint_offset = sizeof(void*);
130
 
        falcon_hton->close_connection = StorageInterface::closeConnection;
131
 
        falcon_hton->savepoint_set = StorageInterface::savepointSet;
132
 
        falcon_hton->savepoint_rollback = StorageInterface::savepointRollback;
133
 
        falcon_hton->savepoint_release = StorageInterface::savepointRelease;
134
 
        falcon_hton->commit = StorageInterface::commit;
135
 
        falcon_hton->rollback = StorageInterface::rollback;
136
 
        falcon_hton->create = falcon_create_handler;
137
 
        falcon_hton->drop_database  = StorageInterface::dropDatabase;
138
 
        falcon_hton->panic  = StorageInterface::panic;
139
 
        falcon_hton->alter_table_flags  = StorageInterface::alter_table_flags;
140
 
 
141
 
#ifdef XA_ENABLED
142
 
        falcon_hton->prepare = StorageInterface::prepare;
143
 
#endif
144
 
 
145
 
        falcon_hton->commit_by_xid = StorageInterface::commit_by_xid;
146
 
        falcon_hton->rollback_by_xid = StorageInterface::rollback_by_xid;
147
 
 
148
 
        falcon_hton->alter_tablespace = StorageInterface::alter_tablespace;
149
 
        //falcon_hton->show_status  = StorageInterface::show_status;
150
 
        falcon_hton->flags = HTON_NO_FLAGS;
151
 
 
152
 
        storageHandler->addNfsLogger(-1, StorageInterface::logger, NULL);
153
 
 
154
 
        if (falcon_debug_server)
155
 
                storageHandler->startNfsServer();
156
 
 
157
 
        //TimeTest timeTest;
158
 
        //timeTest.testScaled(16, 2, 100000);
159
 
        
160
 
        //pluginHandler = new NfsPluginHandler;
161
 
        
162
 
        DBUG_RETURN(0);
163
 
}
164
 
 
165
 
 
166
 
int StorageInterface::falcon_deinit(void *p)
167
 
{
168
 
        storageHandler->shutdownHandler();
169
 
        
170
 
        return 0;
171
 
}
172
 
 
173
 
int falcon_strnxfrm (void *cs, 
174
 
                     const char *dst, uint dstlen,
175
 
                     const char *src, uint srclen)
176
 
{
177
 
        CHARSET_INFO *charset = (CHARSET_INFO*) cs;
178
 
 
179
 
        return charset->coll->strnxfrm(charset, (uchar *) dst, dstlen, MAX_INDEX_KEY_LENGTH,
180
 
                                      (uchar *) src, srclen, 0);
181
 
}
182
 
 
183
 
char falcon_get_pad_char (void *cs)
184
 
{
185
 
        return (char) ((CHARSET_INFO*) cs)->pad_char;
186
 
}
187
 
 
188
 
int falcon_cs_is_binary (void *cs)
189
 
{
190
 
        return (0 == strcmp(((CHARSET_INFO*) cs)->name, "binary"));
191
 
//      return ((((CHARSET_INFO*) cs)->state & MY_CS_BINSORT) == MY_CS_BINSORT);
192
 
}
193
 
 
194
 
unsigned int falcon_get_mbmaxlen (void *cs)
195
 
{
196
 
        return ((CHARSET_INFO*) cs)->mbmaxlen;
197
 
}
198
 
 
199
 
char falcon_get_min_sort_char (void *cs)
200
 
{
201
 
        return (char) ((CHARSET_INFO*) cs)->min_sort_char;
202
 
}
203
 
 
204
 
// Return the actual number of characters in the string
205
 
// Note, this is not the number of characters with collatable weight.
206
 
 
207
 
uint falcon_strnchrlen(void *cs, const char *s, uint l)
208
 
{
209
 
        CHARSET_INFO *charset = (CHARSET_INFO*) cs;
210
 
 
211
 
        if (charset->mbmaxlen == 1)
212
 
                return l;
213
 
 
214
 
        uint chrCount = 0;
215
 
        uchar *ch = (uchar *) s;
216
 
        uchar *end = ch + l;
217
 
 
218
 
        while (ch < end)
219
 
                {
220
 
                int len = charset->cset->mbcharlen(charset, *ch);
221
 
                if (len == 0)
222
 
                        break;  // invalid character.
223
 
 
224
 
                ch += len;
225
 
                chrCount++;
226
 
                }
227
 
 
228
 
        return chrCount;
229
 
}
230
 
 
231
 
// Determine how many bytes are required to store the output of cs->coll->strnxfrm()
232
 
// cs is how the source string is formatted.
233
 
// srcLen is the number of bytes in the source string.
234
 
// partialKey is the max key buffer size if not zero.
235
 
// bufSize is the ultimate maximum destSize.
236
 
// If the string is multibyte, strnxfrmlen expects srcLen to be 
237
 
// the maximum number of characters this can be.  Falcon wants to send 
238
 
// a number that represents the actual number of characters in the string
239
 
// so that the call to cs->coll->strnxfrm() will not pad.
240
 
 
241
 
uint falcon_strnxfrmlen(void *cs, const char *s, uint srcLen,
242
 
                                                int partialKey, int bufSize)
243
 
{
244
 
        CHARSET_INFO *charset = (CHARSET_INFO*) cs;
245
 
        uint chrLen = falcon_strnchrlen(cs, s, srcLen);
246
 
        int maxChrLen = partialKey ? min(chrLen, partialKey / charset->mbmaxlen) : chrLen;
247
 
 
248
 
        return min(charset->coll->strnxfrmlen(charset, maxChrLen * charset->mbmaxlen), (uint) bufSize);
249
 
}
250
 
 
251
 
// Return the number of bytes used in s to hold a certain number of characters.
252
 
// This partialKey is a byte length with charset->mbmaxlen figured in.
253
 
// In other words, it is the number of characters times mbmaxlen.
254
 
 
255
 
uint falcon_strntrunc(void *cs, int partialKey, const char *s, uint l)
256
 
{
257
 
        CHARSET_INFO *charset = (CHARSET_INFO*) cs;
258
 
 
259
 
        if ((charset->mbmaxlen == 1) || (partialKey == 0))
260
 
                return min((uint) partialKey, l);
261
 
 
262
 
        int charLimit = partialKey / charset->mbmaxlen;
263
 
        uchar *ch = (uchar *) s;
264
 
        uchar *end = ch + l;
265
 
 
266
 
        while ((ch < end) && charLimit)
267
 
                {
268
 
                int len = charset->cset->mbcharlen(charset, *ch);
269
 
                if (len == 0)
270
 
                        break;  // invalid character.
271
 
 
272
 
                ch += len;
273
 
                charLimit--;
274
 
                }
275
 
 
276
 
        return ch - (uchar *) s;
277
 
}
278
 
 
279
 
int falcon_strnncoll(void *cs, const char *s1, uint l1, const char *s2, uint l2, char flag)
280
 
{
281
 
        CHARSET_INFO *charset = (CHARSET_INFO*) cs;
282
 
 
283
 
        return charset->coll->strnncoll(charset, (uchar *) s1, l1, (uchar *) s2, l2, flag);
284
 
}
285
 
 
286
 
int falcon_strnncollsp(void *cs, const char *s1, uint l1, const char *s2, uint l2, char flag)
287
 
{
288
 
        CHARSET_INFO *charset = (CHARSET_INFO*) cs;
289
 
 
290
 
        return charset->coll->strnncollsp(charset, (uchar *) s1, l1, (uchar *) s2, l2, flag);
291
 
}
292
 
 
293
 
int (*strnncoll)(struct charset_info_st *, const uchar *, uint, const uchar *, uint, my_bool);
294
 
 
295
 
/***
296
 
#ifdef _DEBUG
297
 
#undef THIS_FILE
298
 
static const char THIS_FILE[]=__FILE__;
299
 
#endif
300
 
***/
301
 
 
302
 
#ifndef DIG_PER_DEC1
303
 
typedef decimal_digit_t dec1;
304
 
typedef longlong      dec2;
305
 
 
306
 
#define DIG_PER_DEC1 9
307
 
#define DIG_MASK     100000000
308
 
#define DIG_BASE     1000000000
309
 
#define DIG_MAX      (DIG_BASE-1)
310
 
#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
311
 
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
312
 
#endif
313
 
 
314
 
//////////////////////////////////////////////////////////////////////
315
 
// Construction/Destruction
316
 
//////////////////////////////////////////////////////////////////////
317
 
 
318
 
StorageInterface::StorageInterface(handlerton *hton, st_table_share *table_arg)
319
 
  : handler(hton, table_arg)
320
 
{
321
 
        ref_length = sizeof(lastRecord);
322
 
        stats.records = 1000;
323
 
        stats.data_file_length = 10000;
324
 
        tableLocked = false;
325
 
        lockForUpdate = false;
326
 
        storageTable = NULL;
327
 
        storageConnection = NULL;
328
 
        storageShare = NULL;
329
 
        share = table_arg;
330
 
        lastRecord = -1;
331
 
        mySqlThread = NULL;
332
 
        activeBlobs = NULL;
333
 
        freeBlobs = NULL;
334
 
        errorText = NULL;
335
 
        
336
 
        if (table_arg)
337
 
                {
338
 
                recordLength = table_arg->reclength;
339
 
                tempTable = false;
340
 
                }
341
 
}
342
 
 
343
 
 
344
 
StorageInterface::~StorageInterface(void)
345
 
{
346
 
        if (activeBlobs)
347
 
                freeActiveBlobs();
348
 
 
349
 
        for (StorageBlob *blob; (blob = freeBlobs); )
350
 
                {
351
 
                freeBlobs = blob->next;
352
 
                delete blob;
353
 
                }
354
 
 
355
 
        if (storageTable)
356
 
                {
357
 
                storageTable->deleteStorageTable();
358
 
                storageTable = NULL;
359
 
                }
360
 
 
361
 
        if (storageConnection)
362
 
                {
363
 
                storageConnection->release();
364
 
                storageConnection = NULL;
365
 
                }
366
 
 
367
 
        //delete [] dbName;
368
 
}
369
 
 
370
 
int StorageInterface::rnd_init(bool scan)
371
 
{
372
 
        DBUG_ENTER("StorageInterface::rnd_init");
373
 
        nextRecord = 0;
374
 
        lastRecord = -1;
375
 
 
376
 
        DBUG_RETURN(0);
377
 
}
378
 
 
379
 
 
380
 
int StorageInterface::open(const char *name, int mode, uint test_if_locked)
381
 
{
382
 
        DBUG_ENTER("StorageInterface::open");
383
 
        
384
 
        if (!mySqlThread)
385
 
                mySqlThread = current_thd;
386
 
                
387
 
        if (!storageTable)
388
 
                {
389
 
                storageShare = storageHandler->findTable(name);
390
 
                storageConnection = storageHandler->getStorageConnection(storageShare, mySqlThread, mySqlThread->thread_id, OpenDatabase, falcon_tablespace_mode);
391
 
                
392
 
                if (!storageConnection)
393
 
                        DBUG_RETURN(HA_ERR_NO_CONNECTION);
394
 
                
395
 
                *((StorageConnection**) thd_ha_data(mySqlThread, falcon_hton)) = storageConnection;
396
 
                storageConnection->addRef();
397
 
                storageTable = storageConnection->getStorageTable(storageShare);
398
 
                
399
 
                if (!storageShare->initialized)
400
 
                        {
401
 
                        storageShare->lock(true);
402
 
                        
403
 
                        if (!storageShare->initialized)
404
 
                                {
405
 
                                thr_lock_init((THR_LOCK *)storageShare->impure);
406
 
                                storageShare->setTablePath(name, tempTable);
407
 
                                storageShare->initialized = true;
408
 
                                }
409
 
                        
410
 
                        // Register any collations used
411
 
                        
412
 
                        uint fieldCount = (table) ? table->s->fields : 0;
413
 
                        
414
 
                        for (uint n = 0; n < fieldCount; ++n)
415
 
                                {
416
 
                                Field *field = table->field[n];
417
 
                                CHARSET_INFO *charset = field->charset();
418
 
                                
419
 
                                if (charset)
420
 
                                        storageShare->registerCollation(charset->name, charset);
421
 
                                }
422
 
 
423
 
                        storageShare->unlock();
424
 
                        }
425
 
                }
426
 
 
427
 
        int ret = storageTable->open();
428
 
 
429
 
        if (ret)
430
 
                DBUG_RETURN(error(ret));
431
 
 
432
 
        thr_lock_data_init((THR_LOCK *)storageShare->impure, &lockData, NULL);
433
 
 
434
 
        ret = setIndexes();
435
 
        if (ret)
436
 
                DBUG_RETURN(error(ret));
437
 
 
438
 
        DBUG_RETURN(0);
439
 
}
440
 
 
441
 
 
442
 
StorageConnection* StorageInterface::getStorageConnection(THD* thd)
443
 
{
444
 
        return *(StorageConnection**) thd_ha_data(thd, falcon_hton);
445
 
}
446
 
 
447
 
int StorageInterface::close(void)
448
 
{
449
 
  DBUG_ENTER("StorageInterface::close");
450
 
  DBUG_RETURN(0);
451
 
}
452
 
 
453
 
int StorageInterface::rnd_next(uchar *buf)
454
 
{
455
 
        DBUG_ENTER("StorageInterface::rnd_next");
456
 
        ha_statistic_increment(&SSV::ha_read_rnd_next_count);
457
 
 
458
 
        if (activeBlobs)
459
 
                freeActiveBlobs();
460
 
 
461
 
        lastRecord = storageTable->next(nextRecord, lockForUpdate);
462
 
 
463
 
        if (lastRecord < 0)
464
 
                {
465
 
                if (lastRecord == StorageErrorRecordNotFound)
466
 
                        {
467
 
                        lastRecord = -1;
468
 
                        table->status = STATUS_NOT_FOUND;
469
 
                        DBUG_RETURN(HA_ERR_END_OF_FILE);
470
 
                        }
471
 
                
472
 
                DBUG_RETURN(error(lastRecord));
473
 
                }
474
 
        else
475
 
                table->status = 0;
476
 
 
477
 
        decodeRecord(buf);
478
 
        nextRecord = lastRecord + 1;
479
 
 
480
 
        DBUG_RETURN(0);
481
 
}
482
 
 
483
 
 
484
 
void StorageInterface::unlock_row(void)
485
 
{
486
 
        storageTable->unlockRow();
487
 
}
488
 
 
489
 
int StorageInterface::rnd_pos(uchar *buf, uchar *pos)
490
 
{
491
 
        int recordNumber;
492
 
        DBUG_ENTER("StorageInterface::rnd_pos");
493
 
        ha_statistic_increment(&SSV::ha_read_rnd_next_count);
494
 
 
495
 
        memcpy(&recordNumber, pos, sizeof(recordNumber));
496
 
 
497
 
        if (activeBlobs)
498
 
                freeActiveBlobs();
499
 
 
500
 
        int ret = storageTable->fetch(recordNumber, lockForUpdate);
501
 
 
502
 
        if (ret)
503
 
                {
504
 
                table->status = STATUS_NOT_FOUND;
505
 
                DBUG_RETURN(error(ret));
506
 
                }
507
 
 
508
 
        lastRecord = recordNumber;
509
 
        decodeRecord(buf);
510
 
        table->status = 0;
511
 
 
512
 
        DBUG_RETURN(0);
513
 
}
514
 
 
515
 
void StorageInterface::position(const uchar *record)
516
 
{
517
 
  DBUG_ENTER("StorageInterface::position");
518
 
  memcpy(ref, &lastRecord, sizeof(lastRecord));
519
 
  DBUG_VOID_RETURN;
520
 
}
521
 
 
522
 
int StorageInterface::info(uint what)
523
 
{
524
 
        DBUG_ENTER("StorageInterface::info");
525
 
 
526
 
#ifndef NO_OPTIMIZE
527
 
        if (what & HA_STATUS_VARIABLE)
528
 
                getDemographics();
529
 
#endif
530
 
 
531
 
        if (what & HA_STATUS_AUTO)
532
 
                stats.auto_increment_value = storageShare->getSequenceValue(0);
533
 
 
534
 
        if (what & HA_STATUS_ERRKEY)
535
 
                errkey = indexErrorId;
536
 
 
537
 
        DBUG_RETURN(0);
538
 
}
539
 
 
540
 
 
541
 
void StorageInterface::getDemographics(void)
542
 
{
543
 
        DBUG_ENTER("StorageInterface::getDemographics");
544
 
 
545
 
        stats.records = (ha_rows) storageShare->estimateCardinality();
546
 
        // Temporary fix for Bug#28686. (HK) 2007-05-26.
547
 
        if (!stats.records)
548
 
                stats.records = 2;
549
 
 
550
 
        stats.block_size = 4096;
551
 
 
552
 
        for (uint n = 0; n < table->s->keys; ++n)
553
 
                {
554
 
                KEY *key = table->s->key_info + n;
555
 
                StorageIndexDesc *desc = storageShare->getIndex(n);
556
 
                
557
 
                if (desc)
558
 
                        {
559
 
                        ha_rows n = 1 << desc->numberSegments;
560
 
                        
561
 
                        for (uint segment = 0; segment < key->key_parts; ++segment, n >>= 1)
562
 
                                {
563
 
                                ha_rows recordsPerSegment = (ha_rows) desc->segmentRecordCounts[segment];
564
 
                                key->rec_per_key[segment] = MAX(recordsPerSegment, n);
565
 
                                }
566
 
                        }
567
 
                }
568
 
 
569
 
        DBUG_VOID_RETURN;
570
 
}
571
 
 
572
 
int StorageInterface::optimize(THD* thd, HA_CHECK_OPT* check_opt)
573
 
{
574
 
        DBUG_ENTER("StorageInterface::optimize");
575
 
 
576
 
        int ret = storageTable->optimize();
577
 
        
578
 
        if (ret)
579
 
                DBUG_RETURN(error(ret));
580
 
 
581
 
        DBUG_RETURN(0);
582
 
}
583
 
 
584
 
uint8 StorageInterface::table_cache_type(void)
585
 
{
586
 
        return HA_CACHE_TBL_TRANSACT;
587
 
}
588
 
 
589
 
const char *StorageInterface::table_type(void) const
590
 
{
591
 
        DBUG_ENTER("StorageInterface::table_type");
592
 
        DBUG_RETURN(falcon_hton_name);
593
 
}
594
 
 
595
 
 
596
 
const char **StorageInterface::bas_ext(void) const
597
 
{
598
 
        DBUG_ENTER("StorageInterface::bas_ext");
599
 
        DBUG_RETURN(falcon_extensions);
600
 
}
601
 
 
602
 
 
603
 
ulonglong StorageInterface::table_flags(void) const
604
 
{
605
 
        DBUG_ENTER("StorageInterface::table_flags");
606
 
        DBUG_RETURN(HA_REC_NOT_IN_SEQ | HA_NULL_IN_KEY | HA_AUTO_PART_KEY |
607
 
                    HA_PARTIAL_COLUMN_READ | HA_CAN_GEOMETRY);
608
 
}
609
 
 
610
 
 
611
 
ulong StorageInterface::index_flags(uint idx, uint part, bool all_parts) const
612
 
{
613
 
        DBUG_ENTER("StorageInterface::index_flags");
614
 
        DBUG_RETURN(HA_READ_RANGE | HA_KEY_SCAN_NOT_ROR);
615
 
}
616
 
 
617
 
 
618
 
int StorageInterface::create(const char *mySqlName, TABLE *form,
619
 
                            HA_CREATE_INFO *info)
620
 
{
621
 
        DBUG_ENTER("StorageInterface::create");
622
 
        tempTable = (info->options & HA_LEX_CREATE_TMP_TABLE) ? true : false;
623
 
        OpenOption openOption = (tempTable) ? OpenTemporaryDatabase : OpenOrCreateDatabase;
624
 
 
625
 
        if (storageTable)
626
 
                {
627
 
                storageTable->deleteStorageTable();
628
 
                storageTable = NULL;
629
 
                }
630
 
        
631
 
        if (!mySqlThread)
632
 
                mySqlThread = current_thd;
633
 
        
634
 
        storageShare = storageHandler->createTable(mySqlName, info->tablespace, tempTable);
635
 
        
636
 
        if (!storageShare)
637
 
                DBUG_RETURN(HA_ERR_TABLE_EXIST);
638
 
 
639
 
        storageConnection = storageHandler->getStorageConnection(storageShare, mySqlThread, mySqlThread->thread_id, openOption, falcon_tablespace_mode);
640
 
        *((StorageConnection**) thd_ha_data(mySqlThread, falcon_hton)) = storageConnection;
641
 
        
642
 
        if (!storageConnection)
643
 
                DBUG_RETURN(HA_ERR_NO_CONNECTION);
644
 
        
645
 
        storageTable = storageConnection->getStorageTable(storageShare);
646
 
        storageTable->localTable = this;
647
 
 
648
 
        int ret;
649
 
        int64 incrementValue = 0;
650
 
        uint n;
651
 
        CmdGen gen;
652
 
        const char *tableName = storageTable->getName();
653
 
        const char *schemaName = storageTable->getSchemaName();
654
 
        gen.gen("create table \"%s\".\"%s\" (\n", schemaName, tableName);
655
 
        const char *sep = "";
656
 
        char nameBuffer[129];
657
 
 
658
 
        for (n = 0; n < form->s->fields; ++n)
659
 
                {
660
 
                Field *field = form->field[n];
661
 
                CHARSET_INFO *charset = field->charset();
662
 
                
663
 
                if (charset)
664
 
                        storageShare->registerCollation(charset->name, charset);
665
 
 
666
 
                storageShare->cleanupFieldName(field->field_name, nameBuffer,
667
 
                                                                                sizeof(nameBuffer));
668
 
                gen.gen("%s  \"%s\" ", sep, nameBuffer);
669
 
                int ret = genType(field, &gen);
670
 
 
671
 
                if (ret)
672
 
                        DBUG_RETURN(ret);
673
 
                
674
 
                if (!field->maybe_null())
675
 
                        gen.gen(" not null");
676
 
                        
677
 
                sep = ",\n";
678
 
                }
679
 
 
680
 
        if (form->found_next_number_field) // && form->s->next_number_key_offset == 0)
681
 
                {
682
 
                incrementValue = info->auto_increment_value;
683
 
 
684
 
                if (incrementValue == 0)
685
 
                        incrementValue = 1;
686
 
                }
687
 
 
688
 
        if (form->s->primary_key < form->s->keys)
689
 
                {
690
 
                KEY *key = form->key_info + form->s->primary_key;
691
 
                gen.gen(",\n  primary key ");
692
 
                genKeyFields(key, &gen);
693
 
                }
694
 
 
695
 
        gen.gen (")");
696
 
        const char *tableSpace = NULL;
697
 
        
698
 
        if (falcon_tablespace_mode == (uint)TABLESPACE_INTERNAL)
699
 
                {
700
 
                if (tempTable)
701
 
                        tableSpace = TEMPORARY_TABLESPACE;
702
 
                else if (info->tablespace)
703
 
                        tableSpace = info->tablespace;
704
 
                else
705
 
                        tableSpace = DEFAULT_TABLESPACE;
706
 
                }
707
 
        
708
 
        if (tableSpace)
709
 
                gen.gen(" tablespace %s", tableSpace);
710
 
 
711
 
        DBUG_PRINT("info",("incrementValue = " I64FORMAT, (long long int)incrementValue));
712
 
 
713
 
        if ((ret = storageTable->create(gen.getString(), incrementValue)))
714
 
                DBUG_RETURN(error(ret));
715
 
 
716
 
        for (n = 0; n < form->s->keys; ++n)
717
 
                if (n != form->s->primary_key)
718
 
                        if ((ret = createIndex(schemaName, tableName, form->key_info + n, n)))
719
 
                                {
720
 
                                storageTable->deleteTable();
721
 
                                
722
 
                                DBUG_RETURN(error(ret));
723
 
                                }
724
 
 
725
 
        DBUG_RETURN(0);
726
 
}
727
 
 
728
 
int StorageInterface::add_index(TABLE* table_arg, KEY* key_info, uint num_of_keys)
729
 
{
730
 
        DBUG_ENTER("StorageInterface::add_index");
731
 
        int ret = createIndex(storageTable->getSchemaName(), storageTable->getName(), key_info, table_arg->s->keys);
732
 
        
733
 
        DBUG_RETURN(ret);
734
 
}
735
 
 
736
 
int StorageInterface::createIndex(const char *schemaName, const char *tableName,
737
 
                                 KEY *key, int indexNumber)
738
 
{
739
 
        CmdGen gen;
740
 
        const char *unique = (key->flags & HA_NOSAME) ? "unique " : "";
741
 
        gen.gen("create %sindex \"%s$%d\" on %s.\"%s\" ", unique, tableName,
742
 
                indexNumber, schemaName, tableName);
743
 
        genKeyFields(key, &gen);
744
 
        const char *sql = gen.getString();
745
 
 
746
 
        return storageTable->share->createIndex(storageConnection, key->name, sql);
747
 
}
748
 
 
749
 
#if 0
750
 
uint StorageInterface::alter_table_flags(uint flags)
751
 
{
752
 
        if (flags & ALTER_DROP_PARTITION)
753
 
                return 0;
754
 
 
755
 
        return HA_ONLINE_ADD_INDEX | HA_ONLINE_ADD_UNIQUE_INDEX;
756
 
}
757
 
#endif
758
 
 
759
 
bool StorageInterface::check_if_incompatible_data(HA_CREATE_INFO* create_info, uint table_changes)
760
 
{
761
 
        if (true || create_info->auto_increment_value != 0)
762
 
                return COMPATIBLE_DATA_NO;
763
 
                
764
 
        return COMPATIBLE_DATA_YES;
765
 
}
766
 
 
767
 
THR_LOCK_DATA **StorageInterface::store_lock(THD *thd, THR_LOCK_DATA **to,
768
 
                                            enum thr_lock_type lock_type)
769
 
{
770
 
        DBUG_ENTER("StorageInterface::store_lock");
771
 
        //lockForUpdate = (lock_type == TL_WRITE && thd->lex->sql_command == SQLCOM_SELECT);
772
 
        lockForUpdate = (lock_type == TL_WRITE);
773
 
        
774
 
        if (lock_type != TL_IGNORE && lockData.type == TL_UNLOCK)
775
 
                {
776
 
                /*
777
 
                  Here is where we get into the guts of a row level lock.
778
 
                  If TL_UNLOCK is set
779
 
                  If we are not doing a LOCK TABLE or DISCARD/IMPORT
780
 
                  TABLESPACE, then allow multiple writers
781
 
                */
782
 
 
783
 
                if ( (lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) &&
784
 
                     !thd_in_lock_tables(thd))
785
 
                        lock_type = TL_WRITE_ALLOW_WRITE;
786
 
 
787
 
                /*
788
 
                  In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
789
 
                  MySQL would use the lock TL_READ_NO_INSERT on t2, and that
790
 
                  would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
791
 
                  to t2. Convert the lock to a normal read lock to allow
792
 
                  concurrent inserts to t2.
793
 
                */
794
 
 
795
 
                #ifdef XXX_TALK_TO_SERGEI
796
 
                if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd))
797
 
                        lock_type = TL_READ;
798
 
                #endif
799
 
 
800
 
 
801
 
                lockData.type = lock_type;
802
 
                }
803
 
 
804
 
        *to++ = &lockData;
805
 
        DBUG_RETURN(to);
806
 
}
807
 
 
808
 
 
809
 
int StorageInterface::delete_table(const char *tableName)
810
 
{
811
 
        DBUG_ENTER("StorageInterface::delete_table");
812
 
        
813
 
        if (!mySqlThread)
814
 
                mySqlThread = current_thd;
815
 
                
816
 
        if (!storageShare)
817
 
                storageShare = storageHandler->findTable(tableName);
818
 
        
819
 
        if (!storageConnection)
820
 
                if ( !(storageConnection = storageHandler->getStorageConnection(storageShare, mySqlThread, mySqlThread->thread_id, OpenDatabase, falcon_tablespace_mode)) )
821
 
                        DBUG_RETURN(0);
822
 
 
823
 
        if (!storageTable)
824
 
                storageTable = storageConnection->getStorageTable(storageShare);
825
 
        
826
 
        if (storageShare)
827
 
                {
828
 
                storageShare->lock(true);
829
 
 
830
 
                if (storageShare->initialized)
831
 
                        {
832
 
                        thr_lock_delete((THR_LOCK*) storageShare->impure);
833
 
                        storageShare->initialized = false;
834
 
                        //DBUG_ASSERT(false);
835
 
                        }
836
 
 
837
 
                storageShare->unlock();
838
 
                }
839
 
 
840
 
        int res = storageTable->deleteTable();
841
 
        storageTable->deleteStorageTable();
842
 
        storageTable = NULL;
843
 
 
844
 
        if (res == StorageErrorTableNotFound)
845
 
                res = 0;
846
 
                
847
 
        DBUG_RETURN(error(res));
848
 
}
849
 
 
850
 
uint StorageInterface::max_supported_keys(void) const
851
 
{
852
 
        DBUG_ENTER("StorageInterface::max_supported_keys");
853
 
        DBUG_RETURN(MAX_KEY);
854
 
}
855
 
 
856
 
 
857
 
int StorageInterface::write_row(uchar *buff)
858
 
{
859
 
        DBUG_ENTER("StorageInterface::write_row");
860
 
        ha_statistic_increment(&SSV::ha_write_count);
861
 
 
862
 
        /* If we have a timestamp column, update it to the current time */
863
 
 
864
 
        if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
865
 
                table->timestamp_field->set_time();
866
 
 
867
 
        /*
868
 
                If we have an auto_increment column and we are writing a changed row
869
 
                or a new row, then update the auto_increment value in the record.
870
 
        */
871
 
 
872
 
        if (table->next_number_field && buff == table->record[0])
873
 
                {
874
 
                update_auto_increment();
875
 
 
876
 
                /*
877
 
                   If the new value is less than the current highest value, it will be
878
 
                   ignored by setSequenceValue().
879
 
                */
880
 
 
881
 
                int code = storageShare->setSequenceValue(table->next_number_field->val_int());
882
 
                
883
 
                if (code)
884
 
                        DBUG_RETURN(error(code));
885
 
                }
886
 
 
887
 
        encodeRecord(buff, false);
888
 
        lastRecord = storageTable->insert();
889
 
 
890
 
        if (lastRecord < 0)
891
 
                {
892
 
                int code = lastRecord >> StoreErrorIndexShift;
893
 
                indexErrorId = (lastRecord & StoreErrorIndexMask) - 1;
894
 
                
895
 
                DBUG_RETURN(error(code));
896
 
                }
897
 
 
898
 
        if (++insertCount > LOAD_AUTOCOMMIT_RECORDS)
899
 
                switch (thd_sql_command(mySqlThread))
900
 
                        {
901
 
                        case SQLCOM_LOAD:
902
 
                        case SQLCOM_ALTER_TABLE:
903
 
                                storageHandler->commit(mySqlThread);
904
 
                                storageConnection->startTransaction(thd_tx_isolation(mySqlThread));
905
 
                                storageConnection->markVerb();
906
 
                                insertCount = 0;
907
 
                                break;
908
 
                        
909
 
                        default:
910
 
                                ;
911
 
                        }
912
 
 
913
 
        DBUG_RETURN(0);
914
 
}
915
 
 
916
 
 
917
 
int StorageInterface::update_row(const uchar* oldData, uchar* newData)
918
 
{
919
 
        DBUG_ENTER("StorageInterface::update_row");
920
 
        DBUG_ASSERT (lastRecord >= 0);
921
 
 
922
 
        ha_statistic_increment(&SSV::ha_update_count);
923
 
 
924
 
        /* If we have a timestamp column, update it to the current time */
925
 
        
926
 
        if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
927
 
                table->timestamp_field->set_time();
928
 
 
929
 
        /* If we have an auto_increment column, update the sequence value.  */
930
 
 
931
 
        Field *autoInc = table->found_next_number_field;
932
 
        
933
 
        if ((autoInc) && bitmap_is_set(table->read_set, autoInc->field_index))
934
 
                {
935
 
                int code = storageShare->setSequenceValue(autoInc->val_int());
936
 
                
937
 
                if (code)
938
 
                        DBUG_RETURN(error(code));
939
 
                }
940
 
 
941
 
        encodeRecord(newData, true);
942
 
 
943
 
        int ret = storageTable->updateRow(lastRecord);
944
 
 
945
 
        if (ret)
946
 
                {
947
 
                int code = ret >> StoreErrorIndexShift;
948
 
                indexErrorId = (ret & StoreErrorIndexMask) - 1;
949
 
                DBUG_RETURN(error(code));
950
 
                }
951
 
 
952
 
        DBUG_RETURN(0);
953
 
}
954
 
 
955
 
 
956
 
int StorageInterface::delete_row(const uchar* buf)
957
 
{
958
 
        DBUG_ENTER("StorageInterface::delete_row");
959
 
        DBUG_ASSERT (lastRecord >= 0);
960
 
        ha_statistic_increment(&SSV::ha_delete_count);
961
 
 
962
 
        if (activeBlobs)
963
 
                freeActiveBlobs();
964
 
 
965
 
        int ret = storageTable->deleteRow(lastRecord);
966
 
 
967
 
        if (ret < 0)
968
 
                DBUG_RETURN(error(ret));
969
 
 
970
 
        lastRecord = -1;
971
 
 
972
 
        DBUG_RETURN(0);
973
 
}
974
 
 
975
 
 
976
 
int StorageInterface::commit(handlerton *hton, THD* thd, bool all)
977
 
{
978
 
        DBUG_ENTER("StorageInterface::commit");
979
 
        StorageConnection *storageConnection = getStorageConnection(thd);
980
 
        
981
 
        if (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
982
 
                {
983
 
                if (storageConnection)
984
 
                        storageConnection->commit();
985
 
                else
986
 
                        storageHandler->commit(thd);
987
 
                }
988
 
        else
989
 
                {
990
 
                if (storageConnection)
991
 
                        storageConnection->releaseVerb();
992
 
                else
993
 
                        storageHandler->releaseVerb(thd);
994
 
                }
995
 
        
996
 
        DBUG_RETURN(0);
997
 
}
998
 
 
999
 
int StorageInterface::prepare(handlerton* hton, THD* thd, bool all)
1000
 
{
1001
 
        DBUG_ENTER("StorageInterface::prepare");
1002
 
 
1003
 
        if (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
1004
 
                storageHandler->prepare(thd, sizeof(thd->transaction.xid), (const unsigned char*) &thd->transaction.xid);
1005
 
        else
1006
 
                {
1007
 
                StorageConnection *storageConnection = getStorageConnection(thd);
1008
 
                
1009
 
                if (storageConnection)
1010
 
                        storageConnection->releaseVerb();
1011
 
                else
1012
 
                        storageHandler->releaseVerb(thd);
1013
 
                }
1014
 
        
1015
 
        DBUG_RETURN(0);
1016
 
}
1017
 
 
1018
 
int StorageInterface::rollback(handlerton *hton, THD *thd, bool all)
1019
 
{
1020
 
        DBUG_ENTER("StorageInterface::rollback");
1021
 
        StorageConnection *storageConnection = getStorageConnection(thd);
1022
 
 
1023
 
        if (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
1024
 
                {
1025
 
                if (storageConnection)
1026
 
                        storageConnection->rollback();
1027
 
                else
1028
 
                        storageHandler->rollback(thd);
1029
 
                }
1030
 
        else
1031
 
                {
1032
 
                if (storageConnection)
1033
 
                        storageConnection->rollbackVerb();
1034
 
                else
1035
 
                        storageHandler->rollbackVerb(thd);
1036
 
                }
1037
 
        
1038
 
        DBUG_RETURN(0);
1039
 
}
1040
 
 
1041
 
int StorageInterface::commit_by_xid(handlerton* hton, XID* xid)
1042
 
{
1043
 
        DBUG_ENTER("StorageInterface::commit_by_xid");
1044
 
        int ret = storageHandler->commitByXID(sizeof(XID), (const unsigned char*) xid);
1045
 
        DBUG_RETURN(ret);
1046
 
}
1047
 
 
1048
 
int StorageInterface::rollback_by_xid(handlerton* hton, XID* xid)
1049
 
{
1050
 
        DBUG_ENTER("StorageInterface::rollback_by_xid");
1051
 
        int ret = storageHandler->rollbackByXID(sizeof(XID), (const unsigned char*) xid);
1052
 
        DBUG_RETURN(ret);
1053
 
}
1054
 
 
1055
 
const COND* StorageInterface::cond_push(const COND* cond)
1056
 
{
1057
 
#ifdef COND_PUSH_ENABLED
1058
 
        DBUG_ENTER("StorageInterface::cond_push");
1059
 
        char buff[256];
1060
 
        String str(buff,(uint32) sizeof(buff), system_charset_info);
1061
 
        str.length(0);
1062
 
        Item *cond_ptr= (COND *)cond;
1063
 
        cond_ptr->print(&str);
1064
 
        str.append('\0');
1065
 
        DBUG_PRINT("StorageInterface::cond_push", ("%s", str.ptr()));
1066
 
        DBUG_RETURN(0);
1067
 
#else
1068
 
        return handler::cond_push(cond);
1069
 
#endif
1070
 
}
1071
 
 
1072
 
void StorageInterface::startTransaction(void)
1073
 
{
1074
 
        threadSwitch(table->in_use);
1075
 
 
1076
 
        if (!storageConnection->transactionActive)
1077
 
                {
1078
 
                storageConnection->startTransaction(thd_tx_isolation(mySqlThread));
1079
 
                trans_register_ha(mySqlThread, true, falcon_hton);
1080
 
                }
1081
 
 
1082
 
        switch (thd_tx_isolation(mySqlThread))
1083
 
                {
1084
 
                case ISO_READ_UNCOMMITTED:
1085
 
                        error(StorageWarningReadUncommitted);
1086
 
                        break;
1087
 
                        
1088
 
                case ISO_SERIALIZABLE:
1089
 
                        error(StorageWarningSerializable);
1090
 
                        break;
1091
 
                }
1092
 
}
1093
 
 
1094
 
 
1095
 
int StorageInterface::savepointSet(handlerton *hton, THD *thd, void *savePoint)
1096
 
{
1097
 
        return storageHandler->savepointSet(thd, savePoint);
1098
 
}
1099
 
 
1100
 
 
1101
 
int StorageInterface::savepointRollback(handlerton *hton, THD *thd, void *savePoint)
1102
 
{
1103
 
        return storageHandler->savepointRollback(thd, savePoint);
1104
 
}
1105
 
 
1106
 
 
1107
 
int StorageInterface::savepointRelease(handlerton *hton, THD *thd, void *savePoint)
1108
 
{
1109
 
        return storageHandler->savepointRelease(thd, savePoint);
1110
 
}
1111
 
 
1112
 
 
1113
 
int StorageInterface::index_read(uchar *buf, const uchar *keyBytes, uint key_len,
1114
 
                                enum ha_rkey_function find_flag)
1115
 
{
1116
 
        DBUG_ENTER("StorageInterface::index_read");
1117
 
        int ret, which = 0;
1118
 
        ha_statistic_increment(&SSV::ha_read_key_count);
1119
 
 
1120
 
        // XXX This needs to be revisited
1121
 
        switch(find_flag) 
1122
 
                {
1123
 
                case HA_READ_KEY_EXACT:
1124
 
                        which = UpperBound | LowerBound;
1125
 
                        break;
1126
 
                        
1127
 
                case HA_READ_KEY_OR_NEXT:
1128
 
                        storageTable->setPartialKey();
1129
 
                        which = LowerBound;
1130
 
                        break;
1131
 
                        
1132
 
                case HA_READ_AFTER_KEY:     // ???
1133
 
                        if (!storageTable->isKeyNull((const unsigned char*) keyBytes, key_len))
1134
 
                                which = LowerBound;
1135
 
 
1136
 
                        break;
1137
 
 
1138
 
                case HA_READ_BEFORE_KEY:    // ???
1139
 
                case HA_READ_PREFIX_LAST_OR_PREV: // ???
1140
 
                case HA_READ_PREFIX_LAST:   // ???
1141
 
                case HA_READ_PREFIX:
1142
 
                case HA_READ_KEY_OR_PREV:
1143
 
                default:
1144
 
                        DBUG_RETURN(HA_ERR_UNSUPPORTED);
1145
 
                }
1146
 
 
1147
 
        const unsigned char *key = (const unsigned char*) keyBytes;
1148
 
        
1149
 
        if (which)
1150
 
                if ((ret = storageTable->setIndexBound(key, key_len, which)))
1151
 
                        DBUG_RETURN(error(ret));
1152
 
 
1153
 
        if ((ret = storageTable->indexScan()))
1154
 
                DBUG_RETURN(error(ret));
1155
 
 
1156
 
        nextRecord = 0;
1157
 
        
1158
 
        for (;;)
1159
 
                {
1160
 
                int ret = index_next(buf);
1161
 
                
1162
 
                if (ret)
1163
 
                        DBUG_RETURN(ret);
1164
 
                
1165
 
                int comparison = storageTable->compareKey(key, key_len);
1166
 
                
1167
 
                if ((which & LowerBound) && comparison < 0)
1168
 
                        continue;
1169
 
                
1170
 
                if ((which & UpperBound) && comparison > 0)
1171
 
                        continue;
1172
 
                
1173
 
                DBUG_RETURN(0);
1174
 
                }
1175
 
}
1176
 
 
1177
 
 
1178
 
int StorageInterface::index_init(uint idx, bool sorted)
1179
 
{
1180
 
        DBUG_ENTER("StorageInterface::index_init");
1181
 
        active_index = idx;
1182
 
        nextRecord = 0;
1183
 
        haveStartKey = false;
1184
 
        haveEndKey = false;
1185
 
        
1186
 
        if (!storageTable->setIndex(idx))
1187
 
                DBUG_RETURN(0);
1188
 
 
1189
 
        StorageIndexDesc indexDesc;
1190
 
        getKeyDesc(table->key_info + idx, &indexDesc);
1191
 
 
1192
 
        if (idx == table->s->primary_key)
1193
 
                indexDesc.primaryKey = true;
1194
 
 
1195
 
        int ret = storageTable->setIndex(table->s->keys, idx, &indexDesc);
1196
 
 
1197
 
        if (ret)
1198
 
                DBUG_RETURN(error(ret));
1199
 
 
1200
 
        DBUG_RETURN(0);
1201
 
}
1202
 
 
1203
 
 
1204
 
int StorageInterface::index_end(void)
1205
 
{
1206
 
        DBUG_ENTER("StorageInterface::index_end");
1207
 
        storageTable->indexEnd();
1208
 
        DBUG_RETURN(0);
1209
 
}
1210
 
 
1211
 
ha_rows StorageInterface::records_in_range(uint indexId, key_range *lower,
1212
 
                                         key_range *upper)
1213
 
{
1214
 
        DBUG_ENTER("StorageInterface::records_in_range");
1215
 
 
1216
 
#ifdef NO_OPTIMIZE
1217
 
        DBUG_RETURN(handler::records_in_range(indexId, lower, upper));
1218
 
#endif
1219
 
 
1220
 
        ha_rows cardinality = (ha_rows) storageShare->estimateCardinality();
1221
 
 
1222
 
        if (!lower)
1223
 
                DBUG_RETURN(MAX(cardinality, 2));
1224
 
        
1225
 
        StorageIndexDesc *index = storageShare->getIndex(indexId);
1226
 
        
1227
 
        if (!index)
1228
 
                DBUG_RETURN(MAX(cardinality, 2));
1229
 
        
1230
 
        int numberSegments = 0;
1231
 
        
1232
 
        for (int map = lower->keypart_map; map; map >>= 1)
1233
 
                ++numberSegments;
1234
 
 
1235
 
        if (index->unique && numberSegments == index->numberSegments)
1236
 
                DBUG_RETURN(1);
1237
 
 
1238
 
        ha_rows segmentRecords = (ha_rows) index->segmentRecordCounts[numberSegments - 1];
1239
 
        ha_rows guestimate = cardinality;
1240
 
 
1241
 
        if (lower->flag == HA_READ_KEY_EXACT)
1242
 
                {
1243
 
                if (segmentRecords)
1244
 
                        guestimate = segmentRecords;
1245
 
                else
1246
 
                        for (int n = 0; n < numberSegments; ++n)
1247
 
                                guestimate /= 10;       
1248
 
                }
1249
 
        else
1250
 
                guestimate /= 3;
1251
 
 
1252
 
        DBUG_RETURN(MAX(guestimate, 2));
1253
 
}
1254
 
 
1255
 
 
1256
 
void StorageInterface::getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo)
1257
 
{
1258
 
        int numberKeys = keyInfo->key_parts;
1259
 
        indexInfo->numberSegments = numberKeys;
1260
 
        indexInfo->name = keyInfo->name;
1261
 
        indexInfo->unique = (keyInfo->flags & HA_NOSAME);
1262
 
        indexInfo->primaryKey = false;
1263
 
 
1264
 
        for (int n = 0; n < numberKeys; ++n) 
1265
 
                {
1266
 
                StorageSegment *segment = indexInfo->segments + n;
1267
 
                KEY_PART_INFO *part = keyInfo->key_part + n;
1268
 
                segment->offset = part->offset;
1269
 
                segment->length = part->length;
1270
 
                segment->type = part->field->key_type();
1271
 
                segment->nullBit = part->null_bit;
1272
 
                segment->isUnsigned = (part->field->flags & ENUM_FLAG) ?
1273
 
                        true : ((Field_num*) part->field)->unsigned_flag;
1274
 
 
1275
 
                switch (segment->type)
1276
 
                        {
1277
 
                        case HA_KEYTYPE_TEXT:
1278
 
                        case HA_KEYTYPE_VARTEXT1:
1279
 
                        case HA_KEYTYPE_VARTEXT2:
1280
 
                        case HA_KEYTYPE_VARBINARY1:
1281
 
                        case HA_KEYTYPE_VARBINARY2:
1282
 
                                segment->mysql_charset = part->field->charset();
1283
 
                                break;
1284
 
                        
1285
 
                        default:
1286
 
                                segment->mysql_charset = NULL;
1287
 
                        }
1288
 
                }
1289
 
}
1290
 
 
1291
 
 
1292
 
int StorageInterface::rename_table(const char *from, const char *to)
1293
 
{
1294
 
        DBUG_ENTER("StorageInterface::rename_table");
1295
 
        //tempTable = storageHandler->isTempTable(from) > 0;
1296
 
        table = 0; // XXX hack?
1297
 
        int ret = open(from, 0, 0);
1298
 
 
1299
 
        if (ret)
1300
 
                DBUG_RETURN(ret);
1301
 
 
1302
 
        DBUG_RETURN(storageShare->renameTable(storageConnection, to));
1303
 
}
1304
 
 
1305
 
 
1306
 
double StorageInterface::read_time(uint index, uint ranges, ha_rows rows)
1307
 
{
1308
 
        DBUG_ENTER("StorageInterface::read_time");
1309
 
        DBUG_RETURN(rows2double(rows / 3));
1310
 
}
1311
 
 
1312
 
 
1313
 
int StorageInterface::read_range_first(const key_range *start_key,
1314
 
                                      const key_range *end_key,
1315
 
                                      bool eq_range_arg, bool sorted)
1316
 
{
1317
 
        DBUG_ENTER("StorageInterface::read_range_first");
1318
 
        storageTable->clearIndexBounds();
1319
 
        haveStartKey = false;
1320
 
        haveEndKey = false;
1321
 
        
1322
 
        if (start_key && !storageTable->isKeyNull((const unsigned char*) start_key->key, start_key->length))
1323
 
                {
1324
 
                haveStartKey = true;
1325
 
                startKey = *start_key;
1326
 
                
1327
 
                if (start_key->flag == HA_READ_KEY_OR_NEXT)
1328
 
                        storageTable->setPartialKey();
1329
 
                else if (start_key->flag == HA_READ_AFTER_KEY)
1330
 
                        storageTable->setReadAfterKey();
1331
 
                        
1332
 
                int ret = storageTable->setIndexBound((const unsigned char*) start_key->key,
1333
 
                                                                                                start_key->length, LowerBound);
1334
 
                if (ret)
1335
 
                        DBUG_RETURN(ret);
1336
 
                }
1337
 
 
1338
 
        if (end_key)
1339
 
                {
1340
 
                if (end_key->flag == HA_READ_BEFORE_KEY)
1341
 
                        storageTable->setReadBeforeKey();
1342
 
 
1343
 
                int ret = storageTable->setIndexBound((const unsigned char*) end_key->key,
1344
 
                                                                                                end_key->length, UpperBound);
1345
 
                if (ret)
1346
 
                        DBUG_RETURN(ret);
1347
 
                }
1348
 
 
1349
 
        storageTable->indexScan();
1350
 
        nextRecord = 0;
1351
 
        lastRecord = -1;
1352
 
        eq_range = eq_range_arg;
1353
 
        end_range = 0;
1354
 
 
1355
 
        if (end_key)
1356
 
                {
1357
 
                haveEndKey = true;
1358
 
                endKey = *end_key;
1359
 
                end_range = &save_end_range;
1360
 
                save_end_range = *end_key;
1361
 
                key_compare_result_on_equal = ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1362
 
                                                                                (end_key->flag == HA_READ_AFTER_KEY) ? -1 :
1363
 
                                                                                0);
1364
 
                }
1365
 
        
1366
 
        range_key_part = table->key_info[active_index].key_part;
1367
 
        
1368
 
        for (;;)
1369
 
                {
1370
 
                int result = index_next(table->record[0]);
1371
 
 
1372
 
                if (result)
1373
 
                        {
1374
 
                        if (result == HA_ERR_KEY_NOT_FOUND)
1375
 
                                result = HA_ERR_END_OF_FILE;
1376
 
                            
1377
 
                        table->status = result;
1378
 
                        DBUG_RETURN(result);
1379
 
                        }
1380
 
                
1381
 
                DBUG_RETURN(0);
1382
 
                }
1383
 
}
1384
 
 
1385
 
 
1386
 
int StorageInterface::index_next(uchar *buf)
1387
 
{
1388
 
        DBUG_ENTER("StorageInterface::index_next");
1389
 
        ha_statistic_increment(&SSV::ha_read_next_count);
1390
 
 
1391
 
        if (activeBlobs)
1392
 
                freeActiveBlobs();
1393
 
 
1394
 
        for (;;)
1395
 
                {
1396
 
                lastRecord = storageTable->nextIndexed(nextRecord, lockForUpdate);
1397
 
 
1398
 
                if (lastRecord < 0)
1399
 
                        {
1400
 
                        if (lastRecord == StorageErrorRecordNotFound)
1401
 
                                {
1402
 
                                lastRecord = -1;
1403
 
                                table->status = STATUS_NOT_FOUND;
1404
 
                                DBUG_RETURN(HA_ERR_END_OF_FILE);
1405
 
                                }
1406
 
                        
1407
 
                        DBUG_RETURN(error(lastRecord));
1408
 
                        }
1409
 
 
1410
 
                nextRecord = lastRecord + 1;
1411
 
                
1412
 
                if (haveStartKey)
1413
 
                        {
1414
 
                        int n = storageTable->compareKey((const unsigned char*) startKey.key, startKey.length);
1415
 
                        
1416
 
                        if (n < 0 || (n == 0 && startKey.flag == HA_READ_AFTER_KEY))
1417
 
                                {
1418
 
                                storageTable->unlockRow();
1419
 
                                continue;
1420
 
                                }
1421
 
                        }
1422
 
                        
1423
 
                if (haveEndKey)
1424
 
                        {
1425
 
                        int n = storageTable->compareKey((const unsigned char*) endKey.key, endKey.length);
1426
 
                        
1427
 
                        if (n > 0 || (n == 0 && endKey.flag == HA_READ_BEFORE_KEY))
1428
 
                                {
1429
 
                                storageTable->unlockRow();
1430
 
                                continue;
1431
 
                                }
1432
 
                        }
1433
 
                
1434
 
                decodeRecord(buf);
1435
 
                table->status = 0;
1436
 
 
1437
 
                DBUG_RETURN(0);
1438
 
                }
1439
 
}
1440
 
 
1441
 
 
1442
 
int StorageInterface::index_next_same(uchar *buf, const uchar *key, uint key_len)
1443
 
{
1444
 
        DBUG_ENTER("StorageInterface::index_next_same");
1445
 
        ha_statistic_increment(&SSV::ha_read_next_count);
1446
 
        
1447
 
        for (;;)
1448
 
                {
1449
 
                int ret = index_next(buf);
1450
 
                
1451
 
                if (ret)
1452
 
                        DBUG_RETURN(ret);
1453
 
                
1454
 
                int comparison = storageTable->compareKey((const unsigned char*) key, key_len);
1455
 
                
1456
 
                if (comparison == 0)
1457
 
                        DBUG_RETURN(0);
1458
 
                }
1459
 
}
1460
 
 
1461
 
 
1462
 
double StorageInterface::scan_time(void)
1463
 
{
1464
 
        DBUG_ENTER("StorageInterface::scan_time");
1465
 
        DBUG_RETURN(stats.records * 1000);
1466
 
}
1467
 
 
1468
 
bool StorageInterface::threadSwitch(THD* newThread)
1469
 
{
1470
 
        if (newThread == mySqlThread)
1471
 
                return false;
1472
 
 
1473
 
        if (storageConnection)
1474
 
                {
1475
 
                if (!storageConnection->mySqlThread && !mySqlThread)
1476
 
                        {
1477
 
                        storageConnection->setMySqlThread(newThread);
1478
 
                        mySqlThread = newThread;
1479
 
                        
1480
 
                        return false;
1481
 
                        }
1482
 
        
1483
 
                storageConnection->release();
1484
 
                }       
1485
 
 
1486
 
        storageConnection = storageHandler->getStorageConnection(storageShare, newThread, newThread->thread_id, OpenDatabase, falcon_tablespace_mode);
1487
 
 
1488
 
        if (storageTable)
1489
 
                storageTable->setConnection(storageConnection);
1490
 
        else
1491
 
                storageTable = storageConnection->getStorageTable(storageShare);
1492
 
 
1493
 
        mySqlThread = newThread;
1494
 
 
1495
 
        return true;
1496
 
}
1497
 
 
1498
 
 
1499
 
int StorageInterface::threadSwitchError(void)
1500
 
{
1501
 
        return 1;
1502
 
}
1503
 
 
1504
 
 
1505
 
int StorageInterface::error(int storageError)
1506
 
{
1507
 
        DBUG_ENTER("StorageInterface::error");
1508
 
 
1509
 
        if (storageError == 0)
1510
 
                {
1511
 
                DBUG_PRINT("info", ("returning 0"));
1512
 
                DBUG_RETURN(0);
1513
 
                }
1514
 
 
1515
 
        switch (storageError) 
1516
 
                {
1517
 
                case StorageErrorDupKey:
1518
 
                        DBUG_PRINT("info", ("StorageErrorDupKey"));
1519
 
                        DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
1520
 
 
1521
 
                case StorageErrorDeadlock:
1522
 
                        DBUG_PRINT("info", ("StorageErrorDeadlock"));
1523
 
                        DBUG_RETURN(HA_ERR_LOCK_DEADLOCK);
1524
 
                        //DBUG_RETURN(200 - storageError);
1525
 
 
1526
 
                case StorageErrorRecordNotFound:
1527
 
                        DBUG_PRINT("info", ("StorageErrorRecordNotFound"));
1528
 
                        DBUG_RETURN(HA_ERR_KEY_NOT_FOUND);
1529
 
 
1530
 
                case StorageErrorTableNotFound:
1531
 
                        DBUG_PRINT("info", ("StorageErrorTableNotFound"));
1532
 
                        DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
1533
 
 
1534
 
                case StorageErrorNoIndex:
1535
 
                        DBUG_PRINT("info", ("StorageErrorNoIndex"));
1536
 
                        DBUG_RETURN(HA_ERR_WRONG_INDEX);
1537
 
 
1538
 
                case StorageErrorBadKey:
1539
 
                        DBUG_PRINT("info", ("StorageErrorBadKey"));
1540
 
                        DBUG_RETURN(HA_ERR_WRONG_INDEX);
1541
 
 
1542
 
                case StorageErrorIndexOverflow:
1543
 
                        DBUG_PRINT("info", ("StorageErrorIndexOverflow"));
1544
 
                        DBUG_RETURN(HA_WRONG_CREATE_OPTION); // HA_ERR_TOO_LONG_KEY does not exist
1545
 
 
1546
 
                case StorageErrorTableExits:
1547
 
                        DBUG_PRINT("info", ("StorageErrorTableExits"));
1548
 
                        DBUG_RETURN(HA_ERR_TABLE_EXIST);
1549
 
 
1550
 
                case StorageErrorUpdateConflict:
1551
 
                        DBUG_PRINT("info", ("StorageErrorUpdateConflict"));
1552
 
                        DBUG_RETURN(HA_ERR_RECORD_CHANGED);
1553
 
 
1554
 
                case StorageErrorUncommittedUpdates:
1555
 
                        DBUG_PRINT("info", ("StorageErrorUncommittedUpdates"));
1556
 
                        DBUG_RETURN(HA_ERR_TABLE_EXIST);
1557
 
 
1558
 
                case StorageErrorUncommittedRecords:
1559
 
                        DBUG_PRINT("info", ("StorageErrorUncommittedRecords"));
1560
 
                        DBUG_RETURN(200 - storageError);
1561
 
 
1562
 
                case StorageErrorNoSequence:
1563
 
                        DBUG_PRINT("info", ("StorageErrorNoSequence"));
1564
 
 
1565
 
                        if (storageConnection)
1566
 
                                storageConnection->setErrorText("no sequenced defined for autoincrement operation");
1567
 
 
1568
 
                        DBUG_RETURN(200 - storageError);
1569
 
 
1570
 
                case StorageErrorTruncation:
1571
 
                        DBUG_PRINT("info", ("StorageErrorTruncation"));
1572
 
                        DBUG_RETURN(HA_ERR_TO_BIG_ROW);
1573
 
 
1574
 
                case StorageWarningSerializable:
1575
 
                        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1576
 
                                            ER_CANT_CHANGE_TX_ISOLATION,
1577
 
                                            "Falcon does not support SERIALIZABLE ISOLATION, using REPEATABLE READ instead.");
1578
 
                        DBUG_RETURN(0);
1579
 
 
1580
 
                case StorageWarningReadUncommitted:
1581
 
                        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1582
 
                                            ER_CANT_CHANGE_TX_ISOLATION,
1583
 
                                            "Falcon does not support READ UNCOMMITTED ISOLATION, using REPEATABLE READ instead.");
1584
 
                        DBUG_RETURN(0);
1585
 
 
1586
 
                case StorageErrorOutOfMemory:
1587
 
                        DBUG_PRINT("info", ("StorageErrorOutOfMemory"));
1588
 
                        DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1589
 
 
1590
 
                case StorageErrorOutOfRecordMemory:
1591
 
                        DBUG_PRINT("info", ("StorageErrorOutOfRecordMemory"));
1592
 
                        DBUG_RETURN(200 - storageError);
1593
 
 
1594
 
                default:
1595
 
                        DBUG_PRINT("info", ("Unknown Falcon Error"));
1596
 
                        DBUG_RETURN(200 - storageError);
1597
 
                }
1598
 
 
1599
 
        DBUG_RETURN(storageError);
1600
 
}
1601
 
 
1602
 
int StorageInterface::start_stmt(THD *thd, thr_lock_type lock_type)
1603
 
{
1604
 
        DBUG_ENTER("StorageInterface::start_stmt");
1605
 
        threadSwitch(thd);
1606
 
        
1607
 
        if (storageConnection->markVerb())
1608
 
                trans_register_ha(thd, FALSE, falcon_hton);
1609
 
 
1610
 
        DBUG_RETURN(0);
1611
 
}
1612
 
 
1613
 
 
1614
 
int StorageInterface::external_lock(THD *thd, int lock_type)
1615
 
{
1616
 
        DBUG_ENTER("StorageInterface::external_lock");
1617
 
        threadSwitch(thd);
1618
 
 
1619
 
        if (lock_type == F_UNLCK)
1620
 
                {
1621
 
                storageConnection->setCurrentStatement(NULL);
1622
 
 
1623
 
                if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
1624
 
                        storageConnection->endImplicitTransaction();
1625
 
                else
1626
 
                        storageConnection->releaseVerb();
1627
 
 
1628
 
                if (storageTable)
1629
 
                        {
1630
 
                        storageTable->clearRecord();
1631
 
                        storageTable->clearBitmap();
1632
 
                        storageTable->clearAlter();
1633
 
                        }
1634
 
                }
1635
 
        else
1636
 
                {
1637
 
                if (storageConnection && thd->query)
1638
 
                        storageConnection->setCurrentStatement(thd->query);
1639
 
 
1640
 
                insertCount = 0;
1641
 
                
1642
 
                switch (thd_sql_command(thd))
1643
 
                        {
1644
 
                        case SQLCOM_ALTER_TABLE:
1645
 
                        case SQLCOM_DROP_INDEX:
1646
 
                        case SQLCOM_CREATE_INDEX:
1647
 
                                {
1648
 
                                int ret = storageTable->alterCheck();
1649
 
                                
1650
 
                                if (ret)
1651
 
                                        DBUG_RETURN(error(ret));
1652
 
                                }
1653
 
                                break;
1654
 
 
1655
 
                        default:
1656
 
                                break;
1657
 
                        }
1658
 
 
1659
 
                if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
1660
 
                        {
1661
 
                        if (storageConnection->startTransaction(thd_tx_isolation(thd)))
1662
 
                                trans_register_ha(thd, true, falcon_hton);
1663
 
                                
1664
 
                        if (storageConnection->markVerb())
1665
 
                                trans_register_ha(thd, false, falcon_hton);
1666
 
                        }
1667
 
                else
1668
 
                        {
1669
 
                        if (storageConnection->startImplicitTransaction(thd_tx_isolation(thd)))
1670
 
                                trans_register_ha(thd, false, falcon_hton);
1671
 
                        }
1672
 
                        
1673
 
                switch (thd_tx_isolation(mySqlThread))
1674
 
                        {
1675
 
                        case ISO_READ_UNCOMMITTED:
1676
 
                                error(StorageWarningReadUncommitted);
1677
 
                                break;
1678
 
                                
1679
 
                        case ISO_SERIALIZABLE:
1680
 
                                error(StorageWarningSerializable);
1681
 
                                break;
1682
 
                        }
1683
 
                }
1684
 
 
1685
 
        DBUG_RETURN(0);
1686
 
}
1687
 
 
1688
 
 
1689
 
void StorageInterface::get_auto_increment(ulonglong offset, ulonglong increment,
1690
 
                                         ulonglong nb_desired_values,
1691
 
                                         ulonglong *first_value,
1692
 
                                         ulonglong *nb_reserved_values)
1693
 
{
1694
 
        DBUG_ENTER("StorageInterface::get_auto_increment");
1695
 
        *first_value = storageShare->getSequenceValue(1);
1696
 
        *nb_reserved_values = 1;
1697
 
 
1698
 
        DBUG_VOID_RETURN;
1699
 
}
1700
 
 
1701
 
int StorageInterface::reset_auto_increment(ulonglong value)
1702
 
{
1703
 
        return handler::reset_auto_increment(value);
1704
 
}
1705
 
 
1706
 
const char *StorageInterface::index_type(uint key_number)
1707
 
{
1708
 
  DBUG_ENTER("StorageInterface::index_type");
1709
 
  DBUG_RETURN("BTREE");
1710
 
}
1711
 
 
1712
 
void StorageInterface::dropDatabase(handlerton *hton, char *path)
1713
 
{
1714
 
        DBUG_ENTER("StorageInterface::dropDatabase");
1715
 
        storageHandler->dropDatabase(path);
1716
 
 
1717
 
        DBUG_VOID_RETURN;
1718
 
}
1719
 
 
1720
 
 
1721
 
void StorageInterface::freeActiveBlobs(void)
1722
 
{
1723
 
        for (StorageBlob *blob; (blob = activeBlobs); )
1724
 
                {
1725
 
                activeBlobs = blob->next;
1726
 
                storageTable->freeBlob(blob);
1727
 
                blob->next = freeBlobs;
1728
 
                freeBlobs = blob;
1729
 
                }
1730
 
}
1731
 
 
1732
 
 
1733
 
void StorageInterface::shutdown(handlerton *htons)
1734
 
{
1735
 
        storageHandler->shutdownHandler();
1736
 
}
1737
 
 
1738
 
 
1739
 
int StorageInterface::panic(handlerton* hton, ha_panic_function flag)
1740
 
{
1741
 
        storageHandler->shutdownHandler();
1742
 
        
1743
 
        return 0;
1744
 
}
1745
 
 
1746
 
 
1747
 
int StorageInterface::closeConnection(handlerton *hton, THD *thd)
1748
 
{
1749
 
        DBUG_ENTER("NfsStorageEngine::closeConnection");
1750
 
        storageHandler->closeConnections(thd);
1751
 
        *thd_ha_data(thd, hton) = NULL;
1752
 
 
1753
 
        DBUG_RETURN(0);
1754
 
}
1755
 
 
1756
 
 
1757
 
int StorageInterface::alter_tablespace(handlerton* hton, THD* thd, st_alter_tablespace* ts_info)
1758
 
{
1759
 
        DBUG_ENTER("NfsStorageEngine::alter_tablespace");
1760
 
        int ret = 0;
1761
 
 
1762
 
        /*
1763
 
        CREATE TABLESPACE tablespace
1764
 
                ADD DATAFILE 'file'
1765
 
                USE LOGFILE GROUP logfile_group
1766
 
                [EXTENT_SIZE [=] extent_size]
1767
 
                INITIAL_SIZE [=] initial_size
1768
 
                ENGINE [=] engine
1769
 
        */
1770
 
        
1771
 
        switch (ts_info->ts_cmd_type)
1772
 
                {
1773
 
                case CREATE_TABLESPACE:
1774
 
                        ret = storageHandler->createTablespace(ts_info->tablespace_name, ts_info->data_file_name, falcon_tablespace_mode);
1775
 
                        break;
1776
 
                
1777
 
                case DROP_TABLESPACE:
1778
 
                        ret = storageHandler->deleteTablespace(ts_info->tablespace_name);
1779
 
                        break;
1780
 
                
1781
 
                default:
1782
 
                        DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
1783
 
                }
1784
 
        
1785
 
        DBUG_RETURN(ret);
1786
 
}
1787
 
 
1788
 
uint StorageInterface::max_supported_key_length(void) const
1789
 
{
1790
 
        // Assume 4K page unless proven otherwise.
1791
 
        if (storageConnection)
1792
 
                return storageConnection->getMaxKeyLength();
1793
 
 
1794
 
        return MAX_INDEX_KEY_LENGTH_4K;  // Default value.
1795
 
}
1796
 
 
1797
 
 
1798
 
uint StorageInterface::max_supported_key_part_length(void) const
1799
 
{
1800
 
        // Assume 4K page unless proven otherwise.
1801
 
        if (storageConnection)
1802
 
                return storageConnection->getMaxKeyLength();
1803
 
 
1804
 
        return MAX_INDEX_KEY_LENGTH_4K;  // Default for future sizes.
1805
 
}
1806
 
 
1807
 
 
1808
 
void StorageInterface::logger(int mask, const char* text, void* arg)
1809
 
{
1810
 
        if (mask & falcon_debug_mask)
1811
 
                {
1812
 
                printf ("%s", text);
1813
 
                
1814
 
                if (falcon_log_file)
1815
 
                        fprintf(falcon_log_file, "%s", text);
1816
 
                }
1817
 
}
1818
 
 
1819
 
 
1820
 
int StorageInterface::setIndexes(void)
1821
 
{
1822
 
        if (!table || storageShare->haveIndexes())
1823
 
                return 0;
1824
 
 
1825
 
        storageShare->lock(true);
1826
 
 
1827
 
        if (!storageShare->haveIndexes())
1828
 
                {
1829
 
                StorageIndexDesc indexDesc;
1830
 
 
1831
 
                for (uint n = 0; n < table->s->keys; ++n)
1832
 
                        {
1833
 
                        getKeyDesc(table->key_info + n, &indexDesc);
1834
 
 
1835
 
                        if (n == table->s->primary_key)
1836
 
                                indexDesc.primaryKey = true;
1837
 
 
1838
 
                        int ret = storageTable->setIndex(table->s->keys, n, &indexDesc);
1839
 
                        if (ret)
1840
 
                                return ret;
1841
 
                        }
1842
 
                }
1843
 
 
1844
 
        storageShare->unlock();
1845
 
        return 0;
1846
 
}
1847
 
 
1848
 
 
1849
 
int StorageInterface::genType(Field* field, CmdGen* gen)
1850
 
{
1851
 
        const char *type;
1852
 
        const char *arg = NULL;
1853
 
        int length = 0;
1854
 
 
1855
 
        switch (field->real_type()) 
1856
 
                {
1857
 
                case MYSQL_TYPE_DECIMAL:
1858
 
                case MYSQL_TYPE_TINY:
1859
 
                case MYSQL_TYPE_SHORT:
1860
 
                case MYSQL_TYPE_BIT:
1861
 
                        type = "smallint";
1862
 
                        break;
1863
 
 
1864
 
                case MYSQL_TYPE_INT24:
1865
 
                case MYSQL_TYPE_LONG:
1866
 
                case MYSQL_TYPE_YEAR:
1867
 
                        type = "int";
1868
 
                        break;
1869
 
 
1870
 
                case MYSQL_TYPE_FLOAT:
1871
 
                        type = "float";
1872
 
                        break;
1873
 
 
1874
 
                case MYSQL_TYPE_DOUBLE:
1875
 
                        type = "double";
1876
 
                        break;
1877
 
 
1878
 
                case MYSQL_TYPE_TIMESTAMP:
1879
 
                        type = "timestamp";
1880
 
                        break;
1881
 
 
1882
 
                case MYSQL_TYPE_SET:
1883
 
                case MYSQL_TYPE_LONGLONG:
1884
 
                        type = "bigint";
1885
 
                        break;
1886
 
 
1887
 
                /*
1888
 
                        Falcon's date and time types don't handle invalid dates like MySQL's do,
1889
 
                        so we just use an int for storage
1890
 
                */
1891
 
                
1892
 
                case MYSQL_TYPE_DATE:
1893
 
                case MYSQL_TYPE_TIME:
1894
 
                case MYSQL_TYPE_ENUM:
1895
 
                case MYSQL_TYPE_NEWDATE:
1896
 
                        type = "int";
1897
 
                        break;
1898
 
 
1899
 
                case MYSQL_TYPE_DATETIME:
1900
 
                        type = "bigint";
1901
 
                        break;
1902
 
 
1903
 
                case MYSQL_TYPE_VARCHAR:
1904
 
                case MYSQL_TYPE_VAR_STRING:
1905
 
                case MYSQL_TYPE_STRING:
1906
 
                        {
1907
 
                        CHARSET_INFO *charset = field->charset();
1908
 
 
1909
 
                        if (charset)
1910
 
                                {
1911
 
                                arg = charset->name;
1912
 
                                type = "varchar (%d) collation %s";
1913
 
                                }
1914
 
                        else
1915
 
                                type = "varchar (%d)";
1916
 
                                
1917
 
                        length = field->field_length;
1918
 
                        }
1919
 
                        break;
1920
 
 
1921
 
                case MYSQL_TYPE_TINY_BLOB:
1922
 
                case MYSQL_TYPE_LONG_BLOB:
1923
 
                case MYSQL_TYPE_BLOB:
1924
 
                case MYSQL_TYPE_MEDIUM_BLOB:
1925
 
                case MYSQL_TYPE_GEOMETRY:
1926
 
                        if (field->field_length < 256)
1927
 
                                type = "varchar (256)";
1928
 
                        else
1929
 
                                type = "blob";
1930
 
                        break;
1931
 
 
1932
 
                case MYSQL_TYPE_NEWDECIMAL:
1933
 
                        {
1934
 
                        Field_new_decimal *newDecimal = (Field_new_decimal*) field;
1935
 
                        
1936
 
                        /***
1937
 
                        if (newDecimal->precision > 18 && newDecimal->dec > 9)
1938
 
                                {
1939
 
                                errorText = "columns with greater than 18 digits precision and greater than 9 digits of fraction are not supported";
1940
 
                                
1941
 
                                return HA_ERR_UNSUPPORTED;
1942
 
                                }
1943
 
                        ***/
1944
 
                                
1945
 
                        gen->gen("numeric (%d,%d)", newDecimal->precision, newDecimal->dec);
1946
 
                        
1947
 
                        return 0;
1948
 
                        }
1949
 
 
1950
 
                default:
1951
 
                        errorText = "unsupported Falcon data type";
1952
 
                        
1953
 
                        return HA_ERR_UNSUPPORTED;
1954
 
                }
1955
 
 
1956
 
        gen->gen(type, length, arg);
1957
 
 
1958
 
        return 0;
1959
 
}
1960
 
 
1961
 
 
1962
 
void StorageInterface::genKeyFields(KEY* key, CmdGen* gen)
1963
 
{
1964
 
        const char *sep = "(";
1965
 
        char nameBuffer[129];
1966
 
 
1967
 
        for (uint n = 0; n < key->key_parts; ++n)
1968
 
                {
1969
 
                KEY_PART_INFO *part = key->key_part + n;
1970
 
                Field *field = part->field;
1971
 
                storageShare->cleanupFieldName(field->field_name, nameBuffer,
1972
 
                                                                                sizeof(nameBuffer));
1973
 
                
1974
 
                if (part->key_part_flag & HA_PART_KEY_SEG)
1975
 
                        gen->gen("%s\"%s\"(%d)", sep, nameBuffer, part->length);
1976
 
                else
1977
 
                        gen->gen("%s\"%s\"", sep, nameBuffer);
1978
 
                        
1979
 
                sep = ", ";
1980
 
                }
1981
 
 
1982
 
        gen->gen(")");
1983
 
}
1984
 
 
1985
 
 
1986
 
void StorageInterface::encodeRecord(uchar *buf, bool updateFlag)
1987
 
{
1988
 
        storageTable->preInsert();
1989
 
        my_ptrdiff_t ptrDiff = buf - table->record[0];
1990
 
        my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->read_set);
1991
 
 
1992
 
        for (uint n = 0; n < table->s->fields; ++n)
1993
 
                {
1994
 
                Field *field = table->field[n];
1995
 
 
1996
 
                if (ptrDiff)
1997
 
                        field->move_field_offset(ptrDiff);
1998
 
 
1999
 
                if (updateFlag && !bitmap_is_set(table->write_set, field->field_index))
2000
 
                        {
2001
 
                        const unsigned char *p = storageTable->getEncoding(n);
2002
 
                        storageTable->dataStream.encodeEncoding(p);
2003
 
                        }
2004
 
                else if (field->is_null())
2005
 
                        storageTable->dataStream.encodeNull();
2006
 
                else
2007
 
                        switch (field->real_type()) 
2008
 
                                {
2009
 
                                case MYSQL_TYPE_TINY:
2010
 
                                case MYSQL_TYPE_SHORT:
2011
 
                                case MYSQL_TYPE_INT24:
2012
 
                                case MYSQL_TYPE_LONG:
2013
 
                                case MYSQL_TYPE_LONGLONG:
2014
 
                                case MYSQL_TYPE_YEAR:
2015
 
                                case MYSQL_TYPE_DECIMAL:
2016
 
                                case MYSQL_TYPE_ENUM:
2017
 
                                case MYSQL_TYPE_SET:
2018
 
                                case MYSQL_TYPE_BIT:
2019
 
                                        storageTable->dataStream.encodeInt64(field->val_int());
2020
 
                                        break;
2021
 
 
2022
 
                                case MYSQL_TYPE_NEWDECIMAL:
2023
 
                                        {
2024
 
                                        int precision = ((Field_new_decimal *)field)->precision;
2025
 
                                        int scale = ((Field_new_decimal *)field)->dec;
2026
 
                                        
2027
 
                                        if (precision < 19)
2028
 
                                                {
2029
 
                                                int64 value = ScaledBinary::getInt64FromBinaryDecimal((const char *) field->ptr,
2030
 
                                                                                                                                                        precision,
2031
 
                                                                                                                                                        scale);
2032
 
                                                storageTable->dataStream.encodeInt64(value, scale);
2033
 
                                                }
2034
 
                                        else
2035
 
                                                {
2036
 
                                                BigInt bigInt;
2037
 
                                                ScaledBinary::getBigIntFromBinaryDecimal((const char*) field->ptr, precision, scale, &bigInt);
2038
 
                                                
2039
 
                                                // Handle value as int64 if possible. Even if the number fits
2040
 
                                                // an int64, it can only be scaled within 18 digits or less.
2041
 
        
2042
 
                                                if (bigInt.fitsInInt64() && scale < 19)
2043
 
                                                        {
2044
 
                                                        int64 value = bigInt.getInt();
2045
 
                                                        storageTable->dataStream.encodeInt64(value, scale);
2046
 
                                                        }
2047
 
                                                else
2048
 
                                                        storageTable->dataStream.encodeBigInt(&bigInt);
2049
 
                                                }
2050
 
                                        }
2051
 
                                        break;
2052
 
 
2053
 
                                case MYSQL_TYPE_DOUBLE:
2054
 
                                case MYSQL_TYPE_FLOAT:
2055
 
                                        storageTable->dataStream.encodeDouble(field->val_real());
2056
 
                                        break;
2057
 
 
2058
 
                                case MYSQL_TYPE_TIMESTAMP:
2059
 
                                        {
2060
 
                                        my_bool nullValue;
2061
 
                                        int64 value = ((Field_timestamp*) field)->get_timestamp(&nullValue);
2062
 
                                        storageTable->dataStream.encodeDate(value * 1000);
2063
 
                                        }
2064
 
                                        break;
2065
 
 
2066
 
                                case MYSQL_TYPE_DATE:
2067
 
                                        storageTable->dataStream.encodeInt64(field->val_int());
2068
 
                                        break;
2069
 
 
2070
 
                                case MYSQL_TYPE_NEWDATE:
2071
 
                                        //storageTable->dataStream.encodeInt64(field->val_int());
2072
 
                                        storageTable->dataStream.encodeInt64(uint3korr(field->ptr));
2073
 
                                        break;
2074
 
 
2075
 
                                case MYSQL_TYPE_TIME:
2076
 
                                        storageTable->dataStream.encodeInt64(field->val_int());
2077
 
                                        break;
2078
 
 
2079
 
                                case MYSQL_TYPE_DATETIME:
2080
 
                                        storageTable->dataStream.encodeInt64(field->val_int());
2081
 
                                        break;
2082
 
 
2083
 
                                case MYSQL_TYPE_VARCHAR:
2084
 
                                case MYSQL_TYPE_VAR_STRING:
2085
 
                                case MYSQL_TYPE_STRING:
2086
 
                                        {
2087
 
                                        String string;
2088
 
                                        String buffer;
2089
 
                                        field->val_str(&buffer, &string);
2090
 
                                        storageTable->dataStream.encodeOpaque(string.length(), string.ptr());
2091
 
                                        }
2092
 
                                        break;
2093
 
 
2094
 
                                case MYSQL_TYPE_TINY_BLOB:
2095
 
                                        {
2096
 
                                        Field_blob *blob = (Field_blob*) field;
2097
 
                                        uint length = blob->get_length();
2098
 
                                        uchar *ptr;
2099
 
                                        blob->get_ptr(&ptr);
2100
 
                                        storageTable->dataStream.encodeOpaque(length, (const char*) ptr);
2101
 
                                        }
2102
 
                                        break;
2103
 
 
2104
 
                                case MYSQL_TYPE_LONG_BLOB:
2105
 
                                case MYSQL_TYPE_BLOB:
2106
 
                                case MYSQL_TYPE_MEDIUM_BLOB:
2107
 
                                case MYSQL_TYPE_GEOMETRY:
2108
 
                                        {
2109
 
                                        Field_blob *blob = (Field_blob*) field;
2110
 
                                        uint length = blob->get_length();
2111
 
                                        uchar *ptr;
2112
 
                                        blob->get_ptr(&ptr);
2113
 
                                        StorageBlob *storageBlob;
2114
 
                                        uint32 blobId;
2115
 
 
2116
 
                                        for (storageBlob = activeBlobs; storageBlob; storageBlob = storageBlob->next)
2117
 
                                                if (storageBlob->data == (uchar*) ptr)
2118
 
                                                        {
2119
 
                                                        blobId = storageBlob->blobId;
2120
 
                                                        break;
2121
 
                                                        }
2122
 
 
2123
 
                                        if (!storageBlob)
2124
 
                                                {
2125
 
                                                StorageBlob storageBlob;
2126
 
                                                storageBlob.length = length;
2127
 
                                                storageBlob.data = (uchar *)ptr;
2128
 
                                                blobId = storageTable->storeBlob(&storageBlob);
2129
 
                                                blob->set_ptr(storageBlob.length, storageBlob.data);
2130
 
                                                }
2131
 
                                                
2132
 
                                        storageTable->dataStream.encodeBinaryBlob(blobId);
2133
 
                                        }
2134
 
                                        break;
2135
 
 
2136
 
                                default:
2137
 
                                        storageTable->dataStream.encodeOpaque(field->field_length, (const char*) field->ptr);
2138
 
                                }
2139
 
 
2140
 
                if (ptrDiff)
2141
 
                        field->move_field_offset(-ptrDiff);
2142
 
                }
2143
 
 
2144
 
        dbug_tmp_restore_column_map(table->read_set, old_map);
2145
 
}
2146
 
 
2147
 
void StorageInterface::decodeRecord(uchar *buf)
2148
 
{
2149
 
        EncodedDataStream *dataStream = &storageTable->dataStream;
2150
 
        my_ptrdiff_t ptrDiff = buf - table->record[0];
2151
 
        my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set);
2152
 
        DBUG_ENTER("StorageInterface::decodeRecord");
2153
 
 
2154
 
        for (uint n = 0; n < table->s->fields; ++n)
2155
 
                {
2156
 
                Field *field = table->field[n];
2157
 
                dataStream->decode();
2158
 
 
2159
 
                if (ptrDiff)
2160
 
                        field->move_field_offset(ptrDiff);
2161
 
 
2162
 
                // @todo (HK) Affects Bug#28158: Falcon unique key violation gives wrong error message
2163
 
                // @todo (KL) Affects Bug#26827: Falcon: column is null after update of a different column
2164
 
                // both of these bugs need to be fixed in the server, not here.  
2165
 
                // This call to set_null is correct.  When they are fixed, we can delete these comments.
2166
 
                
2167
 
                if (dataStream->type == edsTypeNull || !bitmap_is_set(table->read_set, field->field_index))
2168
 
                        field->set_null();
2169
 
                else
2170
 
                        {
2171
 
                        field->set_notnull();
2172
 
 
2173
 
                        switch (field->real_type()) 
2174
 
                                {
2175
 
                                case MYSQL_TYPE_TINY:
2176
 
                                case MYSQL_TYPE_SHORT:
2177
 
                                case MYSQL_TYPE_INT24:
2178
 
                                case MYSQL_TYPE_LONG:
2179
 
                                case MYSQL_TYPE_LONGLONG:
2180
 
                                case MYSQL_TYPE_YEAR:
2181
 
                                case MYSQL_TYPE_DECIMAL:
2182
 
                                case MYSQL_TYPE_ENUM:
2183
 
                                case MYSQL_TYPE_SET:
2184
 
                                case MYSQL_TYPE_BIT:
2185
 
                                        field->store(dataStream->getInt64(),
2186
 
                                                                ((Field_num*)field)->unsigned_flag);
2187
 
                                        break;
2188
 
 
2189
 
                                case MYSQL_TYPE_NEWDECIMAL:
2190
 
                                        {
2191
 
                                        int precision = ((Field_new_decimal*) field)->precision;
2192
 
                                        int scale = ((Field_new_decimal*) field)->dec;
2193
 
                                        
2194
 
                                        if (dataStream->type == edsTypeBigInt)
2195
 
                                                ScaledBinary::putBigInt(&dataStream->bigInt, (char*) field->ptr, precision, scale);
2196
 
                                        else
2197
 
                                                {
2198
 
                                                int64 value = dataStream->getInt64(scale);
2199
 
                                                ScaledBinary::putBinaryDecimal(value, (char*) field->ptr, precision, scale);
2200
 
                                                }
2201
 
                                        }
2202
 
                                        break;
2203
 
 
2204
 
                                case MYSQL_TYPE_DOUBLE:
2205
 
                                case MYSQL_TYPE_FLOAT:
2206
 
                                        field->store(dataStream->value.dbl);
2207
 
                                        break;
2208
 
 
2209
 
                                case MYSQL_TYPE_TIMESTAMP:
2210
 
                                        {
2211
 
                                        int value = (int) (dataStream->value.integer64 / 1000);
2212
 
                                        longstore(field->ptr, value);
2213
 
                                        }
2214
 
                                        break;
2215
 
 
2216
 
                                case MYSQL_TYPE_DATE:
2217
 
                                        field->store(dataStream->getInt64(), false);
2218
 
                                        break;
2219
 
 
2220
 
                                case MYSQL_TYPE_NEWDATE:
2221
 
                                        //field->store(dataStream->getInt64(), false);
2222
 
                                        int3store(field->ptr, dataStream->getInt32());
2223
 
                                        break;
2224
 
 
2225
 
                                case MYSQL_TYPE_TIME:
2226
 
                                        field->store(dataStream->getInt64(), false);
2227
 
                                        break;
2228
 
 
2229
 
                                case MYSQL_TYPE_DATETIME:
2230
 
                                        field->store(dataStream->getInt64(), false);
2231
 
                                        break;
2232
 
 
2233
 
                                case MYSQL_TYPE_VARCHAR:
2234
 
                                case MYSQL_TYPE_VAR_STRING:
2235
 
                                case MYSQL_TYPE_STRING:
2236
 
                                        field->store((const char*) dataStream->value.string.data,
2237
 
                                                                dataStream->value.string.length, field->charset());
2238
 
                                        break;
2239
 
 
2240
 
                                case MYSQL_TYPE_TINY_BLOB:
2241
 
                                        {
2242
 
                                        Field_blob *blob = (Field_blob*) field;
2243
 
                                        blob->set_ptr(dataStream->value.string.length,
2244
 
                                                      (uchar*) dataStream->value.string.data);
2245
 
                                        }
2246
 
                                        break;
2247
 
 
2248
 
                                case MYSQL_TYPE_LONG_BLOB:
2249
 
                                case MYSQL_TYPE_BLOB:
2250
 
                                case MYSQL_TYPE_MEDIUM_BLOB:
2251
 
                                case MYSQL_TYPE_GEOMETRY:
2252
 
                                        {
2253
 
                                        Field_blob *blob = (Field_blob*) field;
2254
 
                                        StorageBlob *storageBlob = freeBlobs;
2255
 
 
2256
 
                                        if (storageBlob)
2257
 
                                                freeBlobs = storageBlob->next;
2258
 
                                        else
2259
 
                                                storageBlob = new StorageBlob;
2260
 
 
2261
 
                                        storageBlob->next = activeBlobs;
2262
 
                                        activeBlobs = storageBlob;
2263
 
                                        storageBlob->blobId = dataStream->value.blobId;
2264
 
                                        storageTable->getBlob(storageBlob->blobId, storageBlob);
2265
 
                                        blob->set_ptr(storageBlob->length, (uchar*) storageBlob->data);
2266
 
                                        }
2267
 
                                        break;
2268
 
 
2269
 
                                default:
2270
 
                                        {
2271
 
                                        uint l = dataStream->value.string.length;
2272
 
 
2273
 
                                        if (field->field_length < l)
2274
 
                                                l = field->field_length;
2275
 
 
2276
 
                                        memcpy(field->ptr, dataStream->value.string.data, l);
2277
 
                                        }
2278
 
                                }
2279
 
                        }
2280
 
 
2281
 
                if (ptrDiff)
2282
 
                        field->move_field_offset(-ptrDiff);
2283
 
                }
2284
 
        dbug_tmp_restore_column_map(table->write_set, old_map);
2285
 
 
2286
 
        DBUG_VOID_RETURN;
2287
 
}
2288
 
 
2289
 
 
2290
 
int StorageInterface::extra(ha_extra_function operation)
2291
 
{
2292
 
        DBUG_ENTER("StorageInterface::extra");
2293
 
        DBUG_RETURN(0);
2294
 
}
2295
 
 
2296
 
bool StorageInterface::get_error_message(int error, String *buf)
2297
 
{
2298
 
        if (storageConnection)
2299
 
                {
2300
 
                const char *text = storageConnection->getLastErrorString();
2301
 
                buf->set(text, strlen(text), system_charset_info);
2302
 
                }
2303
 
        else if (errorText)
2304
 
                buf->set(errorText, strlen(errorText), system_charset_info);
2305
 
 
2306
 
        return false;
2307
 
}
2308
 
 
2309
 
void StorageInterface::unlockTable(void)
2310
 
{
2311
 
        if (tableLocked)
2312
 
                {
2313
 
                storageShare->unlock();
2314
 
                tableLocked = false;
2315
 
                }
2316
 
}
2317
 
 
2318
 
//*****************************************************************************
2319
 
//
2320
 
// NfsPluginHandler
2321
 
//
2322
 
//*****************************************************************************
2323
 
NfsPluginHandler::NfsPluginHandler()
2324
 
{
2325
 
        storageConnection       = NULL;
2326
 
        storageTable            = NULL;
2327
 
}
2328
 
 
2329
 
NfsPluginHandler::~NfsPluginHandler()
2330
 
{
2331
 
}
2332
 
 
2333
 
//*****************************************************************************
2334
 
//
2335
 
// System Memory Usage
2336
 
//
2337
 
//*****************************************************************************
2338
 
int NfsPluginHandler::call_fillSystemMemoryDetailTable(THD *thd, TABLE_LIST *tables, COND *cond)
2339
 
{
2340
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2341
 
        
2342
 
        if (storageHandler)
2343
 
                storageHandler->getMemoryDetailInfo(&infoTable);
2344
 
        
2345
 
        return infoTable.error;
2346
 
}
2347
 
 
2348
 
 
2349
 
ST_FIELD_INFO memoryDetailFieldInfo[]=
2350
 
{
2351
 
        {"FILE",                  120, MYSQL_TYPE_STRING,       0, 0, "File", SKIP_OPEN_TABLE},
2352
 
        {"LINE",                        4, MYSQL_TYPE_LONG,             0, 0, "Line", SKIP_OPEN_TABLE},
2353
 
        {"OBJECTS_IN_USE",      4, MYSQL_TYPE_LONG,             0, 0, "Objects in Use", SKIP_OPEN_TABLE},
2354
 
        {"SPACE_IN_USE",        4, MYSQL_TYPE_LONG,             0, 0, "Space in Use", SKIP_OPEN_TABLE},
2355
 
        {"OBJECTS_DELETED", 4, MYSQL_TYPE_LONG,         0, 0, "Objects Deleted", SKIP_OPEN_TABLE},
2356
 
        {"SPACE_DELETED",       4, MYSQL_TYPE_LONG,             0, 0, "Space Deleted", SKIP_OPEN_TABLE},
2357
 
        {0,                                     0, MYSQL_TYPE_STRING,   0, 0, 0, SKIP_OPEN_TABLE}
2358
 
};
2359
 
 
2360
 
int NfsPluginHandler::initSystemMemoryDetail(void *p)
2361
 
{
2362
 
        DBUG_ENTER("initSystemMemoryDetail");
2363
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE*) p;
2364
 
        schema->fields_info = memoryDetailFieldInfo;
2365
 
        schema->fill_table = NfsPluginHandler::call_fillSystemMemoryDetailTable;
2366
 
        DBUG_RETURN(0);
2367
 
}
2368
 
 
2369
 
int NfsPluginHandler::deinitSystemMemoryDetail(void *p)
2370
 
{
2371
 
        DBUG_ENTER("deinitSystemMemoryDetail");
2372
 
        DBUG_RETURN(0);
2373
 
}
2374
 
 
2375
 
//*****************************************************************************
2376
 
//
2377
 
// System memory usage summary
2378
 
//
2379
 
//*****************************************************************************
2380
 
 
2381
 
int NfsPluginHandler::call_fillSystemMemorySummaryTable(THD *thd, TABLE_LIST *tables, COND *cond)
2382
 
{
2383
 
        //return(pluginHandler->fillSystemMemorySummaryTable(thd, tables, cond));
2384
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2385
 
        
2386
 
        if (storageHandler)
2387
 
                storageHandler->getMemorySummaryInfo(&infoTable);
2388
 
        
2389
 
        return infoTable.error;
2390
 
}
2391
 
 
2392
 
ST_FIELD_INFO memorySummaryFieldInfo[]=
2393
 
{
2394
 
        {"TOTAL_SPACE",         4, MYSQL_TYPE_LONGLONG,         0, 0, "Total Space", SKIP_OPEN_TABLE},
2395
 
        {"FREE_SPACE",          4, MYSQL_TYPE_LONGLONG,         0, 0, "Free Space", SKIP_OPEN_TABLE},
2396
 
        {"FREE_SEGMENTS",       4, MYSQL_TYPE_LONG,                     0, 0, "Free Segments", SKIP_OPEN_TABLE},
2397
 
        {"BIG_HUNKS",           4, MYSQL_TYPE_LONG,                     0, 0, "Big Hunks", SKIP_OPEN_TABLE},
2398
 
        {"SMALL_HUNKS",         4, MYSQL_TYPE_LONG,                     0, 0, "Small Hunks", SKIP_OPEN_TABLE},
2399
 
        {"UNIQUE_SIZES",        4, MYSQL_TYPE_LONG,                     0, 0, "Unique Sizes", SKIP_OPEN_TABLE},
2400
 
        {0,                                     0, MYSQL_TYPE_STRING,           0, 0, 0, SKIP_OPEN_TABLE}
2401
 
};
2402
 
 
2403
 
int NfsPluginHandler::initSystemMemorySummary(void *p)
2404
 
{
2405
 
        DBUG_ENTER("initSystemMemorySummary");
2406
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2407
 
        schema->fields_info = memorySummaryFieldInfo;
2408
 
        schema->fill_table = NfsPluginHandler::call_fillSystemMemorySummaryTable;
2409
 
 
2410
 
        DBUG_RETURN(0);
2411
 
}
2412
 
 
2413
 
int NfsPluginHandler::deinitSystemMemorySummary(void *p)
2414
 
{
2415
 
        DBUG_ENTER("deinitSystemMemorySummary");
2416
 
        DBUG_RETURN(0);
2417
 
}
2418
 
 
2419
 
//*****************************************************************************
2420
 
//
2421
 
// Record cache usage detail
2422
 
//
2423
 
//*****************************************************************************
2424
 
 
2425
 
int NfsPluginHandler::call_fillRecordCacheDetailTable(THD *thd, TABLE_LIST *tables, COND *cond)
2426
 
{
2427
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2428
 
 
2429
 
        if (storageHandler)
2430
 
                storageHandler->getRecordCacheDetailInfo(&infoTable);
2431
 
        
2432
 
        return infoTable.error;
2433
 
}
2434
 
 
2435
 
ST_FIELD_INFO recordDetailFieldInfo[]=
2436
 
{
2437
 
        {"FILE",                  120, MYSQL_TYPE_STRING,       0, 0, "File", SKIP_OPEN_TABLE},
2438
 
        {"LINE",                        4, MYSQL_TYPE_LONG,             0, 0, "Line", SKIP_OPEN_TABLE},
2439
 
        {"OBJECTS_IN_USE",      4, MYSQL_TYPE_LONG,             0, 0, "Objects in Use", SKIP_OPEN_TABLE},
2440
 
        {"SPACE_IN_USE",        4, MYSQL_TYPE_LONG,             0, 0, "Space in Use", SKIP_OPEN_TABLE},
2441
 
        {"OBJECTS_DELETED", 4, MYSQL_TYPE_LONG,         0, 0, "Objects Deleted", SKIP_OPEN_TABLE},
2442
 
        {"SPACE_DELETED",       4, MYSQL_TYPE_LONG,             0, 0, "Space Deleted", SKIP_OPEN_TABLE},
2443
 
        {0,                                     0, MYSQL_TYPE_STRING,   0, 0, 0, SKIP_OPEN_TABLE}
2444
 
};
2445
 
 
2446
 
int NfsPluginHandler::initRecordCacheDetail(void *p)
2447
 
{
2448
 
        DBUG_ENTER("initRecordCacheDetail");
2449
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2450
 
        schema->fields_info = recordDetailFieldInfo;
2451
 
        schema->fill_table = NfsPluginHandler::call_fillRecordCacheDetailTable;
2452
 
 
2453
 
        DBUG_RETURN(0);
2454
 
}
2455
 
 
2456
 
int NfsPluginHandler::deinitRecordCacheDetail(void *p)
2457
 
{
2458
 
        DBUG_ENTER("deinitRecordCacheDetail");
2459
 
        DBUG_RETURN(0);
2460
 
}
2461
 
 
2462
 
//*****************************************************************************
2463
 
//
2464
 
// Record cache usage summary
2465
 
//
2466
 
//*****************************************************************************
2467
 
 
2468
 
int NfsPluginHandler::call_fillRecordCacheSummaryTable(THD *thd, TABLE_LIST *tables, COND *cond)
2469
 
{
2470
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2471
 
 
2472
 
        if (storageHandler)
2473
 
                storageHandler->getRecordCacheSummaryInfo(&infoTable);  
2474
 
        
2475
 
        return infoTable.error;
2476
 
}
2477
 
 
2478
 
ST_FIELD_INFO recordSummaryFieldInfo[]=
2479
 
{
2480
 
        {"TOTAL_SPACE",         4, MYSQL_TYPE_LONGLONG,         0, 0, "Total Space", SKIP_OPEN_TABLE},
2481
 
        {"FREE_SPACE",          4, MYSQL_TYPE_LONGLONG,         0, 0, "Free Space", SKIP_OPEN_TABLE},
2482
 
        {"FREE_SEGMENTS",       4, MYSQL_TYPE_LONG,                     0, 0, "Free Segments", SKIP_OPEN_TABLE},
2483
 
        {"BIG_HUNKS",           4, MYSQL_TYPE_LONG,                     0, 0, "Big Hunks", SKIP_OPEN_TABLE},
2484
 
        {"SMALL_HUNKS",         4, MYSQL_TYPE_LONG,                     0, 0, "Small Hunks", SKIP_OPEN_TABLE},
2485
 
        {"UNIQUE_SIZES",        4, MYSQL_TYPE_LONG,                     0, 0, "Unique Sizes", SKIP_OPEN_TABLE},
2486
 
        {0,                                     0, MYSQL_TYPE_STRING,           0, 0, 0, SKIP_OPEN_TABLE}
2487
 
};
2488
 
 
2489
 
int NfsPluginHandler::initRecordCacheSummary(void *p)
2490
 
{
2491
 
        DBUG_ENTER("initRecordCacheSummary");
2492
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2493
 
        schema->fields_info = recordSummaryFieldInfo;
2494
 
        schema->fill_table = NfsPluginHandler::call_fillRecordCacheSummaryTable;
2495
 
 
2496
 
        DBUG_RETURN(0);
2497
 
}
2498
 
 
2499
 
int NfsPluginHandler::deinitRecordCacheSummary(void *p)
2500
 
{
2501
 
        DBUG_ENTER("deinitRecordCacheSummary");
2502
 
        DBUG_RETURN(0);
2503
 
}
2504
 
 
2505
 
//*****************************************************************************
2506
 
//
2507
 
// Database IO
2508
 
//
2509
 
//*****************************************************************************
2510
 
 
2511
 
int NfsPluginHandler::call_fillDatabaseIOTable(THD *thd, TABLE_LIST *tables, COND *cond)
2512
 
{
2513
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2514
 
 
2515
 
        if (storageHandler)
2516
 
                storageHandler->getIOInfo(&infoTable);
2517
 
 
2518
 
        return infoTable.error;
2519
 
}
2520
 
 
2521
 
ST_FIELD_INFO databaseIOFieldInfo[]=
2522
 
{
2523
 
        {"DATABASE",      120, MYSQL_TYPE_STRING,       0, 0, "Database", SKIP_OPEN_TABLE},
2524
 
        {"PAGE_SIZE",           4, MYSQL_TYPE_LONG,             0, 0, "Page Size", SKIP_OPEN_TABLE},
2525
 
        {"BUFFERS",                     4, MYSQL_TYPE_LONG,             0, 0, "Buffers", SKIP_OPEN_TABLE},
2526
 
        {"PHYSICAL_READS",      4, MYSQL_TYPE_LONG,             0, 0, "Physical Reads", SKIP_OPEN_TABLE},
2527
 
        {"WRITES",                      4, MYSQL_TYPE_LONG,             0, 0, "Writes", SKIP_OPEN_TABLE},
2528
 
        {"LOGICAL_READS",       4, MYSQL_TYPE_LONG,             0, 0, "Logical Reads", SKIP_OPEN_TABLE},
2529
 
        {"FAKES",                       4, MYSQL_TYPE_LONG,             0, 0, "Fakes", SKIP_OPEN_TABLE},
2530
 
        {0,                                     0, MYSQL_TYPE_STRING,   0, 0, 0, SKIP_OPEN_TABLE}
2531
 
};
2532
 
 
2533
 
int NfsPluginHandler::initDatabaseIO(void *p)
2534
 
{
2535
 
        DBUG_ENTER("initDatabaseIO");
2536
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2537
 
        schema->fields_info = databaseIOFieldInfo;
2538
 
        schema->fill_table = NfsPluginHandler::call_fillDatabaseIOTable;
2539
 
        
2540
 
        DBUG_RETURN(0);
2541
 
}
2542
 
 
2543
 
int NfsPluginHandler::deinitDatabaseIO(void *p)
2544
 
{
2545
 
        DBUG_ENTER("deinitDatabaseIO");
2546
 
        DBUG_RETURN(0);
2547
 
}
2548
 
 
2549
 
int NfsPluginHandler::callTablesInfo(THD *thd, TABLE_LIST *tables, COND *cond)
2550
 
{
2551
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2552
 
 
2553
 
        if (storageHandler)
2554
 
                storageHandler->getTablesInfo(&infoTable);
2555
 
 
2556
 
        return infoTable.error;
2557
 
}
2558
 
 
2559
 
 
2560
 
ST_FIELD_INFO tablesFieldInfo[]=
2561
 
{
2562
 
        {"SCHEMA_NAME",   127, MYSQL_TYPE_STRING,       0, 0, "Schema Name", SKIP_OPEN_TABLE},
2563
 
        {"TABLE_NAME",    127, MYSQL_TYPE_STRING,       0, 0, "Table Name", SKIP_OPEN_TABLE},
2564
 
        {"TABLESPACE",    127, MYSQL_TYPE_STRING,       0, 0, "Tablespace", SKIP_OPEN_TABLE},
2565
 
        {0,                                     0, MYSQL_TYPE_STRING,   0, 0, 0, SKIP_OPEN_TABLE}
2566
 
};
2567
 
 
2568
 
int NfsPluginHandler::initTablesInfo(void *p)
2569
 
{
2570
 
        DBUG_ENTER("initTablesInfo");
2571
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2572
 
        schema->fields_info = tablesFieldInfo;
2573
 
        schema->fill_table = NfsPluginHandler::callTablesInfo;
2574
 
        
2575
 
        DBUG_RETURN(0);
2576
 
}
2577
 
 
2578
 
int NfsPluginHandler::deinitTablesInfo(void *p)
2579
 
{
2580
 
        DBUG_ENTER("initTables");
2581
 
        DBUG_RETURN(0);
2582
 
}
2583
 
 
2584
 
//*****************************************************************************
2585
 
//
2586
 
// Transaction Information
2587
 
//
2588
 
//*****************************************************************************
2589
 
 
2590
 
int NfsPluginHandler::callTransactionInfo(THD *thd, TABLE_LIST *tables, COND *cond)
2591
 
{
2592
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2593
 
 
2594
 
        if (storageHandler)
2595
 
                storageHandler->getTransactionInfo(&infoTable);
2596
 
 
2597
 
        return infoTable.error;
2598
 
}
2599
 
 
2600
 
ST_FIELD_INFO transactionInfoFieldInfo[]=
2601
 
{
2602
 
        {"DATABASE",            120, MYSQL_TYPE_STRING,         0, 0, "Database", SKIP_OPEN_TABLE},
2603
 
        {"THREAD_ID",           4, MYSQL_TYPE_LONG,                     0, 0, "Thread Id", SKIP_OPEN_TABLE},
2604
 
        {"ID",                          4, MYSQL_TYPE_LONG,                     0, 0, "Id", SKIP_OPEN_TABLE},
2605
 
        {"STATE",                       10, MYSQL_TYPE_STRING,          0, 0, "State", SKIP_OPEN_TABLE},
2606
 
        {"UPDATES",                     4, MYSQL_TYPE_LONG,                     0, 0, "Has Updates", SKIP_OPEN_TABLE},
2607
 
        {"PENDING",                     4, MYSQL_TYPE_LONG,                     0, 0, "Write Pending", SKIP_OPEN_TABLE},
2608
 
        {"DEP",                         4, MYSQL_TYPE_LONG,                     0, 0, "Dependencies", SKIP_OPEN_TABLE},
2609
 
        {"OLDEST",                      4, MYSQL_TYPE_LONG,                     0, 0, "Oldest Active", SKIP_OPEN_TABLE},
2610
 
        {"RECORDS",                     4, MYSQL_TYPE_LONG,                     0, 0, "Has Records", SKIP_OPEN_TABLE},
2611
 
        {"WAITING_FOR",         4, MYSQL_TYPE_LONG,                     0, 0, "Waiting For", SKIP_OPEN_TABLE},
2612
 
        {"STATEMENT",     120, MYSQL_TYPE_STRING,               0, 0, "Statement", SKIP_OPEN_TABLE},
2613
 
        {0,                                     0, MYSQL_TYPE_STRING,           0, 0, 0, SKIP_OPEN_TABLE}
2614
 
};
2615
 
 
2616
 
int NfsPluginHandler::initTransactionInfo(void *p)
2617
 
{
2618
 
        DBUG_ENTER("initTransactionInfo");
2619
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2620
 
        schema->fields_info = transactionInfoFieldInfo;
2621
 
        schema->fill_table = NfsPluginHandler::callTransactionInfo;
2622
 
        
2623
 
        DBUG_RETURN(0);
2624
 
}
2625
 
 
2626
 
int NfsPluginHandler::deinitTransactionInfo(void *p)
2627
 
{
2628
 
        DBUG_ENTER("deinitTransactionInfo");
2629
 
        DBUG_RETURN(0);
2630
 
}
2631
 
 
2632
 
//*****************************************************************************
2633
 
//
2634
 
// Transaction Summary Information
2635
 
//
2636
 
//*****************************************************************************
2637
 
 
2638
 
int NfsPluginHandler::callTransactionSummaryInfo(THD *thd, TABLE_LIST *tables, COND *cond)
2639
 
{
2640
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2641
 
 
2642
 
        if (storageHandler)
2643
 
                storageHandler->getTransactionSummaryInfo(&infoTable);
2644
 
 
2645
 
        return infoTable.error;
2646
 
}
2647
 
 
2648
 
ST_FIELD_INFO transactionInfoFieldSummaryInfo[]=
2649
 
{
2650
 
        {"DATABASE",            120, MYSQL_TYPE_STRING,         0, 0, "Database", SKIP_OPEN_TABLE},
2651
 
        {"COMMITTED",           4, MYSQL_TYPE_LONG,                     0, 0, "Committed Transaction.", SKIP_OPEN_TABLE},
2652
 
        {"ROLLED_BACK",         4, MYSQL_TYPE_LONG,                     0, 0, "Transactions Rolled Back.", SKIP_OPEN_TABLE},
2653
 
        {"ACTIVE",              4, MYSQL_TYPE_LONG,                     0, 0, "Active Transactions", SKIP_OPEN_TABLE},
2654
 
        {"PENDING_COMMIT",      4, MYSQL_TYPE_LONG,                     0, 0, "Transaction Pending Commit", SKIP_OPEN_TABLE},
2655
 
        {"PENDING_COMPLETION",4, MYSQL_TYPE_LONG,               0, 0, "Transaction Pending Completion", SKIP_OPEN_TABLE},
2656
 
        {0,                                     0, MYSQL_TYPE_STRING,           0, 0, 0, SKIP_OPEN_TABLE}
2657
 
};
2658
 
 
2659
 
int NfsPluginHandler::initTransactionSummaryInfo(void *p)
2660
 
{
2661
 
        DBUG_ENTER("initTransactionSummaryInfo");
2662
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2663
 
        schema->fields_info = transactionInfoFieldSummaryInfo;
2664
 
        schema->fill_table = NfsPluginHandler::callTransactionSummaryInfo;
2665
 
        
2666
 
        DBUG_RETURN(0);
2667
 
}
2668
 
 
2669
 
int NfsPluginHandler::deinitTransactionSummaryInfo(void *p)
2670
 
{
2671
 
        DBUG_ENTER("deinitTransactionInfo");
2672
 
        DBUG_RETURN(0);
2673
 
}
2674
 
 
2675
 
 
2676
 
//*****************************************************************************
2677
 
//
2678
 
// SerialLog Information
2679
 
//
2680
 
//*****************************************************************************
2681
 
 
2682
 
int NfsPluginHandler::callSerialLogInfo(THD *thd, TABLE_LIST *tables, COND *cond)
2683
 
{
2684
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2685
 
 
2686
 
        if (storageHandler)
2687
 
                storageHandler->getSerialLogInfo(&infoTable);
2688
 
 
2689
 
        return infoTable.error;
2690
 
}
2691
 
 
2692
 
ST_FIELD_INFO serialSerialLogFieldInfo[]=
2693
 
{
2694
 
        {"DATABASE",            120, MYSQL_TYPE_STRING,         0, 0, "Database", SKIP_OPEN_TABLE},
2695
 
        {"TRANSACTIONS",        4, MYSQL_TYPE_LONG,                     0, 0, "Transactions", SKIP_OPEN_TABLE},
2696
 
        {"BLOCKS",                      8, MYSQL_TYPE_LONGLONG,         0, 0, "Blocks", SKIP_OPEN_TABLE},
2697
 
        {"WINDOWS",                     4, MYSQL_TYPE_LONG,                     0, 0, "Windows", SKIP_OPEN_TABLE},
2698
 
        {"BUFFERS",                     4, MYSQL_TYPE_LONG,                     0, 0, "Buffers", SKIP_OPEN_TABLE},
2699
 
        {0,                                     0, MYSQL_TYPE_STRING,           0, 0, 0, SKIP_OPEN_TABLE}
2700
 
};
2701
 
 
2702
 
int NfsPluginHandler::initSerialLogInfo(void *p)
2703
 
{
2704
 
        DBUG_ENTER("initSerialLogInfoInfo");
2705
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2706
 
        schema->fields_info = serialSerialLogFieldInfo;
2707
 
        schema->fill_table = NfsPluginHandler::callSerialLogInfo;
2708
 
        
2709
 
        DBUG_RETURN(0);
2710
 
}
2711
 
 
2712
 
int NfsPluginHandler::deinitSerialLogInfo(void *p)
2713
 
{
2714
 
        DBUG_ENTER("deinitSerialLogInfo");
2715
 
        DBUG_RETURN(0);
2716
 
}
2717
 
 
2718
 
 
2719
 
//*****************************************************************************
2720
 
//
2721
 
// Sync Information
2722
 
//
2723
 
//*****************************************************************************
2724
 
 
2725
 
int NfsPluginHandler::callSyncInfo(THD *thd, TABLE_LIST *tables, COND *cond)
2726
 
{
2727
 
        InfoTableImpl infoTable(thd, tables, system_charset_info);
2728
 
 
2729
 
        if (storageHandler)
2730
 
                storageHandler->getSyncInfo(&infoTable);
2731
 
 
2732
 
        return infoTable.error;
2733
 
}
2734
 
 
2735
 
ST_FIELD_INFO syncInfoFieldInfo[]=
2736
 
{
2737
 
        {"CALLER",                      120, MYSQL_TYPE_STRING,         0, 0, "Caller", SKIP_OPEN_TABLE},
2738
 
        {"SHARED",                      4, MYSQL_TYPE_LONG,                     0, 0, "Shared", SKIP_OPEN_TABLE},
2739
 
        {"EXCLUSIVE",           4, MYSQL_TYPE_LONG,                     0, 0, "Exclusive", SKIP_OPEN_TABLE},
2740
 
        {"WAITS",                       4, MYSQL_TYPE_LONG,                     0, 0, "Waits", SKIP_OPEN_TABLE},
2741
 
        {"QUEUE_LENGTH",        4, MYSQL_TYPE_LONG,                     0, 0, "Queue Length", SKIP_OPEN_TABLE},
2742
 
        {0,                                     0, MYSQL_TYPE_STRING,           0, 0, 0, SKIP_OPEN_TABLE}
2743
 
};
2744
 
 
2745
 
int NfsPluginHandler::initSyncInfo(void *p)
2746
 
{
2747
 
        DBUG_ENTER("initSyncInfo");
2748
 
        ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *)p;
2749
 
        schema->fields_info = syncInfoFieldInfo;
2750
 
        schema->fill_table = NfsPluginHandler::callSyncInfo;
2751
 
        
2752
 
        DBUG_RETURN(0);
2753
 
}
2754
 
 
2755
 
int NfsPluginHandler::deinitSyncInfo(void *p)
2756
 
{
2757
 
        DBUG_ENTER("deinitSyncInfo");
2758
 
        DBUG_RETURN(0);
2759
 
}
2760
 
 
2761
 
static void updateIndexChillThreshold(MYSQL_THD thd,
2762
 
                                      struct st_mysql_sys_var *var,
2763
 
                                      void *var_ptr, void *save)
2764
 
{
2765
 
        // TBD; Apply this setting to all configurations associated with 'thd'.
2766
 
        //uint newFalconIndexChillThreshold = *((uint *) save);
2767
 
}
2768
 
 
2769
 
static void updateRecordChillThreshold(MYSQL_THD thd,
2770
 
                                      struct st_mysql_sys_var *var,
2771
 
                                      void *var_ptr, void *save)
2772
 
{
2773
 
        // TBD; Apply this setting to all configurations associated with 'thd'.
2774
 
        //uint newFalconRecordChillThreshold = *((uint *) save);
2775
 
}
2776
 
 
2777
 
 
2778
 
void StorageInterface::updateFsyncDisable(MYSQL_THD thd, struct st_mysql_sys_var* variable, void *var_ptr, void *save)
2779
 
{
2780
 
        falcon_disable_fsync = *(my_bool*) save;
2781
 
        
2782
 
        if (storageHandler)
2783
 
                storageHandler->setSyncDisable(falcon_disable_fsync);
2784
 
}
2785
 
 
2786
 
void StorageInterface::updateRecordMemoryMax(MYSQL_THD thd, struct st_mysql_sys_var* variable, void* var_ptr, void* save)
2787
 
{
2788
 
        falcon_record_memory_max = *(unsigned long long*) save;
2789
 
        
2790
 
        if (storageHandler)
2791
 
                storageHandler->setRecordMemoryMax(falcon_record_memory_max);
2792
 
}
2793
 
 
2794
 
void StorageInterface::updateRecordScavengeThreshold(MYSQL_THD thd, struct st_mysql_sys_var* variable, void* var_ptr, void* save)
2795
 
{
2796
 
        falcon_record_scavenge_threshold = *(int*) save;
2797
 
        
2798
 
        if (storageHandler)
2799
 
                storageHandler->setRecordScavengeThreshold(falcon_record_scavenge_threshold);
2800
 
}
2801
 
 
2802
 
void StorageInterface::updateRecordScavengeFloor(MYSQL_THD thd, struct st_mysql_sys_var* variable, void* var_ptr, void* save)
2803
 
{
2804
 
        falcon_record_scavenge_floor = *(int*) save;
2805
 
        
2806
 
        if (storageHandler)
2807
 
                storageHandler->setRecordScavengeFloor(falcon_record_scavenge_floor);
2808
 
}
2809
 
 
2810
 
 
2811
 
static MYSQL_SYSVAR_BOOL(debug_server, falcon_debug_server,
2812
 
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
2813
 
  "Enable Falcon debug code.",
2814
 
  NULL, NULL, FALSE);
2815
 
 
2816
 
static MYSQL_SYSVAR_BOOL(disable_fsync, falcon_disable_fsync,
2817
 
  PLUGIN_VAR_NOCMDARG, // | PLUGIN_VAR_READONLY,
2818
 
  "Disable periodic fsync().",
2819
 
  NULL, StorageInterface::updateFsyncDisable, FALSE);
2820
 
 
2821
 
static MYSQL_SYSVAR_STR(serial_log_dir, falcon_serial_log_dir,
2822
 
  PLUGIN_VAR_RQCMDARG| PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC,
2823
 
  "Falcon serial log file directory.",
2824
 
  NULL, NULL, NULL);
2825
 
 
2826
 
static MYSQL_SYSVAR_STR(checkpoint_schedule, falcon_checkpoint_schedule,
2827
 
  PLUGIN_VAR_RQCMDARG| PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC,
2828
 
  "Falcon checkpoint schedule.",
2829
 
  NULL, NULL, "7 * * * * *");
2830
 
 
2831
 
static MYSQL_SYSVAR_STR(scavenge_schedule, falcon_scavenge_schedule,
2832
 
  PLUGIN_VAR_RQCMDARG| PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC,
2833
 
  "Falcon record scavenge schedule.",
2834
 
  NULL, NULL, "15,45 * * * * *");
2835
 
 
2836
 
static MYSQL_SYSVAR_INT(debug_mask, falcon_debug_mask,
2837
 
  PLUGIN_VAR_RQCMDARG,
2838
 
  "Falcon message type mask for logged messages.",
2839
 
  NULL, NULL, 0, 0, INT_MAX, 0);
2840
 
 
2841
 
static MYSQL_SYSVAR_ULONGLONG(record_memory_max, falcon_record_memory_max,
2842
 
  PLUGIN_VAR_RQCMDARG, // | PLUGIN_VAR_READONLY,
2843
 
  "The maximum size of the record memory cache.",
2844
 
  NULL, StorageInterface::updateRecordMemoryMax, LL(250)<<20, 0, (ulonglong) ~0, LL(1)<<20);
2845
 
 
2846
 
static MYSQL_SYSVAR_INT(record_scavenge_threshold, falcon_record_scavenge_threshold,
2847
 
  PLUGIN_VAR_OPCMDARG, // | PLUGIN_VAR_READONLY,
2848
 
  "The percentage of falcon_record_memory_max that will cause the scavenger thread to start scavenging records from the record cache.",
2849
 
  NULL, StorageInterface::updateRecordScavengeThreshold, 67, 10, 100, 1);
2850
 
  
2851
 
static MYSQL_SYSVAR_INT(record_scavenge_floor, falcon_record_scavenge_floor,
2852
 
  PLUGIN_VAR_OPCMDARG, // | PLUGIN_VAR_READONLY,
2853
 
  "A percentage of falcon_record_memory_threshold that defines the amount of record data that will remain in the record cache after a scavenge run.",
2854
 
  NULL, StorageInterface::updateRecordScavengeFloor, 50, 10, 90, 1);
2855
 
 
2856
 
static MYSQL_SYSVAR_ULONGLONG(initial_allocation, falcon_initial_allocation,
2857
 
  PLUGIN_VAR_RQCMDARG, // | PLUGIN_VAR_READONLY,
2858
 
  "Initial allocation (in bytes) of falcon user tablespace.",
2859
 
  NULL, NULL, 0, 0, LL(4000000000), LL(1)<<20);
2860
 
 
2861
 
/***
2862
 
static MYSQL_SYSVAR_UINT(allocation_extent, falcon_allocation_extent,
2863
 
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
2864
 
  "The percentage of the current size of falcon_user.fts to use as the size of the next extension to the file.",
2865
 
  NULL, NULL, 10, 0, 100, 1);
2866
 
***/
2867
 
 
2868
 
static MYSQL_SYSVAR_ULONGLONG(page_cache_size, falcon_page_cache_size,
2869
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2870
 
  "The amount of memory to be used for the database page cache.",
2871
 
  NULL, NULL, LL(4)<<20, LL(2)<<20, (ulonglong) ~0, LL(1)<<20);
2872
 
 
2873
 
static MYSQL_SYSVAR_UINT(page_size, falcon_page_size,
2874
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2875
 
  "The page size used when creating a Falcon tablespace.",
2876
 
  NULL, NULL, 4096, 1024, 32768, 1024);
2877
 
 
2878
 
static MYSQL_SYSVAR_UINT(serial_log_buffers, falcon_serial_log_buffers,
2879
 
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2880
 
  "The number of buffers allocated for Falcon serial log.",
2881
 
  NULL, NULL, 10, 10, 32768, 10);
2882
 
 
2883
 
static MYSQL_SYSVAR_UINT(index_chill_threshold, falcon_index_chill_threshold,
2884
 
  PLUGIN_VAR_RQCMDARG,
2885
 
  "Mbytes of pending index data that is 'frozen' to the Falcon serial log.",
2886
 
  NULL, &updateIndexChillThreshold, 4, 1, 1024, 1);
2887
 
 
2888
 
/***
2889
 
static MYSQL_SYSVAR_UINT(tablespace_mode, falcon_tablespace_mode,
2890
 
  PLUGIN_VAR_RQCMDARG,
2891
 
  "tablespace mapping mode.",
2892
 
  NULL, NULL, 0, 0, 3, 1);
2893
 
***/
2894
 
 
2895
 
static MYSQL_SYSVAR_UINT(record_chill_threshold, falcon_record_chill_threshold,
2896
 
  PLUGIN_VAR_RQCMDARG,
2897
 
  "Mbytes of pending record data that is 'frozen' to the Falcon serial log.",
2898
 
  NULL, &updateRecordChillThreshold, 5, 1, 1024, 1);
2899
 
 
2900
 
static MYSQL_SYSVAR_UINT(max_transaction_backlog, falcon_max_transaction_backlog,
2901
 
  PLUGIN_VAR_RQCMDARG,
2902
 
  "Maximum number of backlogged transactions.",
2903
 
  NULL, NULL, 150, 1, 1000000, 1);
2904
 
 
2905
 
static struct st_mysql_sys_var* falconVariables[]= {
2906
 
        MYSQL_SYSVAR(debug_server),
2907
 
        MYSQL_SYSVAR(disable_fsync),
2908
 
        MYSQL_SYSVAR(serial_log_dir),
2909
 
        MYSQL_SYSVAR(checkpoint_schedule),
2910
 
        MYSQL_SYSVAR(scavenge_schedule),
2911
 
        MYSQL_SYSVAR(debug_mask),
2912
 
        MYSQL_SYSVAR(record_memory_max),
2913
 
        MYSQL_SYSVAR(record_scavenge_floor),
2914
 
        MYSQL_SYSVAR(record_scavenge_threshold),
2915
 
        MYSQL_SYSVAR(initial_allocation),
2916
 
        //MYSQL_SYSVAR(allocation_extent),
2917
 
        MYSQL_SYSVAR(page_cache_size),
2918
 
        MYSQL_SYSVAR(page_size),
2919
 
        MYSQL_SYSVAR(serial_log_buffers),
2920
 
        MYSQL_SYSVAR(index_chill_threshold),
2921
 
        MYSQL_SYSVAR(record_chill_threshold),
2922
 
        MYSQL_SYSVAR(max_transaction_backlog),
2923
 
        //MYSQL_SYSVAR(tablespace_mode),
2924
 
        NULL
2925
 
};
2926
 
 
2927
 
static st_mysql_storage_engine falcon_storage_engine                    =       { MYSQL_HANDLERTON_INTERFACE_VERSION};
2928
 
static st_mysql_information_schema falcon_system_memory_detail  =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2929
 
static st_mysql_information_schema falcon_system_memory_summary =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2930
 
static st_mysql_information_schema falcon_record_cache_detail   =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2931
 
static st_mysql_information_schema falcon_record_cache_summary  =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2932
 
static st_mysql_information_schema falcon_database_io                   =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2933
 
static st_mysql_information_schema falcon_transaction_info              =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2934
 
static st_mysql_information_schema falcon_transaction_summary_info=     { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2935
 
static st_mysql_information_schema falcon_sync_info                             =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2936
 
static st_mysql_information_schema falcon_serial_log_info               =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2937
 
static st_mysql_information_schema falcon_tables                                =       { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION};
2938
 
 
2939
 
mysql_declare_plugin(falcon)
2940
 
        {
2941
 
        MYSQL_STORAGE_ENGINE_PLUGIN,
2942
 
        &falcon_storage_engine,
2943
 
        falcon_hton_name,
2944
 
        "MySQL AB",
2945
 
        "Falcon storage engine",
2946
 
        PLUGIN_LICENSE_GPL,
2947
 
        StorageInterface::falcon_init,                          /* plugin init */
2948
 
        StorageInterface::falcon_deinit,                                /* plugin deinit */
2949
 
        0x0100,                                                                         /* 1.0 */
2950
 
        falconStatus,                                                           /* status variables */
2951
 
        falconVariables,                                                        /* system variables */
2952
 
        NULL                                                                            /* config options */
2953
 
        },
2954
 
        
2955
 
        {
2956
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
2957
 
        &falcon_system_memory_detail,
2958
 
        "FALCON_SYSTEM_MEMORY_DETAIL",
2959
 
        "MySQL AB",
2960
 
        "Falcon System Memory Detail.",
2961
 
        PLUGIN_LICENSE_GPL,
2962
 
        NfsPluginHandler::initSystemMemoryDetail,       /* plugin init */
2963
 
        NfsPluginHandler::deinitSystemMemoryDetail,     /* plugin deinit */
2964
 
        0x0005,
2965
 
        NULL,                                                                           /* status variables */
2966
 
        NULL,                                                                           /* system variables */
2967
 
        NULL                                                                            /* config options */
2968
 
        },
2969
 
        
2970
 
        {
2971
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
2972
 
        &falcon_system_memory_summary,
2973
 
        "FALCON_SYSTEM_MEMORY_SUMMARY",
2974
 
        "MySQL AB",
2975
 
        "Falcon System Memory Summary.",
2976
 
        PLUGIN_LICENSE_GPL,
2977
 
        NfsPluginHandler::initSystemMemorySummary,      /* plugin init */
2978
 
        NfsPluginHandler::deinitSystemMemorySummary,/* plugin deinit */
2979
 
        0x0005,
2980
 
        NULL,                                                                           /* status variables */
2981
 
        NULL,                                                                           /* system variables */
2982
 
        NULL                                                                            /* config options */
2983
 
        },
2984
 
        
2985
 
        {
2986
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
2987
 
        &falcon_record_cache_detail,
2988
 
        "FALCON_RECORD_CACHE_DETAIL",
2989
 
        "MySQL AB",
2990
 
        "Falcon Record Cache Detail.",
2991
 
        PLUGIN_LICENSE_GPL,
2992
 
        NfsPluginHandler::initRecordCacheDetail,        /* plugin init */
2993
 
        NfsPluginHandler::deinitRecordCacheDetail,      /* plugin deinit */
2994
 
        0x0005,
2995
 
        NULL,                                                                           /* status variables */
2996
 
        NULL,                                                                           /* system variables */
2997
 
        NULL                                                                            /* config options */
2998
 
        },
2999
 
        
3000
 
        {
3001
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
3002
 
        &falcon_record_cache_summary,
3003
 
        "FALCON_RECORD_CACHE_SUMMARY",
3004
 
        "MySQL AB",
3005
 
        "Falcon Record Cache Summary.",
3006
 
        PLUGIN_LICENSE_GPL,
3007
 
        NfsPluginHandler::initRecordCacheSummary,       /* plugin init */
3008
 
        NfsPluginHandler::deinitRecordCacheSummary,     /* plugin deinit */
3009
 
        0x0005,
3010
 
        NULL,                                                                           /* status variables */
3011
 
        NULL,                                                                           /* system variables */
3012
 
        NULL                                                                            /* config options   */
3013
 
        },
3014
 
        
3015
 
        {
3016
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
3017
 
        &falcon_transaction_info,
3018
 
        "FALCON_TRANSACTIONS",
3019
 
        "MySQL AB",
3020
 
        "Falcon Transactions.",
3021
 
        PLUGIN_LICENSE_GPL,
3022
 
        NfsPluginHandler::initTransactionInfo,          /* plugin init */
3023
 
        NfsPluginHandler::deinitTransactionInfo,        /* plugin deinit */
3024
 
        0x0005,
3025
 
        NULL,                                                                           /* status variables */
3026
 
        NULL,                                                                           /* system variables */
3027
 
        NULL                                                                            /* config options   */
3028
 
        },
3029
 
        
3030
 
        {
3031
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
3032
 
        &falcon_transaction_summary_info,
3033
 
        "FALCON_TRANSACTION_SUMMARY",
3034
 
        "MySQL AB",
3035
 
        "Falcon Transaction Summary.",
3036
 
        PLUGIN_LICENSE_GPL,
3037
 
        NfsPluginHandler::initTransactionSummaryInfo,           /* plugin init */
3038
 
        NfsPluginHandler::deinitTransactionSummaryInfo, /* plugin deinit */
3039
 
        0x0005,
3040
 
        NULL,                                                                           /* status variables */
3041
 
        NULL,                                                                           /* system variables */
3042
 
        NULL                                                                            /* config options   */
3043
 
        },
3044
 
        
3045
 
        {
3046
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
3047
 
        &falcon_sync_info,
3048
 
        "FALCON_SYNCOBJECTS",
3049
 
        "MySQL AB",
3050
 
        "Falcon SyncObjects.",
3051
 
        PLUGIN_LICENSE_GPL,
3052
 
        NfsPluginHandler::initSyncInfo,                         /* plugin init */
3053
 
        NfsPluginHandler::deinitSyncInfo,                       /* plugin deinit */
3054
 
        0x0005,
3055
 
        NULL,                                                                           /* status variables */
3056
 
        NULL,                                                                           /* system variables */
3057
 
        NULL                                                                            /* config options   */
3058
 
        },
3059
 
        
3060
 
        {
3061
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
3062
 
        &falcon_serial_log_info,
3063
 
        "FALCON_SERIAL_LOG",
3064
 
        "MySQL AB",
3065
 
        "Falcon Serial Log.",
3066
 
        PLUGIN_LICENSE_GPL,
3067
 
        NfsPluginHandler::initSerialLogInfo,            /* plugin init */
3068
 
        NfsPluginHandler::deinitSerialLogInfo,          /* plugin deinit */
3069
 
        0x0005,
3070
 
        NULL,                                                                           /* status variables */
3071
 
        NULL,                                                                           /* system variables */
3072
 
        NULL                                                                            /* config options   */
3073
 
        },
3074
 
        
3075
 
        {
3076
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
3077
 
        &falcon_database_io,
3078
 
        "FALCON_DATABASE_IO",
3079
 
        "MySQL AB",
3080
 
        "Falcon Database IO.",
3081
 
        PLUGIN_LICENSE_GPL,
3082
 
        NfsPluginHandler::initDatabaseIO,                       /* plugin init */
3083
 
        NfsPluginHandler::deinitDatabaseIO,                     /* plugin deinit */
3084
 
        0x0005,
3085
 
        NULL,                                                                           /* status variables */
3086
 
        NULL,                                                                           /* system variables */
3087
 
        NULL                                                                            /* config options   */
3088
 
        },
3089
 
 
3090
 
        {
3091
 
        MYSQL_INFORMATION_SCHEMA_PLUGIN,
3092
 
        &falcon_tables,
3093
 
        "FALCON_TABLES",
3094
 
        "MySQL AB",
3095
 
        "Falcon Tables.",
3096
 
        PLUGIN_LICENSE_GPL,
3097
 
        NfsPluginHandler::initTablesInfo,                       /* plugin init */
3098
 
        NfsPluginHandler::deinitTablesInfo,                     /* plugin deinit */
3099
 
        0x0005,
3100
 
        NULL,                                                                           /* status variables */
3101
 
        NULL,                                                                           /* system variables */
3102
 
        NULL                                                                            /* config options   */
3103
 
        }
3104
 
        
3105
 
mysql_declare_plugin_end;