~posulliv/drizzle/optimizer-style-cleanup

« back to all changes in this revision

Viewing changes to plugin/pbxt/src/systab_xt.cc

  • Committer: Padraig O'Sullivan
  • Date: 2010-04-17 01:38:47 UTC
  • mfrom: (1237.9.238 bad-staging)
  • Revision ID: osullivan.padraig@gmail.com-20100417013847-ibjioqsfbmf5yg4g
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
 
2
 *
 
3
 * PrimeBase Media Stream for MySQL
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * Paul McCullagh
 
20
 *
 
21
 * 2007-07-18
 
22
 *
 
23
 * H&G2JCtL
 
24
 *
 
25
 * System tables.
 
26
 *
 
27
 */
 
28
 
 
29
#include "xt_config.h"
 
30
 
 
31
#include <stdlib.h>
 
32
#include <time.h>
 
33
#ifdef DRIZZLED
 
34
#include <drizzled/session.h>
 
35
#include <drizzled/table.h>
 
36
#include <drizzled/current_session.h>
 
37
#endif
 
38
 
 
39
#include "ha_pbxt.h"
 
40
#include "systab_xt.h"
 
41
#include "discover_xt.h"
 
42
#include "table_xt.h"
 
43
#include "strutil_xt.h"
 
44
#include "database_xt.h"
 
45
#include "trace_xt.h"
 
46
 
 
47
#if MYSQL_VERSION_ID >= 50120
 
48
#define byte uchar
 
49
#endif
 
50
 
 
51
/*
 
52
 * -------------------------------------------------------------------------
 
53
 * SYSTEM TABLE DEFINITIONS
 
54
 */
 
55
 
 
56
//--------------------------------
 
57
static DT_FIELD_INFO xt_location_info[] =
 
58
{
 
59
        { "Path",                               128,    NULL, MYSQL_TYPE_VARCHAR,       (CHARSET_INFO *) system_charset_info,   0,      "The location of PBXT tables"},
 
60
        { "Table_count",                0,              NULL, MYSQL_TYPE_LONGLONG,      NULL,                                   NOT_NULL_FLAG,          "The number of PBXT table in this location"},
 
61
        { NULL,                                 0,              NULL, MYSQL_TYPE_STRING,        NULL,                                   0, NULL}
 
62
};
 
63
 
 
64
static DT_FIELD_INFO xt_statistics_info[] =
 
65
{
 
66
        { "ID",                                 0,      NULL, MYSQL_TYPE_LONG,                  NULL,                                   NOT_NULL_FLAG,          "The ID of the statistic"},
 
67
        { "Name",                               40,     NULL, MYSQL_TYPE_VARCHAR,               (CHARSET_INFO *) system_charset_info,   0,      "The name of the statistic"},
 
68
        { "Value",                              0,      NULL,   MYSQL_TYPE_LONGLONG,    NULL,                                   NOT_NULL_FLAG,          "The accumulated value"},
 
69
        { NULL,                                 0,      NULL, MYSQL_TYPE_STRING,                NULL,                                   0, NULL}
 
70
};
 
71
 
 
72
/*
 
73
static DT_FIELD_INFO xt_reference_info[] =
 
74
{
 
75
        {"Table_name",          128,                                    NULL, MYSQL_TYPE_STRING,        system_charset_info,    NOT_NULL_FLAG,  "The name of the referencing table"},
 
76
        {"Blob_id",                     NULL,                                   NULL, MYSQL_TYPE_LONGLONG,      NULL,                                   NOT_NULL_FLAG,  "The BLOB reference number - part of the BLOB URL"},
 
77
        {"Column_name",         50,                                             NULL, MYSQL_TYPE_STRING,        system_charset_info,    NOT_NULL_FLAG,  "The column name of the referencing field"},
 
78
        {"Row_condition",       50,                                             NULL, MYSQL_TYPE_VARCHAR,       system_charset_info,    0,                              "This condition identifies the row in the table"},
 
79
        {"Blob_url",            50,                                             NULL, MYSQL_TYPE_VARCHAR,       system_charset_info,    NOT_NULL_FLAG,  "The BLOB URL for HTTP GET access"},
 
80
        {"Repository_id",       NULL,                                   NULL, MYSQL_TYPE_LONG,          NULL,                                   NOT_NULL_FLAG,  "The repository file number of the BLOB"},
 
81
        {"Repo_blob_offset",NULL,                                       NULL, MYSQL_TYPE_LONGLONG,      NULL,                                   NOT_NULL_FLAG,  "The offset in the repository file"},
 
82
        {"Blob_size",           NULL,                                   NULL, MYSQL_TYPE_LONGLONG,      NULL,                                   NOT_NULL_FLAG,  "The size of the BLOB in bytes"},
 
83
        {"Deletion_time",       NULL,                                   NULL, MYSQL_TYPE_TIMESTAMP,     NULL,                                   0,                              "The time the BLOB was deleted"},
 
84
        {"Remove_in",           NULL,                                   NULL, MYSQL_TYPE_LONG,          NULL,                                   0,                              "The number of seconds before the reference/BLOB is removed perminently"},
 
85
        {"Temp_log_id",         NULL,                                   NULL, MYSQL_TYPE_LONG,          NULL,                                   0,                              "Temporary log number of the referencing deletion entry"},
 
86
        {"Temp_log_offset",     NULL,                                   NULL, MYSQL_TYPE_LONGLONG,      NULL,                                   0,                              "Temporary log offset of the referencing deletion entry"},
 
87
        {NULL,                          NULL,                                   NULL, MYSQL_TYPE_STRING,        NULL, 0,                                                                                        NULL}
 
88
};
 
89
*/
 
