Пример #1
0
/* {{{ mysqlnd_stmt_execute_generate_request */
enum_func_status
mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer)
{
	MYSQLND_STMT_DATA * stmt = s->data;
	zend_uchar	*p = stmt->execute_cmd_buffer.buffer,
				*cmd_buffer = stmt->execute_cmd_buffer.buffer;
	size_t cmd_buffer_length = stmt->execute_cmd_buffer.length;
	enum_func_status ret;

	DBG_ENTER("mysqlnd_stmt_execute_generate_request");

	int4store(p, stmt->stmt_id);
	p += 4;

	/* flags is 4 bytes, we store just 1 */
	int1store(p, (zend_uchar) stmt->flags);
	p++;

	/* Make it all zero */
	int4store(p, 0);

	int1store(p, 1); /* and send 1 for iteration count */
	p+= 4;

	ret = mysqlnd_stmt_execute_store_params(s, &cmd_buffer, &p, &cmd_buffer_length);

	*free_buffer = (cmd_buffer != stmt->execute_cmd_buffer.buffer);
	*request_len = (p - cmd_buffer);
	*request = cmd_buffer;
	DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"******");
	DBG_RETURN(ret);
}
Пример #2
0
static void 
create_record(char *record, uint rownr)
{
	char           *pos;
	bzero((char *)record, MAX_REC_LENGTH);
	record[0] = 1;		/* delete marker */
	if (rownr == 0 && keyinfo[0].seg[0].null_bit)
		record[0] |= keyinfo[0].seg[0].null_bit;	/* Null key */

	pos = record + 1;
	if (recinfo[1].type == FIELD_BLOB) {
		uint		tmp;
		char           *ptr;
		create_key_part(blob_key, rownr);
		tmp = strlen(blob_key);
		int4store(pos, tmp);
		ptr = blob_key;
		memcpy_fixed(pos + 4, &ptr, sizeof(char *));
		pos += recinfo[1].length;
	} else if (recinfo[1].type == FIELD_VARCHAR) {
		uint		tmp;
		create_key_part(pos + 2, rownr);
		tmp = strlen(pos + 2);
		int2store(pos, tmp);
		pos += recinfo[1].length;
	} else {
		create_key_part(pos, rownr);
		pos += recinfo[1].length;
	}
	if (recinfo[2].type == FIELD_BLOB) {
		uint		tmp;
		char           *ptr;;
		sprintf(blob_record, "... row: %d", rownr);
		strappend(blob_record, max(MAX_REC_LENGTH - rownr, 10), ' ');
		tmp = strlen(blob_record);
		int4store(pos, tmp);
		ptr = blob_record;
		memcpy_fixed(pos + 4, &ptr, sizeof(char *));
	} else if (recinfo[2].type == FIELD_VARCHAR) {
		uint		tmp;
		sprintf(pos + 2, "... row: %d", rownr);
		tmp = strlen(pos + 2);
		int2store(pos, tmp);
	} else {
		sprintf(pos, "... row: %d", rownr);
		strappend(pos, recinfo[2].length, ' ');
	}
}
Пример #3
0
/* {{{ mysqlnd_com_stmt_reset_run */
static enum_func_status
mysqlnd_com_stmt_reset_run(void *cmd)
{
	zend_uchar cmd_buf[MYSQLND_STMT_ID_LENGTH /* statement id */];
	struct st_mysqlnd_protocol_com_stmt_reset_command * command = (struct st_mysqlnd_protocol_com_stmt_reset_command *) cmd;
	enum_func_status ret = FAIL;
	MYSQLND_CONN_DATA * conn = command->context.conn;
	func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
	func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;

	DBG_ENTER("mysqlnd_com_stmt_reset_run");

	int4store(cmd_buf, command->context.stmt_id);
	ret = send_command(conn->payload_decoder_factory, COM_STMT_RESET, cmd_buf, sizeof(cmd_buf), FALSE,
					   &conn->state,
					   conn->error_info,
					   conn->upsert_status,
					   conn->stats,
					   conn->m->send_close,
					   conn);
	if (PASS == ret) {
		ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_STMT_RESET, TRUE,
										   conn->error_info, conn->upsert_status, &conn->last_message, conn->persistent);
	}

	DBG_RETURN(ret);
}
Пример #4
0
/* {{{ mysqlnd_command::stmt_reset */
static enum_func_status
MYSQLND_METHOD(mysqlnd_command, stmt_reset)(MYSQLND_CONN_DATA * const conn, const zend_ulong stmt_id)
{
	const func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
	const func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
	zend_uchar cmd_buf[MYSQLND_STMT_ID_LENGTH /* statement id */];
	enum_func_status ret = FAIL;

	DBG_ENTER("mysqlnd_command::stmt_reset");

	int4store(cmd_buf, stmt_id);
	ret = send_command(conn->payload_decoder_factory, COM_STMT_RESET, cmd_buf, sizeof(cmd_buf), FALSE,
					   &conn->state,
					   conn->error_info,
					   conn->upsert_status,
					   conn->stats,
					   conn->m->send_close,
					   conn);
	if (PASS == ret) {
		ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_STMT_RESET, TRUE,
										   conn->error_info, conn->upsert_status, &conn->last_message);
	}

	DBG_RETURN(ret);
}
Пример #5
0
static inline
int
write_uint32_le(datasink_t *sink, ds_file_t *file, ulong n)
{
	char tmp[4];

	int4store(tmp, n);
	return sink->write(file, tmp, sizeof(tmp));
}
Пример #6
0
int test_write(MI_INFO *file,int id,int lock_type)
{
  uint i,tries,count,lock;

  lock=0;
  if (rnd(2) == 0 || lock_type == F_RDLCK)
  {
    lock=1;
    if (mi_lock_database(file,F_WRLCK))
    {
      if (lock_type == F_RDLCK && my_errno == EDEADLK)
      {
	printf("%2d: write:  deadlock\n",id); fflush(stdout);
	return 0;
      }
      fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
      mi_close(file);
      return 1;
    }
    if (rnd(2) == 0)
      mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
  }

  sprintf((char*) record.id,"%7d",getpid());
  strnmov((char*) record.text,"Testing...", sizeof(record.text));

  tries=(uint) rnd(100)+10;
  for (i=count=0 ; i < tries ; i++)
  {
    uint32 tmp=rnd(80000)+20000;
    int4store(record.nr,tmp);
    if (!mi_write(file,record.id))
      count++;
    else
    {
      if (my_errno != HA_ERR_FOUND_DUPP_KEY)
      {
	fprintf(stderr,"%2d: Got error %d (errno %d) from write\n",id,my_errno,
		errno);
	return 1;
      }
    }
  }
  if (lock)
  {
    mi_extra(file,HA_EXTRA_NO_CACHE,0);
    if (mi_lock_database(file,F_UNLCK))
    {
      fprintf(stderr,"%2d: Can't unlock table\n",id);
      exit(0);
    }
  }
  printf("%2d: write:  %5d\n",id,count); fflush(stdout);
  return 0;
}
Пример #7
0
void put_rec(uchar *buff, uint end, uint len, uint tag)
{
  uint i;
  uint num;
  num= uint4korr(buff);
  if (!len)
    len= 1;
  if (end + 4*2 + len > TEST_PAGE_SIZE)
    return;
  int4store(buff + end, len);
  end+=  4;
  int4store(buff + end, tag);
  end+=  4;
  num++;
  int4store(buff, num);
  for (i= end; i < (len + end); i++)
  {
    buff[i]= (uchar) num % 256;
  }
}
Пример #8
0
int packfrm(uchar *data, size_t len,
            uchar **pack_data, size_t *pack_len)
{
  int error;
  size_t org_len, comp_len, blob_len;
  uchar *blob;
  DBUG_ENTER("packfrm");
  DBUG_PRINT("enter", ("data: 0x%lx  len: %lu", (long) data, (ulong) len));

  error= 1;
  org_len= len;
  if (my_compress((uchar*)data, &org_len, &comp_len))
    goto err;

  DBUG_PRINT("info", ("org_len: %lu  comp_len: %lu", (ulong) org_len,
                      (ulong) comp_len));
  DBUG_DUMP("compressed", data, org_len);

  error= 2;
  blob_len= BLOB_HEADER + org_len;
  if (!(blob= (uchar*) my_malloc(blob_len,MYF(MY_WME))))
    goto err;

  /* Store compressed blob in machine independent format */
  int4store(blob, 1);
  int4store(blob+4, (uint32) len);
  int4store(blob+8, (uint32) org_len);          /* compressed length */

  /* Copy frm data into blob, already in machine independent format */
  memcpy(blob+BLOB_HEADER, data, org_len);

  *pack_data= blob;
  *pack_len=  blob_len;
  error= 0;

  DBUG_PRINT("exit", ("pack_data: 0x%lx  pack_len: %lu",
                      (long) *pack_data, (ulong) *pack_len));
err:
  DBUG_RETURN(error);

}
int xb_crypt_write_chunk(xb_wcrypt_t *crypt, const void *buf, size_t olen,
			 size_t elen, const void *iv, size_t ivlen)
{
	uchar		tmpbuf[XB_CRYPT_CHUNK_MAGIC_SIZE + 8 + 8 + 8 + 4 + 8];
	uchar		*ptr;
	ulong		checksum;

	xb_ad(olen <= INT_MAX);
	if (olen > INT_MAX)
		return 0;

	xb_ad(elen <= INT_MAX);
	if (elen > INT_MAX)
		return 0;

	xb_ad(ivlen <= INT_MAX);
	if (ivlen > INT_MAX)
		return 0;

	ptr = tmpbuf;

	memcpy(ptr, XB_CRYPT_CHUNK_MAGIC2, XB_CRYPT_CHUNK_MAGIC_SIZE);
	ptr += XB_CRYPT_CHUNK_MAGIC_SIZE;

	int8store(ptr, (ulonglong)0);	/* reserved */
	ptr += 8;

	int8store(ptr, (ulonglong)olen); /* original size */
	ptr += 8;

	int8store(ptr, (ulonglong)elen); /* encrypted (actual) size */
	ptr += 8;

	checksum = crc32(0, buf, elen);
	int4store(ptr, checksum);	/* checksum */
	ptr += 4;

	int8store(ptr, (ulonglong)ivlen); /* iv size */
	ptr += 8;

	xb_ad(ptr <= tmpbuf + sizeof(tmpbuf));

	if (crypt->write(crypt->userdata, tmpbuf, ptr-tmpbuf) == -1)
		return 1;

	if (crypt->write(crypt->userdata, iv, ivlen) == -1)
		return 1;

	if (crypt->write(crypt->userdata, buf, elen) == -1)
		return 1;

	return 0;
}
Пример #10
0
void _nisam_log_record(enum nisam_log_commands command, N_INFO *info, const byte *record, ulong filepos, int result)
{
  char buff[17],*pos;
  int error,old_errno;
  uint length;
  ulong pid=(ulong) GETPID();

  old_errno=my_errno;
  if (!info->s->base.blobs)
    length=info->s->base.reclength;
  else
    length=info->s->base.reclength+ _calc_total_blob_length(info,record);
  buff[0]=(char) command;
  int2store(buff+1,info->dfile);
  int4store(buff+3,pid);
  int2store(buff+7,result);
  int4store(buff+9,filepos);
  int4store(buff+13,length);
  pthread_mutex_lock(&THR_LOCK_isam);
  error=my_lock(nisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
  VOID(my_write(nisam_log_file,buff,sizeof(buff),MYF(0)));
  VOID(my_write(nisam_log_file,(byte*) record,info->s->base.reclength,MYF(0)));
  if (info->s->base.blobs)
  {
    N_BLOB *blob,*end;

    for (end=info->blobs+info->s->base.blobs, blob= info->blobs;
	 blob != end ;
	 blob++)
    {
      bmove(&pos,record+blob->offset+blob->pack_length,sizeof(char*));
      VOID(my_write(nisam_log_file,pos,blob->length,MYF(0)));
    }
  }
  if (!error)
    error=my_lock(nisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
  pthread_mutex_unlock(&THR_LOCK_isam);
  my_errno=old_errno;
}
Пример #11
0
int _nisam_delete_static_record(N_INFO *info)
{
  uchar temp[5];				/* 1+sizeof(uint32) */

  info->s->state.del++;
  info->s->state.empty+=info->s->base.reclength;
  temp[0]= '\0';			/* Mark that record is deleted */
  int4store(temp+1,info->s->state.dellink);
  info->s->state.dellink = info->lastpos;
  info->rec_cache.seek_not_done=1;
  VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0)));
  return (my_write(info->dfile,(byte*) temp,(uint) sizeof(temp),
		   MYF(MY_NABP)) != 0);
}
Пример #12
0
size_t vio_write_shared_memory(Vio *vio, const uchar *buf, size_t size)
{
  size_t length, remain, sz;
  HANDLE pos;
  const uchar *current_position;
  HANDLE events[2];
  DWORD timeout;
  DBUG_ENTER("vio_write_shared_memory");

  remain= size;
  current_position= buf;
  timeout= vio->write_timeout >= 0 ? vio->write_timeout : INFINITE;

  events[0]= vio->event_server_read;
  events[1]= vio->event_conn_closed;

  while (remain != 0)
  {
    DWORD wait_status;

    wait_status= WaitForMultipleObjects(array_elements(events), events,
                                        FALSE, timeout);

    if (wait_status != WAIT_OBJECT_0)
    {
      /* Set error code to indicate a timeout error or disconnect. */
      if (wait_status == WAIT_TIMEOUT)
        SetLastError(SOCKET_ETIMEDOUT);
      else
        SetLastError(ERROR_GRACEFUL_DISCONNECT);

      DBUG_RETURN((size_t) -1);
    }

    sz= (remain > shared_memory_buffer_length ? shared_memory_buffer_length :
         remain);

    int4store(vio->handle_map, sz);
    pos= vio->handle_map + 4;
    memcpy(pos, current_position, sz);
    remain-= sz;
    current_position+= sz;
    if (!SetEvent(vio->event_client_wrote))
      DBUG_RETURN((size_t) -1);
  }
  length= size;

  DBUG_RETURN(length);
}
Пример #13
0
static void 
update_record(char *record)
{
	char           *pos = record + 1;
	if (recinfo[1].type == FIELD_BLOB) {
		char           *column, *ptr;
		int		length;
		length = uint4korr(pos);	/* Long blob */
		memcpy_fixed(&column, pos + 4, sizeof(char *));
		memcpy(blob_key, column, length);	/* Move old key */
		ptr = blob_key;
		memcpy_fixed(pos + 4, &ptr, sizeof(char *));	/* Store pointer to new
								 * key */
		if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM)
			casedn(blob_key, length);
		pos += recinfo[1].length;
	} else if (recinfo[1].type == FIELD_VARCHAR) {
		uint		length = uint2korr(pos);
		casedn(pos + 2, length);
		pos += recinfo[1].length;
	} else {
		if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM)
			casedn(pos, keyinfo[0].seg[0].length);
		pos += recinfo[1].length;
	}

	if (recinfo[2].type == FIELD_BLOB) {
		char           *column;
		int		length;
		length = uint4korr(pos);
		memcpy_fixed(&column, pos + 4, sizeof(char *));
		memcpy(blob_record, column, length);
		bfill(blob_record + length, 20, '.');	/* Make it larger */
		length += 20;
		int4store(pos, length);
		column = blob_record;
		memcpy_fixed(pos + 4, &column, sizeof(char *));
	} else if (recinfo[2].type == FIELD_VARCHAR) {
		/* Second field is longer than 10 characters */
		uint		length = uint2korr(pos);
		bfill(pos + 2 + length, recinfo[2].length - length - 2, '.');
		length = recinfo[2].length - 2;
		int2store(pos, length);
	} else {
		bfill(pos + recinfo[2].length - 10, 10, '.');
	}
}
Пример #14
0
int write_header(azio_stream *s)
{
  char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE];
  char *ptr= buffer;

  s->block_size= AZ_BUFSIZE_WRITE;
  s->version = (unsigned char)az_magic[1];
  s->minor_version = (unsigned char)az_magic[2];


  /* Write a very simple .az header: */
  memset(buffer, 0, AZHEADER_SIZE + AZMETA_BUFFER_SIZE);
  *(ptr + AZ_MAGIC_POS)= az_magic[0];
  *(ptr + AZ_VERSION_POS)= (unsigned char)s->version;
  *(ptr + AZ_MINOR_VERSION_POS)= (unsigned char)s->minor_version;
  *(ptr + AZ_BLOCK_POS)= (unsigned char)(s->block_size/1024); /* Reserved for block size */
  *(ptr + AZ_STRATEGY_POS)= (unsigned char)Z_DEFAULT_STRATEGY; /* Compression Type */

  int4store(ptr + AZ_FRM_POS, s->frm_start_pos); /* FRM Block */
  int4store(ptr + AZ_FRM_LENGTH_POS, s->frm_length); /* FRM Block */
  int4store(ptr + AZ_COMMENT_POS, s->comment_start_pos); /* COMMENT Block */
  int4store(ptr + AZ_COMMENT_LENGTH_POS, s->comment_length); /* COMMENT Block */
  int4store(ptr + AZ_META_POS, 0); /* Meta Block */
  int4store(ptr + AZ_META_LENGTH_POS, 0); /* Meta Block */
  int8store(ptr + AZ_START_POS, (unsigned long long)s->start); /* Start of Data Block Index Block */
  int8store(ptr + AZ_ROW_POS, (unsigned long long)s->rows); /* Start of Data Block Index Block */
  int8store(ptr + AZ_FLUSH_POS, (unsigned long long)s->forced_flushes); /* Start of Data Block Index Block */
  int8store(ptr + AZ_CHECK_POS, (unsigned long long)s->check_point); /* Start of Data Block Index Block */
  int8store(ptr + AZ_AUTOINCREMENT_POS, (unsigned long long)s->auto_increment); /* Start of Data Block Index Block */
  int4store(ptr+ AZ_LONGEST_POS , s->longest_row); /* Longest row */
  int4store(ptr+ AZ_SHORTEST_POS, s->shortest_row); /* Shorest row */
  int4store(ptr+ AZ_FRM_POS, 
            AZHEADER_SIZE + AZMETA_BUFFER_SIZE); /* FRM position */
  *(ptr + AZ_DIRTY_POS)= (unsigned char)s->dirty; /* Start of Data Block Index Block */

  /* Always begin at the begining, and end there as well */
  return my_pwrite(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE,
                   0, MYF(MY_NABP)) ? 1 : 0;
}
Пример #15
0
/* {{{ mysqlnd_command::stmt_close */
static enum_func_status
MYSQLND_METHOD(mysqlnd_command, stmt_close)(MYSQLND_CONN_DATA * const conn, const zend_ulong stmt_id)
{
	func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
	zend_uchar cmd_buf[MYSQLND_STMT_ID_LENGTH /* statement id */];
	enum_func_status ret = FAIL;

	DBG_ENTER("mysqlnd_command::stmt_close");

	int4store(cmd_buf, stmt_id);
	ret = send_command(conn->payload_decoder_factory, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf), FALSE,
					   &conn->state,
					   conn->error_info,
					   conn->upsert_status,
					   conn->stats,
					   conn->m->send_close,
					   conn);

	DBG_RETURN(ret);
}
Пример #16
0
void _nisam_log_command(enum nisam_log_commands command, N_INFO *info, const byte *buffert, uint length, int result)
{
  char buff[9];
  int error,old_errno;
  ulong pid=(ulong) GETPID();

  old_errno=my_errno;
  buff[0]=(char) command;
  int2store(buff+1,info->dfile);
  int4store(buff+3,pid);
  int2store(buff+7,result);
  pthread_mutex_lock(&THR_LOCK_isam);
  error=my_lock(nisam_log_file,F_WRLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
  VOID(my_write(nisam_log_file,buff,sizeof(buff),MYF(0)));
  if (buffert)
    VOID(my_write(nisam_log_file,buffert,length,MYF(0)));
  if (!error)
    error=my_lock(nisam_log_file,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
  pthread_mutex_unlock(&THR_LOCK_isam);
  my_errno=old_errno;
}
Пример #17
0
/* {{{ mysqlnd_com_process_kill_run */
enum_func_status
mysqlnd_com_process_kill_run(void *cmd)
{
	struct st_mysqlnd_protocol_com_process_kill_command * command = (struct st_mysqlnd_protocol_com_process_kill_command *) cmd;
	zend_uchar buff[4];
	enum_func_status ret = FAIL;
	MYSQLND_CONN_DATA * conn = command->context.conn;
	zend_bool read_response = command->context.read_response;
	func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
	func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;

	DBG_ENTER("mysqlnd_com_process_kill_run");
	int4store(buff, command->context.process_id);

	ret = send_command(conn->payload_decoder_factory, COM_PROCESS_KILL, buff, 4, FALSE,
					   &conn->state,
					   conn->error_info,
					   conn->upsert_status,
					   conn->stats,
					   conn->m->send_close,
					   conn);
	if (PASS == ret && read_response) {
		ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_PROCESS_KILL, TRUE,
										   conn->error_info, conn->upsert_status, &conn->last_message, conn->persistent);
	}

	if (read_response) {
		/*
		  The server sends 0 but libmysql doesn't read it and has established
		  a protocol of giving back -1. Thus we have to follow it :(
		*/
		UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
	} else if (PASS == ret) {
		SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
		conn->m->send_close(conn);
	}

	DBG_RETURN(ret);
}
Пример #18
0
/* {{{ mysqlnd_com_stmt_close_run */
static enum_func_status
mysqlnd_com_stmt_close_run(void *cmd)
{
	zend_uchar cmd_buf[MYSQLND_STMT_ID_LENGTH /* statement id */];
	struct st_mysqlnd_protocol_com_stmt_close_command * command = (struct st_mysqlnd_protocol_com_stmt_close_command *) cmd;
	enum_func_status ret = FAIL;
	MYSQLND_CONN_DATA * conn = command->context.conn;
	func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;

	DBG_ENTER("mysqlnd_com_stmt_close_run");

	int4store(cmd_buf, command->context.stmt_id);
	ret = send_command(conn->payload_decoder_factory, COM_STMT_CLOSE, cmd_buf, sizeof(cmd_buf), FALSE,
					   &conn->state,
					   conn->error_info,
					   conn->upsert_status,
					   conn->stats,
					   conn->m->send_close,
					   conn);

	DBG_RETURN(ret);
}
ssize_t pvio_shm_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
{
  HANDLE events[2];
  PVIO_SHM *pvio_shm= (PVIO_SHM *)pvio->data;
  size_t bytes_to_write= length;
  uchar *buffer_pos= (uchar *)buffer;
  
  if (!pvio_shm)
    return -1;

  events[0]= pvio_shm->event[PVIO_SHM_CONNECTION_CLOSED];
  events[1]= pvio_shm->event[PVIO_SHM_SERVER_READ];

  while (bytes_to_write)
  {
    size_t pkt_length;
    switch (WaitForMultipleObjects(2, events, 0, pvio->timeout[PVIO_WRITE_TIMEOUT])) {
    case WAIT_OBJECT_0: /* connection closed */
      SetLastError(ERROR_GRACEFUL_DISCONNECT);
      return -1;
    case WAIT_OBJECT_0 + 1: /* server_read */
      break;
    case WAIT_TIMEOUT:
      SetLastError(ETIMEDOUT);
    default:
      return -1;
    }
    pkt_length= MIN(PVIO_SHM_BUFFER_SIZE, length);
    int4store(pvio_shm->map, pkt_length);
    memcpy((uchar *)pvio_shm->map + 4, buffer_pos, length);
    buffer_pos+= length;
    bytes_to_write-= length;

    if (!SetEvent(pvio_shm->event[PVIO_SHM_CLIENT_WROTE]))
      return -1;
  }
  return (ssize_t)length;
}
Пример #20
0
/* {{{ mysqlnd_command::process_kill */
static enum_func_status
MYSQLND_METHOD(mysqlnd_command, process_kill)(MYSQLND_CONN_DATA * const conn, const unsigned int process_id, const zend_bool read_response)
{
	const func_mysqlnd_protocol_payload_decoder_factory__send_command send_command = conn->payload_decoder_factory->m.send_command;
	const func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response = conn->payload_decoder_factory->m.send_command_handle_response;
	zend_uchar buff[4];
	enum_func_status ret = FAIL;

	DBG_ENTER("mysqlnd_command::process_kill");
	int4store(buff, process_id);

	ret = send_command(conn->payload_decoder_factory, COM_PROCESS_KILL, buff, 4, FALSE,
					   &conn->state,
					   conn->error_info,
					   conn->upsert_status,
					   conn->stats,
					   conn->m->send_close,
					   conn);
	if (PASS == ret && read_response) {
		ret = send_command_handle_response(conn->payload_decoder_factory, PROT_OK_PACKET, FALSE, COM_PROCESS_KILL, TRUE,
										   conn->error_info, conn->upsert_status, &conn->last_message);
	}

	if (read_response) {
		/*
		  The server sends 0 but libmysql doesn't read it and has established
		  a protocol of giving back -1. Thus we have to follow it :(
		*/
		UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
	} else if (PASS == ret) {
		SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
		conn->m->send_close(conn);
	}

	DBG_RETURN(ret);
}
Пример #21
0
static void update_record(uchar *record)
{
  uchar *pos=record+1;
  if (recinfo[1].type == FIELD_BLOB)
  {
    uchar *column,*ptr;
    int length;
    length=uint4korr(pos);			/* Long blob */
    memcpy_fixed(&column,pos+4,sizeof(char*));
    memcpy(blob_key,column,length);		/* Move old key */
    ptr=blob_key;
    memcpy_fixed(pos+4,&ptr,sizeof(char*));	/* Store pointer to new key */
    if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM)
      default_charset_info->cset->casedn(default_charset_info,
                                         (char*) blob_key, length,
                                         (char*) blob_key, length);
    pos+=recinfo[1].length;
  }
  else if (recinfo[1].type == FIELD_VARCHAR)
  {
    uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
    uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
    default_charset_info->cset->casedn(default_charset_info,
                                       (char*) pos + pack_length, length,
                                       (char*) pos + pack_length, length);
    pos+=recinfo[1].length;
  }
  else
  {
    if (keyinfo[0].seg[0].type != HA_KEYTYPE_NUM)
      default_charset_info->cset->casedn(default_charset_info,
                                         (char*) pos, keyinfo[0].seg[0].length,
                                         (char*) pos, keyinfo[0].seg[0].length);
    pos+=recinfo[1].length;
  }

  if (recinfo[2].type == FIELD_BLOB)
  {
    uchar *column;
    int length;
    length=uint4korr(pos);
    memcpy_fixed(&column,pos+4,sizeof(char*));
    memcpy(blob_record,column,length);
    bfill(blob_record+length,20,'.');	/* Make it larger */
    length+=20;
    int4store(pos,length);
    column= blob_record;
    memcpy_fixed(pos+4,&column,sizeof(char*));
  }
  else if (recinfo[2].type == FIELD_VARCHAR)
  {
    /* Second field is longer than 10 characters */
    uint pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
    uint length= pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos);
    bfill(pos+pack_length+length,recinfo[2].length-length-pack_length,'.');
    length=recinfo[2].length-pack_length;
    if (pack_length == 1)
      *(uchar*) pos= (uchar) length;
    else
      int2store(pos,length);
  }
  else
  {
    bfill(pos+recinfo[2].length-10,10,'.');
  }
}
int main(int argc __attribute__((unused)), char *argv[])
{
  uint pagen;
  uchar long_tr_id[6];
  PAGECACHE pagecache;
  LSN lsn, first_lsn, theor_lsn;
  LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1];
  MY_INIT(argv[0]);

  plan(2);

  bzero(&pagecache, sizeof(pagecache));
  /*
    Don't give an error if we can't create dir, as it may already exist from a previously aborted
    run
  */
  maria_data_root= create_tmpdir(argv[0]);
  if (maria_log_remove(0))
    exit(1);

  bzero(long_tr_id, 6);
