~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_handler.cc

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
27
 
  keep two item lists per Session - normal free_list and handler_items.
 
27
  keep two item lists per THD - normal free_list and handler_items.
28
28
  The second is to be freeed only on thread end. mysql_ha_open should
29
29
  then do { handler_items=concat(handler_items, free_list); free_list=0; }
30
30
 
34
34
 
35
35
/*
36
36
  There are two containers holding information about open handler tables.
37
 
  The first is 'session->handler_tables'. It is a linked list of Table objects.
38
 
  It is used like 'session->open_tables' in the table cache. The trick is to
 
37
  The first is 'thd->handler_tables'. It is a linked list of Table objects.
 
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
41
  The second container is a HASH. It holds objects of the type TableList.
44
44
  is, that we want handler tables to survive FLUSH Table commands. A table
45
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
 
  functions with 'session->handler_tables', the closed tables are removed from
 
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
50
  to mysql_ha_open() as a TableList. So we store this information in the
58
58
 
59
59
#include <drizzled/server_includes.h>
60
60
#include <drizzled/sql_select.h>
61
 
#include <drizzled/error.h>
62
61
 
 
62
#define HANDLER_TABLES_HASH_SIZE 120
63
63
 
64
64
/**
65
65
  Close a HANDLER table.
66
66
 
67
 
  @param session Thread identifier.
 
67
  @param thd Thread identifier.
68
68
  @param tables A list of tables with the first entry to close.
69
69
  @param is_locked If LOCK_open is locked.
70
70
 
73
73
  @note Broadcasts refresh if it closed a table with old version.
74
74
*/
75
75
 
76
 