90
 
 
91
#define XT_SYSTAB_INVALID                       0
 
92
#define XT_SYSTAB_LOCATION_ID           1
 
93
#define XT_SYSTAB_STATISTICS_ID         2
 
94
 
 
95
static THR_LOCK sys_location_lock;
 
96
static THR_LOCK sys_statistics_lock;
 
97
static xtBool   sys_lock_inited = FALSE;
 
98
 
 
99
static XTSystemTableShareRec xt_internal_tables[] =
 
100
{
 
101
        { XT_SYSTAB_LOCATION_ID,        "pbxt.location", &sys_location_lock, xt_location_info, NULL, FALSE},
 
102
        { XT_SYSTAB_STATISTICS_ID,      "pbxt.statistics", &sys_statistics_lock, xt_statistics_info, NULL, FALSE},
 
103
        { XT_SYSTAB_INVALID,            NULL, NULL, NULL, NULL, FALSE}
 
104
};
 
105
 
 
106
 
 
107
/*
 
108
static int pbms_discover_handler(handlerton *hton, THD* thd, const char *db, const char *name, uchar **frmblob, size_t *frmlen)
 
109
{
 
110
        int err = 1, i = 0;
 
111
        MY_STAT stat_info;
 
112
 
 
113
        // Check that the database exists!
 
114
        if ((!db) || ! my_stat(db,&stat_info,MYF(0)))
 
115
                return err;
 
116
                
 
117
        while (pbms_internal_tables[i].name) {
 
118
                if (!strcasecmp(name, pbms_internal_tables[i].name)) {
 
119
                        err = ms_create_table_frm(hton, thd, db, name, pbms_internal_tables[i].info, pbms_internal_tables[i].keys, frmblob, frmlen);
 
120
                        break;
 
121
                }
 
122
                i++;
 
123
        }
 
124
        
 
125
        return err;
 
126
}
 
127
*/
 
128
 
 
129
/*
 
130
 * -------------------------------------------------------------------------
 
131
 * MYSQL UTILITIES
 
132
 */
 
133
 
 
134
static void xt_my_set_notnull_in_record(Field *field, char *record)
 
135
{
 
136
        if (field->null_ptr)
 
137
                record[(uint) (field->null_ptr - (uchar *) field->table->record[0])] &= (uchar) ~field->null_bit;
 
138
}
 
139
 
 
140
/*
 
141
 * -------------------------------------------------------------------------
 
142
 * OPEN SYSTEM TABLES
 
143
 */
 
144
 
 
145
XTOpenSystemTable::XTOpenSystemTable(XTThreadPtr self, XTDatabaseHPtr db, XTSystemTableShare *share, TABLE *table):
 
146
XTObject()
 
147
{
 
148
        ost_share = share;
 
149
        ost_my_table = table;
 
150
        ost_db = db;
 
151
        xt_heap_reference(self, db);
 
152
}
 
153
 
 
154
XTOpenSystemTable::~XTOpenSystemTable()
 
155
{
 
156
        XTSystemTableShare::releaseSystemTable(this);
 
157
}
 
