~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2003 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
670.2.2 by Monty Taylor
Got rid of the rest of common_includes. Now on to server_includes.
17
#include <drizzled/server_includes.h>
584.1.14 by Monty Taylor
Removed field.h from common_includes.
18
#include <drizzled/field.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
19
#include <drizzled/field/blob.h>
20
#include <drizzled/field/timestamp.h>
212.4.2 by Monty Taylor
Fixed the includes in places to make the myisam header file move work.
21
#include <storage/myisam/myisam.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
22
#include <drizzled/table.h>
23
#include <drizzled/session.h>
875 by Brian Aker
Remove my_open() call for Archive.
24
#include <stdio.h>
1 by brian
clean slate
25
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
26
#include <storage/archive/ha_archive.h>
1 by brian
clean slate
27
28
/*
584.5.1 by Monty Taylor
Removed field includes from field.h.
29
  First, if you want to understand storage engines you should look at
30
  ha_example.cc and ha_example.h.
1 by brian
clean slate
31
32
  This example was written as a test case for a customer who needed
33
  a storage engine without indexes that could compress data very well.
34
  So, welcome to a completely compressed storage engine. This storage
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
35
  engine only does inserts. No replace, deletes, or updates. All reads are
1 by brian
clean slate
36
  complete table scans. Compression is done through a combination of packing
37
  and making use of the zlib library
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
38
1 by brian
clean slate
39
  We keep a file pointer open for each instance of ha_archive for each read
40
  but for writes we keep one open file handle just for that. We flush it
41
  only if we have a read occur. azip handles compressing lots of records
42
  at once much better then doing lots of little records between writes.
43
  It is possible to not lock on writes but this would then mean we couldn't
44
  handle bulk inserts as well (that is if someone was trying to read at
45
  the same time since we would want to flush).
46
47
  A "meta" file is kept alongside the data file. This file serves two purpose.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
48
  The first purpose is to track the number of rows in the table. The second
49
  purpose is to determine if the table was closed properly or not. When the
50
  meta file is first opened it is marked as dirty. It is opened when the table
51
  itself is opened for writing. When the table is closed the new count for rows
52
  is written to the meta file and the file is marked as clean. If the meta file
53
  is opened and it is marked as dirty, it is assumed that a crash occured. At
1 by brian
clean slate
54
  this point an error occurs and the user is told to rebuild the file.
55
  A rebuild scans the rows and rewrites the meta file. If corruption is found
56
  in the data file then the meta file is not repaired.
57
58
  At some point a recovery method for such a drastic case needs to be divised.
59
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
60
  Locks are row level, and you will get a consistant read.
1 by brian
clean slate
61
62
  For performance as far as table scans go it is quite fast. I don't have
63
  good numbers but locally it has out performed both Innodb and MyISAM. For
64
  Innodb the question will be if the table can be fit into the buffer
65
  pool. For MyISAM its a question of how much the file system caches the
66
  MyISAM file. With enough free memory MyISAM is faster. Its only when the OS
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
67
  doesn't have enough memory to cache entire table that archive turns out
68
  to be any faster.
1 by brian
clean slate
69
70
  Examples between MyISAM (packed) and Archive.
71
72
  Table with 76695844 identical rows:
73
  29680807 a_archive.ARZ
74
  920350317 a.MYD
75
76
77
  Table with 8991478 rows (all of Slashdot's comments):
78
  1922964506 comment_archive.ARZ
79
  2944970297 comment_text.MYD
80
81
82
  TODO:
83
   Allow users to set compression level.
84
   Allow adjustable block size.
85
   Implement versioning, should be easy.
86
   Allow for errors, find a way to mark bad rows.
87
   Add optional feature so that rows can be flushed at interval (which will cause less
88
     compression but may speed up ordered searches).
89
   Checkpoint the meta file to allow for faster rebuilds.
90
   Option to allow for dirty reads, this would lower the sync calls, which would make
91
     inserts a lot faster, but would mean highly arbitrary reads.
92
93
    -Brian
94
*/
95
96
/* Variables for archive share methods */
97
pthread_mutex_t archive_mutex;
98
static HASH archive_open_tables;
99
static unsigned int global_version;
100
101
/* The file extension */
102
#define ARZ ".ARZ"               // The data file
103
#define ARN ".ARN"               // Files used during an optimize call
104
105
106
/* Static declarations for handerton */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
107
static handler *archive_create_handler(handlerton *hton,
108
                                       TABLE_SHARE *table,
1 by brian
clean slate
109
                                       MEM_ROOT *mem_root);
110
278 by Brian Aker
Fixed my_bool issue in options.
111
static bool archive_use_aio= false;
1 by brian
clean slate
112
113
/*
114
  Number of rows that will force a bulk insert.
115
*/
116
#define ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT 2
117
118
/*
119
  Size of header used for row
120
*/
121
#define ARCHIVE_ROW_HEADER_SIZE 4
122
123
static handler *archive_create_handler(handlerton *hton,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
124
                                       TABLE_SHARE *table,
1 by brian
clean slate
125
                                       MEM_ROOT *mem_root)
126
{
127
  return new (mem_root) ha_archive(hton, table);
128
}
129
130
/*
131
  Used for hash table that tracks open tables.
132
*/
653 by Brian Aker
More solaris bits
133
static unsigned char* archive_get_key(ARCHIVE_SHARE *share, size_t *length, bool)
1 by brian
clean slate
134
{
135
  *length=share->table_name_length;
481 by Brian Aker
Remove all of uchar.
136
  return (unsigned char*) share->table_name;
1 by brian
clean slate
137
}
138
139
140
/*
141
  Initialize the archive handler.
142
143
  SYNOPSIS
144
    archive_db_init()
145
    void *
146
147
  RETURN
163 by Brian Aker
Merge Monty's code.
148
    false       OK
149
    true        Error
1 by brian
clean slate
150
*/
151
152
int archive_db_init(void *p)
153
{
154
  handlerton *archive_hton;
155
156
  archive_hton= (handlerton *)p;
157
  archive_hton->state= SHOW_OPTION_YES;
158
  archive_hton->create= archive_create_handler;
159
  archive_hton->flags= HTON_NO_FLAGS;
160
161
  /* When the engine starts up set the first version */
162
  global_version= 1;
163
164
  if (pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST))
165
    goto error;
166
  if (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
167
                (hash_get_key) archive_get_key, 0, 0))
168
  {
398.1.10 by Monty Taylor
Actually removed VOID() this time.
169
    pthread_mutex_destroy(&archive_mutex);
1 by brian
clean slate
170
  }
171
  else
172
  {
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
173
    return(false);
1 by brian
clean slate
174
  }
175
error:
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
176
  return(true);
1 by brian
clean slate
177
}
178
179
/*
180
  Release the archive handler.
181
182
  SYNOPSIS
183
    archive_db_done()
184
    void
185
186
  RETURN
163 by Brian Aker
Merge Monty's code.
187
    false       OK
1 by brian
clean slate
188
*/
189
653 by Brian Aker
More solaris bits
190
int archive_db_done(void *)
1 by brian
clean slate
191
{
192
  hash_free(&archive_open_tables);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
193
  pthread_mutex_destroy(&archive_mutex);
1 by brian
clean slate
194
195
  return 0;
196
}
197
198
199
ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg)
200
  :handler(hton, table_arg), delayed_insert(0), bulk_insert(0)