#ifndef DBUG_OFF
#if defined(__WIN__)
  default_dbug_option= "d:t:i:O,\\ma_test_loghandler.trace";
#else
  default_dbug_option= "d:t:i:o,/tmp/ma_test_loghandler.trace";
#endif
  if (argc > 1)
  {
    DBUG_SET(default_dbug_option);
    DBUG_SET_INITIAL(default_dbug_option);
  }
#endif

  if (ma_control_file_open(TRUE, TRUE))
  {
    fprintf(stderr, "Can't init control file (%d)\n", errno);
    exit(1);
  }
  if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
                             PCACHE_PAGE, 0)) == 0)
  {
    fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
    exit(1);
  }
  if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache,
                               LOG_FLAGS, 0, &translog_example_table_init, 0))
  {
    fprintf(stderr, "Can't init loghandler (%d)\n", errno);
    exit(1);
  }
  /* Suppressing of automatic record writing */
  dummy_transaction_object.first_undo_lsn|= TRANSACTION_LOGGED_LONG_ID;

  theor_lsn= translog_first_theoretical_lsn();
  if (theor_lsn == 1)
  {
    fprintf(stderr, "Error reading the first log file.");
    translog_destroy();
    exit(1);
  }
  if (theor_lsn == LSN_IMPOSSIBLE)
  {
    fprintf(stderr, "There is no first log file.");
    translog_destroy();
    exit(1);
  }
  first_lsn= translog_first_lsn_in_log();
  if (first_lsn != LSN_IMPOSSIBLE)
  {
    fprintf(stderr, "Incorrect first lsn response (%lu,0x%lx).",
            LSN_IN_PARTS(first_lsn));
    translog_destroy();
    exit(1);
  }
  ok(1, "Empty log response");


  int4store(long_tr_id, 0);
  parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
  parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
  if (translog_write_record(&lsn,
                            LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                            &dummy_transaction_object, NULL, 6,
                            TRANSLOG_INTERNAL_PARTS + 1,
                            parts, NULL, NULL))
  {
    fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
    translog_destroy();
    exit(1);
  }

  theor_lsn= translog_first_theoretical_lsn();
  if (theor_lsn == 1)
  {
    fprintf(stderr, "Error reading the first log file\n");
    translog_destroy();
    exit(1);
  }
  if (theor_lsn == LSN_IMPOSSIBLE)
  {
    fprintf(stderr, "There is no first log file\n");
    translog_destroy();
    exit(1);
  }
  first_lsn= translog_first_lsn_in_log();
  if (first_lsn != theor_lsn)
  {
    fprintf(stderr, "Incorrect first lsn: (%lu,0x%lx)  "
            " theoretical first: (%lu,0x%lx)\n",
            LSN_IN_PARTS(first_lsn), LSN_IN_PARTS(theor_lsn));
    translog_destroy();
    exit(1);
  }

  ok(1, "Full log response");

  translog_destroy();
  end_pagecache(&pagecache, 1);
  ma_control_file_end();
  if (maria_log_remove(maria_data_root))
    exit(1);
  exit(0);
}
int main(int argc __attribute__((unused)), char *argv[])
{
  ulong i;
  uint pagen;
  uchar long_tr_id[6];
  PAGECACHE pagecache;
  LSN lsn;
  LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1];
  uchar *long_buffer= malloc(LONG_BUFFER_SIZE);

  MY_INIT(argv[0]);

  plan(4);

  bzero(&pagecache, sizeof(pagecache));
  bzero(long_buffer, LONG_BUFFER_SIZE);
  maria_data_root= create_tmpdir(argv[0]);
  if (maria_log_remove(0))
    exit(1);

  bzero(long_tr_id, 6);
