mirror of
https://github.com/MariaDB/server.git
synced 2025-07-01 03:26:54 +03:00
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
This commit is contained in:
@ -519,7 +519,7 @@ enum en_fieldtype {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum data_file_type {
|
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 */
|
/* For key ranges */
|
||||||
|
@ -12550,9 +12550,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
|
|||||||
create_info.data_file_length= ~(ulonglong) 0;
|
create_info.data_file_length= ~(ulonglong) 0;
|
||||||
|
|
||||||
if ((error= maria_create(share->table_name.str,
|
if ((error= maria_create(share->table_name.str,
|
||||||
share->reclength < 64 &&
|
table->no_rows ? NO_RECORD :
|
||||||
!share->blob_fields ? STATIC_RECORD :
|
(share->reclength < 64 &&
|
||||||
BLOCK_RECORD,
|
!share->blob_fields ? STATIC_RECORD :
|
||||||
|
BLOCK_RECORD),
|
||||||
share->keys, &keydef,
|
share->keys, &keydef,
|
||||||
(uint) (*recinfo-start_recinfo),
|
(uint) (*recinfo-start_recinfo),
|
||||||
start_recinfo,
|
start_recinfo,
|
||||||
|
@ -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_search.c ma_page.c ma_key_recover.c ma_key.c \
|
||||||
ma_locking.c ma_state.c \
|
ma_locking.c ma_state.c \
|
||||||
ma_rrnd.c ma_scan.c ma_cache.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_blockrec.c ma_bitmap.c \
|
||||||
ma_update.c ma_write.c ma_unique.c \
|
ma_update.c ma_write.c ma_unique.c \
|
||||||
ma_delete.c \
|
ma_delete.c \
|
||||||
|
@ -993,10 +993,12 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
}
|
}
|
||||||
if ((share->data_file_type != BLOCK_RECORD &&
|
if ((share->data_file_type != BLOCK_RECORD &&
|
||||||
|
share->data_file_type != NO_RECORD &&
|
||||||
record >= share->state.state.data_file_length) ||
|
record >= share->state.state.data_file_length) ||
|
||||||
(share->data_file_type == BLOCK_RECORD &&
|
(share->data_file_type == BLOCK_RECORD &&
|
||||||
ma_recordpos_to_page(record) * share->base.min_block_length >=
|
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
|
#ifndef DBUG_OFF
|
||||||
char llbuff2[22], llbuff3[22];
|
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:
|
case COMPRESSED_RECORD:
|
||||||
error= check_compressed_record(param, info, extend, record);
|
error= check_compressed_record(param, info, extend, record);
|
||||||
break;
|
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 */
|
} /* switch */
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
@ -2277,7 +2285,14 @@ static int initialize_variables_for_repair(HA_CHECK *param,
|
|||||||
{
|
{
|
||||||
MARIA_SHARE *share= info->s;
|
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));
|
memcpy(org_share, share, sizeof(*share));
|
||||||
|
|
||||||
/* Repair code relies on share->state.state so we have to update it here */
|
/* 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);
|
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;
|
sort_param->filepos+=reclength+length;
|
||||||
share->state.split++;
|
share->state.split++;
|
||||||
break;
|
break;
|
||||||
|
case NO_RECORD:
|
||||||
|
DBUG_RETURN(1); /* Impossible */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sort_param->master)
|
if (sort_param->master)
|
||||||
|
@ -250,10 +250,16 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
datafile_type= BLOCK_RECORD;
|
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)
|
if (datafile_type == DYNAMIC_RECORD)
|
||||||
options|= HA_OPTION_PACK_RECORD; /* Must use packed records */
|
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 */
|
/* We can't use checksum with static length rows */
|
||||||
flags&= ~HA_CREATE_CHECKSUM;
|
flags&= ~HA_CREATE_CHECKSUM;
|
||||||
@ -366,7 +372,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
}
|
}
|
||||||
else
|
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,
|
pointer= maria_get_pointer_length(ci->data_file_length,
|
||||||
maria_data_pointer_size);
|
maria_data_pointer_size);
|
||||||
else
|
else
|
||||||
|
66
storage/maria/ma_norec.c
Normal file
66
storage/maria/ma_norec.c
Normal file
@ -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;
|
||||||
|
}
|
@ -1076,6 +1076,20 @@ void _ma_setup_functions(register MARIA_SHARE *share)
|
|||||||
else
|
else
|
||||||
share->calc_checksum= _ma_checksum;
|
share->calc_checksum= _ma_checksum;
|
||||||
break;
|
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:
|
case BLOCK_RECORD:
|
||||||
share->once_init= _ma_once_init_block_record;
|
share->once_init= _ma_once_init_block_record;
|
||||||
share->once_end= _ma_once_end_block_record;
|
share->once_end= _ma_once_end_block_record;
|
||||||
|
@ -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 4: pos= (my_off_t) mi_uint4korr(after_key); break;
|
||||||
case 3: pos= (my_off_t) mi_uint3korr(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 2: pos= (my_off_t) mi_uint2korr(after_key); break;
|
||||||
|
case 0: /* NO_RECORD */
|
||||||
default:
|
default:
|
||||||
pos=0L; /* Shut compiler up */
|
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 4: mi_int4store(buff,pos); break;
|
||||||
case 3: mi_int3store(buff,pos); break;
|
case 3: mi_int3store(buff,pos); break;
|
||||||
case 2: mi_int2store(buff,(uint) pos); break;
|
case 2: mi_int2store(buff,(uint) pos); break;
|
||||||
|
case 0: break; /* For NO_RECORD */
|
||||||
default: abort(); /* Impossible */
|
default: abort(); /* Impossible */
|
||||||
}
|
}
|
||||||
} /* _ma_dpointer */
|
} /* _ma_dpointer */
|
||||||
|
@ -409,6 +409,10 @@ static int run_test(const char *filename)
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
printf("- Reading rows with key\n");
|
printf("- Reading rows with key\n");
|
||||||
record[1]= 0; /* For nicer printf */
|
record[1]= 0; /* For nicer printf */
|
||||||
|
|
||||||
|
if (record_type == NO_RECORD)
|
||||||
|
maria_extra(file, HA_EXTRA_KEYREAD, 0);
|
||||||
|
|
||||||
for (i=0 ; i <= 25 ; i++)
|
for (i=0 ; i <= 25 ; i++)
|
||||||
{
|
{
|
||||||
create_key(key,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);
|
(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)
|
if (!silent)
|
||||||
printf("- Reading rows with position\n");
|
printf("- Reading rows with position\n");
|
||||||
|
|
||||||
if (maria_scan_init(file))
|
if (maria_scan_init(file))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "maria_scan_init failed\n");
|
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},
|
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"rows-in-block", 'M', "Store rows in block format",
|
{"rows-in-block", 'M', "Store rows in block format",
|
||||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
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,
|
{"row-pointer-size", 'R', "Undocumented", (uchar**) &rec_pointer_size,
|
||||||
(uchar**) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
(uchar**) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"silent", 's', "Undocumented",
|
{"silent", 's', "Undocumented",
|
||||||
@ -816,6 +828,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
case 'M':
|
case 'M':
|
||||||
record_type= BLOCK_RECORD;
|
record_type= BLOCK_RECORD;
|
||||||
break;
|
break;
|
||||||
|
case 'n':
|
||||||
|
record_type= NO_RECORD;
|
||||||
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
if (key_field == FIELD_VARCHAR)
|
if (key_field == FIELD_VARCHAR)
|
||||||
{
|
{
|
||||||
@ -887,6 +902,10 @@ static void get_options(int argc, char *argv[])
|
|||||||
exit(ho_error);
|
exit(ho_error);
|
||||||
if (transactional)
|
if (transactional)
|
||||||
record_type= BLOCK_RECORD;
|
record_type= BLOCK_RECORD;
|
||||||
|
if (record_type == NO_RECORD)
|
||||||
|
skip_update= skip_delete= 1;
|
||||||
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} /* get options */
|
} /* get options */
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ static const char *field_pack[]=
|
|||||||
|
|
||||||
static const char *record_formats[]=
|
static const char *record_formats[]=
|
||||||
{
|
{
|
||||||
"Fixed length", "Packed", "Compressed", "Block", "?"
|
"Fixed length", "Packed", "Compressed", "Block", "No data", "?", "?"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *bitmap_description[]=
|
static const char *bitmap_description[]=
|
||||||
|
@ -871,6 +871,18 @@ extern my_bool _ma_update_static_record(MARIA_HA *, MARIA_RECORD_POS,
|
|||||||
const uchar *, const uchar *);
|
const uchar *, const uchar *);
|
||||||
extern my_bool _ma_delete_static_record(MARIA_HA *info, const uchar *record);
|
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_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_ck_write(MARIA_HA *info, MARIA_KEY *key);
|
||||||
extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key,
|
extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key,
|
||||||
MARIA_RECORD_POS *root);
|
MARIA_RECORD_POS *root);
|
||||||
|
@ -250,6 +250,7 @@ sub run_check_tests
|
|||||||
["-p -B --key_length=480","-sm"],
|
["-p -B --key_length=480","-sm"],
|
||||||
["--checksum --unique","-se"],
|
["--checksum --unique","-se"],
|
||||||
["--unique","-se"],
|
["--unique","-se"],
|
||||||
|
["--rows-no-data", "-s"],
|
||||||
["--key_multiple -N -S","-sm"],
|
["--key_multiple -N -S","-sm"],
|
||||||
["--key_multiple -a -p --key_length=480","-sm"],
|
["--key_multiple -a -p --key_length=480","-sm"],
|
||||||
["--key_multiple -a -B --key_length=480","-sm"],
|
["--key_multiple -a -B --key_length=480","-sm"],
|
||||||
|
Reference in New Issue
Block a user