~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

Viewing changes to storage/blackhole/ha_blackhole.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2005 MySQL AB
 
2
 
 
3
  This program is free software; you can redistribute it and/or modify
 
4
  it under the terms of the GNU General Public License as published by
 
5
  the Free Software Foundation; version 2 of the License.
 
6
 
 
7
  This program is distributed in the hope that it will be useful,
 
8
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
  GNU General Public License for more details.
 
11
 
 
12
  You should have received a copy of the GNU General Public License
 
13
  along with this program; if not, write to the Free Software
 
14
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
#ifdef USE_PRAGMA_IMPLEMENTATION
 
18
#pragma implementation                          // gcc: Class implementation
 
19
#endif
 
20
 
 
21
#include "mysql_priv.h"
 
22
#include "ha_blackhole.h"
 
23
 
 
24
/* Static declarations for handlerton */
 
25
 
 
26
static handler *blackhole_create_handler(handlerton *hton,
 
27
                                         TABLE_SHARE *table,
 
28
                                         MEM_ROOT *mem_root)
 
29
{
 
30
  return new (mem_root) ha_blackhole(hton, table);
 
31
}
 
32
 
 
33
 
 
34
/* Static declarations for shared structures */
 
35
 
 
36
static pthread_mutex_t blackhole_mutex;
 
37
static HASH blackhole_open_tables;
 
38
 
 
39
static st_blackhole_share *get_share(const char *table_name);
 
40
static void free_share(st_blackhole_share *share);
 
41
 
 
42
/*****************************************************************************
 
43
** BLACKHOLE tables
 
44
*****************************************************************************/
 
45
 
 
46
ha_blackhole::ha_blackhole(handlerton *hton,
 
47
                           TABLE_SHARE *table_arg)
 
48
  :handler(hton, table_arg)
 
49
{}
 
50
 
 
51
 
 
52
static const char *ha_blackhole_exts[] = {
 
53
  NullS
 
54
};
 
55
 
 
56
const char **ha_blackhole::bas_ext() const
 
57
{
 
58
  return ha_blackhole_exts;
 
59
}
 
60
 
 
61
int ha_blackhole::open(const char *name, int mode, uint test_if_locked)
 
62
{
 
63
  DBUG_ENTER("ha_blackhole::open");
 
64
 
 
65
  if (!(share= get_share(name)))
 
66
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
67
 
 
68
  thr_lock_data_init(&share->lock, &lock, NULL);
 
69
  DBUG_RETURN(0);
 
70
}
 
71
 
 
72
int ha_blackhole::close(void)
 
73
{
 
74
  DBUG_ENTER("ha_blackhole::close");
 
75
  free_share(share);
 
76
  DBUG_RETURN(0);
 
77
}
 
78
 
 
79
int ha_blackhole::create(const char *name, TABLE *table_arg,
 
80
                         HA_CREATE_INFO *create_info)
 
81
{
 
82
  DBUG_ENTER("ha_blackhole::create");
 
83
  DBUG_RETURN(0);
 
84
}
 
85
 
 
86
const char *ha_blackhole::index_type(uint key_number)
 
87
{
 
88
  DBUG_ENTER("ha_blackhole::index_type");
 
89
  DBUG_RETURN((table_share->key_info[key_number].flags & HA_FULLTEXT) ? 
 
90
              "FULLTEXT" :
 
91
              (table_share->key_info[key_number].flags & HA_SPATIAL) ?
 
92
              "SPATIAL" :
 
93
              (table_share->key_info[key_number].algorithm ==
 
94
               HA_KEY_ALG_RTREE) ? "RTREE" : "BTREE");
 
95
}
 
96
 
 
97
int ha_blackhole::write_row(uchar * buf)
 
98
{
 
99
  DBUG_ENTER("ha_blackhole::write_row");
 
100
  DBUG_RETURN(table->next_number_field ? update_auto_increment() : 0);
 
101
}
 
102
 
 
103
int ha_blackhole::rnd_init(bool scan)
 
104
{
 
105
  DBUG_ENTER("ha_blackhole::rnd_init");
 
106
  DBUG_RETURN(0);
 
107
}
 
108
 
 
109
 
 
110
int ha_blackhole::rnd_next(uchar *buf)
 
111
{
 
112
  DBUG_ENTER("ha_blackhole::rnd_next");
 
113
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
114
}
 