#ifndef DBUG_OFF
#if defined(__WIN__)
  default_dbug_option= "d:t:i:O,\\ma_test_loghandler.trace";
#else
  default_dbug_option= "d:t:i:o,/tmp/ma_test_loghandler.trace";
#endif
  if (argc > 1)
  {
    DBUG_SET(default_dbug_option);
    DBUG_SET_INITIAL(default_dbug_option);
  }
#endif

  if (ma_control_file_open(TRUE, TRUE))
  {
    fprintf(stderr, "Can't init control file (%d)\n", errno);
    exit(1);
  }
  if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
                             PCACHE_PAGE, 0, 0)) == 0)
  {
    fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
    exit(1);
  }
  if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache,
                               LOG_FLAGS, 0, &translog_example_table_init,
                               0))
  {
    fprintf(stderr, "Can't init loghandler (%d)\n", errno);
    exit(1);
  }
  /* Suppressing of automatic record writing */
  dummy_transaction_object.first_undo_lsn|= TRANSACTION_LOGGED_LONG_ID;

  /* write more then 1 file */
  int4store(long_tr_id, 0);
  parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
  parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
  if (translog_write_record(&lsn,
                            LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                            &dummy_transaction_object, NULL, 6,
                            TRANSLOG_INTERNAL_PARTS + 1,
                            parts, NULL, NULL))
  {
    fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
    translog_destroy();
    exit(1);
  }

  translog_purge(lsn);
  if (!translog_is_file(1))
  {
    fprintf(stderr, "First file was removed after first record\n");
    translog_destroy();
    exit(1);
  }
  ok(1, "First is not removed");

  for(i= 0; i < LOG_FILE_SIZE/6 && LSN_FILE_NO(lsn) == 1; i++)
  {
    if (translog_write_record(&lsn,
                              LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                              &dummy_transaction_object, NULL, 6,
                              TRANSLOG_INTERNAL_PARTS + 1,
                              parts, NULL, NULL))
    {
      fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
      translog_destroy();
      exit(1);
    }
  }

  translog_purge(lsn);
  if (translog_is_file(1))
  {
    fprintf(stderr, "First file was not removed.\n");
    translog_destroy();
    exit(1);
  }

  ok(1, "First file is removed");

  parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_buffer;
  parts[TRANSLOG_INTERNAL_PARTS + 0].length= LONG_BUFFER_SIZE;
  if (translog_write_record(&lsn,
			    LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE,
			    &dummy_transaction_object, NULL, LONG_BUFFER_SIZE,
			    TRANSLOG_INTERNAL_PARTS + 1, parts, NULL, NULL))
  {
    fprintf(stderr, "Can't write variable record\n");
    translog_destroy();
    exit(1);
  }

  translog_purge(lsn);
  if (!translog_is_file(2) || !translog_is_file(3))
  {
    fprintf(stderr, "Second file (%d) or third file (%d) is not present.\n",
	    translog_is_file(2), translog_is_file(3));
    translog_destroy();
    exit(1);
  }

  ok(1, "Second and third files are not removed");

  int4store(long_tr_id, 0);
  parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
  parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
  if (translog_write_record(&lsn,
                            LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                            &dummy_transaction_object, NULL, 6,
                            TRANSLOG_INTERNAL_PARTS + 1,
                            parts, NULL, NULL))
  {
    fprintf(stderr, "Can't write last record\n");
    translog_destroy();
    exit(1);
  }

  translog_purge(lsn);
  if (translog_is_file(2))
  {
    fprintf(stderr, "Second file is not removed\n");
    translog_destroy();
    exit(1);
  }

  ok(1, "Second file is removed");

  translog_destroy();
  end_pagecache(&pagecache, 1);
  ma_control_file_end();
  if (maria_log_remove(maria_data_root))
    exit(1);

  my_uuid_end();
  my_free_open_file_info();
  my_end(0);

  exit(0);
}
Пример #24
0
static int create_sys_files(struct languages *lang_head,
                            struct errors *error_head, uint row_count)
{
    FILE *to;
    uint csnum= 0, length, i, row_nr;
    uchar head[32];
    char outfile[FN_REFLEN], *outfile_end;
    long start_pos;
    struct message *tmp;
    struct languages *tmp_lang;
    struct errors *tmp_error;

    MY_STAT stat_info;
    DBUG_ENTER("create_sys_files");