201
{
202
  /* Set our original buffer from pre-allocated memory */
203
  buffer.set((char *)byte_buffer, IO_SIZE, system_charset_info);
204
205
  /* The size of the offset value we will use for position() */
206
  ref_length= sizeof(my_off_t);
163 by Brian Aker
Merge Monty's code.
207
  archive_reader_open= false;
1 by brian
clean slate
208
}
209
210
/*
211
  This method reads the header of a datafile and returns whether or not it was successful.
212
*/
213
int ha_archive::read_data_header(azio_stream *file_to_read)
214
{
215
  if (azread_init(file_to_read) == -1)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
216
    return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
217
218
  if (file_to_read->version >= 3)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
219
    return(0);
1 by brian
clean slate
220
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
221
  return(1);
1 by brian
clean slate
222
}
223
224
225
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
226
  We create the shared memory space that we will use for the open table.
1 by brian
clean slate
227
  No matter what we try to get or create a share. This is so that a repair
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
228
  table operation can occur.
1 by brian
clean slate
229
230
  See ha_example.cc for a longer description.
231
*/
232
ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc)
233
{
482 by Brian Aker
Remove uint.
234
  uint32_t length;
1 by brian
clean slate
235
236
  pthread_mutex_lock(&archive_mutex);
237
  length=(uint) strlen(table_name);
238
239
  if (!(share=(ARCHIVE_SHARE*) hash_search(&archive_open_tables,
481 by Brian Aker
Remove all of uchar.
240
                                           (unsigned char*) table_name,
1 by brian
clean slate
241
                                           length)))
242
  {
243
    char *tmp_name;
244
    azio_stream archive_tmp;
245
246
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
247
                          &share, sizeof(*share),
248
                          &tmp_name, length+1,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
249
                          NULL))
1 by brian
clean slate
250
    {
251
      pthread_mutex_unlock(&archive_mutex);
252
      *rc= HA_ERR_OUT_OF_MEM;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
253
      return(NULL);
1 by brian
clean slate
254
    }
255
256
    share->use_count= 0;
257
    share->table_name_length= length;
258
    share->table_name= tmp_name;
163 by Brian Aker
Merge Monty's code.
259
    share->crashed= false;
260
    share->archive_write_open= false;
1 by brian
clean slate
261
    fn_format(share->data_file_name, table_name, "",
262
              ARZ, MY_REPLACE_EXT | MY_UNPACK_FILENAME);
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
263
    strcpy(share->table_name, table_name);
1 by brian
clean slate
264
    /*
265
      We will use this lock for rows.
266
    */
398.1.10 by Monty Taylor
Actually removed VOID() this time.
267
    pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
268
1 by brian
clean slate
269
    /*
270
      We read the meta file, but do not mark it dirty. Since we are not
271
      doing a write we won't mark it dirty (and we won't open it for
272
      anything but reading... open it for write and we will generate null
273
      compression writes).
274
    */
492.1.14 by Monty Taylor
Removed O_BINARY and FILE_BINARY.
275
    if (!(azopen(&archive_tmp, share->data_file_name, O_RDONLY,
1 by brian
clean slate
276
                 AZ_METHOD_BLOCK)))
277
    {
398.1.10 by Monty Taylor
Actually removed VOID() this time.
278
      pthread_mutex_destroy(&share->mutex);
1 by brian
clean slate
279
      free(share);
280
      pthread_mutex_unlock(&archive_mutex);
281
      *rc= HA_ERR_CRASHED_ON_REPAIR;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
282
      return(NULL);
1 by brian
clean slate
283
    }
284
    stats.auto_increment_value= archive_tmp.auto_increment + 1;
285
    share->rows_recorded= (ha_rows)archive_tmp.rows;
286
    share->crashed= archive_tmp.dirty;
287
    if (share->version < global_version)
288
    {
289
      share->version_rows= share->rows_recorded;
290
      share->version= global_version;
291
    }
292
    azclose(&archive_tmp);
293
481 by Brian Aker
Remove all of uchar.
294
    my_hash_insert(&archive_open_tables, (unsigned char*) share);
1 by brian
clean slate
295
    thr_lock_init(&share->lock);
296
  }
297
  share->use_count++;
298
  if (share->crashed)
299
    *rc= HA_ERR_CRASHED_ON_USAGE;
300
  pthread_mutex_unlock(&archive_mutex);
301
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
302
  return(share);
1 by brian
clean slate
303
}
304
305
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
306
/*
1 by brian
clean slate
307
  Free the share.
308
  See ha_example.cc for a description.
309
*/
310
int ha_archive::free_share()
311
{
312
  int rc= 0;
313
314
  pthread_mutex_lock(&archive_mutex);
315
  if (!--share->use_count)
316
  {
481 by Brian Aker
Remove all of uchar.
317
    hash_delete(&archive_open_tables, (unsigned char*) share);
1 by brian
clean slate
318
    thr_lock_delete(&share->lock);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
319
    pthread_mutex_destroy(&share->mutex);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
320
    /*
1 by brian
clean slate
321
      We need to make sure we don't reset the crashed state.
322
      If we open a crashed file, wee need to close it as crashed unless
323
      it has been repaired.
324
      Since we will close the data down after this, we go on and count
325
      the flush on close;
326
    */
163 by Brian Aker
Merge Monty's code.
327
    if (share->archive_write_open == true)
1 by brian
clean slate
328
    {
329
      if (azclose(&(share->archive_write)))
330
        rc= 1;
331
    }
481 by Brian Aker
Remove all of uchar.
332
    free((unsigned char*) share);
1 by brian
clean slate
333
  }
334
  pthread_mutex_unlock(&archive_mutex);
335
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
336
  return(rc);
1 by brian
clean slate
337
}
338
339
int ha_archive::init_archive_writer()
340
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
341
  /*
1 by brian
clean slate
342
    It is expensive to open and close the data files and since you can't have
343
    a gzip file that can be both read and written we keep a writer open
344
    that is shared amoung all open tables.
345
  */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
346
  if (!(azopen(&(share->archive_write), share->data_file_name,
492.1.14 by Monty Taylor
Removed O_BINARY and FILE_BINARY.
347
               O_RDWR, AZ_METHOD_BLOCK)))
1 by brian
clean slate
348
  {
163 by Brian Aker
Merge Monty's code.
349
    share->crashed= true;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
350
    return(1);
1 by brian
clean slate
351
  }
163 by Brian Aker
Merge Monty's code.
352
  share->archive_write_open= true;
1 by brian
clean slate
353
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
354
  return(0);
1 by brian
clean slate
355
}
356
357
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
358
/*
1 by brian
clean slate
359
  No locks are required because it is associated with just one handler instance
360
*/
361
int ha_archive::init_archive_reader()
362
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
363
  /*
1 by brian
clean slate
364
    It is expensive to open and close the data files and since you can't have
365
    a gzip file that can be both read and written we keep a writer open
366
    that is shared amoung all open tables.
367
  */