158
 
 
159
/*
 
160
 * -------------------------------------------------------------------------
 
161
 * LOCATION TABLE
 
162
 */
 
163
 
 
164
XTLocationTable::XTLocationTable(XTThreadPtr self, XTDatabaseHPtr db, XTSystemTableShare *share, TABLE *table):
 
165
XTOpenSystemTable(self, db, share, table)
 
166
{
 
167
}
 
168
 
 
169
XTLocationTable::~XTLocationTable()
 
170
{
 
171
        unuse();
 
172
}
 
173
 
 
174
bool XTLocationTable::use()
 
175
{
 
176
        return true;
 
177
}
 
178
 
 
179
bool XTLocationTable::unuse()
 
180
{
 
181
        return true;
 
182
}
 
183
 
 
184
 
 
185
bool XTLocationTable::seqScanInit()
 
186
{
 
187
        lt_index = 0;
 
188
        return true;
 
189
}
 
190
 
 
191
bool XTLocationTable::seqScanNext(char *buf, bool *eof)
 
192
{
 
193
        bool ok = true;
 
194
 
 
195
        *eof = false;
 
196
 
 
197
        xt_ht_lock(NULL, ost_db->db_tables);
 
198
        if (lt_index >= xt_sl_get_size(ost_db->db_table_paths)) {
 
199
                ok = false;
 
200
                *eof = true;
 
201
                goto done;
 
202
        }
 
203
        loadRow(buf, lt_index);
 
204
        lt_index++;
 
205
 
 
206
        done:
 
207
        xt_ht_unlock(NULL, ost_db->db_tables);
 
208
        return ok;
 
209
#ifdef xxx
 
210
        csWord4         last_access;
 
211
        csWord4         last_ref;
 
212
        csWord4         creation_time;
 
213
        csWord4         access_code;
 
214
        csWord2         cont_type;
 
215
        size_t          ref_size;
 
216
        csWord2         head_size;
 
217
        csWord8         blob_size;
 
218
        uint32          len;
 
219
        Field           *curr_field;
 
220
        byte            *save;
 
221
        MX_BITMAP       *save_write_set;
 
222
 
 
223
        last_access = CS_GET_DISK_4(blob->rb_last_access_4);
 
224
        last_ref = CS_GET_DISK_4(blob->rb_last_ref_4);
 
225
        creation_time = CS_GET_DISK_4(blob->rb_create_time_4);
 
226
        cont_type = CS_GET_DISK_2(blob->rb_cont_type_2);
 
227
        ref_size = CS_GET_DISK_1(blob->rb_ref_size_1);
 
228
        head_size = CS_GET_DISK_2(blob->rb_head_size_2);
 
229
        blob_size = CS_GET_DISK_6(blob->rb_blob_size_6);
 
230
        access_code = CS_GET_DISK_4(blob->rb_auth_code_4);
 
231
 
 
232
        /* ASSERT_COLUMN_MARKED_FOR_WRITE is failing when
 
233
         * I use store()!??
 
234
         * But I want to use it! :(
 
235
         */
 
236
        save_write_set = table->write_set;
 
237
        table->write_set = NULL;
 
238
 
 
239
        memset(buf, 0xFF, table->s->null_bytes);
 
240
        for (Field **field=table->field ; *field ; field++) {
 
241
                curr_field = *field;
 
242
 
 
243
                save = curr_field->ptr;
 
244
#if MYSQL_VERSION_ID < 50114
 
245
                curr_field->ptr = (byte *) buf + curr_field->offset();
 
246
#else
 
247
                curr_field->ptr = (byte *) buf + curr_field->offset(curr_field->table->record[0]);
 
248
#endif
 
249
                switch (curr_field->field_name[0]) {
 
250
                        case 'A':
 
251
                                ASSERT(strcmp(curr_field->field_name, "Access_code") == 0);
 
252
                                curr_field->store(access_code, true);
 
253
                                xt_my_set_notnull_in_record(curr_field, buf);
 
254
                                break;
 
255
                        case 'R':
 
256
                                switch (curr_field->field_name[6]) {
 
257
                                        case 't':
 
258
                                                // Repository_id     INT
 
259
                                                ASSERT(strcmp(curr_field->field_name, "Repository_id") == 0);
 
260
                                                curr_field->store(iRepoFile->myRepo->getRepoID(), true);
 
261
                                                xt_my_set_notnull_in_record(curr_field, buf);
 
262
                                                break;
 
263
                                        case 'l':
 
264
                                                // Repo_blob_offset  BIGINT
 
265
                                                ASSERT(strcmp(curr_field->field_name, "Repo_blob_offset") == 0);
 
266
                                                curr_field->store(iRepoOffset, true);
 
267
                                                xt_my_set_notnull_in_record(curr_field, buf);
 
268
                                                break;
 
269
                                }
 
270
                                break;
 
271
                        case 'B':
 
272
                                switch (curr_field->field_name[5]) {
 
273
                                        case 's':
 
274
                                                // Blob_size         BIGINT
 
275
                                                ASSERT(strcmp(curr_field->field_name, "Blob_size") == 0);
 
276
                                                curr_field->store(blob_size, true);
 
277
                                                xt_my_set_notnull_in_record(curr_field, buf);
 
278
                                                break;
 
279
                                        case 'd':
 
280
                                                // Blob_data         LONGBLOB
 
281
                                                ASSERT(strcmp(curr_field->field_name, "Blob_data") == 0);
 
282
                                                if (blob_size <= 0xFFFFFFF) {
 
283
                                                        iBlobBuffer->setLength((u_int) blob_size);
 
284
                                                        len = iRepoFile->read(iBlobBuffer->getBuffer(0), iRepoOffset + head_size, (size_t) blob_size, 0);
 
285
                                                        ((Field_blob *) curr_field)->set_ptr(len, (byte *) iBlobBuffer->getBuffer(0));
 
286
                                                        xt_my_set_notnull_in_record(curr_field, buf);
 
287
                                                }
 
288
                                                break;
 
289
                                }
 
290
                                break;
 
291
                        case 'H':
 
292
                                // Head_size         SMALLINT UNSIGNED
 
293
                                ASSERT(strcmp(curr_field->field_name, "Head_size") == 0);
 
294
                                curr_field->store(head_size, true);
 
295
                                xt_my_set_notnull_in_record(curr_field, buf);
 
296
                                break;
 
297
                        case 'C':
 
298
                                switch (curr_field->field_name[1]) {
 
299
                                        case 'r':
 
300
                                                // Creation_time     TIMESTAMP
 
301
                                                ASSERT(strcmp(curr_field->field_name, "Creation_time") == 0);
 
302
                                                curr_field->store(ms_my_1970_to_mysql_time(creation_time), true);
 
303
                                                xt_my_set_notnull_in_record(curr_field, buf);
 
304
                                                break;
 
305
                                        case 'o':
 
306
                                                // Content_type      CHAR(128)
 
307
                                                ASSERT(strcmp(curr_field->field_name, "Content_type") == 0);
 
308
                                                CSString *cont_type_str = ost_share->mySysDatabase->getContentType(cont_type);
 
309
                                                if (cont_type_str) {
 
310
                                                        curr_field->store(cont_type_str->getCString(), cont_type_str->length(), &my_charset_utf8_general_ci);
 
311
                                                        cont_type_str->release();
 
312
                                                        xt_my_set_notnull_in_record(curr_field, buf);
 
313
                                                }
 
314
                                                break;
 
315
                                }
 
316
                                break;
 
317
                        case 'L':
 
318
                                switch (curr_field->field_name[5]) {
 
319
                                        case 'r':
 
320
                                                // Last_ref_time     TIMESTAMP
 
321
                                                ASSERT(strcmp(curr_field->field_name, "Last_ref_time") == 0);
 
322
                                                curr_field->store(ms_my_1970_to_mysql_time(last_ref), true);
 
323
                                                xt_my_set_notnull_in_record(curr_field, buf);
 
324
                                                break;
 
325
                                        case 'a':
 
326
                                                // Last_access_time  TIMESTAMP
 
327
                                                ASSERT(strcmp(curr_field->field_name, "Last_access_time") == 0);
 
328
                                                curr_field->store(ms_my_1970_to_mysql_time(last_access), true);
 
329
                                                xt_my_set_notnull_in_record(curr_field, buf);
 
330
                                                break;
 
331
                                }
 
332
                                break;
 
333
                }
 
334
                curr_field->ptr = save;
 
335
        }
 
336
 
 
337
        table->write_set = save_write_set;
 
338
        return true;
 
339
#endif
 
340
}
 