    /*
       going over all languages and assembling corresponding error messages
    */
    for (tmp_lang= lang_head; tmp_lang; tmp_lang= tmp_lang->next_lang)
    {

        /* setting charset name */
        if (!(csnum= get_charset_number(tmp_lang->charset, MY_CS_PRIMARY)))
        {
            fprintf(stderr, "Unknown charset '%s' in '%s'\n", tmp_lang->charset,
                    TXTFILE);
            DBUG_RETURN(1);
        }

        outfile_end= strxmov(outfile, DATADIRECTORY,
                             tmp_lang->lang_long_name, NullS);
        if (!my_stat(outfile, &stat_info,MYF(0)))
        {
            if (my_mkdir(outfile, 0777,MYF(0)) < 0)
            {
                fprintf(stderr, "Can't create output directory for %s\n",
                        outfile);
                DBUG_RETURN(1);
            }
        }

        strxmov(outfile_end, FN_ROOTDIR, OUTFILE, NullS);

        if (!(to= my_fopen(outfile, O_WRONLY | FILE_BINARY, MYF(MY_WME))))
            DBUG_RETURN(1);

        /* 4 is for 4 bytes to store row position / error message */
        start_pos= (long) (HEADER_LENGTH + row_count * 4);
        fseek(to, start_pos, 0);
        row_nr= 0;
        for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
        {
            /* dealing with messages */
            tmp= find_message(tmp_error, tmp_lang->lang_short_name, FALSE);

            if (!tmp)
            {
                fprintf(stderr,
                        "Did not find message for %s neither in %s nor in default "
                        "language\n", tmp_error->er_name, tmp_lang->lang_short_name);
                goto err;
            }
            if (copy_rows(to, tmp->text, row_nr, start_pos))
            {
                fprintf(stderr, "Failed to copy rows to %s\n", outfile);
                goto err;
            }
            row_nr++;
        }

        /* continue with header of the errmsg.sys file */
        length= ftell(to) - HEADER_LENGTH - row_count * 4;
        memset(head, 0, HEADER_LENGTH);
        memmove(head, file_head, 4);
        head[4]= 1;
        int4store(head + 6, length);
        int4store(head + 10, row_count);
        head[30]= csnum;

        my_fseek(to, 0l, MY_SEEK_SET, MYF(0));
        if (my_fwrite(to, (uchar*) head, HEADER_LENGTH, MYF(MY_WME | MY_FNABP)))
            goto err;

        for (i= 0; i < row_count; i++)
        {
            int4store(head, file_pos[i]);
            if (my_fwrite(to, (uchar*) head, 4, MYF(MY_WME | MY_FNABP)))
                goto err;
        }
        my_fclose(to, MYF(0));
    }
    DBUG_RETURN(0);

err:
    my_fclose(to, MYF(0));
    DBUG_RETURN(1);
}
Пример #25
0
int main(int argc, char *argv[])
{
  uint i;
  int j,n1,n2,n3,error,k;
  uint write_count,update,dupp_keys,opt_delete,start,length,blob_pos,
       reclength,ant,found_parts;
  my_off_t lastpos;
  ha_rows range_records,records;
  MARIA_HA *file;
  MARIA_KEYDEF keyinfo[10];
  MARIA_COLUMNDEF recinfo[10];
  MARIA_INFO info;
  char *blob_buffer;
  MARIA_CREATE_INFO create_info;
  char filename[FN_REFLEN];

#ifdef SAFE_MUTEX
  safe_mutex_deadlock_detector= 1;
#endif
  MY_INIT(argv[0]);

  maria_data_root= (char *)".";
  get_options(argc,argv);
  fn_format(filename, "test2", maria_data_root, "", MYF(0));

  if (! async_io)
    my_disable_async_io=1;

  /* If we sync or not have no affect on this test */
  my_disable_sync= 1;

  /* Maria requires that we always have a page cache */
  if (maria_init() ||
      (init_pagecache(maria_pagecache, pagecache_size, 0, 0,
		      maria_block_size, MY_WME) == 0) ||
      ma_control_file_open(TRUE, TRUE) ||
      (init_pagecache(maria_log_pagecache,
		      TRANSLOG_PAGECACHE_SIZE, 0, 0,
		      TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
      translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
		    0, 0, maria_log_pagecache,
		    TRANSLOG_DEFAULT_FLAGS, 0) ||
      (transactional && (trnman_init(0) || ma_checkpoint_init(0))))
  {
    fprintf(stderr, "Error in initialization");
    exit(1);
  }
  if (opt_versioning)
    init_thr_lock();

  reclength=STANDARD_LENGTH+60+(use_blob ? 8 : 0);
  blob_pos=STANDARD_LENGTH+60;
  keyinfo[0].seg= &glob_keyseg[0][0];
  keyinfo[0].seg[0].start=0;
  keyinfo[0].seg[0].length=6;
  keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[0].seg[0].language= default_charset_info->number;
  keyinfo[0].seg[0].flag=(uint8) pack_seg;
  keyinfo[0].seg[0].null_bit=0;
  keyinfo[0].seg[0].null_pos=0;
  keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[0].keysegs=1;
  keyinfo[0].flag = pack_type;
  keyinfo[0].block_length= 0;                   /* Default block length */
  keyinfo[1].seg= &glob_keyseg[1][0];
  keyinfo[1].seg[0].start=7;
  keyinfo[1].seg[0].length=6;
  keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
  keyinfo[1].seg[0].flag=0;
  keyinfo[1].seg[0].null_bit=0;
  keyinfo[1].seg[0].null_pos=0;
  keyinfo[1].seg[1].start=0;			/* two part key */
  keyinfo[1].seg[1].length=6;
  keyinfo[1].seg[1].type=HA_KEYTYPE_NUM;
  keyinfo[1].seg[1].flag=HA_REVERSE_SORT;
  keyinfo[1].seg[1].null_bit=0;
  keyinfo[1].seg[1].null_pos=0;
  keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[1].keysegs=2;
  keyinfo[1].flag =0;
  keyinfo[1].block_length= MARIA_MIN_KEY_BLOCK_LENGTH;  /* Diff blocklength */
  keyinfo[2].seg= &glob_keyseg[2][0];
  keyinfo[2].seg[0].start=12;
  keyinfo[2].seg[0].length=8;
  keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
  keyinfo[2].seg[0].flag=HA_REVERSE_SORT;
  keyinfo[2].seg[0].null_bit=0;
  keyinfo[2].seg[0].null_pos=0;
  keyinfo[2].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[2].keysegs=1;
  keyinfo[2].flag =HA_NOSAME;
  keyinfo[2].block_length= 0;                   /* Default block length */
  keyinfo[3].seg= &glob_keyseg[3][0];
  keyinfo[3].seg[0].start=0;
  keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0);
  keyinfo[3].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[3].seg[0].language=default_charset_info->number;
  keyinfo[3].seg[0].flag=(uint8) pack_seg;
  keyinfo[3].seg[0].null_bit=0;
  keyinfo[3].seg[0].null_pos=0;
  keyinfo[3].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[3].keysegs=1;
  keyinfo[3].flag = pack_type;
  keyinfo[3].block_length= 0;                   /* Default block length */
  keyinfo[4].seg= &glob_keyseg[4][0];
  keyinfo[4].seg[0].start=0;
  keyinfo[4].seg[0].length=5;
  keyinfo[4].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[4].seg[0].language=default_charset_info->number;
  keyinfo[4].seg[0].flag=0;
  keyinfo[4].seg[0].null_bit=0;
  keyinfo[4].seg[0].null_pos=0;
  keyinfo[4].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[4].keysegs=1;
  keyinfo[4].flag = pack_type;
  keyinfo[4].block_length= 0;                   /* Default block length */
  keyinfo[5].seg= &glob_keyseg[5][0];
  keyinfo[5].seg[0].start=0;
  keyinfo[5].seg[0].length=4;
  keyinfo[5].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[5].seg[0].language=default_charset_info->number;
  keyinfo[5].seg[0].flag=pack_seg;
  keyinfo[5].seg[0].null_bit=0;
  keyinfo[5].seg[0].null_pos=0;
  keyinfo[5].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[5].keysegs=1;
  keyinfo[5].flag = pack_type;
  keyinfo[5].block_length= 0;                   /* Default block length */

  recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
  recinfo[0].length=7;
  recinfo[0].null_bit=0;
  recinfo[0].null_pos=0;
  recinfo[1].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
  recinfo[1].length=5;
  recinfo[1].null_bit=0;
  recinfo[1].null_pos=0;
  recinfo[2].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
  recinfo[2].length=9;
  recinfo[2].null_bit=0;
  recinfo[2].null_pos=0;
  recinfo[3].type=FIELD_NORMAL;
  recinfo[3].length=STANDARD_LENGTH-7-5-9-4;
  recinfo[3].null_bit=0;
  recinfo[3].null_pos=0;
  recinfo[4].type=pack_fields ? FIELD_SKIP_ZERO : 0;
  recinfo[4].length=4;
  recinfo[4].null_bit=0;
  recinfo[4].null_pos=0;
  recinfo[5].type=pack_fields ? FIELD_SKIP_ENDSPACE : 0;
  recinfo[5].length=60;
  recinfo[5].null_bit=0;
  recinfo[5].null_pos=0;
  if (use_blob)
  {
    recinfo[6].type=FIELD_BLOB;
    recinfo[6].length=4+portable_sizeof_char_ptr;
    recinfo[6].null_bit=0;
    recinfo[6].null_pos=0;
  }

  write_count=update=dupp_keys=opt_delete=0;
  blob_buffer=0;

  for (i=1000 ; i>0 ; i--) key1[i]=0;
  for (i=5000 ; i>0 ; i--) key3[i]=0;

  if (!silent)
    printf("- Creating maria-file\n");
  file= 0;
  bzero((char*) &create_info,sizeof(create_info));
  create_info.max_rows=(ha_rows) (rec_pointer_size ?
				  (1L << (rec_pointer_size*8))/
				  reclength : 0);
  create_info.reloc_rows=(ha_rows) 100;
  create_info.transactional= transactional;
  if (maria_create(filename, record_type, keys,&keyinfo[first_key],
		use_blob ? 7 : 6, &recinfo[0],
		0,(MARIA_UNIQUEDEF*) 0,
		&create_info,create_flag))
    goto err;
  if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
    goto err;
  maria_begin(file);
  if (opt_versioning)
    maria_versioning(file, 1);
  if (testflag == 1)
    goto end;
  if (checkpoint == 1 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
    goto err;
  if (!silent)
    printf("- Writing key:s\n");
  if (do_locking)
    maria_lock_database(file,F_WRLCK);
  if (write_cacheing)
    maria_extra(file,HA_EXTRA_WRITE_CACHE,0);
  if (opt_quick_mode)
    maria_extra(file,HA_EXTRA_QUICK,0);

  for (i=0 ; i < recant ; i++)
  {
    ulong blob_length;
    n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
    sprintf((char*) record,"%6d:%4d:%8d:Pos: %4d    ",n1,n2,n3,write_count);
    int4store(record+STANDARD_LENGTH-4,(long) i);
    fix_length(record,(uint) STANDARD_LENGTH+rnd(60));
    put_blob_in_record(record+blob_pos,&blob_buffer, &blob_length);
    DBUG_PRINT("test",("record: %d  blob_length: %lu", i, blob_length));

    if (maria_write(file,record))
    {
      if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
      {
	printf("Error: %d in write at record: %d\n",my_errno,i);
	goto err;
      }
      if (verbose) printf("   Double key: %d at record# %d\n", n3, i);
    }
    else
    {
      if (key3[n3] == 1 && first_key <3 && first_key+keys >= 3)
      {
	printf("Error: Didn't get error when writing second key: '%8d'\n",n3);
	goto err2;
      }
      write_count++; key1[n1]++; key3[n3]=1;
    }

    /* Check if we can find key without flushing database */
    if (i % 10 == 0)
    {
      for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
      if (!j)
	for (j=999 ; j>0 && key1[j] == 0 ; j--) ;
      sprintf((char*) key,"%6d",j);
      if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      {
	printf("Test in loop: Can't find key: \"%s\"\n",key);
	goto err;
      }
    }
  }
  if (checkpoint == 2 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
    goto err;

  if (write_cacheing)
  {
    if (maria_extra(file,HA_EXTRA_NO_CACHE,0))
    {
      puts("got error from maria_extra(HA_EXTRA_NO_CACHE)");
      goto err;
    }
  }

  if (testflag == 2)
    goto end;

#ifdef REMOVE_WHEN_WE_HAVE_RESIZE
  if (pagecacheing)
    resize_pagecache(maria_pagecache, maria_block_size,
                     pagecache_size * 2, 0, 0);
#endif
  if (!silent)
    printf("- Delete\n");
  if (srand_arg)
    srand(srand_arg);
  if (!update_count)
    update_count= recant/10;

  for (i=0 ; i < update_count ; i++)
  {
    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
    if (j != 0)
    {
      sprintf((char*) key,"%6d",j);
      if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      {
	printf("can't find key1: \"%s\"\n",key);
	goto err;
      }
      if (bcmp(read_record+keyinfo[0].seg[0].start,
               key, keyinfo[0].seg[0].length))
      {
	printf("Found wrong record when searching for key: \"%s\"\n",key);
	goto err2;
      }
      if (opt_delete == (uint) remove_count)		/* While testing */
	goto end;
      if (maria_delete(file,read_record))
      {
	printf("error: %d; can't delete record: \"%s\"\n", my_errno,read_record);
	goto err;
      }
      opt_delete++;
      key1[atoi((char*) read_record+keyinfo[0].seg[0].start)]--;
      key3[atoi((char*) read_record+keyinfo[2].seg[0].start)]=0;
    }
    else
    {
      puts("Warning: Skipping delete test because no dupplicate keys");
      break;
    }
  }
  if (testflag == 3)
    goto end;
  if (checkpoint == 3 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
    goto err;

  if (!silent)
    printf("- Update\n");
  if (srand_arg)
    srand(srand_arg);
  if (!update_count)
    update_count= recant/10;

  for (i=0 ; i < update_count ; i++)
  {
    n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
    sprintf((char*) record2,"%6d:%4d:%8d:XXX: %4d     ",n1,n2,n3,update);
    int4store(record2+STANDARD_LENGTH-4,(long) i);
    fix_length(record2,(uint) STANDARD_LENGTH+rnd(60));

    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
    if (j != 0)
    {
      sprintf((char*) key,"%6d",j);
      if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      {
	printf("can't find key1: \"%s\"\n", (char*) key);
	goto err;
      }
      if (bcmp(read_record+keyinfo[0].seg[0].start,
               key, keyinfo[0].seg[0].length))
      {
	printf("Found wrong record when searching for key: \"%s\"; Found \"%.*s\"\n",
               key, keyinfo[0].seg[0].length,
               read_record+keyinfo[0].seg[0].start);
	goto err2;
      }
      if (use_blob)
      {
        ulong blob_length;
	if (i & 1)
	  put_blob_in_record(record2+blob_pos,&blob_buffer, &blob_length);
	else
	  bmove(record2+blob_pos, read_record+blob_pos, 4 + sizeof(char*));
      }
      if (skip_update)
        continue;
      if (maria_update(file,read_record,record2))
      {
	if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
	{
	  printf("error: %d; can't update:\nFrom: \"%s\"\nTo:   \"%s\"\n",
		 my_errno,read_record,record2);
	  goto err;
	}
	if (verbose)
	  printf("Double key when tried to update:\nFrom: \"%s\"\nTo:   \"%s\"\n",record,record2);
      }
      else
      {
	key1[atoi((char*) read_record+keyinfo[0].seg[0].start)]--;
	key3[atoi((char*) read_record+keyinfo[2].seg[0].start)]=0;
	key1[n1]++; key3[n3]=1;
	update++;
      }
    }
  }
  if (testflag == 4)
    goto end;
  if (checkpoint == 4 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
    goto err;

  for (i=999, dupp_keys=j=0 ; i>0 ; i--)
  {
    if (key1[i] > dupp_keys)
    {
      dupp_keys=key1[i]; j=i;
    }
  }
  sprintf((char*) key,"%6d",j);
  start=keyinfo[0].seg[0].start;
  length=keyinfo[0].seg[0].length;
  if (dupp_keys)
  {
    if (!silent)
      printf("- Same key: first - next -> last - prev -> first\n");
    DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
    if (verbose) printf("	 Using key: \"%s\"  Keys: %d\n",key,dupp_keys);

    if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    if (maria_rsame(file,read_record2,-1))
      goto err;
    if (memcmp(read_record,read_record2,reclength) != 0)
    {
      printf("maria_rsame didn't find same record\n");
      goto err2;
    }
    info.recpos=maria_position(file);
    if (maria_rfirst(file,read_record2,0) ||
	maria_rsame_with_pos(file,read_record2,0,info.recpos) ||
	memcmp(read_record,read_record2,reclength) != 0)
    {
      printf("maria_rsame_with_pos didn't find same record\n");
      goto err2;
    }
    {
      int skr;
      info.recpos= maria_position(file);
      skr= maria_rnext(file,read_record2,0);
      if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
	  maria_rprev(file,read_record2,0) ||
	  memcmp(read_record,read_record2,reclength) != 0 ||
          info.recpos != maria_position(file))
      {
	printf("maria_rsame_with_pos lost position\n");
	goto err;
      }
    }
    ant=1;
    while (maria_rnext(file,read_record2,0) == 0 &&
	   memcmp(read_record2+start,key,length) == 0) ant++;
    if (ant != dupp_keys)
    {
      printf("next: Found: %d keys of %d\n",ant,dupp_keys);
      goto err2;
    }
    ant=0;
    while (maria_rprev(file,read_record3,0) == 0 &&
	   bcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys)
    {
      printf("prev: Found: %d records of %d\n",ant,dupp_keys);
      goto err2;
    }

    /* Check of maria_rnext_same */
    if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    ant=1;
    while (!maria_rnext_same(file,read_record3) && ant < dupp_keys+10)
      ant++;
    if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
    {
      printf("maria_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
      goto err2;
    }
  }

  if (!silent)
    printf("- All keys: first - next -> last - prev -> first\n");
  DBUG_PRINT("progpos",("All keys: first - next -> last - prev -> first"));
  ant=1;
  if (maria_rfirst(file,read_record,0))
  {
    printf("Can't find first record\n");
    goto err;
  }
  while ((error=maria_rnext(file,read_record3,0)) == 0 && ant < write_count+10)
    ant++;
  if (ant != write_count - opt_delete || error != HA_ERR_END_OF_FILE)
  {
    printf("next: I found: %d records of %d (error: %d)\n",
	   ant, write_count - opt_delete, error);
    goto err;
  }
  if (maria_rlast(file,read_record2,0) ||
      bcmp(read_record2,read_record3,reclength))
  {
    printf("Can't find last record\n");
    DBUG_DUMP("record2", read_record2, reclength);
    DBUG_DUMP("record3", read_record3, reclength);
    goto err2;
  }
  ant=1;
  while (maria_rprev(file,read_record3,0) == 0 && ant < write_count+10)
    ant++;
  if (ant != write_count - opt_delete)
  {
    printf("prev: I found: %d records of %d\n",ant,write_count);
    goto err2;
  }
  if (bcmp(read_record,read_record3,reclength))
  {
    printf("Can't find first record\n");
    goto err2;
  }

  if (!silent)
    printf("- Test if: Read first - next - prev - prev - next == first\n");
  DBUG_PRINT("progpos",("- Read first - next - prev - prev - next == first"));
  if (maria_rfirst(file,read_record,0) ||
      maria_rnext(file,read_record3,0) ||
      maria_rprev(file,read_record3,0) ||
      maria_rprev(file,read_record3,0) == 0 ||
      maria_rnext(file,read_record3,0))
      goto err;
  if (bcmp(read_record,read_record3,reclength) != 0)
     printf("Can't find first record\n");

  if (!silent)
    printf("- Test if: Read last - prev - next - next - prev == last\n");
  DBUG_PRINT("progpos",("Read last - prev - next - next - prev == last"));
  if (maria_rlast(file,read_record2,0) ||
      maria_rprev(file,read_record3,0) ||
      maria_rnext(file,read_record3,0) ||
      maria_rnext(file,read_record3,0) == 0 ||
      maria_rprev(file,read_record3,0))
      goto err;
  if (bcmp(read_record2,read_record3,reclength))
     printf("Can't find last record\n");
#ifdef NOT_ANYMORE
  if (!silent)
    puts("- Test read key-part");
  strmov(key2,key);
  for(i=strlen(key2) ; i-- > 1 ;)
  {
    key2[i]=0;

    /* The following row is just to catch some bugs in the key code */
    bzero((char*) file->lastkey,file->s->base.max_key_length*2);
    if (maria_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX))
      goto err;
    if (bcmp(read_record+start,key,(uint) i))
    {
      puts("Didn't find right record");
      goto err2;
    }
  }
#endif
  if (dupp_keys > 2)
  {
    if (!silent)
      printf("- Read key (first) - next - delete - next -> last\n");
    DBUG_PRINT("progpos",("first - next - delete - next -> last"));
    if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    if (maria_rnext(file,read_record3,0)) goto err;
    if (maria_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=1;
    while (maria_rnext(file,read_record3,0) == 0 &&
	   bcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-1)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1);
      goto err2;
    }
  }
  if (dupp_keys>4)
  {
    if (!silent)
      printf("- Read last of key - prev - delete - prev -> first\n");
    DBUG_PRINT("progpos",("last - prev - delete - prev -> first"));
    if (maria_rprev(file,read_record3,0)) goto err;
    if (maria_rprev(file,read_record3,0)) goto err;
    if (maria_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=1;
    while (maria_rprev(file,read_record3,0) == 0 &&
	   bcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-2)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2);
      goto err2;
    }
  }
  if (dupp_keys > 6)
  {
    if (!silent)
      printf("- Read first - delete - next -> last\n");
    DBUG_PRINT("progpos",("first - delete - next -> last"));
    if (maria_rkey(file,read_record3,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    if (maria_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=1;
    if (maria_rnext(file,read_record,0))
      goto err;					/* Skall finnas poster */
    while (maria_rnext(file,read_record3,0) == 0 &&
	   bcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-3)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3);
      goto err2;
    }

    if (!silent)
      printf("- Read last - delete - prev -> first\n");
    DBUG_PRINT("progpos",("last - delete - prev -> first"));
    if (maria_rprev(file,read_record3,0)) goto err;
    if (maria_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=0;
    while (maria_rprev(file,read_record3,0) == 0 &&
	   bcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-4)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4);
      goto err2;
    }
  }

  if (!silent)
    puts("- Test if: Read rrnd - same");
  DBUG_PRINT("progpos",("Read rrnd - same"));
  assert(maria_scan_init(file) == 0);
  for (i=0 ; i < write_count ; i++)
  {
    int tmp;
    if ((tmp= maria_scan(file,read_record)) &&
        tmp != HA_ERR_END_OF_FILE &&
        tmp != HA_ERR_RECORD_DELETED)
    {
      printf("Got error %d when scanning table\n", tmp);
      break;
    }
    if (!tmp)
    {
      /* Remember position to last found row */
      info.recpos= maria_position(file);
      bmove(read_record2,read_record,reclength);
    }
  }
  maria_scan_end(file);
  if (i != write_count && i != write_count - opt_delete)
  {
    printf("Found wrong number of rows while scanning table\n");
    goto err2;
  }

  if (maria_rsame_with_pos(file,read_record,0,info.recpos))
    goto err;
  if (bcmp(read_record,read_record2,reclength) != 0)
  {
    printf("maria_rsame_with_pos didn't find same record\n");
    goto err2;
  }

  for (i=min(2,keys) ; i-- > 0 ;)
  {
    if (maria_rsame(file,read_record2,(int) i)) goto err;
    if (bcmp(read_record,read_record2,reclength) != 0)
    {
      printf("maria_rsame didn't find same record\n");
      goto err2;
    }
  }
  if (!silent)
    puts("- Test maria_records_in_range");
  maria_status(file,&info,HA_STATUS_VARIABLE);
  for (i=0 ; i < info.keys ; i++)
  {
    key_range min_key, max_key;
    if (maria_rfirst(file,read_record,(int) i) ||
	maria_rlast(file,read_record2,(int) i))
      goto err;
    copy_key(file,(uint) i, read_record,  key);
    copy_key(file,(uint) i, read_record2, key2);
    min_key.key= key;
    min_key.keypart_map= HA_WHOLE_KEY;
    min_key.flag= HA_READ_KEY_EXACT;
    max_key.key= key2;
    max_key.keypart_map= HA_WHOLE_KEY;
    max_key.flag= HA_READ_AFTER_KEY;

    range_records= maria_records_in_range(file,(int) i, &min_key, &max_key);
    if (range_records < info.records*8/10 ||
	range_records > info.records*12/10)
    {
      printf("maria_records_range returned %ld; Should be about %ld\n",
	     (long) range_records,(long) info.records);
      goto err2;
    }
    if (verbose)
    {
      printf("maria_records_range returned %ld;  Exact is %ld  (diff: %4.2g %%)\n",
	     (long) range_records, (long) info.records,
	     labs((long) range_records - (long) info.records)*100.0/
	     info.records);
    }
  }
  for (i=0 ; i < 5 ; i++)
  {
    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
    for (k=rnd(1000)+1 ; k>0 && key1[k] == 0 ; k--) ;
    if (j != 0 && k != 0)
    {
      key_range min_key, max_key;
      if (j > k)
	swap_variables(int, j, k);
      sprintf((char*) key,"%6d",j);
      sprintf((char*) key2,"%6d",k);

      min_key.key= key;
      min_key.keypart_map= HA_WHOLE_KEY;
      min_key.flag= HA_READ_AFTER_KEY;
      max_key.key= key2;
      max_key.keypart_map= HA_WHOLE_KEY;
      max_key.flag= HA_READ_BEFORE_KEY;
      range_records= maria_records_in_range(file, 0, &min_key, &max_key);
      records=0;
      for (j++ ; j < k ; j++)
	records+=key1[j];
      if ((long) range_records < (long) records*7/10-2 ||
	  (long) range_records > (long) records*14/10+2)
      {
	printf("maria_records_range for key: %d returned %lu; Should be about %lu\n",
	       i, (ulong) range_records, (ulong) records);
	goto err2;
      }
      if (verbose && records)
      {
	printf("maria_records_range returned %lu;  Exact is %lu  (diff: %4.2g %%)\n",
	       (ulong) range_records, (ulong) records,
	       labs((long) range_records-(long) records)*100.0/records);

      }
    }
    }

  if (!silent)
    printf("- maria_info\n");
  maria_status(file,&info,HA_STATUS_VARIABLE | HA_STATUS_CONST);
  if (info.records != write_count-opt_delete ||
      info.deleted > opt_delete + update || info.keys != keys)
  {
    puts("Wrong info from maria_info");
    printf("Got: records: %lu  delete: %lu  i_keys: %d\n",
	   (ulong) info.records, (ulong) info.deleted, info.keys);
    goto err2;
  }
  if (verbose)
  {
    char buff[80];
    get_date(buff,3,info.create_time);
    printf("info: Created %s\n",buff);
    get_date(buff,3,info.check_time);
    printf("info: checked %s\n",buff);
    get_date(buff,3,info.update_time);
    printf("info: Modified %s\n",buff);
  }

  maria_panic(HA_PANIC_WRITE);
  maria_panic(HA_PANIC_READ);
  if (maria_is_changed(file))
    puts("Warning: maria_is_changed reported that datafile was changed");

  if (!silent)
    printf("- maria_extra(CACHE) + maria_rrnd.... + maria_extra(NO_CACHE)\n");
  if (maria_reset(file) || maria_extra(file,HA_EXTRA_CACHE,0))
  {
    if (do_locking || (!use_blob && !pack_fields))
    {
      puts("got error from maria_extra(HA_EXTRA_CACHE)");
      goto err;
    }
  }
  ant=0;
  assert(maria_scan_init(file) == 0);
  while ((error= maria_scan(file,record)) != HA_ERR_END_OF_FILE &&
	 ant < write_count + 10)
    ant+= error ? 0 : 1;
  maria_scan_end(file);
  if (ant != write_count-opt_delete)
  {
    printf("scan with cache: I can only find: %d records of %d\n",
	   ant,write_count-opt_delete);
    maria_scan_end(file);
    goto err2;
  }
  if (maria_extra(file,HA_EXTRA_NO_CACHE,0))
  {
    puts("got error from maria_extra(HA_EXTRA_NO_CACHE)");
    maria_scan_end(file);
    goto err;
  }
  maria_scan_end(file);

  ant=0;
  maria_scan_init(file);
  while ((error=maria_scan(file,record)) != HA_ERR_END_OF_FILE &&
	 ant < write_count + 10)
	ant+= error ? 0 : 1;
  if (ant != write_count-opt_delete)
  {
    printf("scan with cache: I can only find: %d records of %d\n",
	   ant,write_count-opt_delete);
    maria_scan_end(file);
    goto err2;
  }
  maria_scan_end(file);

  if (testflag == 5)
    goto end;
  if (checkpoint == 5 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
    goto err;

  if (!silent)
    printf("- Removing keys\n");
  DBUG_PRINT("progpos",("Removing keys"));
  lastpos = HA_OFFSET_ERROR;
  /* DBUG_POP(); */
  maria_reset(file);
  found_parts=0;
  maria_scan_init(file);
  while ((error= maria_scan(file,read_record)) != HA_ERR_END_OF_FILE)
  {
    info.recpos=maria_position(file);
    if (lastpos >= info.recpos && lastpos != HA_OFFSET_ERROR)
    {
      printf("maria_rrnd didn't advance filepointer; old: %ld, new: %ld\n",
	     (long) lastpos, (long) info.recpos);
      goto err2;
    }
    lastpos=info.recpos;
    if (error == 0)
    {
      if (opt_delete == (uint) remove_count)		/* While testing */
	goto end;
      if (rnd(2) == 1 && maria_rsame(file,read_record,-1))
      {
	printf("can't find record %lx\n",(long) info.recpos);
	goto err;
      }
      if (use_blob)
      {
	ulong blob_length,pos;
	uchar *ptr;
	memcpy(&ptr, read_record+blob_pos+4, sizeof(ptr));
        blob_length= uint4korr(read_record+blob_pos);
	for (pos=0 ; pos < blob_length ; pos++)
	{
	  if (ptr[pos] != (uchar) (blob_length+pos))
	  {
	    printf("Found blob with wrong info at %ld\n",(long) lastpos);
            maria_scan_end(file);
            my_errno= 0;
	    goto err2;
	  }
	}
      }
      if (maria_delete(file,read_record))
      {
	printf("can't delete record: %6.6s, delete_count: %d\n",
	       read_record, opt_delete);
        maria_scan_end(file);
	goto err;
      }
      opt_delete++;
    }
    else
      found_parts++;
  }
  if (my_errno != HA_ERR_END_OF_FILE && my_errno != HA_ERR_RECORD_DELETED)
    printf("error: %d from maria_rrnd\n",my_errno);
  if (write_count != opt_delete)
  {
    printf("Deleted only %d of %d records (%d parts)\n",opt_delete,write_count,
	   found_parts);
    maria_scan_end(file);
    goto err2;
  }
  if (testflag == 6)
    goto end;
  if (checkpoint == 6 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
    goto err;

end:
  maria_scan_end(file);
  if (die_in_middle_of_transaction)
  {
    /* As commit record is not done, UNDO entries needs to be rolled back */
    switch (die_in_middle_of_transaction) {
    case 1:
      /*
        Flush changed data and index pages go to disk
        That will also flush log. Recovery will skip REDOs and apply UNDOs.
      */
      _ma_flush_table_files(file, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
                            FLUSH_RELEASE, FLUSH_RELEASE);
      break;
    case 2:
      /*
        Just flush log. Pages are likely to not be on disk. Recovery will
        then execute REDOs and UNDOs.
      */
      if (translog_flush(file->trn->undo_lsn))
        goto err;
      break;
    case 3:
      /*
        Flush nothing. Pages and log are likely to not be on disk. Recovery
        will then do nothing.
      */
      break;
    case 4:
      /*
        Flush changed data pages go to disk. Changed index pages are not
        flushed. Recovery will skip some REDOs and apply UNDOs.
      */
      _ma_flush_table_files(file, MARIA_FLUSH_DATA, FLUSH_RELEASE,
                            FLUSH_RELEASE);
      /*
        We have to flush log separately as the redo for the last key page
        may not be flushed
      */
      if (translog_flush(file->trn->undo_lsn))
        goto err;
      break;
    }
    printf("Dying on request without maria_commit()/maria_close()\n");
    sf_leaking_memory= 1; /* no memory leak reports here */
    exit(0);
  }
  if (maria_commit(file))
    goto err;
  if (maria_close(file))
  {
    file= 0;
    goto err;
  }
  file= 0;
  maria_panic(HA_PANIC_CLOSE);			/* Should close log */
  if (!silent)
  {
    printf("\nFollowing test have been made:\n");
    printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
    if (rec_pointer_size)
      printf("Record pointer size:  %d\n",rec_pointer_size);
    printf("maria_block_size:    %lu\n", maria_block_size);
    if (write_cacheing)
      puts("Key cache resized");
    if (write_cacheing)
      puts("Write cacheing used");
    if (write_cacheing)
      puts("quick mode");
    if (async_io && do_locking)
      puts("Asyncron io with locking used");
    else if (do_locking)
      puts("Locking used");
    if (use_blob)
      puts("blobs used");
    printf("key cache status: \n\
blocks used:%10lu\n\
not flushed:%10lu\n\
w_requests: %10lu\n\
writes:     %10lu\n\
r_requests: %10lu\n\
reads:      %10lu\n",
           maria_pagecache->blocks_used,
           maria_pagecache->global_blocks_changed,
           (ulong) maria_pagecache->global_cache_w_requests,
           (ulong) maria_pagecache->global_cache_write,
           (ulong) maria_pagecache->global_cache_r_requests,
           (ulong) maria_pagecache->global_cache_read);
  }
Пример #26
0
/* {{{ mysqlnd_stmt_execute_store_params */
static void
mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p,
								  size_t *buf_len, unsigned int null_byte_offset TSRMLS_DC)
{
	MYSQLND_STMT_DATA * stmt = s->data;
	unsigned int i = 0;
	size_t left = (*buf_len - (*p - *buf));
	size_t data_size = 0;
	zval **copies = NULL;/* if there are different types */

/* 1. Store type information */
	if (stmt->send_types_to_server) {

		/* 2 bytes per type, and leave 20 bytes for future use */
		if (left < ((stmt->param_count * 2) + 20)) {
			unsigned int offset = *p - *buf;
			zend_uchar *tmp_buf;
			*buf_len = offset + stmt->param_count * 2 + 20;
			tmp_buf = mnd_emalloc(*buf_len);
			memcpy(tmp_buf, *buf, offset);
			*buf = tmp_buf;
			
			/* Update our pos pointer */
			*p = *buf + offset;
		}
		for (i = 0; i < stmt->param_count; i++) {
			/* our types are not unsigned */
#if SIZEOF_LONG==8  
			if (stmt->param_bind[i].type == MYSQL_TYPE_LONG) {
				stmt->param_bind[i].type = MYSQL_TYPE_LONGLONG;
			}
#endif
			int2store(*p, stmt->param_bind[i].type);
			*p+= 2;
		}
	}

/* 2. Store data */
	/* 2.1 Calculate how much space we need */
	for (i = 0; i < stmt->param_count; i++) {
		unsigned int j;
		zval *the_var = stmt->param_bind[i].zv;

		if (!the_var || (stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB &&
						 Z_TYPE_P(the_var) == IS_NULL)) {
			continue;
		}
		for (j = i + 1; j < stmt->param_count; j++) {
			if (stmt->param_bind[j].zv == the_var) {
				/* Double binding of the same zval, make a copy */
				mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
				break; 
			}
		}

		switch (stmt->param_bind[i].type) {
			case MYSQL_TYPE_DOUBLE:
				data_size += 8;
				if (Z_TYPE_P(the_var) != IS_DOUBLE) {
					if (!copies || !copies[i]) {
						mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
					}
				}
				break;
#if SIZEOF_LONG==8  
			case MYSQL_TYPE_LONGLONG:
				data_size += 8;
#elif SIZEOF_LONG==4
			case MYSQL_TYPE_LONG:
				data_size += 4;
#else
#error "Should not happen"
#endif
				if (Z_TYPE_P(the_var) != IS_LONG) {
					if (!copies || !copies[i]) {
						mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
					}
				}
				break;
			case MYSQL_TYPE_LONG_BLOB:
				if (!(stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED)) {
					/*
					  User hasn't sent anything, we will send empty string.
					  Empty string has length of 0, encoded in 1 byte. No real
					  data will follows after it.
					*/
					data_size++;
				}
				break;
			case MYSQL_TYPE_VAR_STRING:
				data_size += 8; /* max 8 bytes for size */
#if PHP_MAJOR_VERSION < 6
				if (Z_TYPE_P(the_var) != IS_STRING)
#elif PHP_MAJOR_VERSION >= 6
				if (Z_TYPE_P(the_var) != IS_STRING || Z_TYPE_P(the_var) == IS_UNICODE)
#endif
				{
					if (!copies || !copies[i]) {
						mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
					}
					the_var = copies[i];
#if PHP_MAJOR_VERSION >= 6
					if (Z_TYPE_P(the_var) == IS_UNICODE) {
						zval_unicode_to_string_ex(the_var, UG(utf8_conv) TSRMLS_CC);
					}
#endif
				}
				convert_to_string_ex(&the_var);
				data_size += Z_STRLEN_P(the_var);
				break;
		}

	}

	/* 2.2 Enlarge the buffer, if needed */
	left = (*buf_len - (*p - *buf));
	if (left < data_size) {
		unsigned int offset = *p - *buf;
		zend_uchar *tmp_buf;
		*buf_len = offset + data_size + 10; /* Allocate + 10 for safety */
		tmp_buf = mnd_emalloc(*buf_len);
		memcpy(tmp_buf, *buf, offset);
		*buf = tmp_buf;
		/* Update our pos pointer */
		*p = *buf + offset;	
	}

	/* 2.3 Store the actual data */
	for (i = 0; i < stmt->param_count; i++) {
		zval *data = copies && copies[i]? copies[i]: stmt->param_bind[i].zv;
		/* Handle long data */
		if (stmt->param_bind[i].zv && Z_TYPE_P(data) == IS_NULL) {
			(*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
		} else {
			switch (stmt->param_bind[i].type) {
				case MYSQL_TYPE_DOUBLE:
					convert_to_double_ex(&data);
					float8store(*p, Z_DVAL_P(data));
					(*p) += 8;
					break;
#if SIZEOF_LONG==8  
				case MYSQL_TYPE_LONGLONG:
					convert_to_long_ex(&data);
					int8store(*p, Z_LVAL_P(data));
					(*p) += 8;
					break;
#elif SIZEOF_LONG==4
				case MYSQL_TYPE_LONG:
					convert_to_long_ex(&data);
					int4store(*p, Z_LVAL_P(data));
					(*p) += 4;
					break;
#else
#error "Should not happen"
#endif
				case MYSQL_TYPE_LONG_BLOB:
					if (stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED) {
						stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED;
					} else {
						/* send_long_data() not called, send empty string */
						*p = php_mysqlnd_net_store_length(*p, 0);
					}
					break;
				case MYSQL_TYPE_VAR_STRING:{
						unsigned int len = Z_STRLEN_P(data);
						/* to is after p. The latter hasn't been moved */
						*p = php_mysqlnd_net_store_length(*p, len);
						memcpy(*p, Z_STRVAL_P(data), len);
						(*p) += len;
					}
					break;
				default:
					/* Won't happen, but set to NULL */
					(*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
					break;
			}
		}
	}
	if (copies) {
		for (i = 0; i < stmt->param_count; i++) {
			if (copies[i]) {
				zval_ptr_dtor(&copies[i]);
			}
		}
		mnd_efree(copies);	
	}
}
int main(int argc __attribute__((unused)), char *argv[])
{
  uint pagen;
  int rc= 1;
  uchar long_tr_id[6];
  PAGECACHE pagecache;
  LSN first_lsn;
  TRANSLOG_HEADER_BUFFER rec;
  LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1];
  translog_size_t len;

  MY_INIT(argv[0]);

  plan(1);

  bzero(&pagecache, sizeof(pagecache));
  maria_data_root= create_tmpdir(argv[0]);
  if (maria_log_remove(0))
    exit(1);

  bzero(long_tr_id, 6);
#ifndef DBUG_OFF
#if defined(__WIN__)
  default_dbug_option= "d:t:i:O,\\ma_test_loghandler.trace";
#else
  default_dbug_option= "d:t:i:o,/tmp/ma_test_loghandler.trace";
#endif
  if (argc > 1)
  {
    DBUG_SET(default_dbug_option);
    DBUG_SET_INITIAL(default_dbug_option);
  }
#endif

  if (ma_control_file_open(TRUE, TRUE))
  {
    fprintf(stderr, "Can't init control file (%d)\n", errno);
    exit(1);
  }
  if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
                             PCACHE_PAGE, 0)) == 0)
  {
    fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
    exit(1);
  }
  if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache,
                               LOG_FLAGS, 0, &translog_example_table_init,
                               0))
  {
    fprintf(stderr, "Can't init loghandler (%d)\n", errno);
    exit(1);
  }
  /* Suppressing of automatic record writing */
  dummy_transaction_object.first_undo_lsn|= TRANSACTION_LOGGED_LONG_ID;

  int4store(long_tr_id, 0);
  long_tr_id[5]= 0xff;
  parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
  parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
  if (translog_write_record(&first_lsn,
                            LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                            &dummy_transaction_object, NULL, 6,
                            TRANSLOG_INTERNAL_PARTS + 1,
                            parts, NULL, NULL))
  {
    fprintf(stderr, "Can't write record #%lu\n", (ulong) 0);
    translog_destroy();
    exit(1);
  }

  len= translog_read_record_header(first_lsn, &rec);
  if (len == 0)
  {
    fprintf(stderr, "translog_read_record_header failed (%d)\n", errno);
    goto err;
  }
  if (rec.type !=LOGREC_FIXED_RECORD_0LSN_EXAMPLE || rec.short_trid != 0 ||
      rec.record_length != 6 || uint4korr(rec.header) != 0 ||
      ((uchar)rec.header[4]) != 0 || ((uchar)rec.header[5]) != 0xFF ||
      first_lsn != rec.lsn)
  {
    fprintf(stderr, "Incorrect LOGREC_FIXED_RECORD_0LSN_EXAMPLE "
            "data read(0)\n"
            "type: %u (%d)  strid: %u (%d)  len: %u (%d)  i: %u (%d), "
            "4: %u (%d)  5: %u (%d)  "
            "lsn(%lu,0x%lx) (%d)\n",
            (uint) rec.type, (rec.type !=LOGREC_FIXED_RECORD_0LSN_EXAMPLE),
            (uint) rec.short_trid, (rec.short_trid != 0),
            (uint) rec.record_length, (rec.record_length != 6),
            (uint) uint4korr(rec.header), (uint4korr(rec.header) != 0),
            (uint) rec.header[4], (((uchar)rec.header[4]) != 0),
            (uint) rec.header[5], (((uchar)rec.header[5]) != 0xFF),
            LSN_IN_PARTS(rec.lsn), (first_lsn != rec.lsn));
    goto err;
  }

  ok(1, "read OK");
  rc= 0;