163 by Brian Aker
Merge Monty's code.
368
  if (archive_reader_open == false)
1 by brian
clean slate
369
  {
370
    az_method method;
371
372
    switch (archive_use_aio)
373
    {
163 by Brian Aker
Merge Monty's code.
374
    case false:
1 by brian
clean slate
375
      method= AZ_METHOD_BLOCK;
376
      break;
163 by Brian Aker
Merge Monty's code.
377
    case true:
1 by brian
clean slate
378
      method= AZ_METHOD_AIO;
379
      break;
380
    default:
381
      method= AZ_METHOD_BLOCK;
382
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
383
    if (!(azopen(&archive, share->data_file_name, O_RDONLY,
1 by brian
clean slate
384
                 method)))
385
    {
163 by Brian Aker
Merge Monty's code.
386
      share->crashed= true;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
387
      return(1);
1 by brian
clean slate
388
    }
163 by Brian Aker
Merge Monty's code.
389
    archive_reader_open= true;
1 by brian
clean slate
390
  }
391
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
392
  return(0);
1 by brian
clean slate
393
}
394
395
396
/*
397
  We just implement one additional file extension.
398
*/
399
static const char *ha_archive_exts[] = {
400
  ARZ,
461 by Monty Taylor
Removed NullS. bu-bye.
401
  NULL
1 by brian
clean slate
402
};
403
404
const char **ha_archive::bas_ext() const
405
{
406
  return ha_archive_exts;
407
}
408
409
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
410
/*
1 by brian
clean slate
411
  When opening a file we:
412
  Create/get our shared structure.
413
  Init out lock.
414
  We open the file we will read from.
415
*/
653 by Brian Aker
More solaris bits
416
int ha_archive::open(const char *name, int, uint32_t open_options)
1 by brian
clean slate
417
{
418
  int rc= 0;
419
  share= get_share(name, &rc);
420
421
  if (rc == HA_ERR_CRASHED_ON_USAGE && !(open_options & HA_OPEN_FOR_REPAIR))
422
  {
423
    /* purecov: begin inspected */
424
    free_share();
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
425
    return(rc);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
426
    /* purecov: end */
1 by brian
clean slate
427
  }
428
  else if (rc == HA_ERR_OUT_OF_MEM)
429
  {
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
430
    return(rc);
1 by brian
clean slate
431
  }
432
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
433
  assert(share);
1 by brian
clean slate
434
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
435
  record_buffer= create_record_buffer(table->s->reclength +
1 by brian
clean slate
436
                                      ARCHIVE_ROW_HEADER_SIZE);
437
438
  if (!record_buffer)
439
  {
440
    free_share();
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
441
    return(HA_ERR_OUT_OF_MEM);
1 by brian
clean slate
442
  }
443
444
  thr_lock_data_init(&share->lock, &lock, NULL);
445
446
  if (rc == HA_ERR_CRASHED_ON_USAGE && open_options & HA_OPEN_FOR_REPAIR)
447
  {
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
448
    return(0);
1 by brian
clean slate
449
  }
450
  else
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
451
    return(rc);
1 by brian
clean slate
452
}
453
454
455
/*
456
  Closes the file.
457
458
  SYNOPSIS
459
    close();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
460
1 by brian
clean slate
461
  IMPLEMENTATION:
462
463
  We first close this storage engines file handle to the archive and
464
  then remove our reference count to the table (and possibly free it
465
  as well).
466
467
  RETURN
468
    0  ok
469
    1  Error
470
*/
471
472
int ha_archive::close(void)
473
{
474
  int rc= 0;
475
476
  destroy_record_buffer(record_buffer);
477
478
  /* First close stream */
163 by Brian Aker
Merge Monty's code.
479
  if (archive_reader_open == true)
1 by brian
clean slate
480
  {
481
    if (azclose(&archive))
482
      rc= 1;
483
  }
484
  /* then also close share */
485
  rc|= free_share();
486
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
487
  return(rc);
1 by brian
clean slate
488
}
489
490
491
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
492
  We create our data file here. The format is pretty simple.
1 by brian
clean slate
493
  You can read about the format of the data file above.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
494
  Unlike other storage engines we do not "pack" our data. Since we
495
  are about to do a general compression, packing would just be a waste of
496
  CPU time. If the table has blobs they are written after the row in the order
1 by brian
clean slate
497
  of creation.
498
*/
499
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
500
int ha_archive::create(const char *name, Table *table_arg,
1 by brian
clean slate
501
                       HA_CREATE_INFO *create_info)
502
{
503
  char name_buff[FN_REFLEN];
504
  char linkname[FN_REFLEN];
875 by Brian Aker
Remove my_open() call for Archive.
505
  int error= 0;
1 by brian
clean slate
506
  azio_stream create_stream;            /* Archive file we are working with */
875 by Brian Aker
Remove my_open() call for Archive.
507
  FILE *frm_file;                   /* File handler for readers */
15 by brian
Fix for stat, NETWARE removal
508
  struct stat file_stat;
481 by Brian Aker
Remove all of uchar.
509
  unsigned char *frm_ptr;
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
510
  int r;
1 by brian
clean slate
511
512
  stats.auto_increment_value= create_info->auto_increment_value;
513
482 by Brian Aker
Remove uint.
514
  for (uint32_t key= 0; key < table_arg->sizeKeys(); key++)
1 by brian
clean slate
515
  {
516
    KEY *pos= table_arg->key_info+key;
517
    KEY_PART_INFO *key_part=     pos->key_part;
518
    KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
519
520
    for (; key_part != key_part_end; key_part++)
521
    {
522
      Field *field= key_part->field;
523
524
      if (!(field->flags & AUTO_INCREMENT_FLAG))
525
      {
526
        error= -1;
527
        goto error;
528
      }
529
    }
530
  }
531
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
532
  /*
1 by brian
clean slate
533
    We reuse name_buff since it is available.
534
  */
535
  if (create_info->data_file_name && create_info->data_file_name[0] != '#')
536
  {
537
    fn_format(name_buff, create_info->data_file_name, "", ARZ,
538
              MY_REPLACE_EXT | MY_UNPACK_FILENAME);
539
    fn_format(linkname, name, "", ARZ,
540
              MY_REPLACE_EXT | MY_UNPACK_FILENAME);
541
  }
542
  else
543
  {
544
    fn_format(name_buff, name, "", ARZ,
545
              MY_REPLACE_EXT | MY_UNPACK_FILENAME);
546
    linkname[0]= 0;
547
  }
548
549
  /*
550
    There is a chance that the file was "discovered". In this case
551
    just use whatever file is there.
552
  */
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
553
  r= stat(name_buff, &file_stat);
554
  if (r == -1 && errno!=ENOENT)
555
  {
556
    return errno;
557
  }
558
  if (!r)
559
    return HA_ERR_TABLE_EXIST;
560
561
  my_errno= 0;
562
  if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR,
563
	       AZ_METHOD_BLOCK)))