341
 
 
342
void XTLocationTable::loadRow(char *buf, xtWord4 row_id)
 
343
{
 
344
        TABLE                   *table = ost_my_table;
 
345
        Field                   *curr_field;
 
346
        XTTablePathPtr  tp_ptr;
 
347
        byte                    *save;
 
348
        MX_BITMAP               *save_write_set;
 
349
 
 
350
        /* ASSERT_COLUMN_MARKED_FOR_WRITE is failing when
 
351
         * I use store()!??
 
352
         * But I want to use it! :(
 
353
         */
 
354
        save_write_set = table->write_set;
 
355
        table->write_set = NULL;
 
356
 
 
357
        memset(buf, 0xFF, table->s->null_bytes);
 
358
 
 
359
        tp_ptr = *((XTTablePathPtr *) xt_sl_item_at(ost_db->db_table_paths, row_id));
 
360
 
 
361
        for (Field **field=table->field ; *field ; field++) {
 
362
                curr_field = *field;
 
363
 
 
364
                save = curr_field->ptr;
 
365
#if MYSQL_VERSION_ID < 50114
 
366
                curr_field->ptr = (byte *) buf + curr_field->offset();
 
367
#else
 
368
                curr_field->ptr = (byte *) buf + curr_field->offset(curr_field->table->record[0]);
 
369
#endif
 
370
                switch (curr_field->field_name[0]) {
 
371
                        case 'P':
 
372
                                // Path                 VARCHAR(128)
 
373
                                ASSERT_NS(strcmp(curr_field->field_name, "Path") == 0);
 
374
                                curr_field->store(tp_ptr->tp_path, strlen(tp_ptr->tp_path), &my_charset_utf8_general_ci);
 
375
                                xt_my_set_notnull_in_record(curr_field, buf);
 
376
                                break;
 
377
                        case 'T':
 
378
                                // Table_count   INT
 
379
                                ASSERT_NS(strcmp(curr_field->field_name, "Table_count") == 0);
 
380
                                curr_field->store(tp_ptr->tp_tab_count, true);
 
381
                                xt_my_set_notnull_in_record(curr_field, buf);
 
382
                                break;
 
383
                }
 
384
                curr_field->ptr = save;
 
385
        }
 
386
        table->write_set = save_write_set;
 
387
}
 