err:
  translog_destroy();
  end_pagecache(&pagecache, 1);
  ma_control_file_end();
  if (maria_log_remove(maria_data_root))
    exit(1);

  exit(rc);
}
Пример #28
0
int test_update(MI_INFO *file,int id,int lock_type)
{
  uint i,lock,found,next,prev,update;
  uint32 tmp;
  char find[4];
  struct record new_record;

  lock=0;
  if (rnd(2) == 0 || lock_type == F_RDLCK)
  {
    lock=1;
    if (mi_lock_database(file,F_WRLCK))
    {
      if (lock_type == F_RDLCK && my_errno == EDEADLK)
      {
	printf("%2d: write:  deadlock\n",id); fflush(stdout);
	return 0;
      }
      fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
      return 1;
    }
  }
  bzero((char*) &new_record,sizeof(new_record));
  strmov((char*) new_record.text,"Updated");

  found=next=prev=update=0;
  for (i=0 ; i < 100 ; i++)
  {
    tmp=rnd(100000);
    int4store(find,tmp);
    if (!mi_rkey(file,record.id,1,(uchar*) find, HA_WHOLE_KEY,
                 HA_READ_KEY_EXACT))
      found++;
    else
    {
      if (my_errno != HA_ERR_KEY_NOT_FOUND)
      {
	fprintf(stderr,"%2d: Got error %d from read in update\n",id,my_errno);
	return 1;
      }
      else if (!mi_rnext(file,record.id,1))
	next++;
      else
      {
	if (my_errno != HA_ERR_END_OF_FILE)
	{
	  fprintf(stderr,"%2d: Got error %d from rnext in update\n",
		  id,my_errno);
	  return 1;
	}
	else if (!mi_rprev(file,record.id,1))
	  prev++;
	else
	{
	  if (my_errno != HA_ERR_END_OF_FILE)
	  {
	    fprintf(stderr,"%2d: Got error %d from rnext in update\n",
		    id,my_errno);
	    return 1;
	  }
	  continue;
	}
      }
    }
    memcpy(new_record.id, record.id, sizeof(record.id));
    tmp=rnd(20000)+40000;
    int4store(new_record.nr,tmp);
    if (!mi_update(file,record.id,new_record.id))
      update++;
    else
    {
      if (my_errno != HA_ERR_RECORD_CHANGED &&
	  my_errno != HA_ERR_RECORD_DELETED &&
	  my_errno != HA_ERR_FOUND_DUPP_KEY)
      {
	fprintf(stderr,"%2d: Got error %d from update\n",id,my_errno);
	return 1;
      }
    }
  }
  if (lock)
  {
    if (mi_lock_database(file,F_UNLCK))
    {
      fprintf(stderr,"Can't unlock table,id, error%d\n",my_errno);
      return 1;
    }
  }
  printf("%2d: update: %5d\n",id,update); fflush(stdout);
  return 0;
}
Пример #29
0
int main(int argc, char *argv[])
{
  uint i;
  int j,n1,n2,n3,error,k;
  uint write_count,update,dupp_keys,opt_delete,start,length,blob_pos,
       reclength,ant,found_parts;
  my_off_t lastpos;
  ha_rows range_records,records;
  MI_INFO *file;
  MI_KEYDEF keyinfo[10];
  MI_COLUMNDEF recinfo[10];
  MI_ISAMINFO info;
  const char *filename;
  char *blob_buffer;
  MI_CREATE_INFO create_info;
  MY_INIT(argv[0]);

  filename= "test2";
  get_options(argc,argv);
  if (! async_io)
    my_disable_async_io=1;

  reclength=STANDARD_LENGTH+60+(use_blob ? 8 : 0);
  blob_pos=STANDARD_LENGTH+60;
  keyinfo[0].seg= &glob_keyseg[0][0];
  keyinfo[0].seg[0].start=0;
  keyinfo[0].seg[0].length=6;
  keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[0].seg[0].language= default_charset_info->number;
  keyinfo[0].seg[0].flag=(uint8) pack_seg;
  keyinfo[0].seg[0].null_bit=0;
  keyinfo[0].seg[0].null_pos=0;
  keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[0].keysegs=1;
  keyinfo[0].flag = pack_type;
  keyinfo[0].block_length= 0;                   /* Default block length */
  keyinfo[1].seg= &glob_keyseg[1][0];
  keyinfo[1].seg[0].start=7;
  keyinfo[1].seg[0].length=6;
  keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
  keyinfo[1].seg[0].flag=0;
  keyinfo[1].seg[0].null_bit=0;
  keyinfo[1].seg[0].null_pos=0;
  keyinfo[1].seg[1].start=0;			/* two part key */
  keyinfo[1].seg[1].length=6;
  keyinfo[1].seg[1].type=HA_KEYTYPE_NUM;
  keyinfo[1].seg[1].flag=HA_REVERSE_SORT;
  keyinfo[1].seg[1].null_bit=0;
  keyinfo[1].seg[1].null_pos=0;
  keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[1].keysegs=2;
  keyinfo[1].flag =0;
  keyinfo[1].block_length= MI_MIN_KEY_BLOCK_LENGTH;  /* Diff blocklength */
  keyinfo[2].seg= &glob_keyseg[2][0];
  keyinfo[2].seg[0].start=12;
  keyinfo[2].seg[0].length=8;
  keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
  keyinfo[2].seg[0].flag=HA_REVERSE_SORT;
  keyinfo[2].seg[0].null_bit=0;
  keyinfo[2].seg[0].null_pos=0;
  keyinfo[2].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[2].keysegs=1;
  keyinfo[2].flag =HA_NOSAME;
  keyinfo[2].block_length= 0;                   /* Default block length */
  keyinfo[3].seg= &glob_keyseg[3][0];
  keyinfo[3].seg[0].start=0;
  keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0);
  keyinfo[3].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[3].seg[0].language=default_charset_info->number;
  keyinfo[3].seg[0].flag=(uint8) pack_seg;
  keyinfo[3].seg[0].null_bit=0;
  keyinfo[3].seg[0].null_pos=0;
  keyinfo[3].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[3].keysegs=1;
  keyinfo[3].flag = pack_type;
  keyinfo[3].block_length= 0;                   /* Default block length */
  keyinfo[4].seg= &glob_keyseg[4][0];
  keyinfo[4].seg[0].start=0;
  keyinfo[4].seg[0].length=5;
  keyinfo[4].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[4].seg[0].language=default_charset_info->number;
  keyinfo[4].seg[0].flag=0;
  keyinfo[4].seg[0].null_bit=0;
  keyinfo[4].seg[0].null_pos=0;
  keyinfo[4].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[4].keysegs=1;
  keyinfo[4].flag = pack_type;
  keyinfo[4].block_length= 0;                   /* Default block length */
  keyinfo[5].seg= &glob_keyseg[5][0];
  keyinfo[5].seg[0].start=0;
  keyinfo[5].seg[0].length=4;
  keyinfo[5].seg[0].type=HA_KEYTYPE_TEXT;
  keyinfo[5].seg[0].language=default_charset_info->number;
  keyinfo[5].seg[0].flag=pack_seg;
  keyinfo[5].seg[0].null_bit=0;
  keyinfo[5].seg[0].null_pos=0;
  keyinfo[5].key_alg=HA_KEY_ALG_BTREE;
  keyinfo[5].keysegs=1;
  keyinfo[5].flag = pack_type;
  keyinfo[5].block_length= 0;                   /* Default block length */

  recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
  recinfo[0].length=7;
  recinfo[0].null_bit=0;
  recinfo[0].null_pos=0;
  recinfo[1].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
  recinfo[1].length=5;
  recinfo[1].null_bit=0;
  recinfo[1].null_pos=0;
  recinfo[2].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
  recinfo[2].length=9;
  recinfo[2].null_bit=0;
  recinfo[2].null_pos=0;
  recinfo[3].type=FIELD_NORMAL;
  recinfo[3].length=STANDARD_LENGTH-7-5-9-4;
  recinfo[3].null_bit=0;
  recinfo[3].null_pos=0;
  recinfo[4].type=pack_fields ? FIELD_SKIP_ZERO : 0;
  recinfo[4].length=4;
  recinfo[4].null_bit=0;
  recinfo[4].null_pos=0;
  recinfo[5].type=pack_fields ? FIELD_SKIP_ENDSPACE : 0;
  recinfo[5].length=60;
  recinfo[5].null_bit=0;
  recinfo[5].null_pos=0;
  if (use_blob)
  {
    recinfo[6].type=FIELD_BLOB;
    recinfo[6].length=4+portable_sizeof_char_ptr;
    recinfo[6].null_bit=0;
    recinfo[6].null_pos=0;
  }

  write_count=update=dupp_keys=opt_delete=0;
  blob_buffer=0;

  for (i=1000 ; i>0 ; i--) key1[i]=0;
  for (i=4999 ; i>0 ; i--) key3[i]=0;

  if (!silent)
    printf("- Creating isam-file\n");
  /*  DBUG_PUSH(""); */
  /* my_delete(filename,MYF(0)); */	/* Remove old locks under gdb */
  file= 0;
  bzero((char*) &create_info,sizeof(create_info));
  create_info.max_rows=(ha_rows) (rec_pointer_size ?
				  (1L << (rec_pointer_size*8))/
				  reclength : 0);
  create_info.reloc_rows=(ha_rows) 100;
  if (mi_create(filename,keys,&keyinfo[first_key],
		use_blob ? 7 : 6, &recinfo[0],
		0,(MI_UNIQUEDEF*) 0,
		&create_info,create_flag))
    goto err;
  if (use_log)
    mi_log(1);
  if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
    goto err;
  if (!silent)
    printf("- Writing key:s\n");
  if (key_cacheing)
    init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0);
  if (locking)
    mi_lock_database(file,F_WRLCK);
  if (write_cacheing)
    mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
  if (opt_quick_mode)
    mi_extra(file,HA_EXTRA_QUICK,0);

  for (i=0 ; i < recant ; i++)
  {
    n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
    sprintf((char*) record,"%6d:%4d:%8d:Pos: %4d    ",n1,n2,n3,write_count);
    int4store(record+STANDARD_LENGTH-4,(long) i);
    fix_length(record,(uint) STANDARD_LENGTH+rnd(60));
    put_blob_in_record(record+blob_pos,&blob_buffer);
    DBUG_PRINT("test",("record: %d",i));

    if (mi_write(file,record))
    {
      if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
      {
	printf("Error: %d in write at record: %d\n",my_errno,i);
	goto err;
      }
      if (verbose) printf("   Double key: %d\n",n3);
    }
    else
    {
      if (key3[n3] == 1 && first_key <3 && first_key+keys >= 3)
      {
	printf("Error: Didn't get error when writing second key: '%8d'\n",n3);
	goto err;
      }
      write_count++; key1[n1]++; key3[n3]=1;
    }

    /* Check if we can find key without flushing database */
    if (i == recant/2)
    {
      for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
      if (!j)
	for (j=999 ; j>0 && key1[j] == 0 ; j--) ;
      sprintf((char*) key,"%6d",j);
      if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      {
	printf("Test in loop: Can't find key: \"%s\"\n",key);
	goto err;
      }
    }
  }
  if (testflag==1) goto end;

  if (write_cacheing)
  {
    if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
    {
      puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
      goto end;
    }
  }
  if (key_cacheing)
    resize_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size*2,0,0);

  if (!silent)
    printf("- Delete\n");
  for (i=0 ; i<recant/10 ; i++)
  {
    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
    if (j != 0)
    {
      sprintf((char*) key,"%6d",j);
      if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      {
	printf("can't find key1: \"%s\"\n",key);
	goto err;
      }
      if (opt_delete == (uint) remove_count)		/* While testing */
	goto end;
      if (mi_delete(file,read_record))
      {
	printf("error: %d; can't delete record: \"%s\"\n", my_errno,read_record);
	goto err;
      }
      opt_delete++;
      key1[atoi((char*) read_record+keyinfo[0].seg[0].start)]--;
      key3[atoi((char*) read_record+keyinfo[2].seg[0].start)]=0;
    }
    else
      puts("Warning: Skipping delete test because no dupplicate keys");
  }
  if (testflag==2) goto end;

  if (!silent)
    printf("- Update\n");
  for (i=0 ; i<recant/10 ; i++)
  {
    n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
    sprintf((char*) record2,"%6d:%4d:%8d:XXX: %4d     ",n1,n2,n3,update);
    int4store(record2+STANDARD_LENGTH-4,(long) i);
    fix_length(record2,(uint) STANDARD_LENGTH+rnd(60));

    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
    if (j != 0)
    {
      sprintf((char*) key,"%6d",j);
      if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      {
	printf("can't find key1: \"%s\"\n",(char*) key);
	goto err;
      }
      if (use_blob)
      {
	if (i & 1)
	  put_blob_in_record(record+blob_pos,&blob_buffer);
	else
	  bmove(record+blob_pos,read_record+blob_pos,8);
      }
      if (mi_update(file,read_record,record2))
      {
	if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
	{
	  printf("error: %d; can't update:\nFrom: \"%s\"\nTo:   \"%s\"\n",
		 my_errno,read_record,record2);
	  goto err;
	}
	if (verbose)
	  printf("Double key when tried to update:\nFrom: \"%s\"\nTo:   \"%s\"\n",record,record2);
      }
      else
      {
	key1[atoi((char*) read_record+keyinfo[0].seg[0].start)]--;
	key3[atoi((char*) read_record+keyinfo[2].seg[0].start)]=0;
	key1[n1]++; key3[n3]=1;
	update++;
      }
    }
  }
  if (testflag == 3)
    goto end;

  for (i=999, dupp_keys=j=0 ; i>0 ; i--)
  {
    if (key1[i] > dupp_keys)
    {
      dupp_keys=key1[i]; j=i;
    }
  }
  sprintf((char*) key,"%6d",j);
  start=keyinfo[0].seg[0].start;
  length=keyinfo[0].seg[0].length;
  if (dupp_keys)
  {
    if (!silent)
      printf("- Same key: first - next -> last - prev -> first\n");
    DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
    if (verbose) printf("	 Using key: \"%s\"  Keys: %d\n",key,dupp_keys);

    if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    if (mi_rsame(file,read_record2,-1))
      goto err;
    if (memcmp(read_record,read_record2,reclength) != 0)
    {
      printf("mi_rsame didn't find same record\n");
      goto end;
    }
    info.recpos=mi_position(file);
    if (mi_rfirst(file,read_record2,0) ||
	mi_rsame_with_pos(file,read_record2,0,info.recpos) ||
	memcmp(read_record,read_record2,reclength) != 0)
    {
      printf("mi_rsame_with_pos didn't find same record\n");
      goto end;
    }
    {
      int skr=mi_rnext(file,read_record2,0);
      if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
	  mi_rprev(file,read_record2,-1) ||
	  memcmp(read_record,read_record2,reclength) != 0)
      {
	printf("mi_rsame_with_pos lost position\n");
	goto end;
      }
    }
    ant=1;
    while (mi_rnext(file,read_record2,0) == 0 &&
	   memcmp(read_record2+start,key,length) == 0) ant++;
    if (ant != dupp_keys)
    {
      printf("next: Found: %d keys of %d\n",ant,dupp_keys);
      goto end;
    }
    ant=0;
    while (mi_rprev(file,read_record3,0) == 0 &&
	   memcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys)
    {
      printf("prev: Found: %d records of %d\n",ant,dupp_keys);
      goto end;
    }

    /* Check of mi_rnext_same */
    if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    ant=1;
    while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
      ant++;
    if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
    {
      printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
      goto end;
    }
  }

  if (!silent)
    printf("- All keys: first - next -> last - prev -> first\n");
  DBUG_PRINT("progpos",("All keys: first - next -> last - prev -> first"));
  ant=1;
  if (mi_rfirst(file,read_record,0))
  {
    printf("Can't find first record\n");
    goto end;
  }
  while ((error=mi_rnext(file,read_record3,0)) == 0 && ant < write_count+10)
    ant++;
  if (ant != write_count - opt_delete || error != HA_ERR_END_OF_FILE)
  {
    printf("next: I found: %d records of %d (error: %d)\n",
	   ant, write_count - opt_delete, error);
    goto end;
  }
  if (mi_rlast(file,read_record2,0) ||
      memcmp(read_record2,read_record3,reclength))
  {
    printf("Can't find last record\n");
    DBUG_DUMP("record2",(uchar*) read_record2,reclength);
    DBUG_DUMP("record3",(uchar*) read_record3,reclength);
    goto end;
  }
  ant=1;
  while (mi_rprev(file,read_record3,0) == 0 && ant < write_count+10)
    ant++;
  if (ant != write_count - opt_delete)
  {
    printf("prev: I found: %d records of %d\n",ant,write_count);
    goto end;
  }
  if (memcmp(read_record,read_record3,reclength))
  {
    printf("Can't find first record\n");
    goto end;
  }

  if (!silent)
    printf("- Test if: Read first - next - prev - prev - next == first\n");
  DBUG_PRINT("progpos",("- Read first - next - prev - prev - next == first"));
  if (mi_rfirst(file,read_record,0) ||
      mi_rnext(file,read_record3,0) ||
      mi_rprev(file,read_record3,0) ||
      mi_rprev(file,read_record3,0) == 0 ||
      mi_rnext(file,read_record3,0))
      goto err;
  if (memcmp(read_record,read_record3,reclength) != 0)
     printf("Can't find first record\n");

  if (!silent)
    printf("- Test if: Read last - prev - next - next - prev == last\n");
  DBUG_PRINT("progpos",("Read last - prev - next - next - prev == last"));
  if (mi_rlast(file,read_record2,0) ||
      mi_rprev(file,read_record3,0) ||
      mi_rnext(file,read_record3,0) ||
      mi_rnext(file,read_record3,0) == 0 ||
      mi_rprev(file,read_record3,0))
      goto err;
  if (memcmp(read_record2,read_record3,reclength))
     printf("Can't find last record\n");