564
  {
565
    error= errno;
566
    goto error2;
567
  }
568
569
  if (linkname[0])
570
    my_symlink(name_buff, linkname, MYF(0));
571
  fn_format(name_buff, name, "", ".frm",
572
	    MY_REPLACE_EXT | MY_UNPACK_FILENAME);
573
574
  /*
575
    Here is where we open up the frm and pass it to archive to store
576
  */
875 by Brian Aker
Remove my_open() call for Archive.
577
  if ((frm_file= fopen(name_buff, "r")) > 0)
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
578
  {
875 by Brian Aker
Remove my_open() call for Archive.
579
    if (fstat(fileno(frm_file), &file_stat))
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
580
    {
779.3.21 by Monty Taylor
Fixed solaris fixes for linux. Oh, and I also seem to have fixed some more configure stuff.
581
      if ((uint64_t)file_stat.st_size > SIZE_MAX)
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
582
      {
583
        error= ENOMEM;
584
        goto error2;
585
      }
586
      frm_ptr= (unsigned char *)malloc((size_t)file_stat.st_size);
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
587
      if (frm_ptr)
1 by brian
clean slate
588
      {
875 by Brian Aker
Remove my_open() call for Archive.
589
        size_t length_io;
590
	length_io= read(fileno(frm_file), frm_ptr, (size_t)file_stat.st_size);
591
592
        if (length_io != (size_t)file_stat.st_size)
593
        {
594
          free(frm_ptr);
595
          goto error2;
596
        }
597
598
	length_io= azwrite_frm(&create_stream, (char *)frm_ptr, (size_t)file_stat.st_size);
599
600
        if (length_io != (size_t)file_stat.st_size)
601
        {
602
          free(frm_ptr);
603
          goto error2;
604
        }
605
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
606
	free(frm_ptr);
1 by brian
clean slate
607
      }
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
608
    }
875 by Brian Aker
Remove my_open() call for Archive.
609
    fclose(frm_file);
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
610
  }
611
612
  if (create_info->comment.str)
875 by Brian Aker
Remove my_open() call for Archive.
613
  {
614
    size_t write_length;
615
616
    write_length= azwrite_comment(&create_stream, create_info->comment.str,
617
                                  (unsigned int)create_info->comment.length);
618
619
    if (write_length == (size_t)create_info->comment.length)
620
      goto error2;
621
  }
784.1.1 by Stewart Smith
fix ARCHIVE table creation and archive test
622
623
  /*
624
    Yes you need to do this, because the starting value
625
    for the autoincrement may not be zero.
626
  */
627
  create_stream.auto_increment= stats.auto_increment_value ?
628
    stats.auto_increment_value - 1 : 0;
629
  if (azclose(&create_stream))
630
  {
631
    error= errno;
632
    goto error2;
633
  }
1 by brian
clean slate
634
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
635
  return(0);
1 by brian
clean slate
636
637
error2:
638
  delete_table(name);
639
error:
640
  /* Return error number, if we got one */
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
641
  return(error ? error : -1);
1 by brian
clean slate
642
}
643
644
/*
645
  This is where the actual row is written out.
646
*/
481 by Brian Aker
Remove all of uchar.
647
int ha_archive::real_write_row(unsigned char *buf, azio_stream *writer)
1 by brian
clean slate
648
{
875 by Brian Aker
Remove my_open() call for Archive.
649
  off_t written;
1 by brian
clean slate
650
  unsigned int r_pack_length;
651
652
  /* We pack the row for writing */
653
  r_pack_length= pack_row(buf);
654
655
  written= azwrite_row(writer, record_buffer->buffer, r_pack_length);
656
  if (written != r_pack_length)
657
  {
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
658
    return(-1);
1 by brian
clean slate
659
  }
660
661
  if (!delayed_insert || !bulk_insert)
163 by Brian Aker
Merge Monty's code.
662
    share->dirty= true;
1 by brian
clean slate
663
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
664
  return(0);
1 by brian
clean slate
665
}
666
667
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
668
/*
1 by brian
clean slate
669
  Calculate max length needed for row. This includes
670
  the bytes required for the length in the header.
671
*/
672
653 by Brian Aker
More solaris bits
673
uint32_t ha_archive::max_row_length(const unsigned char *)
1 by brian
clean slate
674
{
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
675
  uint32_t length= (uint32_t)(table->getRecordLength() + table->sizeFields()*2);
1 by brian
clean slate
676
  length+= ARCHIVE_ROW_HEADER_SIZE;
677
482 by Brian Aker
Remove uint.
678
  uint32_t *ptr, *end;
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
679
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
1 by brian
clean slate
680
       ptr != end ;
681
       ptr++)
682
  {
683
      length += 2 + ((Field_blob*)table->field[*ptr])->get_length();
684
  }
685
686
  return length;
