2006-04-11 15:45:10 +02:00
|
|
|
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2007-03-02 11:20:23 +01:00
|
|
|
the Free Software Foundation; version 2 of the License.
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
Update FSF address
This commit is based on the work of Michal Schorm, rebased on the
earliest MariaDB version.
Th command line used to generate this diff was:
find ./ -type f \
-exec sed -i -e 's/Foundation, Inc., 59 Temple Place, Suite 330, Boston, /Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, /g' {} \; \
-exec sed -i -e 's/Foundation, Inc. 59 Temple Place.* Suite 330, Boston, /Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, /g' {} \; \
-exec sed -i -e 's/MA.*.....-1307.*USA/MA 02110-1335 USA/g' {} \; \
-exec sed -i -e 's/Foundation, Inc., 59 Temple/Foundation, Inc., 51 Franklin/g' {} \; \
-exec sed -i -e 's/Place, Suite 330, Boston, MA.*02111-1307.*USA/Street, Fifth Floor, Boston, MA 02110-1335 USA/g' {} \; \
-exec sed -i -e 's/MA.*.....-1307/MA 02110-1335/g' {} \;
2019-05-10 19:49:46 +02:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
Functions to handle space-packed-records and blobs
|
|
|
|
|
|
|
|
A row may be stored in one or more linked blocks.
|
|
|
|
The block size is between MARIA_MIN_BLOCK_LENGTH and MARIA_MAX_BLOCK_LENGTH.
|
|
|
|
Each block is aligned on MARIA_DYN_ALIGN_SIZE.
|
|
|
|
The reson for the max block size is to not have too many different types
|
|
|
|
of blocks. For the differnet block types, look at _ma_get_block_info()
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "maria_def.h"
|
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
static my_bool write_dynamic_record(MARIA_HA *info,const uchar *record,
|
2007-01-18 20:38:14 +01:00
|
|
|
ulong reclength);
|
2006-04-11 15:45:10 +02:00
|
|
|
static int _ma_find_writepos(MARIA_HA *info,ulong reclength,my_off_t *filepos,
|
|
|
|
ulong *length);
|
2007-01-18 20:38:14 +01:00
|
|
|
static my_bool update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *record, ulong reclength);
|
2007-01-18 20:38:14 +01:00
|
|
|
static my_bool delete_dynamic_record(MARIA_HA *info,MARIA_RECORD_POS filepos,
|
|
|
|
uint second_read);
|
2007-07-02 19:45:15 +02:00
|
|
|
static my_bool _ma_cmp_buffer(File file, const uchar *buff, my_off_t filepos,
|
2007-01-18 20:38:14 +01:00
|
|
|
uint length);
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
/* Interface function from MARIA_HA */
|
|
|
|
|
|
|
|
#ifdef HAVE_MMAP
|
|
|
|
|
|
|
|
/*
|
|
|
|
Create mmaped area for MARIA handler
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
_ma_dynmap_file()
|
|
|
|
info MARIA handler
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 ok
|
|
|
|
1 error.
|
|
|
|
*/
|
|
|
|
|
|
|
|
my_bool _ma_dynmap_file(MARIA_HA *info, my_off_t size)
|
|
|
|
{
|
|
|
|
DBUG_ENTER("_ma_dynmap_file");
|
Completion of merge of mysql-5.1 into mysql-maria.
Manually imported changes done to MyISAM (include/myisam.h,
storage/myisam/*, sql/ha_myisam.*, mysql-test/t/myisam.test,
mysql-test/t/ps_2myisam.test) the last
months into Maria (tedious, should do it more frequently in the
future), including those not done at the previous 5.1->Maria merge
(please in the future don't forget to apply MyISAM changes to Maria
when you merge 5.1 into Maria).
Note: I didn't try to import anything which could be MyISAM-related
in other tests of mysql-test (I didn't want to dig in all csets),
but as QA is working to make most tests re-usable for other engines
(Falcon), it is likely that we'll benefit from this and just have
to set engine=Maria somewhere to run those tests on Maria.
func_group and partition tests fail but they already do in main 5.1
on my machine. No Valgrind error in t/*maria*.test.
Monty: please see the commit comment of maria.result and check.
BitKeeper/deleted/.del-ha_maria.m4:
Delete: config/ac-macros/ha_maria.m4
configure.in:
fix for the new way of enabling engines
include/maria.h:
importing changes done to MyISAM the last months into Maria
include/my_handler.h:
importing changes done to MyISAM the last months into Maria
include/myisam.h:
importing changes done to MyISAM the last months into Maria
mysql-test/r/maria.result:
identical to myisam.result, except the engine name in some places
AND in the line testing key_block_size=1000000000000000000:
Maria gives a key block size of 8192 while MyISAM gives 4096;
is it explainable by the difference between MARIA_KEY_BLOCK_LENGTH
and the same constant in MyISAM? Monty?
mysql-test/r/ps_maria.result:
identical to ps_2myisam.result (except the engine name in some places)
mysql-test/t/maria.test:
instead of engine=maria everywhere, I use @@storage_engine (reduces
the diff with myisam.test).
importing changes done to MyISAM the last months into Maria
mysys/my_handler.c:
importing changes done to MyISAM the last months into Maria
sql/ha_maria.cc:
importing changes done to MyISAM the last months into Maria
sql/ha_maria.h:
importing changes done to MyISAM the last months into Maria
sql/mysqld.cc:
unneeded
storage/maria/Makefile.am:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_check.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_create.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_delete_table.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_dynrec.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_extra.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_ft_boolean_search.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_ft_eval.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_ft_nlq_search.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_ft_parser.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_ft_test1.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_ft_update.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_ftdefs.h:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_key.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_open.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_page.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_rkey.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_rsamepos.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_rt_index.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_rt_mbr.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_search.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_sort.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_test1.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_test2.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_test3.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_update.c:
importing changes done to MyISAM the last months into Maria
storage/maria/ma_write.c:
importing changes done to MyISAM the last months into Maria
storage/maria/maria_chk.c:
importing changes done to MyISAM the last months into Maria
storage/maria/maria_def.h:
importing changes done to MyISAM the last months into Maria
storage/maria/maria_ftdump.c:
importing changes done to MyISAM the last months into Maria
storage/maria/maria_pack.c:
importing changes done to MyISAM the last months into Maria
2006-08-10 16:36:54 +02:00
|
|
|
if (size > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN)
|
|
|
|
{
|
|
|
|
DBUG_PRINT("warning", ("File is too large for mmap"));
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2007-03-01 18:23:58 +01:00
|
|
|
/*
|
|
|
|
Ingo wonders if it is good to use MAP_NORESERVE. From the Linux man page:
|
|
|
|
MAP_NORESERVE
|
|
|
|
Do not reserve swap space for this mapping. When swap space is
|
|
|
|
reserved, one has the guarantee that it is possible to modify the
|
|
|
|
mapping. When swap space is not reserved one might get SIGSEGV
|
|
|
|
upon a write if no physical memory is available.
|
|
|
|
*/
|
2007-07-02 19:45:15 +02:00
|
|
|
info->s->file_map= (uchar*)
|
2006-04-11 15:45:10 +02:00
|
|
|
my_mmap(0, (size_t)(size + MEMMAP_EXTRA_MARGIN),
|
|
|
|
info->s->mode==O_RDONLY ? PROT_READ :
|
|
|
|
PROT_READ | PROT_WRITE,
|
|
|
|
MAP_SHARED | MAP_NORESERVE,
|
2007-04-04 22:37:09 +02:00
|
|
|
info->dfile.file, 0L);
|
2007-07-02 19:45:15 +02:00
|
|
|
if (info->s->file_map == (uchar*) MAP_FAILED)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
info->s->file_map= NULL;
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
#if defined(HAVE_MADVISE)
|
2007-10-04 19:33:42 +02:00
|
|
|
madvise((char*) info->s->file_map, size, MADV_RANDOM);
|
2006-04-11 15:45:10 +02:00
|
|
|
#endif
|
|
|
|
info->s->mmaped_length= size;
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Resize mmaped area for MARIA handler
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
_ma_remap_file()
|
|
|
|
info MARIA handler
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
*/
|
|
|
|
|
|
|
|
void _ma_remap_file(MARIA_HA *info, my_off_t size)
|
|
|
|
{
|
|
|
|
if (info->s->file_map)
|
|
|
|
{
|
2011-04-25 17:22:25 +02:00
|
|
|
my_munmap((char*) info->s->file_map,
|
|
|
|
(size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN);
|
2006-04-11 15:45:10 +02:00
|
|
|
_ma_dynmap_file(info, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Read bytes from MySAM handler, using mmap or pread
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
_ma_mmap_pread()
|
|
|
|
info MARIA handler
|
|
|
|
Buffer Input buffer
|
|
|
|
Count Count of bytes for read
|
|
|
|
offset Start position
|
|
|
|
MyFlags
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 ok
|
|
|
|
*/
|
|
|
|
|
2007-10-04 19:33:42 +02:00
|
|
|
size_t _ma_mmap_pread(MARIA_HA *info, uchar *Buffer,
|
|
|
|
size_t Count, my_off_t offset, myf MyFlags)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-04-04 22:37:09 +02:00
|
|
|
DBUG_PRINT("info", ("maria_read with mmap %d\n", info->dfile.file));
|
WL#3138: Maria - fast "SELECT COUNT(*) FROM t;" and "CHECKSUM TABLE t"
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
Fixed wrong call to strmake
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert
Allow storing year 2155 in year field
When running with purify/valgrind avoid copying structures over themself
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
Fixed that ndb doesn't crash on duplicate key error when start_bulk_insert/end_bulk_insert are not called
include/maria.h:
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
include/my_tree.h:
Added macro 'reset_free_element()' to be able to ignore calls to the external free function.
Is used to optimize end-bulk-insert in case of failures, in which case we don't want write the remaining keys in the tree
mysql-test/install_test_db.sh:
Upgrade to new mysql_install_db options
mysql-test/r/maria-mvcc.result:
New tests
mysql-test/r/maria.result:
New tests
mysql-test/suite/ndb/r/ndb_auto_increment.result:
Fixed error message now when bulk insert is not always called
mysql-test/suite/ndb/t/ndb_auto_increment.test:
Fixed error message now when bulk insert is not always called
mysql-test/t/maria-mvcc.test:
Added testing of versioning of count(*)
mysql-test/t/maria-page-checksum.test:
Added comment
mysql-test/t/maria.test:
More tests
mysys/hash.c:
Code style change
sql/field.cc:
Allow storing year 2155 in year field
sql/ha_ndbcluster.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_ndbcluster.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/handler.cc:
Don't call get_dup_key() if there is no table object. This can happen if the handler generates a duplicate key error on commit
sql/handler.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored (ie, the table will be deleted)
sql/item.cc:
Style fix
Removed compiler warning
sql/log_event.cc:
Added new argument to ha_end_bulk_insert()
sql/log_event_old.cc:
Added new argument to ha_end_bulk_insert()
sql/mysqld.cc:
Removed compiler warning
sql/protocol.cc:
Added DBUG
sql/sql_class.cc:
Added DBUG
Fixed wrong call to strmake
sql/sql_insert.cc:
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert involves a lot of if's)
Added new argument to ha_end_bulk_insert()
sql/sql_load.cc:
Added new argument to ha_end_bulk_insert()
sql/sql_parse.cc:
Style fixes
Avoid goto in common senario
sql/sql_select.cc:
When running with purify/valgrind avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_select.h:
Avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_table.cc:
Call HA_EXTRA_PREPARE_FOR_DROP if table created by ALTER TABLE is going to be dropped
Added new argument to ha_end_bulk_insert()
storage/archive/ha_archive.cc:
Added new argument to end_bulk_insert()
storage/archive/ha_archive.h:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.cc:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.h:
Added new argument to end_bulk_insert()
storage/maria/Makefile.am:
Added ma_state.c and ma_state.h
storage/maria/ha_maria.cc:
Versioning of count(*) and checksum
- share->state.state is now assumed to be correct, not handler->state
- Call _ma_setup_live_state() in external lock to get count(*)/checksum versioning. In case of
not versioned and not concurrent insertable table, file->s->state.state contains the correct state information
Other things:
- file->s -> share
- Added DBUG_ASSERT() for unlikely case
- Optimized end_bulk_insert() to not write anything if table is going to be deleted (as in failed alter table)
- Indentation changes in external_lock becasue of removed 'goto' caused a big conflict even if very little was changed
storage/maria/ha_maria.h:
New argument to end_bulk_insert()
storage/maria/ma_blockrec.c:
Update for versioning of count(*) and checksum
Keep share->state.state.data_file_length up to date (not info->state->data_file_length)
Moved _ma_block_xxxx_status() and maria_versioning() functions to ma_state.c
storage/maria/ma_check.c:
Update and use share->state.state instead of info->state
info->s to share
Update info->state at end of repair
Call _ma_reset_state() to update share->state_history at end of repair
storage/maria/ma_checkpoint.c:
Call _ma_remove_not_visible_states() on checkpoint to clean up not visible state history from tables
storage/maria/ma_close.c:
Remember state history for running transaction even if table is closed
storage/maria/ma_commit.c:
Ensure we always call trnman_commit_trn() even if other calls fails. If we don't do that, the translog and state structures will not be freed
storage/maria/ma_delete.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/ma_delete_all.c:
Versioning of count(*) and checksum:
- Ensure that share->state.state is updated, as here is where we store the primary information
storage/maria/ma_dynrec.c:
Use lock_key_trees instead of concurrent_insert to check if trees should be locked.
This allows us to lock trees both for concurrent_insert and for index versioning.
storage/maria/ma_extra.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- share->concurrent_insert -> share->non_transactional_concurrent_insert
- Don't update share->state.state from info->state if transactional table
Optimization:
- Don't flush io_cache or bitmap if we are using FLUSH_IGNORE_CHANGED
storage/maria/ma_info.c:
Get most state information from current state
storage/maria/ma_init.c:
Add hash table and free function to store states for closed tables
Install hook for transaction commit/rollback to update history state
storage/maria/ma_key_recover.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
storage/maria/ma_locking.c:
Versioning of count(*) and checksum:
- Call virtual functions (if exists) to restore/update status
- Move _ma_xxx_status() functions to ma_state.c
info->s -> share
storage/maria/ma_open.c:
Versioning of count(*) and checksum:
- For not transactional tables, set info->state to point to new allocated state structure.
- Initialize new info->state_start variable that points to state at start of transaction
- Copy old history states from hash table (maria_stored_states) first time the table is opened
- Split flag share->concurrent_insert to non_transactional_concurrent_insert & lock_key_tree
- For now, only enable versioning of tables without keys (to be fixed in soon!)
- Added new virtual function to restore status in maria_lock_database)
More DBUG
storage/maria/ma_page.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Modify share->state.state.key_file_length under share->intern_lock
storage/maria/ma_range.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
info->s -> share
storage/maria/ma_recovery.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Update state information on close and when reenabling logging
storage/maria/ma_rkey.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext_same.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
- Only skip rows based on file length if non_transactional_concurrent_insert is set
storage/maria/ma_rprev.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rsame.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_sort.c:
Use share->state.state instead of info->state
Fixed indentation
storage/maria/ma_static.c:
Added maria_stored_state
storage/maria/ma_update.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
- Remove optimization for index file update as it doesn't work for transactional tables
storage/maria/ma_write.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/maria_def.h:
Move MARIA_STATUS_INFO to ma_state.h
Changes to MARIA_SHARE:
- Added state_history to store count(*)/checksum states
- Added in_trans as counter if table is used by running transactions
- Split concurrent_insert into lock_key_trees and on_transactional_concurrent_insert.
- Added virtual function lock_restore_status
Changes to MARIA_HA:
- save_state -> state_save
- Added state_start to store state at start of transaction
storage/maria/maria_pack.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
Indentation fixes
storage/maria/trnman.c:
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
More DBUG
Changed return type of trnman_end_trn() to my_bool
Added trnman_get_min_trid() to get minimum trid in use.
Added trnman_exists_active_transactions() to check if there exist a running transaction started between two commit id
storage/maria/trnman.h:
Added 'used_tables'
Moved all pointers into same groups to get better memory alignment
storage/maria/trnman_public.h:
Added prototypes for new functions and variables
Chagned return type of trnman_end_trn() to my_bool
storage/myisam/ha_myisam.cc:
Added argument to end_bulk_insert() if operation should be aborted
storage/myisam/ha_myisam.h:
Added argument to end_bulk_insert() if operation should be aborted
storage/maria/ma_state.c:
Functions to handle state of count(*) and checksum
storage/maria/ma_state.h:
Structures and declarations to handle state of count(*) and checksum
2008-05-29 17:33:33 +02:00
|
|
|
if (info->s->lock_key_trees)
|
2011-07-13 21:10:18 +02:00
|
|
|
mysql_rwlock_rdlock(&info->s->mmap_lock);
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
The following test may fail in the following cases:
|
|
|
|
- We failed to remap a memory area (fragmented memory?)
|
|
|
|
- This thread has done some writes, but not yet extended the
|
|
|
|
memory mapped area.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (info->s->mmaped_length >= offset + Count)
|
|
|
|
{
|
|
|
|
memcpy(Buffer, info->s->file_map + offset, Count);
|
WL#3138: Maria - fast "SELECT COUNT(*) FROM t;" and "CHECKSUM TABLE t"
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
Fixed wrong call to strmake
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert
Allow storing year 2155 in year field
When running with purify/valgrind avoid copying structures over themself
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
Fixed that ndb doesn't crash on duplicate key error when start_bulk_insert/end_bulk_insert are not called
include/maria.h:
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
include/my_tree.h:
Added macro 'reset_free_element()' to be able to ignore calls to the external free function.
Is used to optimize end-bulk-insert in case of failures, in which case we don't want write the remaining keys in the tree
mysql-test/install_test_db.sh:
Upgrade to new mysql_install_db options
mysql-test/r/maria-mvcc.result:
New tests
mysql-test/r/maria.result:
New tests
mysql-test/suite/ndb/r/ndb_auto_increment.result:
Fixed error message now when bulk insert is not always called
mysql-test/suite/ndb/t/ndb_auto_increment.test:
Fixed error message now when bulk insert is not always called
mysql-test/t/maria-mvcc.test:
Added testing of versioning of count(*)
mysql-test/t/maria-page-checksum.test:
Added comment
mysql-test/t/maria.test:
More tests
mysys/hash.c:
Code style change
sql/field.cc:
Allow storing year 2155 in year field
sql/ha_ndbcluster.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_ndbcluster.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/handler.cc:
Don't call get_dup_key() if there is no table object. This can happen if the handler generates a duplicate key error on commit
sql/handler.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored (ie, the table will be deleted)
sql/item.cc:
Style fix
Removed compiler warning
sql/log_event.cc:
Added new argument to ha_end_bulk_insert()
sql/log_event_old.cc:
Added new argument to ha_end_bulk_insert()
sql/mysqld.cc:
Removed compiler warning
sql/protocol.cc:
Added DBUG
sql/sql_class.cc:
Added DBUG
Fixed wrong call to strmake
sql/sql_insert.cc:
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert involves a lot of if's)
Added new argument to ha_end_bulk_insert()
sql/sql_load.cc:
Added new argument to ha_end_bulk_insert()
sql/sql_parse.cc:
Style fixes
Avoid goto in common senario
sql/sql_select.cc:
When running with purify/valgrind avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_select.h:
Avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_table.cc:
Call HA_EXTRA_PREPARE_FOR_DROP if table created by ALTER TABLE is going to be dropped
Added new argument to ha_end_bulk_insert()
storage/archive/ha_archive.cc:
Added new argument to end_bulk_insert()
storage/archive/ha_archive.h:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.cc:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.h:
Added new argument to end_bulk_insert()
storage/maria/Makefile.am:
Added ma_state.c and ma_state.h
storage/maria/ha_maria.cc:
Versioning of count(*) and checksum
- share->state.state is now assumed to be correct, not handler->state
- Call _ma_setup_live_state() in external lock to get count(*)/checksum versioning. In case of
not versioned and not concurrent insertable table, file->s->state.state contains the correct state information
Other things:
- file->s -> share
- Added DBUG_ASSERT() for unlikely case
- Optimized end_bulk_insert() to not write anything if table is going to be deleted (as in failed alter table)
- Indentation changes in external_lock becasue of removed 'goto' caused a big conflict even if very little was changed
storage/maria/ha_maria.h:
New argument to end_bulk_insert()
storage/maria/ma_blockrec.c:
Update for versioning of count(*) and checksum
Keep share->state.state.data_file_length up to date (not info->state->data_file_length)
Moved _ma_block_xxxx_status() and maria_versioning() functions to ma_state.c
storage/maria/ma_check.c:
Update and use share->state.state instead of info->state
info->s to share
Update info->state at end of repair
Call _ma_reset_state() to update share->state_history at end of repair
storage/maria/ma_checkpoint.c:
Call _ma_remove_not_visible_states() on checkpoint to clean up not visible state history from tables
storage/maria/ma_close.c:
Remember state history for running transaction even if table is closed
storage/maria/ma_commit.c:
Ensure we always call trnman_commit_trn() even if other calls fails. If we don't do that, the translog and state structures will not be freed
storage/maria/ma_delete.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/ma_delete_all.c:
Versioning of count(*) and checksum:
- Ensure that share->state.state is updated, as here is where we store the primary information
storage/maria/ma_dynrec.c:
Use lock_key_trees instead of concurrent_insert to check if trees should be locked.
This allows us to lock trees both for concurrent_insert and for index versioning.
storage/maria/ma_extra.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- share->concurrent_insert -> share->non_transactional_concurrent_insert
- Don't update share->state.state from info->state if transactional table
Optimization:
- Don't flush io_cache or bitmap if we are using FLUSH_IGNORE_CHANGED
storage/maria/ma_info.c:
Get most state information from current state
storage/maria/ma_init.c:
Add hash table and free function to store states for closed tables
Install hook for transaction commit/rollback to update history state
storage/maria/ma_key_recover.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
storage/maria/ma_locking.c:
Versioning of count(*) and checksum:
- Call virtual functions (if exists) to restore/update status
- Move _ma_xxx_status() functions to ma_state.c
info->s -> share
storage/maria/ma_open.c:
Versioning of count(*) and checksum:
- For not transactional tables, set info->state to point to new allocated state structure.
- Initialize new info->state_start variable that points to state at start of transaction
- Copy old history states from hash table (maria_stored_states) first time the table is opened
- Split flag share->concurrent_insert to non_transactional_concurrent_insert & lock_key_tree
- For now, only enable versioning of tables without keys (to be fixed in soon!)
- Added new virtual function to restore status in maria_lock_database)
More DBUG
storage/maria/ma_page.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Modify share->state.state.key_file_length under share->intern_lock
storage/maria/ma_range.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
info->s -> share
storage/maria/ma_recovery.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Update state information on close and when reenabling logging
storage/maria/ma_rkey.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext_same.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
- Only skip rows based on file length if non_transactional_concurrent_insert is set
storage/maria/ma_rprev.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rsame.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_sort.c:
Use share->state.state instead of info->state
Fixed indentation
storage/maria/ma_static.c:
Added maria_stored_state
storage/maria/ma_update.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
- Remove optimization for index file update as it doesn't work for transactional tables
storage/maria/ma_write.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/maria_def.h:
Move MARIA_STATUS_INFO to ma_state.h
Changes to MARIA_SHARE:
- Added state_history to store count(*)/checksum states
- Added in_trans as counter if table is used by running transactions
- Split concurrent_insert into lock_key_trees and on_transactional_concurrent_insert.
- Added virtual function lock_restore_status
Changes to MARIA_HA:
- save_state -> state_save
- Added state_start to store state at start of transaction
storage/maria/maria_pack.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
Indentation fixes
storage/maria/trnman.c:
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
More DBUG
Changed return type of trnman_end_trn() to my_bool
Added trnman_get_min_trid() to get minimum trid in use.
Added trnman_exists_active_transactions() to check if there exist a running transaction started between two commit id
storage/maria/trnman.h:
Added 'used_tables'
Moved all pointers into same groups to get better memory alignment
storage/maria/trnman_public.h:
Added prototypes for new functions and variables
Chagned return type of trnman_end_trn() to my_bool
storage/myisam/ha_myisam.cc:
Added argument to end_bulk_insert() if operation should be aborted
storage/myisam/ha_myisam.h:
Added argument to end_bulk_insert() if operation should be aborted
storage/maria/ma_state.c:
Functions to handle state of count(*) and checksum
storage/maria/ma_state.h:
Structures and declarations to handle state of count(*) and checksum
2008-05-29 17:33:33 +02:00
|
|
|
if (info->s->lock_key_trees)
|
2011-07-13 21:10:18 +02:00
|
|
|
mysql_rwlock_unlock(&info->s->mmap_lock);
|
2006-04-11 15:45:10 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
WL#3138: Maria - fast "SELECT COUNT(*) FROM t;" and "CHECKSUM TABLE t"
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
Fixed wrong call to strmake
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert
Allow storing year 2155 in year field
When running with purify/valgrind avoid copying structures over themself
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
Fixed that ndb doesn't crash on duplicate key error when start_bulk_insert/end_bulk_insert are not called
include/maria.h:
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
include/my_tree.h:
Added macro 'reset_free_element()' to be able to ignore calls to the external free function.
Is used to optimize end-bulk-insert in case of failures, in which case we don't want write the remaining keys in the tree
mysql-test/install_test_db.sh:
Upgrade to new mysql_install_db options
mysql-test/r/maria-mvcc.result:
New tests
mysql-test/r/maria.result:
New tests
mysql-test/suite/ndb/r/ndb_auto_increment.result:
Fixed error message now when bulk insert is not always called
mysql-test/suite/ndb/t/ndb_auto_increment.test:
Fixed error message now when bulk insert is not always called
mysql-test/t/maria-mvcc.test:
Added testing of versioning of count(*)
mysql-test/t/maria-page-checksum.test:
Added comment
mysql-test/t/maria.test:
More tests
mysys/hash.c:
Code style change
sql/field.cc:
Allow storing year 2155 in year field
sql/ha_ndbcluster.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_ndbcluster.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/handler.cc:
Don't call get_dup_key() if there is no table object. This can happen if the handler generates a duplicate key error on commit
sql/handler.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored (ie, the table will be deleted)
sql/item.cc:
Style fix
Removed compiler warning
sql/log_event.cc:
Added new argument to ha_end_bulk_insert()
sql/log_event_old.cc:
Added new argument to ha_end_bulk_insert()
sql/mysqld.cc:
Removed compiler warning
sql/protocol.cc:
Added DBUG
sql/sql_class.cc:
Added DBUG
Fixed wrong call to strmake
sql/sql_insert.cc:
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert involves a lot of if's)
Added new argument to ha_end_bulk_insert()
sql/sql_load.cc:
Added new argument to ha_end_bulk_insert()
sql/sql_parse.cc:
Style fixes
Avoid goto in common senario
sql/sql_select.cc:
When running with purify/valgrind avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_select.h:
Avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_table.cc:
Call HA_EXTRA_PREPARE_FOR_DROP if table created by ALTER TABLE is going to be dropped
Added new argument to ha_end_bulk_insert()
storage/archive/ha_archive.cc:
Added new argument to end_bulk_insert()
storage/archive/ha_archive.h:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.cc:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.h:
Added new argument to end_bulk_insert()
storage/maria/Makefile.am:
Added ma_state.c and ma_state.h
storage/maria/ha_maria.cc:
Versioning of count(*) and checksum
- share->state.state is now assumed to be correct, not handler->state
- Call _ma_setup_live_state() in external lock to get count(*)/checksum versioning. In case of
not versioned and not concurrent insertable table, file->s->state.state contains the correct state information
Other things:
- file->s -> share
- Added DBUG_ASSERT() for unlikely case
- Optimized end_bulk_insert() to not write anything if table is going to be deleted (as in failed alter table)
- Indentation changes in external_lock becasue of removed 'goto' caused a big conflict even if very little was changed
storage/maria/ha_maria.h:
New argument to end_bulk_insert()
storage/maria/ma_blockrec.c:
Update for versioning of count(*) and checksum
Keep share->state.state.data_file_length up to date (not info->state->data_file_length)
Moved _ma_block_xxxx_status() and maria_versioning() functions to ma_state.c
storage/maria/ma_check.c:
Update and use share->state.state instead of info->state
info->s to share
Update info->state at end of repair
Call _ma_reset_state() to update share->state_history at end of repair
storage/maria/ma_checkpoint.c:
Call _ma_remove_not_visible_states() on checkpoint to clean up not visible state history from tables
storage/maria/ma_close.c:
Remember state history for running transaction even if table is closed
storage/maria/ma_commit.c:
Ensure we always call trnman_commit_trn() even if other calls fails. If we don't do that, the translog and state structures will not be freed
storage/maria/ma_delete.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/ma_delete_all.c:
Versioning of count(*) and checksum:
- Ensure that share->state.state is updated, as here is where we store the primary information
storage/maria/ma_dynrec.c:
Use lock_key_trees instead of concurrent_insert to check if trees should be locked.
This allows us to lock trees both for concurrent_insert and for index versioning.
storage/maria/ma_extra.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- share->concurrent_insert -> share->non_transactional_concurrent_insert
- Don't update share->state.state from info->state if transactional table
Optimization:
- Don't flush io_cache or bitmap if we are using FLUSH_IGNORE_CHANGED
storage/maria/ma_info.c:
Get most state information from current state
storage/maria/ma_init.c:
Add hash table and free function to store states for closed tables
Install hook for transaction commit/rollback to update history state
storage/maria/ma_key_recover.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
storage/maria/ma_locking.c:
Versioning of count(*) and checksum:
- Call virtual functions (if exists) to restore/update status
- Move _ma_xxx_status() functions to ma_state.c
info->s -> share
storage/maria/ma_open.c:
Versioning of count(*) and checksum:
- For not transactional tables, set info->state to point to new allocated state structure.
- Initialize new info->state_start variable that points to state at start of transaction
- Copy old history states from hash table (maria_stored_states) first time the table is opened
- Split flag share->concurrent_insert to non_transactional_concurrent_insert & lock_key_tree
- For now, only enable versioning of tables without keys (to be fixed in soon!)
- Added new virtual function to restore status in maria_lock_database)
More DBUG
storage/maria/ma_page.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Modify share->state.state.key_file_length under share->intern_lock
storage/maria/ma_range.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
info->s -> share
storage/maria/ma_recovery.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Update state information on close and when reenabling logging
storage/maria/ma_rkey.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext_same.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
- Only skip rows based on file length if non_transactional_concurrent_insert is set
storage/maria/ma_rprev.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rsame.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_sort.c:
Use share->state.state instead of info->state
Fixed indentation
storage/maria/ma_static.c:
Added maria_stored_state
storage/maria/ma_update.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
- Remove optimization for index file update as it doesn't work for transactional tables
storage/maria/ma_write.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/maria_def.h:
Move MARIA_STATUS_INFO to ma_state.h
Changes to MARIA_SHARE:
- Added state_history to store count(*)/checksum states
- Added in_trans as counter if table is used by running transactions
- Split concurrent_insert into lock_key_trees and on_transactional_concurrent_insert.
- Added virtual function lock_restore_status
Changes to MARIA_HA:
- save_state -> state_save
- Added state_start to store state at start of transaction
storage/maria/maria_pack.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
Indentation fixes
storage/maria/trnman.c:
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
More DBUG
Changed return type of trnman_end_trn() to my_bool
Added trnman_get_min_trid() to get minimum trid in use.
Added trnman_exists_active_transactions() to check if there exist a running transaction started between two commit id
storage/maria/trnman.h:
Added 'used_tables'
Moved all pointers into same groups to get better memory alignment
storage/maria/trnman_public.h:
Added prototypes for new functions and variables
Chagned return type of trnman_end_trn() to my_bool
storage/myisam/ha_myisam.cc:
Added argument to end_bulk_insert() if operation should be aborted
storage/myisam/ha_myisam.h:
Added argument to end_bulk_insert() if operation should be aborted
storage/maria/ma_state.c:
Functions to handle state of count(*) and checksum
storage/maria/ma_state.h:
Structures and declarations to handle state of count(*) and checksum
2008-05-29 17:33:33 +02:00
|
|
|
if (info->s->lock_key_trees)
|
2011-07-13 21:10:18 +02:00
|
|
|
mysql_rwlock_unlock(&info->s->mmap_lock);
|
|
|
|
return mysql_file_pread(info->dfile.file, Buffer, Count, offset, MyFlags);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* wrapper for my_pread in case if mmap isn't used */
|
|
|
|
|
2007-10-04 19:33:42 +02:00
|
|
|
size_t _ma_nommap_pread(MARIA_HA *info, uchar *Buffer,
|
|
|
|
size_t Count, my_off_t offset, myf MyFlags)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2011-07-13 21:10:18 +02:00
|
|
|
return mysql_file_pread(info->dfile.file, Buffer, Count, offset, MyFlags);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Write bytes to MySAM handler, using mmap or pwrite
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
_ma_mmap_pwrite()
|
|
|
|
info MARIA handler
|
|
|
|
Buffer Output buffer
|
|
|
|
Count Count of bytes for write
|
|
|
|
offset Start position
|
|
|
|
MyFlags
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 ok
|
|
|
|
!=0 error. In this case return error from pwrite
|
|
|
|
*/
|
|
|
|
|
2007-10-04 19:33:42 +02:00
|
|
|
size_t _ma_mmap_pwrite(MARIA_HA *info, const uchar *Buffer,
|
|
|
|
size_t Count, my_off_t offset, myf MyFlags)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-04-04 22:37:09 +02:00
|
|
|
DBUG_PRINT("info", ("maria_write with mmap %d\n", info->dfile.file));
|
WL#3138: Maria - fast "SELECT COUNT(*) FROM t;" and "CHECKSUM TABLE t"
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
Fixed wrong call to strmake
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert
Allow storing year 2155 in year field
When running with purify/valgrind avoid copying structures over themself
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
Fixed that ndb doesn't crash on duplicate key error when start_bulk_insert/end_bulk_insert are not called
include/maria.h:
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
include/my_tree.h:
Added macro 'reset_free_element()' to be able to ignore calls to the external free function.
Is used to optimize end-bulk-insert in case of failures, in which case we don't want write the remaining keys in the tree
mysql-test/install_test_db.sh:
Upgrade to new mysql_install_db options
mysql-test/r/maria-mvcc.result:
New tests
mysql-test/r/maria.result:
New tests
mysql-test/suite/ndb/r/ndb_auto_increment.result:
Fixed error message now when bulk insert is not always called
mysql-test/suite/ndb/t/ndb_auto_increment.test:
Fixed error message now when bulk insert is not always called
mysql-test/t/maria-mvcc.test:
Added testing of versioning of count(*)
mysql-test/t/maria-page-checksum.test:
Added comment
mysql-test/t/maria.test:
More tests
mysys/hash.c:
Code style change
sql/field.cc:
Allow storing year 2155 in year field
sql/ha_ndbcluster.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_ndbcluster.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/handler.cc:
Don't call get_dup_key() if there is no table object. This can happen if the handler generates a duplicate key error on commit
sql/handler.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored (ie, the table will be deleted)
sql/item.cc:
Style fix
Removed compiler warning
sql/log_event.cc:
Added new argument to ha_end_bulk_insert()
sql/log_event_old.cc:
Added new argument to ha_end_bulk_insert()
sql/mysqld.cc:
Removed compiler warning
sql/protocol.cc:
Added DBUG
sql/sql_class.cc:
Added DBUG
Fixed wrong call to strmake
sql/sql_insert.cc:
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert involves a lot of if's)
Added new argument to ha_end_bulk_insert()
sql/sql_load.cc:
Added new argument to ha_end_bulk_insert()
sql/sql_parse.cc:
Style fixes
Avoid goto in common senario
sql/sql_select.cc:
When running with purify/valgrind avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_select.h:
Avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_table.cc:
Call HA_EXTRA_PREPARE_FOR_DROP if table created by ALTER TABLE is going to be dropped
Added new argument to ha_end_bulk_insert()
storage/archive/ha_archive.cc:
Added new argument to end_bulk_insert()
storage/archive/ha_archive.h:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.cc:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.h:
Added new argument to end_bulk_insert()
storage/maria/Makefile.am:
Added ma_state.c and ma_state.h
storage/maria/ha_maria.cc:
Versioning of count(*) and checksum
- share->state.state is now assumed to be correct, not handler->state
- Call _ma_setup_live_state() in external lock to get count(*)/checksum versioning. In case of
not versioned and not concurrent insertable table, file->s->state.state contains the correct state information
Other things:
- file->s -> share
- Added DBUG_ASSERT() for unlikely case
- Optimized end_bulk_insert() to not write anything if table is going to be deleted (as in failed alter table)
- Indentation changes in external_lock becasue of removed 'goto' caused a big conflict even if very little was changed
storage/maria/ha_maria.h:
New argument to end_bulk_insert()
storage/maria/ma_blockrec.c:
Update for versioning of count(*) and checksum
Keep share->state.state.data_file_length up to date (not info->state->data_file_length)
Moved _ma_block_xxxx_status() and maria_versioning() functions to ma_state.c
storage/maria/ma_check.c:
Update and use share->state.state instead of info->state
info->s to share
Update info->state at end of repair
Call _ma_reset_state() to update share->state_history at end of repair
storage/maria/ma_checkpoint.c:
Call _ma_remove_not_visible_states() on checkpoint to clean up not visible state history from tables
storage/maria/ma_close.c:
Remember state history for running transaction even if table is closed
storage/maria/ma_commit.c:
Ensure we always call trnman_commit_trn() even if other calls fails. If we don't do that, the translog and state structures will not be freed
storage/maria/ma_delete.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/ma_delete_all.c:
Versioning of count(*) and checksum:
- Ensure that share->state.state is updated, as here is where we store the primary information
storage/maria/ma_dynrec.c:
Use lock_key_trees instead of concurrent_insert to check if trees should be locked.
This allows us to lock trees both for concurrent_insert and for index versioning.
storage/maria/ma_extra.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- share->concurrent_insert -> share->non_transactional_concurrent_insert
- Don't update share->state.state from info->state if transactional table
Optimization:
- Don't flush io_cache or bitmap if we are using FLUSH_IGNORE_CHANGED
storage/maria/ma_info.c:
Get most state information from current state
storage/maria/ma_init.c:
Add hash table and free function to store states for closed tables
Install hook for transaction commit/rollback to update history state
storage/maria/ma_key_recover.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
storage/maria/ma_locking.c:
Versioning of count(*) and checksum:
- Call virtual functions (if exists) to restore/update status
- Move _ma_xxx_status() functions to ma_state.c
info->s -> share
storage/maria/ma_open.c:
Versioning of count(*) and checksum:
- For not transactional tables, set info->state to point to new allocated state structure.
- Initialize new info->state_start variable that points to state at start of transaction
- Copy old history states from hash table (maria_stored_states) first time the table is opened
- Split flag share->concurrent_insert to non_transactional_concurrent_insert & lock_key_tree
- For now, only enable versioning of tables without keys (to be fixed in soon!)
- Added new virtual function to restore status in maria_lock_database)
More DBUG
storage/maria/ma_page.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Modify share->state.state.key_file_length under share->intern_lock
storage/maria/ma_range.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
info->s -> share
storage/maria/ma_recovery.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Update state information on close and when reenabling logging
storage/maria/ma_rkey.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext_same.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
- Only skip rows based on file length if non_transactional_concurrent_insert is set
storage/maria/ma_rprev.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rsame.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_sort.c:
Use share->state.state instead of info->state
Fixed indentation
storage/maria/ma_static.c:
Added maria_stored_state
storage/maria/ma_update.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
- Remove optimization for index file update as it doesn't work for transactional tables
storage/maria/ma_write.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/maria_def.h:
Move MARIA_STATUS_INFO to ma_state.h
Changes to MARIA_SHARE:
- Added state_history to store count(*)/checksum states
- Added in_trans as counter if table is used by running transactions
- Split concurrent_insert into lock_key_trees and on_transactional_concurrent_insert.
- Added virtual function lock_restore_status
Changes to MARIA_HA:
- save_state -> state_save
- Added state_start to store state at start of transaction
storage/maria/maria_pack.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
Indentation fixes
storage/maria/trnman.c:
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
More DBUG
Changed return type of trnman_end_trn() to my_bool
Added trnman_get_min_trid() to get minimum trid in use.
Added trnman_exists_active_transactions() to check if there exist a running transaction started between two commit id
storage/maria/trnman.h:
Added 'used_tables'
Moved all pointers into same groups to get better memory alignment
storage/maria/trnman_public.h:
Added prototypes for new functions and variables
Chagned return type of trnman_end_trn() to my_bool
storage/myisam/ha_myisam.cc:
Added argument to end_bulk_insert() if operation should be aborted
storage/myisam/ha_myisam.h:
Added argument to end_bulk_insert() if operation should be aborted
storage/maria/ma_state.c:
Functions to handle state of count(*) and checksum
storage/maria/ma_state.h:
Structures and declarations to handle state of count(*) and checksum
2008-05-29 17:33:33 +02:00
|
|
|
if (info->s->lock_key_trees)
|
2011-07-13 21:10:18 +02:00
|
|
|
mysql_rwlock_rdlock(&info->s->mmap_lock);
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
The following test may fail in the following cases:
|
|
|
|
- We failed to remap a memory area (fragmented memory?)
|
|
|
|
- This thread has done some writes, but not yet extended the
|
|
|
|
memory mapped area.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (info->s->mmaped_length >= offset + Count)
|
|
|
|
{
|
|
|
|
memcpy(info->s->file_map + offset, Buffer, Count);
|
WL#3138: Maria - fast "SELECT COUNT(*) FROM t;" and "CHECKSUM TABLE t"
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
Fixed wrong call to strmake
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert
Allow storing year 2155 in year field
When running with purify/valgrind avoid copying structures over themself
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
Fixed that ndb doesn't crash on duplicate key error when start_bulk_insert/end_bulk_insert are not called
include/maria.h:
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
include/my_tree.h:
Added macro 'reset_free_element()' to be able to ignore calls to the external free function.
Is used to optimize end-bulk-insert in case of failures, in which case we don't want write the remaining keys in the tree
mysql-test/install_test_db.sh:
Upgrade to new mysql_install_db options
mysql-test/r/maria-mvcc.result:
New tests
mysql-test/r/maria.result:
New tests
mysql-test/suite/ndb/r/ndb_auto_increment.result:
Fixed error message now when bulk insert is not always called
mysql-test/suite/ndb/t/ndb_auto_increment.test:
Fixed error message now when bulk insert is not always called
mysql-test/t/maria-mvcc.test:
Added testing of versioning of count(*)
mysql-test/t/maria-page-checksum.test:
Added comment
mysql-test/t/maria.test:
More tests
mysys/hash.c:
Code style change
sql/field.cc:
Allow storing year 2155 in year field
sql/ha_ndbcluster.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_ndbcluster.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/handler.cc:
Don't call get_dup_key() if there is no table object. This can happen if the handler generates a duplicate key error on commit
sql/handler.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored (ie, the table will be deleted)
sql/item.cc:
Style fix
Removed compiler warning
sql/log_event.cc:
Added new argument to ha_end_bulk_insert()
sql/log_event_old.cc:
Added new argument to ha_end_bulk_insert()
sql/mysqld.cc:
Removed compiler warning
sql/protocol.cc:
Added DBUG
sql/sql_class.cc:
Added DBUG
Fixed wrong call to strmake
sql/sql_insert.cc:
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert involves a lot of if's)
Added new argument to ha_end_bulk_insert()
sql/sql_load.cc:
Added new argument to ha_end_bulk_insert()
sql/sql_parse.cc:
Style fixes
Avoid goto in common senario
sql/sql_select.cc:
When running with purify/valgrind avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_select.h:
Avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_table.cc:
Call HA_EXTRA_PREPARE_FOR_DROP if table created by ALTER TABLE is going to be dropped
Added new argument to ha_end_bulk_insert()
storage/archive/ha_archive.cc:
Added new argument to end_bulk_insert()
storage/archive/ha_archive.h:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.cc:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.h:
Added new argument to end_bulk_insert()
storage/maria/Makefile.am:
Added ma_state.c and ma_state.h
storage/maria/ha_maria.cc:
Versioning of count(*) and checksum
- share->state.state is now assumed to be correct, not handler->state
- Call _ma_setup_live_state() in external lock to get count(*)/checksum versioning. In case of
not versioned and not concurrent insertable table, file->s->state.state contains the correct state information
Other things:
- file->s -> share
- Added DBUG_ASSERT() for unlikely case
- Optimized end_bulk_insert() to not write anything if table is going to be deleted (as in failed alter table)
- Indentation changes in external_lock becasue of removed 'goto' caused a big conflict even if very little was changed
storage/maria/ha_maria.h:
New argument to end_bulk_insert()
storage/maria/ma_blockrec.c:
Update for versioning of count(*) and checksum
Keep share->state.state.data_file_length up to date (not info->state->data_file_length)
Moved _ma_block_xxxx_status() and maria_versioning() functions to ma_state.c
storage/maria/ma_check.c:
Update and use share->state.state instead of info->state
info->s to share
Update info->state at end of repair
Call _ma_reset_state() to update share->state_history at end of repair
storage/maria/ma_checkpoint.c:
Call _ma_remove_not_visible_states() on checkpoint to clean up not visible state history from tables
storage/maria/ma_close.c:
Remember state history for running transaction even if table is closed
storage/maria/ma_commit.c:
Ensure we always call trnman_commit_trn() even if other calls fails. If we don't do that, the translog and state structures will not be freed
storage/maria/ma_delete.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/ma_delete_all.c:
Versioning of count(*) and checksum:
- Ensure that share->state.state is updated, as here is where we store the primary information
storage/maria/ma_dynrec.c:
Use lock_key_trees instead of concurrent_insert to check if trees should be locked.
This allows us to lock trees both for concurrent_insert and for index versioning.
storage/maria/ma_extra.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- share->concurrent_insert -> share->non_transactional_concurrent_insert
- Don't update share->state.state from info->state if transactional table
Optimization:
- Don't flush io_cache or bitmap if we are using FLUSH_IGNORE_CHANGED
storage/maria/ma_info.c:
Get most state information from current state
storage/maria/ma_init.c:
Add hash table and free function to store states for closed tables
Install hook for transaction commit/rollback to update history state
storage/maria/ma_key_recover.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
storage/maria/ma_locking.c:
Versioning of count(*) and checksum:
- Call virtual functions (if exists) to restore/update status
- Move _ma_xxx_status() functions to ma_state.c
info->s -> share
storage/maria/ma_open.c:
Versioning of count(*) and checksum:
- For not transactional tables, set info->state to point to new allocated state structure.
- Initialize new info->state_start variable that points to state at start of transaction
- Copy old history states from hash table (maria_stored_states) first time the table is opened
- Split flag share->concurrent_insert to non_transactional_concurrent_insert & lock_key_tree
- For now, only enable versioning of tables without keys (to be fixed in soon!)
- Added new virtual function to restore status in maria_lock_database)
More DBUG
storage/maria/ma_page.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Modify share->state.state.key_file_length under share->intern_lock
storage/maria/ma_range.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
info->s -> share
storage/maria/ma_recovery.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Update state information on close and when reenabling logging
storage/maria/ma_rkey.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext_same.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
- Only skip rows based on file length if non_transactional_concurrent_insert is set
storage/maria/ma_rprev.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rsame.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_sort.c:
Use share->state.state instead of info->state
Fixed indentation
storage/maria/ma_static.c:
Added maria_stored_state
storage/maria/ma_update.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
- Remove optimization for index file update as it doesn't work for transactional tables
storage/maria/ma_write.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/maria_def.h:
Move MARIA_STATUS_INFO to ma_state.h
Changes to MARIA_SHARE:
- Added state_history to store count(*)/checksum states
- Added in_trans as counter if table is used by running transactions
- Split concurrent_insert into lock_key_trees and on_transactional_concurrent_insert.
- Added virtual function lock_restore_status
Changes to MARIA_HA:
- save_state -> state_save
- Added state_start to store state at start of transaction
storage/maria/maria_pack.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
Indentation fixes
storage/maria/trnman.c:
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
More DBUG
Changed return type of trnman_end_trn() to my_bool
Added trnman_get_min_trid() to get minimum trid in use.
Added trnman_exists_active_transactions() to check if there exist a running transaction started between two commit id
storage/maria/trnman.h:
Added 'used_tables'
Moved all pointers into same groups to get better memory alignment
storage/maria/trnman_public.h:
Added prototypes for new functions and variables
Chagned return type of trnman_end_trn() to my_bool
storage/myisam/ha_myisam.cc:
Added argument to end_bulk_insert() if operation should be aborted
storage/myisam/ha_myisam.h:
Added argument to end_bulk_insert() if operation should be aborted
storage/maria/ma_state.c:
Functions to handle state of count(*) and checksum
storage/maria/ma_state.h:
Structures and declarations to handle state of count(*) and checksum
2008-05-29 17:33:33 +02:00
|
|
|
if (info->s->lock_key_trees)
|
2011-07-13 21:10:18 +02:00
|
|
|
mysql_rwlock_unlock(&info->s->mmap_lock);
|
2006-04-11 15:45:10 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
info->s->nonmmaped_inserts++;
|
WL#3138: Maria - fast "SELECT COUNT(*) FROM t;" and "CHECKSUM TABLE t"
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
Fixed wrong call to strmake
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert
Allow storing year 2155 in year field
When running with purify/valgrind avoid copying structures over themself
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
Fixed that ndb doesn't crash on duplicate key error when start_bulk_insert/end_bulk_insert are not called
include/maria.h:
Added argument to maria_end_bulk_insert() to know if the table will be deleted after the operation
include/my_tree.h:
Added macro 'reset_free_element()' to be able to ignore calls to the external free function.
Is used to optimize end-bulk-insert in case of failures, in which case we don't want write the remaining keys in the tree
mysql-test/install_test_db.sh:
Upgrade to new mysql_install_db options
mysql-test/r/maria-mvcc.result:
New tests
mysql-test/r/maria.result:
New tests
mysql-test/suite/ndb/r/ndb_auto_increment.result:
Fixed error message now when bulk insert is not always called
mysql-test/suite/ndb/t/ndb_auto_increment.test:
Fixed error message now when bulk insert is not always called
mysql-test/t/maria-mvcc.test:
Added testing of versioning of count(*)
mysql-test/t/maria-page-checksum.test:
Added comment
mysql-test/t/maria.test:
More tests
mysys/hash.c:
Code style change
sql/field.cc:
Allow storing year 2155 in year field
sql/ha_ndbcluster.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_ndbcluster.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.cc:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/ha_partition.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored
sql/handler.cc:
Don't call get_dup_key() if there is no table object. This can happen if the handler generates a duplicate key error on commit
sql/handler.h:
Added new argument to end_bulk_insert() to signal if the bulk insert should ignored (ie, the table will be deleted)
sql/item.cc:
Style fix
Removed compiler warning
sql/log_event.cc:
Added new argument to ha_end_bulk_insert()
sql/log_event_old.cc:
Added new argument to ha_end_bulk_insert()
sql/mysqld.cc:
Removed compiler warning
sql/protocol.cc:
Added DBUG
sql/sql_class.cc:
Added DBUG
Fixed wrong call to strmake
sql/sql_insert.cc:
Don't call bulk insert in case of inserting only one row (speed optimization as starting/stopping bulk insert involves a lot of if's)
Added new argument to ha_end_bulk_insert()
sql/sql_load.cc:
Added new argument to ha_end_bulk_insert()
sql/sql_parse.cc:
Style fixes
Avoid goto in common senario
sql/sql_select.cc:
When running with purify/valgrind avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_select.h:
Avoid copying structures over themself. This is not a real bug in itself, but it's a waste of cycles and causes valgrind warnings
sql/sql_table.cc:
Call HA_EXTRA_PREPARE_FOR_DROP if table created by ALTER TABLE is going to be dropped
Added new argument to ha_end_bulk_insert()
storage/archive/ha_archive.cc:
Added new argument to end_bulk_insert()
storage/archive/ha_archive.h:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.cc:
Added new argument to end_bulk_insert()
storage/federated/ha_federated.h:
Added new argument to end_bulk_insert()
storage/maria/Makefile.am:
Added ma_state.c and ma_state.h
storage/maria/ha_maria.cc:
Versioning of count(*) and checksum
- share->state.state is now assumed to be correct, not handler->state
- Call _ma_setup_live_state() in external lock to get count(*)/checksum versioning. In case of
not versioned and not concurrent insertable table, file->s->state.state contains the correct state information
Other things:
- file->s -> share
- Added DBUG_ASSERT() for unlikely case
- Optimized end_bulk_insert() to not write anything if table is going to be deleted (as in failed alter table)
- Indentation changes in external_lock becasue of removed 'goto' caused a big conflict even if very little was changed
storage/maria/ha_maria.h:
New argument to end_bulk_insert()
storage/maria/ma_blockrec.c:
Update for versioning of count(*) and checksum
Keep share->state.state.data_file_length up to date (not info->state->data_file_length)
Moved _ma_block_xxxx_status() and maria_versioning() functions to ma_state.c
storage/maria/ma_check.c:
Update and use share->state.state instead of info->state
info->s to share
Update info->state at end of repair
Call _ma_reset_state() to update share->state_history at end of repair
storage/maria/ma_checkpoint.c:
Call _ma_remove_not_visible_states() on checkpoint to clean up not visible state history from tables
storage/maria/ma_close.c:
Remember state history for running transaction even if table is closed
storage/maria/ma_commit.c:
Ensure we always call trnman_commit_trn() even if other calls fails. If we don't do that, the translog and state structures will not be freed
storage/maria/ma_delete.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/ma_delete_all.c:
Versioning of count(*) and checksum:
- Ensure that share->state.state is updated, as here is where we store the primary information
storage/maria/ma_dynrec.c:
Use lock_key_trees instead of concurrent_insert to check if trees should be locked.
This allows us to lock trees both for concurrent_insert and for index versioning.
storage/maria/ma_extra.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- share->concurrent_insert -> share->non_transactional_concurrent_insert
- Don't update share->state.state from info->state if transactional table
Optimization:
- Don't flush io_cache or bitmap if we are using FLUSH_IGNORE_CHANGED
storage/maria/ma_info.c:
Get most state information from current state
storage/maria/ma_init.c:
Add hash table and free function to store states for closed tables
Install hook for transaction commit/rollback to update history state
storage/maria/ma_key_recover.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
storage/maria/ma_locking.c:
Versioning of count(*) and checksum:
- Call virtual functions (if exists) to restore/update status
- Move _ma_xxx_status() functions to ma_state.c
info->s -> share
storage/maria/ma_open.c:
Versioning of count(*) and checksum:
- For not transactional tables, set info->state to point to new allocated state structure.
- Initialize new info->state_start variable that points to state at start of transaction
- Copy old history states from hash table (maria_stored_states) first time the table is opened
- Split flag share->concurrent_insert to non_transactional_concurrent_insert & lock_key_tree
- For now, only enable versioning of tables without keys (to be fixed in soon!)
- Added new virtual function to restore status in maria_lock_database)
More DBUG
storage/maria/ma_page.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Modify share->state.state.key_file_length under share->intern_lock
storage/maria/ma_range.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
info->s -> share
storage/maria/ma_recovery.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
- Update state information on close and when reenabling logging
storage/maria/ma_rkey.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rnext_same.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
- Only skip rows based on file length if non_transactional_concurrent_insert is set
storage/maria/ma_rprev.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_rsame.c:
Versioning of count(*) and checksum:
- Lock trees based on share->lock_key_trees
storage/maria/ma_sort.c:
Use share->state.state instead of info->state
Fixed indentation
storage/maria/ma_static.c:
Added maria_stored_state
storage/maria/ma_update.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
- Remove optimization for index file update as it doesn't work for transactional tables
storage/maria/ma_write.c:
Versioning of count(*) and checksum:
- Always update info->state->checksum and info->state->records
storage/maria/maria_def.h:
Move MARIA_STATUS_INFO to ma_state.h
Changes to MARIA_SHARE:
- Added state_history to store count(*)/checksum states
- Added in_trans as counter if table is used by running transactions
- Split concurrent_insert into lock_key_trees and on_transactional_concurrent_insert.
- Added virtual function lock_restore_status
Changes to MARIA_HA:
- save_state -> state_save
- Added state_start to store state at start of transaction
storage/maria/maria_pack.c:
Versioning of count(*) and checksum:
- Use share->state.state instead of info->state
Indentation fixes
storage/maria/trnman.c:
Added hook 'trnnam_end_trans_hook' that is called when transaction ends
Added trn->used_tables that is used to an entry for all tables used by transaction
More DBUG
Changed return type of trnman_end_trn() to my_bool
Added trnman_get_min_trid() to get minimum trid in use.
Added trnman_exists_active_transactions() to check if there exist a running transaction started between two commit id
storage/maria/trnman.h:
Added 'used_tables'
Moved all pointers into same groups to get better memory alignment
storage/maria/trnman_public.h:
Added prototypes for new functions and variables
Chagned return type of trnman_end_trn() to my_bool
storage/myisam/ha_myisam.cc:
Added argument to end_bulk_insert() if operation should be aborted
storage/myisam/ha_myisam.h:
Added argument to end_bulk_insert() if operation should be aborted
storage/maria/ma_state.c:
Functions to handle state of count(*) and checksum
storage/maria/ma_state.h:
Structures and declarations to handle state of count(*) and checksum
2008-05-29 17:33:33 +02:00
|
|
|
if (info->s->lock_key_trees)
|
2011-07-13 21:10:18 +02:00
|
|
|
mysql_rwlock_unlock(&info->s->mmap_lock);
|
2007-04-04 22:37:09 +02:00
|
|
|
return my_pwrite(info->dfile.file, Buffer, Count, offset, MyFlags);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* wrapper for my_pwrite in case if mmap isn't used */
|
|
|
|
|
2007-10-04 19:33:42 +02:00
|
|
|
size_t _ma_nommap_pwrite(MARIA_HA *info, const uchar *Buffer,
|
|
|
|
size_t Count, my_off_t offset, myf MyFlags)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-04-04 22:37:09 +02:00
|
|
|
return my_pwrite(info->dfile.file, Buffer, Count, offset, MyFlags);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
my_bool _ma_write_dynamic_record(MARIA_HA *info, const uchar *record)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
ulong reclength= _ma_rec_pack(info,info->rec_buff + MARIA_REC_BUFF_OFFSET,
|
|
|
|
record);
|
|
|
|
return (write_dynamic_record(info,info->rec_buff + MARIA_REC_BUFF_OFFSET,
|
|
|
|
reclength));
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
my_bool _ma_update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS pos,
|
2007-07-02 19:45:15 +02:00
|
|
|
const uchar *oldrec __attribute__ ((unused)),
|
|
|
|
const uchar *record)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
uint length= _ma_rec_pack(info, info->rec_buff + MARIA_REC_BUFF_OFFSET,
|
|
|
|
record);
|
|
|
|
return (update_dynamic_record(info, pos,
|
|
|
|
info->rec_buff + MARIA_REC_BUFF_OFFSET,
|
|
|
|
length));
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
my_bool _ma_write_blob_record(MARIA_HA *info, const uchar *record)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *rec_buff;
|
2006-04-11 15:45:10 +02:00
|
|
|
int error;
|
|
|
|
ulong reclength,reclength2,extra;
|
|
|
|
|
|
|
|
extra= (ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER)+MARIA_SPLIT_LENGTH+
|
|
|
|
MARIA_DYN_DELETE_BLOCK_HEADER+1);
|
|
|
|
reclength= (info->s->base.pack_reclength +
|
|
|
|
_ma_calc_total_blob_length(info,record)+ extra);
|
2015-08-11 13:03:25 +02:00
|
|
|
if (!(rec_buff=(uchar*) my_safe_alloca(reclength)))
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-03-01 18:23:58 +01:00
|
|
|
my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
|
2007-01-18 20:38:14 +01:00
|
|
|
return(1);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
2007-01-18 20:38:14 +01:00
|
|
|
reclength2= _ma_rec_pack(info,
|
|
|
|
rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
|
2006-04-11 15:45:10 +02:00
|
|
|
record);
|
|
|
|
DBUG_PRINT("info",("reclength: %lu reclength2: %lu",
|
|
|
|
reclength, reclength2));
|
|
|
|
DBUG_ASSERT(reclength2 <= reclength);
|
2007-01-18 20:38:14 +01:00
|
|
|
error= write_dynamic_record(info,
|
|
|
|
rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
|
|
|
|
reclength2);
|
2015-08-11 13:03:25 +02:00
|
|
|
my_safe_afree(rec_buff, reclength);
|
2007-01-18 20:38:14 +01:00
|
|
|
return(error != 0);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos,
|
2007-07-02 19:45:15 +02:00
|
|
|
const uchar *oldrec __attribute__ ((unused)),
|
|
|
|
const uchar *record)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *rec_buff;
|
2006-04-11 15:45:10 +02:00
|
|
|
int error;
|
2018-02-14 18:14:24 +01:00
|
|
|
ulong reclength,reclength2,extra;
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
extra= (ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER)+MARIA_SPLIT_LENGTH+
|
|
|
|
MARIA_DYN_DELETE_BLOCK_HEADER);
|
|
|
|
reclength= (info->s->base.pack_reclength+
|
|
|
|
_ma_calc_total_blob_length(info,record)+ extra);
|
|
|
|
#ifdef NOT_USED /* We now support big rows */
|
|
|
|
if (reclength > MARIA_DYN_MAX_ROW_LENGTH)
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_TO_BIG_ROW;
|
2007-01-18 20:38:14 +01:00
|
|
|
return 1;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
#endif
|
2015-08-11 13:03:25 +02:00
|
|
|
if (!(rec_buff=(uchar*) my_safe_alloca(reclength)))
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-03-01 18:23:58 +01:00
|
|
|
my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
|
2007-01-18 20:38:14 +01:00
|
|
|
return(1);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
2018-02-14 18:14:24 +01:00
|
|
|
reclength2= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
|
2006-04-11 15:45:10 +02:00
|
|
|
record);
|
2018-02-14 18:14:24 +01:00
|
|
|
DBUG_ASSERT(reclength2 <= reclength);
|
2006-04-11 15:45:10 +02:00
|
|
|
error=update_dynamic_record(info,pos,
|
|
|
|
rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER),
|
2018-02-14 18:14:24 +01:00
|
|
|
reclength2);
|
2015-08-11 13:03:25 +02:00
|
|
|
my_safe_afree(rec_buff, reclength);
|
2007-01-18 20:38:14 +01:00
|
|
|
return(error != 0);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
This patch is a collection of patches from from Sanja, Sergei and Monty.
Added logging and pinning of pages to block format.
Integration of transaction manager, log handler.
Better page cache intergration
Split trnman.h into two files, so that we don't have to include my_atomic.h into C++ programs.
Renaming of structures, more comments, more debugging etc.
Fixed problem with small head block + long varchar.
Added extra argument to delete_record() and update_record() (needed for UNDO logging)
Small changes to interface of pagecache and log handler.
Change initialization of log_record_type_descriptors to not be depending on enum order.
Use array of LEX_STRING's to send data to log handler
Added 'dummy' transaction option to MARIA_INFO so that we can always assume 'trn' exists.
include/lf.h:
Interface fixes
Rename of structures
(Patch from Sergei via Sanja)
include/my_atomic.h:
More comments
include/my_global.h:
Added MY_ERRPTR
include/pagecache.h:
Added undo LSN when unlocking pages
mysql-test/r/maria.result:
Updated results
mysql-test/t/maria.test:
Added autocommit around lock tables
(Patch from Sanja)
mysys/lf_alloc-pin.c:
Post-review fixes, simple optimizations
More comments
Struct slot renames
Check amount of memory on stack
(Patch from Sergei)
mysys/lf_dynarray.c:
More comments
mysys/lf_hash.c:
More comments
After review fixes
(Patch from Sergei)
storage/maria/ha_maria.cc:
Split trnman.h into two files, so that we don't have to include my_atomic.h into the .cc program.
(Temporary fix to avoid bug in gcc)
Move out all deferencing of the transaction structure.
Transaction manager integrated (Patch from Sergei)
storage/maria/ha_maria.h:
Added prototype for start_stmt()
storage/maria/lockman.c:
Function call rename
storage/maria/ma_bitmap.c:
Mark deleted pages free from page cache
storage/maria/ma_blockrec.c:
Offset -> rownr
More debugging
Fixed problem with small head block + long varchar
Added logging of changed pages
Added logging of undo (Including only loggging of changed fields in case of update)
Added pinning/unpinning of all changed pages
More comments
Added free_full_pages() as the same code was used in several places.
fill_rows_parts() renamed as fill_insert_undo_parts()
offset -> rownr
Added some optimization of not transactional tables
_ma_update_block_record() has new parameter, as we need original row to do efficent undo for update
storage/maria/ma_blockrec.h:
Added ROW_EXTENTS_ON_STACK
Changed prototype for update and delete of row
storage/maria/ma_check.c:
Added original row to delete_record() call
storage/maria/ma_control_file.h:
Added ifdefs for C++
storage/maria/ma_delete.c:
Added original row to delete_record() call
(Needed for efficent undo logging)
storage/maria/ma_dynrec.c:
Added extra argument to delete_record() and update_record()
Removed not used variable
storage/maria/ma_init.c:
Initialize log handler
storage/maria/ma_loghandler.c:
Removed not used variable
Change initialization of log_record_type_descriptors to not be depending on enum order
Use array of LEX_STRING's to send data to log handler
storage/maria/ma_loghandler.h:
New defines
Use array of LEX_STRING's to send data to log handler
storage/maria/ma_open.c:
Added 'dummy' transaction option to MARIA_INFO so that we can always assume 'trn' exists.
Store in MARIA_SHARE->page_type if pages will have up to date LSN's
storage/maria/ma_pagecache.c:
Don't decrease number of readers when using pagecache_write()/pagecache_read()
In pagecache_write() decrement request count if page was left pinned
Added pagecache_delete_pages()
Removed some casts
Make trace output consistent with rest of code
Simplify calling of DBUG_ASSERT(0)
Only update LSN if the LSN is bigger than what's already on the page
Added LSN parameter pagecache_unpin_page(), pagecache_unpin(), and pagecache_unlock()
(Part of patch from Sanja)
storage/maria/ma_static.c:
Added 'dummy' transaction option to MARIA_INFO so that we can always assume 'trn' exists.
Added default page cache
storage/maria/ma_statrec.c:
Added extra argument to delete_record() and update_record()
storage/maria/ma_test1.c:
Added option -T for transactions
storage/maria/ma_test2.c:
Added option -T for transactions
storage/maria/ma_test_all.sh:
Test with transactions
storage/maria/ma_update.c:
Changed prototype for update of row
storage/maria/maria_def.h:
Changed prototype for update & delete of row as block records need to access the old row
Store in MARIA_SHARE->page_type if pages will have up to date LSN's
Added MARIA_MAX_TREE_LEVELS to allow us to calculate the number of possible pinned pages we may need.
Removed not used 'empty_bits_buffer'
Added pointer to transaction object
Added array for pinned pages
Added log_row_parts array for logging of field data.
Added MARIA_PINNED_PAGE to store pinned pages
storage/maria/trnman.c:
Added accessor functions to transaction object
Added missing DBUG_RETURN()
More debugging
More comments
Changed // comment of code to #ifdef NOT_USED
Transaction manager integrated.
Post review fixes
Part of patch originally from Sergei
storage/maria/trnman.h:
Split trnman.h into two files, so that we don't have to include my_atomic.h into the .cc program.
(Temporary fix to avoid bug in gcc)
storage/maria/unittest/ma_pagecache_single.c:
Added missing argument
Added SKIP_BIG_TESTS
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/trnman-t.c:
Stack overflow detection
(Patch from Sergei)
unittest/unit.pl:
Command-line options --big and --verbose
(Patch from Sergei)
unittest/mytap/tap.c:
Detect --big
(Patch from Sergei)
unittest/mytap/tap.h:
Skip_big_tests and SKIP_BIG_TESTS
(Patch from Sergei)
storage/maria/trnman_public.h:
New BitKeeper file ``storage/maria/trnman_public.h''
2007-05-29 19:13:56 +02:00
|
|
|
my_bool _ma_delete_dynamic_record(MARIA_HA *info,
|
2007-07-02 19:45:15 +02:00
|
|
|
const uchar *record __attribute__ ((unused)))
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
return delete_dynamic_record(info, info->cur_row.lastpos, 0);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
/**
|
|
|
|
Write record to data-file.
|
|
|
|
|
|
|
|
@todo it's cheating: it casts "const uchar*" to uchar*.
|
|
|
|
*/
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
static my_bool write_dynamic_record(MARIA_HA *info, const uchar *record,
|
2007-01-18 20:38:14 +01:00
|
|
|
ulong reclength)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
int flag;
|
|
|
|
ulong length;
|
|
|
|
my_off_t filepos;
|
|
|
|
DBUG_ENTER("write_dynamic_record");
|
|
|
|
|
|
|
|
flag=0;
|
2008-04-01 16:57:30 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
Check if we have enough room for the new record.
|
|
|
|
First we do simplified check to make usual case faster.
|
|
|
|
Then we do more precise check for the space left.
|
|
|
|
Though it still is not absolutely precise, as
|
|
|
|
we always use MARIA_MAX_DYN_BLOCK_HEADER while it can be
|
|
|
|
less in the most of the cases.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (unlikely(info->s->base.max_data_file_length -
|
|
|
|
info->state->data_file_length <
|
|
|
|
reclength + MARIA_MAX_DYN_BLOCK_HEADER))
|
|
|
|
{
|
|
|
|
if (info->s->base.max_data_file_length - info->state->data_file_length +
|
|
|
|
info->state->empty - info->state->del * MARIA_MAX_DYN_BLOCK_HEADER <
|
|
|
|
reclength + MARIA_MAX_DYN_BLOCK_HEADER)
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_RECORD_FILE_FULL;
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-11 15:45:10 +02:00
|
|
|
do
|
|
|
|
{
|
|
|
|
if (_ma_find_writepos(info,reclength,&filepos,&length))
|
|
|
|
goto err;
|
|
|
|
if (_ma_write_part_record(info,filepos,length,
|
|
|
|
(info->append_insert_at_end ?
|
|
|
|
HA_OFFSET_ERROR : info->s->state.dellink),
|
2007-07-02 19:45:15 +02:00
|
|
|
(uchar**) &record,&reclength,&flag))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
} while (reclength);
|
|
|
|
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
err:
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get a block for data ; The given data-area must be used !! */
|
|
|
|
|
|
|
|
static int _ma_find_writepos(MARIA_HA *info,
|
|
|
|
ulong reclength, /* record length */
|
|
|
|
my_off_t *filepos, /* Return file pos */
|
|
|
|
ulong *length) /* length of block at filepos */
|
|
|
|
{
|
|
|
|
MARIA_BLOCK_INFO block_info;
|
|
|
|
ulong tmp;
|
|
|
|
DBUG_ENTER("_ma_find_writepos");
|
|
|
|
|
|
|
|
if (info->s->state.dellink != HA_OFFSET_ERROR &&
|
|
|
|
!info->append_insert_at_end)
|
|
|
|
{
|
|
|
|
/* Deleted blocks exists; Get last used block */
|
|
|
|
*filepos=info->s->state.dellink;
|
|
|
|
block_info.second_read=0;
|
|
|
|
info->rec_cache.seek_not_done=1;
|
2011-01-26 14:29:36 +01:00
|
|
|
if (!(_ma_get_block_info(info, &block_info, info->dfile.file,
|
2007-04-04 22:37:09 +02:00
|
|
|
info->s->state.dellink) &
|
2006-04-11 15:45:10 +02:00
|
|
|
BLOCK_DELETED))
|
|
|
|
{
|
|
|
|
DBUG_PRINT("error",("Delete link crashed"));
|
2011-01-26 14:29:36 +01:00
|
|
|
_ma_set_fatal_error(info->s, HA_ERR_WRONG_IN_RECORD);
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(-1);
|
|
|
|
}
|
|
|
|
info->s->state.dellink=block_info.next_filepos;
|
|
|
|
info->state->del--;
|
|
|
|
info->state->empty-= block_info.block_len;
|
|
|
|
*length= block_info.block_len;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No deleted blocks; Allocate a new block */
|
|
|
|
*filepos=info->state->data_file_length;
|
2014-02-19 11:05:15 +01:00
|
|
|
if ((tmp= reclength + 3 + MY_TEST(reclength >= (65520 - 3))) <
|
2006-04-11 15:45:10 +02:00
|
|
|
info->s->base.min_block_length)
|
|
|
|
tmp= info->s->base.min_block_length;
|
|
|
|
else
|
|
|
|
tmp= ((tmp+MARIA_DYN_ALIGN_SIZE-1) &
|
|
|
|
(~ (ulong) (MARIA_DYN_ALIGN_SIZE-1)));
|
|
|
|
if (info->state->data_file_length >
|
|
|
|
(info->s->base.max_data_file_length - tmp))
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_RECORD_FILE_FULL;
|
|
|
|
DBUG_RETURN(-1);
|
|
|
|
}
|
|
|
|
if (tmp > MARIA_MAX_BLOCK_LENGTH)
|
|
|
|
tmp=MARIA_MAX_BLOCK_LENGTH;
|
|
|
|
*length= tmp;
|
|
|
|
info->state->data_file_length+= tmp;
|
|
|
|
info->s->state.split++;
|
|
|
|
info->update|=HA_STATE_WRITE_AT_END;
|
|
|
|
}
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
} /* _ma_find_writepos */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Unlink a deleted block from the deleted list.
|
|
|
|
This block will be combined with the preceding or next block to form
|
|
|
|
a big block.
|
|
|
|
*/
|
|
|
|
|
2008-02-19 00:00:58 +01:00
|
|
|
static my_bool unlink_deleted_block(MARIA_HA *info,
|
|
|
|
MARIA_BLOCK_INFO *block_info)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
DBUG_ENTER("unlink_deleted_block");
|
|
|
|
if (block_info->filepos == info->s->state.dellink)
|
|
|
|
{
|
|
|
|
/* First deleted block; We can just use this ! */
|
|
|
|
info->s->state.dellink=block_info->next_filepos;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MARIA_BLOCK_INFO tmp;
|
|
|
|
tmp.second_read=0;
|
|
|
|
/* Unlink block from the previous block */
|
2011-01-26 14:29:36 +01:00
|
|
|
if (!(_ma_get_block_info(info, &tmp, info->dfile.file,
|
|
|
|
block_info->prev_filepos)
|
2006-04-11 15:45:10 +02:00
|
|
|
& BLOCK_DELETED))
|
|
|
|
DBUG_RETURN(1); /* Something is wrong */
|
|
|
|
mi_sizestore(tmp.header+4,block_info->next_filepos);
|
2007-10-04 19:33:42 +02:00
|
|
|
if (info->s->file_write(info, tmp.header+4,8,
|
2006-04-11 15:45:10 +02:00
|
|
|
block_info->prev_filepos+4, MYF(MY_NABP)))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
/* Unlink block from next block */
|
|
|
|
if (block_info->next_filepos != HA_OFFSET_ERROR)
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
if (!(_ma_get_block_info(info, &tmp, info->dfile.file,
|
2007-04-04 22:37:09 +02:00
|
|
|
block_info->next_filepos)
|
2006-04-11 15:45:10 +02:00
|
|
|
& BLOCK_DELETED))
|
|
|
|
DBUG_RETURN(1); /* Something is wrong */
|
|
|
|
mi_sizestore(tmp.header+12,block_info->prev_filepos);
|
2007-10-04 19:33:42 +02:00
|
|
|
if (info->s->file_write(info, tmp.header+12,8,
|
2006-04-11 15:45:10 +02:00
|
|
|
block_info->next_filepos+12,
|
|
|
|
MYF(MY_NABP)))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* We now have one less deleted block */
|
|
|
|
info->state->del--;
|
|
|
|
info->state->empty-= block_info->block_len;
|
|
|
|
info->s->state.split--;
|
|
|
|
|
|
|
|
/*
|
|
|
|
If this was a block that we where accessing through table scan
|
|
|
|
(maria_rrnd() or maria_scan(), then ensure that we skip over this block
|
|
|
|
when doing next maria_rrnd() or maria_scan().
|
|
|
|
*/
|
2007-01-18 20:38:14 +01:00
|
|
|
if (info->cur_row.nextpos == block_info->filepos)
|
|
|
|
info->cur_row.nextpos+= block_info->block_len;
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Add a backward link to delete block
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
update_backward_delete_link()
|
|
|
|
info MARIA handler
|
|
|
|
delete_block Position to delete block to update.
|
|
|
|
If this is 'HA_OFFSET_ERROR', nothing will be done
|
|
|
|
filepos Position to block that 'delete_block' should point to
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 ok
|
|
|
|
1 error. In this case my_error is set.
|
|
|
|
*/
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
static my_bool update_backward_delete_link(MARIA_HA *info,
|
|
|
|
my_off_t delete_block,
|
|
|
|
MARIA_RECORD_POS filepos)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
MARIA_BLOCK_INFO block_info;
|
|
|
|
DBUG_ENTER("update_backward_delete_link");
|
|
|
|
|
|
|
|
if (delete_block != HA_OFFSET_ERROR)
|
|
|
|
{
|
|
|
|
block_info.second_read=0;
|
2011-01-26 14:29:36 +01:00
|
|
|
if (_ma_get_block_info(info, &block_info, info->dfile.file, delete_block)
|
2006-04-11 15:45:10 +02:00
|
|
|
& BLOCK_DELETED)
|
|
|
|
{
|
2007-10-04 19:33:42 +02:00
|
|
|
uchar buff[8];
|
2006-04-11 15:45:10 +02:00
|
|
|
mi_sizestore(buff,filepos);
|
|
|
|
if (info->s->file_write(info,buff, 8, delete_block+12, MYF(MY_NABP)))
|
|
|
|
DBUG_RETURN(1); /* Error on write */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
_ma_set_fatal_error(info->s, HA_ERR_WRONG_IN_RECORD);
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(1); /* Wrong delete link */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
}
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
/* Delete datarecord from database */
|
|
|
|
/* info->rec_cache.seek_not_done is updated in cmp_record */
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
static my_bool delete_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
|
|
|
|
uint second_read)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
uint length,b_type;
|
|
|
|
MARIA_BLOCK_INFO block_info,del_block;
|
|
|
|
int error;
|
|
|
|
my_bool remove_next_block;
|
|
|
|
DBUG_ENTER("delete_dynamic_record");
|
|
|
|
|
|
|
|
/* First add a link from the last block to the new one */
|
|
|
|
error= update_backward_delete_link(info, info->s->state.dellink, filepos);
|
|
|
|
|
|
|
|
block_info.second_read=second_read;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Remove block at 'filepos' */
|
2011-01-26 14:29:36 +01:00
|
|
|
if ((b_type= _ma_get_block_info(info, &block_info, info->dfile.file,
|
|
|
|
filepos))
|
2006-04-11 15:45:10 +02:00
|
|
|
& (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
|
|
|
|
BLOCK_FATAL_ERROR) ||
|
|
|
|
(length=(uint) (block_info.filepos-filepos) +block_info.block_len) <
|
|
|
|
MARIA_MIN_BLOCK_LENGTH)
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
_ma_set_fatal_error(info->s, HA_ERR_WRONG_IN_RECORD);
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
/* Check if next block is a delete block */
|
|
|
|
del_block.second_read=0;
|
|
|
|
remove_next_block=0;
|
2011-01-26 14:29:36 +01:00
|
|
|
if (_ma_get_block_info(info, &del_block, info->dfile.file,
|
|
|
|
filepos + length) &
|
2007-01-18 20:38:14 +01:00
|
|
|
BLOCK_DELETED && del_block.block_len+length <
|
|
|
|
MARIA_DYN_MAX_BLOCK_LENGTH)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
/* We can't remove this yet as this block may be the head block */
|
|
|
|
remove_next_block=1;
|
|
|
|
length+=del_block.block_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
block_info.header[0]=0;
|
|
|
|
mi_int3store(block_info.header+1,length);
|
|
|
|
mi_sizestore(block_info.header+4,info->s->state.dellink);
|
|
|
|
if (b_type & BLOCK_LAST)
|
|
|
|
bfill(block_info.header+12,8,255);
|
|
|
|
else
|
|
|
|
mi_sizestore(block_info.header+12,block_info.next_filepos);
|
2009-01-09 05:23:25 +01:00
|
|
|
if (info->s->file_write(info, block_info.header, 20, filepos,
|
2006-04-11 15:45:10 +02:00
|
|
|
MYF(MY_NABP)))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
info->s->state.dellink = filepos;
|
|
|
|
info->state->del++;
|
|
|
|
info->state->empty+=length;
|
|
|
|
filepos=block_info.next_filepos;
|
|
|
|
|
|
|
|
/* Now it's safe to unlink the deleted block directly after this one */
|
|
|
|
if (remove_next_block && unlink_deleted_block(info,&del_block))
|
|
|
|
error=1;
|
|
|
|
} while (!(b_type & BLOCK_LAST));
|
|
|
|
|
|
|
|
DBUG_RETURN(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Write a block to datafile */
|
|
|
|
|
|
|
|
int _ma_write_part_record(MARIA_HA *info,
|
|
|
|
my_off_t filepos, /* points at empty block */
|
|
|
|
ulong length, /* length of block */
|
|
|
|
my_off_t next_filepos,/* Next empty block */
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar **record, /* pointer to record ptr */
|
2006-04-11 15:45:10 +02:00
|
|
|
ulong *reclength, /* length of *record */
|
|
|
|
int *flag) /* *flag == 0 if header */
|
|
|
|
{
|
|
|
|
ulong head_length,res_length,extra_length,long_block,del_length;
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *pos,*record_end;
|
2006-04-11 15:45:10 +02:00
|
|
|
my_off_t next_delete_block;
|
|
|
|
uchar temp[MARIA_SPLIT_LENGTH+MARIA_DYN_DELETE_BLOCK_HEADER];
|
|
|
|
DBUG_ENTER("_ma_write_part_record");
|
|
|
|
|
|
|
|
next_delete_block=HA_OFFSET_ERROR;
|
|
|
|
|
|
|
|
res_length=extra_length=0;
|
|
|
|
if (length > *reclength + MARIA_SPLIT_LENGTH)
|
|
|
|
{ /* Splitt big block */
|
|
|
|
res_length=MY_ALIGN(length- *reclength - MARIA_EXTEND_BLOCK_LENGTH,
|
|
|
|
MARIA_DYN_ALIGN_SIZE);
|
|
|
|
length-= res_length; /* Use this for first part */
|
|
|
|
}
|
|
|
|
long_block= (length < 65520L && *reclength < 65520L) ? 0 : 1;
|
|
|
|
if (length == *reclength+ 3 + long_block)
|
|
|
|
{
|
|
|
|
/* Block is exactly of the right length */
|
|
|
|
temp[0]=(uchar) (1+ *flag)+(uchar) long_block; /* Flag is 0 or 6 */
|
|
|
|
if (long_block)
|
|
|
|
{
|
|
|
|
mi_int3store(temp+1,*reclength);
|
|
|
|
head_length=4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mi_int2store(temp+1,*reclength);
|
|
|
|
head_length=3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (length-long_block < *reclength+4)
|
|
|
|
{ /* To short block */
|
|
|
|
if (next_filepos == HA_OFFSET_ERROR)
|
|
|
|
next_filepos= (info->s->state.dellink != HA_OFFSET_ERROR &&
|
|
|
|
!info->append_insert_at_end ?
|
|
|
|
info->s->state.dellink : info->state->data_file_length);
|
|
|
|
if (*flag == 0) /* First block */
|
|
|
|
{
|
|
|
|
if (*reclength > MARIA_MAX_BLOCK_LENGTH)
|
|
|
|
{
|
|
|
|
head_length= 16;
|
|
|
|
temp[0]=13;
|
|
|
|
mi_int4store(temp+1,*reclength);
|
|
|
|
mi_int3store(temp+5,length-head_length);
|
2009-01-09 05:23:25 +01:00
|
|
|
mi_sizestore(temp+8,next_filepos);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
head_length=5+8+long_block*2;
|
|
|
|
temp[0]=5+(uchar) long_block;
|
|
|
|
if (long_block)
|
|
|
|
{
|
|
|
|
mi_int3store(temp+1,*reclength);
|
|
|
|
mi_int3store(temp+4,length-head_length);
|
2009-01-09 05:23:25 +01:00
|
|
|
mi_sizestore(temp+7,next_filepos);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mi_int2store(temp+1,*reclength);
|
|
|
|
mi_int2store(temp+3,length-head_length);
|
2009-01-09 05:23:25 +01:00
|
|
|
mi_sizestore(temp+5,next_filepos);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
head_length=3+8+long_block;
|
|
|
|
temp[0]=11+(uchar) long_block;
|
|
|
|
if (long_block)
|
|
|
|
{
|
|
|
|
mi_int3store(temp+1,length-head_length);
|
2009-01-09 05:23:25 +01:00
|
|
|
mi_sizestore(temp+4,next_filepos);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mi_int2store(temp+1,length-head_length);
|
2009-01-09 05:23:25 +01:00
|
|
|
mi_sizestore(temp+3,next_filepos);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* Block with empty info last */
|
|
|
|
head_length=4+long_block;
|
|
|
|
extra_length= length- *reclength-head_length;
|
|
|
|
temp[0]= (uchar) (3+ *flag)+(uchar) long_block; /* 3,4 or 9,10 */
|
|
|
|
if (long_block)
|
|
|
|
{
|
|
|
|
mi_int3store(temp+1,*reclength);
|
|
|
|
temp[4]= (uchar) (extra_length);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mi_int2store(temp+1,*reclength);
|
|
|
|
temp[3]= (uchar) (extra_length);
|
|
|
|
}
|
2009-01-09 05:23:25 +01:00
|
|
|
length= *reclength+head_length; /* Write only what is needed */
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
2009-01-09 05:23:25 +01:00
|
|
|
DBUG_DUMP("header", temp, head_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
/* Make a long block for one write */
|
|
|
|
record_end= *record+length-head_length;
|
|
|
|
del_length=(res_length ? MARIA_DYN_DELETE_BLOCK_HEADER : 0);
|
2009-01-09 05:23:25 +01:00
|
|
|
bmove((*record-head_length), temp, head_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
memcpy(temp,record_end,(size_t) (extra_length+del_length));
|
2009-01-09 05:23:25 +01:00
|
|
|
bzero(record_end, extra_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
if (res_length)
|
|
|
|
{
|
|
|
|
/* Check first if we can join this block with the next one */
|
|
|
|
MARIA_BLOCK_INFO del_block;
|
|
|
|
my_off_t next_block=filepos+length+extra_length+res_length;
|
|
|
|
|
|
|
|
del_block.second_read=0;
|
|
|
|
if (next_block < info->state->data_file_length &&
|
|
|
|
info->s->state.dellink != HA_OFFSET_ERROR)
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
if ((_ma_get_block_info(info, &del_block, info->dfile.file, next_block)
|
2006-04-11 15:45:10 +02:00
|
|
|
& BLOCK_DELETED) &&
|
|
|
|
res_length + del_block.block_len < MARIA_DYN_MAX_BLOCK_LENGTH)
|
|
|
|
{
|
|
|
|
if (unlink_deleted_block(info,&del_block))
|
|
|
|
goto err;
|
|
|
|
res_length+=del_block.block_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a delete link of the last part of the block */
|
|
|
|
pos=record_end+extra_length;
|
|
|
|
pos[0]= '\0';
|
|
|
|
mi_int3store(pos+1,res_length);
|
|
|
|
mi_sizestore(pos+4,info->s->state.dellink);
|
|
|
|
bfill(pos+12,8,255); /* End link */
|
|
|
|
next_delete_block=info->s->state.dellink;
|
|
|
|
info->s->state.dellink= filepos+length+extra_length;
|
|
|
|
info->state->del++;
|
|
|
|
info->state->empty+=res_length;
|
|
|
|
info->s->state.split++;
|
|
|
|
}
|
|
|
|
if (info->opt_flag & WRITE_CACHE_USED &&
|
|
|
|
info->update & HA_STATE_WRITE_AT_END)
|
|
|
|
{
|
|
|
|
if (info->update & HA_STATE_EXTEND_BLOCK)
|
|
|
|
{
|
|
|
|
info->update&= ~HA_STATE_EXTEND_BLOCK;
|
2009-01-09 05:23:25 +01:00
|
|
|
if (my_block_write(&info->rec_cache, *record-head_length,
|
2006-04-11 15:45:10 +02:00
|
|
|
length+extra_length+del_length,filepos))
|
|
|
|
goto err;
|
|
|
|
}
|
2009-01-09 05:23:25 +01:00
|
|
|
else if (my_b_write(&info->rec_cache, *record-head_length,
|
2006-04-11 15:45:10 +02:00
|
|
|
length+extra_length+del_length))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
info->rec_cache.seek_not_done=1;
|
2009-01-09 05:23:25 +01:00
|
|
|
if (info->s->file_write(info, *record-head_length,
|
2007-01-18 20:38:14 +01:00
|
|
|
length+extra_length+
|
|
|
|
del_length,filepos,info->s->write_flag))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
memcpy(record_end,temp,(size_t) (extra_length+del_length));
|
|
|
|
*record=record_end;
|
|
|
|
*reclength-=(length-head_length);
|
|
|
|
*flag=6;
|
|
|
|
|
|
|
|
if (del_length)
|
|
|
|
{
|
|
|
|
/* link the next delete block to this */
|
|
|
|
if (update_backward_delete_link(info, next_delete_block,
|
|
|
|
info->s->state.dellink))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
err:
|
|
|
|
DBUG_PRINT("exit",("errno: %d",my_errno));
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
} /* _ma_write_part_record */
|
|
|
|
|
|
|
|
|
|
|
|
/* update record from datafile */
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
static my_bool update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *record, ulong reclength)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
int flag;
|
|
|
|
uint error;
|
|
|
|
ulong length;
|
|
|
|
MARIA_BLOCK_INFO block_info;
|
|
|
|
DBUG_ENTER("update_dynamic_record");
|
|
|
|
|
|
|
|
flag=block_info.second_read=0;
|
2008-04-01 16:57:30 +02:00
|
|
|
/*
|
|
|
|
Check if we have enough room for the record.
|
|
|
|
First we do simplified check to make usual case faster.
|
|
|
|
Then we do more precise check for the space left.
|
|
|
|
Though it still is not absolutely precise, as
|
|
|
|
we always use MARIA_MAX_DYN_BLOCK_HEADER while it can be
|
|
|
|
less in the most of the cases.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
compare with just the reclength as we're going
|
|
|
|
to get some space from the old replaced record
|
|
|
|
*/
|
|
|
|
if (unlikely(info->s->base.max_data_file_length -
|
|
|
|
info->state->data_file_length < reclength))
|
|
|
|
{
|
|
|
|
/* If new record isn't longer, we can go on safely */
|
|
|
|
if (info->cur_row.total_length < reclength)
|
|
|
|
{
|
|
|
|
if (info->s->base.max_data_file_length - info->state->data_file_length +
|
|
|
|
info->state->empty - info->state->del * MARIA_MAX_DYN_BLOCK_HEADER <
|
|
|
|
reclength - info->cur_row.total_length + MARIA_MAX_DYN_BLOCK_HEADER)
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_RECORD_FILE_FULL;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Remember length for updated row if it's updated again */
|
|
|
|
info->cur_row.total_length= reclength;
|
|
|
|
|
2006-04-11 15:45:10 +02:00
|
|
|
while (reclength > 0)
|
|
|
|
{
|
|
|
|
if (filepos != info->s->state.dellink)
|
|
|
|
{
|
|
|
|
block_info.next_filepos= HA_OFFSET_ERROR;
|
2011-01-26 14:29:36 +01:00
|
|
|
if ((error= _ma_get_block_info(info, &block_info, info->dfile.file,
|
|
|
|
filepos))
|
2006-04-11 15:45:10 +02:00
|
|
|
& (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
|
|
|
|
BLOCK_FATAL_ERROR))
|
|
|
|
{
|
|
|
|
DBUG_PRINT("error",("Got wrong block info"));
|
|
|
|
if (!(error & BLOCK_FATAL_ERROR))
|
2011-01-26 14:29:36 +01:00
|
|
|
_ma_set_fatal_error(info->s, HA_ERR_WRONG_IN_RECORD);
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
length=(ulong) (block_info.filepos-filepos) + block_info.block_len;
|
|
|
|
if (length < reclength)
|
|
|
|
{
|
|
|
|
uint tmp=MY_ALIGN(reclength - length + 3 +
|
2014-02-19 11:05:15 +01:00
|
|
|
MY_TEST(reclength >= 65520L), MARIA_DYN_ALIGN_SIZE);
|
2006-04-11 15:45:10 +02:00
|
|
|
/* Don't create a block bigger than MARIA_MAX_BLOCK_LENGTH */
|
2013-03-25 23:03:13 +01:00
|
|
|
tmp= MY_MIN(length+tmp, MARIA_MAX_BLOCK_LENGTH)-length;
|
2006-04-11 15:45:10 +02:00
|
|
|
/* Check if we can extend this block */
|
|
|
|
if (block_info.filepos + block_info.block_len ==
|
|
|
|
info->state->data_file_length &&
|
|
|
|
info->state->data_file_length <
|
|
|
|
info->s->base.max_data_file_length-tmp)
|
|
|
|
{
|
|
|
|
/* extend file */
|
|
|
|
DBUG_PRINT("info",("Extending file with %d bytes",tmp));
|
2007-01-18 20:38:14 +01:00
|
|
|
if (info->cur_row.nextpos == info->state->data_file_length)
|
|
|
|
info->cur_row.nextpos+= tmp;
|
2006-04-11 15:45:10 +02:00
|
|
|
info->state->data_file_length+= tmp;
|
|
|
|
info->update|= HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK;
|
|
|
|
length+=tmp;
|
|
|
|
}
|
|
|
|
else if (length < MARIA_MAX_BLOCK_LENGTH - MARIA_MIN_BLOCK_LENGTH)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Check if next block is a deleted block
|
|
|
|
Above we have MARIA_MIN_BLOCK_LENGTH to avoid the problem where
|
|
|
|
the next block is so small it can't be splited which could
|
|
|
|
casue problems
|
|
|
|
*/
|
|
|
|
|
|
|
|
MARIA_BLOCK_INFO del_block;
|
|
|
|
del_block.second_read=0;
|
2011-01-26 14:29:36 +01:00
|
|
|
if (_ma_get_block_info(info, &del_block, info->dfile.file,
|
2006-04-11 15:45:10 +02:00
|
|
|
block_info.filepos + block_info.block_len) &
|
|
|
|
BLOCK_DELETED)
|
|
|
|
{
|
|
|
|
/* Use; Unlink it and extend the current block */
|
|
|
|
DBUG_PRINT("info",("Extending current block"));
|
|
|
|
if (unlink_deleted_block(info,&del_block))
|
|
|
|
goto err;
|
|
|
|
if ((length+=del_block.block_len) > MARIA_MAX_BLOCK_LENGTH)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
New block was too big, link overflow part back to
|
|
|
|
delete list
|
|
|
|
*/
|
|
|
|
my_off_t next_pos;
|
|
|
|
ulong rest_length= length-MARIA_MAX_BLOCK_LENGTH;
|
|
|
|
set_if_bigger(rest_length, MARIA_MIN_BLOCK_LENGTH);
|
|
|
|
next_pos= del_block.filepos+ del_block.block_len - rest_length;
|
|
|
|
|
|
|
|
if (update_backward_delete_link(info, info->s->state.dellink,
|
|
|
|
next_pos))
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
|
|
|
|
/* create delete link for data that didn't fit into the page */
|
|
|
|
del_block.header[0]=0;
|
|
|
|
mi_int3store(del_block.header+1, rest_length);
|
|
|
|
mi_sizestore(del_block.header+4,info->s->state.dellink);
|
|
|
|
bfill(del_block.header+12,8,255);
|
2009-01-09 05:23:25 +01:00
|
|
|
if (info->s->file_write(info, del_block.header, 20,
|
2007-01-18 20:38:14 +01:00
|
|
|
next_pos, MYF(MY_NABP)))
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(1);
|
|
|
|
info->s->state.dellink= next_pos;
|
|
|
|
info->s->state.split++;
|
|
|
|
info->state->del++;
|
|
|
|
info->state->empty+= rest_length;
|
|
|
|
length-= rest_length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (_ma_find_writepos(info,reclength,&filepos,&length))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
if (_ma_write_part_record(info,filepos,length,block_info.next_filepos,
|
|
|
|
&record,&reclength,&flag))
|
|
|
|
goto err;
|
|
|
|
if ((filepos=block_info.next_filepos) == HA_OFFSET_ERROR)
|
|
|
|
{
|
|
|
|
/* Start writing data on deleted blocks */
|
|
|
|
filepos=info->s->state.dellink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (block_info.next_filepos != HA_OFFSET_ERROR)
|
|
|
|
if (delete_dynamic_record(info,block_info.next_filepos,1))
|
|
|
|
goto err;
|
2008-04-01 16:57:30 +02:00
|
|
|
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(0);
|
|
|
|
err:
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Pack a record. Return new reclength */
|
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
|
|
|
|
register const uchar *from)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
uint length,new_length,flag,bit,i;
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
const uchar *pos,*end;
|
|
|
|
uchar *startpos,*packpos;
|
2006-04-11 15:45:10 +02:00
|
|
|
enum en_fieldtype type;
|
2007-04-19 12:18:56 +02:00
|
|
|
reg3 MARIA_COLUMNDEF *column;
|
2006-04-11 15:45:10 +02:00
|
|
|
MARIA_BLOB *blob;
|
|
|
|
DBUG_ENTER("_ma_rec_pack");
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
flag= 0;
|
|
|
|
bit= 1;
|
|
|
|
startpos= packpos=to;
|
|
|
|
to+= info->s->base.pack_bytes;
|
|
|
|
blob= info->blobs;
|
2007-04-19 12:18:56 +02:00
|
|
|
column= info->s->columndef;
|
2007-01-18 20:38:14 +01:00
|
|
|
if (info->s->base.null_bytes)
|
|
|
|
{
|
|
|
|
memcpy(to, from, info->s->base.null_bytes);
|
|
|
|
from+= info->s->base.null_bytes;
|
|
|
|
to+= info->s->base.null_bytes;
|
|
|
|
}
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-04-19 12:18:56 +02:00
|
|
|
for (i=info->s->base.fields ; i-- > 0; from+= length, column++)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
length=(uint) column->length;
|
|
|
|
if ((type = (enum en_fieldtype) column->type) != FIELD_NORMAL)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
if (type == FIELD_BLOB)
|
|
|
|
{
|
|
|
|
if (!blob->length)
|
|
|
|
flag|=bit;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *temp_pos;
|
2007-04-19 12:18:56 +02:00
|
|
|
size_t tmp_length=length-portable_sizeof_char_ptr;
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to,from,tmp_length);
|
2011-04-25 17:22:25 +02:00
|
|
|
memcpy(&temp_pos,from+tmp_length,sizeof(char*));
|
2006-04-11 15:45:10 +02:00
|
|
|
memcpy(to+tmp_length,temp_pos,(size_t) blob->length);
|
|
|
|
to+=tmp_length+blob->length;
|
|
|
|
}
|
|
|
|
blob++;
|
|
|
|
}
|
|
|
|
else if (type == FIELD_SKIP_ZERO)
|
|
|
|
{
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
if (memcmp(from, maria_zero_string, length) == 0)
|
2006-04-11 15:45:10 +02:00
|
|
|
flag|=bit;
|
|
|
|
else
|
|
|
|
{
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, from, (size_t) length);
|
2007-12-10 13:21:45 +01:00
|
|
|
to+=length;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == FIELD_SKIP_ENDSPACE ||
|
|
|
|
type == FIELD_SKIP_PRESPACE)
|
|
|
|
{
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
pos= from; end= from + length;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (type == FIELD_SKIP_ENDSPACE)
|
|
|
|
{ /* Pack trailing spaces */
|
2007-07-27 12:06:39 +02:00
|
|
|
while (end > from && *(end-1) == ' ')
|
2006-04-11 15:45:10 +02:00
|
|
|
end--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* Pack pref-spaces */
|
|
|
|
while (pos < end && *pos == ' ')
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
new_length=(uint) (end-pos);
|
2014-02-19 11:05:15 +01:00
|
|
|
if (new_length + 1 + MY_TEST(column->length > 255 && new_length > 127)
|
2006-04-11 15:45:10 +02:00
|
|
|
< length)
|
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
if (column->length > 255 && new_length > 127)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2008-05-26 16:10:32 +02:00
|
|
|
to[0]= (uchar) ((new_length & 127) + 128);
|
|
|
|
to[1]= (uchar) (new_length >> 7);
|
2006-04-11 15:45:10 +02:00
|
|
|
to+=2;
|
|
|
|
}
|
|
|
|
else
|
2008-05-26 16:10:32 +02:00
|
|
|
*to++= (uchar) new_length;
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, pos, (size_t) new_length); to+=new_length;
|
2006-04-11 15:45:10 +02:00
|
|
|
flag|=bit;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(to,from,(size_t) length); to+=length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == FIELD_VARCHAR)
|
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
uint pack_length= HA_VARCHAR_PACKLENGTH(column->length -1);
|
2006-04-11 15:45:10 +02:00
|
|
|
uint tmp_length;
|
|
|
|
if (pack_length == 1)
|
|
|
|
{
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
tmp_length= (uint) *from;
|
2006-04-11 15:45:10 +02:00
|
|
|
*to++= *from;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp_length= uint2korr(from);
|
|
|
|
store_key_length_inc(to,tmp_length);
|
|
|
|
}
|
|
|
|
memcpy(to, from+pack_length,tmp_length);
|
|
|
|
to+= tmp_length;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(to,from,(size_t) length); to+=length;
|
|
|
|
continue; /* Normal field */
|
|
|
|
}
|
|
|
|
if ((bit= bit << 1) >= 256)
|
|
|
|
{
|
2008-05-26 16:10:32 +02:00
|
|
|
*packpos++ = (uchar) flag;
|
2006-04-11 15:45:10 +02:00
|
|
|
bit=1; flag=0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(to,from,(size_t) length); to+=length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (bit != 1)
|
2008-05-26 16:10:32 +02:00
|
|
|
*packpos= (uchar) flag;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (info->s->calc_checksum)
|
2007-07-02 19:45:15 +02:00
|
|
|
*to++= (uchar) info->cur_row.checksum;
|
2007-07-27 12:06:39 +02:00
|
|
|
DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
|
|
|
|
DBUG_RETURN((uint) (to-startpos));
|
2006-04-11 15:45:10 +02:00
|
|
|
} /* _ma_rec_pack */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2007-01-18 20:38:14 +01:00
|
|
|
Check if a record was correctly packed. Used only by maria_chk
|
2006-04-11 15:45:10 +02:00
|
|
|
Returns 0 if record is ok.
|
|
|
|
*/
|
|
|
|
|
2007-07-27 12:06:39 +02:00
|
|
|
my_bool _ma_rec_check(MARIA_HA *info,const uchar *record, uchar *rec_buff,
|
2007-07-01 15:20:57 +02:00
|
|
|
ulong packed_length, my_bool with_checksum,
|
|
|
|
ha_checksum checksum)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
uint length,new_length,flag,bit,i;
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
const uchar *pos,*end;
|
|
|
|
uchar *packpos,*to;
|
2006-04-11 15:45:10 +02:00
|
|
|
enum en_fieldtype type;
|
2007-04-19 12:18:56 +02:00
|
|
|
reg3 MARIA_COLUMNDEF *column;
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_ENTER("_ma_rec_check");
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
packpos=rec_buff; to= rec_buff+info->s->base.pack_bytes;
|
2007-04-19 12:18:56 +02:00
|
|
|
column= info->s->columndef;
|
2006-04-11 15:45:10 +02:00
|
|
|
flag= *packpos; bit=1;
|
2007-01-18 20:38:14 +01:00
|
|
|
record+= info->s->base.null_bytes;
|
|
|
|
to+= info->s->base.null_bytes;
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-04-19 12:18:56 +02:00
|
|
|
for (i=info->s->base.fields ; i-- > 0; record+= length, column++)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
length=(uint) column->length;
|
|
|
|
if ((type = (enum en_fieldtype) column->type) != FIELD_NORMAL)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
if (type == FIELD_BLOB)
|
|
|
|
{
|
|
|
|
uint blob_length=
|
2007-04-19 12:18:56 +02:00
|
|
|
_ma_calc_blob_length(length-portable_sizeof_char_ptr,record);
|
2006-04-11 15:45:10 +02:00
|
|
|
if (!blob_length && !(flag & bit))
|
|
|
|
goto err;
|
|
|
|
if (blob_length)
|
2007-04-19 12:18:56 +02:00
|
|
|
to+=length - portable_sizeof_char_ptr+ blob_length;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
else if (type == FIELD_SKIP_ZERO)
|
|
|
|
{
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
if (memcmp(record, maria_zero_string, length) == 0)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
if (!(flag & bit))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
to+=length;
|
|
|
|
}
|
|
|
|
else if (type == FIELD_SKIP_ENDSPACE ||
|
|
|
|
type == FIELD_SKIP_PRESPACE)
|
|
|
|
{
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
pos= record; end= record + length;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (type == FIELD_SKIP_ENDSPACE)
|
|
|
|
{ /* Pack trailing spaces */
|
|
|
|
while (end > record && *(end-1) == ' ')
|
|
|
|
end--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* Pack pre-spaces */
|
|
|
|
while (pos < end && *pos == ' ')
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
new_length=(uint) (end-pos);
|
2014-02-19 11:05:15 +01:00
|
|
|
if (new_length + 1 + MY_TEST(column->length > 255 && new_length > 127)
|
2006-04-11 15:45:10 +02:00
|
|
|
< length)
|
|
|
|
{
|
|
|
|
if (!(flag & bit))
|
|
|
|
goto err;
|
2007-04-19 12:18:56 +02:00
|
|
|
if (column->length > 255 && new_length > 127)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2008-05-26 16:10:32 +02:00
|
|
|
/* purecov: begin inspected */
|
|
|
|
if (to[0] != (uchar) ((new_length & 127) + 128) ||
|
|
|
|
to[1] != (uchar) (new_length >> 7))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
to+=2;
|
2008-05-26 16:10:32 +02:00
|
|
|
/* purecov: end */
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
2008-05-26 16:10:32 +02:00
|
|
|
else if (*to++ != (uchar) new_length)
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
to+=new_length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
to+=length;
|
|
|
|
}
|
|
|
|
else if (type == FIELD_VARCHAR)
|
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
uint pack_length= HA_VARCHAR_PACKLENGTH(column->length -1);
|
2006-04-11 15:45:10 +02:00
|
|
|
uint tmp_length;
|
|
|
|
if (pack_length == 1)
|
|
|
|
{
|
Injecting more "const" declarations into code which does not change
pointed data.
I ran gcc -Wcast-qual on storage/maria, this identified un-needed casts,
a couple of functions which said they had a const parameter though
they changed the pointed content! This is fixed here. Some suspicious
places receive a comment.
The original intention of running -Wcast-qual was to find what code
changes R-tree keys: I added const words, but hidden casts
like those of int2store (casts target to (uint16*)) removed const
checking; -Wcast-qual helped find those hidden casts.
Log handler does not change the content pointed by LEX_STRING::str it
receives, so we now use a struct which has a const inside, to emphasize
this and be able to pass "const uchar*" buffers to log handler
without fear of their content being changed by it.
One-line fix for a merge glitch (when merging from MyISAM).
include/m_string.h:
As Maria's log handler uses LEX_STRING but never changes the content
pointed by LEX_STRING::str, and assigns uchar* into this member most
of the time, we introduce a new struct LEX_CUSTRING
(C const U unsigned) for the log handler.
include/my_global.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
include/my_handler.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
ha_find_null() does not change *a.
include/my_sys.h:
insert_dynamic() does not change *element.
include/myisampack.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
mysys/array.c:
insert_dynamic() does not change *element
mysys/my_handler.c:
ha_find_null() does not change *a
storage/maria/ma_bitmap.c:
Log handler receives const strings now
storage/maria/ma_blockrec.c:
Log handler receives const strings now.
_ma_apply_undo_row_delete/update() do change *header.
storage/maria/ma_blockrec.h:
correct prototype
storage/maria/ma_check.c:
Log handler receives const strings now. Un-needed casts
storage/maria/ma_checkpoint.c:
Log handler receives const strings now
storage/maria/ma_checksum.c:
unneeded cast
storage/maria/ma_commit.c:
Log handler receives const strings now
storage/maria/ma_create.c:
Log handler receives const strings now
storage/maria/ma_dbug.c:
fixing warning of gcc -Wcast-qual
storage/maria/ma_delete.c:
Log handler receives const strings now
storage/maria/ma_delete_all.c:
Log handler receives const strings now
storage/maria/ma_delete_table.c:
Log handler receives const strings now
storage/maria/ma_dynrec.c:
fixing some warnings of gcc -Wcast-qual. Unneeded casts removed.
Comment about function which lies.
storage/maria/ma_ft_parser.c:
fix for warnings of gcc -Wcast-qual, removing unneeded casts
storage/maria/ma_ft_update.c:
less casts, comment
storage/maria/ma_key.c:
less casts, stay const (warnings of gcc -Wcast-qual)
storage/maria/ma_key_recover.c:
Log handler receives const strings now
storage/maria/ma_loghandler.c:
Log handler receives const strings now
storage/maria/ma_loghandler.h:
Log handler receives const strings now
storage/maria/ma_loghandler_lsn.h:
In macros which read pointed content: use const pointers so that
gcc -Wcast-qual does not warn about casting a const pointer to non-const.
storage/maria/ma_page.c:
Log handler receives const strings now; more const
storage/maria/ma_recovery.c:
Log handler receives const strings now
storage/maria/ma_rename.c:
Log handler receives const strings now
storage/maria/ma_rt_index.c:
more const, to emphasize that functions don't change pointed content.
best_key= NULL was forgotten during merge from MyISAM a few days ago,
was causing a Valgrind warning
storage/maria/ma_rt_index.h:
new proto
storage/maria/ma_rt_key.c:
more const
storage/maria/ma_rt_key.h:
new proto
storage/maria/ma_rt_mbr.c:
more const for functions which deserve it
storage/maria/ma_rt_mbr.h:
new prototype
storage/maria/ma_rt_split.c:
make const what is not changed.
storage/maria/ma_search.c:
un-needed casts, more const
storage/maria/ma_sp_key.c:
more const
storage/maria/ma_unique.c:
un-needed casts.
storage/maria/ma_write.c:
Log handler receives const strings now
storage/maria/maria_def.h:
some more const
storage/maria/unittest/ma_test_loghandler-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Log handler receives const strings now
storage/maria/unittest/ma_test_loghandler_purge-t.c:
Log handler receives const strings now
2008-04-03 15:40:25 +02:00
|
|
|
tmp_length= (uint) *record;
|
2006-04-11 15:45:10 +02:00
|
|
|
to+= 1+ tmp_length;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp_length= uint2korr(record);
|
|
|
|
to+= get_pack_length(tmp_length)+tmp_length;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
to+=length;
|
|
|
|
continue; /* Normal field */
|
|
|
|
}
|
|
|
|
if ((bit= bit << 1) >= 256)
|
|
|
|
{
|
|
|
|
flag= *++packpos;
|
|
|
|
bit=1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
to+= length;
|
|
|
|
}
|
2007-07-27 12:06:39 +02:00
|
|
|
if (packed_length != (uint) (to - rec_buff) +
|
2014-02-19 11:05:15 +01:00
|
|
|
MY_TEST(info->s->calc_checksum) || (bit != 1 && (flag & ~(bit - 1))))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
2007-07-01 15:20:57 +02:00
|
|
|
if (with_checksum && ((uchar) checksum != (uchar) *to))
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
DBUG_PRINT("error",("wrong checksum for row"));
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
|
|
|
|
err:
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-09 18:15:10 +02:00
|
|
|
/*
|
|
|
|
@brief Unpacks a record
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-09-09 18:15:10 +02:00
|
|
|
@return Recordlength
|
|
|
|
@retval >0 ok
|
|
|
|
@retval MY_FILE_ERROR (== -1) Error.
|
|
|
|
my_errno is set to HA_ERR_WRONG_IN_RECORD
|
|
|
|
*/
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
ulong _ma_rec_unpack(register MARIA_HA *info, register uchar *to, uchar *from,
|
2006-04-11 15:45:10 +02:00
|
|
|
ulong found_length)
|
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
uint flag,bit,length,min_pack_length, column_length;
|
2006-04-11 15:45:10 +02:00
|
|
|
enum en_fieldtype type;
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *from_end,*to_end,*packpos;
|
2007-04-19 12:18:56 +02:00
|
|
|
reg3 MARIA_COLUMNDEF *column, *end_column;
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_ENTER("_ma_rec_unpack");
|
|
|
|
|
|
|
|
to_end=to + info->s->base.reclength;
|
|
|
|
from_end=from+found_length;
|
|
|
|
flag= (uchar) *from; bit=1; packpos=from;
|
|
|
|
if (found_length < info->s->base.min_pack_length)
|
|
|
|
goto err;
|
2007-01-18 20:38:14 +01:00
|
|
|
from+= info->s->base.pack_bytes;
|
|
|
|
min_pack_length= info->s->base.min_pack_length - info->s->base.pack_bytes;
|
|
|
|
|
|
|
|
if ((length= info->s->base.null_bytes))
|
|
|
|
{
|
|
|
|
memcpy(to, from, length);
|
|
|
|
from+= length;
|
|
|
|
to+= length;
|
|
|
|
min_pack_length-= length;
|
|
|
|
}
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-04-19 12:18:56 +02:00
|
|
|
for (column= info->s->columndef, end_column= column + info->s->base.fields;
|
|
|
|
column < end_column ; to+= column_length, column++)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
column_length= column->length;
|
|
|
|
if ((type = (enum en_fieldtype) column->type) != FIELD_NORMAL &&
|
2006-04-11 15:45:10 +02:00
|
|
|
(type != FIELD_CHECK))
|
|
|
|
{
|
|
|
|
if (type == FIELD_VARCHAR)
|
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
uint pack_length= HA_VARCHAR_PACKLENGTH(column_length-1);
|
2006-04-11 15:45:10 +02:00
|
|
|
if (pack_length == 1)
|
|
|
|
{
|
|
|
|
length= (uint) *(uchar*) from;
|
2007-04-19 12:18:56 +02:00
|
|
|
if (length > column_length-1)
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
*to= *from++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
get_key_length(length, from);
|
2007-04-19 12:18:56 +02:00
|
|
|
if (length > column_length-2)
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
int2store(to,length);
|
|
|
|
}
|
|
|
|
if (from+length > from_end)
|
|
|
|
goto err;
|
|
|
|
memcpy(to+pack_length, from, length);
|
|
|
|
from+= length;
|
|
|
|
min_pack_length--;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (flag & bit)
|
|
|
|
{
|
|
|
|
if (type == FIELD_BLOB || type == FIELD_SKIP_ZERO)
|
2009-01-09 05:23:25 +01:00
|
|
|
bzero(to, column_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
else if (type == FIELD_SKIP_ENDSPACE ||
|
|
|
|
type == FIELD_SKIP_PRESPACE)
|
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
if (column->length > 255 && *from & 128)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
if (from + 1 >= from_end)
|
|
|
|
goto err;
|
|
|
|
length= (*from & 127)+ ((uint) (uchar) *(from+1) << 7); from+=2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (from == from_end)
|
|
|
|
goto err;
|
|
|
|
length= (uchar) *from++;
|
|
|
|
}
|
|
|
|
min_pack_length--;
|
2007-04-19 12:18:56 +02:00
|
|
|
if (length >= column_length ||
|
2006-04-11 15:45:10 +02:00
|
|
|
min_pack_length + length > (uint) (from_end - from))
|
|
|
|
goto err;
|
|
|
|
if (type == FIELD_SKIP_ENDSPACE)
|
|
|
|
{
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, from, (size_t) length);
|
|
|
|
bfill(to+length, column_length-length, ' ');
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-01-09 05:23:25 +01:00
|
|
|
bfill(to, column_length-length, ' ');
|
|
|
|
memcpy(to+column_length-length, from, (size_t) length);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
from+=length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == FIELD_BLOB)
|
|
|
|
{
|
2007-04-19 12:18:56 +02:00
|
|
|
uint size_length=column_length- portable_sizeof_char_ptr;
|
2006-04-11 15:45:10 +02:00
|
|
|
ulong blob_length= _ma_calc_blob_length(size_length,from);
|
2007-03-01 18:23:58 +01:00
|
|
|
ulong from_left= (ulong) (from_end - from);
|
|
|
|
if (from_left < size_length ||
|
|
|
|
from_left - size_length < blob_length ||
|
|
|
|
from_left - size_length - blob_length < min_pack_length)
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, from, (size_t) size_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
from+=size_length;
|
2011-04-25 17:22:25 +02:00
|
|
|
memcpy(to+size_length,(uchar*) &from,sizeof(char*));
|
2006-04-11 15:45:10 +02:00
|
|
|
from+=blob_length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE)
|
|
|
|
min_pack_length--;
|
2007-04-19 12:18:56 +02:00
|
|
|
if (min_pack_length + column_length > (uint) (from_end - from))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, from, (size_t) column_length); from+=column_length;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
if ((bit= bit << 1) >= 256)
|
|
|
|
{
|
|
|
|
flag= (uchar) *++packpos; bit=1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (min_pack_length > (uint) (from_end - from))
|
|
|
|
goto err;
|
2007-04-19 12:18:56 +02:00
|
|
|
min_pack_length-=column_length;
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, from, (size_t) column_length);
|
2007-04-19 12:18:56 +02:00
|
|
|
from+=column_length;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (info->s->calc_checksum)
|
2007-01-18 20:38:14 +01:00
|
|
|
info->cur_row.checksum= (uint) (uchar) *from++;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (to == to_end && from == from_end && (bit == 1 || !(flag & ~(bit-1))))
|
|
|
|
DBUG_RETURN(found_length);
|
|
|
|
|
|
|
|
err:
|
2011-01-26 14:29:36 +01:00
|
|
|
_ma_set_fatal_error(info->s, HA_ERR_WRONG_IN_RECORD);
|
2017-09-19 19:45:17 +02:00
|
|
|
DBUG_PRINT("error",("to_end: %p -> %p from_end: %p -> %p",
|
|
|
|
to, to_end, from, from_end));
|
2009-01-09 05:23:25 +01:00
|
|
|
DBUG_DUMP("from", info->rec_buff, info->s->base.min_pack_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(MY_FILE_ERROR);
|
|
|
|
} /* _ma_rec_unpack */
|
|
|
|
|
|
|
|
|
|
|
|
/* Calc length of blob. Update info in blobs->length */
|
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
ulong _ma_calc_total_blob_length(MARIA_HA *info, const uchar *record)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
ulong length;
|
|
|
|
MARIA_BLOB *blob,*end;
|
|
|
|
|
|
|
|
for (length=0, blob= info->blobs, end=blob+info->s->base.blobs ;
|
|
|
|
blob != end;
|
|
|
|
blob++)
|
|
|
|
{
|
2008-01-07 17:54:41 +01:00
|
|
|
blob->length= _ma_calc_blob_length(blob->pack_length,
|
|
|
|
record + blob->offset);
|
2006-04-11 15:45:10 +02:00
|
|
|
length+=blob->length;
|
|
|
|
}
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
ulong _ma_calc_blob_length(uint length, const uchar *pos)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
switch (length) {
|
|
|
|
case 1:
|
|
|
|
return (uint) (uchar) *pos;
|
|
|
|
case 2:
|
|
|
|
return (uint) uint2korr(pos);
|
|
|
|
case 3:
|
|
|
|
return uint3korr(pos);
|
|
|
|
case 4:
|
|
|
|
return uint4korr(pos);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0; /* Impossible */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
void _ma_store_blob_length(uchar *pos,uint pack_length,uint length)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
switch (pack_length) {
|
|
|
|
case 1:
|
|
|
|
*pos= (uchar) length;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
int2store(pos,length);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
int3store(pos,length);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
int4store(pos,length);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-07 17:07:17 +02:00
|
|
|
/*
|
|
|
|
Read record from datafile.
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
_ma_read_dynamic_record()
|
|
|
|
info MARIA_HA pointer to table.
|
|
|
|
filepos From where to read the record.
|
|
|
|
buf Destination for record.
|
|
|
|
|
|
|
|
NOTE
|
|
|
|
If a write buffer is active, it needs to be flushed if its contents
|
|
|
|
intersects with the record to read. We always check if the position
|
2007-07-02 19:45:15 +02:00
|
|
|
of the first uchar of the write buffer is lower than the position
|
|
|
|
past the last uchar to read. In theory this is also true if the write
|
2006-09-07 17:07:17 +02:00
|
|
|
buffer is completely below the read segment. That is, if there is no
|
|
|
|
intersection. But this case is unusual. We flush anyway. Only if the
|
2007-07-02 19:45:15 +02:00
|
|
|
first uchar in the write buffer is above the last uchar to read, we do
|
2006-09-07 17:07:17 +02:00
|
|
|
not flush.
|
|
|
|
|
|
|
|
A dynamic record may need several reads. So this check must be done
|
|
|
|
before every read. Reading a dynamic record starts with reading the
|
|
|
|
block header. If the record does not fit into the free space of the
|
|
|
|
header, the block may be longer than the header. In this case a
|
|
|
|
second read is necessary. These one or two reads repeat for every
|
|
|
|
part of the record.
|
|
|
|
|
|
|
|
RETURN
|
2007-09-09 18:15:10 +02:00
|
|
|
0 OK
|
|
|
|
# Error number
|
2006-09-07 17:07:17 +02:00
|
|
|
*/
|
2007-09-09 18:15:10 +02:00
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
int _ma_read_dynamic_record(MARIA_HA *info, uchar *buf,
|
2007-01-18 20:38:14 +01:00
|
|
|
MARIA_RECORD_POS filepos)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2006-09-07 17:07:17 +02:00
|
|
|
int block_of_record;
|
This patch is a collection of patches from from Sanja, Sergei and Monty.
Added logging and pinning of pages to block format.
Integration of transaction manager, log handler.
Better page cache intergration
Split trnman.h into two files, so that we don't have to include my_atomic.h into C++ programs.
Renaming of structures, more comments, more debugging etc.
Fixed problem with small head block + long varchar.
Added extra argument to delete_record() and update_record() (needed for UNDO logging)
Small changes to interface of pagecache and log handler.
Change initialization of log_record_type_descriptors to not be depending on enum order.
Use array of LEX_STRING's to send data to log handler
Added 'dummy' transaction option to MARIA_INFO so that we can always assume 'trn' exists.
include/lf.h:
Interface fixes
Rename of structures
(Patch from Sergei via Sanja)
include/my_atomic.h:
More comments
include/my_global.h:
Added MY_ERRPTR
include/pagecache.h:
Added undo LSN when unlocking pages
mysql-test/r/maria.result:
Updated results
mysql-test/t/maria.test:
Added autocommit around lock tables
(Patch from Sanja)
mysys/lf_alloc-pin.c:
Post-review fixes, simple optimizations
More comments
Struct slot renames
Check amount of memory on stack
(Patch from Sergei)
mysys/lf_dynarray.c:
More comments
mysys/lf_hash.c:
More comments
After review fixes
(Patch from Sergei)
storage/maria/ha_maria.cc:
Split trnman.h into two files, so that we don't have to include my_atomic.h into the .cc program.
(Temporary fix to avoid bug in gcc)
Move out all deferencing of the transaction structure.
Transaction manager integrated (Patch from Sergei)
storage/maria/ha_maria.h:
Added prototype for start_stmt()
storage/maria/lockman.c:
Function call rename
storage/maria/ma_bitmap.c:
Mark deleted pages free from page cache
storage/maria/ma_blockrec.c:
Offset -> rownr
More debugging
Fixed problem with small head block + long varchar
Added logging of changed pages
Added logging of undo (Including only loggging of changed fields in case of update)
Added pinning/unpinning of all changed pages
More comments
Added free_full_pages() as the same code was used in several places.
fill_rows_parts() renamed as fill_insert_undo_parts()
offset -> rownr
Added some optimization of not transactional tables
_ma_update_block_record() has new parameter, as we need original row to do efficent undo for update
storage/maria/ma_blockrec.h:
Added ROW_EXTENTS_ON_STACK
Changed prototype for update and delete of row
storage/maria/ma_check.c:
Added original row to delete_record() call
storage/maria/ma_control_file.h:
Added ifdefs for C++
storage/maria/ma_delete.c:
Added original row to delete_record() call
(Needed for efficent undo logging)
storage/maria/ma_dynrec.c:
Added extra argument to delete_record() and update_record()
Removed not used variable
storage/maria/ma_init.c:
Initialize log handler
storage/maria/ma_loghandler.c:
Removed not used variable
Change initialization of log_record_type_descriptors to not be depending on enum order
Use array of LEX_STRING's to send data to log handler
storage/maria/ma_loghandler.h:
New defines
Use array of LEX_STRING's to send data to log handler
storage/maria/ma_open.c:
Added 'dummy' transaction option to MARIA_INFO so that we can always assume 'trn' exists.
Store in MARIA_SHARE->page_type if pages will have up to date LSN's
storage/maria/ma_pagecache.c:
Don't decrease number of readers when using pagecache_write()/pagecache_read()
In pagecache_write() decrement request count if page was left pinned
Added pagecache_delete_pages()
Removed some casts
Make trace output consistent with rest of code
Simplify calling of DBUG_ASSERT(0)
Only update LSN if the LSN is bigger than what's already on the page
Added LSN parameter pagecache_unpin_page(), pagecache_unpin(), and pagecache_unlock()
(Part of patch from Sanja)
storage/maria/ma_static.c:
Added 'dummy' transaction option to MARIA_INFO so that we can always assume 'trn' exists.
Added default page cache
storage/maria/ma_statrec.c:
Added extra argument to delete_record() and update_record()
storage/maria/ma_test1.c:
Added option -T for transactions
storage/maria/ma_test2.c:
Added option -T for transactions
storage/maria/ma_test_all.sh:
Test with transactions
storage/maria/ma_update.c:
Changed prototype for update of row
storage/maria/maria_def.h:
Changed prototype for update & delete of row as block records need to access the old row
Store in MARIA_SHARE->page_type if pages will have up to date LSN's
Added MARIA_MAX_TREE_LEVELS to allow us to calculate the number of possible pinned pages we may need.
Removed not used 'empty_bits_buffer'
Added pointer to transaction object
Added array for pinned pages
Added log_row_parts array for logging of field data.
Added MARIA_PINNED_PAGE to store pinned pages
storage/maria/trnman.c:
Added accessor functions to transaction object
Added missing DBUG_RETURN()
More debugging
More comments
Changed // comment of code to #ifdef NOT_USED
Transaction manager integrated.
Post review fixes
Part of patch originally from Sergei
storage/maria/trnman.h:
Split trnman.h into two files, so that we don't have to include my_atomic.h into the .cc program.
(Temporary fix to avoid bug in gcc)
storage/maria/unittest/ma_pagecache_single.c:
Added missing argument
Added SKIP_BIG_TESTS
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
Test logging with new LEX_STRING parameter
(Patch from Sanja)
storage/maria/unittest/trnman-t.c:
Stack overflow detection
(Patch from Sergei)
unittest/unit.pl:
Command-line options --big and --verbose
(Patch from Sergei)
unittest/mytap/tap.c:
Detect --big
(Patch from Sergei)
unittest/mytap/tap.h:
Skip_big_tests and SKIP_BIG_TESTS
(Patch from Sergei)
storage/maria/trnman_public.h:
New BitKeeper file ``storage/maria/trnman_public.h''
2007-05-29 19:13:56 +02:00
|
|
|
uint b_type;
|
2006-04-11 15:45:10 +02:00
|
|
|
MARIA_BLOCK_INFO block_info;
|
|
|
|
File file;
|
2011-10-29 20:40:03 +02:00
|
|
|
uchar *UNINIT_VAR(to);
|
|
|
|
uint UNINIT_VAR(left_length);
|
2007-01-18 20:38:14 +01:00
|
|
|
DBUG_ENTER("_ma_read_dynamic_record");
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-09-09 18:15:10 +02:00
|
|
|
if (filepos == HA_OFFSET_ERROR)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
file= info->dfile.file;
|
|
|
|
block_of_record= 0; /* First block of record is numbered as zero. */
|
|
|
|
block_info.second_read= 0;
|
|
|
|
do
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-09-09 18:15:10 +02:00
|
|
|
/* A corrupted table can have wrong pointers. (Bug# 19835) */
|
|
|
|
if (filepos == HA_OFFSET_ERROR)
|
|
|
|
goto panic;
|
|
|
|
if (info->opt_flag & WRITE_CACHE_USED &&
|
|
|
|
(info->rec_cache.pos_in_file < filepos +
|
|
|
|
MARIA_BLOCK_INFO_HEADER_LENGTH) &&
|
|
|
|
flush_io_cache(&info->rec_cache))
|
|
|
|
goto err;
|
|
|
|
info->rec_cache.seek_not_done=1;
|
2011-01-26 14:29:36 +01:00
|
|
|
if ((b_type= _ma_get_block_info(info, &block_info, file, filepos)) &
|
2007-09-09 18:15:10 +02:00
|
|
|
(BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
|
|
|
|
BLOCK_FATAL_ERROR))
|
|
|
|
{
|
|
|
|
if (b_type & (BLOCK_SYNC_ERROR | BLOCK_DELETED))
|
|
|
|
my_errno=HA_ERR_RECORD_DELETED;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
if (block_of_record++ == 0) /* First block */
|
|
|
|
{
|
2008-04-01 16:57:30 +02:00
|
|
|
info->cur_row.total_length= block_info.rec_len;
|
2007-09-09 18:15:10 +02:00
|
|
|
if (block_info.rec_len > (uint) info->s->base.max_pack_length)
|
2006-09-07 17:07:17 +02:00
|
|
|
goto panic;
|
2007-09-09 18:15:10 +02:00
|
|
|
if (info->s->base.blobs)
|
2006-09-07 17:07:17 +02:00
|
|
|
{
|
2007-09-09 18:15:10 +02:00
|
|
|
if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
|
|
|
|
block_info.rec_len +
|
|
|
|
info->s->base.extra_rec_buff_size))
|
|
|
|
goto err;
|
2006-09-07 17:07:17 +02:00
|
|
|
}
|
2007-09-09 18:15:10 +02:00
|
|
|
to= info->rec_buff;
|
|
|
|
left_length=block_info.rec_len;
|
|
|
|
}
|
|
|
|
if (left_length < block_info.data_len || ! block_info.data_len)
|
|
|
|
goto panic; /* Wrong linked record */
|
|
|
|
/* copy information that is already read */
|
|
|
|
{
|
|
|
|
uint offset= (uint) (block_info.filepos - filepos);
|
|
|
|
uint prefetch_len= (sizeof(block_info.header) - offset);
|
|
|
|
filepos+= sizeof(block_info.header);
|
|
|
|
|
|
|
|
if (prefetch_len > block_info.data_len)
|
|
|
|
prefetch_len= block_info.data_len;
|
|
|
|
if (prefetch_len)
|
2006-09-07 17:07:17 +02:00
|
|
|
{
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, block_info.header + offset, prefetch_len);
|
2007-09-09 18:15:10 +02:00
|
|
|
block_info.data_len-= prefetch_len;
|
|
|
|
left_length-= prefetch_len;
|
|
|
|
to+= prefetch_len;
|
2006-09-07 17:07:17 +02:00
|
|
|
}
|
2007-09-09 18:15:10 +02:00
|
|
|
}
|
|
|
|
/* read rest of record from file */
|
|
|
|
if (block_info.data_len)
|
|
|
|
{
|
|
|
|
if (info->opt_flag & WRITE_CACHE_USED &&
|
|
|
|
info->rec_cache.pos_in_file < filepos + block_info.data_len &&
|
|
|
|
flush_io_cache(&info->rec_cache))
|
|
|
|
goto err;
|
|
|
|
/*
|
|
|
|
What a pity that this method is not called 'file_pread' and that
|
|
|
|
there is no equivalent without seeking. We are at the right
|
|
|
|
position already. :(
|
|
|
|
*/
|
2009-01-09 05:23:25 +01:00
|
|
|
if (info->s->file_read(info, to, block_info.data_len,
|
2007-09-09 18:15:10 +02:00
|
|
|
filepos, MYF(MY_NABP)))
|
|
|
|
goto panic;
|
|
|
|
left_length-=block_info.data_len;
|
|
|
|
to+=block_info.data_len;
|
|
|
|
}
|
|
|
|
filepos= block_info.next_filepos;
|
|
|
|
} while (left_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-09-09 18:15:10 +02:00
|
|
|
info->update|= HA_STATE_AKTIV; /* We have a aktive record */
|
|
|
|
fast_ma_writeinfo(info);
|
|
|
|
DBUG_RETURN(_ma_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
|
|
|
|
MY_FILE_ERROR ? 0 : my_errno);
|
|
|
|
|
|
|
|
err:
|
2006-04-11 15:45:10 +02:00
|
|
|
fast_ma_writeinfo(info);
|
2007-09-09 18:15:10 +02:00
|
|
|
DBUG_RETURN(my_errno);
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
panic:
|
2011-01-26 14:29:36 +01:00
|
|
|
_ma_set_fatal_error(info->s, HA_ERR_WRONG_IN_RECORD);
|
2007-09-09 18:15:10 +02:00
|
|
|
goto err;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* compare unique constraint between stored rows */
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
my_bool _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
|
2007-07-02 19:45:15 +02:00
|
|
|
const uchar *record, MARIA_RECORD_POS pos)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *old_rec_buff,*old_record;
|
2008-01-10 20:21:36 +01:00
|
|
|
size_t old_rec_buff_size;
|
2007-01-18 20:38:14 +01:00
|
|
|
my_bool error;
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_ENTER("_ma_cmp_dynamic_unique");
|
|
|
|
|
2015-08-11 13:03:25 +02:00
|
|
|
if (!(old_record= my_safe_alloca(info->s->base.reclength)))
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(1);
|
|
|
|
|
|
|
|
/* Don't let the compare destroy blobs that may be in use */
|
2007-01-18 20:38:14 +01:00
|
|
|
old_rec_buff= info->rec_buff;
|
|
|
|
old_rec_buff_size= info->rec_buff_size;
|
|
|
|
|
2006-04-11 15:45:10 +02:00
|
|
|
if (info->s->base.blobs)
|
Fixed bug in undo_key_delete; Caused crashed key files in recovery
Maria is now used for internal temporary tables in MySQL
Better usage of VARCHAR and long strings in temporary tables
Use packed fields if BLOCK_RECORD is used
null_bytes are not anymore stored in a separate field
New interface to remember and restore scan position
Fixed bugs in unique handling
Don't sync Maria temporary tables
Lock control file while it's used to stop several processes from using it
Changed value of MA_DONT_OVERWRITE_FILE as it collided with MY_SYNC_DIR
Split MY_DONT_WAIT into MY_NO_WAIT and MY_SHORT_WAIT (for my_lock())
Added MY_FORCE_LOCK
include/my_sys.h:
Changed value of MA_DONT_OVERWRITE_FILE as it collided with MY_SYNC_DIR
Split MY_DONT_WAIT into MY_NO_WAIT and MY_SHORT_WAIT (for my_lock())
Added MY_FORCE_LOCK
include/myisam.h:
Make MyISAM columndef compile time compatible with Maria
mysql-test/lib/mtr_process.pl:
Removed confusing warning (It's common that there is a lot of other files than pid files)
mysql-test/mysql-test-run.pl:
Added --sync-frm to speed up tests
mysql-test/r/maria-recovery.result:
Updated results from wrong push
mysql-test/suite/rpl/t/rpl_innodb_bug28430.test:
Marked test as --big
mysys/my_lock.c:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
mysys/my_thr_init.c:
Fix that we don't give name to thread before it's properly initied
sql/handler.cc:
Added myisam.h
sql/handler.h:
Changes to use Maria for internal temporary tables
Removed not needed argument to restart_rnd_next()
Added function remember_rnd_pos()
sql/my_lock.c:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
sql/mysql_priv.h:
Added maria_hton
sql/sql_class.h:
Changes to use Maria for internal temporary tables
sql/sql_select.cc:
Changes to use Maria for internal temporary tables
Temporary tables didn't properly switch to dynamic row format if long strings was used
Better usage of VARCHAR in temporary tables
Use new interface to restart scan in duplicate removal
sql/sql_select.h:
Changes to use Maria for internal temporary tables
sql/sql_show.cc:
Changes to use Maria for internal temporary tables
Removed all end space
sql/sql_table.cc:
Set HA_OPTION_PACK_RECORD if we are not using default or static record
sql/sql_union.cc:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
sql/sql_update.cc:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
storage/maria/ha_maria.cc:
Use packed fields
null_bytes are not anymore stored in a separate field
Changes to use Maria for internal temporary tables
Give warning if we try to do an ALTER TABLE to a unusable row format
storage/maria/ha_maria.h:
Allow Maria with block format to restart scanning at given position
storage/maria/ma_blockrec.c:
Added functions to remember and restore scan position
Allocate cur_row.extents so that we don't have to do a malloc on first read
Fixed bug when using packed row without packed strings
Removed unneeded calls to free_full_pages()
Fixed unlikely bug when using old bitmap to read head page and head page had gone away
Remember row position when doing undo of delete and update row (needed for undo of key delete)
storage/maria/ma_blockrec.h:
Added functions to remember and restore scan position
storage/maria/ma_close.c:
Don't sync temporary tables
storage/maria/ma_control_file.c:
Lock control file while it's used to stop several processes from using it
storage/maria/ma_create.c:
Fixed bug when using FIELD_NORMAL that was longer than FULL_PAGE_SIZE
Fixed bug that casued fields to not be ordered according to offset
Fixed bug in unique creation
storage/maria/ma_delete.c:
Don't write record reference when deleting key.
(Rowid is likely to be different when we undo this)
storage/maria/ma_dynrec.c:
Fixed core dump when comparing records (happended in unique handling)
storage/maria/ma_extra.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
Removed TODO comment. (Was not relevant as all other instances are guranteed to be closed when we the code is excecuted)
Added DBUG_ASSERT() to prove above.
storage/maria/ma_key_recover.c:
CLR's for UNDO_ROW_DELETE and UNDO_ROW_UPDATE now include rowid for the row.
This was needed for undo_key_delete to work, as undo of delete row is likely to put row in a new position.
undo_delete_key now doesn't include row position
storage/maria/ma_open.c:
Added virtual functions for remembering and restoring scan position
Fixed wrong key search method when using multi-byte character sets (Bug#32705)
Store original column number in index file
NOTE: Index files are now incompatible with previous versions!
(Ok as we haven't yet made a public Maria release)
storage/maria/ma_recovery.c:
Set info->cur_row.lastpos when reading CLR's for UNDO_ROW_DELETE or UNDO_ROW_UPDATE
storage/maria/ma_scan.c:
Added default function to remember and restore scan position
storage/maria/maria_def.h:
Added virtual functions & variables to remember and restore scan position
Added MARIA_MAX_CONTROL_FILE_LOCK_RETRY
storage/myisam/ha_myisam.cc:
Fixed compiler errors as columdef->type is now an enum, not an integer
Added functions to remember and restore scan position
storage/myisam/ha_myisam.h:
Added functions to remember and restore scan position
storage/myisam/mi_check.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/mi_extra.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/mi_open.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/myisamdef.h:
MY_DONT_WAIT -> MY_SHORT_WAIT
2007-12-17 00:17:37 +01:00
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
info->rec_buff= 0;
|
Fixed bug in undo_key_delete; Caused crashed key files in recovery
Maria is now used for internal temporary tables in MySQL
Better usage of VARCHAR and long strings in temporary tables
Use packed fields if BLOCK_RECORD is used
null_bytes are not anymore stored in a separate field
New interface to remember and restore scan position
Fixed bugs in unique handling
Don't sync Maria temporary tables
Lock control file while it's used to stop several processes from using it
Changed value of MA_DONT_OVERWRITE_FILE as it collided with MY_SYNC_DIR
Split MY_DONT_WAIT into MY_NO_WAIT and MY_SHORT_WAIT (for my_lock())
Added MY_FORCE_LOCK
include/my_sys.h:
Changed value of MA_DONT_OVERWRITE_FILE as it collided with MY_SYNC_DIR
Split MY_DONT_WAIT into MY_NO_WAIT and MY_SHORT_WAIT (for my_lock())
Added MY_FORCE_LOCK
include/myisam.h:
Make MyISAM columndef compile time compatible with Maria
mysql-test/lib/mtr_process.pl:
Removed confusing warning (It's common that there is a lot of other files than pid files)
mysql-test/mysql-test-run.pl:
Added --sync-frm to speed up tests
mysql-test/r/maria-recovery.result:
Updated results from wrong push
mysql-test/suite/rpl/t/rpl_innodb_bug28430.test:
Marked test as --big
mysys/my_lock.c:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
mysys/my_thr_init.c:
Fix that we don't give name to thread before it's properly initied
sql/handler.cc:
Added myisam.h
sql/handler.h:
Changes to use Maria for internal temporary tables
Removed not needed argument to restart_rnd_next()
Added function remember_rnd_pos()
sql/my_lock.c:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
sql/mysql_priv.h:
Added maria_hton
sql/sql_class.h:
Changes to use Maria for internal temporary tables
sql/sql_select.cc:
Changes to use Maria for internal temporary tables
Temporary tables didn't properly switch to dynamic row format if long strings was used
Better usage of VARCHAR in temporary tables
Use new interface to restart scan in duplicate removal
sql/sql_select.h:
Changes to use Maria for internal temporary tables
sql/sql_show.cc:
Changes to use Maria for internal temporary tables
Removed all end space
sql/sql_table.cc:
Set HA_OPTION_PACK_RECORD if we are not using default or static record
sql/sql_union.cc:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
sql/sql_update.cc:
If MY_FORCE_LOCK is given, use locking even if my_disable_locking is given
If MY_NO_WAIT is given, return at once if lock is occupied
If MY_SHORT_WAIT is given, wait some time for lock before returning (This was called MY_DONT_WAIT before)
storage/maria/ha_maria.cc:
Use packed fields
null_bytes are not anymore stored in a separate field
Changes to use Maria for internal temporary tables
Give warning if we try to do an ALTER TABLE to a unusable row format
storage/maria/ha_maria.h:
Allow Maria with block format to restart scanning at given position
storage/maria/ma_blockrec.c:
Added functions to remember and restore scan position
Allocate cur_row.extents so that we don't have to do a malloc on first read
Fixed bug when using packed row without packed strings
Removed unneeded calls to free_full_pages()
Fixed unlikely bug when using old bitmap to read head page and head page had gone away
Remember row position when doing undo of delete and update row (needed for undo of key delete)
storage/maria/ma_blockrec.h:
Added functions to remember and restore scan position
storage/maria/ma_close.c:
Don't sync temporary tables
storage/maria/ma_control_file.c:
Lock control file while it's used to stop several processes from using it
storage/maria/ma_create.c:
Fixed bug when using FIELD_NORMAL that was longer than FULL_PAGE_SIZE
Fixed bug that casued fields to not be ordered according to offset
Fixed bug in unique creation
storage/maria/ma_delete.c:
Don't write record reference when deleting key.
(Rowid is likely to be different when we undo this)
storage/maria/ma_dynrec.c:
Fixed core dump when comparing records (happended in unique handling)
storage/maria/ma_extra.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
Removed TODO comment. (Was not relevant as all other instances are guranteed to be closed when we the code is excecuted)
Added DBUG_ASSERT() to prove above.
storage/maria/ma_key_recover.c:
CLR's for UNDO_ROW_DELETE and UNDO_ROW_UPDATE now include rowid for the row.
This was needed for undo_key_delete to work, as undo of delete row is likely to put row in a new position.
undo_delete_key now doesn't include row position
storage/maria/ma_open.c:
Added virtual functions for remembering and restoring scan position
Fixed wrong key search method when using multi-byte character sets (Bug#32705)
Store original column number in index file
NOTE: Index files are now incompatible with previous versions!
(Ok as we haven't yet made a public Maria release)
storage/maria/ma_recovery.c:
Set info->cur_row.lastpos when reading CLR's for UNDO_ROW_DELETE or UNDO_ROW_UPDATE
storage/maria/ma_scan.c:
Added default function to remember and restore scan position
storage/maria/maria_def.h:
Added virtual functions & variables to remember and restore scan position
Added MARIA_MAX_CONTROL_FILE_LOCK_RETRY
storage/myisam/ha_myisam.cc:
Fixed compiler errors as columdef->type is now an enum, not an integer
Added functions to remember and restore scan position
storage/myisam/ha_myisam.h:
Added functions to remember and restore scan position
storage/myisam/mi_check.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/mi_extra.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/mi_open.c:
MY_DONT_WAIT -> MY_SHORT_WAIT
storage/myisam/myisamdef.h:
MY_DONT_WAIT -> MY_SHORT_WAIT
2007-12-17 00:17:37 +01:00
|
|
|
info->rec_buff_size= 0;
|
|
|
|
}
|
2007-01-18 20:38:14 +01:00
|
|
|
error= _ma_read_dynamic_record(info, old_record, pos) != 0;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (!error)
|
2007-01-18 20:38:14 +01:00
|
|
|
error=_ma_unique_comp(def, record, old_record, def->null_are_equal) != 0;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (info->s->base.blobs)
|
|
|
|
{
|
2011-04-25 17:22:25 +02:00
|
|
|
my_free(info->rec_buff);
|
2007-01-18 20:38:14 +01:00
|
|
|
info->rec_buff= old_rec_buff;
|
|
|
|
info->rec_buff_size= old_rec_buff_size;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
2015-08-11 13:03:25 +02:00
|
|
|
my_safe_afree(old_record, info->s->base.reclength);
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_RETURN(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
/* Compare of record on disk with packed record in memory */
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
my_bool _ma_cmp_dynamic_record(register MARIA_HA *info,
|
2007-07-02 19:45:15 +02:00
|
|
|
register const uchar *record)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
uint flag, reclength, b_type,cmp_length;
|
2006-04-11 15:45:10 +02:00
|
|
|
my_off_t filepos;
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *buffer;
|
2006-04-11 15:45:10 +02:00
|
|
|
MARIA_BLOCK_INFO block_info;
|
2007-01-18 20:38:14 +01:00
|
|
|
my_bool error= 1;
|
2015-02-10 11:05:49 +01:00
|
|
|
size_t UNINIT_VAR(buffer_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_ENTER("_ma_cmp_dynamic_record");
|
|
|
|
|
|
|
|
if (info->opt_flag & WRITE_CACHE_USED)
|
|
|
|
{
|
|
|
|
info->update&= ~(HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK);
|
|
|
|
if (flush_io_cache(&info->rec_cache))
|
2007-01-18 20:38:14 +01:00
|
|
|
DBUG_RETURN(1);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
info->rec_cache.seek_not_done=1;
|
|
|
|
|
|
|
|
/* If nobody have touched the database we don't have to test rec */
|
|
|
|
|
|
|
|
buffer=info->rec_buff;
|
|
|
|
if ((info->opt_flag & READ_CHECK_USED))
|
|
|
|
{ /* If check isn't disabled */
|
|
|
|
if (info->s->base.blobs)
|
|
|
|
{
|
2014-03-10 20:14:38 +01:00
|
|
|
buffer_length= (info->s->base.pack_reclength +
|
|
|
|
_ma_calc_total_blob_length(info,record));
|
2015-08-11 13:03:25 +02:00
|
|
|
if (!(buffer=(uchar*) my_safe_alloca(buffer_length)))
|
2007-01-18 20:38:14 +01:00
|
|
|
DBUG_RETURN(1);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
reclength= _ma_rec_pack(info,buffer,record);
|
|
|
|
record= buffer;
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
filepos= info->cur_row.lastpos;
|
2006-04-11 15:45:10 +02:00
|
|
|
flag=block_info.second_read=0;
|
|
|
|
block_info.next_filepos=filepos;
|
|
|
|
while (reclength > 0)
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
if ((b_type= _ma_get_block_info(info, &block_info, info->dfile.file,
|
2006-04-11 15:45:10 +02:00
|
|
|
block_info.next_filepos))
|
|
|
|
& (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
|
|
|
|
BLOCK_FATAL_ERROR))
|
|
|
|
{
|
|
|
|
if (b_type & (BLOCK_SYNC_ERROR | BLOCK_DELETED))
|
|
|
|
my_errno=HA_ERR_RECORD_CHANGED;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
if (flag == 0) /* First block */
|
|
|
|
{
|
|
|
|
flag=1;
|
|
|
|
if (reclength != block_info.rec_len)
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_RECORD_CHANGED;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
} else if (reclength < block_info.data_len)
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
_ma_set_fatal_error(info->s, HA_ERR_WRONG_IN_RECORD);
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2007-01-18 20:38:14 +01:00
|
|
|
reclength-= block_info.data_len;
|
|
|
|
cmp_length= block_info.data_len;
|
|
|
|
if (!reclength && info->s->calc_checksum)
|
|
|
|
cmp_length--; /* 'record' may not contain checksum */
|
|
|
|
|
2007-04-04 22:37:09 +02:00
|
|
|
if (_ma_cmp_buffer(info->dfile.file, record, block_info.filepos,
|
2007-01-18 20:38:14 +01:00
|
|
|
cmp_length))
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
my_errno=HA_ERR_RECORD_CHANGED;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
flag=1;
|
|
|
|
record+=block_info.data_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
my_errno=0;
|
2007-01-18 20:38:14 +01:00
|
|
|
error= 0;
|
2006-04-11 15:45:10 +02:00
|
|
|
err:
|
|
|
|
if (buffer != info->rec_buff)
|
2015-08-11 13:03:25 +02:00
|
|
|
my_safe_afree(buffer, buffer_length);
|
2007-01-18 20:38:14 +01:00
|
|
|
DBUG_PRINT("exit", ("result: %d", error));
|
|
|
|
DBUG_RETURN(error);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Compare file to buffert */
|
|
|
|
|
2007-07-02 19:45:15 +02:00
|
|
|
static my_bool _ma_cmp_buffer(File file, const uchar *buff, my_off_t filepos,
|
2007-01-18 20:38:14 +01:00
|
|
|
uint length)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
uint next_length;
|
2007-10-04 19:33:42 +02:00
|
|
|
uchar temp_buff[IO_SIZE*2];
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_ENTER("_ma_cmp_buffer");
|
|
|
|
|
|
|
|
next_length= IO_SIZE*2 - (uint) (filepos & (IO_SIZE-1));
|
|
|
|
|
|
|
|
while (length > IO_SIZE*2)
|
|
|
|
{
|
2011-07-13 21:10:18 +02:00
|
|
|
if (mysql_file_pread(file,temp_buff,next_length,filepos, MYF(MY_NABP)) ||
|
2007-10-04 19:33:42 +02:00
|
|
|
memcmp(buff, temp_buff, next_length))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
filepos+=next_length;
|
|
|
|
buff+=next_length;
|
|
|
|
length-= next_length;
|
|
|
|
next_length=IO_SIZE*2;
|
|
|
|
}
|
2011-07-13 21:10:18 +02:00
|
|
|
if (mysql_file_pread(file,temp_buff,length,filepos,MYF(MY_NABP)))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
2007-10-04 19:33:42 +02:00
|
|
|
DBUG_RETURN(memcmp(buff, temp_buff, length) != 0);
|
2006-04-11 15:45:10 +02:00
|
|
|
err:
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-07 17:07:17 +02:00
|
|
|
/*
|
2007-04-19 12:18:56 +02:00
|
|
|
Read next record from datafile during table scan.
|
2006-09-07 17:07:17 +02:00
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
_ma_read_rnd_dynamic_record()
|
|
|
|
info MARIA_HA pointer to table.
|
|
|
|
buf Destination for record.
|
|
|
|
filepos From where to read the record.
|
|
|
|
skip_deleted_blocks If to repeat reading until a non-deleted
|
|
|
|
record is found.
|
|
|
|
|
|
|
|
NOTE
|
2007-04-19 12:18:56 +02:00
|
|
|
This is identical to _ma_read_dynamic_record(), except the following
|
|
|
|
cases:
|
2006-09-07 17:07:17 +02:00
|
|
|
|
2007-04-19 12:18:56 +02:00
|
|
|
- If there is no active row at 'filepos', continue scanning for
|
|
|
|
an active row. (This is becasue the previous
|
|
|
|
_ma_read_rnd_dynamic_record() call stored the next block position
|
|
|
|
in filepos, but this position may not be a start block for a row
|
|
|
|
- We may have READ_CACHING enabled, in which case we use the cache
|
|
|
|
to read rows.
|
2006-09-07 17:07:17 +02:00
|
|
|
|
2007-04-19 12:18:56 +02:00
|
|
|
For other comments, check _ma_read_dynamic_record()
|
2006-09-07 17:07:17 +02:00
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 OK
|
2007-09-09 18:15:10 +02:00
|
|
|
!= 0 Error number
|
2006-09-07 17:07:17 +02:00
|
|
|
*/
|
|
|
|
|
2007-01-18 20:38:14 +01:00
|
|
|
int _ma_read_rnd_dynamic_record(MARIA_HA *info,
|
2007-07-02 19:45:15 +02:00
|
|
|
uchar *buf,
|
2007-01-23 20:13:26 +01:00
|
|
|
MARIA_RECORD_POS filepos,
|
2006-04-11 15:45:10 +02:00
|
|
|
my_bool skip_deleted_blocks)
|
|
|
|
{
|
2011-10-18 12:44:12 +02:00
|
|
|
int block_of_record;
|
|
|
|
#ifdef MARIA_EXTERNAL_LOCKING
|
|
|
|
int info_read;
|
|
|
|
#endif
|
2006-04-11 15:45:10 +02:00
|
|
|
uint left_len,b_type;
|
2011-10-29 20:40:03 +02:00
|
|
|
uchar *UNINIT_VAR(to);
|
2006-04-11 15:45:10 +02:00
|
|
|
MARIA_BLOCK_INFO block_info;
|
2007-12-10 01:32:00 +01:00
|
|
|
MARIA_SHARE *share= info->s;
|
2006-04-11 15:45:10 +02:00
|
|
|
DBUG_ENTER("_ma_read_rnd_dynamic_record");
|
|
|
|
|
2011-10-18 12:44:12 +02:00
|
|
|
#ifdef MARIA_EXTERNAL_LOCKING
|
2006-04-11 15:45:10 +02:00
|
|
|
info_read=0;
|
2011-10-18 12:44:12 +02:00
|
|
|
#endif
|
2006-04-11 15:45:10 +02:00
|
|
|
|
|
|
|
if (info->lock_type == F_UNLCK)
|
|
|
|
{
|
|
|
|
#ifndef UNSAFE_LOCKING
|
|
|
|
#else
|
|
|
|
info->tmp_lock_type=F_RDLCK;
|
|
|
|
#endif
|
|
|
|
}
|
2011-10-18 12:44:12 +02:00
|
|
|
#ifdef MARIA_EXTERNAL_LOCKING
|
2006-04-11 15:45:10 +02:00
|
|
|
else
|
|
|
|
info_read=1; /* memory-keyinfoblock is ok */
|
2011-10-18 12:44:12 +02:00
|
|
|
#endif
|
2006-04-11 15:45:10 +02:00
|
|
|
|
2006-09-07 17:07:17 +02:00
|
|
|
block_of_record= 0; /* First block of record is numbered as zero. */
|
|
|
|
block_info.second_read= 0;
|
2006-04-11 15:45:10 +02:00
|
|
|
left_len=1;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (filepos >= info->state->data_file_length)
|
|
|
|
{
|
2011-07-04 03:32:53 +02:00
|
|
|
#ifdef MARIA_EXTERNAL_LOCKING
|
2006-04-11 15:45:10 +02:00
|
|
|
if (!info_read)
|
|
|
|
{ /* Check if changed */
|
|
|
|
info_read=1;
|
|
|
|
info->rec_cache.seek_not_done=1;
|
2007-09-03 11:05:17 +02:00
|
|
|
if (_ma_state_info_read_dsk(share->kfile.file, &share->state))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto panic;
|
|
|
|
}
|
|
|
|
if (filepos >= info->state->data_file_length)
|
|
|
|
{
|
|
|
|
my_errno= HA_ERR_END_OF_FILE;
|
|
|
|
goto err;
|
|
|
|
}
|
2011-07-04 03:32:53 +02:00
|
|
|
#else
|
|
|
|
my_errno= HA_ERR_END_OF_FILE;
|
|
|
|
goto err;
|
|
|
|
#endif
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
if (info->opt_flag & READ_CACHE_USED)
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
if (_ma_read_cache(info, &info->rec_cache, block_info.header, filepos,
|
2006-04-11 15:45:10 +02:00
|
|
|
sizeof(block_info.header),
|
2006-09-07 17:07:17 +02:00
|
|
|
(!block_of_record && skip_deleted_blocks ?
|
|
|
|
READING_NEXT : 0) | READING_HEADER))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto panic;
|
2011-01-26 14:29:36 +01:00
|
|
|
b_type= _ma_get_block_info(info, &block_info,-1,filepos);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (info->opt_flag & WRITE_CACHE_USED &&
|
2006-09-07 17:07:17 +02:00
|
|
|
info->rec_cache.pos_in_file < filepos + MARIA_BLOCK_INFO_HEADER_LENGTH &&
|
2006-04-11 15:45:10 +02:00
|
|
|
flush_io_cache(&info->rec_cache))
|
|
|
|
DBUG_RETURN(my_errno);
|
|
|
|
info->rec_cache.seek_not_done=1;
|
2011-01-26 14:29:36 +01:00
|
|
|
b_type= _ma_get_block_info(info, &block_info, info->dfile.file, filepos);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (b_type & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
|
|
|
|
BLOCK_FATAL_ERROR))
|
|
|
|
{
|
|
|
|
if ((b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
|
|
|
|
&& skip_deleted_blocks)
|
|
|
|
{
|
|
|
|
filepos=block_info.filepos+block_info.block_len;
|
|
|
|
block_info.second_read=0;
|
|
|
|
continue; /* Search after next_record */
|
|
|
|
}
|
|
|
|
if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
|
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
my_errno= HA_ERR_RECORD_DELETED;
|
|
|
|
info->cur_row.lastpos= block_info.filepos;
|
|
|
|
info->cur_row.nextpos= block_info.filepos+block_info.block_len;
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
goto err;
|
|
|
|
}
|
2006-09-07 17:07:17 +02:00
|
|
|
if (block_of_record == 0) /* First block */
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2008-04-01 16:57:30 +02:00
|
|
|
info->cur_row.total_length= block_info.rec_len;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (block_info.rec_len > (uint) share->base.max_pack_length)
|
|
|
|
goto panic;
|
2007-01-18 20:38:14 +01:00
|
|
|
info->cur_row.lastpos= filepos;
|
2006-04-11 15:45:10 +02:00
|
|
|
if (share->base.blobs)
|
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
|
|
|
|
block_info.rec_len +
|
|
|
|
info->s->base.extra_rec_buff_size))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2007-01-18 20:38:14 +01:00
|
|
|
to= info->rec_buff;
|
2006-04-11 15:45:10 +02:00
|
|
|
left_len=block_info.rec_len;
|
|
|
|
}
|
|
|
|
if (left_len < block_info.data_len)
|
|
|
|
goto panic; /* Wrong linked record */
|
|
|
|
|
|
|
|
/* copy information that is already read */
|
|
|
|
{
|
|
|
|
uint offset=(uint) (block_info.filepos - filepos);
|
|
|
|
uint tmp_length= (sizeof(block_info.header) - offset);
|
|
|
|
filepos=block_info.filepos;
|
|
|
|
|
|
|
|
if (tmp_length > block_info.data_len)
|
|
|
|
tmp_length= block_info.data_len;
|
|
|
|
if (tmp_length)
|
|
|
|
{
|
2009-01-09 05:23:25 +01:00
|
|
|
memcpy(to, block_info.header+offset, tmp_length);
|
2006-04-11 15:45:10 +02:00
|
|
|
block_info.data_len-=tmp_length;
|
|
|
|
left_len-=tmp_length;
|
|
|
|
to+=tmp_length;
|
|
|
|
filepos+=tmp_length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* read rest of record from file */
|
|
|
|
if (block_info.data_len)
|
|
|
|
{
|
|
|
|
if (info->opt_flag & READ_CACHE_USED)
|
|
|
|
{
|
2011-01-26 14:29:36 +01:00
|
|
|
if (_ma_read_cache(info, &info->rec_cache, to,filepos,
|
2006-04-11 15:45:10 +02:00
|
|
|
block_info.data_len,
|
2006-09-07 17:07:17 +02:00
|
|
|
(!block_of_record && skip_deleted_blocks) ?
|
|
|
|
READING_NEXT : 0))
|
2006-04-11 15:45:10 +02:00
|
|
|
goto panic;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-09-07 17:07:17 +02:00
|
|
|
if (info->opt_flag & WRITE_CACHE_USED &&
|
|
|
|
info->rec_cache.pos_in_file <
|
|
|
|
block_info.filepos + block_info.data_len &&
|
|
|
|
flush_io_cache(&info->rec_cache))
|
|
|
|
goto err;
|
2007-04-04 22:37:09 +02:00
|
|
|
/* VOID(my_seek(info->dfile.file, filepos, MY_SEEK_SET, MYF(0))); */
|
2011-07-13 21:10:18 +02:00
|
|
|
if (mysql_file_read(info->dfile.file, to, block_info.data_len, MYF(MY_NABP)))
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-12-04 22:23:42 +01:00
|
|
|
if (my_errno == HA_ERR_FILE_TOO_SHORT)
|
2011-01-26 14:29:36 +01:00
|
|
|
{
|
|
|
|
/* Unexpected end of file */
|
|
|
|
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
|
|
|
|
}
|
2006-04-11 15:45:10 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-09-07 17:07:17 +02:00
|
|
|
/*
|
|
|
|
Increment block-of-record counter. If it was the first block,
|
|
|
|
remember the position behind the block for the next call.
|
|
|
|
*/
|
|
|
|
if (block_of_record++ == 0)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
2007-01-18 20:38:14 +01:00
|
|
|
info->cur_row.nextpos= block_info.filepos+block_info.block_len;
|
2006-04-11 15:45:10 +02:00
|
|
|
skip_deleted_blocks=0;
|
|
|
|
}
|
|
|
|
left_len-=block_info.data_len;
|
|
|
|
to+=block_info.data_len;
|
|
|
|
filepos=block_info.next_filepos;
|
|
|
|
} while (left_len);
|
|
|
|
|
|
|
|
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
|
|
|
|
fast_ma_writeinfo(info);
|
|
|
|
if (_ma_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
|
|
|
|
MY_FILE_ERROR)
|
|
|
|
DBUG_RETURN(0);
|
|
|
|
DBUG_RETURN(my_errno); /* Wrong record */
|
|
|
|
|
|
|
|
panic:
|
2011-01-26 14:29:36 +01:00
|
|
|
/* Something is fatal wrong */
|
|
|
|
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
|
2006-04-11 15:45:10 +02:00
|
|
|
err:
|
2007-09-09 18:15:10 +02:00
|
|
|
fast_ma_writeinfo(info);
|
|
|
|
DBUG_RETURN(my_errno);
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Read and process header from a dynamic-record-file */
|
|
|
|
|
2011-01-26 14:29:36 +01:00
|
|
|
uint _ma_get_block_info(MARIA_HA *handler, MARIA_BLOCK_INFO *info, File file,
|
|
|
|
my_off_t filepos)
|
2006-04-11 15:45:10 +02:00
|
|
|
{
|
|
|
|
uint return_val=0;
|
|
|
|
uchar *header=info->header;
|
|
|
|
|
|
|
|
if (file >= 0)
|
|
|
|
{
|
2006-09-07 17:07:17 +02:00
|
|
|
/*
|
|
|
|
We do not use my_pread() here because we want to have the file
|
|
|
|
pointer set to the end of the header after this function.
|
|
|
|
my_pread() may leave the file pointer untouched.
|
|
|
|
*/
|
2011-07-13 21:10:18 +02:00
|
|
|
mysql_file_seek(file,filepos,MY_SEEK_SET,MYF(0));
|
|
|
|
if (mysql_file_read(file, header, sizeof(info->header),MYF(0)) !=
|
2006-04-11 15:45:10 +02:00
|
|
|
sizeof(info->header))
|
2011-01-26 14:29:36 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
This is either an error or just reading at end of file.
|
|
|
|
Don't give a fatal error for this case.
|
|
|
|
*/
|
|
|
|
my_errno= HA_ERR_WRONG_IN_RECORD;
|
|
|
|
return BLOCK_ERROR;
|
|
|
|
}
|
2006-04-11 15:45:10 +02:00
|
|
|
}
|
2007-10-04 19:33:42 +02:00
|
|
|
DBUG_DUMP("header",header,MARIA_BLOCK_INFO_HEADER_LENGTH);
|
2006-04-11 15:45:10 +02:00
|
|
|
if (info->second_read)
|
|
|
|
{
|
|
|
|
if (info->header[0] <= 6 || info->header[0] == 13)
|
|
|
|
return_val=BLOCK_SYNC_ERROR;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (info->header[0] > 6 && info->header[0] != 13)
|
|
|
|
return_val=BLOCK_SYNC_ERROR;
|
|
|
|
}
|
|
|
|
info->next_filepos= HA_OFFSET_ERROR; /* Dummy if no next block */
|
|
|
|
|
|
|
|
switch (info->header[0]) {
|
|
|
|
case 0:
|
|
|
|
if ((info->block_len=(uint) mi_uint3korr(header+1)) <
|
|
|
|
MARIA_MIN_BLOCK_LENGTH ||
|
|
|
|
(info->block_len & (MARIA_DYN_ALIGN_SIZE -1)))
|
|
|
|
goto err;
|
|
|
|
info->filepos=filepos;
|
|
|
|
info->next_filepos=mi_sizekorr(header+4);
|
|
|
|
info->prev_filepos=mi_sizekorr(header+12);
|
|
|
|
#if SIZEOF_OFF_T == 4
|
|
|
|
if ((mi_uint4korr(header+4) != 0 &&
|
|
|
|
(mi_uint4korr(header+4) != (ulong) ~0 ||
|
|
|
|
info->next_filepos != (ulong) ~0)) ||
|
|
|
|
(mi_uint4korr(header+12) != 0 &&
|
|
|
|
(mi_uint4korr(header+12) != (ulong) ~0 ||
|
|
|
|
info->prev_filepos != (ulong) ~0)))
|
|
|
|
goto err;
|
|
|
|
#endif
|
|
|
|
return return_val | BLOCK_DELETED; /* Deleted block */
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
info->rec_len=info->data_len=info->block_len=mi_uint2korr(header+1);
|
|
|
|
info->filepos=filepos+3;
|
|
|
|
return return_val | BLOCK_FIRST | BLOCK_LAST;
|
|
|
|
case 2:
|
|
|
|
info->rec_len=info->data_len=info->block_len=mi_uint3korr(header+1);
|
|
|
|
info->filepos=filepos+4;
|
|
|
|
return return_val | BLOCK_FIRST | BLOCK_LAST;
|
|
|
|
|
|
|
|
case 13:
|
|
|
|
info->rec_len=mi_uint4korr(header+1);
|
|
|
|
info->block_len=info->data_len=mi_uint3korr(header+5);
|
|
|
|
info->next_filepos=mi_sizekorr(header+8);
|
|
|
|
info->second_read=1;
|
|
|
|
info->filepos=filepos+16;
|
|
|
|
return return_val | BLOCK_FIRST;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
info->rec_len=info->data_len=mi_uint2korr(header+1);
|
|
|
|
info->block_len=info->rec_len+ (uint) header[3];
|
|
|
|
info->filepos=filepos+4;
|
|
|
|
return return_val | BLOCK_FIRST | BLOCK_LAST;
|
|
|
|
case 4:
|
|
|
|
info->rec_len=info->data_len=mi_uint3korr(header+1);
|
|
|
|
info->block_len=info->rec_len+ (uint) header[4];
|
|
|
|
info->filepos=filepos+5;
|
|
|
|
return return_val | BLOCK_FIRST | BLOCK_LAST;
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
info->rec_len=mi_uint2korr(header+1);
|
|
|
|
info->block_len=info->data_len=mi_uint2korr(header+3);
|
|
|
|
info->next_filepos=mi_sizekorr(header+5);
|
|
|
|
info->second_read=1;
|
|
|
|
info->filepos=filepos+13;
|
|
|
|
return return_val | BLOCK_FIRST;
|
|
|
|
case 6:
|
|
|
|
info->rec_len=mi_uint3korr(header+1);
|
|
|
|
info->block_len=info->data_len=mi_uint3korr(header+4);
|
|
|
|
info->next_filepos=mi_sizekorr(header+7);
|
|
|
|
info->second_read=1;
|
|
|
|
info->filepos=filepos+15;
|
|
|
|
return return_val | BLOCK_FIRST;
|
|
|
|
|
|
|
|
/* The following blocks are identical to 1-6 without rec_len */
|
|
|
|
case 7:
|
|
|
|
info->data_len=info->block_len=mi_uint2korr(header+1);
|
|
|
|
info->filepos=filepos+3;
|
|
|
|
return return_val | BLOCK_LAST;
|
|
|
|
case 8:
|
|
|
|
info->data_len=info->block_len=mi_uint3korr(header+1);
|
|
|
|
info->filepos=filepos+4;
|
|
|
|
return return_val | BLOCK_LAST;
|
|
|
|
|
|
|
|
case 9:
|
|
|
|
info->data_len=mi_uint2korr(header+1);
|
|
|
|
info->block_len=info->data_len+ (uint) header[3];
|
|
|
|
info->filepos=filepos+4;
|
|
|
|
return return_val | BLOCK_LAST;
|
|
|
|
case 10:
|
|
|
|
info->data_len=mi_uint3korr(header+1);
|
|
|
|
info->block_len=info->data_len+ (uint) header[4];
|
|
|
|
info->filepos=filepos+5;
|
|
|
|
return return_val | BLOCK_LAST;
|
|
|
|
|
|
|
|
case 11:
|
|
|
|
info->data_len=info->block_len=mi_uint2korr(header+1);
|
|
|
|
info->next_filepos=mi_sizekorr(header+3);
|
|
|
|
info->second_read=1;
|
|
|
|
info->filepos=filepos+11;
|
|
|
|
return return_val;
|
|
|
|
case 12:
|
|
|
|
info->data_len=info->block_len=mi_uint3korr(header+1);
|
|
|
|
info->next_filepos=mi_sizekorr(header+4);
|
|
|
|
info->second_read=1;
|
|
|
|
info->filepos=filepos+12;
|
|
|
|
return return_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
err:
|
2011-02-25 13:55:40 +01:00
|
|
|
if (!handler->in_check_table)
|
|
|
|
{
|
|
|
|
/* We may be scanning the table for new rows; Don't give an error */
|
|
|
|
_ma_set_fatal_error(handler->s, HA_ERR_WRONG_IN_RECORD);
|
|
|
|
}
|
2006-04-11 15:45:10 +02:00
|
|
|
return BLOCK_ERROR;
|
|
|
|
}
|