#ifdef NOT_ANYMORE
  if (!silent)
    puts("- Test read key-part");
  strmov(key2,key);
  for(i=strlen(key2) ; i-- > 1 ;)
  {
    key2[i]=0;

    /* The following row is just to catch some bugs in the key code */
    bzero((char*) file->lastkey,file->s->base.max_key_length*2);
    if (mi_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX))
      goto err;
    if (memcmp(read_record+start,key,(uint) i))
    {
      puts("Didn't find right record");
      goto end;
    }
  }
#endif
  if (dupp_keys > 2)
  {
    if (!silent)
      printf("- Read key (first) - next - delete - next -> last\n");
    DBUG_PRINT("progpos",("first - next - delete - next -> last"));
    if (mi_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    if (mi_rnext(file,read_record3,0)) goto err;
    if (mi_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=1;
    while (mi_rnext(file,read_record3,0) == 0 &&
	   memcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-1)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1);
      goto end;
    }
  }
  if (dupp_keys>4)
  {
    if (!silent)
      printf("- Read last of key - prev - delete - prev -> first\n");
    DBUG_PRINT("progpos",("last - prev - delete - prev -> first"));
    if (mi_rprev(file,read_record3,0)) goto err;
    if (mi_rprev(file,read_record3,0)) goto err;
    if (mi_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=1;
    while (mi_rprev(file,read_record3,0) == 0 &&
	   memcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-2)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2);
      goto end;
    }
  }
  if (dupp_keys > 6)
  {
    if (!silent)
      printf("- Read first - delete - next -> last\n");
    DBUG_PRINT("progpos",("first - delete - next -> last"));
    if (mi_rkey(file,read_record3,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
      goto err;
    if (mi_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=1;
    if (mi_rnext(file,read_record,0))
      goto err;					/* Skall finnas poster */
    while (mi_rnext(file,read_record3,0) == 0 &&
	   memcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-3)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3);
      goto end;
    }

    if (!silent)
      printf("- Read last - delete - prev -> first\n");
    DBUG_PRINT("progpos",("last - delete - prev -> first"));
    if (mi_rprev(file,read_record3,0)) goto err;
    if (mi_delete(file,read_record3)) goto err;
    opt_delete++;
    ant=0;
    while (mi_rprev(file,read_record3,0) == 0 &&
	   memcmp(read_record3+start,key,length) == 0) ant++;
    if (ant != dupp_keys-4)
    {
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4);
      goto end;
    }
  }

  if (!silent)
    puts("- Test if: Read rrnd - same");
  DBUG_PRINT("progpos",("Read rrnd - same"));
  for (i=0 ; i < write_count ; i++)
  {
    if (mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR) == 0)
      break;
  }
  if (i == write_count)
    goto err;

  bmove(read_record2,read_record,reclength);
  for (i=min(2,keys) ; i-- > 0 ;)
  {
    if (mi_rsame(file,read_record2,(int) i)) goto err;
    if (memcmp(read_record,read_record2,reclength) != 0)
    {
      printf("is_rsame didn't find same record\n");
      goto end;
    }
  }
  if (!silent)
    puts("- Test mi_records_in_range");
  mi_status(file,&info,HA_STATUS_VARIABLE);
  for (i=0 ; i < info.keys ; i++)
  {
    key_range min_key, max_key;
    if (mi_rfirst(file,read_record,(int) i) ||
	mi_rlast(file,read_record2,(int) i))
      goto err;
    copy_key(file,(uint) i,(uchar*) read_record,(uchar*) key);
    copy_key(file,(uint) i,(uchar*) read_record2,(uchar*) key2);
    min_key.key= key;
    min_key.keypart_map= HA_WHOLE_KEY;
    min_key.flag= HA_READ_KEY_EXACT;
    max_key.key= key2;
    max_key.keypart_map= HA_WHOLE_KEY;
    max_key.flag= HA_READ_AFTER_KEY;

    range_records= mi_records_in_range(file,(int) i, &min_key, &max_key);
    if (range_records < info.records*8/10 ||
	range_records > info.records*12/10)
    {
      printf("mi_records_range returned %ld; Should be about %ld\n",
	     (long) range_records,(long) info.records);
      goto end;
    }
    if (verbose)
    {
      printf("mi_records_range returned %ld;  Exact is %ld  (diff: %4.2g %%)\n",
	     (long) range_records, (long) info.records,
	     labs((long) range_records - (long) info.records)*100.0/
	     info.records);
    }
  }
  for (i=0 ; i < 5 ; i++)
  {
    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
    for (k=rnd(1000)+1 ; k>0 && key1[k] == 0 ; k--) ;
    if (j != 0 && k != 0)
    {
      key_range min_key, max_key;
      if (j > k)
	swap_variables(int, j, k);
      sprintf((char*) key,"%6d",j);
      sprintf((char*) key2,"%6d",k);

      min_key.key= key;
      min_key.length= USE_WHOLE_KEY;
      min_key.flag= HA_READ_AFTER_KEY;
      max_key.key= key2;
      max_key.length= USE_WHOLE_KEY;
      max_key.flag= HA_READ_BEFORE_KEY;
      range_records= mi_records_in_range(file, 0, &min_key, &max_key);
      records=0;
      for (j++ ; j < k ; j++)
	records+=key1[j];
      if ((long) range_records < (long) records*7/10-2 ||
	  (long) range_records > (long) records*14/10+2)
      {
	printf("mi_records_range for key: %d returned %lu; Should be about %lu\n",
	       i, (ulong) range_records, (ulong) records);
	goto end;
      }
      if (verbose && records)
      {
	printf("mi_records_range returned %lu;  Exact is %lu  (diff: %4.2g %%)\n",
	       (ulong) range_records, (ulong) records,
	       labs((long) range_records-(long) records)*100.0/records);

      }
    }
    }

  if (!silent)
    printf("- mi_info\n");
  mi_status(file,&info,HA_STATUS_VARIABLE | HA_STATUS_CONST);
  if (info.records != write_count-opt_delete || info.deleted > opt_delete + update
      || info.keys != keys)
  {
    puts("Wrong info from mi_info");
    printf("Got: records: %lu  delete: %lu  i_keys: %d\n",
	   (ulong) info.records, (ulong) info.deleted, info.keys);
  }
  if (verbose)
  {
    char buff[80];
    get_date(buff,3,info.create_time);
    printf("info: Created %s\n",buff);
    get_date(buff,3,info.check_time);
    printf("info: checked %s\n",buff);
    get_date(buff,3,info.update_time);
    printf("info: Modified %s\n",buff);
  }

  mi_panic(HA_PANIC_WRITE);
  mi_panic(HA_PANIC_READ);
  if (mi_is_changed(file))
    puts("Warning: mi_is_changed reported that datafile was changed");

  if (!silent)
    printf("- mi_extra(CACHE) + mi_rrnd.... + mi_extra(NO_CACHE)\n");
  if (mi_reset(file) || mi_extra(file,HA_EXTRA_CACHE,0))
  {
    if (locking || (!use_blob && !pack_fields))
    {
      puts("got error from mi_extra(HA_EXTRA_CACHE)");
      goto end;
    }
  }
  ant=0;
  while ((error=mi_rrnd(file,record,HA_OFFSET_ERROR)) != HA_ERR_END_OF_FILE &&
	 ant < write_count + 10)
	ant+= error ? 0 : 1;
  if (ant != write_count-opt_delete)
  {
    printf("rrnd with cache: I can only find: %d records of %d\n",
	   ant,write_count-opt_delete);
    goto end;
  }
  if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
  {
    puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
    goto end;
  }

  ant=0;
  mi_scan_init(file);
  while ((error=mi_scan(file,record)) != HA_ERR_END_OF_FILE &&
	 ant < write_count + 10)
	ant+= error ? 0 : 1;
  if (ant != write_count-opt_delete)
  {
    printf("scan with cache: I can only find: %d records of %d\n",
	   ant,write_count-opt_delete);
    goto end;
  }

  if (testflag == 4) goto end;

  if (!silent)
    printf("- Removing keys\n");
  DBUG_PRINT("progpos",("Removing keys"));
  lastpos = HA_OFFSET_ERROR;
  /* DBUG_POP(); */
  mi_reset(file);
  found_parts=0;
  while ((error=mi_rrnd(file,read_record,HA_OFFSET_ERROR)) !=
	 HA_ERR_END_OF_FILE)
  {
    info.recpos=mi_position(file);
    if (lastpos >= info.recpos && lastpos != HA_OFFSET_ERROR)
    {
      printf("mi_rrnd didn't advance filepointer; old: %ld, new: %ld\n",
	     (long) lastpos, (long) info.recpos);
      goto err;
    }
    lastpos=info.recpos;
    if (error == 0)
    {
      if (opt_delete == (uint) remove_count)		/* While testing */
	goto end;
      if (mi_rsame(file,read_record,-1))
      {
	printf("can't find record %lx\n",(long) info.recpos);
	goto err;
      }
      if (use_blob)
      {
	ulong blob_length,pos;
	uchar *ptr;
	longget(blob_length,read_record+blob_pos+4);
	ptr=(uchar*) blob_length;
	longget(blob_length,read_record+blob_pos);
	for (pos=0 ; pos < blob_length ; pos++)
	{
	  if (ptr[pos] != (uchar) (blob_length+pos))
	  {
	    printf("found blob with wrong info at %ld\n",(long) lastpos);
	    use_blob=0;
	    break;
	  }
	}
      }
      if (mi_delete(file,read_record))
      {
	printf("can't delete record: %6.6s,  delete_count: %d\n",
	       read_record, opt_delete);
	goto err;
      }
      opt_delete++;
    }
    else
      found_parts++;
  }
  if (my_errno != HA_ERR_END_OF_FILE && my_errno != HA_ERR_RECORD_DELETED)
    printf("error: %d from mi_rrnd\n",my_errno);
  if (write_count != opt_delete)
  {
    printf("Deleted only %d of %d records (%d parts)\n",opt_delete,write_count,
	   found_parts);
    goto err;
  }
