summaryrefslogtreecommitdiff
path: root/storage/maria
diff options
context:
space:
mode:
Diffstat (limited to 'storage/maria')
-rw-r--r--storage/maria/Makefile.am3
-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.c1716
-rw-r--r--storage/maria/ma_checksum.c25
-rw-r--r--storage/maria/ma_close.c29
-rw-r--r--storage/maria/ma_create.c454
-rw-r--r--storage/maria/ma_dbug.c6
-rw-r--r--storage/maria/ma_delete.c204
-rw-r--r--storage/maria/ma_delete_all.c3
-rw-r--r--storage/maria/ma_dynrec.c261
-rw-r--r--storage/maria/ma_extra.c34
-rw-r--r--storage/maria/ma_ft_boolean_search.c34
-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.c271
-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.c76
-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.c14
-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.c132
-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.sh289
-rw-r--r--storage/maria/ma_unique.c30
-rw-r--r--storage/maria/ma_update.c37
-rw-r--r--storage/maria/ma_write.c216
-rw-r--r--storage/maria/maria_chk.c195
-rw-r--r--storage/maria/maria_def.h463
-rw-r--r--storage/maria/maria_ftdump.c6
-rw-r--r--storage/maria/maria_pack.c100
62 files changed, 8602 insertions, 2817 deletions
diff --git a/storage/maria/Makefile.am b/storage/maria/Makefile.am
index d4315b4d446..b2936143c36 100644
--- a/storage/maria/Makefile.am
+++ b/storage/maria/Makefile.am
@@ -28,7 +28,7 @@ bin_PROGRAMS = maria_chk maria_pack maria_ftdump
maria_chk_DEPENDENCIES= $(LIBRARIES)
maria_pack_DEPENDENCIES=$(LIBRARIES)
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
+noinst_HEADERS = maria_def.h ma_blockrec.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
ma_test1_DEPENDENCIES= $(LIBRARIES)
ma_test2_DEPENDENCIES= $(LIBRARIES)
ma_test3_DEPENDENCIES= $(LIBRARIES)
@@ -42,6 +42,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/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 69d863e6366..3fece3687e1 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -28,43 +28,43 @@
#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(HA_CHECK *param, MARIA_HA *info,byte *buff,
my_off_t filepos);
-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;
@@ -182,7 +182,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;
}
}
@@ -223,18 +223,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],*buff;
DBUG_ENTER("check_k_link");
- if (param->testflag & T_VERBOSE)
- printf("block_size %4d:",block_size);
-
- 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)
{
@@ -243,12 +239,12 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info, uint nr)
if (param->testflag & T_VERBOSE)
printf("%16s",llstr(next_link,llbuff));
if (next_link > info->state->key_file_length ||
- next_link & (info->s->blocksize-1))
+ next_link & (info->s->block_size-1))
DBUG_RETURN(1);
if (!(buff=key_cache_read(info->s->key_cache,
info->s->kfile, next_link, DFLT_INIT_HITS,
(byte*) info->buff,
- maria_block_size, block_size, 1)))
+ block_size, block_size, 1)))
DBUG_RETURN(1);
next_link=mi_sizekorr(buff);
records--;
@@ -274,9 +270,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);
@@ -291,7 +288,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));
@@ -341,7 +338,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)
{
@@ -359,23 +356,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++)
@@ -433,11 +429,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)
@@ -456,7 +451,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)
{
@@ -479,7 +474,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");
@@ -528,21 +523,22 @@ 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];
- if (page > info->state->key_file_length || (page & (info->s->blocksize -1)))
+ if (page > info->state->key_file_length || (page & (info->s->block_size -1)))
{
my_off_t max_length=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
_ma_check_print_error(param,"Wrong pagepointer: %s at page: %s",
llstr(page,llbuff),llstr(page,llbuff2));
- if (page+info->s->blocksize > max_length)
+ if (page+info->s->block_size > max_length)
goto err;
info->state->key_file_length=(max_length &
- ~ (my_off_t) (info->s->blocksize-1));
+ ~ (my_off_t) (info->s->block_size-1));
}
if (!_ma_fetch_keypage(info,keyinfo,page, DFLT_INIT_HITS,buff,0))
{
@@ -577,10 +573,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.
@@ -617,7 +613,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;
@@ -631,12 +628,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]++;
@@ -652,12 +649,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];
@@ -668,7 +665,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);
@@ -698,8 +695,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);
@@ -713,21 +710,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)
@@ -735,14 +735,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]++;
}
@@ -795,7 +795,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)
{
@@ -852,355 +852,844 @@ 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;
+}
+
+
+/*
+ Functions to loop through all rows and check if they are ok
+
+ NOTES
+ One function for each record format
- pos=my_b_tell(&param->read_cache);
- bzero((char*) key_checksum, info->s->base.keys * sizeof(key_checksum[0]));
+ 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,&block_info, -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,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;
+ }
+ else
+ {
+ 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);
}
- 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 */
+ {
+ 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,&block_info, -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,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)
{
- printf("%s\r", llstr(records,llbuff)); VOID(fflush(stdout));
+ _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
+*/
- /* Check if keys match the record */
- for (key=0,keyinfo= info->s->keyinfo; key < info->s->base.keys;
- key++,keyinfo++)
+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++)
{
- 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);
- }
- }
+ 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);
+ }
+ }
}
}
- else
+ 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;
+
+ 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 (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))
+ {
+ _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;
+ }
+ /* 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))
+ {
+ 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;
+ }
+ 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)
{
- got_error=0;
- if (error++ > MAXERR || !(param->testflag & T_VERBOSE))
- goto err2;
+ tail_count+= real_row_count;
+ continue;
}
- next:; /* Next record */
+ 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 &&
@@ -1213,9 +1702,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",
@@ -1225,68 +1715,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);
@@ -1297,7 +1802,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;
@@ -1348,7 +1853,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;
@@ -1357,14 +1863,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);
@@ -1376,10 +1879,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;
@@ -1411,8 +1911,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,
@@ -1436,7 +1935,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,
@@ -1530,8 +2029,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;
@@ -1545,26 +2043,20 @@ 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);
@@ -1577,10 +2069,10 @@ static int writekeys(HA_CHECK *param, register MARIA_HA *info, byte *buff,
my_off_t filepos)
{
register uint i;
- uchar *key;
+ byte *key;
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))
@@ -1632,7 +2124,7 @@ static int writekeys(HA_CHECK *param, register MARIA_HA *info, byte *buff,
}
/* Remove checksum that was added to glob_crc in sort_get_next_record */
if (param->calc_checksum)
- param->glob_crc-= info->checksum;
+ param->glob_crc-= info->cur_row.checksum;
DBUG_PRINT("error",("errno: %d",my_errno));
DBUG_RETURN(-1);
} /* writekeys */
@@ -1640,15 +2132,16 @@ static int writekeys(HA_CHECK *param, register MARIA_HA *info, byte *buff,
/* 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))
@@ -1764,7 +2257,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);
@@ -1779,8 +2272,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 */
@@ -1795,8 +2288,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);
@@ -1811,12 +2303,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");
@@ -1824,7 +2317,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);
@@ -1907,9 +2400,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
@@ -1981,7 +2472,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;
@@ -2034,7 +2525,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;
@@ -2042,14 +2534,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);
@@ -2059,10 +2548,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;
}
@@ -2072,14 +2558,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
@@ -2191,13 +2676,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,
@@ -2276,7 +2761,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",
@@ -2315,9 +2800,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;
}
@@ -2329,8 +2814,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;
}
@@ -2340,8 +2824,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));
@@ -2349,10 +2832,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);
}
@@ -2435,15 +2915,12 @@ 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);
@@ -2453,10 +2930,7 @@ int maria_repair_parallel(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;
}
@@ -2466,14 +2940,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
@@ -2573,12 +3046,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++)
@@ -2698,7 +3171,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",
@@ -2736,9 +3209,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;
}
@@ -2750,8 +3223,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;
}
@@ -2771,21 +3243,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)))
@@ -2799,7 +3268,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,
@@ -2808,7 +3277,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;
@@ -2841,7 +3311,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,
@@ -2881,6 +3352,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 (;;)
{
@@ -2904,7 +3378,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (*sort_param->record)
{
if (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);
}
@@ -3088,8 +3562,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)
{
@@ -3107,8 +3584,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)
{
@@ -3158,7 +3634,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (sort_param->read_cache.error < 0)
DBUG_RETURN(1);
if (info->s->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,
@@ -3172,7 +3648,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
}
if (param->calc_checksum)
- param->glob_crc+= info->checksum;
+ param->glob_crc+= info->cur_row.checksum;
DBUG_RETURN(0);
}
if (!searching)
@@ -3230,7 +3706,6 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
llstr(sort_param->pos,llbuff));
continue;
}
- info->checksum=_ma_checksum(info,sort_param->record);
if (!sort_param->fix_datafile)
{
sort_param->filepos=sort_param->pos;
@@ -3240,8 +3715,12 @@ 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 (param->calc_checksum)
- param->glob_crc+= info->checksum;
+
+ {
+ info->cur_row.checksum= (*info->s->calc_checksum)(info,
+ sort_param->record);
+ param->glob_crc+= info->cur_row.checksum;
+ }
DBUG_RETURN(0);
}
}
@@ -3267,6 +3746,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))
@@ -3276,7 +3758,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)
@@ -3298,10 +3779,9 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
}
from=sort_info->buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER);
}
- info->checksum=_ma_checksum(info,sort_param->record);
+ 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
{
@@ -3322,7 +3802,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;
@@ -3337,7 +3816,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;
@@ -3369,7 +3847,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];
@@ -3379,11 +3857,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)
@@ -3391,7 +3869,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]++;
}
@@ -3400,17 +3878,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->
@@ -3418,7 +3896,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
@@ -3429,10 +3907,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;
@@ -3441,24 +3920,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;
}
@@ -3478,10 +3957,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;
@@ -3514,13 +3994,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. */
@@ -3569,21 +4050,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;
@@ -3591,7 +4073,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 :
@@ -3617,7 +4099,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;
@@ -3625,14 +4107,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)
@@ -3644,10 +4126,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))
@@ -3665,7 +4147,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;
@@ -3680,7 +4162,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);
}
@@ -3688,8 +4170,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");
@@ -3699,10 +4182,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);
}
@@ -3738,7 +4224,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);
@@ -3749,10 +4235,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 */
@@ -3768,9 +4254,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);
@@ -3778,7 +4264,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 */
@@ -3821,7 +4307,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));
@@ -3877,8 +4364,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;
@@ -3894,7 +4383,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;
@@ -3916,21 +4405,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,
@@ -3939,8 +4436,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 */
@@ -3990,7 +4488,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)
{
@@ -4303,12 +4802,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;
@@ -4316,3 +4810,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 5b940eaf4c3..e5d2985ce47 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -28,7 +28,7 @@ int maria_close(register MARIA_HA *info)
int error=0,flag;
MARIA_SHARE *share=info->s;
DBUG_ENTER("maria_close");
- DBUG_PRINT("enter",("base: %lx reopen: %u locks: %u",
+ DBUG_PRINT("enter",("base: 0x%lx reopen: %u locks: %u",
info,(uint) share->reopen, (uint) share->tot_locks));
pthread_mutex_lock(&THR_LOCK_maria);
@@ -60,16 +60,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.
@@ -78,18 +84,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 b9fb4eb0d5b..82585e78ba7 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -18,6 +18,7 @@
#include "ma_ftdefs.h"
#include "ma_sp_defs.h"
+#include "ma_blockrec.h"
#if defined(MSDOS) || defined(__WIN__)
#ifdef __WIN__
@@ -28,41 +29,48 @@
#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;
DBUG_ENTER("maria_create");
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));
@@ -73,22 +81,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)
@@ -101,59 +111,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--;
@@ -166,14 +207,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 || (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 (packed && record_type == STATIC_RECORD)
+ record_type= BLOCK_RECORD;
+ if (record_type == DYNAMIC_RECORD)
+ options|= HA_OPTION_PACK_RECORD; /* Must use packed records */
+
+ 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;
@@ -183,18 +237,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 ||
@@ -204,20 +264,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 (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
- pointer=maria_get_pointer_length(ci->data_file_length,maria_data_pointer_size);
+ {
+ 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 (!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 */
@@ -227,19 +324,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;
@@ -253,11 +345,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;
}
@@ -431,35 +523,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= 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;
@@ -476,14 +555,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. */
@@ -505,11 +582,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;
@@ -518,9 +597,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)
@@ -534,13 +615,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;
@@ -548,9 +626,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;
@@ -559,7 +637,7 @@ int maria_create(const char *name,uint keys,MARIA_KEYDEF *keydefs,
/* max_data_file_length and max_key_file_length are recalculated on open */
if (options & HA_OPTION_TMP_TABLE)
- 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=
(share.base.pack_reclength+3 < MARIA_EXTEND_BLOCK_LENGTH &&
@@ -632,72 +710,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)
- {
- (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)
{
- 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 (options & HA_OPTION_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 (options & HA_OPTION_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))) < 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))) < 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"));
@@ -738,7 +807,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;
@@ -776,6 +845,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))
@@ -783,9 +853,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)
@@ -797,7 +885,8 @@ 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;
@@ -826,7 +915,6 @@ 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),
@@ -868,3 +956,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 d1ad9edbed5..2669585202a 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", 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,14 +592,14 @@ 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;
}
else
{ /* Page is full */
endpos=anc_buff+anc_length;
- DBUG_PRINT("test",("anc_buff: %lx endpos: %lx",anc_buff,endpos));
+ DBUG_PRINT("test",("anc_buff: 0x%lx endpos: 0x%lx",anc_buff,endpos));
if (keypos != anc_buff+2+key_reflength &&
!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,keypos,&length))
goto err;
@@ -601,22 +607,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);
@@ -624,15 +629,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);
@@ -655,11 +660,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))
@@ -668,17 +672,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);
@@ -711,18 +715,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);
@@ -730,15 +733,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);
@@ -763,15 +766,15 @@ 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: %lx page_end: %lx",keypos,page_end));
+ DBUG_PRINT("enter",("keypos: 0x%lx page_end: 0x%lx", keypos, page_end));
start=keypos;
if (!(keyinfo->flag &
@@ -795,7 +798,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);
@@ -882,7 +885,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 b16d82ed9f7..3e1448e858a 100644
--- a/storage/maria/ma_delete_all.c
+++ b/storage/maria/ma_delete_all.c
@@ -43,8 +43,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 047826408c3..a1d4ee58bf1 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,13 +1256,13 @@ 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);
err:
my_errno= HA_ERR_WRONG_IN_RECORD;
- DBUG_PRINT("error",("to_end: %lx -> %lx from_end: %lx -> %lx",
+ DBUG_PRINT("error",("to_end: 0x%lx -> 0x%lx from_end: 0x%lx -> 0x%lx",
to,to_end,from,from_end));
DBUG_DUMP("from",(byte*) info->rec_buff,info->s->base.min_pack_length);
DBUG_RETURN(MY_FILE_ERROR);
@@ -1305,16 +1327,17 @@ void _ma_store_blob_length(byte *pos,uint pack_length,uint length)
/* Read record from datafile */
- /* Returns 0 if ok, -1 if error */
+ /* Returns 0 if ok, 1 if 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 flag;
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)
{
@@ -1349,17 +1372,18 @@ 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)
goto panic; /* Wrong linked record */
- if (info->s->file_read(info,(byte*) to,block_info.data_len,block_info.filepos,
+ if (info->s->file_read(info,(byte*) to,block_info.data_len,
+ block_info.filepos,
MYF(MY_NABP)))
goto panic;
left_length-=block_info.data_len;
@@ -1369,55 +1393,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 */
@@ -1427,7 +1457,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;
@@ -1440,12 +1470,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)
@@ -1472,9 +1502,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;
@@ -1484,17 +1518,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];
@@ -1514,14 +1550,15 @@ 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);
}
-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,
+ register MARIA_RECORD_POS filepos,
my_bool skip_deleted_blocks)
{
int flag,info_read,save_errno;
@@ -1594,9 +1631,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;
}
@@ -1604,15 +1641,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)
@@ -1658,7 +1695,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, byte *buf,
}
if (flag++ == 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 d600fedb99b..a75b8084214 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;
@@ -327,8 +329,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;
@@ -419,8 +426,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);
@@ -428,7 +440,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 83901cb5e47..40ac88bfcbf 100644
--- a/storage/maria/ma_ft_boolean_search.c
+++ b/storage/maria/ma_ft_boolean_search.c
@@ -332,7 +332,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
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;
+ byte *lastkey_buf= ftbw->word+ftbw->off;
LINT_INIT(off);
if (ftbw->flags & FTB_FLAG_TRUNC)
@@ -343,7 +343,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
@@ -352,10 +352,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);
}
@@ -369,7 +369,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,
@@ -379,11 +379,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 */
@@ -405,7 +405,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;
@@ -425,15 +425,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;
}
@@ -796,11 +796,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)
@@ -851,9 +851,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);
@@ -877,7 +877,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 318bbe341e4..b1d119732e2 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"
static int maria_inited= 0;
pthread_mutex_t THR_LOCK_maria;
@@ -42,6 +43,7 @@ int maria_init(void)
{
maria_inited= 1;
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 ecd51f5dc92..d366c9461d6 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,*end;
- uchar *start;
+ const byte *pos,*end;
+ 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;
}
@@ -121,7 +121,7 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
length=(uint) (end-pos);
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;
}
@@ -134,18 +134,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;
}
@@ -184,14 +184,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)););
@@ -217,10 +217,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");
@@ -232,7 +232,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)
@@ -249,11 +249,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] == ' ')
@@ -268,7 +269,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;
}
@@ -282,7 +283,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;
}
@@ -297,7 +298,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;
@@ -321,7 +322,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
@@ -358,8 +359,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++)
{
@@ -378,7 +379,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--;
@@ -388,7 +389,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;
}
@@ -429,7 +430,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)
@@ -472,8 +473,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;
}
}
@@ -486,7 +486,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)
@@ -526,7 +526,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 837b0fbac66..a2ea4349338 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: %lx new_key_cache_handle: %lx",
- share->key_cache, key_cache));
+ DBUG_PRINT("enter",
+ ("old_key_cache_handle: 0x%lx new_key_cache_handle: 0x%lx",
+ share->key_cache, 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 adb4b03bebe..62746eba875 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;
@@ -350,7 +363,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));
@@ -358,13 +371,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)
@@ -373,8 +386,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 38e71a44f8b..cbc781c589e 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) &&
@@ -239,6 +244,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);
@@ -246,25 +252,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;
@@ -286,29 +273,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++)
@@ -319,7 +302,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++)
{
@@ -423,28 +406,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();
@@ -456,25 +454,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;
#ifdef THREAD
thr_lock_init(&share->lock);
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
@@ -493,6 +478,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)
{
@@ -512,9 +498,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;
}
@@ -530,7 +518,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;
@@ -540,7 +528,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 */
@@ -557,8 +545,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)
@@ -570,7 +562,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++;
@@ -580,15 +573,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
@@ -608,12 +603,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));
@@ -636,38 +634,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;
}
@@ -684,28 +667,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;
@@ -716,22 +708,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;
}
@@ -798,55 +810,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;
}
}
@@ -858,54 +868,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;
}
@@ -924,7 +931,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;
}
@@ -938,74 +945,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;
}
@@ -1018,13 +1035,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));
}
@@ -1033,12 +1050,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;
@@ -1062,9 +1078,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;
@@ -1081,10 +1097,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));
@@ -1129,47 +1145,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;
}
@@ -1264,3 +1277,25 @@ int maria_indexes_are_disabled(MARIA_HA *info)
return (! maria_is_any_key_active(share->state.key_map) && share->base.keys);
}
+
+
+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 eb99e299f9a..69d2f15ca16 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,55 +59,61 @@ 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_BLOCK_INFO *info,
+static uchar *_ma_mempack_get_block_info(MARIA_HA *maria,
+ MARIA_BLOCK_INFO *info,
uchar *header);
#endif
@@ -121,21 +130,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");
@@ -144,7 +175,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)))
{
@@ -206,7 +236,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;
@@ -257,7 +287,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)
{
@@ -432,7 +463,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;
@@ -466,15 +497,20 @@ int _ma_pack_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
MARIA_SHARE *share=info->s;
DBUG_ENTER("_ma_pack_rec_unpack");
- init_bit_buffer(&info->bit_buff, (uchar*) from,reclength);
-
+ 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(&info->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,&info->bit_buff,(uchar*) to,
- (uchar*) end_field);
+ (*current_field->unpack)(current_field,&info->bit_buff, to, end_field);
}
if (! info->bit_buff.error &&
info->bit_buff.pos - info->bit_buff.bits/8 == info->bit_buff.end)
@@ -487,7 +523,7 @@ int _ma_pack_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
/* 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:
@@ -541,8 +577,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));
@@ -554,8 +591,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));
@@ -563,8 +600,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),' ');
@@ -572,8 +609,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))
@@ -596,8 +634,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))
@@ -615,8 +654,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))
@@ -634,8 +673,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)
@@ -648,8 +687,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))
@@ -673,8 +713,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))
@@ -693,8 +734,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))
@@ -712,8 +753,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)
@@ -726,24 +767,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,
@@ -755,16 +796,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);
@@ -775,7 +816,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*));
@@ -785,21 +827,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 */
@@ -815,8 +857,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;
@@ -850,7 +892,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
@@ -870,7 +912,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);
@@ -880,8 +922,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;
@@ -967,7 +1009,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);
@@ -977,7 +1019,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 (;;)
@@ -991,8 +1034,9 @@ 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;
@@ -1039,9 +1083,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,buf,info->rec_buff,
@@ -1053,10 +1097,10 @@ 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_BLOCK_INFO *info, File file,
- my_off_t filepos)
+uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BLOCK_INFO *info,
+ File file, my_off_t filepos)
{
- uchar *header=info->header;
+ uchar *header= info->header;
uint head_length,ref_length;
LINT_INIT(ref_length);
@@ -1078,8 +1122,9 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BLOCK_INFO *info, File file,
{
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,
- &maria->rec_buff)))
+ if (_ma_alloc_buffer(&maria->rec_buff, &maria->rec_buff_size,
+ info->rec_len + info->blob_len +
+ maria->s->base.extra_rec_buff_size))
return BLOCK_FATAL_ERROR; /* not enough memory */
maria->bit_buff.blob_pos=(uchar*) maria->rec_buff+info->rec_len;
maria->bit_buff.blob_end= maria->bit_buff.blob_pos+info->blob_len;
@@ -1098,7 +1143,8 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BLOCK_INFO *info, File file,
/* 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;
@@ -1174,8 +1220,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)
{
@@ -1195,7 +1243,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);
}
@@ -1207,7 +1255,8 @@ void _ma_unmap_file(MARIA_HA *info)
}
-static uchar *_ma_mempack_get_block_info(MARIA_HA *maria,MARIA_BLOCK_INFO *info,
+static uchar *_ma_mempack_get_block_info(MARIA_HA *maria,
+ MARIA_BLOCK_INFO *info,
uchar *header)
{
header+= read_pack_length((uint) maria->s->pack.version, header,
@@ -1217,8 +1266,8 @@ static uchar *_ma_mempack_get_block_info(MARIA_HA *maria,MARIA_BLOCK_INFO *info,
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,
- &maria->rec_buff)))
+ if (_ma_alloc_buffer(&maria->rec_buff, &maria->rec_buff_size,
+ info->blob_len + maria->s->base.extra_rec_buff_size))
return 0; /* not enough memory */
maria->bit_buff.blob_pos=(uchar*) maria->rec_buff;
maria->bit_buff.blob_end= (uchar*) maria->rec_buff + info->blob_len;
@@ -1227,7 +1276,8 @@ static uchar *_ma_mempack_get_block_info(MARIA_HA *maria,MARIA_BLOCK_INFO *info,
}
-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;
@@ -1246,8 +1296,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)))
{
@@ -1274,8 +1325,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,buf,pos, block_info.rec_len));
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index 054b8e16468..e7ca329c3e2 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",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 0f6883f4c9d..243e8e1b9c3 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,12 +68,12 @@ 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;
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]);
@@ -113,24 +113,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)
@@ -147,13 +146,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");
@@ -162,7 +161,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);
@@ -213,11 +212,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 2cb54a73b15..bd92ebd4e4c 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,15 +82,17 @@ 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 are searching for an exact key (including the data pointer)
@@ -98,50 +100,65 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key, uint key_len
then the result is "key not found".
*/
if ((search_flag == HA_READ_KEY_EXACT) &&
- (info->lastpos >= info->state->data_file_length))
+ (info->cur_row.lastpos >= info->state->data_file_length))
{
my_errno= HA_ERR_KEY_NOT_FOUND;
- info->lastpos= HA_OFFSET_ERROR;
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
}
- else while (info->lastpos >= info->state->data_file_length)
+ else
{
- /*
- Skip rows that are inserted by other threads since we got a lock
- Note that this can only happen if we are not searching after an
- exact key, because the keys are sorted according to position
- */
-
- if (_ma_search_next(info, keyinfo, info->lastkey,
- info->lastkey_length,
- maria_readnext_vec[search_flag],
- info->s->state.key_root[inx]))
- break;
+ while (info->cur_row.lastpos >= info->state->data_file_length)
+ {
+ /*
+ Skip rows that are inserted by other threads since we got a lock
+ Note that this can only happen if we are not searching after an
+ exact key, because the keys are sorted according to position
+ */
+
+ if (_ma_search_next(info, keyinfo, info->lastkey,
+ info->lastkey_length,
+ maria_readnext_vec[search_flag],
+ info->s->state.key_root[inx]))
+ {
+ info->cur_row.lastpos= HA_OFFSET_ERROR;
+ break;
+ }
+ }
}
}
}
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;
@@ -150,6 +167,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 09861c03c32..859f0da9b51 100644
--- a/storage/maria/ma_rsamepos.c
+++ b/storage/maria/ma_rsamepos.c
@@ -28,29 +28,31 @@
** 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));
- if (inx < -1 || (inx >= 0 && !maria_is_key_active(info->s->state.key_map, inx)))
+ if (inx < -1 ||
+ (inx >= 0 && !maria_is_key_active(info->s->state.key_map, inx)))
{
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
}
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 5ae23c37261..3859bd96149 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -44,31 +44,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,
@@ -96,27 +96,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;
}
@@ -124,7 +124,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);
@@ -152,8 +152,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))
@@ -230,7 +230,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;
}
}
@@ -251,7 +251,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)
{
@@ -260,7 +260,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])))
{
@@ -277,7 +277,7 @@ static ha_rows NEAR_F find_all_keys(MARIA_SORT_PARAM *info, uint keys,
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;
}
@@ -308,7 +308,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);
@@ -336,7 +336,6 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
my_b_clear(&info->tempfile_for_exceptions);
bzero((char*) &info->buffpek,sizeof(info->buffpek));
bzero((char*) &info->unique, sizeof(info->unique));
- sort_keys= (uchar **) NULL;
memavl=max(info->sortbuff_size, MIN_SORT_MEMORY);
idx= info->sort_info->max_records;
@@ -365,15 +364,15 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
}
while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
}
- if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
- ((info->keyinfo->flag & HA_FULLTEXT) ?
- HA_FT_MAXBYTELEN : 0), MYF(0))))
+ if ((sort_keys=(byte**) my_malloc(keys*(sort_length+sizeof(char*))+
+ ((info->keyinfo->flag & HA_FULLTEXT) ?
+ HA_FT_MAXBYTELEN : 0), MYF(0))))
{
if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK),
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;
@@ -393,7 +392,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
info->sort_keys=sort_keys;
idx=error=0;
- sort_keys[0]=(uchar*) (sort_keys+keys);
+ sort_keys[0]=(byte*) (sort_keys+keys);
while (!(error=info->sort_info->got_error) &&
!(error=(*info->key_read)(info,sort_keys[idx])))
@@ -411,7 +410,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
(BUFFPEK *)alloc_dynamic(&info->buffpek),
&info->tempfile))
goto err;
- 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;
}
@@ -422,7 +421,8 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
if (info->buffpek.elements)
{
if (info->write_keys(info,sort_keys, idx,
- (BUFFPEK *) alloc_dynamic(&info->buffpek), &info->tempfile))
+ (BUFFPEK *) alloc_dynamic(&info->buffpek),
+ &info->tempfile))
goto err;
info->keys=(info->buffpek.elements-1)*(keys-1)+idx;
}
@@ -434,8 +434,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
err:
info->sort_info->got_error=1; /* no need to protect this with a mutex */
- if (sort_keys)
- my_free((gptr) sort_keys,MYF(0));
+ my_free((gptr) sort_keys, MYF(MY_ALLOW_ZERO_PTR));
info->sort_keys=0;
delete_dynamic(& info->buffpek);
close_cached_file(&info->tempfile);
@@ -499,8 +498,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
}
}
my_free((gptr) sinfo->sort_keys,MYF(0));
- 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));
sinfo->sort_keys=0;
}
@@ -548,7 +546,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))
{
@@ -564,7 +562,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) ||
@@ -596,7 +594,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;
}
@@ -607,12 +605,14 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
}
#endif /* THREAD */
- /* Write all keys in memory to file for later merge */
-static int NEAR_F write_keys(MARIA_SORT_PARAM *info, register uchar **sort_keys,
+/* Write all keys in memory to file for later merge */
+
+static int NEAR_F 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");
@@ -628,7 +628,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);
@@ -639,7 +639,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))))
@@ -651,11 +651,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");
@@ -670,14 +670,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;
@@ -688,8 +688,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 */
@@ -697,7 +697,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");
@@ -706,7 +707,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);
@@ -716,7 +717,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;
@@ -797,11 +798,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++)
{
@@ -855,18 +856,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;
@@ -874,7 +874,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,
@@ -923,7 +923,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));
@@ -955,7 +955,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
{
@@ -969,21 +969,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)
@@ -997,7 +997,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");
@@ -1007,8 +1007,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 0aef24f40a9..11049d6f279 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 840ecb2eeb7..6d54a078f25 100644
--- a/storage/maria/ma_test2.c
+++ b/storage/maria/ma_test2.c
@@ -38,7 +38,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);
@@ -46,10 +47,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;
@@ -201,16 +203,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))
@@ -230,12 +230,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))
{
@@ -257,7 +258,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)
@@ -270,7 +271,8 @@ int main(int argc, char *argv[])
}
}
}
- if (testflag==1) goto end;
+ if (testflag == 1)
+ goto end;
if (write_cacheing)
{
@@ -285,6 +287,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--) ;
@@ -296,6 +300,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))
@@ -310,10 +320,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);
@@ -330,10 +343,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);
}
@@ -395,10 +417,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;
@@ -588,13 +612,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 ;)
@@ -602,7 +637,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;
}
}
@@ -716,12 +751,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;
}
@@ -743,7 +780,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");
@@ -752,8 +790,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)
@@ -767,7 +805,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;
@@ -783,9 +821,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;
}
}
}
@@ -793,6 +832,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++;
@@ -800,6 +840,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)
@@ -851,8 +892,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:
@@ -864,8 +904,7 @@ err:
} /* main */
- /* l{ser optioner */
- /* OBS! intierar endast DEBUG - ingen debuggning h{r ! */
+/* Read options */
static void get_options(int argc, char **argv)
{
@@ -879,7 +918,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;
@@ -896,7 +937,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;
@@ -910,9 +951,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;
@@ -943,6 +984,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;
@@ -954,6 +998,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;
@@ -973,7 +1018,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);
@@ -1010,7 +1055,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)
@@ -1028,10 +1074,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 96b896b03c6..4911d13f2f1 100644
--- a/storage/maria/ma_test3.c
+++ b/storage/maria/ma_test3.c
@@ -97,8 +97,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 f857127dca9..17e654ac51f 100755
--- a/storage/maria/ma_test_all.sh
+++ b/storage/maria/ma_test_all.sh
@@ -5,143 +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
-./maria_chk$suffix -es 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
+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 -l
-./maria_log$suffix
-./ma_test2$suffix $silent -L -K -W -P -m50 -l -b100
-./maria_log$suffix
+#
+# 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 bc1aa71966b..8348bfbd84b 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,
memcmp((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 248b17ce2c9..c86ebd16c6f 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);
VOID(_ma_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0));
allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0)
@@ -184,8 +195,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 24768b36c89..a4fe5506c8e 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)
{
@@ -162,8 +189,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)
@@ -207,14 +236,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);
@@ -223,7 +259,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");
@@ -242,7 +278,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;
@@ -275,15 +311,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);
@@ -292,7 +330,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;
@@ -302,11 +340,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);
@@ -322,21 +360,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",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))
@@ -351,9 +389,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)
{
@@ -373,7 +411,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;
@@ -392,7 +430,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);
@@ -447,25 +485,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",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
@@ -478,7 +516,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: %lx",
+ DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: 0x%lx",
s_temp.n_ref_length,s_temp.n_length,s_temp.key));
}
#endif
@@ -517,19 +555,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 *)
@@ -570,11 +609,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");
@@ -582,7 +621,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)
@@ -614,8 +653,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,
@@ -638,12 +677,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;
@@ -672,24 +711,25 @@ uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
} while (page < end);
*return_key_length=length;
*after_key=page;
- DBUG_PRINT("exit",("returns: %lx page: %lx half: %lx",lastpos,page,end));
+ DBUG_PRINT("exit",("returns: 0x%lx page: 0x%lx half: 0x%lx",
+ lastpos, page, end));
DBUG_RETURN(lastpos);
} /* _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;
@@ -727,7 +767,8 @@ static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
}
*return_key_length=last_length;
*after_key=lastpos;
- DBUG_PRINT("exit",("returns: %lx page: %lx end: %lx",prevpos,page,end));
+ DBUG_PRINT("exit",("returns: 0x%lx page: 0x%lx end: 0x%lx",
+ prevpos, page, end));
DBUG_RETURN(prevpos);
} /* _ma_find_last_pos */
@@ -736,14 +777,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");
@@ -880,7 +921,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;
@@ -896,22 +938,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 e423a3f5c36..8ea00fa9776 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -36,21 +36,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 ",
@@ -59,23 +61,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;
@@ -88,7 +97,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);
@@ -98,7 +107,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));
@@ -112,7 +121,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));
@@ -134,7 +143,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);
@@ -218,7 +227,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},
@@ -259,7 +268,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.",
@@ -346,7 +355,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);
}
@@ -381,7 +390,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\
@@ -390,10 +399,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\
@@ -419,7 +428,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\
@@ -436,7 +445,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\
@@ -684,7 +693,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':
@@ -700,6 +709,7 @@ get_one_option(int optid,
{
int method;
enum_handler_stats_method method_conv;
+ LINT_INIT(method_conv);
maria_stats_method_str= argument;
if ((method=find_type(argument, &maria_stats_method_typelib, 2)) <= 0)
{
@@ -778,10 +788,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)
@@ -796,17 +806,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;
@@ -849,7 +858,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'",
@@ -862,7 +872,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:
@@ -871,7 +892,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 |
@@ -969,6 +991,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;
}
/*
@@ -989,7 +1012,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)
{
@@ -1032,8 +1056,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 */
@@ -1112,8 +1135,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);
@@ -1163,12 +1185,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)
@@ -1195,10 +1216,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)
{
@@ -1212,14 +1233,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);
@@ -1260,25 +1275,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 */
@@ -1286,14 +1294,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));
@@ -1303,13 +1311,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);
@@ -1417,7 +1425,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)
@@ -1446,8 +1454,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)
@@ -1475,7 +1484,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];
@@ -1532,7 +1541,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;
@@ -1544,14 +1553,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'",
@@ -1568,7 +1574,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)))
@@ -1589,7 +1595,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))
@@ -1626,8 +1633,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)
{
@@ -1644,17 +1650,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;
@@ -1665,7 +1671,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);
@@ -1679,7 +1685,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)))
@@ -1688,7 +1694,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;
}
@@ -1699,7 +1706,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;
@@ -1738,7 +1745,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 ecd93807a06..778c5817e4f 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 */
@@ -70,7 +71,7 @@ typedef struct st_maria_state_info
ulong status;
ulong *rec_per_key_part;
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 */
@@ -91,60 +92,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;
@@ -155,6 +169,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
@@ -175,28 +209,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;
- 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 */
@@ -208,21 +250,24 @@ 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;
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;
@@ -237,45 +282,106 @@ typedef struct st_maria_bit_buff
uint error;
} MARIA_BIT_BUFF;
+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;
/*
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 */
@@ -298,19 +404,19 @@ 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;
- 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 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
@@ -361,15 +467,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; } \
}
@@ -398,7 +504,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 */
@@ -428,85 +533,88 @@ 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[];
/* 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);
@@ -514,74 +622,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,
@@ -592,11 +695,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, byte *to, byte *from,
ulong reclength);
extern ulonglong _ma_safe_mul(ulonglong a, ulonglong b);
@@ -613,9 +718,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;
@@ -672,11 +777,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);
@@ -690,14 +794,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);
@@ -711,6 +815,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 b840072aed0..0faa64327eb 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 c5a53b1ffac..e4e38cb6e9d 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)
@@ -1109,14 +1102,14 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
DBUG_PRINT("info", ("column: %3lu", count - huff_counts + 1));
if (verbose >= 2)
- VOID(printf("column: %3lu\n", count - huff_counts + 1));
+ VOID(printf("column: %3u\n", count - huff_counts + 1));
if (count->tree_buff)
{
DBUG_PRINT("info", ("number of distinct values: %lu",
(count->tree_pos - count->tree_buff) /
count->field_length));
if (verbose >= 2)
- VOID(printf("number of distinct values: %lu\n",
+ VOID(printf("number of distinct values: %u\n",
(count->tree_pos - count->tree_buff) /
count->field_length));
}
@@ -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,
@@ -2281,7 +2275,7 @@ static my_off_t write_huff_tree(HUFF_TREE *huff_tree, uint trees)
if (bits > 8 * sizeof(code))
{
VOID(fflush(stdout));
- VOID(fprintf(stderr, "error: Huffman code too long: %u/%lu\n",
+ VOID(fprintf(stderr, "error: Huffman code too long: %u/%u\n",
bits, 8 * sizeof(code)));
errors++;
break;
@@ -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));
@@ -2934,7 +2939,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;
@@ -2944,6 +2950,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;
@@ -2962,14 +2970,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;
@@ -3037,21 +3044,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);
@@ -3060,6 +3064,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);
}
}
@@ -3068,11 +3074,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);
}