44 #include "my_global.h"
46 #include "sql_class.h"
47 #include <mysql/plugin.h>
50 #include "probes_mysql.h"
60 #define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(ulonglong) \
61 + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(uchar)
62 #define TINA_CHECK_HEADER 254 // The number we use to determine corruption
63 #define BLOB_MEMROOT_ALLOC_SIZE 8192
66 #define CSV_EXT ".CSV" // The data file
67 #define CSN_EXT ".CSN" // Files used during repair and update
68 #define CSM_EXT ".CSM" // Meta file
73 static int read_meta_file(File meta_file, ha_rows *rows);
74 static int write_meta_file(File meta_file, ha_rows rows,
bool dirty);
76 extern "C" void tina_get_status(
void* param,
int concurrent_insert);
77 extern "C" void tina_update_status(
void* param);
78 extern "C" my_bool tina_check_status(
void* param);
82 static HASH tina_open_tables;
101 return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) );
104 static uchar* tina_get_key(
TINA_SHARE *share,
size_t *length,
105 my_bool not_used __attribute__((unused)))
107 *length=share->table_name_length;
108 return (uchar*) share->table_name;
111 #ifdef HAVE_PSI_INTERFACE
113 static PSI_mutex_key csv_key_mutex_tina, csv_key_mutex_TINA_SHARE_mutex;
115 static PSI_mutex_info all_tina_mutexes[]=
117 { &csv_key_mutex_tina,
"tina", PSI_FLAG_GLOBAL},
118 { &csv_key_mutex_TINA_SHARE_mutex,
"TINA_SHARE::mutex", 0}
121 static PSI_file_key csv_key_file_metadata, csv_key_file_data,
124 static PSI_file_info all_tina_files[]=
126 { &csv_key_file_metadata,
"metadata", 0},
127 { &csv_key_file_data,
"data", 0},
128 { &csv_key_file_update,
"update", 0}
131 static void init_tina_psi_keys(
void)
133 const char* category=
"csv";
136 count= array_elements(all_tina_mutexes);
139 count= array_elements(all_tina_files);
144 static int tina_init_func(
void *p)
148 #ifdef HAVE_PSI_INTERFACE
149 init_tina_psi_keys();
154 (void) my_hash_init(&tina_open_tables,system_charset_info,32,0,0,
155 (my_hash_get_key) tina_get_key,0,0);
156 tina_hton->state= SHOW_OPTION_YES;
157 tina_hton->db_type= DB_TYPE_CSV_DB;
158 tina_hton->create= tina_create_handler;
159 tina_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES |
164 static int tina_done_func(
void *p)
166 my_hash_free(&tina_open_tables);
179 char meta_file_name[FN_REFLEN];
185 length=(uint) strlen(table_name);
191 if (!(share=(
TINA_SHARE*) my_hash_search(&tina_open_tables,
195 if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
196 &share,
sizeof(*share),
205 share->is_log_table= FALSE;
206 share->table_name_length= length;
207 share->table_name= tmp_name;
208 share->crashed= FALSE;
209 share->rows_recorded= 0;
210 share->update_file_opened= FALSE;
211 share->tina_write_opened= FALSE;
212 share->data_file_version= 0;
213 strmov(share->table_name, table_name);
214 fn_format(share->data_file_name, table_name,
"", CSV_EXT,
215 MY_REPLACE_EXT|MY_UNPACK_FILENAME);
216 fn_format(meta_file_name, table_name,
"", CSM_EXT,
217 MY_REPLACE_EXT|MY_UNPACK_FILENAME);
220 share->data_file_name, &file_stat, MYF(MY_WME)) == NULL)
222 share->saved_data_file_length= file_stat.st_size;
224 if (my_hash_insert(&tina_open_tables, (uchar*) share))
226 thr_lock_init(&share->lock);
228 &share->mutex, MY_MUTEX_INIT_FAST);
239 MYF(MY_WME))) == -1) ||
240 read_meta_file(share->meta_file, &share->rows_recorded))
241 share->crashed= TRUE;
276 static int read_meta_file(File meta_file, ha_rows *rows)
278 uchar meta_buffer[META_BUFFER_SIZE];
279 uchar *ptr= meta_buffer;
281 DBUG_ENTER(
"ha_tina::read_meta_file");
284 if (
mysql_file_read(meta_file, (uchar*)meta_buffer, META_BUFFER_SIZE, 0)
286 DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
292 ptr+=
sizeof(uchar)*2;
293 *rows= (ha_rows)uint8korr(ptr);
294 ptr+=
sizeof(ulonglong);
299 ptr+= 3*
sizeof(ulonglong);
302 if ((meta_buffer[0] != (uchar)TINA_CHECK_HEADER) ||
303 ((
bool)(*ptr)== TRUE))
304 DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
331 static int write_meta_file(File meta_file, ha_rows rows,
bool dirty)
333 uchar meta_buffer[META_BUFFER_SIZE];
334 uchar *ptr= meta_buffer;
336 DBUG_ENTER(
"ha_tina::write_meta_file");
338 *ptr= (uchar)TINA_CHECK_HEADER;
340 *ptr= (uchar)TINA_VERSION;
342 int8store(ptr, (ulonglong)rows);
343 ptr+=
sizeof(ulonglong);
344 memset(ptr, 0, 3*
sizeof(ulonglong));
349 ptr+= 3*
sizeof(ulonglong);
362 bool ha_tina::check_and_repair(THD *thd)
365 DBUG_ENTER(
"ha_tina::check_and_repair");
369 DBUG_RETURN(
repair(thd, &check_opt));
373 int ha_tina::init_tina_writer()
375 DBUG_ENTER(
"ha_tina::init_tina_writer");
382 (void)write_meta_file(share->meta_file, share->rows_recorded, TRUE);
384 if ((share->tina_write_filedes=
386 share->data_file_name, O_RDWR|O_APPEND,
389 DBUG_PRINT(
"info", (
"Could not open tina file writes"));
390 share->crashed= TRUE;
391 DBUG_RETURN(my_errno ? my_errno : -1);
393 share->tina_write_opened= TRUE;
399 bool ha_tina::is_crashed()
const
401 DBUG_ENTER(
"ha_tina::is_crashed");
402 DBUG_RETURN(share->crashed);
410 DBUG_ENTER(
"ha_tina::free_share");
413 if (!--share->use_count){
415 (void)write_meta_file(share->meta_file, share->rows_recorded,
416 share->crashed ? TRUE :FALSE);
419 if (share->tina_write_opened)
423 share->tina_write_opened= FALSE;
426 my_hash_delete(&tina_open_tables, (uchar*) share);
427 thr_lock_delete(&share->lock);
433 DBUG_RETURN(result_code);
448 my_off_t end,
int *eoln_len)
452 for (my_off_t x= begin; x < end; x++)
455 if (data_buff->get_value(x) ==
'\n')
458 if (data_buff->get_value(x) ==
'\r')
461 if (x + 1 == end || (data_buff->get_value(x + 1) !=
'\n'))
479 return new (mem_root)
ha_tina(hton, table);
489 current_position(0), next_position(0), local_saved_data_file_length(0),
490 file_buff(0), chain_alloced(0), chain_size(DEFAULT_CHAIN_LENGTH),
491 local_data_file_version(0), records_is_known(0)
494 buffer.set((
char*)byte_buffer, IO_SIZE, &my_charset_bin);
497 init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0);;
505 int ha_tina::encode_quote(uchar *
buf)
507 char attribute_buffer[1024];
508 String attribute(attribute_buffer,
sizeof(attribute_buffer),
511 my_bitmap_map *org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
514 for (
Field **field=table->field ; *field ; field++)
518 const bool was_null= (*field)->is_null();
526 (*field)->set_default();
527 (*field)->set_notnull();
530 (*field)->val_str(&attribute,&attribute);
533 (*field)->set_null();
535 if ((*field)->str_needs_quotes())
537 ptr= attribute.ptr();
538 end_ptr= attribute.length() + ptr;
542 for (; ptr < end_ptr; ptr++)
549 else if (*ptr ==
'\r')
554 else if (*ptr ==
'\\')
559 else if (*ptr ==
'\n')
571 buffer.append(attribute);
577 buffer.length(buffer.length() - 1);
582 dbug_tmp_restore_column_map(table->read_set, org_bitmap);
583 return (buffer.length());
591 int ha_tina::chain_append()
593 if ( chain_ptr != chain && (chain_ptr -1)->end == current_position)
594 (chain_ptr -1)->end= next_position;
598 if ((off_t)(chain_ptr - chain) == (chain_size -1))
600 my_off_t location= chain_ptr - chain;
601 chain_size += DEFAULT_CHAIN_LENGTH;
605 if ((chain= (
tina_set *) my_realloc((uchar*)chain,
606 chain_size, MYF(MY_WME))) == NULL)
613 memcpy(ptr, chain, DEFAULT_CHAIN_LENGTH *
sizeof(
tina_set));
617 chain_ptr= chain + location;
619 chain_ptr->begin= current_position;
620 chain_ptr->end= next_position;
631 int ha_tina::find_current_row(uchar *buf)
633 my_off_t end_offset, curr_offset= current_position;
635 my_bitmap_map *org_bitmap;
638 DBUG_ENTER(
"ha_tina::find_current_row");
640 free_root(&blobroot, MYF(0));
647 find_eoln_buff(file_buff, current_position,
648 local_saved_data_file_length, &eoln_len)) == 0)
649 DBUG_RETURN(HA_ERR_END_OF_FILE);
652 read_all= !bitmap_is_clear_all(table->write_set);
654 org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
655 error= HA_ERR_CRASHED_ON_USAGE;
657 memset(buf, 0, table->s->null_bytes);
686 for (
Field **field=table->field ; *field ; field++)
691 if (curr_offset >= end_offset)
693 curr_char= file_buff->get_value(curr_offset);
695 if (curr_char ==
'"')
701 for ( ; curr_offset < end_offset; curr_offset++)
703 curr_char= file_buff->get_value(curr_offset);
705 if (curr_char ==
'"' &&
706 (curr_offset == end_offset - 1 ||
707 file_buff->get_value(curr_offset + 1) ==
','))
713 if (curr_char ==
'\\' && curr_offset != (end_offset - 1))
716 curr_char= file_buff->get_value(curr_offset);
717 if (curr_char ==
'r')
719 else if (curr_char ==
'n' )
721 else if (curr_char ==
'\\' || curr_char ==
'"')
722 buffer.append(curr_char);
726 buffer.append(curr_char);
735 if (curr_offset == end_offset - 1)
737 buffer.append(curr_char);
743 for ( ; curr_offset < end_offset; curr_offset++)
745 curr_char= file_buff->get_value(curr_offset);
747 if (curr_char ==
',')
752 if (curr_char ==
'\\' && curr_offset != (end_offset - 1))
755 curr_char= file_buff->get_value(curr_offset);
756 if (curr_char ==
'r')
758 else if (curr_char ==
'n' )
760 else if (curr_char ==
'\\' || curr_char ==
'"')
761 buffer.append(curr_char);
765 buffer.append(curr_char);
774 if (curr_offset == end_offset - 1 && curr_char ==
'"')
776 buffer.append(curr_char);
781 if (read_all || bitmap_is_set(table->read_set, (*field)->field_index))
783 bool is_enum= ((*field)->real_type() == MYSQL_TYPE_ENUM);
792 if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(),
793 is_enum ? CHECK_FIELD_IGNORE : CHECK_FIELD_WARN))
798 if ((*field)->flags & BLOB_FLAG)
802 uint length, packlength;
805 length= blob->get_length(blob->ptr);
806 memcpy(&src, blob->ptr + packlength,
sizeof(
char*));
809 tgt= (uchar*) alloc_root(&blobroot, length);
810 bmove(tgt, src, length);
811 memcpy(blob->ptr + packlength, &tgt,
sizeof(
char*));
816 next_position= end_offset + eoln_len;
820 dbug_tmp_restore_column_map(table->write_set, org_bitmap);
829 static const char *ha_tina_exts[] = {
845 void tina_get_status(
void* param,
int concurrent_insert)
851 void tina_update_status(
void* param)
854 tina->update_status();
858 my_bool tina_check_status(
void* param)
875 void ha_tina::get_status()
877 if (share->is_log_table)
884 local_saved_data_file_length= share->saved_data_file_length;
888 local_saved_data_file_length= share->saved_data_file_length;
913 void ha_tina::update_status()
916 share->saved_data_file_length= local_saved_data_file_length;
925 int ha_tina::open(
const char *
name,
int mode, uint open_options)
927 DBUG_ENTER(
"ha_tina::open");
929 if (!(share= get_share(name, table)))
930 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
932 if (share->crashed && !(open_options & HA_OPEN_FOR_REPAIR))
935 DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
938 local_data_file_version= share->data_file_version;
940 share->data_file_name,
941 O_RDONLY, MYF(MY_WME))) == -1)
944 DBUG_RETURN(my_errno ? my_errno : -1);
952 thr_lock_data_init(&share->lock, &lock, (
void*)
this);
955 share->lock.get_status= tina_get_status;
956 share->lock.update_status= tina_update_status;
957 share->lock.check_status= tina_check_status;
967 int ha_tina::close(
void)
970 DBUG_ENTER(
"ha_tina::close");
972 DBUG_RETURN(free_share(share) || rc);
980 int ha_tina::write_row(uchar * buf)
983 DBUG_ENTER(
"ha_tina::write_row");
986 DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
988 ha_statistic_increment(&SSV::ha_write_count);
990 size= encode_quote(buf);
992 if (!share->tina_write_opened)
993 if (init_tina_writer())
998 MYF(MY_WME | MY_NABP)))
1002 local_saved_data_file_length+=
size;
1006 share->rows_recorded++;
1008 if (share->is_log_table)
1017 int ha_tina::open_update_temp_file_if_needed()
1019 char updated_fname[FN_REFLEN];
1021 if (!share->update_file_opened)
1023 if ((update_temp_file=
1025 fn_format(updated_fname, share->table_name,
1027 MY_REPLACE_EXT | MY_UNPACK_FILENAME),
1028 0, O_RDWR | O_TRUNC, MYF(MY_WME))) < 0)
1030 share->update_file_opened= TRUE;
1031 temp_file_length= 0;
1044 int ha_tina::update_row(
const uchar * old_data, uchar * new_data)
1048 DBUG_ENTER(
"ha_tina::update_row");
1050 ha_statistic_increment(&SSV::ha_update_count);
1052 size= encode_quote(new_data);
1064 if (open_update_temp_file_if_needed())
1068 MYF(MY_WME | MY_NABP)))
1070 temp_file_length+=
size;
1074 DBUG_ASSERT(!share->is_log_table);
1077 DBUG_PRINT(
"info",(
"rc = %d", rc));
1091 int ha_tina::delete_row(
const uchar * buf)
1093 DBUG_ENTER(
"ha_tina::delete_row");
1094 ha_statistic_increment(&SSV::ha_delete_count);
1101 DBUG_ASSERT(share->rows_recorded);
1103 share->rows_recorded--;
1107 DBUG_ASSERT(!share->is_log_table);
1126 int ha_tina::init_data_file()
1128 if (local_data_file_version != share->data_file_version)
1130 local_data_file_version= share->data_file_version;
1133 share->data_file_name, O_RDONLY,
1134 MYF(MY_WME))) == -1)
1135 return my_errno ? my_errno : -1;
1137 file_buff->init_buff(data_file);
1175 DBUG_ENTER(
"ha_tina::rnd_init");
1178 if (share->crashed || init_data_file())
1179 DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
1181 current_position= next_position= 0;
1183 records_is_known= 0;
1206 DBUG_ENTER(
"ha_tina::rnd_next");
1207 MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
1212 rc= HA_ERR_CRASHED_ON_USAGE;
1216 ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1218 current_position= next_position;
1221 if (!local_saved_data_file_length)
1223 rc= HA_ERR_END_OF_FILE;
1227 if ((rc= find_current_row(buf)))
1233 MYSQL_READ_ROW_DONE(rc);
1246 void ha_tina::position(
const uchar *
record)
1248 DBUG_ENTER(
"ha_tina::position");
1249 my_store_ptr(ref,
ref_length, current_position);
1262 DBUG_ENTER(
"ha_tina::rnd_pos");
1263 MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
1265 ha_statistic_increment(&SSV::ha_read_rnd_count);
1266 current_position= my_get_ptr(pos,
ref_length);
1267 rc= find_current_row(buf);
1268 MYSQL_READ_ROW_DONE(rc);
1277 int ha_tina::info(uint flag)
1279 DBUG_ENTER(
"ha_tina::info");
1281 if (!records_is_known &&
stats.records < 2)
1291 int ha_tina::extra(
enum ha_extra_function operation)
1293 DBUG_ENTER(
"ha_tina::extra");
1294 if (operation == HA_EXTRA_MARK_AS_LOG_TABLE)
1297 share->is_log_table= TRUE;
1309 bool ha_tina::get_write_pos(my_off_t *end_pos,
tina_set *closest_hole)
1311 if (closest_hole == chain_ptr)
1312 *end_pos= file_buff->end();
1314 *end_pos= min(file_buff->end(), closest_hole->begin);
1315 return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
1325 int ha_tina::rnd_end()
1327 char updated_fname[FN_REFLEN];
1328 my_off_t file_buffer_start= 0;
1329 DBUG_ENTER(
"ha_tina::rnd_end");
1331 free_root(&blobroot, MYF(0));
1332 records_is_known= 1;
1334 if ((chain_ptr - chain) > 0)
1342 file_buff->init_buff(data_file);
1348 my_qsort(chain, (
size_t)(chain_ptr - chain),
sizeof(
tina_set),
1349 (qsort_cmp)sort_set);
1351 my_off_t write_begin= 0, write_end;
1354 if (open_update_temp_file_if_needed())
1358 while ((file_buffer_start != (my_off_t)-1))
1360 bool in_hole= get_write_pos(&write_end, ptr);
1361 my_off_t write_length= write_end - write_begin;
1367 (uchar*) (file_buff->ptr() +
1368 (write_begin - file_buff->start())),
1369 (size_t)write_length, MYF_RW))
1371 temp_file_length+= write_length;
1376 while (file_buff->end() <= ptr->end &&
1377 file_buffer_start != (my_off_t)-1)
1378 file_buffer_start= file_buff->read_next();
1379 write_begin= ptr->end;
1383 write_begin= write_end;
1385 if (write_end == file_buff->end())
1386 file_buffer_start= file_buff->read_next();
1394 share->update_file_opened= FALSE;
1396 if (share->tina_write_opened)
1404 share->tina_write_opened= FALSE;
1413 fn_format(updated_fname, share->table_name,
1415 MY_REPLACE_EXT | MY_UNPACK_FILENAME),
1416 share->data_file_name, MYF(0)))
1421 share->data_file_name,
1422 O_RDONLY, MYF(MY_WME))) == -1)
1423 DBUG_RETURN(my_errno ? my_errno : -1);
1432 share->data_file_version++;
1433 local_data_file_version= share->data_file_version;
1439 (void)write_meta_file(share->meta_file, share->rows_recorded, FALSE);
1444 local_saved_data_file_length= temp_file_length;
1450 share->update_file_opened= FALSE;
1475 char repaired_fname[FN_REFLEN];
1479 ha_rows rows_repaired= 0;
1480 my_off_t write_begin= 0, write_end;
1481 DBUG_ENTER(
"ha_tina::repair");
1484 if (!share->saved_data_file_length)
1486 share->rows_recorded= 0;
1491 table->use_all_columns();
1492 if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1493 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1496 if (init_data_file())
1497 DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR);
1504 local_saved_data_file_length= share->saved_data_file_length;
1506 current_position= next_position= 0;
1509 while (!(rc= find_current_row(buf)))
1511 thd_inc_row_count(thd);
1513 current_position= next_position;
1516 free_root(&blobroot, MYF(0));
1520 if (rc == HA_ERR_END_OF_FILE)
1527 share->rows_recorded= rows_repaired;
1536 fn_format(repaired_fname,
1539 MY_REPLACE_EXT|MY_UNPACK_FILENAME),
1540 0, O_RDWR | O_TRUNC, MYF(MY_WME))) < 0)
1541 DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR);
1543 file_buff->init_buff(data_file);
1547 share->rows_recorded= rows_repaired;
1552 write_end= min(file_buff->end(), current_position);
1553 if ((write_end - write_begin) &&
1555 (size_t) (write_end - write_begin), MYF_RW)))
1558 write_begin= write_end;
1559 if (write_end== current_position)
1562 file_buff->read_next();
1571 if (share->tina_write_opened)
1579 DBUG_RETURN(my_errno ? my_errno : -1);
1580 share->tina_write_opened= FALSE;
1585 repaired_fname, share->data_file_name, MYF(0)))
1590 share->data_file_name, O_RDWR|O_APPEND,
1591 MYF(MY_WME))) == -1)
1592 DBUG_RETURN(my_errno ? my_errno : -1);
1595 local_saved_data_file_length= (size_t) current_position;
1598 share->crashed= FALSE;
1599 DBUG_RETURN(HA_ADMIN_OK);
1609 DBUG_ENTER(
"ha_tina::delete_all_rows");
1611 if (!records_is_known)
1612 DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
1614 if (!share->tina_write_opened)
1615 if (init_tina_writer())
1624 share->rows_recorded= 0;
1626 local_saved_data_file_length= 0;
1636 enum thr_lock_type lock_type)
1638 if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
1639 lock.type=lock_type;
1649 int ha_tina::create(
const char *name,
TABLE *table_arg,
1652 char name_buff[FN_REFLEN];
1654 DBUG_ENTER(
"ha_tina::create");
1659 for (
Field **field= table_arg->s->field; *field; field++)
1661 if ((*field)->real_maybe_null())
1663 my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0),
"nullable columns");
1664 DBUG_RETURN(HA_ERR_UNSUPPORTED);
1670 fn_format(name_buff, name,
"", CSM_EXT,
1671 MY_REPLACE_EXT|MY_UNPACK_FILENAME),
1672 0, O_RDWR | O_TRUNC, MYF(MY_WME))) < 0)
1675 write_meta_file(create_file, 0, FALSE);
1679 fn_format(name_buff, name,
"", CSV_EXT,
1680 MY_REPLACE_EXT|MY_UNPACK_FILENAME),
1681 0, O_RDWR | O_TRUNC, MYF(MY_WME))) < 0)
1693 const char *old_proc_info;
1694 ha_rows count= share->rows_recorded;
1695 DBUG_ENTER(
"ha_tina::check");
1697 old_proc_info= thd_proc_info(thd,
"Checking table");
1698 if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1699 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1702 if (init_data_file())
1703 DBUG_RETURN(HA_ERR_CRASHED);
1710 local_saved_data_file_length= share->saved_data_file_length;
1712 current_position= next_position= 0;
1715 while (!(rc= find_current_row(buf)))
1717 thd_inc_row_count(thd);
1719 current_position= next_position;
1722 free_root(&blobroot, MYF(0));
1725 thd_proc_info(thd, old_proc_info);
1727 if ((rc != HA_ERR_END_OF_FILE) || count)
1729 share->crashed= TRUE;
1730 DBUG_RETURN(HA_ADMIN_CORRUPT);
1733 DBUG_RETURN(HA_ADMIN_OK);
1740 return COMPATIBLE_DATA_YES;
1744 { MYSQL_HANDLERTON_INTERFACE_VERSION };
1746 mysql_declare_plugin(csv)
1748 MYSQL_STORAGE_ENGINE_PLUGIN,
1749 &csv_storage_engine,
1751 "Brian Aker, MySQL AB",
1752 "CSV storage engine",
1762 mysql_declare_plugin_end;