end:
  if (mi_close(file))
    goto err;
  mi_panic(HA_PANIC_CLOSE);			/* Should close log */
  if (!silent)
  {
    printf("\nFollowing test have been made:\n");
    printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
    if (rec_pointer_size)
      printf("Record pointer size:  %d\n",rec_pointer_size);
    printf("myisam_block_size:    %lu\n", myisam_block_size);
    if (key_cacheing)
    {
      puts("Key cache used");
      printf("key_cache_block_size: %u\n", key_cache_block_size);
      if (write_cacheing)
	puts("Key cache resized");
    }
    if (write_cacheing)
      puts("Write cacheing used");
    if (write_cacheing)
      puts("quick mode");
    if (async_io && locking)
      puts("Asyncron io with locking used");
    else if (locking)
      puts("Locking used");
    if (use_blob)
      puts("blobs used");
    printf("key cache status: \n\
blocks used:%10lu\n\
not flushed:%10lu\n\
w_requests: %10lu\n\
writes:     %10lu\n\
r_requests: %10lu\n\
reads:      %10lu\n",
           dflt_key_cache->blocks_used,
           dflt_key_cache->global_blocks_changed,
           (ulong) dflt_key_cache->global_cache_w_requests,
           (ulong) dflt_key_cache->global_cache_write,
           (ulong) dflt_key_cache->global_cache_r_requests,
           (ulong) dflt_key_cache->global_cache_read);
  }