115
 
 
116
 
 
117
int ha_blackhole::rnd_pos(uchar * buf, uchar *pos)
 
118
{
 
119
  DBUG_ENTER("ha_blackhole::rnd_pos");
 
120
  DBUG_ASSERT(0);
 
121
  DBUG_RETURN(0);
 
122
}
 
123
 
 
124
 
 
125
void ha_blackhole::position(const uchar *record)
 
126
{
 
127
  DBUG_ENTER("ha_blackhole::position");
 
128
  DBUG_ASSERT(0);
 
129
  DBUG_VOID_RETURN;
 
130
}
 
131
 
 
132
 
 
133
int ha_blackhole::info(uint flag)
 
134
{
 
135
  DBUG_ENTER("ha_blackhole::info");
 
136
 
 
137
  bzero((char*) &stats, sizeof(stats));
 
138
  if (flag & HA_STATUS_AUTO)
 
139
    stats.auto_increment_value= 1;
 
140
  DBUG_RETURN(0);
 
141
}
 
142
 
 
143
int ha_blackhole::external_lock(THD *thd, int lock_type)
 
144
{
 
145
  DBUG_ENTER("ha_blackhole::external_lock");
 
146
  DBUG_RETURN(0);
 
147
}
 
148
 
 
149
 
 
150
THR_LOCK_DATA **ha_blackhole::store_lock(THD *thd,
 
151
                                         THR_LOCK_DATA **to,
 
152
                                         enum thr_lock_type lock_type)
 
153
{
 
154
  DBUG_ENTER("ha_blackhole::store_lock");
 
155
  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
 
156
  {
 
157
    /*
 
158
      Here is where we get into the guts of a row level lock.
 
159
      If TL_UNLOCK is set
 
160
      If we are not doing a LOCK TABLE or DISCARD/IMPORT
 
161
      TABLESPACE, then allow multiple writers
 
162
    */
 
163
 
 
164
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
 
165
         lock_type <= TL_WRITE) && !thd_in_lock_tables(thd)
 
166
        && !thd_tablespace_op(thd))
 
167
      lock_type = TL_WRITE_ALLOW_WRITE;
 
168
 
 
169
    /*
 
170
      In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
 
171
      MySQL would use the lock TL_READ_NO_INSERT on t2, and that
 
172
      would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
 
173
      to t2. Convert the lock to a normal read lock to allow
 
174
      concurrent inserts to t2.
 
175
    */
 
176
 
 
177
    if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd))
 
178
      lock_type = TL_READ;
 
179
 
 
180
    lock.type= lock_type;
 
181
  }
 
182
  *to++= &lock;
 
183
  DBUG_RETURN(to);
 
184
}
 
185
 
 
186
 
 
187
int ha_blackhole::index_read_map(uchar * buf, const uchar * key,
 
188
                                 key_part_map keypart_map,
 
189
                             enum ha_rkey_function find_flag)
 
190
{
 
191
  DBUG_ENTER("ha_blackhole::index_read");
 
192
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
193
}
 
194
 
 
195
 
 
196
int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key,
 
197
                                 key_part_map keypart_map,
 
198
                                 enum ha_rkey_function find_flag)
 
199
{
 
200
  DBUG_ENTER("ha_blackhole::index_read_idx");
 
201
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
202
}
 
203
 
 
204
 
 
205
int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key,
 
206
                                      key_part_map keypart_map)
 
207
{
 
208
  DBUG_ENTER("ha_blackhole::index_read_last");
 
209
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
210
}
 
211
 
 
212
 
 
213
int ha_blackhole::index_next(uchar * buf)
 
214
{
 
215
  DBUG_ENTER("ha_blackhole::index_next");
 
216
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
217
}
 
218
 
 
219
 
 
220
int ha_blackhole::index_prev(uchar * buf)
 
221
{
 
222
  DBUG_ENTER("ha_blackhole::index_prev");
 
223
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
224
}
 
225
 
 
226
 
 
227
int ha_blackhole::index_first(uchar * buf)
 
228
{
 
229
  DBUG_ENTER("ha_blackhole::index_first");
 
230
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
231
}
 
232
 
 
233
 
 
234
int ha_blackhole::index_last(uchar * buf)
 
