LTP GCOV extension - code coverage report
Current view: directory - storage/maria - ma_test1.c
Test: mtr_and_unit.info
Date: 2009-03-05 Instrumented lines: 407
Code covered: 86.2 % Executed lines: 351

       1                 : /* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
       2                 : 
       3                 :    This program is free software; you can redistribute it and/or modify
       4                 :    it under the terms of the GNU General Public License as published by
       5                 :    the Free Software Foundation; version 2 of the License.
       6                 : 
       7                 :    This program is distributed in the hope that it will be useful,
       8                 :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9                 :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10                 :    GNU General Public License for more details.
      11                 : 
      12                 :    You should have received a copy of the GNU General Public License
      13                 :    along with this program; if not, write to the Free Software
      14                 :    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
      15                 : 
      16                 : /* Testing of the basic functions of a MARIA table */
      17                 : 
      18                 : #include "maria_def.h"
      19                 : #include <my_getopt.h>
      20                 : #include <m_string.h>
      21                 : #include "ma_control_file.h"
      22                 : #include "ma_loghandler.h"
      23                 : #include "ma_checkpoint.h"
      24                 : #include "trnman.h"
      25                 : 
      26                 : extern PAGECACHE *maria_log_pagecache;
      27                 : extern char *maria_data_root;
      28                 : 
      29                 : #define MAX_REC_LENGTH 1024
      30                 : 
      31                 : static void usage();
      32                 : 
      33                 : static int rec_pointer_size=0, flags[50], testflag, checkpoint;
      34                 : static int key_field=FIELD_SKIP_PRESPACE,extra_field=FIELD_SKIP_ENDSPACE;
      35                 : static int key_type=HA_KEYTYPE_NUM;
      36                 : static int create_flag=0;
      37                 : static ulong blob_length;
      38                 : static enum data_file_type record_type= DYNAMIC_RECORD;
      39                 : 
      40                 : static uint insert_count, update_count, remove_count;
      41                 : static uint pack_keys=0, pack_seg=0, key_length;
      42                 : static uint unique_key=HA_NOSAME;
      43                 : static uint die_in_middle_of_transaction;
      44                 : static my_bool pagecacheing, null_fields, silent, skip_update, opt_unique;
      45                 : static my_bool verbose, skip_delete, transactional;
      46                 : static my_bool opt_versioning= 0;
      47                 : static MARIA_COLUMNDEF recinfo[4];
      48                 : static MARIA_KEYDEF keyinfo[10];
      49                 : static HA_KEYSEG keyseg[10];
      50                 : static HA_KEYSEG uniqueseg[10];
      51                 : 
      52                 : static int run_test(const char *filename);
      53                 : static void get_options(int argc, char *argv[]);
      54                 : static void create_key(uchar *key,uint rownr);
      55                 : static void create_record(uchar *record,uint rownr);
      56                 : static void update_record(uchar *record);
      57                 : 
      58                 : 
      59                 : /*
      60                 :   These are here only for testing of recovery with undo. We are not
      61                 :   including maria_def.h here as this test is also to be an example of
      62                 :   how to use maria outside of the maria directory
      63                 : */
      64                 : 
      65                 : extern int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
      66                 :                                  enum flush_type flush_type_for_data,
      67                 :                                  enum flush_type flush_type_for_index);
      68                 : #define MARIA_FLUSH_DATA  1
      69                 : 
      70                 : 
      71                 : int main(int argc,char *argv[])
      72             320 : {
      73                 : #if defined(SAFE_MUTEX) && defined(THREAD)
      74             320 :   safe_mutex_deadlock_detector= 1;
      75                 : #endif
      76             320 :   MY_INIT(argv[0]);
      77             320 :   get_options(argc,argv);
      78             320 :   maria_data_root= (char *)".";
      79                 :   /* Maria requires that we always have a page cache */
      80             320 :   if (maria_init() ||
      81                 :       (init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0,
      82                 :                       maria_block_size, MY_WME) == 0) ||
      83                 :       ma_control_file_open(TRUE, TRUE) ||
      84                 :       (init_pagecache(maria_log_pagecache,
      85                 :                       TRANSLOG_PAGECACHE_SIZE, 0, 0,
      86                 :                       TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
      87                 :       translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
      88                 :                     0, 0, maria_log_pagecache,
      89                 :                     TRANSLOG_DEFAULT_FLAGS, 0) ||
      90                 :       (transactional && (trnman_init(0) || ma_checkpoint_init(0))))
      91                 :   {
      92               0 :     fprintf(stderr, "Error in initialization\n");
      93               0 :     exit(1);
      94                 :   }
      95             320 :   if (opt_versioning)
      96              71 :     init_thr_lock();
      97                 : 
      98             320 :   exit(run_test("test1"));
      99                 : }
     100                 : 
     101                 : 
     102                 : static int run_test(const char *filename)
     103             320 : {
     104                 :   MARIA_HA *file;
     105             320 :   int i,j= 0,error,deleted,rec_length,uniques=0;
     106                 :   uint offset_to_key;
     107                 :   ha_rows found,row_count;
     108                 :   uchar record[MAX_REC_LENGTH],key[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH];
     109                 :   MARIA_UNIQUEDEF uniquedef;
     110                 :   MARIA_CREATE_INFO create_info;
     111                 : 
     112             320 :   if (die_in_middle_of_transaction)
     113              64 :     null_fields= 1;
     114                 : 
     115             320 :   bzero((char*) recinfo,sizeof(recinfo));
     116             320 :   bzero((char*) &create_info,sizeof(create_info));
     117                 : 
     118                 :   /* First define 2 columns */
     119             320 :   create_info.null_bytes= 1;
     120             320 :   recinfo[0].type= key_field;
     121             320 :   recinfo[0].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr :
     122                 :                       key_length);
     123             320 :   if (key_field == FIELD_VARCHAR)
     124              20 :     recinfo[0].length+= HA_VARCHAR_PACKLENGTH(key_length);
     125             320 :   recinfo[1].type=extra_field;
     126             320 :   recinfo[1].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : 24);
     127             320 :   if (extra_field == FIELD_VARCHAR)
     128              20 :     recinfo[1].length+= HA_VARCHAR_PACKLENGTH(recinfo[1].length);
     129             320 :   recinfo[1].null_bit= null_fields ? 2 : 0;
     130                 : 
     131             320 :   if (opt_unique)
     132                 :   {
     133              40 :     recinfo[2].type=FIELD_CHECK;
     134              40 :     recinfo[2].length=MARIA_UNIQUE_HASH_LENGTH;
     135                 :   }
     136             320 :   rec_length= recinfo[0].length + recinfo[1].length + recinfo[2].length +
     137                 :     create_info.null_bytes;
     138                 : 
     139             320 :   if (key_type == HA_KEYTYPE_VARTEXT1 &&
     140                 :       key_length > 255)
     141              15 :     key_type= HA_KEYTYPE_VARTEXT2;
     142                 : 
     143                 :   /* Define a key over the first column */
     144             320 :   keyinfo[0].seg=keyseg;
     145             320 :   keyinfo[0].keysegs=1;
     146             320 :   keyinfo[0].block_length= 0;                   /* Default block length */
     147             320 :   keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
     148             320 :   keyinfo[0].seg[0].type= key_type;
     149             320 :   keyinfo[0].seg[0].flag= pack_seg;
     150             320 :   keyinfo[0].seg[0].start=1;
     151             320 :   keyinfo[0].seg[0].length=key_length;
     152             320 :   keyinfo[0].seg[0].null_bit= null_fields ? 2 : 0;
     153             320 :   keyinfo[0].seg[0].null_pos=0;
     154             320 :   keyinfo[0].seg[0].language= default_charset_info->number;
     155             320 :   if (pack_seg & HA_BLOB_PART)
     156                 :   {
     157              74 :     keyinfo[0].seg[0].bit_start=4;              /* Length of blob length */
     158                 :   }
     159             320 :   keyinfo[0].flag = (uint8) (pack_keys | unique_key);
     160                 : 
     161             320 :   bzero((uchar*) flags,sizeof(flags));
     162             320 :   if (opt_unique)
     163                 :   {
     164                 :     uint start;
     165              40 :     uniques=1;
     166              40 :     bzero((char*) &uniquedef,sizeof(uniquedef));
     167              40 :     bzero((char*) uniqueseg,sizeof(uniqueseg));
     168              40 :     uniquedef.seg=uniqueseg;
     169              40 :     uniquedef.keysegs=2;
     170                 : 
     171                 :     /* Make a unique over all columns (except first NULL fields) */
     172             120 :     for (i=0, start=1 ; i < 2 ; i++)
     173                 :     {
     174              80 :       uniqueseg[i].start=start;
     175              80 :       start+=recinfo[i].length;
     176              80 :       uniqueseg[i].length=recinfo[i].length;
     177              80 :       uniqueseg[i].language= default_charset_info->number;
     178                 :     }
     179              40 :     uniqueseg[0].type= key_type;
     180              40 :     uniqueseg[0].null_bit= null_fields ? 2 : 0;
     181              40 :     uniqueseg[1].type= HA_KEYTYPE_TEXT;
     182              40 :     if (extra_field == FIELD_BLOB)
     183                 :     {
     184               0 :       uniqueseg[1].length=0;                    /* The whole blob */
     185               0 :       uniqueseg[1].bit_start=4;                 /* long blob */
     186               0 :       uniqueseg[1].flag|= HA_BLOB_PART;
     187                 :     }
     188              40 :     else if (extra_field == FIELD_VARCHAR)
     189                 :     {
     190               5 :       uniqueseg[1].flag|= HA_VAR_LENGTH_PART;
     191               5 :       uniqueseg[1].type= (HA_VARCHAR_PACKLENGTH(recinfo[1].length-1) == 1 ?
     192                 :                           HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2);
     193                 :     }
     194                 :   }
     195                 :   else
     196             280 :     uniques=0;
     197                 : 
     198             320 :   offset_to_key= test(null_fields);
     199             320 :   if (key_field == FIELD_BLOB || key_field == FIELD_VARCHAR)
     200              94 :     offset_to_key+= 2;
     201                 : 
     202             320 :   if (!silent)
     203               0 :     printf("- Creating maria file\n");
     204             320 :   create_info.max_rows=(ulong) (rec_pointer_size ?
     205                 :                                 (1L << (rec_pointer_size*8))/40 :
     206                 :                                 0);
     207             320 :   create_info.transactional= transactional;
     208             320 :   if (maria_create(filename, record_type, 1, keyinfo,2+opt_unique,recinfo,
     209                 :                 uniques, &uniquedef, &create_info,
     210                 :                 create_flag))
     211             320 :     goto err;
     212             320 :   if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
     213             320 :     goto err;
     214             320 :   if (!silent)
     215               0 :     printf("- Writing key:s\n");
     216                 : 
     217             320 :   if (maria_begin(file))
     218             320 :     goto err;
     219             320 :   if (opt_versioning)
     220              71 :     maria_versioning(file, 1);
     221             320 :   my_errno=0;
     222             320 :   row_count=deleted=0;
     223            8320 :   for (i=49 ; i>=1 ; i-=2 )
     224                 :   {
     225            8000 :     if (insert_count-- == 0)
     226                 :     {
     227               0 :       if (testflag)
     228               0 :         break;
     229               0 :       VOID(maria_close(file));
     230               0 :       exit(0);
     231                 :     }
     232            8000 :     j=i%25 +1;
     233            8000 :     create_record(record,j);
     234            8000 :     error=maria_write(file,record);
     235            8000 :     if (!error)
     236            8000 :       row_count++;
     237            8000 :     flags[j]=1;
     238            8000 :     if (verbose || error)
     239               0 :       printf("J= %2d  maria_write: %d  errno: %d\n", j,error,my_errno);
     240                 :   }
     241                 : 
     242             320 :   if (maria_commit(file) || maria_begin(file))
     243                 :     goto err;
     244                 : 
     245             320 :   if (checkpoint == 1 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
     246             320 :     goto err;
     247                 : 
     248             320 :   if (testflag == 1)
     249             304 :     goto end;
     250                 : 
     251                 :   /* Insert 2 rows with null values */
     252             304 :   if (null_fields)
     253                 :   {
     254             167 :     create_record(record,0);
     255             167 :     error=maria_write(file,record);
     256             167 :     if (!error)
     257             167 :       row_count++;
     258             167 :     if (verbose || error)
     259               0 :       printf("J= NULL  maria_write: %d  errno: %d\n", error,my_errno);
     260             167 :     error=maria_write(file,record);
     261             167 :     if (!error)
     262             167 :       row_count++;
     263             167 :     if (verbose || error)
     264               0 :       printf("J= NULL  maria_write: %d  errno: %d\n", error,my_errno);
     265             167 :     flags[0]=2;
     266                 :   }
     267                 : 
     268             304 :   if (checkpoint == 2 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
     269             304 :     goto err;
     270                 : 
     271             304 :   if (testflag == 2)
     272                 :   {
     273              32 :     printf("Terminating after inserts\n");
     274              32 :     goto end;
     275                 :   }
     276                 : 
     277             272 :   if (maria_commit(file) || maria_begin(file))
     278                 :     goto err;
     279                 : 
     280             272 :   if (!skip_update)
     281                 :   {
     282             272 :     if (opt_unique)
     283                 :     {
     284              40 :       if (!silent)
     285               0 :         printf("- Checking unique constraint\n");
     286              40 :       create_record(record,j);                  /* Check last created row */
     287              40 :       if (!maria_write(file,record) || my_errno != HA_ERR_FOUND_DUPP_UNIQUE)
     288                 :       {
     289               0 :         printf("unique check failed\n");
     290                 :       }
     291                 :     }
     292             272 :     if (!silent)
     293               0 :       printf("- Updating rows\n");
     294                 : 
     295                 :     /* Update first last row to force extend of file */
     296             272 :     if (maria_rsame(file,read_record,-1))
     297                 :     {
     298               0 :       printf("Can't find last row with maria_rsame\n");
     299                 :     }
     300                 :     else
     301                 :     {
     302             272 :       memcpy(record,read_record,rec_length);
     303             272 :       update_record(record);
     304             272 :       if (maria_update(file,read_record,record))
     305                 :       {
     306               0 :         printf("Can't update last row: %.*s\n",
     307                 :                keyinfo[0].seg[0].length,read_record+1);
     308                 :       }
     309                 :     }
     310                 : 
     311                 :     /* Read through all rows and update them */
     312             272 :     assert(maria_scan_init(file) == 0);
     313                 : 
     314             272 :     found=0;
     315            7614 :     while ((error= maria_scan(file,read_record)) == 0)
     316                 :     {
     317            7070 :       if (--update_count == 0) { VOID(maria_close(file)) ; exit(0) ; }
     318            7070 :       memcpy(record,read_record,rec_length);
     319            7070 :       update_record(record);
     320            7070 :       if (maria_update(file,read_record,record))
     321                 :       {
     322               0 :         printf("Can't update row: %.*s, error: %d\n",
     323                 :                keyinfo[0].seg[0].length,record+1,my_errno);
     324                 :       }
     325            7070 :       found++;
     326                 :     }
     327             272 :     if (found != row_count)
     328               0 :       printf("Found %ld of %ld rows\n", (ulong) found, (ulong) row_count);
     329             272 :     maria_scan_end(file);
     330                 :   }
     331                 : 
     332             272 :   if (checkpoint == 3 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
     333             272 :     goto err;
     334                 : 
     335             272 :   if (testflag == 3)
     336                 :   {
     337              48 :     printf("Terminating after updates\n");
     338              48 :     goto end;
     339                 :   }
     340             224 :   if (!silent)
     341               0 :     printf("- Reopening file\n");
     342             224 :   if (maria_commit(file))
     343             224 :     goto err;
     344             224 :   if (maria_close(file))
     345             224 :     goto err;
     346             224 :   if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
     347             224 :     goto err;
     348             224 :   if (maria_begin(file))
     349             224 :     goto err;
     350             224 :   if (opt_versioning)
     351              55 :     maria_versioning(file, 1);
     352             224 :   if (!skip_delete)
     353                 :   {
     354             224 :     if (!silent)
     355               0 :       printf("- Removing keys\n");
     356                 : 
     357            2688 :     for (i=0 ; i <= 10 ; i++)
     358                 :     {
     359                 :       /*
     360                 :         If you want to debug the problem in ma_test_recovery with BLOBs
     361                 :         (see @todo there), you can break out of the loop after just one
     362                 :         delete, it is enough, like this:
     363                 :         if (i==1) break;
     364                 :       */
     365                 :       /* testing */
     366            2464 :       if (remove_count-- == 0)
     367                 :       {
     368               0 :         fprintf(stderr,
     369                 :                 "delete-rows number of rows deleted; Going down hard!\n");
     370               0 :         goto end;
     371                 :       }
     372            2464 :       j=i*2;
     373            2464 :       if (!flags[j])
     374            2327 :         continue;
     375            2327 :       create_key(key,j);
     376            2327 :       my_errno=0;
     377            2327 :       if ((error = maria_rkey(file, read_record, 0, key,
     378                 :                               HA_WHOLE_KEY, HA_READ_KEY_EXACT)))
     379                 :       {
     380               0 :         if (verbose || (flags[j] >= 1 ||
     381                 :                         (error && my_errno != HA_ERR_KEY_NOT_FOUND)))
     382               0 :           printf("key: '%.*s'  maria_rkey:  %3d  errno: %3d\n",
     383                 :                  (int) key_length,key+offset_to_key,error,my_errno);
     384                 :       }
     385                 :       else
     386                 :       {
     387            2327 :         error=maria_delete(file,read_record);
     388            2327 :         if (verbose || error)
     389               0 :           printf("key: '%.*s'  maria_delete: %3d  errno: %3d\n",
     390                 :                  (int) key_length, key+offset_to_key, error, my_errno);
     391            2327 :         if (! error)
     392                 :         {
     393            2327 :           deleted++;
     394            2327 :           flags[j]--;
     395                 :         }
     396                 :       }
     397                 :     }
     398                 :   }
     399                 : 
     400             224 :   if (checkpoint == 4 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
     401             224 :     goto err;
     402                 : 
     403             224 :   if (testflag == 4)
     404                 :   {
     405              32 :     printf("Terminating after deletes\n");
     406              32 :     goto end;
     407                 :   }
     408                 : 
     409             192 :   if (!silent)
     410               0 :     printf("- Reading rows with key\n");
     411             192 :   record[1]= 0;                                 /* For nicer printf */
     412            5184 :   for (i=0 ; i <= 25 ; i++)
     413                 :   {
     414            4992 :     create_key(key,i);
     415            4992 :     my_errno=0;
     416            4992 :     error=maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT);
     417            4992 :     if (verbose ||
     418                 :         (error == 0 && flags[i] == 0 && unique_key) ||
     419                 :         (error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND)))
     420                 :     {
     421               0 :       printf("key: '%.*s'  maria_rkey: %3d  errno: %3d  record: %s\n",
     422                 :              (int) key_length,key+offset_to_key,error,my_errno,record+1);
     423                 :     }
     424                 :   }
     425                 : 
     426             192 :   if (!silent)
     427               0 :     printf("- Reading rows with position\n");
     428             192 :   if (maria_scan_init(file))
     429                 :   {
     430               0 :     fprintf(stderr, "maria_scan_init failed\n");
     431               0 :     goto err;
     432                 :   }
     433                 : 
     434            3528 :   for (i=1,found=0 ; i <= 30 ; i++)
     435                 :   {
     436            3528 :     my_errno=0;
     437            3528 :     if ((error= maria_scan(file, read_record)) == HA_ERR_END_OF_FILE)
     438                 :     {
     439             192 :       if (found != row_count-deleted)
     440               0 :         printf("Found only %ld of %ld rows\n", (ulong) found,
     441                 :                (ulong) (row_count - deleted));
     442                 :       break;
     443                 :     }
     444            3336 :     if (!error)
     445            2935 :       found++;
     446            3336 :     if (verbose || (error != 0 && error != HA_ERR_RECORD_DELETED &&
     447                 :                     error != HA_ERR_END_OF_FILE))
     448                 :     {
     449               0 :       printf("pos: %2d  maria_rrnd: %3d  errno: %3d  record: %s\n",
     450                 :              i-1,error,my_errno,read_record+1);
     451                 :     }
     452                 :   }
     453             192 :   maria_scan_end(file);
     454                 : 
     455             320 : end:
     456             320 :   if (die_in_middle_of_transaction)
     457                 :   {
     458                 :     /* As commit record is not done, UNDO entries needs to be rolled back */
     459              64 :     switch (die_in_middle_of_transaction) {
     460                 :     case 1:
     461                 :       /*
     462                 :         Flush changed pages go to disk. That will also flush log. Recovery
     463                 :         will skip REDOs and apply UNDOs.
     464                 :       */
     465              16 :       _ma_flush_table_files(file, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
     466                 :                             FLUSH_RELEASE, FLUSH_RELEASE);
     467              16 :       break;
     468                 :     case 2:
     469                 :       /*
     470                 :         Just flush log. Pages are likely to not be on disk. Recovery will
     471                 :         then execute REDOs and UNDOs.
     472                 :       */
     473              16 :       if (translog_flush(file->trn->undo_lsn))
     474                 :         goto err;
     475                 :       break;
     476                 :     case 3:
     477                 :       /*
     478                 :         Flush nothing. Pages and log are likely to not be on disk. Recovery
     479                 :         will then do nothing.
     480                 :       */
     481                 :       break;
     482                 :     case 4:
     483                 :       /*
     484                 :         Flush changed data pages go to disk. Changed index pages are not
     485                 :         flushed. Recovery will skip some REDOs and apply UNDOs.
     486                 :       */
     487              16 :       _ma_flush_table_files(file, MARIA_FLUSH_DATA, FLUSH_RELEASE,
     488                 :                             FLUSH_RELEASE);
     489                 :       /*
     490                 :         We have to flush log separately as the redo for the last key page
     491                 :         may not be flushed
     492                 :       */
     493              16 :       if (translog_flush(file->trn->undo_lsn))
     494              64 :         goto err;
     495                 :       break;
     496                 :     }
     497              64 :     printf("Dying on request without maria_commit()/maria_close()\n");
     498              64 :     exit(0);
     499                 :   }
     500                 : 
     501             256 :   if (maria_commit(file))
     502             256 :     goto err;
     503             256 :   if (maria_close(file))
     504             256 :     goto err;
     505             256 :   maria_end();
     506             256 :   my_end(MY_CHECK_ERROR);
     507                 : 
     508             256 :   return (0);
     509               0 : err:
     510               0 :   printf("got error: %3d when using maria-database\n",my_errno);
     511               0 :   return 1;                     /* skip warning */
     512                 : }
     513                 : 
     514                 : 
     515                 : static void create_key_part(uchar *key,uint rownr)
     516           15384 : {
     517           15384 :   if (!unique_key)
     518            2445 :     rownr&=7;                                       /* Some identical keys */
     519           15384 :   if (keyinfo[0].seg[0].type == HA_KEYTYPE_NUM)
     520                 :   {
     521            6218 :     sprintf((char*) key,"%*d",keyinfo[0].seg[0].length,rownr);
     522                 :   }
     523            9166 :   else if (keyinfo[0].seg[0].type == HA_KEYTYPE_VARTEXT1 ||
     524                 :            keyinfo[0].seg[0].type == HA_KEYTYPE_VARTEXT2)
     525                 :   {                                             /* Alpha record */
     526                 :     /* Create a key that may be easily packed */
     527            3651 :     bfill(key,keyinfo[0].seg[0].length,rownr < 10 ? 'A' : 'B');
     528            3651 :     sprintf((char*) key+keyinfo[0].seg[0].length-2,"%-2d",rownr);
     529            3651 :     if ((rownr & 7) == 0)
     530                 :     {
     531                 :       /* Change the key to force a unpack of the next key */
     532             550 :       bfill(key+3,keyinfo[0].seg[0].length-5,rownr < 10 ? 'a' : 'b');
     533                 :     }
     534                 :   }
     535                 :   else
     536                 :   {                                             /* Alpha record */
     537            5515 :     if (keyinfo[0].seg[0].flag & HA_SPACE_PACK)
     538            2445 :       sprintf((char*) key,"%-*d",keyinfo[0].seg[0].length,rownr);
     539                 :     else
     540                 :     {
     541                 :       /* Create a key that may be easily packed */
     542            3070 :       bfill(key,keyinfo[0].seg[0].length,rownr < 10 ? 'A' : 'B');
     543            3070 :       sprintf((char*) key+keyinfo[0].seg[0].length-2,"%-2d",rownr);
     544            3070 :       if ((rownr & 7) == 0)
     545                 :       {
     546                 :         /* Change the key to force a unpack of the next key */
     547             450 :         key[1]= (rownr < 10 ? 'a' : 'b');
     548                 :       }
     549                 :     }
     550                 :   }
     551                 : }
     552                 : 
     553                 : 
     554                 : static void create_key(uchar *key,uint rownr)
     555            7319 : {
     556            7319 :   if (keyinfo[0].seg[0].null_bit)
     557                 :   {
     558            2387 :     if (rownr == 0)
     559                 :     {
     560             142 :       key[0]=1;                                 /* null key */
     561             142 :       key[1]=0;                                 /* For easy print of key */
     562             142 :       return;
     563                 :     }
     564            2245 :     *key++=0;
     565                 :   }
     566            7177 :   if (keyinfo[0].seg[0].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART))
     567                 :   {
     568                 :     uint tmp;
     569            1230 :     create_key_part(key+2,rownr);
     570            1230 :     tmp=strlen((char*) key+2);
     571            1230 :     int2store(key,tmp);
     572                 :   }
     573                 :   else
     574            5947 :     create_key_part(key,rownr);
     575                 : }
     576                 : 
     577                 : 
     578                 : static uchar blob_key[MAX_REC_LENGTH];
     579                 : static uchar blob_record[MAX_REC_LENGTH+20*20];
     580                 : 
     581                 : 
     582                 : static void create_record(uchar *record,uint rownr)
     583            8207 : {
     584                 :   uchar *pos;
     585            8207 :   bzero((char*) record,MAX_REC_LENGTH);
     586            8207 :   record[0]=1;                                  /* delete marker */
     587            8207 :   if (rownr == 0 && keyinfo[0].seg[0].null_bit)
     588             167 :     record[0]|=keyinfo[0].seg[0].null_bit;      /* Null key */
     589                 : 
     590            8207 :   pos=record+1;
     591            8207 :   if (recinfo[0].type == FIELD_BLOB)
     592                 :   {
     593                 :     uint tmp;
     594                 :     uchar *ptr;
     595            1911 :     create_key_part(blob_key,rownr);
     596            1911 :     tmp=strlen((char*) blob_key);
     597            1911 :     int4store(pos,tmp);
     598            1911 :     ptr=blob_key;
     599            1911 :     memcpy_fixed(pos+4,&ptr,sizeof(char*));
     600            1911 :     pos+=recinfo[0].length;
     601                 :   }
     602            6296 :   else if (recinfo[0].type == FIELD_VARCHAR)
     603                 :   {
     604             510 :     uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[0].length-1);
     605             510 :     create_key_part(pos+pack_length,rownr);
     606             510 :     tmp= strlen((char*) pos+pack_length);
     607             510 :     if (pack_length == 1)
     608             255 :       *(uchar*) pos= (uchar) tmp;
     609                 :     else
     610             255 :       int2store(pos,tmp);
     611             510 :     pos+= recinfo[0].length;
     612                 :   }
     613                 :   else
     614                 :   {
     615            5786 :     create_key_part(pos,rownr);
     616            5786 :     pos+=recinfo[0].length;
     617                 :   }
     618            8207 :   if (recinfo[1].type == FIELD_BLOB)
     619                 :   {
     620                 :     uint tmp;
     621                 :     uchar *ptr;;
     622            1911 :     sprintf((char*) blob_record,"... row: %d", rownr);
     623            1911 :     strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
     624            1911 :     tmp=strlen((char*) blob_record);
     625            1911 :     int4store(pos,tmp);
     626            1911 :     ptr=blob_record;
     627            1911 :     memcpy_fixed(pos+4,&ptr,sizeof(char*));
     628                 :   }
     629            6296 :   else if (recinfo[1].type == FIELD_VARCHAR)
     630                 :   {
     631             510 :     uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
     632             510 :     sprintf((char*) pos+pack_length, "... row: %d", rownr);
     633             510 :     tmp= strlen((char*) pos+pack_length);
     634             510 :     if (pack_length == 1)
     635             510 :       *pos= (uchar) tmp;
     636                 :     else
     637               0 :       int2store(pos,tmp);
     638                 :   }
     639                 :   else
     640                 :   {
     641            5786 :     sprintf((char*) pos,"... row: %d", rownr);
     642            5786 :     strappend((char*) pos,recinfo[1].length,' ');
     643                 :   }
     644                 : }
     645                 : 
     646                 : /* change row to test re-packing of rows and reallocation of keys */
     647                 : 
     648                 : static void update_record(uchar *record)
     649            7342 : {
     650            7342 :   uchar *pos=record+1;
     651            7342 :   if (recinfo[0].type == FIELD_BLOB)
     652                 :   {
     653                 :     uchar *column,*ptr;
     654                 :     int length;
     655            1390 :     length=uint4korr(pos);                      /* Long blob */
     656            1390 :     memcpy_fixed(&column,pos+4,sizeof(char*));
     657            1390 :     memcpy(blob_key,column,length);             /* Move old key */
     658            1390 :     ptr=blob_key;
     659            1390 :     memcpy_fixed(pos+4,&ptr,sizeof(char*)); /* Store pointer to new key */
     660            1390 :     if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM)
     661            1390 :       default_charset_info->cset->casedn(default_charset_info,
     662                 :                                          (char*) blob_key, length,
     663                 :                                          (char*) blob_key, length);
     664            1390 :     pos+=recinfo[0].length;
     665                 :   }
     666            5952 :   else if (recinfo[0].type == FIELD_VARCHAR)
     667                 :   {
     668             530 :     uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[0].length-1);
     669             530 :     uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
     670             530 :     default_charset_info->cset->casedn(default_charset_info,
     671                 :                                        (char*) pos + pack_length, length,
     672                 :                                        (char*) pos + pack_length, length);
     673             530 :     pos+=recinfo[0].length;
     674                 :   }
     675                 :   else
     676                 :   {
     677            5422 :     if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM)
     678            2390 :       default_charset_info->cset->casedn(default_charset_info,
     679                 :                                          (char*) pos, keyinfo[0].seg[0].length,
     680                 :                                          (char*) pos, keyinfo[0].seg[0].length);
     681            5422 :     pos+=recinfo[0].length;
     682                 :   }
     683                 : 
     684            7342 :   if (recinfo[1].type == FIELD_BLOB)
     685                 :   {
     686                 :     uchar *column;
     687                 :     int length;
     688            1390 :     length=uint4korr(pos);
     689            1390 :     memcpy_fixed(&column,pos+4,sizeof(char*));
     690            1390 :     memcpy(blob_record,column,length);
     691            1390 :     bfill(blob_record+length,20,'.');   /* Make it larger */
     692            1390 :     length+=20;
     693            1390 :     int4store(pos,length);
     694            1390 :     column=blob_record;
     695            1390 :     memcpy_fixed(pos+4,&column,sizeof(char*));
     696                 :   }
     697            5952 :   else if (recinfo[1].type == FIELD_VARCHAR)
     698                 :   {
     699                 :     /* Second field is longer than 10 characters */
     700             530 :     uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
     701             530 :     uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
     702             530 :     pos= record+ recinfo[1].offset;
     703             530 :     bfill(pos+pack_length+length,recinfo[1].length-length-pack_length,'.');
     704             530 :     length=recinfo[1].length-pack_length;
     705             530 :     if (pack_length == 1)
     706             530 :       *(uchar*) pos= (uchar) length;
     707                 :     else
     708               0 :       int2store(pos,length);
     709                 :   }
     710                 :   else
     711                 :   {
     712            5422 :     bfill(pos+recinfo[1].length-10,10,'.');
     713                 :   }
     714                 : }
     715                 : 
     716                 : 
     717                 : static struct my_option my_long_options[] =
     718                 : {
     719                 :   {"checkpoint", 'H', "Checkpoint at specified stage", (uchar**) &checkpoint,
     720                 :    (uchar**) &checkpoint, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
     721                 :   {"checksum", 'c', "Undocumented",
     722                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     723                 : #ifndef DBUG_OFF
     724                 :   {"debug", '#', "Undocumented",
     725                 :    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
     726                 : #endif
     727                 :   {"delete-rows", 'd', "Abort after this many rows has been deleted",
     728                 :    (uchar**) &remove_count, (uchar**) &remove_count, 0, GET_UINT, REQUIRED_ARG,
     729                 :    1000, 0, 0, 0, 0, 0},
     730                 :   {"help", '?', "Display help and exit",
     731                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     732                 :   {"insert-rows", 'i', "Undocumented", (uchar**) &insert_count,
     733                 :    (uchar**) &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
     734                 :   {"key-alpha", 'a', "Use a key of type HA_KEYTYPE_TEXT",
     735                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     736                 :   {"key-binary-pack", 'B', "Undocumented",
     737                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     738                 :   {"key-blob", 'b', "Undocumented",
     739                 :    (uchar**) &blob_length, (uchar**) &blob_length,
     740                 :    0, GET_ULONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
     741                 :   {"key-cache", 'K', "Undocumented", (uchar**) &pagecacheing,
     742                 :    (uchar**) &pagecacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
     743                 :   {"key-length", 'k', "Undocumented", (uchar**) &key_length,
     744                 :    (uchar**) &key_length, 0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0},
     745                 :   {"key-multiple", 'm', "Don't use unique keys",
     746                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     747                 :   {"key-prefix_pack", 'P', "Undocumented",
     748                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     749                 :   {"key-space_pack", 'p', "Undocumented",
     750                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     751                 :   {"key-varchar", 'w', "Test VARCHAR keys",
     752                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     753                 :   {"null-fields", 'N', "Define fields with NULL",
     754                 :    (uchar**) &null_fields, (uchar**) &null_fields, 0, GET_BOOL, NO_ARG,
     755                 :    0, 0, 0, 0, 0, 0},
     756                 :   {"row-fixed-size", 'S', "Fixed size records",
     757                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     758                 :   {"rows-in-block", 'M', "Store rows in block format",
     759                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     760                 :   {"row-pointer-size", 'R', "Undocumented", (uchar**) &rec_pointer_size,
     761                 :    (uchar**) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
     762                 :   {"silent", 's', "Undocumented",
     763                 :    (uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
     764                 :    0, 0},
     765                 :   {"skip-delete", 'D', "Don't test deletes", (uchar**) &skip_delete,
     766                 :    (uchar**) &skip_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
     767                 :   {"skip-update", 'U', "Don't test updates", (uchar**) &skip_update,
     768                 :    (uchar**) &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
     769                 :   {"testflag", 't', "Stop test at specified stage", (uchar**) &testflag,
     770                 :    (uchar**) &testflag, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
     771                 :   {"test-undo", 'A',
     772                 :    "Abort hard. Used for testing recovery with undo",
     773                 :    (uchar**) &die_in_middle_of_transaction,
     774                 :    (uchar**) &die_in_middle_of_transaction,
     775                 :    0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
     776                 :   {"transactional", 'T',
     777                 :    "Test in transactional mode. (Only works with block format)",
     778                 :    (uchar**) &transactional, (uchar**) &transactional, 0, GET_BOOL, NO_ARG,
     779                 :    0, 0, 0, 0, 0, 0},
     780                 :   {"unique", 'E', "Check unique handling", (uchar**) &opt_unique,
     781                 :    (uchar**) &opt_unique, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
     782                 :   {"update-rows", 'u', "Max number of rows to update", (uchar**) &update_count,
     783                 :    (uchar**) &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
     784                 :   {"verbose", 'v', "Be more verbose", (uchar**) &verbose,
     785                 :    (uchar**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
     786                 :   {"version", 'V', "Print version number and exit",
     787                 :    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
     788                 :   {"versioning", 'C', "Use row versioning (only works with block format)",
     789                 :    (uchar**) &opt_versioning,  (uchar**) &opt_versioning, 0, GET_BOOL,
     790                 :    NO_ARG, 0, 0, 0, 0, 0, 0},
     791                 :   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
     792                 : };
     793                 : 
     794                 : 
     795                 : static my_bool
     796                 : get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
     797                 :                char *argument __attribute__((unused)))
     798            1972 : {
     799            1972 :   switch(optid) {
     800                 :   case 'a':
     801              80 :     key_type= HA_KEYTYPE_TEXT;
     802              80 :     break;
     803                 :   case 'c':
     804             195 :     create_flag|= HA_CREATE_CHECKSUM | HA_CREATE_PAGE_CHECKSUM;
     805             195 :     break;
     806                 :   case 'R':                             /* Length of record pointer */
     807              10 :     if (rec_pointer_size > 3)
     808               0 :       rec_pointer_size=0;
     809                 :     break;
     810                 :   case 'P':
     811              25 :     pack_keys= HA_PACK_KEY;             /* Use prefix compression */
     812              25 :     break;
     813                 :   case 'B':
     814              35 :     pack_keys= HA_BINARY_PACK_KEY;      /* Use binary compression */
     815              35 :     break;
     816                 :   case 'M':
     817             244 :     record_type= BLOCK_RECORD;
     818             244 :     break;
     819                 :   case 'S':
     820              53 :     if (key_field == FIELD_VARCHAR)
     821                 :     {
     822               4 :       create_flag=0;                    /* Static sized varchar */
     823               4 :       record_type= STATIC_RECORD;
     824                 :     }
     825              49 :     else if (key_field != FIELD_BLOB)
     826                 :     {
     827              47 :       key_field=FIELD_NORMAL;           /* static-size record */
     828              47 :       extra_field=FIELD_NORMAL;
     829              47 :       record_type= STATIC_RECORD;
     830                 :     }
     831                 :     break;
     832                 :   case 'p':
     833              40 :     pack_keys=HA_PACK_KEY;              /* Use prefix + space packing */
     834              40 :     pack_seg=HA_SPACE_PACK;
     835              40 :     key_type=HA_KEYTYPE_TEXT;
     836              40 :     break;
     837                 :   case 'm':
     838              40 :     unique_key=0;
     839              40 :     break;
     840                 :   case 'b':
     841              74 :     key_field=FIELD_BLOB;                       /* blob key */
     842              74 :     extra_field= FIELD_BLOB;
     843              74 :     pack_seg|= HA_BLOB_PART;
     844              74 :     key_type= HA_KEYTYPE_VARTEXT1;
     845              74 :     if (record_type == STATIC_RECORD)
     846               0 :       record_type= DYNAMIC_RECORD;
     847                 :     break;
     848                 :   case 'k':
     849              75 :     if (key_length < 4 || key_length > HA_MAX_KEY_LENGTH)
     850                 :     {
     851               0 :       fprintf(stderr,"Wrong key length\n");
     852               0 :       exit(1);
     853                 :     }
     854                 :     break;
     855                 :   case 'w':
     856              20 :     key_field=FIELD_VARCHAR;                    /* varchar keys */
     857              20 :     extra_field= FIELD_VARCHAR;
     858              20 :     key_type= HA_KEYTYPE_VARTEXT1;
     859              20 :     pack_seg|= HA_VAR_LENGTH_PART;
     860              20 :     if (record_type == STATIC_RECORD)
     861               0 :       record_type= DYNAMIC_RECORD;
     862                 :     break;
     863                 :   case 'K':                                     /* Use key cacheing */
     864               5 :     pagecacheing=1;
     865               5 :     break;
     866                 :   case 'V':
     867               0 :     printf("test1 Ver 1.2 \n");
     868               0 :     exit(0);
     869                 :   case '#':
     870               0 :     DBUG_PUSH(argument);
     871               0 :     break;
     872                 :   case '?':
     873               0 :     usage();
     874               0 :     exit(1);
     875                 :   }
     876            1972 :   return 0;
     877                 : }
     878                 : 
     879                 : 
     880                 : /* Read options */
     881                 : 
     882                 : static void get_options(int argc, char *argv[])
     883             320 : {
     884                 :   int ho_error;
     885                 : 
     886             320 :   if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
     887               0 :     exit(ho_error);
     888             320 :   if (transactional)
     889             206 :     record_type= BLOCK_RECORD;
     890                 :   return;
     891                 : } /* get options */
     892                 : 
     893                 : 
     894                 : static void usage()
     895               0 : {
     896               0 :   printf("Usage: %s [options]\n\n", my_progname);
     897               0 :   my_print_help(my_long_options);
     898               0 :   my_print_variables(my_long_options);
     899                 : }

Generated by: LTP GCOV extension version 1.4