Пример #30
0
int main(int argc __attribute__((unused)), char *argv[])
{
  ulong i;
  uint pagen;
  uchar long_tr_id[6];
  PAGECACHE pagecache;
  LSN lsn;
  LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1];
  uchar *long_buffer= malloc(LONG_BUFFER_SIZE);

  MY_INIT(argv[0]);

  plan(2);

  bzero(&pagecache, sizeof(pagecache));
  bzero(long_buffer, LONG_BUFFER_SIZE);
  maria_data_root= create_tmpdir(argv[0]);
  if (maria_log_remove(0))
    exit(1);

  bzero(long_tr_id, 6);
#ifndef DBUG_OFF
#if defined(__WIN__)
  default_dbug_option= "d:t:i:O,\\ma_test_loghandler.trace";
#else
  default_dbug_option= "d:t:i:o,/tmp/ma_test_loghandler.trace";
#endif
  if (argc > 1)
  {
    DBUG_SET(default_dbug_option);
    DBUG_SET_INITIAL(default_dbug_option);
  }
#endif

  if (ma_control_file_open(TRUE, TRUE))
  {
    fprintf(stderr, "Can't init control file (%d)\n", errno);
    exit(1);
  }
  if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
                             PCACHE_PAGE, 0)) == 0)
  {
    fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
    exit(1);
  }
  if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache,
                               LOG_FLAGS, 0, &translog_example_table_init,
                               0))
  {
    fprintf(stderr, "Can't init loghandler (%d)\n", errno);
    exit(1);
  }
  /* Suppressing of automatic record writing */
  dummy_transaction_object.first_undo_lsn|= TRANSACTION_LOGGED_LONG_ID;

  /* write more then 1 file */
  int4store(long_tr_id, 0);
  parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
  parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
  if (translog_write_record(&lsn,
                            LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                            &dummy_transaction_object, NULL, 6,
                            TRANSLOG_INTERNAL_PARTS + 1,
                            parts, NULL, NULL))
  {
    fprintf(stderr, "Can't write record #0\n");
    translog_destroy();
    exit(1);
  }

  for(i= 0; i < LOG_FILE_SIZE/6 && LSN_FILE_NO(lsn) == 1; i++)
  {
    if (translog_write_record(&lsn,
                              LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                              &dummy_transaction_object, NULL, 6,
                              TRANSLOG_INTERNAL_PARTS + 1,
                              parts, NULL, NULL))
    {
      fprintf(stderr, "Can't write record #0\n");
      translog_destroy();
      exit(1);
    }
  }

  translog_destroy();
  end_pagecache(&pagecache, 1);
  ma_control_file_end();

  {
    char file_name[FN_REFLEN];
    for (i= 1; i <= 2; i++)
    {
      translog_filename_by_fileno(i, file_name);
      if (my_access(file_name, W_OK))
      {
        fprintf(stderr, "No file '%s'\n", file_name);
        exit(1);
      }
      if (my_delete(file_name, MYF(MY_WME)) != 0)
      {
        fprintf(stderr, "Error %d during removing file'%s'\n",
                errno, file_name);
        exit(1);
      }
    }
  }

  if (ma_control_file_open(TRUE, TRUE))
  {
    fprintf(stderr, "Can't init control file (%d)\n", errno);
    exit(1);
  }
  if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
                             PCACHE_PAGE, 0)) == 0)
  {
    fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
    exit(1);
  }
  if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache,
                               LOG_FLAGS, 0, &translog_example_table_init,
                               1))
  {
    fprintf(stderr, "Can't init loghandler (%d)\n", errno);
    exit(1);
  }
  /* Suppressing of automatic record writing */
  dummy_transaction_object.first_undo_lsn|= TRANSACTION_LOGGED_LONG_ID;

  ok(1, "Log init OK");

  int4store(long_tr_id, 0);
  parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
  parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
  if (translog_write_record(&lsn,
                            LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
                            &dummy_transaction_object, NULL, 6,
                            TRANSLOG_INTERNAL_PARTS + 1,
                            parts, NULL, NULL))
  {
    fprintf(stderr, "Can't write record #0\n");
    translog_destroy();
    exit(1);
  }

  translog_destroy();
  end_pagecache(&pagecache, 1);
  ma_control_file_end();

  if (!translog_is_file(3))
  {
    fprintf(stderr, "No file #3\n");
    exit(1);
  }

  ok(1, "New log is OK");

  if (maria_log_remove(maria_data_root))
    exit(1);
  exit(0);
}