summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorunknown <monty@mysql.com/narttu.mysql.fi>2007-01-23 21:13:26 +0200
committerunknown <monty@mysql.com/narttu.mysql.fi>2007-01-23 21:13:26 +0200
commitca42b36cc99fa0fb1d12a3150316bf3164909a07 (patch)
tree09269afde6ea92811b9a270afbfa86d3dc42dcc2 /storage
parentb635df555adec7ebdc4cd40e102d51006c802639 (diff)
parent345959c660d7401c9dc991a2c572ba145d6e199c (diff)
downloadmariadb-git-ca42b36cc99fa0fb1d12a3150316bf3164909a07.tar.gz
Merge with new version
storage/myisam/mi_rsamepos.c: Auto merged include/m_string.h: Automatic merge include/maria.h: manual merge include/my_base.h: Automatic merge include/my_sys.h: Automatic merge mysys/mf_keycache.c: Automatic merge mysys/my_pread.c: Automatic merge sql/filesort.cc: Automatic merge sql/gen_lex_hash.cc: Automatic merge sql/mysqld.cc: Automatic merge sql/uniques.cc: Automatic merge storage/maria/Makefile.am: manual_merge storage/maria/ha_maria.cc: Automatic merge storage/maria/ma_check.c: manual merge storage/maria/ma_close.c: manual merge storage/maria/ma_create.c: manual merge storage/maria/ma_delete.c: manual merge storage/maria/ma_delete_all.c: Automatic merge storage/maria/ma_dynrec.c: manual merge storage/maria/ma_extra.c: Automatic merge storage/maria/ma_ft_boolean_search.c: manual merge storage/maria/ma_init.c: Automatic merge storage/maria/ma_key.c: manual merge storage/maria/ma_keycache.c: manual merge storage/maria/ma_locking.c: Automatic merge storage/maria/ma_open.c: manual merge storage/maria/ma_packrec.c: manual merge storage/maria/ma_page.c: Automatic merge storage/maria/ma_range.c: Automatic merge storage/maria/ma_rkey.c: manual merge storage/maria/ma_rsamepos.c: manual merge storage/maria/ma_sort.c: manual merge storage/maria/ma_statrec.c: Automatic merge storage/maria/ma_test2.c: Automatic merge storage/maria/ma_test3.c: Automatic merge storage/maria/ma_test_all.sh: Use new version storage/maria/ma_unique.c: Automatic merge storage/maria/ma_update.c: Automatic merge storage/maria/ma_write.c: manual merge storage/maria/maria_chk.c: manual merge storage/maria/maria_def.h: manual merge Added length pointer to _ma_page_get_block_info() storage/maria/maria_ftdump.c: Automatic merge storage/maria/maria_pack.c: manual merge storage/myisam/mi_check.c: Automatic merge storage/myisam/mi_create.c: Automatic merge storage/myisam/mi_test2.c: Automatic merge storage/myisam/sort.c: Automatic merge
Diffstat (limited to 'storage')
-rw-r--r--storage/maria/Makefile.am3
-rw-r--r--storage/maria/ha_maria.cc69
-rw-r--r--storage/maria/ma_bitmap.c1704
-rw-r--r--storage/maria/ma_blockrec.c2742
-rw-r--r--storage/maria/ma_blockrec.h160
-rw-r--r--storage/maria/ma_check.c1753
-rw-r--r--storage/maria/ma_checksum.c25
-rw-r--r--storage/maria/ma_close.c27
-rw-r--r--storage/maria/ma_create.c461
-rw-r--r--storage/maria/ma_dbug.c6
-rw-r--r--storage/maria/ma_delete.c200
-rw-r--r--storage/maria/ma_delete_all.c3
-rw-r--r--storage/maria/ma_dynrec.c258
-rw-r--r--storage/maria/ma_extra.c34
-rw-r--r--storage/maria/ma_ft_boolean_search.c36
-rw-r--r--storage/maria/ma_ft_nlq_search.c35
-rw-r--r--storage/maria/ma_ft_update.c23
-rw-r--r--storage/maria/ma_fulltext.h2
-rw-r--r--storage/maria/ma_info.c22
-rw-r--r--storage/maria/ma_init.c2
-rw-r--r--storage/maria/ma_key.c68
-rw-r--r--storage/maria/ma_keycache.c5
-rw-r--r--storage/maria/ma_locking.c53
-rw-r--r--storage/maria/ma_open.c653
-rw-r--r--storage/maria/ma_packrec.c302
-rw-r--r--storage/maria/ma_page.c35
-rw-r--r--storage/maria/ma_range.c37
-rw-r--r--storage/maria/ma_rfirst.c2
-rw-r--r--storage/maria/ma_rkey.c48
-rw-r--r--storage/maria/ma_rlast.c2
-rw-r--r--storage/maria/ma_rnext.c9
-rw-r--r--storage/maria/ma_rnext_same.c33
-rw-r--r--storage/maria/ma_rprev.c9
-rw-r--r--storage/maria/ma_rrnd.c34
-rw-r--r--storage/maria/ma_rsame.c26
-rw-r--r--storage/maria/ma_rsamepos.c11
-rw-r--r--storage/maria/ma_rt_index.c266
-rw-r--r--storage/maria/ma_rt_index.h17
-rw-r--r--storage/maria/ma_rt_key.c12
-rw-r--r--storage/maria/ma_rt_key.h12
-rw-r--r--storage/maria/ma_rt_mbr.c34
-rw-r--r--storage/maria/ma_rt_mbr.h29
-rw-r--r--storage/maria/ma_rt_split.c15
-rw-r--r--storage/maria/ma_rt_test.c9
-rw-r--r--storage/maria/ma_scan.c33
-rw-r--r--storage/maria/ma_search.c351
-rw-r--r--storage/maria/ma_sort.c142
-rw-r--r--storage/maria/ma_sp_defs.h2
-rw-r--r--storage/maria/ma_sp_key.c2
-rw-r--r--storage/maria/ma_sp_test.c9
-rw-r--r--storage/maria/ma_static.c12
-rw-r--r--storage/maria/ma_statrec.c74
-rw-r--r--storage/maria/ma_test1.c162
-rw-r--r--storage/maria/ma_test2.c122
-rw-r--r--storage/maria/ma_test3.c4
-rwxr-xr-xstorage/maria/ma_test_all.sh288
-rw-r--r--storage/maria/ma_unique.c30
-rw-r--r--storage/maria/ma_update.c37
-rw-r--r--storage/maria/ma_write.c210
-rw-r--r--storage/maria/maria_chk.c194
-rw-r--r--storage/maria/maria_def.h472
-rw-r--r--storage/maria/maria_ftdump.c6
-rw-r--r--storage/maria/maria_pack.c94
-rw-r--r--storage/myisam/mi_check.c63
-rw-r--r--storage/myisam/mi_create.c10
-rw-r--r--storage/myisam/mi_test2.c2
-rw-r--r--storage/myisam/sort.c10
67 files changed, 8708 insertions, 2907 deletions
diff --git a/storage/maria/Makefile.am b/storage/maria/Makefile.am
index 24636f139ab..d7a5fa97eee 100644
--- a/storage/maria/Makefile.am
+++ b/storage/maria/Makefile.am
@@ -54,7 +54,7 @@ noinst_PROGRAMS = ma_test1 ma_test2 ma_test3 ma_rt_test ma_sp_test
noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \
ma_sp_defs.h ma_fulltext.h ma_ftdefs.h ma_ft_test1.h \
ma_ft_eval.h trnman.h lockman.h tablockman.h \
- ma_control_file.h ha_maria.h
+ ma_control_file.h ha_maria.h ma_blockrec.h
ma_test1_DEPENDENCIES= $(LIBRARIES)
ma_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \
$(top_builddir)/storage/myisam/libmyisam.a \
@@ -98,6 +98,7 @@ libmaria_a_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \
ma_search.c ma_page.c ma_key.c ma_locking.c \
ma_rrnd.c ma_scan.c ma_cache.c \
ma_statrec.c ma_packrec.c ma_dynrec.c \
+ ma_blockrec.c ma_bitmap.c \
ma_update.c ma_write.c ma_unique.c \
ma_delete.c \
ma_rprev.c ma_rfirst.c ma_rlast.c ma_rsame.c \
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 13f468b41aa..102f987f01a 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -229,10 +229,10 @@ int ha_maria::dump(THD * thd, int fd)
{
MARIA_SHARE *share= file->s;
NET *net= &thd->net;
- uint blocksize= share->blocksize;
+ uint block_size= share->block_size;
my_off_t bytes_to_read= share->state.state.data_file_length;
int data_fd= file->dfile;
- byte *buf= (byte *) my_malloc(blocksize, MYF(MY_WME));
+ byte *buf= (byte *) my_malloc(block_size, MYF(MY_WME));
if (!buf)
return ENOMEM;
@@ -240,7 +240,7 @@ int ha_maria::dump(THD * thd, int fd)
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
for (; bytes_to_read > 0;)
{
- uint bytes= my_read(data_fd, buf, blocksize, MYF(MY_WME));
+ uint bytes= my_read(data_fd, buf, block_size, MYF(MY_WME));
if (bytes == MY_FILE_ERROR)
{
error= errno;
@@ -386,7 +386,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
const char *old_proc_info= thd->proc_info;
thd->proc_info= "Checking table";
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "check";
param.db_name= table->s->db.str;
@@ -476,7 +476,7 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
HA_CHECK param;
MARIA_SHARE *share= file->s;
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "analyze";
param.db_name= table->s->db.str;
@@ -535,7 +535,7 @@ int ha_maria::restore(THD * thd, HA_CHECK_OPT *check_opt)
err:
{
HA_CHECK param;
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "restore";
param.db_name= table->s->db.str;
@@ -598,7 +598,7 @@ int ha_maria::backup(THD * thd, HA_CHECK_OPT *check_opt)
err:
{
HA_CHECK param;
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "backup";
param.db_name= table->s->db.str;
@@ -619,7 +619,7 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
if (!file)
return HA_ADMIN_INTERNAL_ERROR;
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "repair";
param.testflag= ((check_opt->flags & ~(T_EXTEND)) |
@@ -667,7 +667,7 @@ int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
return HA_ADMIN_INTERNAL_ERROR;
HA_CHECK param;
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "optimize";
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
@@ -862,7 +862,7 @@ err:
{
/* Send error to user */
HA_CHECK param;
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "assign_to_keycache";
param.db_name= table->s->db.str;
@@ -930,7 +930,7 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
err:
{
HA_CHECK param;
- mariachk_init(&param);
+ maria_chk_init(&param);
param.thd= thd;
param.op_name= "preload_keys";
param.db_name= table->s->db.str;
@@ -1039,7 +1039,7 @@ int ha_maria::enable_indexes(uint mode)
HA_CHECK param;
const char *save_proc_info= thd->proc_info;
thd->proc_info= "Creating index";
- mariachk_init(&param);
+ maria_chk_init(&param);
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
T_CREATE_MISSING_KEYS);
@@ -1424,7 +1424,7 @@ int ha_maria::info(uint flag)
if (flag & HA_STATUS_ERRKEY)
{
errkey= info.errkey;
- my_store_ptr(dup_ref, ref_length, info.dupp_key_pos);
+ my_store_ptr(dup_ref, ref_length, info.dup_key_pos);
}
/* Faster to always update, than to do it based on flag */
stats.update_time= info.update_time;
@@ -1514,6 +1514,7 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
HA_KEYSEG *keyseg;
TABLE_SHARE *share= table_arg->s;
uint options= share->db_options_in_use;
+ enum data_file_type row_type;
DBUG_ENTER("ha_maria::create");
type= HA_KEYTYPE_BINARY; // Keep compiler happy
@@ -1641,27 +1642,27 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
if (recpos != minpos)
{ // Reserved space (Null bits?)
bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
- recinfo_pos->type= (int) FIELD_NORMAL;
+ recinfo_pos->type= FIELD_NORMAL;
recinfo_pos++->length= (uint16) (minpos - recpos);
}
if (!found)
break;
if (found->flags & BLOB_FLAG)
- recinfo_pos->type= (int) FIELD_BLOB;
+ recinfo_pos->type= FIELD_BLOB;
else if (found->type() == MYSQL_TYPE_VARCHAR)
recinfo_pos->type= FIELD_VARCHAR;
else if (!(options & HA_OPTION_PACK_RECORD))
- recinfo_pos->type= (int) FIELD_NORMAL;
+ recinfo_pos->type= FIELD_NORMAL;
else if (found->zero_pack())
- recinfo_pos->type= (int) FIELD_SKIP_ZERO;
+ recinfo_pos->type= FIELD_SKIP_ZERO;
else
- recinfo_pos->type= (int) ((length <= 3 ||
- (found->flags & ZEROFILL_FLAG)) ?
- FIELD_NORMAL :
- found->type() == MYSQL_TYPE_STRING ||
- found->type() == MYSQL_TYPE_VAR_STRING ?
- FIELD_SKIP_ENDSPACE : FIELD_SKIP_PRESPACE);
+ recinfo_pos->type= ((length <= 3 ||
+ (found->flags & ZEROFILL_FLAG)) ?
+ FIELD_NORMAL :
+ found->type() == MYSQL_TYPE_STRING ||
+ found->type() == MYSQL_TYPE_VAR_STRING ?
+ FIELD_SKIP_ENDSPACE : FIELD_SKIP_PRESPACE);
if (found->null_ptr)
{
recinfo_pos->null_bit= found->null_bit;
@@ -1700,12 +1701,26 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
if (options & HA_OPTION_DELAY_KEY_WRITE)
create_flags |= HA_CREATE_DELAY_KEY_WRITE;
+ switch (info->row_type) {
+ case ROW_TYPE_FIXED:
+ row_type= STATIC_RECORD;
+ break;
+ case ROW_TYPE_DYNAMIC:
+ row_type= DYNAMIC_RECORD;
+ break;
+ default:
+ case ROW_TYPE_PAGES:
+ row_type= BLOCK_RECORD;
+ break;
+ }
+
/* TODO: Check that the following fn_format is really needed */
error=
- maria_create(fn_format
- (buff, name, "", "", MY_UNPACK_FILENAME | MY_APPEND_EXT),
- share->keys, keydef, (uint) (recinfo_pos - recinfo), recinfo,
- 0, (MARIA_UNIQUEDEF *) 0, &create_info, create_flags);
+ maria_create(fn_format(buff, name, "", "",
+ MY_UNPACK_FILENAME | MY_APPEND_EXT),
+ row_type, share->keys, keydef, (uint) (recinfo_pos - recinfo),
+ recinfo, 0, (MARIA_UNIQUEDEF *) 0, &create_info,
+ create_flags);
my_free((gptr) recinfo, MYF(0));
DBUG_RETURN(error);
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
new file mode 100644
index 00000000000..5ed5a776658
--- /dev/null
+++ b/storage/maria/ma_bitmap.c
@@ -0,0 +1,1704 @@
+/* Copyright (C) 2007 Michael Widenius
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Bitmap handling (for records in block)
+
+ The data file starts with a bitmap page, followed by as many data
+ pages as the bitmap can cover. After this there is a new bitmap page
+ and more data pages etc.
+
+ The bitmap code assumes there is always an active bitmap page and thus
+ that there is at least one bitmap page in the file
+
+ Structure of bitmap page:
+
+ Fixed size records (to be implemented later):
+
+ 2 bits are used to indicate:
+
+ 0 Empty
+ 1 50-75 % full (at least room for 2 records)
+ 2 75-100 % full (at least room for one record)
+ 3 100 % full (no more room for records)
+
+ Assuming 8K pages, this will allow us to map:
+ 8192 (bytes per page) * 4 (pages mapped per byte) * 8192 (page size)= 256M
+
+ (For Maria this will be 7*4 * 8192 = 224K smaller because of LSN)
+
+ Note that for fixed size rows, we can't add more columns without doing
+ a full reorganization of the table. The user can always force a dynamic
+ size row format by specifying ROW_FORMAT=dynamic.
+
+
+ Dynamic size records:
+
+ 3 bits are used to indicate
+
+ 0 Empty page
+ 1 0-30 % full (at least room for 3 records)
+ 2 30-60 % full (at least room for 2 records)
+ 3 60-90 % full (at least room for one record)
+ 4 100 % full (no more room for records)
+ 5 Tail page, 0-40 % full
+ 6 Tail page, 40-80 % full
+ 7 Full tail page or full blob page
+
+ Assuming 8K pages, this will allow us to map:
+ 8192 (bytes per page) * 8 bits/byte / 3 bits/page * 8192 (page size)= 170.7M
+
+ Note that values 1-3 may be adjust for each individual table based on
+ 'min record length'. Tail pages are for overflow data which can be of
+ any size and thus doesn't have to be adjusted for different tables.
+ If we add more columns to the table, some of the originally calculated
+ 'cut off' points may not be optimal, but they shouldn't be 'drasticly
+ wrong'.
+
+ When allocating data from the bitmap, we are trying to do it in a
+ 'best fit' manner. Blobs and varchar blocks are given out in large
+ continuous extents to allow fast access to these. Before allowing a
+ row to 'flow over' to other blocks, we will compact the page and use
+ all space on it. If there is many rows in the page, we will ensure
+ there is *LEFT_TO_GROW_ON_SPLIT* bytes left on the page to allow other
+ rows to grow.
+
+ The bitmap format allows us to extend the row file in big chunks, if needed.
+
+ When calculating the size for a packed row, we will calculate the following
+ things separately:
+ - Row header + null_bits + empty_bits fixed size segments etc.
+ - Size of all char/varchar fields
+ - Size of each blob field
+
+ The bitmap handler will get all the above information and return
+ either one page or a set of pages to put the different parts.
+
+ Bitmaps are read on demand in response to insert/delete/update operations.
+ The following bitmap pointers will be cached and stored on disk on close:
+ - Current insert_bitmap; When inserting new data we will first try to
+ fill this one.
+ - First bitmap which is not completely full. This is updated when we
+ free data with an update or delete.
+
+ While flushing out bitmaps, we will cache the status of the bitmap in memory
+ to avoid having to read a bitmap for insert of new data that will not
+ be of any use
+ - Total empty space
+ - Largest number of continuous pages
+
+ Bitmap ONLY goes to disk in the following scenarios
+ - The file is closed (and we flush all changes to disk)
+ - On checkpoint
+ (Ie: When we do a checkpoint, we have to ensure that all bitmaps are
+ put on disk even if they are not in the page cache).
+ - When explicitely requested (for example on backup or after recvoery,
+ to simplify things)
+
+*/
+
+#include "maria_def.h"
+#include "ma_blockrec.h"
+
+/* Number of pages to store blob parts */
+#define BLOB_SEGMENT_MIN_SIZE 128
+
+#define FULL_HEAD_PAGE 4
+#define FULL_TAIL_PAGE 7
+
+static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
+ MARIA_FILE_BITMAP *bitmap)
+{
+ return (key_cache_write(share->key_cache,
+ bitmap->file, bitmap->page * bitmap->block_size, 0,
+ (byte*) bitmap->map,
+ bitmap->block_size, bitmap->block_size, 1));
+}
+
+/*
+ Initialize bitmap. This is called the first time a file is opened
+*/
+
+my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
+{
+ uint aligned_bit_blocks;
+ uint max_page_size;
+ MARIA_FILE_BITMAP *bitmap= &share->bitmap;
+ uint size= share->block_size;
+#ifndef DBUG_OFF
+ /* We want to have a copy of the bitmap to be able to print differences */
+ size*= 2;
+#endif
+
+ if (!(bitmap->map= (uchar*) my_malloc(size, MYF(MY_WME))))
+ return 1;
+
+ bitmap->file= file;
+ bitmap->changed= 0;
+ bitmap->block_size= share->block_size;
+ /* Size needs to be alligned on 6 */
+ aligned_bit_blocks= share->block_size / 6;
+ bitmap->total_size= aligned_bit_blocks * 6;
+ /*
+ In each 6 bytes, we have 6*8/3 = 16 pages covered
+ The +1 is to add the bitmap page, as this doesn't have to be covered
+ */
+ bitmap->pages_covered= aligned_bit_blocks * 16 + 1;
+
+ /* Update size for bits */
+ /* TODO; Make this dependent of the row size */
+ max_page_size= share->block_size - PAGE_OVERHEAD_SIZE;
+ bitmap->sizes[0]= max_page_size; /* Empty page */
+ bitmap->sizes[1]= max_page_size - max_page_size * 30 / 100;
+ bitmap->sizes[2]= max_page_size - max_page_size * 60 / 100;
+ bitmap->sizes[3]= max_page_size - max_page_size * 90 / 100;
+ bitmap->sizes[4]= 0; /* Full page */
+ bitmap->sizes[5]= max_page_size - max_page_size * 40 / 100;
+ bitmap->sizes[6]= max_page_size - max_page_size * 80 / 100;
+ bitmap->sizes[7]= 0;
+
+ pthread_mutex_init(&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW);
+
+ /*
+ Start by reading first page (assume table scan)
+ Later code is simpler if it can assume we always have an active bitmap.
+ */
+ if (_ma_read_bitmap_page(share, bitmap, (ulonglong) 0))
+ return(1);
+ return 0;
+}
+
+
+/*
+ Free data allocated by _ma_bitmap_init
+*/
+
+my_bool _ma_bitmap_end(MARIA_SHARE *share)
+{
+ my_bool res= 0;
+ _ma_flush_bitmap(share);
+ pthread_mutex_destroy(&share->bitmap.bitmap_lock);
+ my_free((byte*) share->bitmap.map, MYF(MY_ALLOW_ZERO_PTR));
+ return res;
+}
+
+
+/*
+ Flush bitmap to disk
+*/
+
+my_bool _ma_flush_bitmap(MARIA_SHARE *share)
+{
+ my_bool res= 0;
+ if (share->bitmap.changed)
+ {
+ pthread_mutex_lock(&share->bitmap.bitmap_lock);
+ if (share->bitmap.changed)
+ {
+ res= write_changed_bitmap(share, &share->bitmap);
+ share->bitmap.changed= 0;
+ }
+ pthread_mutex_unlock(&share->bitmap.bitmap_lock);
+ }
+ return res;
+}
+
+
+/*
+ Return bitmap pattern for the smallest head block that can hold 'size'
+
+ SYNOPSIS
+ size_to_head_pattern()
+ bitmap Bitmap
+ size Requested size
+
+ RETURN
+ 0-3 For a description of the bitmap sizes, see the header
+*/
+
+static uint size_to_head_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
+{
+ if (size <= bitmap->sizes[3])
+ return 3;
+ if (size <= bitmap->sizes[2])
+ return 2;
+ if (size <= bitmap->sizes[1])
+ return 1;
+ DBUG_ASSERT(size <= bitmap->sizes[0]);
+ return 0;
+}
+
+
+/*
+ Return bitmap pattern for block where there is size bytes free
+*/
+
+uint _ma_free_size_to_head_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
+{
+ if (size < bitmap->sizes[3])
+ return 4;
+ if (size < bitmap->sizes[2])
+ return 3;
+ if (size < bitmap->sizes[1])
+ return 2;
+ return (size < bitmap->sizes[0]) ? 1 : 0;
+}
+
+
+/*
+ Return bitmap pattern for the smallest tail block that can hold 'size'
+
+ SYNOPSIS
+ size_to_tail_pattern()
+ bitmap Bitmap
+ size Requested size
+
+ RETURN
+ 0, 5 or 6 For a description of the bitmap sizes, see the header
+*/
+
+static uint size_to_tail_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
+{
+ if (size <= bitmap->sizes[6])
+ return 6;
+ if (size <= bitmap->sizes[5])
+ return 5;
+ DBUG_ASSERT(size <= bitmap->sizes[0]);
+ return 0;
+}
+
+
+static uint free_size_to_tail_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
+{
+ if (size >= bitmap->sizes[0])
+ return 0; /* Revert to empty page */
+ if (size < bitmap->sizes[6])
+ return 7;
+ if (size < bitmap->sizes[5])
+ return 6;
+ return 5;
+}
+
+
+/*
+ Return size guranteed to be available on a page
+
+ SYNOPSIS
+ pattern_to_head_size
+ bitmap Bitmap
+ pattern Pattern (0-7)
+
+ RETURN
+ 0 - block_size
+*/
+
+static inline uint pattern_to_size(MARIA_FILE_BITMAP *bitmap, uint pattern)
+{
+ DBUG_ASSERT(pattern <= 7);
+ return bitmap->sizes[pattern];
+}
+
+
+/*
+ Print bitmap for debugging
+*/
+
+#ifndef DBUG_OFF
+
+const char *bits_to_txt[]=
+{
+ "empty", "00-30% full", "30-60% full", "60-90% full", "full",
+ "tail 00-40 % full", "tail 40-80 % full", "tail/blob full"
+};
+
+static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap)
+{
+ uchar *pos, *end, *org_pos;
+ ulong page;
+
+ end= bitmap->map+ bitmap->used_size;
+ DBUG_LOCK_FILE;
+ fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
+ (ulong) bitmap->page);
+
+ page= (ulong) bitmap->page+1;
+ for (pos= bitmap->map, org_pos= bitmap->map+bitmap->block_size ; pos < end ;
+ pos+= 6, org_pos+= 6)
+ {
+ ulonglong bits= uint6korr(pos); /* 6 bytes = 6*8/3= 16 patterns */
+ ulonglong org_bits= uint6korr(org_pos);
+ uint i;
+ if (bits != org_bits)
+ {
+ for (i= 0; i < 16 ; i++, bits>>= 3, org_bits>>= 3)
+ {
+ if ((bits & 7) != (org_bits & 7))
+ fprintf(DBUG_FILE, "Page: %8lu %s -> %s\n", page+i,
+ bits_to_txt[org_bits & 7], bits_to_txt[bits & 7]);
+ }
+ }
+ page+= 16;
+ }
+ fputc('\n', DBUG_FILE);
+ DBUG_UNLOCK_FILE;
+ memcpy(bitmap->map+ bitmap->block_size, bitmap->map, bitmap->block_size);
+}
+
+#endif /* DBUG_OFF */
+
+
+/***************************************************************************
+ Reading & writing bitmap pages
+***************************************************************************/
+
+/*
+ Read a given bitmap page
+
+ SYNOPSIS
+ read_bitmap_page()
+ info Maria handler
+ bitmap Bitmap handler
+ page Page to read
+
+ TODO
+ Update 'bitmap->used_size' to real size of used bitmap
+
+ RETURN
+ 0 ok
+ 1 error (Error writing old bitmap or reading bitmap page)
+*/
+
+my_bool _ma_read_bitmap_page(MARIA_SHARE *share, MARIA_FILE_BITMAP *bitmap,
+ ulonglong page)
+{
+ my_off_t position= page * bitmap->block_size;
+ my_bool res;
+ DBUG_ENTER("_ma_read_bitmap_page");
+ DBUG_ASSERT(page % bitmap->pages_covered == 0);
+
+ bitmap->page= page;
+ if (position >= share->state.state.data_file_length)
+ {
+ share->state.state.data_file_length= position + bitmap->block_size;
+ bzero(bitmap->map, bitmap->block_size);
+ bitmap->used_size= 0;
+ DBUG_RETURN(0);
+ }
+ bitmap->used_size= bitmap->total_size;
+ res= key_cache_read(share->key_cache,
+ bitmap->file, position, 0,
+ (byte*) bitmap->map,
+ bitmap->block_size, bitmap->block_size, 0) == 0;
+#ifndef DBUG_OFF
+ if (!res)
+ memcpy(bitmap->map+ bitmap->block_size, bitmap->map, bitmap->block_size);
+#endif
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Change to another bitmap page
+
+ SYNOPSIS
+ _ma_change_bitmap_page()
+ info Maria handler
+ bitmap Bitmap handler
+ page Bitmap page to read
+
+ NOTES
+ If old bitmap was changed, write it out before reading new one
+ We return empty bitmap if page is outside of file size
+
+ RETURN
+ 0 ok
+ 1 error (Error writing old bitmap or reading bitmap page)
+*/
+
+static my_bool _ma_change_bitmap_page(MARIA_HA *info,
+ MARIA_FILE_BITMAP *bitmap,
+ ulonglong page)
+{
+ DBUG_ENTER("_ma_change_bitmap_page");
+ DBUG_ASSERT(page % bitmap->pages_covered == 0);
+
+ if (bitmap->changed)
+ {
+ if (write_changed_bitmap(info->s, bitmap))
+ DBUG_RETURN(1);
+ bitmap->changed= 0;
+ }
+ DBUG_RETURN(_ma_read_bitmap_page(info->s, bitmap, page));
+}
+
+
+/*
+ Read next suitable bitmap
+
+ SYNOPSIS
+ move_to_next_bitmap()
+ bitmap Bitmap handle
+
+ TODO
+ Add cache of bitmaps to not read something that is not usable
+
+ RETURN
+ 0 ok
+ 1 error (either couldn't save old bitmap or read new one
+*/
+
+static my_bool move_to_next_bitmap(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap)
+{
+ ulonglong page= bitmap->page;
+ MARIA_STATE_INFO *state= &info->s->state;
+ DBUG_ENTER("move_to_next_bitmap");
+
+ if (state->first_bitmap_with_space != ~(ulonglong) 0 &&
+ state->first_bitmap_with_space != page)
+ {
+ page= state->first_bitmap_with_space;
+ state->first_bitmap_with_space= ~(ulonglong) 0;
+ }
+ else
+ page+= bitmap->pages_covered;
+ DBUG_RETURN(_ma_change_bitmap_page(info, bitmap, page));
+}
+
+
+/****************************************************************************
+ Allocate data in bitmaps
+****************************************************************************/
+
+/*
+ Store data in 'block' and mark the place used in the bitmap
+
+ SYNOPSIS
+ fill_block()
+ bitmap Bitmap handle
+ block Store data about what we found
+ best_data Pointer to best 6 byte aligned area in bitmap->map
+ best_pos Which bit in *best_data the area starts
+ 0 = first bit pattern, 1 second bit pattern etc
+ fill_pattern Bitmap pattern to store in best_data[best_pos]
+*/
+
+static void fill_block(MARIA_FILE_BITMAP *bitmap,
+ MARIA_BITMAP_BLOCK *block,
+ uchar *best_data, uint best_pos, uint best_bits,
+ uint fill_pattern)
+{
+ uint page, offset, tmp;
+ uchar *data;
+
+ /* For each 6 bytes we have 6*8/3= 16 patterns */
+ page= (best_data - bitmap->map) / 6 * 16 + best_pos;
+ block->page= bitmap->page + 1 + page;
+ block->page_count= 1 + TAIL_BIT;
+ block->empty_space= pattern_to_size(bitmap, best_bits);
+ block->sub_blocks= 1;
+ block->org_bitmap_value= best_bits;
+ block->used= BLOCKUSED_TAIL;
+
+ /*
+ Mark place used by reading/writing 2 bytes at a time to handle
+ bitmaps in overlapping bytes
+ */
+ best_pos*= 3;
+ data= best_data+ best_pos / 8;
+ offset= best_pos & 7;
+ tmp= uint2korr(data);
+ tmp= (tmp & ~(7 << offset)) | (fill_pattern << offset);
+ int2store(data, tmp);
+ bitmap->changed= 1;
+ DBUG_EXECUTE("bitmap", _ma_print_bitmap(bitmap););
+}
+
+
+/*
+ Allocate data for head block
+
+ SYNOPSIS
+ allocate_head()
+ bitmap bitmap
+ size Size of block we need to find
+ block Store found information here
+
+ RETURN
+ 0 ok (block is updated)
+ 1 error (no space in bitmap; block is not touched)
+*/
+
+
+static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
+ MARIA_BITMAP_BLOCK *block)
+{
+ uint min_bits= size_to_head_pattern(bitmap, size);
+ uchar *data= bitmap->map, *end= data + bitmap->used_size;
+ uchar *best_data= 0;
+ uint best_bits= (uint) -1, best_pos;
+ DBUG_ENTER("allocate_head");
+
+ LINT_INIT(best_pos);
+ DBUG_ASSERT(size <= FULL_PAGE_SIZE(bitmap->block_size));
+
+ for (; data < end; data += 6)
+ {
+ ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
+ uint i;
+
+ /*
+ Skip common patterns
+ We can skip empty pages (if we already found a match) or
+ anything matching the following pattern as this will be either
+ a full page or a tail page
+ */
+ if ((!bits && best_data) ||
+ ((bits & LL(04444444444444444)) == LL(04444444444444444)))
+ continue;
+ for (i= 0; i < 16 ; i++, bits >>= 3)
+ {
+ uint pattern= bits & 7;
+ if (pattern <= min_bits)
+ {
+ if (pattern == min_bits)
+ {
+ /* Found perfect match */
+ best_bits= min_bits;
+ best_data= data;
+ best_pos= i;
+ goto found;
+ }
+ if ((int) pattern > (int) best_bits)
+ {
+ best_bits= pattern;
+ best_data= data;
+ best_pos= i;
+ }
+ }
+ }
+ }
+ if (!best_data)
+ {
+ if (bitmap->used_size == bitmap->total_size)
+ DBUG_RETURN(1);
+ /* Allocate data at end of bitmap */
+ bitmap->used_size+= 6;
+ best_data= data;
+ best_pos= best_bits= 0;
+ }
+
+found:
+ fill_block(bitmap, block, best_data, best_pos, best_bits, FULL_HEAD_PAGE);
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Allocate data for tail block
+
+ SYNOPSIS
+ allocate_tail()
+ bitmap bitmap
+ size Size of block we need to find
+ block Store found information here
+
+ RETURN
+ 0 ok (block is updated)
+ 1 error (no space in bitmap; block is not touched)
+*/
+
+
+static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
+ MARIA_BITMAP_BLOCK *block)
+{
+ uint min_bits= size_to_tail_pattern(bitmap, size);
+ uchar *data= bitmap->map, *end= data + bitmap->used_size;
+ uchar *best_data= 0;
+ uint best_bits= (uint) -1, best_pos;
+ DBUG_ENTER("allocate_tail");
+ DBUG_PRINT("enter", ("size: %u", size));
+
+ LINT_INIT(best_pos);
+ DBUG_ASSERT(size <= FULL_PAGE_SIZE(bitmap->block_size));
+
+ for (; data < end; data += 6)
+ {
+ ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
+ uint i;
+
+ /*
+ Skip common patterns
+ We can skip empty pages (if we already found a match) or
+ the following patterns: 1-4 or 7
+ */
+
+ if ((!bits && best_data) || bits == LL(0xffffffffffff))
+ continue;
+ for (i= 0; i < 16; i++, bits >>= 3)
+ {
+ uint pattern= bits & 7;
+ if (pattern <= min_bits && (!pattern || pattern >= 5))
+ {
+ if (pattern == min_bits)
+ {
+ best_bits= min_bits;
+ best_data= data;
+ best_pos= i;
+ goto found;
+ }
+ if ((int) pattern > (int) best_bits)
+ {
+ best_bits= pattern;
+ best_data= data;
+ best_pos= i;
+ }
+ }
+ }
+ }
+ if (!best_data)
+ {
+ if (bitmap->used_size == bitmap->total_size)
+ DBUG_RETURN(1);
+ /* Allocate data at end of bitmap */
+ bitmap->used_size+= 6;
+ best_pos= best_bits= 0;
+ }
+
+found:
+ fill_block(bitmap, block, best_data, best_pos, best_bits, FULL_TAIL_PAGE);
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Allocate data for full blocks
+
+ SYNOPSIS
+ allocate_full_pages()
+ bitmap bitmap
+ pages_needed Total size in pages (bitmap->total_size) we would like to have
+ block Store found information here
+ full_page 1 if we are not allowed to split extent
+
+ IMPLEMENTATION
+ We will return the smallest area >= size. If there is no such
+ block, we will return the biggest area that satisfies
+ area_size >= min(BLOB_SEGMENT_MIN_SIZE*full_page_size, size)
+
+ To speed up searches, we will only consider areas that has at least 16 free
+ pages starting on an even boundary. When finding such an area, we will
+ extend it with all previous and following free pages. This will ensure
+ we don't get holes between areas
+
+ RETURN
+ # Blocks used
+ 0 error (no space in bitmap; block is not touched)
+*/
+
+static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
+ ulong pages_needed,
+ MARIA_BITMAP_BLOCK *block, my_bool full_page)
+{
+ uchar *data= bitmap->map, *data_end= data + bitmap->used_size;
+ uchar *page_end= data + bitmap->total_size;
+ uchar *best_data= 0;
+ uint min_size;
+ uint best_area_size, best_prefix_area_size, best_suffix_area_size;
+ uint page, size;
+ ulonglong best_prefix_bits;
+ DBUG_ENTER("allocate_full_pages");
+ DBUG_PRINT("enter", ("pages_needed: %lu", pages_needed));
+
+ /* Following variables are only used if best_data is set */
+ LINT_INIT(best_prefix_bits);
+ LINT_INIT(best_prefix_area_size);
+ LINT_INIT(best_suffix_area_size);
+
+ min_size= pages_needed;
+ if (!full_page && min_size > BLOB_SEGMENT_MIN_SIZE)
+ min_size= BLOB_SEGMENT_MIN_SIZE;
+ best_area_size= ~(uint) 0;
+
+ for (; data < page_end; data+= 6)
+ {
+ ulonglong bits= uint6korr(data); /* 6 bytes = 6*8/3= 16 patterns */
+ uchar *data_start;
+ ulonglong prefix_bits= 0;
+ uint area_size, prefix_area_size, suffix_area_size;
+
+ /* Find area with at least 16 free pages */
+ if (bits)
+ continue;
+ data_start= data;
+ /* Find size of area */
+ for (data+=6 ; data < data_end ; data+= 6)
+ {
+ if ((bits= uint6korr(data)))
+ break;
+ }
+ area_size= (data - data_start) / 6 * 16;
+ if (area_size >= best_area_size)
+ continue;
+ prefix_area_size= suffix_area_size= 0;
+ if (!bits)
+ {
+ /*
+ End of page; All the rest of the bits on page are part of area
+ This is needed because bitmap->used_size only covers the set bits
+ in the bitmap.
+ */
+ area_size+= (page_end - data) / 6 * 16;
+ if (area_size >= best_area_size)
+ break;
+ data= page_end;
+ }
+ else
+ {
+ /* Add bits at end of page */
+ for (; !(bits & 7); bits >>= 3)
+ suffix_area_size++;
+ area_size+= suffix_area_size;
+ }
+ if (data_start != bitmap->map)
+ {
+ /* Add bits before page */
+ bits= prefix_bits= uint6korr(data_start - 6);
+ DBUG_ASSERT(bits != 0);
+ /* 111 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 */
+ if (!(bits & LL(07000000000000000)))
+ {
+ data_start-= 6;
+ do
+ {
+ prefix_area_size++;
+ bits<<= 3;
+ } while (!(bits & LL(07000000000000000)));
+ area_size+= prefix_area_size;
+ /* Calculate offset to page from data_start */
+ prefix_area_size= 16 - prefix_area_size;
+ }
+ }
+ if (area_size >= min_size && area_size <= best_area_size)
+ {
+ best_data= data_start;
+ best_area_size= area_size;
+ best_prefix_bits= prefix_bits;
+ best_prefix_area_size= prefix_area_size;
+ best_suffix_area_size= suffix_area_size;
+
+ /* Prefer to put data in biggest possible area */
+ if (area_size <= pages_needed)
+ min_size= area_size;
+ else
+ min_size= pages_needed;
+ }
+ }
+ if (!best_data)
+ DBUG_RETURN(0); /* No room on page */
+
+ /*
+ Now allocate min(pages_needed, area_size), starting from
+ best_start + best_prefix_area_size
+ */
+ if (best_area_size > pages_needed)
+ best_area_size= pages_needed;
+
+ /* For each 6 bytes we have 6*8/3= 16 patterns */
+ page= ((best_data - bitmap->map) * 8) / 3 + best_prefix_area_size;
+ block->page= bitmap->page + 1 + page;
+ block->page_count= best_area_size;
+ block->empty_space= 0;
+ block->sub_blocks= 1;
+ block->org_bitmap_value= 0;
+ block->used= 0;
+ DBUG_PRINT("info", ("page: %lu page_count: %u",
+ (ulong) block->page, block->page_count));
+
+ if (best_prefix_area_size)
+ {
+ ulonglong tmp;
+ /* Convert offset back to bits */
+ best_prefix_area_size= 16 - best_prefix_area_size;
+ if (best_area_size < best_prefix_area_size)
+ {
+ tmp= (LL(1) << best_area_size*3) - 1;
+ best_area_size= best_prefix_area_size; /* for easy end test */
+ }
+ else
+ tmp= (LL(1) << best_prefix_area_size*3) - 1;
+ tmp<<= (16 - best_prefix_area_size) * 3;
+ DBUG_ASSERT((best_prefix_bits & tmp) == 0);
+ best_prefix_bits|= tmp;
+ int6store(best_data, best_prefix_bits);
+ if (!(best_area_size-= best_prefix_area_size))
+ {
+ DBUG_EXECUTE("bitmap", _ma_print_bitmap(bitmap););
+ DBUG_RETURN(block->page_count);
+ }
+ best_data+= 6;
+ }
+ best_area_size*= 3; /* Bits to set */
+ size= best_area_size/8; /* Bytes to set */
+ bfill(best_data, size, 255);
+ best_data+= size;
+ if ((best_area_size-= size * 8))
+ {
+ /* fill last byte */
+ *best_data|= (uchar) ((1 << best_area_size) -1);
+ best_data++;
+ }
+ if (data_end < best_data)
+ bitmap->used_size= (uint) (best_data - bitmap->map);
+ bitmap->changed= 1;
+ DBUG_EXECUTE("bitmap", _ma_print_bitmap(bitmap););
+ DBUG_RETURN(block->page_count);
+}
+
+
+/****************************************************************************
+ Find right bitmaps where to store data
+****************************************************************************/
+
+/*
+ Find right bitmap and position for head block
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+static my_bool find_head(MARIA_HA *info, uint length, uint position)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+ MARIA_BITMAP_BLOCK *block;
+ /* There is always place for head blocks in bitmap_blocks */
+ block= dynamic_element(&info->bitmap_blocks, position, MARIA_BITMAP_BLOCK *);
+
+ while (allocate_head(bitmap, length, block))
+ if (move_to_next_bitmap(info, bitmap))
+ return 1;
+ return 0;
+}
+
+
+/*
+ Find right bitmap and position for tail
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+static my_bool find_tail(MARIA_HA *info, uint length, uint position)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+ MARIA_BITMAP_BLOCK *block;
+ DBUG_ENTER("find_tail");
+
+ /* Needed, as there is no error checking in dynamic_element */
+ if (allocate_dynamic(&info->bitmap_blocks, position))
+ DBUG_RETURN(1);
+ block= dynamic_element(&info->bitmap_blocks, position, MARIA_BITMAP_BLOCK *);
+
+ while (allocate_tail(bitmap, length, block))
+ if (move_to_next_bitmap(info, bitmap))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Find right bitmap and position for full blocks in one extent
+
+ NOTES
+ This is used to allocate the main extent after the 'head' block
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+static my_bool find_mid(MARIA_HA *info, ulong pages, uint position)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+ MARIA_BITMAP_BLOCK *block;
+ block= dynamic_element(&info->bitmap_blocks, position, MARIA_BITMAP_BLOCK *);
+
+ while (allocate_full_pages(bitmap, pages, block, 1))
+ {
+ if (move_to_next_bitmap(info, bitmap))
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+ Find right bitmap and position for putting a blob
+
+ NOTES
+ The extents are stored last in info->bitmap_blocks
+
+ IMPLEMENTATION
+ Allocate all full pages for the block + optionally one tail
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+static my_bool find_blob(MARIA_HA *info, ulong length)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+ uint full_page_size= FULL_PAGE_SIZE(info->s->block_size);
+ ulong pages;
+ uint rest_length, used;
+ uint first_block_pos;
+ MARIA_BITMAP_BLOCK *first_block= 0;
+ DBUG_ENTER("find_blob");
+ DBUG_PRINT("enter", ("length: %lu", length));
+
+ pages= length / full_page_size;
+ rest_length= (uint) (length - pages * full_page_size);
+ if (rest_length >= MAX_TAIL_SIZE(info->s->block_size))
+ {
+ pages++;
+ rest_length= 0;
+ }
+
+ if (pages)
+ {
+ MARIA_BITMAP_BLOCK *block;
+ if (allocate_dynamic(&info->bitmap_blocks,
+ info->bitmap_blocks.elements +
+ pages / BLOB_SEGMENT_MIN_SIZE + 2))
+ DBUG_RETURN(1);
+ first_block_pos= info->bitmap_blocks.elements;
+ block= dynamic_element(&info->bitmap_blocks, info->bitmap_blocks.elements,
+ MARIA_BITMAP_BLOCK*);
+ first_block= block;
+ do
+ {
+ used= allocate_full_pages(bitmap,
+ (pages >= 65535 ? 65535 : (uint) pages), block,
+ 0);
+ if (!used && move_to_next_bitmap(info, bitmap))
+ DBUG_RETURN(1);
+ info->bitmap_blocks.elements++;
+ block++;
+ } while ((pages-= used) != 0);
+ }
+ if (rest_length && find_tail(info, rest_length,
+ info->bitmap_blocks.elements++))
+ DBUG_RETURN(1);
+ if (first_block)
+ first_block->sub_blocks= info->bitmap_blocks.elements - first_block_pos;
+ DBUG_RETURN(0);
+}
+
+
+static my_bool allocate_blobs(MARIA_HA *info, MARIA_ROW *row)
+{
+ ulong *length, *end;
+ uint elements;
+ /*
+ Reserve size for:
+ head block
+ one extent
+ tail block
+ */
+ elements= info->bitmap_blocks.elements;
+ for (length= row->blob_lengths, end= length + info->s->base.blobs;
+ length < end; length++)
+ {
+ if (*length && find_blob(info, *length))
+ return 1;
+ }
+ row->extents_count= (info->bitmap_blocks.elements - elements);
+ return 0;
+}
+
+
+static void use_head(MARIA_HA *info, ulonglong page, uint size,
+ uint block_position)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+ MARIA_BITMAP_BLOCK *block;
+ uchar *data;
+ uint offset, tmp, offset_page;
+
+ block= dynamic_element(&info->bitmap_blocks, block_position,
+ MARIA_BITMAP_BLOCK*);
+ block->page= page;
+ block->page_count= 1 + TAIL_BIT;
+ block->empty_space= size;
+ block->sub_blocks= 1;
+ block->used= BLOCKUSED_TAIL;
+
+ /*
+ Mark place used by reading/writing 2 bytes at a time to handle
+ bitmaps in overlapping bytes
+ */
+ offset_page= (uint) (page - bitmap->page - 1) * 3;
+ offset= offset_page & 7;
+ data= bitmap->map + offset_page / 8;
+ tmp= uint2korr(data);
+ block->org_bitmap_value= (tmp >> offset) & 7;
+ tmp= (tmp & ~(7 << offset)) | (FULL_HEAD_PAGE << offset);
+ int2store(data, tmp);
+ bitmap->changed= 1;
+ DBUG_EXECUTE("bitmap", _ma_print_bitmap(bitmap););
+}
+
+
+/*
+ Find out where to split the row;
+*/
+
+static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
+ uint extents_length, uint split_size)
+{
+ uint row_length= row->base_length;
+ uint *lengths, *lengths_end;
+
+ DBUG_ASSERT(row_length < split_size);
+ /*
+ Store first in all_field_lengths the different parts that are written
+ to the row. This needs to be in same order as in
+ ma_block_rec.c::write_block_record()
+ */
+ row->null_field_lengths[-3]= extents_length;
+ row->null_field_lengths[-2]= share->base.fixed_not_null_fields_length;
+ row->null_field_lengths[-1]= row->field_lengths_length;
+ for (lengths= row->null_field_lengths - EXTRA_LENGTH_FIELDS,
+ lengths_end= (lengths + share->base.pack_fields - share->base.blobs +
+ EXTRA_LENGTH_FIELDS); lengths < lengths_end; lengths++)
+ {
+ if (row_length + *lengths > split_size)
+ break;
+ row_length+= *lengths;
+ }
+ return row_length;
+}
+
+
+static my_bool write_rest_of_head(MARIA_HA *info, uint position,
+ ulong rest_length)
+{
+ MARIA_SHARE *share= info->s;
+ uint full_page_size= FULL_PAGE_SIZE(share->block_size);
+ MARIA_BITMAP_BLOCK *block;
+
+ if (position == 0)
+ {
+ /* Write out full pages */
+ uint pages= rest_length / full_page_size;
+
+ rest_length%= full_page_size;
+ if (rest_length >= MAX_TAIL_SIZE(share->block_size))
+ {
+ /* Put tail on a full page */
+ pages++;
+ rest_length= 0;
+ }
+ if (find_mid(info, rest_length / full_page_size, 1))
+ return 1;
+ /*
+ Insert empty block after full pages, to allow write_block_record() to
+ split segment into used + free page
+ */
+ block= dynamic_element(&info->bitmap_blocks, 2, MARIA_BITMAP_BLOCK*);
+ block->page_count= 0;
+ block->used= 0;
+ }
+ if (rest_length)
+ {
+ if (find_tail(info, rest_length, ELEMENTS_RESERVED_FOR_MAIN_PART - 1))
+ return 1;
+ }
+ else
+ {
+ /* Empty tail block */
+ block= dynamic_element(&info->bitmap_blocks,
+ ELEMENTS_RESERVED_FOR_MAIN_PART - 1,
+ MARIA_BITMAP_BLOCK *);
+ block->page_count= 0;
+ block->used= 0;
+ }
+ return 0;
+}
+
+
+/*
+ Find where to store one row
+
+ SYNPOSIS
+ _ma_bitmap_find_place()
+ info Maria handler
+ row Information about row to write
+ blocks Store data about allocated places here
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
+ MARIA_BITMAP_BLOCKS *blocks)
+{
+ MARIA_SHARE *share= info->s;
+ my_bool res= 1;
+ uint full_page_size, position, max_page_size;
+ uint head_length, row_length, rest_length, extents_length;
+ DBUG_ENTER("_ma_bitmap_find_place");
+
+ blocks->count= 0;
+ blocks->tail_page_skipped= blocks->page_skipped= 0;
+ row->extents_count= 0;
+ /*
+ Reserver place for the following blocks:
+ - Head block
+ - Full page block
+ - Marker block to allow write_block_record() to split full page blocks
+ into full and free part
+ - Tail block
+ */
+
+ info->bitmap_blocks.elements= ELEMENTS_RESERVED_FOR_MAIN_PART;
+ max_page_size= (share->block_size - PAGE_OVERHEAD_SIZE);
+
+ pthread_mutex_lock(&share->bitmap.bitmap_lock);
+
+ if (row->total_length <= max_page_size)
+ {
+ /* Row fits in one page */
+ position= ELEMENTS_RESERVED_FOR_MAIN_PART - 1;
+ if (find_head(info, (uint) row->total_length, position))
+ goto abort;
+ goto end;
+ }
+
+ /*
+ First allocate all blobs (so that we can find out the needed size for
+ the main block.
+ */
+ if (row->blob_length && allocate_blobs(info, row))
+ goto abort;
+
+ extents_length= row->extents_count * ROW_EXTENT_SIZE;
+ if ((head_length= (row->head_length + extents_length)) <= max_page_size)
+ {
+ /* Main row part fits into one page */
+ position= ELEMENTS_RESERVED_FOR_MAIN_PART - 1;
+ if (find_head(info, head_length, position))
+ goto abort;
+ goto end;
+ }
+
+ /* Allocate enough space */
+ head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE;
+
+ /* The first segment size is stored in 'row_length' */
+ row_length= find_where_to_split_row(share, row, extents_length,
+ max_page_size);
+
+ full_page_size= FULL_PAGE_SIZE(share->block_size);
+ position= 0;
+ if (head_length - row_length <= full_page_size)
+ position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
+ if (find_head(info, row_length, position))
+ goto abort;
+ rest_length= head_length - row_length;
+ if (write_rest_of_head(info, position, rest_length))
+ goto abort;
+
+end:
+ blocks->block= dynamic_element(&info->bitmap_blocks, position,
+ MARIA_BITMAP_BLOCK*);
+ blocks->block->sub_blocks= ELEMENTS_RESERVED_FOR_MAIN_PART - position;
+ /* First block's page_count is for all blocks */
+ blocks->count= info->bitmap_blocks.elements - position;
+ res= 0;
+
+abort:
+ pthread_mutex_unlock(&share->bitmap.bitmap_lock);
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Find where to put row on update (when head page is already defined)
+
+ SYNPOSIS
+ _ma_bitmap_find_new_place()
+ info Maria handler
+ row Information about row to write
+ page On which page original row was stored
+ free_size Free size on head page
+ blocks Store data about allocated places here
+
+ NOTES
+ This function is only called when the new row can't fit in the space of
+ the old row in the head page.
+
+ This is essently same as _ma_bitmap_find_place() except that
+ we don't call find_head() to search in bitmaps where to put the page.
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
+ ulonglong page, uint free_size,
+ MARIA_BITMAP_BLOCKS *blocks)
+{
+ MARIA_SHARE *share= info->s;
+ my_bool res= 1;
+ uint full_page_size, position;
+ uint head_length, row_length, rest_length, extents_length;
+ DBUG_ENTER("_ma_bitmap_find_new_place");
+
+ blocks->count= 0;
+ blocks->tail_page_skipped= blocks->page_skipped= 0;
+ row->extents_count= 0;
+ info->bitmap_blocks.elements= ELEMENTS_RESERVED_FOR_MAIN_PART;
+
+ pthread_mutex_lock(&share->bitmap.bitmap_lock);
+ if (share->bitmap.page != page / share->bitmap.pages_covered &&
+ _ma_change_bitmap_page(info, &share->bitmap,
+ page / share->bitmap.pages_covered))
+ goto abort;
+
+ /*
+ First allocate all blobs (so that we can find out the needed size for
+ the main block.
+ */
+ if (row->blob_length && allocate_blobs(info, row))
+ goto abort;
+
+ extents_length= row->extents_count * ROW_EXTENT_SIZE;
+ if ((head_length= (row->head_length + extents_length)) <= free_size)
+ {
+ /* Main row part fits into one page */
+ position= ELEMENTS_RESERVED_FOR_MAIN_PART - 1;
+ use_head(info, page, head_length, position);
+ goto end;
+ }
+
+ /* Allocate enough space */
+ head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE;
+
+ /* The first segment size is stored in 'row_length' */
+ row_length= find_where_to_split_row(share, row, extents_length, free_size);
+
+ full_page_size= FULL_PAGE_SIZE(share->block_size);
+ position= 0;
+ if (head_length - row_length <= full_page_size)
+ position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
+ use_head(info, page, row_length, position);
+ rest_length= head_length - row_length;
+
+ if (write_rest_of_head(info, position, rest_length))
+ goto abort;
+
+end:
+ blocks->block= dynamic_element(&info->bitmap_blocks, position,
+ MARIA_BITMAP_BLOCK*);
+ blocks->block->sub_blocks= ELEMENTS_RESERVED_FOR_MAIN_PART - position;
+ /* First block's page_count is for all blocks */
+ blocks->count= info->bitmap_blocks.elements - position;
+ res= 0;
+
+abort:
+ pthread_mutex_unlock(&share->bitmap.bitmap_lock);
+ DBUG_RETURN(res);
+}
+
+
+/****************************************************************************
+ Clear and reset bits
+****************************************************************************/
+
+static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
+ ulonglong page, uint fill_pattern)
+{
+ ulonglong bitmap_page;
+ uint offset_page, offset, tmp, org_tmp;
+ uchar *data;
+ DBUG_ENTER("set_page_bits");
+
+ bitmap_page= page / bitmap->pages_covered;
+ if (bitmap_page != bitmap->page &&
+ _ma_change_bitmap_page(info, bitmap, bitmap_page))
+ DBUG_RETURN(1);
+
+ /* Find page number from start of bitmap */
+ offset_page= page - bitmap->page - 1;
+ /*
+ Mark place used by reading/writing 2 bytes at a time to handle
+ bitmaps in overlapping bytes
+ */
+ offset_page*= 3;
+ offset= offset_page & 7;
+ data= bitmap->map + offset_page / 8;
+ org_tmp= tmp= uint2korr(data);
+ tmp= (tmp & ~(7 << offset)) | (fill_pattern << offset);
+ if (tmp == org_tmp)
+ DBUG_RETURN(0); /* No changes */
+ int2store(data, tmp);
+
+ bitmap->changed= 1;
+ DBUG_EXECUTE("bitmap", _ma_print_bitmap(bitmap););
+ if (fill_pattern != 3 && fill_pattern != 7 &&
+ page < info->s->state.first_bitmap_with_space)
+ info->s->state.first_bitmap_with_space= page;
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Get bitmap pattern for a given page
+
+ SYNOPSIS
+
+ get_page_bits()
+ info Maria handler
+ bitmap Bitmap handler
+ page Page number
+
+ RETURN
+ 0-7 Bitmap pattern
+ ~0 Error (couldn't read page)
+*/
+
+static uint get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
+ ulonglong page)
+{
+ ulonglong bitmap_page;
+ uint offset_page, offset, tmp;
+ uchar *data;
+ DBUG_ENTER("get_page_bits");
+
+ bitmap_page= page / bitmap->pages_covered;
+ if (bitmap_page != bitmap->page &&
+ _ma_change_bitmap_page(info, bitmap, bitmap_page))
+ DBUG_RETURN(~ (uint) 0);
+
+ /* Find page number from start of bitmap */
+ offset_page= page - bitmap->page - 1;
+ /*
+ Mark place used by reading/writing 2 bytes at a time to handle
+ bitmaps in overlapping bytes
+ */
+ offset_page*= 3;
+ offset= offset_page & 7;
+ data= bitmap->map + offset_page / 8;
+ tmp= uint2korr(data);
+ DBUG_RETURN((tmp >> offset) & 7);
+}
+
+
+/*
+ Mark all pages in a region as free
+
+ SYNOPSIS
+ reset_full_page_bits()
+ info Maria handler
+ bitmap Bitmap handler
+ page Start page
+ page_count Number of pages
+
+ NOTES
+ We assume that all pages in region is covered by same bitmap
+ One must have a lock on info->s->bitmap.bitmap_lock
+
+ RETURN
+ 0 ok
+ 1 Error (when reading bitmap)
+*/
+
+my_bool _ma_reset_full_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
+ ulonglong page, uint page_count)
+{
+ ulonglong bitmap_page;
+ uint offset, bit_start, bit_count, tmp;
+ uchar *data;
+ DBUG_ENTER("_ma_reset_full_page_bits");
+ DBUG_PRINT("enter", ("page: %lu page_count: %u", (ulong) page, page_count));
+ safe_mutex_assert_owner(&info->s->bitmap.bitmap_lock);
+
+ bitmap_page= page / bitmap->pages_covered;
+ if (bitmap_page != bitmap->page &&
+ _ma_change_bitmap_page(info, bitmap, bitmap_page))
+ DBUG_RETURN(1);
+
+ /* Find page number from start of bitmap */
+ page= page - bitmap->page - 1;
+
+ /* Clear bits from 'page * 3' -> '(page + page_count) * 3' */
+ bit_start= page * 3;
+ bit_count= page_count * 3;
+
+ data= bitmap->map + bit_start / 8;
+ offset= bit_start & 7;
+
+ tmp= (255 << offset); /* Bits to keep */
+ if (bit_count + offset < 8)
+ {
+ /* Only clear bits between 'offset' and 'offset+bit_count-1' */
+ tmp^= (255 << (offset + bit_count));
+ }
+ *data&= ~tmp;
+
+ if ((int) (bit_count-= (8 - offset)) > 0)
+ {
+ uint fill;
+ data++;
+ /*
+ -1 is here to avoid one 'if' statement and to let the following code
+ handle the last byte
+ */
+ if ((fill= (bit_count - 1) / 8))
+ {
+ bzero(data, fill);
+ data+= fill;
+ }
+ bit_count-= fill * 8; /* Bits left to clear */
+ tmp= (1 << bit_count) - 1;
+ *data&= ~tmp;
+ }
+ if (bitmap->page < (ulonglong) info->s->state.first_bitmap_with_space)
+ info->s->state.first_bitmap_with_space= bitmap->page;
+ bitmap->changed= 1;
+ DBUG_EXECUTE("bitmap", _ma_print_bitmap(bitmap););
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Correct bitmap pages to reflect the true allocation
+
+ SYNOPSIS
+ _ma_bitmap_release_unused()
+ info Maria handle
+ blocks Bitmap blocks
+
+ IMPLEMENTATION
+ If block->used & BLOCKUSED_TAIL is set:
+ If block->used & BLOCKUSED_USED is set, then the bits for the
+ corresponding page is set according to block->empty_space
+ If block->used & BLOCKUSED_USED is not set, then the bits for
+ the corresponding page is set to org_bitmap_value;
+
+ If block->used & BLOCKUSED_TAIL is not set:
+ if block->used is not set, the bits for the corresponding page are
+ cleared
+
+ For the first block (head block) the logic is same as for a tail block
+
+ RETURN
+ 0 ok
+ 1 error (Couldn't write or read bitmap page)
+*/
+
+my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
+{
+ MARIA_BITMAP_BLOCK *block= blocks->block, *end= block + blocks->count;
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+ uint bits, current_bitmap_value;
+ DBUG_ENTER("_ma_bitmap_release_unused");
+
+ /*
+ We can skip FULL_HEAD_PAGE (4) as the page was marked as 'full'
+ when we allocated space in the page
+ */
+ current_bitmap_value= FULL_HEAD_PAGE;
+
+ pthread_mutex_lock(&info->s->bitmap.bitmap_lock);
+
+ /* First handle head block */
+ if (block->used & BLOCKUSED_USED)
+ {
+ DBUG_PRINT("info", ("head empty_space: %u", block->empty_space));
+ bits= _ma_free_size_to_head_pattern(bitmap, block->empty_space);
+ if (block->used & BLOCKUSED_USE_ORG_BITMAP)
+ current_bitmap_value= block->org_bitmap_value;
+ }
+ else
+ bits= block->org_bitmap_value;
+ if (bits != current_bitmap_value &&
+ set_page_bits(info, bitmap, block->page, bits))
+ goto err;
+
+
+ /* Handle all full pages and tail pages (for head page and blob) */
+ for (block++; block < end; block++)
+ {
+ if (block->used & BLOCKUSED_TAIL)
+ {
+ if (block->used & BLOCKUSED_USED)
+ {
+ DBUG_PRINT("info", ("tail empty_space: %u", block->empty_space));
+ bits= free_size_to_tail_pattern(bitmap, block->empty_space);
+ }
+ else
+ bits= block->org_bitmap_value;
+ if (bits != FULL_TAIL_PAGE &&
+ set_page_bits(info, bitmap, block->page, bits))
+ goto err;
+ }
+ if (!(block->used & BLOCKUSED_USED) &&
+ _ma_reset_full_page_bits(info, bitmap,
+ block->page, block->page_count))
+ goto err;
+ }
+ pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
+ DBUG_RETURN(0);
+
+err:
+ pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Free full pages from bitmap
+
+ SYNOPSIS
+ _ma_bitmap_free_full_pages()
+ info Maria handle
+ extents Extents (as stored on disk)
+ count Number of extents
+
+ IMPLEMENTATION
+ Mark all full pages (not tails) from extents as free
+
+ RETURN
+ 0 ok
+ 1 error (Couldn't write or read bitmap page)
+*/
+
+my_bool _ma_bitmap_free_full_pages(MARIA_HA *info, const byte *extents,
+ uint count)
+{
+ DBUG_ENTER("_ma_bitmap_free_full_pages");
+
+ pthread_mutex_lock(&info->s->bitmap.bitmap_lock);
+ for (; count--; extents += ROW_EXTENT_SIZE)
+ {
+ ulonglong page= uint5korr(extents);
+ uint page_count= uint2korr(extents + ROW_EXTENT_PAGE_SIZE);
+ if (!(page_count & TAIL_BIT))
+ {
+ if (_ma_reset_full_page_bits(info, &info->s->bitmap, page, page_count))
+ {
+ pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
+ DBUG_RETURN(1);
+ }
+ }
+ }
+ pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
+ DBUG_RETURN(0);
+}
+
+
+
+my_bool _ma_bitmap_set(MARIA_HA *info, ulonglong pos, my_bool head,
+ uint empty_space)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+ uint bits;
+ my_bool res;
+ DBUG_ENTER("_ma_bitmap_set");
+
+ pthread_mutex_lock(&info->s->bitmap.bitmap_lock);
+ bits= (head ?
+ _ma_free_size_to_head_pattern(bitmap, empty_space) :
+ free_size_to_tail_pattern(bitmap, empty_space));
+ res= set_page_bits(info, bitmap, pos, bits);
+ pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Check that bitmap pattern is correct for a page
+
+ NOTES
+ Used in maria_chk
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+my_bool _ma_check_bitmap_data(MARIA_HA *info,
+ enum en_page_type page_type, ulonglong page,
+ uint empty_space, uint *bitmap_pattern)
+{
+ uint bits;
+ switch (page_type) {
+ case UNALLOCATED_PAGE:
+ case MAX_PAGE_TYPE:
+ bits= 0;
+ break;
+ case HEAD_PAGE:
+ bits= _ma_free_size_to_head_pattern(&info->s->bitmap, empty_space);
+ break;
+ case TAIL_PAGE:
+ bits= free_size_to_tail_pattern(&info->s->bitmap, empty_space);
+ break;
+ case BLOB_PAGE:
+ bits= FULL_TAIL_PAGE;
+ break;
+ }
+ return (*bitmap_pattern= get_page_bits(info, &info->s->bitmap, page)) !=
+ bits;
+}
+
+
+/*
+ Check that bitmap pattern is correct for a page
+
+ NOTES
+ Used in maria_chk
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+my_bool _ma_check_if_right_bitmap_type(MARIA_HA *info,
+ enum en_page_type page_type,
+ ulonglong page,
+ uint *bitmap_pattern)
+{
+ if ((*bitmap_pattern= get_page_bits(info, &info->s->bitmap, page)) > 7)
+ return 1; /* Couldn't read page */
+ switch (page_type) {
+ case HEAD_PAGE:
+ return *bitmap_pattern < 1 || *bitmap_pattern > 4;
+ case TAIL_PAGE:
+ return *bitmap_pattern < 5;
+ case BLOB_PAGE:
+ return *bitmap_pattern != 7;
+ default:
+ break;
+ }
+ DBUG_ASSERT(0);
+ return 1;
+}
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
new file mode 100644
index 00000000000..6eac151d76e
--- /dev/null
+++ b/storage/maria/ma_blockrec.c
@@ -0,0 +1,2742 @@
+/* Copyright (C) 2007 Michael Widenius
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Storage of records in block
+
+ Maria will have a LSN at start of each page (including the bitmap page)
+ Maria will for each row have the additional information:
+
+ TRANSID Transaction ID that last updated row (6 bytes)
+ VER_PTR Version pointer that points on the UNDO entry that
+ contains last version of the row versions (7 bytes)
+
+ The different page types that are in a data file are:
+
+ Bitmap pages Map of free pages in the next extent (8129 page size
+ gives us 256M of mapped pages / bitmap)
+ Head page Start of rows are stored on this page.
+ A rowid always points to a head page
+ Blob page This page is totally filled with data from one blob or by
+ a set of long VARCHAR/CHAR fields
+ Tail page This contains the last part from different rows, blobs
+ or varchar fields.
+
+ The data file starts with a bitmap page, followed by as many data
+ pages as the bitmap can cover. After this there is a new bitmap page
+ and more data pages etc.
+
+ For information about the bitmap page, see ma_bitmap.c
+
+ Structure of data and tail page:
+
+ The page has a row directory at end of page to allow us to do deletes
+ without having to reorganize the page. It also allows us to store some
+ extra bytes after each row to allow them to grow without having to move
+ around other rows
+
+ Page header:
+
+ LSN 7 bytes Log position for last page change
+ PAGE_TYPE 1 byte 1 for head / 2 for tail / 3 for blob
+ NO 1 byte Number of row/tail entries on page
+ empty space 2 bytes Empty space on page
+
+ The upmost bit in PAGE_TYPE is set to 1 if the data on the page
+ can be compacted to get more space. (PAGE_CAN_BE_COMPACTED)
+
+ Row data
+
+ Row directory of NO entires, that consist of the following for each row
+ (in reverse order; ie, first record is stored last):
+
+ Position 2 bytes Position of row on page
+ Length 2 bytes Length of entry
+
+ For Position and Length, the 1 upmost bit of the position and the 1
+ upmost bit of the length could be used for some states of the row (in
+ other words, we should try to keep these reserved)
+
+ eof flag 1 byte Reserved for full page read testing
+
+ ----------------
+
+ Structure of blob pages:
+
+ LSN 7 bytes Log position for last page change
+ PAGE_TYPE 1 byte 3
+
+ data
+
+ -----------------
+
+ Row data structure:
+
+ Flag 1 byte Marker of which header field exists
+ TRANSID 6 bytes TRANSID of changing transaction
+ (optional, added on insert and first
+ update/delete)
+ VER_PTR 7 bytes Pointer to older version in log
+ (undo record)
+ (optional, added after first
+ update/delete)
+ DELETE_TRANSID 6 bytes (optional). TRANSID of original row.
+ Added on delete.
+ Nulls_extended 1 byte To allow us to add new DEFAULT NULL
+ fields (optional, added after first
+ change of row after alter table)
+ Number of ROW_EXTENT's 1-3 byte Length encoded, optional
+ This is the number of extents the
+ row is split into
+ First row_extent 7 byte Pointer to first row extent (optional)
+
+ Total length of length array 1-3 byte Only used if we have
+ char/varchar/blob fields.
+ Row checksum 1 byte Only if table created with checksums
+ Null_bits .. One bit for each NULL field
+ Empty_bits .. One bit for each NOT NULL field. This bit is
+ 0 if the value is 0 or empty string.
+
+ field_offsets 2 byte/offset
+ For each 32 field, there is one offset that
+ points to where the field information starts
+ in the block. This is to provide fast access
+ to later field in the row when we only need
+ to return a small set of fields.
+
+ Things marked above as 'optional' will only be present if the corresponding
+ bit is set in 'Flag' field.
+
+ Data in the following order:
+ (Field order is precalculated when table is created)
+
+ Critical fixed length, not null, fields. (Note, these can't be dropped)
+ Fixed length, null fields
+
+ Length array, 1-4 byte per field for all CHAR/VARCHAR/BLOB fields.
+ Number of bytes used in length array per entry is depending on max length
+ for field.
+
+ ROW_EXTENT's
+ CHAR data (space stripped)
+ VARCHAR data
+ BLOB data
+
+ Fields marked in null_bits or empty_bits are not stored in data part or
+ length array.
+
+ If row doesn't fit into the given block, then the first EXTENT will be
+ stored last on the row. This is done so that we don't break any field
+ data in the middle.
+
+ We first try to store the full row into one block. If that's not possible
+ we move out each big blob into their own extents. If this is not enough we
+ move out a concatenation of all varchars to their own extent.
+
+ Each blob and the concatenated char/varchar fields are stored the following
+ way:
+ - Store the parts in as many full-contiguous pages as possible.
+ - The last part, that doesn't fill a full page, is stored in tail page.
+
+ When doing an insert of a new row, we don't have to have
+ VER_PTR in the row. This will make rows that are not changed stored
+ efficiently. On update and delete we would add TRANSID (if it was an old
+ committed row) and VER_PTR to
+ the row. On row page compaction we can easily detect rows where
+ TRANSID was committed before the the longest running transaction
+ started and we can then delete TRANSID and VER_PTR from the row to
+ gain more space.
+
+ If a row is deleted in Maria, we change TRANSID to current transid and
+ change VER_PTR to point to the undo record for the delete. The undo
+ record must contain the original TRANSID, so that another transaction
+ can use this to check if they should use the found row or go to the
+ previous row pointed to by the VER_PTR in the undo row.
+
+ Description of the different parts:
+
+ Flag is coded as:
+
+ Description bit
+ TRANS_ID_exists 0
+ VER_PTR_exists 1
+ Row is deleted 2 (Means that DELETE_TRANSID exists)
+ Nulls_extended_exists 3
+ Row is split 7 This means that 'Number_of_row_extents' exists
+
+
+ This would be a way to get more space on a page when doing page
+ compaction as we don't need to store TRANSID that have committed
+ before the smallest running transaction we have in memory.
+
+ Nulls_extended is the number of new DEFAULT NULL fields in the row
+ compared to the number of DEFAULT NULL fields when the first version
+ of the table was created. If Nulls_extended doesn't exist in the row,
+ we know it's 0 as this must be one of the original rows from when the
+ table was created first time. This coding allows us to add 255*8 =
+ 2048 new fields without requiring a full alter table.
+
+ Empty_bits is used to allow us to store 0, 0.0, empty string, empty
+ varstring and empty blob efficiently. (This is very good for data
+ warehousing where NULL's are often regarded as evil). Having this
+ bitmap also allows us to drop information of a field during a future
+ delete if field was deleted with ALTER TABLE DROP COLUMN. To be able
+ to handle DROP COLUMN, we must store in the index header the fields
+ that has been dropped. When unpacking a row we will ignore dropped
+ fields. When storing a row, we will mark a dropped field either with a
+ null in the null bit map or in the empty_bits and not store any data
+ for it.
+
+ One ROW_EXTENT is coded as:
+
+ START_PAGE 5 bytes
+ PAGE_COUNT 2 bytes. High bit is used to indicate tail page/
+ end of blob
+ With 8K pages, we can cover 256M in one extent. This coding gives us a
+ maximum file size of 2^40*8192 = 8192 tera
+
+ As an example of ROW_EXTENT handling, assume a row with one integer
+ field (value 5), two big VARCHAR fields (size 250 and 8192*3), and 2
+ big BLOB fields that we have updated.
+
+ The record format for storing this into an empty file would be:
+
+ Page 1:
+
+ 00 00 00 00 00 00 00 LSN
+ 01 Only one row in page
+ xx xx Empty space on page
+
+ 10 Flag: row split, VER_PTR exists
+ 01 00 00 00 00 00 TRANSID 1
+ 00 00 00 00 00 01 00 VER_PTR to first block in LOG file 1
+ 5 Number of row extents
+ 02 00 00 00 00 03 00 VARCHAR's are stored in full pages 2,3,4
+ 0 No null fields
+ 0 No empty fields
+ 05 00 00 00 00 00 80 Tail page for VARCHAR, rowid 0
+ 06 00 00 00 00 80 00 First blob, stored at page 6-133
+ 05 00 00 00 00 01 80 Tail of first blob (896 bytes) at page 5
+ 86 00 00 00 00 80 00 Second blob, stored at page 134-262
+ 05 00 00 00 00 02 80 Tail of second blob (896 bytes) at page 5
+ 05 00 5 integer
+ FA Length of first varchar field (size 250)
+ 00 60 Length of second varchar field (size 8192*3)
+ 00 60 10 First medium BLOB, 1M
+ 01 00 10 00 Second BLOB, 1M
+ xx xx xx xx xx xx Varchars are stored here until end of page
+
+ ..... until end of page
+
+ 09 00 F4 1F 00 (Start position 9, length 8180, end byte)
+*/
+
+#define SANITY_CHECKS
+
+#include "maria_def.h"
+#include "ma_blockrec.h"
+
+typedef struct st_maria_extent_cursor
+{
+ byte *extent;
+ byte *data_start; /* For error checking */
+ MARIA_RECORD_POS *tail_positions;
+ my_off_t page;
+ uint extent_count, page_count;
+ uint tail; /* <> 0 if current extent is a tail page */
+ my_bool first_extent;
+} MARIA_EXTENT_CURSOR;
+
+
+static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails);
+static my_bool delete_head_or_tail(MARIA_HA *info,
+ ulonglong page, uint record_number,
+ my_bool head);
+static void _ma_print_directory(byte *buff, uint block_size);
+
+/****************************************************************************
+ Initialization
+****************************************************************************/
+
+/*
+ Initialize data needed for block structures
+*/
+
+
+/* Size of the different header elements for a row */
+
+static uchar header_sizes[]=
+{
+ TRANSID_SIZE,
+ VERPTR_SIZE,
+ TRANSID_SIZE, /* Delete transid */
+ 1 /* Null extends */
+};
+
+/*
+ Calculate array of all used headers
+
+ Used to speed up:
+
+ size= 1;
+ if (flag & 1)
+ size+= TRANSID_SIZE;
+ if (flag & 2)
+ size+= VERPTR_SIZE;
+ if (flag & 4)
+ size+= TRANSID_SIZE
+ if (flag & 8)
+ size+= 1;
+
+ NOTES
+ This is called only once at startup of Maria
+*/
+
+static uchar total_header_size[1 << array_elements(header_sizes)];
+#define PRECALC_HEADER_BITMASK (array_elements(total_header_size) -1)
+
+void _ma_init_block_record_data(void)
+{
+ uint i;
+ bzero(total_header_size, sizeof(total_header_size));
+ total_header_size[0]= FLAG_SIZE; /* Flag byte */
+ for (i= 1; i < array_elements(total_header_size); i++)
+ {
+ uint size= FLAG_SIZE, j, bit;
+ for (j= 0; (bit= (1 << j)) <= i; j++)
+ {
+ if (i & bit)
+ size+= header_sizes[j];
+ }
+ total_header_size[i]= size;
+ }
+}
+
+
+my_bool _ma_once_init_block_row(MARIA_SHARE *share, File data_file)
+{
+
+ share->base.max_data_file_length=
+ (((ulonglong) 1 << ((share->base.rec_reflength-1)*8))-1) *
+ share->block_size;
+#if SIZEOF_OFF_T == 4
+ set_if_smaller(max_data_file_length, INT_MAX32);
+#endif
+ return _ma_bitmap_init(share, data_file);
+}
+
+
+my_bool _ma_once_end_block_row(MARIA_SHARE *share)
+{
+ int res= _ma_bitmap_end(share);
+ if (flush_key_blocks(share->key_cache, share->bitmap.file,
+ share->temporary ? FLUSH_IGNORE_CHANGED :
+ FLUSH_RELEASE))
+ res= 1;
+ if (share->bitmap.file >= 0 && my_close(share->bitmap.file, MYF(MY_WME)))
+ res= 1;
+ return res;
+}
+
+
+/* Init info->cur_row structure */
+
+my_bool _ma_init_block_row(MARIA_HA *info)
+{
+ MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row;
+ DBUG_ENTER("_ma_init_block_row");
+
+ if (!my_multi_malloc(MY_WME,
+ &row->empty_bits_buffer, info->s->base.pack_bytes,
+ &row->field_lengths, info->s->base.max_field_lengths,
+ &row->blob_lengths, sizeof(ulong) * info->s->base.blobs,
+ &row->null_field_lengths, (sizeof(uint) *
+ (info->s->base.fields -
+ info->s->base.blobs)),
+ &row->tail_positions, (sizeof(MARIA_RECORD_POS) *
+ (info->s->base.blobs + 2)),
+ &new_row->empty_bits_buffer, info->s->base.pack_bytes,
+ &new_row->field_lengths,
+ info->s->base.max_field_lengths,
+ &new_row->blob_lengths,
+ sizeof(ulong) * info->s->base.blobs,
+ &new_row->null_field_lengths, (sizeof(uint) *
+ (info->s->base.fields -
+ info->s->base.blobs)),
+ NullS, 0))
+ DBUG_RETURN(1);
+ if (my_init_dynamic_array(&info->bitmap_blocks,
+ sizeof(MARIA_BITMAP_BLOCK),
+ ELEMENTS_RESERVED_FOR_MAIN_PART, 16))
+ my_free((char*) &info->bitmap_blocks, MYF(0));
+ row->base_length= new_row->base_length= info->s->base_length;
+ DBUG_RETURN(0);
+}
+
+void _ma_end_block_row(MARIA_HA *info)
+{
+ DBUG_ENTER("_ma_end_block_row");
+ my_free((gptr) info->cur_row.empty_bits_buffer, MYF(MY_ALLOW_ZERO_PTR));
+ delete_dynamic(&info->bitmap_blocks);
+ my_free((gptr) info->cur_row.extents, MYF(MY_ALLOW_ZERO_PTR));
+ DBUG_VOID_RETURN;
+}
+
+
+/****************************************************************************
+ Helper functions
+****************************************************************************/
+
+static inline uint empty_pos_after_row(byte *dir)
+{
+ byte *prev;
+ /*
+ Find previous used entry. (There is always a previous entry as
+ the directory never starts with a deleted entry)
+ */
+ for (prev= dir - DIR_ENTRY_SIZE ;
+ prev[0] == 0 && prev[1] == 0 ;
+ prev-= DIR_ENTRY_SIZE)
+ {}
+ return (uint) uint2korr(prev);
+}
+
+
+static my_bool check_if_zero(byte *pos, uint length)
+{
+ byte *end;
+ for (end= pos+ length; pos != end ; pos++)
+ if (pos[0] != 0)
+ return 1;
+ return 0;
+}
+
+
+/*
+ Find free postion in directory
+
+ SYNOPSIS
+ find_free_position()
+ buff Page
+ block_size Size of page
+ res_rownr Store index to free position here
+ res_length Store length of found segment here
+ empty_space Store length of empty space on disk here. This is
+ all empty space, including the found block.
+
+ NOTES
+ If there is a free directory entry (entry with postion == 0),
+ then use it and change it to be the size of the empty block
+ after the previous entry. This guarantees that all row entries
+ are stored on disk in inverse directory order, which makes life easier for
+ 'compact_page()' and to know if there is free space after any block.
+
+ If there is no free entry (entry with postion == 0), then we create
+ a new one.
+
+ We will update the offset and the length of the found dir entry to
+ match the position and empty space found.
+
+ buff[EMPTY_SPACE_OFFSET] is NOT updated but left up to the caller
+
+ RETURN
+ 0 Error (directory full)
+ # Pointer to directory entry on page
+*/
+
+static byte *find_free_position(byte *buff, uint block_size, uint *res_rownr,
+ uint *res_length, uint *empty_space)
+{
+ uint max_entry= (uint) ((uchar*) buff)[DIR_ENTRY_OFFSET];
+ uint entry, length, first_pos;
+ byte *dir, *end;
+
+ dir= (buff + block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE);
+ end= buff + block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
+
+ first_pos= PAGE_HEADER_SIZE;
+ *empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
+
+ /* Search after first empty position */
+ for (entry= 0 ; dir <= end ; end-= DIR_ENTRY_SIZE, entry--)
+ {
+ if (end[0] == 0 && end[1] == 0) /* Found not used entry */
+ {
+ length= empty_pos_after_row(end) - first_pos;
+ int2store(end, first_pos); /* Update dir entry */
+ int2store(end + 2, length);
+ *res_rownr= entry;
+ *res_length= length;
+ return end;
+ }
+ first_pos= uint2korr(end) + uint2korr(end + 2);
+ }
+ /* No empty places in dir; create a new one */
+ if (max_entry == MAX_ROWS_PER_PAGE)
+ return 0;
+ buff[DIR_ENTRY_OFFSET]= (byte) (uchar) max_entry+1;
+ dir-= DIR_ENTRY_SIZE;
+ length= (uint) (dir - buff - first_pos);
+ DBUG_ASSERT(length <= *empty_space - DIR_ENTRY_SIZE);
+ int2store(dir, first_pos);
+ int2store(dir+2, length); /* Current max length */
+ *res_rownr= max_entry;
+ *res_length= length;
+
+ /* Reduce directory entry size from free space size */
+ (*empty_space)-= DIR_ENTRY_SIZE;
+ return dir;
+
+}
+
+/****************************************************************************
+ Updating records
+****************************************************************************/
+
+/*
+ Calculate length of all the different field parts
+*/
+
+static void calc_record_size(MARIA_HA *info, const byte *record,
+ MARIA_ROW *row)
+{
+ MARIA_SHARE *share= info->s;
+ byte *field_length_data;
+ MARIA_COLUMNDEF *rec, *end_field;
+ uint blob_count= 0, *null_field_lengths= row->null_field_lengths;
+
+ row->normal_length= row->char_length= row->varchar_length=
+ row->blob_length= row->extents_count= 0;
+
+ /* Create empty bitmap and calculate length of each varlength/char field */
+ bzero(row->empty_bits_buffer, share->base.pack_bytes);
+ row->empty_bits= row->empty_bits_buffer;
+ field_length_data= row->field_lengths;
+ for (rec= share->rec + share->base.fixed_not_null_fields,
+ end_field= share->rec + share->base.fields;
+ rec < end_field; rec++, null_field_lengths++)
+ {
+ if ((record[rec->null_pos] & rec->null_bit))
+ {
+ if (rec->type != FIELD_BLOB)
+ *null_field_lengths= 0;
+ continue;
+ }
+ switch ((enum en_fieldtype) rec->type) {
+ case FIELD_CHECK:
+ case FIELD_NORMAL: /* Fixed length field */
+ case FIELD_ZERO:
+ DBUG_ASSERT(rec->empty_bit == 0);
+ /* fall through */
+ case FIELD_SKIP_PRESPACE: /* Not packed */
+ row->normal_length+= rec->length;
+ *null_field_lengths= rec->length;
+ break;
+ case FIELD_SKIP_ZERO: /* Fixed length field */
+ if (memcmp(record+ rec->null_pos, maria_zero_string,
+ rec->length) == 0)
+ {
+ row->empty_bits[rec->empty_pos] |= rec->empty_bit;
+ *null_field_lengths= 0;
+ }
+ else
+ {
+ row->normal_length+= rec->length;
+ *null_field_lengths= rec->length;
+ }
+ break;
+ case FIELD_SKIP_ENDSPACE: /* CHAR */
+ {
+ const char *pos, *end;
+ for (pos= record + rec->offset, end= pos + rec->length;
+ end > pos && end[-1] == ' '; end--)
+ ;
+ if (pos == end) /* If empty string */
+ {
+ row->empty_bits[rec->empty_pos]|= rec->empty_bit;
+ *null_field_lengths= 0;
+ }
+ else
+ {
+ uint length= (end - pos);
+ if (rec->length <= 255)
+ *field_length_data++= (byte) (uchar) length;
+ else
+ {
+ int2store(field_length_data, length);
+ field_length_data+= 2;
+ }
+ row->char_length+= length;
+ *null_field_lengths= length;
+ }
+ break;
+ }
+ case FIELD_VARCHAR:
+ {
+ uint length;
+ const byte *field_pos= record + rec->offset;
+ /* 256 is correct as this includes the length byte */
+ if (rec->length <= 256)
+ {
+ if (!(length= (uint) (uchar) *field_pos))
+ {
+ row->empty_bits[rec->empty_pos]|= rec->empty_bit;
+ *null_field_lengths= 0;
+ break;
+ }
+ *field_length_data++= *field_pos;
+ }
+ else
+ {
+ if (!(length= uint2korr(field_pos)))
+ {
+ row->empty_bits[rec->empty_pos]|= rec->empty_bit;
+ break;
+ }
+ field_length_data[0]= field_pos[0];
+ field_length_data[1]= field_pos[1];
+ field_length_data+= 2;
+ }
+ row->varchar_length+= length;
+ *null_field_lengths= length;
+ break;
+ }
+ case FIELD_BLOB:
+ {
+ const byte *field_pos= record + rec->offset;
+ uint size_length= rec->length - maria_portable_sizeof_char_ptr;
+ ulong blob_length= _ma_calc_blob_length(size_length, field_pos);
+ if (!blob_length)
+ {
+ row->empty_bits[rec->empty_pos]|= rec->empty_bit;
+ row->blob_lengths[blob_count++]= 0;
+ break;
+ }
+ row->blob_length+= blob_length;
+ row->blob_lengths[blob_count++]= blob_length;
+ memcpy(field_length_data, field_pos, size_length);
+ field_length_data+= size_length;
+ break;
+ }
+ default:
+ DBUG_ASSERT(0);
+ }
+ }
+ row->field_lengths_length= (uint) (field_length_data - row->field_lengths);
+ row->head_length= (row->base_length +
+ share->base.fixed_not_null_fields_length +
+ row->field_lengths_length +
+ size_to_store_key_length(row->field_lengths_length) +
+ row->normal_length +
+ row->char_length + row->varchar_length);
+ row->total_length= (row->head_length + row->blob_length);
+ if (row->total_length < share->base.min_row_length)
+ row->total_length= share->base.min_row_length;
+}
+
+
+/*
+ Compact page by removing all space between rows
+
+ IMPLEMENTATION
+ Move up all rows to start of page.
+ Move blocks that are directly after each other with one memmove.
+
+ TODO LATER
+ Remove TRANSID from rows that are visible to all transactions
+
+ SYNOPSIS
+ compact_page()
+ buff Page to compact
+ block_size Size of page
+ recnr Put empty data after this row
+*/
+
+
+void compact_page(byte *buff, uint block_size, uint rownr)
+{
+ uint max_entry= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET];
+ uint page_pos, next_free_pos, start_of_found_block, diff, end_of_found_block;
+ byte *dir, *end;
+ DBUG_ENTER("compact_page");
+ DBUG_PRINT("enter", ("rownr: %u", rownr));
+ DBUG_ASSERT(max_entry > 0 &&
+ max_entry < (block_size - PAGE_HEADER_SIZE -
+ PAGE_SUFFIX_SIZE) / DIR_ENTRY_SIZE);
+
+ /* Move all entries before and including rownr up to start of page */
+ dir= buff + block_size - DIR_ENTRY_SIZE * (rownr+1) - PAGE_SUFFIX_SIZE;
+ end= buff + block_size - DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE;
+ page_pos= next_free_pos= start_of_found_block= PAGE_HEADER_SIZE;
+ diff= 0;
+ for (; dir <= end ; end-= DIR_ENTRY_SIZE)
+ {
+ uint offset= uint2korr(end);
+
+ if (offset)
+ {
+ uint row_length= uint2korr(end + 2);
+ DBUG_ASSERT(offset >= page_pos);
+ DBUG_ASSERT(buff + offset + row_length <= dir);
+
+ if (offset != next_free_pos)
+ {
+ uint length= (next_free_pos - start_of_found_block);
+ /*
+ There was empty space before this and prev block
+ Check if we have to move prevous block up to page start
+ */
+ if (page_pos != start_of_found_block)
+ {
+ /* move up previous block */
+ memmove(buff + page_pos, buff + start_of_found_block, length);
+ }
+ page_pos+= length;
+ /* next continous block starts here */
+ start_of_found_block= offset;
+ diff= offset - page_pos;
+ }
+ int2store(end, offset - diff); /* correct current pos */
+ next_free_pos= offset + row_length;
+ }
+ }
+ if (page_pos != start_of_found_block)
+ {
+ uint length= (next_free_pos - start_of_found_block);
+ memmove(buff + page_pos, buff + start_of_found_block, length);
+ }
+ start_of_found_block= uint2korr(dir);
+
+ if (rownr != max_entry - 1)
+ {
+ /* Move all entries after rownr to end of page */
+ uint rownr_length;
+ next_free_pos= end_of_found_block= page_pos=
+ block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE;
+ diff= 0;
+ /* End points to entry before 'rownr' */
+ for (dir= buff + end_of_found_block ; dir <= end ; dir+= DIR_ENTRY_SIZE)
+ {
+ uint offset= uint2korr(dir);
+ uint row_length= uint2korr(dir + 2);
+ uint row_end= offset + row_length;
+ if (!offset)
+ continue;
+ DBUG_ASSERT(offset >= start_of_found_block && row_end <= next_free_pos);
+
+ if (row_end != next_free_pos)
+ {
+ uint length= (end_of_found_block - next_free_pos);
+ if (page_pos != end_of_found_block)
+ {
+ /* move next block down */
+ memmove(buff + page_pos - length, buff + next_free_pos, length);
+ }
+ page_pos-= length;
+ /* next continous block starts here */
+ end_of_found_block= row_end;
+ diff= page_pos - row_end;
+ }
+ int2store(dir, offset + diff); /* correct current pos */
+ next_free_pos= offset;
+ }
+ if (page_pos != end_of_found_block)
+ {
+ uint length= (end_of_found_block - next_free_pos);
+ memmove(buff + page_pos - length, buff + next_free_pos, length);
+ next_free_pos= page_pos- length;
+ }
+ /* Extend rownr block to cover hole */
+ rownr_length= next_free_pos - start_of_found_block;
+ int2store(dir+2, rownr_length);
+ }
+ else
+ {
+ /* Extend last block cover whole page */
+ uint length= (uint) (dir - buff) - start_of_found_block;
+ int2store(dir+2, length);
+
+ buff[PAGE_TYPE_OFFSET]&= ~(byte) PAGE_CAN_BE_COMPACTED;
+ }
+ DBUG_EXECUTE("directory", _ma_print_directory(buff, block_size););
+ DBUG_VOID_RETURN;
+}
+
+
+
+/*
+ Read or initialize new head or tail page
+
+ SYNOPSIS
+ get_head_or_tail_page()
+ info Maria handler
+ block Block to read
+ buff Suggest this buffer to key cache
+ length Minimum space needed
+ page_type HEAD_PAGE || TAIL_PAGE
+ res Store result position here
+
+ NOTES
+ We don't decremented buff[EMPTY_SPACE_OFFSET] with the allocated data
+ as we don't know how much data the caller will actually use.
+
+ RETURN
+ 0 ok All slots in 'res' are updated
+ 1 error my_errno is set
+*/
+
+struct st_row_pos_info
+{
+ byte *buff; /* page buffer */
+ byte *data; /* Place for data */
+ byte *dir; /* Directory */
+ uint length; /* Length for data */
+ uint offset; /* Offset to directory */
+ uint empty_space; /* Space left on page */
+};
+
+static my_bool get_head_or_tail_page(MARIA_HA *info,
+ MARIA_BITMAP_BLOCK *block,
+ byte *buff, uint length, uint page_type,
+ struct st_row_pos_info *res)
+{
+ uint block_size;
+ DBUG_ENTER("get_head_or_tail_page");
+
+ block_size= info->s->block_size;
+ if (block->org_bitmap_value == 0) /* Empty block */
+ {
+ /* New page */
+ bzero(buff, PAGE_HEADER_SIZE);
+
+ /*
+ We zero the rest of the block to avoid getting old memory information
+ to disk and to allow the file to be compressed better if archived.
+ The rest of the code does not assume the block is zeroed above
+ PAGE_OVERHEAD_SIZE
+ */
+ bzero(buff+ PAGE_HEADER_SIZE + length,
+ block_size - length - PAGE_HEADER_SIZE - DIR_ENTRY_SIZE -
+ PAGE_SUFFIX_SIZE);
+ buff[PAGE_TYPE_OFFSET]= (byte) page_type;
+ buff[DIR_ENTRY_OFFSET]= 1;
+ res->buff= buff;
+ res->empty_space= res->length= (block_size - PAGE_OVERHEAD_SIZE);
+ res->data= (buff + PAGE_HEADER_SIZE);
+ res->dir= res->data + res->length;
+ /* Store poistion to the first row */
+ int2store(res->dir, PAGE_HEADER_SIZE);
+ res->offset= 0;
+ DBUG_ASSERT(length <= res->length);
+ }
+ else
+ {
+ byte *dir;
+ /* Read old page */
+ if (!(res->buff= key_cache_read(info->s->key_cache,
+ info->dfile,
+ (my_off_t) block->page * block_size, 0,
+ buff, block_size, block_size, 0)))
+ DBUG_RETURN(1);
+ DBUG_ASSERT((res->buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == page_type);
+ if (!(dir= find_free_position(buff, block_size, &res->offset,
+ &res->length, &res->empty_space)))
+ {
+ if (res->length < length)
+ {
+ if (res->empty_space + res->length < length)
+ {
+ compact_page(res->buff, block_size, res->offset);
+ /* All empty space are now after current position */
+ res->length= res->empty_space= uint2korr(dir+2);
+ }
+ if (res->length < length)
+ goto crashed; /* Wrong bitmap information */
+ }
+ }
+ res->dir= dir;
+ res->data= res->buff + uint2korr(dir);
+ }
+ DBUG_RETURN(0);
+
+crashed:
+ my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Write tail of non-blob-data or blob
+
+ SYNOPSIS
+ write_tail()
+ info Maria handler
+ block Block to tail page
+ row_part Data to write to page
+ length Length of data
+
+ NOTES
+ block->page_count is updated to the directory offset for the tail
+ so that we can store the position in the row extent information
+
+ RETURN
+ 0 ok
+ block->page_count is set to point (dir entry + TAIL_BIT)
+
+ 1 error; In this case my_errno is set to the error
+*/
+
+static my_bool write_tail(MARIA_HA *info,
+ MARIA_BITMAP_BLOCK *block,
+ byte *row_part, uint length)
+{
+ MARIA_SHARE *share= share= info->s;
+ uint block_size= share->block_size, empty_space;
+ struct st_row_pos_info row_pos;
+ my_off_t position;
+ DBUG_ENTER("write_tail");
+ DBUG_PRINT("enter", ("page: %lu length: %u",
+ (ulong) block->page, length));
+
+ info->keybuff_used= 1;
+ if (get_head_or_tail_page(info, block, info->keyread_buff, length,
+ TAIL_PAGE, &row_pos))
+ DBUG_RETURN(1);
+
+ memcpy(row_pos.data, row_part, length);
+ int2store(row_pos.dir + 2, length);
+ empty_space= row_pos.empty_space - length;
+ int2store(row_pos.buff + EMPTY_SPACE_OFFSET, empty_space);
+ block->page_count= row_pos.offset + TAIL_BIT;
+ /*
+ If there is less directory entries free than number of possible tails
+ we can write for a row, we mark the page full to ensure that we don't
+ during _ma_bitmap_find_place() allocate more entires on the tail page
+ than it can hold
+ */
+ block->empty_space= ((uint) ((uchar*) row_pos.buff)[DIR_ENTRY_OFFSET] <=
+ MAX_ROWS_PER_PAGE - 1 - info->s->base.blobs ?
+ empty_space : 0);
+ block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
+
+ /* Increase data file size, if extended */
+ position= (my_off_t) block->page * block_size;
+ if (info->state->data_file_length <= position)
+ info->state->data_file_length= position + block_size;
+ DBUG_RETURN(key_cache_write(share->key_cache,
+ info->dfile, position, 0,
+ row_pos.buff, block_size, block_size, 1));
+}
+
+
+/*
+ Write full pages
+
+ SYNOPSIS
+ write_full_pages()
+ info Maria handler
+ block Where to write data
+ data Data to write
+ length Length of data
+
+*/
+
+static my_bool write_full_pages(MARIA_HA *info,
+ MARIA_BITMAP_BLOCK *block,
+ byte *data, ulong length)
+{
+ my_off_t page;
+ MARIA_SHARE *share= share= info->s;
+ uint block_size= share->block_size;
+ uint data_size= FULL_PAGE_SIZE(block_size);
+ byte *buff= info->keyread_buff;
+ uint page_count;
+ my_off_t position;
+ DBUG_ENTER("write_full_pages");
+ DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu",
+ length, (ulong) block->page, block->page_count));
+
+ info->keybuff_used= 1;
+ page= block->page;
+ page_count= block->page_count;
+
+ position= (my_off_t) (page + page_count) * block_size;
+ if (info->state->data_file_length < position)
+ info->state->data_file_length= position;
+
+ /* Increase data file size, if extended */
+
+ for (; length; data+= data_size)
+ {
+ uint copy_length;
+ if (!page_count--)
+ {
+ block++;
+ page= block->page;
+ page_count= block->page_count - 1;
+ DBUG_PRINT("info", ("page: %lu page_count: %lu",
+ (ulong) block->page, block->page_count));
+
+ position= (page + page_count + 1) * block_size;
+ if (info->state->data_file_length < position)
+ info->state->data_file_length= position;
+ }
+ bzero(buff, LSN_SIZE);
+ buff[PAGE_TYPE_OFFSET]= (byte) BLOB_PAGE;
+ copy_length= min(data_size, length);
+ memcpy(buff + LSN_SIZE + PAGE_TYPE_SIZE, data, copy_length);
+ length-= copy_length;
+
+ if (key_cache_write(share->key_cache,
+ info->dfile, (my_off_t) page * block_size, 0,
+ buff, block_size, block_size, 1))
+ DBUG_RETURN(1);
+ page++;
+ block->used= BLOCKUSED_USED;
+ }
+ DBUG_RETURN(0);
+}
+
+
+
+
+/*
+ Store packed extent data
+
+ SYNOPSIS
+ store_extent_info()
+ to Store first packed data here
+ row_extents_second_part Store rest here
+ first_block First block to store
+ count Number of blocks
+
+ NOTES
+ We don't have to store the position for the head block
+*/
+
+static void store_extent_info(byte *to,
+ byte *row_extents_second_part,
+ MARIA_BITMAP_BLOCK *first_block,
+ uint count)
+{
+ MARIA_BITMAP_BLOCK *block, *end_block;
+ uint copy_length;
+ my_bool first_found= 0;
+
+ for (block= first_block, end_block= first_block+count ;
+ block < end_block; block++)
+ {
+ /* The following is only false for marker blocks */
+ if (likely(block->used))
+ {
+ int5store(to, block->page);
+ int2store(to + 5, block->page_count);
+ to+= ROW_EXTENT_SIZE;
+ if (!first_found)
+ {
+ first_found= 1;
+ to= row_extents_second_part;
+ }
+ }
+ }
+ copy_length= (count -1) * ROW_EXTENT_SIZE;
+ /*
+ In some unlikely cases we have allocated to many blocks. Clear this
+ data.
+ */
+ bzero(to, (my_size_t) (row_extents_second_part + copy_length - to));
+}
+
+/*
+ Write a record to a (set of) pages
+*/
+
+static my_bool write_block_record(MARIA_HA *info, const byte *record,
+ MARIA_ROW *row,
+ MARIA_BITMAP_BLOCKS *bitmap_blocks,
+ struct st_row_pos_info *row_pos)
+{
+ byte *data, *end_of_data, *tmp_data_used, *tmp_data;
+ byte *row_extents_first_part, *row_extents_second_part;
+ byte *field_length_data;
+ byte *page_buff;
+ MARIA_BITMAP_BLOCK *block, *head_block;
+ MARIA_SHARE *share;
+ MARIA_COLUMNDEF *rec, *end_field;
+ uint block_size, flag;
+ ulong *blob_lengths;
+ my_off_t position;
+ my_bool row_extents_in_use;
+ DBUG_ENTER("write_block_record");
+
+ LINT_INIT(row_extents_first_part);
+ LINT_INIT(row_extents_second_part);
+
+ share= info->s;
+ head_block= bitmap_blocks->block;
+ block_size= share->block_size;
+
+ info->cur_row.lastpos= ma_recordpos(head_block->page, row_pos->offset);
+ page_buff= row_pos->buff;
+ data= row_pos->data;
+ end_of_data= data + row_pos->length;
+
+ /* Write header */
+ flag= share->base.default_row_flag;
+ row_extents_in_use= 0;
+ if (unlikely(row->total_length > row_pos->length))
+ {
+ /* Need extent */
+ if (bitmap_blocks->count <= 1)
+ goto crashed; /* Wrong in bitmap */
+ flag|= ROW_FLAG_EXTENTS;
+ row_extents_in_use= 1;
+ }
+ /* For now we have only a minimum header */
+ *data++= (uchar) flag;
+ if (unlikely(flag & ROW_FLAG_NULLS_EXTENDED))
+ *data++= (uchar) (share->base.null_bytes -
+ share->base.original_null_bytes);
+ if (row_extents_in_use)
+ {
+ /* Store first extent in header */
+ store_key_length_inc(data, bitmap_blocks->count - 1);
+ row_extents_first_part= data;
+ data+= ROW_EXTENT_SIZE;
+ }
+ if (share->base.pack_fields)
+ store_key_length_inc(data, row->field_lengths_length);
+ if (share->calc_checksum)
+ *(data++)= (byte) info->cur_row.checksum;
+ memcpy(data, record, share->base.null_bytes);
+ data+= share->base.null_bytes;
+ memcpy(data, row->empty_bits, share->base.pack_bytes);
+ data+= share->base.pack_bytes;
+
+ /*
+ Allocate a buffer of rest of data (except blobs)
+
+ To avoid double copying of data, we copy as many columns that fits into
+ the page. The rest goes into info->packed_row.
+
+ Using an extra buffer, instead of doing continous writes to different
+ pages, uses less code and we don't need to have to do a complex call
+ for every data segment we want to store.
+ */
+ if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
+ row->head_length))
+ DBUG_RETURN(1);
+
+ tmp_data_used= 0; /* Either 0 or last used byte in 'data' */
+ tmp_data= data;
+
+ if (row_extents_in_use)
+ {
+ uint copy_length= (bitmap_blocks->count - 2) * ROW_EXTENT_SIZE;
+ if (!tmp_data_used && tmp_data + copy_length > end_of_data)
+ {
+ tmp_data_used= tmp_data;
+ tmp_data= info->rec_buff;
+ }
+ row_extents_second_part= tmp_data;
+ /*
+ We will copy the extents here when we have figured out the tail
+ positions.
+ */
+ tmp_data+= copy_length;
+ }
+
+ /* Copy fields that has fixed lengths (primary key etc) */
+ for (rec= share->rec, end_field= rec + share->base.fixed_not_null_fields;
+ rec < end_field; rec++)
+ {
+ if (!tmp_data_used && tmp_data + rec->length > end_of_data)
+ {
+ tmp_data_used= tmp_data;
+ tmp_data= info->rec_buff;
+ }
+ memcpy(tmp_data, record + rec->offset, rec->length);
+ tmp_data+= rec->length;
+ }
+
+ /* Copy length of data for variable length fields */
+ if (!tmp_data_used && tmp_data + row->field_lengths_length > end_of_data)
+ {
+ tmp_data_used= tmp_data;
+ tmp_data= info->rec_buff;
+ }
+ field_length_data= row->field_lengths;
+ memcpy(tmp_data, field_length_data, row->field_lengths_length);
+ tmp_data+= row->field_lengths_length;
+
+ /* Copy variable length fields and fields with null/zero */
+ for (end_field= share->rec + share->base.fields - share->base.blobs;
+ rec < end_field ;
+ rec++)
+ {
+ const byte *field_pos;
+ ulong length;
+ if ((record[rec->null_pos] & rec->null_bit) ||
+ (row->empty_bits[rec->empty_pos] & rec->empty_bit))
+ continue;
+
+ field_pos= record + rec->offset;
+ switch ((enum en_fieldtype) rec->type) {
+ case FIELD_NORMAL: /* Fixed length field */
+ case FIELD_SKIP_PRESPACE:
+ case FIELD_SKIP_ZERO: /* Fixed length field */
+ length= rec->length;
+ break;
+ case FIELD_SKIP_ENDSPACE: /* CHAR */
+ /* Char that is space filled */
+ if (rec->length <= 255)
+ length= (uint) (uchar) *field_length_data++;
+ else
+ {
+ length= uint2korr(field_length_data);
+ field_length_data+= 2;
+ }
+ break;
+ case FIELD_VARCHAR:
+ if (rec->length <= 256)
+ {
+ length= (uint) (uchar) *field_length_data++;
+ field_pos++; /* Skip length byte */
+ }
+ else
+ {
+ length= uint2korr(field_length_data);
+ field_length_data+= 2;
+ field_pos+= 2;
+ }
+ break;
+ default: /* Wrong data */
+ DBUG_ASSERT(0);
+ break;
+ }
+ if (!tmp_data_used && tmp_data + length > end_of_data)
+ {
+ /* Data didn't fit in page; Change to use tmp buffer */
+ tmp_data_used= tmp_data;
+ tmp_data= info->rec_buff;
+ }
+ memcpy((char*) tmp_data, (char*) field_pos, length);
+ tmp_data+= length;
+ }
+
+ block= head_block + head_block->sub_blocks; /* Point to first blob data */
+
+ end_field= rec + share->base.blobs;
+ blob_lengths= row->blob_lengths;
+ if (!tmp_data_used)
+ {
+ /* Still room on page; Copy as many blobs we can into this page */
+ data= tmp_data;
+ for (; rec < end_field && *blob_lengths < (ulong) (end_of_data - data);
+ rec++, blob_lengths++)
+ {
+ byte *tmp_pos;
+ uint length;
+ if (!*blob_lengths) /* Null or "" */
+ continue;
+ length= rec->length - maria_portable_sizeof_char_ptr;
+ memcpy_fixed((byte*) &tmp_pos, record + rec->offset + length,
+ sizeof(char*));
+ memcpy(data, tmp_pos, *blob_lengths);
+ data+= *blob_lengths;
+ /* Skip over tail page that was to be used to store blob */
+ block++;
+ bitmap_blocks->tail_page_skipped= 1;
+ }
+ if (head_block->sub_blocks > 1)
+ {
+ /* We have allocated pages that where not used */
+ bitmap_blocks->page_skipped= 1;
+ }
+ }
+ else
+ data= tmp_data_used; /* Get last used on page */
+
+ {
+ /* Update page directory */
+ uint length= (uint) (data - row_pos->data);
+ DBUG_PRINT("info", ("head length: %u", length));
+ if (length < info->s->base.min_row_length)
+ length= info->s->base.min_row_length;
+
+ int2store(row_pos->dir + 2, length);
+ /* update empty space at start of block */
+ row_pos->empty_space-= length;
+ int2store(page_buff + EMPTY_SPACE_OFFSET, row_pos->empty_space);
+ /* Mark in bitmaps how the current page was actually used */
+ head_block->empty_space= row_pos->empty_space;
+ if (page_buff[DIR_ENTRY_OFFSET] == (char) MAX_ROWS_PER_PAGE)
+ head_block->empty_space= 0; /* Page is full */
+ head_block->used= BLOCKUSED_USED;
+ }
+
+ /*
+ Now we have to write tail pages, as we need to store the position
+ to them in the row extent header.
+
+ We first write out all blob tails, to be able to store them in
+ the current page or 'tmp_data'.
+
+ Then we write the tail of the non-blob fields (The position to the
+ tail page is stored either in row header, the extents in the head
+ page or in the first full page of the non-blob data. It's never in
+ the tail page of the non-blob data)
+ */
+
+ if (row_extents_in_use)
+ {
+ if (rec != end_field) /* If blob fields */
+ {
+ MARIA_COLUMNDEF *save_rec= rec;
+ MARIA_BITMAP_BLOCK *save_block= block;
+ MARIA_BITMAP_BLOCK *end_block;
+ ulong *save_blob_lengths= blob_lengths;
+
+ for (; rec < end_field; rec++, blob_lengths++)
+ {
+ byte *blob_pos;
+ if (!*blob_lengths) /* Null or "" */
+ continue;
+ if (block[block->sub_blocks - 1].used & BLOCKUSED_TAIL)
+ {
+ uint length;
+ length= rec->length - maria_portable_sizeof_char_ptr;
+ memcpy_fixed((byte *) &blob_pos, record + rec->offset + length,
+ sizeof(char*));
+ length= *blob_lengths % FULL_PAGE_SIZE(block_size); /* tail size */
+ if (write_tail(info, block + block->sub_blocks-1,
+ blob_pos + *blob_lengths - length,
+ length))
+ goto disk_err;
+ }
+ for (end_block= block + block->sub_blocks; block < end_block; block++)
+ {
+ /*
+ Set only a bit, to not cause bitmap code to belive a block is full
+ when there is still a lot of entries in it
+ */
+ block->used|= BLOCKUSED_USED;
+ }
+ }
+ rec= save_rec;
+ block= save_block;
+ blob_lengths= save_blob_lengths;
+ }
+
+ if (tmp_data_used) /* non blob data overflows */
+ {
+ MARIA_BITMAP_BLOCK *cur_block, *end_block;
+ MARIA_BITMAP_BLOCK *head_tail_block= 0;
+ ulong length;
+ ulong data_length= (tmp_data - info->rec_buff);
+
+#ifdef SANITY_CHECK
+ if (cur_block->sub_blocks == 1)
+ goto crashed; /* no reserved full or tails */
+#endif
+
+ /*
+ Find out where to write tail for non-blob fields.
+
+ Problem here is that the bitmap code may have allocated more
+ space than we need. We have to handle the following cases:
+
+ - Bitmap code allocated a tail page we don't need.
+ - The last full page allocated needs to be changed to a tail page
+ (Because we put more data than we thought on the head page)
+
+ The reserved pages in bitmap_blocks for the main page has one of
+ the following allocations:
+ - Full pages, with following blocks:
+ # * full pages
+ empty page ; To be used if we change last full to tail page. This
+ has 'count' = 0.
+ tail page (optional, if last full page was part full)
+ - One tail page
+ */
+
+ cur_block= head_block + 1;
+ end_block= head_block + head_block->sub_blocks;
+ while (data_length >= (length= (cur_block->page_count *
+ FULL_PAGE_SIZE(block_size))))
+ {
+#ifdef SANITY_CHECK
+ if ((cur_block == end_block) || (cur_block->used & BLOCKUSED_BIT))
+ goto crashed;
+#endif
+ data_length-= length;
+ (cur_block++)->used= BLOCKUSED_USED;
+ }
+ if (data_length)
+ {
+#ifdef SANITY_CHECK
+ if ((cur_block == end_block))
+ goto crashed;
+#endif
+ if (cur_block->used & BLOCKUSED_TAIL)
+ {
+ DBUG_ASSERT(data_length < MAX_TAIL_SIZE(block_size));
+ /* tail written to full tail page */
+ cur_block->used= BLOCKUSED_USED;
+ head_tail_block= cur_block;
+ }
+ else if (data_length > length - MAX_TAIL_SIZE(block_size))
+ {
+ /* tail written to full page */
+ cur_block->used= BLOCKUSED_USED;
+ if ((cur_block != end_block - 1) &&
+ (end_block[-1].used & BLOCKUSED_TAIL))
+ bitmap_blocks->tail_page_skipped= 1;
+ }
+ else
+ {
+ /*
+ cur_block is a full block, followed by an empty and optional
+ tail block. Change cur_block to a tail block or split it
+ into full blocks and tail blocks.
+ */
+ DBUG_ASSERT(cur_block[1].page_count == 0);
+ if (cur_block->page_count == 1)
+ {
+ /* convert full block to tail block */
+ cur_block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
+ head_tail_block= cur_block;
+ }
+ else
+ {
+ DBUG_ASSERT(data_length < length - FULL_PAGE_SIZE(block_size));
+ DBUG_PRINT("info", ("Splitting blocks into full and tail"));
+ cur_block[1].page= (cur_block->page + cur_block->page_count - 1);
+ cur_block[1].page_count= 1;
+ cur_block[1].used= 1;
+ cur_block->page_count--;
+ cur_block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
+ head_tail_block= cur_block + 1;
+ }
+ if (end_block[-1].used & BLOCKUSED_TAIL)
+ bitmap_blocks->tail_page_skipped= 1;
+ }
+ }
+ else
+ {
+ /* Must be an empty or tail page */
+ DBUG_ASSERT(cur_block->page_count == 0 ||
+ cur_block->used & BLOCKUSED_TAIL);
+ if (end_block[-1].used & BLOCKUSED_TAIL)
+ bitmap_blocks->tail_page_skipped= 1;
+ }
+
+ /*
+ Write all extents into page or tmp_buff
+
+ Note that we still don't have a correct position for the tail
+ of the non-blob fields.
+ */
+ store_extent_info(row_extents_first_part,
+ row_extents_second_part,
+ head_block+1, bitmap_blocks->count - 1);
+ if (head_tail_block)
+ {
+ ulong data_length= (tmp_data - info->rec_buff);
+ uint length;
+ byte *extent_data;
+
+ length= (uint) (data_length % FULL_PAGE_SIZE(block_size));
+ if (write_tail(info, head_tail_block, data + data_length - length,
+ length))
+ goto disk_err;
+ tmp_data-= length; /* Remove the tail */
+
+ /* Store the tail position for the non-blob fields */
+ if (head_tail_block == head_block + 1)
+ extent_data= row_extents_first_part;
+ else
+ extent_data= row_extents_second_part +
+ ((head_tail_block - head_block) - 2) * ROW_EXTENT_SIZE;
+ int5store(extent_data, head_tail_block->page);
+ int2store(extent_data + 5, head_tail_block->page_count);
+ }
+ }
+ else
+ store_extent_info(row_extents_first_part,
+ row_extents_second_part,
+ head_block+1, bitmap_blocks->count - 1);
+ }
+ /* Increase data file size, if extended */
+ position= (my_off_t) head_block->page * block_size;
+ if (info->state->data_file_length <= position)
+ info->state->data_file_length= position + block_size;
+ if (key_cache_write(share->key_cache,
+ info->dfile, position, 0,
+ page_buff, share->block_size, share->block_size, 1))
+ goto disk_err;
+
+ if (tmp_data_used)
+ {
+ /* Write data stored in info->rec_buff to pages */
+ DBUG_ASSERT(bitmap_blocks->count != 0);
+ if (write_full_pages(info, bitmap_blocks->block + 1, info->rec_buff,
+ (ulong) (tmp_data - info->rec_buff)))
+ goto disk_err;
+ }
+
+ /* Write rest of blobs (data, but no tails as they are already written) */
+ for (; rec < end_field; rec++, blob_lengths++)
+ {
+ byte *blob_pos;
+ uint length;
+ ulong blob_length;
+ if (!*blob_lengths) /* Null or "" */
+ continue;
+ length= rec->length - maria_portable_sizeof_char_ptr;
+ memcpy_fixed((byte*) &blob_pos, record + rec->offset + length,
+ sizeof(char*));
+ /* remove tail part */
+ blob_length= *blob_lengths;
+ if (block[block->sub_blocks - 1].used & BLOCKUSED_TAIL)
+ blob_length-= (blob_length % FULL_PAGE_SIZE(block_size));
+
+ if (write_full_pages(info, block, blob_pos, blob_length))
+ goto disk_err;
+ block+= block->sub_blocks;
+ }
+ /* Release not used space in used pages */
+ if (_ma_bitmap_release_unused(info, bitmap_blocks))
+ goto disk_err;
+ DBUG_RETURN(0);
+
+crashed:
+ my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */
+disk_err:
+ /* Something was wrong with data on record */
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Write a record (to get the row id for it)
+
+ SYNOPSIS
+ _ma_write_init_block_record()
+ info Maria handler
+ record Record to write
+
+ NOTES
+ This is done BEFORE we write the keys to the row!
+
+ RETURN
+ HA_OFFSET_ERROR Something went wrong
+ # Rowid for row
+*/
+
+MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
+ const byte *record)
+{
+ MARIA_BITMAP_BLOCKS *blocks= &info->cur_row.insert_blocks;
+ struct st_row_pos_info row_pos;
+ DBUG_ENTER("_ma_write_init_block_record");
+
+ calc_record_size(info, record, &info->cur_row);
+ if (_ma_bitmap_find_place(info, &info->cur_row, blocks))
+ DBUG_RETURN(HA_OFFSET_ERROR); /* Error reding bitmap */
+ if (get_head_or_tail_page(info, blocks->block, info->buff,
+ info->s->base.min_row_length, HEAD_PAGE, &row_pos))
+ DBUG_RETURN(HA_OFFSET_ERROR);
+ info->cur_row.lastpos= ma_recordpos(blocks->block->page, row_pos.offset);
+ if (info->s->calc_checksum)
+ info->cur_row.checksum= (info->s->calc_checksum)(info,record);
+ if (write_block_record(info, record, &info->cur_row, blocks, &row_pos))
+ DBUG_RETURN(HA_OFFSET_ERROR); /* Error reading bitmap */
+ DBUG_PRINT("exit", ("Rowid: %lu", (ulong) info->cur_row.lastpos));
+ DBUG_RETURN(info->cur_row.lastpos);
+}
+
+
+/*
+ Dummy function for (*info->s->write_record)()
+
+ Nothing to do here, as we already wrote the record in
+ _ma_write_init_block_record()
+*/
+
+my_bool _ma_write_block_record(MARIA_HA *info __attribute__ ((unused)),
+ const byte *record __attribute__ ((unused))
+)
+{
+ return 0; /* Row already written */
+}
+
+
+/*
+ Remove row written by _ma_write_block_record
+
+ SYNOPSIS
+ _ma_abort_write_block_record()
+ info Maria handler
+
+ INFORMATION
+ This is called in case we got a duplicate unique key while
+ writing keys.
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+my_bool _ma_write_abort_block_record(MARIA_HA *info)
+{
+ my_bool res= 0;
+ MARIA_BITMAP_BLOCKS *blocks= &info->cur_row.insert_blocks;
+ MARIA_BITMAP_BLOCK *block, *end;
+ DBUG_ENTER("_ma_abort_write_block_record");
+
+ if (delete_head_or_tail(info,
+ ma_recordpos_to_page(info->cur_row.lastpos),
+ ma_recordpos_to_offset(info->cur_row.lastpos), 1))
+ res= 1;
+ for (block= blocks->block + 1, end= block + blocks->count - 1; block < end;
+ block++)
+ {
+ if (block->used & BLOCKUSED_TAIL)
+ {
+ /*
+ block->page_count is set to the tail directory entry number in
+ write_block_record()
+ */
+ if (delete_head_or_tail(info, block->page, block->page_count & ~TAIL_BIT,
+ 0))
+ res= 1;
+ }
+ else
+ {
+ pthread_mutex_lock(&info->s->bitmap.bitmap_lock);
+ if (_ma_reset_full_page_bits(info, &info->s->bitmap, block->page,
+ block->page_count))
+ res= 1;
+ pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
+ }
+ }
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Update a record
+
+ NOTES
+ For the moment, we assume that info->curr_row.extents is always updated
+ when a row is read. In the future we may decide to read this on demand
+ for rows split into many extents.
+*/
+
+my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
+ const byte *record)
+{
+ MARIA_BITMAP_BLOCKS *blocks= &info->cur_row.insert_blocks;
+ byte *buff;
+ MARIA_ROW *cur_row= &info->cur_row, *new_row= &info->new_row;
+ uint rownr, org_empty_size, head_length;
+ uint block_size= info->s->block_size;
+ byte *dir;
+ ulonglong page;
+ struct st_row_pos_info row_pos;
+ DBUG_ENTER("_ma_update_block_record");
+ DBUG_PRINT("enter", ("rowid: %lu", (long) record_pos));
+
+ calc_record_size(info, record, new_row);
+ page= ma_recordpos_to_page(record_pos);
+
+ if (!(buff= key_cache_read(info->s->key_cache,
+ info->dfile, (my_off_t) page * block_size, 0,
+ info->buff, block_size, block_size, 0)))
+ DBUG_RETURN(1);
+ org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
+ rownr= ma_recordpos_to_offset(record_pos);
+ dir= (buff + block_size - DIR_ENTRY_SIZE * rownr -
+ DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
+
+ if ((org_empty_size + cur_row->head_length) >= new_row->total_length)
+ {
+ uint empty, offset, length;
+ MARIA_BITMAP_BLOCK block;
+
+ /*
+ We can fit the new row in the same page as the original head part
+ of the row
+ */
+ block.org_bitmap_value= _ma_free_size_to_head_pattern(&info->s->bitmap,
+ org_empty_size);
+ offset= uint2korr(dir);
+ length= uint2korr(dir + 2);
+ empty= 0;
+ if (new_row->total_length > length)
+ {
+ /* See if there is empty space after */
+ if (rownr != (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET] - 1)
+ empty= empty_pos_after_row(dir) - (offset + length);
+ if (new_row->total_length > length + empty)
+ {
+ compact_page(buff, info->s->block_size, rownr);
+ org_empty_size= 0;
+ length= uint2korr(dir + 2);
+ }
+ }
+ row_pos.buff= buff;
+ row_pos.offset= rownr;
+ row_pos.empty_space= org_empty_size + length;
+ row_pos.dir= dir;
+ row_pos.data= buff + uint2korr(dir);
+ row_pos.length= length + empty;
+ blocks->block= &block;
+ blocks->count= 1;
+ block.page= page;
+ block.sub_blocks= 1;
+ block.used= BLOCKUSED_USED | BLOCKUSED_USE_ORG_BITMAP;
+ block.empty_space= row_pos.empty_space;
+ /* Update cur_row, if someone calls update at once again */
+ cur_row->head_length= new_row->total_length;
+ if (_ma_bitmap_free_full_pages(info, cur_row->extents,
+ cur_row->extents_count))
+ DBUG_RETURN(1);
+ DBUG_RETURN(write_block_record(info, record, new_row, blocks, &row_pos));
+ }
+ /*
+ Allocate all size in block for record
+ QQ: Need to improve this to do compact if we can fit one more blob into
+ the head page
+ */
+ head_length= uint2korr(dir + 2);
+ if (buff[PAGE_TYPE_OFFSET] & PAGE_CAN_BE_COMPACTED && org_empty_size &&
+ (head_length < new_row->head_length ||
+ (new_row->total_length <= head_length &&
+ org_empty_size + head_length >= new_row->total_length)))
+ {
+ compact_page(buff, info->s->block_size, rownr);
+ org_empty_size= 0;
+ head_length= uint2korr(dir + 2);
+ }
+
+ /* Delete old row */
+ if (delete_tails(info, cur_row->tail_positions))
+ DBUG_RETURN(1);
+ if (_ma_bitmap_free_full_pages(info, cur_row->extents,
+ cur_row->extents_count))
+ DBUG_RETURN(1);
+ if (_ma_bitmap_find_new_place(info, new_row, page, head_length, blocks))
+ DBUG_RETURN(1);
+
+ row_pos.buff= buff;
+ row_pos.offset= rownr;
+ row_pos.empty_space= org_empty_size + head_length;
+ row_pos.dir= dir;
+ row_pos.data= buff + uint2korr(dir);
+ row_pos.length= head_length;
+ DBUG_RETURN(write_block_record(info, record, new_row, blocks, &row_pos));
+}
+
+
+/*
+ Delete a head a tail part
+
+ SYNOPSIS
+ delete_head_or_tail()
+ info Maria handler
+ page Page (not file offset!) on which the row is
+ head 1 if this is a head page
+
+ NOTES
+ Uses info->keyread_buff
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+static my_bool delete_head_or_tail(MARIA_HA *info,
+ ulonglong page, uint record_number,
+ my_bool head)
+{
+ MARIA_SHARE *share= info->s;
+ uint number_of_records, empty_space, length;
+ uint block_size= share->block_size;
+ byte *buff, *dir;
+ my_off_t position;
+ DBUG_ENTER("delete_head_or_tail");
+
+ info->keybuff_used= 1;
+ if (!(buff= key_cache_read(share->key_cache,
+ info->dfile, page * block_size, 0,
+ info->keyread_buff,
+ block_size, block_size, 0)))
+ DBUG_RETURN(1);
+
+ number_of_records= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET];
+#ifdef SANITY_CHECKS
+ if (record_number >= number_of_records ||
+ record_number > MAX_ROWS_PER_PAGE ||
+ record_number > ((block_size - LSN_SIZE - PAGE_TYPE_SIZE - 1 -
+ PAGE_SUFFIX_SIZE) / (DIR_ENTRY_SIZE + MIN_TAIL_SIZE)))
+ {
+ DBUG_PRINT("error", ("record_number: %u number_of_records: %u",
+ record_number, number_of_records));
+ DBUG_RETURN(1);
+ }
+#endif
+
+ dir= (buff + block_size - DIR_ENTRY_SIZE * record_number -
+ DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
+ dir[0]= dir[1]= 0; /* Delete entry */
+ length= uint2korr(dir + 2);
+ empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
+
+ if (record_number == number_of_records - 1)
+ {
+ /* Delete this entry and all following empty directory entries */
+ byte *end= buff + block_size - PAGE_SUFFIX_SIZE;
+ do
+ {
+ number_of_records--;
+ dir+= DIR_ENTRY_SIZE;
+ empty_space+= DIR_ENTRY_SIZE;
+ } while (dir < end && dir[0] == 0 && dir[1] == 0);
+ buff[DIR_ENTRY_OFFSET]= (byte) (uchar) number_of_records;
+ }
+ empty_space+= length;
+ if (number_of_records != 0)
+ {
+ int2store(buff + EMPTY_SPACE_OFFSET, empty_space);
+ buff[PAGE_TYPE_OFFSET]|= (byte) PAGE_CAN_BE_COMPACTED;
+ position= (my_off_t) page * block_size;
+ if (key_cache_write(share->key_cache,
+ info->dfile, position, 0,
+ buff, block_size, block_size, 1))
+ DBUG_RETURN(1);
+ }
+ else
+ {
+ DBUG_ASSERT(empty_space >= info->s->bitmap.sizes[0]);
+ }
+ DBUG_PRINT("info", ("empty_space: %u", empty_space));
+ DBUG_RETURN(_ma_bitmap_set(info, page, head, empty_space));
+}
+
+
+/*
+ delete all tails
+
+ SYNOPSIS
+ delete_tails()
+ info Handler
+ tails Pointer to vector of tail positions, ending with 0
+
+ NOTES
+ Uses info->keyread_buff
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails)
+{
+ my_bool res= 0;
+ DBUG_ENTER("delete_tails");
+ for (; *tails; tails++)
+ {
+ if (delete_head_or_tail(info,
+ ma_recordpos_to_page(*tails),
+ ma_recordpos_to_offset(*tails), 0))
+ res= 1;
+ }
+ DBUG_RETURN(res);
+}
+
+
+/*
+ Delete a record
+
+ NOTES
+ For the moment, we assume that info->cur_row.extents is always updated
+ when a row is read. In the future we may decide to read this on demand
+ for rows with many splits.
+*/
+
+my_bool _ma_delete_block_record(MARIA_HA *info)
+{
+ DBUG_ENTER("_ma_delete_block_record");
+ if (delete_head_or_tail(info,
+ ma_recordpos_to_page(info->cur_row.lastpos),
+ ma_recordpos_to_offset(info->cur_row.lastpos),
+ 1) ||
+ delete_tails(info, info->cur_row.tail_positions))
+ DBUG_RETURN(1);
+ DBUG_RETURN(_ma_bitmap_free_full_pages(info, info->cur_row.extents,
+ info->cur_row.extents_count));
+}
+
+
+/****************************************************************************
+ Reading of records
+****************************************************************************/
+
+/*
+ Read position to record from record directory at end of page
+
+ SYNOPSIS
+ get_record_position()
+ buff page buffer
+ block_size block size for page
+ record_number Record number in index
+ end_of_data pointer to end of data for record
+
+ RETURN
+ 0 Error in data
+ # Pointer to start of record.
+ In this case *end_of_data is set.
+*/
+
+static byte *get_record_position(byte *buff, uint block_size,
+ uint record_number, byte **end_of_data)
+{
+ uint number_of_records= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET];
+ byte *dir;
+ byte *data;
+ uint offset, length;
+
+#ifdef SANITY_CHECKS
+ if (record_number >= number_of_records ||
+ record_number > MAX_ROWS_PER_PAGE ||
+ record_number > ((block_size - PAGE_HEADER_SIZE - PAGE_SUFFIX_SIZE) /
+ (DIR_ENTRY_SIZE + MIN_TAIL_SIZE)))
+ {
+ DBUG_PRINT("error",
+ ("Wrong row number: record_number: %u number_of_records: %u",
+ record_number, number_of_records));
+ return 0;
+ }
+#endif
+
+ dir= (buff + block_size - DIR_ENTRY_SIZE * record_number -
+ DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
+ offset= uint2korr(dir);
+ length= uint2korr(dir + 2);
+#ifdef SANITY_CHECKS
+ if (offset < PAGE_HEADER_SIZE ||
+ offset + length > (block_size -
+ number_of_records * DIR_ENTRY_SIZE -
+ PAGE_SUFFIX_SIZE))
+ {
+ DBUG_PRINT("error",
+ ("Wrong row position: record_number: %u offset: %u "
+ "length: %u number_of_records: %u",
+ record_number, offset, length, number_of_records));
+ return 0;
+ }
+#endif
+ data= buff + offset;
+ *end_of_data= data + length;
+ return data;
+}
+
+
+/*
+ Init extent
+
+ NOTES
+ extent is a cursor over which pages to read
+*/
+
+static void init_extent(MARIA_EXTENT_CURSOR *extent, byte *extent_info,
+ uint extents, MARIA_RECORD_POS *tail_positions)
+{
+ uint page_count;
+ extent->extent= extent_info;
+ extent->extent_count= extents;
+ extent->page= uint5korr(extent_info); /* First extent */
+ page_count= uint2korr(extent_info+5);
+ extent->page_count= page_count & ~TAIL_BIT;
+ extent->tail= page_count & TAIL_BIT;
+ extent->tail_positions= tail_positions;
+}
+
+
+/*
+ Read next extent
+
+ SYNOPSIS
+ read_next_extent()
+ info Maria handler
+ extent Pointer to current extent (this is updated to point
+ to next)
+ end_of_data Pointer to end of data in read block (out)
+
+ NOTES
+ New block is read into info->buff
+
+ RETURN
+ 0 Error; my_errno is set
+ # Pointer to start of data in read block
+ In this case end_of_data is updated to point to end of data.
+*/
+
+static byte *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
+ byte **end_of_data)
+{
+ MARIA_SHARE *share= info->s;
+ byte *buff, *data;
+ DBUG_ENTER("read_next_extent");
+
+ if (!extent->page_count)
+ {
+ uint page_count;
+ if (!--extent->extent_count)
+ goto crashed;
+ extent->extent+= ROW_EXTENT_SIZE;
+ extent->page= uint5korr(extent->extent);
+ page_count= uint2korr(extent->extent+ROW_EXTENT_PAGE_SIZE);
+ extent->tail= page_count & TAIL_BIT;
+ extent->page_count= (page_count & ~TAIL_BIT);
+ extent->first_extent= 0;
+ DBUG_PRINT("info",("New extent. Page: %lu page_count: %u tail_flag: %d",
+ (ulong) extent->page, extent->page_count,
+ extent->tail != 0));
+ }
+
+ if (info->cur_row.empty_bits != info->cur_row.empty_bits_buffer)
+ {
+ /*
+ First read of extents: Move data from info->buff to
+ internals buffers.
+ */
+ memcpy(info->cur_row.empty_bits_buffer, info->cur_row.empty_bits,
+ share->base.pack_bytes);
+ info->cur_row.empty_bits= info->cur_row.empty_bits_buffer;
+ }
+
+ if (!(buff= key_cache_read(share->key_cache,
+ info->dfile, extent->page * share->block_size, 0,
+ info->buff,
+ share->block_size, share->block_size, 0)))
+ {
+ /* check if we tried to read over end of file (ie: bad data in record) */
+ if ((extent->page + 1) * share->block_size > info->state->data_file_length)
+ goto crashed;
+ DBUG_RETURN(0);
+ }
+ if (!extent->tail)
+ {
+ /* Full data page */
+ DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == BLOB_PAGE);
+ extent->page++; /* point to next page */
+ extent->page_count--;
+ *end_of_data= buff + share->block_size;
+ info->cur_row.full_page_count++; /* For maria_chk */
+ DBUG_RETURN(extent->data_start= buff + LSN_SIZE + PAGE_TYPE_SIZE);
+ }
+ /* Found tail. page_count is in this case the position in the tail page */
+
+ DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == TAIL_PAGE);
+ *(extent->tail_positions++)= ma_recordpos(extent->page,
+ extent->page_count);
+ info->cur_row.tail_count++; /* For maria_chk */
+
+ if (!(data= get_record_position(buff, share->block_size,
+ extent->page_count,
+ end_of_data)))
+ goto crashed;
+ extent->data_start= data;
+ extent->page_count= 0; /* No more data in extent */
+ DBUG_RETURN(data);
+
+
+crashed:
+ my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */
+ DBUG_PRINT("error", ("wrong extent information"));
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Read data that may be split over many blocks
+
+ SYNOPSIS
+ read_long_data()
+ info Maria handler
+ to Store result string here (this is allocated)
+ extent Pointer to current extent position
+ data Current position in buffer
+ end_of_data End of data in buffer
+
+ NOTES
+ When we have to read a new buffer, it's read into info->buff
+
+ This loop is implemented by goto's instead of a for() loop as
+ the code is notable smaller and faster this way (and it's not nice
+ to jump into a for loop() or into a 'then' clause)
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+static my_bool read_long_data(MARIA_HA *info, byte *to, ulong length,
+ MARIA_EXTENT_CURSOR *extent,
+ byte **data, byte **end_of_data)
+{
+ DBUG_ENTER("read_long_data");
+ DBUG_PRINT("enter", ("length: %lu", length));
+ DBUG_ASSERT(*data <= *end_of_data);
+
+ for(;;)
+ {
+ uint left_length;
+ left_length= (uint) (*end_of_data - *data);
+ if (likely(left_length >= length))
+ {
+ memcpy(to, *data, length);
+ (*data)+= length;
+ DBUG_RETURN(0);
+ }
+ memcpy(to, *data, left_length);
+ to+= left_length;
+ length-= left_length;
+ if (!(*data= read_next_extent(info, extent, end_of_data)))
+ break;
+ }
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Read a record from page (helper function for _ma_read_block_record())
+
+ SYNOPSIS
+ _ma_read_block_record2()
+ info Maria handler
+ record Store record here
+ data Start of head data for row
+ end_of_data End of data for row
+
+ NOTES
+ The head page is already read by caller
+ Following data is update in info->cur_row:
+
+ cur_row.head_length is set to size of entry in head block
+ cur_row.tail_positions is set to point to all tail blocks
+ cur_row.extents points to extents data
+ cur_row.extents_counts contains number of extents
+ cur_row.empty_bits points to empty bits part in read record
+ cur_row.field_lengths contains packed length of all fields
+
+ RETURN
+ 0 ok
+ # Error code
+*/
+
+int _ma_read_block_record2(MARIA_HA *info, byte *record,
+ byte *data, byte *end_of_data)
+{
+ MARIA_SHARE *share= info->s;
+ byte *field_length_data, *blob_buffer, *start_of_data;
+ uint flag, null_bytes, cur_null_bytes, row_extents, field_lengths;
+ my_bool found_blob= 0;
+ MARIA_EXTENT_CURSOR extent;
+ MARIA_COLUMNDEF *rec, *end_field;
+ DBUG_ENTER("_ma_read_block_record2");
+
+ LINT_INIT(field_lengths);
+ LINT_INIT(field_length_data);
+ LINT_INIT(blob_buffer);
+
+ start_of_data= data;
+ flag= (uint) (uchar) data[0];
+ cur_null_bytes= share->base.original_null_bytes;
+ null_bytes= share->base.null_bytes;
+ info->cur_row.head_length= (uint) (end_of_data - data);
+ info->cur_row.full_page_count= info->cur_row.tail_count= 0;
+
+ /* Skip trans header (for now, until we have MVCC csupport) */
+ data+= total_header_size[(flag & PRECALC_HEADER_BITMASK)];
+ if (flag & ROW_FLAG_NULLS_EXTENDED)
+ cur_null_bytes+= data[-1];
+
+ row_extents= 0;
+ if (flag & ROW_FLAG_EXTENTS)
+ {
+ uint row_extent_size;
+ /*
+ Record is split over many data pages.
+ Get number of extents and first extent
+ */
+ get_key_length(row_extents, data);
+ info->cur_row.extents_count= row_extents;
+ row_extent_size= row_extents * ROW_EXTENT_SIZE;
+ if (info->cur_row.extents_buffer_length < row_extent_size &&
+ _ma_alloc_buffer(&info->cur_row.extents,
+ &info->cur_row.extents_buffer_length,
+ row_extent_size))
+ DBUG_RETURN(my_errno);
+ memcpy(info->cur_row.extents, data, ROW_EXTENT_SIZE);
+ data+= ROW_EXTENT_SIZE;
+ init_extent(&extent, info->cur_row.extents, row_extents,
+ info->cur_row.tail_positions);
+ }
+ else
+ {
+ info->cur_row.extents_count= 0;
+ (*info->cur_row.tail_positions)= 0;
+ extent.page_count= 0;
+ extent.extent_count= 1;
+ }
+ extent.first_extent= 1;
+
+ if (share->base.max_field_lengths)
+ {
+ get_key_length(field_lengths, data);
+#ifdef SANITY_CHECKS
+ if (field_lengths > share->base.max_field_lengths)
+ goto err;
+#endif
+ }
+
+ if (share->calc_checksum)
+ info->cur_row.checksum= (uint) (uchar) *data++;
+ /* data now points on null bits */
+ memcpy(record, data, cur_null_bytes);
+ if (unlikely(cur_null_bytes != null_bytes))
+ {
+ /*
+ This only happens if we have added more NULL columns with
+ ALTER TABLE and are fetching an old, not yet modified old row
+ */
+ bzero(record + cur_null_bytes, (uint) (null_bytes - cur_null_bytes));
+ }
+ data+= null_bytes;
+ info->cur_row.empty_bits= (byte*) data; /* Pointer to empty bitmask */
+ data+= share->base.pack_bytes;
+
+ /* TODO: Use field offsets, instead of just skipping them */
+ data+= share->base.field_offsets * FIELD_OFFSET_SIZE;
+
+ /*
+ Read row extents (note that first extent was already read into
+ info->cur_row.extents above)
+ */
+ if (row_extents)
+ {
+ if (read_long_data(info, info->cur_row.extents + ROW_EXTENT_SIZE,
+ (row_extents - 1) * ROW_EXTENT_SIZE,
+ &extent, &data, &end_of_data))
+ DBUG_RETURN(my_errno);
+ }
+
+ /*
+ Data now points to start of fixed length field data that can't be null
+ or 'empty'. Note that these fields can't be split over blocks
+ */
+ for (rec= share->rec, end_field= rec + share->base.fixed_not_null_fields;
+ rec < end_field; rec++)
+ {
+ uint rec_length= rec->length;
+ if (data >= end_of_data &&
+ !(data= read_next_extent(info, &extent, &end_of_data)))
+ goto err;
+ memcpy(record + rec->offset, data, rec_length);
+ data+= rec_length;
+ }
+
+ /* Read array of field lengths. This may be stored in several extents */
+ if (share->base.max_field_lengths)
+ {
+ field_length_data= info->cur_row.field_lengths;
+ if (read_long_data(info, field_length_data, field_lengths, &extent,
+ &data, &end_of_data))
+ DBUG_RETURN(my_errno);
+ }
+
+ /* Read variable length data. Each of these may be split over many extents */
+ for (end_field= share->rec + share->base.fields; rec < end_field; rec++)
+ {
+ enum en_fieldtype type= (enum en_fieldtype) rec->type;
+ byte *field_pos= record + rec->offset;
+ /* First check if field is present in record */
+ if (record[rec->null_pos] & rec->null_bit)
+ continue;
+ else if (info->cur_row.empty_bits[rec->empty_pos] & rec->empty_bit)
+ {
+ if (type == FIELD_SKIP_ENDSPACE)
+ bfill(record + rec->offset, rec->length, ' ');
+ else
+ bzero(record + rec->offset, rec->fill_length);
+ continue;
+ }
+ switch (type) {
+ case FIELD_NORMAL: /* Fixed length field */
+ case FIELD_SKIP_PRESPACE:
+ case FIELD_SKIP_ZERO: /* Fixed length field */
+ if (data >= end_of_data &&
+ !(data= read_next_extent(info, &extent, &end_of_data)))
+ goto err;
+ memcpy(field_pos, data, rec->length);
+ data+= rec->length;
+ break;
+ case FIELD_SKIP_ENDSPACE: /* CHAR */
+ {
+ /* Char that is space filled */
+ uint length;
+ if (rec->length <= 255)
+ length= (uint) (uchar) *field_length_data++;
+ else
+ {
+ length= uint2korr(field_length_data);
+ field_length_data+= 2;
+ }
+#ifdef SANITY_CHECKS
+ if (length > rec->length)
+ goto err;
+#endif
+ if (read_long_data(info, field_pos, length, &extent, &data,
+ &end_of_data))
+ DBUG_RETURN(my_errno);
+ bfill(field_pos + length, rec->length - length, ' ');
+ break;
+ }
+ case FIELD_VARCHAR:
+ {
+ ulong length;
+ if (rec->length <= 256)
+ {
+ length= (uint) (uchar) (*field_pos++= *field_length_data++);
+ }
+ else
+ {
+ length= uint2korr(field_length_data);
+ field_pos[0]= field_length_data[0];
+ field_pos[1]= field_length_data[1];
+ field_pos+= 2;
+ field_length_data+= 2;
+ }
+ if (read_long_data(info, field_pos, length, &extent, &data,
+ &end_of_data))
+ DBUG_RETURN(my_errno);
+ break;
+ }
+ case FIELD_BLOB:
+ {
+ uint size_length= rec->length - maria_portable_sizeof_char_ptr;
+ ulong blob_length= _ma_calc_blob_length(size_length, field_length_data);
+
+ if (!found_blob)
+ {
+ /* Calculate total length for all blobs */
+ ulong blob_lengths= 0;
+ byte *length_data= field_length_data;
+ MARIA_COLUMNDEF *blob_field= rec;
+
+ found_blob= 1;
+ for (; blob_field < end_field; blob_field++)
+ {
+ uint size_length;
+ if ((record[blob_field->null_pos] & blob_field->null_bit) ||
+ (info->cur_row.empty_bits[blob_field->empty_pos] &
+ blob_field->empty_bit))
+ continue;
+ size_length= blob_field->length - maria_portable_sizeof_char_ptr;
+ blob_lengths+= _ma_calc_blob_length(size_length, length_data);
+ length_data+= size_length;
+ }
+ DBUG_PRINT("info", ("Total blob length: %lu", blob_lengths));
+ if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
+ blob_lengths))
+ DBUG_RETURN(my_errno);
+ blob_buffer= info->rec_buff;
+ }
+
+ memcpy(field_pos, field_length_data, size_length);
+ memcpy_fixed(field_pos + size_length, (byte *) & blob_buffer,
+ sizeof(char*));
+ field_length_data+= size_length;
+
+ /*
+ After we have read one extent, then each blob is in it's own extent
+ */
+ if (extent.first_extent && (ulong) (end_of_data - data) < blob_length)
+ end_of_data= data; /* Force read of next extent */
+
+ if (read_long_data(info, blob_buffer, blob_length, &extent, &data,
+ &end_of_data))
+ DBUG_RETURN(my_errno);
+ blob_buffer+= blob_length;
+ break;
+ }
+#ifdef EXTRA_DEBUG
+ default:
+ DBUG_ASSERT(0); /* purecov: deadcode */
+ goto err;
+#endif
+ }
+ continue;
+ }
+
+ if (row_extents)
+ {
+ DBUG_PRINT("info", ("Row read: page_count: %lu extent_count: %lu",
+ extent.page_count, extent.extent_count));
+ *extent.tail_positions= 0; /* End marker */
+ if (extent.page_count)
+ goto err;
+ if (extent.extent_count > 1)
+ if (check_if_zero(extent.extent,
+ (extent.extent_count-1) * ROW_EXTENT_SIZE))
+ goto err;
+ }
+ else
+ {
+ DBUG_PRINT("info", ("Row read"));
+ if (data != end_of_data && (uint) (end_of_data - start_of_data) >=
+ info->s->base.min_row_length)
+ goto err;
+ }
+
+ info->update|= HA_STATE_AKTIV; /* We have a aktive record */
+ DBUG_RETURN(0);
+
+err:
+ /* Something was wrong with data on record */
+ DBUG_PRINT("error", ("Found record with wrong data"));
+ DBUG_RETURN((my_errno= HA_ERR_WRONG_IN_RECORD));
+}
+
+
+/*
+ Read a record based on record position
+
+ SYNOPSIS
+ _ma_read_block_record()
+ info Maria handler
+ record Store record here
+ record_pos Record position
+*/
+
+int _ma_read_block_record(MARIA_HA *info, byte *record,
+ MARIA_RECORD_POS record_pos)
+{
+ byte *data, *end_of_data, *buff;
+ my_off_t page;
+ uint offset;
+ uint block_size= info->s->block_size;
+ DBUG_ENTER("_ma_read_block_record");
+ DBUG_PRINT("enter", ("rowid: %lu", (long) record_pos));
+
+ page= ma_recordpos_to_page(record_pos) * block_size;
+ offset= ma_recordpos_to_offset(record_pos);
+
+ if (!(buff= key_cache_read(info->s->key_cache,
+ info->dfile, page, 0, info->buff,
+ block_size, block_size, 1)))
+ DBUG_RETURN(1);
+ DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == HEAD_PAGE);
+ if (!(data= get_record_position(buff, block_size, offset, &end_of_data)))
+ {
+ my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */
+ DBUG_PRINT("error", ("Wrong directory entry in data block"));
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(_ma_read_block_record2(info, record, data, end_of_data));
+}
+
+
+/* compare unique constraint between stored rows */
+
+my_bool _ma_cmp_block_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
+ const byte *record, MARIA_RECORD_POS pos)
+{
+ byte *org_rec_buff, *old_record;
+ my_size_t org_rec_buff_size;
+ int error;
+ DBUG_ENTER("_ma_cmp_block_unique");
+
+ if (!(old_record= my_alloca(info->s->base.reclength)))
+ DBUG_RETURN(1);
+
+ /* Don't let the compare destroy blobs that may be in use */
+ org_rec_buff= info->rec_buff;
+ org_rec_buff_size= info->rec_buff_size;
+ if (info->s->base.blobs)
+ {
+ /* Force realloc of record buffer*/
+ info->rec_buff= 0;
+ info->rec_buff_size= 0;
+ }
+ error= _ma_read_block_record(info, old_record, pos);
+ if (!error)
+ error= _ma_unique_comp(def, record, old_record, def->null_are_equal);
+ if (info->s->base.blobs)
+ {
+ my_free(info->rec_buff, MYF(MY_ALLOW_ZERO_PTR));
+ info->rec_buff= org_rec_buff;
+ info->rec_buff_size= org_rec_buff_size;
+ }
+ DBUG_PRINT("exit", ("result: %d", error));
+ my_afree(old_record);
+ DBUG_RETURN(error != 0);
+}
+
+
+/****************************************************************************
+ Table scan
+****************************************************************************/
+
+/*
+ Allocate buffers for table scan
+
+ SYNOPSIS
+ _ma_scan_init_block_record(MARIA_HA *info)
+
+ IMPLEMENTATION
+ We allocate one buffer for the current bitmap and one buffer for the
+ current page
+*/
+
+my_bool _ma_scan_init_block_record(MARIA_HA *info)
+{
+ byte *ptr;
+ if (!(ptr= (byte *) my_malloc(info->s->block_size * 2, MYF(MY_WME))))
+ return (1);
+ info->scan.bitmap_buff= ptr;
+ info->scan.page_buff= ptr + info->s->block_size;
+ info->scan.bitmap_end= info->scan.bitmap_buff + info->s->bitmap.total_size;
+
+ /* Set scan variables to get _ma_scan_block() to start with reading bitmap */
+ info->scan.number_of_rows= 0;
+ info->scan.bitmap_pos= info->scan.bitmap_end;
+ info->scan.bitmap_page= (ulong) - (long) info->s->bitmap.pages_covered;
+ /*
+ We have to flush bitmap as we will read the bitmap from the page cache
+ while scanning rows
+ */
+ return _ma_flush_bitmap(info->s);
+}
+
+
+/* Free buffers allocated by _ma_scan_block_init() */
+
+void _ma_scan_end_block_record(MARIA_HA *info)
+{
+ my_free(info->scan.bitmap_buff, MYF(0));
+ info->scan.bitmap_buff= 0;
+}
+
+
+/*
+ Read next record while scanning table
+
+ SYNOPSIS
+ _ma_scan_block_record()
+ info Maria handler
+ record Store found here
+ record_pos Value stored in info->cur_row.next_pos after last call
+ skip_deleted
+
+ NOTES
+ - One must have called mi_scan() before this
+ - In this version, we don't actually need record_pos, we as easily
+ use a variable in info->scan
+
+ IMPLEMENTATION
+ Current code uses a lot of goto's to separate the different kind of
+ states we may be in. This gives us a minimum of executed if's for
+ the normal cases. I tried several different ways to code this, but
+ the current one was in the end the most readable and fastest.
+
+ RETURN
+ 0 ok
+ # Error code
+*/
+
+int _ma_scan_block_record(MARIA_HA *info, byte *record,
+ MARIA_RECORD_POS record_pos,
+ my_bool skip_deleted __attribute__ ((unused)))
+{
+ uint block_size;
+ my_off_t filepos;
+ DBUG_ENTER("_ma_scan_block_record");
+
+restart_record_read:
+ /* Find next row in current page */
+ if (likely(record_pos < info->scan.number_of_rows))
+ {
+ uint length, offset;
+ byte *data, *end_of_data;
+
+ while (!(offset= uint2korr(info->scan.dir)))
+ {
+ info->scan.dir-= DIR_ENTRY_SIZE;
+ record_pos++;
+#ifdef SANITY_CHECKS
+ if (info->scan.dir < info->scan.dir_end)
+ goto err;
+#endif
+ }
+ /* found row */
+ info->cur_row.lastpos= info->scan.row_base_page + record_pos;
+ info->cur_row.nextpos= record_pos + 1;
+ data= info->scan.page_buff + offset;
+ length= uint2korr(info->scan.dir + 2);
+ end_of_data= data + length;
+ info->scan.dir-= DIR_ENTRY_SIZE; /* Point to previous row */
+#ifdef SANITY_CHECKS
+ if (end_of_data > info->scan.dir_end ||
+ offset < PAGE_HEADER_SIZE || length < info->s->base.min_block_length)
+ goto err;
+#endif
+ DBUG_PRINT("info", ("rowid: %lu", (ulong) info->cur_row.lastpos));
+ DBUG_RETURN(_ma_read_block_record2(info, record, data, end_of_data));
+ }
+
+ /* Find next head page in current bitmap */
+restart_bitmap_scan:
+ block_size= info->s->block_size;
+ if (likely(info->scan.bitmap_pos < info->scan.bitmap_end))
+ {
+ byte *data= info->scan.bitmap_pos;
+ longlong bits= info->scan.bits;
+ uint bit_pos= info->scan.bit_pos;
+
+ do
+ {
+ while (likely(bits))
+ {
+ uint pattern= bits & 7;
+ bits >>= 3;
+ bit_pos++;
+ if (pattern > 0 && pattern <= 4)
+ {
+ /* Found head page; Read it */
+ ulong page;
+ info->scan.bitmap_pos= data;
+ info->scan.bits= bits;
+ info->scan.bit_pos= bit_pos;
+ page= (info->scan.bitmap_page + 1 +
+ (data - info->scan.bitmap_buff) / 6 * 16 + bit_pos - 1);
+ info->scan.row_base_page= ma_recordpos(page, 0);
+ if (!(key_cache_read(info->s->key_cache,
+ info->dfile,
+ (my_off_t) page * block_size,
+ 0, info->scan.page_buff,
+ block_size, block_size, 0)))
+ DBUG_RETURN(my_errno);
+ if (((info->scan.page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) !=
+ HEAD_PAGE) ||
+ (info->scan.number_of_rows=
+ (uint) (uchar) info->scan.page_buff[DIR_ENTRY_OFFSET]) == 0)
+ {
+ DBUG_PRINT("error", ("Wrong page header"));
+ DBUG_RETURN((my_errno= HA_ERR_WRONG_IN_RECORD));
+ }
+ info->scan.dir= (info->scan.page_buff + block_size -
+ PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE);
+ info->scan.dir_end= (info->scan.dir -
+ (info->scan.number_of_rows - 1) *
+ DIR_ENTRY_SIZE);
+ record_pos= 0;
+ goto restart_record_read;
+ }
+ }
+ for (data+= 6; data < info->scan.bitmap_end; data+= 6)
+ {
+ bits= uint6korr(data);
+ if (bits && ((bits & LL(04444444444444444)) != LL(04444444444444444)))
+ break;
+ }
+ bit_pos= 0;
+ } while (data < info->scan.bitmap_end);
+ }
+
+ /* Read next bitmap */
+ info->scan.bitmap_page+= info->s->bitmap.pages_covered;
+ filepos= (my_off_t) info->scan.bitmap_page * block_size;
+ if (unlikely(filepos >= info->state->data_file_length))
+ {
+ DBUG_RETURN((my_errno= HA_ERR_END_OF_FILE));
+ }
+ if (!(key_cache_read(info->s->key_cache, info->dfile, filepos,
+ 0, info->scan.bitmap_buff, block_size, block_size, 0)))
+ DBUG_RETURN(my_errno);
+ /* Skip scanning 'bits' in bitmap scan code */
+ info->scan.bitmap_pos= info->scan.bitmap_buff - 6;
+ info->scan.bits= 0;
+ goto restart_bitmap_scan;
+
+err:
+ DBUG_PRINT("error", ("Wrong data on page"));
+ DBUG_RETURN((my_errno= HA_ERR_WRONG_IN_RECORD));
+}
+
+
+/*
+ Compare a row against a stored one
+
+ NOTES
+ Not implemented, as block record is not supposed to be used in a shared
+ global environment
+*/
+
+my_bool _ma_compare_block_record(MARIA_HA *info __attribute__ ((unused)),
+ const byte *record __attribute__ ((unused)))
+{
+ return 0;
+}
+
+
+#ifndef DBUG_OFF
+
+static void _ma_print_directory(byte *buff, uint block_size)
+{
+ uint max_entry= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET], row= 0;
+ uint end_of_prev_row= PAGE_HEADER_SIZE;
+ byte *dir, *end;
+
+ dir= buff + block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE;
+ end= buff + block_size - DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE;
+
+ DBUG_LOCK_FILE;
+ fprintf(DBUG_FILE,"Directory dump (pos:length):\n");
+
+ for (row= 1; dir <= end ; end-= DIR_ENTRY_SIZE, row++)
+ {
+ uint offset= uint2korr(end);
+ uint length= uint2korr(end+2);
+ fprintf(DBUG_FILE, " %4u:%4u", offset, offset ? length : 0);
+ if (!(row % (80/12)))
+ fputc('\n', DBUG_FILE);
+ if (offset)
+ {
+ DBUG_ASSERT(offset >= end_of_prev_row);
+ end_of_prev_row= offset + length;
+ }
+ }
+ fputc('\n', DBUG_FILE);
+ fflush(DBUG_FILE);
+ DBUG_UNLOCK_FILE;
+}
+#endif /* DBUG_OFF */
+
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
new file mode 100644
index 00000000000..ec99dbfcae2
--- /dev/null
+++ b/storage/maria/ma_blockrec.h
@@ -0,0 +1,160 @@
+/* Copyright (C) 2007 Michael Widenius
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Storage of records in block
+*/
+
+#define LSN_SIZE 7
+#define DIRCOUNT_SIZE 1 /* Stores number of rows on page */
+#define EMPTY_SPACE_SIZE 2 /* Stores empty space on page */
+#define PAGE_TYPE_SIZE 1
+#define PAGE_SUFFIX_SIZE 0 /* Bytes for page suffix */
+#define PAGE_HEADER_SIZE (LSN_SIZE + DIRCOUNT_SIZE + EMPTY_SPACE_SIZE +\
+ PAGE_TYPE_SIZE)
+#define PAGE_OVERHEAD_SIZE (PAGE_HEADER_SIZE + DIR_ENTRY_SIZE + \
+ PAGE_SUFFIX_SIZE)
+#define BLOCK_RECORD_POINTER_SIZE 6
+
+#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - PAGE_TYPE_SIZE)
+
+#define ROW_EXTENT_PAGE_SIZE 5
+#define ROW_EXTENT_COUNT_SIZE 2
+#define ROW_EXTENT_SIZE (ROW_EXTENT_PAGE_SIZE + ROW_EXTENT_COUNT_SIZE)
+#define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */
+#define ELEMENTS_RESERVED_FOR_MAIN_PART 4
+#define EXTRA_LENGTH_FIELDS 3
+
+#define FLAG_SIZE 1
+#define TRANSID_SIZE 6
+#define VERPTR_SIZE 7
+#define DIR_ENTRY_SIZE 4
+#define FIELD_OFFSET_SIZE 2
+
+/* Minimum header size needed for a new row */
+#define BASE_ROW_HEADER_SIZE FLAG_SIZE
+#define TRANS_ROW_EXTRA_HEADER_SIZE TRANSID_SIZE
+
+#define PAGE_TYPE_MASK 127
+enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE };
+
+#define PAGE_TYPE_OFFSET LSN_SIZE
+#define DIR_ENTRY_OFFSET LSN_SIZE+PAGE_TYPE_SIZE
+#define EMPTY_SPACE_OFFSET (DIR_ENTRY_OFFSET + DIRCOUNT_SIZE)
+
+#define PAGE_CAN_BE_COMPACTED 128 /* Bit in PAGE_TYPE */
+
+/* Bits used for flag byte (one byte, first in record) */
+#define ROW_FLAG_TRANSID 1
+#define ROW_FLAG_VER_PTR 2
+#define ROW_FLAG_DELETE_TRANSID 4
+#define ROW_FLAG_NULLS_EXTENDED 8
+#define ROW_FLAG_EXTENTS 128
+#define ROW_FLAG_ALL (1+2+4+8+128)
+
+/* Variables that affects how data pages are utilized */
+#define MIN_TAIL_SIZE 32
+
+/* Fixed part of Max possible header size; See table in ma_blockrec.c */
+#define MAX_FIXED_HEADER_SIZE (FLAG_SIZE + 3 + ROW_EXTENT_SIZE + 3)
+#define TRANS_MAX_FIXED_HEADER_SIZE (MAX_FIXED_HEADER_SIZE + \
+ FLAG_SIZE + TRANSID_SIZE + VERPTR_SIZE + \
+ TRANSID_SIZE)
+
+/* We use 1 byte in record header to store number of directory entries */
+#define MAX_ROWS_PER_PAGE 255
+
+/* Bits for MARIA_BITMAP_BLOCKS->used */
+#define BLOCKUSED_USED 1
+#define BLOCKUSED_USE_ORG_BITMAP 2
+#define BLOCKUSED_TAIL 4
+
+/* defines that affects allocation (density) of data */
+
+/* If we fill up a block to 75 %, don't create a new tail page for it */
+#define MAX_TAIL_SIZE(block_size) ((block_size) *3 / 4)
+
+/* Functions to convert MARIA_RECORD_POS to/from page:offset */
+
+static inline MARIA_RECORD_POS ma_recordpos(ulonglong page, uint offset)
+{
+ return (MARIA_RECORD_POS) ((page << 8) | offset);
+}
+
+static inline my_off_t ma_recordpos_to_page(MARIA_RECORD_POS record_pos)
+{
+ return record_pos >> 8;
+}
+
+static inline my_off_t ma_recordpos_to_offset(MARIA_RECORD_POS record_pos)
+{
+ return record_pos & 255;
+}
+
+/* ma_blockrec.c */
+void _ma_init_block_record_data(void);
+my_bool _ma_once_init_block_row(MARIA_SHARE *share, File dfile);
+my_bool _ma_once_end_block_row(MARIA_SHARE *share);
+my_bool _ma_init_block_row(MARIA_HA *info);
+void _ma_end_block_row(MARIA_HA *info);
+
+my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS pos,
+ const byte *record);
+my_bool _ma_delete_block_record(MARIA_HA *info);
+int _ma_read_block_record(MARIA_HA *info, byte *record,
+ MARIA_RECORD_POS record_pos);
+int _ma_read_block_record2(MARIA_HA *info, byte *record,
+ byte *data, byte *end_of_data);
+int _ma_scan_block_record(MARIA_HA *info, byte *record,
+ MARIA_RECORD_POS, my_bool);
+my_bool _ma_cmp_block_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
+ const byte *record, MARIA_RECORD_POS pos);
+my_bool _ma_scan_init_block_record(MARIA_HA *info);
+void _ma_scan_end_block_record(MARIA_HA *info);
+
+MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info,
+ const byte *record);
+my_bool _ma_write_block_record(MARIA_HA *info, const byte *record);
+my_bool _ma_write_abort_block_record(MARIA_HA *info);
+my_bool _ma_compare_block_record(register MARIA_HA *info,
+ register const byte *record);
+
+/* ma_bitmap.c */
+my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
+my_bool _ma_bitmap_end(MARIA_SHARE *share);
+my_bool _ma_flush_bitmap(MARIA_SHARE *share);
+my_bool _ma_read_bitmap_page(MARIA_SHARE *share, MARIA_FILE_BITMAP *bitmap,
+ ulonglong page);
+my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
+ MARIA_BITMAP_BLOCKS *result_blocks);
+my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks);
+my_bool _ma_bitmap_free_full_pages(MARIA_HA *info, const byte *extents,
+ uint count);
+my_bool _ma_bitmap_set(MARIA_HA *info, ulonglong pos, my_bool head,
+ uint empty_space);
+my_bool _ma_reset_full_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
+ ulonglong page, uint page_count);
+uint _ma_free_size_to_head_pattern(MARIA_FILE_BITMAP *bitmap, uint size);
+my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *new_row,
+ ulonglong page, uint free_size,
+ MARIA_BITMAP_BLOCKS *result_blocks);
+my_bool _ma_check_bitmap_data(MARIA_HA *info,
+ enum en_page_type page_type, ulonglong page,
+ uint empty_space, uint *bitmap_pattern);
+my_bool _ma_check_if_right_bitmap_type(MARIA_HA *info,
+ enum en_page_type page_type,
+ ulonglong page,
+ uint *bitmap_pattern);
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 2a800ae41ad..682ce276a5b 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -53,42 +53,42 @@
#include <sys/mman.h>
#endif
#include "ma_rt_index.h"
+#include "ma_blockrec.h"
-#ifndef USE_RAID
-#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
-#define my_raid_delete(A,B,C) my_delete(A,B)
-#endif
-
- /* Functions defined in this file */
+/* Functions defined in this file */
-static int check_k_link(HA_CHECK *param, MARIA_HA *info,uint nr);
+static int check_k_link(HA_CHECK *param, MARIA_HA *info, my_off_t next_link);
static int chk_index(HA_CHECK *param, MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff, ha_rows *keys,
+ my_off_t page, byte *buff, ha_rows *keys,
ha_checksum *key_checksum, uint level);
static uint isam_key_length(MARIA_HA *info,MARIA_KEYDEF *keyinfo);
static ha_checksum calc_checksum(ha_rows count);
static int writekeys(MARIA_SORT_PARAM *sort_param);
-static int sort_one_index(HA_CHECK *param, MARIA_HA *info,MARIA_KEYDEF *keyinfo,
+static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
+ MARIA_KEYDEF *keyinfo,
my_off_t pagepos, File new_file);
-static int sort_key_read(MARIA_SORT_PARAM *sort_param,void *key);
-static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param,void *key);
+static int sort_key_read(MARIA_SORT_PARAM *sort_param, byte *key);
+static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, byte *key);
static int sort_get_next_record(MARIA_SORT_PARAM *sort_param);
-static int sort_key_cmp(MARIA_SORT_PARAM *sort_param, const void *a,const void *b);
-static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param, const void *a);
-static int sort_key_write(MARIA_SORT_PARAM *sort_param, const void *a);
+static int sort_key_cmp(MARIA_SORT_PARAM *sort_param, const void *a,
+ const void *b);
+static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param,
+ const byte *a);
+static int sort_key_write(MARIA_SORT_PARAM *sort_param, const byte *a);
static my_off_t get_record_for_key(MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- uchar *key);
+ const byte *key);
static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
reg1 SORT_KEY_BLOCKS *key_block,
- uchar *key, my_off_t prev_block);
+ const byte *key, my_off_t prev_block);
static int sort_delete_record(MARIA_SORT_PARAM *sort_param);
/*static int _ma_flush_pending_blocks(HA_CHECK *param);*/
static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
uint buffer_length);
static ha_checksum maria_byte_checksum(const byte *buf, uint length);
static void set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share);
+static void restore_data_file_type(MARIA_SHARE *share);
-void mariachk_init(HA_CHECK *param)
+void maria_chk_init(HA_CHECK *param)
{
bzero((gptr) param,sizeof(*param));
param->opt_follow_links=1;
@@ -206,7 +206,7 @@ int maria_chk_del(HA_CHECK *param, register MARIA_HA *info, uint test_flag)
else
{
param->record_checksum+=(ha_checksum) next_link;
- next_link= _ma_rec_pos(info->s,(uchar*) buff+1);
+ next_link= _ma_rec_pos(info->s, buff+1);
empty+=info->s->base.pack_reclength;
}
}
@@ -247,19 +247,14 @@ wrong:
/* Check delete links in index file */
-static int check_k_link(HA_CHECK *param, register MARIA_HA *info, uint nr)
+static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
+ my_off_t next_link)
{
- my_off_t next_link;
- uint block_size=(nr+1)*MARIA_MIN_KEY_BLOCK_LENGTH;
+ uint block_size= info->s->block_size;
ha_rows records;
char llbuff[21], llbuff2[21], *buff;
DBUG_ENTER("check_k_link");
- DBUG_PRINT("enter", ("block_size: %u", block_size));
-
- if (param->testflag & T_VERBOSE)
- printf("block_size %4u:", block_size); /* purecov: tested */
- next_link=info->s->state.key_del[nr];
records= (ha_rows) (info->state->key_file_length / block_size);
while (next_link != HA_OFFSET_ERROR && records > 0)
{
@@ -280,26 +275,22 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info, uint nr)
/* purecov: end */
}
- /* Key blocks must be aligned at MARIA_MIN_KEY_BLOCK_LENGTH. */
- if (next_link & (MARIA_MIN_KEY_BLOCK_LENGTH - 1))
+ /* Key blocks must be aligned at block_size */
+ if (next_link & (block_size -1))
{
/* purecov: begin tested */
_ma_check_print_error(param, "Mis-aligned key block: %s "
"minimum key block length: %u",
- llstr(next_link, llbuff), MARIA_MIN_KEY_BLOCK_LENGTH);
+ llstr(next_link, llbuff),
+ block_size);
DBUG_RETURN(1);
/* purecov: end */
}
-
- /*
- Read the key block with MARIA_MIN_KEY_BLOCK_LENGTH to find next link.
- If the key cache block size is smaller than block_size, we can so
- avoid unecessary eviction of cache block.
- */
+
if (!(buff=key_cache_read(info->s->key_cache,
info->s->kfile, next_link, DFLT_INIT_HITS,
- (byte*) info->buff, MARIA_MIN_KEY_BLOCK_LENGTH,
- MARIA_MIN_KEY_BLOCK_LENGTH, 1)))
+ (byte*) info->buff,
+ block_size, block_size, 1)))
{
/* purecov: begin tested */
_ma_check_print_error(param, "key cache read error for block: %s",
@@ -331,9 +322,10 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
char buff[22],buff2[22];
DBUG_ENTER("maria_chk_size");
- if (!(param->testflag & T_SILENT)) puts("- check file-size");
+ if (!(param->testflag & T_SILENT))
+ puts("- check file-size");
- /* The following is needed if called externally (not from mariachk) */
+ /* The following is needed if called externally (not from maria_chk) */
flush_key_blocks(info->s->key_cache,
info->s->kfile, FLUSH_FORCE_WRITE);
@@ -348,7 +340,7 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
"Size of indexfile is: %-8s Should be: %s",
llstr(size,buff), llstr(skr,buff2));
}
- else
+ else if (!(param->testflag & T_VERY_SILENT))
_ma_check_print_warning(param,
"Size of indexfile is: %-8s Should be: %s",
llstr(size,buff), llstr(skr,buff2));
@@ -398,7 +390,7 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
} /* maria_chk_size */
- /* Check keys */
+/* Check keys */
int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
{
@@ -416,23 +408,22 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
puts("- check key delete-chain");
param->key_file_blocks=info->s->base.keystart;
- for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
- if (check_k_link(param,info,key))
- {
- if (param->testflag & T_VERBOSE) puts("");
- _ma_check_print_error(param,"key delete-link-chain corrupted");
- DBUG_RETURN(-1);
- }
+ if (check_k_link(param, info, info->s->state.key_del))
+ {
+ if (param->testflag & T_VERBOSE) puts("");
+ _ma_check_print_error(param,"key delete-link-chain corrupted");
+ DBUG_RETURN(-1);
+ }
if (!(param->testflag & T_SILENT)) puts("- check index reference");
all_keydata=all_totaldata=key_totlength=0;
old_record_checksum=0;
init_checksum=param->record_checksum;
- if (!(share->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
- old_record_checksum=calc_checksum(info->state->records+info->state->del-1)*
- share->base.pack_reclength;
+ if (share->data_file_type == STATIC_RECORD)
+ old_record_checksum= (calc_checksum(info->state->records +
+ info->state->del-1) *
+ share->base.pack_reclength);
rec_per_key_part= param->rec_per_key_part;
for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ;
rec_per_key_part+=keyinfo->keysegs, key++, keyinfo++)
@@ -490,11 +481,10 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
result= -1;
continue;
}
- if (found_keys - full_text_keys == 1 &&
- ((share->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
- (param->testflag & T_DONT_CHECK_CHECKSUM)))
- old_record_checksum=param->record_checksum;
+ if ((found_keys - full_text_keys == 1 &&
+ !(share->data_file_type == STATIC_RECORD)) ||
+ (param->testflag & T_DONT_CHECK_CHECKSUM))
+ old_record_checksum= param->record_checksum;
else if (old_record_checksum != param->record_checksum)
{
if (key)
@@ -513,7 +503,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
/* Check that auto_increment key is bigger than max key value */
ulonglong auto_increment;
info->lastinx=key;
- _ma_read_key_record(info, 0L, info->rec_buff);
+ _ma_read_key_record(info, info->rec_buff, 0);
auto_increment= ma_retrieve_auto_increment(info, info->rec_buff);
if (auto_increment > info->s->state.auto_increment)
{
@@ -536,7 +526,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
if (!maria_rkey(info, info->rec_buff, key, (const byte*) info->lastkey,
keyinfo->seg->length, HA_READ_KEY_EXACT))
{
- /* Don't count this as a real warning, as mariachk can't correct it */
+ /* Don't count this as a real warning, as maria_chk can't correct it */
uint save=param->warning_printed;
_ma_check_print_warning(param, "Found row where the auto_increment "
"column has the value 0");
@@ -585,9 +575,10 @@ do_stat:
} /* maria_chk_key */
-static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff, ha_rows *keys,
- ha_checksum *key_checksum, uint level)
+static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
+ MARIA_KEYDEF *keyinfo,
+ my_off_t page, byte *buff, ha_rows *keys,
+ ha_checksum *key_checksum, uint level)
{
char llbuff[22],llbuff2[22];
DBUG_ENTER("chk_index_down");
@@ -604,19 +595,19 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo
llstr(info->state->key_file_length, llbuff2));
if (page + keyinfo->block_length > max_length)
goto err;
- /* Fix the remebered key file length. */
+ /* Fix the remembered key file length. */
info->state->key_file_length= (max_length &
~ (my_off_t) (keyinfo->block_length - 1));
/* purecov: end */
}
- /* Key blocks must be aligned at MARIA_MIN_KEY_BLOCK_LENGTH. */
- if (page & (MARIA_MIN_KEY_BLOCK_LENGTH - 1))
+ /* Key blocks must be aligned at block length */
+ if (page & (info->s->block_size -1))
{
/* purecov: begin tested */
_ma_check_print_error(param, "Mis-aligned key block: %s "
"minimum key block length: %u",
- llstr(page, llbuff), MARIA_MIN_KEY_BLOCK_LENGTH);
+ llstr(page, llbuff), info->s->block_size);
goto err;
/* purecov: end */
}
@@ -657,10 +648,10 @@ err:
static
void maria_collect_stats_nonulls_first(HA_KEYSEG *keyseg, ulonglong *notnull,
- uchar *key)
+ const byte *key)
{
uint first_null, kp;
- first_null= ha_find_null(keyseg, key) - keyseg;
+ first_null= ha_find_null(keyseg, (uchar*) key) - keyseg;
/*
All prefix tuples that don't include keypart_{first_null} are not-null
tuples (and all others aren't), increment counters for them.
@@ -697,7 +688,8 @@ void maria_collect_stats_nonulls_first(HA_KEYSEG *keyseg, ulonglong *notnull,
static
int maria_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull,
- uchar *prev_key, uchar *last_key)
+ const byte *prev_key,
+ const byte *last_key)
{
uint diffs[2];
uint first_null_seg, kp;
@@ -711,12 +703,12 @@ int maria_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull,
last_key that is NULL or different from corresponding
value in prev_key.
*/
- ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY,
+ ha_key_cmp(keyseg, (uchar*) prev_key, (uchar*) last_key, USE_WHOLE_KEY,
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diffs);
seg= keyseg + diffs[0] - 1;
/* Find first NULL in last_key */
- first_null_seg= ha_find_null(seg, last_key + diffs[1]) - keyseg;
+ first_null_seg= ha_find_null(seg, (uchar*) last_key + diffs[1]) - keyseg;
for (kp= 0; kp < first_null_seg; kp++)
notnull[kp]++;
@@ -732,12 +724,12 @@ int maria_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull,
/* Check if index is ok */
static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff, ha_rows *keys,
+ my_off_t page, byte *buff, ha_rows *keys,
ha_checksum *key_checksum, uint level)
{
int flag;
uint used_length,comp_flag,nod_flag,key_length=0;
- uchar key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
+ byte key[HA_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
my_off_t next_page,record;
char llbuff[22];
uint diff_pos[2];
@@ -748,7 +740,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (keyinfo->flag & HA_SPATIAL)
DBUG_RETURN(0);
- if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
+ if (!(temp_buff=(byte*) my_alloca((uint) keyinfo->block_length)))
{
_ma_check_print_error(param,"Not enough memory for keyblock");
DBUG_RETURN(-1);
@@ -778,8 +770,8 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
{
if (*_ma_killed_ptr(param))
goto err;
- memcpy((char*) info->lastkey,(char*) key,key_length);
- info->lastkey_length=key_length;
+ memcpy(info->lastkey, key, key_length);
+ info->lastkey_length= key_length;
if (nod_flag)
{
next_page= _ma_kpos(nod_flag,keypos);
@@ -793,21 +785,24 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
break;
if (keypos > endpos)
{
- _ma_check_print_error(param,"Wrong key block length at page: %s",llstr(page,llbuff));
+ _ma_check_print_error(param,"Wrong key block length at page: %s",
+ llstr(page,llbuff));
goto err;
}
if ((*keys)++ &&
- (flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
- comp_flag, diff_pos)) >=0)
+ (flag=ha_key_cmp(keyinfo->seg, (uchar*) info->lastkey, (uchar*) key,
+ key_length, comp_flag, diff_pos)) >=0)
{
- DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length);
- DBUG_DUMP("new",(byte*) key, key_length);
- DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos));
+ DBUG_DUMP("old", info->lastkey, info->lastkey_length);
+ DBUG_DUMP("new", key, key_length);
+ DBUG_DUMP("new_in_page", old_keypos, (uint) (keypos-old_keypos));
if (comp_flag & SEARCH_FIND && flag == 0)
- _ma_check_print_error(param,"Found duplicated key at page %s",llstr(page,llbuff));
+ _ma_check_print_error(param,"Found duplicated key at page %s",
+ llstr(page,llbuff));
else
- _ma_check_print_error(param,"Key in wrong position at page %s",llstr(page,llbuff));
+ _ma_check_print_error(param,"Key in wrong position at page %s",
+ llstr(page,llbuff));
goto err;
}
if (param->testflag & T_STATISTICS)
@@ -815,14 +810,14 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (*keys != 1L) /* not first_key */
{
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
- ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
- SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
+ ha_key_cmp(keyinfo->seg, (uchar*) info->lastkey, (uchar*) key,
+ USE_WHOLE_KEY, SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
diff_pos);
else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
{
diff_pos[0]= maria_collect_stats_nonulls_next(keyinfo->seg,
- param->notnull_count,
- info->lastkey, key);
+ param->notnull_count,
+ info->lastkey, key);
}
param->unique_count[diff_pos[0]-1]++;
}
@@ -875,7 +870,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
DBUG_DUMP("new_in_page",(char*) old_keypos,(uint) (keypos-old_keypos));
goto err;
}
- param->record_checksum+=(ha_checksum) record;
+ param->record_checksum+= (ha_checksum) record;
}
if (keypos != endpos)
{
@@ -932,358 +927,848 @@ static uint isam_key_length(MARIA_HA *info, register MARIA_KEYDEF *keyinfo)
} /* key_length */
- /* Check that record-link is ok */
-int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
+static void record_pos_to_txt(MARIA_HA *info, my_off_t recpos,
+ char *buff)
{
- int error,got_error,flag;
- uint key,left_length,b_type,field;
- ha_rows records,del_blocks;
- my_off_t used,empty,pos,splits,start_recpos,
- del_length,link_used,start_block;
- byte *record,*to;
- char llbuff[22],llbuff2[22],llbuff3[22];
- ha_checksum intern_record_checksum;
- ha_checksum key_checksum[HA_MAX_POSSIBLE_KEY];
- my_bool static_row_size;
- MARIA_KEYDEF *keyinfo;
- MARIA_BLOCK_INFO block_info;
- DBUG_ENTER("maria_chk_data_link");
-
- if (!(param->testflag & T_SILENT))
+ if (info->s->data_file_type != BLOCK_RECORD)
+ llstr(recpos, buff);
+ else
{
- if (extend)
- puts("- check records and index references");
- else
- puts("- check record links");
+ my_off_t page= ma_recordpos_to_page(recpos);
+ uint row= ma_recordpos_to_offset(recpos);
+ char *end= longlong10_to_str(page, buff, 10);
+ *(end++)= ':';
+ longlong10_to_str(row, end, 10);
}
+}
- if (!(record= (byte*) my_malloc(info->s->base.pack_reclength,MYF(0))))
+
+/*
+ Check that keys in records exist in index tree
+
+ SYNOPSIS
+ check_keys_in_record()
+ param Check paramenter
+ info Maria handler
+ extend Type of check (extended or normal)
+ start_recpos Position to row
+ record Record buffer
+
+ NOTES
+ This function also calculates record checksum & number of rows
+*/
+
+static int check_keys_in_record(HA_CHECK *param, MARIA_HA *info, int extend,
+ my_off_t start_recpos, byte *record)
+{
+ MARIA_KEYDEF *keyinfo;
+ char llbuff[22+4];
+ uint key;
+
+ param->tmp_record_checksum+= (ha_checksum) start_recpos;
+ param->records++;
+ if (param->testflag & T_WRITE_LOOP && param->records % WRITE_COUNT == 0)
{
- _ma_check_print_error(param,"Not enough memory for record");
- DBUG_RETURN(-1);
+ printf("%s\r", llstr(param->records, llbuff));
+ VOID(fflush(stdout));
}
- records=del_blocks=0;
- used=link_used=splits=del_length=0;
- intern_record_checksum=param->glob_crc=0;
- LINT_INIT(left_length); LINT_INIT(start_recpos); LINT_INIT(to);
- got_error=error=0;
- empty=info->s->pack.header_length;
- /* Check how to calculate checksum of rows */
- static_row_size=1;
- if (info->s->data_file_type == COMPRESSED_RECORD)
+ /* Check if keys match the record */
+ for (key=0, keyinfo= info->s->keyinfo; key < info->s->base.keys;
+ key++,keyinfo++)
{
- for (field=0 ; field < info->s->base.fields ; field++)
+ if (maria_is_key_active(info->s->state.key_map, key))
{
- if (info->s->rec[field].base_type == FIELD_BLOB ||
- info->s->rec[field].base_type == FIELD_VARCHAR)
+ if(!(keyinfo->flag & HA_FULLTEXT))
{
- static_row_size=0;
- break;
+ uint key_length= _ma_make_key(info,key,info->lastkey,record,
+ start_recpos);
+ if (extend)
+ {
+ /* We don't need to lock the key tree here as we don't allow
+ concurrent threads when running maria_chk
+ */
+ int search_result=
+#ifdef HAVE_RTREE_KEYS
+ (keyinfo->flag & HA_SPATIAL) ?
+ maria_rtree_find_first(info, key, info->lastkey, key_length,
+ MBR_EQUAL | MBR_DATA) :
+#endif
+ _ma_search(info,keyinfo,info->lastkey,key_length,
+ SEARCH_SAME, info->s->state.key_root[key]);
+ if (search_result)
+ {
+ record_pos_to_txt(info, start_recpos, llbuff);
+ _ma_check_print_error(param,
+ "Record at: %14s "
+ "Can't find key for index: %2d",
+ llbuff, key+1);
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ return -1;
+ }
+ }
+ else
+ param->tmp_key_crc[key]+=
+ maria_byte_checksum((byte*) info->lastkey, key_length);
}
}
}
+ return 0;
+}
+
- pos=my_b_tell(&param->read_cache);
- bzero((char*) key_checksum, info->s->base.keys * sizeof(key_checksum[0]));
+/*
+ Functions to loop through all rows and check if they are ok
+
+ NOTES
+ One function for each record format
+
+ RESULT
+ 0 ok
+ -1 Interrupted by user
+ 1 Error
+*/
+
+static int check_static_record(HA_CHECK *param, MARIA_HA *info, int extend,
+ byte *record)
+{
+ my_off_t start_recpos, pos;
+ char llbuff[22];
+
+ pos= 0;
while (pos < info->state->data_file_length)
{
if (*_ma_killed_ptr(param))
- goto err2;
- switch (info->s->data_file_type) {
- case STATIC_RECORD:
- if (my_b_read(&param->read_cache,(byte*) record,
- info->s->base.pack_reclength))
- goto err;
- start_recpos=pos;
- pos+=info->s->base.pack_reclength;
- splits++;
- if (*record == '\0')
+ return -1;
+ if (my_b_read(&param->read_cache,(byte*) record,
+ info->s->base.pack_reclength))
+ {
+ _ma_check_print_error(param,
+ "got error: %d when reading datafile at position: %s",
+ my_errno, llstr(pos, llbuff));
+ return 1;
+ }
+ start_recpos= pos;
+ pos+= info->s->base.pack_reclength;
+ param->splits++;
+ if (*record == '\0')
+ {
+ param->del_blocks++;
+ param->del_length+= info->s->base.pack_reclength;
+ continue; /* Record removed */
+ }
+ param->glob_crc+= _ma_static_checksum(info,record);
+ param->used+= info->s->base.pack_reclength;
+ if (check_keys_in_record(param, info, extend, start_recpos, record))
+ return 1;
+ }
+ return 0;
+}
+
+
+static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend,
+ byte *record)
+{
+ MARIA_BLOCK_INFO block_info;
+ my_off_t start_recpos, start_block, pos;
+ byte *to;
+ ulong left_length;
+ uint b_type;
+ char llbuff[22],llbuff2[22],llbuff3[22];
+ DBUG_ENTER("check_dynamic_record");
+
+ pos= 0;
+ while (pos < info->state->data_file_length)
+ {
+ my_bool got_error= 0;
+ int flag;
+ if (*_ma_killed_ptr(param))
+ DBUG_RETURN(-1);
+
+ flag= block_info.second_read=0;
+ block_info.next_filepos=pos;
+ do
+ {
+ if (_ma_read_cache(&param->read_cache,(byte*) block_info.header,
+ (start_block=block_info.next_filepos),
+ sizeof(block_info.header),
+ (flag ? 0 : READING_NEXT) | READING_HEADER))
{
- del_blocks++;
- del_length+=info->s->base.pack_reclength;
- continue; /* Record removed */
+ _ma_check_print_error(param,
+ "got error: %d when reading datafile at position: %s",
+ my_errno, llstr(start_block, llbuff));
+ DBUG_RETURN(1);
}
- param->glob_crc+= _ma_static_checksum(info,record);
- used+=info->s->base.pack_reclength;
- break;
- case DYNAMIC_RECORD:
- flag=block_info.second_read=0;
- block_info.next_filepos=pos;
- do
+
+ if (start_block & (MARIA_DYN_ALIGN_SIZE-1))
{
- if (_ma_read_cache(&param->read_cache,(byte*) block_info.header,
- (start_block=block_info.next_filepos),
- sizeof(block_info.header),
- (flag ? 0 : READING_NEXT) | READING_HEADER))
- goto err;
- if (start_block & (MARIA_DYN_ALIGN_SIZE-1))
- {
- _ma_check_print_error(param,"Wrong aligned block at %s",
- llstr(start_block,llbuff));
- goto err2;
- }
- b_type= _ma_get_block_info(&block_info,-1,start_block);
- if (b_type & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
- BLOCK_FATAL_ERROR))
- {
- if (b_type & BLOCK_SYNC_ERROR)
- {
- if (flag)
- {
- _ma_check_print_error(param,"Unexpected byte: %d at link: %s",
- (int) block_info.header[0],
- llstr(start_block,llbuff));
- goto err2;
- }
- pos=block_info.filepos+block_info.block_len;
- goto next;
- }
- if (b_type & BLOCK_DELETED)
- {
- if (block_info.block_len < info->s->base.min_block_length)
- {
- _ma_check_print_error(param,
- "Deleted block with impossible length %lu at %s",
- block_info.block_len,llstr(pos,llbuff));
- goto err2;
- }
- if ((block_info.next_filepos != HA_OFFSET_ERROR &&
- block_info.next_filepos >= info->state->data_file_length) ||
- (block_info.prev_filepos != HA_OFFSET_ERROR &&
- block_info.prev_filepos >= info->state->data_file_length))
- {
- _ma_check_print_error(param,"Delete link points outside datafile at %s",
- llstr(pos,llbuff));
- goto err2;
- }
- del_blocks++;
- del_length+=block_info.block_len;
- pos=block_info.filepos+block_info.block_len;
- splits++;
- goto next;
- }
- _ma_check_print_error(param,"Wrong bytesec: %d-%d-%d at linkstart: %s",
- block_info.header[0],block_info.header[1],
- block_info.header[2],
- llstr(start_block,llbuff));
- goto err2;
- }
- if (info->state->data_file_length < block_info.filepos+
- block_info.block_len)
- {
- _ma_check_print_error(param,
- "Recordlink that points outside datafile at %s",
- llstr(pos,llbuff));
- got_error=1;
- break;
- }
- splits++;
- if (!flag++) /* First block */
- {
- start_recpos=pos;
- pos=block_info.filepos+block_info.block_len;
- if (block_info.rec_len > (uint) info->s->base.max_pack_length)
- {
- _ma_check_print_error(param,"Found too long record (%lu) at %s",
- (ulong) block_info.rec_len,
- llstr(start_recpos,llbuff));
- got_error=1;
- break;
- }
- if (info->s->base.blobs)
- {
- if (!(to= _ma_alloc_rec_buff(info, block_info.rec_len,
- &info->rec_buff)))
- {
- _ma_check_print_error(param,
- "Not enough memory (%lu) for blob at %s",
- (ulong) block_info.rec_len,
- llstr(start_recpos,llbuff));
- got_error=1;
- break;
- }
- }
- else
- to= info->rec_buff;
- left_length=block_info.rec_len;
- }
- if (left_length < block_info.data_len)
- {
- _ma_check_print_error(param,"Found too long record (%lu) at %s",
- (ulong) block_info.data_len,
- llstr(start_recpos,llbuff));
- got_error=1;
- break;
- }
- if (_ma_read_cache(&param->read_cache,(byte*) to,block_info.filepos,
- (uint) block_info.data_len,
- flag == 1 ? READING_NEXT : 0))
- goto err;
- to+=block_info.data_len;
- link_used+= block_info.filepos-start_block;
- used+= block_info.filepos - start_block + block_info.data_len;
- empty+=block_info.block_len-block_info.data_len;
- left_length-=block_info.data_len;
- if (left_length)
- {
- if (b_type & BLOCK_LAST)
- {
- _ma_check_print_error(param,
- "Wrong record length %s of %s at %s",
- llstr(block_info.rec_len-left_length,llbuff),
- llstr(block_info.rec_len, llbuff2),
- llstr(start_recpos,llbuff3));
- got_error=1;
- break;
- }
- if (info->state->data_file_length < block_info.next_filepos)
- {
- _ma_check_print_error(param,
- "Found next-recordlink that points outside datafile at %s",
- llstr(block_info.filepos,llbuff));
- got_error=1;
- break;
- }
- }
- } while (left_length);
- if (! got_error)
+ _ma_check_print_error(param,"Wrong aligned block at %s",
+ llstr(start_block,llbuff));
+ DBUG_RETURN(1);
+ }
+ b_type= _ma_get_block_info(&block_info,-1,start_block);
+ if (b_type & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
+ BLOCK_FATAL_ERROR))
{
- if (_ma_rec_unpack(info,record,info->rec_buff,block_info.rec_len) ==
- MY_FILE_ERROR)
- {
- _ma_check_print_error(param,"Found wrong record at %s",
- llstr(start_recpos,llbuff));
- got_error=1;
- }
- else
- {
- info->checksum=_ma_checksum(info,record);
- if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE))
- {
- if (_ma_rec_check(info,record, info->rec_buff,block_info.rec_len,
- test(info->s->calc_checksum)))
- {
- _ma_check_print_error(param,"Found wrong packed record at %s",
- llstr(start_recpos,llbuff));
- got_error=1;
- }
- }
- if (!got_error)
- param->glob_crc+= info->checksum;
- }
+ if (b_type & BLOCK_SYNC_ERROR)
+ {
+ if (flag)
+ {
+ _ma_check_print_error(param,"Unexpected byte: %d at link: %s",
+ (int) block_info.header[0],
+ llstr(start_block,llbuff));
+ DBUG_RETURN(1);
+ }
+ pos=block_info.filepos+block_info.block_len;
+ goto next;
+ }
+ if (b_type & BLOCK_DELETED)
+ {
+ if (block_info.block_len < info->s->base.min_block_length)
+ {
+ _ma_check_print_error(param,
+ "Deleted block with impossible length %lu at %s",
+ block_info.block_len,llstr(pos,llbuff));
+ DBUG_RETURN(1);
+ }
+ if ((block_info.next_filepos != HA_OFFSET_ERROR &&
+ block_info.next_filepos >= info->state->data_file_length) ||
+ (block_info.prev_filepos != HA_OFFSET_ERROR &&
+ block_info.prev_filepos >= info->state->data_file_length))
+ {
+ _ma_check_print_error(param,"Delete link points outside datafile at %s",
+ llstr(pos,llbuff));
+ DBUG_RETURN(1);
+ }
+ param->del_blocks++;
+ param->del_length+= block_info.block_len;
+ param->splits++;
+ pos= block_info.filepos+block_info.block_len;
+ goto next;
+ }
+ _ma_check_print_error(param,"Wrong bytesec: %d-%d-%d at linkstart: %s",
+ block_info.header[0],block_info.header[1],
+ block_info.header[2],
+ llstr(start_block,llbuff));
+ DBUG_RETURN(1);
}
- else if (!flag)
- pos=block_info.filepos+block_info.block_len;
- break;
- case COMPRESSED_RECORD:
- if (_ma_read_cache(&param->read_cache,(byte*) block_info.header, pos,
- info->s->pack.ref_length, READING_NEXT))
- goto err;
- start_recpos=pos;
- splits++;
- VOID(_ma_pack_get_block_info(info, &info->bit_buff, &block_info,
- &info->rec_buff, -1, start_recpos));
- pos=block_info.filepos+block_info.rec_len;
- if (block_info.rec_len < (uint) info->s->min_pack_length ||
- block_info.rec_len > (uint) info->s->max_pack_length)
+ if (info->state->data_file_length < block_info.filepos+
+ block_info.block_len)
{
- _ma_check_print_error(param,
- "Found block with wrong recordlength: %d at %s",
- block_info.rec_len, llstr(start_recpos,llbuff));
- got_error=1;
- break;
+ _ma_check_print_error(param,
+ "Recordlink that points outside datafile at %s",
+ llstr(pos,llbuff));
+ got_error=1;
+ break;
}
- if (_ma_read_cache(&param->read_cache,(byte*) info->rec_buff,
- block_info.filepos, block_info.rec_len, READING_NEXT))
- goto err;
- if (_ma_pack_rec_unpack(info, &info->bit_buff, record,
- info->rec_buff, block_info.rec_len))
+ param->splits++;
+ if (!flag++) /* First block */
{
- _ma_check_print_error(param,"Found wrong record at %s",
- llstr(start_recpos,llbuff));
- got_error=1;
+ start_recpos=pos;
+ pos=block_info.filepos+block_info.block_len;
+ if (block_info.rec_len > (uint) info->s->base.max_pack_length)
+ {
+ _ma_check_print_error(param,"Found too long record (%lu) at %s",
+ (ulong) block_info.rec_len,
+ llstr(start_recpos,llbuff));
+ got_error=1;
+ break;
+ }
+ if (info->s->base.blobs)
+ {
+ if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
+ block_info.rec_len +
+ info->s->base.extra_rec_buff_size))
+
+ {
+ _ma_check_print_error(param,
+ "Not enough memory (%lu) for blob at %s",
+ (ulong) block_info.rec_len,
+ llstr(start_recpos,llbuff));
+ got_error=1;
+ break;
+ }
+ }
+ to= info->rec_buff;
+ left_length= block_info.rec_len;
+ }
+ if (left_length < block_info.data_len)
+ {
+ _ma_check_print_error(param,"Found too long record (%lu) at %s",
+ (ulong) block_info.data_len,
+ llstr(start_recpos,llbuff));
+ got_error=1;
+ break;
+ }
+ if (_ma_read_cache(&param->read_cache,(byte*) to,block_info.filepos,
+ (uint) block_info.data_len,
+ flag == 1 ? READING_NEXT : 0))
+ {
+ _ma_check_print_error(param,
+ "got error: %d when reading datafile at position: %s", my_errno, llstr(block_info.filepos, llbuff));
+
+ DBUG_RETURN(1);
+ }
+ to+=block_info.data_len;
+ param->link_used+= block_info.filepos-start_block;
+ param->used+= block_info.filepos - start_block + block_info.data_len;
+ param->empty+= block_info.block_len-block_info.data_len;
+ left_length-= block_info.data_len;
+ if (left_length)
+ {
+ if (b_type & BLOCK_LAST)
+ {
+ _ma_check_print_error(param,
+ "Wrong record length %s of %s at %s",
+ llstr(block_info.rec_len-left_length,llbuff),
+ llstr(block_info.rec_len, llbuff2),
+ llstr(start_recpos,llbuff3));
+ got_error=1;
+ break;
+ }
+ if (info->state->data_file_length < block_info.next_filepos)
+ {
+ _ma_check_print_error(param,
+ "Found next-recordlink that points outside datafile at %s",
+ llstr(block_info.filepos,llbuff));
+ got_error=1;
+ break;
+ }
+ }
+ } while (left_length);
+
+ if (! got_error)
+ {
+ if (_ma_rec_unpack(info,record,info->rec_buff,block_info.rec_len) ==
+ MY_FILE_ERROR)
+ {
+ _ma_check_print_error(param,"Found wrong record at %s",
+ llstr(start_recpos,llbuff));
+ got_error=1;
}
- if (static_row_size)
- param->glob_crc+= _ma_static_checksum(info,record);
else
- param->glob_crc+= _ma_checksum(info,record);
- link_used+= (block_info.filepos - start_recpos);
- used+= (pos-start_recpos);
- } /* switch */
+ {
+ info->cur_row.checksum= _ma_checksum(info,record);
+ if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE))
+ {
+ if (_ma_rec_check(info,record, info->rec_buff,block_info.rec_len,
+ test(info->s->calc_checksum)))
+ {
+ _ma_check_print_error(param,"Found wrong packed record at %s",
+ llstr(start_recpos,llbuff));
+ got_error= 1;
+ }
+ }
+ param->glob_crc+= info->cur_row.checksum;
+ }
+
+ if (! got_error)
+ {
+ if (check_keys_in_record(param, info, extend, start_recpos, record))
+ DBUG_RETURN(1);
+ }
+ else
+ {
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ DBUG_RETURN(1);
+ }
+ }
+ else if (!flag)
+ pos= block_info.filepos+block_info.block_len;
+next:;
+ }
+ DBUG_RETURN(0);
+}
+
+
+static int check_compressed_record(HA_CHECK *param, MARIA_HA *info, int extend,
+ byte *record)
+{
+ my_off_t start_recpos, pos;
+ char llbuff[22];
+ bool got_error= 0;
+ MARIA_BLOCK_INFO block_info;
+ DBUG_ENTER("check_compressed_record");
+
+ pos= info->s->pack.header_length; /* Skip header */
+ while (pos < info->state->data_file_length)
+ {
+ if (*_ma_killed_ptr(param))
+ DBUG_RETURN(-1);
+
+ if (_ma_read_cache(&param->read_cache,(byte*) block_info.header, pos,
+ info->s->pack.ref_length, READING_NEXT))
+ {
+ _ma_check_print_error(param,
+ "got error: %d when reading datafile at position: %s",
+ my_errno, llstr(pos, llbuff));
+ DBUG_RETURN(1);
+ }
+
+ start_recpos= pos;
+ param->splits++;
+ VOID(_ma_pack_get_block_info(info, &info->bit_buff, &block_info,
+ &info->rec_buff, -1, start_recpos));
+ pos=block_info.filepos+block_info.rec_len;
+ if (block_info.rec_len < (uint) info->s->min_pack_length ||
+ block_info.rec_len > (uint) info->s->max_pack_length)
+ {
+ _ma_check_print_error(param,
+ "Found block with wrong recordlength: %d at %s",
+ block_info.rec_len, llstr(start_recpos,llbuff));
+ got_error=1;
+ goto end;
+ }
+ if (_ma_read_cache(&param->read_cache,(byte*) info->rec_buff,
+ block_info.filepos, block_info.rec_len, READING_NEXT))
+ {
+ _ma_check_print_error(param,
+ "got error: %d when reading datafile at position: %s",
+ my_errno, llstr(block_info.filepos, llbuff));
+ DBUG_RETURN(1);
+ }
+ if (_ma_pack_rec_unpack(info, &info->bit_buff, record,
+ info->rec_buff, block_info.rec_len))
+ {
+ _ma_check_print_error(param,"Found wrong record at %s",
+ llstr(start_recpos,llbuff));
+ got_error=1;
+ goto end;
+ }
+ param->glob_crc+= (*info->s->calc_checksum)(info,record);
+ param->link_used+= (block_info.filepos - start_recpos);
+ param->used+= (pos-start_recpos);
+
+end:
if (! got_error)
{
- intern_record_checksum+=(ha_checksum) start_recpos;
- records++;
- if (param->testflag & T_WRITE_LOOP && records % WRITE_COUNT == 0)
+ if (check_keys_in_record(param, info, extend, start_recpos, record))
+ DBUG_RETURN(1);
+ }
+ else
+ {
+ got_error= 0; /* Reset for next loop */
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Check if layout on a page is ok
+*/
+
+static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
+ my_off_t page_pos, byte *page,
+ uint row_count, uint head_empty,
+ uint *real_rows_found)
+{
+ uint empty, last_row_end, row, first_dir_entry;
+ byte *dir_entry;
+ char llbuff[22];
+ DBUG_ENTER("check_page_layout");
+
+ empty= 0;
+ last_row_end= PAGE_HEADER_SIZE;
+ *real_rows_found= 0;
+
+ dir_entry= page+ info->s->block_size - PAGE_SUFFIX_SIZE;
+ first_dir_entry= info->s->block_size - row_count* DIR_ENTRY_SIZE;
+ for (row= 0 ; row < row_count ; row++)
+ {
+ uint pos, length;
+ dir_entry-= DIR_ENTRY_SIZE;
+ pos= uint2korr(dir_entry);
+ if (!pos)
+ {
+ if (row == row_count -1)
+ {
+ _ma_check_print_error(param,
+ "Page %9s: First entry in directory is 0",
+ llstr(page_pos, llbuff));
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ DBUG_RETURN(1);
+ }
+ continue; /* Deleted row */
+ }
+ (*real_rows_found)++;
+ length= uint2korr(dir_entry+2);
+ param->used+= length;
+ if (pos < last_row_end)
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Row %3u overlapps with previous row",
+ llstr(page_pos, llbuff), row);
+ DBUG_RETURN(1);
+ }
+ empty+= (pos - last_row_end);
+ last_row_end= pos + length;
+ if (last_row_end > first_dir_entry)
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Row %3u overlapps with directory",
+ llstr(page_pos, llbuff), row);
+ DBUG_RETURN(1);
+ }
+ }
+ empty+= (first_dir_entry - last_row_end);
+
+ if (empty != head_empty)
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Wrong empty size. Stored: %5u Actual: %5u",
+ llstr(page_pos, llbuff), head_empty, empty);
+ DBUG_RETURN(param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE));
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Check all rows on head page
+
+ NOTES
+ Before this, we have already called check_page_layout(), so
+ we know the block is logicaly correct (even if the rows may not be that)
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+
+static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, byte *record,
+ int extend, my_off_t page_pos, byte *page_buff,
+ uint row_count)
+{
+ byte *dir_entry;
+ uint row;
+ char llbuff[22], llbuff2[22];
+ DBUG_ENTER("check_head_page");
+
+ dir_entry= page_buff+ info->s->block_size - PAGE_SUFFIX_SIZE;
+ for (row= 0 ; row < row_count ; row++)
+ {
+ uint pos, length, flag;
+ dir_entry-= DIR_ENTRY_SIZE;
+ pos= uint2korr(dir_entry);
+ if (!pos)
+ continue;
+ length= uint2korr(dir_entry+2);
+ if (length < info->s->base.min_block_length)
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Row %3u is too short (%d bytes)",
+ llstr(page_pos, llbuff), row, length);
+ DBUG_RETURN(1);
+ }
+ flag= (uint) (uchar) page_buff[pos];
+ if (flag & ~(ROW_FLAG_ALL))
+ _ma_check_print_error(param,
+ "Page %9s: Row %3u has wrong flag: %d",
+ llstr(page_pos, llbuff), row, flag);
+
+ DBUG_PRINT("info", ("rowid: %s page: %lu row: %u",
+ llstr(ma_recordpos(page_pos/info->s->block_size, row),
+ llbuff),
+ (ulong) (page_pos / info->s->block_size), row));
+ if (_ma_read_block_record2(info, record, page_buff+pos,
+ page_buff+pos+length))
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Row %3d is crashed",
+ llstr(page_pos, llbuff), row);
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ DBUG_RETURN(1);
+ continue;
+ }
+ if (info->s->calc_checksum)
+ {
+ info->cur_row.checksum= _ma_checksum(info, record);
+ param->glob_crc+= info->cur_row.checksum;
+ }
+ if (info->cur_row.extents_count)
+ {
+ byte *extents= info->cur_row.extents;
+ uint i;
+ /* Check that bitmap has the right marker for the found extents */
+ for (i= 0 ; i < info->cur_row.extents_count ; i++)
{
- printf("%s\r", llstr(records,llbuff)); VOID(fflush(stdout));
+ uint page, page_count, page_type;
+ page= uint5korr(extents);
+ page_count= uint2korr(extents+5);
+ extents+= ROW_EXTENT_SIZE;
+ page_type= BLOB_PAGE;
+ if (page_count & TAIL_BIT)
+ {
+ page_count= 1;
+ page_type= TAIL_PAGE;
+ }
+ for ( ; page_count--; page++)
+ {
+ uint bitmap_pattern;
+ if (_ma_check_if_right_bitmap_type(info, page_type, page,
+ &bitmap_pattern))
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Row: %3d has an extent with wrong information in bitmap: Page %9s Page_type: %d Bitmap: %d",
+ llstr(page_pos, llbuff), row,
+ llstr(page * info->s->bitmap.block_size,
+ llbuff2),
+ page_type,
+ bitmap_pattern);
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ DBUG_RETURN(1);
+ }
+ }
}
+ }
+ param->full_page_count+= info->cur_row.full_page_count;
+ param->tail_count+= info->cur_row.tail_count;
+ if (check_keys_in_record(param, info, extend,
+ ma_recordpos(page_pos/info->s->block_size, row),
+ record))
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+
+static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
+ byte *record)
+{
+ my_off_t pos;
+ byte *page_buff, *bitmap_buff, *data;
+ char llbuff[22], llbuff2[22];
+ uint block_size= info->s->block_size;
+ ha_rows full_page_count, tail_count;
+ my_bool full_dir;
+ uint offset_page, offset;
- /* Check if keys match the record */
+ if (_ma_scan_init_block_record(info))
+ {
+ _ma_check_print_error(param, "got error %d when initializing scan",
+ my_errno);
+ return 1;
+ }
+ bitmap_buff= info->scan.bitmap_buff;
+ page_buff= info->scan.page_buff;
+ full_page_count= tail_count= 0;
+ param->full_page_count= param->tail_count= 0;
+ param->used= param->link_used= 0;
- for (key=0,keyinfo= info->s->keyinfo; key < info->s->base.keys;
- key++,keyinfo++)
+ for (pos= 0;
+ pos < info->state->data_file_length;
+ pos+= block_size)
+ {
+ uint row_count, real_row_count, empty_space, page_type, bitmap_pattern;
+ LINT_INIT(row_count);
+ LINT_INIT(empty_space);
+
+ if (*_ma_killed_ptr(param))
+ {
+ _ma_scan_end_block_record(info);
+ return -1;
+ }
+ if (((pos / block_size) % info->s->bitmap.pages_covered) == 0)
+ {
+ /* Bitmap page */
+ if (_ma_read_cache(&param->read_cache, bitmap_buff, pos,
+ block_size, READING_NEXT))
{
- if (maria_is_key_active(info->s->state.key_map, key))
- {
- if(!(keyinfo->flag & HA_FULLTEXT))
- {
- uint key_length= _ma_make_key(info,key,info->lastkey,record,
- start_recpos);
- if (extend)
- {
- /* We don't need to lock the key tree here as we don't allow
- concurrent threads when running mariachk
- */
- int search_result=
-#ifdef HAVE_RTREE_KEYS
- (keyinfo->flag & HA_SPATIAL) ?
- maria_rtree_find_first(info, key, info->lastkey, key_length,
- MBR_EQUAL | MBR_DATA) :
-#endif
- _ma_search(info,keyinfo,info->lastkey,key_length,
- SEARCH_SAME, info->s->state.key_root[key]);
- if (search_result)
- {
- _ma_check_print_error(param,"Record at: %10s "
- "Can't find key for index: %2d",
- llstr(start_recpos,llbuff),key+1);
- if (error++ > MAXERR || !(param->testflag & T_VERBOSE))
- goto err2;
- }
- }
- else
- key_checksum[key]+=maria_byte_checksum((byte*) info->lastkey,
- key_length);
- }
- }
+ _ma_check_print_error(param,
+ "Page %9s: Got error: %d when reading datafile",
+ my_errno, llstr(pos, llbuff));
+ goto err;
}
+ param->used+= block_size;
+ param->link_used+= block_size;
+ continue;
}
- else
+ /* Skip pages marked as empty in bitmap */
+ offset_page= (((pos / block_size) % info->s->bitmap.pages_covered) -1) * 3;
+ offset= offset_page & 7;
+ data= bitmap_buff + offset_page / 8;
+ bitmap_pattern= uint2korr(data);
+ param->splits++;
+ if (!((bitmap_pattern >> offset) & 7))
{
- got_error=0;
- if (error++ > MAXERR || !(param->testflag & T_VERBOSE))
- goto err2;
+ param->empty+= block_size;
+ param->del_blocks++;
+ continue;
+ }
+
+ if (_ma_read_cache(&param->read_cache, page_buff, pos,
+ block_size, READING_NEXT))
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Got error: %d when reading datafile",
+ my_errno, llstr(pos, llbuff));
+ goto err;
+ }
+ page_type= page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK;
+ if (page_type == UNALLOCATED_PAGE || page_type >= MAX_PAGE_TYPE)
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Found wrong page type %d\n",
+ llstr(pos, llbuff), page_type);
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ goto err;
+ }
+ switch ((enum en_page_type) page_type) {
+ case UNALLOCATED_PAGE:
+ case MAX_PAGE_TYPE:
+ DBUG_PRINT("warning",
+ ("Found page with wrong page type: %d", page_type));
+ DBUG_ASSERT(0);
+ break;
+ case HEAD_PAGE:
+ row_count= ((uchar*) page_buff)[DIR_ENTRY_OFFSET];
+ empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
+ param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
+ row_count * DIR_ENTRY_SIZE);
+ param->link_used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
+ row_count * DIR_ENTRY_SIZE);
+ full_dir= row_count == MAX_ROWS_PER_PAGE;
+ break;
+ case TAIL_PAGE:
+ row_count= ((uchar*) page_buff)[DIR_ENTRY_OFFSET];
+ empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
+ param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
+ row_count * DIR_ENTRY_SIZE);
+ param->link_used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
+ row_count * DIR_ENTRY_SIZE);
+ full_dir= row_count == MAX_ROWS_PER_PAGE;
+ break;
+ case BLOB_PAGE:
+ full_page_count++;
+ full_dir= 0;
+ empty_space= block_size; /* for error reporting */
+ param->link_used+= (LSN_SIZE + PAGE_TYPE_SIZE);
+ param->used+= block_size;
+ break;
}
- next:; /* Next record */
+ if (_ma_check_bitmap_data(info, page_type, pos / block_size,
+ full_dir ? 0 : empty_space,
+ &bitmap_pattern))
+ {
+ _ma_check_print_error(param,
+ "Page %9s: Wrong data in bitmap. Page_type: %d empty_space: %u Bitmap: %d",
+ llstr(pos, llbuff), page_type, empty_space,
+ bitmap_pattern);
+ if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
+ goto err;
+ }
+ if ((enum en_page_type) page_type == BLOB_PAGE)
+ continue;
+ param->empty+= empty_space;
+ if (check_page_layout(param, info, pos, page_buff, row_count,
+ empty_space, &real_row_count))
+ goto err;
+ if ((enum en_page_type) page_type == TAIL_PAGE)
+ {
+ tail_count+= real_row_count;
+ continue;
+ }
+ if (check_head_page(param, info, record, extend, pos, page_buff,
+ row_count))
+ goto err;
}
+
+ _ma_scan_end_block_record(info);
+
+ if (full_page_count != param->full_page_count)
+ _ma_check_print_error(param, "Full page count read through records was %s but we found %s pages while scanning table",
+ llstr(param->full_page_count, llbuff),
+ llstr(full_page_count, llbuff2));
+ if (tail_count != param->tail_count)
+ _ma_check_print_error(param, "Tail count read through records was %s but we found %s tails while scanning table",
+ llstr(param->tail_count, llbuff),
+ llstr(tail_count, llbuff2));
+
+ /* Update splits to avoid warning */
+ info->s->state.split= param->splits;
+ info->state->del= param->del_blocks;
+ return param->error_printed != 0;
+
+err:
+ _ma_scan_end_block_record(info);
+ return 1;
+}
+
+
+ /* Check that record-link is ok */
+
+int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
+{
+ int error;
+ byte *record;
+ char llbuff[22],llbuff2[22],llbuff3[22];
+ DBUG_ENTER("maria_chk_data_link");
+
+ if (!(param->testflag & T_SILENT))
+ {
+ if (extend)
+ puts("- check records and index references");
+ else
+ puts("- check record links");
+ }
+
+ if (!(record= (byte*) my_malloc(info->s->base.pack_reclength,MYF(0))))
+ {
+ _ma_check_print_error(param,"Not enough memory for record");
+ DBUG_RETURN(-1);
+ }
+ param->records= param->del_blocks= 0;
+ param->used= param->link_used= param->splits= param->del_length= 0;
+ param->tmp_record_checksum= param->glob_crc= 0;
+ param->err_count= 0;
+ LINT_INIT(left_length); LINT_INIT(start_recpos); LINT_INIT(to);
+ error= 0;
+ param->empty= info->s->pack.header_length;
+
+ bzero((char*) param->tmp_key_crc,
+ info->s->base.keys * sizeof(param->tmp_key_crc[0]));
+
+ switch (info->s->data_file_type) {
+ case BLOCK_RECORD:
+ error= check_block_record(param, info, extend, record);
+ break;
+ case STATIC_RECORD:
+ error= check_static_record(param, info, extend, record);
+ break;
+ case DYNAMIC_RECORD:
+ error= check_dynamic_record(param, info, extend, record);
+ break;
+ case COMPRESSED_RECORD:
+ error= check_compressed_record(param, info, extend, record);
+ break;
+ } /* switch */
+
+ if (error)
+ goto err;
+
if (param->testflag & T_WRITE_LOOP)
{
VOID(fputs(" \r",stdout)); VOID(fflush(stdout));
}
- if (records != info->state->records)
+ if (param->records != info->state->records)
{
- _ma_check_print_error(param,"Record-count is not ok; is %-10s Should be: %s",
- llstr(records,llbuff), llstr(info->state->records,llbuff2));
+ _ma_check_print_error(param,
+ "Record-count is not ok; found %-10s Should be: %s",
+ llstr(param->records,llbuff),
+ llstr(info->state->records,llbuff2));
error=1;
}
else if (param->record_checksum &&
- param->record_checksum != intern_record_checksum)
+ param->record_checksum != param->tmp_record_checksum)
{
_ma_check_print_error(param,
- "Keypointers and record positions doesn't match");
+ "Key pointers and record positions doesn't match");
error=1;
}
else if (param->glob_crc != info->state->checksum &&
@@ -1296,9 +1781,10 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
}
else if (!extend)
{
+ uint key;
for (key=0 ; key < info->s->base.keys; key++)
{
- if (key_checksum[key] != param->key_crc[key] &&
+ if (param->tmp_key_crc[key] != param->key_crc[key] &&
!(info->s->keyinfo[key].flag & (HA_FULLTEXT | HA_SPATIAL)))
{
_ma_check_print_error(param,"Checksum for key: %2d doesn't match checksum for records",
@@ -1308,68 +1794,83 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
}
}
- if (del_length != info->state->empty)
+ if (param->del_length != info->state->empty)
{
_ma_check_print_warning(param,
"Found %s deleted space. Should be %s",
- llstr(del_length,llbuff2),
+ llstr(param->del_length,llbuff2),
llstr(info->state->empty,llbuff));
}
- if (used+empty+del_length != info->state->data_file_length)
+ if (param->used + param->empty + param->del_length !=
+ info->state->data_file_length)
{
_ma_check_print_warning(param,
- "Found %s record-data and %s unused data and %s deleted-data",
- llstr(used,llbuff),llstr(empty,llbuff2),
- llstr(del_length,llbuff3));
+ "Found %s record data and %s unused data and %s deleted data",
+ llstr(param->used, llbuff),
+ llstr(param->empty,llbuff2),
+ llstr(param->del_length,llbuff3));
_ma_check_print_warning(param,
- "Total %s, Should be: %s",
- llstr((used+empty+del_length),llbuff),
+ "Total %s Should be: %s",
+ llstr((param->used+param->empty+param->del_length),
+ llbuff),
llstr(info->state->data_file_length,llbuff2));
}
- if (del_blocks != info->state->del)
+ if (param->del_blocks != info->state->del)
{
_ma_check_print_warning(param,
"Found %10s deleted blocks Should be: %s",
- llstr(del_blocks,llbuff),
+ llstr(param->del_blocks,llbuff),
llstr(info->state->del,llbuff2));
}
- if (splits != info->s->state.split)
+ if (param->splits != info->s->state.split)
{
_ma_check_print_warning(param,
"Found %10s parts Should be: %s parts",
- llstr(splits,llbuff),
+ llstr(param->splits, llbuff),
llstr(info->s->state.split,llbuff2));
}
if (param->testflag & T_INFO)
{
if (param->warning_printed || param->error_printed)
puts("");
- if (used != 0 && ! param->error_printed)
+ if (param->used != 0 && ! param->error_printed)
{
- printf("Records:%18s M.recordlength:%9lu Packed:%14.0f%%\n",
- llstr(records,llbuff), (long)((used-link_used)/records),
- (info->s->base.blobs ? 0.0 :
- (ulonglong2double((ulonglong) info->s->base.reclength*records)-
- my_off_t2double(used))/
- ulonglong2double((ulonglong) info->s->base.reclength*records)*100.0));
- printf("Recordspace used:%9.0f%% Empty space:%12d%% Blocks/Record: %6.2f\n",
- (ulonglong2double(used-link_used)/ulonglong2double(used-link_used+empty)*100.0),
- (!records ? 100 : (int) (ulonglong2double(del_length+empty)/
- my_off_t2double(used)*100.0)),
- ulonglong2double(splits - del_blocks) / records);
+ if (param->records)
+ {
+ printf("Records:%18s M.recordlength:%9lu Packed:%14.0f%%\n",
+ llstr(param->records,llbuff),
+ (long)((param->used - param->link_used)/param->records),
+ (info->s->base.blobs ? 0.0 :
+ (ulonglong2double((ulonglong) info->s->base.reclength *
+ param->records)-
+ my_off_t2double(param->used))/
+ ulonglong2double((ulonglong) info->s->base.reclength *
+ param->records)*100.0));
+ printf("Recordspace used:%9.0f%% Empty space:%12d%% Blocks/Record: %6.2f\n",
+ (ulonglong2double(param->used - param->link_used)/
+ ulonglong2double(param->used-param->link_used+param->empty)*100.0),
+ (!param->records ? 100 :
+ (int) (ulonglong2double(param->del_length+param->empty)/
+ my_off_t2double(param->used)*100.0)),
+ ulonglong2double(param->splits - param->del_blocks) /
+ param->records);
+ }
+ else
+ printf("Records:%18s\n", "0");
}
printf("Record blocks:%12s Delete blocks:%10s\n",
- llstr(splits-del_blocks,llbuff),llstr(del_blocks,llbuff2));
+ llstr(param->splits - param->del_blocks, llbuff),
+ llstr(param->del_blocks, llbuff2));
printf("Record data: %12s Deleted data: %10s\n",
- llstr(used-link_used,llbuff),llstr(del_length,llbuff2));
+ llstr(param->used - param->link_used,llbuff),
+ llstr(param->del_length, llbuff2));
printf("Lost space: %12s Linkdata: %10s\n",
- llstr(empty,llbuff),llstr(link_used,llbuff2));
+ llstr(param->empty, llbuff),llstr(param->link_used, llbuff2));
}
my_free((gptr) record,MYF(0));
DBUG_RETURN (error);
+
err:
- _ma_check_print_error(param,"got error: %d when reading datafile at record: %s",my_errno, llstr(records,llbuff));
- err2:
my_free((gptr) record,MYF(0));
param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1);
@@ -1380,7 +1881,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
/* Save new datafile-name in temp_filename */
int maria_repair(HA_CHECK *param, register MARIA_HA *info,
- my_string name, int rep_quick)
+ my_string name, int rep_quick)
{
int error,got_error;
uint i;
@@ -1431,7 +1932,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
info->opt_flag|=WRITE_CACHE_USED;
if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
MYF(0))) ||
- !_ma_alloc_rec_buff(info, -1, &sort_param.rec_buff))
+ _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
+ info->s->base.default_rec_buff_size))
{
_ma_check_print_error(param, "Not enough memory for extra record");
goto err;
@@ -1440,14 +1942,11 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (!rep_quick)
{
/* Get real path for data file */
- if ((new_file=my_raid_create(fn_format(param->temp_filename,
- share->data_file_name, "",
- DATA_TMP_EXT, 2+4),
- 0,param->tmpfile_createflag,
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize,
- MYF(0))) < 0)
+ if ((new_file= my_create(fn_format(param->temp_filename,
+ share->data_file_name, "",
+ DATA_TMP_EXT, 2+4),
+ 0,param->tmpfile_createflag,
+ MYF(0))) < 0)
{
_ma_check_print_error(param,"Can't create new tempfile: '%s'",
param->temp_filename);
@@ -1460,10 +1959,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
info->s->state.dellink= HA_OFFSET_ERROR;
info->rec_cache.file=new_file;
if (param->testflag & T_UNPACK)
- {
- share->options&= ~HA_OPTION_COMPRESS_RECORD;
- mi_int2store(share->state.header.options,share->options);
- }
+ restore_data_file_type(share);
}
sort_info.info=info;
sort_info.param = param;
@@ -1495,8 +1991,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
share->state.key_root[i]= HA_OFFSET_ERROR;
/* Drop the delete chain. */
- for (i=0 ; i < share->state.header.max_block_size_index ; i++)
- share->state.key_del[i]= HA_OFFSET_ERROR;
+ share->state.key_del= HA_OFFSET_ERROR;
/*
If requested, activate (enable) all keys in key_map. In this case,
@@ -1520,7 +2015,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
_ma_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
info->errkey+1,
llstr(sort_param.start_recpos,llbuff),
- llstr(info->dupp_key_pos,llbuff2));
+ llstr(info->dup_key_pos,llbuff2));
if (param->testflag & T_VERBOSE)
{
VOID(_ma_make_key(info,(uint) info->errkey,info->lastkey,
@@ -1614,8 +2109,7 @@ err:
my_close(new_file,MYF(0));
info->dfile=new_file= -1;
if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
- DATA_TMP_EXT, share->base.raid_chunks,
- (param->testflag & T_BACKUP_DATA ?
+ DATA_TMP_EXT, (param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
_ma_open_datafile(info,share,-1))
got_error=1;
@@ -1629,44 +2123,38 @@ err:
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
- VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
- MYF(MY_WME)));
+ VOID(my_delete(param->temp_filename, MYF(MY_WME)));
info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
}
maria_mark_crashed_on_repair(info);
}
- my_free(_ma_get_rec_buff_ptr(info, sort_param.rec_buff),
- MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.rec_buff, MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
VOID(end_io_cache(&info->rec_cache));
got_error|=_ma_flush_blocks(param, share->key_cache, share->kfile);
- if (!got_error && param->testflag & T_UNPACK)
- {
- share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
- share->pack.header_length=0;
- share->data_file_type=sort_info.new_data_file_type;
- }
+ if (!got_error && (param->testflag & T_UNPACK))
+ restore_data_file_type(share);
share->state.changed|= (STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES |
STATE_NOT_ANALYZED);
DBUG_RETURN(got_error);
}
-/* Uppate keyfile when doing repair */
+/* Uppdate keyfile when doing repair */
static int writekeys(MARIA_SORT_PARAM *sort_param)
{
register uint i;
- uchar *key;
+ byte *key;
MARIA_HA *info= sort_param->sort_info->info;
byte *buff= sort_param->record;
my_off_t filepos= sort_param->filepos;
DBUG_ENTER("writekeys");
- key=info->lastkey+info->s->base.max_key_length;
+ key= info->lastkey+info->s->base.max_key_length;
for (i=0 ; i < info->s->base.keys ; i++)
{
if (maria_is_key_active(info->s->state.key_map, i))
@@ -1718,7 +2206,7 @@ static int writekeys(MARIA_SORT_PARAM *sort_param)
}
/* Remove checksum that was added to glob_crc in sort_get_next_record */
if (sort_param->calc_checksum)
- sort_param->sort_info->param->glob_crc-= info->checksum;
+ sort_param->glob_crc-= info->cur_row.checksum;
DBUG_PRINT("error",("errno: %d",my_errno));
DBUG_RETURN(-1);
} /* writekeys */
@@ -1726,15 +2214,16 @@ static int writekeys(MARIA_SORT_PARAM *sort_param)
/* Change all key-pointers that points to a records */
-int maria_movepoint(register MARIA_HA *info, byte *record, my_off_t oldpos,
- my_off_t newpos, uint prot_key)
+int maria_movepoint(register MARIA_HA *info, byte *record,
+ MARIA_RECORD_POS oldpos, MARIA_RECORD_POS newpos,
+ uint prot_key)
{
register uint i;
- uchar *key;
+ byte *key;
uint key_length;
DBUG_ENTER("maria_movepoint");
- key=info->lastkey+info->s->base.max_key_length;
+ key= info->lastkey+info->s->base.max_key_length;
for (i=0 ; i < info->s->base.keys; i++)
{
if (i != prot_key && maria_is_key_active(info->s->state.key_map, i))
@@ -1828,8 +2317,9 @@ int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, my_string name)
param->temp_filename);
DBUG_RETURN(-1);
}
- if (maria_filecopy(param, new_file,share->kfile,0L,
- (ulong) share->base.keystart, "headerblock"))
+ if (new_header_length &&
+ maria_filecopy(param, new_file,share->kfile,0L,
+ (ulong) share->base.keystart, "headerblock"))
goto err;
param->new_file_pos=share->base.keystart;
@@ -1850,7 +2340,7 @@ int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, my_string name)
index_pos[key]= HA_OFFSET_ERROR; /* No blocks */
}
- /* Flush key cache for this file if we are calling this outside mariachk */
+ /* Flush key cache for this file if we are calling this outside maria_chk */
flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
share->state.version=(ulong) time((time_t*) 0);
@@ -1865,8 +2355,8 @@ int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, my_string name)
VOID(my_close(share->kfile,MYF(MY_WME)));
share->kfile = -1;
VOID(my_close(new_file,MYF(MY_WME)));
- if (maria_change_to_newfile(share->index_file_name,MARIA_NAME_IEXT,INDEX_TMP_EXT,0,
- MYF(0)) ||
+ if (maria_change_to_newfile(share->index_file_name, MARIA_NAME_IEXT,
+ INDEX_TMP_EXT, MYF(0)) ||
_ma_open_keyfile(share))
goto err2;
info->lock_type= F_UNLCK; /* Force maria_readinfo to lock */
@@ -1881,8 +2371,7 @@ int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, my_string name)
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
for (key=0 ; key < info->s->base.keys ; key++)
info->s->state.key_root[key]=index_pos[key];
- for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
- info->s->state.key_del[key]= HA_OFFSET_ERROR;
+ info->s->state.key_del= HA_OFFSET_ERROR;
info->s->state.changed&= ~STATE_NOT_SORTED_PAGES;
DBUG_RETURN(0);
@@ -1897,12 +2386,13 @@ err2:
/* Sort records recursive using one index */
-static int sort_one_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
+ MARIA_KEYDEF *keyinfo,
my_off_t pagepos, File new_file)
{
uint length,nod_flag,used_length, key_length;
- uchar *buff,*keypos,*endpos;
- uchar key[HA_MAX_POSSIBLE_KEY_BUFF];
+ byte *buff,*keypos,*endpos;
+ byte key[HA_MAX_POSSIBLE_KEY_BUFF];
my_off_t new_page_pos,next_page;
char llbuff[22];
DBUG_ENTER("sort_one_index");
@@ -1910,7 +2400,7 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo
new_page_pos=param->new_file_pos;
param->new_file_pos+=keyinfo->block_length;
- if (!(buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
+ if (!(buff= (byte*) my_alloca((uint) keyinfo->block_length)))
{
_ma_check_print_error(param,"Not enough memory for key block");
DBUG_RETURN(-1);
@@ -1993,9 +2483,7 @@ err:
*/
int maria_change_to_newfile(const char * filename, const char * old_ext,
- const char * new_ext,
- uint raid_chunks __attribute__((unused)),
- myf MyFlags)
+ const char * new_ext, myf MyFlags)
{
char old_filename[FN_REFLEN],new_filename[FN_REFLEN];
#ifdef USE_RAID
@@ -2067,7 +2555,7 @@ err:
*/
int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
- const char * name, int rep_quick)
+ const char * name, int rep_quick)
{
int got_error;
uint i;
@@ -2120,7 +2608,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
MYF(0))) ||
- !_ma_alloc_rec_buff(info, -1, &sort_param.rec_buff))
+ _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
+ info->s->base.default_rec_buff_size))
{
_ma_check_print_error(param, "Not enough memory for extra record");
goto err;
@@ -2128,14 +2617,11 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
if (!rep_quick)
{
/* Get real path for data file */
- if ((new_file=my_raid_create(fn_format(param->temp_filename,
- share->data_file_name, "",
- DATA_TMP_EXT, 2+4),
- 0,param->tmpfile_createflag,
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize,
- MYF(0))) < 0)
+ if ((new_file=my_create(fn_format(param->temp_filename,
+ share->data_file_name, "",
+ DATA_TMP_EXT, 2+4),
+ 0,param->tmpfile_createflag,
+ MYF(0))) < 0)
{
_ma_check_print_error(param,"Can't create new tempfile: '%s'",
param->temp_filename);
@@ -2146,10 +2632,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
- {
- share->options&= ~HA_OPTION_COMPRESS_RECORD;
- mi_int2store(share->state.header.options,share->options);
- }
+ restore_data_file_type(share);
share->state.dellink= HA_OFFSET_ERROR;
info->rec_cache.file=new_file;
}
@@ -2159,14 +2642,13 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
{
/*
Flush key cache for this file if we are calling this outside
- mariachk
+ maria_chk
*/
flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
/* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
- for (i=0 ; i < share->state.header.max_block_size_index ; i++)
- share->state.key_del[i]= HA_OFFSET_ERROR;
+ share->state.key_del= HA_OFFSET_ERROR;
info->state->key_file_length=share->base.keystart;
}
else
@@ -2278,13 +2760,13 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
10*param->sort_buffer_length/sort_param.key_length;
}
- sort_param.key_read=sort_maria_ft_key_read;
- sort_param.key_write=sort_maria_ft_key_write;
+ sort_param.key_read= sort_maria_ft_key_read;
+ sort_param.key_write= sort_maria_ft_key_write;
}
else
{
- sort_param.key_read=sort_key_read;
- sort_param.key_write=sort_key_write;
+ sort_param.key_read= sort_key_read;
+ sort_param.key_write= sort_key_write;
}
if (_ma_create_index_by_sort(&sort_param,
@@ -2364,7 +2846,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
skr < share->base.reloc*share->base.min_pack_length)
skr=share->base.reloc*share->base.min_pack_length;
#endif
- if (skr != sort_info.filelength && !info->s->base.raid_type)
+ if (skr != sort_info.filelength)
if (my_chsize(info->dfile,skr,0,MYF(0)))
_ma_check_print_warning(param,
"Can't change size of datafile, error: %d",
@@ -2403,9 +2885,9 @@ err:
my_close(new_file,MYF(0));
info->dfile=new_file= -1;
if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
- DATA_TMP_EXT, share->base.raid_chunks,
- (param->testflag & T_BACKUP_DATA ?
- MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
+ DATA_TMP_EXT,
+ (param->testflag & T_BACKUP_DATA ?
+ MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
_ma_open_datafile(info,share,-1))
got_error=1;
}
@@ -2417,8 +2899,7 @@ err:
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
- VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
- MYF(MY_WME)));
+ VOID(my_delete(param->temp_filename, MYF(MY_WME)));
if (info->dfile == new_file)
info->dfile= -1;
}
@@ -2428,8 +2909,7 @@ err:
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
share->state.changed|=STATE_NOT_SORTED_PAGES;
- my_free(_ma_get_rec_buff_ptr(info, sort_param.rec_buff),
- MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.rec_buff, MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
@@ -2437,10 +2917,7 @@ err:
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
if (!got_error && (param->testflag & T_UNPACK))
- {
- share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
- share->pack.header_length=0;
- }
+ restore_data_file_type(share);
DBUG_RETURN(got_error);
}
@@ -2582,29 +3059,22 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (!rep_quick)
{
/* Get real path for data file */
- if ((new_file=my_raid_create(fn_format(param->temp_filename,
- share->data_file_name, "",
- DATA_TMP_EXT,
- 2+4),
- 0,param->tmpfile_createflag,
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize,
- MYF(0))) < 0)
+ if ((new_file= my_create(fn_format(param->temp_filename,
+ share->data_file_name, "",
+ DATA_TMP_EXT,
+ 2+4),
+ 0,param->tmpfile_createflag,
+ MYF(0))) < 0)
{
_ma_check_print_error(param,"Can't create new tempfile: '%s'",
param->temp_filename);
goto err;
}
- if (new_header_length &&
- maria_filecopy(param, new_file,info->dfile,0L,new_header_length,
- "datafile-header"))
+ if (maria_filecopy(param, new_file,info->dfile,0L,new_header_length,
+ "datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
- {
- share->options&= ~HA_OPTION_COMPRESS_RECORD;
- mi_int2store(share->state.header.options,share->options);
- }
+ restore_data_file_type(share);
share->state.dellink= HA_OFFSET_ERROR;
info->rec_cache.file=new_file;
}
@@ -2614,14 +3084,13 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
{
/*
Flush key cache for this file if we are calling this outside
- mariachk
+ maria_chk
*/
flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
/* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
- for (i=0 ; i < share->state.header.max_block_size_index ; i++)
- share->state.key_del[i]= HA_OFFSET_ERROR;
+ share->state.key_del= HA_OFFSET_ERROR;
info->state->key_file_length=share->base.keystart;
}
else
@@ -2720,12 +3189,12 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
sort_param[i].record= (((char *)(sort_param+share->base.keys))+
(share->base.pack_reclength * i));
- if (!_ma_alloc_rec_buff(info, -1, &sort_param[i].rec_buff))
+ if (_ma_alloc_buffer(&sort_param[i].rec_buff, &sort_param[i].rec_buff_size,
+ share->base.default_rec_buff_size))
{
_ma_check_print_error(param,"Not enough memory!");
goto err;
}
-
sort_param[i].key_length=share->rec_reflength;
for (keyseg=sort_param[i].seg; keyseg->type != HA_KEYTYPE_END;
keyseg++)
@@ -2884,7 +3353,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
skr < share->base.reloc*share->base.min_pack_length)
skr=share->base.reloc*share->base.min_pack_length;
#endif
- if (skr != sort_info.filelength && !info->s->base.raid_type)
+ if (skr != sort_info.filelength)
if (my_chsize(info->dfile,skr,0,MYF(0)))
_ma_check_print_warning(param,
"Can't change size of datafile, error: %d",
@@ -2935,9 +3404,9 @@ err:
my_close(new_file,MYF(0));
info->dfile=new_file= -1;
if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
- DATA_TMP_EXT, share->base.raid_chunks,
- (param->testflag & T_BACKUP_DATA ?
- MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
+ DATA_TMP_EXT,
+ (param->testflag & T_BACKUP_DATA ?
+ MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
_ma_open_datafile(info,share,-1))
got_error=1;
}
@@ -2949,8 +3418,7 @@ err:
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
- VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
- MYF(MY_WME)));
+ VOID(my_delete(param->temp_filename, MYF(MY_WME)));
if (info->dfile == new_file)
info->dfile= -1;
}
@@ -2970,21 +3438,18 @@ err:
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
if (!got_error && (param->testflag & T_UNPACK))
- {
- share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
- share->pack.header_length=0;
- }
+ restore_data_file_type(share);
DBUG_RETURN(got_error);
#endif /* THREAD */
}
/* Read next record and return next key */
-static int sort_key_read(MARIA_SORT_PARAM *sort_param, void *key)
+static int sort_key_read(MARIA_SORT_PARAM *sort_param, byte *key)
{
int error;
- MARIA_SORT_INFO *sort_info=sort_param->sort_info;
- MARIA_HA *info=sort_info->info;
+ MARIA_SORT_INFO *sort_info= sort_param->sort_info;
+ MARIA_HA *info= sort_info->info;
DBUG_ENTER("sort_key_read");
if ((error=sort_get_next_record(sort_param)))
@@ -2998,7 +3463,7 @@ static int sort_key_read(MARIA_SORT_PARAM *sort_param, void *key)
}
sort_param->real_key_length=
(info->s->rec_reflength+
- _ma_make_key(info, sort_param->key, (uchar*) key,
+ _ma_make_key(info, sort_param->key, key,
sort_param->record, sort_param->filepos));
#ifdef HAVE_purify
bzero(key+sort_param->real_key_length,
@@ -3007,7 +3472,8 @@ static int sort_key_read(MARIA_SORT_PARAM *sort_param, void *key)
DBUG_RETURN(_ma_sort_write_record(sort_param));
} /* sort_key_read */
-static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, void *key)
+
+static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, byte *key)
{
int error;
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
@@ -3040,7 +3506,8 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, void *key)
sort_param->real_key_length=(info->s->rec_reflength+
_ma_ft_make_key(info, sort_param->key,
- key, wptr++, sort_param->filepos));
+ key, wptr++,
+ sort_param->filepos));
#ifdef HAVE_purify
if (sort_param->key_length > sort_param->real_key_length)
bzero(key+sort_param->real_key_length,
@@ -3109,6 +3576,9 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
DBUG_RETURN(1);
switch (share->data_file_type) {
+ case BLOCK_RECORD:
+ DBUG_ASSERT(0);
+ break;
case STATIC_RECORD:
for (;;)
{
@@ -3132,7 +3602,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (*sort_param->record)
{
if (sort_param->calc_checksum)
- param->glob_crc+= (info->checksum=
+ param->glob_crc+= (info->cur_row.checksum=
_ma_static_checksum(info,sort_param->record));
DBUG_RETURN(0);
}
@@ -3317,8 +3787,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
sort_param->pos=block_info.filepos+block_info.block_len;
if (share->base.blobs)
{
- if (!(to=_ma_alloc_rec_buff(info,block_info.rec_len,
- &(sort_param->rec_buff))))
+ if (_ma_alloc_buffer(&sort_param->rec_buff,
+ &sort_param->rec_buff_size,
+ block_info.rec_len +
+ info->s->base.extra_rec_buff_size))
+
{
if (param->max_record_length >= block_info.rec_len)
{
@@ -3336,8 +3809,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
}
}
- else
- to= sort_param->rec_buff;
+ to= sort_param->rec_buff;
}
if (left_length < block_info.data_len || ! block_info.data_len)
{
@@ -3409,7 +3881,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (sort_param->read_cache.error < 0)
DBUG_RETURN(1);
if (sort_param->calc_checksum)
- info->checksum= _ma_checksum(info, sort_param->record);
+ info->cur_row.checksum= _ma_checksum(info, sort_param->record);
if ((param->testflag & (T_EXTEND | T_REP)) || searching)
{
if (_ma_rec_check(info, sort_param->record, sort_param->rec_buff,
@@ -3424,7 +3896,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
}
if (sort_param->calc_checksum)
- param->glob_crc+= info->checksum;
+ param->glob_crc+= info->cur_row.checksum;
DBUG_RETURN(0);
}
if (!searching)
@@ -3492,9 +3964,13 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
sort_param->max_pos=(sort_param->pos=block_info.filepos+
block_info.rec_len);
info->packed_length=block_info.rec_len;
+
if (sort_param->calc_checksum)
- param->glob_crc+= (info->checksum=
- _ma_checksum(info, sort_param->record));
+ {
+ info->cur_row.checksum= (*info->s->calc_checksum)(info,
+ sort_param->record);
+ param->glob_crc+= info->cur_row.checksum;
+ }
DBUG_RETURN(0);
}
}
@@ -3533,6 +4009,9 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
if (sort_param->fix_datafile)
{
switch (sort_info->new_data_file_type) {
+ case BLOCK_RECORD:
+ DBUG_ASSERT(0);
+ break;
case STATIC_RECORD:
if (my_b_write(&info->rec_cache,sort_param->record,
share->base.pack_reclength))
@@ -3542,7 +4021,6 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
}
sort_param->filepos+=share->base.pack_reclength;
info->s->state.split++;
- /* sort_info->param->glob_crc+=_ma_static_checksum(info, sort_param->record); */
break;
case DYNAMIC_RECORD:
if (! info->blobs)
@@ -3564,11 +4042,10 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
}
from=sort_info->buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER);
}
- /* We can use info->checksum here as only one thread calls this. */
- info->checksum=_ma_checksum(info,sort_param->record);
+ /* We can use info->checksum here as only one thread calls this */
+ info->cur_row.checksum= _ma_checksum(info,sort_param->record);
reclength= _ma_rec_pack(info,from,sort_param->record);
flag=0;
- /* sort_info->param->glob_crc+=info->checksum; */
do
{
@@ -3589,7 +4066,6 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
sort_param->filepos+=block_length;
info->s->state.split++;
} while (reclength);
- /* sort_info->param->glob_crc+=info->checksum; */
break;
case COMPRESSED_RECORD:
reclength=info->packed_length;
@@ -3604,7 +4080,6 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
_ma_check_print_error(param,"%d when writing to datafile",my_errno);
DBUG_RETURN(1);
}
- /* sort_info->param->glob_crc+=info->checksum; */
sort_param->filepos+=reclength+length;
info->s->state.split++;
break;
@@ -3636,7 +4111,7 @@ static int sort_key_cmp(MARIA_SORT_PARAM *sort_param, const void *a,
} /* sort_key_cmp */
-static int sort_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
+static int sort_key_write(MARIA_SORT_PARAM *sort_param, const byte *a)
{
uint diff_pos[2];
char llbuff[22],llbuff2[22];
@@ -3646,11 +4121,11 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
if (sort_info->key_block->inited)
{
- cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
+ cmp=ha_key_cmp(sort_param->seg, (uchar*) sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
diff_pos);
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
- ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
+ ha_key_cmp(sort_param->seg, (uchar*) sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
@@ -3658,7 +4133,7 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
diff_pos[0]= maria_collect_stats_nonulls_next(sort_param->seg,
sort_param->notnull,
sort_info->key_block->lastkey,
- (uchar*)a);
+ a);
}
sort_param->unique[diff_pos[0]-1]++;
}
@@ -3667,17 +4142,17 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
cmp= -1;
if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
maria_collect_stats_nonulls_first(sort_param->seg, sort_param->notnull,
- (uchar*)a);
+ a);
}
if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
{
sort_info->dupp++;
- sort_info->info->lastpos=get_record_for_key(sort_info->info,
- sort_param->keyinfo,
- (uchar*) a);
+ sort_info->info->cur_row.lastpos= get_record_for_key(sort_info->info,
+ sort_param->keyinfo,
+ a);
_ma_check_print_warning(param,
"Duplicate key for record at %10s against record at %10s",
- llstr(sort_info->info->lastpos,llbuff),
+ llstr(sort_info->info->cur_row.lastpos, llbuff),
llstr(get_record_for_key(sort_info->info,
sort_param->keyinfo,
sort_info->key_block->
@@ -3685,7 +4160,7 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
llbuff2));
param->testflag|=T_RETRY_WITHOUT_QUICK;
if (sort_info->param->testflag & T_VERBOSE)
- _ma_print_key(stdout,sort_param->seg,(uchar*) a, USE_WHOLE_KEY);
+ _ma_print_key(stdout,sort_param->seg, a, USE_WHOLE_KEY);
return (sort_delete_record(sort_param));
}
#ifndef DBUG_OFF
@@ -3696,10 +4171,11 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
return(1);
}
#endif
- return (sort_insert_key(sort_param,sort_info->key_block,
- (uchar*) a, HA_OFFSET_ERROR));
+ return (sort_insert_key(sort_param, sort_info->key_block,
+ a, HA_OFFSET_ERROR));
} /* sort_key_write */
+
int _ma_sort_ft_buf_flush(MARIA_SORT_PARAM *sort_param)
{
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
@@ -3708,24 +4184,24 @@ int _ma_sort_ft_buf_flush(MARIA_SORT_PARAM *sort_param)
uint val_off, val_len;
int error;
SORT_FT_BUF *maria_ft_buf=sort_info->ft_buf;
- uchar *from, *to;
+ byte *from, *to;
val_len=share->ft2_keyinfo.keylength;
get_key_full_length_rdonly(val_off, maria_ft_buf->lastkey);
- to=maria_ft_buf->lastkey+val_off;
+ to= maria_ft_buf->lastkey+val_off;
if (maria_ft_buf->buf)
{
/* flushing first-level tree */
- error=sort_insert_key(sort_param,key_block,maria_ft_buf->lastkey,
- HA_OFFSET_ERROR);
+ error= sort_insert_key(sort_param,key_block,maria_ft_buf->lastkey,
+ HA_OFFSET_ERROR);
for (from=to+val_len;
!error && from < maria_ft_buf->buf;
from+= val_len)
{
memcpy(to, from, val_len);
- error=sort_insert_key(sort_param,key_block,maria_ft_buf->lastkey,
- HA_OFFSET_ERROR);
+ error= sort_insert_key(sort_param,key_block,maria_ft_buf->lastkey,
+ HA_OFFSET_ERROR);
}
return error;
}
@@ -3745,10 +4221,11 @@ int _ma_sort_ft_buf_flush(MARIA_SORT_PARAM *sort_param)
maria_ft_buf->lastkey,HA_OFFSET_ERROR);
}
-static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
+
+static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param,
+ const byte *a)
{
uint a_len, val_off, val_len, error;
- uchar *p;
MARIA_SORT_INFO *sort_info= sort_param->sort_info;
SORT_FT_BUF *ft_buf= sort_info->ft_buf;
SORT_KEY_BLOCKS *key_block= sort_info->key_block;
@@ -3781,13 +4258,14 @@ static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param, const void *a)
if (ha_compare_text(sort_param->seg->charset,
((uchar *)a)+1,a_len-1,
- ft_buf->lastkey+1,val_off-1, 0, 0)==0)
+ (uchar*) ft_buf->lastkey+1,val_off-1, 0, 0)==0)
{
+ byte *p;
if (!ft_buf->buf) /* store in second-level tree */
{
ft_buf->count++;
return sort_insert_key(sort_param,key_block,
- ((uchar *)a)+a_len, HA_OFFSET_ERROR);
+ a + a_len, HA_OFFSET_ERROR);
}
/* storing the key in the buffer. */
@@ -3836,21 +4314,22 @@ word_init_ft_buf:
/* get pointer to record from a key */
static my_off_t get_record_for_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key)
+ const byte *key)
{
- return _ma_dpos(info,0,key + _ma_keylength(keyinfo,key));
+ return _ma_dpos(info,0, key + _ma_keylength(keyinfo, key));
} /* get_record_for_key */
/* Insert a key in sort-key-blocks */
static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
- register SORT_KEY_BLOCKS *key_block, uchar *key,
+ register SORT_KEY_BLOCKS *key_block,
+ const byte *key,
my_off_t prev_block)
{
uint a_length,t_length,nod_flag;
my_off_t filepos,key_file_length;
- uchar *anc_buff,*lastkey;
+ byte *anc_buff,*lastkey;
MARIA_KEY_PARAM s_temp;
MARIA_HA *info;
MARIA_KEYDEF *keyinfo=sort_param->keyinfo;
@@ -3858,7 +4337,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
HA_CHECK *param=sort_info->param;
DBUG_ENTER("sort_insert_key");
- anc_buff=key_block->buff;
+ anc_buff= key_block->buff;
info=sort_info->info;
lastkey=key_block->lastkey;
nod_flag= (key_block == sort_info->key_block ? 0 :
@@ -3884,7 +4363,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
_ma_kpointer(info,key_block->end_pos,prev_block);
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
- (uchar*) 0,lastkey,lastkey,key,
+ (byte*) 0,lastkey,lastkey,key,
&s_temp);
(*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
a_length+=t_length;
@@ -3892,14 +4371,14 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
key_block->end_pos+=t_length;
if (a_length <= keyinfo->block_length)
{
- VOID(_ma_move_key(keyinfo,key_block->lastkey,key));
+ VOID(_ma_move_key(keyinfo, key_block->lastkey, key));
key_block->last_length=a_length-t_length;
DBUG_RETURN(0);
}
/* Fill block with end-zero and write filled block */
maria_putint(anc_buff,key_block->last_length,nod_flag);
- bzero((byte*) anc_buff+key_block->last_length,
+ bzero(anc_buff+key_block->last_length,
keyinfo->block_length- key_block->last_length);
key_file_length=info->state->key_file_length;
if ((filepos= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
@@ -3911,10 +4390,10 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
if (_ma_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
DBUG_RETURN(1);
}
- else if (my_pwrite(info->s->kfile,(byte*) anc_buff,
+ else if (my_pwrite(info->s->kfile,anc_buff,
(uint) keyinfo->block_length,filepos, param->myf_rw))
DBUG_RETURN(1);
- DBUG_DUMP("buff",(byte*) anc_buff,maria_getint(anc_buff));
+ DBUG_DUMP("buff",anc_buff,maria_getint(anc_buff));
/* Write separator-key to block in next level */
if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
@@ -3932,7 +4411,7 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
{
uint i;
int old_file,error;
- uchar *key;
+ byte *key;
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
HA_CHECK *param=sort_info->param;
MARIA_HA *info=sort_info->info;
@@ -3947,7 +4426,7 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
{
_ma_check_print_error(param,
- "Recover aborted; Can't run standard recovery on compressed tables with errors in data-file. Use switch 'mariachk --safe-recover' to fix it\n",stderr);;
+ "Recover aborted; Can't run standard recovery on compressed tables with errors in data-file. Use switch 'maria_chk --safe-recover' to fix it\n",stderr);;
DBUG_RETURN(1);
}
@@ -3955,8 +4434,9 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
info->dfile=info->rec_cache.file;
if (sort_info->current_key)
{
- key=info->lastkey+info->s->base.max_key_length;
- if ((error=(*info->s->read_rnd)(info,sort_param->record,info->lastpos,0)) &&
+ key= info->lastkey+info->s->base.max_key_length;
+ if ((error=(*info->s->read_record)(info,sort_param->record,
+ info->cur_row.lastpos)) &&
error != HA_ERR_RECORD_DELETED)
{
_ma_check_print_error(param,"Can't read record to be removed");
@@ -3966,10 +4446,13 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
for (i=0 ; i < sort_info->current_key ; i++)
{
- uint key_length= _ma_make_key(info,i,key,sort_param->record,info->lastpos);
- if (_ma_ck_delete(info,i,key,key_length))
+ uint key_length= _ma_make_key(info, i, key, sort_param->record,
+ info->cur_row.lastpos);
+ if (_ma_ck_delete(info, i, key, key_length))
{
- _ma_check_print_error(param,"Can't delete key %d from record to be removed",i+1);
+ _ma_check_print_error(param,
+ "Can't delete key %d from record to be removed",
+ i+1);
info->dfile=old_file;
DBUG_RETURN(1);
}
@@ -4005,7 +4488,7 @@ int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
if (nod_flag)
_ma_kpointer(info,key_block->end_pos,filepos);
key_file_length=info->state->key_file_length;
- bzero((byte*) key_block->buff+length, keyinfo->block_length-length);
+ bzero(key_block->buff+length, keyinfo->block_length-length);
if ((filepos= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
@@ -4016,10 +4499,10 @@ int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
DFLT_INIT_HITS, key_block->buff))
DBUG_RETURN(1);
}
- else if (my_pwrite(info->s->kfile,(byte*) key_block->buff,
+ else if (my_pwrite(info->s->kfile,key_block->buff,
(uint) keyinfo->block_length,filepos, myf_rw))
DBUG_RETURN(1);
- DBUG_DUMP("buff",(byte*) key_block->buff,length);
+ DBUG_DUMP("buff",key_block->buff,length);
nod_flag=1;
}
info->s->state.key_root[sort_param->key]=filepos; /* Last is root for tree */
@@ -4035,9 +4518,9 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
SORT_KEY_BLOCKS *block;
DBUG_ENTER("alloc_key_blocks");
- if (!(block=(SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
- buffer_length+IO_SIZE)*blocks,
- MYF(0))))
+ if (!(block= (SORT_KEY_BLOCKS*) my_malloc((sizeof(SORT_KEY_BLOCKS)+
+ buffer_length+IO_SIZE)*blocks,
+ MYF(0))))
{
_ma_check_print_error(param,"Not enough memory for sort-key-blocks");
return(0);
@@ -4045,7 +4528,7 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
for (i=0 ; i < blocks ; i++)
{
block[i].inited=0;
- block[i].buff=(uchar*) (block+blocks)+(buffer_length+IO_SIZE)*i;
+ block[i].buff= (byte*) (block+blocks)+(buffer_length+IO_SIZE)*i;
}
DBUG_RETURN(block);
} /* alloc_key_blocks */
@@ -4088,7 +4571,8 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
share= *(*org_info)->s;
unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
(param->testflag & T_UNPACK);
- if (!(keyinfo=(MARIA_KEYDEF*) my_alloca(sizeof(MARIA_KEYDEF)*share.base.keys)))
+ if (!(keyinfo=(MARIA_KEYDEF*) my_alloca(sizeof(MARIA_KEYDEF) *
+ share.base.keys)))
DBUG_RETURN(0);
memcpy((byte*) keyinfo,(byte*) share.keyinfo,
(size_t) (sizeof(MARIA_KEYDEF)*share.base.keys));
@@ -4144,8 +4628,10 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
keyseg++; /* Skip end pointer */
}
- /* Copy the unique definitions and change them to point at the new key
- segments*/
+ /*
+ Copy the unique definitions and change them to point at the new key
+ segments
+ */
memcpy((byte*) uniquedef,(byte*) share.uniqueinfo,
(size_t) (sizeof(MARIA_UNIQUEDEF)*(share.state.header.uniques)));
for (u_ptr=uniquedef,u_end=uniquedef+share.state.header.uniques;
@@ -4161,7 +4647,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
(ulong) share.base.min_pack_length);
else
max_records=0;
- unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
+ unpack= (share.data_file_type == COMPRESSED_RECORD) &&
(param->testflag & T_UNPACK);
share.options&= ~HA_OPTION_TEMP_COMPRESS_RECORD;
@@ -4183,21 +4669,29 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
create_info.language = (param->language ? param->language :
share.state.header.language);
create_info.key_file_length= status_info.key_file_length;
+ create_info.org_data_file_type= ((enum data_file_type)
+ share.state.header.org_data_file_type);
+
/*
Allow for creating an auto_increment key. This has an effect only if
an auto_increment key exists in the original table.
*/
create_info.with_auto_increment= TRUE;
- /* We don't have to handle symlinks here because we are using
- HA_DONT_TOUCH_DATA */
- if (maria_create(filename,
- share.base.keys - share.state.header.uniques,
- keyinfo, share.base.fields, recdef,
- share.state.header.uniques, uniquedef,
- &create_info,
- HA_DONT_TOUCH_DATA))
- {
- _ma_check_print_error(param,"Got error %d when trying to recreate indexfile",my_errno);
+ create_info.null_bytes= share.base.null_bytes;
+ /*
+ We don't have to handle symlinks here because we are using
+ HA_DONT_TOUCH_DATA
+ */
+ if (maria_create(filename, share.data_file_type,
+ share.base.keys - share.state.header.uniques,
+ keyinfo, share.base.fields, recdef,
+ share.state.header.uniques, uniquedef,
+ &create_info,
+ HA_DONT_TOUCH_DATA))
+ {
+ _ma_check_print_error(param,
+ "Got error %d when trying to recreate indexfile",
+ my_errno);
goto end;
}
*org_info=maria_open(filename,O_RDWR,
@@ -4206,8 +4700,9 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
HA_OPEN_ABORT_IF_LOCKED);
if (!*org_info)
{
- _ma_check_print_error(param,"Got error %d when trying to open re-created indexfile",
- my_errno);
+ _ma_check_print_error(param,
+ "Got error %d when trying to open re-created indexfile",
+ my_errno);
goto end;
}
/* We are modifing */
@@ -4257,7 +4752,8 @@ int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile)
return 0;
}
- /* Update state and mariachk_time of indexfile */
+
+/* Update state and maria_chk time of indexfile */
int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
{
@@ -4570,12 +5066,7 @@ set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share)
COMPRESSED_RECORD && sort_info->param->testflag & T_UNPACK)
{
MARIA_SHARE tmp;
-
- if (share->options & HA_OPTION_PACK_RECORD)
- sort_info->new_data_file_type = DYNAMIC_RECORD;
- else
- sort_info->new_data_file_type = STATIC_RECORD;
-
+ sort_info->new_data_file_type= share->state.header.org_data_file_type;
/* Set delete_function for sort_delete_record() */
memcpy((char*) &tmp, share, sizeof(*share));
tmp.options= ~HA_OPTION_COMPRESS_RECORD;
@@ -4583,3 +5074,13 @@ set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share)
share->delete_record=tmp.delete_record;
}
}
+
+static void restore_data_file_type(MARIA_SHARE *share)
+{
+ share->options&= ~HA_OPTION_COMPRESS_RECORD;
+ mi_int2store(share->state.header.options,share->options);
+ share->state.header.data_file_type=
+ share->state.header.org_data_file_type;
+ share->data_file_type= share->state.header.data_file_type=
+ share->pack.header_length= 0;
+}
diff --git a/storage/maria/ma_checksum.c b/storage/maria/ma_checksum.c
index 054873706a4..1b0f683fe63 100644
--- a/storage/maria/ma_checksum.c
+++ b/storage/maria/ma_checksum.c
@@ -18,23 +18,27 @@
#include "maria_def.h"
-ha_checksum _ma_checksum(MARIA_HA *info, const byte *buf)
+ha_checksum _ma_checksum(MARIA_HA *info, const byte *record)
{
uint i;
ha_checksum crc=0;
MARIA_COLUMNDEF *rec=info->s->rec;
- for (i=info->s->base.fields ; i-- ; buf+=(rec++)->length)
+ if (info->s->base.null_bytes)
+ crc= my_checksum(crc, record, info->s->base.null_bytes);
+
+ for (i=info->s->base.fields ; i-- ; )
{
- const byte *pos;
+ const byte *pos= record + rec->offset;
ulong length;
+
switch (rec->type) {
case FIELD_BLOB:
{
length= _ma_calc_blob_length(rec->length-
maria_portable_sizeof_char_ptr,
- buf);
- memcpy((char*) &pos, buf+rec->length- maria_portable_sizeof_char_ptr,
+ pos);
+ memcpy((char*) &pos, pos+rec->length- maria_portable_sizeof_char_ptr,
sizeof(char*));
break;
}
@@ -42,18 +46,17 @@ ha_checksum _ma_checksum(MARIA_HA *info, const byte *buf)
{
uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length-1);
if (pack_length == 1)
- length= (ulong) *(uchar*) buf;
+ length= (ulong) *(uchar*) pos;
else
- length= uint2korr(buf);
- pos= buf+pack_length;
+ length= uint2korr(pos);
+ pos+= pack_length;
break;
}
default:
- length=rec->length;
- pos=buf;
+ length= rec->length;
break;
}
- crc=my_checksum(crc, pos ? pos : "", length);
+ crc= my_checksum(crc, pos ? pos : "", length);
}
return crc;
}
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index e1a4bb08301..2a874079961 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -69,16 +69,22 @@ int maria_close(register MARIA_HA *info)
maria_open_list=list_delete(maria_open_list,&info->open_list);
pthread_mutex_unlock(&share->intern_lock);
- my_free(_ma_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
+ my_free(info->rec_buff, MYF(MY_ALLOW_ZERO_PTR));
+ (share->end)(info);
+
+ if (info->s->data_file_type == BLOCK_RECORD)
+ info->dfile= -1; /* Closed in ma_end_once_block_row */
if (flag)
{
- if (share->kfile >= 0 &&
- flush_key_blocks(share->key_cache, share->kfile,
- share->temporary ? FLUSH_IGNORE_CHANGED :
- FLUSH_RELEASE))
- error=my_errno;
if (share->kfile >= 0)
{
+ if ((*share->once_end)(share))
+ error= my_errno;
+ if (flush_key_blocks(share->key_cache, share->kfile,
+ share->temporary ? FLUSH_IGNORE_CHANGED :
+ FLUSH_RELEASE))
+ error= my_errno;
+
/*
If we are crashed, we can safely flush the current state as it will
not change the crashed state.
@@ -87,18 +93,13 @@ int maria_close(register MARIA_HA *info)
*/
if (share->mode != O_RDONLY && maria_is_crashed(info))
_ma_state_info_write(share->kfile, &share->state, 1);
- if (my_close(share->kfile,MYF(0)))
- error = my_errno;
+ if (my_close(share->kfile, MYF(0)))
+ error= my_errno;
}
#ifdef HAVE_MMAP
if (share->file_map)
_ma_unmap_file(info);
#endif
- if (share->decode_trees)
- {
- my_free((gptr) share->decode_trees,MYF(0));
- my_free((gptr) share->decode_tables,MYF(0));
- }
#ifdef THREAD
thr_lock_delete(&share->lock);
VOID(pthread_mutex_destroy(&share->intern_lock));
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index d99c4fcc26b..59f5f7d1a4d 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -19,6 +19,7 @@
#include "ma_ftdefs.h"
#include "ma_sp_defs.h"
#include <my_bit.h>
+#include "ma_blockrec.h"
#if defined(MSDOS) || defined(__WIN__)
#ifdef __WIN__
@@ -29,36 +30,40 @@
#endif
#include <m_ctype.h>
+static int compare_columns(MARIA_COLUMNDEF **a, MARIA_COLUMNDEF **b);
+
/*
Old options is used when recreating database, from maria_chk
*/
-int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
- uint columns, MARIA_COLUMNDEF *recinfo,
- uint uniques, MARIA_UNIQUEDEF *uniquedefs,
- MARIA_CREATE_INFO *ci,uint flags)
+int maria_create(const char *name, enum data_file_type record_type,
+ uint keys,MARIA_KEYDEF *keydefs,
+ uint columns, MARIA_COLUMNDEF *recinfo,
+ uint uniques, MARIA_UNIQUEDEF *uniquedefs,
+ MARIA_CREATE_INFO *ci,uint flags)
{
register uint i,j;
File dfile,file;
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
myf create_flag;
- uint fields,length,max_key_length,packed,pointer,real_length_diff,
+ uint length,max_key_length,packed,pack_bytes,pointer,real_length_diff,
key_length,info_length,key_segs,options,min_key_length_skip,
base_pos,long_varchar_count,varchar_length,
- max_key_block_length,unique_key_parts,fulltext_keys,offset;
- uint aligned_key_start, block_length;
+ unique_key_parts,fulltext_keys,offset;
+ uint max_field_lengths, extra_header_size;
ulong reclength, real_reclength,min_pack_length;
char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
ulong pack_reclength;
ulonglong tot_length,max_rows, tmp;
enum en_fieldtype type;
+ enum data_file_type org_record_type= record_type;
MARIA_SHARE share;
MARIA_KEYDEF *keydef,tmp_keydef;
MARIA_UNIQUEDEF *uniquedef;
HA_KEYSEG *keyseg,tmp_keyseg;
- MARIA_COLUMNDEF *rec;
+ MARIA_COLUMNDEF *rec, *rec_end;
ulong *rec_per_key_part;
- my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MARIA_MAX_KEY_BLOCK_SIZE];
+ my_off_t key_root[HA_MAX_POSSIBLE_KEY];
MARIA_CREATE_INFO tmp_create_info;
my_bool tmp_table= FALSE; /* cache for presence of HA_OPTION_TMP_TABLE */
myf sync_dir= MY_SYNC_DIR;
@@ -66,6 +71,9 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u",
keys, columns, uniques, flags));
+ LINT_INIT(dfile);
+ LINT_INIT(file);
+
if (!ci)
{
bzero((char*) &tmp_create_info,sizeof(tmp_create_info));
@@ -76,22 +84,24 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
{
DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION);
}
- LINT_INIT(dfile);
- LINT_INIT(file);
errpos=0;
options=0;
bzero((byte*) &share,sizeof(share));
if (flags & HA_DONT_TOUCH_DATA)
{
+ org_record_type= ci->org_data_file_type;
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
options=ci->old_options &
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
else
+ {
+ /* Uncompressing rows */
options=ci->old_options &
(HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
+ }
}
if (ci->reloc_rows > ci->max_rows)
@@ -104,59 +114,90 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
/* Start by checking fields and field-types used */
- reclength=varchar_length=long_varchar_count=packed=
- min_pack_length=pack_reclength=0;
- for (rec=recinfo, fields=0 ;
- fields != columns ;
- rec++,fields++)
+ varchar_length=long_varchar_count=packed=
+ pack_reclength= max_field_lengths= 0;
+ reclength= min_pack_length= ci->null_bytes;
+
+ for (rec= recinfo, rec_end= rec + columns ; rec != rec_end ; rec++)
{
- reclength+=rec->length;
- if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL &&
- type != FIELD_CHECK)
+ /* Fill in not used struct parts */
+ rec->offset= reclength;
+ rec->empty_pos= 0;
+ rec->empty_bit= 0;
+ rec->fill_length= rec->length;
+
+ reclength+= rec->length;
+ type= rec->type;
+ if (type == FIELD_SKIP_PRESPACE && record_type == BLOCK_RECORD)
+ type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
+
+ if (type != FIELD_NORMAL && type != FIELD_CHECK)
{
- packed++;
+ rec->empty_pos= packed/8;
+ rec->empty_bit= (1 << (packed & 7));
if (type == FIELD_BLOB)
{
+ packed++;
share.base.blobs++;
if (pack_reclength != INT_MAX32)
{
if (rec->length == 4+maria_portable_sizeof_char_ptr)
pack_reclength= INT_MAX32;
else
- pack_reclength+=(1 << ((rec->length-maria_portable_sizeof_char_ptr)*8)); /* Max blob length */
+ {
+ /* Add max possible blob length */
+ pack_reclength+= (1 << ((rec->length-
+ maria_portable_sizeof_char_ptr)*8));
+ }
}
+ max_field_lengths+= (rec->length - maria_portable_sizeof_char_ptr);
}
else if (type == FIELD_SKIP_PRESPACE ||
type == FIELD_SKIP_ENDSPACE)
{
- if (pack_reclength != INT_MAX32)
- pack_reclength+= rec->length > 255 ? 2 : 1;
+ max_field_lengths+= rec->length > 255 ? 2 : 1;
min_pack_length++;
+ packed++;
}
else if (type == FIELD_VARCHAR)
{
varchar_length+= rec->length-1; /* Used for min_pack_length */
- packed--;
pack_reclength++;
min_pack_length++;
+ max_field_lengths++;
+ packed++;
/* We must test for 257 as length includes pack-length */
if (test(rec->length >= 257))
{
long_varchar_count++;
- pack_reclength+= 2; /* May be packed on 3 bytes */
+ max_field_lengths++;
}
}
else if (type != FIELD_SKIP_ZERO)
{
min_pack_length+=rec->length;
- packed--; /* Not a pack record type */
+ rec->empty_pos= 0;
+ rec->empty_bit= 0;
}
+ else
+ packed++;
}
else /* FIELD_NORMAL */
+ {
min_pack_length+=rec->length;
+ if (!rec->null_bit)
+ {
+ share.base.fixed_not_null_fields++;
+ share.base.fixed_not_null_fields_length+= rec->length;
+ }
+ }
}
if ((packed & 7) == 1)
- { /* Bad packing, try to remove a zero-field */
+ {
+ /*
+ Not optimal packing, try to remove a 1 byte length zero-field as
+ this will get same record length, but smaller pack overhead
+ */
while (rec != recinfo)
{
rec--;
@@ -169,14 +210,27 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
}
}
}
+ share.base.null_bytes= ci->null_bytes;
+ share.base.original_null_bytes= ci->null_bytes;
+ share.base.transactional= ci->transactional;
+ share.base.max_field_lengths= max_field_lengths;
+ share.base.field_offsets= 0; /* for future */
+
+ if (pack_reclength != INT_MAX32)
+ pack_reclength+= max_field_lengths + long_varchar_count;
+
+ if (packed && record_type == STATIC_RECORD)
+ record_type= BLOCK_RECORD;
+ if (record_type == DYNAMIC_RECORD)
+ options|= HA_OPTION_PACK_RECORD; /* Must use packed records */
- if (packed || (flags & HA_PACK_RECORD))
- options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
- /* We can't use checksum with static length rows */
- if (!(options & HA_OPTION_PACK_RECORD))
+ if (record_type == STATIC_RECORD)
+ {
+ /* We can't use checksum with static length rows */
+ flags&= ~HA_CREATE_CHECKSUM;
options&= ~HA_OPTION_CHECKSUM;
- if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
min_pack_length+= varchar_length;
+ }
if (flags & HA_CREATE_TMP_TABLE)
{
options|= HA_OPTION_TMP_TABLE;
@@ -186,18 +240,24 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
{
options|= HA_OPTION_CHECKSUM;
min_pack_length++;
+ pack_reclength++;
}
if (flags & HA_CREATE_DELAY_KEY_WRITE)
options|= HA_OPTION_DELAY_KEY_WRITE;
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
options|= HA_OPTION_RELIES_ON_SQL_LAYER;
- packed=(packed+7)/8;
+ pack_bytes= (packed + 7) / 8;
if (pack_reclength != INT_MAX32)
- pack_reclength+= reclength+packed +
+ pack_reclength+= reclength+pack_bytes +
test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
- min_pack_length+=packed;
-
+ min_pack_length+= pack_bytes;
+ /* Calculate min possible row length for rows-in-block */
+ extra_header_size= MAX_FIXED_HEADER_SIZE;
+ if (ci->transactional)
+ extra_header_size= TRANS_MAX_FIXED_HEADER_SIZE;
+ share.base.min_row_length= (extra_header_size + share.base.null_bytes +
+ pack_bytes);
if (!ci->data_file_length && ci->max_rows)
{
if (pack_reclength == INT_MAX32 ||
@@ -207,20 +267,57 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength;
}
else if (!ci->max_rows)
- ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
- ((options & HA_OPTION_PACK_RECORD) ?
- 3 : 0)));
+ {
+ if (record_type == BLOCK_RECORD)
+ {
+ uint rows_per_page= ((maria_block_size - PAGE_OVERHEAD_SIZE) /
+ (min_pack_length + extra_header_size +
+ DIR_ENTRY_SIZE));
+ ulonglong data_file_length= ci->data_file_length;
+ if (data_file_length)
+ data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
+ 8)) -1));
+ if (rows_per_page > 0)
+ {
+ set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
+ ci->max_rows= ci->data_file_length / maria_block_size * rows_per_page;
+ }
+ else
+ ci->max_rows= ci->data_file_length / (min_pack_length +
+ extra_header_size +
+ DIR_ENTRY_SIZE);
+ }
+ else
+ ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
+ ((options &
+ HA_OPTION_PACK_RECORD) ?
+ 3 : 0)));
+ }
+ max_rows= (ulonglong) ci->max_rows;
+ if (record_type == BLOCK_RECORD)
+ {
+ /* The + 1 is for record position withing page */
+ pointer= maria_get_pointer_length((ci->data_file_length /
+ maria_block_size), 3) + 1;
+ set_if_smaller(pointer, BLOCK_RECORD_POINTER_SIZE);
- if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
- pointer=maria_get_pointer_length(ci->data_file_length,maria_data_pointer_size);
+ if (!max_rows)
+ max_rows= (((((ulonglong) 1 << ((pointer-1)*8)) -1) * maria_block_size) /
+ min_pack_length);
+ }
else
- pointer=maria_get_pointer_length(ci->max_rows,maria_data_pointer_size);
- if (!(max_rows=(ulonglong) ci->max_rows))
- max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length);
-
+ {
+ if (record_type != STATIC_RECORD)
+ pointer= maria_get_pointer_length(ci->data_file_length,
+ maria_data_pointer_size);
+ else
+ pointer= maria_get_pointer_length(ci->max_rows, maria_data_pointer_size);
+ if (!max_rows)
+ max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length);
+ }
real_reclength=reclength;
- if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)))
+ if (record_type == STATIC_RECORD)
{
if (reclength <= pointer)
reclength=pointer+1; /* reserve place for delete link */
@@ -230,19 +327,14 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
max_key_length=0; tot_length=0 ; key_segs=0;
fulltext_keys=0;
- max_key_block_length=0;
share.state.rec_per_key_part=rec_per_key_part;
share.state.key_root=key_root;
- share.state.key_del=key_del;
+ share.state.key_del= HA_OFFSET_ERROR;
if (uniques)
- {
- max_key_block_length= maria_block_size;
- max_key_length= MARIA_UNIQUE_HASH_LENGTH + pointer;
- }
+ max_key_length= MARIA_UNIQUE_HASH_LENGTH + pointer;
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
{
-
share.state.key_root[i]= HA_OFFSET_ERROR;
min_key_length_skip=length=real_length_diff=0;
key_length=pointer;
@@ -256,11 +348,11 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
if (flags & HA_DONT_TOUCH_DATA)
{
/*
- called by mariachk - i.e. table structure was taken from
- MYI file and SPATIAL key *does have* additional sp_segs keysegs.
- keydef->seg here points right at the GEOMETRY segment,
- so we only need to decrease keydef->keysegs.
- (see maria_recreate_table() in _ma_check.c)
+ Called by maria_chk - i.e. table structure was taken from
+ MYI file and SPATIAL key *does have* additional sp_segs keysegs.
+ keydef->seg here points right at the GEOMETRY segment,
+ so we only need to decrease keydef->keysegs.
+ (see maria_recreate_table() in _ma_check.c)
*/
keydef->keysegs-=sp_segs-1;
}
@@ -434,35 +526,22 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
key_segs)
share.state.rec_per_key_part[key_segs-1]=1L;
length+=key_length;
- /* Get block length for key, if defined by user */
- block_length= (keydef->block_length ?
- my_round_up_to_next_power(keydef->block_length) :
- maria_block_size);
- block_length= max(block_length, MARIA_MIN_KEY_BLOCK_LENGTH);
- block_length= min(block_length, MARIA_MAX_KEY_BLOCK_LENGTH);
-
- keydef->block_length= (uint16) MARIA_BLOCK_SIZE(length-real_length_diff,
- pointer,MARIA_MAX_KEYPTR_SIZE,
- block_length);
- if (keydef->block_length > MARIA_MAX_KEY_BLOCK_LENGTH ||
- length >= HA_MAX_KEY_BUFF)
+ if (length >= min(HA_MAX_KEY_BUFF, MARIA_MAX_KEY_LENGTH))
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
}
- set_if_bigger(max_key_block_length,keydef->block_length);
+ keydef->block_length= maria_block_size;
keydef->keylength= (uint16) key_length;
keydef->minlength= (uint16) (length-min_key_length_skip);
keydef->maxlength= (uint16) length;
if (length > max_key_length)
max_key_length= length;
- tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/
- (length*2)))*
- (ulong) keydef->block_length;
+ tot_length+= ((max_rows/(ulong) (((uint) maria_block_size-5)/
+ (length*2))) *
+ maria_block_size);
}
- for (i=max_key_block_length/MARIA_MIN_KEY_BLOCK_LENGTH ; i-- ; )
- key_del[i]=HA_OFFSET_ERROR;
unique_key_parts=0;
offset=reclength-uniques*MARIA_UNIQUE_HASH_LENGTH;
@@ -479,14 +558,12 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
key_segs+=uniques; /* Each unique has 1 key seg */
base_pos=(MARIA_STATE_INFO_SIZE + keys * MARIA_STATE_KEY_SIZE +
- max_key_block_length/MARIA_MIN_KEY_BLOCK_LENGTH*
- MARIA_STATE_KEYBLOCK_SIZE+
- key_segs*MARIA_STATE_KEYSEG_SIZE);
- info_length=base_pos+(uint) (MARIA_BASE_INFO_SIZE+
- keys * MARIA_KEYDEF_SIZE+
- uniques * MARIA_UNIQUEDEF_SIZE +
- (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
- columns*MARIA_COLUMNDEF_SIZE);
+ key_segs * MARIA_STATE_KEYSEG_SIZE);
+ info_length= base_pos+(uint) (MARIA_BASE_INFO_SIZE+
+ keys * MARIA_KEYDEF_SIZE+
+ uniques * MARIA_UNIQUEDEF_SIZE +
+ (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
+ columns*MARIA_COLUMNDEF_SIZE);
DBUG_PRINT("info", ("info_length: %u", info_length));
/* There are only 16 bits for the total header length. */
@@ -508,11 +585,13 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
mi_int2store(share.state.header.state_info_length,MARIA_STATE_INFO_SIZE);
mi_int2store(share.state.header.base_info_length,MARIA_BASE_INFO_SIZE);
mi_int2store(share.state.header.base_pos,base_pos);
+ share.state.header.data_file_type= record_type;
+ share.state.header.org_data_file_type= org_record_type;
share.state.header.language= (ci->language ?
ci->language : default_charset_info->number);
- share.state.header.max_block_size_index= max_key_block_length/MARIA_MIN_KEY_BLOCK_LENGTH;
share.state.dellink = HA_OFFSET_ERROR;
+ share.state.first_bitmap_with_space= 0;
share.state.process= (ulong) getpid();
share.state.unique= (ulong) 0;
share.state.update_count=(ulong) 0;
@@ -521,9 +600,11 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
share.state.auto_increment=ci->auto_increment;
share.options=options;
share.base.rec_reflength=pointer;
+ share.base.block_size= maria_block_size;
+
/* Get estimate for index file length (this may be wrong for FT keys) */
- tmp= (tot_length + max_key_block_length * keys *
- MARIA_INDEX_BLOCK_MARGIN) / MARIA_MIN_KEY_BLOCK_LENGTH;
+ tmp= (tot_length + maria_block_size * keys *
+ MARIA_INDEX_BLOCK_MARGIN) / maria_block_size;
/*
use maximum of key_file_length we calculated and key_file_length value we
got from MYI file header (see also mariapack.c:save_state)
@@ -537,13 +618,10 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
maria_set_all_keys_active(share.state.key_map, keys);
- aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
- max_key_block_length :
- maria_block_size);
share.base.keystart = share.state.state.key_file_length=
- MY_ALIGN(info_length, aligned_key_start);
- share.base.max_key_block_length=max_key_block_length;
+ MY_ALIGN(info_length, maria_block_size);
+ share.base.max_key_block_length= maria_block_size;
share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
share.base.records=ci->max_rows;
share.base.reloc= ci->reloc_rows;
@@ -551,9 +629,9 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
share.base.max_pack_length=pack_reclength;
share.base.min_pack_length=min_pack_length;
- share.base.pack_bits=packed;
- share.base.fields=fields;
- share.base.pack_fields=packed;
+ share.base.pack_bytes= pack_bytes;
+ share.base.fields= columns;
+ share.base.pack_fields= packed;
#ifdef USE_RAID
share.base.raid_type=ci->raid_type;
share.base.raid_chunks=ci->raid_chunks;
@@ -565,7 +643,7 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
{
tmp_table= TRUE;
sync_dir= 0;
- share.base.max_data_file_length=(my_off_t) ci->data_file_length;
+ share.base.max_data_file_length= (my_off_t) ci->data_file_length;
}
share.base.min_block_length=
@@ -645,72 +723,63 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
if (!(flags & HA_DONT_TOUCH_DATA))
{
-#ifdef USE_RAID
- if (share.base.raid_type)
+ if (ci->data_file_name)
{
- (void) fn_format(filename, name, "", MARIA_NAME_DEXT,
- MY_UNPACK_FILENAME | MY_APPEND_EXT);
- if ((dfile=my_raid_create(filename, 0, create_mode,
- share.base.raid_type,
- share.base.raid_chunks,
- share.base.raid_chunksize,
- MYF(MY_WME | MY_RAID))) < 0)
- goto err;
- }
- else
-#endif
- {
- if (ci->data_file_name)
- {
- char *dext= strrchr(ci->data_file_name, '.');
- int have_dext= dext && !strcmp(dext, MARIA_NAME_DEXT);
+ char *dext= strrchr(ci->data_file_name, '.');
+ int have_dext= dext && !strcmp(dext, MARIA_NAME_DEXT);
- if (tmp_table)
- {
- char *path;
- /* chop off the table name, tempory tables use generated name */
- if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
- *path= '\0';
- fn_format(filename, name, ci->data_file_name, MARIA_NAME_DEXT,
- MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
- }
- else
- {
- fn_format(filename, ci->data_file_name, "", MARIA_NAME_DEXT,
- MY_UNPACK_FILENAME |
- (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
- }
- fn_format(linkname, name, "",MARIA_NAME_DEXT,
- MY_UNPACK_FILENAME | MY_APPEND_EXT);
- linkname_ptr=linkname;
- create_flag=0;
+ if (tmp_table)
+ {
+ char *path;
+ /* chop off the table name, tempory tables use generated name */
+ if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
+ *path= '\0';
+ fn_format(filename, name, ci->data_file_name, MARIA_NAME_DEXT,
+ MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
}
else
{
- fn_format(filename,name,"", MARIA_NAME_DEXT,
- MY_UNPACK_FILENAME | MY_APPEND_EXT);
- linkname_ptr=0;
- create_flag=MY_DELETE_OLD;
+ fn_format(filename, ci->data_file_name, "", MARIA_NAME_DEXT,
+ MY_UNPACK_FILENAME |
+ (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
}
- if ((dfile=
- my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
- MYF(MY_WME | create_flag | sync_dir))) < 0)
- goto err;
+ fn_format(linkname, name, "",MARIA_NAME_DEXT,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT);
+ linkname_ptr=linkname;
+ create_flag=0;
+ }
+ else
+ {
+ fn_format(filename,name,"", MARIA_NAME_DEXT,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT);
+ linkname_ptr=0;
+ create_flag=MY_DELETE_OLD;
}
+ if ((dfile=
+ my_create_with_symlink(linkname_ptr, filename, 0, create_mode,
+ MYF(MY_WME | create_flag | sync_dir))) < 0)
+ goto err;
errpos=3;
+
+ if (record_type == BLOCK_RECORD)
+ {
+ /* Write one bitmap page */
+ char buff[IO_SIZE];
+ uint i;
+ bzero(buff, sizeof(buff));
+ for (i= 0 ; i < maria_block_size ; i+= IO_SIZE)
+ if (my_write(dfile, (byte*) buff, sizeof(buff), MYF(MY_NABP)))
+ goto err;
+ share.state.state.data_file_length= maria_block_size;
+ }
}
DBUG_PRINT("info", ("write state info and base info"));
if (_ma_state_info_write(file, &share.state, 2) ||
_ma_base_info_write(file, &share.base))
goto err;
-#ifndef DBUG_OFF
- if ((uint) my_tell(file,MYF(0)) != base_pos+ MARIA_BASE_INFO_SIZE)
- {
- uint pos=(uint) my_tell(file,MYF(0));
- DBUG_PRINT("warning",("base_length: %d != used_length: %d",
- base_pos+ MARIA_BASE_INFO_SIZE, pos));
- }
-#endif
+ DBUG_PRINT("info", ("base_pos: %d base_info_size: %d",
+ base_pos, MARIA_BASE_INFO_SIZE));
+ DBUG_ASSERT(my_tell(file,MYF(0)) == base_pos+ MARIA_BASE_INFO_SIZE);
/* Write key and keyseg definitions */
DBUG_PRINT("info", ("write key and keyseg definitions"));
@@ -751,7 +820,7 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
{
tmp_keydef.keysegs=1;
tmp_keydef.flag= HA_UNIQUE_CHECK;
- tmp_keydef.block_length= (uint16)maria_block_size;
+ tmp_keydef.block_length= (uint16) maria_block_size;
tmp_keydef.keylength= MARIA_UNIQUE_HASH_LENGTH + pointer;
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
tmp_keyseg.type= MARIA_UNIQUE_HASH_TYPE;
@@ -789,6 +858,7 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
}
break;
default:
+ DBUG_ASSERT((keyseg->flag & HA_VAR_LENGTH_PART) == 0);
break;
}
if (_ma_keyseg_write(file, keyseg))
@@ -796,9 +866,27 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
}
}
DBUG_PRINT("info", ("write field definitions"));
- for (i=0 ; i < share.base.fields ; i++)
- if (_ma_recinfo_write(file, &recinfo[i]))
+ if (record_type == BLOCK_RECORD)
+ {
+ /* Store columns in a more efficent order */
+ MARIA_COLUMNDEF **tmp, **pos;
+ if (!(tmp= (MARIA_COLUMNDEF**) my_malloc(share.base.fields *
+ sizeof(MARIA_COLUMNDEF*),
+ MYF(MY_WME))))
goto err;
+ for (rec= recinfo, pos= tmp ; rec != rec_end ; rec++, pos++)
+ *pos= rec;
+ qsort(tmp, share.base.fields, sizeof(*tmp), (qsort_cmp) compare_columns);
+ for (i=0 ; i < share.base.fields ; i++)
+ if (_ma_recinfo_write(file, tmp[i]))
+ goto err;
+ }
+ else
+ {
+ for (i=0 ; i < share.base.fields ; i++)
+ if (_ma_recinfo_write(file, &recinfo[i]))
+ goto err;
+ }
#ifndef DBUG_OFF
if ((uint) my_tell(file,MYF(0)) != info_length)
@@ -810,19 +898,17 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
#endif
/* Enlarge files */
- DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart));
+ DBUG_PRINT("info", ("enlarge to keystart: %lu",
+ (ulong) share.base.keystart));
if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
goto err;
- if (!tmp_table && my_sync(file, MYF(0)))
- goto err;
-
if (! (flags & HA_DONT_TOUCH_DATA))
{
#ifdef USE_RELOC
if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,0,MYF(0)))
goto err;
- if (!tmp_table && my_sync(dfile, MYF(0)))
+ if (!tmp_table && my_sync(file, MYF(0)))
goto err;
#endif
/* if !USE_RELOC, there was no write to the file, no need to sync it */
@@ -858,18 +944,17 @@ err:
VOID(my_close(dfile,MYF(0)));
/* fall through */
case 2:
- /* QQ: Tõnu should add a call to my_raid_delete() here */
if (! (flags & HA_DONT_TOUCH_DATA))
my_delete_with_symlink(fn_format(filename,name,"",MARIA_NAME_DEXT,
MY_UNPACK_FILENAME | MY_APPEND_EXT),
- MYF(sync_dir));
+ sync_dir);
/* fall through */
case 1:
VOID(my_close(file,MYF(0)));
if (! (flags & HA_DONT_TOUCH_DATA))
my_delete_with_symlink(fn_format(filename,name,"",MARIA_NAME_IEXT,
MY_UNPACK_FILENAME | MY_APPEND_EXT),
- MYF(sync_dir));
+ sync_dir);
}
my_free((char*) rec_per_key_part, MYF(0));
DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */
@@ -900,3 +985,59 @@ uint maria_get_pointer_length(ulonglong file_length, uint def)
}
return def;
}
+
+
+/*
+ Sort columns for records-in-block
+
+ IMPLEMENTATION
+ Sort columns in following order:
+
+ Fixed size, not null columns
+ Fixed length, null fields
+ Variable length fields (CHAR, VARCHAR)
+ Blobs
+
+ For same kind of fields, keep fields in original order
+*/
+
+static inline int sign(longlong a)
+{
+ return a < 0 ? -1 : (a > 0 ? 1 : 0);
+}
+
+
+int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
+{
+ MARIA_COLUMNDEF *a= *a_ptr, *b= *b_ptr;
+ enum en_fieldtype a_type, b_type;
+
+ a_type= (a->type == FIELD_NORMAL || a->type == FIELD_CHECK ?
+ FIELD_NORMAL : a->type);
+ b_type= (b->type == FIELD_NORMAL || b->type == FIELD_CHECK ?
+ FIELD_NORMAL : b->type);
+
+ if (a_type == FIELD_NORMAL && !a->null_bit)
+ {
+ if (b_type != FIELD_NORMAL || b->null_bit)
+ return -1;
+ return sign((long) (a->offset - b->offset));
+ }
+ if (b_type == FIELD_NORMAL && !b->null_bit)
+ return 1;
+ if (a_type == b_type)
+ return sign((long) (a->offset - b->offset));
+ if (a_type == FIELD_NORMAL)
+ return -1;
+ if (b_type == FIELD_NORMAL)
+ return 1;
+ if (a_type == FIELD_BLOB)
+ return 1;
+ if (b_type == FIELD_BLOB)
+ return -1;
+ return sign((long) (a->offset - b->offset));
+}
+
+
+
+
diff --git a/storage/maria/ma_dbug.c b/storage/maria/ma_dbug.c
index 7f2bff85047..596bf18bfe5 100644
--- a/storage/maria/ma_dbug.c
+++ b/storage/maria/ma_dbug.c
@@ -21,15 +21,15 @@
/* Print a key in user understandable format */
void _ma_print_key(FILE *stream, register HA_KEYSEG *keyseg,
- const uchar *key, uint length)
+ const byte *key, uint length)
{
int flag;
short int s_1;
long int l_1;
float f_1;
double d_1;
- const uchar *end;
- const uchar *key_end=key+length;
+ const byte *end;
+ const byte *key_end= key + length;
VOID(fputs("Key: \"",stream));
flag=0;
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index f0295a3c413..9198989dcb7 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -20,26 +20,25 @@
#include "ma_rt_index.h"
static int d_search(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uint comp_flag,
- uchar *key,uint key_length,my_off_t page,uchar *anc_buff);
-static int del(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *key,uchar *anc_buff,
- my_off_t leaf_page,uchar *leaf_buff,uchar *keypos,
- my_off_t next_block,uchar *ret_key);
-static int underflow(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *anc_buff,
- my_off_t leaf_page,uchar *leaf_buff,uchar *keypos);
-static uint remove_key(MARIA_KEYDEF *keyinfo,uint nod_flag,uchar *keypos,
- uchar *lastkey,uchar *page_end,
+ byte *key,uint key_length,my_off_t page,byte *anc_buff);
+static int del(MARIA_HA *info,MARIA_KEYDEF *keyinfo,byte *key,byte *anc_buff,
+ my_off_t leaf_page,byte *leaf_buff,byte *keypos,
+ my_off_t next_block,byte *ret_key);
+static int underflow(MARIA_HA *info,MARIA_KEYDEF *keyinfo,byte *anc_buff,
+ my_off_t leaf_page,byte *leaf_buff,byte *keypos);
+static uint remove_key(MARIA_KEYDEF *keyinfo,uint nod_flag,byte *keypos,
+ byte *lastkey,byte *page_end,
my_off_t *next_block);
static int _ma_ck_real_delete(register MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_length, my_off_t *root);
+ byte *key, uint key_length, my_off_t *root);
int maria_delete(MARIA_HA *info,const byte *record)
{
uint i;
- uchar *old_key;
+ byte *old_key;
int save_errno;
char lastpos[8];
-
MARIA_SHARE *share=info->s;
DBUG_ENTER("maria_delete");
@@ -61,17 +60,15 @@ int maria_delete(MARIA_HA *info,const byte *record)
}
if (_ma_readinfo(info,F_WRLCK,1))
DBUG_RETURN(my_errno);
- if (info->s->calc_checksum)
- info->checksum=(*info->s->calc_checksum)(info,record);
if ((*share->compare_record)(info,record))
goto err; /* Error on read-check */
if (_ma_mark_file_changed(info))
goto err;
- /* Remove all keys from the .ISAM file */
+ /* Remove all keys from the index file */
- old_key=info->lastkey2;
+ old_key= info->lastkey2;
for (i=0 ; i < share->base.keys ; i++ )
{
if (maria_is_key_active(info->s->state.key_map, i))
@@ -79,13 +76,13 @@ int maria_delete(MARIA_HA *info,const byte *record)
info->s->keyinfo[i].version++;
if (info->s->keyinfo[i].flag & HA_FULLTEXT )
{
- if (_ma_ft_del(info,i,(char*) old_key,record,info->lastpos))
+ if (_ma_ft_del(info,i,(char*) old_key,record,info->cur_row.lastpos))
goto err;
}
else
{
if (info->s->keyinfo[i].ck_delete(info,i,old_key,
- _ma_make_key(info,i,old_key,record,info->lastpos)))
+ _ma_make_key(info,i,old_key,record,info->cur_row.lastpos)))
goto err;
}
/* The above changed info->lastkey2. Inform maria_rnext_same(). */
@@ -95,12 +92,21 @@ int maria_delete(MARIA_HA *info,const byte *record)
if ((*share->delete_record)(info))
goto err; /* Remove record from database */
- info->state->checksum-=info->checksum;
+
+ /*
+ We can't use the row based checksum as this doesn't have enough
+ precision.
+ */
+ if (info->s->calc_checksum)
+ {
+ info->cur_row.checksum= (*info->s->calc_checksum)(info,record);
+ info->state->checksum-= info->cur_row.checksum;
+ }
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
info->state->records--;
- mi_sizestore(lastpos,info->lastpos);
+ mi_sizestore(lastpos, info->cur_row.lastpos);
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0)
@@ -113,7 +119,7 @@ int maria_delete(MARIA_HA *info,const byte *record)
err:
save_errno=my_errno;
- mi_sizestore(lastpos,info->lastpos);
+ mi_sizestore(lastpos, info->cur_row.lastpos);
if (save_errno != HA_ERR_RECORD_CHANGED)
{
maria_print_error(info->s, HA_ERR_CRASHED);
@@ -135,7 +141,7 @@ err:
/* Remove a key from the btree index */
-int _ma_ck_delete(register MARIA_HA *info, uint keynr, uchar *key,
+int _ma_ck_delete(register MARIA_HA *info, uint keynr, byte *key,
uint key_length)
{
return _ma_ck_real_delete(info, info->s->keyinfo+keynr, key, key_length,
@@ -144,12 +150,12 @@ int _ma_ck_delete(register MARIA_HA *info, uint keynr, uchar *key,
static int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_length, my_off_t *root)
+ byte *key, uint key_length, my_off_t *root)
{
int error;
uint nod_flag;
my_off_t old_root;
- uchar *root_buff;
+ byte *root_buff;
DBUG_ENTER("_ma_ck_real_delete");
if ((old_root=*root) == HA_OFFSET_ERROR)
@@ -157,7 +163,7 @@ static int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
maria_print_error(info->s, HA_ERR_CRASHED);
DBUG_RETURN(my_errno=HA_ERR_CRASHED);
}
- if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
+ if (!(root_buff= (byte*) my_alloca((uint) keyinfo->block_length+
HA_MAX_KEY_BUFF*2)))
{
DBUG_PRINT("error",("Couldn't allocate memory"));
@@ -212,17 +218,17 @@ err:
*/
static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uint comp_flag, uchar *key, uint key_length,
- my_off_t page, uchar *anc_buff)
+ uint comp_flag, byte *key, uint key_length,
+ my_off_t page, byte *anc_buff)
{
int flag,ret_value,save_flag;
uint length,nod_flag,search_key_length;
my_bool last_key;
- uchar *leaf_buff,*keypos;
+ byte *leaf_buff,*keypos;
my_off_t leaf_page,next_block;
- uchar lastkey[HA_MAX_KEY_BUFF];
+ byte lastkey[HA_MAX_KEY_BUFF];
DBUG_ENTER("d_search");
- DBUG_DUMP("page",(byte*) anc_buff,maria_getint(anc_buff));
+ DBUG_DUMP("page",anc_buff,maria_getint(anc_buff));
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length,
@@ -264,7 +270,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* popular word. two-level tree. going down */
uint tmp_key_length;
my_off_t root;
- uchar *kpos=keypos;
+ byte *kpos=keypos;
if (!(tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&kpos,lastkey)))
{
@@ -304,8 +310,8 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (nod_flag)
{
leaf_page= _ma_kpos(nod_flag,keypos);
- if (!(leaf_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
- HA_MAX_KEY_BUFF*2)))
+ if (!(leaf_buff= (byte*) my_alloca((uint) keyinfo->block_length+
+ HA_MAX_KEY_BUFF*2)))
{
DBUG_PRINT("error",("Couldn't allocate memory"));
my_errno=ENOMEM;
@@ -366,7 +372,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (!_ma_get_last_key(info,keyinfo,anc_buff,lastkey,keypos,&length))
goto err;
ret_value= _ma_insert(info,keyinfo,key,anc_buff,keypos,lastkey,
- (uchar*) 0,(uchar*) 0,(my_off_t) 0,(my_bool) 0);
+ (byte*) 0,(byte*) 0,(my_off_t) 0,(my_bool) 0);
}
}
if (ret_value == 0 && maria_getint(anc_buff) > keyinfo->block_length)
@@ -378,14 +384,14 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
ret_value|= _ma_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
else
{
- DBUG_DUMP("page",(byte*) anc_buff,maria_getint(anc_buff));
+ DBUG_DUMP("page",anc_buff,maria_getint(anc_buff));
}
- my_afree((byte*) leaf_buff);
+ my_afree(leaf_buff);
DBUG_PRINT("exit",("Return: %d",ret_value));
DBUG_RETURN(ret_value);
err:
- my_afree((byte*) leaf_buff);
+ my_afree(leaf_buff);
DBUG_PRINT("exit",("Error: %d",my_errno));
DBUG_RETURN (-1);
} /* d_search */
@@ -393,24 +399,25 @@ err:
/* Remove a key that has a page-reference */
-static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *key,
- uchar *anc_buff, my_off_t leaf_page, uchar *leaf_buff,
- uchar *keypos, /* Pos to where deleted key was */
+static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
+ byte *key, byte *anc_buff, my_off_t leaf_page,
+ byte *leaf_buff,
+ byte *keypos, /* Pos to where deleted key was */
my_off_t next_block,
- uchar *ret_key) /* key before keypos in anc_buff */
+ byte *ret_key) /* key before keypos in anc_buff */
{
int ret_value,length;
uint a_length,nod_flag,tmp;
my_off_t next_page;
- uchar keybuff[HA_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
+ byte keybuff[HA_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
MARIA_SHARE *share=info->s;
MARIA_KEY_PARAM s_temp;
DBUG_ENTER("del");
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", (long) leaf_page,
(ulong) keypos));
- DBUG_DUMP("leaf_buff",(byte*) leaf_buff,maria_getint(leaf_buff));
+ DBUG_DUMP("leaf_buff",leaf_buff,maria_getint(leaf_buff));
- endpos=leaf_buff+maria_getint(leaf_buff);
+ endpos= leaf_buff+ maria_getint(leaf_buff);
if (!(key_start= _ma_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
&tmp)))
DBUG_RETURN(-1);
@@ -418,14 +425,14 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *k
if ((nod_flag=_ma_test_if_nod(leaf_buff)))
{
next_page= _ma_kpos(nod_flag,endpos);
- if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
+ if (!(next_buff= (byte*) my_alloca((uint) keyinfo->block_length+
HA_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0))
ret_value= -1;
else
{
- DBUG_DUMP("next_page",(byte*) next_buff,maria_getint(next_buff));
+ DBUG_DUMP("next_page",next_buff,maria_getint(next_buff));
if ((ret_value=del(info,keyinfo,key,anc_buff,next_page,next_buff,
keypos,next_block,ret_key)) >0)
{
@@ -446,13 +453,13 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *k
&tmp))
goto err;
ret_value= _ma_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
- (uchar*) 0,(uchar*) 0,(my_off_t) 0,0);
+ (byte*) 0,(byte*) 0,(my_off_t) 0,0);
}
}
if (_ma_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
goto err;
}
- my_afree((byte*) next_buff);
+ my_afree(next_buff);
DBUG_RETURN(ret_value);
}
@@ -472,11 +479,11 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *k
prev_key=(keypos == anc_buff+2+share->base.key_reflength ?
0 : ret_key);
length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength,
- keypos == endpos ? (uchar*) 0 : keypos,
+ keypos == endpos ? (byte*) 0 : keypos,
prev_key, prev_key,
keybuff,&s_temp);
if (length > 0)
- bmove_upp((byte*) endpos+length,(byte*) endpos,(uint) (endpos-keypos));
+ bmove_upp(endpos+length,endpos,(uint) (endpos-keypos));
else
bmove(keypos,keypos-length, (int) (endpos-keypos)+length);
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
@@ -497,28 +504,28 @@ err:
/* Balances adjacent pages if underflow occours */
static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *anc_buff,
+ byte *anc_buff,
my_off_t leaf_page,/* Ancestor page and underflow page */
- uchar *leaf_buff,
- uchar *keypos) /* Position to pos after key */
+ byte *leaf_buff,
+ byte *keypos) /* Position to pos after key */
{
int t_length;
uint length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
key_reflength,key_length;
my_off_t next_page;
- uchar anc_key[HA_MAX_KEY_BUFF],leaf_key[HA_MAX_KEY_BUFF],
- *buff,*endpos,*next_keypos,*anc_pos,*half_pos,*temp_pos,*prev_key,
- *after_key;
+ byte anc_key[HA_MAX_KEY_BUFF],leaf_key[HA_MAX_KEY_BUFF];
+ byte *buff,*endpos,*next_keypos,*anc_pos,*half_pos,*temp_pos,*prev_key;
+ byte *after_key;
MARIA_KEY_PARAM s_temp;
MARIA_SHARE *share=info->s;
DBUG_ENTER("underflow");
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page,
(ulong) keypos));
- DBUG_DUMP("anc_buff",(byte*) anc_buff,maria_getint(anc_buff));
- DBUG_DUMP("leaf_buff",(byte*) leaf_buff,maria_getint(leaf_buff));
+ DBUG_DUMP("anc_buff",anc_buff,maria_getint(anc_buff));
+ DBUG_DUMP("leaf_buff",leaf_buff,maria_getint(leaf_buff));
buff=info->buff;
- info->buff_used=1;
+ info->keybuff_used=1;
next_keypos=keypos;
nod_flag=_ma_test_if_nod(leaf_buff);
p_length=nod_flag+2;
@@ -551,26 +558,25 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
goto err;
buff_length=maria_getint(buff);
- DBUG_DUMP("next",(byte*) buff,buff_length);
+ DBUG_DUMP("next",buff,buff_length);
/* find keys to make a big key-page */
- bmove((byte*) next_keypos-key_reflength,(byte*) buff+2,
- key_reflength);
+ bmove(next_keypos-key_reflength, buff+2, key_reflength);
if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,next_keypos,&length)
|| !_ma_get_last_key(info,keyinfo,leaf_buff,leaf_key,
leaf_buff+leaf_length,&length))
goto err;
/* merge pages and put parting key from anc_buff between */
- prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
+ prev_key=(leaf_length == p_length ? (byte*) 0 : leaf_key);
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,buff+p_length,
prev_key, prev_key,
anc_key, &s_temp);
length=buff_length-p_length;
endpos=buff+length+leaf_length+t_length;
/* buff will always be larger than before !*/
- bmove_upp((byte*) endpos, (byte*) buff+buff_length,length);
- memcpy((byte*) buff, (byte*) leaf_buff,(size_t) leaf_length);
+ bmove_upp(endpos, buff+buff_length,length);
+ memcpy(buff, leaf_buff,(size_t) leaf_length);
(*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
buff_length=(uint) (endpos-buff);
maria_putint(buff,buff_length,nod_flag);
@@ -586,7 +592,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (buff_length <= keyinfo->block_length)
{ /* Keys in one page */
- memcpy((byte*) leaf_buff,(byte*) buff,(size_t) buff_length);
+ memcpy(leaf_buff,buff,(size_t) buff_length);
if (_ma_dispose(info,keyinfo,next_page,DFLT_INIT_HITS))
goto err;
}
@@ -602,22 +608,21 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
&key_length, &after_key)))
goto err;
length=(uint) (half_pos-buff);
- memcpy((byte*) leaf_buff,(byte*) buff,(size_t) length);
+ memcpy(leaf_buff,buff,(size_t) length);
maria_putint(leaf_buff,length,nod_flag);
/* Correct new keypointer to leaf_page */
half_pos=after_key;
_ma_kpointer(info,leaf_key+key_length,next_page);
/* Save key in anc_buff */
- prev_key=(keypos == anc_buff+2+key_reflength ? (uchar*) 0 : anc_key),
+ prev_key=(keypos == anc_buff+2+key_reflength ? (byte*) 0 : anc_key),
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
- (keypos == endpos ? (uchar*) 0 :
+ (keypos == endpos ? (byte*) 0 :
keypos),
prev_key, prev_key,
leaf_key, &s_temp);
if (t_length >= 0)
- bmove_upp((byte*) endpos+t_length,(byte*) endpos,
- (uint) (endpos-keypos));
+ bmove_upp(endpos+t_length, endpos, (uint) (endpos-keypos));
else
bmove(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
@@ -625,15 +630,15 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* Store key first in new page */
if (nod_flag)
- bmove((byte*) buff+2,(byte*) half_pos-nod_flag,(size_t) nod_flag);
+ bmove(buff+2,half_pos-nod_flag,(size_t) nod_flag);
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key))
goto err;
- t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0,
- (uchar*) 0, (uchar *) 0,
+ t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (byte*) 0,
+ (byte*) 0, (byte*) 0,
leaf_key, &s_temp);
/* t_length will always be > 0 for a new page !*/
length=(uint) ((buff+maria_getint(buff))-half_pos);
- bmove((byte*) buff+p_length+t_length,(byte*) half_pos,(size_t) length);
+ bmove(buff+p_length+t_length, half_pos, (size_t) length);
(*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp);
maria_putint(buff,length+t_length+p_length,nod_flag);
@@ -656,11 +661,10 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
goto err;
buff_length=maria_getint(buff);
endpos=buff+buff_length;
- DBUG_DUMP("prev",(byte*) buff,buff_length);
+ DBUG_DUMP("prev",buff,buff_length);
/* find keys to make a big key-page */
- bmove((byte*) next_keypos - key_reflength,(byte*) leaf_buff+2,
- key_reflength);
+ bmove(next_keypos - key_reflength, leaf_buff+2, key_reflength);
next_keypos=keypos;
if (!(*keyinfo->get_key)(keyinfo,key_reflength,&next_keypos,
anc_key))
@@ -669,17 +673,17 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
goto err;
/* merge pages and put parting key from anc_buff between */
- prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
+ prev_key=(leaf_length == p_length ? (byte*) 0 : leaf_key);
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
(leaf_length == p_length ?
- (uchar*) 0 : leaf_buff+p_length),
+ (byte*) 0 : leaf_buff+p_length),
prev_key, prev_key,
anc_key, &s_temp);
if (t_length >= 0)
- bmove((byte*) endpos+t_length,(byte*) leaf_buff+p_length,
- (size_t) (leaf_length-p_length));
+ bmove(endpos+t_length, leaf_buff+p_length,
+ (size_t) (leaf_length-p_length));
else /* We gained space */
- bmove((byte*) endpos,(byte*) leaf_buff+((int) p_length-t_length),
+ bmove(endpos,leaf_buff+((int) p_length-t_length),
(size_t) (leaf_length-p_length+t_length));
(*keyinfo->store_key)(keyinfo,endpos,&s_temp);
@@ -712,18 +716,17 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
goto err;
_ma_kpointer(info,leaf_key+key_length,leaf_page);
/* Save key in anc_buff */
- DBUG_DUMP("anc_buff",(byte*) anc_buff,anc_length);
- DBUG_DUMP("key_to_anc",(byte*) leaf_key,key_length);
+ DBUG_DUMP("anc_buff",anc_buff,anc_length);
+ DBUG_DUMP("key_to_anc",leaf_key,key_length);
temp_pos=anc_buff+anc_length;
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
- keypos == temp_pos ? (uchar*) 0
+ keypos == temp_pos ? (byte*) 0
: keypos,
anc_pos, anc_pos,
leaf_key,&s_temp);
if (t_length > 0)
- bmove_upp((byte*) temp_pos+t_length,(byte*) temp_pos,
- (uint) (temp_pos-keypos));
+ bmove_upp(temp_pos+t_length, temp_pos, (uint) (temp_pos-keypos));
else
bmove(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
@@ -731,15 +734,15 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* Store first key on new page */
if (nod_flag)
- bmove((byte*) leaf_buff+2,(byte*) half_pos-nod_flag,(size_t) nod_flag);
+ bmove(leaf_buff+2,half_pos-nod_flag,(size_t) nod_flag);
if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key)))
goto err;
- DBUG_DUMP("key_to_leaf",(byte*) leaf_key,length);
- t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (uchar*) 0,
- (uchar*) 0, (uchar*) 0, leaf_key, &s_temp);
+ DBUG_DUMP("key_to_leaf",leaf_key,length);
+ t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (byte*) 0,
+ (byte*) 0, (byte*) 0, leaf_key, &s_temp);
length=(uint) ((buff+buff_length)-half_pos);
DBUG_PRINT("info",("t_length: %d length: %d",t_length,(int) length));
- bmove((byte*) leaf_buff+p_length+t_length,(byte*) half_pos,
+ bmove(leaf_buff+p_length+t_length,half_pos,
(size_t) length);
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
maria_putint(leaf_buff,length+t_length+p_length,nod_flag);
@@ -764,13 +767,13 @@ err:
*/
static uint remove_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar *keypos, /* Where key starts */
- uchar *lastkey, /* key to be removed */
- uchar *page_end, /* End of page */
+ byte *keypos, /* Where key starts */
+ byte *lastkey, /* key to be removed */
+ byte *page_end, /* End of page */
my_off_t *next_block) /* ptr to next block */
{
int s_length;
- uchar *start;
+ byte *start;
DBUG_ENTER("remove_key");
DBUG_PRINT("enter",("keypos: 0x%lx page_end: 0x%lx",(long) keypos, (long) page_end));
@@ -796,7 +799,7 @@ static uint remove_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
{
if (keyinfo->flag & HA_BINARY_PACK_KEY)
{
- uchar *old_key=start;
+ byte *old_key=start;
uint next_length,prev_length,prev_pack_length;
get_key_length(next_length,keypos);
get_key_pack_length(prev_length,prev_pack_length,old_key);
@@ -883,7 +886,6 @@ static uint remove_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
}
}
end:
- bmove((byte*) start,(byte*) start+s_length,
- (uint) (page_end-start-s_length));
+ bmove(start, start+s_length, (uint) (page_end-start-s_length));
DBUG_RETURN((uint) s_length);
} /* remove_key */
diff --git a/storage/maria/ma_delete_all.c b/storage/maria/ma_delete_all.c
index fccd29b15f1..616147c1067 100644
--- a/storage/maria/ma_delete_all.c
+++ b/storage/maria/ma_delete_all.c
@@ -44,8 +44,7 @@ int maria_delete_all_rows(MARIA_HA *info)
info->state->empty=info->state->key_empty=0;
info->state->checksum=0;
- for (i=share->base.max_key_block_length/MARIA_MIN_KEY_BLOCK_LENGTH ; i-- ; )
- state->key_del[i]= HA_OFFSET_ERROR;
+ state->key_del= HA_OFFSET_ERROR;
for (i=0 ; i < share->base.keys ; i++)
state->key_root[i]= HA_OFFSET_ERROR;
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index e0f87addb43..c3d0bf1fb0a 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -26,19 +26,16 @@
#include "maria_def.h"
-/* Enough for comparing if number is zero */
-static char zero_string[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-static int write_dynamic_record(MARIA_HA *info,const byte *record,
- ulong reclength);
+static my_bool write_dynamic_record(MARIA_HA *info,const byte *record,
+ ulong reclength);
static int _ma_find_writepos(MARIA_HA *info,ulong reclength,my_off_t *filepos,
ulong *length);
-static int update_dynamic_record(MARIA_HA *info,my_off_t filepos,byte *record,
- ulong reclength);
-static int delete_dynamic_record(MARIA_HA *info,my_off_t filepos,
- uint second_read);
-static int _ma_cmp_buffer(File file, const byte *buff, my_off_t filepos,
- uint length);
+static my_bool update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
+ byte *record, ulong reclength);
+static my_bool delete_dynamic_record(MARIA_HA *info,MARIA_RECORD_POS filepos,
+ uint second_read);
+static my_bool _ma_cmp_buffer(File file, const byte *buff, my_off_t filepos,
+ uint length);
#ifdef THREAD
/* Play it safe; We have a small stack when using threads */
@@ -224,19 +221,26 @@ uint _ma_nommap_pwrite(MARIA_HA *info, byte *Buffer,
}
-int _ma_write_dynamic_record(MARIA_HA *info, const byte *record)
+my_bool _ma_write_dynamic_record(MARIA_HA *info, const byte *record)
{
- ulong reclength= _ma_rec_pack(info,info->rec_buff,record);
- return (write_dynamic_record(info,info->rec_buff,reclength));
+ ulong reclength= _ma_rec_pack(info,info->rec_buff + MARIA_REC_BUFF_OFFSET,
+ record);
+ return (write_dynamic_record(info,info->rec_buff + MARIA_REC_BUFF_OFFSET,
+ reclength));
}
-int _ma_update_dynamic_record(MARIA_HA *info, my_off_t pos, const byte *record)
+my_bool _ma_update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS pos,
+ const byte *record)
{
- uint length= _ma_rec_pack(info,info->rec_buff,record);
- return (update_dynamic_record(info,pos,info->rec_buff,length));
+ uint length= _ma_rec_pack(info, info->rec_buff + MARIA_REC_BUFF_OFFSET,
+ record);
+ return (update_dynamic_record(info, pos,
+ info->rec_buff + MARIA_REC_BUFF_OFFSET,
+ length));
}
-int _ma_write_blob_record(MARIA_HA *info, const byte *record)
+
+my_bool _ma_write_blob_record(MARIA_HA *info, const byte *record)
{
byte *rec_buff;
int error;
@@ -246,31 +250,27 @@ int _ma_write_blob_record(MARIA_HA *info, const byte *record)
MARIA_DYN_DELETE_BLOCK_HEADER+1);
reclength= (info->s->base.pack_reclength +
_ma_calc_total_blob_length(info,record)+ extra);
-#ifdef NOT_USED /* We now support big rows */
- if (reclength > MARIA_DYN_MAX_ROW_LENGTH)
- {
- my_errno=HA_ERR_TO_BIG_ROW;
- return -1;
- }
-#endif
if (!(rec_buff=(byte*) my_alloca(reclength)))
{
my_errno=ENOMEM;
- return(-1);
+ return(1);
}
- reclength2= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
+ reclength2= _ma_rec_pack(info,
+ rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
record);
DBUG_PRINT("info",("reclength: %lu reclength2: %lu",
reclength, reclength2));
DBUG_ASSERT(reclength2 <= reclength);
- error=write_dynamic_record(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
- reclength2);
+ error= write_dynamic_record(info,
+ rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
+ reclength2);
my_afree(rec_buff);
- return(error);
+ return(error != 0);
}
-int _ma_update_blob_record(MARIA_HA *info, my_off_t pos, const byte *record)
+my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos,
+ const byte *record)
{
byte *rec_buff;
int error;
@@ -284,13 +284,13 @@ int _ma_update_blob_record(MARIA_HA *info, my_off_t pos, const byte *record)
if (reclength > MARIA_DYN_MAX_ROW_LENGTH)
{
my_errno=HA_ERR_TO_BIG_ROW;
- return -1;
+ return 1;
}
#endif
if (!(rec_buff=(byte*) my_alloca(reclength)))
{
my_errno=ENOMEM;
- return(-1);
+ return(1);
}
reclength= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
record);
@@ -298,20 +298,20 @@ int _ma_update_blob_record(MARIA_HA *info, my_off_t pos, const byte *record)
rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
reclength);
my_afree(rec_buff);
- return(error);
+ return(error != 0);
}
-int _ma_delete_dynamic_record(MARIA_HA *info)
+my_bool _ma_delete_dynamic_record(MARIA_HA *info)
{
- return delete_dynamic_record(info,info->lastpos,0);
+ return delete_dynamic_record(info, info->cur_row.lastpos, 0);
}
/* Write record to data-file */
-static int write_dynamic_record(MARIA_HA *info, const byte *record,
- ulong reclength)
+static my_bool write_dynamic_record(MARIA_HA *info, const byte *record,
+ ulong reclength)
{
int flag;
ulong length;
@@ -443,8 +443,8 @@ static bool unlink_deleted_block(MARIA_HA *info, MARIA_BLOCK_INFO *block_info)
(maria_rrnd() or maria_scan(), then ensure that we skip over this block
when doing next maria_rrnd() or maria_scan().
*/
- if (info->nextpos == block_info->filepos)
- info->nextpos+=block_info->block_len;
+ if (info->cur_row.nextpos == block_info->filepos)
+ info->cur_row.nextpos+= block_info->block_len;
DBUG_RETURN(0);
}
@@ -464,8 +464,9 @@ static bool unlink_deleted_block(MARIA_HA *info, MARIA_BLOCK_INFO *block_info)
1 error. In this case my_error is set.
*/
-static int update_backward_delete_link(MARIA_HA *info, my_off_t delete_block,
- my_off_t filepos)
+static my_bool update_backward_delete_link(MARIA_HA *info,
+ my_off_t delete_block,
+ MARIA_RECORD_POS filepos)
{
MARIA_BLOCK_INFO block_info;
DBUG_ENTER("update_backward_delete_link");
@@ -490,11 +491,11 @@ static int update_backward_delete_link(MARIA_HA *info, my_off_t delete_block,
DBUG_RETURN(0);
}
- /* Delete datarecord from database */
- /* info->rec_cache.seek_not_done is updated in cmp_record */
+/* Delete datarecord from database */
+/* info->rec_cache.seek_not_done is updated in cmp_record */
-static int delete_dynamic_record(MARIA_HA *info, my_off_t filepos,
- uint second_read)
+static my_bool delete_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
+ uint second_read)
{
uint length,b_type;
MARIA_BLOCK_INFO block_info,del_block;
@@ -522,7 +523,8 @@ static int delete_dynamic_record(MARIA_HA *info, my_off_t filepos,
del_block.second_read=0;
remove_next_block=0;
if (_ma_get_block_info(&del_block,info->dfile,filepos+length) &
- BLOCK_DELETED && del_block.block_len+length < MARIA_DYN_MAX_BLOCK_LENGTH)
+ BLOCK_DELETED && del_block.block_len+length <
+ MARIA_DYN_MAX_BLOCK_LENGTH)
{
/* We can't remove this yet as this block may be the head block */
remove_next_block=1;
@@ -719,8 +721,9 @@ int _ma_write_part_record(MARIA_HA *info,
else
{
info->rec_cache.seek_not_done=1;
- if (info->s->file_write(info,(byte*) *record-head_length,length+extra_length+
- del_length,filepos,info->s->write_flag))
+ if (info->s->file_write(info,(byte*) *record-head_length,
+ length+extra_length+
+ del_length,filepos,info->s->write_flag))
goto err;
}
memcpy(record_end,temp,(size_t) (extra_length+del_length));
@@ -745,8 +748,8 @@ err:
/* update record from datafile */
-static int update_dynamic_record(MARIA_HA *info, my_off_t filepos, byte *record,
- ulong reclength)
+static my_bool update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
+ byte *record, ulong reclength)
{
int flag;
uint error;
@@ -784,8 +787,8 @@ static int update_dynamic_record(MARIA_HA *info, my_off_t filepos, byte *record,
{
/* extend file */
DBUG_PRINT("info",("Extending file with %d bytes",tmp));
- if (info->nextpos == info->state->data_file_length)
- info->nextpos+= tmp;
+ if (info->cur_row.nextpos == info->state->data_file_length)
+ info->cur_row.nextpos+= tmp;
info->state->data_file_length+= tmp;
info->update|= HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK;
length+=tmp;
@@ -829,8 +832,8 @@ static int update_dynamic_record(MARIA_HA *info, my_off_t filepos, byte *record,
mi_int3store(del_block.header+1, rest_length);
mi_sizestore(del_block.header+4,info->s->state.dellink);
bfill(del_block.header+12,8,255);
- if (info->s->file_write(info,(byte*) del_block.header,20, next_pos,
- MYF(MY_NABP)))
+ if (info->s->file_write(info,(byte*) del_block.header, 20,
+ next_pos, MYF(MY_NABP)))
DBUG_RETURN(1);
info->s->state.dellink= next_pos;
info->s->state.split++;
@@ -877,9 +880,18 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
MARIA_BLOB *blob;
DBUG_ENTER("_ma_rec_pack");
- flag=0 ; bit=1;
- startpos=packpos=to; to+= info->s->base.pack_bits; blob=info->blobs;
- rec=info->s->rec;
+ flag= 0;
+ bit= 1;
+ startpos= packpos=to;
+ to+= info->s->base.pack_bytes;
+ blob= info->blobs;
+ rec= info->s->rec;
+ if (info->s->base.null_bytes)
+ {
+ memcpy(to, from, info->s->base.null_bytes);
+ from+= info->s->base.null_bytes;
+ to+= info->s->base.null_bytes;
+ }
for (i=info->s->base.fields ; i-- > 0; from+= length,rec++)
{
@@ -903,7 +915,7 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
}
else if (type == FIELD_SKIP_ZERO)
{
- if (memcmp((byte*) from,zero_string,length) == 0)
+ if (memcmp((byte*) from, maria_zero_string, length) == 0)
flag|=bit;
else
{
@@ -981,7 +993,7 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
if (bit != 1)
*packpos= (char) (uchar) flag;
if (info->s->calc_checksum)
- *to++=(char) info->checksum;
+ *to++= (byte) info->cur_row.checksum;
DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
DBUG_RETURN((uint) (to-startpos));
} /* _ma_rec_pack */
@@ -989,7 +1001,7 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
/*
- Check if a record was correctly packed. Used only by mariachk
+ Check if a record was correctly packed. Used only by maria_chk
Returns 0 if record is ok.
*/
@@ -1002,9 +1014,11 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
reg3 MARIA_COLUMNDEF *rec;
DBUG_ENTER("_ma_rec_check");
- packpos=rec_buff; to= rec_buff+info->s->base.pack_bits;
+ packpos=rec_buff; to= rec_buff+info->s->base.pack_bytes;
rec=info->s->rec;
flag= *packpos; bit=1;
+ record+= info->s->base.null_bytes;
+ to+= info->s->base.null_bytes;
for (i=info->s->base.fields ; i-- > 0; record+= length, rec++)
{
@@ -1022,7 +1036,7 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
}
else if (type == FIELD_SKIP_ZERO)
{
- if (memcmp((byte*) record,zero_string,length) == 0)
+ if (memcmp((byte*) record, maria_zero_string, length) == 0)
{
if (!(flag & bit))
goto err;
@@ -1098,7 +1112,7 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
if (packed_length != (uint) (to - rec_buff) + test(info->s->calc_checksum) ||
(bit != 1 && (flag & ~(bit - 1))))
goto err;
- if (with_checksum && ((uchar) info->checksum != (uchar) *to))
+ if (with_checksum && ((uchar) info->cur_row.checksum != (uchar) *to))
{
DBUG_PRINT("error",("wrong checksum for row"));
goto err;
@@ -1129,8 +1143,16 @@ ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
flag= (uchar) *from; bit=1; packpos=from;
if (found_length < info->s->base.min_pack_length)
goto err;
- from+= info->s->base.pack_bits;
- min_pack_length=info->s->base.min_pack_length - info->s->base.pack_bits;
+ from+= info->s->base.pack_bytes;
+ min_pack_length= info->s->base.min_pack_length - info->s->base.pack_bytes;
+
+ if ((length= info->s->base.null_bytes))
+ {
+ memcpy(to, from, length);
+ from+= length;
+ to+= length;
+ min_pack_length-= length;
+ }
for (rec=info->s->rec , end_field=rec+info->s->base.fields ;
rec < end_field ; to+= rec_length, rec++)
@@ -1234,7 +1256,7 @@ ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
}
}
if (info->s->calc_checksum)
- from++;
+ info->cur_row.checksum= (uint) (uchar) *from++;
if (to == to_end && from == from_end && (bit == 1 || !(flag & ~(bit-1))))
DBUG_RETURN(found_length);
@@ -1314,7 +1336,6 @@ void _ma_store_blob_length(byte *pos,uint pack_length,uint length)
buf Destination for record.
NOTE
-
If a write buffer is active, it needs to be flushed if its contents
intersects with the record to read. We always check if the position
of the first byte of the write buffer is lower than the position
@@ -1333,17 +1354,17 @@ void _ma_store_blob_length(byte *pos,uint pack_length,uint length)
RETURN
0 OK
- -1 Error
+ 1 Error
*/
-
-int _ma_read_dynamic_record(MARIA_HA *info, my_off_t filepos, byte *buf)
+int _ma_read_dynamic_record(MARIA_HA *info, byte *buf,
+ MARIA_RECORD_POS filepos)
{
int block_of_record;
uint b_type,left_length;
byte *to;
MARIA_BLOCK_INFO block_info;
File file;
- DBUG_ENTER("maria_read_dynamic_record");
+ DBUG_ENTER("_ma_read_dynamic_record");
if (filepos != HA_OFFSET_ERROR)
{
@@ -1376,12 +1397,12 @@ int _ma_read_dynamic_record(MARIA_HA *info, my_off_t filepos, byte *buf)
goto panic;
if (info->s->base.blobs)
{
- if (!(to=_ma_alloc_rec_buff(info, block_info.rec_len,
- &info->rec_buff)))
+ if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
+ block_info.rec_len +
+ info->s->base.extra_rec_buff_size))
goto err;
}
- else
- to= info->rec_buff;
+ to= info->rec_buff;
left_length=block_info.rec_len;
}
if (left_length < block_info.data_len || ! block_info.data_len)
@@ -1426,55 +1447,61 @@ int _ma_read_dynamic_record(MARIA_HA *info, my_off_t filepos, byte *buf)
info->update|= HA_STATE_AKTIV; /* We have a aktive record */
fast_ma_writeinfo(info);
DBUG_RETURN(_ma_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
- MY_FILE_ERROR ? 0 : -1);
+ MY_FILE_ERROR ? 0 : 1);
}
fast_ma_writeinfo(info);
- DBUG_RETURN(-1); /* Wrong data to read */
+ DBUG_RETURN(1); /* Wrong data to read */
panic:
my_errno=HA_ERR_WRONG_IN_RECORD;
err:
VOID(_ma_writeinfo(info,0));
- DBUG_RETURN(-1);
+ DBUG_RETURN(1);
}
/* compare unique constraint between stored rows */
-int _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
- const byte *record, my_off_t pos)
+my_bool _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
+ const byte *record, MARIA_RECORD_POS pos)
{
- byte *rec_buff,*old_record;
- int error;
+ byte *old_rec_buff,*old_record;
+ my_off_t old_rec_buff_size;
+ my_bool error;
DBUG_ENTER("_ma_cmp_dynamic_unique");
if (!(old_record=my_alloca(info->s->base.reclength)))
DBUG_RETURN(1);
/* Don't let the compare destroy blobs that may be in use */
- rec_buff=info->rec_buff;
+ old_rec_buff= info->rec_buff;
+ old_rec_buff_size= info->rec_buff_size;
+
if (info->s->base.blobs)
- info->rec_buff=0;
- error= _ma_read_dynamic_record(info,pos,old_record);
+ info->rec_buff= 0;
+ error= _ma_read_dynamic_record(info, old_record, pos) != 0;
if (!error)
- error=_ma_unique_comp(def, record, old_record, def->null_are_equal);
+ error=_ma_unique_comp(def, record, old_record, def->null_are_equal) != 0;
if (info->s->base.blobs)
{
- my_free(_ma_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
- info->rec_buff=rec_buff;
+ my_free(info->rec_buff, MYF(MY_ALLOW_ZERO_PTR));
+ info->rec_buff= old_rec_buff;
+ info->rec_buff_size= old_rec_buff_size;
}
my_afree(old_record);
DBUG_RETURN(error);
}
- /* Compare of record one disk with packed record in memory */
+ /* Compare of record on disk with packed record in memory */
-int _ma_cmp_dynamic_record(register MARIA_HA *info, register const byte *record)
+my_bool _ma_cmp_dynamic_record(register MARIA_HA *info,
+ register const byte *record)
{
- uint flag,reclength,b_type;
+ uint flag, reclength, b_type,cmp_length;
my_off_t filepos;
byte *buffer;
MARIA_BLOCK_INFO block_info;
+ my_bool error= 1;
DBUG_ENTER("_ma_cmp_dynamic_record");
/* We are going to do changes; dont let anybody disturb */
@@ -1484,7 +1511,7 @@ int _ma_cmp_dynamic_record(register MARIA_HA *info, register const byte *record)
{
info->update&= ~(HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK);
if (flush_io_cache(&info->rec_cache))
- DBUG_RETURN(-1);
+ DBUG_RETURN(1);
}
info->rec_cache.seek_not_done=1;
@@ -1497,12 +1524,12 @@ int _ma_cmp_dynamic_record(register MARIA_HA *info, register const byte *record)
{
if (!(buffer=(byte*) my_alloca(info->s->base.pack_reclength+
_ma_calc_total_blob_length(info,record))))
- DBUG_RETURN(-1);
+ DBUG_RETURN(1);
}
reclength= _ma_rec_pack(info,buffer,record);
record= buffer;
- filepos=info->lastpos;
+ filepos= info->cur_row.lastpos;
flag=block_info.second_read=0;
block_info.next_filepos=filepos;
while (reclength > 0)
@@ -1529,9 +1556,13 @@ int _ma_cmp_dynamic_record(register MARIA_HA *info, register const byte *record)
my_errno=HA_ERR_WRONG_IN_RECORD;
goto err;
}
- reclength-=block_info.data_len;
+ reclength-= block_info.data_len;
+ cmp_length= block_info.data_len;
+ if (!reclength && info->s->calc_checksum)
+ cmp_length--; /* 'record' may not contain checksum */
+
if (_ma_cmp_buffer(info->dfile,record,block_info.filepos,
- block_info.data_len))
+ cmp_length))
{
my_errno=HA_ERR_RECORD_CHANGED;
goto err;
@@ -1541,17 +1572,19 @@ int _ma_cmp_dynamic_record(register MARIA_HA *info, register const byte *record)
}
}
my_errno=0;
+ error= 0;
err:
if (buffer != info->rec_buff)
my_afree((gptr) buffer);
- DBUG_RETURN(my_errno);
+ DBUG_PRINT("exit", ("result: %d", error));
+ DBUG_RETURN(error);
}
/* Compare file to buffert */
-static int _ma_cmp_buffer(File file, const byte *buff, my_off_t filepos,
- uint length)
+static my_bool _ma_cmp_buffer(File file, const byte *buff, my_off_t filepos,
+ uint length)
{
uint next_length;
char temp_buff[IO_SIZE*2];
@@ -1571,7 +1604,7 @@ static int _ma_cmp_buffer(File file, const byte *buff, my_off_t filepos,
}
if (my_pread(file,temp_buff,length,filepos,MYF(MY_NABP)))
goto err;
- DBUG_RETURN(memcmp((byte*) buff,temp_buff,length));
+ DBUG_RETURN(memcmp((byte*) buff,temp_buff,length) != 0);
err:
DBUG_RETURN(1);
}
@@ -1611,8 +1644,9 @@ err:
!= 0 Error
*/
-int _ma_read_rnd_dynamic_record(MARIA_HA *info, byte *buf,
- register my_off_t filepos,
+int _ma_read_rnd_dynamic_record(MARIA_HA *info,
+ byte *buf,
+ MARIA_RECORD_POS filepos,
my_bool skip_deleted_blocks)
{
int block_of_record, info_read, save_errno;
@@ -1686,9 +1720,9 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, byte *buf,
}
if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
{
- my_errno=HA_ERR_RECORD_DELETED;
- info->lastpos=block_info.filepos;
- info->nextpos=block_info.filepos+block_info.block_len;
+ my_errno= HA_ERR_RECORD_DELETED;
+ info->cur_row.lastpos= block_info.filepos;
+ info->cur_row.nextpos= block_info.filepos+block_info.block_len;
}
goto err;
}
@@ -1696,15 +1730,15 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, byte *buf,
{
if (block_info.rec_len > (uint) share->base.max_pack_length)
goto panic;
- info->lastpos=filepos;
+ info->cur_row.lastpos= filepos;
if (share->base.blobs)
{
- if (!(to= _ma_alloc_rec_buff(info, block_info.rec_len,
- &info->rec_buff)))
+ if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
+ block_info.rec_len +
+ info->s->base.extra_rec_buff_size))
goto err;
}
- else
- to= info->rec_buff;
+ to= info->rec_buff;
left_len=block_info.rec_len;
}
if (left_len < block_info.data_len)
@@ -1760,7 +1794,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, byte *buf,
*/
if (block_of_record++ == 0)
{
- info->nextpos=block_info.filepos+block_info.block_len;
+ info->cur_row.nextpos= block_info.filepos+block_info.block_len;
skip_deleted_blocks=0;
}
left_len-=block_info.data_len;
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index 1f649a00753..90e79362442 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -19,7 +19,8 @@
#include <sys/mman.h>
#endif
-static void maria_extra_keyflag(MARIA_HA *info, enum ha_extra_function function);
+static void maria_extra_keyflag(MARIA_HA *info,
+ enum ha_extra_function function);
/*
@@ -38,7 +39,8 @@ static void maria_extra_keyflag(MARIA_HA *info, enum ha_extra_function function)
# error
*/
-int maria_extra(MARIA_HA *info, enum ha_extra_function function, void *extra_arg)
+int maria_extra(MARIA_HA *info, enum ha_extra_function function,
+ void *extra_arg)
{
int error=0;
ulong cache_size;
@@ -49,7 +51,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, void *extra_arg
switch (function) {
case HA_EXTRA_RESET_STATE: /* Reset state (don't free buffers) */
info->lastinx= 0; /* Use first index as def */
- info->last_search_keypage=info->lastpos= HA_OFFSET_ERROR;
+ info->last_search_keypage= info->cur_row.lastpos= HA_OFFSET_ERROR;
info->page_changed=1;
/* Next/prev gives first/last */
if (info->opt_flag & READ_CACHE_USED)
@@ -115,7 +117,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, void *extra_arg
case HA_EXTRA_REINIT_CACHE:
if (info->opt_flag & READ_CACHE_USED)
{
- reinit_io_cache(&info->rec_cache,READ_CACHE,info->nextpos,
+ reinit_io_cache(&info->rec_cache, READ_CACHE, info->cur_row.nextpos,
(pbool) (info->lock_type != F_UNLCK),
(pbool) test(info->update & HA_STATE_ROW_CHANGED));
info->update&= ~HA_STATE_ROW_CHANGED;
@@ -185,7 +187,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, void *extra_arg
(byte*) info->lastkey,info->lastkey_length);
info->save_update= info->update;
info->save_lastinx= info->lastinx;
- info->save_lastpos= info->lastpos;
+ info->save_lastpos= info->cur_row.lastpos;
info->save_lastkey_length=info->lastkey_length;
if (function == HA_EXTRA_REMEMBER_POS)
break;
@@ -203,7 +205,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, void *extra_arg
info->save_lastkey_length);
info->update= info->save_update | HA_STATE_WRITTEN;
info->lastinx= info->save_lastinx;
- info->lastpos= info->save_lastpos;
+ info->cur_row.lastpos= info->save_lastpos;
info->lastkey_length=info->save_lastkey_length;
}
info->read_record= share->read_record;
@@ -325,8 +327,13 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, void *extra_arg
maria_mark_crashed(info); /* Fatal error found */
}
}
- if (share->base.blobs)
- _ma_alloc_rec_buff(info, -1, &info->rec_buff);
+ if (share->base.blobs && info->rec_buff_size >
+ share->base.default_rec_buff_size)
+ {
+ info->rec_buff_size= 1; /* Force realloc */
+ _ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
+ share->base.default_rec_buff_size);
+ }
break;
case HA_EXTRA_NORMAL: /* Theese isn't in use */
info->quick_mode=0;
@@ -422,8 +429,13 @@ int maria_reset(MARIA_HA *info)
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
error= end_io_cache(&info->rec_cache);
}
- if (share->base.blobs)
- _ma_alloc_rec_buff(info, -1, &info->rec_buff);
+ if (share->base.blobs && info->rec_buff_size >
+ share->base.default_rec_buff_size)
+ {
+ info->rec_buff_size= 1; /* Force realloc */
+ _ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
+ share->base.default_rec_buff_size);
+ }
#if defined(HAVE_MMAP) && defined(HAVE_MADVISE)
if (info->opt_flag & MEMMAP_USED)
madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
@@ -431,7 +443,7 @@ int maria_reset(MARIA_HA *info)
info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
info->quick_mode=0;
info->lastinx= 0; /* Use first index as def */
- info->last_search_keypage= info->lastpos= HA_OFFSET_ERROR;
+ info->last_search_keypage= info->cur_row.lastpos= HA_OFFSET_ERROR;
info->page_changed= 1;
info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
HA_STATE_PREV_FOUND);
diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c
index 24b51ef469c..06b044e9e38 100644
--- a/storage/maria/ma_ft_boolean_search.c
+++ b/storage/maria/ma_ft_boolean_search.c
@@ -331,8 +331,8 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
int subkeys=1;
my_bool can_go_down;
MARIA_HA *info=ftb->info;
- uint off, extra=HA_FT_WLEN+info->s->base.rec_reflength;
- byte *lastkey_buf=ftbw->word+ftbw->off;
+ uint off= 0, extra=HA_FT_WLEN+info->s->base.rec_reflength;
+ byte *lastkey_buf= ftbw->word+ftbw->off;
if (ftbw->flags & FTB_FLAG_TRUNC)
lastkey_buf+=ftbw->len;
@@ -342,7 +342,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
ftbw->key_root=info->s->state.key_root[ftb->keynr];
ftbw->keyinfo=info->s->keyinfo+ftb->keynr;
- r= _ma_search(info, ftbw->keyinfo, (uchar*) ftbw->word, ftbw->len,
+ r= _ma_search(info, ftbw->keyinfo, ftbw->word, ftbw->len,
SEARCH_FIND | SEARCH_BIGGER, ftbw->key_root);
}
else
@@ -351,10 +351,10 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
if (ftbw->docid[0] < *ftbw->max_docid)
{
sflag|= SEARCH_SAME;
- _ma_dpointer(info, (uchar *)(ftbw->word + ftbw->len + HA_FT_WLEN),
+ _ma_dpointer(info, (ftbw->word + ftbw->len + HA_FT_WLEN),
*ftbw->max_docid);
}
- r= _ma_search(info, ftbw->keyinfo, (uchar*) lastkey_buf,
+ r= _ma_search(info, ftbw->keyinfo, lastkey_buf,
USE_WHOLE_KEY, sflag, ftbw->key_root);
}
@@ -368,7 +368,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
off=info->lastkey_length-extra;
subkeys=ft_sintXkorr(info->lastkey+off);
}
- if (subkeys<0 || info->lastpos < info->state->data_file_length)
+ if (subkeys<0 || info->cur_row.lastpos < info->state->data_file_length)
break;
r= _ma_search_next(info, ftbw->keyinfo, info->lastkey,
info->lastkey_length,
@@ -378,11 +378,11 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
if (!r && !ftbw->off)
{
r= ha_compare_text(ftb->charset,
- info->lastkey+1,
+ (uchar*) info->lastkey+1,
info->lastkey_length-extra-1,
- (uchar*) ftbw->word+1,
+ (uchar*) ftbw->word+1,
ftbw->len-1,
- (my_bool) (ftbw->flags & FTB_FLAG_TRUNC),0);
+ (my_bool) (ftbw->flags & FTB_FLAG_TRUNC), 0);
}
if (r) /* not found */
@@ -404,7 +404,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
}
/* going up to the first-level tree to continue search there */
- _ma_dpointer(info, (uchar*) (lastkey_buf+HA_FT_WLEN), ftbw->key_root);
+ _ma_dpointer(info, (lastkey_buf+HA_FT_WLEN), ftbw->key_root);
ftbw->key_root=info->s->state.key_root[ftb->keynr];
ftbw->keyinfo=info->s->keyinfo+ftb->keynr;
ftbw->off=0;
@@ -424,15 +424,15 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
TODO here: subkey-based optimization
*/
ftbw->off=off;
- ftbw->key_root=info->lastpos;
+ ftbw->key_root= info->cur_row.lastpos;
ftbw->keyinfo=& info->s->ft2_keyinfo;
r= _ma_search_first(info, ftbw->keyinfo, ftbw->key_root);
DBUG_ASSERT(r==0); /* found something */
memcpy(lastkey_buf+off, info->lastkey, info->lastkey_length);
}
- ftbw->docid[0]=info->lastpos;
+ ftbw->docid[0]= info->cur_row.lastpos;
if (ftbw->flags & FTB_FLAG_YES)
- *ftbw->max_docid= info->lastpos;
+ *ftbw->max_docid= info->cur_row.lastpos;
return 0;
}
@@ -795,11 +795,11 @@ int maria_ft_boolean_read_next(FT_INFO *ftb, char *record)
/* but it managed already to get past this line once */
continue;
- info->lastpos=curdoc;
+ info->cur_row.lastpos= curdoc;
/* Clear all states, except that the table was updated */
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
- if (!(*info->read_record)(info,curdoc,record))
+ if (!(*info->read_record)(info, record, curdoc))
{
info->update|= HA_STATE_AKTIV; /* Record is read */
if (ftb->with_scan && maria_ft_boolean_find_relevance(ftb,record,0)==0)
@@ -850,9 +850,9 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
(uchar*)ftbw->word + 1,ftbw->len - 1,
(my_bool)(ftbw->flags & FTB_FLAG_TRUNC), 0))
break;
- if (ftbw->docid[1] == ftb->info->lastpos)
+ if (ftbw->docid[1] == ftb->info->cur_row.lastpos)
continue;
- ftbw->docid[1]= ftb->info->lastpos;
+ ftbw->docid[1]= ftb->info->cur_row.lastpos;
_ftb_climb_the_tree(ftb, ftbw, ftb_param->ftsi);
}
return(0);
@@ -876,7 +876,7 @@ float maria_ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
{
FTB_EXPR *ftbe;
FT_SEG_ITERATOR ftsi, ftsi2;
- my_off_t docid=ftb->info->lastpos;
+ MARIA_RECORD_POS docid= ftb->info->cur_row.lastpos;
MY_FTB_FIND_PARAM ftb_param;
MYSQL_FTPARSER_PARAM *param;
struct st_mysql_ftparser *parser= ftb->keynr == NO_SUCH_KEY ?
diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c
index 993857aecbb..4c922516455 100644
--- a/storage/maria/ma_ft_nlq_search.c
+++ b/storage/maria/ma_ft_nlq_search.c
@@ -69,8 +69,8 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
FT_SUPERDOC sdoc, *sptr;
TREE_ELEMENT *selem;
double gweight=1;
- MARIA_HA *info=aio->info;
- uchar *keybuff=aio->keybuff;
+ MARIA_HA *info= aio->info;
+ byte *keybuff= (byte*) aio->keybuff;
MARIA_KEYDEF *keyinfo=info->s->keyinfo+aio->keynr;
my_off_t key_root=info->s->state.key_root[aio->keynr];
uint extra=HA_FT_WLEN+info->s->base.rec_reflength;
@@ -92,7 +92,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
for (r= _ma_search(info, keyinfo, keybuff, keylen, SEARCH_FIND, key_root) ;
!r &&
(subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 &&
- info->lastpos >= info->state->data_file_length ;
+ info->cur_row.lastpos >= info->state->data_file_length ;
r= _ma_search_next(info, keyinfo, info->lastkey,
info->lastkey_length, SEARCH_BIGGER, key_root))
;
@@ -104,8 +104,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
{
if (keylen &&
- ha_compare_text(aio->charset,info->lastkey+1,
- info->lastkey_length-extra-1, keybuff+1,keylen-1,0,0))
+ ha_compare_text(aio->charset,
+ (uchar*) info->lastkey+1, info->lastkey_length-extra-1,
+ (uchar*) keybuff+1, keylen-1, 0, 0))
break;
if (subkeys<0)
@@ -118,7 +119,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
*/
keybuff+=keylen;
keyinfo=& info->s->ft2_keyinfo;
- key_root=info->lastpos;
+ key_root= info->cur_row.lastpos;
keylen=0;
r= _ma_search_first(info, keyinfo, key_root);
goto do_skip;
@@ -132,7 +133,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
if (tmp_weight==0)
DBUG_RETURN(doc_cnt); /* stopword, doc_cnt should be 0 */
- sdoc.doc.dpos=info->lastpos;
+ sdoc.doc.dpos= info->cur_row.lastpos;
/* saving document matched into dtree */
if (!(selem=tree_insert(&aio->dtree, &sdoc, 0, aio->dtree.custom_arg)))
@@ -162,7 +163,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
SEARCH_BIGGER, key_root);
do_skip:
while ((subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 &&
- !r && info->lastpos >= info->state->data_file_length)
+ !r && info->cur_row.lastpos >= info->state->data_file_length)
r= _ma_search_next(info, keyinfo, info->lastkey, info->lastkey_length,
SEARCH_BIGGER, key_root);
@@ -209,22 +210,22 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, byte *query,
ALL_IN_ONE aio;
FT_DOC *dptr;
FT_INFO *dlist=NULL;
- my_off_t saved_lastpos=info->lastpos;
+ MARIA_RECORD_POS saved_lastpos= info->cur_row.lastpos;
struct st_mysql_ftparser *parser;
MYSQL_FTPARSER_PARAM *ftparser_param;
DBUG_ENTER("maria_ft_init_nlq_search");
-/* black magic ON */
+ /* black magic ON */
if ((int) (keynr = _ma_check_index(info,keynr)) < 0)
DBUG_RETURN(NULL);
if (_ma_readinfo(info,F_RDLCK,1))
DBUG_RETURN(NULL);
-/* black magic OFF */
+ /* black magic OFF */
aio.info=info;
aio.keynr=keynr;
aio.charset=info->s->keyinfo[keynr].seg->charset;
- aio.keybuff=info->lastkey+info->s->base.max_key_length;
+ aio.keybuff= (uchar*) info->lastkey+info->s->base.max_key_length;
parser= info->s->keyinfo[keynr].parser;
if (! (ftparser_param= maria_ftparser_call_initializer(info, keynr, 0)))
goto err;
@@ -254,7 +255,7 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, byte *query,
while (best.elements)
{
my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos;
- if (!(*info->read_record)(info,docid,record))
+ if (!(*info->read_record)(info, record, docid))
{
info->update|= HA_STATE_AKTIV;
ftparser_param->flags= MYSQL_FTFLAGS_NEED_COPY;
@@ -296,7 +297,7 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, byte *query,
err:
delete_tree(&aio.dtree);
delete_tree(&wtree);
- info->lastpos=saved_lastpos;
+ info->cur_row.lastpos= saved_lastpos;
DBUG_RETURN(dlist);
}
@@ -313,8 +314,8 @@ int maria_ft_nlq_read_next(FT_INFO *handler, char *record)
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
- info->lastpos=handler->doc[handler->curdoc].dpos;
- if (!(*info->read_record)(info,info->lastpos,record))
+ info->cur_row.lastpos= handler->doc[handler->curdoc].dpos;
+ if (!(*info->read_record)(info, record, info->cur_row.lastpos))
{
info->update|= HA_STATE_AKTIV; /* Record is read */
return 0;
@@ -329,7 +330,7 @@ float maria_ft_nlq_find_relevance(FT_INFO *handler,
{
int a,b,c;
FT_DOC *docs=handler->doc;
- my_off_t docid=handler->info->lastpos;
+ MARIA_RECORD_POS docid= handler->info->cur_row.lastpos;
if (docid == HA_POS_ERROR)
return -5.0;
diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c
index 965f9afc91d..25f4d5a67a0 100644
--- a/storage/maria/ma_ft_update.c
+++ b/storage/maria/ma_ft_update.c
@@ -141,7 +141,7 @@ static int _ma_ft_store(MARIA_HA *info, uint keynr, byte *keybuf,
for (; wlist->pos; wlist++)
{
key_length= _ma_ft_make_key(info,keynr,keybuf,wlist,filepos);
- if (_ma_ck_write(info,keynr,(uchar*) keybuf,key_length))
+ if (_ma_ck_write(info, keynr, keybuf, key_length))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
@@ -156,7 +156,7 @@ static int _ma_ft_erase(MARIA_HA *info, uint keynr, byte *keybuf,
for (; wlist->pos; wlist++)
{
key_length= _ma_ft_make_key(info,keynr,keybuf,wlist,filepos);
- if (_ma_ck_delete(info,keynr,(uchar*) keybuf,key_length))
+ if (_ma_ck_delete(info, keynr, keybuf, key_length))
err=1;
}
DBUG_RETURN(err);
@@ -219,13 +219,13 @@ int _ma_ft_update(MARIA_HA *info, uint keynr, byte *keybuf,
if (cmp < 0 || cmp2)
{
key_length= _ma_ft_make_key(info,keynr,keybuf,old_word,pos);
- if ((error= _ma_ck_delete(info,keynr,(uchar*) keybuf,key_length)))
+ if ((error= _ma_ck_delete(info,keynr, keybuf,key_length)))
goto err;
}
if (cmp > 0 || cmp2)
{
- key_length= _ma_ft_make_key(info,keynr,keybuf,new_word,pos);
- if ((error= _ma_ck_write(info,keynr,(uchar*) keybuf,key_length)))
+ key_length= _ma_ft_make_key(info, keynr, keybuf, new_word,pos);
+ if ((error= _ma_ck_write(info, keynr, keybuf,key_length)))
goto err;
}
if (cmp<=0) old_word++;
@@ -277,8 +277,9 @@ int _ma_ft_del(MARIA_HA *info, uint keynr, byte *keybuf, const byte *record,
DBUG_RETURN(error);
}
+
uint _ma_ft_make_key(MARIA_HA *info, uint keynr, byte *keybuf, FT_WORD *wptr,
- my_off_t filepos)
+ my_off_t filepos)
{
byte buf[HA_FT_MAXBYTELEN+16];
DBUG_ENTER("_ma_ft_make_key");
@@ -294,7 +295,7 @@ uint _ma_ft_make_key(MARIA_HA *info, uint keynr, byte *keybuf, FT_WORD *wptr,
int2store(buf+HA_FT_WLEN,wptr->len);
memcpy(buf+HA_FT_WLEN+2,wptr->pos,wptr->len);
- DBUG_RETURN(_ma_make_key(info,keynr,(uchar*) keybuf,buf,filepos));
+ DBUG_RETURN(_ma_make_key(info, keynr, keybuf, buf, filepos));
}
@@ -302,12 +303,12 @@ uint _ma_ft_make_key(MARIA_HA *info, uint keynr, byte *keybuf, FT_WORD *wptr,
convert key value to ft2
*/
-uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, uchar *key)
+uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, byte *key)
{
my_off_t root;
DYNAMIC_ARRAY *da=info->ft1_to_ft2;
MARIA_KEYDEF *keyinfo=&info->s->ft2_keyinfo;
- uchar *key_ptr= (uchar*) dynamic_array_ptr(da, 0), *end;
+ byte *key_ptr= (byte*) dynamic_array_ptr(da, 0), *end;
uint length, key_length;
DBUG_ENTER("_ma_ft_convert_to_ft2");
@@ -329,13 +330,13 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, uchar *key)
/* creating pageful of keys */
maria_putint(info->buff,length+2,0);
memcpy(info->buff+2, key_ptr, length);
- info->buff_used=info->page_changed=1; /* info->buff is used */
+ info->keybuff_used=info->page_changed=1; /* info->buff is used */
if ((root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
_ma_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff))
DBUG_RETURN(-1);
/* inserting the rest of key values */
- end= (uchar*) dynamic_array_ptr(da, da->elements);
+ end= (byte*) dynamic_array_ptr(da, da->elements);
for (key_ptr+=length; key_ptr < end; key_ptr+=keyinfo->keylength)
if(_ma_ck_real_write_btree(info, keyinfo, key_ptr, 0, &root, SEARCH_SAME))
DBUG_RETURN(-1);
diff --git a/storage/maria/ma_fulltext.h b/storage/maria/ma_fulltext.h
index 946a5628175..cf21471b316 100644
--- a/storage/maria/ma_fulltext.h
+++ b/storage/maria/ma_fulltext.h
@@ -25,4 +25,4 @@ int _ma_ft_cmp(MARIA_HA *, uint, const byte *, const byte *);
int _ma_ft_add(MARIA_HA *, uint, byte *, const byte *, my_off_t);
int _ma_ft_del(MARIA_HA *, uint, byte *, const byte *, my_off_t);
-uint _ma_ft_convert_to_ft2(MARIA_HA *, uint, uchar *);
+uint _ma_ft_convert_to_ft2(MARIA_HA *, uint, byte *);
diff --git a/storage/maria/ma_info.c b/storage/maria/ma_info.c
index b22ffa41833..397cd2465d4 100644
--- a/storage/maria/ma_info.c
+++ b/storage/maria/ma_info.c
@@ -23,9 +23,9 @@
/* Get position to last record */
-my_off_t maria_position(MARIA_HA *info)
+MARIA_RECORD_POS maria_position(MARIA_HA *info)
{
- return info->lastpos;
+ return info->cur_row.lastpos;
}
@@ -38,7 +38,7 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
MARIA_SHARE *share=info->s;
DBUG_ENTER("maria_status");
- x->recpos = info->lastpos;
+ x->recpos= info->cur_row.lastpos;
if (flag == HA_STATUS_POS)
DBUG_RETURN(0); /* Compatible with ISAM */
if (!(flag & HA_STATUS_NO_LOCK))
@@ -64,8 +64,8 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
}
if (flag & HA_STATUS_ERRKEY)
{
- x->errkey = info->errkey;
- x->dupp_key_pos= info->dupp_key_pos;
+ x->errkey= info->errkey;
+ x->dup_key_pos= info->dup_key_pos;
}
if (flag & HA_STATUS_CONST)
{
@@ -121,13 +121,17 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
void _ma_report_error(int errcode, const char *file_name)
{
- size_t lgt;
+ uint length;
DBUG_ENTER("_ma_report_error");
DBUG_PRINT("enter",("errcode %d, table '%s'", errcode, file_name));
- if ((lgt= strlen(file_name)) > 64)
- file_name+= lgt - 64;
+ if ((length= strlen(file_name)) > 64)
+ {
+ uint dir_length= dirname_length(file_name);
+ file_name+= dir_length;
+ if ((length-= dir_length) > 64)
+ file_name+= length - 64;
+ }
my_error(errcode, MYF(ME_NOREFRESH), file_name);
DBUG_VOID_RETURN;
}
-
diff --git a/storage/maria/ma_init.c b/storage/maria/ma_init.c
index 476e8f694fc..679aa8c6f8f 100644
--- a/storage/maria/ma_init.c
+++ b/storage/maria/ma_init.c
@@ -18,6 +18,7 @@
#include "maria_def.h"
#include <ft_global.h>
+#include "ma_blockrec.h"
my_bool maria_inited= FALSE;
pthread_mutex_t THR_LOCK_maria;
@@ -42,6 +43,7 @@ int maria_init(void)
{
maria_inited= TRUE;
pthread_mutex_init(&THR_LOCK_maria,MY_MUTEX_INIT_SLOW);
+ _ma_init_block_record_data();
}
return 0;
}
diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c
index 78465ca729f..deab2b9c983 100644
--- a/storage/maria/ma_key.c
+++ b/storage/maria/ma_key.c
@@ -49,11 +49,11 @@ static int _ma_put_key_in_record(MARIA_HA *info,uint keynr,byte *record);
Length of key
*/
-uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
- const byte *record, my_off_t filepos)
+uint _ma_make_key(register MARIA_HA *info, uint keynr, byte *key,
+ const byte *record, MARIA_RECORD_POS filepos)
{
- byte *pos;
- uchar *start;
+ const byte *pos;
+ byte *start;
reg1 HA_KEYSEG *keyseg;
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
DBUG_ENTER("_ma_make_key");
@@ -64,7 +64,7 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
TODO: nulls processing
*/
#ifdef HAVE_SPATIAL
- DBUG_RETURN(sp_make_key(info,keynr,key,record,filepos));
+ DBUG_RETURN(sp_make_key(info,keynr, key,record,filepos));
#else
DBUG_ASSERT(0); /* maria_open should check that this never happens*/
#endif
@@ -91,17 +91,17 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
length);
- pos= (byte*) record+keyseg->start;
+ pos= record+keyseg->start;
if (type == HA_KEYTYPE_BIT)
{
if (keyseg->bit_length)
{
uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
keyseg->bit_start, keyseg->bit_length);
- *key++= bits;
+ *key++= (char) bits;
length--;
}
- memcpy((byte*) key, pos, length);
+ memcpy(key, pos, length);
key+= length;
continue;
}
@@ -120,7 +120,7 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
}
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((byte*) key,(byte*) pos,(size_t) char_length);
+ memcpy(key, pos, (size_t) char_length);
key+=char_length;
continue;
}
@@ -133,18 +133,18 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
set_if_smaller(length,tmp_length);
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((byte*) key,(byte*) pos,(size_t) char_length);
+ memcpy(key,pos,(size_t) char_length);
key+= char_length;
continue;
}
else if (keyseg->flag & HA_BLOB_PART)
{
uint tmp_length= _ma_calc_blob_length(keyseg->bit_start,pos);
- memcpy_fixed((byte*) &pos,pos+keyseg->bit_start,sizeof(char*));
+ memcpy_fixed(&pos,pos+keyseg->bit_start,sizeof(char*));
set_if_smaller(length,tmp_length);
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((byte*) key,(byte*) pos,(size_t) char_length);
+ memcpy(key,pos,(size_t) char_length);
key+= char_length;
continue;
}
@@ -183,14 +183,14 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
continue;
}
FIX_LENGTH(cs, pos, length, char_length);
- memcpy((byte*) key, pos, char_length);
+ memcpy(key, pos, char_length);
if (length > char_length)
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
key+= length;
}
_ma_dpointer(info,key,filepos);
DBUG_PRINT("exit",("keynr: %d",keynr));
- DBUG_DUMP("key",(byte*) start,(uint) (key-start)+keyseg->length);
+ DBUG_DUMP("key",start,(uint) (key-start)+keyseg->length);
DBUG_EXECUTE("key",
_ma_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start,
(uint) (key-start)););
@@ -216,10 +216,10 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
last_use_keyseg Store pointer to the keyseg after the last used one
*/
-uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uchar *old,
- uint k_length, HA_KEYSEG **last_used_keyseg)
+uint _ma_pack_key(register MARIA_HA *info, uint keynr, byte *key,
+ const byte *old, uint k_length, HA_KEYSEG **last_used_keyseg)
{
- uchar *start_key=key;
+ byte *start_key=key;
HA_KEYSEG *keyseg;
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
DBUG_ENTER("_ma_pack_key");
@@ -231,7 +231,7 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uchar *old,
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
uint length=min((uint) keyseg->length,(uint) k_length);
uint char_length;
- uchar *pos;
+ const byte *pos;
CHARSET_INFO *cs=keyseg->charset;
if (keyseg->null_bit)
@@ -248,11 +248,12 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uchar *old,
continue; /* Found NULL */
}
}
- char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
- pos=old;
+ char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
+ length);
+ pos= old;
if (keyseg->flag & HA_SPACE_PACK)
{
- uchar *end=pos+length;
+ const byte *end= pos + length;
if (type != HA_KEYTYPE_NUM)
{
while (end > pos && end[-1] == ' ')
@@ -267,7 +268,7 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uchar *old,
length=(uint) (end-pos);
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
- memcpy((byte*) key,pos,(size_t) char_length);
+ memcpy(key,pos,(size_t) char_length);
key+= char_length;
continue;
}
@@ -281,7 +282,7 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uchar *old,
FIX_LENGTH(cs, pos, length, char_length);
store_key_length_inc(key,char_length);
old+=2; /* Skip length */
- memcpy((byte*) key, pos,(size_t) char_length);
+ memcpy(key, pos,(size_t) char_length);
key+= char_length;
continue;
}
@@ -296,7 +297,7 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uchar *old,
continue;
}
FIX_LENGTH(cs, pos, length, char_length);
- memcpy((byte*) key, pos, char_length);
+ memcpy(key, pos, char_length);
if (length > char_length)
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
key+= length;
@@ -320,7 +321,7 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key, uchar *old,
length+= keyseg->length;
keyseg++;
} while (keyseg->type);
- bzero((byte*) key,length);
+ bzero(key,length);
key+=length;
}
#endif
@@ -357,8 +358,8 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
byte *blob_ptr;
DBUG_ENTER("_ma_put_key_in_record");
- blob_ptr= (byte*) info->lastkey2; /* Place to put blob parts */
- key=(byte*) info->lastkey; /* KEy that was read */
+ blob_ptr= info->lastkey2; /* Place to put blob parts */
+ key=info->lastkey; /* KEy that was read */
key_end=key+info->lastkey_length;
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
{
@@ -377,7 +378,7 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
if (keyseg->bit_length)
{
- uchar bits= *key++;
+ byte bits= *key++;
set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
keyseg->bit_length);
length--;
@@ -387,7 +388,7 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
keyseg->bit_length);
}
- memcpy(record + keyseg->start, (byte*) key, length);
+ memcpy(record + keyseg->start, key, length);
key+= length;
continue;
}
@@ -430,7 +431,7 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
else
int2store(record+keyseg->start, length);
/* And key data */
- memcpy(record+keyseg->start + keyseg->bit_start, (byte*) key, length);
+ memcpy(record+keyseg->start + keyseg->bit_start, key, length);
key+= length;
}
else if (keyseg->flag & HA_BLOB_PART)
@@ -473,8 +474,7 @@ static int _ma_put_key_in_record(register MARIA_HA *info, uint keynr,
if (key+keyseg->length > key_end)
goto err;
#endif
- memcpy(record+keyseg->start,(byte*) key,
- (size_t) keyseg->length);
+ memcpy(record+keyseg->start, key, (size_t) keyseg->length);
key+= keyseg->length;
}
}
@@ -487,7 +487,7 @@ err:
/* Here when key reads are used */
-int _ma_read_key_record(MARIA_HA *info, my_off_t filepos, byte *buf)
+int _ma_read_key_record(MARIA_HA *info, byte *buf, MARIA_RECORD_POS filepos)
{
fast_ma_writeinfo(info);
if (filepos != HA_OFFSET_ERROR)
@@ -527,7 +527,7 @@ ulonglong ma_retrieve_auto_increment(MARIA_HA *info,const byte *record)
ulonglong value= 0; /* Store unsigned values here */
longlong s_value= 0; /* Store signed values here */
HA_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
- const uchar *key= (uchar*) record + keyseg->start;
+ const byte *key= record + keyseg->start;
switch (keyseg->type) {
case HA_KEYTYPE_INT8:
diff --git a/storage/maria/ma_keycache.c b/storage/maria/ma_keycache.c
index 4f150d905ed..64725baae86 100644
--- a/storage/maria/ma_keycache.c
+++ b/storage/maria/ma_keycache.c
@@ -54,8 +54,9 @@ int maria_assign_to_key_cache(MARIA_HA *info,
int error= 0;
MARIA_SHARE* share= info->s;
DBUG_ENTER("maria_assign_to_key_cache");
- DBUG_PRINT("enter",("old_key_cache_handle: 0x%lx new_key_cache_handle: 0x%lx",
- (long) share->key_cache, (long) key_cache));
+ DBUG_PRINT("enter",
+ ("old_key_cache_handle: 0x%lx new_key_cache_handle: 0x%lx",
+ (long) share->key_cache, (long) key_cache));
/*
Skip operation if we didn't change key cache. This can happen if we
diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c
index 848fb7e9682..6a0bbe82dcb 100644
--- a/storage/maria/ma_locking.c
+++ b/storage/maria/ma_locking.c
@@ -60,13 +60,25 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
else
count= --share->w_locks;
--share->tot_locks;
- if (info->lock_type == F_WRLCK && !share->w_locks &&
- !share->delay_key_write && flush_key_blocks(share->key_cache,
- share->kfile,FLUSH_KEEP))
+ if (info->lock_type == F_WRLCK && !share->w_locks)
{
- error=my_errno;
- maria_print_error(info->s, HA_ERR_CRASHED);
- maria_mark_crashed(info); /* Mark that table must be checked */
+ if (!share->delay_key_write && flush_key_blocks(share->key_cache,
+ share->kfile,
+ FLUSH_KEEP))
+ {
+ error= my_errno;
+ maria_print_error(info->s, HA_ERR_CRASHED);
+ /* Mark that table must be checked */
+ maria_mark_crashed(info);
+ }
+ if (share->data_file_type == BLOCK_RECORD &&
+ flush_key_blocks(share->key_cache, info->dfile, FLUSH_KEEP))
+ {
+ error= my_errno;
+ maria_print_error(info->s, HA_ERR_CRASHED);
+ /* Mark that table must be checked */
+ maria_mark_crashed(info);
+ }
}
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
@@ -84,16 +96,17 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
if (share->changed && !share->w_locks)
{
#ifdef HAVE_MMAP
- if ((info->s->mmaped_length != info->s->state.state.data_file_length) &&
- (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS))
- {
- if (info->s->concurrent_insert)
- rw_wrlock(&info->s->mmap_lock);
- _ma_remap_file(info, info->s->state.state.data_file_length);
- info->s->nonmmaped_inserts= 0;
- if (info->s->concurrent_insert)
- rw_unlock(&info->s->mmap_lock);
- }
+ if ((info->s->mmaped_length !=
+ info->s->state.state.data_file_length) &&
+ (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS))
+ {
+ if (info->s->concurrent_insert)
+ rw_wrlock(&info->s->mmap_lock);
+ _ma_remap_file(info, info->s->state.state.data_file_length);
+ info->s->nonmmaped_inserts= 0;
+ if (info->s->concurrent_insert)
+ rw_unlock(&info->s->mmap_lock);
+ }
#endif
share->state.process= share->last_process=share->this_process;
share->state.unique= info->last_unique= info->this_unique;
@@ -363,7 +376,7 @@ int _ma_readinfo(register MARIA_HA *info, int lock_type, int check_keybuffer)
int _ma_writeinfo(register MARIA_HA *info, uint operation)
{
int error,olderror;
- MARIA_SHARE *share=info->s;
+ MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_writeinfo");
DBUG_PRINT("info",("operation: %u tot_locks: %u", operation,
share->tot_locks));
@@ -371,13 +384,13 @@ int _ma_writeinfo(register MARIA_HA *info, uint operation)
error=0;
if (share->tot_locks == 0)
{
- olderror=my_errno; /* Remember last error */
if (operation)
{ /* Two threads can't be here */
+ olderror= my_errno; /* Remember last error */
share->state.process= share->last_process= share->this_process;
share->state.unique= info->last_unique= info->this_unique;
share->state.update_count= info->last_loop= ++info->this_loop;
- if ((error=_ma_state_info_write(share->kfile, &share->state, 1)))
+ if ((error= _ma_state_info_write(share->kfile, &share->state, 1)))
olderror=my_errno;
#ifdef __WIN__
if (maria_flush)
@@ -386,8 +399,8 @@ int _ma_writeinfo(register MARIA_HA *info, uint operation)
_commit(info->dfile);
}
#endif
+ my_errno=olderror;
}
- my_errno=olderror;
}
else if (operation)
share->changed= 1; /* Mark keyfile changed */
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index ab38d2baea1..19113196f15 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -19,6 +19,7 @@
#include "ma_fulltext.h"
#include "ma_sp_defs.h"
#include "ma_rt_index.h"
+#include "ma_blockrec.h"
#include <m_ctype.h>
#if defined(MSDOS) || defined(__WIN__)
@@ -33,6 +34,12 @@
#endif
static void setup_key_functions(MARIA_KEYDEF *keyinfo);
+static my_bool maria_scan_init_dummy(MARIA_HA *info);
+static void maria_scan_end_dummy(MARIA_HA *info);
+static my_bool maria_once_init_dummy(MARIA_SHARE *, File);
+static my_bool maria_once_end_dummy(MARIA_SHARE *);
+static byte *_ma_base_info_read(byte *ptr, MARIA_BASE_INFO *base);
+
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
pos+=size;}
@@ -76,7 +83,7 @@ MARIA_HA *_ma_test_if_reopen(char *filename)
MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
{
int kfile,open_mode,save_errno,have_rtree=0;
- uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
+ uint i,j,len,errpos,head_length,base_pos,info_length,keys,
key_parts,unique_key_parts,fulltext_keys,uniques;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN];
@@ -84,13 +91,13 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
MARIA_HA info,*m_info,*old_info;
MARIA_SHARE share_buff,*share;
ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG];
- my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MARIA_MAX_KEY_BLOCK_SIZE];
+ my_off_t key_root[HA_MAX_POSSIBLE_KEY];
ulonglong max_key_file_length, max_data_file_length;
DBUG_ENTER("maria_open");
LINT_INIT(m_info);
kfile= -1;
- errpos=0;
+ errpos= 0;
head_length=sizeof(share_buff.state.header);
bzero((byte*) &info,sizeof(info));
@@ -103,7 +110,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
bzero((gptr) &share_buff,sizeof(share_buff));
share_buff.state.rec_per_key_part=rec_per_key_part;
share_buff.state.key_root=key_root;
- share_buff.state.key_del=key_del;
share_buff.key_cache= multi_key_cache_search(name_buff, strlen(name_buff),
maria_key_cache);
@@ -121,7 +127,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
goto err;
}
share->mode=open_mode;
- errpos=1;
+ errpos= 1;
if (my_read(kfile,(char*) share->state.header.file_version,head_length,
MYF(MY_NABP)))
{
@@ -165,17 +171,17 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
info_length=mi_uint2korr(share->state.header.header_length);
- base_pos=mi_uint2korr(share->state.header.base_pos);
+ base_pos= mi_uint2korr(share->state.header.base_pos);
if (!(disk_cache=(char*) my_alloca(info_length+128)))
{
my_errno=ENOMEM;
goto err;
}
end_pos=disk_cache+info_length;
- errpos=2;
+ errpos= 2;
VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
- errpos=3;
+ errpos= 3;
if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
{
my_errno=HA_ERR_CRASHED;
@@ -195,15 +201,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
share->state_diff_length=len-MARIA_STATE_INFO_SIZE;
- _ma_state_info_read((uchar*) disk_cache, &share->state);
+ _ma_state_info_read(disk_cache, &share->state);
len= mi_uint2korr(share->state.header.base_info_length);
if (len != MARIA_BASE_INFO_SIZE)
{
DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d",
len,MARIA_BASE_INFO_SIZE));
}
- disk_pos= (char*)
- _ma_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);
+ disk_pos= _ma_base_info_read(disk_cache + base_pos, &share->base);
share->state.state_length=base_pos;
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
@@ -242,6 +247,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
(_ma_safe_mul(share->base.pack_reclength,
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
+
max_key_file_length=
_ma_safe_mul(MARIA_MIN_KEY_BLOCK_LENGTH,
((ulonglong) 1 << (share->base.key_reflength*8))-1);
@@ -249,25 +255,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
set_if_smaller(max_data_file_length, INT_MAX32);
set_if_smaller(max_key_file_length, INT_MAX32);
#endif
-#if USE_RAID && SYSTEM_SIZEOF_OFF_T == 4
- set_if_smaller(max_key_file_length, INT_MAX32);
- if (!share->base.raid_type)
- {
- set_if_smaller(max_data_file_length, INT_MAX32);
- }
- else
- {
- set_if_smaller(max_data_file_length,
- (ulonglong) share->base.raid_chunks << 31);
- }
-#elif !defined(USE_RAID)
- if (share->base.raid_type)
- {
- DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
- my_errno=HA_ERR_UNSUPPORTED;
- goto err;
- }
-#endif
share->base.max_data_file_length=(my_off_t) max_data_file_length;
share->base.max_key_file_length=(my_off_t) max_key_file_length;
@@ -289,29 +276,25 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
&share->index_file_name,strlen(index_name)+1,
&share->data_file_name,strlen(data_name)+1,
&share->state.key_root,keys*sizeof(my_off_t),
- &share->state.key_del,
- (share->state.header.max_block_size_index*sizeof(my_off_t)),
#ifdef THREAD
&share->key_root_lock,sizeof(rw_lock_t)*keys,
#endif
&share->mmap_lock,sizeof(rw_lock_t),
NullS))
goto err;
- errpos=4;
+ errpos= 4;
+
*share=share_buff;
memcpy((char*) share->state.rec_per_key_part,
(char*) rec_per_key_part, sizeof(long)*key_parts);
memcpy((char*) share->state.key_root,
(char*) key_root, sizeof(my_off_t)*keys);
- memcpy((char*) share->state.key_del,
- (char*) key_del, (sizeof(my_off_t) *
- share->state.header.max_block_size_index));
strmov(share->unique_file_name, name_buff);
share->unique_name_length= strlen(name_buff);
strmov(share->index_file_name, index_name);
strmov(share->data_file_name, data_name);
- share->blocksize=min(IO_SIZE,maria_block_size);
+ share->block_size= maria_block_size;
{
HA_KEYSEG *pos=share->keyparts;
for (i=0 ; i < keys ; i++)
@@ -322,7 +305,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
end_pos);
if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
have_rtree=1;
- set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
+ set_if_smaller(share->block_size,share->keyinfo[i].block_length);
share->keyinfo[i].seg=pos;
for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
{
@@ -428,28 +411,43 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
share->ftparsers= 0;
}
-
- disk_pos_assert(disk_pos + share->base.fields *MARIA_COLUMNDEF_SIZE, end_pos);
- for (i=j=offset=0 ; i < share->base.fields ; i++)
+ share->data_file_type= share->state.header.data_file_type;
+ share->base_length= (BASE_ROW_HEADER_SIZE +
+ share->base.is_nulls_extended +
+ share->base.null_bytes +
+ share->base.pack_bytes +
+ test(share->options & HA_OPTION_CHECKSUM));
+ if (share->base.transactional)
+ share->base_length+= TRANS_ROW_EXTRA_HEADER_SIZE;
+ share->base.default_rec_buff_size= max(share->base.pack_reclength,
+ share->base.max_key_length);
+ if (share->data_file_type == DYNAMIC_RECORD)
+ {
+ share->base.extra_rec_buff_size=
+ (ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER) + MARIA_SPLIT_LENGTH +
+ MARIA_REC_BUFF_OFFSET);
+ share->base.default_rec_buff_size+= share->base.extra_rec_buff_size;
+ }
+ disk_pos_assert(disk_pos + share->base.fields *MARIA_COLUMNDEF_SIZE,
+ end_pos);
+ for (i= j= 0 ; i < share->base.fields ; i++)
{
disk_pos=_ma_recinfo_read(disk_pos,&share->rec[i]);
share->rec[i].pack_type=0;
share->rec[i].huff_tree=0;
- share->rec[i].offset=offset;
if (share->rec[i].type == (int) FIELD_BLOB)
{
share->blobs[j].pack_length=
share->rec[i].length-maria_portable_sizeof_char_ptr;;
- share->blobs[j].offset=offset;
+ share->blobs[j].offset= share->rec[i].offset;
j++;
}
- offset+=share->rec[i].length;
}
share->rec[i].type=(int) FIELD_LAST; /* End marker */
if (_ma_open_datafile(&info, share, -1))
goto err;
- errpos=5;
+ errpos= 5;
share->kfile=kfile;
share->this_process=(ulong) getpid();
@@ -461,25 +459,12 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->rec_reflength=share->base.rec_reflength; /* May be changed */
share->base.margin_key_file_length=(share->base.max_key_file_length -
(keys ? MARIA_INDEX_BLOCK_MARGIN *
- share->blocksize * keys : 0));
- share->blocksize=min(IO_SIZE,maria_block_size);
- share->data_file_type=STATIC_RECORD;
- if (share->options & HA_OPTION_COMPRESS_RECORD)
- {
- share->data_file_type = COMPRESSED_RECORD;
- share->options|= HA_OPTION_READ_ONLY_DATA;
- info.s=share;
- if (_ma_read_pack_info(&info,
- (pbool)
- test(!(share->options &
- (HA_OPTION_PACK_RECORD |
- HA_OPTION_TEMP_COMPRESS_RECORD)))))
- goto err;
- }
- else if (share->options & HA_OPTION_PACK_RECORD)
- share->data_file_type = DYNAMIC_RECORD;
+ share->block_size * keys : 0));
+ share->block_size= share->base.block_size;
my_afree((gptr) disk_cache);
_ma_setup_functions(share);
+ if ((*share->once_init)(share, info.dfile))
+ goto err;
share->is_log_table= FALSE;
#ifdef THREAD
thr_lock_init(&share->lock);
@@ -499,6 +484,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
HA_OPTION_COMPRESS_RECORD |
HA_OPTION_TEMP_COMPRESS_RECORD)) ||
(open_flags & HA_OPEN_TMP_TABLE) ||
+ share->data_file_type == BLOCK_RECORD ||
have_rtree) ? 0 : 1;
if (share->concurrent_insert)
{
@@ -518,9 +504,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
my_errno=EACCES; /* Can't open in write mode */
goto err;
}
- if (_ma_open_datafile(&info, share, old_info->dfile))
+ if (share->data_file_type == BLOCK_RECORD)
+ info.dfile= share->bitmap.file;
+ else if (_ma_open_datafile(&info, share, old_info->dfile))
goto err;
- errpos=5;
+ errpos= 5;
have_rtree= old_info->maria_rtree_recursion_state != NULL;
}
@@ -536,7 +524,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
&info.maria_rtree_recursion_state,have_rtree ? 1024 : 0,
NullS))
goto err;
- errpos=6;
+ errpos= 6;
if (!have_rtree)
info.maria_rtree_recursion_state= NULL;
@@ -546,7 +534,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
info.lastkey2=info.lastkey+share->base.max_key_length;
info.s=share;
- info.lastpos= HA_OFFSET_ERROR;
+ info.cur_row.lastpos= HA_OFFSET_ERROR;
info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
info.opt_flag=READ_CHECK_USED;
info.this_unique= (ulong) info.dfile; /* Uniq number in process */
@@ -563,8 +551,12 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
info.ft1_to_ft2=0;
info.errkey= -1;
info.page_changed=1;
+ info.keyread_buff= info.buff + share->base.max_key_block_length;
+ if ((*share->init)(&info))
+ goto err;
+
pthread_mutex_lock(&share->intern_lock);
- info.read_record=share->read_record;
+ info.read_record= share->read_record;
share->reopen++;
share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
if (share->options & HA_OPTION_READ_ONLY_DATA)
@@ -576,7 +568,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
if ((open_flags & HA_OPEN_TMP_TABLE) ||
(share->options & HA_OPTION_TMP_TABLE))
{
- share->temporary=share->delay_key_write=1;
+ share->temporary= share->delay_key_write= 1;
+
share->write_flag=MYF(MY_NABP);
share->w_locks++; /* We don't have to update status */
share->tot_locks++;
@@ -586,15 +579,17 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
maria_delay_key_write)
share->delay_key_write=1;
+
info.state= &share->state.state; /* Change global values by default */
pthread_mutex_unlock(&share->intern_lock);
/* Allocate buffer for one record */
-
- /* prerequisites: bzero(info) && info->s=share; are met. */
- if (!_ma_alloc_rec_buff(&info, -1, &info.rec_buff))
+ /* prerequisites: info->rec_buffer == 0 && info->rec_buff_size == 0 */
+ if (_ma_alloc_buffer(&info.rec_buff, &info.rec_buff_size,
+ share->base.default_rec_buff_size))
goto err;
- bzero(info.rec_buff, _ma_get_rec_buff_len(&info, info.rec_buff));
+
+ bzero(info.rec_buff, share->base.default_rec_buff_size);
*m_info=info;
#ifdef THREAD
@@ -614,12 +609,15 @@ err:
_ma_report_error(save_errno, name);
switch (errpos) {
case 6:
+ (*share->end)(&info);
my_free((gptr) m_info,MYF(0));
/* fall through */
case 5:
- VOID(my_close(info.dfile,MYF(0)));
+ if (share->data_file_type != BLOCK_RECORD)
+ VOID(my_close(info.dfile,MYF(0)));
if (old_info)
break; /* Don't remove open table */
+ (*share->once_end)(share);
/* fall through */
case 4:
my_free((gptr) share,MYF(0));
@@ -642,38 +640,23 @@ err:
} /* maria_open */
-byte *_ma_alloc_rec_buff(MARIA_HA *info, ulong length, byte **buf)
-{
- uint extra;
- uint32 old_length;
- LINT_INIT(old_length);
+/*
+ Reallocate a buffer, if the current buffer is not large enough
+*/
- if (! *buf || length > (old_length=_ma_get_rec_buff_len(info, *buf)))
+my_bool _ma_alloc_buffer(byte **old_addr, my_size_t *old_size,
+ my_size_t new_size)
+{
+ if (*old_size < new_size)
{
- byte *newptr = *buf;
-
- /* to simplify initial init of info->rec_buf in maria_open and maria_extra */
- if (length == (ulong) -1)
- {
- length= max(info->s->base.pack_reclength,
- info->s->base.max_key_length);
- /* Avoid unnecessary realloc */
- if (newptr && length == old_length)
- return newptr;
- }
-
- extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
- ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER)+MARIA_SPLIT_LENGTH+
- MARIA_REC_BUFF_OFFSET : 0);
- if (extra && newptr)
- newptr-= MARIA_REC_BUFF_OFFSET;
- if (!(newptr=(byte*) my_realloc((gptr)newptr, length+extra+8,
- MYF(MY_ALLOW_ZERO_PTR))))
- return newptr;
- *((uint32 *) newptr)= (uint32) length;
- *buf= newptr+(extra ? MARIA_REC_BUFF_OFFSET : 0);
+ byte *addr;
+ if (!(addr= (byte*) my_realloc((gptr) *old_addr, new_size,
+ MYF(MY_ALLOW_ZERO_PTR))))
+ return 1;
+ *old_addr= addr;
+ *old_size= new_size;
}
- return *buf;
+ return 0;
}
@@ -690,28 +673,37 @@ ulonglong _ma_safe_mul(ulonglong a, ulonglong b)
void _ma_setup_functions(register MARIA_SHARE *share)
{
- if (share->options & HA_OPTION_COMPRESS_RECORD)
- {
+ share->once_init= maria_once_init_dummy;
+ share->once_end= maria_once_end_dummy;
+ share->init= maria_scan_init_dummy;
+ share->end= maria_scan_end_dummy;
+ share->scan_init= maria_scan_init_dummy;
+ share->scan_end= maria_scan_end_dummy;
+ share->write_record_init= _ma_write_init_default;
+ share->write_record_abort= _ma_write_abort_default;
+
+ switch (share->data_file_type) {
+ case COMPRESSED_RECORD:
share->read_record= _ma_read_pack_record;
- share->read_rnd= _ma_read_rnd_pack_record;
- if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
- share->calc_checksum=0; /* No checksum */
- else if (share->options & HA_OPTION_PACK_RECORD)
- share->calc_checksum= _ma_checksum;
- else
+ share->scan= _ma_read_rnd_pack_record;
+ share->once_init= _ma_once_init_pack_row;
+ share->once_end= _ma_once_end_pack_row;
+ /* Calculate checksum according how the original row was stored */
+ if (share->state.header.org_data_file_type == STATIC_RECORD)
share->calc_checksum= _ma_static_checksum;
- }
- else if (share->options & HA_OPTION_PACK_RECORD)
- {
+ else
+ share->calc_checksum= _ma_checksum;
+ share->calc_write_checksum= share->calc_checksum;
+ break;
+ case DYNAMIC_RECORD:
share->read_record= _ma_read_dynamic_record;
- share->read_rnd= _ma_read_rnd_dynamic_record;
+ share->scan= _ma_read_rnd_dynamic_record;
share->delete_record= _ma_delete_dynamic_record;
share->compare_record= _ma_cmp_dynamic_record;
share->compare_unique= _ma_cmp_dynamic_unique;
- share->calc_checksum= _ma_checksum;
-
+ share->calc_checksum= share->calc_write_checksum= _ma_checksum;
/* add bits used to pack data to pack_reclength for faster allocation */
- share->base.pack_reclength+= share->base.pack_bits;
+ share->base.pack_reclength+= share->base.pack_bytes;
if (share->base.blobs)
{
share->update_record= _ma_update_blob_record;
@@ -722,22 +714,42 @@ void _ma_setup_functions(register MARIA_SHARE *share)
share->write_record= _ma_write_dynamic_record;
share->update_record= _ma_update_dynamic_record;
}
- }
- else
- {
+ break;
+ case STATIC_RECORD:
share->read_record= _ma_read_static_record;
- share->read_rnd= _ma_read_rnd_static_record;
+ share->scan= _ma_read_rnd_static_record;
share->delete_record= _ma_delete_static_record;
share->compare_record= _ma_cmp_static_record;
share->update_record= _ma_update_static_record;
share->write_record= _ma_write_static_record;
share->compare_unique= _ma_cmp_static_unique;
- share->calc_checksum= _ma_static_checksum;
+ share->calc_checksum= share->calc_write_checksum= _ma_static_checksum;
+ break;
+ case BLOCK_RECORD:
+ share->once_init= _ma_once_init_block_row;
+ share->once_end= _ma_once_end_block_row;
+ share->init= _ma_init_block_row;
+ share->end= _ma_end_block_row;
+ share->write_record_init= _ma_write_init_block_record;
+ share->write_record_abort= _ma_write_abort_block_record;
+ share->scan_init= _ma_scan_init_block_record;
+ share->scan_end= _ma_scan_end_block_record;
+ share->read_record= _ma_read_block_record;
+ share->scan= _ma_scan_block_record;
+ share->delete_record= _ma_delete_block_record;
+ share->compare_record= _ma_compare_block_record;
+ share->update_record= _ma_update_block_record;
+ share->write_record= _ma_write_block_record;
+ share->compare_unique= _ma_cmp_block_unique;
+ share->calc_checksum= _ma_checksum;
+ share->calc_write_checksum= 0;
+ break;
}
share->file_read= _ma_nommap_pread;
share->file_write= _ma_nommap_pwrite;
- if (!(share->options & HA_OPTION_CHECKSUM))
- share->calc_checksum=0;
+ if (!(share->options & HA_OPTION_CHECKSUM) &&
+ share->data_file_type != COMPRESSED_RECORD)
+ share->calc_checksum= share->calc_write_checksum= 0;
return;
}
@@ -804,55 +816,53 @@ uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite)
{
uchar buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE];
uchar *ptr=buff;
- uint i, keys= (uint) state->header.keys,
- key_blocks=state->header.max_block_size_index;
+ uint i, keys= (uint) state->header.keys;
DBUG_ENTER("_ma_state_info_write");
memcpy_fixed(ptr,&state->header,sizeof(state->header));
ptr+=sizeof(state->header);
/* open_count must be first because of _ma_mark_file_changed ! */
- mi_int2store(ptr,state->open_count); ptr +=2;
- *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
- mi_rowstore(ptr,state->state.records); ptr +=8;
- mi_rowstore(ptr,state->state.del); ptr +=8;
- mi_rowstore(ptr,state->split); ptr +=8;
- mi_sizestore(ptr,state->dellink); ptr +=8;
- mi_sizestore(ptr,state->state.key_file_length); ptr +=8;
- mi_sizestore(ptr,state->state.data_file_length); ptr +=8;
- mi_sizestore(ptr,state->state.empty); ptr +=8;
- mi_sizestore(ptr,state->state.key_empty); ptr +=8;
- mi_int8store(ptr,state->auto_increment); ptr +=8;
- mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
- mi_int4store(ptr,state->process); ptr +=4;
- mi_int4store(ptr,state->unique); ptr +=4;
- mi_int4store(ptr,state->status); ptr +=4;
- mi_int4store(ptr,state->update_count); ptr +=4;
-
- ptr+=state->state_diff_length;
+ mi_int2store(ptr,state->open_count); ptr+= 2;
+ *ptr++= (uchar)state->changed;
+ *ptr++= state->sortkey;
+ mi_rowstore(ptr,state->state.records); ptr+= 8;
+ mi_rowstore(ptr,state->state.del); ptr+= 8;
+ mi_rowstore(ptr,state->split); ptr+= 8;
+ mi_sizestore(ptr,state->dellink); ptr+= 8;
+ mi_sizestore(ptr,state->first_bitmap_with_space); ptr+= 8;
+ mi_sizestore(ptr,state->state.key_file_length); ptr+= 8;
+ mi_sizestore(ptr,state->state.data_file_length); ptr+= 8;
+ mi_sizestore(ptr,state->state.empty); ptr+= 8;
+ mi_sizestore(ptr,state->state.key_empty); ptr+= 8;
+ mi_int8store(ptr,state->auto_increment); ptr+= 8;
+ mi_int8store(ptr,(ulonglong) state->state.checksum); ptr+= 8;
+ mi_int4store(ptr,state->process); ptr+= 4;
+ mi_int4store(ptr,state->unique); ptr+= 4;
+ mi_int4store(ptr,state->status); ptr+= 4;
+ mi_int4store(ptr,state->update_count); ptr+= 4;
+
+ ptr+= state->state_diff_length;
for (i=0; i < keys; i++)
{
- mi_sizestore(ptr,state->key_root[i]); ptr +=8;
- }
- for (i=0; i < key_blocks; i++)
- {
- mi_sizestore(ptr,state->key_del[i]); ptr +=8;
+ mi_sizestore(ptr,state->key_root[i]); ptr+= 8;
}
- if (pWrite & 2) /* From isamchk */
+ mi_sizestore(ptr,state->key_del); ptr+= 8;
+ if (pWrite & 2) /* From maria_chk */
{
uint key_parts= mi_uint2korr(state->header.key_parts);
- mi_int4store(ptr,state->sec_index_changed); ptr +=4;
- mi_int4store(ptr,state->sec_index_used); ptr +=4;
- mi_int4store(ptr,state->version); ptr +=4;
- mi_int8store(ptr,state->key_map); ptr +=8;
- mi_int8store(ptr,(ulonglong) state->create_time); ptr +=8;
- mi_int8store(ptr,(ulonglong) state->recover_time); ptr +=8;
- mi_int8store(ptr,(ulonglong) state->check_time); ptr +=8;
- mi_sizestore(ptr,state->rec_per_key_rows); ptr+=8;
+ mi_int4store(ptr,state->sec_index_changed); ptr+= 4;
+ mi_int4store(ptr,state->sec_index_used); ptr+= 4;
+ mi_int4store(ptr,state->version); ptr+= 4;
+ mi_int8store(ptr,state->key_map); ptr+= 8;
+ mi_int8store(ptr,(ulonglong) state->create_time); ptr+= 8;
+ mi_int8store(ptr,(ulonglong) state->recover_time); ptr+= 8;
+ mi_int8store(ptr,(ulonglong) state->check_time); ptr+= 8;
+ mi_sizestore(ptr,state->rec_per_key_rows); ptr+= 8;
for (i=0 ; i < key_parts ; i++)
{
- mi_int4store(ptr,state->rec_per_key_part[i]); ptr+=4;
+ mi_int4store(ptr,state->rec_per_key_part[i]); ptr+=4;
}
}
@@ -864,54 +874,51 @@ uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite)
}
-uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
+byte *_ma_state_info_read(byte *ptr, MARIA_STATE_INFO *state)
{
- uint i,keys,key_parts,key_blocks;
+ uint i,keys,key_parts;
memcpy_fixed(&state->header,ptr, sizeof(state->header));
- ptr +=sizeof(state->header);
- keys=(uint) state->header.keys;
- key_parts=mi_uint2korr(state->header.key_parts);
- key_blocks=state->header.max_block_size_index;
-
- state->open_count = mi_uint2korr(ptr); ptr +=2;
- state->changed= (bool) *ptr++;
- state->sortkey = (uint) *ptr++;
- state->state.records= mi_rowkorr(ptr); ptr +=8;
- state->state.del = mi_rowkorr(ptr); ptr +=8;
- state->split = mi_rowkorr(ptr); ptr +=8;
- state->dellink= mi_sizekorr(ptr); ptr +=8;
- state->state.key_file_length = mi_sizekorr(ptr); ptr +=8;
- state->state.data_file_length= mi_sizekorr(ptr); ptr +=8;
- state->state.empty = mi_sizekorr(ptr); ptr +=8;
- state->state.key_empty= mi_sizekorr(ptr); ptr +=8;
- state->auto_increment=mi_uint8korr(ptr); ptr +=8;
- state->state.checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
- state->process= mi_uint4korr(ptr); ptr +=4;
- state->unique = mi_uint4korr(ptr); ptr +=4;
- state->status = mi_uint4korr(ptr); ptr +=4;
- state->update_count=mi_uint4korr(ptr); ptr +=4;
+ ptr+= sizeof(state->header);
+ keys= (uint) state->header.keys;
+ key_parts= mi_uint2korr(state->header.key_parts);
+
+ state->open_count = mi_uint2korr(ptr); ptr+= 2;
+ state->changed= (my_bool) *ptr++;
+ state->sortkey= (uint) *ptr++;
+ state->state.records= mi_rowkorr(ptr); ptr+= 8;
+ state->state.del = mi_rowkorr(ptr); ptr+= 8;
+ state->split = mi_rowkorr(ptr); ptr+= 8;
+ state->dellink= mi_sizekorr(ptr); ptr+= 8;
+ state->first_bitmap_with_space= mi_sizekorr(ptr); ptr+= 8;
+ state->state.key_file_length = mi_sizekorr(ptr); ptr+= 8;
+ state->state.data_file_length= mi_sizekorr(ptr); ptr+= 8;
+ state->state.empty = mi_sizekorr(ptr); ptr+= 8;
+ state->state.key_empty= mi_sizekorr(ptr); ptr+= 8;
+ state->auto_increment=mi_uint8korr(ptr); ptr+= 8;
+ state->state.checksum=(ha_checksum) mi_uint8korr(ptr);ptr+= 8;
+ state->process= mi_uint4korr(ptr); ptr+= 4;
+ state->unique = mi_uint4korr(ptr); ptr+= 4;
+ state->status = mi_uint4korr(ptr); ptr+= 4;
+ state->update_count=mi_uint4korr(ptr); ptr+= 4;
ptr+= state->state_diff_length;
for (i=0; i < keys; i++)
{
- state->key_root[i]= mi_sizekorr(ptr); ptr +=8;
- }
- for (i=0; i < key_blocks; i++)
- {
- state->key_del[i] = mi_sizekorr(ptr); ptr +=8;
+ state->key_root[i]= mi_sizekorr(ptr); ptr+= 8;
}
- state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
- state->sec_index_used = mi_uint4korr(ptr); ptr +=4;
- state->version = mi_uint4korr(ptr); ptr +=4;
- state->key_map = mi_uint8korr(ptr); ptr +=8;
- state->create_time = (time_t) mi_sizekorr(ptr); ptr +=8;
- state->recover_time =(time_t) mi_sizekorr(ptr); ptr +=8;
- state->check_time = (time_t) mi_sizekorr(ptr); ptr +=8;
- state->rec_per_key_rows=mi_sizekorr(ptr); ptr +=8;
+ state->key_del= mi_sizekorr(ptr); ptr+= 8;
+ state->sec_index_changed = mi_uint4korr(ptr); ptr+= 4;
+ state->sec_index_used = mi_uint4korr(ptr); ptr+= 4;
+ state->version = mi_uint4korr(ptr); ptr+= 4;
+ state->key_map = mi_uint8korr(ptr); ptr+= 8;
+ state->create_time = (time_t) mi_sizekorr(ptr); ptr+= 8;
+ state->recover_time =(time_t) mi_sizekorr(ptr); ptr+= 8;
+ state->check_time = (time_t) mi_sizekorr(ptr); ptr+= 8;
+ state->rec_per_key_rows=mi_sizekorr(ptr); ptr+= 8;
for (i=0 ; i < key_parts ; i++)
{
- state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4;
+ state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4;
}
return ptr;
}
@@ -930,7 +937,7 @@ uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state, my_bool pRead)
}
else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
return (MY_FILE_ERROR);
- _ma_state_info_read((uchar*) buff, state);
+ _ma_state_info_read(buff, state);
}
return 0;
}
@@ -944,74 +951,84 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
{
uchar buff[MARIA_BASE_INFO_SIZE], *ptr=buff;
- mi_sizestore(ptr,base->keystart); ptr +=8;
- mi_sizestore(ptr,base->max_data_file_length); ptr +=8;
- mi_sizestore(ptr,base->max_key_file_length); ptr +=8;
- mi_rowstore(ptr,base->records); ptr +=8;
- mi_rowstore(ptr,base->reloc); ptr +=8;
- mi_int4store(ptr,base->mean_row_length); ptr +=4;
- mi_int4store(ptr,base->reclength); ptr +=4;
- mi_int4store(ptr,base->pack_reclength); ptr +=4;
- mi_int4store(ptr,base->min_pack_length); ptr +=4;
- mi_int4store(ptr,base->max_pack_length); ptr +=4;
- mi_int4store(ptr,base->min_block_length); ptr +=4;
- mi_int4store(ptr,base->fields); ptr +=4;
- mi_int4store(ptr,base->pack_fields); ptr +=4;
- *ptr++=base->rec_reflength;
- *ptr++=base->key_reflength;
- *ptr++=base->keys;
- *ptr++=base->auto_key;
- mi_int2store(ptr,base->pack_bits); ptr +=2;
- mi_int2store(ptr,base->blobs); ptr +=2;
- mi_int2store(ptr,base->max_key_block_length); ptr +=2;
- mi_int2store(ptr,base->max_key_length); ptr +=2;
- mi_int2store(ptr,base->extra_alloc_bytes); ptr +=2;
+ mi_sizestore(ptr,base->keystart); ptr+= 8;
+ mi_sizestore(ptr,base->max_data_file_length); ptr+= 8;
+ mi_sizestore(ptr,base->max_key_file_length); ptr+= 8;
+ mi_rowstore(ptr,base->records); ptr+= 8;
+ mi_rowstore(ptr,base->reloc); ptr+= 8;
+ mi_int4store(ptr,base->mean_row_length); ptr+= 4;
+ mi_int4store(ptr,base->reclength); ptr+= 4;
+ mi_int4store(ptr,base->pack_reclength); ptr+= 4;
+ mi_int4store(ptr,base->min_pack_length); ptr+= 4;
+ mi_int4store(ptr,base->max_pack_length); ptr+= 4;
+ mi_int4store(ptr,base->min_block_length); ptr+= 4;
+ mi_int2store(ptr,base->fields); ptr+= 2;
+ mi_int2store(ptr,base->fixed_not_null_fields); ptr+= 2;
+ mi_int2store(ptr,base->fixed_not_null_fields_length); ptr+= 2;
+ mi_int2store(ptr,base->max_field_lengths); ptr+= 2;
+ mi_int2store(ptr,base->pack_fields); ptr+= 2;
+ mi_int2store(ptr,0); ptr+= 2;
+ mi_int2store(ptr,base->null_bytes); ptr+= 2;
+ mi_int2store(ptr,base->original_null_bytes); ptr+= 2;
+ mi_int2store(ptr,base->field_offsets); ptr+= 2;
+ mi_int2store(ptr,base->min_row_length); ptr+= 2;
+ mi_int2store(ptr,base->block_size); ptr+= 2;
+ *ptr++= base->rec_reflength;
+ *ptr++= base->key_reflength;
+ *ptr++= base->keys;
+ *ptr++= base->auto_key;
+ *ptr++= base->transactional;
+ *ptr++= 0; /* Reserved */
+ mi_int2store(ptr,base->pack_bytes); ptr+= 2;
+ mi_int2store(ptr,base->blobs); ptr+= 2;
+ mi_int2store(ptr,base->max_key_block_length); ptr+= 2;
+ mi_int2store(ptr,base->max_key_length); ptr+= 2;
+ mi_int2store(ptr,base->extra_alloc_bytes); ptr+= 2;
*ptr++= base->extra_alloc_procent;
- *ptr++= base->raid_type;
- mi_int2store(ptr,base->raid_chunks); ptr +=2;
- mi_int4store(ptr,base->raid_chunksize); ptr +=4;
- bzero(ptr,6); ptr +=6; /* extra */
+ bzero(ptr,16); ptr+= 16; /* extra */
+ DBUG_ASSERT((ptr - buff) == MARIA_BASE_INFO_SIZE);
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
}
-uchar *_ma_n_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
+static byte *_ma_base_info_read(byte *ptr, MARIA_BASE_INFO *base)
{
- base->keystart = mi_sizekorr(ptr); ptr +=8;
- base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
- base->max_key_file_length = mi_sizekorr(ptr); ptr +=8;
- base->records = (ha_rows) mi_sizekorr(ptr); ptr +=8;
- base->reloc = (ha_rows) mi_sizekorr(ptr); ptr +=8;
- base->mean_row_length = mi_uint4korr(ptr); ptr +=4;
- base->reclength = mi_uint4korr(ptr); ptr +=4;
- base->pack_reclength = mi_uint4korr(ptr); ptr +=4;
- base->min_pack_length = mi_uint4korr(ptr); ptr +=4;
- base->max_pack_length = mi_uint4korr(ptr); ptr +=4;
- base->min_block_length = mi_uint4korr(ptr); ptr +=4;
- base->fields = mi_uint4korr(ptr); ptr +=4;
- base->pack_fields = mi_uint4korr(ptr); ptr +=4;
-
- base->rec_reflength = *ptr++;
- base->key_reflength = *ptr++;
- base->keys= *ptr++;
- base->auto_key= *ptr++;
- base->pack_bits = mi_uint2korr(ptr); ptr +=2;
- base->blobs = mi_uint2korr(ptr); ptr +=2;
- base->max_key_block_length= mi_uint2korr(ptr); ptr +=2;
- base->max_key_length = mi_uint2korr(ptr); ptr +=2;
- base->extra_alloc_bytes = mi_uint2korr(ptr); ptr +=2;
- base->extra_alloc_procent = *ptr++;
- base->raid_type= *ptr++;
- base->raid_chunks= mi_uint2korr(ptr); ptr +=2;
- base->raid_chunksize= mi_uint4korr(ptr); ptr +=4;
- /* TO BE REMOVED: Fix for old RAID files */
- if (base->raid_type == 0)
- {
- base->raid_chunks=0;
- base->raid_chunksize=0;
- }
-
- ptr+=6;
+ base->keystart= mi_sizekorr(ptr); ptr+= 8;
+ base->max_data_file_length= mi_sizekorr(ptr); ptr+= 8;
+ base->max_key_file_length= mi_sizekorr(ptr); ptr+= 8;
+ base->records= (ha_rows) mi_sizekorr(ptr); ptr+= 8;
+ base->reloc= (ha_rows) mi_sizekorr(ptr); ptr+= 8;
+ base->mean_row_length= mi_uint4korr(ptr); ptr+= 4;
+ base->reclength= mi_uint4korr(ptr); ptr+= 4;
+ base->pack_reclength= mi_uint4korr(ptr); ptr+= 4;
+ base->min_pack_length= mi_uint4korr(ptr); ptr+= 4;
+ base->max_pack_length= mi_uint4korr(ptr); ptr+= 4;
+ base->min_block_length= mi_uint4korr(ptr); ptr+= 4;
+ base->fields= mi_uint2korr(ptr); ptr+= 2;
+ base->fixed_not_null_fields= mi_uint2korr(ptr); ptr+= 2;
+ base->fixed_not_null_fields_length= mi_uint2korr(ptr);ptr+= 2;
+ base->max_field_lengths= mi_uint2korr(ptr); ptr+= 2;
+ base->pack_fields= mi_uint2korr(ptr); ptr+= 2;
+ ptr+= 2;
+ base->null_bytes= mi_uint2korr(ptr); ptr+= 2;
+ base->original_null_bytes= mi_uint2korr(ptr); ptr+= 2;
+ base->field_offsets= mi_uint2korr(ptr); ptr+= 2;
+ base->min_row_length= mi_uint2korr(ptr); ptr+= 2;
+ base->block_size= mi_uint2korr(ptr); ptr+= 2;
+
+ base->rec_reflength= *ptr++;
+ base->key_reflength= *ptr++;
+ base->keys= *ptr++;
+ base->auto_key= *ptr++;
+ base->transactional= *ptr++;
+ ptr++;
+ base->pack_bytes= mi_uint2korr(ptr); ptr+= 2;
+ base->blobs= mi_uint2korr(ptr); ptr+= 2;
+ base->max_key_block_length= mi_uint2korr(ptr); ptr+= 2;
+ base->max_key_length= mi_uint2korr(ptr); ptr+= 2;
+ base->extra_alloc_bytes= mi_uint2korr(ptr); ptr+= 2;
+ base->extra_alloc_procent= *ptr++;
+ ptr+= 16;
return ptr;
}
@@ -1024,13 +1041,13 @@ uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef)
uchar buff[MARIA_KEYDEF_SIZE];
uchar *ptr=buff;
- *ptr++ = (uchar) keydef->keysegs;
- *ptr++ = keydef->key_alg; /* Rtree or Btree */
- mi_int2store(ptr,keydef->flag); ptr +=2;
- mi_int2store(ptr,keydef->block_length); ptr +=2;
- mi_int2store(ptr,keydef->keylength); ptr +=2;
- mi_int2store(ptr,keydef->minlength); ptr +=2;
- mi_int2store(ptr,keydef->maxlength); ptr +=2;
+ *ptr++= (uchar) keydef->keysegs;
+ *ptr++= keydef->key_alg; /* Rtree or Btree */
+ mi_int2store(ptr,keydef->flag); ptr+= 2;
+ mi_int2store(ptr,keydef->block_length); ptr+= 2;
+ mi_int2store(ptr,keydef->keylength); ptr+= 2;
+ mi_int2store(ptr,keydef->minlength); ptr+= 2;
+ mi_int2store(ptr,keydef->maxlength); ptr+= 2;
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
}
@@ -1039,12 +1056,11 @@ char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef)
keydef->keysegs = (uint) *ptr++;
keydef->key_alg = *ptr++; /* Rtree or Btree */
- keydef->flag = mi_uint2korr(ptr); ptr +=2;
- keydef->block_length = mi_uint2korr(ptr); ptr +=2;
- keydef->keylength = mi_uint2korr(ptr); ptr +=2;
- keydef->minlength = mi_uint2korr(ptr); ptr +=2;
- keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
- keydef->block_size_index = keydef->block_length/MARIA_MIN_KEY_BLOCK_LENGTH-1;
+ keydef->flag = mi_uint2korr(ptr); ptr+= 2;
+ keydef->block_length = mi_uint2korr(ptr); ptr+= 2;
+ keydef->keylength = mi_uint2korr(ptr); ptr+= 2;
+ keydef->minlength = mi_uint2korr(ptr); ptr+= 2;
+ keydef->maxlength = mi_uint2korr(ptr); ptr+= 2;
keydef->underflow_block_length=keydef->block_length/3;
keydef->version = 0; /* Not saved */
keydef->parser = &ft_default_parser;
@@ -1068,9 +1084,9 @@ int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg)
*ptr++= keyseg->bit_start;
*ptr++= keyseg->bit_end;
*ptr++= keyseg->bit_length;
- mi_int2store(ptr,keyseg->flag); ptr+=2;
- mi_int2store(ptr,keyseg->length); ptr+=2;
- mi_int4store(ptr,keyseg->start); ptr+=4;
+ mi_int2store(ptr,keyseg->flag); ptr+= 2;
+ mi_int2store(ptr,keyseg->length); ptr+= 2;
+ mi_int4store(ptr,keyseg->start); ptr+= 4;
pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
mi_int4store(ptr, pos);
ptr+=4;
@@ -1087,10 +1103,10 @@ char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg)
keyseg->bit_start = *ptr++;
keyseg->bit_end = *ptr++;
keyseg->bit_length = *ptr++;
- keyseg->flag = mi_uint2korr(ptr); ptr +=2;
- keyseg->length = mi_uint2korr(ptr); ptr +=2;
- keyseg->start = mi_uint4korr(ptr); ptr +=4;
- keyseg->null_pos = mi_uint4korr(ptr); ptr +=4;
+ keyseg->flag = mi_uint2korr(ptr); ptr+= 2;
+ keyseg->length = mi_uint2korr(ptr); ptr+= 2;
+ keyseg->start = mi_uint4korr(ptr); ptr+= 4;
+ keyseg->null_pos = mi_uint4korr(ptr); ptr+= 4;
keyseg->charset=0; /* Will be filled in later */
if (keyseg->null_bit)
keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
@@ -1135,47 +1151,44 @@ uint _ma_recinfo_write(File file, MARIA_COLUMNDEF *recinfo)
uchar buff[MARIA_COLUMNDEF_SIZE];
uchar *ptr=buff;
- mi_int2store(ptr,recinfo->type); ptr +=2;
- mi_int2store(ptr,recinfo->length); ptr +=2;
- *ptr++ = recinfo->null_bit;
- mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
+ mi_int6store(ptr,recinfo->offset); ptr+= 6;
+ mi_int2store(ptr,recinfo->type); ptr+= 2;
+ mi_int2store(ptr,recinfo->length); ptr+= 2;
+ mi_int2store(ptr,recinfo->fill_length); ptr+= 2;
+ mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
+ mi_int2store(ptr,recinfo->empty_pos); ptr+= 2;
+ (*ptr++)= recinfo->null_bit;
+ (*ptr++)= recinfo->empty_bit;
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
}
char *_ma_recinfo_read(char *ptr, MARIA_COLUMNDEF *recinfo)
{
- recinfo->type= mi_sint2korr(ptr); ptr +=2;
- recinfo->length=mi_uint2korr(ptr); ptr +=2;
- recinfo->null_bit= (uint8) *ptr++;
- recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
- return ptr;
+ recinfo->offset= mi_uint6korr(ptr); ptr+= 6;
+ recinfo->type= mi_sint2korr(ptr); ptr+= 2;
+ recinfo->length= mi_uint2korr(ptr); ptr+= 2;
+ recinfo->fill_length= mi_uint2korr(ptr); ptr+= 2;
+ recinfo->null_pos= mi_uint2korr(ptr); ptr+= 2;
+ recinfo->empty_pos= mi_uint2korr(ptr); ptr+= 2;
+ recinfo->null_bit= (uint8) *ptr++;
+ recinfo->empty_bit= (uint8) *ptr++;
+ return ptr;
}
/**************************************************************************
-Open data file with or without RAID
-We can't use dup() here as the data file descriptors need to have different
-active seek-positions.
+ Open data file
+ We can't use dup() here as the data file descriptors need to have different
+ active seek-positions.
-The argument file_to_dup is here for the future if there would on some OS
-exist a dup()-like call that would give us two different file descriptors.
+ The argument file_to_dup is here for the future if there would on some OS
+ exist a dup()-like call that would give us two different file descriptors.
*************************************************************************/
-int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, File file_to_dup __attribute__((unused)))
+int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share,
+ File file_to_dup __attribute__((unused)))
{
-#ifdef USE_RAID
- if (share->base.raid_type)
- {
- info->dfile=my_raid_open(share->data_file_name,
- share->mode | O_SHARE,
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize,
- MYF(MY_WME | MY_RAID));
- }
- else
-#endif
- info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
- MYF(MY_WME));
+ info->dfile= my_open(share->data_file_name, share->mode | O_SHARE,
+ MYF(MY_WME));
return info->dfile >= 0 ? 0 : 1;
}
@@ -1287,3 +1300,25 @@ int maria_indexes_are_disabled(MARIA_HA *info)
*/
return 2;
}
+
+
+static my_bool maria_scan_init_dummy(MARIA_HA *info __attribute__((unused)))
+{
+ return 0;
+}
+
+static void maria_scan_end_dummy(MARIA_HA *info __attribute__((unused)))
+{
+}
+
+static my_bool maria_once_init_dummy(MARIA_SHARE *share
+ __attribute__((unused)),
+ File dfile __attribute__((unused)))
+{
+ return 0;
+}
+
+static my_bool maria_once_end_dummy(MARIA_SHARE *share __attribute__((unused)))
+{
+ return 0;
+}
diff --git a/storage/maria/ma_packrec.c b/storage/maria/ma_packrec.c
index c29cf1a672a..6e481c0bc6d 100644
--- a/storage/maria/ma_packrec.c
+++ b/storage/maria/ma_packrec.c
@@ -44,7 +44,10 @@
#define OFFSET_TABLE_SIZE 512
-static uint read_huff_table(MARIA_BIT_BUFF *bit_buff,MARIA_DECODE_TREE *decode_tree,
+static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
+ pbool fix_keys);
+static uint read_huff_table(MARIA_BIT_BUFF *bit_buff,
+ MARIA_DECODE_TREE *decode_tree,
uint16 **decode_table,byte **intervall_buff,
uint16 *tmp_buff);
static void make_quick_table(uint16 *to_table,uint16 *decode_table,
@@ -56,56 +59,64 @@ static uint copy_decode_table(uint16 *to_pos,uint offset,
uint16 *decode_table);
static uint find_longest_bitstream(uint16 *table, uint16 *end);
static void (*get_unpack_function(MARIA_COLUMNDEF *rec))(MARIA_COLUMNDEF *field,
- MARIA_BIT_BUFF *buff,
- uchar *to,
- uchar *end);
-static void uf_zerofill_skip_zero(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ MARIA_BIT_BUFF *buff,
+ byte *to,
+ byte *end);
+static void uf_zerofill_skip_zero(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to,byte *end);
static void uf_skip_zero(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_space_normal(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
-static void uf_space_endspace_selected(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end);
+ byte *to,byte *end);
+static void uf_space_endspace_selected(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end);
static void uf_endspace_selected(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_space_endspace(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_endspace(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
-static void uf_space_prespace_selected(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end);
+ byte *to,byte *end);
+static void uf_space_prespace_selected(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end);
static void uf_prespace_selected(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_space_prespace(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_prespace(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_zerofill_normal(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_constant(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_intervall(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_zero(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
+ byte *to,byte *end);
static void uf_blob(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end);
+ byte *to, byte *end);
static void uf_varchar1(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end);
+ byte *to, byte *end);
static void uf_varchar2(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end);
+ byte *to, byte *end);
static void decode_bytes(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
- uchar *to,uchar *end);
-static uint decode_pos(MARIA_BIT_BUFF *bit_buff,MARIA_DECODE_TREE *decode_tree);
-static void init_bit_buffer(MARIA_BIT_BUFF *bit_buff,uchar *buffer,uint length);
+ byte *to,byte *end);
+static uint decode_pos(MARIA_BIT_BUFF *bit_buff,
+ MARIA_DECODE_TREE *decode_tree);
+static void init_bit_buffer(MARIA_BIT_BUFF *bit_buff,uchar *buffer,
+ uint length);
static uint fill_and_get_bits(MARIA_BIT_BUFF *bit_buff,uint count);
static void fill_buffer(MARIA_BIT_BUFF *bit_buff);
static uint max_bit(uint value);
static uint read_pack_length(uint version, const uchar *buf, ulong *length);
#ifdef HAVE_MMAP
-static uchar *_ma_mempack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
- MARIA_BLOCK_INFO *info, byte **rec_buff_p,
+static uchar *_ma_mempack_get_block_info(MARIA_HA *maria,
+ MARIA_BIT_BUFF *bit_buff,
+ MARIA_BLOCK_INFO *info,
+ byte **rec_buff_p,
+ my_size_t *rec_buff_size_p,
uchar *header);
#endif
@@ -122,21 +133,43 @@ static maria_bit_type mask[]=
0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
#endif
- };
+};
- /* Read all packed info, allocate memory and fix field structs */
+my_bool _ma_once_init_pack_row(MARIA_SHARE *share, File dfile)
+{
+ share->options|= HA_OPTION_READ_ONLY_DATA;
+ if (_ma_read_pack_info(share, dfile,
+ (pbool)
+ test(!(share->options &
+ (HA_OPTION_PACK_RECORD |
+ HA_OPTION_TEMP_COMPRESS_RECORD)))))
+ return 1;
+ return 0;
+}
-my_bool _ma_read_pack_info(MARIA_HA *info, pbool fix_keys)
+my_bool _ma_once_end_pack_row(MARIA_SHARE *share)
+{
+ if (share->decode_trees)
+ {
+ my_free((gptr) share->decode_trees,MYF(0));
+ my_free((gptr) share->decode_tables,MYF(0));
+ }
+ return 0;
+}
+
+
+/* Read all packed info, allocate memory and fix field structs */
+
+static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
+ pbool fix_keys)
{
- File file;
int diff_length;
uint i,trees,huff_tree_bits,rec_reflength,length;
uint16 *decode_table,*tmp_buff;
ulong elements,intervall_length;
char *disk_cache,*intervall_buff;
uchar header[32];
- MARIA_SHARE *share=info->s;
MARIA_BIT_BUFF bit_buff;
DBUG_ENTER("_ma_read_pack_info");
@@ -145,7 +178,6 @@ my_bool _ma_read_pack_info(MARIA_HA *info, pbool fix_keys)
else if (maria_quick_table_bits > MAX_QUICK_TABLE_BITS)
maria_quick_table_bits=MAX_QUICK_TABLE_BITS;
- file=info->dfile;
my_errno=0;
if (my_read(file,(byte*) header,sizeof(header),MYF(MY_NABP)))
{
@@ -207,7 +239,7 @@ my_bool _ma_read_pack_info(MARIA_HA *info, pbool fix_keys)
share->rec[i].space_length_bits=get_bits(&bit_buff,5);
share->rec[i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff,
huff_tree_bits);
- share->rec[i].unpack=get_unpack_function(share->rec+i);
+ share->rec[i].unpack= get_unpack_function(share->rec+i);
}
skip_to_next_byte(&bit_buff);
decode_table=share->decode_tables;
@@ -266,7 +298,8 @@ err0:
/* Read on huff-code-table from datafile */
-static uint read_huff_table(MARIA_BIT_BUFF *bit_buff, MARIA_DECODE_TREE *decode_tree,
+static uint read_huff_table(MARIA_BIT_BUFF *bit_buff,
+ MARIA_DECODE_TREE *decode_tree,
uint16 **decode_table, byte **intervall_buff,
uint16 *tmp_buff)
{
@@ -441,7 +474,7 @@ static uint find_longest_bitstream(uint16 *table, uint16 *end)
HA_ERR_WRONG_IN_RECORD or -1 on error
*/
-int _ma_read_pack_record(MARIA_HA *info, my_off_t filepos, byte *buf)
+int _ma_read_pack_record(MARIA_HA *info, byte *buf, MARIA_RECORD_POS filepos)
{
MARIA_BLOCK_INFO block_info;
File file;
@@ -452,7 +485,8 @@ int _ma_read_pack_record(MARIA_HA *info, my_off_t filepos, byte *buf)
file=info->dfile;
if (_ma_pack_get_block_info(info, &info->bit_buff, &block_info,
- &info->rec_buff, file, filepos))
+ &info->rec_buff, &info->rec_buff_size, file,
+ filepos))
goto err;
if (my_read(file,(byte*) info->rec_buff + block_info.offset ,
block_info.rec_len - block_info.offset, MYF(MY_NABP)))
@@ -477,15 +511,20 @@ int _ma_pack_rec_unpack(register MARIA_HA *info, MARIA_BIT_BUFF *bit_buff,
MARIA_SHARE *share=info->s;
DBUG_ENTER("_ma_pack_rec_unpack");
+ if (info->s->base.null_bytes)
+ {
+ memcpy(to, from, info->s->base.null_bytes);
+ to+= info->s->base.null_bytes;
+ from+= info->s->base.null_bytes;
+ reclength-= info->s->base.null_bytes;
+ }
init_bit_buffer(bit_buff, (uchar*) from, reclength);
-
for (current_field=share->rec, end=current_field+share->base.fields ;
current_field < end ;
current_field++,to=end_field)
{
end_field=to+current_field->length;
- (*current_field->unpack)(current_field, bit_buff, (uchar*) to,
- (uchar*) end_field);
+ (*current_field->unpack)(current_field, bit_buff, to, end_field);
}
if (!bit_buff->error &&
bit_buff->pos - bit_buff->bits / 8 == bit_buff->end)
@@ -498,7 +537,7 @@ int _ma_pack_rec_unpack(register MARIA_HA *info, MARIA_BIT_BUFF *bit_buff,
/* Return function to unpack field */
static void (*get_unpack_function(MARIA_COLUMNDEF *rec))
-(MARIA_COLUMNDEF *, MARIA_BIT_BUFF *, uchar *, uchar *)
+ (MARIA_COLUMNDEF *, MARIA_BIT_BUFF *, byte *, byte *)
{
switch (rec->base_type) {
case FIELD_SKIP_ZERO:
@@ -552,8 +591,9 @@ static void (*get_unpack_function(MARIA_COLUMNDEF *rec))
/* The different functions to unpack a field */
-static void uf_zerofill_skip_zero(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end)
+static void uf_zerofill_skip_zero(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
if (get_bit(bit_buff))
bzero((char*) to,(uint) (end-to));
@@ -565,8 +605,8 @@ static void uf_zerofill_skip_zero(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff
}
}
-static void uf_skip_zero(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_skip_zero(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
if (get_bit(bit_buff))
bzero((char*) to,(uint) (end-to));
@@ -574,8 +614,8 @@ static void uf_skip_zero(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *
decode_bytes(rec,bit_buff,to,end);
}
-static void uf_space_normal(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_space_normal(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
if (get_bit(bit_buff))
bfill((byte*) to,(end-to),' ');
@@ -583,8 +623,9 @@ static void uf_space_normal(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, ucha
decode_bytes(rec,bit_buff,to,end);
}
-static void uf_space_endspace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end)
+static void uf_space_endspace_selected(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if (get_bit(bit_buff))
@@ -607,8 +648,9 @@ static void uf_space_endspace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit
}
}
-static void uf_endspace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end)
+static void uf_endspace_selected(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if (get_bit(bit_buff))
@@ -626,8 +668,8 @@ static void uf_endspace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
decode_bytes(rec,bit_buff,to,end);
}
-static void uf_space_endspace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_space_endspace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if (get_bit(bit_buff))
@@ -645,8 +687,8 @@ static void uf_space_endspace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uc
}
}
-static void uf_endspace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_endspace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
@@ -659,8 +701,9 @@ static void uf_endspace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *t
bfill((byte*) end-spaces,spaces,' ');
}
-static void uf_space_prespace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end)
+static void uf_space_prespace_selected(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if (get_bit(bit_buff))
@@ -684,8 +727,9 @@ static void uf_space_prespace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit
}
-static void uf_prespace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end)
+static void uf_prespace_selected(MARIA_COLUMNDEF *rec,
+ MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if (get_bit(bit_buff))
@@ -704,8 +748,8 @@ static void uf_prespace_selected(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
}
-static void uf_space_prespace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_space_prespace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if (get_bit(bit_buff))
@@ -723,8 +767,8 @@ static void uf_space_prespace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uc
}
}
-static void uf_prespace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_prespace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
uint spaces;
if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
@@ -737,24 +781,24 @@ static void uf_prespace(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *t
decode_bytes(rec,bit_buff,to+spaces,end);
}
-static void uf_zerofill_normal(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_zerofill_normal(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
end-=rec->space_length_bits;
- decode_bytes(rec,bit_buff,(uchar*) to,end);
+ decode_bytes(rec,bit_buff, to, end);
bzero((char*) end,rec->space_length_bits);
}
static void uf_constant(MARIA_COLUMNDEF *rec,
MARIA_BIT_BUFF *bit_buff __attribute__((unused)),
- uchar *to,
- uchar *end)
+ byte *to, byte *end)
{
memcpy(to,rec->huff_tree->intervalls,(size_t) (end-to));
}
-static void uf_intervall(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void uf_intervall(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to,
+ byte *end)
{
reg1 uint field_length=(uint) (end-to);
memcpy(to,rec->huff_tree->intervalls+field_length*decode_pos(bit_buff,
@@ -766,16 +810,16 @@ static void uf_intervall(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *
/*ARGSUSED*/
static void uf_zero(MARIA_COLUMNDEF *rec __attribute__((unused)),
MARIA_BIT_BUFF *bit_buff __attribute__((unused)),
- uchar *to, uchar *end)
+ byte *to, byte *end)
{
- bzero((char*) to,(uint) (end-to));
+ bzero(to, (uint) (end-to));
}
static void uf_blob(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end)
+ byte *to, byte *end)
{
if (get_bit(bit_buff))
- bzero((byte*) to,(end-to));
+ bzero(to, (uint) (end-to));
else
{
ulong length=get_bits(bit_buff,rec->space_length_bits);
@@ -786,7 +830,8 @@ static void uf_blob(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
bzero((byte*) to,(end-to));
return;
}
- decode_bytes(rec,bit_buff,bit_buff->blob_pos,bit_buff->blob_pos+length);
+ decode_bytes(rec,bit_buff,(byte*) bit_buff->blob_pos,
+ (byte*) bit_buff->blob_pos+length);
_ma_store_blob_length((byte*) to,pack_length,length);
memcpy_fixed((char*) to+pack_length,(char*) &bit_buff->blob_pos,
sizeof(char*));
@@ -796,21 +841,21 @@ static void uf_blob(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
static void uf_varchar1(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end __attribute__((unused)))
+ byte *to, byte *end __attribute__((unused)))
{
if (get_bit(bit_buff))
to[0]= 0; /* Zero lengths */
else
{
ulong length=get_bits(bit_buff,rec->space_length_bits);
- *to= (uchar) length;
+ *to= (char) length;
decode_bytes(rec,bit_buff,to+1,to+1+length);
}
}
static void uf_varchar2(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
- uchar *to, uchar *end __attribute__((unused)))
+ byte *to, byte *end __attribute__((unused)))
{
if (get_bit(bit_buff))
to[0]=to[1]=0; /* Zero lengths */
@@ -826,8 +871,8 @@ static void uf_varchar2(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
#if BITS_SAVED == 64
-static void decode_bytes(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,uchar *to,
- uchar *end)
+static void decode_bytes(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
reg1 uint bits,low_byte;
reg3 uint16 *pos;
@@ -861,7 +906,7 @@ static void decode_bytes(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,uchar *to
low_byte=decode_tree->table[low_byte];
if (low_byte & IS_CHAR)
{
- *to++ = (low_byte & 255); /* Found char in quick table */
+ *to++ = (char) (low_byte & 255); /* Found char in quick table */
bits-= ((low_byte >> 8) & 31); /* Remove bits used */
}
else
@@ -881,7 +926,7 @@ static void decode_bytes(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,uchar *to
decode_bytes_test_bit(7);
bits-=8;
}
- *to++ = *pos;
+ *to++ = (char) *pos;
}
} while (to != end);
@@ -891,8 +936,8 @@ static void decode_bytes(MARIA_COLUMNDEF *rec,MARIA_BIT_BUFF *bit_buff,uchar *to
#else
-static void decode_bytes(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *to,
- uchar *end)
+static void decode_bytes(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
+ byte *to, byte *end)
{
reg1 uint bits,low_byte;
reg3 uint16 *pos;
@@ -978,7 +1023,7 @@ static void decode_bytes(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *
decode_bytes_test_bit(7);
bits-=8;
}
- *to++ = (uchar) *pos;
+ *to++ = (char) *pos;
}
} while (to != end);
@@ -988,7 +1033,8 @@ static void decode_bytes(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff, uchar *
#endif /* BIT_SAVED == 64 */
-static uint decode_pos(MARIA_BIT_BUFF *bit_buff, MARIA_DECODE_TREE *decode_tree)
+static uint decode_pos(MARIA_BIT_BUFF *bit_buff,
+ MARIA_DECODE_TREE *decode_tree)
{
uint16 *pos=decode_tree->table;
for (;;)
@@ -1002,11 +1048,12 @@ static uint decode_pos(MARIA_BIT_BUFF *bit_buff, MARIA_DECODE_TREE *decode_tree)
}
-int _ma_read_rnd_pack_record(MARIA_HA *info, byte *buf,
- register my_off_t filepos,
+int _ma_read_rnd_pack_record(MARIA_HA *info,
+ byte *buf,
+ register MARIA_RECORD_POS filepos,
my_bool skip_deleted_blocks)
{
- uint b_type;
+ File file;
MARIA_BLOCK_INFO block_info;
MARIA_SHARE *share=info->s;
DBUG_ENTER("_ma_read_rnd_pack_record");
@@ -1017,19 +1064,18 @@ int _ma_read_rnd_pack_record(MARIA_HA *info, byte *buf,
goto err;
}
+ file= info->dfile;
if (info->opt_flag & READ_CACHE_USED)
{
if (_ma_read_cache(&info->rec_cache, (byte*) block_info.header,
filepos, share->pack.ref_length,
skip_deleted_blocks ? READING_NEXT : 0))
goto err;
- b_type= _ma_pack_get_block_info(info, &info->bit_buff, &block_info,
- &info->rec_buff, -1, filepos);
+ file= -1;
}
- else
- b_type= _ma_pack_get_block_info(info, &info->bit_buff, &block_info,
- &info->rec_buff, info->dfile, filepos);
- if (b_type)
+ if (_ma_pack_get_block_info(info, &info->bit_buff, &block_info,
+ &info->rec_buff, &info->rec_buff_size,
+ file, filepos))
goto err; /* Error code is already set */
#ifndef DBUG_OFF
if (block_info.rec_len > share->max_pack_length)
@@ -1053,9 +1099,9 @@ int _ma_read_rnd_pack_record(MARIA_HA *info, byte *buf,
MYF(MY_NABP)))
goto err;
}
- info->packed_length=block_info.rec_len;
- info->lastpos=filepos;
- info->nextpos=block_info.filepos+block_info.rec_len;
+ info->packed_length= block_info.rec_len;
+ info->cur_row.lastpos= filepos;
+ info->cur_row.nextpos= block_info.filepos+block_info.rec_len;
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
DBUG_RETURN (_ma_pack_rec_unpack(info, &info->bit_buff, buf,
@@ -1068,10 +1114,11 @@ int _ma_read_rnd_pack_record(MARIA_HA *info, byte *buf,
/* Read and process header from a huff-record-file */
uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
- MARIA_BLOCK_INFO *info, byte **rec_buff_p,
+ MARIA_BLOCK_INFO *info,
+ byte **rec_buff_p, my_size_t *rec_buff_size_p,
File file, my_off_t filepos)
{
- uchar *header=info->header;
+ uchar *header= info->header;
uint head_length,ref_length;
LINT_INIT(ref_length);
@@ -1093,8 +1140,9 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
{
head_length+= read_pack_length((uint) maria->s->pack.version,
header + head_length, &info->blob_len);
- if (!(_ma_alloc_rec_buff(maria,info->rec_len + info->blob_len,
- rec_buff_p)))
+ if (_ma_alloc_buffer(rec_buff_p, rec_buff_size_p,
+ info->rec_len + info->blob_len +
+ maria->s->base.extra_rec_buff_size))
return BLOCK_FATAL_ERROR; /* not enough memory */
bit_buff->blob_pos= (uchar*) *rec_buff_p + info->rec_len;
bit_buff->blob_end= bit_buff->blob_pos + info->blob_len;
@@ -1113,7 +1161,8 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
/* rutines for bit buffer */
/* Note buffer must be 6 byte bigger than longest row */
-static void init_bit_buffer(MARIA_BIT_BUFF *bit_buff, uchar *buffer, uint length)
+static void init_bit_buffer(MARIA_BIT_BUFF *bit_buff, uchar *buffer,
+ uint length)
{
bit_buff->pos=buffer;
bit_buff->end=buffer+length;
@@ -1189,8 +1238,10 @@ static uint max_bit(register uint value)
#ifdef HAVE_MMAP
-static int _ma_read_mempack_record(MARIA_HA *info,my_off_t filepos,byte *buf);
-static int _ma_read_rnd_mempack_record(MARIA_HA*, byte *,my_off_t, my_bool);
+static int _ma_read_mempack_record(MARIA_HA *info, byte *buf,
+ MARIA_RECORD_POS filepos);
+static int _ma_read_rnd_mempack_record(MARIA_HA*, byte *, MARIA_RECORD_POS,
+ my_bool);
my_bool _ma_memmap_file(MARIA_HA *info)
{
@@ -1210,7 +1261,7 @@ my_bool _ma_memmap_file(MARIA_HA *info)
}
info->opt_flag|= MEMMAP_USED;
info->read_record= share->read_record= _ma_read_mempack_record;
- share->read_rnd= _ma_read_rnd_mempack_record;
+ share->scan= _ma_read_rnd_mempack_record;
DBUG_RETURN(1);
}
@@ -1222,9 +1273,13 @@ void _ma_unmap_file(MARIA_HA *info)
}
-static uchar *_ma_mempack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
- MARIA_BLOCK_INFO *info, byte **rec_buff_p,
- uchar *header)
+static uchar *
+_ma_mempack_get_block_info(MARIA_HA *maria,
+ MARIA_BIT_BUFF *bit_buff,
+ MARIA_BLOCK_INFO *info,
+ byte **rec_buff_p,
+ my_size_t *rec_buff_size_p,
+ uchar *header)
{
header+= read_pack_length((uint) maria->s->pack.version, header,
&info->rec_len);
@@ -1233,8 +1288,8 @@ static uchar *_ma_mempack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_bu
header+= read_pack_length((uint) maria->s->pack.version, header,
&info->blob_len);
/* _ma_alloc_rec_buff sets my_errno on error */
- if (!(_ma_alloc_rec_buff(maria, info->blob_len,
- rec_buff_p)))
+ if (_ma_alloc_buffer(rec_buff_p, rec_buff_size,
+ info->blob_len + maria->s->base.extra_rec_buff_size))
return 0; /* not enough memory */
bit_buff->blob_pos= (uchar*) *rec_buff_p;
bit_buff->blob_end= (uchar*) *rec_buff_p + info->blob_len;
@@ -1243,7 +1298,8 @@ static uchar *_ma_mempack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_bu
}
-static int _ma_read_mempack_record(MARIA_HA *info, my_off_t filepos, byte *buf)
+static int _ma_read_mempack_record(MARIA_HA *info, byte *buf,
+ MARIA_RECORD_POS filepos)
{
MARIA_BLOCK_INFO block_info;
MARIA_SHARE *share=info->s;
@@ -1255,6 +1311,7 @@ static int _ma_read_mempack_record(MARIA_HA *info, my_off_t filepos, byte *buf)
if (!(pos= (byte*) _ma_mempack_get_block_info(info, &info->bit_buff,
&block_info, &info->rec_buff,
+ &info->rec_buff_size,
(uchar*) share->file_map+
filepos)))
DBUG_RETURN(-1);
@@ -1264,8 +1321,9 @@ static int _ma_read_mempack_record(MARIA_HA *info, my_off_t filepos, byte *buf)
/*ARGSUSED*/
-static int _ma_read_rnd_mempack_record(MARIA_HA *info, byte *buf,
- register my_off_t filepos,
+static int _ma_read_rnd_mempack_record(MARIA_HA *info,
+ byte *buf,
+ register MARIA_RECORD_POS filepos,
my_bool skip_deleted_blocks
__attribute__((unused)))
{
@@ -1280,9 +1338,11 @@ static int _ma_read_rnd_mempack_record(MARIA_HA *info, byte *buf,
goto err;
}
if (!(pos= (byte*) _ma_mempack_get_block_info(info, &info->bit_buff,
- &block_info, &info->rec_buff,
+ &block_info,
+ &info->rec_buff,
+ &info->rec_buff_size,
(uchar*)
- (start=share->file_map+
+ (start= share->file_map +
filepos))))
goto err;
#ifndef DBUG_OFF
@@ -1293,8 +1353,8 @@ static int _ma_read_rnd_mempack_record(MARIA_HA *info, byte *buf,
}
#endif
info->packed_length=block_info.rec_len;
- info->lastpos=filepos;
- info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len;
+ info->cur_row.lastpos= filepos;
+ info->cur_row.nextpos= filepos+(uint) (pos-start)+block_info.rec_len;
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
DBUG_RETURN (_ma_pack_rec_unpack(info, &info->bit_buff, buf,
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index e5f9f47eaa5..d0a11ad08ab 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -20,22 +20,20 @@
/* Fetch a key-page in memory */
-uchar *_ma_fetch_keypage(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page, int level,
- uchar *buff, int return_buffer)
+byte *_ma_fetch_keypage(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ my_off_t page, int level,
+ byte *buff, int return_buffer)
{
- uchar *tmp;
+ byte *tmp;
uint page_size;
DBUG_ENTER("_ma_fetch_keypage");
DBUG_PRINT("enter",("page: %ld", (long) page));
- tmp=(uchar*) key_cache_read(info->s->key_cache,
- info->s->kfile, page, level, (byte*) buff,
- (uint) keyinfo->block_length,
- (uint) keyinfo->block_length,
- return_buffer);
+ tmp= key_cache_read(info->s->key_cache, info->s->kfile, page, level, buff,
+ info->s->block_size, info->s->block_size,
+ return_buffer);
if (tmp == info->buff)
- info->buff_used=1;
+ info->keybuff_used=1;
else if (!tmp)
{
DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno));
@@ -53,8 +51,8 @@ uchar *_ma_fetch_keypage(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
DBUG_DUMP("page", (char*) tmp, keyinfo->block_length);
info->last_keypage = HA_OFFSET_ERROR;
maria_print_error(info->s, HA_ERR_CRASHED);
- my_errno = HA_ERR_CRASHED;
- tmp = 0;
+ my_errno= HA_ERR_CRASHED;
+ tmp= 0;
}
DBUG_RETURN(tmp);
} /* _ma_fetch_keypage */
@@ -63,7 +61,7 @@ uchar *_ma_fetch_keypage(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* Write a key-page on disk */
int _ma_write_keypage(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- my_off_t page, int level, uchar *buff)
+ my_off_t page, int level, byte *buff)
{
reg3 uint length;
DBUG_ENTER("_ma_write_keypage");
@@ -112,8 +110,8 @@ int _ma_dispose(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
DBUG_ENTER("_ma_dispose");
DBUG_PRINT("enter",("pos: %ld", (long) pos));
- old_link= info->s->state.key_del[keyinfo->block_size_index];
- info->s->state.key_del[keyinfo->block_size_index]= pos;
+ old_link= info->s->state.key_del;
+ info->s->state.key_del= pos;
mi_sizestore(buff,old_link);
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
DBUG_RETURN(key_cache_write(info->s->key_cache,
@@ -129,11 +127,10 @@ int _ma_dispose(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
{
my_off_t pos;
- char buff[8];
+ byte buff[8];
DBUG_ENTER("_ma_new");
- if ((pos= info->s->state.key_del[keyinfo->block_size_index]) ==
- HA_OFFSET_ERROR)
+ if ((pos= info->s->state.key_del) == HA_OFFSET_ERROR)
{
if (info->state->key_file_length >=
info->s->base.max_key_file_length - keyinfo->block_length)
@@ -153,7 +150,7 @@ my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
(uint) keyinfo->block_length,0))
pos= HA_OFFSET_ERROR;
else
- info->s->state.key_del[keyinfo->block_size_index]= mi_sizekorr(buff);
+ info->s->state.key_del= mi_sizekorr(buff);
}
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
DBUG_PRINT("exit",("Pos: %ld",(long) pos));
diff --git a/storage/maria/ma_range.c b/storage/maria/ma_range.c
index c837fe5e6e3..d3806aa79bc 100644
--- a/storage/maria/ma_range.c
+++ b/storage/maria/ma_range.c
@@ -24,10 +24,10 @@
static ha_rows _ma_record_pos(MARIA_HA *info,const byte *key,uint key_len,
enum ha_rkey_function search_flag);
-static double _ma_search_pos(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *key,
- uint key_len,uint nextflag,my_off_t pos);
-static uint _ma_keynr(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *page,
- uchar *keypos,uint *ret_max_key);
+static double _ma_search_pos(MARIA_HA *info,MARIA_KEYDEF *keyinfo, byte *key,
+ uint key_len,uint nextflag, my_off_t pos);
+static uint _ma_keynr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *page,
+ byte *keypos, uint *ret_max_key);
/*
@@ -68,7 +68,7 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
#ifdef HAVE_RTREE_KEYS
case HA_KEY_ALG_RTREE:
{
- uchar * key_buff;
+ byte *key_buff;
uint start_key_len;
/*
@@ -88,7 +88,7 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
}
key_buff= info->lastkey+info->s->base.max_key_length;
start_key_len= _ma_pack_key(info,inx, key_buff,
- (uchar*) min_key->key, min_key->length,
+ min_key->key, min_key->length,
(HA_KEYSEG**) 0);
res= maria_rtree_estimate(info, inx, key_buff, start_key_len,
maria_read_vec[min_key->flag]);
@@ -128,24 +128,23 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const byte *key, uint key_len,
{
uint inx=(uint) info->lastinx, nextflag;
MARIA_KEYDEF *keyinfo=info->s->keyinfo+inx;
- uchar *key_buff;
+ byte *key_buff;
double pos;
-
DBUG_ENTER("_ma_record_pos");
DBUG_PRINT("enter",("search_flag: %d",search_flag));
if (key_len == 0)
- key_len=USE_WHOLE_KEY;
+ key_len= USE_WHOLE_KEY;
key_buff=info->lastkey+info->s->base.max_key_length;
- key_len= _ma_pack_key(info,inx,key_buff,(uchar*) key,key_len,
+ key_len= _ma_pack_key(info, inx, key_buff, key, key_len,
(HA_KEYSEG**) 0);
- DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,
- (uchar*) key_buff,key_len););
+ DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, keyinfo->seg,
+ key_buff, key_len););
nextflag=maria_read_vec[search_flag];
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
key_len=USE_WHOLE_KEY;
- pos= _ma_search_pos(info,keyinfo,key_buff,key_len,
+ pos= _ma_search_pos(info,keyinfo, key_buff, key_len,
nextflag | SEARCH_SAVE_BUFF,
info->s->state.key_root[inx]);
if (pos >= 0.0)
@@ -162,13 +161,13 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const byte *key, uint key_len,
static double _ma_search_pos(register MARIA_HA *info,
register MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_len, uint nextflag,
+ byte *key, uint key_len, uint nextflag,
register my_off_t pos)
{
int flag;
uint nod_flag,keynr,max_keynr;
my_bool after_key;
- uchar *keypos,*buff;
+ byte *keypos, *buff;
double offset;
DBUG_ENTER("_ma_search_pos");
@@ -177,7 +176,7 @@ static double _ma_search_pos(register MARIA_HA *info,
if (!(buff= _ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,1)))
goto err;
- flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
+ flag=(*keyinfo->bin_search)(info, keyinfo, buff, key, key_len, nextflag,
&keypos,info->lastkey, &after_key);
nod_flag=_ma_test_if_nod(buff);
keynr= _ma_keynr(info,keyinfo,buff,keypos,&max_keynr);
@@ -228,11 +227,11 @@ err:
/* Get keynummer of current key and max number of keys in nod */
-static uint _ma_keynr(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *keypos, uint *ret_max_key)
+static uint _ma_keynr(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
+ byte *page, byte *keypos, uint *ret_max_key)
{
uint nod_flag,keynr,max_key;
- uchar t_buff[HA_MAX_KEY_BUFF],*end;
+ byte t_buff[HA_MAX_KEY_BUFF],*end;
end= page+maria_getint(page);
nod_flag=_ma_test_if_nod(page);
diff --git a/storage/maria/ma_rfirst.c b/storage/maria/ma_rfirst.c
index 503e8989936..6fa8af75c40 100644
--- a/storage/maria/ma_rfirst.c
+++ b/storage/maria/ma_rfirst.c
@@ -21,7 +21,7 @@
int maria_rfirst(MARIA_HA *info, byte *buf, int inx)
{
DBUG_ENTER("maria_rfirst");
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
info->update|= HA_STATE_PREV_FOUND;
DBUG_RETURN(maria_rnext(info,buf,inx));
} /* maria_rfirst */
diff --git a/storage/maria/ma_rkey.c b/storage/maria/ma_rkey.c
index 7338c96482f..17eae760a3a 100644
--- a/storage/maria/ma_rkey.c
+++ b/storage/maria/ma_rkey.c
@@ -22,16 +22,16 @@
/* Read a record using key */
/* Ordinary search_flag is 0 ; Give error if no record with key */
-int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len,
- enum ha_rkey_function search_flag)
+int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key,
+ uint key_len, enum ha_rkey_function search_flag)
{
- uchar *key_buff;
+ byte *key_buff;
MARIA_SHARE *share=info->s;
MARIA_KEYDEF *keyinfo;
HA_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("maria_rkey");
- DBUG_PRINT("enter", ("base: %lx buf: %lx inx: %d search_flag: %d",
+ DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d",
(long) info, (long) buf, inx, search_flag));
if ((inx = _ma_check_index(info,inx)) < 0)
@@ -47,7 +47,7 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len
/*
key is already packed!; This happens when we are using a MERGE TABLE
*/
- key_buff=info->lastkey+info->s->base.max_key_length;
+ key_buff= info->lastkey+info->s->base.max_key_length;
pack_key_length= key_len;
bmove(key_buff,key,key_len);
last_used_keyseg= 0;
@@ -58,7 +58,7 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len
key_len=USE_WHOLE_KEY;
/* Save the packed key for later use in the second buffer of lastkey. */
key_buff=info->lastkey+info->s->base.max_key_length;
- pack_key_length= _ma_pack_key(info,(uint) inx, key_buff, (uchar*) key,
+ pack_key_length= _ma_pack_key(info,(uint) inx, key_buff, key,
key_len, &last_used_keyseg);
/* Save packed_key_length for use by the MERGE engine. */
info->pack_key_length= pack_key_length;
@@ -82,22 +82,24 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len
if (maria_rtree_find_first(info,inx,key_buff,use_key_length,nextflag) < 0)
{
maria_print_error(info->s, HA_ERR_CRASHED);
- my_errno=HA_ERR_CRASHED;
- goto err;
+ my_errno= HA_ERR_CRASHED;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
}
break;
#endif
case HA_KEY_ALG_BTREE:
default:
if (!_ma_search(info, keyinfo, key_buff, use_key_length,
- maria_read_vec[search_flag], info->s->state.key_root[inx]))
+ maria_read_vec[search_flag],
+ info->s->state.key_root[inx]) &&
+ share->concurrent_insert)
{
/*
If we searching for a partial key (or using >, >=, < or <=) and
the data is outside of the data file, we need to continue searching
for the first key inside the data file
*/
- if (info->lastpos >= info->state->data_file_length &&
+ if (info->cur_row.lastpos >= info->state->data_file_length &&
(search_flag != HA_READ_KEY_EXACT ||
last_used_keyseg != keyinfo->seg + keyinfo->keysegs))
{
@@ -125,36 +127,45 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len
SEARCH_FIND, not_used))
{
my_errno= HA_ERR_KEY_NOT_FOUND;
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
break;
}
- } while (info->lastpos >= info->state->data_file_length);
+ } while (info->cur_row.lastpos >= info->state->data_file_length);
}
}
}
if (share->concurrent_insert)
rw_unlock(&share->key_root_lock[inx]);
+ if (info->cur_row.lastpos == HA_OFFSET_ERROR)
+ {
+ fast_ma_writeinfo(info);
+ goto err;
+ }
+
/* Calculate length of the found key; Used by maria_rnext_same */
- if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg &&
- info->lastpos != HA_OFFSET_ERROR)
+ if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg)
info->last_rkey_length= _ma_keylength_part(keyinfo, info->lastkey,
last_used_keyseg);
else
info->last_rkey_length= pack_key_length;
+
/* Check if we don't want to have record back, only error message */
if (!buf)
- DBUG_RETURN(info->lastpos == HA_OFFSET_ERROR ? my_errno : 0);
-
- if (!(*info->read_record)(info,info->lastpos,buf))
+ {
+ fast_ma_writeinfo(info);
+ DBUG_RETURN(0);
+ }
+ if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
{
info->update|= HA_STATE_AKTIV; /* Record is read */
DBUG_RETURN(0);
}
- info->lastpos = HA_OFFSET_ERROR; /* Didn't find key */
+ info->cur_row.lastpos= HA_OFFSET_ERROR; /* Didn't find row */
+err:
/* Store last used key as a base for read next */
memcpy(info->lastkey,key_buff,pack_key_length);
info->last_rkey_length= pack_key_length;
@@ -163,6 +174,5 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len
if (search_flag == HA_READ_AFTER_KEY)
info->update|=HA_STATE_NEXT_FOUND; /* Previous gives last row */
-err:
DBUG_RETURN(my_errno);
} /* _ma_rkey */
diff --git a/storage/maria/ma_rlast.c b/storage/maria/ma_rlast.c
index 8ce26afa78d..504cc89aed3 100644
--- a/storage/maria/ma_rlast.c
+++ b/storage/maria/ma_rlast.c
@@ -21,7 +21,7 @@
int maria_rlast(MARIA_HA *info, byte *buf, int inx)
{
DBUG_ENTER("maria_rlast");
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
info->update|= HA_STATE_NEXT_FOUND;
DBUG_RETURN(maria_rprev(info,buf,inx));
} /* maria_rlast */
diff --git a/storage/maria/ma_rnext.c b/storage/maria/ma_rnext.c
index 8f342c6a8d2..c7feded933e 100644
--- a/storage/maria/ma_rnext.c
+++ b/storage/maria/ma_rnext.c
@@ -34,7 +34,8 @@ int maria_rnext(MARIA_HA *info, byte *buf, int inx)
if ((inx = _ma_check_index(info,inx)) < 0)
DBUG_RETURN(my_errno);
flag=SEARCH_BIGGER; /* Read next */
- if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND)
+ if (info->cur_row.lastpos == HA_OFFSET_ERROR &&
+ info->update & HA_STATE_PREV_FOUND)
flag=0; /* Read first */
if (fast_ma_readinfo(info))
@@ -86,7 +87,7 @@ int maria_rnext(MARIA_HA *info, byte *buf, int inx)
{
if (!error)
{
- while (info->lastpos >= info->state->data_file_length)
+ while (info->cur_row.lastpos >= info->state->data_file_length)
{
/* Skip rows inserted by other threads since we got a lock */
if ((error= _ma_search_next(info,info->s->keyinfo+inx,
@@ -110,9 +111,9 @@ int maria_rnext(MARIA_HA *info, byte *buf, int inx)
}
else if (!buf)
{
- DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
+ DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0);
}
- else if (!(*info->read_record)(info,info->lastpos,buf))
+ else if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
{
info->update|= HA_STATE_AKTIV; /* Record is read */
DBUG_RETURN(0);
diff --git a/storage/maria/ma_rnext_same.c b/storage/maria/ma_rnext_same.c
index b53639073e3..a5ce0cfe15c 100644
--- a/storage/maria/ma_rnext_same.c
+++ b/storage/maria/ma_rnext_same.c
@@ -17,13 +17,14 @@
#include "maria_def.h"
#include "ma_rt_index.h"
- /*
- Read next row with the same key as previous read, but abort if
- the key changes.
- One may have done a write, update or delete of the previous row.
- NOTE! Even if one changes the previous row, the next read is done
- based on the position of the last used key!
- */
+/*
+ Read next row with the same key as previous read, but abort if
+ the key changes.
+ One may have done a write, update or delete of the previous row.
+
+ NOTE! Even if one changes the previous row, the next read is done
+ based on the position of the last used key!
+*/
int maria_rnext_same(MARIA_HA *info, byte *buf)
{
@@ -32,9 +33,10 @@ int maria_rnext_same(MARIA_HA *info, byte *buf)
MARIA_KEYDEF *keyinfo;
DBUG_ENTER("maria_rnext_same");
- if ((int) (inx=info->lastinx) < 0 || info->lastpos == HA_OFFSET_ERROR)
+ if ((int) (inx= info->lastinx) < 0 ||
+ info->cur_row.lastpos == HA_OFFSET_ERROR)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
- keyinfo=info->s->keyinfo+inx;
+ keyinfo= info->s->keyinfo+inx;
if (fast_ma_readinfo(info))
DBUG_RETURN(my_errno);
@@ -50,7 +52,7 @@ int maria_rnext_same(MARIA_HA *info, byte *buf)
{
error=1;
my_errno=HA_ERR_END_OF_FILE;
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
break;
}
break;
@@ -68,16 +70,17 @@ int maria_rnext_same(MARIA_HA *info, byte *buf)
info->lastkey_length,SEARCH_BIGGER,
info->s->state.key_root[inx])))
break;
- if (ha_key_cmp(keyinfo->seg, info->lastkey, info->lastkey2,
+ if (ha_key_cmp(keyinfo->seg, (uchar*) info->lastkey,
+ (uchar*) info->lastkey2,
info->last_rkey_length, SEARCH_FIND, not_used))
{
error=1;
my_errno=HA_ERR_END_OF_FILE;
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
break;
}
/* Skip rows that are inserted by other threads since we got a lock */
- if (info->lastpos < info->state->data_file_length)
+ if (info->cur_row.lastpos < info->state->data_file_length)
break;
}
}
@@ -94,9 +97,9 @@ int maria_rnext_same(MARIA_HA *info, byte *buf)
}
else if (!buf)
{
- DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
+ DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0);
}
- else if (!(*info->read_record)(info,info->lastpos,buf))
+ else if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
{
info->update|= HA_STATE_AKTIV; /* Record is read */
DBUG_RETURN(0);
diff --git a/storage/maria/ma_rprev.c b/storage/maria/ma_rprev.c
index 8dd4498cf8b..ea562359ded 100644
--- a/storage/maria/ma_rprev.c
+++ b/storage/maria/ma_rprev.c
@@ -33,7 +33,8 @@ int maria_rprev(MARIA_HA *info, byte *buf, int inx)
if ((inx = _ma_check_index(info,inx)) < 0)
DBUG_RETURN(my_errno);
flag=SEARCH_SMALLER; /* Read previous */
- if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_NEXT_FOUND)
+ if (info->cur_row.lastpos == HA_OFFSET_ERROR &&
+ info->update & HA_STATE_NEXT_FOUND)
flag=0; /* Read last */
if (fast_ma_readinfo(info))
@@ -56,7 +57,7 @@ int maria_rprev(MARIA_HA *info, byte *buf, int inx)
{
if (!error)
{
- while (info->lastpos >= info->state->data_file_length)
+ while (info->cur_row.lastpos >= info->state->data_file_length)
{
/* Skip rows that are inserted by other threads since we got a lock */
if ((error= _ma_search_next(info,share->keyinfo+inx,info->lastkey,
@@ -77,9 +78,9 @@ int maria_rprev(MARIA_HA *info, byte *buf, int inx)
}
else if (!buf)
{
- DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
+ DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0);
}
- else if (!(*info->read_record)(info,info->lastpos,buf))
+ else if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
{
info->update|= HA_STATE_AKTIV; /* Record is read */
DBUG_RETURN(0);
diff --git a/storage/maria/ma_rrnd.c b/storage/maria/ma_rrnd.c
index 2f01c0e92c5..33940d5f23f 100644
--- a/storage/maria/ma_rrnd.c
+++ b/storage/maria/ma_rrnd.c
@@ -21,40 +21,34 @@
#include "maria_def.h"
/*
- Read a row based on position.
- If filepos= HA_OFFSET_ERROR then read next row
- Return values
- Returns one of following values:
- 0 = Ok.
- HA_ERR_RECORD_DELETED = Record is deleted.
- HA_ERR_END_OF_FILE = EOF.
+ Read a row based on position.
+
+ RETURN
+ 0 Ok.
+ HA_ERR_RECORD_DELETED Record is deleted.
+ HA_ERR_END_OF_FILE EOF.
*/
-int maria_rrnd(MARIA_HA *info, byte *buf, register my_off_t filepos)
+int maria_rrnd(MARIA_HA *info, byte *buf, MARIA_RECORD_POS filepos)
{
- my_bool skip_deleted_blocks;
DBUG_ENTER("maria_rrnd");
- skip_deleted_blocks=0;
-
+ DBUG_ASSERT(filepos != HA_OFFSET_ERROR);
+#ifdef NOT_USED
if (filepos == HA_OFFSET_ERROR)
{
skip_deleted_blocks=1;
- if (info->lastpos == HA_OFFSET_ERROR) /* First read ? */
- filepos= info->s->pack.header_length; /* Read first record */
+ if (info->cur_row.lastpos == HA_OFFSET_ERROR) /* First read ? */
+ filepos= info->s->pack.header_length; /* Read first record */
else
- filepos= info->nextpos;
+ filepos= info->cur_row.nextpos;
}
+#endif
- if (info->once_flags & RRND_PRESERVE_LASTINX)
- info->once_flags&= ~RRND_PRESERVE_LASTINX;
- else
- info->lastinx= -1; /* Can't forward or backward */
/* Init all but update-flag */
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
-
if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache))
DBUG_RETURN(my_errno);
- DBUG_RETURN ((*info->s->read_rnd)(info,buf,filepos,skip_deleted_blocks));
+ DBUG_RETURN((*info->s->read_record)(info, buf, filepos));
}
diff --git a/storage/maria/ma_rsame.c b/storage/maria/ma_rsame.c
index 913ae3b4370..7556c1e7332 100644
--- a/storage/maria/ma_rsame.c
+++ b/storage/maria/ma_rsame.c
@@ -16,14 +16,17 @@
#include "maria_def.h"
- /*
- ** Find current row with read on position or read on key
- ** If inx >= 0 find record using key
- ** Return values:
- ** 0 = Ok.
- ** HA_ERR_KEY_NOT_FOUND = Row is deleted
- ** HA_ERR_END_OF_FILE = End of file
- */
+/*
+ Find current row with read on position or read on key
+
+ NOTES
+ If inx >= 0 find record using key
+
+ RETURN
+ 0 Ok
+ HA_ERR_KEY_NOT_FOUND Row is deleted
+ HA_ERR_END_OF_FILE End of file
+*/
int maria_rsame(MARIA_HA *info, byte *record, int inx)
@@ -34,7 +37,8 @@ int maria_rsame(MARIA_HA *info, byte *record, int inx)
{
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
}
- if (info->lastpos == HA_OFFSET_ERROR || info->update & HA_STATE_DELETED)
+ if (info->cur_row.lastpos == HA_OFFSET_ERROR ||
+ info->update & HA_STATE_DELETED)
{
DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND); /* No current record */
}
@@ -48,7 +52,7 @@ int maria_rsame(MARIA_HA *info, byte *record, int inx)
{
info->lastinx=inx;
info->lastkey_length= _ma_make_key(info,(uint) inx,info->lastkey,record,
- info->lastpos);
+ info->cur_row.lastpos);
if (info->s->concurrent_insert)
rw_rdlock(&info->s->key_root_lock[inx]);
VOID(_ma_search(info,info->s->keyinfo+inx,info->lastkey, USE_WHOLE_KEY,
@@ -58,7 +62,7 @@ int maria_rsame(MARIA_HA *info, byte *record, int inx)
rw_unlock(&info->s->key_root_lock[inx]);
}
- if (!(*info->read_record)(info,info->lastpos,record))
+ if (!(*info->read_record)(info, record, info->cur_row.lastpos))
DBUG_RETURN(0);
if (my_errno == HA_ERR_RECORD_DELETED)
my_errno=HA_ERR_KEY_NOT_FOUND;
diff --git a/storage/maria/ma_rsamepos.c b/storage/maria/ma_rsamepos.c
index b49ef8d294a..92138693c62 100644
--- a/storage/maria/ma_rsamepos.c
+++ b/storage/maria/ma_rsamepos.c
@@ -28,7 +28,8 @@
** HA_ERR_END_OF_FILE = End of file
*/
-int maria_rsame_with_pos(MARIA_HA *info, byte *record, int inx, my_off_t filepos)
+int maria_rsame_with_pos(MARIA_HA *info, byte *record, int inx,
+ MARIA_RECORD_POS filepos)
{
DBUG_ENTER("maria_rsame_with_pos");
DBUG_PRINT("enter",("index: %d filepos: %ld", inx, (long) filepos));
@@ -40,18 +41,18 @@ int maria_rsame_with_pos(MARIA_HA *info, byte *record, int inx, my_off_t filepos
}
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
- if ((*info->s->read_rnd)(info,record,filepos,0))
+ if ((*info->s->read_record)(info, record, filepos))
{
if (my_errno == HA_ERR_RECORD_DELETED)
my_errno=HA_ERR_KEY_NOT_FOUND;
DBUG_RETURN(my_errno);
}
- info->lastpos=filepos;
- info->lastinx=inx;
+ info->cur_row.lastpos= filepos;
+ info->lastinx= inx;
if (inx >= 0)
{
info->lastkey_length= _ma_make_key(info,(uint) inx,info->lastkey,record,
- info->lastpos);
+ info->cur_row.lastpos);
info->update|=HA_STATE_KEY_CHANGED; /* Don't use indexposition */
}
DBUG_RETURN(0);
diff --git a/storage/maria/ma_rt_index.c b/storage/maria/ma_rt_index.c
index 83ced5b8167..8e8ec6c991b 100644
--- a/storage/maria/ma_rt_index.c
+++ b/storage/maria/ma_rt_index.c
@@ -53,18 +53,17 @@ typedef struct st_page_list
1 Not found
*/
-static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint search_flag,
- uint nod_cmp_flag, my_off_t page, int level)
+static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ uint search_flag,
+ uint nod_cmp_flag, my_off_t page, int level)
{
- uchar *k;
- uchar *last;
uint nod_flag;
int res;
- uchar *page_buf;
+ byte *page_buf, *k, *last;
int k_len;
uint *saved_key = (uint*) (info->maria_rtree_recursion_state) + level;
- if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
+ if (!(page_buf = (byte*) my_alloca((uint)keyinfo->block_length)))
{
my_errno = HA_ERR_OUT_OF_MEM;
return -1;
@@ -77,24 +76,27 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint sear
if(info->maria_rtree_recursion_depth >= level)
{
- k = page_buf + *saved_key;
+ k= page_buf + *saved_key;
}
else
{
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
}
- last = rt_PAGE_END(page_buf);
+ last= rt_PAGE_END(page_buf);
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag))
{
if (nod_flag)
{
/* this is an internal node in the tree */
- if (!(res = maria_rtree_key_cmp(keyinfo->seg, info->first_mbr_key, k,
- info->last_rkey_length, nod_cmp_flag)))
+ if (!(res = maria_rtree_key_cmp(keyinfo->seg,
+ info->first_mbr_key, k,
+ info->last_rkey_length, nod_cmp_flag)))
{
- switch ((res = maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag,
- _ma_kpos(nod_flag, k), level + 1)))
+ switch ((res = maria_rtree_find_req(info, keyinfo, search_flag,
+ nod_cmp_flag,
+ _ma_kpos(nod_flag, k),
+ level + 1)))
{
case 0: /* found - exit from recursion */
*saved_key = k - page_buf;
@@ -111,11 +113,11 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint sear
else
{
/* this is a leaf */
- if (!maria_rtree_key_cmp(keyinfo->seg, info->first_mbr_key, k,
- info->last_rkey_length, search_flag))
+ if (!maria_rtree_key_cmp(keyinfo->seg, info->first_mbr_key,
+ k, info->last_rkey_length, search_flag))
{
- uchar *after_key = rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
- info->lastpos = _ma_dpos(info, 0, after_key);
+ byte *after_key = (byte*) rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
+ info->cur_row.lastpos = _ma_dpos(info, 0, after_key);
info->lastkey_length = k_len + info->s->base.rec_reflength;
memcpy(info->lastkey, k, info->lastkey_length);
info->maria_rtree_recursion_depth = level;
@@ -126,11 +128,11 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint sear
info->int_keypos = info->buff;
info->int_maxpos = info->buff + (last - after_key);
memcpy(info->buff, after_key, last - after_key);
- info->buff_used = 0;
+ info->keybuff_used = 0;
}
else
{
- info->buff_used = 1;
+ info->keybuff_used = 1;
}
res = 0;
@@ -138,7 +140,7 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint sear
}
}
}
- info->lastpos = HA_OFFSET_ERROR;
+ info->cur_row.lastpos = HA_OFFSET_ERROR;
my_errno = HA_ERR_KEY_NOT_FOUND;
res = 1;
@@ -148,7 +150,7 @@ ok:
err1:
my_afree((byte*)page_buf);
- info->lastpos = HA_OFFSET_ERROR;
+ info->cur_row.lastpos = HA_OFFSET_ERROR;
return -1;
}
@@ -170,8 +172,8 @@ err1:
1 Not found
*/
-int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key, uint key_length,
- uint search_flag)
+int maria_rtree_find_first(MARIA_HA *info, uint keynr, byte *key,
+ uint key_length, uint search_flag)
{
my_off_t root;
uint nod_cmp_flag;
@@ -191,11 +193,12 @@ int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key, uint key_leng
info->last_rkey_length = key_length;
info->maria_rtree_recursion_depth = -1;
- info->buff_used = 1;
+ info->keybuff_used = 1;
- nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
- MBR_WITHIN : MBR_INTERSECT);
- return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0);
+ nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
+ MBR_WITHIN : MBR_INTERSECT);
+ return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root,
+ 0);
}
@@ -221,27 +224,29 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag)
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
if (info->update & HA_STATE_DELETED)
- return maria_rtree_find_first(info, keynr, info->lastkey, info->lastkey_length,
- search_flag);
+ return maria_rtree_find_first(info, keynr, info->lastkey,
+ info->lastkey_length,
+ search_flag);
- if (!info->buff_used)
+ if (!info->keybuff_used)
{
- uchar *key= info->int_keypos;
+ byte *key= info->int_keypos;
while (key < info->int_maxpos)
{
- if (!maria_rtree_key_cmp(keyinfo->seg, info->first_mbr_key, key,
- info->last_rkey_length, search_flag))
+ if (!maria_rtree_key_cmp(keyinfo->seg,
+ info->first_mbr_key, key,
+ info->last_rkey_length, search_flag))
{
- uchar *after_key = key + keyinfo->keylength;
+ byte *after_key= key + keyinfo->keylength;
- info->lastpos= _ma_dpos(info, 0, after_key);
+ info->cur_row.lastpos= _ma_dpos(info, 0, after_key);
memcpy(info->lastkey, key, info->lastkey_length);
if (after_key < info->int_maxpos)
info->int_keypos= after_key;
else
- info->buff_used= 1;
+ info->keybuff_used= 1;
return 0;
}
key+= keyinfo->keylength;
@@ -274,15 +279,12 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag)
static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_length,
my_off_t page, int level)
{
- uchar *k;
- uchar *last;
- uint nod_flag;
+ byte *page_buf, *last, *k;
+ uint nod_flag, k_len;
int res;
- uchar *page_buf;
- uint k_len;
- uint *saved_key = (uint*) (info->maria_rtree_recursion_state) + level;
+ uint *saved_key= (uint*) (info->maria_rtree_recursion_state) + level;
- if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
+ if (!(page_buf= (byte*) my_alloca((uint)keyinfo->block_length)))
return -1;
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
goto err1;
@@ -312,7 +314,7 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_l
{
/* this is an internal node in the tree */
switch ((res = maria_rtree_get_req(info, keyinfo, key_length,
- _ma_kpos(nod_flag, k), level + 1)))
+ _ma_kpos(nod_flag, k), level + 1)))
{
case 0: /* found - exit from recursion */
*saved_key = k - page_buf;
@@ -328,8 +330,8 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_l
else
{
/* this is a leaf */
- uchar *after_key = rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
- info->lastpos = _ma_dpos(info, 0, after_key);
+ byte *after_key = rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
+ info->cur_row.lastpos = _ma_dpos(info, 0, after_key);
info->lastkey_length = k_len + info->s->base.rec_reflength;
memcpy(info->lastkey, k, info->lastkey_length);
@@ -338,21 +340,21 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_l
if (after_key < last)
{
- info->int_keypos = (uchar*)saved_key;
+ info->int_keypos = (byte*) saved_key;
memcpy(info->buff, page_buf, keyinfo->block_length);
info->int_maxpos = rt_PAGE_END(info->buff);
- info->buff_used = 0;
+ info->keybuff_used = 0;
}
else
{
- info->buff_used = 1;
+ info->keybuff_used = 1;
}
res = 0;
goto ok;
}
}
- info->lastpos = HA_OFFSET_ERROR;
+ info->cur_row.lastpos = HA_OFFSET_ERROR;
my_errno = HA_ERR_KEY_NOT_FOUND;
res = 1;
@@ -362,7 +364,7 @@ ok:
err1:
my_afree((byte*)page_buf);
- info->lastpos = HA_OFFSET_ERROR;
+ info->cur_row.lastpos = HA_OFFSET_ERROR;
return -1;
}
@@ -388,7 +390,7 @@ int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length)
}
info->maria_rtree_recursion_depth = -1;
- info->buff_used = 1;
+ info->keybuff_used = 1;
return maria_rtree_get_req(info, &keyinfo[keynr], key_length, root, 0);
}
@@ -408,23 +410,23 @@ int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length)
my_off_t root;
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
- if (!info->buff_used)
+ if (!info->keybuff_used)
{
uint k_len = keyinfo->keylength - info->s->base.rec_reflength;
/* rt_PAGE_NEXT_KEY(info->int_keypos) */
- uchar *key = info->buff + *(int*)info->int_keypos + k_len +
+ byte *key = info->buff + *(int*)info->int_keypos + k_len +
info->s->base.rec_reflength;
/* rt_PAGE_NEXT_KEY(key) */
- uchar *after_key = key + k_len + info->s->base.rec_reflength;
+ byte *after_key = key + k_len + info->s->base.rec_reflength;
- info->lastpos = _ma_dpos(info, 0, after_key);
+ info->cur_row.lastpos = _ma_dpos(info, 0, after_key);
info->lastkey_length = k_len + info->s->base.rec_reflength;
memcpy(info->lastkey, key, k_len + info->s->base.rec_reflength);
*(int*)info->int_keypos = key - info->buff;
if (after_key >= info->int_maxpos)
{
- info->buff_used = 1;
+ info->keybuff_used = 1;
}
return 0;
@@ -447,8 +449,10 @@ int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length)
*/
#ifdef PICK_BY_PERIMETER
-static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uint key_length, uchar *page_buf, uint nod_flag)
+static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ uchar *key,
+ uint key_length, byte *page_buf,
+ uint nod_flag)
{
double increase;
double best_incr = DBL_MAX;
@@ -480,16 +484,18 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar
#endif /*PICK_BY_PERIMETER*/
#ifdef PICK_BY_AREA
-static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uint key_length, uchar *page_buf, uint nod_flag)
+static byte *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *key,
+ uint key_length, byte *page_buf,
+ uint nod_flag)
{
double increase;
double best_incr = DBL_MAX;
double area;
double best_area;
- uchar *best_key;
- uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
- uchar *last = rt_PAGE_END(page_buf);
+ byte *best_key;
+ byte *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
+ byte *last = rt_PAGE_END(page_buf);
LINT_INIT(best_area);
LINT_INIT(best_key);
@@ -498,7 +504,7 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar
{
/* The following is safe as -1.0 is an exact number */
if ((increase = maria_rtree_area_increase(keyinfo->seg, k, key, key_length,
- &area)) == -1.0)
+ &area)) == -1.0)
return NULL;
/* The following should be safe, even if we compare doubles */
if (increase < best_incr)
@@ -532,16 +538,17 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar
1 Child was split
*/
-static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uint key_length, my_off_t page, my_off_t *new_page,
- int ins_level, int level)
+static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *key,
+ uint key_length, my_off_t page,
+ my_off_t *new_page,
+ int ins_level, int level)
{
- uchar *k;
uint nod_flag;
- uchar *page_buf;
int res;
+ byte *page_buf, *k;
- if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length +
+ if (!(page_buf= (byte*) my_alloca((uint)keyinfo->block_length +
HA_MAX_KEY_BUFF)))
{
my_errno = HA_ERR_OUT_OF_MEM;
@@ -555,10 +562,11 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *
(ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */
{
if ((k = maria_rtree_pick_key(info, keyinfo, key, key_length, page_buf,
- nod_flag)) == NULL)
+ nod_flag)) == NULL)
goto err1;
switch ((res = maria_rtree_insert_req(info, keyinfo, key, key_length,
- _ma_kpos(nod_flag, k), new_page, ins_level, level + 1)))
+ _ma_kpos(nod_flag, k), new_page,
+ ins_level, level + 1)))
{
case 0: /* child was not split */
{
@@ -569,14 +577,15 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *
}
case 1: /* child was split */
{
- uchar *new_key = page_buf + keyinfo->block_length + nod_flag;
+ byte *new_key = page_buf + keyinfo->block_length + nod_flag;
/* set proper MBR for key */
if (maria_rtree_set_key_mbr(info, keyinfo, k, key_length,
- _ma_kpos(nod_flag, k)))
+ _ma_kpos(nod_flag, k)))
goto err1;
/* add new key for new page */
_ma_kpointer(info, new_key - nod_flag, *new_page);
- if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length, *new_page))
+ if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length,
+ *new_page))
goto err1;
res = maria_rtree_add_key(info, keyinfo, new_key, key_length,
page_buf, new_page);
@@ -593,18 +602,18 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *
}
else
{
- res = maria_rtree_add_key(info, keyinfo, key, key_length, page_buf, new_page);
+ res = maria_rtree_add_key(info, keyinfo, key, key_length, page_buf,
+ new_page);
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
goto err1;
- goto ok;
}
ok:
- my_afree((byte*)page_buf);
+ my_afree(page_buf);
return res;
err1:
- my_afree((byte*)page_buf);
+ my_afree(page_buf);
return -1;
}
@@ -618,8 +627,8 @@ err1:
1 Root was split
*/
-static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
- uint key_length, int ins_level)
+static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, byte *key,
+ uint key_length, int ins_level)
{
my_off_t old_root;
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
@@ -632,7 +641,7 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
if ((old_root = _ma_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
return -1;
- info->buff_used = 1;
+ info->keybuff_used = 1;
maria_putint(info->buff, 2, 0);
res = maria_rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
if (_ma_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
@@ -650,13 +659,12 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
}
case 1: /* root was split, grow a new root */
{
- uchar *new_root_buf;
+ byte *new_root_buf, *new_key;
my_off_t new_root;
- uchar *new_key;
uint nod_flag = info->s->base.key_reflength;
- if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length +
- HA_MAX_KEY_BUFF)))
+ if (!(new_root_buf= (byte*) my_alloca((uint)keyinfo->block_length +
+ HA_MAX_KEY_BUFF)))
{
my_errno = HA_ERR_OUT_OF_MEM;
return -1;
@@ -670,15 +678,19 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
new_key = new_root_buf + keyinfo->block_length + nod_flag;
_ma_kpointer(info, new_key - nod_flag, old_root);
- if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length, old_root))
+ if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length,
+ old_root))
goto err1;
- if (maria_rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL)
+ if (maria_rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf,
+ NULL)
== -1)
goto err1;
_ma_kpointer(info, new_key - nod_flag, new_page);
- if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length, new_page))
+ if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length,
+ new_page))
goto err1;
- if (maria_rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL)
+ if (maria_rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf,
+ NULL)
== -1)
goto err1;
if (_ma_write_keypage(info, keyinfo, new_root,
@@ -710,10 +722,11 @@ err1:
0 OK
*/
-int maria_rtree_insert(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
+int maria_rtree_insert(MARIA_HA *info, uint keynr, byte *key, uint key_length)
{
return (!key_length ||
- (maria_rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ? -1 : 0;
+ (maria_rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ?
+ -1 : 0;
}
@@ -756,18 +769,18 @@ err1:
2 Empty leaf
*/
-static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uint key_length, my_off_t page, uint *page_size,
- stPageList *ReinsertList, int level)
+static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *key,
+ uint key_length, my_off_t page,
+ uint *page_size,
+ stPageList *ReinsertList, int level)
{
- uchar *k;
- uchar *last;
ulong i;
uint nod_flag;
- uchar *page_buf;
int res;
+ byte *page_buf, *last, *k;
- if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
+ if (!(page_buf = (byte*) my_alloca((uint)keyinfo->block_length)))
{
my_errno = HA_ERR_OUT_OF_MEM;
return -1;
@@ -779,7 +792,7 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
last = rt_PAGE_END(page_buf);
- for (i = 0; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag), ++i)
+ for (i = 0; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag), i++)
{
if (nod_flag)
{
@@ -792,7 +805,8 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *
case 0: /* deleted */
{
/* test page filling */
- if (*page_size + key_length >= rt_PAGE_MIN_SIZE(keyinfo->block_length))
+ if (*page_size + key_length >=
+ rt_PAGE_MIN_SIZE(keyinfo->block_length))
{
/* OK */
if (maria_rtree_set_key_mbr(info, keyinfo, k, key_length,
@@ -805,7 +819,8 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *
else
{
/* too small: delete key & add it descendant to reinsert list */
- if (maria_rtree_fill_reinsert_list(ReinsertList, _ma_kpos(nod_flag, k),
+ if (maria_rtree_fill_reinsert_list(ReinsertList,
+ _ma_kpos(nod_flag, k),
level + 1))
goto err1;
maria_rtree_delete_key(info, page_buf, k, key_length, nod_flag);
@@ -883,7 +898,7 @@ err1:
0 Deleted
*/
-int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
+int maria_rtree_delete(MARIA_HA *info, uint keynr, byte *key, uint key_length)
{
uint page_size;
stPageList ReinsertList;
@@ -914,12 +929,10 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
ulong i;
for (i = 0; i < ReinsertList.n_pages; ++i)
{
- uchar *page_buf;
uint nod_flag;
- uchar *k;
- uchar *last;
+ byte *page_buf, *k, *last;
- if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
+ if (!(page_buf = (byte*) my_alloca((uint)keyinfo->block_length)))
{
my_errno = HA_ERR_OUT_OF_MEM;
goto err1;
@@ -935,11 +948,11 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
if (maria_rtree_insert_level(info, keynr, k, key_length,
ReinsertList.pages[i].level) == -1)
{
- my_afree((byte*)page_buf);
+ my_afree(page_buf);
goto err1;
}
}
- my_afree((byte*)page_buf);
+ my_afree(page_buf);
if (_ma_dispose(info, keyinfo, ReinsertList.pages[i].offs,
DFLT_INIT_HITS))
goto err1;
@@ -969,16 +982,14 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
err1:
return -1;
}
- case 1: /* not found */
+ case 1: /* not found */
{
my_errno = HA_ERR_KEY_NOT_FOUND;
return -1;
}
default:
- case -1: /* error */
- {
+ case -1: /* error */
return -1;
- }
}
}
@@ -990,17 +1001,14 @@ err1:
estimated value
*/
-ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
+ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, byte *key,
uint key_length, uint flag)
{
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
my_off_t root;
uint i = 0;
- uchar *k;
- uchar *last;
- uint nod_flag;
- uchar *page_buf;
- uint k_len;
+ uint nod_flag, k_len;
+ byte *page_buf, *k, *last;
double area = 0;
ha_rows res = 0;
@@ -1009,7 +1017,7 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
return HA_POS_ERROR;
- if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
+ if (!(page_buf= (byte*) my_alloca((uint)keyinfo->block_length)))
return HA_POS_ERROR;
if (!_ma_fetch_keypage(info, keyinfo, root, DFLT_INIT_HITS, page_buf, 0))
goto err1;
@@ -1020,7 +1028,7 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
last = rt_PAGE_END(page_buf);
- for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag), ++i)
+ for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag), i++)
{
if (nod_flag)
{
@@ -1035,7 +1043,8 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
}
else if (flag & (MBR_WITHIN | MBR_EQUAL))
{
- if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN))
+ if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length,
+ MBR_WITHIN))
area += 1;
}
else
@@ -1045,14 +1054,15 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
{
if (flag & (MBR_CONTAIN | MBR_INTERSECT))
{
- area += maria_rtree_overlapping_area(keyinfo->seg, key, k, key_length) /
- k_area;
+ area+= maria_rtree_overlapping_area(keyinfo->seg, key, k,
+ key_length) / k_area;
}
else if (flag & (MBR_WITHIN | MBR_EQUAL))
{
- if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN))
- area += maria_rtree_rect_volume(keyinfo->seg, key, key_length) /
- k_area;
+ if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length,
+ MBR_WITHIN))
+ area+= (maria_rtree_rect_volume(keyinfo->seg, key, key_length) /
+ k_area);
}
else
goto err1;
@@ -1076,7 +1086,7 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
return res;
err1:
- my_afree((byte*)page_buf);
+ my_afree(page_buf);
return HA_POS_ERROR;
}
diff --git a/storage/maria/ma_rt_index.h b/storage/maria/ma_rt_index.h
index ff431d81372..76b6c6e230c 100644
--- a/storage/maria/ma_rt_index.h
+++ b/storage/maria/ma_rt_index.h
@@ -27,21 +27,22 @@
#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length) / 3)
-int maria_rtree_insert(MARIA_HA *info, uint keynr, uchar *key, uint key_length);
-int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length);
+int maria_rtree_insert(MARIA_HA *info, uint keynr, byte *key, uint key_length);
+int maria_rtree_delete(MARIA_HA *info, uint keynr, byte *key, uint key_length);
-int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key, uint key_length,
- uint search_flag);
+int maria_rtree_find_first(MARIA_HA *info, uint keynr, byte *key,
+ uint key_length, uint search_flag);
int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag);
int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length);
int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length);
-ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
- uint key_length, uint flag);
+ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, byte *key,
+ uint key_length, uint flag);
-int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_length, my_off_t *new_page_offs);
+int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint key_length,
+ my_off_t *new_page_offs);
#endif /*HAVE_RTREE_KEYS*/
#endif /* _rt_index_h */
diff --git a/storage/maria/ma_rt_key.c b/storage/maria/ma_rt_key.c
index 2732fefffbe..1453195d263 100644
--- a/storage/maria/ma_rt_key.c
+++ b/storage/maria/ma_rt_key.c
@@ -30,8 +30,8 @@
1 Split
*/
-int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uint key_length, uchar *page_buf, my_off_t *new_page)
+int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
+ uint key_length, byte *page_buf, my_off_t *new_page)
{
uint page_size = maria_getint(page_buf);
uint nod_flag = _ma_test_if_nod(page_buf);
@@ -61,14 +61,16 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
new_page) ? -1 : 1);
}
+
/*
Delete key from the page
*/
-int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
+
+int maria_rtree_delete_key(MARIA_HA *info, byte *page_buf, byte *key,
uint key_length, uint nod_flag)
{
uint16 page_size = maria_getint(page_buf);
- uchar *key_start;
+ byte *key_start;
key_start= key - nod_flag;
if (!nod_flag)
@@ -87,7 +89,7 @@ int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
Calculate and store key MBR
*/
-int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
+int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
uint key_length, my_off_t child_page)
{
if (!_ma_fetch_keypage(info, keyinfo, child_page,
diff --git a/storage/maria/ma_rt_key.h b/storage/maria/ma_rt_key.h
index 448024ed8c5..f44251782c1 100644
--- a/storage/maria/ma_rt_key.h
+++ b/storage/maria/ma_rt_key.h
@@ -22,12 +22,12 @@
#ifdef HAVE_RTREE_KEYS
-int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uint key_length, uchar *page_buf, my_off_t *new_page);
-int maria_rtree_delete_key(MARIA_HA *info, uchar *page, uchar *key,
- uint key_length, uint nod_flag);
-int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uint key_length, my_off_t child_page);
+int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
+ uint key_length, byte *page_buf, my_off_t *new_page);
+int maria_rtree_delete_key(MARIA_HA *info, byte *page, byte *key,
+ uint key_length, uint nod_flag);
+int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
+ uint key_length, my_off_t child_page);
#endif /*HAVE_RTREE_KEYS*/
#endif /* _rt_key_h */
diff --git a/storage/maria/ma_rt_mbr.c b/storage/maria/ma_rt_mbr.c
index 67b1d59f505..851618a4300 100644
--- a/storage/maria/ma_rt_mbr.c
+++ b/storage/maria/ma_rt_mbr.c
@@ -93,8 +93,9 @@
MBR_DATA(a,b) Data reference is the same
Returns 0 on success.
*/
-int maria_rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length,
- uint nextflag)
+
+int maria_rtree_key_cmp(HA_KEYSEG *keyseg, byte *b, byte *a, uint key_length,
+ uint nextflag)
{
for (; (int) key_length > 0; keyseg += 2 )
{
@@ -153,7 +154,7 @@ int maria_rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length,
end:
if (nextflag & MBR_DATA)
{
- uchar *end = a + keyseg->length;
+ byte *end = a + keyseg->length;
do
{
if (*a++ != *b++)
@@ -182,7 +183,7 @@ end:
/*
Calculates rectangle volume
*/
-double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
+double maria_rtree_rect_volume(HA_KEYSEG *keyseg, byte *a, uint key_length)
{
double res = 1;
for (; (int)key_length > 0; keyseg += 2)
@@ -263,7 +264,7 @@ double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
Creates an MBR as an array of doubles.
*/
-int maria_rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
+int maria_rtree_d_mbr(HA_KEYSEG *keyseg, byte *a, uint key_length, double *res)
{
for (; (int)key_length > 0; keyseg += 2)
{
@@ -352,7 +353,7 @@ int maria_rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
Result is written to c
*/
-int maria_rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
+int maria_rtree_combine_rect(HA_KEYSEG *keyseg, byte* a, byte* b, byte* c,
uint key_length)
{
for ( ; (int) key_length > 0 ; keyseg += 2)
@@ -443,7 +444,7 @@ int maria_rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
/*
Calculates overlapping area of two MBRs a & b
*/
-double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
+double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, byte* a, byte* b,
uint key_length)
{
double res = 1;
@@ -525,10 +526,11 @@ double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
}
/*
-Calculates MBR_AREA(a+b) - MBR_AREA(a)
+ Calculates MBR_AREA(a+b) - MBR_AREA(a)
*/
-double maria_rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
- uint key_length, double *ab_area)
+
+double maria_rtree_area_increase(HA_KEYSEG *keyseg, byte *a, byte *b,
+ uint key_length, double *ab_area)
{
double a_area= 1.0;
double loc_ab_area= 1.0;
@@ -620,7 +622,7 @@ safe_end:
/*
Calculates MBR_PERIMETER(a+b) - MBR_PERIMETER(a)
*/
-double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
+double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, byte* a, byte* b,
uint key_length, double *ab_perim)
{
double a_perim = 0.0;
@@ -731,16 +733,16 @@ double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
}
/*
-Calculates key page total MBR = MBR(key1) + MBR(key2) + ...
+ Calculates key page total MBR = MBR(key1) + MBR(key2) + ...
*/
-int maria_rtree_page_mbr(MARIA_HA *info, HA_KEYSEG *keyseg, uchar *page_buf,
- uchar *c, uint key_length)
+int maria_rtree_page_mbr(MARIA_HA *info, HA_KEYSEG *keyseg, byte *page_buf,
+ byte *c, uint key_length)
{
uint inc = 0;
uint k_len = key_length;
uint nod_flag = _ma_test_if_nod(page_buf);
- uchar *k;
- uchar *last = rt_PAGE_END(page_buf);
+ byte *k;
+ byte *last = rt_PAGE_END(page_buf);
for (; (int)key_length > 0; keyseg += 2)
{
diff --git a/storage/maria/ma_rt_mbr.h b/storage/maria/ma_rt_mbr.h
index 81e2a6851d4..3282ee0d7a3 100644
--- a/storage/maria/ma_rt_mbr.h
+++ b/storage/maria/ma_rt_mbr.h
@@ -20,19 +20,20 @@
#ifdef HAVE_RTREE_KEYS
-int maria_rtree_key_cmp(HA_KEYSEG *keyseg, uchar *a, uchar *b, uint key_length,
- uint nextflag);
-int maria_rtree_combine_rect(HA_KEYSEG *keyseg,uchar *, uchar *, uchar*,
- uint key_length);
-double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar*, uint key_length);
-int maria_rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res);
-double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, uchar *a, uchar *b,
- uint key_length);
-double maria_rtree_area_increase(HA_KEYSEG *keyseg, uchar *a, uchar *b,
- uint key_length, double *ab_area);
-double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
- uint key_length, double *ab_perim);
-int maria_rtree_page_mbr(MARIA_HA *info, HA_KEYSEG *keyseg, uchar *page_buf,
- uchar* c, uint key_length);
+int maria_rtree_key_cmp(HA_KEYSEG *keyseg, byte *a, byte *b, uint key_length,
+ uint nextflag);
+int maria_rtree_combine_rect(HA_KEYSEG *keyseg,byte *, byte *, byte*,
+ uint key_length);
+double maria_rtree_rect_volume(HA_KEYSEG *keyseg, byte*, uint key_length);
+int maria_rtree_d_mbr(HA_KEYSEG *keyseg, byte *a, uint key_length,
+ double *res);
+double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, byte *a, byte *b,
+ uint key_length);
+double maria_rtree_area_increase(HA_KEYSEG *keyseg, byte *a, byte *b,
+ uint key_length, double *ab_area);
+double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, byte* a, byte* b,
+ uint key_length, double *ab_perim);
+int maria_rtree_page_mbr(MARIA_HA *info, HA_KEYSEG *keyseg, byte *page_buf,
+ byte* c, uint key_length);
#endif /*HAVE_RTREE_KEYS*/
#endif /* _rt_mbr_h */
diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c
index 034799efd89..00c8d18f5e5 100644
--- a/storage/maria/ma_rt_split.c
+++ b/storage/maria/ma_rt_split.c
@@ -27,7 +27,7 @@ typedef struct
{
double square;
int n_node;
- uchar *key;
+ byte *key;
double *coords;
} SplitStruct;
@@ -243,8 +243,9 @@ static int split_maria_rtree_node(SplitStruct *node, int n_entries,
return 0;
}
-int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page, uchar *key,
- uint key_length, my_off_t *new_page_offs)
+int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *page, byte *key,
+ uint key_length, my_off_t *new_page_offs)
{
int n1, n2; /* Number of items in groups */
@@ -255,8 +256,8 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page, u
double *next_coord;
double *old_coord;
int n_dim;
- uchar *source_cur, *cur1, *cur2;
- uchar *new_page;
+ byte *source_cur, *cur1, *cur2;
+ byte *new_page;
int err_code= 0;
uint nod_flag= _ma_test_if_nod(page);
uint full_length= key_length + (nod_flag ? nod_flag :
@@ -300,7 +301,7 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page, u
goto split_err;
}
- if (!(new_page = (uchar*)my_alloca((uint)keyinfo->block_length)))
+ if (!(new_page = (byte*) my_alloca((uint)keyinfo->block_length)))
{
err_code= -1;
goto split_err;
@@ -313,7 +314,7 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page, u
n1= n2 = 0;
for (cur = task; cur < stop; ++cur)
{
- uchar *to;
+ byte *to;
if (cur->n_node == 1)
{
to = cur1;
diff --git a/storage/maria/ma_rt_test.c b/storage/maria/ma_rt_test.c
index ca4825c2ce2..04b0c88c222 100644
--- a/storage/maria/ma_rt_test.c
+++ b/storage/maria/ma_rt_test.c
@@ -153,10 +153,11 @@ static int run_test(const char *filename)
create_info.max_rows=10000000;
if (maria_create(filename,
- 1, /* keys */
- keyinfo,
- 1+2*ndims+opt_unique, /* columns */
- recinfo,uniques,&uniquedef,&create_info,create_flag))
+ DYNAMIC_RECORD,
+ 1, /* keys */
+ keyinfo,
+ 1+2*ndims+opt_unique, /* columns */
+ recinfo,uniques,&uniquedef,&create_info,create_flag))
goto err;
if (!silent)
diff --git a/storage/maria/ma_scan.c b/storage/maria/ma_scan.c
index c9c988722b7..4538c87e2be 100644
--- a/storage/maria/ma_scan.c
+++ b/storage/maria/ma_scan.c
@@ -21,26 +21,41 @@
int maria_scan_init(register MARIA_HA *info)
{
DBUG_ENTER("maria_scan_init");
- info->nextpos=info->s->pack.header_length; /* Read first record */
+
+ info->cur_row.nextpos= info->s->pack.header_length; /* Read first record */
info->lastinx= -1; /* Can't forward or backward */
if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache))
DBUG_RETURN(my_errno);
+
+ if ((*info->s->scan_init)(info))
+ DBUG_RETURN(my_errno);
DBUG_RETURN(0);
}
/*
- Read a row based on position.
- If filepos= HA_OFFSET_ERROR then read next row
- Return values
- Returns one of following values:
- 0 = Ok.
- HA_ERR_END_OF_FILE = EOF.
+ Read a row based on position.
+
+ SYNOPSIS
+ maria_scan()
+ info Maria handler
+ record Read data here
+
+ RETURN
+ 0 ok
+ HA_ERR_END_OF_FILE End of file
+ # Error code
*/
-int maria_scan(MARIA_HA *info, byte *buf)
+int maria_scan(MARIA_HA *info, byte *record)
{
DBUG_ENTER("maria_scan");
/* Init all but update-flag */
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
- DBUG_RETURN ((*info->s->read_rnd)(info,buf,info->nextpos,1));
+ DBUG_RETURN((*info->s->scan)(info, record, info->cur_row.nextpos, 1));
+}
+
+
+void maria_scan_end(MARIA_HA *info)
+{
+ (*info->s->scan_end)(info);
}
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index af25be06a09..d8738ae4639 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -19,8 +19,9 @@
#include "ma_fulltext.h"
#include "m_ctype.h"
-static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos,
+static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *page,
+ byte *key, byte *keypos,
uint *return_key_length);
/* Check index */
@@ -55,31 +56,32 @@ int _ma_check_index(MARIA_HA *info, int inx)
*/
int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_len, uint nextflag, register my_off_t pos)
+ byte *key, uint key_len, uint nextflag, register my_off_t pos)
{
my_bool last_key;
int error,flag;
uint nod_flag;
- uchar *keypos,*maxpos;
- uchar lastkey[HA_MAX_KEY_BUFF],*buff;
+ byte *keypos,*maxpos;
+ byte lastkey[HA_MAX_KEY_BUFF],*buff;
DBUG_ENTER("_ma_search");
DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu",
- (ulong) pos, nextflag, (ulong) info->lastpos));
+ (ulong) pos, nextflag, (ulong) info->cur_row.lastpos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,key_len););
if (pos == HA_OFFSET_ERROR)
{
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
DBUG_RETURN(-1); /* Not found ; return error */
DBUG_RETURN(1); /* Search at upper levels */
}
- if (!(buff= _ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
+ if (!(buff= _ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,
+ info->keyread_buff,
test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
- DBUG_DUMP("page",(byte*) buff,maria_getint(buff));
+ DBUG_DUMP("page", buff, maria_getint(buff));
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
&keypos,lastkey, &last_key);
@@ -118,9 +120,10 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
}
if (pos != info->last_keypage)
{
- uchar *old_buff=buff;
- if (!(buff= _ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)))))
+ byte *old_buff=buff;
+ if (!(buff= _ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,
+ info->keyread_buff,
+ test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
keypos=buff+(keypos-old_buff);
maxpos=buff+(maxpos-old_buff);
@@ -133,8 +136,8 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
&info->lastkey_length))
goto err;
if (!(nextflag & SEARCH_SMALLER) &&
- ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
- not_used))
+ ha_key_cmp(keyinfo->seg, (uchar*) info->lastkey, (uchar*) key, key_len,
+ SEARCH_FIND, not_used))
{
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
goto err;
@@ -147,22 +150,22 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
goto err;
memcpy(info->lastkey,lastkey,info->lastkey_length);
}
- info->lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
+ info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
/* Save position for a possible read next / previous */
- info->int_keypos=info->buff+ (keypos-buff);
- info->int_maxpos=info->buff+ (maxpos-buff);
+ info->int_keypos= info->keyread_buff+ (keypos-buff);
+ info->int_maxpos= info->keyread_buff+ (maxpos-buff);
info->int_nod_flag=nod_flag;
info->int_keytree_version=keyinfo->version;
info->last_search_keypage=info->last_keypage;
info->page_changed=0;
- info->buff_used= (info->buff != buff); /* If we have to reread buff */
+ info->keybuff_used= (info->keyread_buff != buff); /* If we have to reread */
- DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
+ DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
DBUG_RETURN(0);
err:
DBUG_PRINT("exit",("Error: %d",my_errno));
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
info->page_changed=1;
DBUG_RETURN (-1);
} /* _ma_search */
@@ -173,9 +176,9 @@ err:
/* ret_pos point to where find or bigger key starts */
/* ARGSUSED */
-int _ma_bin_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
- uchar *buff __attribute__((unused)), my_bool *last_key)
+int _ma_bin_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint key_len, uint comp_flag, byte **ret_pos,
+ byte *buff __attribute__((unused)), my_bool *last_key)
{
reg4 int start,mid,end,save_end;
int flag;
@@ -192,16 +195,16 @@ int _ma_bin_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
while (start != end)
{
mid= (start+end)/2;
- if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len,
- comp_flag, not_used))
+ if ((flag=ha_key_cmp(keyinfo->seg,(uchar*) page+(uint) mid*totlength,
+ (uchar*) key, key_len, comp_flag, not_used))
>= 0)
end=mid;
else
start=mid+1;
}
if (mid != start)
- flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len,
- comp_flag, not_used);
+ flag=ha_key_cmp(keyinfo->seg, (uchar*) page+(uint) start*totlength,
+ (uchar*) key, key_len, comp_flag, not_used);
if (flag < 0)
start++; /* point at next, bigger key */
*ret_pos=page+(uint) start*totlength;
@@ -237,13 +240,13 @@ int _ma_bin_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
< 0 Not found.
*/
-int _ma_seq_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
- uchar *buff, my_bool *last_key)
+int _ma_seq_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint key_len, uint comp_flag, byte **ret_pos,
+ byte *buff, my_bool *last_key)
{
int flag;
uint nod_flag,length,not_used[2];
- uchar t_buff[HA_MAX_KEY_BUFF],*end;
+ byte t_buff[HA_MAX_KEY_BUFF],*end;
DBUG_ENTER("_ma_seq_search");
LINT_INIT(flag); LINT_INIT(length);
@@ -264,8 +267,8 @@ int _ma_seq_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
length, (long) page, (long) end));
DBUG_RETURN(MARIA_FOUND_WRONG_KEY);
}
- if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
- not_used)) >= 0)
+ if ((flag= ha_key_cmp(keyinfo->seg, (uchar*) t_buff,(uchar*) key,
+ key_len,comp_flag, not_used)) >= 0)
break;
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("page: 0x%lx key: '%s' flag: %d", (long) page, t_buff,
@@ -282,9 +285,9 @@ int _ma_seq_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
} /* _ma_seq_search */
-int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
- uchar *buff, my_bool *last_key)
+int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
+ byte *page, byte *key, uint key_len, uint nextflag,
+ byte **ret_pos, byte *buff, my_bool *last_key)
{
/*
my_flag is raw comparison result to be changed according to
@@ -295,10 +298,11 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
uint nod_flag, length, len, matched, cmplen, kseg_len;
uint prefix_len,suffix_len;
int key_len_skip, seg_len_pack, key_len_left;
- uchar *end, *kseg, *vseg;
- uchar *sort_order=keyinfo->seg->charset->sort_order;
- uchar tt_buff[HA_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
- uchar *saved_from, *saved_to, *saved_vseg;
+ byte *end;
+ uchar *kseg, *vseg, *saved_vseg, *saved_from;
+ uchar *sort_order= keyinfo->seg->charset->sort_order;
+ byte tt_buff[HA_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
+ byte *saved_to;
uint saved_length=0, saved_prefix_len=0;
uint length_pack;
DBUG_ENTER("_ma_prefix_search");
@@ -315,9 +319,9 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
nod_flag=_ma_test_if_nod(page);
page+=2+nod_flag;
*ret_pos=page;
- kseg=key;
+ kseg= (uchar*) key;
- get_key_pack_length(kseg_len,length_pack,kseg);
+ get_key_pack_length(kseg_len, length_pack, kseg);
key_len_skip=length_pack+kseg_len;
key_len_left=(int) key_len- (int) key_len_skip;
/* If key_len is 0, then lenght_pack is 1, then key_len_left is -1. */
@@ -344,7 +348,7 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
{
uint packed= *page & 128;
- vseg=page;
+ vseg= (uchar*) page;
if (keyinfo->seg->length >= 127)
{
suffix_len=mi_uint2korr(vseg) & 32767;
@@ -387,7 +391,7 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,
suffix_len,vseg));
{
- uchar *from=vseg+suffix_len;
+ uchar *from= vseg+suffix_len;
HA_KEYSEG *keyseg;
uint l;
@@ -408,9 +412,9 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
from+=l;
}
- from+=keyseg->length;
- page=from+nod_flag;
- length=from-vseg;
+ from+= keyseg->length;
+ page= (byte*) from+nod_flag;
+ length= (uint) (from-vseg);
}
if (page > end)
@@ -427,7 +431,7 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
{
/* We have to compare. But we can still skip part of the key */
uint left;
- uchar *k=kseg+prefix_len;
+ uchar *k= kseg+prefix_len;
/*
If prefix_len > cmplen then we are in the end-space comparison
@@ -477,7 +481,7 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
for ( ; k < end && *k == ' '; k++) ;
if (k == end)
goto cmp_rest; /* should never happen */
- if (*k < (uchar) ' ')
+ if ((uchar) *k < (uchar) ' ')
{
my_flag= 1; /* Compared string is smaller */
break;
@@ -493,11 +497,11 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
/* We have to compare k and vseg as if they were space extended */
for (end=vseg + (len-cmplen) ;
- vseg < end && *vseg == (uchar) ' ';
+ vseg < end && *vseg == (byte) ' ';
vseg++, matched++) ;
DBUG_ASSERT(vseg < end);
- if (*vseg > (uchar) ' ')
+ if ((uchar) *vseg > (uchar) ' ')
{
my_flag= 1; /* Compared string is smaller */
break;
@@ -534,8 +538,8 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
/* else (matched < prefix_len) ---> do nothing. */
memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
- saved_to=buff+saved_length;
- saved_from=saved_vseg;
+ saved_to= buff+saved_length;
+ saved_from= saved_vseg;
saved_length=length;
*ret_pos=page;
}
@@ -544,12 +548,12 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
if (flag == 0)
{
memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
- saved_to=buff+saved_length;
- saved_from=saved_vseg;
+ saved_to= buff+saved_length;
+ saved_from= saved_vseg;
saved_length=length;
}
if (saved_length)
- memcpy(saved_to,saved_from,saved_length);
+ memcpy(saved_to, (byte*) saved_from, saved_length);
*last_key= page == end;
@@ -560,7 +564,7 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *pag
/* Get pos to a key_block */
-my_off_t _ma_kpos(uint nod_flag, uchar *after_key)
+my_off_t _ma_kpos(uint nod_flag, byte *after_key)
{
after_key-=nod_flag;
switch (nod_flag) {
@@ -596,7 +600,7 @@ my_off_t _ma_kpos(uint nod_flag, uchar *after_key)
/* Save pos to a key_block */
-void _ma_kpointer(register MARIA_HA *info, register uchar *buff, my_off_t pos)
+void _ma_kpointer(register MARIA_HA *info, register byte *buff, my_off_t pos)
{
pos/=MARIA_MIN_KEY_BLOCK_LENGTH;
switch (info->s->base.key_reflength) {
@@ -615,7 +619,7 @@ void _ma_kpointer(register MARIA_HA *info, register uchar *buff, my_off_t pos)
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
case 2: mi_int2store(buff,(uint) pos); break;
- case 1: buff[0]= (uchar) pos; break;
+ case 1: buff[0]= (char) (uchar) pos; break;
default: abort(); /* impossible */
}
} /* _ma_kpointer */
@@ -624,7 +628,7 @@ void _ma_kpointer(register MARIA_HA *info, register uchar *buff, my_off_t pos)
/* Calc pos to a data-record from a key */
-my_off_t _ma_dpos(MARIA_HA *info, uint nod_flag, uchar *after_key)
+my_off_t _ma_dpos(MARIA_HA *info, uint nod_flag, const byte *after_key)
{
my_off_t pos;
after_key-=(nod_flag + info->s->rec_reflength);
@@ -646,15 +650,14 @@ my_off_t _ma_dpos(MARIA_HA *info, uint nod_flag, uchar *after_key)
default:
pos=0L; /* Shut compiler up */
}
- return (info->s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
- pos*info->s->base.pack_reclength;
+ return ((info->s->data_file_type == STATIC_RECORD) ?
+ pos * info->s->base.pack_reclength : pos);
}
/* Calc position from a record pointer ( in delete link chain ) */
-my_off_t _ma_rec_pos(MARIA_SHARE *s, uchar *ptr)
+my_off_t _ma_rec_pos(MARIA_SHARE *s, byte *ptr)
{
my_off_t pos;
switch (s->rec_reflength) {
@@ -704,20 +707,18 @@ my_off_t _ma_rec_pos(MARIA_SHARE *s, uchar *ptr)
break;
default: abort(); /* Impossible */
}
- return ((s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
- pos*s->base.pack_reclength);
+ return ((s->data_file_type == STATIC_RECORD) ?
+ pos * s->base.pack_reclength : pos);
}
/* save position to record */
-void _ma_dpointer(MARIA_HA *info, uchar *buff, my_off_t pos)
+void _ma_dpointer(MARIA_HA *info, byte *buff, my_off_t pos)
{
- if (!(info->s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
+ if (info->s->data_file_type == STATIC_RECORD &&
pos != HA_OFFSET_ERROR)
- pos/=info->s->base.pack_reclength;
+ pos/= info->s->base.pack_reclength;
switch (info->s->rec_reflength) {
#if SIZEOF_OFF_T > 4
@@ -752,7 +753,7 @@ void _ma_dpointer(MARIA_HA *info, uchar *buff, my_off_t pos)
/* same as _ma_get_key but used with fixed length keys */
uint _ma_get_static_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page, register uchar *key)
+ register byte **page, register byte *key)
{
memcpy((byte*) key,(byte*) *page,
(size_t) (keyinfo->keylength+nod_flag));
@@ -776,10 +777,10 @@ uint _ma_get_static_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
*/
uint _ma_get_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page_pos, register uchar *key)
+ register byte **page_pos, register byte *key)
{
reg1 HA_KEYSEG *keyseg;
- uchar *start_key,*page=*page_pos;
+ byte *start_key,*page=*page_pos;
uint length;
start_key=key;
@@ -788,7 +789,7 @@ uint _ma_get_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
if (keyseg->flag & HA_PACK_KEY)
{
/* key with length, packed to previous key */
- uchar *start=key;
+ byte *start= key;
uint packed= *page & 128,tot_length,rest_length;
if (keyseg->length >= 127)
{
@@ -834,7 +835,7 @@ uint _ma_get_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
tot_length=rest_length+length;
/* If the stored length has changed, we must move the key */
- if (tot_length >= 255 && *start != 255)
+ if (tot_length >= 255 && *start != (char) 255)
{
/* length prefix changed from a length of one to a length of 3 */
bmove_upp((char*) key+length+3,(char*) key+length+1,length);
@@ -842,7 +843,7 @@ uint _ma_get_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
mi_int2store(key+1,tot_length);
key+=3+length;
}
- else if (tot_length < 255 && *start == 255)
+ else if (tot_length < 255 && *start == (char) 255)
{
bmove(key+1,key+3,length);
*key=tot_length;
@@ -891,7 +892,7 @@ uint _ma_get_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
if (keyseg->flag &
(HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
{
- uchar *tmp=page;
+ byte *tmp=page;
get_key_length(length,tmp);
length+=(uint) (tmp-page);
}
@@ -913,10 +914,10 @@ uint _ma_get_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
/* key that is packed relatively to previous */
uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page_pos, register uchar *key)
+ register byte **page_pos, register byte *key)
{
reg1 HA_KEYSEG *keyseg;
- uchar *start_key,*page,*page_end,*from,*from_end;
+ byte *start_key,*page,*page_end,*from,*from_end;
uint length,tmp;
DBUG_ENTER("_ma_get_binary_pack_key");
@@ -1018,8 +1019,8 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
/* Get key at position without knowledge of previous key */
/* Returns pointer to next key */
-uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos, uint *return_key_length)
+byte *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, byte *keypos, uint *return_key_length)
{
uint nod_flag;
DBUG_ENTER("_ma_get_key");
@@ -1054,8 +1055,8 @@ uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
/* Get key at position without knowledge of previous key */
/* Returns 0 if ok */
-static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos,
+static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *page, byte *key, byte *keypos,
uint *return_key_length)
{
uint nod_flag;
@@ -1092,11 +1093,11 @@ static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *pa
/* Get last key from key-page */
/* Return pointer to where key starts */
-uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *lastkey, uchar *endpos, uint *return_key_length)
+byte *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *page,
+ byte *lastkey, byte *endpos, uint *return_key_length)
{
uint nod_flag;
- uchar *lastpos;
+ byte *lastpos;
DBUG_ENTER("_ma_get_last_key");
DBUG_PRINT("enter",("page: 0x%lx endpos: 0x%lx", (long) page,
(long) endpos));
@@ -1135,15 +1136,15 @@ uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
/* Calculate length of key */
-uint _ma_keylength(MARIA_KEYDEF *keyinfo, register uchar *key)
+uint _ma_keylength(MARIA_KEYDEF *keyinfo, register const byte *key)
{
reg1 HA_KEYSEG *keyseg;
- uchar *start;
+ const byte *start;
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
return (keyinfo->keylength);
- start=key;
+ start= key;
for (keyseg=keyinfo->seg ; keyseg->type ; keyseg++)
{
if (keyseg->flag & HA_NULL_PART)
@@ -1170,11 +1171,11 @@ uint _ma_keylength(MARIA_KEYDEF *keyinfo, register uchar *key)
after '0xDF' but find 'ss'
*/
-uint _ma_keylength_part(MARIA_KEYDEF *keyinfo, register uchar *key,
+uint _ma_keylength_part(MARIA_KEYDEF *keyinfo, register const byte *key,
HA_KEYSEG *end)
{
reg1 HA_KEYSEG *keyseg;
- uchar *start= key;
+ const byte *start= key;
for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++)
{
@@ -1193,29 +1194,35 @@ uint _ma_keylength_part(MARIA_KEYDEF *keyinfo, register uchar *key,
return (uint) (key-start);
}
- /* Move a key */
-uchar *_ma_move_key(MARIA_KEYDEF *keyinfo, uchar *to, uchar *from)
+/* Move a key */
+
+byte *_ma_move_key(MARIA_KEYDEF *keyinfo, byte *to, const byte *from)
{
reg1 uint length;
- memcpy((byte*) to, (byte*) from,
- (size_t) (length= _ma_keylength(keyinfo,from)));
+ memcpy(to, from, (size_t) (length= _ma_keylength(keyinfo, from)));
return to+length;
}
- /* Find next/previous record with same key */
- /* This can't be used when database is touched after last read */
+
+/*
+ Find next/previous record with same key
+
+ WARNING
+ This can't be used when database is touched after last read
+*/
int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_length, uint nextflag, my_off_t pos)
+ byte *key, uint key_length, uint nextflag, my_off_t pos)
{
int error;
uint nod_flag;
- uchar lastkey[HA_MAX_KEY_BUFF];
+ byte lastkey[HA_MAX_KEY_BUFF];
DBUG_ENTER("_ma_search_next");
- DBUG_PRINT("enter",("nextflag: %u lastpos: %lu int_keypos: %lu",
- nextflag, (ulong) info->lastpos,
- (ulong) info->int_keypos));
+ DBUG_PRINT("enter",("nextflag: %u lastpos: %lu int_keypos: %lu page_changed %d keybuff_used: %d",
+ nextflag, (ulong) info->cur_row.lastpos,
+ (ulong) info->int_keypos,
+ info->page_changed, info->keybuff_used));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
/* Force full read if we are at last key or if we are not on a leaf
@@ -1228,20 +1235,20 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) ||
info->page_changed ||
(info->int_keytree_version != keyinfo->version &&
- (info->int_nod_flag || info->buff_used)))
+ (info->int_nod_flag || info->keybuff_used)))
DBUG_RETURN(_ma_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF, pos));
- if (info->buff_used)
+ if (info->keybuff_used)
{
if (!_ma_fetch_keypage(info,keyinfo,info->last_search_keypage,
- DFLT_INIT_HITS,info->buff,0))
+ DFLT_INIT_HITS,info->keyread_buff,0))
DBUG_RETURN(-1);
- info->buff_used=0;
+ info->keybuff_used=0;
}
- /* Last used buffer is in info->buff */
- nod_flag=_ma_test_if_nod(info->buff);
+ /* Last used buffer is in info->keyread_buff */
+ nod_flag=_ma_test_if_nod(info->keyread_buff);
if (nextflag & SEARCH_BIGGER) /* Next key */
{
@@ -1261,11 +1268,11 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
{
uint length;
/* Find start of previous key */
- info->int_keypos= _ma_get_last_key(info,keyinfo,info->buff,lastkey,
+ info->int_keypos= _ma_get_last_key(info,keyinfo,info->keyread_buff,lastkey,
info->int_keypos, &length);
if (!info->int_keypos)
DBUG_RETURN(-1);
- if (info->int_keypos == info->buff+2)
+ if (info->int_keypos == info->keyread_buff+2)
DBUG_RETURN(_ma_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF, pos));
if ((error= _ma_search(info,keyinfo,key, USE_WHOLE_KEY,
@@ -1274,84 +1281,84 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
DBUG_RETURN(error);
/* QQ: We should be able to optimize away the following call */
- if (! _ma_get_last_key(info,keyinfo,info->buff,lastkey,
+ if (! _ma_get_last_key(info,keyinfo,info->keyread_buff,lastkey,
info->int_keypos,&info->lastkey_length))
DBUG_RETURN(-1);
}
memcpy(info->lastkey,lastkey,info->lastkey_length);
- info->lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
- DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
+ info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
+ DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
DBUG_RETURN(0);
} /* _ma_search_next */
/* Search after position for the first row in an index */
- /* This is stored in info->lastpos */
+ /* This is stored in info->cur_row.lastpos */
int _ma_search_first(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
register my_off_t pos)
{
uint nod_flag;
- uchar *page;
+ byte *page;
DBUG_ENTER("_ma_search_first");
if (pos == HA_OFFSET_ERROR)
{
my_errno=HA_ERR_KEY_NOT_FOUND;
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
do
{
- if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,0))
+ if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->keyread_buff,0))
{
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
- nod_flag=_ma_test_if_nod(info->buff);
- page=info->buff+2+nod_flag;
+ nod_flag=_ma_test_if_nod(info->keyread_buff);
+ page=info->keyread_buff+2+nod_flag;
} while ((pos= _ma_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
info->lastkey)))
DBUG_RETURN(-1); /* Crashed */
- info->int_keypos=page; info->int_maxpos=info->buff+maria_getint(info->buff)-1;
+ info->int_keypos=page; info->int_maxpos=info->keyread_buff+maria_getint(info->keyread_buff)-1;
info->int_nod_flag=nod_flag;
info->int_keytree_version=keyinfo->version;
info->last_search_keypage=info->last_keypage;
- info->page_changed=info->buff_used=0;
- info->lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
+ info->page_changed=info->keybuff_used=0;
+ info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
- DBUG_PRINT("exit",("found key at %lu", (ulong) info->lastpos));
+ DBUG_PRINT("exit",("found key at %lu", (ulong) info->cur_row.lastpos));
DBUG_RETURN(0);
} /* _ma_search_first */
/* Search after position for the last row in an index */
- /* This is stored in info->lastpos */
+ /* This is stored in info->cur_row.lastpos */
int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
register my_off_t pos)
{
uint nod_flag;
- uchar *buff,*page;
+ byte *buff,*page;
DBUG_ENTER("_ma_search_last");
if (pos == HA_OFFSET_ERROR)
{
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
- buff=info->buff;
+ buff=info->keyread_buff;
do
{
if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
{
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
page= buff+maria_getint(buff);
@@ -1361,14 +1368,14 @@ int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (!_ma_get_last_key(info,keyinfo,buff,info->lastkey,page,
&info->lastkey_length))
DBUG_RETURN(-1);
- info->lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
+ info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
info->int_keypos=info->int_maxpos=page;
info->int_nod_flag=nod_flag;
info->int_keytree_version=keyinfo->version;
info->last_search_keypage=info->last_keypage;
- info->page_changed=info->buff_used=0;
+ info->page_changed=info->keybuff_used=0;
- DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
+ DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
DBUG_RETURN(0);
} /* _ma_search_last */
@@ -1391,12 +1398,12 @@ int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
int
_ma_calc_static_key_length(MARIA_KEYDEF *keyinfo,uint nod_flag,
- uchar *next_pos __attribute__((unused)),
- uchar *org_key __attribute__((unused)),
- uchar *prev_key __attribute__((unused)),
- uchar *key, MARIA_KEY_PARAM *s_temp)
+ byte *next_pos __attribute__((unused)),
+ byte *org_key __attribute__((unused)),
+ byte *prev_key __attribute__((unused)),
+ const byte *key, MARIA_KEY_PARAM *s_temp)
{
- s_temp->key=key;
+ s_temp->key= key;
return (int) (s_temp->totlength=keyinfo->keylength+nod_flag);
}
@@ -1404,18 +1411,18 @@ _ma_calc_static_key_length(MARIA_KEYDEF *keyinfo,uint nod_flag,
int
_ma_calc_var_key_length(MARIA_KEYDEF *keyinfo,uint nod_flag,
- uchar *next_pos __attribute__((unused)),
- uchar *org_key __attribute__((unused)),
- uchar *prev_key __attribute__((unused)),
- uchar *key, MARIA_KEY_PARAM *s_temp)
+ byte *next_pos __attribute__((unused)),
+ byte *org_key __attribute__((unused)),
+ byte *prev_key __attribute__((unused)),
+ const byte *key, MARIA_KEY_PARAM *s_temp)
{
- s_temp->key=key;
+ s_temp->key= key;
return (int) (s_temp->totlength= _ma_keylength(keyinfo,key)+nod_flag);
}
/*
length of key with a variable length first segment which is prefix
- compressed (mariachk reports 'packed + stripped')
+ compressed (maria_chk reports 'packed + stripped')
Keys are compressed the following way:
@@ -1434,15 +1441,16 @@ _ma_calc_var_key_length(MARIA_KEYDEF *keyinfo,uint nod_flag,
int
_ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar *next_key,
- uchar *org_key, uchar *prev_key, uchar *key,
+ byte *next_key,
+ byte *org_key, byte *prev_key, const byte *key,
MARIA_KEY_PARAM *s_temp)
{
reg1 HA_KEYSEG *keyseg;
int length;
uint key_length,ref_length,org_key_length=0,
length_pack,new_key_length,diff_flag,pack_marker;
- uchar *start,*end,*key_end,*sort_order;
+ const byte *start,*end,*key_end;
+ uchar *sort_order;
bool same_length;
length_pack=s_temp->ref_length=s_temp->n_ref_length=s_temp->n_length=0;
@@ -1455,7 +1463,7 @@ _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
(keyseg->type == HA_KEYTYPE_VARTEXT1) ||
(keyseg->type == HA_KEYTYPE_VARTEXT2)) &&
!use_strnxfrm(keyseg->charset))
- sort_order=keyseg->charset->sort_order;
+ sort_order= keyseg->charset->sort_order;
/* diff flag contains how many bytes is needed to pack key */
if (keyseg->length >= 127)
@@ -1475,10 +1483,10 @@ _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
{
if (!*key++)
{
- s_temp->key=key;
- s_temp->key_length=0;
- s_temp->totlength=key_length-1+diff_flag;
- s_temp->next_key_pos=0; /* No next key */
+ s_temp->key= key;
+ s_temp->key_length= 0;
+ s_temp->totlength= key_length-1+diff_flag;
+ s_temp->next_key_pos= 0; /* No next key */
return (s_temp->totlength);
}
s_temp->store_not_null=1;
@@ -1490,13 +1498,13 @@ _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
}
else
s_temp->store_not_null=0;
- s_temp->prev_key=org_key;
+ s_temp->prev_key= org_key;
/* The key part will start with a packed length */
get_key_pack_length(new_key_length,length_pack,key);
- end=key_end= key+ new_key_length;
- start=key;
+ end= key_end= key+ new_key_length;
+ start= key;
/* Calc how many characters are identical between this and the prev. key */
if (prev_key)
@@ -1507,11 +1515,12 @@ _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
if (new_key_length && new_key_length == org_key_length)
same_length=1;
else if (new_key_length > org_key_length)
- end=key + org_key_length;
+ end= key + org_key_length;
if (sort_order) /* SerG */
{
- while (key < end && sort_order[*key] == sort_order[*prev_key])
+ while (key < end &&
+ sort_order[* (uchar*) key] == sort_order[* (uchar*) prev_key])
{
key++; prev_key++;
}
@@ -1592,7 +1601,8 @@ _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
key=start;
if (sort_order) /* SerG */
{
- while (key < end && sort_order[*key] == sort_order[*org_key])
+ while (key < end &&
+ sort_order[*(uchar*) key] == sort_order[*(uchar*) org_key])
{
key++; org_key++;
}
@@ -1672,11 +1682,11 @@ _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
uint tmp_length;
key=(start+=ref_length);
if (key+n_length < key_end) /* Normalize length based */
- key_end=key+n_length;
+ key_end= key+n_length;
if (sort_order) /* SerG */
{
- while (key < key_end && sort_order[*key] ==
- sort_order[*next_key])
+ while (key < key_end &&
+ sort_order[*(uchar*) key] == sort_order[*(uchar*) next_key])
{
key++; next_key++;
}
@@ -1716,8 +1726,9 @@ _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
/* Length of key which is prefix compressed */
int _ma_calc_bin_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar *next_key,
- uchar *org_key, uchar *prev_key, uchar *key,
+ byte *next_key,
+ byte *org_key, byte *prev_key,
+ const byte *key,
MARIA_KEY_PARAM *s_temp)
{
uint length,key_length,ref_length;
@@ -1732,10 +1743,10 @@ int _ma_calc_bin_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
{
/* pack key against previous key */
/*
- As keys may be identical when running a sort in mariachk, we
+ As keys may be identical when running a sort in maria_chk, we
have to guard against the case where keys may be identical
*/
- uchar *end;
+ const byte *end;
end=key+key_length;
for ( ; *key == *prev_key && key < end; key++,prev_key++) ;
s_temp->ref_length= ref_length=(uint) (key-s_temp->key);
@@ -1756,7 +1767,7 @@ int _ma_calc_bin_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
/* If first key and next key is packed (only on delete) */
if (!prev_key && org_key && next_length)
{
- uchar *end;
+ const byte *end;
for (key= s_temp->key, end=key+next_length ;
*key == *org_key && key < end;
key++,org_key++) ;
@@ -1798,7 +1809,7 @@ int _ma_calc_bin_pack_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
/* store key without compression */
void _ma_store_static_key(MARIA_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
+ register byte *key_pos,
register MARIA_KEY_PARAM *s_temp)
{
memcpy((byte*) key_pos,(byte*) s_temp->key,(size_t) s_temp->totlength);
@@ -1813,11 +1824,11 @@ void _ma_store_static_key(MARIA_KEYDEF *keyinfo __attribute__((unused)),
void _ma_store_var_pack_key(MARIA_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
+ register byte *key_pos,
register MARIA_KEY_PARAM *s_temp)
{
uint length;
- uchar *start;
+ byte *start;
start=key_pos;
@@ -1876,7 +1887,7 @@ void _ma_store_var_pack_key(MARIA_KEYDEF *keyinfo __attribute__((unused)),
/* variable length key with prefix compression */
void _ma_store_bin_pack_key(MARIA_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
+ register byte *key_pos,
register MARIA_KEY_PARAM *s_temp)
{
store_key_length_inc(key_pos,s_temp->ref_length);
diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c
index c9e3a369851..b63f99379ea 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -49,31 +49,31 @@ extern void print_error _VARARGS((const char *fmt,...));
/* Functions defined in this file */
static ha_rows NEAR_F find_all_keys(MARIA_SORT_PARAM *info,uint keys,
- uchar **sort_keys,
+ byte **sort_keys,
DYNAMIC_ARRAY *buffpek,int *maxbuffer,
IO_CACHE *tempfile,
IO_CACHE *tempfile_for_exceptions);
-static int NEAR_F write_keys(MARIA_SORT_PARAM *info,uchar **sort_keys,
+static int NEAR_F write_keys(MARIA_SORT_PARAM *info, byte **sort_keys,
uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
-static int NEAR_F write_key(MARIA_SORT_PARAM *info, uchar *key,
+static int NEAR_F write_key(MARIA_SORT_PARAM *info, byte *key,
IO_CACHE *tempfile);
-static int NEAR_F write_index(MARIA_SORT_PARAM *info,uchar * *sort_keys,
+static int NEAR_F write_index(MARIA_SORT_PARAM *info, byte **sort_keys,
uint count);
static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info,uint keys,
- uchar * *sort_keys,
+ byte **sort_keys,
BUFFPEK *buffpek,int *maxbuffer,
IO_CACHE *t_file);
static uint NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
uint sort_length);
static int NEAR_F merge_buffers(MARIA_SORT_PARAM *info,uint keys,
IO_CACHE *from_file, IO_CACHE *to_file,
- uchar * *sort_keys, BUFFPEK *lastbuff,
+ byte **sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Fb, BUFFPEK *Tb);
-static int NEAR_F merge_index(MARIA_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
+static int NEAR_F merge_index(MARIA_SORT_PARAM *,uint, byte **,BUFFPEK *, int,
IO_CACHE *);
static int flush_maria_ft_buf(MARIA_SORT_PARAM *info);
-static int NEAR_F write_keys_varlen(MARIA_SORT_PARAM *info,uchar **sort_keys,
+static int NEAR_F write_keys_varlen(MARIA_SORT_PARAM *info, byte **sort_keys,
uint count, BUFFPEK *buffpek,
IO_CACHE *tempfile);
static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
@@ -101,27 +101,27 @@ my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs);
<> 0 Error
*/
-int _ma_create_index_by_sort(MARIA_SORT_PARAM *info,my_bool no_messages,
- ulong sortbuff_size)
+int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
+ ulong sortbuff_size)
{
int error,maxbuffer,skr;
uint memavl,old_memavl,keys,sort_length;
DYNAMIC_ARRAY buffpek;
ha_rows records;
- uchar **sort_keys;
+ byte **sort_keys;
IO_CACHE tempfile, tempfile_for_exceptions;
DBUG_ENTER("_ma_create_index_by_sort");
DBUG_PRINT("enter",("sort_length: %d", info->key_length));
if (info->keyinfo->flag & HA_VAR_LENGTH_KEY)
{
- info->write_keys=write_keys_varlen;
+ info->write_keys= write_keys_varlen;
info->read_to_buffer=read_to_buffer_varlen;
info->write_key=write_merge_key_varlen;
}
else
{
- info->write_keys=write_keys;
+ info->write_keys= write_keys;
info->read_to_buffer=read_to_buffer;
info->write_key=write_merge_key;
}
@@ -129,7 +129,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info,my_bool no_messages,
my_b_clear(&tempfile);
my_b_clear(&tempfile_for_exceptions);
bzero((char*) &buffpek,sizeof(buffpek));
- sort_keys= (uchar **) NULL; error= 1;
+ sort_keys= (byte **) NULL; error= 1;
maxbuffer=1;
memavl=max(sortbuff_size,MIN_SORT_MEMORY);
@@ -158,8 +158,8 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info,my_bool no_messages,
}
while ((maxbuffer= (int) (records/(keys-1)+1)) != skr);
- if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
- HA_FT_MAXBYTELEN, MYF(0))))
+ if ((sort_keys=(byte**) my_malloc(keys*(sort_length+sizeof(char*))+
+ HA_FT_MAXBYTELEN, MYF(0))))
{
if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer,
maxbuffer/2))
@@ -236,7 +236,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info,my_bool no_messages,
&& !my_b_read(&tempfile_for_exceptions,(byte*)sort_keys,
(uint) key_length))
{
- if (_ma_ck_write(index,keyno,(uchar*) sort_keys,key_length-ref_length))
+ if (_ma_ck_write(index,keyno,(byte*) sort_keys,key_length-ref_length))
goto err;
}
}
@@ -257,7 +257,7 @@ err:
/* Search after all keys and place them in a temp. file */
static ha_rows NEAR_F find_all_keys(MARIA_SORT_PARAM *info, uint keys,
- uchar **sort_keys, DYNAMIC_ARRAY *buffpek,
+ byte **sort_keys, DYNAMIC_ARRAY *buffpek,
int *maxbuffer, IO_CACHE *tempfile,
IO_CACHE *tempfile_for_exceptions)
{
@@ -266,7 +266,7 @@ static ha_rows NEAR_F find_all_keys(MARIA_SORT_PARAM *info, uint keys,
DBUG_ENTER("find_all_keys");
idx=error=0;
- sort_keys[0]=(uchar*) (sort_keys+keys);
+ sort_keys[0]= (byte*) (sort_keys+keys);
while (!(error=(*info->key_read)(info,sort_keys[idx])))
{
@@ -279,11 +279,12 @@ static ha_rows NEAR_F find_all_keys(MARIA_SORT_PARAM *info, uint keys,
if (++idx == keys)
{
- if (info->write_keys(info,sort_keys,idx-1,(BUFFPEK *)alloc_dynamic(buffpek),
- tempfile))
+ if (info->write_keys(info,sort_keys,idx-1,
+ (BUFFPEK *)alloc_dynamic(buffpek),
+ tempfile))
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
- sort_keys[0]=(uchar*) (sort_keys+keys);
+ sort_keys[0]=(byte*) (sort_keys+keys);
memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
idx=1;
}
@@ -294,7 +295,7 @@ static ha_rows NEAR_F find_all_keys(MARIA_SORT_PARAM *info, uint keys,
if (buffpek->elements)
{
if (info->write_keys(info,sort_keys,idx,(BUFFPEK *)alloc_dynamic(buffpek),
- tempfile))
+ tempfile))
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
*maxbuffer=buffpek->elements-1;
}
@@ -314,7 +315,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
int error;
uint memavl,old_memavl,keys,sort_length;
uint idx, maxbuffer;
- uchar **sort_keys=0;
+ byte **sort_keys=0;
LINT_INIT(keys);
@@ -346,7 +347,6 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
my_b_clear(&sort_param->tempfile_for_exceptions);
bzero((char*) &sort_param->buffpek,sizeof(sort_param->buffpek));
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
- sort_keys= (uchar **) NULL;
memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
idx= sort_param->sort_info->max_records;
@@ -376,7 +376,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
}
while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
}
- if ((sort_keys= (uchar **)
+ if ((sort_keys= (byte **)
my_malloc(keys*(sort_length+sizeof(char*))+
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
HA_FT_MAXBYTELEN : 0), MYF(0))))
@@ -385,7 +385,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
maxbuffer, maxbuffer/2))
{
my_free((gptr) sort_keys,MYF(0));
- sort_keys= (uchar **) NULL; /* for err: label */
+ sort_keys= (byte **) NULL; /* for err: label */
}
else
break;
@@ -408,7 +408,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
sort_param->sort_keys= sort_keys;
idx= error= 0;
- sort_keys[0]= (uchar*) (sort_keys+keys);
+ sort_keys[0]= (byte*) (sort_keys+keys);
DBUG_PRINT("info", ("reading keys"));
while (!(error= sort_param->sort_info->got_error) &&
@@ -425,11 +425,13 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
if (++idx == keys)
{
if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
- (BUFFPEK *)alloc_dynamic(&sort_param->buffpek),
+ (BUFFPEK *)alloc_dynamic(&sort_param->
+ buffpek),
&sort_param->tempfile))
goto err;
- sort_keys[0]= (uchar*) (sort_keys+keys);
- memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
+ sort_keys[0]= (byte*) (sort_keys+keys);
+ memcpy(sort_keys[0], sort_keys[idx - 1],
+ (size_t) sort_param->key_length);
idx= 1;
}
sort_keys[idx]=sort_keys[idx - 1] + sort_param->key_length;
@@ -439,7 +441,9 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
if (sort_param->buffpek.elements)
{
if (sort_param->write_keys(sort_param,sort_keys, idx,
- (BUFFPEK *) alloc_dynamic(&sort_param->buffpek), &sort_param->tempfile))
+ (BUFFPEK *) alloc_dynamic(&sort_param->
+ buffpek),
+ &sort_param->tempfile))
goto err;
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
}
@@ -452,8 +456,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
err:
DBUG_PRINT("error", ("got some error"));
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
- if (sort_keys)
- my_free((gptr) sort_keys,MYF(0));
+ my_free((gptr) sort_keys,MYF(MY_ALLOW_ZERO_PTR));
sort_param->sort_keys=0;
delete_dynamic(& sort_param->buffpek);
close_cached_file(&sort_param->tempfile);
@@ -506,8 +509,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
if (!sinfo->sort_keys)
{
got_error=1;
- my_free(_ma_get_rec_buff_ptr(info, sinfo->rec_buff),
- MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sinfo->rec_buff, MYF(MY_ALLOW_ZERO_PTR));
continue;
}
if (!got_error)
@@ -581,7 +583,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
{
if (param->testflag & T_VERBOSE)
printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys);
- if (merge_many_buff(sinfo, keys, (uchar **)mergebuf,
+ if (merge_many_buff(sinfo, keys, (byte **) mergebuf,
dynamic_element(&sinfo->buffpek, 0, BUFFPEK *),
(int*) &maxbuffer, &sinfo->tempfile))
{
@@ -597,7 +599,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
}
if (param->testflag & T_VERBOSE)
printf("Key %d - Last merge and dumping keys\n", sinfo->key+1);
- if (merge_index(sinfo, keys, (uchar **)mergebuf,
+ if (merge_index(sinfo, keys, (byte**) mergebuf,
dynamic_element(&sinfo->buffpek,0,BUFFPEK *),
maxbuffer,&sinfo->tempfile) ||
flush_maria_ft_buf(sinfo) ||
@@ -629,7 +631,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
if (key_length > sizeof(maria_ft_buf) ||
my_b_read(&sinfo->tempfile_for_exceptions, (byte*)maria_ft_buf,
(uint)key_length) ||
- _ma_ck_write(info, sinfo->key, (uchar*)maria_ft_buf,
+ _ma_ck_write(info, sinfo->key, maria_ft_buf,
key_length - info->s->rec_reflength))
got_error=1;
}
@@ -640,12 +642,12 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
}
#endif /* THREAD */
- /* Write all keys in memory to file for later merge */
+/* Write all keys in memory to file for later merge */
-static int NEAR_F write_keys(MARIA_SORT_PARAM *info, register uchar **sort_keys,
- uint count, BUFFPEK *buffpek, IO_CACHE *tempfile)
+static int write_keys(MARIA_SORT_PARAM *info, register byte **sort_keys,
+ uint count, BUFFPEK *buffpek, IO_CACHE *tempfile)
{
- uchar **end;
+ byte **end;
uint sort_length=info->key_length;
DBUG_ENTER("write_keys");
@@ -661,7 +663,7 @@ static int NEAR_F write_keys(MARIA_SORT_PARAM *info, register uchar **sort_keys,
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
{
- if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
+ if (my_b_write(tempfile, *sort_keys, (uint) sort_length))
DBUG_RETURN(1); /* purecov: inspected */
}
DBUG_RETURN(0);
@@ -672,7 +674,7 @@ static inline int
my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs)
{
int err;
- uint16 len = _ma_keylength(info->keyinfo, (uchar*) bufs);
+ uint16 len= _ma_keylength(info->keyinfo, bufs);
/* The following is safe as this is a local file */
if ((err= my_b_write(to_file, (byte*)&len, sizeof(len))))
@@ -684,11 +686,11 @@ my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, byte *bufs)
static int NEAR_F write_keys_varlen(MARIA_SORT_PARAM *info,
- register uchar **sort_keys,
+ register byte **sort_keys,
uint count, BUFFPEK *buffpek,
IO_CACHE *tempfile)
{
- uchar **end;
+ byte **end;
int err;
DBUG_ENTER("write_keys_varlen");
@@ -703,14 +705,14 @@ static int NEAR_F write_keys_varlen(MARIA_SORT_PARAM *info,
buffpek->count=count;
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
{
- if ((err= my_var_write(info,tempfile, (byte*) *sort_keys)))
+ if ((err= my_var_write(info,tempfile, *sort_keys)))
DBUG_RETURN(err);
}
DBUG_RETURN(0);
} /* write_keys_varlen */
-static int NEAR_F write_key(MARIA_SORT_PARAM *info, uchar *key,
+static int NEAR_F write_key(MARIA_SORT_PARAM *info, byte *key,
IO_CACHE *tempfile)
{
uint key_length=info->real_key_length;
@@ -721,8 +723,8 @@ static int NEAR_F write_key(MARIA_SORT_PARAM *info, uchar *key,
DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
DBUG_RETURN(1);
- if (my_b_write(tempfile,(byte*)&key_length,sizeof(key_length)) ||
- my_b_write(tempfile,(byte*)key,(uint) key_length))
+ if (my_b_write(tempfile, (byte*)&key_length,sizeof(key_length)) ||
+ my_b_write(tempfile, key, (uint) key_length))
DBUG_RETURN(1);
DBUG_RETURN(0);
} /* write_key */
@@ -730,7 +732,8 @@ static int NEAR_F write_key(MARIA_SORT_PARAM *info, uchar *key,
/* Write index */
-static int NEAR_F write_index(MARIA_SORT_PARAM *info, register uchar **sort_keys,
+static int NEAR_F write_index(MARIA_SORT_PARAM *info,
+ register byte **sort_keys,
register uint count)
{
DBUG_ENTER("write_index");
@@ -739,7 +742,7 @@ static int NEAR_F write_index(MARIA_SORT_PARAM *info, register uchar **sort_keys
(qsort2_cmp) info->key_cmp,info);
while (count--)
{
- if ((*info->key_write)(info,*sort_keys++))
+ if ((*info->key_write)(info, *sort_keys++))
DBUG_RETURN(-1); /* purecov: inspected */
}
DBUG_RETURN(0);
@@ -749,7 +752,7 @@ static int NEAR_F write_index(MARIA_SORT_PARAM *info, register uchar **sort_keys
/* Merge buffers to make < MERGEBUFF2 buffers */
static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
- uchar **sort_keys, BUFFPEK *buffpek,
+ byte **sort_keys, BUFFPEK *buffpek,
int *maxbuffer, IO_CACHE *t_file)
{
register int i;
@@ -830,11 +833,11 @@ static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
register uint count;
uint16 length_of_key = 0;
uint idx;
- uchar *buffp;
+ byte *buffp;
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
{
- buffp = buffpek->base;
+ buffp= buffpek->base;
for (idx=1;idx<=count;idx++)
{
@@ -888,18 +891,17 @@ static int NEAR_F write_merge_key(MARIA_SORT_PARAM *info __attribute__((unused))
static int NEAR_F
merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
- IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
+ IO_CACHE *to_file, byte **sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Fb, BUFFPEK *Tb)
{
int error;
uint sort_length,maxcount;
ha_rows count;
my_off_t to_start_filepos;
- uchar *strpos;
+ byte *strpos;
BUFFPEK *buffpek,**refpek;
QUEUE queue;
volatile int *killed= _ma_killed_ptr(info->sort_info->param);
-
DBUG_ENTER("merge_buffers");
count=error=0;
@@ -907,7 +909,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
LINT_INIT(to_start_filepos);
if (to_file)
to_start_filepos=my_b_tell(to_file);
- strpos=(uchar*) sort_keys;
+ strpos= (byte*) sort_keys;
sort_length=info->key_length;
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
@@ -956,7 +958,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
{
if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
{
- uchar *base=buffpek->base;
+ byte *base= buffpek->base;
uint max_keys=buffpek->max_keys;
VOID(queue_remove(&queue,0));
@@ -988,7 +990,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
- buffpek->base=(uchar *) sort_keys;
+ buffpek->base= (byte*) sort_keys;
buffpek->max_keys=keys;
do
{
@@ -1002,21 +1004,21 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
else
{
- register uchar *end;
+ register byte *end;
strpos= buffpek->key;
- for (end=strpos+buffpek->mem_count*sort_length;
+ for (end= strpos+buffpek->mem_count*sort_length;
strpos != end ;
strpos+=sort_length)
{
- if ((*info->key_write)(info,(void*) strpos))
+ if ((*info->key_write)(info, (byte*) strpos))
{
error=1; goto err; /* purecov: inspected */
}
}
}
}
- while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 &&
- error != 0);
+ while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) !=
+ -1 && error != 0);
lastbuff->count=count;
if (to_file)
@@ -1030,7 +1032,7 @@ err:
/* Do a merge to output-file (save only positions) */
static int NEAR_F
-merge_index(MARIA_SORT_PARAM *info, uint keys, uchar **sort_keys,
+merge_index(MARIA_SORT_PARAM *info, uint keys, byte **sort_keys,
BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
{
DBUG_ENTER("merge_index");
@@ -1040,8 +1042,8 @@ merge_index(MARIA_SORT_PARAM *info, uint keys, uchar **sort_keys,
DBUG_RETURN(0);
} /* merge_index */
-static int
-flush_maria_ft_buf(MARIA_SORT_PARAM *info)
+
+static int flush_maria_ft_buf(MARIA_SORT_PARAM *info)
{
int err=0;
if (info->sort_info->ft_buf)
diff --git a/storage/maria/ma_sp_defs.h b/storage/maria/ma_sp_defs.h
index a7e282f0ddc..8b9dd204ded 100644
--- a/storage/maria/ma_sp_defs.h
+++ b/storage/maria/ma_sp_defs.h
@@ -41,7 +41,7 @@ enum wkbByteOrder
wkbNDR = 1 /* Little Endian */
};
-uint sp_make_key(register MARIA_HA *info, uint keynr, uchar *key,
+uint sp_make_key(register MARIA_HA *info, uint keynr, byte *key,
const byte *record, my_off_t filepos);
#endif /*HAVE_SPATIAL*/
diff --git a/storage/maria/ma_sp_key.c b/storage/maria/ma_sp_key.c
index b9841fed1e7..79345550dd9 100644
--- a/storage/maria/ma_sp_key.c
+++ b/storage/maria/ma_sp_key.c
@@ -37,7 +37,7 @@ static void get_double(double *d, const byte *pos)
float8get(*d, pos);
}
-uint sp_make_key(register MARIA_HA *info, uint keynr, uchar *key,
+uint sp_make_key(register MARIA_HA *info, uint keynr, byte *key,
const byte *record, my_off_t filepos)
{
HA_KEYSEG *keyseg;
diff --git a/storage/maria/ma_sp_test.c b/storage/maria/ma_sp_test.c
index ea812974c8c..1ac1a74d7d7 100644
--- a/storage/maria/ma_sp_test.c
+++ b/storage/maria/ma_sp_test.c
@@ -109,10 +109,11 @@ int run_test(const char *filename)
create_info.max_rows=10000000;
if (maria_create(filename,
- 1, /* keys */
- keyinfo,
- 2, /* columns */
- recinfo,uniques,&uniquedef,&create_info,create_flag))
+ DYNAMIC_RECORD,
+ 1, /* keys */
+ keyinfo,
+ 2, /* columns */
+ recinfo,uniques,&uniquedef,&create_info,create_flag))
goto err;
if (!silent)
diff --git a/storage/maria/ma_static.c b/storage/maria/ma_static.c
index 511c5507aaf..c5580e1e981 100644
--- a/storage/maria/ma_static.c
+++ b/storage/maria/ma_static.c
@@ -25,12 +25,13 @@
LIST *maria_open_list=0;
uchar NEAR maria_file_magic[]=
-{ (uchar) 254, (uchar) 254,'\007', '\001', };
+{ (uchar) 254, (uchar) 254, (uchar) 9, '\001', };
uchar NEAR maria_pack_file_magic[]=
-{ (uchar) 254, (uchar) 254,'\010', '\002', };
+{ (uchar) 254, (uchar) 254, (uchar) 10, '\001', };
uint maria_quick_table_bits=9;
ulong maria_block_size= MARIA_KEY_BLOCK_LENGTH;
-my_bool maria_flush=0, maria_delay_key_write=0, maria_single_user=0;
+my_bool maria_flush= 0, maria_single_user= 0;
+my_bool maria_delay_key_write= 0;
#if defined(THREAD) && !defined(DONT_USE_RW_LOCKS)
ulong maria_concurrent_insert= 2;
#else
@@ -38,11 +39,14 @@ ulong maria_concurrent_insert= 0;
#endif
my_off_t maria_max_temp_length= MAX_FILE_SIZE;
ulong maria_bulk_insert_tree_size=8192*1024;
-ulong maria_data_pointer_size=4;
+ulong maria_data_pointer_size= 4;
KEY_CACHE maria_key_cache_var;
KEY_CACHE *maria_key_cache= &maria_key_cache_var;
+/* Enough for comparing if number is zero */
+byte maria_zero_string[]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
/*
read_vec[] is used for converting between P_READ_KEY.. and SEARCH_
Position is , == , >= , <= , > , <
diff --git a/storage/maria/ma_statrec.c b/storage/maria/ma_statrec.c
index 82e31115ec7..72c5e10d9ab 100644
--- a/storage/maria/ma_statrec.c
+++ b/storage/maria/ma_statrec.c
@@ -19,9 +19,9 @@
#include "maria_def.h"
-int _ma_write_static_record(MARIA_HA *info, const byte *record)
+my_bool _ma_write_static_record(MARIA_HA *info, const byte *record)
{
- uchar temp[8]; /* max pointer length */
+ byte temp[8]; /* max pointer length */
if (info->s->state.dellink != HA_OFFSET_ERROR &&
!info->append_insert_at_end)
{
@@ -86,7 +86,8 @@ int _ma_write_static_record(MARIA_HA *info, const byte *record)
return 1;
}
-int _ma_update_static_record(MARIA_HA *info, my_off_t pos, const byte *record)
+my_bool _ma_update_static_record(MARIA_HA *info, MARIA_RECORD_POS pos,
+ const byte *record)
{
info->rec_cache.seek_not_done=1; /* We have done a seek */
return (info->s->file_write(info,
@@ -96,22 +97,22 @@ int _ma_update_static_record(MARIA_HA *info, my_off_t pos, const byte *record)
}
-int _ma_delete_static_record(MARIA_HA *info)
+my_bool _ma_delete_static_record(MARIA_HA *info)
{
- uchar temp[9]; /* 1+sizeof(uint32) */
-
+ byte temp[9]; /* 1+sizeof(uint32) */
info->state->del++;
info->state->empty+=info->s->base.pack_reclength;
temp[0]= '\0'; /* Mark that record is deleted */
_ma_dpointer(info,temp+1,info->s->state.dellink);
- info->s->state.dellink = info->lastpos;
+ info->s->state.dellink= info->cur_row.lastpos;
info->rec_cache.seek_not_done=1;
- return (info->s->file_write(info,(byte*) temp, 1+info->s->rec_reflength,
- info->lastpos, MYF(MY_NABP)) != 0);
+ return (info->s->file_write(info, temp, 1+info->s->rec_reflength,
+ info->cur_row.lastpos, MYF(MY_NABP)) != 0);
}
-int _ma_cmp_static_record(register MARIA_HA *info, register const byte *old)
+my_bool _ma_cmp_static_record(register MARIA_HA *info,
+ register const byte *old)
{
DBUG_ENTER("_ma_cmp_static_record");
@@ -122,7 +123,7 @@ int _ma_cmp_static_record(register MARIA_HA *info, register const byte *old)
{
if (flush_io_cache(&info->rec_cache))
{
- DBUG_RETURN(-1);
+ DBUG_RETURN(1);
}
info->rec_cache.seek_not_done=1; /* We have done a seek */
}
@@ -130,10 +131,11 @@ int _ma_cmp_static_record(register MARIA_HA *info, register const byte *old)
if ((info->opt_flag & READ_CHECK_USED))
{ /* If check isn't disabled */
info->rec_cache.seek_not_done=1; /* We have done a seek */
- if (info->s->file_read(info, (char*) info->rec_buff, info->s->base.reclength,
- info->lastpos,
- MYF(MY_NABP)))
- DBUG_RETURN(-1);
+ if (info->s->file_read(info, (char*) info->rec_buff,
+ info->s->base.reclength,
+ info->cur_row.lastpos,
+ MYF(MY_NABP)))
+ DBUG_RETURN(1);
if (memcmp((byte*) info->rec_buff, (byte*) old,
(uint) info->s->base.reclength))
{
@@ -147,27 +149,31 @@ int _ma_cmp_static_record(register MARIA_HA *info, register const byte *old)
}
-int _ma_cmp_static_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
- const byte *record, my_off_t pos)
+my_bool _ma_cmp_static_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
+ const byte *record, MARIA_RECORD_POS pos)
{
DBUG_ENTER("_ma_cmp_static_unique");
info->rec_cache.seek_not_done=1; /* We have done a seek */
if (info->s->file_read(info, (char*) info->rec_buff, info->s->base.reclength,
pos, MYF(MY_NABP)))
- DBUG_RETURN(-1);
- DBUG_RETURN(_ma_unique_comp(def, record, info->rec_buff,
- def->null_are_equal));
+ DBUG_RETURN(1);
+ DBUG_RETURN(_ma_unique_comp(def, record, (byte*) info->rec_buff,
+ def->null_are_equal));
}
- /* Read a fixed-length-record */
- /* Returns 0 if Ok. */
- /* 1 if record is deleted */
- /* MY_FILE_ERROR on read-error or locking-error */
+/*
+ Read a fixed-length-record
+
+ RETURN
+ 0 Ok
+ 1 record delete
+ -1 on read-error or locking-error
+*/
-int _ma_read_static_record(register MARIA_HA *info, register my_off_t pos,
- register byte *record)
+int _ma_read_static_record(register MARIA_HA *info, register byte *record,
+ MARIA_RECORD_POS pos)
{
int error;
@@ -180,7 +186,7 @@ int _ma_read_static_record(register MARIA_HA *info, register my_off_t pos,
info->rec_cache.seek_not_done=1; /* We have done a seek */
error=info->s->file_read(info,(char*) record,info->s->base.reclength,
- pos,MYF(MY_NABP)) != 0;
+ pos, MYF(MY_NABP)) != 0;
fast_ma_writeinfo(info);
if (! error)
{
@@ -201,8 +207,8 @@ int _ma_read_static_record(register MARIA_HA *info, register my_off_t pos,
int _ma_read_rnd_static_record(MARIA_HA *info, byte *buf,
- register my_off_t filepos,
- my_bool skip_deleted_blocks)
+ MARIA_RECORD_POS filepos,
+ my_bool skip_deleted_blocks)
{
int locked,error,cache_read;
uint cache_length;
@@ -211,10 +217,6 @@ int _ma_read_rnd_static_record(MARIA_HA *info, byte *buf,
cache_read=0;
cache_length=0;
- if (info->opt_flag & WRITE_CACHE_USED &&
- (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) &&
- flush_io_cache(&info->rec_cache))
- DBUG_RETURN(my_errno);
if (info->opt_flag & READ_CACHE_USED)
{ /* Cache in use */
if (filepos == my_b_tell(&info->rec_cache) &&
@@ -256,12 +258,12 @@ int _ma_read_rnd_static_record(MARIA_HA *info, byte *buf,
fast_ma_writeinfo(info);
DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE);
}
- info->lastpos= filepos;
- info->nextpos= filepos+share->base.pack_reclength;
+ info->cur_row.lastpos= filepos;
+ info->cur_row.nextpos= filepos+share->base.pack_reclength;
if (! cache_read) /* No cacheing */
{
- if ((error= _ma_read_static_record(info,filepos,buf)))
+ if ((error= _ma_read_static_record(info, buf, filepos)))
{
if (error > 0)
error=my_errno=HA_ERR_RECORD_DELETED;
diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c
index 69d432a5d95..0f37391c1d4 100644
--- a/storage/maria/ma_test1.c
+++ b/storage/maria/ma_test1.c
@@ -28,12 +28,13 @@ static int rec_pointer_size=0, flags[50];
static int key_field=FIELD_SKIP_PRESPACE,extra_field=FIELD_SKIP_ENDSPACE;
static int key_type=HA_KEYTYPE_NUM;
static int create_flag=0;
+static enum data_file_type record_type= DYNAMIC_RECORD;
static uint insert_count, update_count, remove_count;
static uint pack_keys=0, pack_seg=0, key_length;
static uint unique_key=HA_NOSAME;
static my_bool key_cacheing, null_fields, silent, skip_update, opt_unique,
- verbose;
+ verbose, skip_delete;
static MARIA_COLUMNDEF recinfo[4];
static MARIA_KEYDEF keyinfo[10];
static HA_KEYSEG keyseg[10];
@@ -63,31 +64,30 @@ static int run_test(const char *filename)
MARIA_HA *file;
int i,j,error,deleted,rec_length,uniques=0;
ha_rows found,row_count;
- my_off_t pos;
char record[MAX_REC_LENGTH],key[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH];
MARIA_UNIQUEDEF uniquedef;
MARIA_CREATE_INFO create_info;
bzero((char*) recinfo,sizeof(recinfo));
+ bzero((char*) &create_info,sizeof(create_info));
/* First define 2 columns */
- recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1; /* For NULL bits */
- recinfo[1].type=key_field;
- recinfo[1].length= (key_field == FIELD_BLOB ? 4+maria_portable_sizeof_char_ptr :
+ create_info.null_bytes= 1;
+ recinfo[0].type= key_field;
+ recinfo[0].length= (key_field == FIELD_BLOB ? 4+maria_portable_sizeof_char_ptr :
key_length);
if (key_field == FIELD_VARCHAR)
- recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);;
- recinfo[2].type=extra_field;
- recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + maria_portable_sizeof_char_ptr : 24);
+ recinfo[0].length+= HA_VARCHAR_PACKLENGTH(key_length);
+ recinfo[1].type=extra_field;
+ recinfo[1].length= (extra_field == FIELD_BLOB ? 4 + maria_portable_sizeof_char_ptr : 24);
if (extra_field == FIELD_VARCHAR)
- recinfo[2].length+= HA_VARCHAR_PACKLENGTH(recinfo[2].length);
+ recinfo[1].length+= HA_VARCHAR_PACKLENGTH(recinfo[1].length);
if (opt_unique)
{
- recinfo[3].type=FIELD_CHECK;
- recinfo[3].length=MARIA_UNIQUE_HASH_LENGTH;
+ recinfo[2].type=FIELD_CHECK;
+ recinfo[2].length=MARIA_UNIQUE_HASH_LENGTH;
}
- rec_length=recinfo[0].length+recinfo[1].length+recinfo[2].length+
- recinfo[3].length;
+ rec_length= recinfo[0].length+recinfo[1].length+recinfo[2].length;
if (key_type == HA_KEYTYPE_VARTEXT1 &&
key_length > 255)
@@ -125,8 +125,8 @@ static int run_test(const char *filename)
for (i=0, start=1 ; i < 2 ; i++)
{
uniqueseg[i].start=start;
- start+=recinfo[i+1].length;
- uniqueseg[i].length=recinfo[i+1].length;
+ start+=recinfo[i].length;
+ uniqueseg[i].length=recinfo[i].length;
uniqueseg[i].language= default_charset_info->number;
}
uniqueseg[0].type= key_type;
@@ -139,18 +139,21 @@ static int run_test(const char *filename)
uniqueseg[1].flag|= HA_BLOB_PART;
}
else if (extra_field == FIELD_VARCHAR)
+ {
uniqueseg[1].flag|= HA_VAR_LENGTH_PART;
+ uniqueseg[1].type= (HA_VARCHAR_PACKLENGTH(recinfo[1].length-1) == 1 ?
+ HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2);
+ }
}
else
uniques=0;
if (!silent)
- printf("- Creating isam-file\n");
- bzero((char*) &create_info,sizeof(create_info));
+ printf("- Creating maria file\n");
create_info.max_rows=(ulong) (rec_pointer_size ?
(1L << (rec_pointer_size*8))/40 :
0);
- if (maria_create(filename,1,keyinfo,3+opt_unique,recinfo,
+ if (maria_create(filename, record_type, 1, keyinfo,2+opt_unique,recinfo,
uniques, &uniquedef, &create_info,
create_flag))
goto err;
@@ -223,9 +226,10 @@ static int run_test(const char *filename)
}
/* Read through all rows and update them */
- pos=(my_off_t) 0;
+ assert(maria_scan_init(file) == 0);
+
found=0;
- while ((error=maria_rrnd(file,read_record,pos)) == 0)
+ while ((error= maria_scan(file,read_record)) == 0)
{
if (update_count-- == 0) { VOID(maria_close(file)) ; exit(0) ; }
memcpy(record,read_record,rec_length);
@@ -236,17 +240,17 @@ static int run_test(const char *filename)
keyinfo[0].seg[0].length,record+1,my_errno);
}
found++;
- pos=HA_OFFSET_ERROR;
}
if (found != row_count)
printf("Found %ld of %ld rows\n", (ulong) found, (ulong) row_count);
+ maria_scan_end(file);
}
if (!silent)
printf("- Reopening file\n");
if (maria_close(file)) goto err;
if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) goto err;
- if (!skip_update)
+ if (!skip_delete)
{
if (!silent)
printf("- Removing keys\n");
@@ -254,7 +258,13 @@ static int run_test(const char *filename)
for (i=0 ; i <= 10 ; i++)
{
/* testing */
- if (remove_count-- == 0) { VOID(maria_close(file)) ; exit(0) ; }
+ if (remove_count-- == 0)
+ {
+ fprintf(stderr,
+ "delete-rows number of rows deleted; Going down hard!\n");
+ VOID(maria_close(file));
+ exit(0) ;
+ }
j=i*2;
if (!flags[j])
continue;
@@ -283,6 +293,7 @@ static int run_test(const char *filename)
}
if (!silent)
printf("- Reading rows with key\n");
+ record[1]= 0; /* For nicer printf */
for (i=0 ; i <= 25 ; i++)
{
create_key(key,i);
@@ -299,10 +310,16 @@ static int run_test(const char *filename)
if (!silent)
printf("- Reading rows with position\n");
+ if (maria_scan_init(file))
+ {
+ fprintf(stderr, "maria_scan_init failed\n");
+ goto err;
+ }
+
for (i=1,found=0 ; i <= 30 ; i++)
{
my_errno=0;
- if ((error=maria_rrnd(file,read_record,i == 1 ? 0L : HA_OFFSET_ERROR)) == -1)
+ if ((error= maria_scan(file, read_record)) == HA_ERR_END_OF_FILE)
{
if (found != row_count-deleted)
printf("Found only %ld of %ld rows\n", (ulong) found,
@@ -318,7 +335,8 @@ static int run_test(const char *filename)
i-1,error,my_errno,read_record+1);
}
}
- if (maria_close(file)) goto err;
+ if (maria_close(file))
+ goto err;
maria_end();
my_end(MY_CHECK_ERROR);
@@ -346,7 +364,7 @@ static void create_key_part(char *key,uint rownr)
if ((rownr & 7) == 0)
{
/* Change the key to force a unpack of the next key */
- bfill(key+3,keyinfo[0].seg[0].length-4,rownr < 10 ? 'a' : 'b');
+ bfill(key+3,keyinfo[0].seg[0].length-5,rownr < 10 ? 'a' : 'b');
}
}
else
@@ -375,7 +393,7 @@ static void create_key(char *key,uint rownr)
if (rownr == 0)
{
key[0]=1; /* null key */
- key[1]=0; /* Fore easy print of key */
+ key[1]=0; /* For easy print of key */
return;
}
*key++=0;
@@ -405,7 +423,7 @@ static void create_record(char *record,uint rownr)
record[0]|=keyinfo[0].seg[0].null_bit; /* Null key */
pos=record+1;
- if (recinfo[1].type == FIELD_BLOB)
+ if (recinfo[0].type == FIELD_BLOB)
{
uint tmp;
char *ptr;
@@ -414,25 +432,25 @@ static void create_record(char *record,uint rownr)
int4store(pos,tmp);
ptr=blob_key;
memcpy_fixed(pos+4,&ptr,sizeof(char*));
- pos+=recinfo[1].length;
+ pos+=recinfo[0].length;
}
- else if (recinfo[1].type == FIELD_VARCHAR)
+ else if (recinfo[0].type == FIELD_VARCHAR)
{
- uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
+ uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[0].length-1);
create_key_part(pos+pack_length,rownr);
tmp= strlen(pos+pack_length);
if (pack_length == 1)
*(uchar*) pos= (uchar) tmp;
else
int2store(pos,tmp);
- pos+= recinfo[1].length;
+ pos+= recinfo[0].length;
}
else
{
create_key_part(pos,rownr);
- pos+=recinfo[1].length;
+ pos+=recinfo[0].length;
}
- if (recinfo[2].type == FIELD_BLOB)
+ if (recinfo[1].type == FIELD_BLOB)
{
uint tmp;
char *ptr;;
@@ -443,7 +461,7 @@ static void create_record(char *record,uint rownr)
ptr=blob_record;
memcpy_fixed(pos+4,&ptr,sizeof(char*));
}
- else if (recinfo[2].type == FIELD_VARCHAR)
+ else if (recinfo[1].type == FIELD_VARCHAR)
{
uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
sprintf(pos+pack_length, "... row: %d", rownr);
@@ -456,7 +474,7 @@ static void create_record(char *record,uint rownr)
else
{
sprintf(pos,"... row: %d", rownr);
- strappend(pos,recinfo[2].length,' ');
+ strappend(pos,recinfo[1].length,' ');
}
}
@@ -465,7 +483,7 @@ static void create_record(char *record,uint rownr)
static void update_record(char *record)
{
char *pos=record+1;
- if (recinfo[1].type == FIELD_BLOB)
+ if (recinfo[0].type == FIELD_BLOB)
{
char *column,*ptr;
int length;
@@ -477,16 +495,16 @@ static void update_record(char *record)
if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM)
default_charset_info->cset->casedn(default_charset_info,
blob_key, length, blob_key, length);
- pos+=recinfo[1].length;
+ pos+=recinfo[0].length;
}
- else if (recinfo[1].type == FIELD_VARCHAR)
+ else if (recinfo[0].type == FIELD_VARCHAR)
{
- uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
+ uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[0].length-1);
uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
default_charset_info->cset->casedn(default_charset_info,
pos + pack_length, length,
pos + pack_length, length);
- pos+=recinfo[1].length;
+ pos+=recinfo[0].length;
}
else
{
@@ -494,10 +512,10 @@ static void update_record(char *record)
default_charset_info->cset->casedn(default_charset_info,
pos, keyinfo[0].seg[0].length,
pos, keyinfo[0].seg[0].length);
- pos+=recinfo[1].length;
+ pos+=recinfo[0].length;
}
- if (recinfo[2].type == FIELD_BLOB)
+ if (recinfo[1].type == FIELD_BLOB)
{
char *column;
int length;
@@ -510,13 +528,14 @@ static void update_record(char *record)
column=blob_record;
memcpy_fixed(pos+4,&column,sizeof(char*));
}
- else if (recinfo[2].type == FIELD_VARCHAR)
+ else if (recinfo[1].type == FIELD_VARCHAR)
{
/* Second field is longer than 10 characters */
uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
- bfill(pos+pack_length+length,recinfo[2].length-length-pack_length,'.');
- length=recinfo[2].length-pack_length;
+ pos= record+ recinfo[1].offset;
+ bfill(pos+pack_length+length,recinfo[1].length-length-pack_length,'.');
+ length=recinfo[1].length-pack_length;
if (pack_length == 1)
*(uchar*) pos= (uchar) length;
else
@@ -524,7 +543,7 @@ static void update_record(char *record)
}
else
{
- bfill(pos+recinfo[2].length-10,10,'.');
+ bfill(pos+recinfo[1].length-10,10,'.');
}
}
@@ -537,44 +556,49 @@ static struct my_option my_long_options[] =
{"debug", '#', "Undocumented",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"delete_rows", 'd', "Undocumented", (gptr*) &remove_count,
- (gptr*) &remove_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"delete-rows", 'd', "Abort after this many rows has been deleted",
+ (gptr*) &remove_count, (gptr*) &remove_count, 0, GET_UINT, REQUIRED_ARG,
+ 1000, 0, 0, 0, 0, 0},
{"help", '?', "Display help and exit",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"insert_rows", 'i', "Undocumented", (gptr*) &insert_count,
+ {"insert-rows", 'i', "Undocumented", (gptr*) &insert_count,
(gptr*) &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
- {"key_alpha", 'a', "Use a key of type HA_KEYTYPE_TEXT",
+ {"key-alpha", 'a', "Use a key of type HA_KEYTYPE_TEXT",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"key_binary_pack", 'B', "Undocumented",
+ {"key-binary-pack", 'B', "Undocumented",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"key_blob", 'b', "Undocumented",
+ {"key-blob", 'b', "Undocumented",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"key_cache", 'K', "Undocumented", (gptr*) &key_cacheing,
+ {"key-cache", 'K', "Undocumented", (gptr*) &key_cacheing,
(gptr*) &key_cacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"key_length", 'k', "Undocumented", (gptr*) &key_length, (gptr*) &key_length,
+ {"key-length", 'k', "Undocumented", (gptr*) &key_length, (gptr*) &key_length,
0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0},
- {"key_multiple", 'm', "Undocumented",
+ {"key-multiple", 'm', "Undocumented",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"key_prefix_pack", 'P', "Undocumented",
+ {"key-prefix_pack", 'P', "Undocumented",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"key_space_pack", 'p', "Undocumented",
+ {"key-space_pack", 'p', "Undocumented",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"key_varchar", 'w', "Test VARCHAR keys",
+ {"key-varchar", 'w', "Test VARCHAR keys",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"null_fields", 'N', "Define fields with NULL",
+ {"null-fields", 'N', "Define fields with NULL",
(gptr*) &null_fields, (gptr*) &null_fields, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
- {"row_fixed_size", 'S', "Undocumented",
+ {"row-fixed-size", 'S', "Fixed size records",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"rows-in-block", 'M', "Store rows in block format",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"row_pointer_size", 'R', "Undocumented", (gptr*) &rec_pointer_size,
+ {"row-pointer-size", 'R', "Undocumented", (gptr*) &rec_pointer_size,
(gptr*) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"silent", 's', "Undocumented",
(gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"skip_update", 'U', "Undocumented", (gptr*) &skip_update,
+ {"skip-delete", 'U', "Don't test deletes", (gptr*) &skip_delete,
+ (gptr*) &skip_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-update", 'D', "Don't test updates", (gptr*) &skip_update,
(gptr*) &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"unique", 'C', "Undocumented", (gptr*) &opt_unique, (gptr*) &opt_unique, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"update_rows", 'u', "Undocumented", (gptr*) &update_count,
+ {"update-rows", 'u', "Undocumented", (gptr*) &update_count,
(gptr*) &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
{"verbose", 'v', "Be more verbose", (gptr*) &verbose, (gptr*) &verbose, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -605,15 +629,20 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'B':
pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */
break;
+ case 'M':
+ record_type= BLOCK_RECORD;
+ break;
case 'S':
if (key_field == FIELD_VARCHAR)
{
create_flag=0; /* Static sized varchar */
+ record_type= STATIC_RECORD;
}
else if (key_field != FIELD_BLOB)
{
key_field=FIELD_NORMAL; /* static-size record */
extra_field=FIELD_NORMAL;
+ record_type= STATIC_RECORD;
}
break;
case 'p':
@@ -629,6 +658,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
extra_field= FIELD_BLOB;
pack_seg|= HA_BLOB_PART;
key_type= HA_KEYTYPE_VARTEXT1;
+ if (record_type == STATIC_RECORD)
+ record_type= DYNAMIC_RECORD;
break;
case 'k':
if (key_length < 4 || key_length > HA_MAX_KEY_LENGTH)
@@ -642,7 +673,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
extra_field= FIELD_VARCHAR;
key_type= HA_KEYTYPE_VARTEXT1;
pack_seg|= HA_VAR_LENGTH_PART;
- create_flag|= HA_PACK_RECORD;
+ if (record_type == STATIC_RECORD)
+ record_type= DYNAMIC_RECORD;
break;
case 'K': /* Use key cacheing */
key_cacheing=1;
diff --git a/storage/maria/ma_test2.c b/storage/maria/ma_test2.c
index 40f7d2aaffb..46b8c710d4a 100644
--- a/storage/maria/ma_test2.c
+++ b/storage/maria/ma_test2.c
@@ -39,7 +39,8 @@
static void get_options(int argc, char *argv[]);
static uint rnd(uint max_value);
static void fix_length(byte *record,uint length);
-static void put_blob_in_record(char *blob_pos,char **blob_buffer);
+static void put_blob_in_record(char *blob_pos,char **blob_buffer,
+ ulong *length);
static void copy_key(struct st_maria_info *info,uint inx,
uchar *record,uchar *key);
@@ -47,10 +48,11 @@ static int verbose=0,testflag=0,
first_key=0,async_io=0,key_cacheing=0,write_cacheing=0,locking=0,
rec_pointer_size=0,pack_fields=1,silent=0,
opt_quick_mode=0;
-static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1,
- create_flag=0;
+static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1;
+static int create_flag= 0, srand_arg= 0;
static ulong key_cache_size=IO_SIZE*16;
static uint key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
+static enum data_file_type record_type= DYNAMIC_RECORD;
static uint keys=MARIA_KEYS,recant=1000;
static uint use_blob=0;
@@ -202,16 +204,14 @@ int main(int argc, char *argv[])
for (i=4999 ; i>0 ; i--) key3[i]=0;
if (!silent)
- printf("- Creating isam-file\n");
- /* DBUG_PUSH(""); */
- /* my_delete(filename,MYF(0)); */ /* Remove old locks under gdb */
+ printf("- Creating maria-file\n");
file= 0;
bzero((char*) &create_info,sizeof(create_info));
create_info.max_rows=(ha_rows) (rec_pointer_size ?
(1L << (rec_pointer_size*8))/
reclength : 0);
create_info.reloc_rows=(ha_rows) 100;
- if (maria_create(filename,keys,&keyinfo[first_key],
+ if (maria_create(filename, record_type, keys,&keyinfo[first_key],
use_blob ? 7 : 6, &recinfo[0],
0,(MARIA_UNIQUEDEF*) 0,
&create_info,create_flag))
@@ -231,12 +231,13 @@ int main(int argc, char *argv[])
for (i=0 ; i < recant ; i++)
{
+ ulong blob_length;
n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
sprintf(record,"%6d:%4d:%8d:Pos: %4d ",n1,n2,n3,write_count);
int4store(record+STANDARD_LENGTH-4,(long) i);
fix_length(record,(uint) STANDARD_LENGTH+rnd(60));
- put_blob_in_record(record+blob_pos,&blob_buffer);
- DBUG_PRINT("test",("record: %d",i));
+ put_blob_in_record(record+blob_pos,&blob_buffer, &blob_length);
+ DBUG_PRINT("test",("record: %d blob_length: %lu", i, blob_length));
if (maria_write(file,record))
{
@@ -258,7 +259,7 @@ int main(int argc, char *argv[])
}
/* Check if we can find key without flushing database */
- if (i == recant/2)
+ if (i % 10 == 0)
{
for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
if (!j)
@@ -271,7 +272,8 @@ int main(int argc, char *argv[])
}
}
}
- if (testflag==1) goto end;
+ if (testflag == 1)
+ goto end;
if (write_cacheing)
{
@@ -286,6 +288,8 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Delete\n");
+ if (srand_arg)
+ srand(srand_arg);
for (i=0 ; i<recant/10 ; i++)
{
for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
@@ -297,6 +301,12 @@ int main(int argc, char *argv[])
printf("can't find key1: \"%s\"\n",key);
goto err;
}
+ if (bcmp(read_record+keyinfo[0].seg[0].start,
+ key, keyinfo[0].seg[0].length))
+ {
+ printf("Found wrong record when searching for key: \"%s\"\n",key);
+ goto err;
+ }
if (opt_delete == (uint) remove_count) /* While testing */
goto end;
if (maria_delete(file,read_record))
@@ -311,10 +321,13 @@ int main(int argc, char *argv[])
else
puts("Warning: Skipping delete test because no dupplicate keys");
}
- if (testflag==2) goto end;
+ if (testflag == 2)
+ goto end;
if (!silent)
printf("- Update\n");
+ if (srand_arg)
+ srand(srand_arg);
for (i=0 ; i<recant/10 ; i++)
{
n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
@@ -331,10 +344,19 @@ int main(int argc, char *argv[])
printf("can't find key1: \"%s\"\n",key);
goto err;
}
+ if (bcmp(read_record+keyinfo[0].seg[0].start,
+ key, keyinfo[0].seg[0].length))
+ {
+ printf("Found wrong record when searching for key: \"%s\"; Found \"%.*s\"\n",
+ key, keyinfo[0].seg[0].length,
+ read_record+keyinfo[0].seg[0].start);
+ goto err;
+ }
if (use_blob)
{
+ ulong blob_length;
if (i & 1)
- put_blob_in_record(record+blob_pos,&blob_buffer);
+ put_blob_in_record(record+blob_pos,&blob_buffer, &blob_length);
else
bmove(record+blob_pos,read_record+blob_pos,8);
}
@@ -396,10 +418,12 @@ int main(int argc, char *argv[])
goto end;
}
{
+ info.recpos= maria_position(file);
int skr=maria_rnext(file,read_record2,0);
if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
maria_rprev(file,read_record2,-1) ||
- memcmp(read_record,read_record2,reclength) != 0)
+ memcmp(read_record,read_record2,reclength) != 0 ||
+ info.recpos != maria_position(file))
{
printf("maria_rsame_with_pos lost position\n");
goto end;
@@ -589,13 +613,24 @@ int main(int argc, char *argv[])
if (!silent)
puts("- Test if: Read rrnd - same");
DBUG_PRINT("progpos",("Read rrnd - same"));
+ assert(maria_scan_init(file) == 0);
for (i=0 ; i < write_count ; i++)
{
- if (maria_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR) == 0)
+ int tmp;
+ if ((tmp= maria_scan(file,read_record)) &&
+ tmp != HA_ERR_END_OF_FILE &&
+ tmp != HA_ERR_RECORD_DELETED)
+ {
+ printf("Got error %d when scanning table\n", tmp);
break;
+ }
}
- if (i == write_count)
+ maria_scan_end(file);
+ if (i != write_count && i != write_count - opt_delete)
+ {
+ printf("Found wrong number of rows while scanning table\n");
goto err;
+ }
bmove(read_record2,read_record,reclength);
for (i=min(2,keys) ; i-- > 0 ;)
@@ -603,7 +638,7 @@ int main(int argc, char *argv[])
if (maria_rsame(file,read_record2,(int) i)) goto err;
if (bcmp(read_record,read_record2,reclength) != 0)
{
- printf("is_rsame didn't find same record\n");
+ printf("maria_rsame didn't find same record\n");
goto end;
}
}
@@ -717,12 +752,14 @@ int main(int argc, char *argv[])
}
}
ant=0;
- while ((error=maria_rrnd(file,record,HA_OFFSET_ERROR)) != HA_ERR_END_OF_FILE &&
+ assert(maria_scan_init(file) == 0);
+ while ((error= maria_scan(file,record)) != HA_ERR_END_OF_FILE &&
ant < write_count + 10)
- ant+= error ? 0 : 1;
+ ant+= error ? 0 : 1;
+ maria_scan_end(file);
if (ant != write_count-opt_delete)
{
- printf("rrnd with cache: I can only find: %d records of %d\n",
+ printf("scan with cache: I can only find: %d records of %d\n",
ant,write_count-opt_delete);
goto end;
}
@@ -744,7 +781,8 @@ int main(int argc, char *argv[])
goto end;
}
- if (testflag == 4) goto end;
+ if (testflag == 4)
+ goto end;
if (!silent)
printf("- Removing keys\n");
@@ -753,8 +791,8 @@ int main(int argc, char *argv[])
/* DBUG_POP(); */
maria_reset(file);
found_parts=0;
- while ((error=maria_rrnd(file,read_record,HA_OFFSET_ERROR)) !=
- HA_ERR_END_OF_FILE)
+ maria_scan_init(file);
+ while ((error= maria_scan(file,read_record)) != HA_ERR_END_OF_FILE)
{
info.recpos=maria_position(file);
if (lastpos >= info.recpos && lastpos != HA_OFFSET_ERROR)
@@ -768,7 +806,7 @@ int main(int argc, char *argv[])
{
if (opt_delete == (uint) remove_count) /* While testing */
goto end;
- if (maria_rsame(file,read_record,-1))
+ if (rnd(2) == 1 && maria_rsame(file,read_record,-1))
{
printf("can't find record %lx\n",(long) info.recpos);
goto err;
@@ -784,9 +822,10 @@ int main(int argc, char *argv[])
{
if (ptr[pos] != (uchar) (blob_length+pos))
{
- printf("found blob with wrong info at %ld\n",(long) lastpos);
- use_blob=0;
- break;
+ printf("Found blob with wrong info at %ld\n",(long) lastpos);
+ maria_scan_end(file);
+ my_errno= 0;
+ goto err;
}
}
}
@@ -794,6 +833,7 @@ int main(int argc, char *argv[])
{
printf("can't delete record: %6.6s, delete_count: %d\n",
read_record, opt_delete);
+ maria_scan_end(file);
goto err;
}
opt_delete++;
@@ -801,6 +841,7 @@ int main(int argc, char *argv[])
else
found_parts++;
}
+ maria_scan_end(file);
if (my_errno != HA_ERR_END_OF_FILE && my_errno != HA_ERR_RECORD_DELETED)
printf("error: %d from maria_rrnd\n",my_errno);
if (write_count != opt_delete)
@@ -852,8 +893,7 @@ reads: %10lu\n",
(ulong) maria_key_cache->global_cache_read);
}
end_key_cache(maria_key_cache,1);
- if (blob_buffer)
- my_free(blob_buffer,MYF(0));
+ my_free(blob_buffer, MYF(MY_ALLOW_ZERO_PTR));
my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
return(0);
err:
@@ -865,8 +905,7 @@ err:
} /* main */
- /* l{ser optioner */
- /* OBS! intierar endast DEBUG - ingen debuggning h{r ! */
+/* Read options */
static void get_options(int argc, char **argv)
{
@@ -880,7 +919,9 @@ static void get_options(int argc, char **argv)
pack_type= HA_BINARY_PACK_KEY;
break;
case 'b':
- use_blob=1;
+ use_blob= 1;
+ if (*++pos)
+ use_blob= atol(pos);
break;
case 'K': /* Use key cacheing */
key_cacheing=1;
@@ -897,7 +938,7 @@ static void get_options(int argc, char **argv)
break;
case 'i':
if (*++pos)
- srand(atoi(pos));
+ srand(srand_arg= atoi(pos));
break;
case 'L':
locking=1;
@@ -911,9 +952,9 @@ static void get_options(int argc, char **argv)
verbose=1;
break;
case 'm': /* records */
- if ((recant=atoi(++pos)) < 10)
+ if ((recant=atoi(++pos)) < 10 && testflag > 1)
{
- fprintf(stderr,"record count must be >= 10\n");
+ fprintf(stderr,"record count must be >= 10 (if testflag != 1)\n");
exit(1);
}
break;
@@ -944,6 +985,9 @@ static void get_options(int argc, char **argv)
keys > (uint) (MARIA_KEYS-first_key))
keys=MARIA_KEYS-first_key;
break;
+ case 'M':
+ record_type= BLOCK_RECORD;
+ break;
case 'P':
pack_type=0; /* Don't use DIFF_LENGTH */
pack_seg=0;
@@ -955,6 +999,7 @@ static void get_options(int argc, char **argv)
break;
case 'S':
pack_fields=0; /* Static-length-records */
+ record_type= STATIC_RECORD;
break;
case 's':
silent=1;
@@ -974,7 +1019,7 @@ static void get_options(int argc, char **argv)
case '?':
case 'I':
case 'V':
- printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
+ printf("%s Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
puts("By Monty, for your professional use\n");
printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n",
progname);
@@ -1011,7 +1056,8 @@ static void fix_length(byte *rec, uint length)
/* Put maybe a blob in record */
-static void put_blob_in_record(char *blob_pos, char **blob_buffer)
+static void put_blob_in_record(char *blob_pos, char **blob_buffer,
+ ulong *blob_length)
{
ulong i,length;
if (use_blob)
@@ -1029,10 +1075,12 @@ static void put_blob_in_record(char *blob_pos, char **blob_buffer)
(*blob_buffer)[i]=(char) (length+i);
int4store(blob_pos,length);
memcpy_fixed(blob_pos+4,(char*) blob_buffer,sizeof(char*));
+ *blob_length= length;
}
else
{
int4store(blob_pos,0);
+ *blob_length= 0;
}
}
return;
diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c
index 2f205c33b12..f6ed248ce16 100644
--- a/storage/maria/ma_test3.c
+++ b/storage/maria/ma_test3.c
@@ -101,8 +101,8 @@ int main(int argc,char **argv)
puts("- Creating maria-file");
my_delete(filename,MYF(0)); /* Remove old locks under gdb */
- if (maria_create(filename,2,&keyinfo[0],2,&recinfo[0],0,(MARIA_UNIQUEDEF*) 0,
- (MARIA_CREATE_INFO*) 0,0))
+ if (maria_create(filename,BLOCK_RECORD, 2, &keyinfo[0],2,&recinfo[0],0,
+ (MARIA_UNIQUEDEF*) 0, (MARIA_CREATE_INFO*) 0,0))
exit(1);
rnd_init(0);
diff --git a/storage/maria/ma_test_all.sh b/storage/maria/ma_test_all.sh
index 73234d93ae4..17e654ac51f 100755
--- a/storage/maria/ma_test_all.sh
+++ b/storage/maria/ma_test_all.sh
@@ -5,142 +5,188 @@
valgrind="valgrind --alignment=8 --leak-check=yes"
silent="-s"
+suffix=""
+#set -x -v -e
-if test -f ma_test1$MACH ; then suffix=$MACH ; else suffix=""; fi
-./ma_test1$suffix $silent
-./maria_chk$suffix -se test1
-./ma_test1$suffix $silent -N -S
-./maria_chk$suffix -se test1
-./ma_test1$suffix $silent -P --checksum
-./maria_chk$suffix -se test1
-./ma_test1$suffix $silent -P -N -S
-./maria_chk$suffix -se test1
-./ma_test1$suffix $silent -B -N -R2
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -k 480 --unique
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -N -S -R1
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -p -S
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -p -S -N --unique
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -p -S -N --key_length=127 --checksum
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -p -S -N --key_length=128
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -p -S --key_length=480
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -B
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -B --key_length=64 --unique
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -B -k 480 --checksum
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -B -k 480 -N --unique --checksum
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -m
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -m -P --unique --checksum
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -m -P --key_length=480 --key_cache
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -m -p
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -w -S --unique
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -w --key_length=64 --checksum
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -w -N --key_length=480
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -w -S --key_length=480 --checksum
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -b -N
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -a -b --key_length=480
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent -p -B --key_length=480
-./maria_chk$suffix -sm test1
+run_tests()
+{
+ row_type=$1
+ #
+ # First some simple tests
+ #
+ ./ma_test1$suffix $silent $row_type
+ ./maria_chk$suffix -se test1
+ ./ma_test1$suffix $silent -N $row_type
+ ./maria_chk$suffix -se test1
+ ./ma_test1$suffix $silent -P --checksum $row_type
+ ./maria_chk$suffix -se test1
+ ./ma_test1$suffix $silent -P -N $row_type
+ ./maria_chk$suffix -se test1
+ ./ma_test1$suffix $silent -B -N -R2 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -k 480 --unique $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -N -R1 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -p $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -p -N --unique $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -p -N --key_length=127 --checksum $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -p -N --key_length=128 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -p --key_length=480 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -B $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -B --key_length=64 --unique $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -B -k 480 --checksum $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -B -k 480 -N --unique --checksum $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -m $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -m -P --unique --checksum $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -m -P --key_length=480 --key_cache $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -m -p $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -w --unique $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -w --key_length=64 --checksum $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -w -N --key_length=480 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -w --key_length=480 --checksum $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -b -N $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -a -b --key_length=480 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent -p -B --key_length=480 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent --checksum --unique $row_type
+ ./maria_chk$suffix -se test1
+ ./ma_test1$suffix $silent --unique $row_type
+ ./maria_chk$suffix -se test1
+
+ ./ma_test1$suffix $silent --key_multiple -N -S $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent --key_multiple -a -p --key_length=480 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent --key_multiple -a -B --key_length=480 $row_type
+ ./maria_chk$suffix -sm test1
+ ./ma_test1$suffix $silent --key_multiple -P -S $row_type
+ ./maria_chk$suffix -sm test1
+
+ ./maria_pack$suffix --force -s test1
+ ./maria_chk$suffix -ess test1
+
+ ./ma_test2$suffix $silent -L -K -W -P $row_type
+ ./maria_chk$suffix -sm test2
+ ./ma_test2$suffix $silent -L -K -W -P -A $row_type
+ ./maria_chk$suffix -sm test2
+ ./ma_test2$suffix $silent -L -K -P -R3 -m50 -b1000000 $row_type
+ ./maria_chk$suffix -sm test2
+ ./ma_test2$suffix $silent -L -B $row_type
+ ./maria_chk$suffix -sm test2
+ ./ma_test2$suffix $silent -D -B -c $row_type
+ ./maria_chk$suffix -sm test2
+ ./ma_test2$suffix $silent -m10000 -e4096 -K $row_type
+ ./maria_chk$suffix -sm test2
+ ./ma_test2$suffix $silent -m10000 -e8192 -K $row_type
+ ./maria_chk$suffix -sm test2
+ ./ma_test2$suffix $silent -m10000 -e16384 -E16384 -K -L $row_type
+ ./maria_chk$suffix -sm test2
+}
-./ma_test1$suffix $silent --checksum
-./maria_chk$suffix -se test1
-./maria_chk$suffix -rs test1
-./maria_chk$suffix -se test1
-./maria_chk$suffix -rqs test1
-./maria_chk$suffix -se test1
-./maria_chk$suffix -rs --correct-checksum test1
-./maria_chk$suffix -se test1
-./maria_chk$suffix -rqs --correct-checksum test1
-./maria_chk$suffix -se test1
-./maria_chk$suffix -ros --correct-checksum test1
-./maria_chk$suffix -se test1
-./maria_chk$suffix -rqos --correct-checksum test1
-./maria_chk$suffix -se test1
+run_repair_tests()
+{
+ row_type=$1
+ ./ma_test1$suffix $silent --checksum $row_type
+ ./maria_chk$suffix -se test1
+ ./maria_chk$suffix -rs test1
+ ./maria_chk$suffix -se test1
+ ./maria_chk$suffix -rqs test1
+ ./maria_chk$suffix -se test1
+ ./maria_chk$suffix -rs --correct-checksum test1
+ ./maria_chk$suffix -se test1
+ ./maria_chk$suffix -rqs --correct-checksum test1
+ ./maria_chk$suffix -se test1
+ ./maria_chk$suffix -ros --correct-checksum test1
+ ./maria_chk$suffix -se test1
+ ./maria_chk$suffix -rqos --correct-checksum test1
+ ./maria_chk$suffix -se test1
+}
-# check of maria_pack / maria_chk
-./maria_pack$suffix --force -s test1
-# Ignore error for index file
-./maria_chk$suffix -es test1 2>&1 >& /dev/null
-./maria_chk$suffix -rqs test1
-./maria_chk$suffix -es test1
-./maria_chk$suffix -rs test1
-./maria_chk$suffix -es test1
-./maria_chk$suffix -rus test1
-./maria_chk$suffix -es test1
+run_pack_tests()
+{
+ row_type=$1
+ # check of maria_pack / maria_chk
+ ./ma_test1$suffix $silent --checksum $row_type
+ ./maria_pack$suffix --force -s test1
+ ./maria_chk$suffix -ess test1
+ ./maria_chk$suffix -rqs test1
+ ./maria_chk$suffix -es test1
+ ./maria_chk$suffix -rs test1
+ ./maria_chk$suffix -es test1
+ ./maria_chk$suffix -rus test1
+ ./maria_chk$suffix -es test1
+
+ ./ma_test1$suffix $silent --checksum -S $row_type
+ ./maria_chk$suffix -se test1
+ ./maria_chk$suffix -ros test1
+ ./maria_chk$suffix -rqs test1
+ ./maria_chk$suffix -se test1
+
+ ./maria_pack$suffix --force -s test1
+ ./maria_chk$suffix -rqs test1
+ ./maria_chk$suffix -es test1
+ ./maria_chk$suffix -rus test1
+ ./maria_chk$suffix -es test1
+}
-./ma_test1$suffix $silent --checksum -S
-./maria_chk$suffix -se test1
-./maria_chk$suffix -ros test1
-./maria_chk$suffix -rqs test1
-./maria_chk$suffix -se test1
+echo "Running tests with dynamic row format"
+run_tests ""
+run_repair_tests ""
+run_pack_tests ""
-./maria_pack$suffix --force -s test1
-./maria_chk$suffix -rqs test1
-./maria_chk$suffix -es test1
-./maria_chk$suffix -rus test1
-./maria_chk$suffix -es test1
+echo "Running tests with static row format"
+run_tests -S
+run_repair_tests -S
+run_pack_tests -S
-./ma_test1$suffix $silent --checksum --unique
-./maria_chk$suffix -se test1
-./ma_test1$suffix $silent --unique -S
-./maria_chk$suffix -se test1
+echo "Running tests with block row format"
+run_tests -M
+#
+# Tests that gives warnings
+#
-./ma_test1$suffix $silent --key_multiple -N -S
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent --key_multiple -a -p --key_length=480
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent --key_multiple -a -B --key_length=480
-./maria_chk$suffix -sm test1
-./ma_test1$suffix $silent --key_multiple -P -S
-./maria_chk$suffix -sm test1
-
-./ma_test2$suffix $silent -L -K -W -P
-./maria_chk$suffix -sm test2
-./ma_test2$suffix $silent -L -K -W -P -A
-./maria_chk$suffix -sm test2
./ma_test2$suffix $silent -L -K -W -P -S -R1 -m500
-echo "ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135"
./maria_chk$suffix -sm test2
+echo "ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135"
./ma_test2$suffix $silent -L -K -R1 -m2000
+echo "./maria_chk$suffix -sm test2 will warn that 'Datafile is almost full'"
./maria_chk$suffix -sm test2
-./ma_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000
-./maria_chk$suffix -sm test2
-./ma_test2$suffix $silent -L -B
-./maria_chk$suffix -sm test2
-./ma_test2$suffix $silent -D -B -c
-./maria_chk$suffix -sm test2
-./ma_test2$suffix $silent -m10000 -e8192 -K
-./maria_chk$suffix -sm test2
-./ma_test2$suffix $silent -m10000 -e16384 -E16384 -K -L
-./maria_chk$suffix -sm test2
+./maria_chk$suffix -ssm test2
-./ma_test2$suffix $silent -L -K -W -P -m50
-./ma_test2$suffix $silent -L -K -W -P -m50 -b100
+#
+# Some timing tests
+#
time ./ma_test2$suffix $silent
+time ./ma_test2$suffix $silent -S
+time ./ma_test2$suffix $silent -M
+time ./ma_test2$suffix $silent -B
+time ./ma_test2$suffix $silent -L
+time ./ma_test2$suffix $silent -K
time ./ma_test2$suffix $silent -K -B
time ./ma_test2$suffix $silent -L -B
time ./ma_test2$suffix $silent -L -K -B
time ./ma_test2$suffix $silent -L -K -W -B
-time ./ma_test2$suffix $silent -L -K -W -S -B
-time ./ma_test2$suffix $silent -D -K -W -S -B
+time ./ma_test2$suffix $silent -L -K -W -B -S
+time ./ma_test2$suffix $silent -L -K -W -B -M
+time ./ma_test2$suffix $silent -D -K -W -B -S
diff --git a/storage/maria/ma_unique.c b/storage/maria/ma_unique.c
index e2c7ca3c80c..b79c5558933 100644
--- a/storage/maria/ma_unique.c
+++ b/storage/maria/ma_unique.c
@@ -22,10 +22,11 @@
my_bool _ma_check_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def, byte *record,
ha_checksum unique_hash, my_off_t disk_pos)
{
- my_off_t lastpos=info->lastpos;
+ my_off_t lastpos=info->cur_row.lastpos;
MARIA_KEYDEF *key= &info->s->keyinfo[def->key];
- uchar *key_buff=info->lastkey2;
+ byte *key_buff= info->lastkey2;
DBUG_ENTER("_ma_check_unique");
+ DBUG_PRINT("enter",("unique_hash: %lu", unique_hash));
maria_unique_store(record+key->seg->start, unique_hash);
_ma_make_key(info,def->key,key_buff,record,0);
@@ -33,24 +34,25 @@ my_bool _ma_check_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def, byte *record,
/* The above changed info->lastkey2. Inform maria_rnext_same(). */
info->update&= ~HA_STATE_RNEXT_SAME;
- if (_ma_search(info,info->s->keyinfo+def->key,key_buff,MARIA_UNIQUE_HASH_LENGTH,
+ if (_ma_search(info,info->s->keyinfo+def->key,key_buff,
+ MARIA_UNIQUE_HASH_LENGTH,
SEARCH_FIND,info->s->state.key_root[def->key]))
{
info->page_changed=1; /* Can't optimize read next */
- info->lastpos= lastpos;
+ info->cur_row.lastpos= lastpos;
DBUG_RETURN(0); /* No matching rows */
}
for (;;)
{
- if (info->lastpos != disk_pos &&
- !(*info->s->compare_unique)(info,def,record,info->lastpos))
+ if (info->cur_row.lastpos != disk_pos &&
+ !(*info->s->compare_unique)(info,def,record,info->cur_row.lastpos))
{
my_errno=HA_ERR_FOUND_DUPP_UNIQUE;
info->errkey= (int) def->key;
- info->dupp_key_pos= info->lastpos;
- info->page_changed=1; /* Can't optimize read next */
- info->lastpos=lastpos;
+ info->dup_key_pos= info->cur_row.lastpos;
+ info->page_changed= 1; /* Can't optimize read next */
+ info->cur_row.lastpos= lastpos;
DBUG_PRINT("info",("Found duplicate"));
DBUG_RETURN(1); /* Found identical */
}
@@ -60,8 +62,8 @@ my_bool _ma_check_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def, byte *record,
bcmp((char*) info->lastkey, (char*) key_buff,
MARIA_UNIQUE_HASH_LENGTH))
{
- info->page_changed=1; /* Can't optimize read next */
- info->lastpos=lastpos;
+ info->page_changed= 1; /* Can't optimize read next */
+ info->cur_row.lastpos= lastpos;
DBUG_RETURN(0); /* end of tree */
}
}
@@ -144,11 +146,11 @@ ha_checksum _ma_unique_hash(MARIA_UNIQUEDEF *def, const byte *record)
RETURN
0 if both rows have equal unique value
- # Rows are different
+ 1 Rows are different
*/
-int _ma_unique_comp(MARIA_UNIQUEDEF *def, const byte *a, const byte *b,
- my_bool null_are_equal)
+my_bool _ma_unique_comp(MARIA_UNIQUEDEF *def, const byte *a, const byte *b,
+ my_bool null_are_equal)
{
const byte *pos_a, *pos_b, *end;
HA_KEYSEG *keyseg;
diff --git a/storage/maria/ma_update.c b/storage/maria/ma_update.c
index b916b211159..e3e391dcccc 100644
--- a/storage/maria/ma_update.c
+++ b/storage/maria/ma_update.c
@@ -24,7 +24,7 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
int flag,key_changed,save_errno;
reg3 my_off_t pos;
uint i;
- uchar old_key[HA_MAX_KEY_BUFF],*new_key;
+ byte old_key[HA_MAX_KEY_BUFF],*new_key;
bool auto_key_changed=0;
ulonglong changed;
MARIA_SHARE *share=info->s;
@@ -49,18 +49,26 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
{
DBUG_RETURN(my_errno=HA_ERR_INDEX_FILE_FULL);
}
- pos=info->lastpos;
+ pos= info->cur_row.lastpos;
if (_ma_readinfo(info,F_WRLCK,1))
DBUG_RETURN(my_errno);
- if (share->calc_checksum)
- old_checksum=info->checksum=(*share->calc_checksum)(info,oldrec);
if ((*share->compare_record)(info,oldrec))
{
- save_errno=my_errno;
+ save_errno= my_errno;
+ DBUG_PRINT("warning", ("Got error from compare record"));
goto err_end; /* Record has changed */
}
+ if (share->calc_checksum)
+ {
+ /*
+ We can't use the row based checksum as this doesn't have enough
+ precision.
+ */
+ if (info->s->calc_checksum)
+ old_checksum= (*info->s->calc_checksum)(info, oldrec);
+ }
/* Calculate and check all unique constraints */
key_changed=0;
@@ -69,7 +77,7 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
MARIA_UNIQUEDEF *def=share->uniqueinfo+i;
if (_ma_unique_comp(def, newrec, oldrec,1) &&
_ma_check_unique(info, def, newrec, _ma_unique_hash(def, newrec),
- info->lastpos))
+ pos))
{
save_errno=my_errno;
goto err_end;
@@ -83,7 +91,7 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
/* Check which keys changed from the original row */
- new_key=info->lastkey2;
+ new_key= info->lastkey2;
changed=0;
for (i=0 ; i < share->base.keys ; i++)
{
@@ -116,7 +124,7 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
info->update&= ~HA_STATE_RNEXT_SAME;
if (new_length != old_length ||
- memcmp((byte*) old_key,(byte*) new_key,new_length))
+ memcmp(old_key, new_key, new_length))
{
if ((int) i == info->lastinx)
key_changed|=HA_STATE_WRITTEN; /* Mark that keyfile changed */
@@ -139,7 +147,7 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
if (share->calc_checksum)
{
- info->checksum=(*share->calc_checksum)(info,newrec);
+ info->cur_row.checksum= (*share->calc_checksum)(info,newrec);
/* Store new checksum in index file header */
key_changed|= HA_STATE_CHANGED;
}
@@ -167,10 +175,13 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
set_if_bigger(info->s->state.auto_increment,
ma_retrieve_auto_increment(info, newrec));
if (share->calc_checksum)
- info->state->checksum+=(info->checksum - old_checksum);
+ info->state->checksum+= (info->cur_row.checksum - old_checksum);
- info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
- key_changed);
+ /*
+ We can't yet have HA_STATE_ACTIVE here, as block_record dosn't support
+ it
+ */
+ info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed);
/*
Every Maria function that updates Maria table must end with
@@ -195,8 +206,6 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
err:
DBUG_PRINT("error",("key: %d errno: %d",i,my_errno));
save_errno=my_errno;
- if (changed)
- key_changed|= HA_STATE_CHANGED;
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
{
info->errkey= (int) i;
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 55c0bf27259..3f1ca59a00a 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -24,33 +24,52 @@
/* Functions declared in this file */
static int w_search(MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- uint comp_flag, uchar *key,
- uint key_length, my_off_t pos, uchar *father_buff,
- uchar *father_keypos, my_off_t father_page,
+ uint comp_flag, byte *key,
+ uint key_length, my_off_t pos, byte *father_buff,
+ byte *father_keypos, my_off_t father_page,
my_bool insert_last);
-static int _ma_balance_page(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *key,
- uchar *curr_buff,uchar *father_buff,
- uchar *father_keypos,my_off_t father_page);
-static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint *return_key_length,
- uchar **after_key);
-int _ma_ck_write_tree(register MARIA_HA *info, uint keynr,uchar *key,
+static int _ma_balance_page(MARIA_HA *info,MARIA_KEYDEF *keyinfo,byte *key,
+ byte *curr_buff,byte *father_buff,
+ byte *father_keypos,my_off_t father_page);
+static byte *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint *return_key_length,
+ byte **after_key);
+int _ma_ck_write_tree(register MARIA_HA *info, uint keynr,byte *key,
uint key_length);
-int _ma_ck_write_btree(register MARIA_HA *info, uint keynr,uchar *key,
+int _ma_ck_write_btree(register MARIA_HA *info, uint keynr,byte *key,
uint key_length);
- /* Write new record to database */
+
+MARIA_RECORD_POS _ma_write_init_default(MARIA_HA *info,
+ const byte *record
+ __attribute__((unused)))
+{
+ return ((info->s->state.dellink != HA_OFFSET_ERROR &&
+ !info->append_insert_at_end) ?
+ info->s->state.dellink :
+ info->state->data_file_length);
+}
+
+my_bool _ma_write_abort_default(MARIA_HA *info __attribute__((unused)))
+{
+ return 0;
+}
+
+
+/* Write new record to a table */
int maria_write(MARIA_HA *info, byte *record)
{
MARIA_SHARE *share=info->s;
uint i;
int save_errno;
- my_off_t filepos;
- uchar *buff;
+ MARIA_RECORD_POS filepos;
+ byte *buff;
my_bool lock_tree= share->concurrent_insert;
+ my_bool fatal_error;
DBUG_ENTER("maria_write");
- DBUG_PRINT("enter",("isam: %d data: %d",info->s->kfile,info->dfile));
+ DBUG_PRINT("enter",("index_file: %d data_file: %d",
+ info->s->kfile,info->dfile));
DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_usage",
maria_print_error(info->s, HA_ERR_CRASHED);
@@ -62,10 +81,6 @@ int maria_write(MARIA_HA *info, byte *record)
if (_ma_readinfo(info,F_WRLCK,1))
DBUG_RETURN(my_errno);
dont_break(); /* Dont allow SIGHUP or SIGINT */
- filepos= ((share->state.dellink != HA_OFFSET_ERROR &&
- !info->append_insert_at_end) ?
- share->state.dellink :
- info->state->data_file_length);
if (share->base.reloc == (ha_rows) 1 &&
share->base.records == (ha_rows) 1 &&
@@ -86,14 +101,26 @@ int maria_write(MARIA_HA *info, byte *record)
for (i=0 ; i < share->state.header.uniques ; i++)
{
if (_ma_check_unique(info,share->uniqueinfo+i,record,
- _ma_unique_hash(share->uniqueinfo+i,record),
- HA_OFFSET_ERROR))
+ _ma_unique_hash(share->uniqueinfo+i,record),
+ HA_OFFSET_ERROR))
goto err2;
}
- /* Write all keys to indextree */
+ if ((info->opt_flag & OPT_NO_ROWS))
+ filepos= HA_OFFSET_ERROR;
+ else
+ {
+ /*
+ This may either calculate a record or, or write the record and return
+ the record id
+ */
+ if ((filepos= (*share->write_record_init)(info, record)) ==
+ HA_OFFSET_ERROR)
+ goto err2;
+ }
- buff=info->lastkey2;
+ /* Write all keys to indextree */
+ buff= info->lastkey2;
for (i=0 ; i < share->base.keys ; i++)
{
if (maria_is_key_active(share->state.key_map, i))
@@ -136,13 +163,13 @@ int maria_write(MARIA_HA *info, byte *record)
rw_unlock(&share->key_root_lock[i]);
}
}
- if (share->calc_checksum)
- info->checksum=(*share->calc_checksum)(info,record);
- if (!(info->opt_flag & OPT_NO_ROWS))
+ if (share->calc_write_checksum)
+ info->cur_row.checksum= (*share->calc_write_checksum)(info,record);
+ if (filepos != HA_OFFSET_ERROR)
{
if ((*share->write_record)(info,record))
goto err;
- info->state->checksum+=info->checksum;
+ info->state->checksum+= info->cur_row.checksum;
}
if (share->base.auto_key)
set_if_bigger(info->s->state.auto_increment,
@@ -150,7 +177,7 @@ int maria_write(MARIA_HA *info, byte *record)
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
HA_STATE_ROW_CHANGED);
info->state->records++;
- info->lastpos=filepos;
+ info->cur_row.lastpos= filepos;
VOID(_ma_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
if (info->invalidator != 0)
{
@@ -174,8 +201,10 @@ int maria_write(MARIA_HA *info, byte *record)
DBUG_RETURN(0);
err:
- save_errno=my_errno;
- if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
+ save_errno= my_errno;
+ fatal_error= 0;
+ if (my_errno == HA_ERR_FOUND_DUPP_KEY ||
+ my_errno == HA_ERR_RECORD_FILE_FULL ||
my_errno == HA_ERR_NULL_IN_SPATIAL)
{
if (info->bulk_insert)
@@ -219,14 +248,21 @@ err:
}
}
else
+ fatal_error= 1;
+
+ if ((*share->write_record_abort)(info))
+ fatal_error= 1;
+ if (fatal_error)
{
maria_print_error(info->s, HA_ERR_CRASHED);
maria_mark_crashed(info);
}
+
info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED);
my_errno=save_errno;
err2:
save_errno=my_errno;
+ DBUG_PRINT("error", ("got error: %d", save_errno));
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(my_errno=save_errno);
@@ -235,7 +271,7 @@ err2:
/* Write one key to btree */
-int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
+int _ma_ck_write(MARIA_HA *info, uint keynr, byte *key, uint key_length)
{
DBUG_ENTER("_ma_ck_write");
@@ -254,7 +290,7 @@ int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
* Normal insert code *
**********************************************************************/
-int _ma_ck_write_btree(register MARIA_HA *info, uint keynr, uchar *key,
+int _ma_ck_write_btree(register MARIA_HA *info, uint keynr, byte *key,
uint key_length)
{
int error;
@@ -287,15 +323,17 @@ int _ma_ck_write_btree(register MARIA_HA *info, uint keynr, uchar *key,
DBUG_RETURN(error);
} /* _ma_ck_write_btree */
+
int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_length, my_off_t *root, uint comp_flag)
+ byte *key, uint key_length, my_off_t *root,
+ uint comp_flag)
{
int error;
DBUG_ENTER("_ma_ck_real_write_btree");
/* key_length parameter is used only if comp_flag is SEARCH_FIND */
if (*root == HA_OFFSET_ERROR ||
(error=w_search(info, keyinfo, comp_flag, key, key_length,
- *root, (uchar *) 0, (uchar*) 0,
+ *root, (byte*) 0, (byte*) 0,
(my_off_t) 0, 1)) > 0)
error= _ma_enlarge_root(info,keyinfo,key,root);
DBUG_RETURN(error);
@@ -304,7 +342,7 @@ int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* Make a new root with key as only pointer */
-int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
+int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
my_off_t *root)
{
uint t_length,nod_flag;
@@ -314,11 +352,11 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
nod_flag= (*root != HA_OFFSET_ERROR) ? share->base.key_reflength : 0;
_ma_kpointer(info,info->buff+2,*root); /* if nod */
- t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar*) 0,
- (uchar*) 0, (uchar*) 0, key,&s_temp);
+ t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(byte*) 0,
+ (byte*) 0, (byte*) 0, key,&s_temp);
maria_putint(info->buff,t_length+2+nod_flag,nod_flag);
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
- info->buff_used=info->page_changed=1; /* info->buff is used */
+ info->keybuff_used=info->page_changed=1; /* info->buff is used */
if ((*root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
_ma_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
DBUG_RETURN(-1);
@@ -334,21 +372,21 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
*/
static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uint comp_flag, uchar *key, uint key_length, my_off_t page,
- uchar *father_buff, uchar *father_keypos,
+ uint comp_flag, byte *key, uint key_length, my_off_t page,
+ byte *father_buff, byte *father_keypos,
my_off_t father_page, my_bool insert_last)
{
int error,flag;
uint nod_flag, search_key_length;
- uchar *temp_buff,*keypos;
- uchar keybuff[HA_MAX_KEY_BUFF];
+ byte *temp_buff,*keypos;
+ byte keybuff[HA_MAX_KEY_BUFF];
my_bool was_last_key;
- my_off_t next_page, dupp_key_pos;
+ my_off_t next_page, dup_key_pos;
DBUG_ENTER("w_search");
DBUG_PRINT("enter",("page: %ld", (long) page));
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
- if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
+ if (!(temp_buff= (byte*) my_alloca((uint) keyinfo->block_length+
HA_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
if (!_ma_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0))
@@ -363,9 +401,9 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* get position to record with duplicated key */
tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff);
if (tmp_key_length)
- dupp_key_pos= _ma_dpos(info,0,keybuff+tmp_key_length);
+ dup_key_pos= _ma_dpos(info,0,keybuff+tmp_key_length);
else
- dupp_key_pos= HA_OFFSET_ERROR;
+ dup_key_pos= HA_OFFSET_ERROR;
if (keyinfo->flag & HA_FULLTEXT)
{
@@ -385,7 +423,7 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
else
{
/* popular word. two-level tree. going down */
- my_off_t root=dupp_key_pos;
+ my_off_t root=dup_key_pos;
keyinfo=&info->s->ft2_keyinfo;
get_key_full_length_rdonly(off, key);
key+=off;
@@ -404,7 +442,7 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
}
else /* not HA_FULLTEXT, normal HA_NOSAME key */
{
- info->dupp_key_pos= dupp_key_pos;
+ info->dup_key_pos= dup_key_pos;
my_afree((byte*) temp_buff);
my_errno=HA_ERR_FOUND_DUPP_KEY;
DBUG_RETURN(-1);
@@ -459,25 +497,25 @@ err:
*/
int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *key, uchar *anc_buff, uchar *key_pos, uchar *key_buff,
- uchar *father_buff, uchar *father_key_pos, my_off_t father_page,
+ byte *key, byte *anc_buff, byte *key_pos, byte *key_buff,
+ byte *father_buff, byte *father_key_pos, my_off_t father_page,
my_bool insert_last)
{
uint a_length,nod_flag;
int t_length;
- uchar *endpos, *prev_key;
+ byte *endpos, *prev_key;
MARIA_KEY_PARAM s_temp;
DBUG_ENTER("_ma_insert");
- DBUG_PRINT("enter",("key_pos: %lx", (long) key_pos));
+ DBUG_PRINT("enter",("key_pos: 0x%lx", (ulong) key_pos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,
USE_WHOLE_KEY););
nod_flag=_ma_test_if_nod(anc_buff);
a_length=maria_getint(anc_buff);
endpos= anc_buff+ a_length;
- prev_key=(key_pos == anc_buff+2+nod_flag ? (uchar*) 0 : key_buff);
+ prev_key=(key_pos == anc_buff+2+nod_flag ? (byte*) 0 : key_buff);
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
- (key_pos == endpos ? (uchar*) 0 : key_pos),
+ (key_pos == endpos ? (byte*) 0 : key_pos),
prev_key, prev_key,
key,&s_temp);
#ifndef DBUG_OFF
@@ -491,7 +529,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
DBUG_PRINT("test",("t_length: %d ref_len: %d",
t_length,s_temp.ref_length));
DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: 0x%lx",
- s_temp.n_ref_length,s_temp.n_length, (long) s_temp.key));
+ s_temp.n_ref_length, s_temp.n_length, (long) s_temp.key));
}
#endif
if (t_length > 0)
@@ -529,19 +567,20 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
Let's consider converting.
We'll compare 'key' and the first key at anc_buff
*/
- uchar *a=key, *b=anc_buff+2+nod_flag;
+ byte *a=key, *b=anc_buff+2+nod_flag;
uint alen, blen, ft2len=info->s->ft2_keyinfo.keylength;
/* the very first key on the page is always unpacked */
DBUG_ASSERT((*b & 128) == 0);
#if HA_FT_MAXLEN >= 127
blen= mi_uint2korr(b); b+=2;
#else
- blen= *b++;
+ blen= *(uchar*) b++;
#endif
get_key_length(alen,a);
DBUG_ASSERT(info->ft1_to_ft2==0);
if (alen == blen &&
- ha_compare_text(keyinfo->seg->charset, a, alen, b, blen, 0, 0)==0)
+ ha_compare_text(keyinfo->seg->charset, (uchar*) a, alen,
+ (uchar*) b, blen, 0, 0) == 0)
{
/* yup. converting */
info->ft1_to_ft2=(DYNAMIC_ARRAY *)
@@ -582,11 +621,11 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
/* split a full page in two and assign emerging item to key */
int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *key, uchar *buff, uchar *key_buff,
+ byte *key, byte *buff, byte *key_buff,
my_bool insert_last_key)
{
uint length,a_length,key_ref_length,t_length,nod_flag,key_length;
- uchar *key_pos,*pos, *after_key;
+ byte *key_pos,*pos, *after_key;
my_off_t new_pos;
MARIA_KEY_PARAM s_temp;
DBUG_ENTER("maria_split_page");
@@ -594,7 +633,7 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (info->s->keyinfo+info->lastinx == keyinfo)
info->page_changed=1; /* Info->buff is used */
- info->buff_used=1;
+ info->keybuff_used=1;
nod_flag=_ma_test_if_nod(buff);
key_ref_length=2+nod_flag;
if (insert_last_key)
@@ -626,8 +665,8 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&key_pos,key_buff))
DBUG_RETURN(-1);
- t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar *) 0,
- (uchar*) 0, (uchar*) 0,
+ t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(byte *) 0,
+ (byte*) 0, (byte*) 0,
key_buff, &s_temp);
length=(uint) ((buff+a_length)-key_pos);
memcpy((byte*) info->buff+key_ref_length+t_length,(byte*) key_pos,
@@ -650,12 +689,12 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
after_key will contain the position to where the next key starts
*/
-uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint *return_key_length,
- uchar **after_key)
+byte *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint *return_key_length,
+ byte **after_key)
{
uint keys,length,key_ref_length;
- uchar *end,*lastpos;
+ byte *end,*lastpos;
DBUG_ENTER("_ma_find_half_pos");
key_ref_length=2+nod_flag;
@@ -690,19 +729,19 @@ uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
} /* _ma_find_half_pos */
- /*
- Split buffer at last key
- Returns pointer to the start of the key before the last key
- key will contain the last key
- */
+/*
+ Split buffer at last key
+ Returns pointer to the start of the key before the last key
+ key will contain the last key
+*/
-static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint *return_key_length,
- uchar **after_key)
+static byte *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, byte *page,
+ byte *key, uint *return_key_length,
+ byte **after_key)
{
uint keys,length,last_length,key_ref_length;
- uchar *end,*lastpos,*prevpos;
- uchar key_buff[HA_MAX_KEY_BUFF];
+ byte *end,*lastpos,*prevpos;
+ byte key_buff[HA_MAX_KEY_BUFF];
DBUG_ENTER("_ma_find_last_pos");
key_ref_length=2;
@@ -750,14 +789,14 @@ static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
/* returns 0 if balance was done */
static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uchar *curr_buff, uchar *father_buff,
- uchar *father_key_pos, my_off_t father_page)
+ byte *key, byte *curr_buff, byte *father_buff,
+ byte *father_key_pos, my_off_t father_page)
{
my_bool right;
uint k_length,father_length,father_keylength,nod_flag,curr_keylength,
right_length,left_length,new_right_length,new_left_length,extra_length,
length,keys;
- uchar *pos,*buff,*extra_buff;
+ byte *pos,*buff,*extra_buff;
my_off_t next_page,new_pos;
byte tmp_part_key[HA_MAX_KEY_BUFF];
DBUG_ENTER("_ma_balance_page");
@@ -894,7 +933,8 @@ typedef struct {
uint keynr;
} bulk_insert_param;
-int _ma_ck_write_tree(register MARIA_HA *info, uint keynr, uchar *key,
+
+int _ma_ck_write_tree(register MARIA_HA *info, uint keynr, byte *key,
uint key_length)
{
int error;
@@ -910,22 +950,22 @@ int _ma_ck_write_tree(register MARIA_HA *info, uint keynr, uchar *key,
/* typeof(_ma_keys_compare)=qsort_cmp2 */
-static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
+static int keys_compare(bulk_insert_param *param, byte *key1, byte *key2)
{
uint not_used[2];
return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg,
- key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
+ (uchar*) key1, (uchar*) key2, USE_WHOLE_KEY, SEARCH_SAME,
not_used);
}
-static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param)
+static int keys_free(byte *key, TREE_FREE mode, bulk_insert_param *param)
{
/*
Probably I can use info->lastkey here, but I'm not sure,
and to be safe I'd better use local lastkey.
*/
- uchar lastkey[HA_MAX_KEY_BUFF];
+ byte lastkey[HA_MAX_KEY_BUFF];
uint keylen;
MARIA_KEYDEF *keyinfo;
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 6ba5200918e..8471d36bec9 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -37,21 +37,23 @@ SET_STACK_SIZE(9000) /* Minimum stack size for program */
static uint decode_bits;
static char **default_argv;
-static const char *load_default_groups[]= { "mariachk", 0 };
+static const char *load_default_groups[]= { "maria_chk", 0 };
static const char *set_collation_name, *opt_tmpdir;
static CHARSET_INFO *set_collation;
static long opt_maria_block_size;
static long opt_key_cache_block_size;
static const char *my_progname_short;
static int stopwords_inited= 0;
-static MY_TMPDIR mariachk_tmpdir;
+static MY_TMPDIR maria_chk_tmpdir;
static const char *type_names[]=
-{ "impossible","char","binary", "short", "long", "float",
+{
+ "impossible","char","binary", "short", "long", "float",
"double","number","unsigned short",
"unsigned long","longlong","ulonglong","int24",
"uint24","int8","varchar", "varbin","?",
- "?"};
+ "?"
+};
static const char *prefix_packed_txt="packed ",
*bin_packed_txt="prefix ",
@@ -60,23 +62,30 @@ static const char *prefix_packed_txt="packed ",
*blob_txt="BLOB ";
static const char *field_pack[]=
-{"","no endspace", "no prespace",
+{
+ "","no endspace", "no prespace",
"no zeros", "blob", "constant", "table-lockup",
- "always zero","varchar","unique-hash","?","?"};
+ "always zero","varchar","unique-hash","?","?"
+};
+
+static const char *record_formats[]=
+{
+ "Fixed length", "Packed", "Compressed", "Block", "?"
+};
static const char *maria_stats_method_str="nulls_unequal";
static void get_options(int *argc,char * * *argv);
static void print_version(void);
static void usage(void);
-static int mariachk(HA_CHECK *param, char *filename);
+static int maria_chk(HA_CHECK *param, char *filename);
static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name);
static int maria_sort_records(HA_CHECK *param, register MARIA_HA *info,
- my_string name, uint sort_key,
- my_bool write_info, my_bool update_index);
+ my_string name, uint sort_key,
+ my_bool write_info, my_bool update_index);
static int sort_record_index(MARIA_SORT_PARAM *sort_param, MARIA_HA *info,
MARIA_KEYDEF *keyinfo,
- my_off_t page,uchar *buff,uint sortkey,
+ my_off_t page, byte *buff,uint sortkey,
File new_file, my_bool update_index);
HA_CHECK check_param;
@@ -89,7 +98,7 @@ int main(int argc, char **argv)
MY_INIT(argv[0]);
my_progname_short= my_progname+dirname_length(my_progname);
- mariachk_init(&check_param);
+ maria_chk_init(&check_param);
check_param.opt_lock_memory= 1; /* Lock memory if possible */
check_param.using_global_keycache = 0;
get_options(&argc,(char***) &argv);
@@ -99,7 +108,7 @@ int main(int argc, char **argv)
while (--argc >= 0)
{
- int new_error=mariachk(&check_param, *(argv++));
+ int new_error=maria_chk(&check_param, *(argv++));
if ((check_param.testflag & T_REP_ANY) != T_REP)
check_param.testflag&= ~T_REP;
VOID(fflush(stdout));
@@ -113,7 +122,7 @@ int main(int argc, char **argv)
if (!(check_param.testflag & T_REP))
check_param.testflag|= T_REP_BY_SORT;
check_param.testflag&= ~T_EXTEND; /* Don't needed */
- error|=mariachk(&check_param, argv[-1]);
+ error|=maria_chk(&check_param, argv[-1]);
check_param.testflag= old_testflag;
VOID(fflush(stdout));
VOID(fflush(stderr));
@@ -135,7 +144,7 @@ int main(int argc, char **argv)
llstr(check_param.total_deleted,buff2));
}
free_defaults(default_argv);
- free_tmpdir(&mariachk_tmpdir);
+ free_tmpdir(&maria_chk_tmpdir);
maria_end();
my_end(check_param.testflag & T_INFO ?
MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
@@ -219,7 +228,7 @@ static struct my_option my_long_options[] =
(gptr*) &check_param.keys_in_use,
0, GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0},
{"max-record-length", OPT_MAX_RECORD_LENGTH,
- "Skip rows bigger than this if mariachk can't allocate memory to hold it",
+ "Skip rows bigger than this if maria_chk can't allocate memory to hold it",
(gptr*) &check_param.max_record_length,
(gptr*) &check_param.max_record_length,
0, GET_ULL, REQUIRED_ARG, LONGLONG_MAX, 0, LONGLONG_MAX, 0, 0, 0},
@@ -260,7 +269,7 @@ static struct my_option my_long_options[] =
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"silent", 's',
- "Only print errors. One can use two -s to make mariachk very silent.",
+ "Only print errors. One can use two -s to make maria_chk very silent.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"sort-index", 'S',
"Sort index blocks. This speeds up 'read-next' in applications.",
@@ -347,7 +356,7 @@ static struct my_option my_long_options[] =
static void print_version(void)
{
- printf("%s Ver 2.7 for %s at %s\n", my_progname, SYSTEM_TYPE,
+ printf("%s Ver 1.0 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
NETWARE_SET_SCREEN_MODE(1);
}
@@ -382,7 +391,7 @@ static void usage(void)
printf(", they will be used\n\
in a round-robin fashion.\n\
-s, --silent Only print errors. One can use two -s to make\n\
- mariachk very silent.\n\
+ maria_chk very silent.\n\
-v, --verbose Print more information. This can be used with\n\
--description and --check. Use many -v for more verbosity.\n\
-V, --version Print version and exit.\n\
@@ -391,10 +400,10 @@ static void usage(void)
puts(" --start-check-pos=# Start reading file at given offset.\n");
#endif
- puts("Check options (check is the default action for mariachk):\n\
+ puts("Check options (check is the default action for maria_chk):\n\
-c, --check Check table for errors.\n\
-e, --extend-check Check the table VERY throughly. Only use this in\n\
- extreme cases as mariachk should normally be able to\n\
+ extreme cases as maria_chk should normally be able to\n\
find out if the table is ok even without this switch.\n\
-F, --fast Check only tables that haven't been closed properly.\n\
-C, --check-only-changed\n\
@@ -420,7 +429,7 @@ static void usage(void)
bit mask of which keys to use. This can be used to\n\
get faster inserts.\n\
--max-record-length=#\n\
- Skip rows bigger than this if mariachk can't allocate\n\
+ Skip rows bigger than this if maria_chk can't allocate\n\
memory to hold it.\n\
-r, --recover Can fix almost anything except unique keys that aren't\n\
unique.\n\
@@ -437,7 +446,7 @@ static void usage(void)
--set-collation=name\n\
Change the collation used by the index.\n\
-q, --quick Faster repair by not modifying the data file.\n\
- One can give a second '-q' to force mariachk to\n\
+ One can give a second '-q' to force maria_chk to\n\
modify the original datafile in case of duplicate keys.\n\
NOTE: Tables where the data file is currupted can't be\n\
fixed with this option.\n\
@@ -685,7 +694,7 @@ get_one_option(int optid,
}
else
{
- DBUG_PUSH(argument ? argument : "d:t:o,/tmp/mariachk.trace");
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/maria_chk.trace");
}
break;
case 'V':
@@ -780,10 +789,10 @@ static void get_options(register int *argc,register char ***argv)
exit(1);
}
- if (init_tmpdir(&mariachk_tmpdir, opt_tmpdir))
+ if (init_tmpdir(&maria_chk_tmpdir, opt_tmpdir))
exit(1);
- check_param.tmpdir=&mariachk_tmpdir;
+ check_param.tmpdir=&maria_chk_tmpdir;
check_param.key_cache_block_size= opt_key_cache_block_size;
if (set_collation_name)
@@ -798,17 +807,16 @@ static void get_options(register int *argc,register char ***argv)
/* Check table */
-static int mariachk(HA_CHECK *param, my_string filename)
+static int maria_chk(HA_CHECK *param, my_string filename)
{
int error,lock_type,recreate;
int rep_quick= param->testflag & (T_QUICK | T_FORCE_UNIQUENESS);
- uint raid_chunks;
MARIA_HA *info;
File datafile;
char llbuff[22],llbuff2[22];
my_bool state_updated=0;
MARIA_SHARE *share;
- DBUG_ENTER("mariachk");
+ DBUG_ENTER("maria_chk");
param->out_flag=error=param->warning_printed=param->error_printed=
recreate=0;
@@ -851,7 +859,8 @@ static int mariachk(HA_CHECK *param, my_string filename)
_ma_check_print_error(param,"File '%s' doesn't exist",filename);
break;
case EACCES:
- _ma_check_print_error(param,"You don't have permission to use '%s'",filename);
+ _ma_check_print_error(param,"You don't have permission to use '%s'",
+ filename);
break;
default:
_ma_check_print_error(param,"%d when opening MARIA-table '%s'",
@@ -864,7 +873,18 @@ static int mariachk(HA_CHECK *param, my_string filename)
share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */
share->tot_locks-= share->r_locks;
share->r_locks=0;
- raid_chunks=share->base.raid_chunks;
+
+ if (share->data_file_type == BLOCK_RECORD &&
+ (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_FAST | T_STATISTICS |
+ T_CHECK | T_CHECK_ONLY_CHANGED)))
+ {
+ _ma_check_print_error(param,
+ "Record format used by '%s' is is not yet supported with repair/check",
+ filename);
+ param->error_printed= 0;
+ error= 1;
+ goto end2;
+ }
/*
Skip the checking of the file if:
@@ -873,7 +893,8 @@ static int mariachk(HA_CHECK *param, my_string filename)
*/
if (param->testflag & (T_FAST | T_CHECK_ONLY_CHANGED))
{
- my_bool need_to_check= maria_is_crashed(info) || share->state.open_count != 0;
+ my_bool need_to_check= (maria_is_crashed(info) ||
+ share->state.open_count != 0);
if ((param->testflag & (T_REP_ANY | T_SORT_RECORDS)) &&
((share->state.changed & (STATE_CHANGED | STATE_CRASHED |
@@ -971,6 +992,7 @@ static int mariachk(HA_CHECK *param, my_string filename)
_ma_check_print_error(param,"Can't lock indexfile of '%s', error: %d",
filename,my_errno);
param->error_printed=0;
+ error= 1;
goto end2;
}
/*
@@ -991,7 +1013,8 @@ static int mariachk(HA_CHECK *param, my_string filename)
if (tmp != share->state.key_map)
info->update|=HA_STATE_CHANGED;
}
- if (rep_quick && maria_chk_del(param, info, param->testflag & ~T_VERBOSE))
+ if (rep_quick &&
+ maria_chk_del(param, info, param->testflag & ~T_VERBOSE))
{
if (param->testflag & T_FORCE_CREATE)
{
@@ -1034,8 +1057,7 @@ static int mariachk(HA_CHECK *param, my_string filename)
{ /* Change temp file to org file */
VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */
error|=maria_change_to_newfile(filename,MARIA_NAME_DEXT,DATA_TMP_EXT,
- raid_chunks,
- MYF(0));
+ MYF(0));
if (_ma_open_datafile(info,info->s, -1))
error=1;
param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */
@@ -1114,8 +1136,7 @@ static int mariachk(HA_CHECK *param, my_string filename)
1,
MYF(MY_WME)));
maria_lock_memory(param);
- if ((info->s->options & (HA_OPTION_PACK_RECORD |
- HA_OPTION_COMPRESS_RECORD)) ||
+ if ((info->s->data_file_type != STATIC_RECORD) ||
(param->testflag & (T_EXTEND | T_MEDIUM)))
error|=maria_chk_data_link(param, info, param->testflag & T_EXTEND);
error|=_ma_flush_blocks(param, share->key_cache, share->kfile);
@@ -1165,12 +1186,11 @@ end2:
{
if (param->out_flag & O_NEW_DATA)
error|=maria_change_to_newfile(filename,MARIA_NAME_DEXT,DATA_TMP_EXT,
- raid_chunks,
- ((param->testflag & T_BACKUP_DATA) ?
- MYF(MY_REDEL_MAKE_BACKUP) : MYF(0)));
+ ((param->testflag & T_BACKUP_DATA) ?
+ MYF(MY_REDEL_MAKE_BACKUP) : MYF(0)));
if (param->out_flag & O_NEW_INDEX)
- error|=maria_change_to_newfile(filename,MARIA_NAME_IEXT,INDEX_TMP_EXT,0,
- MYF(0));
+ error|=maria_change_to_newfile(filename,MARIA_NAME_IEXT,INDEX_TMP_EXT,
+ MYF(0));
}
VOID(fflush(stdout)); VOID(fflush(stderr));
if (param->error_printed)
@@ -1197,10 +1217,10 @@ end2:
filename));
VOID(fflush(stderr));
DBUG_RETURN(error);
-} /* mariachk */
+} /* maria_chk */
- /* Write info about table */
+/* Write info about table */
static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
{
@@ -1214,14 +1234,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
char llbuff[22],llbuff2[22];
DBUG_ENTER("describe");
- printf("\nMARIA file: %s\n",name);
- fputs("Record format: ",stdout);
- if (share->options & HA_OPTION_COMPRESS_RECORD)
- puts("Compressed");
- else if (share->options & HA_OPTION_PACK_RECORD)
- puts("Packed");
- else
- puts("Fixed length");
+ printf("\nMARIA file: %s\n",name);
+ printf("Record format: %s\n", record_formats[share->data_file_type]);
printf("Character set: %s (%d)\n",
get_charset_name(share->state.header.language),
share->state.header.language);
@@ -1262,25 +1276,18 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
printf("Status: %s\n",buff);
if (share->base.auto_key)
{
- printf("Auto increment key: %13d Last value: %13s\n",
+ printf("Auto increment key: %16d Last value: %18s\n",
share->base.auto_key,
llstr(share->state.auto_increment,llbuff));
}
- if (share->base.raid_type)
- {
- printf("RAID: Type: %u Chunks: %u Chunksize: %lu\n",
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize);
- }
if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
- printf("Checksum: %23s\n",llstr(info->state->checksum,llbuff));
+ printf("Checksum: %26s\n",llstr(info->state->checksum,llbuff));
;
if (share->options & HA_OPTION_DELAY_KEY_WRITE)
printf("Keys are only flushed at close\n");
}
- printf("Data records: %13s Deleted blocks: %13s\n",
+ printf("Data records: %16s Deleted blocks: %18s\n",
llstr(info->state->records,llbuff),llstr(info->state->del,llbuff2));
if (param->testflag & T_SILENT)
DBUG_VOID_RETURN; /* This is enough */
@@ -1288,14 +1295,14 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
if (param->testflag & T_VERBOSE)
{
#ifdef USE_RELOC
- printf("Init-relocation: %13s\n",llstr(share->base.reloc,llbuff));
+ printf("Init-relocation: %16s\n",llstr(share->base.reloc,llbuff));
#endif
- printf("Datafile parts: %13s Deleted data: %13s\n",
+ printf("Datafile parts: %16s Deleted data: %18s\n",
llstr(share->state.split,llbuff),
llstr(info->state->empty,llbuff2));
- printf("Datafile pointer (bytes):%9d Keyfile pointer (bytes):%9d\n",
+ printf("Datafile pointer (bytes): %11d Keyfile pointer (bytes): %13d\n",
share->rec_reflength,share->base.key_reflength);
- printf("Datafile length: %13s Keyfile length: %13s\n",
+ printf("Datafile length: %16s Keyfile length: %18s\n",
llstr(info->state->data_file_length,llbuff),
llstr(info->state->key_file_length,llbuff2));
@@ -1305,13 +1312,13 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
{
if (share->base.max_data_file_length != HA_OFFSET_ERROR ||
share->base.max_key_file_length != HA_OFFSET_ERROR)
- printf("Max datafile length: %13s Max keyfile length: %13s\n",
+ printf("Max datafile length: %16s Max keyfile length: %18s\n",
llstr(share->base.max_data_file_length-1,llbuff),
llstr(share->base.max_key_file_length-1,llbuff2));
}
}
-
- printf("Recordlength: %13d\n",(int) share->base.pack_reclength);
+ printf("Block_size: %16d\n",(int) share->block_size);
+ printf("Recordlength: %16d\n",(int) share->base.pack_reclength);
if (! maria_is_all_keys_active(share->state.key_map, share->base.keys))
{
longlong2str(share->state.key_map,buff,2);
@@ -1419,7 +1426,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
if (share->options & HA_OPTION_COMPRESS_RECORD)
printf(" Huff tree Bits");
VOID(putchar('\n'));
- start=1;
+
for (field=0 ; field < share->base.fields ; field++)
{
if (share->options & HA_OPTION_COMPRESS_RECORD)
@@ -1448,8 +1455,9 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
sprintf(null_bit,"%d",share->rec[field].null_bit);
sprintf(null_pos,"%d",share->rec[field].null_pos+1);
}
- printf("%-6d%-6d%-7s%-8s%-8s%-35s",field+1,start,length,
- null_pos, null_bit, buff);
+ printf("%-6d%-6u%-7s%-8s%-8s%-35s",field+1,
+ (uint) share->rec[field].offset+1,
+ length, null_pos, null_bit, buff);
if (share->options & HA_OPTION_COMPRESS_RECORD)
{
if (share->rec[field].huff_tree)
@@ -1477,7 +1485,7 @@ static int maria_sort_records(HA_CHECK *param,
uint key;
MARIA_KEYDEF *keyinfo;
File new_file;
- uchar *temp_buff;
+ byte *temp_buff;
ha_rows old_record_count;
MARIA_SHARE *share=info->s;
char llbuff[22],llbuff2[22];
@@ -1534,7 +1542,7 @@ static int maria_sort_records(HA_CHECK *param,
goto err;
info->opt_flag|=WRITE_CACHE_USED;
- if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
+ if (!(temp_buff=(byte*) my_alloca((uint) keyinfo->block_length)))
{
_ma_check_print_error(param,"Not enough memory for key block");
goto err;
@@ -1546,14 +1554,11 @@ static int maria_sort_records(HA_CHECK *param,
goto err;
}
fn_format(param->temp_filename,name,"", MARIA_NAME_DEXT,2+4+32);
- new_file=my_raid_create(fn_format(param->temp_filename,
- param->temp_filename,"",
- DATA_TMP_EXT,2+4),
- 0,param->tmpfile_createflag,
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize,
- MYF(0));
+ new_file= my_create(fn_format(param->temp_filename,
+ param->temp_filename,"",
+ DATA_TMP_EXT,2+4),
+ 0,param->tmpfile_createflag,
+ MYF(0));
if (new_file < 0)
{
_ma_check_print_error(param,"Can't create new tempfile: '%s'",
@@ -1570,7 +1575,7 @@ static int maria_sort_records(HA_CHECK *param,
for (key=0 ; key < share->base.keys ; key++)
share->keyinfo[key].flag|= HA_SORT_ALLOWS_SAME;
- if (my_pread(share->kfile,(byte*) temp_buff,
+ if (my_pread(share->kfile, temp_buff,
(uint) keyinfo->block_length,
share->state.key_root[sort_key],
MYF(MY_NABP+MY_WME)))
@@ -1591,7 +1596,8 @@ static int maria_sort_records(HA_CHECK *param,
if (sort_info.new_data_file_type != COMPRESSED_RECORD)
info->state->checksum=0;
- if (sort_record_index(&sort_param,info,keyinfo,share->state.key_root[sort_key],
+ if (sort_record_index(&sort_param,info,keyinfo,
+ share->state.key_root[sort_key],
temp_buff, sort_key,new_file,update_index) ||
maria_write_data_suffix(&sort_info,1) ||
flush_io_cache(&info->rec_cache))
@@ -1628,8 +1634,7 @@ err:
{
VOID(end_io_cache(&info->rec_cache));
(void) my_close(new_file,MYF(MY_WME));
- (void) my_raid_delete(param->temp_filename, share->base.raid_chunks,
- MYF(MY_WME));
+ (void) my_delete(param->temp_filename, MYF(MY_WME));
}
if (temp_buff)
{
@@ -1646,17 +1651,17 @@ err:
} /* sort_records */
- /* Sort records recursive using one index */
+/* Sort records recursive using one index */
static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff, uint sort_key,
+ my_off_t page, byte *buff, uint sort_key,
File new_file,my_bool update_index)
{
uint nod_flag,used_length,key_length;
- uchar *temp_buff,*keypos,*endpos;
+ byte *temp_buff,*keypos,*endpos;
my_off_t next_page,rec_pos;
- uchar lastkey[HA_MAX_KEY_BUFF];
+ byte lastkey[HA_MAX_KEY_BUFF];
char llbuff[22];
MARIA_SORT_INFO *sort_info= sort_param->sort_info;
HA_CHECK *param=sort_info->param;
@@ -1667,7 +1672,7 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
if (nod_flag)
{
- if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
+ if (!(temp_buff= (byte*) my_alloca((uint) keyinfo->block_length)))
{
_ma_check_print_error(param,"Not Enough memory");
DBUG_RETURN(-1);
@@ -1681,7 +1686,7 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
_sanity(__FILE__,__LINE__);
if (nod_flag)
{
- next_page= _ma_kpos(nod_flag,keypos);
+ next_page= _ma_kpos(nod_flag, keypos);
if (my_pread(info->s->kfile,(byte*) temp_buff,
(uint) keyinfo->block_length, next_page,
MYF(MY_NABP+MY_WME)))
@@ -1690,7 +1695,8 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
llstr(next_page,llbuff));
goto err;
}
- if (sort_record_index(sort_param, info,keyinfo,next_page,temp_buff,sort_key,
+ if (sort_record_index(sort_param, info,keyinfo,next_page,temp_buff,
+ sort_key,
new_file, update_index))
goto err;
}
@@ -1701,7 +1707,7 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
break;
rec_pos= _ma_dpos(info,0,lastkey+key_length);
- if ((*info->s->read_rnd)(info,sort_param->record,rec_pos,0))
+ if ((*info->s->read_record)(info,sort_param->record,rec_pos))
{
_ma_check_print_error(param,"%d when reading datafile",my_errno);
goto err;
@@ -1740,7 +1746,7 @@ err:
/*
- Check if mariachk was killed by a signal
+ Check if maria_chk was killed by a signal
This is overloaded by other programs that want to be able to abort
sorting
*/
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 9585ecad292..cc93f87de54 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -55,14 +55,15 @@ typedef struct st_maria_state_info
uchar keys; /* number of keys in file */
uchar uniques; /* number of UNIQUE definitions */
uchar language; /* Language for indexes */
- uchar max_block_size_index; /* max keyblock size */
uchar fulltext_keys;
- uchar not_used; /* To align to 8 */
+ uchar data_file_type;
+ uchar org_data_file_type; /* Used by mariapack to store dft */
} header;
MARIA_STATUS_INFO state;
ha_rows split; /* number of split blocks */
my_off_t dellink; /* Link to next removed block */
+ ulonglong first_bitmap_with_space;
ulonglong auto_increment;
ulong process; /* process that updated table last */
ulong unique; /* Unique number for this process */
@@ -71,7 +72,7 @@ typedef struct st_maria_state_info
ulong *rec_per_key_part;
ha_checksum checksum; /* Table checksum */
my_off_t *key_root; /* Start of key trees */
- my_off_t *key_del; /* delete links for trees */
+ my_off_t key_del; /* delete links for trees */
my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
ulong sec_index_changed; /* Updated when new sec_index */
@@ -92,60 +93,73 @@ typedef struct st_maria_state_info
} MARIA_STATE_INFO;
-#define MARIA_STATE_INFO_SIZE (24+14*8+7*4+2*2+8)
+#define MARIA_STATE_INFO_SIZE (24 + 4 + 11*8 + 4*4 + 8 + 3*4 + 5*8)
#define MARIA_STATE_KEY_SIZE 8
#define MARIA_STATE_KEYBLOCK_SIZE 8
#define MARIA_STATE_KEYSEG_SIZE 4
-#define MARIA_STATE_EXTRA_SIZE ((MARIA_MAX_KEY+MARIA_MAX_KEY_BLOCK_SIZE)*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
+#define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
#define MARIA_KEYDEF_SIZE (2+ 5*2)
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
-#define MARIA_COLUMNDEF_SIZE (2*3+1)
-#define MARIA_BASE_INFO_SIZE (5*8 + 8*4 + 4 + 4*2 + 16)
+#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
+#define MARIA_BASE_INFO_SIZE (5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
#define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */
-typedef struct st__ma_base_info
+typedef struct st_ma_base_info
{
- my_off_t keystart; /* Start of keys */
+ my_off_t keystart; /* Start of keys */
my_off_t max_data_file_length;
my_off_t max_key_file_length;
my_off_t margin_key_file_length;
- ha_rows records, reloc; /* Create information */
- ulong mean_row_length; /* Create information */
- ulong reclength; /* length of unpacked record */
- ulong pack_reclength; /* Length of full packed rec */
+ ha_rows records, reloc; /* Create information */
+ ulong mean_row_length; /* Create information */
+ ulong reclength; /* length of unpacked record */
+ ulong pack_reclength; /* Length of full packed rec */
ulong min_pack_length;
- ulong max_pack_length; /* Max possibly length of
- packed rec. */
+ ulong max_pack_length; /* Max possibly length of packed rec */
ulong min_block_length;
- ulong fields, /* fields in table */
- pack_fields; /* packed fields in table */
- uint rec_reflength; /* = 2-8 */
- uint key_reflength; /* = 2-8 */
- uint keys; /* same as in state.header */
- uint auto_key; /* Which key-1 is a auto key */
- uint blobs; /* Number of blobs */
- uint pack_bits; /* Length of packed bits */
- uint max_key_block_length; /* Max block length */
- uint max_key_length; /* Max key length */
+ uint fields; /* fields in table */
+ uint fixed_not_null_fields;
+ uint fixed_not_null_fields_length;
+ uint max_field_lengths;
+ uint pack_fields; /* packed fields in table */
+ uint varlength_fields; /* char/varchar/blobs */
+ uint rec_reflength; /* = 2-8 */
+ uint key_reflength; /* = 2-8 */
+ uint keys; /* same as in state.header */
+ uint auto_key; /* Which key-1 is a auto key */
+ uint blobs; /* Number of blobs */
+ /* Length of packed bits (when table was created first time) */
+ uint pack_bytes;
+ /* Length of null bits (when table was created first time) */
+ uint original_null_bytes;
+ uint null_bytes; /* Null bytes in record */
+ uint field_offsets; /* Number of field offsets */
+ uint max_key_block_length; /* Max block length */
+ uint max_key_length; /* Max key length */
/* Extra allocation when using dynamic record format */
uint extra_alloc_bytes;
uint extra_alloc_procent;
- /* Info about raid */
- uint raid_type, raid_chunks;
- ulong raid_chunksize;
+ uint is_nulls_extended; /* 1 if new null bytes */
+ uint min_row_length;
+ uint default_row_flag; /* 0 or ROW_FLAG_NULLS_EXTENDED */
+ uint block_size;
+ uint default_rec_buff_size;
+ uint extra_rec_buff_size;
+
/* The following are from the header */
uint key_parts, all_key_parts;
+ my_bool transactional;
} MARIA_BASE_INFO;
- /* Structs used intern in database */
+/* Structs used intern in database */
-typedef struct st_maria_blob /* Info of record */
+typedef struct st_maria_blob /* Info of record */
{
- ulong offset; /* Offset to blob in record */
- uint pack_length; /* Type of packed length */
- ulong length; /* Calc:ed for each record */
+ ulong offset; /* Offset to blob in record */
+ uint pack_length; /* Type of packed length */
+ ulong length; /* Calc:ed for each record */
} MARIA_BLOB;
@@ -156,6 +170,26 @@ typedef struct st_maria_pack
uchar version;
} MARIA_PACK;
+typedef struct st_maria_file_bitmap
+{
+ uchar *map;
+ ulonglong page; /* Page number for current bitmap */
+ uint used_size; /* Size of bitmap that is not 0 */
+ File file;
+
+ my_bool changed;
+
+#ifdef THREAD
+ pthread_mutex_t bitmap_lock;
+#endif
+ /* Constants, allocated when initiating bitmaps */
+ uint sizes[8]; /* Size per bit combination */
+ uint total_size; /* Total usable size of bitmap page */
+ uint block_size; /* Block size of file */
+ ulong pages_covered; /* Pages covered by bitmap + 1 */
+} MARIA_FILE_BITMAP;
+
+
#define MAX_NONMAPPED_INSERTS 1000
typedef struct st_maria_share
@@ -176,29 +210,36 @@ typedef struct st_maria_share
symlinks */
*index_file_name;
byte *file_map; /* mem-map of file if possible */
- KEY_CACHE *key_cache; /* ref to the current key cache
- */
+ KEY_CACHE *key_cache; /* ref to the current key cache */
MARIA_DECODE_TREE *decode_trees;
uint16 *decode_tables;
- /* Function to use for a row checksum. */
- int(*read_record) (struct st_maria_info *, my_off_t, byte *);
- int(*write_record) (struct st_maria_info *, const byte *);
- int(*update_record) (struct st_maria_info *, my_off_t, const byte *);
- int(*delete_record) (struct st_maria_info *);
- int(*read_rnd) (struct st_maria_info *, byte *, my_off_t, my_bool);
- int(*compare_record) (struct st_maria_info *, const byte *);
- ha_checksum(*calc_checksum) (struct st_maria_info *, const byte *);
- int(*compare_unique) (struct st_maria_info *, MARIA_UNIQUEDEF *,
- const byte *record, my_off_t pos);
- uint(*file_read) (MARIA_HA *, byte *, uint, my_off_t, myf);
- uint(*file_write) (MARIA_HA *, byte *, uint, my_off_t, myf);
+ my_bool (*once_init)(struct st_maria_share *, File);
+ my_bool (*once_end)(struct st_maria_share *);
+ my_bool (*init)(struct st_maria_info *);
+ void (*end)(struct st_maria_info *);
+ int (*read_record)(struct st_maria_info *, byte *, MARIA_RECORD_POS);
+ my_bool (*scan_init)(struct st_maria_info *);
+ int (*scan)(struct st_maria_info *, byte *, MARIA_RECORD_POS, my_bool);
+ void (*scan_end)(struct st_maria_info *);
+ MARIA_RECORD_POS (*write_record_init)(struct st_maria_info *, const byte *);
+ my_bool (*write_record)(struct st_maria_info *, const byte *);
+ my_bool (*write_record_abort)(struct st_maria_info *);
+ my_bool (*update_record)(struct st_maria_info *, MARIA_RECORD_POS,
+ const byte *);
+ my_bool (*delete_record)(struct st_maria_info *);
+ my_bool (*compare_record)(struct st_maria_info *, const byte *);
+ ha_checksum(*calc_checksum) (struct st_maria_info *, const byte *);
+ ha_checksum(*calc_write_checksum) (struct st_maria_info *, const byte *);
+ my_bool (*compare_unique) (struct st_maria_info *, MARIA_UNIQUEDEF *,
+ const byte *record, MARIA_RECORD_POS pos);
+ uint (*file_read)(MARIA_HA *, byte *, uint, my_off_t, myf);
+ uint (*file_write)(MARIA_HA *, byte *, uint, my_off_t, myf);
invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_process; /* processid */
ulong last_process; /* For table-change-check */
ulong last_version; /* Version on start */
ulong options; /* Options used */
- ulong min_pack_length; /* Theese are used by packed
- data */
+ ulong min_pack_length; /* These are used by packed data */
ulong max_pack_length;
ulong state_diff_length;
uint rec_reflength; /* rec_reflength in use now */
@@ -210,67 +251,132 @@ typedef struct st_maria_share
int mode; /* mode of file on open */
uint reopen; /* How many times reopened */
uint w_locks, r_locks, tot_locks; /* Number of read/write locks */
- uint blocksize; /* blocksize of keyfile */
+ uint block_size; /* block_size of keyfile & data file*/
+ uint base_length;
myf write_flag;
enum data_file_type data_file_type;
+ my_bool temporary;
/* Below flag is needed to make log tables work with concurrent insert */
my_bool is_log_table;
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
- not_flushed, temporary, delay_key_write, concurrent_insert;
+ not_flushed, concurrent_insert;
+ my_bool delay_key_write;
#ifdef THREAD
THR_LOCK lock;
- pthread_mutex_t intern_lock; /* Locking for use with
- _locking */
+ pthread_mutex_t intern_lock; /* Locking for use with _locking */
rw_lock_t *key_root_lock;
#endif
my_off_t mmaped_length;
uint nonmmaped_inserts; /* counter of writing in
non-mmaped area */
+ MARIA_FILE_BITMAP bitmap;
rw_lock_t mmap_lock;
} MARIA_SHARE;
+typedef byte MARIA_BITMAP_BUFFER;
+
+typedef struct st_maria_bitmap_block
+{
+ ulonglong page; /* Page number */
+ /* Number of continuous pages. TAIL_BIT is set if this is a tail page */
+ uint page_count;
+ uint empty_space; /* Set for head and tail pages */
+ /*
+ Number of BLOCKS for block-region (holds all non-blob-fields or one blob)
+ */
+ uint sub_blocks;
+ /* set to <> 0 in write_record() if this block was actually used */
+ uint8 used;
+ uint8 org_bitmap_value;
+} MARIA_BITMAP_BLOCK;
+
+
+typedef struct st_maria_bitmap_blocks
+{
+ MARIA_BITMAP_BLOCK *block;
+ uint count;
+ my_bool tail_page_skipped; /* If some tail pages was not used */
+ my_bool page_skipped; /* If some full pages was not used */
+} MARIA_BITMAP_BLOCKS;
+
+
+/* Data about the currently read row */
+typedef struct st_maria_row
+{
+ MARIA_BITMAP_BLOCKS insert_blocks;
+ MARIA_BITMAP_BUFFER *extents;
+ MARIA_RECORD_POS lastpos, nextpos;
+ MARIA_RECORD_POS *tail_positions;
+ ha_checksum checksum;
+ byte *empty_bits, *field_lengths;
+ byte *empty_bits_buffer; /* For storing cur_row.empty_bits */
+ uint *null_field_lengths; /* All null field lengths */
+ ulong *blob_lengths; /* Length for each blob */
+ ulong base_length, normal_length, char_length, varchar_length, blob_length;
+ ulong head_length, total_length;
+ my_size_t extents_buffer_length; /* Size of 'extents' buffer */
+ uint field_lengths_length; /* Length of data in field_lengths */
+ uint extents_count; /* number of extents in 'extents' */
+ uint full_page_count, tail_count; /* For maria_chk */
+} MARIA_ROW;
+
+/* Data to scan row in blocked format */
+typedef struct st_maria_block_scan
+{
+ byte *bitmap_buff, *bitmap_pos, *bitmap_end, *page_buff;
+ byte *dir, *dir_end;
+ ulong bitmap_page;
+ ulonglong bits;
+ uint number_of_rows, bit_pos;
+ MARIA_RECORD_POS row_base_page;
+} MARIA_BLOCK_SCAN;
+
+
struct st_maria_info
{
MARIA_SHARE *s; /* Shared between open:s */
MARIA_STATUS_INFO *state, save_state;
+ MARIA_ROW cur_row, new_row;
+ MARIA_BLOCK_SCAN scan;
MARIA_BLOB *blobs; /* Pointer to blobs */
MARIA_BIT_BUFF bit_buff;
+ DYNAMIC_ARRAY bitmap_blocks;
/* accumulate indexfile changes between write's */
TREE *bulk_insert;
DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */
MEM_ROOT ft_memroot; /* used by the parser */
MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */
char *filename; /* parameter to open filename */
- uchar *buff, /* Temp area for key */
- *lastkey, *lastkey2; /* Last used search key */
- uchar *first_mbr_key; /* Searhed spatial key */
- byte *rec_buff; /* Tempbuff for recordpack */
- uchar *int_keypos, /* Save position for next/previous */
+ byte *buff; /* page buffer */
+ byte *keyread_buff; /* Buffer for last key read */
+ byte *lastkey, *lastkey2; /* Last used search key */
+ byte *first_mbr_key; /* Searhed spatial key */
+ byte *rec_buff; /* Temp buffer for recordpack */
+ byte *int_keypos, /* Save position for next/previous */
*int_maxpos; /* -""- */
uint int_nod_flag; /* -""- */
uint32 int_keytree_version; /* -""- */
- int(*read_record) (struct st_maria_info *, my_off_t, byte *);
+ int (*read_record) (struct st_maria_info *, byte*, MARIA_RECORD_POS);
invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_unique; /* uniq filenumber or thread */
ulong last_unique; /* last unique number */
ulong this_loop; /* counter for this open */
ulong last_loop; /* last used counter */
- my_off_t lastpos, /* Last record position */
- nextpos; /* Position to next record */
- my_off_t save_lastpos;
+ MARIA_RECORD_POS save_lastpos;
+ MARIA_RECORD_POS dup_key_pos;
my_off_t pos; /* Intern variable */
my_off_t last_keypage; /* Last key page read */
my_off_t last_search_keypage; /* Last keypage when searching */
- my_off_t dupp_key_pos;
- ha_checksum checksum; /* Temp storage for row checksum */
+
/*
QQ: the folloing two xxx_length fields should be removed,
as they are not compatible with parallel repair
*/
ulong packed_length, blob_length; /* Length of found, packed record */
+ my_size_t rec_buff_size;
int dfile; /* The datafile */
uint opt_flag; /* Optim. for space/speed */
uint update; /* If file changed since open */
@@ -293,26 +399,22 @@ struct st_maria_info
my_bool was_locked; /* Was locked in panic */
my_bool append_insert_at_end; /* Set if concurrent insert */
my_bool quick_mode;
- /* If info->buff can't be used for rnext */
+ /* If info->keyread_buff can't be used for rnext */
my_bool page_changed;
- /* If info->buff has to be reread for rnext */
- my_bool buff_used;
- /*
- TODO: decide if we will have Maria-MERGE tables, and if no,
- remove some members here.
- */
- my_bool once_flags; /* For MARIAMRG */
+ /* If info->keyread_buff has to be reread for rnext */
+ my_bool keybuff_used;
+ my_bool once_flags; /* For MARIA_MRG */
#ifdef __WIN__
- my_bool owned_by_merge; /* This Maria table is part of a merge union */
+ my_bool owned_by_merge; /* This Maria table is part of a merge union */
#endif
#ifdef THREAD
THR_LOCK_DATA lock;
#endif
- uchar *maria_rtree_recursion_state; /* For RTREE */
+ uchar *maria_rtree_recursion_state; /* For RTREE */
int maria_rtree_recursion_depth;
};
-/* Some defines used by isam-funktions */
+/* Some defines used by maria-functions */
#define USE_WHOLE_KEY HA_MAX_KEY_BUFF*2 /* Use whole key in _search() */
#define F_EXTRA_LCK -1
@@ -370,15 +472,15 @@ struct st_maria_info
}
#define get_key_full_length(length,key) \
-{ if ((uchar) *(key) != 255) \
- length= ((uint) (uchar) *((key)++))+1; \
+ { if (*(uchar*) (key) != 255) \
+ length= ((uint) *(uchar*) ((key)++))+1; \
else \
{ length=mi_uint2korr((key)+1)+3; (key)+=3; } \
}
#define get_key_full_length_rdonly(length,key) \
-{ if ((uchar) *(key) != 255) \
- length= ((uint) (uchar) *((key)))+1; \
+{ if (*(uchar*) (key) != 255) \
+ length= ((uint) *(uchar*) ((key)))+1; \
else \
{ length=mi_uint2korr((key)+1)+3; } \
}
@@ -407,7 +509,6 @@ struct st_maria_info
#define PACK_TYPE_ZERO_FILL 4
#define MARIA_FOUND_WRONG_KEY 32738 /* Impossible value from ha_key_cmp */
-#define MARIA_MAX_KEY_BLOCK_SIZE (MARIA_MAX_KEY_BLOCK_LENGTH/MARIA_MIN_KEY_BLOCK_LENGTH)
#define MARIA_BLOCK_SIZE(key_length,data_pointer,key_pointer,block_size) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/(block_size)+1)*(block_size))
#define MARIA_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */
#define MARIA_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */
@@ -437,86 +538,89 @@ extern LIST *maria_open_list;
extern uchar NEAR maria_file_magic[], NEAR maria_pack_file_magic[];
extern uint NEAR maria_read_vec[], NEAR maria_readnext_vec[];
extern uint maria_quick_table_bits;
+extern byte maria_zero_string[];
extern my_bool maria_inited;
/* This is used by _ma_calc_xxx_key_length och _ma_store_key */
typedef struct st_maria_s_param
{
- uint ref_length, key_length,
- n_ref_length,
- n_length, totlength, part_of_prev_key, prev_length, pack_marker;
- uchar *key, *prev_key, *next_key_pos;
+ uint ref_length, key_length, n_ref_length;
+ uint n_length, totlength, part_of_prev_key, prev_length, pack_marker;
+ const byte *key;
+ byte *prev_key, *next_key_pos;
bool store_not_null;
} MARIA_KEY_PARAM;
/* Prototypes for intern functions */
-extern int _ma_read_dynamic_record(MARIA_HA *info, my_off_t filepos,
- byte *buf);
-extern int _ma_write_dynamic_record(MARIA_HA *, const byte *);
-extern int _ma_update_dynamic_record(MARIA_HA *, my_off_t, const byte *);
-extern int _ma_delete_dynamic_record(MARIA_HA *info);
-extern int _ma_cmp_dynamic_record(MARIA_HA *info, const byte *record);
-extern int _ma_read_rnd_dynamic_record(MARIA_HA *, byte *, my_off_t,
+extern int _ma_read_dynamic_record(MARIA_HA *, byte *, MARIA_RECORD_POS);
+extern int _ma_read_rnd_dynamic_record(MARIA_HA *, byte *, MARIA_RECORD_POS,
my_bool);
-extern int _ma_write_blob_record(MARIA_HA *, const byte *);
-extern int _ma_update_blob_record(MARIA_HA *, my_off_t, const byte *);
-extern int _ma_read_static_record(MARIA_HA *info, my_off_t filepos,
- byte *buf);
-extern int _ma_write_static_record(MARIA_HA *, const byte *);
-extern int _ma_update_static_record(MARIA_HA *, my_off_t, const byte *);
-extern int _ma_delete_static_record(MARIA_HA *info);
-extern int _ma_cmp_static_record(MARIA_HA *info, const byte *record);
-extern int _ma_read_rnd_static_record(MARIA_HA *, byte *, my_off_t, my_bool);
-extern int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key,
+extern my_bool _ma_write_dynamic_record(MARIA_HA *, const byte *);
+extern my_bool _ma_update_dynamic_record(MARIA_HA *, MARIA_RECORD_POS,
+ const byte *);
+extern my_bool _ma_delete_dynamic_record(MARIA_HA *info);
+extern my_bool _ma_cmp_dynamic_record(MARIA_HA *info, const byte *record);
+extern my_bool _ma_write_blob_record(MARIA_HA *, const byte *);
+extern my_bool _ma_update_blob_record(MARIA_HA *, MARIA_RECORD_POS,
+ const byte *);
+extern int _ma_read_static_record(MARIA_HA *info, byte *, MARIA_RECORD_POS);
+extern int _ma_read_rnd_static_record(MARIA_HA *, byte *, MARIA_RECORD_POS,
+ my_bool);
+extern my_bool _ma_write_static_record(MARIA_HA *, const byte *);
+extern my_bool _ma_update_static_record(MARIA_HA *, MARIA_RECORD_POS,
+ const byte *);
+extern my_bool _ma_delete_static_record(MARIA_HA *info);
+extern my_bool _ma_cmp_static_record(MARIA_HA *info, const byte *record);
+extern int _ma_ck_write(MARIA_HA *info, uint keynr, byte *key,
uint length);
extern int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_length,
- my_off_t *root, uint comp_flag);
+ byte *key, uint key_length,
+ MARIA_RECORD_POS *root, uint comp_flag);
extern int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, my_off_t *root);
-extern int _ma_insert(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
- uchar *anc_buff, uchar *key_pos, uchar *key_buff,
- uchar *father_buff, uchar *father_keypos,
+ byte *key, MARIA_RECORD_POS *root);
+extern int _ma_insert(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
+ byte *anc_buff, byte *key_pos, byte *key_buff,
+ byte *father_buff, byte *father_keypos,
my_off_t father_page, my_bool insert_last);
extern int _ma_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uchar *buff, uchar *key_buff,
+ byte *key, byte *buff, byte *key_buff,
my_bool insert_last);
-extern uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo,
- uchar *page, uchar *key,
+extern byte *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo,
+ byte *page, byte *key,
uint *return_key_length,
- uchar ** after_key);
+ byte ** after_key);
extern int _ma_calc_static_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar *key_pos, uchar *org_key,
- uchar *key_buff, uchar *key,
+ byte *key_pos, byte *org_key,
+ byte *key_buff, const byte *key,
MARIA_KEY_PARAM *s_temp);
extern int _ma_calc_var_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar *key_pos, uchar *org_key,
- uchar *key_buff, uchar *key,
+ byte *key_pos, byte *org_key,
+ byte *key_buff, const byte *key,
MARIA_KEY_PARAM *s_temp);
extern int _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo,
- uint nod_flag, uchar *key_pos,
- uchar *org_key, uchar *prev_key,
- uchar *key,
+ uint nod_flag, byte *key_pos,
+ byte *org_key, byte *prev_key,
+ const byte *key,
MARIA_KEY_PARAM *s_temp);
extern int _ma_calc_bin_pack_key_length(MARIA_KEYDEF *keyinfo,
- uint nod_flag, uchar *key_pos,
- uchar *org_key, uchar *prev_key,
- uchar *key,
+ uint nod_flag, byte *key_pos,
+ byte *org_key, byte *prev_key,
+ const byte *key,
MARIA_KEY_PARAM *s_temp);
-void _ma_store_static_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
+void _ma_store_static_key(MARIA_KEYDEF *keyinfo, byte *key_pos,
MARIA_KEY_PARAM *s_temp);
-void _ma_store_var_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
+void _ma_store_var_pack_key(MARIA_KEYDEF *keyinfo, byte *key_pos,
MARIA_KEY_PARAM *s_temp);
#ifdef NOT_USED
-void _ma_store_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
+void _ma_store_pack_key(MARIA_KEYDEF *keyinfo, byte *key_pos,
MARIA_KEY_PARAM *s_temp);
#endif
-void _ma_store_bin_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
+void _ma_store_bin_pack_key(MARIA_KEYDEF *keyinfo, byte *key_pos,
MARIA_KEY_PARAM *s_temp);
-extern int _ma_ck_delete(MARIA_HA *info, uint keynr, uchar *key,
+extern int _ma_ck_delete(MARIA_HA *info, uint keynr, byte *key,
uint key_length);
extern int _ma_readinfo(MARIA_HA *info, int lock_flag, int check_keybuffer);
extern int _ma_writeinfo(MARIA_HA *info, uint options);
@@ -524,74 +628,69 @@ extern int _ma_test_if_changed(MARIA_HA *info);
extern int _ma_mark_file_changed(MARIA_HA *info);
extern int _ma_decrement_open_count(MARIA_HA *info);
extern int _ma_check_index(MARIA_HA *info, int inx);
-extern int _ma_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
+extern int _ma_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
uint key_len, uint nextflag, my_off_t pos);
extern int _ma_bin_search(struct st_maria_info *info, MARIA_KEYDEF *keyinfo,
- uchar *page, uchar *key, uint key_len,
- uint comp_flag, uchar **ret_pos, uchar *buff,
+ byte *page, byte *key, uint key_len,
+ uint comp_flag, byte **ret_pos, byte *buff,
my_bool *was_last_key);
extern int _ma_seq_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *page, uchar *key, uint key_len,
- uint comp_flag, uchar ** ret_pos, uchar *buff,
+ byte *page, byte *key, uint key_len,
+ uint comp_flag, byte ** ret_pos, byte *buff,
my_bool *was_last_key);
extern int _ma_prefix_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *page, uchar *key, uint key_len,
- uint comp_flag, uchar ** ret_pos, uchar *buff,
+ byte *page, byte *key, uint key_len,
+ uint comp_flag, byte ** ret_pos, byte *buff,
my_bool *was_last_key);
-extern my_off_t _ma_kpos(uint nod_flag, uchar *after_key);
-extern void _ma_kpointer(MARIA_HA *info, uchar *buff, my_off_t pos);
-extern my_off_t _ma_dpos(MARIA_HA *info, uint nod_flag, uchar *after_key);
-extern my_off_t _ma_rec_pos(MARIA_SHARE *info, uchar *ptr);
-extern void _ma_dpointer(MARIA_HA *info, uchar *buff, my_off_t pos);
+extern my_off_t _ma_kpos(uint nod_flag, byte *after_key);
+extern void _ma_kpointer(MARIA_HA *info, byte *buff, my_off_t pos);
+extern MARIA_RECORD_POS _ma_dpos(MARIA_HA *info, uint nod_flag,
+ const byte *after_key);
+extern MARIA_RECORD_POS _ma_rec_pos(MARIA_SHARE *info, byte *ptr);
+extern void _ma_dpointer(MARIA_HA *info, byte *buff, MARIA_RECORD_POS pos);
extern uint _ma_get_static_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar **page, uchar *key);
+ byte **page, byte *key);
extern uint _ma_get_pack_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar **page, uchar *key);
+ byte **page, byte *key);
extern uint _ma_get_binary_pack_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
- uchar ** page_pos, uchar *key);
-extern uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *keypos, uchar *lastkey,
- uchar *endpos, uint *return_key_length);
-extern uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *page, uchar *key, uchar *keypos,
+ byte ** page_pos, byte *key);
+extern byte *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *keypos, byte *lastkey,
+ byte *endpos, uint *return_key_length);
+extern byte *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ byte *page, byte *key, byte *keypos,
uint *return_key_length);
-extern uint _ma_keylength(MARIA_KEYDEF *keyinfo, uchar *key);
-extern uint _ma_keylength_part(MARIA_KEYDEF *keyinfo, register uchar *key,
+extern uint _ma_keylength(MARIA_KEYDEF *keyinfo, const byte *key);
+extern uint _ma_keylength_part(MARIA_KEYDEF *keyinfo, register const byte *key,
HA_KEYSEG *end);
-extern uchar *_ma_move_key(MARIA_KEYDEF *keyinfo, uchar *to, uchar *from);
+extern byte *_ma_move_key(MARIA_KEYDEF *keyinfo, byte *to, const byte *from);
extern int _ma_search_next(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uchar *key, uint key_length, uint nextflag,
+ byte *key, uint key_length, uint nextflag,
my_off_t pos);
extern int _ma_search_first(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
my_off_t pos);
extern int _ma_search_last(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
my_off_t pos);
-extern uchar *_ma_fetch_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page, int level, uchar *buff,
+extern byte *_ma_fetch_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ my_off_t page, int level, byte *buff,
int return_buffer);
extern int _ma_write_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page, int level, uchar *buff);
+ my_off_t page, int level, byte *buff);
extern int _ma_dispose(MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
int level);
extern my_off_t _ma_new(MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level);
-extern uint _ma_make_key(MARIA_HA *info, uint keynr, uchar *key,
- const byte *record, my_off_t filepos);
-extern uint _ma_pack_key(MARIA_HA *info, uint keynr, uchar *key,
- uchar *old, uint key_length,
+extern uint _ma_make_key(MARIA_HA *info, uint keynr, byte *key,
+ const byte *record, MARIA_RECORD_POS filepos);
+extern uint _ma_pack_key(MARIA_HA *info, uint keynr, byte *key,
+ const byte *old, uint key_length,
HA_KEYSEG ** last_used_keyseg);
-extern int _ma_read_key_record(MARIA_HA *info, my_off_t filepos,
- byte *buf);
-extern int _ma_read_cache(IO_CACHE *info, byte *buff, my_off_t pos,
+extern int _ma_read_key_record(MARIA_HA *info, byte *buf, MARIA_RECORD_POS);
+extern int _ma_read_cache(IO_CACHE *info, byte *buff, MARIA_RECORD_POS pos,
uint length, int re_read_if_possibly);
extern ulonglong ma_retrieve_auto_increment(MARIA_HA *info, const byte *record);
-extern byte *_ma_alloc_rec_buff(MARIA_HA *, ulong, byte **);
-#define _ma_get_rec_buff_ptr(info,buf) \
- ((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) ? \
- (buf) - MARIA_REC_BUFF_OFFSET : (buf))
-#define _ma_get_rec_buff_len(info,buf) \
- (*((uint32 *)(_ma_get_rec_buff_ptr(info,buf))))
-
+extern my_bool _ma_alloc_buffer(byte **old_addr, my_size_t *old_size,
+ my_size_t new_size);
extern ulong _ma_rec_unpack(MARIA_HA *info, byte *to, byte *from,
ulong reclength);
extern my_bool _ma_rec_check(MARIA_HA *info, const char *record,
@@ -602,11 +701,13 @@ extern int _ma_write_part_record(MARIA_HA *info, my_off_t filepos,
byte ** record, ulong *reclength,
int *flag);
extern void _ma_print_key(FILE *stream, HA_KEYSEG *keyseg,
- const uchar *key, uint length);
-extern my_bool _ma_read_pack_info(MARIA_HA *info, pbool fix_keys);
-extern int _ma_read_pack_record(MARIA_HA *info, my_off_t filepos,
- byte *buf);
-extern int _ma_read_rnd_pack_record(MARIA_HA *, byte *, my_off_t, my_bool);
+ const byte *key, uint length);
+extern my_bool _ma_once_init_pack_row(MARIA_SHARE *share, File dfile);
+extern my_bool _ma_once_end_pack_row(MARIA_SHARE *share);
+extern int _ma_read_pack_record(MARIA_HA *info, byte *buf,
+ MARIA_RECORD_POS filepos);
+extern int _ma_read_rnd_pack_record(MARIA_HA *, byte *, MARIA_RECORD_POS,
+ my_bool);
extern int _ma_pack_rec_unpack(MARIA_HA *info, MARIA_BIT_BUFF *bit_buff,
byte *to, byte *from, ulong reclength);
extern ulonglong _ma_safe_mul(ulonglong a, ulonglong b);
@@ -623,9 +724,9 @@ typedef struct st_maria_block_info
ulong data_len;
ulong block_len;
ulong blob_len;
- my_off_t filepos;
- my_off_t next_filepos;
- my_off_t prev_filepos;
+ MARIA_RECORD_POS filepos;
+ MARIA_RECORD_POS next_filepos;
+ MARIA_RECORD_POS prev_filepos;
uint second_read;
uint offset;
} MARIA_BLOCK_INFO;
@@ -664,6 +765,7 @@ extern uint _ma_get_block_info(MARIA_BLOCK_INFO *, File, my_off_t);
extern uint _ma_rec_pack(MARIA_HA *info, byte *to, const byte *from);
extern uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
MARIA_BLOCK_INFO *info, byte **rec_buff_p,
+ my_size_t *rec_buff_size,
File file, my_off_t filepos);
extern void _ma_store_blob_length(byte *pos, uint pack_length, uint length);
extern void _ma_report_error(int errcode, const char *file_name);
@@ -683,11 +785,10 @@ extern uint _ma_nommap_pwrite(MARIA_HA *info, byte *Buffer,
uint Count, my_off_t offset, myf MyFlags);
uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite);
-uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state);
+byte *_ma_state_info_read(byte *ptr, MARIA_STATE_INFO *state);
uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state,
my_bool pRead);
uint _ma_base_info_write(File file, MARIA_BASE_INFO *base);
-uchar *_ma_n_base_info_read(uchar *ptr, MARIA_BASE_INFO *base);
int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg);
char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
@@ -701,14 +802,14 @@ ha_checksum _ma_checksum(MARIA_HA *info, const byte *buf);
ha_checksum _ma_static_checksum(MARIA_HA *info, const byte *buf);
my_bool _ma_check_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
byte *record, ha_checksum unique_hash,
- my_off_t pos);
+ MARIA_RECORD_POS pos);
ha_checksum _ma_unique_hash(MARIA_UNIQUEDEF *def, const byte *buf);
-int _ma_cmp_static_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
- const byte *record, my_off_t pos);
-int _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
- const byte *record, my_off_t pos);
-int _ma_unique_comp(MARIA_UNIQUEDEF *def, const byte *a, const byte *b,
- my_bool null_are_equal);
+my_bool _ma_cmp_static_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
+ const byte *record, MARIA_RECORD_POS pos);
+my_bool _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
+ const byte *record, MARIA_RECORD_POS pos);
+my_bool _ma_unique_comp(MARIA_UNIQUEDEF *def, const byte *a, const byte *b,
+ my_bool null_are_equal);
void _ma_get_status(void *param, int concurrent_insert);
void _ma_update_status(void *param);
void _ma_copy_status(void *to, void *from);
@@ -722,6 +823,9 @@ void _ma_setup_functions(register MARIA_SHARE *share);
my_bool _ma_dynmap_file(MARIA_HA *info, my_off_t size);
void _ma_remap_file(MARIA_HA *info, my_off_t size);
+MARIA_RECORD_POS _ma_write_init_default(MARIA_HA *info, const byte *record);
+my_bool _ma_write_abort_default(MARIA_HA *info);
+
/* Functions needed by _ma_check (are overrided in MySQL) */
C_MODE_START
volatile int *_ma_killed_ptr(HA_CHECK *param);
diff --git a/storage/maria/maria_ftdump.c b/storage/maria/maria_ftdump.c
index 4e0b4bf5ce3..ef30540bfce 100644
--- a/storage/maria/maria_ftdump.c
+++ b/storage/maria/maria_ftdump.c
@@ -106,7 +106,7 @@ int main(int argc,char *argv[])
maria_lock_database(info, F_EXTRA_LCK);
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
info->update|= HA_STATE_PREV_FOUND;
while (!(error=maria_rnext(info,NULL,inx)))
@@ -157,9 +157,9 @@ int main(int argc,char *argv[])
if (dump)
{
if (subkeys>=0)
- printf("%9lx %20.7f %s\n", (long) info->lastpos,weight,buf);
+ printf("%9lx %20.7f %s\n", (long) info->cur_row.lastpos,weight,buf);
else
- printf("%9lx => %17d %s\n",(long) info->lastpos,-subkeys,buf);
+ printf("%9lx => %17d %s\n",(long) info->cur_row.lastpos,-subkeys,buf);
}
if (verbose && (total%HOW_OFTEN_TO_WRITE)==0)
printf("%10ld\r",total);
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 24de45a89bc..41c519693d5 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -239,7 +239,7 @@ int main(int argc, char **argv)
}
}
if (ok && isamchk_neaded && !silent)
- puts("Remember to run mariachk -rq on compressed tables");
+ puts("Remember to run maria_chk -rq on compressed tables");
VOID(fflush(stdout));
VOID(fflush(stderr));
free_defaults(default_argv);
@@ -294,7 +294,7 @@ static struct my_option my_long_options[] =
static void print_version(void)
{
- VOID(printf("%s Ver 1.23 for %s on %s\n",
+ VOID(printf("%s Ver 1.0 for %s on %s\n",
my_progname, SYSTEM_TYPE, MACHINE_TYPE));
NETWARE_SET_SCREEN_MODE(1);
}
@@ -308,7 +308,7 @@ static void usage(void)
puts("and you are welcome to modify and redistribute it under the GPL license\n");
puts("Pack a MARIA-table to take much less space.");
- puts("Keys are not updated, you must run mariachk -rq on the datafile");
+ puts("Keys are not updated, you must run maria_chk -rq on the datafile");
puts("afterwards to update the keys.");
puts("You should give the .MYI file as the filename argument.");
@@ -359,7 +359,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
silent= 0;
break;
case '#':
- DBUG_PUSH(argument ? argument : "d:t:o");
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/maria_pack.trace");
break;
case 'V':
print_version();
@@ -665,7 +665,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
/* Display statistics. */
DBUG_PRINT("info", ("Min record length: %6d Max length: %6d "
- "Mean total length: %6ld\n",
+ "Mean total length: %6ld",
mrg->min_pack_length, mrg->max_pack_length,
(ulong) (mrg->records ? (new_length/mrg->records) : 0)));
if (verbose && mrg->records)
@@ -681,6 +681,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
{
error|=my_close(isam_file->dfile,MYF(MY_WME));
isam_file->dfile= -1; /* Tell maria_close file is closed */
+ isam_file->s->bitmap.file= -1;
}
}
@@ -841,32 +842,27 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees, uint trees,
static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
{
int error;
- uint length;
+ uint length, null_bytes;
ulong reclength,max_blob_length;
byte *record,*pos,*next_pos,*end_pos,*start_pos;
ha_rows record_count;
- my_bool static_row_size;
HUFF_COUNTS *count,*end_count;
TREE_ELEMENT *element;
+ ha_checksum(*calc_checksum) (struct st_maria_info *, const byte *);
DBUG_ENTER("get_statistic");
- reclength=mrg->file[0]->s->base.reclength;
+ reclength= mrg->file[0]->s->base.reclength;
+ null_bytes= mrg->file[0]->s->base.null_bytes;
record=(byte*) my_alloca(reclength);
end_count=huff_counts+mrg->file[0]->s->base.fields;
record_count=0; glob_crc=0;
max_blob_length=0;
/* Check how to calculate checksum */
- static_row_size=1;
- for (count=huff_counts ; count < end_count ; count++)
- {
- if (count->field_type == FIELD_BLOB ||
- count->field_type == FIELD_VARCHAR)
- {
- static_row_size=0;
- break;
- }
- }
+ if (mrg->file[0]->s->data_file_type == STATIC_RECORD)
+ calc_checksum= _ma_static_checksum;
+ else
+ calc_checksum= _ma_checksum;
mrg_reset(mrg);
while ((error=mrg_rrnd(mrg,record)) != HA_ERR_END_OF_FILE)
@@ -875,13 +871,10 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
if (! error)
{
/* glob_crc is a checksum over all bytes of all records. */
- if (static_row_size)
- glob_crc+=_ma_static_checksum(mrg->file[0],record);
- else
- glob_crc+=_ma_checksum(mrg->file[0],record);
+ glob_crc+= (*calc_checksum)(mrg->file[0],record);
/* Count the incidence of values separately for every column. */
- for (pos=record,count=huff_counts ;
+ for (pos=record + null_bytes, count=huff_counts ;
count < end_count ;
count++,
pos=next_pos)
@@ -1368,7 +1361,8 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
DBUG_VOID_RETURN;
}
- /* Test if we can use space-compression and empty-field-compression */
+
+/* Test if we can use space-compression and empty-field-compression */
static int
test_space_compress(HUFF_COUNTS *huff_counts, my_off_t records,
@@ -2410,8 +2404,8 @@ static uint max_bit(register uint value)
static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
{
int error;
- uint i,max_calc_length,pack_ref_length,min_record_length,max_record_length,
- intervall,field_length,max_pack_length,pack_blob_length;
+ uint i,max_calc_length,pack_ref_length,min_record_length,max_record_length;
+ uint intervall,field_length,max_pack_length,pack_blob_length, null_bytes;
my_off_t record_count;
char llbuf[32];
ulong length,pack_length;
@@ -2429,6 +2423,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
end_count=huff_counts+isam_file->s->base.fields;
min_record_length= (uint) ~0;
max_record_length=0;
+ null_bytes= isam_file->s->base.null_bytes;
/*
Calculate the maximum number of bits required to pack the records.
@@ -2439,7 +2434,8 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
Empty blobs and varchar are encoded with a single 1 bit. Other blobs
and varchar get a leading 0 bit.
*/
- for (i=max_calc_length=0 ; i < isam_file->s->base.fields ; i++)
+ max_calc_length= null_bytes;
+ for (i= 0 ; i < isam_file->s->base.fields ; i++)
{
if (!(huff_counts[i].pack_type & PACK_TYPE_ZERO_FILL))
huff_counts[i].max_zero_fill=0;
@@ -2475,8 +2471,16 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
if (flush_buffer((ulong) max_calc_length + (ulong) max_pack_length))
break;
record_pos= (byte*) file_buffer.pos;
- file_buffer.pos+=max_pack_length;
- for (start_pos=record, count= huff_counts; count < end_count ; count++)
+ file_buffer.pos+= max_pack_length;
+ if (null_bytes)
+ {
+ /* Copy null bits 'as is' */
+ memcpy(file_buffer.pos, record, null_bytes);
+ file_buffer.pos+= null_bytes;
+ }
+ for (start_pos=record+null_bytes, count= huff_counts;
+ count < end_count ;
+ count++)
{
end_pos=start_pos+(field_length=count->field_length);
tree=count->tree;
@@ -2738,8 +2742,9 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
length=(ulong) ((byte*) file_buffer.pos - record_pos) - max_pack_length;
pack_length= _ma_save_pack_length(pack_version, record_pos, length);
if (pack_blob_length)
- pack_length+= _ma_save_pack_length(pack_version, record_pos + pack_length,
- tot_blob_length);
+ pack_length+= _ma_save_pack_length(pack_version,
+ record_pos + pack_length,
+ tot_blob_length);
DBUG_PRINT("fields", ("record: %lu length: %lu blob-length: %lu "
"length-bytes: %lu", (ulong) record_count, length,
tot_blob_length, pack_length));
@@ -2936,7 +2941,8 @@ static void flush_bits(void)
** functions to handle the joined files
****************************************************************************/
-static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
+static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg,
+ my_off_t new_length,
ha_checksum crc)
{
MARIA_SHARE *share=isam_file->s;
@@ -2946,6 +2952,8 @@ static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length
options|= HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA;
mi_int2store(share->state.header.options,options);
+ share->state.header.org_data_file_type= share->state.header.data_file_type;
+ share->state.header.data_file_type= COMPRESSED_RECORD;
share->state.state.data_file_length=new_length;
share->state.state.del=0;
@@ -2964,14 +2972,13 @@ static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length
}
/*
If there are no disabled indexes, keep key_file_length value from
- original file so "mariachk -rq" can use this value (this is necessary
+ original file so "maria_chk -rq" can use this value (this is necessary
because index size cannot be easily calculated for fulltext keys)
*/
maria_clear_all_keys_active(share->state.key_map);
for (key=0 ; key < share->base.keys ; key++)
share->state.key_root[key]= HA_OFFSET_ERROR;
- for (key=0 ; key < share->state.header.max_block_size_index ; key++)
- share->state.key_del[key]= HA_OFFSET_ERROR;
+ share->state.key_del= HA_OFFSET_ERROR;
isam_file->state->checksum=crc; /* Save crc here */
share->changed=1; /* Force write of header */
share->state.open_count=0;
@@ -3039,21 +3046,18 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
info->end=info->current+info->count;
maria_reset(isam_info);
maria_extra(isam_info, HA_EXTRA_CACHE, 0);
- filepos=isam_info->s->pack.header_length;
+ if ((error= maria_scan_init(isam_info)))
+ return(error);
}
else
- {
isam_info= *info->current;
- filepos= isam_info->nextpos;
- }
for (;;)
{
- isam_info->update&= HA_STATE_CHANGED;
- if (!(error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf,
- filepos, 1)) ||
+ if (!(error= maria_scan(isam_info, buf)) ||
error != HA_ERR_END_OF_FILE)
return (error);
+ maria_scan_end(isam_info);
maria_extra(isam_info,HA_EXTRA_NO_CACHE, 0);
if (info->current+1 == info->end)
return(HA_ERR_END_OF_FILE);
@@ -3062,6 +3066,8 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
filepos=isam_info->s->pack.header_length;
maria_reset(isam_info);
maria_extra(isam_info,HA_EXTRA_CACHE, 0);
+ if ((error= maria_scan_init(isam_info)))
+ return(error);
}
}
@@ -3070,11 +3076,13 @@ static int mrg_close(PACK_MRG_INFO *mrg)
{
uint i;
int error=0;
+ DBUG_ENTER("mrg_close");
+
for (i=0 ; i < mrg->count ; i++)
error|=maria_close(mrg->file[i]);
if (mrg->free_file)
my_free((gptr) mrg->file,MYF(0));
- return error;
+ DBUG_RETURN(error);
}
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index fa9638778d6..1d119e2a1ca 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -935,6 +935,9 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info,int extend)
if (*killed_ptr(param))
goto err2;
switch (info->s->data_file_type) {
+ case BLOCK_RECORD:
+ DBUG_ASSERT(0); /* Impossible */
+ break;
case STATIC_RECORD:
if (my_b_read(&param->read_cache,(byte*) record,
info->s->base.pack_reclength))
@@ -3069,6 +3072,9 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
DBUG_RETURN(1);
switch (share->data_file_type) {
+ case BLOCK_RECORD:
+ DBUG_ASSERT(0); /* Impossible */
+ break;
case STATIC_RECORD:
for (;;)
{
@@ -3493,6 +3499,9 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
if (sort_param->fix_datafile)
{
switch (sort_info->new_data_file_type) {
+ case BLOCK_RECORD:
+ DBUG_ASSERT(0); /* Impossible */
+ break;
case STATIC_RECORD:
if (my_b_write(&info->rec_cache,sort_param->record,
share->base.pack_reclength))
@@ -3606,18 +3615,19 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
if (sort_info->key_block->inited)
{
- cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
+ cmp=ha_key_cmp(sort_param->seg, (uchar*) sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
diff_pos);
if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
- ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
+ ha_key_cmp(sort_param->seg, (uchar*) sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos);
else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS)
{
diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg,
sort_param->notnull,
- sort_info->key_block->lastkey,
+ (uchar*) sort_info->
+ key_block->lastkey,
(uchar*)a);
}
sort_param->unique[diff_pos[0]-1]++;
@@ -3640,8 +3650,8 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
llstr(sort_info->info->lastpos,llbuff),
llstr(get_record_for_key(sort_info->info,
sort_param->keyinfo,
- sort_info->key_block->
- lastkey),
+ (uchar*) sort_info->
+ key_block->lastkey),
llbuff2));
param->testflag|=T_RETRY_WITHOUT_QUICK;
if (sort_info->param->testflag & T_VERBOSE)
@@ -3672,19 +3682,19 @@ int sort_ft_buf_flush(MI_SORT_PARAM *sort_param)
val_len=share->ft2_keyinfo.keylength;
get_key_full_length_rdonly(val_off, ft_buf->lastkey);
- to=ft_buf->lastkey+val_off;
+ to= (uchar*) ft_buf->lastkey+val_off;
if (ft_buf->buf)
{
/* flushing first-level tree */
- error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
+ error=sort_insert_key(sort_param,key_block, (uchar*) ft_buf->lastkey,
HA_OFFSET_ERROR);
for (from=to+val_len;
- !error && from < ft_buf->buf;
+ !error && from < (uchar*) ft_buf->buf;
from+= val_len)
{
memcpy(to, from, val_len);
- error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
+ error=sort_insert_key(sort_param,key_block, (uchar*) ft_buf->lastkey,
HA_OFFSET_ERROR);
}
return error;
@@ -3693,8 +3703,8 @@ int sort_ft_buf_flush(MI_SORT_PARAM *sort_param)
error=flush_pending_blocks(sort_param);
/* updating lastkey with second-level tree info */
ft_intXstore(ft_buf->lastkey+val_off, -ft_buf->count);
- _mi_dpointer(sort_info->info, ft_buf->lastkey+val_off+HA_FT_WLEN,
- share->state.key_root[sort_param->key]);
+ _mi_dpointer(sort_info->info, (uchar*) ft_buf->lastkey+val_off+HA_FT_WLEN,
+ share->state.key_root[sort_param->key]);
/* restoring first level tree data in sort_info/sort_param */
sort_info->key_block=sort_info->key_block_end- sort_info->param->sort_key_blocks;
sort_param->keyinfo=share->keyinfo+sort_param->key;
@@ -3702,7 +3712,7 @@ int sort_ft_buf_flush(MI_SORT_PARAM *sort_param)
/* writing lastkey in first-level tree */
return error ? error :
sort_insert_key(sort_param,sort_info->key_block,
- ft_buf->lastkey,HA_OFFSET_ERROR);
+ (uchar*) ft_buf->lastkey,HA_OFFSET_ERROR);
}
static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a)
@@ -3741,7 +3751,7 @@ static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a)
if (ha_compare_text(sort_param->seg->charset,
((uchar *)a)+1,a_len-1,
- ft_buf->lastkey+1,val_off-1, 0, 0)==0)
+ (uchar*) ft_buf->lastkey+1,val_off-1, 0, 0)==0)
{
if (!ft_buf->buf) /* store in second-level tree */
{
@@ -3757,16 +3767,16 @@ static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a)
return 0;
/* converting to two-level tree */
- p=ft_buf->lastkey+val_off;
+ p= (uchar*) ft_buf->lastkey+val_off;
while (key_block->inited)
key_block++;
sort_info->key_block=key_block;
sort_param->keyinfo=& sort_info->info->s->ft2_keyinfo;
- ft_buf->count=(ft_buf->buf - p)/val_len;
+ ft_buf->count=((uchar*) ft_buf->buf - p)/val_len;
/* flushing buffer to second-level tree */
- for (error=0; !error && p < ft_buf->buf; p+= val_len)
+ for (error=0; !error && p < (uchar*) ft_buf->buf; p+= val_len)
error=sort_insert_key(sort_param,key_block,p,HA_OFFSET_ERROR);
ft_buf->buf=0;
return error;
@@ -3818,9 +3828,9 @@ static int sort_insert_key(MI_SORT_PARAM *sort_param,
HA_CHECK *param=sort_info->param;
DBUG_ENTER("sort_insert_key");
- anc_buff=key_block->buff;
+ anc_buff= (uchar*) key_block->buff;
info=sort_info->info;
- lastkey=key_block->lastkey;
+ lastkey= (uchar*) key_block->lastkey;
nod_flag= (key_block == sort_info->key_block ? 0 :
info->s->base.key_reflength);
@@ -3833,7 +3843,7 @@ static int sort_insert_key(MI_SORT_PARAM *sort_param,
DBUG_RETURN(1);
}
a_length=2+nod_flag;
- key_block->end_pos=anc_buff+2;
+ key_block->end_pos= (char*) anc_buff+2;
lastkey=0; /* No previous key in block */
}
else
@@ -3841,18 +3851,18 @@ static int sort_insert_key(MI_SORT_PARAM *sort_param,
/* Save pointer to previous block */
if (nod_flag)
- _mi_kpointer(info,key_block->end_pos,prev_block);
+ _mi_kpointer(info,(uchar*) key_block->end_pos,prev_block);
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
(uchar*) 0,lastkey,lastkey,key,
&s_temp);
- (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
+ (*keyinfo->store_key)(keyinfo, (uchar*) key_block->end_pos+nod_flag,&s_temp);
a_length+=t_length;
mi_putint(anc_buff,a_length,nod_flag);
key_block->end_pos+=t_length;
if (a_length <= keyinfo->block_length)
{
- VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
+ VOID(_mi_move_key(keyinfo,(uchar*) key_block->lastkey,key));
key_block->last_length=a_length-t_length;
DBUG_RETURN(0);
}
@@ -3877,7 +3887,8 @@ static int sort_insert_key(MI_SORT_PARAM *sort_param,
DBUG_DUMP("buff",(byte*) anc_buff,mi_getint(anc_buff));
/* Write separator-key to block in next level */
- if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
+ if (sort_insert_key(sort_param,key_block+1,(uchar*) key_block->lastkey,
+ filepos))
DBUG_RETURN(1);
/* clear old block and write new key in it */
@@ -3963,7 +3974,7 @@ int flush_pending_blocks(MI_SORT_PARAM *sort_param)
key_block->inited=0;
length=mi_getint(key_block->buff);
if (nod_flag)
- _mi_kpointer(info,key_block->end_pos,filepos);
+ _mi_kpointer(info,(uchar*) key_block->end_pos,filepos);
key_file_length=info->state->key_file_length;
bzero((byte*) key_block->buff+length, keyinfo->block_length-length);
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
@@ -3973,7 +3984,7 @@ int flush_pending_blocks(MI_SORT_PARAM *sort_param)
if (key_file_length == info->state->key_file_length)
{
if (_mi_write_keypage(info, keyinfo, filepos,
- DFLT_INIT_HITS, key_block->buff))
+ DFLT_INIT_HITS, (uchar*) key_block->buff))
DBUG_RETURN(1);
}
else if (my_pwrite(info->s->kfile,(byte*) key_block->buff,
@@ -4005,7 +4016,7 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
for (i=0 ; i < blocks ; i++)
{
block[i].inited=0;
- block[i].buff=(uchar*) (block+blocks)+(buffer_length+IO_SIZE)*i;
+ block[i].buff=(byte*) (block+blocks)+(buffer_length+IO_SIZE)*i;
}
DBUG_RETURN(block);
} /* alloc_key_blocks */
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 114371947e6..a675325f0a1 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -42,7 +42,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
File dfile,file;
int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
myf create_flag;
- uint fields,length,max_key_length,packed,pointer,real_length_diff,
+ uint fields,length,max_key_length,packed,pack_bytes,pointer,real_length_diff,
key_length,info_length,key_segs,options,min_key_length_skip,
base_pos,long_varchar_count,varchar_length,
max_key_block_length,unique_key_parts,fulltext_keys,offset;
@@ -190,11 +190,11 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
options|= HA_OPTION_RELIES_ON_SQL_LAYER;
- packed=(packed+7)/8;
+ pack_bytes= (packed+7)/8;
if (pack_reclength != INT_MAX32)
pack_reclength+= reclength+packed +
test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
- min_pack_length+=packed;
+ min_pack_length+= pack_bytes;
if (!ci->data_file_length && ci->max_rows)
{
@@ -548,9 +548,9 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
share.base.max_pack_length=pack_reclength;
share.base.min_pack_length=min_pack_length;
- share.base.pack_bits=packed;
+ share.base.pack_bits= pack_bytes;
share.base.fields=fields;
- share.base.pack_fields=packed;
+ share.base.pack_fields= packed;
#ifdef USE_RAID
share.base.raid_type=ci->raid_type;
share.base.raid_chunks=ci->raid_chunks;
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index 498b433f846..9cf47e1555b 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -604,7 +604,7 @@ int main(int argc, char *argv[])
if (mi_rsame(file,read_record2,(int) i)) goto err;
if (bcmp(read_record,read_record2,reclength) != 0)
{
- printf("is_rsame didn't find same record\n");
+ printf("mi_rsame didn't find same record\n");
goto end;
}
}
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index 53267e2820c..8bbb1f06804 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -830,7 +830,7 @@ static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
register uint count;
uint16 length_of_key = 0;
uint idx;
- uchar *buffp;
+ byte *buffp;
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
{
@@ -917,7 +917,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
{
count+= buffpek->count;
- buffpek->base= strpos;
+ buffpek->base= (byte*) strpos;
buffpek->max_keys=maxcount;
strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek,
sort_length));
@@ -955,7 +955,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
{
if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
{
- uchar *base=buffpek->base;
+ byte *base= buffpek->base;
uint max_keys=buffpek->max_keys;
VOID(queue_remove(&queue,0));
@@ -987,7 +987,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
- buffpek->base=(uchar *) sort_keys;
+ buffpek->base= (byte*) sort_keys;
buffpek->max_keys=keys;
do
{
@@ -1002,7 +1002,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
else
{
register uchar *end;
- strpos= buffpek->key;
+ strpos= (uchar*) buffpek->key;
for (end=strpos+buffpek->mem_count*sort_length;
strpos != end ;
strpos+=sort_length)