~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_handler.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
  the most natural (easiest, fastest) way to do it is to
22
22
  compute List<Item> field_list not in mysql_ha_read
23
 
  but in mysql_ha_open, and then store it in TABLE structure.
 
23
  but in mysql_ha_open, and then store it in Table structure.
24
24
 
25
25
  The problem here is that mysql_parse calls free_item to free all the
26
26
  items allocated at the end of every query. The workaround would to
34
34
 
35
35
/*
36
36
  There are two containers holding information about open handler tables.
37
 
  The first is 'thd->handler_tables'. It is a linked list of TABLE objects.
 
37
  The first is 'thd->handler_tables'. It is a linked list of Table objects.
38
38
  It is used like 'thd->open_tables' in the table cache. The trick is to
39
39
  exchange these two lists during open and lock of tables. Thus the normal
40
40
  table cache code can be used.
41
 
  The second container is a HASH. It holds objects of the type TABLE_LIST.
 
41
  The second container is a HASH. It holds objects of the type TableList.
42
42
  Despite its name, no lists of tables but only single structs are hashed
43
43
  (the 'next' pointer is always NULL). The reason for theis second container
44
 
  is, that we want handler tables to survive FLUSH TABLE commands. A table
45
 
  affected by FLUSH TABLE must be closed so that other threads are not
 
44
  is, that we want handler tables to survive FLUSH Table commands. A table
 
45
  affected by FLUSH Table must be closed so that other threads are not
46
46
  blocked by handler tables still in use. Since we use the normal table cache
47
47
  functions with 'thd->handler_tables', the closed tables are removed from
48
48
  this list. Hence we need the original open information for the handler
49
49
  table in the case that it is used again. This information is handed over
50
 
  to mysql_ha_open() as a TABLE_LIST. So we store this information in the
51
 
  second container, where it is not affected by FLUSH TABLE. The second
 
50
  to mysql_ha_open() as a TableList. So we store this information in the
 
51
  second container, where it is not affected by FLUSH Table. The second
52
52
  container is implemented as a hash for performance reasons. Consequently,
53
53
  we use it not only for re-opening a handler table, but also for the
54
54
  HANDLER ... READ commands. For this purpose, we store a pointer to the
55
 
  TABLE structure (in the first container) in the TBALE_LIST object in the
 
55
  Table structure (in the first container) in the TBALE_LIST object in the
56
56
  second container. When the table is flushed, the pointer is cleared.
57
57
*/
58
58
 
59
 
#include "mysql_priv.h"
60
 
#include "sql_select.h"
61
 
#include <assert.h>
 
59
#include <drizzled/server_includes.h>
 
60
#include <drizzled/sql_select.h>
62
61
 
63
62
#define HANDLER_TABLES_HASH_SIZE 120
64
63
 
74
73
  @note Broadcasts refresh if it closed a table with old version.
75
74
*/
76
75
 
77
 
static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables,
 
76
static void mysql_ha_close_table(THD *thd, TableList *tables,
78
77
                                 bool is_locked)
79
78
{
80
 
  TABLE **table_ptr;
 
79
  Table **table_ptr;
81
80
 
82
81
  /*
83
82
    Though we could take the table pointer from hash_tables->table,
94
93
  {
95
94
    (*table_ptr)->file->ha_index_or_rnd_end();
96
95
    if (! is_locked)
97
 
      VOID(pthread_mutex_lock(&LOCK_open));
 
96
      pthread_mutex_lock(&LOCK_open);
98
97
    if (close_thread_table(thd, table_ptr))
99
98
    {
100
99
      /* Tell threads waiting for refresh that something has happened */
101
100
      broadcast_refresh();
102
101
    }
103
102
    if (! is_locked)
104
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
103
      pthread_mutex_unlock(&LOCK_open);
105
104
  }
106
105
  else if (tables->table)
