diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-01-14 11:54:39 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-01-14 11:54:39 +0100 |
commit | f5ea301acc593b51b13303899246a38efff92c1a (patch) | |
tree | b85595f5ed66cbb43d12be94f66dc49e3a35d561 | |
parent | 17c188779b2c3d5abafe233a31df32a1a6f20c54 (diff) | |
download | mariadb-git-f5ea301acc593b51b13303899246a38efff92c1a.tar.gz |
Added support for NO_RECORD record format (don't store any row data) for Aria.
This makes the keys smaller (no row pointer) and gives us proper errors if we
use the table wrongly.
sql/sql_select.cc:
Use NO_RECORD for tables that doesn't need row data.
storage/maria/Makefile.am:
Added ma_norec.c
storage/maria/ma_check.c:
Added support for NO_RECORD record format (don't store any row data)
storage/maria/ma_norec.c:
Added support for NO_RECORD record format
storage/maria/ma_open.c:
Added support for NO_RECORD record format
storage/maria/ma_search.c:
Added support for 0 size row pointers (used with NO_RECORD)
storage/maria/ma_test1.c:
Added testing of NO_RECORD record format.
storage/maria/maria_chk.c:
Added support for NO_RECORD
storage/maria/maria_def.h:
Added support for NO_RECORD
storage/maria/unittest/ma_test_all-t:
Added testing of NO_RECORD record format
-rw-r--r-- | include/my_base.h | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 7 | ||||
-rw-r--r-- | storage/maria/Makefile.am | 2 | ||||
-rw-r--r-- | storage/maria/ma_check.c | 25 | ||||
-rw-r--r-- | storage/maria/ma_create.c | 12 | ||||
-rw-r--r-- | storage/maria/ma_norec.c | 66 | ||||
-rw-r--r-- | storage/maria/ma_open.c | 14 | ||||
-rw-r--r-- | storage/maria/ma_search.c | 2 | ||||
-rw-r--r-- | storage/maria/ma_test1.c | 19 | ||||
-rw-r--r-- | storage/maria/maria_chk.c | 2 | ||||
-rw-r--r-- | storage/maria/maria_def.h | 12 | ||||
-rwxr-xr-x | storage/maria/unittest/ma_test_all-t | 1 |
12 files changed, 153 insertions, 11 deletions
diff --git a/include/my_base.h b/include/my_base.h index 8e6436bde70..8f50120a970 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -519,7 +519,7 @@ enum en_fieldtype { }; enum data_file_type { - STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD + STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD, NO_RECORD }; /* For key ranges */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d57cc28254f..b047a33a61b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12550,9 +12550,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, create_info.data_file_length= ~(ulonglong) 0; if ((error= maria_create(share->table_name.str, - share->reclength < 64 && - !share->blob_fields ? STATIC_RECORD : - BLOCK_RECORD, + table->no_rows ? NO_RECORD : + (share->reclength < 64 && + !share->blob_fields ? STATIC_RECORD : + BLOCK_RECORD), share->keys, &keydef, (uint) (*recinfo-start_recinfo), start_recinfo, diff --git a/storage/maria/Makefile.am b/storage/maria/Makefile.am index c2bb61e77dd..3c94ffc29ec 100644 --- a/storage/maria/Makefile.am +++ b/storage/maria/Makefile.am @@ -124,7 +124,7 @@ libaria_la_SOURCES = ma_init.c ma_open.c ma_extra.c ma_info.c ma_rkey.c \ ma_search.c ma_page.c ma_key_recover.c ma_key.c \ ma_locking.c ma_state.c \ ma_rrnd.c ma_scan.c ma_cache.c \ - ma_statrec.c ma_packrec.c ma_dynrec.c \ + ma_statrec.c ma_packrec.c ma_dynrec.c ma_norec.c \ ma_blockrec.c ma_bitmap.c \ ma_update.c ma_write.c ma_unique.c \ ma_delete.c \ diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 35dbc7f04d0..b7bca730051 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -993,10 +993,12 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo, /* fall through */ } if ((share->data_file_type != BLOCK_RECORD && + share->data_file_type != NO_RECORD && record >= share->state.state.data_file_length) || (share->data_file_type == BLOCK_RECORD && ma_recordpos_to_page(record) * share->base.min_block_length >= - share->state.state.data_file_length)) + share->state.state.data_file_length) || + (share->data_file_type == NO_RECORD && record != 0)) { #ifndef DBUG_OFF char llbuff2[22], llbuff3[22]; @@ -2047,6 +2049,12 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend) case COMPRESSED_RECORD: error= check_compressed_record(param, info, extend, record); break; + case NO_RECORD: + param->records= share->state.state.records; + param->record_checksum= 0; + extend= 1; /* No row checksums */ + /* no data, nothing to do */ + break; } /* switch */ if (error) @@ -2277,7 +2285,14 @@ static int initialize_variables_for_repair(HA_CHECK *param, { MARIA_SHARE *share= info->s; - /* Ro allow us to restore state and check how state changed */ + if (share->data_file_type == NO_RECORD) + { + _ma_check_print_error(param, + "Can't repair tables with record type NO_DATA"); + return 1; + } + + /* Allow us to restore state and check how state changed */ memcpy(org_share, share, sizeof(*share)); /* Repair code relies on share->state.state so we have to update it here */ @@ -5184,8 +5199,10 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) } DBUG_RETURN(0); } + case NO_RECORD: + DBUG_RETURN(1); /* Impossible */ } - DBUG_RETURN(1); /* Impossible */ + DBUG_RETURN(1); /* Impossible */ } @@ -5305,6 +5322,8 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param) sort_param->filepos+=reclength+length; share->state.split++; break; + case NO_RECORD: + DBUG_RETURN(1); /* Impossible */ } } if (sort_param->master) diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index 9cf042ed21e..0a74cad6a37 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -250,10 +250,16 @@ int maria_create(const char *name, enum data_file_type datafile_type, datafile_type= BLOCK_RECORD; } + if (datafile_type == NO_RECORD && uniques) + { + /* Can't do unique without data, revert to block records */ + datafile_type= BLOCK_RECORD; + } + if (datafile_type == DYNAMIC_RECORD) options|= HA_OPTION_PACK_RECORD; /* Must use packed records */ - if (datafile_type == STATIC_RECORD) + if (datafile_type == STATIC_RECORD || datafile_type == NO_RECORD) { /* We can't use checksum with static length rows */ flags&= ~HA_CREATE_CHECKSUM; @@ -366,7 +372,9 @@ int maria_create(const char *name, enum data_file_type datafile_type, } else { - if (datafile_type != STATIC_RECORD) + if (datafile_type == NO_RECORD) + pointer= 0; + else if (datafile_type != STATIC_RECORD) pointer= maria_get_pointer_length(ci->data_file_length, maria_data_pointer_size); else diff --git a/storage/maria/ma_norec.c b/storage/maria/ma_norec.c new file mode 100644 index 00000000000..6d4f37e34fd --- /dev/null +++ b/storage/maria/ma_norec.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2010 Monty Program Ab + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Functions to handle tables with no row data (only index) + This is useful when you just want to do key reads or want to use + the index to check against duplicates. +*/ + +#include "maria_def.h" + +my_bool _ma_write_no_record(MARIA_HA *info __attribute__((unused)), + const uchar *record __attribute__((unused))) +{ + return 0; +} + +my_bool _ma_update_no_record(MARIA_HA *info __attribute__((unused)), + MARIA_RECORD_POS pos __attribute__((unused)), + const uchar *oldrec __attribute__((unused)), + const uchar *record __attribute__((unused))) +{ + return HA_ERR_WRONG_COMMAND; +} + + +my_bool _ma_delete_no_record(MARIA_HA *info __attribute__((unused)), + const uchar *record __attribute__((unused))) +{ + return HA_ERR_WRONG_COMMAND; +} + + +int _ma_read_no_record(MARIA_HA *info __attribute__((unused)), + uchar *record __attribute__((unused)), + MARIA_RECORD_POS pos __attribute__((unused))) +{ + return HA_ERR_WRONG_COMMAND; +} + + +int _ma_read_rnd_no_record(MARIA_HA *info __attribute__((unused)), + uchar *buf __attribute__((unused)), + MARIA_RECORD_POS filepos __attribute__((unused)), + my_bool skip_deleted_blocks __attribute__((unused))) +{ + return HA_ERR_WRONG_COMMAND; +} + +my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share __attribute__ ((unused)), + my_off_t pos __attribute__ ((unused))) +{ + return 0; +} diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index ae3a3918eee..95df7378f05 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -1076,6 +1076,20 @@ void _ma_setup_functions(register MARIA_SHARE *share) else share->calc_checksum= _ma_checksum; break; + case NO_RECORD: + share->read_record= _ma_read_no_record; + share->scan= _ma_read_rnd_no_record; + share->delete_record= _ma_delete_no_record; + share->update_record= _ma_update_no_record; + share->write_record= _ma_write_no_record; + share->recpos_to_keypos= _ma_no_keypos_to_recpos; + share->keypos_to_recpos= _ma_no_keypos_to_recpos; + + /* Abort if following functions are called */ + share->compare_record= 0; + share->compare_unique= 0; + share->calc_checksum= 0; + break; case BLOCK_RECORD: share->once_init= _ma_once_init_block_record; share->once_end= _ma_once_end_block_record; diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c index 9f1e8e2554b..8d3b5721336 100644 --- a/storage/maria/ma_search.c +++ b/storage/maria/ma_search.c @@ -785,6 +785,7 @@ MARIA_RECORD_POS _ma_row_pos_from_key(const MARIA_KEY *key) case 4: pos= (my_off_t) mi_uint4korr(after_key); break; case 3: pos= (my_off_t) mi_uint3korr(after_key); break; case 2: pos= (my_off_t) mi_uint2korr(after_key); break; + case 0: /* NO_RECORD */ default: pos=0L; /* Shut compiler up */ } @@ -894,6 +895,7 @@ void _ma_dpointer(MARIA_SHARE *share, uchar *buff, my_off_t pos) case 4: mi_int4store(buff,pos); break; case 3: mi_int3store(buff,pos); break; case 2: mi_int2store(buff,(uint) pos); break; + case 0: break; /* For NO_RECORD */ default: abort(); /* Impossible */ } } /* _ma_dpointer */ diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c index affa3a71634..1df1e6fd19b 100644 --- a/storage/maria/ma_test1.c +++ b/storage/maria/ma_test1.c @@ -409,6 +409,10 @@ static int run_test(const char *filename) if (!silent) printf("- Reading rows with key\n"); record[1]= 0; /* For nicer printf */ + + if (record_type == NO_RECORD) + maria_extra(file, HA_EXTRA_KEYREAD, 0); + for (i=0 ; i <= 25 ; i++) { create_key(key,i); @@ -422,9 +426,15 @@ static int run_test(const char *filename) (int) key_length,key+offset_to_key,error,my_errno,record+1); } } + if (record_type == NO_RECORD) + { + maria_extra(file, HA_EXTRA_NO_KEYREAD, 0); + goto end; + } if (!silent) printf("- Reading rows with position\n"); + if (maria_scan_init(file)) { fprintf(stderr, "maria_scan_init failed\n"); @@ -757,6 +767,8 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"rows-in-block", 'M', "Store rows in block format", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"rows-no-data", 'n', "Don't store any data, only keys", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"row-pointer-size", 'R', "Undocumented", (uchar**) &rec_pointer_size, (uchar**) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"silent", 's', "Undocumented", @@ -816,6 +828,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'M': record_type= BLOCK_RECORD; break; + case 'n': + record_type= NO_RECORD; + break; case 'S': if (key_field == FIELD_VARCHAR) { @@ -887,6 +902,10 @@ static void get_options(int argc, char *argv[]) exit(ho_error); if (transactional) record_type= BLOCK_RECORD; + if (record_type == NO_RECORD) + skip_update= skip_delete= 1; + + return; } /* get options */ diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index 2b280a1eff3..07ec9d6cd39 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -68,7 +68,7 @@ static const char *field_pack[]= static const char *record_formats[]= { - "Fixed length", "Packed", "Compressed", "Block", "?" + "Fixed length", "Packed", "Compressed", "Block", "No data", "?", "?" }; static const char *bitmap_description[]= diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index d187b5f7e02..598023034af 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -871,6 +871,18 @@ extern my_bool _ma_update_static_record(MARIA_HA *, MARIA_RECORD_POS, const uchar *, const uchar *); extern my_bool _ma_delete_static_record(MARIA_HA *info, const uchar *record); extern my_bool _ma_cmp_static_record(MARIA_HA *info, const uchar *record); + +extern my_bool _ma_write_no_record(MARIA_HA *info, const uchar *record); +extern my_bool _ma_update_no_record(MARIA_HA *info, MARIA_RECORD_POS pos, + const uchar *oldrec, const uchar *record); +extern my_bool _ma_delete_no_record(MARIA_HA *info, const uchar *record); +extern int _ma_read_no_record(MARIA_HA *info, uchar *record, + MARIA_RECORD_POS pos); +extern int _ma_read_rnd_no_record(MARIA_HA *info, uchar *buf, + MARIA_RECORD_POS filepos, + my_bool skip_deleted_blocks); +my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share, my_off_t pos); + extern my_bool _ma_ck_write(MARIA_HA *info, MARIA_KEY *key); extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key, MARIA_RECORD_POS *root); diff --git a/storage/maria/unittest/ma_test_all-t b/storage/maria/unittest/ma_test_all-t index 0b11daf7f98..5ba730afc95 100755 --- a/storage/maria/unittest/ma_test_all-t +++ b/storage/maria/unittest/ma_test_all-t @@ -250,6 +250,7 @@ sub run_check_tests ["-p -B --key_length=480","-sm"], ["--checksum --unique","-se"], ["--unique","-se"], + ["--rows-no-data", "-s"], ["--key_multiple -N -S","-sm"], ["--key_multiple -a -p --key_length=480","-sm"], ["--key_multiple -a -B --key_length=480","-sm"], |