~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/info_schema_table.h

  • Committer: Stewart Smith
  • Date: 2010-02-15 01:56:32 UTC
  • mto: (1273.13.96 build)
  • mto: This revision was merged to the branch mainline in revision 1308.
  • Revision ID: stewart@flamingspork.com-20100215015632-pm7lnxfq5j5uh8kj
move DATABASE() to function plugin. modify parser so that it looks for a function named 'database' when DATABASE() is called. Special case still needed in parser due to hilarity of not-really-reserved words.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2009 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 */
 
20
 
 
21
#ifndef DRIZZLED_PLUGIN_INFO_SCHEMA_TABLE_H
 
22
#define DRIZZLED_PLUGIN_INFO_SCHEMA_TABLE_H
 
23
 
 
24
#include "drizzled/plugin/plugin.h"
 
25
#include "drizzled/algorithm/crc32.h"
 
26
#include "drizzled/common.h"
 
27
 
 
28
#include <cstring>
 
29
#include <string>
 
30
#include <set>
 
31
#include <algorithm>
 
32
 
 
33
namespace drizzled
 
34
{
 
35
class Session;
 
36
class TableList;
 
37
class Table;
 
38
 
 
39
typedef struct drizzle_lex_string LEX_STRING;
 
40
 
 
41
extern const std::string INFORMATION_SCHEMA_NAME;
 
42
 
 
43
namespace plugin
 
44
{
 
45
 
 
46
/**
 
47
 * @file
 
48
 *   info_schema.h
 
49
 * @brief 
 
50
 *   Header file which contains all classes related to I_S
 
51
 */
 
52
 
 
53
typedef class Item COND;
 
54
class InfoSchemaTable;
 
55
 
 
56
 
 
57
/**
 
58
 * @class ColumnInfo
 
59
 * @brief
 
60
 *   Represents a field (column) in an I_S table.
 
61
 */
 
62
class ColumnInfo 
 
63
 
64
public: 
 
65
  ColumnInfo(const std::string& in_name, 
 
66
             uint32_t in_length, 
 
67
             enum enum_field_types in_type,
 
68
             int32_t in_value,
 
69
             uint32_t in_flags,
 
70
             const std::string& in_old_name)
 
71
    :
 
72
      name(in_name),
 
73
      length(in_length),
 
74
      type(in_type),
 
75
      value(in_value),
 
76
      flags(in_flags),
 
77
      old_name(in_old_name)
 
78
  {}
 
79
 
 
80
  ColumnInfo()
 
81
    :
 
82
      name(),
 
83
      length(0),
 
84
      type(DRIZZLE_TYPE_VARCHAR),
 
85
      flags(0),
 
86
      old_name()
 
87
  {}
 
88
 
 
89
  /**
 
90
   * @return the name of this column.
 
91
   */
 
92
  const std::string &getName() const
 
93
  {
 
94
    return name;
 
95
  }
 
96
 
 
97
  /**
 
98
   * This method is only ever called from the
 
99
   * InfoSchemaMethods::oldFormat() methods. It is mostly
 
100
   * for old SHOW compatability. It is used when a list
 
101
   * of fields need to be generated for SHOW. The names
 
102
   * for those fields (or columns) are found by calling
 
103
   * this method on each column in the I_S table.
 
104
   *
 
105
   * @return the old name of this column.
 
106
   */
 
107
  const std::string &getOldName() const
 
108
  {
 
109
    return old_name;
 
110
  }
 
111
 
 
112
  /**
 
113
   * @return the flags for this column.
 
114
   */
 
115
  uint32_t getFlags() const
 
116
  {
 
117
    return flags;
 
118
  }
 
119
 
 
120
  /**
 
121
   * @return the length of this column.
 
122
   */
 
123
  uint32_t getLength() const
 
124
  {
 
125
    return length;
 
126
  }
 
127
 
 
128
  /**
 
129
   * @return the value of this column.
 
130
   */
 
131
  int32_t getValue() const
 
132
  {
 
133
    return value;
 
134
  }
 
135
 
 
136
  /**
 
137
   * @return this column's type.
 
138
   */
 
139
  enum enum_field_types getType() const
 
140
  {
 
141
    return type;
 
142
  }
 
143
 
 
144
private:
 
145
 
 
146
  /**
 
147
   * This is used as column name.
 
148
   */
 
149
  const std::string name;
 
150
 
 
151
  /**
 
152
   * For string-type columns, this is the maximum number of
 
153
   * characters. Otherwise, it is the 'display-length' for the column.
 
154
   */
 
155
  uint32_t length;
 
156
 
 
157
  /**
 
158
   * This denotes data type for the column. For the most part, there seems to
 
159
   * be one entry in the enum for each SQL data type, although there seem to
 
160
   * be a number of additional entries in the enum.
 
161
   */
 
162
  enum enum_field_types type;
 
163
 
 
164
  int32_t value;
 
165
 
 
166
  /**
 
167
   * This is used to set column attributes. By default, columns are @c NOT
 
168
   * @c NULL and @c SIGNED, and you can deviate from the default
 
169
   * by setting the appopriate flags. You can use either one of the flags
 
170
   * @c MY_I_S_MAYBE_NULL and @cMY_I_S_UNSIGNED or
 
171
   * combine them using the bitwise or operator @c |. Both flags are
 
172
   * defined in table.h.
 
173
   */
 
174
  uint32_t flags;
 
175
 
 
176
  /**
 
177
   * The name of this column which is used for old SHOW
 
178
   * compatability.
 
179
   */
 
180
  const std::string old_name;
 
181
 
 
182
};
 
183
 
 
184
/**
 
185
 * @class InfoSchemaMethods
 
186
 * @brief
 
187
 *   The methods that an I_S table can support
 
188
 */
 
189
class InfoSchemaMethods
 
190
{
 
191
public:
 
192
  virtual ~InfoSchemaMethods() {}
 
193
 
 
194
  virtual int fillTable(Session *session, 
 
195
                        Table *table,
 
196
                        InfoSchemaTable *schema_table);
 
197
  virtual int processTable(InfoSchemaTable *store_table, 
 
198
                           Session *session, TableList *tables,
 
199
                           Table *table, bool res, LEX_STRING *db_name,
 
200
                           LEX_STRING *table_name);
 
201
  virtual int oldFormat(Session *session, 
 
202
                        InfoSchemaTable *schema_table) const;
 
203
};
 
204
 
 
205
/**
 
206
 * @class InfoSchemaRecord
 
207
 * @brief represents a row in an I_S table
 
208
 */
 
209
class InfoSchemaRecord
 
210
{
 
211
public:
 
212
  InfoSchemaRecord();
 
213
  InfoSchemaRecord(unsigned char *buf, size_t in_len);
 
214
  InfoSchemaRecord(const InfoSchemaRecord &rhs);
 
215
 
 
216
  ~InfoSchemaRecord()
 
217
  {
 
218
    if (record)
 
219
    {
 
220
      delete [] record;
 
221
    }
 
222
  }
 
223
 
 
224
  /**
 
225
   * Copy this record into the memory passed to this function.
 
226
   *
 
227
   * @param[out] buf copy the record into this memory
 
228
   */
 
229
  void copyRecordInto(unsigned char *buf)
 
230
  {
 
231
    memcpy(buf, record, rec_len);
 
232
  }
 
233
 
 
234
  /**
 
235
   * @return the length of this record
 
236
   */
 
237
  size_t getRecordLength() const
 
238
  {
 
239
    return rec_len;
 
240
  }
 
241
 
 
242
  /**
 
243
   * @return the checksum of the data in this record
 
244
   */
 
245
  uint32_t getChecksum() const
 
246
  {
 
247
    return checksum;
 
248
  }
 
249
 
 
250
  /**
 
251
   * @param[in] crc a checksum to compare
 
252
   * @return true if the input checksum matches the checksum for this record; false otherwise
 
253
   */
 
254
  bool checksumMatches(uint32_t crc) const
 
255
  {
 
256
    return (checksum == crc);
 
257
  }
 
258
 
 
259
private:
 
260
 
 
261
  unsigned char *record;
 
262
 
 
263
  size_t rec_len;
 
264
 
 
265
  uint32_t checksum;
 
266
 
 
267
};
 
268
 
 
269
class DeleteRows
 
270
{
 
271
public:
 
272
  template<typename T>
 
273
  inline void operator()(const T *ptr) const
 
274
  {
 
275
    delete ptr;
 
276
  }
 
277
};
 
278
 
 
279
class FindRowByChecksum
 
280
{
 
281
  uint32_t cs;
 
282
public:
 
283
  FindRowByChecksum(uint32_t in_cs)
 
284
    :
 
285
      cs(in_cs)
 
286
  {}
 
287
 
 
288
  inline bool operator()(const InfoSchemaRecord *rec) const
 
289
  {
 
290
    return (cs == rec->getChecksum());
 
291
  }
 
292
};
 
293
 
 
294
/**
 
295
 * @class InfoSchemaTable
 
296
 * @brief 
 
297
 *   Represents an I_S table.
 
298
 */
 
299
class InfoSchemaTable : public Plugin
 
300
{
 
301
  InfoSchemaTable();
 
302
  InfoSchemaTable(const InfoSchemaTable &);
 
303
  InfoSchemaTable& operator=(const InfoSchemaTable &);
 
304
public:
 
305
 
 
306
  typedef std::vector<const ColumnInfo *> Columns;
 
307
  typedef std::vector<InfoSchemaRecord *> Rows;
 
308
  
 
309
  InfoSchemaTable(const std::string& tab_name,
 
310
                  Columns& in_column_info,
 
311
                  int idx_col1,
 
312
                  int idx_col2,
 
313
                  bool in_hidden,
 
314
                  bool in_opt_possible,
 
315
                  uint32_t req_object,
 
316
                  InfoSchemaMethods *in_methods)
 
317
    :
 
318
      Plugin(tab_name, "InfoSchemaTable"),
 
319
      hidden(in_hidden),
 
320
      is_opt_possible(in_opt_possible),
 
321
      first_column_index(idx_col1),
 
322
      second_column_index(idx_col2),
 
323
      requested_object(req_object),
 
324
      column_info(in_column_info),
 
325
      rows(),
 
326
      i_s_methods(in_methods),
 
327
      plugin_name("")
 
328
  {}
 
329
 
 
330
  InfoSchemaTable(const std::string& tab_name,
 
331
                  Columns& in_column_info,
 
332
                  int idx_col1,
 
333
                  int idx_col2,
 
334
                  bool in_hidden,
 
335
                  bool in_opt_possible,
 
336
                  uint32_t req_object,
 
337
                  InfoSchemaMethods *in_methods,
 
338
                  const std::string in_plugin_name)
 
339
    :
 
340
      Plugin(tab_name, "InfoSchemaTable"),
 
341
      hidden(in_hidden),
 
342
      is_opt_possible(in_opt_possible),
 
343
      first_column_index(idx_col1),
 
344
      second_column_index(idx_col2),
 
345
      requested_object(req_object),
 
346
      column_info(in_column_info),
 
347
      rows(),
 
348
      i_s_methods(in_methods),
 
349
      plugin_name(in_plugin_name)
 
350
  {}
 
351
 
 
352
  explicit InfoSchemaTable(const std::string& tab_name)
 
353
    :
 
354
      Plugin(tab_name, "InfoSchemaTable"),
 
355
      hidden(false),
 
356
      is_opt_possible(false),
 
357
      first_column_index(0),
 
358
      second_column_index(0),
 
359
      requested_object(0),
 
360
      column_info(),
 
361
      rows(),
 
362
      i_s_methods(NULL),
 
363
      plugin_name("")
 
364
  {}
 
365
 
 
366
  virtual ~InfoSchemaTable()
 
367
  {
 
368
    std::for_each(rows.begin(),
 
369
                  rows.end(),
 
370
                  DeleteRows());
 
371
    rows.clear();
 
372
  }
 
373
 
 
374
  /**
 
375
   * Set the methods available on this I_S table.
 
376
   * @param[in] new_methods the methods to use
 
377
   */
 
378
  void setInfoSchemaMethods(InfoSchemaMethods *new_methods)
 
379
  {
 
380
    i_s_methods= new_methods;
 
381
  }
 
382
 
 
383
  /**
 
384
   * Fill I_S table.
 
385
   *
 
386
   * @param[in] session a session handler
 
387
   * @return 0 on success; 1 on error
 
388
   */
 
389
  int fillTable(Session *session, Table *table)
 
390
  {
 
391
    int retval= i_s_methods->fillTable(session, table, this);
 
392
    return retval;
 
393
  }
 
394
 
 
395
  /**
 
396
   * Fill and store records into an I_S table.
 
397
   *
 
398
   * @param[in] session a session handler
 
399
   * @param[in] tables table list (processed table)
 
400
   * @param[in] table I_S table
 
401
   * @param[in] res 1 means error during opening of the processed table
 
402
   *                0 means processed table opened without error
 
403
   * @param[in] db_name database name
 
404
   * @param[in] tab_name table name
 
405
   * @return 0 on success; 1 on error
 
406
   */
 
407
  int processTable(Session *session, TableList *tables, Table *table,
 
408
                   bool res, LEX_STRING *db_name, LEX_STRING *tab_name)
 
409
  {
 
410
    int retval= i_s_methods->processTable(this, session, tables, table,
 
411
                                          res, db_name, tab_name);
 
412
    return retval;
 
413
  }
 
414
 
 
415
  /**
 
416
   * For old SHOW compatibility. It is used when old SHOW doesn't
 
417
   * have generated column names. Generates the list of fields
 
418
   * for SHOW.
 
419
   *
 
420
   * @param[in] session a session handler
 
421
   * @param[in] schema_table pointer to element of the I_S tables list
 
422
   */
 
423
  int oldFormat(Session *session, InfoSchemaTable *schema_table) const
 
424
  {
 
425
    int retval= i_s_methods->oldFormat(session, schema_table);
 
426
    return retval;
 
427
  }
 
428
 
 
429
  /**
 
430
   * @param[in] new_first_index value to set first column index to
 
431
   */
 
432
  void setFirstColumnIndex(int32_t new_first_index)
 
433
  {
 
434
    first_column_index= new_first_index;
 
435
  }
 
436
 
 
437
  /**
 
438
   * @param[in] new_second_index value to set second column index to
 
439
   */
 
440
  void setSecondColumnIndex(int32_t new_second_index)
 
441
  {
 
442
    second_column_index= new_second_index;
 
443
  }
 
444
 
 
445
  /**
 
446
   * @param[in] in_column_info the columns info to use for this I_S table
 
447
   */
 
448
  void setColumnInfo(ColumnInfo *in_column_info)
 
449
  {
 
450
    ColumnInfo *tmp= in_column_info;
 
451
    for (; tmp->getName().length() != 0; tmp++)
 
452
    {
 
453
      column_info.push_back(tmp);
 
454
    }
 
455
  }
 
456
 
 
457
  /**
 
458
   * @return the name of the I_S table.
 
459
   */
 
460
  const std::string &getTableName() const
 
461
  {
 
462
    return getName();
 
463
  }
 
464
 
 
465
  /**
 
466
   * @return the names of the I_S tables.
 
467
   */
 
468
  static void getTableNames(std::set<std::string>& tables_names);
 
469
 
 
470
  /**
 
471
   * @return true if this I_S table is hidden; false otherwise.
 
472
   */
 
473
  bool isHidden() const
 
474
  {
 
475
    return hidden;
 
476
  }
 
477
 
 
478
  /**
 
479
   * @return true if I_S optimizations can be performed on this
 
480
   *         I_S table when running the fillTable method; false
 
481
   *         otherwise.
 
482
   */
 
483
  bool isOptimizationPossible() const
 
484
  {
 
485
    return is_opt_possible;
 
486
  }
 
487
 
 
488
  /**
 
489
   * @return the index for the first field.
 
490
   */
 
491
  int32_t getFirstColumnIndex() const
 
492
  {
 
493
    return first_column_index;
 
494
  }
 
495
 
 
496
  /**
 
497
   * @return the index the second field.
 
498
   */
 
499
  int32_t getSecondColumnIndex() const
 
500
  {
 
501
    return second_column_index;
 
502
  }
 
503
 
 
504
  /**
 
505
   * @return the requested object.
 
506
   */
 
507
  uint32_t getRequestedObject() const
 
508
  {
 
509
    return requested_object;
 
510
  }
 
511
 
 
512
  /**
 
513
   * @return the plugin name.
 
514
   */
 
515
  const std::string &getPluginName() const
 
516
  {
 
517
    return plugin_name;
 
518
  }
 
519
 
 
520
  /**
 
521
   * @return the columns for this I_S table
 
522
   */
 
523
  const Columns &getColumns() const
 
524
  {
 
525
    return column_info;
 
526
  }
 
527
 
 
528
  /**
 
529
   * @return the rows for this I_S table.
 
530
   */
 
531
  Rows &getRows()
 
532
  {
 
533
    return rows;
 
534
  }
 
535
 
 
536
  /**
 
537
   * Clear the rows for this table and de-allocate all memory for this rows.
 
538
   */
 
539
  void clearRows()
 
540
  {
 
541
    std::for_each(rows.begin(),
 
542
                  rows.end(),
 
543
                  DeleteRows());
 
544
    rows.clear();
 
545
  }
 
546
 
 
547
  /**
 
548
   * Add a row to the std::vector of rows for this I_S table. For the moment, we check to make sure
 
549
   * that we do not add any duplicate rows. This is done in a niave manner for the moment by
 
550
   * checking the crc of the raw data for each row. We will not add this row to the std::vector of
 
551
   * rows for this I_S table is a duplicate row already exists in the std::vector.
 
552
   *
 
553
   * @param[in] buf raw data for the record to add
 
554
   * @param[in] len size of the raw data for the record to add
 
555
   */
 
556
  void addRow(unsigned char *buf, size_t len)
 
557
  {
 
558
    uint32_t cs= algorithm::crc32((const char *) buf, len);
 
559
    Rows::iterator it= std::find_if(rows.begin(),
 
560
                                    rows.end(),
 
561
                                    FindRowByChecksum(cs));
 
562
    if (it == rows.end())
 
563
    {
 
564
      InfoSchemaRecord *record= new InfoSchemaRecord(buf, len);
 
565
      rows.push_back(record);
 
566
    }
 
567
  }
 
568
 
 
569
  /**
 
570
   * @param[in] index the index of this column
 
571
   * @return the name for the column at the given index
 
572
   */
 
573
  const std::string &getColumnName(int index) const
 
574
  {
 
575
    return column_info[index]->getName();
 
576
  }
 
577
 
 
578
private:
 
579
 
 
580
  /**
 
581
   * Boolean which indicates whether this I_S table
 
582
   * is hidden or not. If it is hidden, it will not show
 
583
   * up in the list of I_S tables.
 
584
   */
 
585
  bool hidden;
 
586
 
 
587
  /**
 
588
   * Boolean which indicates whether optimizations are
 
589
   * possible on this I_S table when performing the
 
590
   * fillTable method.
 
591
   */
 
592
  bool is_opt_possible;
 
593
 
 
594
  /**
 
595
   * The index of the first column.
 
596
   */
 
597
  int32_t first_column_index;
 
598
 
 
599
  /**
 
600
   * The index of the second column.
 
601
   */
 
602
  int32_t second_column_index;
 
603
 
 
604
  /**
 
605
   * The object to open (TABLE | VIEW).
 
606
   */
 
607
  uint32_t requested_object;
 
608
 
 
609
  /**
 
610
   * The columns for this I_S table.
 
611
   */
 
612
  Columns column_info;
 
613
 
 
614
  /**
 
615
   * The rows for this I_S table.
 
616
   */
 
617
  Rows rows;
 
618
 
 
619
  /**
 
620
   * Contains the methods available on this I_S table.
 
621
   */
 
622
  InfoSchemaMethods *i_s_methods;
 
623
 
 
624
  /**
 
625
   * The name of the plugin associated with this I_S table
 
626
   * NULL for non I_S tables. 
 
627
   */ 
 
628
  const std::string plugin_name; 
 
629
 
 
630
public:
 
631
  static bool addPlugin(plugin::InfoSchemaTable *schema_table);
 
632
  static void removePlugin(plugin::InfoSchemaTable *table);
 
633
 
 
634
  static plugin::InfoSchemaTable *getTable(const char *table_name);
 
635
  static int addTableToList(Session *session, std::vector<LEX_STRING*> &files,
 
636
                            const char *wild);
 
637
};
 
638
 
 
639
} /* namespace plugin */
 
640
} /* namespace drizzled */
 
641
 
 
642
#endif /* DRIZZLED_PLUGIN_INFO_SCHEMA_TABLE_H */