mariadb/storage/maria/ma_rt_test.c
unknown 496741d576 Moved randomize and my_rnd under mysys
Added my_uuid
Added pre-support for PAGE_CHECKSUM
Added syntax for CREATE ... PAGE_CHECKSUM=# TABLE_CHECKSUM=#
Reserved place for page checksums on index, bitmap and block pages
Added index number to header of index pages
Added linked list for free directory entries (speeds up inserts with BLOCK format)
Calculate checksums in original column order (fixes bug with checksum on rows with BLOCK format)
Cleaned up all index handling to use 'info->s->keypage_header' (variable size) as the header for index pages (before this was '2')
Added 0xffffffff to end of index and block data bases and 0xfffffffe at end of bitmap pages when page checksums are not enabled
Added _ma_get_page_used() and _ma_get_used_and_node() to simplify index page header handling
rec_per_key_part is now in double precision
Reserved place in index file for my_guid and nulls_per_key_part
Give error HA_ERR_NEW_FILE if trying to open a Maria file with new, not yet supported extensions

Lots of renames to increase readability:

randomize() -> my_rnd_init()
st_maria_info -> st_maria_handler
st_maria_info -> MARIA_HA
st_maria_isaminfo -> st_maria_info
rand_struct -> my_rand_struct
rec_per_key_rows -> records_at_analyze


client/mysqladmin.cc:
  rand_struct -> my_rrnd_struct