687
}
688
689
481 by Brian Aker
Remove all of uchar.
690
unsigned int ha_archive::pack_row(unsigned char *record)
1 by brian
clean slate
691
{
481 by Brian Aker
Remove all of uchar.
692
  unsigned char *ptr;
1 by brian
clean slate
693
694
  if (fix_rec_buff(max_row_length(record)))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
695
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
1 by brian
clean slate
696
697
  /* Copy null bits */
698
  memcpy(record_buffer->buffer, record, table->s->null_bytes);
699
  ptr= record_buffer->buffer + table->s->null_bytes;
700
701
  for (Field **field=table->field ; *field ; field++)
702
  {
703
    if (!((*field)->is_null()))
704
      ptr= (*field)->pack(ptr, record + (*field)->offset(record));
705
  }
706
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
707
  return((unsigned int) (ptr - record_buffer->buffer));
1 by brian
clean slate
708
}
709
710
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
711
/*
1 by brian
clean slate
712
  Look at ha_archive::open() for an explanation of the row format.
713
  Here we just write out the row.
714
715
  Wondering about start_bulk_insert()? We don't implement it for
716
  archive since it optimizes for lots of writes. The only save
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
717
  for implementing start_bulk_insert() is that we could skip
1 by brian
clean slate
718
  setting dirty to true each time.
719
*/
481 by Brian Aker
Remove all of uchar.
720
int ha_archive::write_row(unsigned char *buf)
1 by brian
clean slate
721
{
722
  int rc;
481 by Brian Aker
Remove all of uchar.
723
  unsigned char *read_buf= NULL;
1 by brian
clean slate
724
  uint64_t temp_auto;
481 by Brian Aker
Remove all of uchar.
725
  unsigned char *record=  table->record[0];
1 by brian
clean slate
726
727
  if (share->crashed)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
728
    return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
729
730
  ha_statistic_increment(&SSV::ha_write_count);
731
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
732
    table->timestamp_field->set_time();
733
  pthread_mutex_lock(&share->mutex);
734
163 by Brian Aker
Merge Monty's code.
735
  if (share->archive_write_open == false)
1 by brian
clean slate
736
    if (init_archive_writer())
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
737
      return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
738
739
740
  if (table->next_number_field && record == table->record[0])
741
  {
742
    KEY *mkey= &table->s->key_info[0]; // We only support one key right now
743
    update_auto_increment();
744
    temp_auto= table->next_number_field->val_int();
745
746
    /*
747
      We don't support decremening auto_increment. They make the performance
748
      just cry.
749
    */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
750
    if (temp_auto <= share->archive_write.auto_increment &&
1 by brian
clean slate
751
        mkey->flags & HA_NOSAME)
752
    {
753
      rc= HA_ERR_FOUND_DUPP_KEY;
754
      goto error;
755
    }
756
#ifdef DEAD_CODE
757
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
758
      Bad news, this will cause a search for the unique value which is very
759
      expensive since we will have to do a table scan which will lock up
760
      all other writers during this period. This could perhaps be optimized
1 by brian
clean slate
761
      in the future.
762
    */
763
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
764
      /*
1 by brian
clean slate
765
        First we create a buffer that we can use for reading rows, and can pass
766
        to get_row().
767
      */
656.1.25 by Monty Taylor
Removed my_malloc stuff from storage/
768
      if (!(read_buf= (unsigned char*) malloc(table->s->reclength)))
1 by brian
clean slate
769
      {
770
        rc= HA_ERR_OUT_OF_MEM;
771
        goto error;
772
      }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
773
       /*
1 by brian
clean slate
774
         All of the buffer must be written out or we won't see all of the
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
775
         data
1 by brian
clean slate
776
       */
777
      azflush(&(share->archive_write), Z_SYNC_FLUSH);
778
      /*
779
        Set the position of the local read thread to the beginning postion.
780
      */
781
      if (read_data_header(&archive))
782
      {
783
        rc= HA_ERR_CRASHED_ON_USAGE;
784
        goto error;
785
      }
786
787
      Field *mfield= table->next_number_field;
788
789
      while (!(get_row(&archive, read_buf)))
790
      {
791
        if (!memcmp(read_buf + mfield->offset(record),
792
                    table->next_number_field->ptr,
793
                    mfield->max_display_length()))
794
        {
795
          rc= HA_ERR_FOUND_DUPP_KEY;
796
          goto error;
797
        }
798
      }
799
    }
800
#endif
801
    else
802
    {
803
      if (temp_auto > share->archive_write.auto_increment)
804
        stats.auto_increment_value=
805
          (share->archive_write.auto_increment= temp_auto) + 1;
806
    }
807
  }
808
809
  /*
810
    Notice that the global auto_increment has been increased.
811
    In case of a failed row write, we will never try to reuse the value.
812
  */
813
  share->rows_recorded++;
814
  rc= real_write_row(buf,  &(share->archive_write));
815
error:
816
  pthread_mutex_unlock(&share->mutex);
817
  if (read_buf)
481 by Brian Aker
Remove all of uchar.
818
    free((unsigned char*) read_buf);
1 by brian
clean slate
819
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
820
  return(rc);
1 by brian
clean slate
821
}
822
823
653 by Brian Aker
More solaris bits
824
void ha_archive::get_auto_increment(uint64_t, uint64_t, uint64_t,
825
                                    uint64_t *first_value, uint64_t *nb_reserved_values)
1 by brian
clean slate
826
{
163 by Brian Aker
Merge Monty's code.
827
  *nb_reserved_values= UINT64_MAX;
1 by brian
clean slate
828
  *first_value= share->archive_write.auto_increment + 1;
829
}
830
831
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
653 by Brian Aker
More solaris bits
832
int ha_archive::index_init(uint32_t keynr, bool)
1 by brian
clean slate
833
{
834
  active_index= keynr;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
835
  return(0);
1 by brian
clean slate
836
}
837
838
839
/*
840
  No indexes, so if we get a request for an index search since we tell
841
  the optimizer that we have unique indexes, we scan
842
*/
481 by Brian Aker
Remove all of uchar.
843
int ha_archive::index_read(unsigned char *buf, const unsigned char *key,
482 by Brian Aker
Remove uint.
844
                             uint32_t key_len, enum ha_rkey_function find_flag)
1 by brian
clean slate
845
{
846
  int rc;
847
  rc= index_read_idx(buf, active_index, key, key_len, find_flag);
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
848
  return(rc);
1 by brian
clean slate
849
}
850
851
482 by Brian Aker
Remove uint.
852
int ha_archive::index_read_idx(unsigned char *buf, uint32_t index, const unsigned char *key,
653 by Brian Aker
More solaris bits
853
                               uint32_t key_len, enum ha_rkey_function)
1 by brian
clean slate
854
{
855
  int rc;
856
  bool found= 0;
857
  KEY *mkey= &table->s->key_info[index];
858
  current_k_offset= mkey->key_part->offset;
859
  current_key= key;
860
  current_key_len= key_len;
861
163 by Brian Aker
Merge Monty's code.
862
  rc= rnd_init(true);
1 by brian
clean slate
863
864
  if (rc)
865
    goto error;
866
867
  while (!(get_row(&archive, buf)))
868
  {
869
    if (!memcmp(current_key, buf + current_k_offset, current_key_len))
870
    {
871
      found= 1;
872
      break;
873
    }
874
  }
875
876
  if (found)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
877
    return(0);
1 by brian
clean slate
878
879
error:
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
880
  return(rc ? rc : HA_ERR_END_OF_FILE);
1 by brian
clean slate
881
}
882
883
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
884
int ha_archive::index_next(unsigned char * buf)
885
{
1 by brian
clean slate
886
  bool found= 0;
887
888
  while (!(get_row(&archive, buf)))
889
  {
890
    if (!memcmp(current_key, buf+current_k_offset, current_key_len))
891
    {
892
      found= 1;
893
      break;
894
    }
895
  }
896
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
897
  return(found ? 0 : HA_ERR_END_OF_FILE);
1 by brian
clean slate
898
}
899
900
/*
901
  All calls that need to scan the table start with this method. If we are told
902
  that it is a table scan we rewind the file to the beginning, otherwise
903
  we assume the position will be set.
904
*/
905
906
int ha_archive::rnd_init(bool scan)
907
{
908
  if (share->crashed)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
909
      return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
910
911
  init_archive_reader();
912
913
  /* We rewind the file so that we can read from the beginning if scan */
914
  if (scan)
915
  {
916
    if (read_data_header(&archive))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
917
      return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
918
  }
919
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
920
  return(0);
1 by brian
clean slate
921
}
922
923
924
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
925
  This is the method that is used to read a row. It assumes that the row is
1 by brian
clean slate
926
  positioned where you want it.
