LTP GCOV extension - code coverage report
Current view: directory - storage/maria - ma_open.c
Test: maria-unit-test.html
Date: 2009-03-04 Instrumented lines: 888
Code covered: 81.4 % Executed lines: 723

       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                 : /* open a isam-database */
      17                 : 
      18                 : #include "ma_fulltext.h"
      19                 : #include "ma_sp_defs.h"
      20                 : #include "ma_rt_index.h"
      21                 : #include "ma_blockrec.h"
      22                 : #include <m_ctype.h>
      23                 : 
      24                 : #if defined(MSDOS) || defined(__WIN__)
      25                 : #ifdef __WIN__
      26                 : #include <fcntl.h>
      27                 : #else
      28                 : #include <process.h>                      /* Prototype for getpid */
      29                 : #endif
      30                 : #endif
      31                 : 
      32                 : static void setup_key_functions(MARIA_KEYDEF *keyinfo);
      33                 : static my_bool maria_scan_init_dummy(MARIA_HA *info);
      34                 : static void maria_scan_end_dummy(MARIA_HA *info);
      35                 : static my_bool maria_once_init_dummy(MARIA_SHARE *, File);
      36                 : static my_bool maria_once_end_dummy(MARIA_SHARE *);
      37                 : static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base);
      38                 : static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state);
      39                 : 
      40                 : #define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
      41                 :                                         pos+=size;}
      42                 : 
      43                 : 
      44                 : #define disk_pos_assert(pos, end_pos) \
      45                 : if (pos > end_pos)             \
      46                 : {                              \
      47                 :   my_errno=HA_ERR_CRASHED;     \
      48                 :   goto err;                    \
      49                 : }
      50                 : 
      51                 : 
      52                 : /******************************************************************************
      53                 : ** Return the shared struct if the table is already open.
      54                 : ** In MySQL the server will handle version issues.
      55                 : ******************************************************************************/
      56                 : 
      57                 : MARIA_HA *_ma_test_if_reopen(const char *filename)
      58            3808 : {
      59                 :   LIST *pos;
      60                 : 
      61            3813 :   for (pos=maria_open_list ; pos ; pos=pos->next)
      62                 :   {
      63               5 :     MARIA_HA *info=(MARIA_HA*) pos->data;
      64               5 :     MARIA_SHARE *share= info->s;
      65               5 :     if (!strcmp(share->unique_file_name.str,filename) && share->last_version)
      66               0 :       return info;
      67                 :   }
      68            3808 :   return 0;
      69                 : }
      70                 : 
      71                 : 
      72                 : /*
      73                 :   Open a new instance of an already opened Maria table
      74                 : 
      75                 :   SYNOPSIS
      76                 :     maria_clone_internal()
      77                 :     share       Share of already open table
      78                 :     mode        Mode of table (O_RDONLY | O_RDWR)
      79                 :     data_file   Filedescriptor of data file to use < 0 if one should open
      80                 :                 open it.
      81                 : 
      82                 :  RETURN
      83                 :     #   Maria handler
      84                 :     0   Error
      85                 : */
      86                 : 
      87                 : 
      88                 : static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name,
      89                 :                                       int mode, File data_file)
      90            3245 : {
      91                 :   int save_errno;
      92                 :   uint errpos;
      93                 :   MARIA_HA info,*m_info;
      94                 :   my_bitmap_map *changed_fields_bitmap;
      95            3245 :   DBUG_ENTER("maria_clone_internal");
      96                 : 
      97            3245 :   errpos= 0;
      98            3245 :   bzero((uchar*) &info,sizeof(info));
      99                 : 
     100            3245 :   if (mode == O_RDWR && share->mode == O_RDONLY)
     101                 :   {
     102               0 :     my_errno=EACCES;                            /* Can't open in write mode */
     103               0 :     goto err;
     104                 :   }
     105            3245 :   if (data_file >= 0)
     106            2887 :     info.dfile.file= data_file;
     107             358 :   else if (_ma_open_datafile(&info, share, name, -1))
     108            3245 :     goto err;
     109            3245 :   errpos= 5;
     110                 : 
     111                 :   /* alloc and set up private structure parts */
     112            3245 :   if (!my_multi_malloc(MY_WME,
     113                 :                        &m_info,sizeof(MARIA_HA),
     114                 :                        &info.blobs,sizeof(MARIA_BLOB)*share->base.blobs,
     115                 :                        &info.buff,(share->base.max_key_block_length*2+
     116                 :                                    share->base.max_key_length),
     117                 :                        &info.lastkey_buff,share->base.max_key_length*2+1,
     118                 :                        &info.first_mbr_key, share->base.max_key_length,
     119                 :                        &info.maria_rtree_recursion_state,
     120                 :                        share->have_rtree ? 1024 : 0,
     121                 :                        &changed_fields_bitmap,
     122                 :                        bitmap_buffer_size(share->base.fields),
     123                 :                        NullS))
     124            3245 :     goto err;
     125            3245 :   errpos= 6;
     126                 : 
     127            3245 :   memcpy(info.blobs,share->blobs,sizeof(MARIA_BLOB)*share->base.blobs);
     128            3245 :   info.lastkey_buff2= info.lastkey_buff + share->base.max_key_length;
     129            3245 :   info.last_key.data= info.lastkey_buff;
     130                 : 
     131            3245 :   info.s=share;
     132            3245 :   info.cur_row.lastpos= HA_OFFSET_ERROR;
     133            3245 :   info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
     134            3245 :   info.opt_flag=READ_CHECK_USED;
     135            3245 :   info.this_unique= (ulong) info.dfile.file; /* Uniq number in process */
     136                 : #ifdef EXTERNAL_LOCKING
     137                 :   if (share->data_file_type == COMPRESSED_RECORD)
     138                 :     info.this_unique= share->state.unique;
     139                 :   info.this_loop=0;                             /* Update counter */
     140                 :   info.last_unique= share->state.unique;
     141                 :   info.last_loop=   share->state.update_count;
     142                 : #endif
     143            3245 :   info.errkey= -1;
     144            3245 :   info.page_changed=1;
     145            3245 :   info.keyread_buff= info.buff + share->base.max_key_block_length;
     146                 : 
     147            3245 :   info.lock_type= F_UNLCK;
     148            3245 :   if (share->options & HA_OPTION_TMP_TABLE)
     149               0 :     info.lock_type= F_WRLCK;
     150                 : 
     151            3245 :   _ma_set_data_pagecache_callbacks(&info.dfile, share);
     152            3245 :   bitmap_init(&info.changed_fields, changed_fields_bitmap,
     153                 :               share->base.fields, 0);
     154            3245 :   if ((*share->init)(&info))
     155            3245 :     goto err;
     156                 : 
     157                 :   /* The following should be big enough for all pinning purposes */
     158            3245 :   if (my_init_dynamic_array(&info.pinned_pages,
     159                 :                             sizeof(MARIA_PINNED_PAGE),
     160                 :                             max(share->base.blobs*2 + 4,
     161                 :                                 MARIA_MAX_TREE_LEVELS*3), 16))
     162            3245 :     goto err;
     163                 : 
     164                 : 
     165            3245 :   pthread_mutex_lock(&share->intern_lock);
     166            3245 :   info.read_record= share->read_record;
     167            3245 :   share->reopen++;
     168            3245 :   share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
     169            3245 :   if (share->options & HA_OPTION_READ_ONLY_DATA)
     170                 :   {
     171            1536 :     info.lock_type=F_RDLCK;
     172            1536 :     share->r_locks++;
     173            1536 :     share->tot_locks++;
     174                 :   }
     175            3245 :   if ((share->options & HA_OPTION_DELAY_KEY_WRITE) &&
     176                 :       maria_delay_key_write)
     177               0 :     share->delay_key_write=1;
     178                 : 
     179            3245 :   if (!share->base.born_transactional)   /* For transactional ones ... */
     180                 :   {
     181                 :     /* ... force crash if no trn given */
     182             653 :     _ma_set_trn_for_table(&info, &dummy_transaction_object);
     183             653 :     info.state= &share->state.state;     /* Change global values by default */
     184                 :   }
     185                 :   else
     186                 :   {
     187            2592 :     info.state=  &share->state.common;
     188            2592 :     *info.state= share->state.state;            /* Initial values */
     189                 :   }
     190            3245 :   info.state_start= info.state;                 /* Initial values */
     191                 : 
     192            3245 :   pthread_mutex_unlock(&share->intern_lock);
     193                 : 
     194                 :   /* Allocate buffer for one record */
     195                 :   /* prerequisites: info->rec_buffer == 0 && info->rec_buff_size == 0 */
     196            3245 :   if (_ma_alloc_buffer(&info.rec_buff, &info.rec_buff_size,
     197                 :                        share->base.default_rec_buff_size))
     198            3245 :     goto err;
     199                 : 
     200            3245 :   bzero(info.rec_buff, share->base.default_rec_buff_size);
     201                 : 
     202            3245 :   *m_info=info;
     203                 : #ifdef THREAD
     204            3245 :   thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
     205                 : #endif
     206            3245 :   m_info->open_list.data=(void*) m_info;
     207            3245 :   maria_open_list=list_add(maria_open_list,&m_info->open_list);
     208                 : 
     209            3245 :   DBUG_RETURN(m_info);
     210                 : 
     211               0 : err:
     212               0 :   save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
     213               0 :   if ((save_errno == HA_ERR_CRASHED) ||
     214                 :       (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
     215                 :       (save_errno == HA_ERR_CRASHED_ON_REPAIR))
     216               0 :     _ma_report_error(save_errno, &share->open_file_name);
     217               0 :   switch (errpos) {
     218                 :   case 6:
     219               0 :     (*share->end)(&info);
     220               0 :     delete_dynamic(&info.pinned_pages);
     221               0 :     my_free(m_info, MYF(0));
     222                 :     /* fall through */
     223                 :   case 5:
     224               0 :     if (data_file < 0)
     225               0 :       VOID(my_close(info.dfile.file, MYF(0)));
     226                 :     break;
     227                 :   }
     228               0 :   my_errno=save_errno;
     229               0 :   DBUG_RETURN (NULL);
     230                 : } /* maria_clone_internal */
     231                 : 
     232                 : 
     233                 : /* Make a clone of a maria table */
     234                 : 
     235                 : MARIA_HA *maria_clone(MARIA_SHARE *share, int mode)
     236               0 : {
     237                 :   MARIA_HA *new_info;
     238               0 :   pthread_mutex_lock(&THR_LOCK_maria);
     239               0 :   new_info= maria_clone_internal(share, NullS, mode,
     240                 :                                  share->data_file_type == BLOCK_RECORD ?
     241                 :                                  share->bitmap.file.file : -1);
     242               0 :   pthread_mutex_unlock(&THR_LOCK_maria);
     243               0 :   return new_info;
     244                 : }
     245                 : 
     246                 : 
     247                 : /******************************************************************************
     248                 :   open a MARIA table
     249                 : 
     250                 :   See my_base.h for the handle_locking argument
     251                 :   if handle_locking and HA_OPEN_ABORT_IF_CRASHED then abort if the table
     252                 :   is marked crashed or if we are not using locking and the table doesn't
     253                 :   have an open count of 0.
     254                 : ******************************************************************************/
     255                 : 
     256                 : MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
     257            3350 : {
     258                 :   int kfile,open_mode,save_errno;
     259                 :   uint i,j,len,errpos,head_length,base_pos,info_length,keys, realpath_err,
     260                 :     key_parts,unique_key_parts,fulltext_keys,uniques;
     261                 :   char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
     262                 :        data_name[FN_REFLEN];
     263                 :   uchar *disk_cache, *disk_pos, *end_pos;
     264                 :   MARIA_HA info,*m_info,*old_info;
     265                 :   MARIA_SHARE share_buff,*share;
     266                 :   double rec_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG];
     267                 :   ulong  nulls_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG];
     268                 :   my_off_t key_root[HA_MAX_POSSIBLE_KEY];
     269                 :   ulonglong max_key_file_length, max_data_file_length;
     270            3350 :   my_bool versioning= 1;
     271            3350 :   File data_file= -1;
     272            3350 :   DBUG_ENTER("maria_open");
     273                 : 
     274            3350 :   LINT_INIT(m_info);
     275            3350 :   kfile= -1;
     276            3350 :   errpos= 0;
     277            3350 :   head_length=sizeof(share_buff.state.header);
     278            3350 :   bzero((uchar*) &info,sizeof(info));
     279                 : 
     280            3350 :   realpath_err= my_realpath(name_buff, fn_format(org_name, name, "",
     281                 :                                                  MARIA_NAME_IEXT,
     282                 :                                                  MY_UNPACK_FILENAME),MYF(0));
     283            3350 :   if (my_is_symlink(org_name) &&
     284                 :       (realpath_err || (*maria_test_invalid_symlink)(name_buff)))
     285                 :   {
     286               0 :     my_errno= HA_WRONG_CREATE_OPTION;
     287               0 :     DBUG_RETURN(0);
     288                 :   }
     289                 : 
     290            3350 :   pthread_mutex_lock(&THR_LOCK_maria);
     291            3350 :   old_info= 0;
     292            3350 :   if ((open_flags & HA_OPEN_COPY) ||
     293                 :       !(old_info=_ma_test_if_reopen(name_buff)))
     294                 :   {
     295            3350 :     share= &share_buff;
     296            3350 :     bzero((uchar*) &share_buff,sizeof(share_buff));
     297            3350 :     share_buff.state.rec_per_key_part=   rec_per_key_part;
     298            3350 :     share_buff.state.nulls_per_key_part= nulls_per_key_part;
     299            3350 :     share_buff.state.key_root=key_root;
     300            3350 :     share_buff.pagecache= multi_pagecache_search((uchar*) name_buff,
     301                 :                                                  (uint) strlen(name_buff),
     302                 :                                                  maria_pagecache);
     303                 : 
     304            3350 :     DBUG_EXECUTE_IF("maria_pretend_crashed_table_on_open",
     305                 :                     if (strstr(name, "/t1"))
     306                 :                     {
     307                 :                       my_errno= HA_ERR_CRASHED;
     308                 :                       goto err;
     309                 :                     });
     310            3350 :     if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
     311                 :     {
     312             105 :       if ((errno != EROFS && errno != EACCES) ||
     313                 :           mode != O_RDONLY ||
     314                 :           (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
     315                 :         goto err;
     316                 :     }
     317            3245 :     share->mode=open_mode;
     318            3245 :     errpos= 1;
     319            3245 :     if (my_pread(kfile,share->state.header.file_version, head_length, 0,
     320                 :                  MYF(MY_NABP)))
     321                 :     {
     322               0 :       my_errno= HA_ERR_NOT_A_TABLE;
     323               0 :       goto err;
     324                 :     }
     325            3245 :     if (memcmp(share->state.header.file_version, maria_file_magic, 4))
     326                 :     {
     327               0 :       DBUG_PRINT("error",("Wrong header in %s",name_buff));
     328               0 :       DBUG_DUMP("error_dump", share->state.header.file_version,
     329                 :                 head_length);
     330               0 :       my_errno=HA_ERR_NOT_A_TABLE;
     331               0 :       goto err;
     332                 :     }
     333            3245 :     share->options= mi_uint2korr(share->state.header.options);
     334            3245 :     if (share->options &
     335                 :         ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
     336                 :           HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
     337                 :           HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
     338                 :           HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
     339                 :           HA_OPTION_RELIES_ON_SQL_LAYER | HA_OPTION_NULL_FIELDS |
     340                 :           HA_OPTION_PAGE_CHECKSUM))
     341                 :     {
     342               0 :       DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
     343               0 :       my_errno=HA_ERR_NEW_FILE;
     344               0 :       goto err;
     345                 :     }
     346            3245 :     if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
     347                 :         ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
     348                 :     {
     349               0 :       DBUG_PRINT("error", ("table cannot be opened from non-sql layer"));
     350               0 :       my_errno= HA_ERR_UNSUPPORTED;
     351               0 :       goto err;
     352                 :     }
     353                 :     /* Don't call realpath() if the name can't be a link */
     354            3245 :     if (!strcmp(name_buff, org_name) ||
     355                 :         my_readlink(index_name, org_name, MYF(0)) == -1)
     356               0 :       (void) strmov(index_name, org_name);
     357            3245 :     *strrchr(org_name, FN_EXTCHAR)= '\0';
     358            3245 :     (void) fn_format(data_name,org_name,"",MARIA_NAME_DEXT,
     359                 :                      MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
     360                 : 
     361            3245 :     info_length=mi_uint2korr(share->state.header.header_length);
     362            3245 :     base_pos= mi_uint2korr(share->state.header.base_pos);
     363            3245 :     if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
     364                 :     {
     365               0 :       my_errno=ENOMEM;
     366               0 :       goto err;
     367                 :     }
     368            3245 :     end_pos=disk_cache+info_length;
     369            3245 :     errpos= 3;
     370            3245 :     if (my_pread(kfile, disk_cache, info_length, 0L, MYF(MY_NABP)))
     371                 :     {
     372               0 :       my_errno=HA_ERR_CRASHED;
     373               0 :       goto err;
     374                 :     }
     375            3245 :     len=mi_uint2korr(share->state.header.state_info_length);
     376            3245 :     keys=    (uint) share->state.header.keys;
     377            3245 :     uniques= (uint) share->state.header.uniques;
     378            3245 :     fulltext_keys= (uint) share->state.header.fulltext_keys;
     379            3245 :     key_parts= mi_uint2korr(share->state.header.key_parts);
     380            3245 :     unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
     381            3245 :     if (len != MARIA_STATE_INFO_SIZE)
     382                 :     {
     383               0 :       DBUG_PRINT("warning",
     384                 :                  ("saved_state_info_length: %d  state_info_length: %d",
     385                 :                   len,MARIA_STATE_INFO_SIZE));
     386                 :     }
     387            3245 :     share->state_diff_length=len-MARIA_STATE_INFO_SIZE;
     388                 : 
     389            3245 :     _ma_state_info_read(disk_cache, &share->state);
     390            3245 :     len= mi_uint2korr(share->state.header.base_info_length);
     391            3245 :     if (len != MARIA_BASE_INFO_SIZE)
     392                 :     {
     393               0 :       DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
     394                 :                             len,MARIA_BASE_INFO_SIZE));
     395                 :     }
     396            3245 :     disk_pos= _ma_base_info_read(disk_cache + base_pos, &share->base);
     397            3245 :     share->state.state_length=base_pos;
     398                 : 
     399            3245 :     if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
     400                 :         ((share->state.changed & STATE_CRASHED) ||
     401                 :          ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
     402                 :           (my_disable_locking && share->state.open_count))))
     403                 :     {
     404               0 :       DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u  "
     405                 :                           "changed: %u  open_count: %u  !locking: %d",
     406                 :                           open_flags, share->state.changed,
     407                 :                           share->state.open_count, my_disable_locking));
     408               0 :       my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
     409                 :                 HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
     410               0 :       goto err;
     411                 :     }
     412                 : 
     413                 :     /*
     414                 :       We can ignore testing uuid if STATE_NOT_MOVABLE is set, as in this
     415                 :       case the uuid will be set in _ma_mark_file_changed()
     416                 :     */
     417            3245 :     if ((share->state.changed & STATE_NOT_MOVABLE) &&
     418                 :         share->base.born_transactional &&
     419                 :         ((!(open_flags & HA_OPEN_IGNORE_MOVED_STATE) &&
     420                 :           memcmp(share->base.uuid, maria_uuid, MY_UUID_SIZE)) ||
     421                 :          share->state.create_trid > trnman_get_max_trid()))
     422                 :     {
     423               4 :       if (open_flags & HA_OPEN_FOR_REPAIR)
     424               4 :         share->state.changed|= STATE_MOVED;
     425                 :       else
     426                 :       {
     427               0 :         my_errno= HA_ERR_OLD_FILE;
     428               0 :         goto err;
     429                 :       }
     430                 :     }
     431                 : 
     432                 :     /* sanity check */
     433            3245 :     if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
     434                 :     {
     435               0 :       my_errno=HA_ERR_CRASHED;
     436               0 :       goto err;
     437                 :     }
     438                 : 
     439            3245 :     key_parts+=fulltext_keys*FT_SEGS;
     440            3245 :     if (share->base.max_key_length > maria_max_key_length() ||
     441                 :         keys > MARIA_MAX_KEY || key_parts > MARIA_MAX_KEY * HA_MAX_KEY_SEG)
     442                 :     {
     443               0 :       DBUG_PRINT("error",("Wrong key info:  Max_key_length: %d  keys: %d  key_parts: %d", share->base.max_key_length, keys, key_parts));
     444               0 :       my_errno=HA_ERR_UNSUPPORTED;
     445               0 :       goto err;
     446                 :     }
     447                 : 
     448                 :     /* Ensure we have space in the key buffer for transaction id's */
     449            3245 :     if (share->base.born_transactional)
     450            2618 :       share->base.max_key_length= ALIGN_SIZE(share->base.max_key_length +
     451                 :                                              MARIA_MAX_PACK_TRANSID_SIZE);
     452                 : 
     453                 :     /*
     454                 :       If page cache is not initialized, then assume we will create the
     455                 :       page_cache after the table is opened!
     456                 :       This is only used by maria_check to allow it to check/repair tables
     457                 :       with different block sizes.
     458                 :     */
     459            3245 :     if (share->base.block_size != maria_block_size &&
     460                 :         share_buff.pagecache->inited != 0)
     461                 :     {
     462               0 :       DBUG_PRINT("error", ("Wrong block size %u; Expected %u",
     463                 :                            (uint) share->base.block_size,
     464                 :                            (uint) maria_block_size));
     465               0 :       my_errno=HA_ERR_UNSUPPORTED;
     466               0 :       goto err;
     467                 :     }
     468                 : 
     469                 :     /* Correct max_file_length based on length of sizeof(off_t) */
     470            3245 :     max_data_file_length=
     471                 :       (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
     472                 :       (((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
     473                 :       (_ma_safe_mul(share->base.pack_reclength,
     474                 :                    (ulonglong) 1 << (share->base.rec_reflength*8))-1);
     475                 : 
     476            3245 :     max_key_file_length=
     477                 :       _ma_safe_mul(maria_block_size,
     478                 :                   ((ulonglong) 1 << (share->base.key_reflength*8))-1);
     479                 : #if SIZEOF_OFF_T == 4
     480                 :     set_if_smaller(max_data_file_length, INT_MAX32);
     481                 :     set_if_smaller(max_key_file_length, INT_MAX32);
     482                 : #endif
     483            3245 :     share->base.max_data_file_length=(my_off_t) max_data_file_length;
     484            3245 :     share->base.max_key_file_length=(my_off_t) max_key_file_length;
     485                 : 
     486            3245 :     if (share->options & HA_OPTION_COMPRESS_RECORD)
     487             115 :       share->base.max_key_length+=2; /* For safety */
     488                 :     /* Add space for node pointer */
     489            3245 :     share->base.max_key_length+= share->base.key_reflength;
     490                 : 
     491            3245 :     share->unique_file_name.length= strlen(name_buff);
     492            3245 :     share->index_file_name.length=  strlen(index_name);
     493            3245 :     share->data_file_name.length=   strlen(data_name);
     494            3245 :     share->open_file_name.length=   strlen(name);
     495            3245 :     if (!my_multi_malloc(MY_WME,
     496                 :                          &share,sizeof(*share),
     497                 :                          &share->state.rec_per_key_part,
     498                 :                          sizeof(double) * key_parts,
     499                 :                          &share->state.nulls_per_key_part,
     500                 :                          sizeof(long)* key_parts,
     501                 :                          &share->keyinfo,keys*sizeof(MARIA_KEYDEF),
     502                 :                          &share->uniqueinfo,uniques*sizeof(MARIA_UNIQUEDEF),
     503                 :                          &share->keyparts,
     504                 :                          (key_parts+unique_key_parts+keys+uniques) *
     505                 :                          sizeof(HA_KEYSEG),
     506                 :                          &share->columndef,
     507                 :                          (share->base.fields+1)*sizeof(MARIA_COLUMNDEF),
     508                 :                          &share->column_nr, share->base.fields*sizeof(uint16),
     509                 :                          &share->blobs,sizeof(MARIA_BLOB)*share->base.blobs,
     510                 :                          &share->unique_file_name.str,
     511                 :                          share->unique_file_name.length+1,
     512                 :                          &share->index_file_name.str,
     513                 :                          share->index_file_name.length+1,
     514                 :                          &share->data_file_name.str,
     515                 :                          share->data_file_name.length+1,
     516                 :                          &share->open_file_name.str,
     517                 :                          share->open_file_name.length+1,
     518                 :                          &share->state.key_root,keys*sizeof(my_off_t),
     519                 :                          &share->mmap_lock,sizeof(rw_lock_t),
     520                 :                          NullS))
     521            3245 :       goto err;
     522            3245 :     errpos= 4;
     523                 : 
     524            3245 :     *share=share_buff;
     525            3245 :     memcpy((char*) share->state.rec_per_key_part,
     526                 :            (char*) rec_per_key_part, sizeof(double)*key_parts);
     527            3245 :     memcpy((char*) share->state.nulls_per_key_part,
     528                 :            (char*) nulls_per_key_part, sizeof(long)*key_parts);
     529            3245 :     memcpy((char*) share->state.key_root,
     530                 :            (char*) key_root, sizeof(my_off_t)*keys);
     531            3245 :     strmov(share->unique_file_name.str, name_buff);
     532            3245 :     strmov(share->index_file_name.str, index_name);
     533            3245 :     strmov(share->data_file_name.str,  data_name);
     534            3245 :     strmov(share->open_file_name.str,  name);
     535                 : 
     536            3245 :     share->block_size= share->base.block_size;   /* Convenience */
     537                 :     {
     538            3245 :       HA_KEYSEG *pos=share->keyparts;
     539            3245 :       uint32 ftkey_nr= 1;
     540           11555 :       for (i=0 ; i < keys ; i++)
     541                 :       {
     542            8310 :         share->keyinfo[i].share= share;
     543            8310 :         disk_pos=_ma_keydef_read(disk_pos, &share->keyinfo[i]);
     544            8310 :         share->keyinfo[i].key_nr= i;
     545            8310 :         disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
     546                 :                         end_pos);
     547            8310 :         if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
     548               0 :           share->have_rtree= 1;
     549            8310 :         share->keyinfo[i].seg=pos;
     550           17609 :         for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
     551                 :         {
     552            9299 :           disk_pos=_ma_keyseg_read(disk_pos, pos);
     553            9299 :           if (pos->type == HA_KEYTYPE_TEXT ||
     554                 :               pos->type == HA_KEYTYPE_VARTEXT1 ||
     555                 :               pos->type == HA_KEYTYPE_VARTEXT2)
     556                 :           {
     557            5004 :             if (!pos->language)
     558               0 :               pos->charset=default_charset_info;
     559            5004 :             else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
     560                 :             {
     561               0 :               my_errno=HA_ERR_UNKNOWN_CHARSET;
     562               0 :               goto err;
     563                 :             }
     564                 :           }
     565            4295 :           else if (pos->type == HA_KEYTYPE_BINARY)
     566            1978 :             pos->charset= &my_charset_bin;
     567                 :         }
     568            8310 :         if (share->keyinfo[i].flag & HA_SPATIAL)
     569                 :         {
     570                 : #ifdef HAVE_SPATIAL
     571               0 :           uint sp_segs=SPDIMS*2;
     572               0 :           share->keyinfo[i].seg=pos-sp_segs;
     573               0 :           share->keyinfo[i].keysegs--;
     574               0 :           versioning= 0;
     575                 : #else
     576                 :           my_errno=HA_ERR_UNSUPPORTED;
     577                 :           goto err;
     578                 : #endif
     579                 :         }
     580            8310 :         else if (share->keyinfo[i].flag & HA_FULLTEXT)
     581                 :         {
     582               0 :           versioning= 0;
     583               0 :           DBUG_ASSERT(fulltext_keys);
     584                 :           {
     585                 :             uint k;
     586               0 :             share->keyinfo[i].seg=pos;
     587               0 :             for (k=0; k < FT_SEGS; k++)
     588                 :             {
     589               0 :               *pos= ft_keysegs[k];
     590               0 :               pos[0].language= pos[-1].language;
     591               0 :               if (!(pos[0].charset= pos[-1].charset))
     592                 :               {
     593               0 :                 my_errno=HA_ERR_CRASHED;
     594               0 :                 goto err;
     595                 :               }
     596               0 :               pos++;
     597                 :             }
     598                 :           }
     599               0 :           if (!share->ft2_keyinfo.seg)
     600                 :           {
     601               0 :             memcpy(&share->ft2_keyinfo, &share->keyinfo[i],
     602                 :                    sizeof(MARIA_KEYDEF));
     603               0 :             share->ft2_keyinfo.keysegs=1;
     604               0 :             share->ft2_keyinfo.flag=0;
     605               0 :             share->ft2_keyinfo.keylength=
     606                 :             share->ft2_keyinfo.minlength=
     607                 :             share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength;
     608               0 :             share->ft2_keyinfo.seg=pos-1;
     609               0 :             share->ft2_keyinfo.end=pos;
     610               0 :             setup_key_functions(& share->ft2_keyinfo);
     611                 :           }
     612               0 :           share->keyinfo[i].ftkey_nr= ftkey_nr++;
     613                 :         }
     614            8310 :         setup_key_functions(share->keyinfo+i);
     615            8310 :         share->keyinfo[i].end=pos;
     616            8310 :         pos->type=HA_KEYTYPE_END;                    /* End */
     617            8310 :         pos->length=share->base.rec_reflength;
     618            8310 :         pos->null_bit=0;
     619            8310 :         pos->flag=0;                                 /* For purify */
     620            8310 :         pos++;
     621                 :       }
     622            3365 :       for (i=0 ; i < uniques ; i++)
     623                 :       {
     624             120 :         disk_pos=_ma_uniquedef_read(disk_pos, &share->uniqueinfo[i]);
     625             120 :         disk_pos_assert(disk_pos + share->uniqueinfo[i].keysegs *
     626                 :                         HA_KEYSEG_SIZE, end_pos);
     627             120 :         share->uniqueinfo[i].seg=pos;
     628             360 :         for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++)
     629                 :         {
     630             240 :           disk_pos=_ma_keyseg_read(disk_pos, pos);
     631             240 :           if (pos->type == HA_KEYTYPE_TEXT ||
     632                 :               pos->type == HA_KEYTYPE_VARTEXT1 ||
     633                 :               pos->type == HA_KEYTYPE_VARTEXT2)
     634                 :           {
     635             210 :             if (!pos->language)
     636               0 :               pos->charset=default_charset_info;
     637             210 :             else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
     638                 :             {
     639               0 :               my_errno=HA_ERR_UNKNOWN_CHARSET;
     640               0 :               goto err;
     641                 :             }
     642                 :           }
     643                 :         }
     644             120 :         share->uniqueinfo[i].end=pos;
     645             120 :         pos->type=HA_KEYTYPE_END;                    /* End */
     646             120 :         pos->null_bit=0;
     647             120 :         pos->flag=0;
     648             120 :         pos++;
     649                 :       }
     650            3245 :       share->ftkeys= ftkey_nr;
     651                 :     }
     652            3245 :     share->data_file_type= share->state.header.data_file_type;
     653            3245 :     share->base_length= (BASE_ROW_HEADER_SIZE +
     654                 :                          share->base.is_nulls_extended +
     655                 :                          share->base.null_bytes +
     656                 :                          share->base.pack_bytes +
     657                 :                          test(share->options & HA_OPTION_CHECKSUM));
     658            3245 :     share->keypage_header= ((share->base.born_transactional ?
     659                 :                              LSN_STORE_SIZE + TRANSID_SIZE :
     660                 :                              0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE +
     661                 :                             KEYPAGE_USED_SIZE);
     662            3245 :     share->kfile.file= kfile;
     663                 : 
     664            3245 :     if (open_flags & HA_OPEN_COPY)
     665                 :     {
     666                 :       /*
     667                 :         this instance will be a temporary one used just to create a data
     668                 :         file for REPAIR. Don't do logging. This base information will not go
     669                 :         to disk.
     670                 :       */
     671              45 :       share->base.born_transactional= FALSE;
     672                 :     }
     673            3245 :     if (share->base.born_transactional)
     674                 :     {
     675            2592 :       share->page_type= PAGECACHE_LSN_PAGE;
     676            2592 :       if (share->state.create_rename_lsn == LSN_NEEDS_NEW_STATE_LSNS)
     677                 :       {
     678                 :         /*
     679                 :           Was repaired with maria_chk, maybe later maria_pack-ed. Some sort of
     680                 :           import into the server. It starts its existence (from the point of
     681                 :           view of the server, including server's recovery) now.
     682                 :         */
     683              94 :         if (((open_flags & HA_OPEN_FROM_SQL_LAYER) &&
     684                 :              (share->state.changed & STATE_NOT_MOVABLE)) || maria_in_recovery)
     685               0 :           _ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE,
     686                 :                                     trnman_get_min_safe_trid(), TRUE, TRUE);
     687                 :       }
     688            2498 :       else if ((!LSN_VALID(share->state.create_rename_lsn) ||
     689                 :                 !LSN_VALID(share->state.is_of_horizon) ||
     690                 :                 (cmp_translog_addr(share->state.create_rename_lsn,
     691                 :                                    share->state.is_of_horizon) > 0) ||
     692                 :                 !LSN_VALID(share->state.skip_redo_lsn) ||
     693                 :                 (cmp_translog_addr(share->state.create_rename_lsn,
     694                 :                                    share->state.skip_redo_lsn) > 0)) &&
     695                 :                !(open_flags & HA_OPEN_FOR_REPAIR))
     696                 :       {
     697                 :         /*
     698                 :           If in Recovery, it will not work. If LSN is invalid and not
     699                 :           LSN_NEEDS_NEW_STATE_LSNS, header must be corrupted.
     700                 :           In both cases, must repair.
     701                 :         */
     702               0 :         my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
     703                 :                   HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
     704               0 :         goto err;
     705                 :       }
     706                 :     }
     707                 :     else
     708             653 :       share->page_type= PAGECACHE_PLAIN_PAGE;
     709            3245 :     share->now_transactional= share->base.born_transactional;
     710                 : 
     711                 :     /* Use pack_reclength as we don't want to modify base.pack_recklength */
     712            3245 :     if (share->state.header.org_data_file_type == DYNAMIC_RECORD)
     713                 :     {
     714                 :       /* add bits used to pack data to pack_reclength for faster allocation */
     715             190 :       share->base.pack_reclength+= share->base.pack_bytes;
     716             190 :       share->base.extra_rec_buff_size=
     717                 :         (ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER) + MARIA_SPLIT_LENGTH +
     718                 :          MARIA_REC_BUFF_OFFSET);
     719                 :     }
     720            3245 :     if (share->data_file_type == COMPRESSED_RECORD)
     721                 :     {
     722                 :       /* Need some extra bytes for decode_bytes */
     723             115 :       share->base.extra_rec_buff_size+= 7;
     724                 :     }
     725            3245 :     share->base.default_rec_buff_size= max(share->base.pack_reclength +
     726                 :                                            share->base.extra_rec_buff_size,
     727                 :                                            share->base.max_key_length);
     728                 : 
     729            3245 :     disk_pos_assert(disk_pos + share->base.fields *MARIA_COLUMNDEF_SIZE,
     730                 :                     end_pos);
     731           14260 :     for (i= j= 0 ; i < share->base.fields ; i++)
     732                 :     {
     733           11015 :       disk_pos=_ma_columndef_read(disk_pos,&share->columndef[i]);
     734           11015 :       share->columndef[i].pack_type=0;
     735           11015 :       share->columndef[i].huff_tree=0;
     736           11015 :       if (share->columndef[i].type == FIELD_BLOB)
     737                 :       {
     738            1885 :         share->blobs[j].pack_length=
     739                 :           share->columndef[i].length-portable_sizeof_char_ptr;
     740            1885 :         share->blobs[j].offset= share->columndef[i].offset;
     741            1885 :         j++;
     742                 :       }
     743                 :     }
     744            3245 :     share->columndef[i].type= FIELD_LAST;    /* End marker */
     745            3245 :     disk_pos= _ma_column_nr_read(disk_pos, share->column_nr,
     746                 :                                  share->base.fields);
     747                 : 
     748            3245 :     if ((share->data_file_type == BLOCK_RECORD ||
     749                 :          share->data_file_type == COMPRESSED_RECORD))
     750                 :     {
     751            2887 :       if (_ma_open_datafile(&info, share, name, -1))
     752            2887 :         goto err;
     753            2887 :       data_file= info.dfile.file;
     754                 :     }
     755            3245 :     errpos= 5;
     756                 : 
     757            3245 :     if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
     758               0 :       share->options|= HA_OPTION_DELAY_KEY_WRITE;
     759            3245 :     if (mode == O_RDONLY)
     760            1421 :       share->options|= HA_OPTION_READ_ONLY_DATA;
     761            3245 :     share->is_log_table= FALSE;
     762                 : 
     763            3245 :     if (open_flags & HA_OPEN_TMP_TABLE)
     764                 :     {
     765               0 :       share->options|= HA_OPTION_TMP_TABLE;
     766               0 :       share->temporary= share->delay_key_write= 1;
     767               0 :       share->write_flag=MYF(MY_NABP);
     768               0 :       share->w_locks++;                      /* We don't have to update status */
     769               0 :       share->tot_locks++;
     770                 :     }
     771                 : 
     772            3245 :     _ma_set_index_pagecache_callbacks(&share->kfile, share);
     773            3245 :     share->this_process=(ulong) getpid();
     774                 : #ifdef EXTERNAL_LOCKING
     775                 :     share->last_process= share->state.process;
     776                 : #endif
     777            3245 :     share->base.key_parts=key_parts;
     778            3245 :     share->base.all_key_parts=key_parts+unique_key_parts;
     779            3245 :     if (!(share->last_version=share->state.version))
     780               0 :       share->last_version=1;                 /* Safety */
     781            3245 :     share->rec_reflength=share->base.rec_reflength; /* May be changed */
     782            3245 :     share->base.margin_key_file_length=(share->base.max_key_file_length -
     783                 :                                         (keys ? MARIA_INDEX_BLOCK_MARGIN *
     784                 :                                          share->block_size * keys : 0));
     785            3245 :     share->block_size= share->base.block_size;
     786                 :     my_afree(disk_cache);
     787            3245 :     _ma_setup_functions(share);
     788            3245 :     if ((*share->once_init)(share, info.dfile.file))
     789            3245 :       goto err;
     790            3245 :     if (share->now_transactional)
     791                 :     {
     792                 :       /* Setup initial state that is visible for all */
     793                 :       MARIA_STATE_HISTORY_CLOSED *history;
     794            2592 :       if ((history= (MARIA_STATE_HISTORY_CLOSED *)
     795                 :            hash_search(&maria_stored_state,
     796                 :                        (uchar*) &share->state.create_rename_lsn, 0)))
     797                 :       {
     798                 :         /*
     799                 :           Move history from hash to share. This is safe to do as we
     800                 :           don't have a lock on share->intern_lock.
     801                 :         */
     802               0 :         share->state_history=
     803                 :           _ma_remove_not_visible_states(history->state_history, 0, 0);
     804               0 :         history->state_history= 0;
     805               0 :         (void) hash_delete(&maria_stored_state, (uchar*) history);
     806                 :       }
     807                 :       else
     808                 :       {
     809                 :         /* Table is not part of any active transaction; Create new history */
     810            2592 :         if (!(share->state_history= (MARIA_STATE_HISTORY *)
     811                 :               my_malloc(sizeof(*share->state_history), MYF(MY_WME))))
     812            2592 :           goto err;
     813            2592 :         share->state_history->trid= 0;          /* Visible by all */
     814            2592 :         share->state_history->state= share->state.state;
     815            2592 :         share->state_history->next= 0;
     816                 :       }
     817                 :     }
     818                 : #ifdef THREAD
     819            3245 :     thr_lock_init(&share->lock);
     820            3245 :     pthread_mutex_init(&share->intern_lock, MY_MUTEX_INIT_FAST);
     821            3245 :     pthread_mutex_init(&share->key_del_lock, MY_MUTEX_INIT_FAST);
     822            3245 :     pthread_cond_init(&share->key_del_cond, 0);
     823            3245 :     pthread_mutex_init(&share->close_lock, MY_MUTEX_INIT_FAST);
     824           11555 :     for (i=0; i<keys; i++)
     825            8310 :       VOID(my_rwlock_init(&share->keyinfo[i].root_lock, NULL));
     826            3245 :     VOID(my_rwlock_init(&share->mmap_lock, NULL));
     827                 : 
     828            3245 :     share->row_is_visible= _ma_row_visible_always;
     829            3245 :     share->lock.get_status= _ma_reset_update_flag;
     830            3245 :     if (!thr_lock_inited)
     831                 :     {
     832                 :       /* Probably a single threaded program; Don't use concurrent inserts */
     833            3102 :       maria_concurrent_insert=0;
     834                 :     }
     835             143 :     else if (maria_concurrent_insert)
     836                 :     {
     837             143 :       share->non_transactional_concurrent_insert=
     838                 :         ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
     839                 :                             HA_OPTION_COMPRESS_RECORD |
     840                 :                             HA_OPTION_TEMP_COMPRESS_RECORD)) ||
     841                 :          (open_flags & HA_OPEN_TMP_TABLE) ||
     842                 :          share->data_file_type == BLOCK_RECORD ||
     843                 :          share->have_rtree) ? 0 : 1;
     844             143 :       if (share->non_transactional_concurrent_insert ||
     845                 :           (!share->temporary && share->now_transactional && versioning))
     846                 :       {
     847             143 :         share->lock_key_trees= 1;
     848             143 :         if (share->data_file_type == BLOCK_RECORD)
     849                 :         {
     850             143 :           DBUG_ASSERT(share->now_transactional);
     851             143 :           share->have_versioning= 1;
     852             143 :           share->row_is_visible=     _ma_row_visible_transactional_table;
     853             143 :           share->lock.get_status=    _ma_block_get_status;
     854             143 :           share->lock.update_status= _ma_block_update_status;
     855             143 :           share->lock.check_status=  _ma_block_check_status;
     856                 :           /*
     857                 :             We can for the moment only allow multiple concurrent inserts
     858                 :             only if there is no auto-increment key.  To lift this restriction
     859                 :             we have to:
     860                 :             - Extend statement base replication to support auto-increment
     861                 :             intervalls.
     862                 :             - Fix that we allocate auto-increment in intervals and that
     863                 :               it's properly reset if the interval was not used
     864                 :           */
     865             143 :           share->lock.allow_multiple_concurrent_insert=
     866                 :             share->base.auto_key == 0;
     867             143 :           share->lock_restore_status= 0;
     868                 :         }
     869                 :         else
     870                 :         {
     871               0 :           share->row_is_visible=      _ma_row_visible_non_transactional_table;
     872               0 :           share->lock.get_status=     _ma_get_status;
     873               0 :           share->lock.copy_status=    _ma_copy_status;
     874               0 :           share->lock.update_status=  _ma_update_status;
     875               0 :           share->lock.restore_status= _ma_restore_status;
     876               0 :           share->lock.check_status=   _ma_check_status;
     877               0 :           share->lock_restore_status= _ma_restore_status;
     878                 :         }
     879                 :       }
     880                 :     }
     881                 : #endif
     882                 :     /*
     883                 :       Memory mapping can only be requested after initializing intern_lock.
     884                 :     */
     885            3245 :     if (open_flags & HA_OPEN_MMAP)
     886                 :     {
     887               0 :       info.s= share;
     888               0 :       maria_extra(&info, HA_EXTRA_MMAP, 0);
     889                 :     }
     890                 :   }
     891                 :   else
     892                 :   {
     893               0 :     share= old_info->s;
     894               0 :     if (share->data_file_type == BLOCK_RECORD)
     895               0 :       data_file= share->bitmap.file.file;       /* Only opened once */
     896                 :   }
     897                 : 
     898            3245 :   if (!(m_info= maria_clone_internal(share, name, mode, data_file)))
     899            3245 :     goto err;
     900                 : 
     901            3245 :   pthread_mutex_unlock(&THR_LOCK_maria);
     902            3245 :   DBUG_RETURN(m_info);
     903                 : 
     904             105 : err:
     905             105 :   save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
     906             105 :   if ((save_errno == HA_ERR_CRASHED) ||
     907                 :       (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
     908                 :       (save_errno == HA_ERR_CRASHED_ON_REPAIR))
     909                 :   {
     910                 :     LEX_STRING tmp_name;
     911               0 :     tmp_name.str= (char*) name;
     912               0 :     tmp_name.length= strlen(name);
     913               0 :     _ma_report_error(save_errno, &tmp_name);
     914                 :   }
     915             105 :   if (save_errno == HA_ERR_OLD_FILE) /* uuid is different ? */
     916               0 :     save_errno= HA_ERR_CRASHED_ON_USAGE; /* the code to trigger auto-repair */
     917             105 :   switch (errpos) {
     918                 :   case 5:
     919               0 :     if (data_file >= 0)
     920               0 :       VOID(my_close(data_file, MYF(0)));
     921               0 :     if (old_info)
     922               0 :       break;                                    /* Don't remove open table */
     923               0 :     (*share->once_end)(share);
     924                 :     /* fall through */
     925                 :   case 4:
     926               0 :     my_free(share,MYF(0));
     927                 :     /* fall through */
     928                 :   case 3:
     929                 :     /* fall through */
     930                 :   case 2:
     931                 :     my_afree(disk_cache);
     932                 :     /* fall through */
     933                 :   case 1:
     934               0 :     VOID(my_close(kfile,MYF(0)));
     935                 :     /* fall through */
     936                 :   case 0:
     937                 :   default:
     938                 :     break;
     939                 :   }
     940             105 :   pthread_mutex_unlock(&THR_LOCK_maria);
     941             105 :   my_errno= save_errno;
     942             105 :   DBUG_RETURN (NULL);
     943                 : } /* maria_open */
     944                 : 
     945                 : 
     946                 : /*
     947                 :   Reallocate a buffer, if the current buffer is not large enough
     948                 : */
     949                 : 
     950                 : my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size,
     951                 :                          size_t new_size)
     952          254167 : {
     953          254167 :   if (*old_size < new_size)
     954                 :   {
     955                 :     uchar *addr;
     956            5777 :     if (!(addr= (uchar*) my_realloc(*old_addr, new_size,
     957                 :                                     MYF(MY_ALLOW_ZERO_PTR))))
     958               0 :       return 1;
     959            5777 :     *old_addr= addr;
     960            5777 :     *old_size= new_size;
     961                 :   }
     962          254167 :   return 0;
     963                 : }
     964                 : 
     965                 : 
     966                 : ulonglong _ma_safe_mul(ulonglong a, ulonglong b)
     967            6203 : {
     968            6203 :   ulonglong max_val= ~ (ulonglong) 0;           /* my_off_t is unsigned */
     969                 : 
     970            6203 :   if (!a || max_val / a < b)
     971               0 :     return max_val;
     972            6203 :   return a*b;
     973                 : }
     974                 : 
     975                 :         /* Set up functions in structs */
     976                 : 
     977                 : void _ma_setup_functions(register MARIA_SHARE *share)
     978            3319 : {
     979            3319 :   share->once_init=          maria_once_init_dummy;
     980            3319 :   share->once_end=           maria_once_end_dummy;
     981            3319 :   share->init=            maria_scan_init_dummy;
     982            3319 :   share->end=             maria_scan_end_dummy;
     983            3319 :   share->scan_init=          maria_scan_init_dummy;/* Compat. dummy function */
     984            3319 :   share->scan_end=           maria_scan_end_dummy;/* Compat. dummy function */
     985            3319 :   share->scan_remember_pos=  _ma_def_scan_remember_pos;
     986            3319 :   share->scan_restore_pos=   _ma_def_scan_restore_pos;
     987                 : 
     988            3319 :   share->write_record_init=  _ma_write_init_default;
     989            3319 :   share->write_record_abort= _ma_write_abort_default;
     990            3319 :   share->keypos_to_recpos=   _ma_transparent_recpos;
     991            3319 :   share->recpos_to_keypos=   _ma_transparent_recpos;
     992                 : 
     993            3319 :   switch (share->data_file_type) {
     994                 :   case COMPRESSED_RECORD:
     995             130 :     share->read_record= _ma_read_pack_record;
     996             130 :     share->scan= _ma_read_rnd_pack_record;
     997             130 :     share->once_init= _ma_once_init_pack_row;
     998             130 :     share->once_end=  _ma_once_end_pack_row;
     999                 :     /*
    1000                 :       Calculate checksum according to data in the original, not compressed,
    1001                 :       row.
    1002                 :     */
    1003             160 :     if (share->state.header.org_data_file_type == STATIC_RECORD &&
    1004                 :         ! (share->options & HA_OPTION_NULL_FIELDS))
    1005              30 :       share->calc_checksum= _ma_static_checksum;
    1006                 :     else
    1007             100 :       share->calc_checksum= _ma_checksum;
    1008             130 :     share->calc_write_checksum= share->calc_checksum;
    1009             130 :     break;
    1010                 :   case DYNAMIC_RECORD:
    1011             184 :     share->read_record= _ma_read_dynamic_record;
    1012             184 :     share->scan= _ma_read_rnd_dynamic_record;
    1013             184 :     share->delete_record= _ma_delete_dynamic_record;
    1014             184 :     share->compare_record= _ma_cmp_dynamic_record;
    1015             184 :     share->compare_unique= _ma_cmp_dynamic_unique;
    1016             184 :     share->calc_checksum= share->calc_write_checksum= _ma_checksum;
    1017             184 :     if (share->base.blobs)
    1018                 :     {
    1019              21 :       share->update_record= _ma_update_blob_record;
    1020              21 :       share->write_record= _ma_write_blob_record;
    1021                 :     }
    1022                 :     else
    1023                 :     {
    1024             163 :       share->write_record= _ma_write_dynamic_record;
    1025             163 :       share->update_record= _ma_update_dynamic_record;
    1026                 :     }
    1027                 :     break;
    1028                 :   case STATIC_RECORD:
    1029             200 :     share->read_record=      _ma_read_static_record;
    1030             200 :     share->scan=             _ma_read_rnd_static_record;
    1031             200 :     share->delete_record=    _ma_delete_static_record;
    1032             200 :     share->compare_record=   _ma_cmp_static_record;
    1033             200 :     share->update_record=    _ma_update_static_record;
    1034             200 :     share->write_record=     _ma_write_static_record;
    1035             200 :     share->compare_unique=   _ma_cmp_static_unique;
    1036             200 :     share->keypos_to_recpos= _ma_static_keypos_to_recpos;
    1037             200 :     share->recpos_to_keypos= _ma_static_recpos_to_keypos;
    1038             358 :     if (share->state.header.org_data_file_type == STATIC_RECORD &&
    1039                 :         ! (share->options & HA_OPTION_NULL_FIELDS))
    1040             158 :       share->calc_checksum= _ma_static_checksum;
    1041                 :     else
    1042              42 :       share->calc_checksum= _ma_checksum;
    1043                 :     break;
    1044                 :   case BLOCK_RECORD:
    1045            2805 :     share->once_init= _ma_once_init_block_record;
    1046            2805 :     share->once_end=  _ma_once_end_block_record;
    1047            2805 :     share->init=      _ma_init_block_record;
    1048            2805 :     share->end=       _ma_end_block_record;
    1049            2805 :     share->write_record_init= _ma_write_init_block_record;
    1050            2805 :     share->write_record_abort= _ma_write_abort_block_record;
    1051            2805 :     share->scan_init=   _ma_scan_init_block_record;
    1052            2805 :     share->scan_end=    _ma_scan_end_block_record;
    1053            2805 :     share->scan=        _ma_scan_block_record;
    1054            2805 :     share->scan_remember_pos=  _ma_scan_remember_block_record;
    1055            2805 :     share->scan_restore_pos=   _ma_scan_restore_block_record;
    1056            2805 :     share->read_record= _ma_read_block_record;
    1057            2805 :     share->delete_record= _ma_delete_block_record;
    1058            2805 :     share->compare_record= _ma_compare_block_record;
    1059            2805 :     share->update_record= _ma_update_block_record;
    1060            2805 :     share->write_record=  _ma_write_block_record;
    1061            2805 :     share->compare_unique= _ma_cmp_block_unique;
    1062            2805 :     share->calc_checksum= _ma_checksum;
    1063            2805 :     share->keypos_to_recpos= _ma_transaction_keypos_to_recpos;
    1064            2805 :     share->recpos_to_keypos= _ma_transaction_recpos_to_keypos;
    1065                 : 
    1066                 :     /*
    1067                 :       write_block_record() will calculate the checksum; Tell maria_write()
    1068                 :       that it doesn't have to do this.
    1069                 :     */
    1070            2805 :     share->calc_write_checksum= 0;
    1071                 :     break;
    1072                 :   }
    1073            3319 :   share->file_read= _ma_nommap_pread;
    1074            3319 :   share->file_write= _ma_nommap_pwrite;
    1075            3319 :   share->calc_check_checksum= share->calc_checksum;
    1076                 : 
    1077            3319 :   if (!(share->options & HA_OPTION_CHECKSUM) &&
    1078                 :       share->data_file_type != COMPRESSED_RECORD)
    1079             584 :     share->calc_checksum= share->calc_write_checksum= 0;
    1080                 :   return;
    1081                 : }
    1082                 : 
    1083                 : 
    1084                 : static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
    1085            8310 : {
    1086            8310 :   if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
    1087                 :   {
    1088                 : #ifdef HAVE_RTREE_KEYS
    1089               0 :     keyinfo->ck_insert = maria_rtree_insert;
    1090               0 :     keyinfo->ck_delete = maria_rtree_delete;
    1091                 : #else
    1092                 :     DBUG_ASSERT(0); /* maria_open should check it never happens */
    1093                 : #endif
    1094                 :   }
    1095                 :   else
    1096                 :   {
    1097            8310 :     keyinfo->ck_insert = _ma_ck_write;
    1098            8310 :     keyinfo->ck_delete = _ma_ck_delete;
    1099                 :   }
    1100            8310 :   if (keyinfo->flag & HA_SPATIAL)
    1101               0 :     keyinfo->make_key= _ma_sp_make_key;
    1102                 :   else
    1103            8310 :     keyinfo->make_key= _ma_make_key;
    1104                 : 
    1105            8310 :   if (keyinfo->flag & HA_BINARY_PACK_KEY)
    1106                 :   {                                             /* Simple prefix compression */
    1107             447 :     keyinfo->bin_search= _ma_seq_search;
    1108             447 :     keyinfo->get_key= _ma_get_binary_pack_key;
    1109             447 :     keyinfo->skip_key= _ma_skip_binary_pack_key;
    1110             447 :     keyinfo->pack_key= _ma_calc_bin_pack_key_length;
    1111             447 :     keyinfo->store_key= _ma_store_bin_pack_key;
    1112                 :   }
    1113            7863 :   else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
    1114                 :   {
    1115            2147 :     keyinfo->get_key=  _ma_get_pack_key;
    1116            2147 :     keyinfo->skip_key= _ma_skip_pack_key;
    1117            2147 :     if (keyinfo->seg[0].flag & HA_PACK_KEY)
    1118                 :     {                                           /* Prefix compression */
    1119                 :       /*
    1120                 :         _ma_prefix_search() compares end-space against ASCII blank (' ').
    1121                 :         It cannot be used for character sets, that do not encode the
    1122                 :         blank character like ASCII does. UCS2 is an example. All
    1123                 :         character sets with a fixed width > 1 or a mimimum width > 1
    1124                 :         cannot represent blank like ASCII does. In these cases we have
    1125                 :         to use _ma_seq_search() for the search.
    1126                 :       */
    1127             681 :       if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
    1128                 :           (keyinfo->seg->flag & HA_NULL_PART) ||
    1129                 :           keyinfo->seg->charset->mbminlen > 1)
    1130              45 :         keyinfo->bin_search= _ma_seq_search;
    1131                 :       else
    1132             591 :         keyinfo->bin_search= _ma_prefix_search;
    1133             636 :       keyinfo->pack_key= _ma_calc_var_pack_key_length;
    1134             636 :       keyinfo->store_key= _ma_store_var_pack_key;
    1135                 :     }
    1136                 :     else
    1137                 :     {
    1138            1511 :       keyinfo->bin_search= _ma_seq_search;
    1139            1511 :       keyinfo->pack_key= _ma_calc_var_key_length; /* Variable length key */
    1140            1511 :       keyinfo->store_key= _ma_store_static_key;
    1141                 :     }
    1142                 :   }
    1143                 :   else
    1144                 :   {
    1145            5716 :     keyinfo->bin_search= _ma_bin_search;
    1146            5716 :     keyinfo->get_key= _ma_get_static_key;
    1147            5716 :     keyinfo->skip_key= _ma_skip_static_key;
    1148            5716 :     keyinfo->pack_key= _ma_calc_static_key_length;
    1149            5716 :     keyinfo->store_key= _ma_store_static_key;
    1150                 :   }
    1151                 : 
    1152                 :   /* set keyinfo->write_comp_flag */
    1153            8310 :   if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
    1154               0 :     keyinfo->write_comp_flag=SEARCH_BIGGER; /* Put after same key */
    1155            8310 :   else if (keyinfo->flag & ( HA_NOSAME | HA_FULLTEXT))
    1156                 :   {
    1157            3115 :     keyinfo->write_comp_flag= SEARCH_FIND | SEARCH_UPDATE; /* No duplicates */
    1158            3115 :     if (keyinfo->flag & HA_NULL_ARE_EQUAL)
    1159               0 :       keyinfo->write_comp_flag|= SEARCH_NULL_ARE_EQUAL;
    1160                 :   }
    1161                 :   else
    1162            5195 :     keyinfo->write_comp_flag= SEARCH_SAME; /* Keys in rec-pos order */
    1163            8310 :   keyinfo->write_comp_flag|= SEARCH_INSERT;
    1164                 :   return;
    1165                 : }
    1166                 : 
    1167                 : 
    1168                 : /**
    1169                 :    @brief Function to save and store the header in the index file (.MYI)
    1170                 : 
    1171                 :    Operates under MARIA_SHARE::intern_lock if requested.
    1172                 :    Sets MARIA_SHARE::MARIA_STATE_INFO::is_of_horizon if transactional table.
    1173                 :    Then calls _ma_state_info_write_sub().
    1174                 : 
    1175                 :    @param  share           table
    1176                 :    @param  pWrite          bitmap: if 1 (MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET)
    1177                 :                            is set my_pwrite() is used otherwise my_write();
    1178                 :                            if 2 (MA_STATE_INFO_WRITE_FULL_INFO) is set, info
    1179                 :                            about keys is written (should only be needed
    1180                 :                            after ALTER TABLE ENABLE/DISABLE KEYS, and
    1181                 :                            REPAIR/OPTIMIZE); if 4 (MA_STATE_INFO_WRITE_LOCK)
    1182                 :                            is set, MARIA_SHARE::intern_lock is taken.
    1183                 : 
    1184                 :    @return Operation status
    1185                 :      @retval 0      OK
    1186                 :      @retval 1      Error
    1187                 : */
    1188                 : 
    1189                 : uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
    1190            1028 : {
    1191                 :   uint res;
    1192            1028 :   if (share->options & HA_OPTION_READ_ONLY_DATA)
    1193               7 :     return 0;
    1194                 : 
    1195            1021 :   if (pWrite & MA_STATE_INFO_WRITE_LOCK)
    1196              12 :     pthread_mutex_lock(&share->intern_lock);
    1197            1009 :   else if (maria_multi_threaded)
    1198                 :   {
    1199               0 :     safe_mutex_assert_owner(&share->intern_lock);
    1200                 :   }
    1201            1021 :   if (share->base.born_transactional && translog_status == TRANSLOG_OK &&
    1202                 :       !maria_in_recovery)
    1203                 :   {
    1204                 :     /*
    1205                 :       In a recovery, we want to set is_of_horizon to the LSN of the last
    1206                 :       record executed by Recovery, not the current EOF of the log (which
    1207                 :       is too new). Recovery does it by itself.
    1208                 :     */
    1209             295 :     share->state.is_of_horizon= translog_get_horizon();
    1210             295 :     DBUG_PRINT("info", ("is_of_horizon set to LSN (%lu,0x%lx)",
    1211                 :                         LSN_IN_PARTS(share->state.is_of_horizon)));
    1212                 :   }
    1213            1021 :   res= _ma_state_info_write_sub(share->kfile.file, &share->state, pWrite);
    1214            1021 :   if (pWrite & MA_STATE_INFO_WRITE_LOCK)
    1215              12 :     pthread_mutex_unlock(&share->intern_lock);
    1216            1021 :   share->changed= 0;
    1217            1021 :   return res;
    1218                 : }
    1219                 : 
    1220                 : 
    1221                 : /**
    1222                 :    @brief Function to save and store the header in the index file (.MYI).
    1223                 : 
    1224                 :    Shortcut to use instead of _ma_state_info_write() when appropriate.
    1225                 : 
    1226                 :    @param  file            descriptor of the index file to write
    1227                 :    @param  state           state information to write to the file
    1228                 :    @param  pWrite          bitmap: if 1 (MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET)
    1229                 :                            is set my_pwrite() is used otherwise my_write();
    1230                 :                            if 2 (MA_STATE_INFO_WRITE_FULL_INFO) is set, info
    1231                 :                            about keys is written (should only be needed
    1232                 :                            after ALTER TABLE ENABLE/DISABLE KEYS, and
    1233                 :                            REPAIR/OPTIMIZE).
    1234                 : 
    1235                 :    @notes
    1236                 :      For transactional multiuser tables, this function is called
    1237                 :      with intern_lock & translog_lock or when the last thread who
    1238                 :      is using the table is closing it.
    1239                 :      Because of the translog_lock we don't need to have a lock on
    1240                 :      key_del_lock.
    1241                 : 
    1242                 :    @return Operation status
    1243                 :      @retval 0      OK
    1244                 :      @retval 1      Error
    1245                 : */
    1246                 : 
    1247                 : uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite)
    1248          129108 : {
    1249                 :   uchar  buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE];
    1250          129108 :   uchar *ptr=buff;
    1251          129108 :   uint  i, keys= (uint) state->header.keys;
    1252                 :   size_t res;
    1253          129108 :   DBUG_ENTER("_ma_state_info_write_sub");
    1254                 : 
    1255          129108 :   memcpy_fixed(ptr,&state->header,sizeof(state->header));
    1256          129108 :   ptr+=sizeof(state->header);
    1257                 : 
    1258                 :   /* open_count must be first because of _ma_mark_file_changed ! */
    1259          129108 :   mi_int2store(ptr,state->open_count);                       ptr+= 2;
    1260                 :   /* changed must be second, because of _ma_mark_file_crashed */
    1261          129108 :   mi_int2store(ptr,state->changed);                  ptr+= 2;
    1262                 : 
    1263                 :   /*
    1264                 :     If you change the offset of these LSNs, note that some functions do a
    1265                 :     direct write of them without going through this function.
    1266                 :   */
    1267          129108 :   lsn_store(ptr, state->create_rename_lsn);          ptr+= LSN_STORE_SIZE;
    1268          129108 :   lsn_store(ptr, state->is_of_horizon);                      ptr+= LSN_STORE_SIZE;
    1269          129108 :   lsn_store(ptr, state->skip_redo_lsn);                      ptr+= LSN_STORE_SIZE;
    1270          129108 :   mi_rowstore(ptr,state->state.records);             ptr+= 8;
    1271          129108 :   mi_rowstore(ptr,state->state.del);                 ptr+= 8;
    1272          129108 :   mi_rowstore(ptr,state->split);                     ptr+= 8;
    1273          129108 :   mi_sizestore(ptr,state->dellink);                  ptr+= 8;
    1274          129108 :   mi_sizestore(ptr,state->first_bitmap_with_space);  ptr+= 8;
    1275          129108 :   mi_sizestore(ptr,state->state.key_file_length);    ptr+= 8;
    1276          129108 :   mi_sizestore(ptr,state->state.data_file_length);   ptr+= 8;
    1277          129108 :   mi_sizestore(ptr,state->state.empty);                      ptr+= 8;
    1278          129108 :   mi_sizestore(ptr,state->state.key_empty);          ptr+= 8;
    1279          129108 :   mi_int8store(ptr,state->auto_increment);           ptr+= 8;
    1280          129108 :   mi_int8store(ptr,(ulonglong) state->state.checksum);       ptr+= 8;
    1281          129108 :   mi_int8store(ptr,state->create_trid);                      ptr+= 8;
    1282          129108 :   mi_int4store(ptr,state->status);                   ptr+= 4;
    1283          129108 :   mi_int4store(ptr,state->update_count);             ptr+= 4;
    1284          129108 :   *ptr++= state->sortkey;
    1285          129108 :   *ptr++= 0;                                    /* Reserved */
    1286          129108 :   ptr+= state->state_diff_length;
    1287                 : 
    1288          861039 :   for (i=0; i < keys; i++)
    1289                 :   {
    1290          731931 :     mi_sizestore(ptr,state->key_root[i]);            ptr+= 8;
    1291                 :   }
    1292          129108 :   mi_sizestore(ptr,state->key_del);                  ptr+= 8;
    1293          129108 :   if (pWrite & MA_STATE_INFO_WRITE_FULL_INFO)       /* From maria_chk */
    1294                 :   {
    1295             680 :     uint key_parts= mi_uint2korr(state->header.key_parts);
    1296             680 :     mi_int4store(ptr,state->sec_index_changed);      ptr+= 4;
    1297             680 :     mi_int4store(ptr,state->sec_index_used);         ptr+= 4;
    1298             680 :     mi_int4store(ptr,state->version);                        ptr+= 4;
    1299             680 :     mi_int8store(ptr,state->key_map);                        ptr+= 8;
    1300             680 :     mi_int8store(ptr,(ulonglong) state->create_time);        ptr+= 8;
    1301             680 :     mi_int8store(ptr,(ulonglong) state->recover_time);       ptr+= 8;
    1302             680 :     mi_int8store(ptr,(ulonglong) state->check_time); ptr+= 8;
    1303             680 :     mi_sizestore(ptr, state->records_at_analyze);    ptr+= 8;
    1304                 :     /* reserve place for some information per key */
    1305             680 :     bzero(ptr, keys*4);                                 ptr+= keys*4;
    1306            2498 :     for (i=0 ; i < key_parts ; i++)
    1307                 :     {
    1308            1818 :       float8store(ptr, state->rec_per_key_part[i]);          ptr+= 8;
    1309            1818 :       mi_int4store(ptr, state->nulls_per_key_part[i]);  ptr+= 4;
    1310                 :     }
    1311                 :   }
    1312                 : 
    1313          129108 :   res= (pWrite & MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET) ?
    1314                 :     my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
    1315                 :               MYF(MY_NABP | MY_THREADSAFE)) :
    1316                 :     my_write(file,  buff, (size_t) (ptr-buff),
    1317                 :              MYF(MY_NABP));
    1318          129108 :   DBUG_RETURN(res != 0);
    1319                 : }
    1320                 : 
    1321                 : 
    1322                 : static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
    1323            3245 : {
    1324                 :   uint i,keys,key_parts;
    1325            3245 :   memcpy_fixed(&state->header,ptr, sizeof(state->header));
    1326            3245 :   ptr+= sizeof(state->header);
    1327            3245 :   keys= (uint) state->header.keys;
    1328            3245 :   key_parts= mi_uint2korr(state->header.key_parts);
    1329                 : 
    1330            3245 :   state->open_count = mi_uint2korr(ptr);             ptr+= 2;
    1331            3245 :   state->changed= mi_uint2korr(ptr);                 ptr+= 2;
    1332            3245 :   state->create_rename_lsn= lsn_korr(ptr);           ptr+= LSN_STORE_SIZE;
    1333            3245 :   state->is_of_horizon= lsn_korr(ptr);                       ptr+= LSN_STORE_SIZE;
    1334            3245 :   state->skip_redo_lsn= lsn_korr(ptr);                       ptr+= LSN_STORE_SIZE;
    1335            3245 :   state->state.records= mi_rowkorr(ptr);             ptr+= 8;
    1336            3245 :   state->state.del = mi_rowkorr(ptr);                        ptr+= 8;
    1337            3245 :   state->split       = mi_rowkorr(ptr);                      ptr+= 8;
    1338            3245 :   state->dellink= mi_sizekorr(ptr);                  ptr+= 8;
    1339            3245 :   state->first_bitmap_with_space= mi_sizekorr(ptr);  ptr+= 8;
    1340            3245 :   state->state.key_file_length = mi_sizekorr(ptr);   ptr+= 8;
    1341            3245 :   state->state.data_file_length= mi_sizekorr(ptr);   ptr+= 8;
    1342            3245 :   state->state.empty = mi_sizekorr(ptr);             ptr+= 8;
    1343            3245 :   state->state.key_empty= mi_sizekorr(ptr);          ptr+= 8;
    1344            3245 :   state->auto_increment=mi_uint8korr(ptr);           ptr+= 8;
    1345            3245 :   state->state.checksum=(ha_checksum) mi_uint8korr(ptr);ptr+= 8;
    1346            3245 :   state->create_trid= mi_uint8korr(ptr);             ptr+= 8;
    1347            3245 :   state->status = mi_uint4korr(ptr);                 ptr+= 4;
    1348            3245 :   state->update_count=mi_uint4korr(ptr);             ptr+= 4;
    1349            3245 :   state->sortkey=                                    (uint) *ptr++;
    1350            3245 :   ptr++;                                                /* reserved */
    1351                 : 
    1352            3245 :   ptr+= state->state_diff_length;
    1353                 : 
    1354           11555 :   for (i=0; i < keys; i++)
    1355                 :   {
    1356            8310 :     state->key_root[i]= mi_sizekorr(ptr);            ptr+= 8;
    1357                 :   }
    1358            3245 :   state->key_del= mi_sizekorr(ptr);                  ptr+= 8;
    1359            3245 :   state->sec_index_changed = mi_uint4korr(ptr);      ptr+= 4;
    1360            3245 :   state->sec_index_used =    mi_uint4korr(ptr);      ptr+= 4;
    1361            3245 :   state->version     = mi_uint4korr(ptr);            ptr+= 4;
    1362            3245 :   state->key_map     = mi_uint8korr(ptr);            ptr+= 8;
    1363            3245 :   state->create_time = (time_t) mi_sizekorr(ptr);    ptr+= 8;
    1364            3245 :   state->recover_time =(time_t) mi_sizekorr(ptr);    ptr+= 8;
    1365            3245 :   state->check_time =  (time_t) mi_sizekorr(ptr);    ptr+= 8;
    1366            3245 :   state->records_at_analyze=    mi_sizekorr(ptr);    ptr+= 8;
    1367            3245 :   ptr+= keys * 4;                               /* Skip reserved bytes */
    1368           12544 :   for (i=0 ; i < key_parts ; i++)
    1369                 :   {
    1370            9299 :     float8get(state->rec_per_key_part[i], ptr);              ptr+= 8;
    1371            9299 :     state->nulls_per_key_part[i]= mi_uint4korr(ptr); ptr+= 4;
    1372                 :   }
    1373            3245 :   return ptr;
    1374                 : }
    1375                 : 
    1376                 : 
    1377                 : /**
    1378                 :    @brief Fills the state by reading its copy on disk.
    1379                 : 
    1380                 :    Should not be called for transactional tables, as their state on disk is
    1381                 :    rarely current and so is often misleading for a reader.
    1382                 :    Does nothing in single user mode.
    1383                 : 
    1384                 :    @param  file            file to read from
    1385                 :    @param  state           state which will be filled
    1386                 : */
    1387                 : 
    1388                 : uint _ma_state_info_read_dsk(File file __attribute__((unused)),
    1389                 :                              MARIA_STATE_INFO *state __attribute__((unused)))
    1390            2403 : {
    1391                 : #ifdef EXTERNAL_LOCKING
    1392                 :   uchar buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE];
    1393                 : 
    1394                 :   /* trick to detect transactional tables */
    1395                 :   DBUG_ASSERT(state->create_rename_lsn == LSN_IMPOSSIBLE);
    1396                 :   if (!maria_single_user)
    1397                 :   {
    1398                 :     if (my_pread(file, buff, state->state_length, 0L, MYF(MY_NABP)))
    1399                 :       return 1;
    1400                 :     _ma_state_info_read(buff, state);
    1401                 :   }
    1402                 : #endif
    1403            2403 :   return 0;
    1404                 : }
    1405                 : 
    1406                 : 
    1407                 : /****************************************************************************
    1408                 : **  store and read of MARIA_BASE_INFO
    1409                 : ****************************************************************************/
    1410                 : 
    1411                 : uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
    1412             503 : {
    1413             503 :   uchar buff[MARIA_BASE_INFO_SIZE], *ptr=buff;
    1414                 : 
    1415             503 :   bmove(ptr, maria_uuid, MY_UUID_SIZE);
    1416             503 :   ptr+= MY_UUID_SIZE;
    1417             503 :   mi_sizestore(ptr,base->keystart);                  ptr+= 8;
    1418             503 :   mi_sizestore(ptr,base->max_data_file_length);              ptr+= 8;
    1419             503 :   mi_sizestore(ptr,base->max_key_file_length);               ptr+= 8;
    1420             503 :   mi_rowstore(ptr,base->records);                    ptr+= 8;
    1421             503 :   mi_rowstore(ptr,base->reloc);                              ptr+= 8;
    1422             503 :   mi_int4store(ptr,base->mean_row_length);           ptr+= 4;
    1423             503 :   mi_int4store(ptr,base->reclength);                 ptr+= 4;
    1424             503 :   mi_int4store(ptr,base->pack_reclength);            ptr+= 4;
    1425             503 :   mi_int4store(ptr,base->min_pack_length);           ptr+= 4;
    1426             503 :   mi_int4store(ptr,base->max_pack_length);           ptr+= 4;
    1427             503 :   mi_int4store(ptr,base->min_block_length);          ptr+= 4;
    1428             503 :   mi_int2store(ptr,base->fields);                    ptr+= 2;
    1429             503 :   mi_int2store(ptr,base->fixed_not_null_fields);     ptr+= 2;
    1430             503 :   mi_int2store(ptr,base->fixed_not_null_fields_length);      ptr+= 2;
    1431             503 :   mi_int2store(ptr,base->max_field_lengths);         ptr+= 2;
    1432             503 :   mi_int2store(ptr,base->pack_fields);                       ptr+= 2;
    1433             503 :   mi_int2store(ptr,base->extra_options)                      ptr+= 2;
    1434             503 :   mi_int2store(ptr,base->null_bytes);                   ptr+= 2;
    1435             503 :   mi_int2store(ptr,base->original_null_bytes);               ptr+= 2;
    1436             503 :   mi_int2store(ptr,base->field_offsets);             ptr+= 2;
    1437             503 :   mi_int2store(ptr,0);                                  ptr+= 2; /* reserved */
    1438             503 :   mi_int2store(ptr,base->block_size);                        ptr+= 2;
    1439             503 :   *ptr++= base->rec_reflength;
    1440             503 :   *ptr++= base->key_reflength;
    1441             503 :   *ptr++= base->keys;
    1442             503 :   *ptr++= base->auto_key;
    1443             503 :   *ptr++= base->born_transactional;
    1444             503 :   *ptr++= 0;                                    /* Reserved */
    1445             503 :   mi_int2store(ptr,base->pack_bytes);                        ptr+= 2;
    1446             503 :   mi_int2store(ptr,base->blobs);                     ptr+= 2;
    1447             503 :   mi_int2store(ptr,base->max_key_block_length);              ptr+= 2;
    1448             503 :   mi_int2store(ptr,base->max_key_length);            ptr+= 2;
    1449             503 :   mi_int2store(ptr,base->extra_alloc_bytes);         ptr+= 2;
    1450             503 :   *ptr++= base->extra_alloc_procent;
    1451             503 :   bzero(ptr,16);                                        ptr+= 16; /* extra */
    1452             503 :   DBUG_ASSERT((ptr - buff) == MARIA_BASE_INFO_SIZE);
    1453             503 :   return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
    1454                 : }
    1455                 : 
    1456                 : 
    1457                 : static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
    1458            3245 : {
    1459            3245 :   bmove(base->uuid, ptr, MY_UUID_SIZE);                 ptr+= MY_UUID_SIZE;
    1460            3245 :   base->keystart= mi_sizekorr(ptr);                  ptr+= 8;
    1461            3245 :   base->max_data_file_length= mi_sizekorr(ptr);      ptr+= 8;
    1462            3245 :   base->max_key_file_length= mi_sizekorr(ptr);               ptr+= 8;
    1463            3245 :   base->records=  (ha_rows) mi_sizekorr(ptr);                ptr+= 8;
    1464            3245 :   base->reloc= (ha_rows) mi_sizekorr(ptr);           ptr+= 8;
    1465            3245 :   base->mean_row_length= mi_uint4korr(ptr);          ptr+= 4;
    1466            3245 :   base->reclength= mi_uint4korr(ptr);                        ptr+= 4;
    1467            3245 :   base->pack_reclength= mi_uint4korr(ptr);           ptr+= 4;
    1468            3245 :   base->min_pack_length= mi_uint4korr(ptr);          ptr+= 4;
    1469            3245 :   base->max_pack_length= mi_uint4korr(ptr);          ptr+= 4;
    1470            3245 :   base->min_block_length= mi_uint4korr(ptr);         ptr+= 4;
    1471            3245 :   base->fields= mi_uint2korr(ptr);                   ptr+= 2;
    1472            3245 :   base->fixed_not_null_fields= mi_uint2korr(ptr);       ptr+= 2;
    1473            3245 :   base->fixed_not_null_fields_length= mi_uint2korr(ptr);ptr+= 2;
    1474            3245 :   base->max_field_lengths= mi_uint2korr(ptr);                ptr+= 2;
    1475            3245 :   base->pack_fields= mi_uint2korr(ptr);                      ptr+= 2;
    1476            3245 :   base->extra_options= mi_uint2korr(ptr);            ptr+= 2;
    1477            3245 :   base->null_bytes= mi_uint2korr(ptr);                       ptr+= 2;
    1478            3245 :   base->original_null_bytes= mi_uint2korr(ptr);              ptr+= 2;
    1479            3245 :   base->field_offsets= mi_uint2korr(ptr);            ptr+= 2;
    1480            3245 :                                                         ptr+= 2;
    1481            3245 :   base->block_size= mi_uint2korr(ptr);                       ptr+= 2;
    1482                 : 
    1483            3245 :   base->rec_reflength= *ptr++;
    1484            3245 :   base->key_reflength= *ptr++;
    1485            3245 :   base->keys=               *ptr++;
    1486            3245 :   base->auto_key=      *ptr++;
    1487            3245 :   base->born_transactional= *ptr++;
    1488            3245 :   ptr++;
    1489            3245 :   base->pack_bytes= mi_uint2korr(ptr);                       ptr+= 2;
    1490            3245 :   base->blobs= mi_uint2korr(ptr);                    ptr+= 2;
    1491            3245 :   base->max_key_block_length= mi_uint2korr(ptr);     ptr+= 2;
    1492            3245 :   base->max_key_length= mi_uint2korr(ptr);           ptr+= 2;
    1493            3245 :   base->extra_alloc_bytes= mi_uint2korr(ptr);                ptr+= 2;
    1494            3245 :   base->extra_alloc_procent= *ptr++;
    1495            3245 :   ptr+= 16;
    1496            3245 :   return ptr;
    1497                 : }
    1498                 : 
    1499                 : /*--------------------------------------------------------------------------
    1500                 :   maria_keydef
    1501                 : ---------------------------------------------------------------------------*/
    1502                 : 
    1503                 : my_bool _ma_keydef_write(File file, MARIA_KEYDEF *keydef)
    1504            1308 : {
    1505                 :   uchar buff[MARIA_KEYDEF_SIZE];
    1506            1308 :   uchar *ptr=buff;
    1507                 : 
    1508            1308 :   *ptr++= (uchar) keydef->keysegs;
    1509            1308 :   *ptr++= keydef->key_alg;                   /* Rtree or Btree */
    1510            1308 :   mi_int2store(ptr,keydef->flag);            ptr+= 2;
    1511            1308 :   mi_int2store(ptr,keydef->block_length);    ptr+= 2;
    1512            1308 :   mi_int2store(ptr,keydef->keylength);               ptr+= 2;
    1513            1308 :   mi_int2store(ptr,keydef->minlength);               ptr+= 2;
    1514            1308 :   mi_int2store(ptr,keydef->maxlength);               ptr+= 2;
    1515            1308 :   return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
    1516                 : }
    1517                 : 
    1518                 : uchar *_ma_keydef_read(uchar *ptr, MARIA_KEYDEF *keydef)
    1519            8310 : {
    1520            8310 :    keydef->keysegs   = (uint) *ptr++;
    1521            8310 :    keydef->key_alg   = *ptr++;               /* Rtree or Btree */
    1522                 : 
    1523            8310 :    keydef->flag              = mi_uint2korr(ptr);    ptr+= 2;
    1524            8310 :    keydef->block_length = mi_uint2korr(ptr); ptr+= 2;
    1525            8310 :    keydef->keylength = mi_uint2korr(ptr);    ptr+= 2;
    1526            8310 :    keydef->minlength = mi_uint2korr(ptr);    ptr+= 2;
    1527            8310 :    keydef->maxlength = mi_uint2korr(ptr);    ptr+= 2;
    1528            8310 :    keydef->underflow_block_length=keydef->block_length/3;
    1529            8310 :    keydef->version   = 0;                    /* Not saved */
    1530            8310 :    keydef->parser       = &ft_default_parser;
    1531            8310 :    keydef->ftkey_nr     = 0;
    1532            8310 :    return ptr;
    1533                 : }
    1534                 : 
    1535                 : /***************************************************************************
    1536                 : **  maria_keyseg
    1537                 : ***************************************************************************/
    1538                 : 
    1539                 : my_bool _ma_keyseg_write(File file, const HA_KEYSEG *keyseg)
    1540            1541 : {
    1541                 :   uchar buff[HA_KEYSEG_SIZE];
    1542            1541 :   uchar *ptr=buff;
    1543                 :   ulong pos;
    1544                 : 
    1545            1541 :   *ptr++= keyseg->type;
    1546            1541 :   *ptr++= keyseg->language;
    1547            1541 :   *ptr++= keyseg->null_bit;
    1548            1541 :   *ptr++= keyseg->bit_start;
    1549            1541 :   *ptr++= keyseg->bit_end;
    1550            1541 :   *ptr++= keyseg->bit_length;
    1551            1541 :   mi_int2store(ptr,keyseg->flag);    ptr+= 2;
    1552            1541 :   mi_int2store(ptr,keyseg->length);  ptr+= 2;
    1553            1541 :   mi_int4store(ptr,keyseg->start);   ptr+= 4;
    1554            1541 :   pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
    1555            1541 :   mi_int4store(ptr, pos);
    1556            1541 :   ptr+=4;
    1557                 : 
    1558            1541 :   return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
    1559                 : }
    1560                 : 
    1561                 : 
    1562                 : uchar *_ma_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
    1563            9539 : {
    1564            9539 :    keyseg->type              = *ptr++;
    1565            9539 :    keyseg->language  = *ptr++;
    1566            9539 :    keyseg->null_bit  = *ptr++;
    1567            9539 :    keyseg->bit_start = *ptr++;
    1568            9539 :    keyseg->bit_end   = *ptr++;
    1569            9539 :    keyseg->bit_length   = *ptr++;
    1570            9539 :    keyseg->flag              = mi_uint2korr(ptr);  ptr+= 2;
    1571            9539 :    keyseg->length    = mi_uint2korr(ptr);  ptr+= 2;
    1572            9539 :    keyseg->start     = mi_uint4korr(ptr);  ptr+= 4;
    1573            9539 :    keyseg->null_pos  = mi_uint4korr(ptr);  ptr+= 4;
    1574            9539 :    keyseg->charset=0;                                /* Will be filled in later */
    1575            9539 :    if (keyseg->null_bit)
    1576            1571 :      keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
    1577                 :    else
    1578                 :    {
    1579            7968 :      keyseg->bit_pos= (uint16)keyseg->null_pos;
    1580            7968 :      keyseg->null_pos= 0;
    1581                 :    }
    1582            9539 :    return ptr;
    1583                 : }
    1584                 : 
    1585                 : /*--------------------------------------------------------------------------
    1586                 :   maria_uniquedef
    1587                 : ---------------------------------------------------------------------------*/
    1588                 : 
    1589                 : my_bool _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *def)
    1590              40 : {
    1591                 :   uchar buff[MARIA_UNIQUEDEF_SIZE];
    1592              40 :   uchar *ptr=buff;
    1593                 : 
    1594              40 :   mi_int2store(ptr,def->keysegs);            ptr+=2;
    1595              40 :   *ptr++=  (uchar) def->key;
    1596              40 :   *ptr++ = (uchar) def->null_are_equal;
    1597                 : 
    1598              40 :   return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
    1599                 : }
    1600                 : 
    1601                 : uchar *_ma_uniquedef_read(uchar *ptr, MARIA_UNIQUEDEF *def)
    1602             120 : {
    1603             120 :    def->keysegs = mi_uint2korr(ptr);
    1604             120 :    def->key  = ptr[2];
    1605             120 :    def->null_are_equal=ptr[3];
    1606             120 :    return ptr+4;                                /* 1 extra uchar */
    1607                 : }
    1608                 : 
    1609                 : /***************************************************************************
    1610                 : **  MARIA_COLUMNDEF
    1611                 : ***************************************************************************/
    1612                 : 
    1613                 : my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
    1614            1725 : {
    1615                 :   uchar buff[MARIA_COLUMNDEF_SIZE];
    1616            1725 :   uchar *ptr=buff;
    1617                 : 
    1618            1725 :   mi_int2store(ptr,(ulong) columndef->column_nr); ptr+= 2;
    1619            1725 :   mi_int2store(ptr,(ulong) columndef->offset);         ptr+= 2;
    1620            1725 :   mi_int2store(ptr,columndef->type);           ptr+= 2;
    1621            1725 :   mi_int2store(ptr,columndef->length);                 ptr+= 2;
    1622            1725 :   mi_int2store(ptr,columndef->fill_length);    ptr+= 2;
    1623            1725 :   mi_int2store(ptr,columndef->null_pos);       ptr+= 2;
    1624            1725 :   mi_int2store(ptr,columndef->empty_pos);      ptr+= 2;
    1625                 : 
    1626            1725 :   (*ptr++)= columndef->null_bit;
    1627            1725 :   (*ptr++)= columndef->empty_bit;
    1628            1725 :   ptr[0]= ptr[1]= ptr[2]= ptr[3]= 0;            ptr+= 4;  /* For future */
    1629            1725 :   return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
    1630                 : }
    1631                 : 
    1632                 : uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef)
    1633           11015 : {
    1634           11015 :   columndef->column_nr= mi_uint2korr(ptr);      ptr+= 2;
    1635           11015 :   columndef->offset= mi_uint2korr(ptr);         ptr+= 2;
    1636           11015 :   columndef->type=   mi_sint2korr(ptr);              ptr+= 2;
    1637           11015 :   columndef->length= mi_uint2korr(ptr);              ptr+= 2;
    1638           11015 :   columndef->fill_length= mi_uint2korr(ptr); ptr+= 2;
    1639           11015 :   columndef->null_pos= mi_uint2korr(ptr);    ptr+= 2;
    1640           11015 :   columndef->empty_pos= mi_uint2korr(ptr);   ptr+= 2;
    1641           11015 :   columndef->null_bit=  (uint8) *ptr++;
    1642           11015 :   columndef->empty_bit= (uint8) *ptr++;
    1643           11015 :   ptr+= 4;
    1644           11015 :   return ptr;
    1645                 : }
    1646                 : 
    1647                 : my_bool _ma_column_nr_write(File file, uint16 *offsets, uint columns)
    1648             503 : {
    1649                 :   uchar *buff, *ptr, *end;
    1650             503 :   size_t size= columns*2;
    1651                 :   my_bool res;
    1652                 : 
    1653             503 :   if (!(buff= (uchar*) my_alloca(size)))
    1654               0 :     return 1;
    1655            2228 :   for (ptr= buff, end= ptr + size; ptr < end ; ptr+= 2, offsets++)
    1656            1725 :     int2store(ptr, *offsets);
    1657             503 :   res= my_write(file, buff, size, MYF(MY_NABP)) != 0;
    1658                 :   my_afree(buff);
    1659             503 :   return res;
    1660                 : }
    1661                 : 
    1662                 : 
    1663                 : uchar *_ma_column_nr_read(uchar *ptr, uint16 *offsets, uint columns)
    1664            3245 : {
    1665                 :   uchar *end;
    1666            3245 :   size_t size= columns*2;
    1667           14260 :   for (end= ptr + size; ptr < end ; ptr+=2, offsets++)
    1668           11015 :     *offsets= uint2korr(ptr);
    1669            3245 :   return ptr;
    1670                 : }
    1671                 : 
    1672                 : /**
    1673                 :    @brief Set callbacks for data pages
    1674                 : 
    1675                 :    @note
    1676                 :    We don't use pagecache_file_init here, as we want to keep the
    1677                 :    code readable
    1678                 : */
    1679                 : 
    1680                 : void _ma_set_data_pagecache_callbacks(PAGECACHE_FILE *file,
    1681                 :                                       MARIA_SHARE *share)
    1682            4512 : {
    1683            4512 :   file->callback_data= (uchar*) share;
    1684            4512 :   file->flush_log_callback= &maria_flush_log_for_page_none; /* Do nothing */
    1685                 : 
    1686            4512 :   if (share->temporary)
    1687                 :   {
    1688               0 :     file->read_callback=  &maria_page_crc_check_none;
    1689               0 :     file->write_callback= &maria_page_filler_set_none;
    1690                 :   }
    1691                 :   else
    1692                 :   {
    1693            4512 :     file->read_callback=  &maria_page_crc_check_data;
    1694            4512 :     if (share->options & HA_OPTION_PAGE_CHECKSUM)
    1695            4026 :       file->write_callback= &maria_page_crc_set_normal;
    1696                 :     else
    1697             486 :       file->write_callback= &maria_page_filler_set_normal;
    1698            4512 :     if (share->now_transactional)
    1699            3167 :       file->flush_log_callback= maria_flush_log_for_page;
    1700                 :   }
    1701                 : }
    1702                 : 
    1703                 : 
    1704                 : /**
    1705                 :    @brief Set callbacks for index pages
    1706                 : 
    1707                 :    @note
    1708                 :    We don't use pagecache_file_init here, as we want to keep the
    1709                 :    code readable
    1710                 : */
    1711                 : 
    1712                 : void _ma_set_index_pagecache_callbacks(PAGECACHE_FILE *file,
    1713                 :                                        MARIA_SHARE *share)
    1714            4467 : {
    1715            4467 :   file->callback_data= (uchar*) share;
    1716            4467 :   file->flush_log_callback= &maria_flush_log_for_page_none; /* Do nothing */
    1717            4467 :   file->write_fail= maria_page_write_failure;
    1718                 : 
    1719            4467 :   if (share->temporary)
    1720                 :   {
    1721               0 :     file->read_callback=  &maria_page_crc_check_none;
    1722               0 :     file->write_callback= &maria_page_filler_set_none;
    1723                 :   }
    1724                 :   else
    1725                 :   {
    1726            4467 :     file->read_callback=  &maria_page_crc_check_index;
    1727            4467 :     if (share->options & HA_OPTION_PAGE_CHECKSUM)
    1728            3981 :       file->write_callback= &maria_page_crc_set_index;
    1729                 :     else
    1730             486 :       file->write_callback= &maria_page_filler_set_normal;
    1731                 : 
    1732            4467 :     if (share->now_transactional)
    1733            3167 :       file->flush_log_callback= maria_flush_log_for_page;
    1734                 :   }
    1735                 : }
    1736                 : 
    1737                 : 
    1738                 : /**************************************************************************
    1739                 :  Open data file
    1740                 :   We can't use dup() here as the data file descriptors need to have different
    1741                 :   active seek-positions.
    1742                 : 
    1743                 :   The argument file_to_dup is here for the future if there would on some OS
    1744                 :   exist a dup()-like call that would give us two different file descriptors.
    1745                 : *************************************************************************/
    1746                 : 
    1747                 : int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, const char *org_name,
    1748                 :                       File file_to_dup __attribute__((unused)))
    1749            3320 : {
    1750            3320 :   char *data_name= share->data_file_name.str;
    1751                 :   char real_data_name[FN_REFLEN];
    1752                 : 
    1753            3320 :   if (org_name)
    1754                 :   {
    1755            3245 :     fn_format(real_data_name, org_name, "", MARIA_NAME_DEXT, 4);
    1756            3245 :     if (my_is_symlink(real_data_name))
    1757                 :     {
    1758               0 :       if (my_realpath(real_data_name, real_data_name, MYF(0)) ||
    1759                 :           (*maria_test_invalid_symlink)(real_data_name))
    1760                 :       {
    1761               0 :         my_errno= HA_WRONG_CREATE_OPTION;
    1762               0 :         return 1;
    1763                 :       }
    1764               0 :       data_name= real_data_name;
    1765                 :     }
    1766                 :   }
    1767                 : 
    1768            3320 :   info->dfile.file= share->bitmap.file.file=
    1769                 :     my_open(share->data_file_name.str, share->mode | O_SHARE,
    1770                 :             MYF(MY_WME));
    1771            3320 :   return info->dfile.file >= 0 ? 0 : 1;
    1772                 : }
    1773                 : 
    1774                 : 
    1775                 : int _ma_open_keyfile(MARIA_SHARE *share)
    1776               0 : {
    1777                 :   /*
    1778                 :     Modifications to share->kfile should be under intern_lock to protect
    1779                 :     against a concurrent checkpoint.
    1780                 :   */
    1781               0 :   pthread_mutex_lock(&share->intern_lock);
    1782               0 :   share->kfile.file= my_open(share->unique_file_name.str,
    1783                 :                              share->mode | O_SHARE,
    1784                 :                              MYF(MY_WME));
    1785               0 :   pthread_mutex_unlock(&share->intern_lock);
    1786               0 :   return (share->kfile.file < 0);
    1787                 : }
    1788                 : 
    1789                 : 
    1790                 : /*
    1791                 :   Disable all indexes.
    1792                 : 
    1793                 :   SYNOPSIS
    1794                 :     maria_disable_indexes()
    1795                 :     info        A pointer to the MARIA storage engine MARIA_HA struct.
    1796                 : 
    1797                 :   DESCRIPTION
    1798                 :     Disable all indexes.
    1799                 : 
    1800                 :   RETURN
    1801                 :     0  ok
    1802                 : */
    1803                 : 
    1804                 : int maria_disable_indexes(MARIA_HA *info)
    1805               0 : {
    1806               0 :   MARIA_SHARE *share= info->s;
    1807                 : 
    1808               0 :   maria_clear_all_keys_active(share->state.key_map);
    1809               0 :   return 0;
    1810                 : }
    1811                 : 
    1812                 : 
    1813                 : /*
    1814                 :   Enable all indexes
    1815                 : 
    1816                 :   SYNOPSIS
    1817                 :     maria_enable_indexes()
    1818                 :     info        A pointer to the MARIA storage engine MARIA_HA struct.
    1819                 : 
    1820                 :   DESCRIPTION
    1821                 :     Enable all indexes. The indexes might have been disabled
    1822                 :     by maria_disable_index() before.
    1823                 :     The function works only if both data and indexes are empty,
    1824                 :     otherwise a repair is required.
    1825                 :     To be sure, call handler::delete_all_rows() before.
    1826                 : 
    1827                 :   RETURN
    1828                 :     0  ok
    1829                 :     HA_ERR_CRASHED data or index is non-empty.
    1830                 : */
    1831                 : 
    1832                 : int maria_enable_indexes(MARIA_HA *info)
    1833               0 : {
    1834               0 :   int error= 0;
    1835               0 :   MARIA_SHARE *share= info->s;
    1836               0 :   DBUG_ENTER("maria_enable_indexes");
    1837                 : 
    1838               0 :   if ((share->state.state.data_file_length !=
    1839                 :        (share->data_file_type == BLOCK_RECORD ? share->block_size : 0)) ||
    1840                 :       (share->state.state.key_file_length != share->base.keystart))
    1841                 :   {
    1842               0 :     DBUG_PRINT("error", ("data_file_length: %lu  key_file_length: %lu",
    1843                 :                          (ulong) share->state.state.data_file_length,
    1844                 :                          (ulong) share->state.state.key_file_length));
    1845               0 :     maria_print_error(info->s, HA_ERR_CRASHED);
    1846               0 :     error= HA_ERR_CRASHED;
    1847                 :   }
    1848                 :   else
    1849               0 :     maria_set_all_keys_active(share->state.key_map, share->base.keys);
    1850               0 :   DBUG_RETURN(error);
    1851                 : }
    1852                 : 
    1853                 : 
    1854                 : /*
    1855                 :   Test if indexes are disabled.
    1856                 : 
    1857                 :   SYNOPSIS
    1858                 :     maria_indexes_are_disabled()
    1859                 :     info        A pointer to the MARIA storage engine MARIA_HA struct.
    1860                 : 
    1861                 :   DESCRIPTION
    1862                 :     Test if indexes are disabled.
    1863                 : 
    1864                 :   RETURN
    1865                 :     0  indexes are not disabled
    1866                 :     1  all indexes are disabled
    1867                 :     2  non-unique indexes are disabled
    1868                 : */
    1869                 : 
    1870                 : int maria_indexes_are_disabled(MARIA_HA *info)
    1871               0 : {
    1872               0 :   MARIA_SHARE *share= info->s;
    1873                 : 
    1874                 :   /*
    1875                 :     No keys or all are enabled. keys is the number of keys. Left shifted
    1876                 :     gives us only one bit set. When decreased by one, gives us all all bits
    1877                 :     up to this one set and it gets unset.
    1878                 :   */
    1879               0 :   if (!share->base.keys ||
    1880                 :       (maria_is_all_keys_active(share->state.key_map, share->base.keys)))
    1881               0 :     return 0;
    1882                 : 
    1883                 :   /* All are disabled */
    1884               0 :   if (maria_is_any_key_active(share->state.key_map))
    1885               0 :     return 1;
    1886                 : 
    1887                 :   /*
    1888                 :     We have keys. Some enabled, some disabled.
    1889                 :     Don't check for any non-unique disabled but return directly 2
    1890                 :   */
    1891               0 :   return 2;
    1892                 : }
    1893                 : 
    1894                 : 
    1895                 : static my_bool maria_scan_init_dummy(MARIA_HA *info __attribute__((unused)))
    1896             752 : {
    1897             752 :   return 0;
    1898                 : }
    1899                 : 
    1900                 : static void maria_scan_end_dummy(MARIA_HA *info __attribute__((unused)))
    1901             778 : {
    1902                 : }
    1903                 : 
    1904                 : static my_bool maria_once_init_dummy(MARIA_SHARE *share
    1905                 :                                      __attribute__((unused)),
    1906                 :                                      File dfile __attribute__((unused)))
    1907             364 : {
    1908             364 :   return 0;
    1909                 : }
    1910                 : 
    1911                 : static my_bool maria_once_end_dummy(MARIA_SHARE *share __attribute__((unused)))
    1912             364 : {
    1913             364 :   return 0;
    1914                 : }

Generated by: LTP GCOV extension version 1.4