388
 
 
389
xtWord4 XTLocationTable::seqScanPos(xtWord1 *XT_UNUSED(buf))
 
390
{
 
391
        return lt_index-1;
 
392
}
 
393
 
 
394
bool XTLocationTable::seqScanRead(xtWord4 rec_id, char *buf)
 
395
{
 
396
        loadRow(buf, rec_id);
 
397
        return true;
 
398
}
 
399
 
 
400
/*
 
401
 * -------------------------------------------------------------------------
 
402
 * STATISTICS TABLE
 
403
 */
 
404
 
 
405
XTStatisticsTable::XTStatisticsTable(XTThreadPtr self, XTDatabaseHPtr db, XTSystemTableShare *share, TABLE *table):
 
406
XTOpenSystemTable(self, db, share, table)
 
407
{
 
408
}
 
409
 
 
410
XTStatisticsTable::~XTStatisticsTable()
 
411
{
 
412
        unuse();
 
413
}
 
414
 
 
415
bool XTStatisticsTable::use()
 
416
{
 
417
        return true;
 
418
}
 
419
 
 
420
bool XTStatisticsTable::unuse()
 
421
{
 
422
        return true;
 
423
}
 
424
 
 
425
 
 
426
bool XTStatisticsTable::seqScanInit()
 
427
{
 
428
        tt_index = 0;
 
429
        xt_gather_statistics(&tt_statistics);
 
430
        return true;
 
431
}
 
432
 
 
433
bool XTStatisticsTable::seqScanNext(char *buf, bool *eof)
 
434
{
 
435
        bool ok = true;
 
436
 
 
437
        *eof = false;
 
438
 
 
439
        if (tt_index >= XT_STAT_CURRENT_MAX) {
 
440
                ok = false;
 
441
                *eof = true;
 
442
                goto done;
 
443
        }
 
444
        loadRow(buf, tt_index);
 
445
        tt_index++;
 
446
 
 
447
        done:
 
448
        return ok;
 
449
}
 
450
 
 
451
void XTStatisticsTable::loadRow(char *buf, xtWord4 rec_id)
 