static void mysql_ha_close_table(Session *session, TableList *tables,
 
76
static void mysql_ha_close_table(THD *thd, TableList *tables,
77
77
                                 bool is_locked)
78
78
{
79
79
  Table **table_ptr;
80
80
 
81
81
  /*
82
82
    Though we could take the table pointer from hash_tables->table,
83
 
    we must follow the session->handler_tables chain anyway, as we need the
 
83
    we must follow the thd->handler_tables chain anyway, as we need the
84
84
    address of the 'next' pointer referencing this table
85
85
    for close_thread_table().
86
86
  */
87
 
  for (table_ptr= &(session->handler_tables);
 
87
  for (table_ptr= &(thd->handler_tables);
88
88
       *table_ptr && (*table_ptr != tables->table);
89
89
         table_ptr= &(*table_ptr)->next)
90
90
    ;
93
93
  {
94
94
    (*table_ptr)->file->ha_index_or_rnd_end();
95
95
    if (! is_locked)
96
 
      pthread_mutex_lock(&LOCK_open);
97
 
    if (close_thread_table(session, table_ptr))
 
96
      VOID(pthread_mutex_lock(&LOCK_open));
 
97
    if (close_thread_table(thd, table_ptr))
98
98
    {
99
99
      /* Tell threads waiting for refresh that something has happened */
100
100
      broadcast_refresh();
101
101
    }
102
102
    if (! is_locked)
103
 
      pthread_mutex_unlock(&LOCK_open);
 
103
      VOID(pthread_mutex_unlock(&LOCK_open));
104
104
  }
105
105
  else if (tables->table)
106
106
  {
107
107
    /* Must be a temporary table */
108
108
    Table *table= tables->table;
109
109
    table->file->ha_index_or_rnd_end();
110
 
    table->query_id= session->query_id;
 
110
    table->query_id= thd->query_id;
111
111
    table->open_by_handler= 0;
112
112
  }
113
113
}
118
118
 
119
119
  SYNOPSIS
120
120
    mysql_ha_close()
121
 
    session                         Thread identifier.
 
121
    thd                         Thread identifier.
122
122
    tables                      A list of tables with the first entry to close.
123
123
 
124
124
  DESCRIPTION
130
130
    true  error
131
131
*/
132
132
 
133
 
bool mysql_ha_close(Session *session, TableList *tables)
 
133
bool mysql_ha_close(THD *thd, TableList *tables)
134
134
{
135
135
  TableList    *hash_tables;
136
136
 
137
 
  if ((hash_tables= (TableList*) hash_search(&session->handler_tables_hash,
138
 
                                              (unsigned char*) tables->alias,
 
137
  if ((hash_tables= (TableList*) hash_search(&thd->handler_tables_hash,
 
138
                                              (uchar*) tables->alias,
139
139
                                              strlen(tables->alias) + 1)))
140
140
  {
141
 
    mysql_ha_close_table(session, hash_tables, false);
142
 
    hash_delete(&session->handler_tables_hash, (unsigned char*) hash_tables);
 
141
    mysql_ha_close_table(thd, hash_tables, false);
 
142
    hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
143
143
  }
144
144
  else
145
145
  {
147
147
    return(true);
148
148
  }
149
149
 
150
 
  my_ok(session);
 
150
  my_ok(thd);
151
151
  return(false);
152
152
}
153
153
 
155
155
/**
156
156
  Scan the handler tables hash for matching tables.
157
157
 
158
 
  @param session Thread identifier.
 
158
  @param thd Thread identifier.
159
159
  @param tables The list of tables to remove.
160
160
 
161
161
  @return Pointer to head of linked list (TableList::next_local) of matching
163
163
          table was matched.
164
164
*/
165
165
 
166
 
static TableList *mysql_ha_find(Session *session, TableList *tables)
 
166
static TableList *mysql_ha_find(THD *thd, TableList *tables)
167
167
{
168
168
  TableList *hash_tables, *head= NULL, *first= tables;
169
169
 
170
170
  /* search for all handlers with matching table names */
171
 
  for (uint32_t i= 0; i < session->handler_tables_hash.records; i++)
 
171
  for (uint i= 0; i < thd->handler_tables_hash.records; i++)
172
172
  {
173
 
    hash_tables= (TableList*) hash_element(&session->handler_tables_hash, i);
 
173
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
174
174
    for (tables= first; tables; tables= tables->next_local)
175
175
    {
176
176
      if ((! *tables->db ||
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,
 
177
          ! my_strcasecmp(&my_charset_latin1, hash_tables->db, tables->db)) &&
 
178
          ! my_strcasecmp(&my_charset_latin1, hash_tables->table_name,
179
179
                          tables->table_name))
180
180
        break;
181
181
    }
193
193
/**
194
194
  Remove matching tables from the HANDLER's hash table.
195
195
 
196
 
  @param session Thread identifier.
 
196
  @param thd Thread identifier.
197
197
  @param tables The list of tables to remove.
198
198
  @param is_locked If LOCK_open is locked.
199
199
 
200
200
  @note Broadcasts refresh if it closed a table with old version.
201
201
*/
202
202
 
203
 
void mysql_ha_rm_tables(Session *session, TableList *tables, bool is_locked)
 
203
void mysql_ha_rm_tables(THD *thd, TableList *tables, bool is_locked)
204
204
{
205
205
  TableList *hash_tables, *next;
206
206
 
207
207
  assert(tables);
208
208
 
209
 
  hash_tables= mysql_ha_find(session, tables);
 
209
  hash_tables= mysql_ha_find(thd, tables);
210
210
 
211
211
  while (hash_tables)
212
212
  {
213
213
    next= hash_tables->next_local;
214
214
    if (hash_tables->table)
215
 
      mysql_ha_close_table(session, hash_tables, is_locked);
216
 
    hash_delete(&session->handler_tables_hash, (unsigned char*) hash_tables);
 
215
      mysql_ha_close_table(thd, hash_tables, is_locked);
 
216
    hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
217
217
    hash_tables= next;
218
218
  }
219
219
 
225
225
  Flush (close and mark for re-open) all tables that should be should
226
226
  be reopen.
227
227
 
228
 
  @param session Thread identifier.
 
228
  @param thd Thread identifier.
229
229
 
230
230
  @note Broadcasts refresh if it closed a table with old version.
231
231
*/
232
232
 
233
 
void mysql_ha_flush(Session *session)
 
233
void mysql_ha_flush(THD *thd)
234
234
{
235
235
  TableList *hash_tables;
236
236
 
237
237
  safe_mutex_assert_owner(&LOCK_open);
238
238
 
239
 
  for (uint32_t i= 0; i < session->handler_tables_hash.records; i++)
 
239
  for (uint i= 0; i < thd->handler_tables_hash.records; i++)
240
240
  {
241
 
    hash_tables= (TableList*) hash_element(&session->handler_tables_hash, i);
 
241
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
242
242
    if (hash_tables->table && hash_tables->table->needs_reopen_or_name_lock())
243
243
    {
244
 
      mysql_ha_close_table(session, hash_tables, true);
 
244
      mysql_ha_close_table(thd, hash_tables, true);
245
245
      /* Mark table as closed, ready for re-open. */
246
246
      hash_tables->table= NULL;
247
247
    }
254
254
/**
255
255
  Close all HANDLER's tables.
256
256
 
257
 
  @param session Thread identifier.
 
257
  @param thd Thread identifier.
258
258
 
259
259
  @note Broadcasts refresh if it closed a table with old version.
260
260
*/
261
261
 
262
 
void mysql_ha_cleanup(Session *session)
 
262
void mysql_ha_cleanup(THD *thd)
263
263
{
264
264
  TableList *hash_tables;
265
265
 
266
 
  for (uint32_t i= 0; i < session->handler_tables_hash.records; i++)
 
266
  for (uint i= 0; i < thd->handler_tables_hash.records; i++)
267
267
  {
268
 
    hash_tables= (TableList*) hash_element(&session->handler_tables_hash, i);
 
268
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
269
269
    if (hash_tables->table)
270
 
      mysql_ha_close_table(session, hash_tables, false);
 
270
      mysql_ha_close_table(thd, hash_tables, false);
271
271
   }
272
272
 
273
 
  hash_free(&session->handler_tables_hash);
 
273
  hash_free(&thd->handler_tables_hash);
274
274
 
275
275
  return;
276
276
}