927
*/
481 by Brian Aker
Remove all of uchar.
928
int ha_archive::get_row(azio_stream *file_to_read, unsigned char *buf)
1 by brian
clean slate
929
{
930
  int rc;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
931
1 by brian
clean slate
932
  if (file_to_read->version == ARCHIVE_VERSION)
933
    rc= get_row_version3(file_to_read, buf);
934
  else
935
    rc= -1;
936
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
937
  return(rc);
1 by brian
clean slate
938
}
939
940
/* Reallocate buffer if needed */
941
bool ha_archive::fix_rec_buff(unsigned int length)
942
{
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
943
  assert(record_buffer->buffer);
1 by brian
clean slate
944
945
  if (length > record_buffer->length)
946
  {
481 by Brian Aker
Remove all of uchar.
947
    unsigned char *newptr;
656.1.46 by Monty Taylor
More malloc return cleanups.
948
    if (!(newptr= (unsigned char *)realloc(record_buffer->buffer, length)))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
949
      return(1);
1 by brian
clean slate
950
    record_buffer->buffer= newptr;
951
    record_buffer->length= length;
952
  }
953
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
954
  assert(length <= record_buffer->length);
1 by brian
clean slate
955
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
956
  return(0);
1 by brian
clean slate
957
}
958
481 by Brian Aker
Remove all of uchar.
959
int ha_archive::unpack_row(azio_stream *file_to_read, unsigned char *record)
1 by brian
clean slate
960
{
961
  unsigned int read;
962
  int error;
481 by Brian Aker
Remove all of uchar.
963
  const unsigned char *ptr;
1 by brian
clean slate
964
965
  read= azread_row(file_to_read, &error);
481 by Brian Aker
Remove all of uchar.
966
  ptr= (const unsigned char *)file_to_read->row_ptr;
1 by brian
clean slate
967
968
  if (error || read == 0)
969
  {
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
970
    return(-1);
1 by brian
clean slate
971
  }
972
973
  /* Copy null bits */
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
974
  memcpy(record, ptr, table->getNullBytes());
975
  ptr+= table->getNullBytes();
1 by brian
clean slate
976
  for (Field **field=table->field ; *field ; field++)
977
  {
978
    if (!((*field)->is_null()))
979
    {
980
      ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), ptr);
981
    }
982
  }
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
983
  return(0);
1 by brian
clean slate
984
}
985
986
481 by Brian Aker
Remove all of uchar.
987
int ha_archive::get_row_version3(azio_stream *file_to_read, unsigned char *buf)
1 by brian
clean slate
988
{
989
  int returnable= unpack_row(file_to_read, buf);
990
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
991
  return(returnable);
1 by brian
clean slate
992
}
993
994
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
995
/*
1 by brian
clean slate
996
  Called during ORDER BY. Its position is either from being called sequentially
997
  or by having had ha_archive::rnd_pos() called before it is called.
998
*/
999
481 by Brian Aker
Remove all of uchar.
1000
int ha_archive::rnd_next(unsigned char *buf)
1 by brian
clean slate
1001
{
1002
  int rc;
1003
1004
  if (share->crashed)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1005
      return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
1006
1007
  if (!scan_rows)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1008
    return(HA_ERR_END_OF_FILE);
1 by brian
clean slate
1009
  scan_rows--;
1010
1011
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1012
  current_position= aztell(&archive);
1013
  rc= get_row(&archive, buf);
1014
1015
  table->status=rc ? STATUS_NOT_FOUND: 0;
1016
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1017
  return(rc);
1 by brian
clean slate
1018
}
1019
1020
1021
/*
1022
  Thanks to the table flag HA_REC_NOT_IN_SEQ this will be called after
1023
  each call to ha_archive::rnd_next() if an ordering of the rows is
1024
  needed.
1025
*/
1026
653 by Brian Aker
More solaris bits
1027
void ha_archive::position(const unsigned char *)
1 by brian
clean slate
1028
{
1029
  my_store_ptr(ref, ref_length, current_position);
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1030
  return;
1 by brian
clean slate
1031
}
1032
1033
1034
/*
1035
  This is called after a table scan for each row if the results of the
1036
  scan need to be ordered. It will take *pos and use it to move the
1037
  cursor in the file so that the next row that is called is the
1038
  correctly ordered row.
1039
*/
1040
481 by Brian Aker
Remove all of uchar.
1041
int ha_archive::rnd_pos(unsigned char * buf, unsigned char *pos)
1 by brian
clean slate
1042
{
1043
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1044
  current_position= (my_off_t)my_get_ptr(pos, ref_length);
1045
  if (azseek(&archive, (size_t)current_position, SEEK_SET) == (size_t)(-1L))
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1046
    return(HA_ERR_CRASHED_ON_USAGE);
1047
  return(get_row(&archive, buf));
1 by brian
clean slate
1048
}
1049
1050
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1051
  This method repairs the meta file. It does this by walking the datafile and
1 by brian
clean slate
1052
  rewriting the meta file. Currently it does this by calling optimize with
1053
  the extended flag.
1054
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1055
int ha_archive::repair(Session* session, HA_CHECK_OPT* check_opt)
1 by brian
clean slate
1056
{
1057
  check_opt->flags= T_EXTEND;
520.1.22 by Brian Aker
Second pass of thd cleanup
1058
  int rc= optimize(session, check_opt);
1 by brian
clean slate
1059
1060
  if (rc)
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1061
    return(HA_ERR_CRASHED_ON_REPAIR);
1 by brian
clean slate
1062
163 by Brian Aker
Merge Monty's code.
1063
  share->crashed= false;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1064
  return(0);
1 by brian
clean slate
1065
}
1066
1067
/*
1068
  The table can become fragmented if data was inserted, read, and then
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1069
  inserted again. What we do is open up the file and recompress it completely.
1 by brian
clean slate
1070
*/
653 by Brian Aker
More solaris bits
1071
int ha_archive::optimize(Session *, HA_CHECK_OPT *)
1 by brian
clean slate
1072
{
1073
  int rc= 0;
1074
  azio_stream writer;
1075
  char writer_filename[FN_REFLEN];
1076
1077
  init_archive_reader();
1078
1079
  // now we close both our writer and our reader for the rename
1080
  if (share->archive_write_open)
1081
  {
1082
    azclose(&(share->archive_write));
163 by Brian Aker
Merge Monty's code.
1083
    share->archive_write_open= false;
1 by brian
clean slate
1084
  }
1085
1086
  /* Lets create a file to contain the new data */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1087
  fn_format(writer_filename, share->table_name, "", ARN,
1 by brian
clean slate
1088
            MY_REPLACE_EXT | MY_UNPACK_FILENAME);
1089
492.1.14 by Monty Taylor
Removed O_BINARY and FILE_BINARY.
1090
  if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR, AZ_METHOD_BLOCK)))
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1091
    return(HA_ERR_CRASHED_ON_USAGE);
1 by brian
clean slate
1092
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1093
  /*
1094
    An extended rebuild is a lot more effort. We open up each row and re-record it.
1095
    Any dead rows are removed (aka rows that may have been partially recorded).
1 by brian
clean slate
1096
1097
    As of Archive format 3, this is the only type that is performed, before this
1098
    version it was just done on T_EXTEND
1099
  */
1100
  if (1)