include/maria.h:
  st_maria_info -> MARIA_HA
  st_maria_isaminfo -> st_maria_info
  Changed analyze statistics to be of double precission
  Changed offset to field to be 32bits instead of 64 (safe as a record without blobs can't be that big)
include/my_base.h:
  Added HA_OPTION_PAGE_CHECKSUM & HA_CREATE_PAGE_CHECKSUM
  Fixed comments
  Added HA_ERR_NEW_FILE
include/my_sys.h:
  Added prototypes and structures for my_uuid() and my_rnd()
include/myisamchk.h:
  Changed some buffers to size_t
  Added possibility to have key statistics with double precission
include/mysql_com.h:
  Move rand functions to mysys
libmysql/Makefile.shared:
  Added my_rnd
mysql-test/r/maria.result:
  Updated results
mysql-test/t/maria.test:
  More tests for checksum
mysys/Makefile.am:
  Added my_rnd.c and my_uuid.c
server-tools/instance-manager/listener.cc:
  Fixed include order (my_global.h should always be first)
server-tools/instance-manager/mysql_connection.cc:
  Fixed include order (my_global.h should always be first)
  Use my_rnd_init()
server-tools/instance-manager/mysql_connection.h:
  rand_struct -> my_rand_struct
sql/handler.h:
  Added flag for page checksums
sql/item_func.cc:
  Use new my_rnd() interface
sql/item_func.h:
  Use new my_rnd() interface
sql/item_strfunc.cc:
  Use new my_rnd() interface
sql/lex.h:
  Added PAGE_CHECKSUM and TABLE_CHECKSUM
sql/mysql_priv.h:
  Use new my_rnd() interface
sql/mysqld.cc:
  Use new my_rnd() interface
sql/password.c:
  Move my_rnd() to mysys
  Use new my_rnd() interface
sql/sql_class.cc:
  Use new my_rnd() interface
sql/sql_class.h:
  Use new my_rnd() interface
sql/sql_crypt.cc:
  Use new my_rnd() interface
sql/sql_crypt.h:
  Use new my_rnd() interface
sql/sql_show.cc:
  Simpler handling of ha_choice_values
  Added PAGE_CHECKSUM
sql/sql_table.cc:
  Enable correct checksum handling (for now) if not running in compatible mode
sql/sql_yacc.yy:
  Added table option PAGE_CHECKSUM
  Added future compatible table option TABLE_CHECKSUM (alias for CHECKSUM)
  Added 'choice' target to simplify code
sql/table.cc:
  Store flag for PAGE_CHECKSUM
sql/table.h:
  Added support for PAGE_CHECKSUM
storage/maria/ha_maria.cc:
  Remove protection for incompatbile frm and MAI
  (Slow, not needed test)
  Rec_per_key is now in double
  Remember row type for table
  Give warning if one Maria uses another row type than requested
  Removed some old ASK_MONTY entries (added comments instead)
  Added handling of PAGE_CHECKSUM flags
storage/maria/ma_bitmap.c:
  Added page checksums to bitmap pages
  Added special bitmap marker for bitmap pages
  (Used to find bugs when running without page checksums)
storage/maria/ma_blockrec.c:
  Added a free-link list over directory entries. This makes insert of small rows faster as we don't
  have to scan the whole directory to find a not used entry.
  Moved SANITY_CHECKS to maria_def.h
  Simplify code by introducing dir_entry_pos()
  Added support for PAGE_CHECKSUM
storage/maria/ma_blockrec.h:
  Added DIR_FREE_SIZE (linked list of free directory entries)
  Added PAGE_CHECKSUM
  Added 'dir_entry_pos()'
storage/maria/ma_check.c:
  Check that index pages has correct index number
  Calculate rec_per_key with double precission
  Simplify code by using '_ma_get_used_and_node()'
  Check free directory list
  Remove wrong end \n from messages
  maria_data_on_page() -> _ma_get_page_used()
  maria_putint() -> _ma_store_page_used()
  rec_per_key_rows -> records_at_analyze
storage/maria/ma_checksum.c:
  Calculate checksum in original column order
storage/maria/ma_create.c:
  Store original column order in index file
  Reserve place for nulls_per_key_part (future)
  Added support for PAGE_CHECKSUM
storage/maria/ma_dbug.c:
  Fixed wrong debug output of key of type 'ulong'
storage/maria/ma_delete.c:
  maria_data_on_page() -> _ma_get_used_and_node()
  maria_data_on_page() -> _ma_get_page_used()
  maria_putint() -> _ma_store_page_used()
  Added page header (index key number) to all index pages
  Reserved page for checksum on index pages
  Use keypage_header
storage/maria/ma_ft_update.c:
  maria_putint() -> _ma_store_page_used()
  Store key number at start of page
storage/maria/ma_loghandler.h:
  st_maria_info -> MARIA_HA
storage/maria/ma_open.c:
  rec_per_key is now in double precission
  Added 'nulls_per_key_part'
  Added 'extra_options' (flags for future)
  Added support for PAGE_CHECKSUM
  Give error HA_ERR_NEW_FILE when using unsupported maria extensions
  Added comments
  Add maria_uuid to index file
  Added functions to store and read column_nr map.
  Changed some functions to return my_bool instead of uint
storage/maria/ma_page.c:
  Added checks that pages has correct key nr
  Store 0xffffffff in checksum position if page checksums are not enabled
  Moved key-page-delete link to take into account keypage header
storage/maria/ma_preload.c:
  Remove old MyISAM dependent code
  When scanning pages, only add pages to page cache for the requested index
storage/maria/ma_range.c:
  maria_data_on_page() -> _ma_get_used_and_node()
  Use keypage_header
storage/maria/ma_rt_index.c:
  Fixed indentation
storage/maria/ma_rt_index.h:
  Added support for dynamic index page header
  Reserved place for PAGE_CHECKSUM
storage/maria/ma_rt_key.c:
  Fixed indentation
  maria_data_on_page() -> _ma_get_page_used()
  maria_putint() -> maria_store_page_used()
storage/maria/ma_rt_mbr.c:
  Fixed indentation
storage/maria/ma_rt_split.c:
  Fixed indentation
  maria_data_on_page () -> _ma_get_page_used()
storage/maria/ma_rt_test.c:
  Fixed indentation
storage/maria/ma_search.c:
  Remove support of using -1 as 'last used index' to _ma_check_index()
  maria_data_on_page() -> _ma_get_page_used()
  maria_data_on_page() -> _ma_get_used_and_node()
  Use keypage_header
storage/maria/ma_sort.c:
  Changed some buffers to size_t
  Changed rec_per_key_part to double
storage/maria/ma_static.c:
  Removed NEAR
  Added maria_uuid
storage/maria/ma_test2.c:
  Moevd testflag == 2 to correct place
  Remove test of reading with index number -1 (not supported anymore)
storage/maria/ma_test_recovery.expected:
  Updated results
storage/maria/ma_test_recovery:
  Changed tmp table names so that one can run maria_chk on them
storage/maria/ma_write.c:
  Fixed indentation
  Use keypage_header
  Store index number on index pages
  maria_putint() -> _ma_store_page_used()
  maria_data_on_page() -> ma_get_used_and_node()
  maria_data_on_page() -> _ma_get_page_used()
  Added PAGE_CHECKSUM
  Added Maria handler to some functions
  Removed some not needed casts
storage/maria/maria_chk.c:
  Added error handling for HA_ERR_NEW_FILE
  Added information about page checksums
  rec_per_key_part changed to double
  maria_data_on_page() -> _ma_get_page_used()
  Use keypage_header
storage/maria/maria_def.h:
  Added IDENTICAL_PAGES_AFTER_RECOVERY and SANITY_CHECKS
  Changed rec_per_key_part to double
  Added nulls_per_key_part
  rec_per_key_rows -> records_at_analyze
  st_maria_info -> MARIA_HA
  Reserve place for new statistics variables, uuid, checksums per page etc.
  Removed NEAR tags
  Changed some prototypes to use my_bool and size_t
storage/maria/maria_pack.c:
  st_maria_info -> MARIA_HA
  Fixed indentation
storage/myisam/mi_dbug.c:
  Fix wrong debug output for ULONG
mysys/my_rnd.c:
  New BitKeeper file ``mysys/my_rnd.c''
mysys/my_uuid.c:
  New BitKeeper file ``mysys/my_uuid.c''
2007-10-09 21:09:50 +03:00

475 lines
11 KiB
C

/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
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; version 2 of the License.
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 */
/* Testing of the basic functions of a MARIA rtree table */
/* Written by Alex Barkov who has a shared copyright to this code */
#include "maria.h"
#ifdef HAVE_RTREE_KEYS
#include "ma_rt_index.h"
#define MAX_REC_LENGTH 1024
#define ndims 2
#define KEYALG HA_KEY_ALG_RTREE
static int read_with_pos(MARIA_HA * file, int silent);
static void create_record(char *record,uint rownr);
static void create_record1(char *record,uint rownr);
static void print_record(char * record,my_off_t offs,const char * tail);
static int run_test(const char *filename);
static double rt_data[]=
{
/*1*/ 0,10,0,10,
/*2*/ 5,15,0,10,
/*3*/ 0,10,5,15,
/*4*/ 10,20,10,20,
/*5*/ 0,10,0,10,
/*6*/ 5,15,0,10,
/*7*/ 0,10,5,15,
/*8*/ 10,20,10,20,
/*9*/ 0,10,0,10,
/*10*/ 5,15,0,10,
/*11*/ 0,10,5,15,
/*12*/ 10,20,10,20,
/*13*/ 0,10,0,10,
/*14*/ 5,15,0,10,
/*15*/ 0,10,5,15,
/*16*/ 10,20,10,20,
/*17*/ 5,15,0,10,
/*18*/ 0,10,5,15,
/*19*/ 10,20,10,20,
/*20*/ 0,10,0,10,
/*1*/ 100,110,0,10,
/*2*/ 105,115,0,10,
/*3*/ 100,110,5,15,
/*4*/ 110,120,10,20,
/*5*/ 100,110,0,10,
/*6*/ 105,115,0,10,
/*7*/ 100,110,5,15,
/*8*/ 110,120,10,20,
/*9*/ 100,110,0,10,
/*10*/ 105,115,0,10,
/*11*/ 100,110,5,15,
/*12*/ 110,120,10,20,
/*13*/ 100,110,0,10,
/*14*/ 105,115,0,10,
/*15*/ 100,110,5,15,
/*16*/ 110,120,10,20,
/*17*/ 105,115,0,10,
/*18*/ 100,110,5,15,
/*19*/ 110,120,10,20,
/*20*/ 100,110,0,10,
-1
};
int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
{
MY_INIT(argv[0]);
maria_init();
exit(run_test("rt_test"));
}
static int run_test(const char *filename)
{
MARIA_HA *file;
MARIA_UNIQUEDEF uniquedef;
MARIA_CREATE_INFO create_info;
MARIA_COLUMNDEF recinfo[20];
MARIA_KEYDEF keyinfo[20];
HA_KEYSEG keyseg[20];
key_range range;
int silent=0;
int opt_unique=0;
int create_flag=0;
int key_type=HA_KEYTYPE_DOUBLE;
int key_length=8;
int null_fields=0;
int nrecords=sizeof(rt_data)/(sizeof(double)*4);/* 3000;*/
int rec_length=0;
int uniques=0;
int i;
int error;
int row_count=0;
char record[MAX_REC_LENGTH];
char read_record[MAX_REC_LENGTH];
int upd= 10;
ha_rows hrows;
/* Define a column for NULLs and DEL markers*/
recinfo[0].type=FIELD_NORMAL;
recinfo[0].length=1; /* For NULL bits */
rec_length=1;
/* Define 2*ndims columns for coordinates*/
for (i=1; i<=2*ndims ;i++)
{
recinfo[i].type=FIELD_NORMAL;
recinfo[i].length=key_length;
rec_length+=key_length;
}
/* Define a key with 2*ndims segments */
keyinfo[0].seg=keyseg;
keyinfo[0].keysegs=2*ndims;
keyinfo[0].flag=0;
keyinfo[0].key_alg=KEYALG;
for (i=0; i<2*ndims; i++)
{
keyinfo[0].seg[i].type= key_type;
keyinfo[0].seg[i].flag=0; /* Things like HA_REVERSE_SORT */
keyinfo[0].seg[i].start= (key_length*i)+1;
keyinfo[0].seg[i].length=key_length;
keyinfo[0].seg[i].null_bit= null_fields ? 2 : 0;
keyinfo[0].seg[i].null_pos=0;
keyinfo[0].seg[i].language=default_charset_info->number;
}
if (!silent)
printf("- Creating isam-file\n");
bzero((char*) &create_info,sizeof(create_info));
create_info.max_rows=10000000;
if (maria_create(filename,
DYNAMIC_RECORD,
1, /* keys */
keyinfo,
1+2*ndims+opt_unique, /* columns */
recinfo,uniques,&uniquedef,&create_info,create_flag))
goto err;
if (!silent)
printf("- Open isam-file\n");
if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
goto err;
if (!silent)
printf("- Writing key:s\n");
for (i=0; i<nrecords; i++ )
{
create_record(record,i);
error=maria_write(file,record);
print_record(record,maria_position(file),"\n");
if (!error)
{
row_count++;
}
else
{
printf("maria_write: %d\n", error);
goto err;
}
}
if ((error=read_with_pos(file,silent)))
goto err;
if (!silent)
printf("- Reading rows with key\n");
for (i=0 ; i < nrecords ; i++)
{
my_errno=0;
create_record(record,i);
bzero((char*) read_record,MAX_REC_LENGTH);
error=maria_rkey(file,read_record,0,record+1,0,HA_READ_MBR_EQUAL);
if (error && error!=HA_ERR_KEY_NOT_FOUND)
{
printf(" maria_rkey: %3d errno: %3d\n",error,my_errno);
goto err;
}
if (error == HA_ERR_KEY_NOT_FOUND)
{
print_record(record,maria_position(file)," NOT FOUND\n");
continue;
}
print_record(read_record,maria_position(file),"\n");
}
if (!silent)
printf("- Deleting rows\n");
for (i=0; i < nrecords/4; i++)
{
my_errno=0;
bzero((char*) read_record,MAX_REC_LENGTH);
error=maria_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
if (error)
{
printf("pos: %2d maria_rrnd: %3d errno: %3d\n",i,error,my_errno);
goto err;
}
print_record(read_record,maria_position(file),"\n");
error=maria_delete(file,read_record);
if (error)
{
printf("pos: %2d maria_delete: %3d errno: %3d\n",i,error,my_errno);
goto err;
}
}
if (!silent)
printf("- Updating rows with position\n");
for (i=0; i < (nrecords - nrecords/4) ; i++)
{
my_errno=0;
bzero((char*) read_record,MAX_REC_LENGTH);
error=maria_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
if (error)
{
if (error==HA_ERR_RECORD_DELETED)
continue;
printf("pos: %2d maria_rrnd: %3d errno: %3d\n",i,error,my_errno);
goto err;
}
print_record(read_record,maria_position(file),"");
create_record(record,i+nrecords*upd);
printf("\t-> ");
print_record(record,maria_position(file),"\n");
error=maria_update(file,read_record,record);
if (error)
{
printf("pos: %2d maria_update: %3d errno: %3d\n",i,error,my_errno);
goto err;
}
}
if ((error=read_with_pos(file,silent)))
goto err;
if (!silent)
printf("- Test maria_rkey then a sequence of maria_rnext_same\n");
create_record(record, nrecords*4/5);
print_record(record,0," search for\n");
if ((error=maria_rkey(file,read_record,0,record+1,0,HA_READ_MBR_INTERSECT)))
{
printf("maria_rkey: %3d errno: %3d\n",error,my_errno);
goto err;
}
print_record(read_record,maria_position(file)," maria_rkey\n");
row_count=1;
for (;;)
{
if ((error=maria_rnext_same(file,read_record)))
{
if (error==HA_ERR_END_OF_FILE)
break;
printf("maria_next: %3d errno: %3d\n",error,my_errno);
goto err;
}
print_record(read_record,maria_position(file)," maria_rnext_same\n");
row_count++;
}
printf(" %d rows\n",row_count);
if (!silent)
printf("- Test maria_rfirst then a sequence of maria_rnext\n");
error=maria_rfirst(file,read_record,0);
if (error)
{
printf("maria_rfirst: %3d errno: %3d\n",error,my_errno);
goto err;
}
row_count=1;
print_record(read_record,maria_position(file)," maria_frirst\n");
for (i=0;i<nrecords;i++)
{
if ((error=maria_rnext(file,read_record,0)))
{
if (error==HA_ERR_END_OF_FILE)
break;
printf("maria_next: %3d errno: %3d\n",error,my_errno);
goto err;
}
print_record(read_record,maria_position(file)," maria_rnext\n");
row_count++;
}
printf(" %d rows\n",row_count);
if (!silent)
printf("- Test maria_records_in_range()\n");
create_record1(record, nrecords*4/5);
print_record(record,0,"\n");
range.key= record+1;
range.length= 1000; /* Big enough */
range.flag= HA_READ_MBR_INTERSECT;
hrows= maria_records_in_range(file,0, &range, (key_range*) 0);
printf(" %ld rows\n", (long) hrows);
if (maria_close(file)) goto err;
maria_end();
my_end(MY_CHECK_ERROR);
return 0;
err:
printf("got error: %3d when using maria-database\n",my_errno);
return 1; /* skip warning */
}
static int read_with_pos (MARIA_HA * file,int silent)
{
int error;
int i;
char read_record[MAX_REC_LENGTH];
if (!silent)
printf("- Reading rows with position\n");
for (i=0;;i++)
{
my_errno=0;
bzero((char*) read_record,MAX_REC_LENGTH);
error=maria_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR);
if (error)
{
if (error==HA_ERR_END_OF_FILE)
break;
if (error==HA_ERR_RECORD_DELETED)
continue;
printf("pos: %2d maria_rrnd: %3d errno: %3d\n",i,error,my_errno);
return error;
}
print_record(read_record,maria_position(file),"\n");
}
return 0;
}
#ifdef NOT_USED
static void bprint_record(char * record,
my_off_t offs __attribute__((unused)),
const char * tail)
{
int i;
char * pos;
i=(unsigned char)record[0];
printf("%02X ",i);
for( pos=record+1, i=0; i<32; i++,pos++){
int b=(unsigned char)*pos;
printf("%02X",b);
}
printf("%s",tail);
}
#endif
static void print_record(char * record,
my_off_t offs __attribute__((unused)),
const char * tail)
{
int i;
char * pos;
double c;
printf(" rec=(%d)",(unsigned char)record[0]);
for ( pos=record+1, i=0; i<2*ndims; i++)
{
memcpy(&c,pos,sizeof(c));
float8get(c,pos);
printf(" %.14g ",c);
pos+=sizeof(c);
}
printf("pos=%ld",(long int)offs);
printf("%s",tail);
}
static void create_record1(char *record,uint rownr)
{
int i;
char * pos;
double c=rownr+10;
bzero((char*) record,MAX_REC_LENGTH);
record[0]=0x01; /* DEL marker */
for ( pos=record+1, i=0; i<2*ndims; i++)
{
memcpy(pos,&c,sizeof(c));
float8store(pos,c);
pos+=sizeof(c);
}
}
#ifdef NOT_USED
static void create_record0(char *record,uint rownr)
{
int i;
char * pos;
double c=rownr+10;
double c0=0;
bzero((char*) record,MAX_REC_LENGTH);
record[0]=0x01; /* DEL marker */
for ( pos=record+1, i=0; i<ndims; i++)
{
memcpy(pos,&c0,sizeof(c0));
float8store(pos,c0);
pos+=sizeof(c0);
memcpy(pos,&c,sizeof(c));
float8store(pos,c);
pos+=sizeof(c);
}
}
#endif
static void create_record(char *record,uint rownr)
{
int i;
char *pos;
double *data= rt_data+rownr*4;
record[0]=0x01; /* DEL marker */
for ( pos=record+1, i=0; i<ndims*2; i++)
{
float8store(pos,data[i]);
pos+=8;
}
}
#else
int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
{
exit(0);
}
#endif /*HAVE_RTREE_KEYS*/