452
{
 
453
        TABLE                   *table = ost_my_table;
 
454
        MX_BITMAP               *save_write_set;
 
455
        Field                   *curr_field;
 
456
        byte                    *save;
 
457
        const char              *stat_name;
 
458
        u_llong                 stat_value;
 
459
 
 
460
        /* ASSERT_COLUMN_MARKED_FOR_WRITE is failing when
 
461
         * I use store()!??
 
462
         * But I want to use it! :(
 
463
         */
 
464
        save_write_set = table->write_set;
 
465
        table->write_set = NULL;
 
466
 
 
467
        memset(buf, 0xFF, table->s->null_bytes);
 
468
 
 
469
        stat_name = xt_get_stat_meta_data(rec_id)->sm_name;
 
470
        stat_value = xt_get_statistic(&tt_statistics, ost_db, rec_id);
 
471
 
 
472
        for (Field **field=table->field ; *field ; field++) {
 
473
                curr_field = *field;
 
474
 
 
475
                save = curr_field->ptr;
 
476
#if MYSQL_VERSION_ID < 50114
 
477
                curr_field->ptr = (byte *) buf + curr_field->offset();
 
478
#else
 
479
                curr_field->ptr = (byte *) buf + curr_field->offset(curr_field->table->record[0]);
 
480
#endif
 
481
                switch (curr_field->field_name[0]) {
 
482
                        case 'I':
 
483
                                // Value BIGINT
 
484
                                ASSERT_NS(strcmp(curr_field->field_name, "ID") == 0);
 
485
                                curr_field->store(rec_id+1, true);
 
486
                                xt_my_set_notnull_in_record(curr_field, buf);
 
487
                                break;
 
488
                        case 'N':
 
489
                                // Name VARCHAR(40)
 
490
                                ASSERT_NS(strcmp(curr_field->field_name, "Name") == 0);
 
491
                                curr_field->store(stat_name, strlen(stat_name), &my_charset_utf8_general_ci);
 
492
                                xt_my_set_notnull_in_record(curr_field, buf);
 
493
                                break;
 
494
                        case 'V':
 
495
                                // Value BIGINT
 
496
                                ASSERT_NS(strcmp(curr_field->field_name, "Value") == 0);
 
497
                                curr_field->store(stat_value, true);
 
498
                                xt_my_set_notnull_in_record(curr_field, buf);
 
499
                                break;
 
500
                }
 
501
                curr_field->ptr = save;
 
502
        }
 
503
        table->write_set = save_write_set;
 
504
}
 
505
 
 
506
xtWord4 XTStatisticsTable::seqScanPos(xtWord1 *XT_UNUSED(buf))
 
507
{
 
508
        return tt_index-1;
 
509
}
 
510
 
 
511
bool XTStatisticsTable::seqScanRead(xtWord4 rec_id, char *buf)
 
512
{
 
513
        loadRow(buf, rec_id);
 
514
        return true;
 
515
}
 
516
 
 
517
/*
 
518
 * -------------------------------------------------------------------------
 
519
 * SYSTEM TABLE SHARES
 
520
 */
 
521
 
 
522
static void st_path_to_table_name(size_t size, char *buffer, const char *path)
 
523
{
 
524
        char *str;
 
525
 
 
526
        xt_strcpy(size, buffer, xt_last_2_names_of_path(path));
 
527
        xt_remove_extension(buffer);
 
528
        if ((str = strchr(buffer, '\\')))
 
529
                *str = '.';
 
530
        if ((str = strchr(buffer, '/')))
 
531
                *str = '.';
 
532
}
 
533
 
 
534
void XTSystemTableShare::startUp(XTThreadPtr XT_UNUSED(self))
 
535
{
 
536
        thr_lock_init(&sys_location_lock);
 
537
        thr_lock_init(&sys_statistics_lock);
 
538
        sys_lock_inited = TRUE;
 
539
}
 
540
 
 
541
void XTSystemTableShare::shutDown(XTThreadPtr XT_UNUSED(self))
 
542
{
 
543
        if (sys_lock_inited) {
 
544
                thr_lock_delete(&sys_location_lock);
 
545
                thr_lock_delete(&sys_statistics_lock);
 
546
                sys_lock_inited = FALSE;
 
547
        }
 
548
}
 
549
 
 
550
bool XTSystemTableShare::isSystemTable(const char *table_path)
 
551
{
 
552
        int             i = 0;
 
553
        char    tab_name[100];
 
554
 
 
555
        st_path_to_table_name(100, tab_name, table_path);
 
556
        while (xt_internal_tables[i].sts_path) {
 
557
                if (strcasecmp(tab_name, xt_internal_tables[i].sts_path) == 0)
 
558
                        return true;
 
559
                i++;
 
560
        }
 
561
        return false;
 
562
}
 