1101
  {
1102
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1103
      Now we will rewind the archive file so that we are positioned at the
1 by brian
clean slate
1104
      start of the file.
1105
    */
1106
    azflush(&archive, Z_SYNC_FLUSH);
1107
    rc= read_data_header(&archive);
1108
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1109
    /*
1 by brian
clean slate
1110
      On success of writing out the new header, we now fetch each row and
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1111
      insert it into the new archive file.
1 by brian
clean slate
1112
    */
1113
    if (!rc)
1114
    {
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1115
      uint64_t x;
1116
      uint64_t rows_restored;
1 by brian
clean slate
1117
      share->rows_recorded= 0;
1118
      stats.auto_increment_value= 1;
1119
      share->archive_write.auto_increment= 0;
1120
1121
      rows_restored= archive.rows;
1122
1123
      for (x= 0; x < rows_restored ; x++)
1124
      {
1125
        rc= get_row(&archive, table->record[0]);
1126
1127
        if (rc != 0)
1128
          break;
1129
1130
        real_write_row(table->record[0], &writer);
1131
        /*
1132
          Long term it should be possible to optimize this so that
1133
          it is not called on each row.
1134
        */
1135
        if (table->found_next_number_field)
1136
        {
1137
          Field *field= table->found_next_number_field;
1138
          uint64_t auto_value=
1139
            (uint64_t) field->val_int(table->record[0] +
1140
                                       field->offset(table->record[0]));
1141
          if (share->archive_write.auto_increment < auto_value)
1142
            stats.auto_increment_value=
1143
              (share->archive_write.auto_increment= auto_value) + 1;
1144
        }
1145
      }
1146
      share->rows_recorded= (ha_rows)writer.rows;
1147
    }
1148
1149
    if (rc && rc != HA_ERR_END_OF_FILE)
1150
    {
1151
      goto error;
1152
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1153
  }
1 by brian
clean slate
1154
1155
  azclose(&writer);
163 by Brian Aker
Merge Monty's code.
1156
  share->dirty= false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1157
1 by brian
clean slate
1158
  azclose(&archive);
1159
1160
  // make the file we just wrote be our data file
1161
  rc = my_rename(writer_filename,share->data_file_name,MYF(0));
1162
1163
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1164
  return(rc);
1 by brian
clean slate
1165
error:
1166
  azclose(&writer);
1167
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1168
  return(rc);
1 by brian
clean slate
1169
}
1170
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1171
/*
1 by brian
clean slate
1172
  Below is an example of how to setup row level locking.
1173
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1174
THR_LOCK_DATA **ha_archive::store_lock(Session *session,
1 by brian
clean slate
1175
                                       THR_LOCK_DATA **to,
1176
                                       enum thr_lock_type lock_type)
1177
{
1178
  if (lock_type == TL_WRITE_DELAYED)
163 by Brian Aker
Merge Monty's code.
1179
    delayed_insert= true;
1 by brian
clean slate
1180
  else
163 by Brian Aker
Merge Monty's code.
1181
    delayed_insert= false;
1 by brian
clean slate
1182
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1183
  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
1 by brian
clean slate
1184
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1185
    /*
1 by brian
clean slate
1186
      Here is where we get into the guts of a row level lock.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1187
      If TL_UNLOCK is set
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1188
      If we are not doing a LOCK Table or DISCARD/IMPORT
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1189
      TABLESPACE, then allow multiple writers
1 by brian
clean slate
1190
    */
1191
1192
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
520.1.22 by Brian Aker
Second pass of thd cleanup
1193
         lock_type <= TL_WRITE) && !session_in_lock_tables(session)
1194
        && !session_tablespace_op(session))
1 by brian
clean slate
1195
      lock_type = TL_WRITE_ALLOW_WRITE;
1196
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1197
    /*
1 by brian
clean slate
1198
      In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
1199
      MySQL would use the lock TL_READ_NO_INSERT on t2, and that
1200
      would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
1201
      to t2. Convert the lock to a normal read lock to allow
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1202
      concurrent inserts to t2.
1 by brian
clean slate
1203
    */
1204
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1205
    if (lock_type == TL_READ_NO_INSERT && !session_in_lock_tables(session))
1 by brian
clean slate
1206
      lock_type = TL_READ;
1207
1208
    lock.type=lock_type;
1209
  }
1210
1211
  *to++= &lock;
1212
1213
  return to;
1214
}
1215
1216
void ha_archive::update_create_info(HA_CREATE_INFO *create_info)
1217
{
1218
  ha_archive::info(HA_STATUS_AUTO);
1219
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
1220
  {
1221
    create_info->auto_increment_value= stats.auto_increment_value;
1222
  }
1223
1224
  if (!(my_readlink(share->real_path, share->data_file_name, MYF(0))))
1225
    create_info->data_file_name= share->real_path;
1226
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1227
  return;
1 by brian
clean slate
1228
}
1229
1230
1231
/*
1232
  Hints for optimizer, see ha_tina for more information
1233
*/
482 by Brian Aker
Remove uint.
1234
int ha_archive::info(uint32_t flag)
1 by brian
clean slate
1235
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1236
  /*
1 by brian
clean slate
1237
    If dirty, we lock, and then reset/flush the data.
1238
    I found that just calling azflush() doesn't always work.
1239
  */
1240
  pthread_mutex_lock(&share->mutex);
163 by Brian Aker
Merge Monty's code.
1241
  if (share->dirty == true)
1 by brian
clean slate
1242
  {
1243
    azflush(&(share->archive_write), Z_SYNC_FLUSH);
1244
    share->rows_recorded= share->archive_write.rows;
163 by Brian Aker
Merge Monty's code.
1245
    share->dirty= false;
1 by brian
clean slate
1246
    if (share->version < global_version)
1247
    {
1248
      share->version_rows= share->rows_recorded;
1249
      share->version= global_version;
1250
    }
1251
1252
  }
1253
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1254
  /*
1 by brian
clean slate
1255
    This should be an accurate number now, though bulk and delayed inserts can
1256
    cause the number to be inaccurate.
1257
  */
1258
  stats.records= share->rows_recorded;
1259
  pthread_mutex_unlock(&share->mutex);
1260
1261
  scan_rows= stats.records;
1262
  stats.deleted= 0;
1263
1264
  /* Costs quite a bit more to get all information */
1265
  if (flag & HA_STATUS_TIME)
1266
  {
15 by brian
Fix for stat, NETWARE removal
1267
    struct stat file_stat;  // Stat information for the data file
1 by brian
clean slate
1268
398.1.10 by Monty Taylor
Actually removed VOID() this time.
1269
    stat(share->data_file_name, &file_stat);
1 by brian
clean slate
1270
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
1271
    stats.mean_rec_length= table->getRecordLength()+ buffer.alloced_length();
1 by brian
clean slate
1272
    stats.data_file_length= file_stat.st_size;
1273
    stats.create_time= file_stat.st_ctime;
1274
    stats.update_time= file_stat.st_mtime;
1275
    stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length;
1276
  }
1277
  stats.delete_length= 0;
1278
  stats.index_file_length=0;
1279
1280
  if (flag & HA_STATUS_AUTO)
1281
  {
1282
    init_archive_reader();
1283
    pthread_mutex_lock(&share->mutex);
1284
    azflush(&archive, Z_SYNC_FLUSH);
1285
    pthread_mutex_unlock(&share->mutex);
1286
    stats.auto_increment_value= archive.auto_increment + 1;
1287
  }