235
{
 
236
  DBUG_ENTER("ha_blackhole::index_last");
 
237
  DBUG_RETURN(HA_ERR_END_OF_FILE);
 
238
}
 
239
 
 
240
 
 
241
static st_blackhole_share *get_share(const char *table_name)
 
242
{
 
243
  st_blackhole_share *share;
 
244
  uint length;
 
245
 
 
246
  length= (uint) strlen(table_name);
 
247
  pthread_mutex_lock(&blackhole_mutex);
 
248
    
 
249
  if (!(share= (st_blackhole_share*) hash_search(&blackhole_open_tables,
 
250
                                                 (uchar*) table_name, length)))
 
251
  {
 
252
    if (!(share= (st_blackhole_share*) my_malloc(sizeof(st_blackhole_share) +
 
253
                                                 length,
 
254
                                                 MYF(MY_WME | MY_ZEROFILL))))
 
255
      goto error;
 
256
 
 
257
    share->table_name_length= length;
 
258
    strmov(share->table_name, table_name);
 
259
    
 
260
    if (my_hash_insert(&blackhole_open_tables, (uchar*) share))
 
261
    {
 
262
      my_free((uchar*) share, MYF(0));
 
263
      share= NULL;
 
264
      goto error;
 
265
    }
 
266
    
 
267
    thr_lock_init(&share->lock);
 
268
  }
 
269
  share->use_count++;
 
270
  
 
271
error:
 
272
  pthread_mutex_unlock(&blackhole_mutex);
 
273
  return share;
 
274
}
 
275
 
 
276
static void free_share(st_blackhole_share *share)
 
277
{
 
278
  pthread_mutex_lock(&blackhole_mutex);
 
279
  if (!--share->use_count)
 
280
    hash_delete(&blackhole_open_tables, (uchar*) share);
 
281
  pthread_mutex_unlock(&blackhole_mutex);
 
282
}
 
283
 
 
284
static void blackhole_free_key(st_blackhole_share *share)
 
285
{
 
286
  thr_lock_delete(&share->lock);
 
287
  my_free((uchar*) share, MYF(0));
 
288
}
 
289
 
 
290
static uchar* blackhole_get_key(st_blackhole_share *share, size_t *length,
 
291
                                my_bool not_used __attribute__((unused)))
 
292
{
 
293
  *length= share->table_name_length;
 
294
  return (uchar*) share->table_name;
 
295
}
 
296
 
 
297
static int blackhole_init(void *p)
 
298
{
 
299
  handlerton *blackhole_hton;
 
300
  blackhole_hton= (handlerton *)p;
 
301
  blackhole_hton->state= SHOW_OPTION_YES;
 
302
  blackhole_hton->db_type= DB_TYPE_BLACKHOLE_DB;
 
303
  blackhole_hton->create= blackhole_create_handler;
 
304
  blackhole_hton->flags= HTON_CAN_RECREATE;
 
305
  
 
306
  VOID(pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST));
 
307
  (void) hash_init(&blackhole_open_tables, system_charset_info,32,0,0,
 
308
                   (hash_get_key) blackhole_get_key,
 
309
                   (hash_free_key) blackhole_free_key, 0);
 
310
 
 
311
  return 0;
 
312
}
 
313
 
 
314
static int blackhole_fini(void *p)
 
315
{
 
316
  hash_free(&blackhole_open_tables);
 
317
  pthread_mutex_destroy(&blackhole_mutex);
 
318
 
 
319
  return 0;
 
320
}
 
321
 
 
322
struct st_mysql_storage_engine blackhole_storage_engine=
 
323
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
 
324
 
 
325
mysql_declare_plugin(blackhole)
 
326
{
 
327
  MYSQL_STORAGE_ENGINE_PLUGIN,
 
328
  &blackhole_storage_engine,
 
329
  "BLACKHOLE",
 
330
  "MySQL AB",
 
331
  "/dev/null storage engine (anything you write to it disappears)",
 
332
  PLUGIN_LICENSE_GPL,
 
333
  blackhole_init, /* Plugin Init */
 
334
  blackhole_fini, /* Plugin Deinit */
 
335
  0x0100 /* 1.0 */,
 
336
  NULL,                       /* status variables                */
 
337
  NULL,                       /* system variables                */
 
338
  NULL                        /* config options                  */
 
339
}
 
340
mysql_declare_plugin_end;