summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-01-14 11:54:39 +0100
committerSergei Golubchik <sergii@pisem.net>2011-01-14 11:54:39 +0100
commitf5ea301acc593b51b13303899246a38efff92c1a (patch)
treeb85595f5ed66cbb43d12be94f66dc49e3a35d561
parent17c188779b2c3d5abafe233a31df32a1a6f20c54 (diff)
downloadmariadb-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.h2
-rw-r--r--sql/sql_select.cc7
-rw-r--r--storage/maria/Makefile.am2
-rw-r--r--storage/maria/ma_check.c25
-rw-r--r--storage/maria/ma_create.c12
-rw-r--r--storage/maria/ma_norec.c66
-rw-r--r--storage/maria/ma_open.c14
-rw-r--r--storage/maria/ma_search.c2
-rw-r--r--storage/maria/ma_test1.c19
-rw-r--r--storage/maria/maria_chk.c2
-rw-r--r--storage/maria/maria_def.h12
-rwxr-xr-xstorage/maria/unittest/ma_test_all-t1
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"],