~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_handler.cc

  • Committer: Monty Taylor
  • Date: 2008-10-20 08:48:34 UTC
  • mfrom: (520.1.22 drizzle)
  • Revision ID: monty@inaugust.com-20081020084834-xpb3w01vkcp55o02
Merged trunk.

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 THD - normal free_list and handler_items.
 
27
  keep two item lists per Session - 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 '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
 
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
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 'thd->handler_tables', the closed tables are removed from
 
47
  functions with 'session->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
63
63
/**
64
64
  Close a HANDLER table.
65
65
 
66
 
  @param thd Thread identifier.
 
66
  @param session Thread identifier.
67
67
  @param tables A list of tables with the first entry to close.
68
68
  @param is_locked If LOCK_open is locked.
69
69
 
72
72
  @note Broadcasts refresh if it closed a table with old version.
73
73
*/
74
74
 
75
 
static void mysql_ha_close_table(THD *thd, TableList *tables,
 
75
static void mysql_ha_close_table(Session *session, TableList *tables,
76
76
                                 bool is_locked)
77
77
{
78
78
  Table **table_ptr;
79
79
 
80
80
  /*
81
81
    Though we could take the table pointer from hash_tables->table,
82
 
    we must follow the thd->handler_tables chain anyway, as we need the
 
82
    we must follow the session->handler_tables chain anyway, as we need the
83
83
    address of the 'next' pointer referencing this table
84
84
    for close_thread_table().
85
85
  */
86
 
  for (table_ptr= &(thd->handler_tables);
 
86
  for (table_ptr= &(session->handler_tables);
87
87
       *table_ptr && (*table_ptr != tables->table);
88
88
         table_ptr= &(*table_ptr)->next)
89
89
    ;
93
93
    (*table_ptr)->file->ha_index_or_rnd_end();
94
94
    if (! is_locked)
95
95
      pthread_mutex_lock(&LOCK_open);
96
 
    if (close_thread_table(thd, table_ptr))
 
96
    if (close_thread_table(session, table_ptr))
97
97
    {
98
98
      /* Tell threads waiting for refresh that something has happened */
99
99
      broadcast_refresh();
106
106
    /* Must be a temporary table */
107
107
    Table *table= tables->table;
108
108
    table->file->ha_index_or_rnd_end();
109
 
    table->query_id= thd->query_id;
 
109
    table->query_id= session->query_id;
110
110
    table->open_by_handler= 0;
111
111
  }
112
112
}
117
117
 
118
118
  SYNOPSIS
119
119
    mysql_ha_close()
120
 
    thd                         Thread identifier.
 
120
    session                         Thread identifier.
121
121
    tables                      A list of tables with the first entry to close.
122
122
 
123
123
  DESCRIPTION
129
129
    true  error
130
130
*/
131
131
 
132
 
bool mysql_ha_close(THD *thd, TableList *tables)
 
132
bool mysql_ha_close(Session *session, TableList *tables)
133
133
{
134
134
  TableList    *hash_tables;
135
135
 
136
 
  if ((hash_tables= (TableList*) hash_search(&thd->handler_tables_hash,
 
136
  if ((hash_tables= (TableList*) hash_search(&session->handler_tables_hash,
137
137
                                              (unsigned char*) tables->alias,
138
138
                                              strlen(tables->alias) + 1)))
139
139
  {
140
 
    mysql_ha_close_table(thd, hash_tables, false);
141
 
    hash_delete(&thd->handler_tables_hash, (unsigned char*) hash_tables);
 
140
    mysql_ha_close_table(session, hash_tables, false);
 
141
    hash_delete(&session->handler_tables_hash, (unsigned char*) hash_tables);
142
142
  }
143
143
  else
144
144
  {
146
146
    return(true);
147
147
  }
148
148
 
149
 
  my_ok(thd);
 
149
  my_ok(session);
150
150
  return(false);
151
151
}
152
152
 
154
154
/**
155
155
  Scan the handler tables hash for matching tables.
156
156
 
157
 
  @param thd Thread identifier.
 
157
  @param session Thread identifier.
158
158
  @param tables The list of tables to remove.
159
159
 
160
160
  @return Pointer to head of linked list (TableList::next_local) of matching
162
162
          table was matched.
163
163
*/
164
164
 
165
 
static TableList *mysql_ha_find(THD *thd, TableList *tables)
 
165
static TableList *mysql_ha_find(Session *session, TableList *tables)
166
166
{
167
167
  TableList *hash_tables, *head= NULL, *first= tables;
168
168
 
169
169
  /* search for all handlers with matching table names */
170
 
  for (uint32_t i= 0; i < thd->handler_tables_hash.records; i++)
 
170
  for (uint32_t i= 0; i < session->handler_tables_hash.records; i++)
171
171
  {
172
 
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
 
172
    hash_tables= (TableList*) hash_element(&session->handler_tables_hash, i);
173
173
    for (tables= first; tables; tables= tables->next_local)
174
174
    {
175
175
      if ((! *tables->db ||
192
192
/**
193
193
  Remove matching tables from the HANDLER's hash table.
194
194
 
195
 
  @param thd Thread identifier.
 
195
  @param session Thread identifier.
196
196
  @param tables The list of tables to remove.
197
197
  @param is_locked If LOCK_open is locked.
198
198
 
199
199
  @note Broadcasts refresh if it closed a table with old version.
200
200
*/
201
201
 
202
 
void mysql_ha_rm_tables(THD *thd, TableList *tables, bool is_locked)
 
202
void mysql_ha_rm_tables(Session *session, TableList *tables, bool is_locked)
203
203
{
204
204
  TableList *hash_tables, *next;
205
205
 
206
206
  assert(tables);
207
207
 
208
 
  hash_tables= mysql_ha_find(thd, tables);
 
208
  hash_tables= mysql_ha_find(session, tables);
209
209
 
210
210
  while (hash_tables)
211
211
  {
212
212
    next= hash_tables->next_local;
213
213
    if (hash_tables->table)
214
 
      mysql_ha_close_table(thd, hash_tables, is_locked);
215
 
    hash_delete(&thd->handler_tables_hash, (unsigned char*) hash_tables);
 
214
      mysql_ha_close_table(session, hash_tables, is_locked);
 
215
    hash_delete(&session->handler_tables_hash, (unsigned char*) hash_tables);
216
216
    hash_tables= next;
217
217
  }
218
218
 
224
224
  Flush (close and mark for re-open) all tables that should be should
225
225
  be reopen.
226
226
 
227
 
  @param thd Thread identifier.
 
227
  @param session Thread identifier.
228
228
 
229
229
  @note Broadcasts refresh if it closed a table with old version.
230
230
*/
231
231
 
232
 
void mysql_ha_flush(THD *thd)
 
232
void mysql_ha_flush(Session *session)
233
233
{
234
234
  TableList *hash_tables;
235
235
 
236
236
  safe_mutex_assert_owner(&LOCK_open);
237
237
 
238
 
  for (uint32_t i= 0; i < thd->handler_tables_hash.records; i++)
 
238
  for (uint32_t i= 0; i < session->handler_tables_hash.records; i++)
239
239
  {
240
 
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
 
240
    hash_tables= (TableList*) hash_element(&session->handler_tables_hash, i);
241
241
    if (hash_tables->table && hash_tables->table->needs_reopen_or_name_lock())
242
242
    {
243
 
      mysql_ha_close_table(thd, hash_tables, true);
 
243
      mysql_ha_close_table(session, hash_tables, true);
244
244
      /* Mark table as closed, ready for re-open. */
245
245
      hash_tables->table= NULL;
246
246
    }
253
253
/**
254
254
  Close all HANDLER's tables.
255
255
 
256
 
  @param thd Thread identifier.
 
256
  @param session Thread identifier.
257
257
 
258
258
  @note Broadcasts refresh if it closed a table with old version.
259
259
*/
260
260
 
261
 
void mysql_ha_cleanup(THD *thd)
 
261
void mysql_ha_cleanup(Session *session)
262
262
{
263
263
  TableList *hash_tables;
264
264
 
265
 
  for (uint32_t i= 0; i < thd->handler_tables_hash.records; i++)
 
265
  for (uint32_t i= 0; i < session->handler_tables_hash.records; i++)
266
266
  {
267
 
    hash_tables= (TableList*) hash_element(&thd->handler_tables_hash, i);
 
267
    hash_tables= (TableList*) hash_element(&session->handler_tables_hash, i);
268
268
    if (hash_tables->table)
269
 
      mysql_ha_close_table(thd, hash_tables, false);
 
269
      mysql_ha_close_table(session, hash_tables, false);
270
270
   }
271
271
 
272
 
  hash_free(&thd->handler_tables_hash);
 
272
  hash_free(&session->handler_tables_hash);
273
273
 
274
274
  return;
275
275
}