1288
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1289
  return(0);
1 by brian
clean slate
1290
}
1291
1292
1293
/*
1294
  This method tells us that a bulk insert operation is about to occur. We set
1295
  a flag which will keep write_row from saying that its data is dirty. This in
1296
  turn will keep selects from causing a sync to occur.
1297
  Basically, yet another optimizations to keep compression working well.
1298
*/
1299
void ha_archive::start_bulk_insert(ha_rows rows)
1300
{
1301
  if (!rows || rows >= ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT)
163 by Brian Aker
Merge Monty's code.
1302
    bulk_insert= true;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1303
  return;
1 by brian
clean slate
1304
}
1305
1306
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1307
/*
1 by brian
clean slate
1308
  Other side of start_bulk_insert, is end_bulk_insert. Here we turn off the bulk insert
1309
  flag, and set the share dirty so that the next select will call sync for us.
1310
*/
1311
int ha_archive::end_bulk_insert()
1312
{
163 by Brian Aker
Merge Monty's code.
1313
  bulk_insert= false;
1314
  share->dirty= true;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1315
  return(0);
1 by brian
clean slate
1316
}
1317
1318
/*
1319
  We cancel a truncate command. The only way to delete an archive table is to drop it.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1320
  This is done for security reasons. In a later version we will enable this by
1 by brian
clean slate
1321
  allowing the user to select a different row format.
1322
*/
1323
int ha_archive::delete_all_rows()
1324
{
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1325
  return(HA_ERR_WRONG_COMMAND);
1 by brian
clean slate
1326
}
1327
1328
/*
1329
  We just return state if asked.
1330
*/
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1331
bool ha_archive::is_crashed() const
1 by brian
clean slate
1332
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1333
  return(share->crashed);
1 by brian
clean slate
1334
}
1335
1336
/*
1337
  Simple scan of the tables to make sure everything is ok.
1338
*/
1339
653 by Brian Aker
More solaris bits
1340
int ha_archive::check(Session* session, HA_CHECK_OPT *)
1 by brian
clean slate
1341
{
1342
  int rc= 0;
1343
  const char *old_proc_info;
53.2.2 by Monty Taylor
Updated everything that needs updating to compile with -std=gnu99 -pedantic
1344
  uint64_t x;
1 by brian
clean slate
1345
520.1.22 by Brian Aker
Second pass of thd cleanup
1346
  old_proc_info= get_session_proc_info(session);
1347
  set_session_proc_info(session, "Checking table");
1 by brian
clean slate
1348
  /* Flush any waiting data */
1349
  pthread_mutex_lock(&share->mutex);
1350
  azflush(&(share->archive_write), Z_SYNC_FLUSH);
1351
  pthread_mutex_unlock(&share->mutex);
1352
1353
  /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1354
    Now we will rewind the archive file so that we are positioned at the
1 by brian
clean slate
1355
    start of the file.
1356
  */
1357
  init_archive_reader();
1358
  azflush(&archive, Z_SYNC_FLUSH);
1359
  read_data_header(&archive);
1360
  for (x= 0; x < share->archive_write.rows; x++)
1361
  {
1362
    rc= get_row(&archive, table->record[0]);
1363
1364
    if (rc != 0)
1365
      break;
1366
  }
1367
520.1.22 by Brian Aker
Second pass of thd cleanup
1368
  set_session_proc_info(session, old_proc_info);
1 by brian
clean slate
1369
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1370
  if ((rc && rc != HA_ERR_END_OF_FILE))
1 by brian
clean slate
1371
  {
163 by Brian Aker
Merge Monty's code.
1372
    share->crashed= false;
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1373
    return(HA_ADMIN_CORRUPT);
1 by brian
clean slate
1374
  }
1375
  else
1376
  {
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1377
    return(HA_ADMIN_OK);
1 by brian
clean slate
1378
  }
1379
}
1380
1381
/*
1382
  Check and repair the table if needed.
1383
*/
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1384
bool ha_archive::check_and_repair(Session *session)
1 by brian
clean slate
1385
{
1386
  HA_CHECK_OPT check_opt;
1387
1388
  check_opt.init();
1389
520.1.22 by Brian Aker
Second pass of thd cleanup
1390
  return(repair(session, &check_opt));
1 by brian
clean slate
1391
}
1392
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1393
archive_record_buffer *ha_archive::create_record_buffer(unsigned int length)
1 by brian
clean slate
1394
{
1395
  archive_record_buffer *r;
656.1.25 by Monty Taylor
Removed my_malloc stuff from storage/
1396
  if (!(r= (archive_record_buffer*) malloc(sizeof(archive_record_buffer))))
1 by brian
clean slate
1397
  {
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1398
    return(NULL); /* purecov: inspected */
1 by brian
clean slate
1399
  }
1400
  r->length= (int)length;
1401
656.1.25 by Monty Taylor
Removed my_malloc stuff from storage/
1402
  if (!(r->buffer= (unsigned char*) malloc(r->length)))
1 by brian
clean slate
1403
  {
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1404
    free((char*) r);
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1405
    return(NULL); /* purecov: inspected */
1 by brian
clean slate
1406
  }
1407
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1408
  return(r);
1 by brian
clean slate
1409
}
1410
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1411
void ha_archive::destroy_record_buffer(archive_record_buffer *r)
1 by brian
clean slate
1412
{
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
1413
  free((char*) r->buffer);
1414
  free((char*) r);
51.3.8 by Jay Pipes
Removed DBUG from CSV and Blackhole storage engines
1415
  return;
1 by brian
clean slate
1416
}
1417
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1418
static DRIZZLE_SYSVAR_BOOL(aio, archive_use_aio,
1 by brian
clean slate
1419
  PLUGIN_VAR_NOCMDOPT,
1420
  "Whether or not to use asynchronous IO.",
163 by Brian Aker
Merge Monty's code.
1421
  NULL, NULL, true);
1 by brian
clean slate
1422
1423
static struct st_mysql_sys_var* archive_system_variables[]= {
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1424
  DRIZZLE_SYSVAR(aio),
1 by brian
clean slate
1425
  NULL
1426
};
1427
813.2.1 by Toru Maesaka
Renamed mysql_declare_plugin to drizzle_declare_plugin
1428
drizzle_declare_plugin(archive)
1 by brian
clean slate
1429
{
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1430
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
1 by brian
clean slate
1431
  "ARCHIVE",
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
1432
  "3.5",
1 by brian
clean slate
1433
  "Brian Aker, MySQL AB",
1434
  "Archive storage engine",
1435
  PLUGIN_LICENSE_GPL,
1436
  archive_db_init, /* Plugin Init */
1437
  archive_db_done, /* Plugin Deinit */
1438
  NULL,                       /* status variables                */
1439
  archive_system_variables,   /* system variables                */
1440
  NULL                        /* config options                  */
1441
}
813.2.2 by Toru Maesaka
Renamed mysql_declare_plugin_end to drizzle_declare_plugin_end
1442
drizzle_declare_plugin_end;
1 by brian
clean slate
1443