563
 
 
564
void XTSystemTableShare::setSystemTableDeleted(const char *table_path)
 
565
{
 
566
        int             i = 0;
 
567
        char    tab_name[100];
 
568
 
 
569
        st_path_to_table_name(100, tab_name, table_path);
 
570
        while (xt_internal_tables[i].sts_path) {
 
571
                if (strcasecmp(tab_name, xt_internal_tables[i].sts_path) == 0) {
 
572
                        xt_internal_tables[i].sts_exists = FALSE;
 
573
                        break;
 
574
                }
 
575
                i++;
 
576
        }
 
577
}
 
578
 
 
579
bool XTSystemTableShare::doesSystemTableExist()
 
580
{
 
581
        int i = 0;
 
582
 
 
583
        while (xt_internal_tables[i].sts_path) {
 
584
                if (xt_internal_tables[i].sts_exists)
 
585
                        return true;
 
586
                i++;
 
587
        }
 
588
        return false;
 
589
}
 
590
 
 
591
void XTSystemTableShare::createSystemTables(XTThreadPtr XT_UNUSED(self), XTDatabaseHPtr XT_UNUSED(db))
 
592
{
 
593
#ifdef PBXT_SYS_TAB
 
594
        int             i = 0;
 
595
 
 
596
        while (xt_internal_tables[i].sts_path) {
 
597
#ifdef DRIZZLED
 
598
                // must ignore errors here
 
599
                drizzled::Session *session = current_thd;
 
600
                //session->main_da.disable_status();
 
601
#endif
 
602
                if (!xt_create_table_frm(pbxt_hton,
 
603
                        current_thd, "pbxt",
 
604
                        strchr(xt_internal_tables[i].sts_path, '.') + 1,
 
605
                        xt_internal_tables[i].sts_info,
 
606
                        xt_internal_tables[i].sts_keys,
 
607
                        TRUE /*do not recreate*/))
 
608
                        xt_internal_tables[i].sts_exists = TRUE;
 
609
                i++;
 
610
#ifdef DRIZZLED
 
611
                session->main_da.reset_diagnostics_area();      
 
612
#endif
 
613
        }
 
614
#endif
 
615
}
 
616
 
 
617
XTOpenSystemTable *XTSystemTableShare::openSystemTable(XTThreadPtr self, const char *table_path, TABLE *table)
 
618
{
 
619
        XTSystemTableShare      *share;
 
620
        XTOpenSystemTable       *otab = NULL;
 
621
        int                                     i = 0;
 
622
        char                            tab_name[100];
 
623
 
 
624
        st_path_to_table_name(100, tab_name, table_path);
 
625
        while (xt_internal_tables[i].sts_path) {
 
626
                if (strcasecmp(tab_name, xt_internal_tables[i].sts_path) == 0) {
 
627
                        share = &xt_internal_tables[i];
 
628
                        goto found;
 
629
                }
 
630
                i++;
 
631
        }
 
632
        return NULL;
 
633
 
 
634
        found:
 
635
        share->sts_exists = TRUE;
 
636
        switch (share->sts_id) {
 
637
                case XT_SYSTAB_LOCATION_ID:
 
638
                        if (!(otab = new XTLocationTable(self, self->st_database, share, table)))
 
639
                                xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
 
640
                        break;
 
641
                case XT_SYSTAB_STATISTICS_ID:
 
642
                        if (!(otab = new XTStatisticsTable(self, self->st_database, share, table)))
 
643
                                xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
 
644
                        break;
 
645
                default:
 
646
                        xt_throw_taberr(XT_CONTEXT, XT_ERR_TABLE_NOT_FOUND, (XTPathStrPtr) table_path);
 
647
                        break;
 
648
        }       
 
649
 
 
650
        return otab;
 
651
}
 
652
 
 
653
void XTSystemTableShare::releaseSystemTable(XTOpenSystemTable *tab)
 
654
{
 
655
        if (tab->ost_db) {
 
656
                XTThreadPtr self = xt_get_self();
 
657
 
 
658
                try_(a) {
 
659
                        xt_heap_release(self, tab->ost_db);
 
660
                }
 
661
                catch_(a) {
 
662
                }
 
663
                cont_(a);
 
664
                tab->ost_db = NULL;
 
665
        }
 
666
}