107
106
  {
108
107
    /* Must be a temporary table */
109
 
    TABLE *table= tables->table;
 
108
    Table *table= tables->table;
110
109
    table->file->ha_index_or_rnd_end();
111
110
    table->query_id= thd->query_id;
112
111
    table->open_by_handler= 0;
131
130
    true  error
132
131
*/
133
132
 
134
 
bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
 
133
bool mysql_ha_close(THD *thd, TableList *tables)
135
134
{
136
 
  TABLE_LIST    *hash_tables;
 
135
  TableList    *hash_tables;
137
136
 
138
 
  if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
139
 
                                              (uchar*) tables->alias,
 
137
  if ((hash_tables= (TableList*) hash_search(&thd->handler_tables_hash,
 
138
                                              (unsigned char*) tables->alias,
140
139
                                              strlen(tables->alias) + 1)))
141
140
  {
142
141
    mysql_ha_close_table(thd, hash_tables, false);
143
 
    hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
 
142
    hash_delete(&thd->handler_tables_hash, (unsigned char*) hash_tables);
144
143
  }
145
144
  else
146
145
  {
159
158
  @param thd Thread identifier.
160
159
  @param tables The list of tables to remove.
161
160
 
162
 
  @return Pointer to head of linked list (TABLE_LIST::next_local) of matching
163
 
          TABLE_LIST elements from handler_tables_hash. Otherwise, NULL if no
 
161
  @return Pointer to head of linked list (TableList::next_local) of matching
 
162
          TableList elements from handler_tables_hash. Otherwise, NULL if no
164
163
          table was matched.
165
164
*/
166
165
 
167
 
static TABLE_LIST *mysql_ha_find(THD *thd, TABLE_LIST *tables)
 
166
static TableList *mysql_ha_find(THD *thd, TableList *tables)
168
167
{
169
 
  TABLE_LIST *hash_tables, *head= NULL, *first= tables;
 
168
  TableList *hash_tables, *head= NULL, *first= tables;
170
169
 
171
170
  /* search for all handlers with matching table names */
172
 
  for (uint i= 0; i < thd->handler_tables_hash.records; i++)
 
171
  for (uint32_t i= 0; i < thd->handler_tables_hash.records; i++)
173
172
  {
174
 
    hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
 
173
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
175
174
    for (tables= first; tables; tables= tables->next_local)
176
175
    {
177
176
      if ((! *tables->db ||
178
 
          ! my_strcasecmp(&my_charset_latin1, hash_tables->db, tables->db)) &&
179
 
          ! my_strcasecmp(&my_charset_latin1, hash_tables->table_name,
 
177
          ! my_strcasecmp(&my_charset_utf8_general_ci, hash_tables->db, tables->db)) &&
 
178
          ! my_strcasecmp(&my_charset_utf8_general_ci, hash_tables->table_name,
180
179
                          tables->table_name))
181
180
        break;
182
181
    }
201
200
  @note Broadcasts refresh if it closed a table with old version.
202
201
*/
203
202
 
204
 
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables, bool is_locked)
 
203
void mysql_ha_rm_tables(THD *thd, TableList *tables, bool is_locked)
205
204
{
206
 
  TABLE_LIST *hash_tables, *next;
 
205
  TableList *hash_tables, *next;
207
206
 
208
207
  assert(tables);
209
208
 
214
213
    next= hash_tables->next_local;
215
214
    if (hash_tables->table)
216
215
      mysql_ha_close_table(thd, hash_tables, is_locked);
217
 
    hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
 
216
    hash_delete(&thd->handler_tables_hash, (unsigned char*) hash_tables);
218
217
    hash_tables= next;
219
218
  }
220
219
 
233
232
 
234
233
void mysql_ha_flush(THD *thd)
235
234
{
236
 
  TABLE_LIST *hash_tables;
 
235
  TableList *hash_tables;
237
236
 
238
237
  safe_mutex_assert_owner(&LOCK_open);
239
238
 
240
 
  for (uint i= 0; i < thd->handler_tables_hash.records; i++)
 
239
  for (uint32_t i= 0; i < thd->handler_tables_hash.records; i++)
241
240
  {
242
 
    hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
 
241
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
243
242
    if (hash_tables->table && hash_tables->table->needs_reopen_or_name_lock())
244
243
    {
245
244
      mysql_ha_close_table(thd, hash_tables, true);
262
261
 
263
262
void mysql_ha_cleanup(THD *thd)
264
263
{
265
 
  TABLE_LIST *hash_tables;
 
264
  TableList *hash_tables;
266
265
 
267
 
  for (uint i= 0; i < thd->handler_tables_hash.records; i++)
 
266
  for (uint32_t i= 0; i < thd->handler_tables_hash.records; i++)
268
267
  {
269
 
    hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i);
 
268
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
270
269
    if (hash_tables->table)
271
270
      mysql_ha_close_table(thd, hash_tables, false);
272
271
   }