Commit 0b842a55 authored by unknown's avatar unknown

Merge anna@bk-internal.mysql.com:/home/bk/mysql-5.0

into arthur.local:/my/mysql-5.0-clean
parents 975dafc1 fcaa0217
......@@ -96,6 +96,7 @@ joerg@mysql.com
joreland@mysql.com
jorge@linux.jorge.mysql.com
jplindst@t41.(none)
kaa@polly.local
kaj@work.mysql.com
kent@mysql.com
konstantin@mysql.com
......
dnl ---------------------------------------------------------------------------
dnl Macro: MYSQL_CHECK_FEDERATED
dnl Sets HAVE_FEDERATED if --with-federated-storage-engine is used
dnl ---------------------------------------------------------------------------
AC_DEFUN([MYSQL_CHECK_FEDERATED], [
AC_ARG_WITH([federated-storage-engine],
[
--with-federated-storage-engine
Enable the MySQL Storage Engine],
[federateddb="$withval"],
[federateddb=no])
AC_MSG_CHECKING([for MySQL federated storage engine])
case "$federateddb" in
yes )
AC_DEFINE([HAVE_FEDERATED_DB], [1], [Define to enable Federated Handler])
AC_MSG_RESULT([yes])
[federateddb=yes]
;;
* )
AC_MSG_RESULT([no])
[federateddb=no]
;;
esac
])
dnl ---------------------------------------------------------------------------
dnl END OF MYSQL_CHECK_FEDERATED SECTION
dnl ---------------------------------------------------------------------------
......@@ -38,6 +38,7 @@ sinclude(config/ac-macros/compiler_flag.m4)
sinclude(config/ac-macros/ha_archive.m4)
sinclude(config/ac-macros/ha_berkeley.m4)
sinclude(config/ac-macros/ha_example.m4)
sinclude(config/ac-macros/ha_federated.m4)
sinclude(config/ac-macros/ha_innodb.m4)
sinclude(config/ac-macros/ha_isam.m4)
sinclude(config/ac-macros/ha_ndbcluster.m4)
......@@ -748,7 +749,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
sys/ioctl.h malloc.h sys/malloc.h linux/config.h)
sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h)
#--------------------------------------------------------------------
# Check for system libraries. Adds the library to $LIBS
......@@ -775,6 +776,22 @@ AC_CHECK_FUNC(crypt, AC_DEFINE([HAVE_CRYPT], [1], [crypt]))
AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init))
MYSQL_CHECK_ZLIB_WITH_COMPRESS
# For large pages support
if test "$IS_LINUX" = "true"
then
# For SHM_HUGETLB on Linux
AC_CHECK_DECLS(SHM_HUGETLB,
AC_DEFINE([HAVE_LARGE_PAGES], [1],
[Define if you have large pages support])
AC_DEFINE([HUGETLB_USE_PROC_MEMINFO], [1],
[Define if /proc/meminfo shows the huge page size (Linux only)])
, ,
[
#include <sys/shm.h>
]
)
fi
#--------------------------------------------------------------------
# Check for TCP wrapper support
#--------------------------------------------------------------------
......@@ -2420,6 +2437,7 @@ MYSQL_CHECK_EXAMPLEDB
MYSQL_CHECK_ARCHIVEDB
MYSQL_CHECK_CSVDB
MYSQL_CHECK_NDBCLUSTER
MYSQL_CHECK_FEDERATED
# If we have threads generate some library functions and test programs
sql_server_dirs=
......
......@@ -85,7 +85,7 @@ enum my_lex_states
{
MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT,
MY_LEX_IDENT_SEP, MY_LEX_IDENT_START,
MY_LEX_REAL, MY_LEX_HEX_NUMBER,
MY_LEX_REAL, MY_LEX_HEX_NUMBER, MY_LEX_BIN_NUMBER,
MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END,
MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL,
MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE,
......
......@@ -182,7 +182,8 @@ enum ha_base_keytype {
HA_KEYTYPE_UINT24=13,
HA_KEYTYPE_INT8=14,
HA_KEYTYPE_VARTEXT=15, /* Key is sorted as letters */
HA_KEYTYPE_VARBINARY=16 /* Key is sorted as unsigned chars */
HA_KEYTYPE_VARBINARY=16, /* Key is sorted as unsigned chars */
HA_KEYTYPE_BIT=17
};
#define HA_MAX_KEYTYPE 31 /* Must be log2-1 */
......
......@@ -34,6 +34,8 @@ typedef struct st_HA_KEYSEG /* Key-portion */
uint32 start; /* Start of key in record */
uint32 null_pos; /* position to NULL indicator */
CHARSET_INFO *charset;
uint8 bit_length; /* Length of bit part */
uint16 bit_pos; /* Position to bit part */
} HA_KEYSEG;
#define get_key_length(length,key) \
......@@ -64,6 +66,21 @@ typedef struct st_HA_KEYSEG /* Key-portion */
{ *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \
}
#define get_rec_bits(bit_ptr, bit_ofs, bit_len) \
(((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \
((1 << (bit_len)) - 1))
#define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \
{ \
(bit_ptr)[0]= ((bit_ptr)[0] & ((1 << (bit_ofs)) - 1)) | \
((bits) << (bit_ofs)); \
if ((bit_ofs) + (bit_len) > 8) \
(bit_ptr)[1]= ((bits) & ((1 << (bit_len)) - 1)) >> (8 - (bit_ofs)); \
}
#define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \
set_rec_bits(0, bit_ptr, bit_ofs, bit_len)
extern int mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
my_bool, my_bool);
extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
......
......@@ -168,6 +168,16 @@ extern char *my_strdup_with_length(const byte *from, uint length,
#define TRASH(A,B) /* nothing */
#endif
#ifdef HAVE_LARGE_PAGES
extern uint my_get_large_page_size(void);
extern gptr my_large_malloc(uint size, myf my_flags);
extern void my_large_free(gptr ptr, myf my_flags);
#else
#define my_get_large_page_size() (0)
#define my_large_malloc(A,B) my_malloc_lock((A),(B))
#define my_large_free(A,B) my_free_lock((A),(B))
#endif /* HAVE_LARGE_PAGES */
#ifdef HAVE_ALLOCA
#if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43)
#pragma alloca
......@@ -213,6 +223,11 @@ extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
myf MyFlags);
extern uint my_file_limit;
#ifdef HAVE_LARGE_PAGES
extern my_bool my_use_large_pages;
extern uint my_large_page_size;
#endif
/* charsets */
extern CHARSET_INFO *default_charset_info;
extern CHARSET_INFO *all_charsets[256];
......
......@@ -210,6 +210,7 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
MYSQL_TYPE_BIT,
MYSQL_TYPE_ENUM=247,
MYSQL_TYPE_SET=248,
MYSQL_TYPE_TINY_BLOB=249,
......@@ -250,6 +251,7 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
#define FIELD_TYPE_CHAR MYSQL_TYPE_TINY
#define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM
#define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY
#define FIELD_TYPE_BIT MYSQL_TYPE_BIT
/* Shutdown/kill enums and constants */
......
......@@ -331,6 +331,13 @@ buf_page_is_corrupted(
}
}
#endif
/* If we use checksums validation, make additional check before returning
TRUE to ensure that the checksum is not equal to BUF_NO_CHECKSUM_MAGIC which
might be stored by InnoDB with checksums disabled.
Otherwise, skip checksum calculation and return FALSE */
if (srv_use_checksums) {
old_checksum = buf_calc_page_old_checksum(read_buf);
old_checksum_field = mach_read_from_4(read_buf + UNIV_PAGE_SIZE
......@@ -342,7 +349,8 @@ buf_page_is_corrupted(
2. Newer InnoDB versions store the old formula checksum there. */
if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN)
&& old_checksum_field != old_checksum) {
&& old_checksum_field != old_checksum
&& old_checksum_field != BUF_NO_CHECKSUM_MAGIC) {
return(TRUE);
}
......@@ -353,9 +361,11 @@ buf_page_is_corrupted(
/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
(always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */
if (checksum_field != 0 && checksum_field != checksum) {
if (checksum_field != 0 && checksum_field != checksum
&& checksum_field != BUF_NO_CHECKSUM_MAGIC) {
return(TRUE);
}
}
return(FALSE);
......@@ -379,8 +389,10 @@ buf_page_print(
ut_print_buf(stderr, read_buf, UNIV_PAGE_SIZE);
fputs("InnoDB: End of page dump\n", stderr);
checksum = buf_calc_page_new_checksum(read_buf);
old_checksum = buf_calc_page_old_checksum(read_buf);
checksum = srv_use_checksums ?
buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
old_checksum = srv_use_checksums ?
buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
ut_print_timestamp(stderr);
fprintf(stderr,
......@@ -548,7 +560,7 @@ buf_pool_init(
}
/*----------------------------------------*/
} else {
buf_pool->frame_mem = ut_malloc_low(
buf_pool->frame_mem = os_mem_alloc_large(
UNIV_PAGE_SIZE * (n_frames + 1),
TRUE, FALSE);
}
......
......@@ -448,7 +448,8 @@ buf_flush_init_for_writing(
/* Store the new formula checksum */
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
buf_calc_page_new_checksum(page));
srv_use_checksums ?
buf_calc_page_new_checksum(page) : BUF_NO_CHECKSUM_MAGIC);
/* We overwrite the first 4 bytes of the end lsn field to store
the old formula checksum. Since it depends also on the field
......@@ -456,7 +457,8 @@ buf_flush_init_for_writing(
new formula checksum. */
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
buf_calc_page_old_checksum(page));
srv_use_checksums ?
buf_calc_page_old_checksum(page) : BUF_NO_CHECKSUM_MAGIC);
}
/************************************************************************
......
......@@ -49,7 +49,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \
thr0loc.h thr0loc.ic trx0purge.h trx0purge.ic trx0rec.h \
trx0rec.ic trx0roll.h trx0roll.ic trx0rseg.h trx0rseg.ic \
trx0sys.h trx0sys.ic trx0trx.h trx0trx.ic trx0types.h \
trx0undo.h trx0undo.ic univ.i \
trx0undo.h trx0undo.ic trx0xa.h univ.i \
usr0sess.h usr0sess.ic usr0types.h ut0byte.h ut0byte.ic \
ut0dbg.h ut0lst.h ut0mem.h ut0mem.ic ut0rnd.h ut0rnd.ic \
ut0sort.h ut0ut.h ut0ut.ic
......
......@@ -52,6 +52,8 @@ Created 11/5/1995 Heikki Tuuri
/* Modes for buf_page_get_known_nowait */
#define BUF_MAKE_YOUNG 51
#define BUF_KEEP_OLD 52
/* Magic value to use instead of checksums when they are disabled */
#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
extern buf_pool_t* buf_pool; /* The buffer pool of the database */
extern ibool buf_debug_prints;/* If this is set TRUE, the program
......
......@@ -12,6 +12,11 @@ Created 9/30/1995 Heikki Tuuri
#include "univ.i"
#ifdef UNIV_LINUX
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
typedef void* os_process_t;
typedef unsigned long int os_process_id_t;
......@@ -27,6 +32,10 @@ page size of an Intel x86 processor. We cannot use AWE with 2 MB or 4 MB
pages. */
#define OS_AWE_X86_PAGE_SIZE 4096
extern ibool os_use_large_pages;
/* Large page size. This may be a boot-time option on some platforms */
extern ulint os_large_page_size;
/********************************************************************
Windows AWE support. Tries to enable the "lock pages in memory" privilege for
the current process so that the current process can allocate memory-locked
......@@ -103,6 +112,25 @@ os_mem_alloc_nocache(
/* out: allocated memory */
ulint n); /* in: number of bytes */
/********************************************************************
Allocates large pages memory. */
void*
os_mem_alloc_large(
/*=================*/
/* out: allocated memory */
ulint n, /* in: number of bytes */
ibool set_to_zero, /* in: TRUE if allocated memory should be set
to zero if UNIV_SET_MEM_TO_ZERO is defined */
ibool assert_on_error); /* in: if TRUE, we crash mysqld if the memory
cannot be allocated */
/********************************************************************
Frees large pages memory. */
void
os_mem_free_large(
/*=================*/
void *ptr); /* in: number of bytes */
/********************************************************************
Sets the priority boost for threads released from waiting within the current
process. */
......
......@@ -107,6 +107,7 @@ extern ibool srv_very_fast_shutdown; /* if this TRUE, do not flush the
extern ibool srv_innodb_status;
extern ibool srv_use_doublewrite_buf;
extern ibool srv_use_checksums;
extern ibool srv_set_thread_priorities;
extern int srv_query_thread_priority;
......
......@@ -69,6 +69,10 @@ byte* os_awe_window;
ulint os_awe_window_size;
#endif
ibool os_use_large_pages;
/* Large page size. This may be a boot-time option on some platforms */
ulint os_large_page_size;
/********************************************************************
Windows AWE support. Tries to enable the "lock pages in memory" privilege for
the current process so that the current process can allocate memory-locked
......@@ -515,6 +519,83 @@ os_mem_alloc_nocache(
#endif
}
/********************************************************************
Allocates large pages memory. */
void*
os_mem_alloc_large(
/*=================*/
/* out: allocated memory */
ulint n, /* in: number of bytes */
ibool set_to_zero, /* in: TRUE if allocated memory should be set
to zero if UNIV_SET_MEM_TO_ZERO is defined */
ibool assert_on_error) /* in: if TRUE, we crash mysqld if the memory
cannot be allocated */
{
#ifdef UNIV_LINUX
ulint size;
int shmid;
void *ptr = NULL;
struct shmid_ds buf;
if (!os_use_large_pages || !os_large_page_size) {
goto skip;
}
/* Align block size to os_large_page_size */
size = ((n - 1) & ~(os_large_page_size - 1)) + os_large_page_size;
shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
if (shmid < 0) {
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. "
"errno %d\n", n, errno);
} else {
ptr = shmat(shmid, NULL, 0);
if (ptr == (void *)-1) {
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to attach shared memory "
"segment, errno %d\n", errno);
}
/*
Remove the shared memory segment so that it will be automatically freed
after memory is detached or process exits
*/
shmctl(shmid, IPC_RMID, &buf);
}
if (ptr) {
if (set_to_zero) {
#ifdef UNIV_SET_MEM_TO_ZERO
memset(ret, '\0', size);
#endif
}
return(ptr);
}
fprintf(stderr, "InnoDB HugeTLB: Warning: Using conventional memory pool\n");
#endif
skip:
return(ut_malloc_low(n, set_to_zero, assert_on_error));
}
/********************************************************************
Frees large pages memory. */
void
os_mem_free_large(
/*=================*/
void *ptr) /* in: number of bytes */
{
#ifdef UNIV_LINUX
if (os_use_large_pages && os_large_page_size && !shmdt(ptr)) {
return;
}
#endif
ut_free(ptr);
}
/********************************************************************
Sets the priority boost for threads released from waiting within the current
process. */
......
......@@ -313,6 +313,7 @@ ibool srv_very_fast_shutdown = FALSE; /* if this TRUE, do not flush the
ibool srv_innodb_status = FALSE;
ibool srv_use_doublewrite_buf = TRUE;
ibool srv_use_checksums = TRUE;
ibool srv_set_thread_priorities = TRUE;
int srv_query_thread_priority = 0;
......
......@@ -124,6 +124,22 @@ trx_doublewrite_init(
* sizeof(void*));
}
/********************************************************************
Frees the doublewrite buffer. */
static
void
trx_doublewrite_free(void)
/*======================*/
{
mutex_free(&(trx_doublewrite->mutex));
mem_free(trx_doublewrite->buf_block_arr);
ut_free(trx_doublewrite->write_buf_unaligned);
mem_free(trx_doublewrite);
trx_doublewrite = NULL;
}
/********************************************************************
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
multiple tablespace format. */
......@@ -512,6 +528,9 @@ trx_sys_doublewrite_init_or_restore_pages(
fil_flush_file_spaces(FIL_TABLESPACE);
if (!srv_use_doublewrite_buf)
trx_doublewrite_free();
leave_func:
ut_free(unaligned_read_buf);
}
......
......@@ -3813,8 +3813,9 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
case MYSQL_TYPE_DOUBLE:
{
ulonglong value= TIME_to_ulonglong(time);
return fetch_float_with_conversion(param, field,
fetch_float_with_conversion(param, field,
ulonglong2double(value), DBL_DIG);
break;
}
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
......@@ -3823,7 +3824,8 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
case MYSQL_TYPE_LONGLONG:
{
longlong value= (longlong) TIME_to_ulonglong(time);
return fetch_long_with_conversion(param, field, value);
fetch_long_with_conversion(param, field, value);
break;
}
default:
{
......@@ -4140,13 +4142,13 @@ static my_bool is_binary_compatible(enum enum_field_types type1,
enum enum_field_types type2)
{
static const enum enum_field_types
range1[]= { MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR, 0 },
range2[]= { MYSQL_TYPE_INT24, MYSQL_TYPE_LONG, 0 },
range3[]= { MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIMESTAMP, 0 },
range1[]= { MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR, MYSQL_TYPE_NULL },
range2[]= { MYSQL_TYPE_INT24, MYSQL_TYPE_LONG, MYSQL_TYPE_NULL },
range3[]= { MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_NULL },
range4[]= { MYSQL_TYPE_ENUM, MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB,
MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY,
MYSQL_TYPE_DECIMAL, 0 },
MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NULL },
*range_list[]= { range1, range2, range3, range4 },
**range_list_end= range_list + sizeof(range_list)/sizeof(*range_list);
const enum enum_field_types **range, *type;
......@@ -4157,7 +4159,7 @@ static my_bool is_binary_compatible(enum enum_field_types type1,
{
/* check that both type1 and type2 are in the same range */
bool type1_found= FALSE, type2_found= FALSE;
for (type= *range; *type; type++)
for (type= *range; *type != MYSQL_TYPE_NULL; type++)
{
type1_found|= type1 == *type;
type2_found|= type2 == *type;
......
......@@ -82,6 +82,19 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
length);
pos= (byte*) record+keyseg->start;
if (type == HA_KEYTYPE_BIT)
{
if (keyseg->bit_length)
{
uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
keyseg->bit_start, keyseg->bit_length);
*key++= bits;
length--;
}
memcpy((byte*) key, pos, length);
key+= length;
continue;
}
if (keyseg->flag & HA_SPACE_PACK)
{
end=pos+length;
......@@ -333,6 +346,26 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
}
record[keyseg->null_pos]&= ~keyseg->null_bit;
}
if (keyseg->type == HA_KEYTYPE_BIT)
{
uint length= keyseg->length;
if (keyseg->bit_length)
{
uchar bits= *key++;
set_rec_bits(bits, record + keyseg->bit_pos, keyseg->bit_start,
keyseg->bit_length);
length--;
}
else
{
clr_rec_bits(record + keyseg->bit_pos, keyseg->bit_start,
keyseg->bit_length);
}
memcpy(record + keyseg->start, (byte*) key, length);
key+= length;
continue;
}
if (keyseg->flag & HA_SPACE_PACK)
{
uint length;
......
......@@ -1049,11 +1049,12 @@ int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
*ptr++ =keyseg->null_bit;
*ptr++ =keyseg->bit_start;
*ptr++ =keyseg->bit_end;
*ptr++ =0; /* Not used */
*ptr++= keyseg->bit_length;
mi_int2store(ptr,keyseg->flag); ptr+=2;
mi_int2store(ptr,keyseg->length); ptr+=2;
mi_int4store(ptr,keyseg->start); ptr+=4;
mi_int4store(ptr,keyseg->null_pos); ptr+=4;
mi_int4store(ptr, keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos);
ptr+=4;
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
}
......@@ -1066,12 +1067,19 @@ char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg)
keyseg->null_bit = *ptr++;
keyseg->bit_start = *ptr++;
keyseg->bit_end = *ptr++;
ptr++;
keyseg->bit_length = *ptr++;
keyseg->flag = mi_uint2korr(ptr); ptr +=2;
keyseg->length = mi_uint2korr(ptr); ptr +=2;
keyseg->start = mi_uint4korr(ptr); ptr +=4;
keyseg->null_pos = mi_uint4korr(ptr); ptr +=4;
keyseg->charset=0; /* Will be filled in later */
if (keyseg->null_bit)
keyseg->bit_pos= keyseg->null_pos + (keyseg->null_bit == 7);
else
{
keyseg->bit_pos= keyseg->null_pos;
keyseg->null_pos= 0;
}
return ptr;
}
......
-- require r/have_federated_db.require
disable_query_log;
show variables like "have_federated_db";
enable_query_log;
......@@ -104,7 +104,7 @@ drop table t5 ;
# c5 integer, c6 bigint, c7 float, c8 double,
# c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
# c13 date, c14 datetime, c15 timestamp(14), c16 time,
# c17 year, c18 bit, c19 bool, c20 char,
# c17 year, c18 tinyint, c19 bool, c20 char,
# c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
# c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
# c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......
......@@ -34,7 +34,7 @@ eval create table t9
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......
......@@ -1347,7 +1347,7 @@ run_testcase ()
tsrcdir=$TESTDIR/$tname-src
result_file="r/$tname.result"
echo $tname > $CURRENT_TEST
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0`
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0 \& \( $tname : federated \) = 0`
if [ -n "$RESULT_EXT" -a \( x$RECORD = x1 -o -f "$result_file$RESULT_EXT" \) ] ; then
result_file="$result_file$RESULT_EXT"
fi
......
This diff is collapsed.
This diff is collapsed.
Variable_name Value
have_federated_db YES
......@@ -14,7 +14,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -325,6 +325,7 @@ NDB YES/NO Alias for NDBCLUSTER
EXAMPLE YES/NO Example storage engine
ARCHIVE YES/NO Archive storage engine
CSV YES/NO CSV storage engine
FEDERATED YES/NO Federated MySQL storage engine
drop table if exists t5;
prepare stmt1 from ' drop table if exists t5 ' ;
execute stmt1 ;
......
......@@ -11,7 +11,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -66,7 +66,7 @@ def test t9 t9 c14 c14 12 19 19 Y 128 0 63
def test t9 t9 c15 c15 7 19 19 N 1249 0 63
def test t9 t9 c16 c16 11 8 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 1 1 Y 32768 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
......
......@@ -11,7 +11,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -66,7 +66,7 @@ def test t9 t9 c14 c14 12 19 19 Y 128 0 63
def test t9 t9 c15 c15 7 19 19 N 1249 0 63
def test t9 t9 c16 c16 11 8 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 1 1 Y 32768 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
......
......@@ -12,7 +12,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 varchar(100), c24 varchar(100),
c25 varchar(100), c26 varchar(100), c27 varchar(100), c28 varchar(100),
c29 varchar(100), c30 varchar(100), c31 enum('one', 'two', 'three'),
......@@ -67,7 +67,7 @@ def test t9 t9 c14 c14 12 19 19 Y 128 0 63
def test t9 t9 c15 c15 7 19 19 N 1249 0 63
def test t9 t9 c16 c16 11 8 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 1 1 Y 32768 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
......
......@@ -13,7 +13,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -33,7 +33,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -53,7 +53,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -109,7 +109,7 @@ def test t9 t9 c14 c14 12 19 19 Y 128 0 63
def test t9 t9 c15 c15 7 19 19 N 1249 0 63
def test t9 t9 c16 c16 11 8 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 1 1 Y 32768 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
......@@ -3062,7 +3062,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -3118,7 +3118,7 @@ def test t9 t9 c14 c14 12 19 19 Y 128 0 63
def test t9 t9 c15 c15 7 19 19 N 1249 0 63
def test t9 t9 c16 c16 11 8 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 1 1 Y 32768 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
......
......@@ -11,7 +11,7 @@ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -66,7 +66,7 @@ def test t9 t9 c14 c14 12 19 19 Y 128 0 63
def test t9 t9 c15 c15 7 19 19 N 1249 0 63
def test t9 t9 c16 c16 11 8 8 Y 128 0 63
def test t9 t9 c17 c17 13 4 4 Y 32864 0 63
def test t9 t9 c18 c18 1 1 1 Y 32768 0 63
def test t9 t9 c18 c18 1 4 1 Y 32768 0 63
def test t9 t9 c19 c19 1 1 1 Y 32768 0 63
def test t9 t9 c20 c20 254 1 1 Y 0 0 8
def test t9 t9 c21 c21 254 10 10 Y 0 0 8
......
This diff is collapsed.
select 0 + b'1';
0 + b'1'
1
select 0 + b'0';
0 + b'0'
0
select 0 + b'000001';
0 + b'000001'
1
select 0 + b'000011';
0 + b'000011'
3
select 0 + b'000101';
0 + b'000101'
5
select 0 + b'000000';
0 + b'000000'
0
select 0 + b'10000000';
0 + b'10000000'
128
select 0 + b'11111111';
0 + b'11111111'
255
select 0 + b'10000001';
0 + b'10000001'
129
select 0 + b'1000000000000000';
0 + b'1000000000000000'
32768
select 0 + b'1111111111111111';
0 + b'1111111111111111'
65535
select 0 + b'1000000000000001';
0 + b'1000000000000001'
32769
drop table if exists t1;
create table t1 (a bit(65));
ERROR 42000: Column length too big for column 'a' (max = 64); use BLOB instead
create table t1 (a bit(0));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a bit, key(a)) engine=innodb;
ERROR 42000: The storage engine for the table doesn't support BIT FIELD
create table t1 (a bit(64));
insert into t1 values
(b'1111111111111111111111111111111111111111111111111111111111111111'),
(b'1000000000000000000000000000000000000000000000000000000000000000'),
(b'0000000000000000000000000000000000000000000000000000000000000001'),
(b'1010101010101010101010101010101010101010101010101010101010101010'),
(b'0101010101010101010101010101010101010101010101010101010101010101');
select hex(a) from t1;
hex(a)
FFFFFFFFFFFFFFFF
8000000000000000
1
AAAAAAAAAAAAAAAA
5555555555555555
drop table t1;
create table t1 (a bit);
insert into t1 values (b'0'), (b'1'), (b'000'), (b'100'), (b'001');
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 4
select hex(a) from t1;
hex(a)
0
1
0
1
1
alter table t1 add unique (a);
ERROR 23000: Duplicate entry '' for key 1
drop table t1;
create table t1 (a bit(2));
insert into t1 values (b'00'), (b'01'), (b'10'), (b'100');
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 4
select a+0 from t1;
a+0
0
1
2
3
alter table t1 add key (a);
explain select a+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 2 NULL 4 Using index
select a+0 from t1;
a+0
0
1
2
3
drop table t1;
create table t1 (a bit(7), b bit(9), key(a, b));
insert into t1 values
(94, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),
(75, 42), (108, 67), (79, 349), (59, 188), (68, 206), (49, 345), (118, 380),
(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),
(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),
(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),
(44, 307), (68, 454), (57, 135);
explain select a+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 38 Using index
select a+0 from t1;
a+0
0
4
5
9
23
24
28
29
30
31
34
44
49
56
57
59
60
61
68
68
75
77
78
79
87
88
94
94
104
106
108
111
116
118
119
122
123
127
explain select b+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 38 Using index
select b+0 from t1;
b+0
177
245
178
363
36
398
499
399
83
438
202
307
345
379
135
188
343
152
206
454
42
133
123
349
351
411
46
468
280
446
67
368
390
380
368
118
411
403
explain select a+0, b+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 38 Using index
select a+0, b+0 from t1;
a+0 b+0
0 177
4 245
5 178
9 363
23 36
24 398
28 499
29 399
30 83
31 438
34 202
44 307
49 345
56 379
57 135
59 188
60 343
61 152
68 206
68 454
75 42
77 133
78 123
79 349
87 351
88 411
94 46
94 468
104 280
106 446
108 67
111 368
116 390
118 380
119 368
122 118
123 411
127 403
explain select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 2 NULL 27 Using where; Using index; Using filesort
select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
a+0 b+0
44 307
49 345
56 379
60 343
68 206
68 454
79 349
87 351
88 411
94 468
104 280
106 446
111 368
116 390
118 380
119 368
123 411
127 403
explain select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 2 NULL 8 Using where; Using index; Using filesort
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
61 152
59 188
68 206
44 307
60 343
49 345
56 379
68 454
set @@max_length_for_sort_data=0;
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
61 152
59 188
68 206
44 307
60 343
49 345
56 379
68 454
select hex(min(a)) from t1;
hex(min(a))
0
select hex(min(b)) from t1;
hex(min(b))
24
select hex(min(a)), hex(max(a)), hex(min(b)), hex(max(b)) from t1;
hex(min(a)) hex(max(a)) hex(min(b)) hex(max(b))
0 7F 24 1F3
drop table t1;
create table t1 (a int not null, b bit, c bit(9), key(a, b, c));
insert into t1 values
(4, NULL, 1), (4, 0, 3), (2, 1, 4), (1, 1, 100), (4, 0, 23), (4, 0, 54),
(56, 0, 22), (4, 1, 100), (23, 0, 1), (4, 0, 34);
select a+0, b+0, c+0 from t1;
a+0 b+0 c+0
1 1 100
2 1 4
4 NULL 1
4 0 3
4 0 23
4 0 34
4 0 54
4 1 100
23 0 1
56 0 22
select hex(min(b)) from t1 where a = 4;
hex(min(b))
0
select hex(min(c)) from t1 where a = 4 and b = 0;
hex(min(c))
3
select hex(max(b)) from t1;
hex(max(b))
1
select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2;
a+0 b+0 c+0
4 0 3
4 0 23
select a+0, b+0, c+0 from t1 order by b desc;
a+0 b+0 c+0
2 1 4
1 1 100
4 1 100
4 0 3
4 0 23
4 0 54
56 0 22
23 0 1
4 0 34
4 NULL 1
select a+0, b+0, c+0 from t1 order by c;
a+0 b+0 c+0
4 NULL 1
23 0 1
4 0 3
2 1 4
56 0 22
4 0 23
4 0 34
4 0 54
1 1 100
4 1 100
drop table t1;
create table t1(a bit(2), b bit(2));
insert into t1 (a) values (0x01), (0x03), (0x02);
update t1 set b= concat(a);
select a+0, b+0 from t1;
a+0 b+0
1 1
3 3
2 2
drop table t1;
create table t1 (a bit(7), key(a));
insert into t1 values (44), (57);
select a+0 from t1;
a+0
44
57
drop table t1;
......@@ -1299,6 +1299,8 @@ INSERT INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
SELECT * FROM t2;
OPTIMIZE TABLE t2;
SELECT * FROM t2;
REPAIR TABLE t2;
SELECT * FROM t2;
#
# Test bulk inserts
......
This diff is collapsed.
......@@ -32,7 +32,7 @@ eval create table t9
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 varchar(100), c24 varchar(100),
c25 varchar(100), c26 varchar(100), c27 varchar(100), c28 varchar(100),
c29 varchar(100), c30 varchar(100), c31 enum('one', 'two', 'three'),
......
......@@ -32,7 +32,7 @@ create table t9
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......@@ -63,7 +63,7 @@ create table t9
c5 integer, c6 bigint, c7 float, c8 double,
c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
c13 date, c14 datetime, c15 timestamp(14), c16 time,
c17 year, c18 bit, c19 bool, c20 char,
c17 year, c18 tinyint, c19 bool, c20 char,
c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
......
#
# testing of the BIT column type
#
select 0 + b'1';
select 0 + b'0';
select 0 + b'000001';
select 0 + b'000011';
select 0 + b'000101';
select 0 + b'000000';
select 0 + b'10000000';
select 0 + b'11111111';
select 0 + b'10000001';
select 0 + b'1000000000000000';
select 0 + b'1111111111111111';
select 0 + b'1000000000000001';
--disable_warnings
drop table if exists t1;
--enable_warnings
--error 1074
create table t1 (a bit(65));
create table t1 (a bit(0));
show create table t1;
drop table t1;
--error 1178
create table t1 (a bit, key(a)) engine=innodb;
create table t1 (a bit(64));
insert into t1 values
(b'1111111111111111111111111111111111111111111111111111111111111111'),
(b'1000000000000000000000000000000000000000000000000000000000000000'),
(b'0000000000000000000000000000000000000000000000000000000000000001'),
(b'1010101010101010101010101010101010101010101010101010101010101010'),
(b'0101010101010101010101010101010101010101010101010101010101010101');
select hex(a) from t1;
drop table t1;
create table t1 (a bit);
insert into t1 values (b'0'), (b'1'), (b'000'), (b'100'), (b'001');
select hex(a) from t1;
--error 1062
alter table t1 add unique (a);
drop table t1;
create table t1 (a bit(2));
insert into t1 values (b'00'), (b'01'), (b'10'), (b'100');
select a+0 from t1;
alter table t1 add key (a);
explain select a+0 from t1;
select a+0 from t1;
drop table t1;
create table t1 (a bit(7), b bit(9), key(a, b));
insert into t1 values
(94, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),
(75, 42), (108, 67), (79, 349), (59, 188), (68, 206), (49, 345), (118, 380),
(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),
(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),
(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),
(44, 307), (68, 454), (57, 135);
explain select a+0 from t1;
select a+0 from t1;
explain select b+0 from t1;
select b+0 from t1;
explain select a+0, b+0 from t1;
select a+0, b+0 from t1;
explain select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
explain select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
set @@max_length_for_sort_data=0;
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
select hex(min(a)) from t1;
select hex(min(b)) from t1;
select hex(min(a)), hex(max(a)), hex(min(b)), hex(max(b)) from t1;
drop table t1;
create table t1 (a int not null, b bit, c bit(9), key(a, b, c));
insert into t1 values
(4, NULL, 1), (4, 0, 3), (2, 1, 4), (1, 1, 100), (4, 0, 23), (4, 0, 54),
(56, 0, 22), (4, 1, 100), (23, 0, 1), (4, 0, 34);
select a+0, b+0, c+0 from t1;
select hex(min(b)) from t1 where a = 4;
select hex(min(c)) from t1 where a = 4 and b = 0;
select hex(max(b)) from t1;
select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2;
select a+0, b+0, c+0 from t1 order by b desc;
select a+0, b+0, c+0 from t1 order by c;
drop table t1;
create table t1(a bit(2), b bit(2));
insert into t1 (a) values (0x01), (0x03), (0x02);
update t1 set b= concat(a);
select a+0, b+0 from t1;
drop table t1;
# Some magic numbers
create table t1 (a bit(7), key(a));
insert into t1 values (44), (57);
select a+0 from t1;
drop table t1;
......@@ -53,7 +53,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
my_net.c my_semaphore.c my_port.c my_sleep.c \
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
my_handler.c my_netware.c
my_handler.c my_netware.c my_largepage.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
......
......@@ -341,8 +341,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
blocks--;
/* Allocate memory for cache page buffers */
if ((keycache->block_mem=
my_malloc_lock((ulong) blocks * keycache->key_cache_block_size,
MYF(0))))
my_large_malloc((ulong) blocks * keycache->key_cache_block_size,
MYF(MY_WME))))
{
/*
Allocate memory for blocks, hash_links and hash entries;
......@@ -351,7 +351,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
if ((keycache->block_root= (BLOCK_LINK*) my_malloc((uint) length,
MYF(0))))
break;
my_free_lock(keycache->block_mem, MYF(0));
my_large_free(keycache->block_mem, MYF(0));
}
if (blocks < 8)
{
......@@ -421,7 +421,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
keycache->blocks= 0;
if (keycache->block_mem)
{
my_free_lock((gptr) keycache->block_mem, MYF(0));
my_large_free((gptr) keycache->block_mem, MYF(0));
keycache->block_mem= NULL;
}
if (keycache->block_root)
......@@ -605,7 +605,7 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
{
if (keycache->block_mem)
{
my_free_lock((gptr) keycache->block_mem, MYF(0));
my_large_free((gptr) keycache->block_mem, MYF(0));
keycache->block_mem= NULL;
my_free((gptr) keycache->block_root, MYF(0));
keycache->block_root= NULL;
......
......@@ -178,6 +178,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
}
break;
case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_BIT:
if (keyseg->flag & HA_SPACE_PACK)
{
int a_length,b_length,pack_length;
......
/* Copyright (C) 2004 MySQL 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; either version 2 of the License, or
(at your option) any later version.
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 */
#include "mysys_priv.h"
#ifdef HAVE_LARGE_PAGES
#ifdef HAVE_SYS_IPC_H
#include <sys/ipc.h>
#endif
#ifdef HAVE_SYS_SHM_H
#include <sys/shm.h>
#endif
static uint my_get_large_page_size_int(void);
static gptr my_large_malloc_int(uint size, myf my_flags);
static my_bool my_large_free_int(gptr ptr, myf my_flags);
/* Gets the size of large pages from the OS */
uint my_get_large_page_size(void)
{
uint size;
DBUG_ENTER("my_get_large_page_size");
if (!(size = my_get_large_page_size_int()))
fprintf(stderr, "Warning: Failed to determine large page size\n");
DBUG_RETURN(size);
}
/*
General large pages allocator.
Tries to allocate memory from large pages pool and falls back to
my_malloc_lock() in case of failure
*/
gptr my_large_malloc(uint size, myf my_flags)
{
gptr ptr;
DBUG_ENTER("my_large_malloc");
if (my_use_large_pages && my_large_page_size)
{
if ((ptr = my_large_malloc_int(size, my_flags)) != NULL)
DBUG_RETURN(ptr);
if (my_flags & MY_WME)
fprintf(stderr, "Warning: Using conventional memory pool\n");
}
DBUG_RETURN(my_malloc_lock(size, my_flags));
}
/*
General large pages deallocator.
Tries to deallocate memory as if it was from large pages pool and falls back
to my_free_lock() in case of failure
*/
void my_large_free(gptr ptr, myf my_flags __attribute__((unused)))
{
DBUG_ENTER("my_large_free");
/*
my_large_free_int() can only fail if ptr was not allocated with
my_large_malloc_int(), i.e. my_malloc_lock() was used so we should free it
with my_free_lock()
*/
if (!my_use_large_pages || !my_large_page_size ||
!my_large_free_int(ptr, my_flags))
my_free_lock(ptr, my_flags);
DBUG_VOID_RETURN;
}
#ifdef HUGETLB_USE_PROC_MEMINFO
/* Linux-specific function to determine the size of large pages */
uint my_get_large_page_size_int(void)
{
FILE *f;
uint size = 0;
char buf[256];
DBUG_ENTER("my_get_large_page_size_int");
if (!(f = my_fopen("/proc/meminfo", O_RDONLY, MYF(MY_WME))))
goto finish;
while (fgets(buf, sizeof(buf), f))
if (sscanf(buf, "Hugepagesize: %u kB", &size))
break;
my_fclose(f, MYF(MY_WME));
finish:
DBUG_RETURN(size * 1024);
}
#endif /* HUGETLB_USE_PROC_MEMINFO */
#if HAVE_DECL_SHM_HUGETLB
/* Linux-specific large pages allocator */
gptr my_large_malloc_int(uint size, myf my_flags)
{
int shmid;
gptr ptr;
struct shmid_ds buf;
DBUG_ENTER("my_large_malloc_int");
/* Align block size to my_large_page_size */
size = ((size - 1) & ~(my_large_page_size - 1)) + my_large_page_size;
shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
if (shmid < 0)
{
if (my_flags & MY_WME)
fprintf(stderr,
"Warning: Failed to allocate %d bytes from HugeTLB memory."
" errno %d\n", size, errno);
DBUG_RETURN(NULL);
}
ptr = shmat(shmid, NULL, 0);
if (ptr == (void *)-1)
{
if (my_flags& MY_WME)
fprintf(stderr, "Warning: Failed to attach shared memory segment,"
" errno %d\n", errno);
shmctl(shmid, IPC_RMID, &buf);
DBUG_RETURN(NULL);
}
/*
Remove the shared memory segment so that it will be automatically freed
after memory is detached or process exits
*/
shmctl(shmid, IPC_RMID, &buf);
DBUG_RETURN(ptr);
}
/* Linux-specific large pages deallocator */
my_bool my_large_free_int(byte *ptr, myf my_flags __attribute__((unused)))
{
DBUG_ENTER("my_large_free_int");
DBUG_RETURN(shmdt(ptr) == 0);
}
#endif /* HAVE_DECL_SHM_HUGETLB */
#endif /* HAVE_LARGE_PAGES */
......@@ -61,6 +61,12 @@ const char *soundex_map= "01230120022455012623010202";
USED_MEM* my_once_root_block=0; /* pointer to first block */
uint my_once_extra=ONCE_ALLOC_INIT; /* Memory to alloc / block */
/* from my_largepage.c */
#ifdef HAVE_LARGE_PAGES
my_bool my_use_large_pages= 0;
uint my_large_page_size= 0;
#endif
/* from my_tempnam */
#if !defined(HAVE_TEMPNAM) || defined(HPUX11)
int _my_tempnam_used=0;
......
......@@ -38,6 +38,18 @@
Command *parse_command(Command_factory * factory, const char *text);
Mysql_connection_thread_args::Mysql_connection_thread_args(
struct st_vio *vio_arg,
Thread_registry &thread_registry_arg,
const User_map &user_map_arg,
ulong connection_id_arg,
Instance_map &instance_map_arg) :
vio(vio_arg)
,thread_registry(thread_registry_arg)
,user_map(user_map_arg)
,connection_id(connection_id_arg)
,instance_map(instance_map_arg)
{}
/*
MySQL connection - handle one connection with mysql command line client
......
......@@ -48,13 +48,7 @@ struct Mysql_connection_thread_args
Thread_registry &thread_registry_arg,
const User_map &user_map_arg,
ulong connection_id_arg,
Instance_map &instance_map_arg) :
vio(vio_arg)
,thread_registry(thread_registry_arg)
,user_map(user_map_arg)
,connection_id(connection_id_arg)
,instance_map(instance_map_arg)
{}
Instance_map &instance_map_arg);
};
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_CONNECTION_H
......@@ -62,7 +62,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
parse_file.h sql_view.h sql_trigger.h \
examples/ha_example.h examples/ha_archive.h \
examples/ha_tina.h
examples/ha_tina.h \
ha_federated.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
......@@ -98,7 +99,9 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
sp_cache.cc parse_file.cc sql_trigger.cc \
examples/ha_example.cc examples/ha_archive.cc \
examples/ha_tina.cc
examples/ha_tina.cc \
ha_federated.cc
gen_lex_hash_SOURCES = gen_lex_hash.cc
gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
mysql_tzinfo_to_sql_SOURCES = mysql_tzinfo_to_sql.cc
......
......@@ -22,6 +22,7 @@
#ifdef HAVE_ARCHIVE_DB
#include "ha_archive.h"
#include <my_dir.h>
/*
First, if you want to understand storage engines you should look at
......@@ -227,8 +228,7 @@ int ha_archive::read_meta_file(File meta_file, ulonglong *rows)
/*
This method writes out the header of a meta file and returns whether or not it was successful.
By setting dirty you say whether or not the file represents the actual state of the data file.
Upon ::open() we set to dirty, and upon ::close() we set to clean. If we determine during
a read that the file was dirty we will force a rebuild of this file.
Upon ::open() we set to dirty, and upon ::close() we set to clean.
*/
int ha_archive::write_meta_file(File meta_file, ulonglong rows, bool dirty)
{
......@@ -305,6 +305,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
share->use_count= 0;
share->table_name_length= length;
share->table_name= tmp_name;
share->crashed= FALSE;
fn_format(share->data_file_name,table_name,"",ARZ,MY_REPLACE_EXT|MY_UNPACK_FILENAME);
fn_format(meta_file_name,table_name,"",ARM,MY_REPLACE_EXT|MY_UNPACK_FILENAME);
strmov(share->table_name,table_name);
......@@ -315,23 +316,14 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
if ((share->meta_file= my_open(meta_file_name, O_RDWR, MYF(0))) == -1)
goto error;
if (read_meta_file(share->meta_file, &share->rows_recorded))
{
/*
The problem here is that for some reason, probably a crash, the meta
file has been corrupted. So what do we do? Well we try to rebuild it
ourself. Once that happens, we reread it, but if that fails we just
call it quits and return an error.
*/
if (rebuild_meta_file(share->table_name, share->meta_file))
goto error;
if (read_meta_file(share->meta_file, &share->rows_recorded))
goto error;
}
/*
After we read, we set the file to dirty. When we close, we will do the
opposite.
opposite. If the meta file will not open we assume it is crashed and
leave it up to the user to fix.
*/
if (read_meta_file(share->meta_file, &share->rows_recorded))
share->crashed= TRUE;
else
(void)write_meta_file(share->meta_file, share->rows_recorded, TRUE);
/*
It is expensive to open and close the data files and since you can't have
......@@ -408,7 +400,7 @@ int ha_archive::open(const char *name, int mode, uint test_if_locked)
DBUG_ENTER("ha_archive::open");
if (!(share= get_share(name, table)))
DBUG_RETURN(1);
DBUG_RETURN(-1);
thr_lock_data_init(&share->lock,&lock,NULL);
if ((archive= gzopen(share->data_file_name, "rb")) == NULL)
......@@ -530,6 +522,9 @@ int ha_archive::write_row(byte * buf)
z_off_t written;
DBUG_ENTER("ha_archive::write_row");
if (share->crashed)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
......@@ -579,6 +574,9 @@ int ha_archive::rnd_init(bool scan)
DBUG_ENTER("ha_archive::rnd_init");
int read; // gzread() returns int, and we use this to check the header
if (share->crashed)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
/* We rewind the file so that we can read from the beginning if scan */
if (scan)
{
......@@ -672,6 +670,9 @@ int ha_archive::rnd_next(byte *buf)
int rc;
DBUG_ENTER("ha_archive::rnd_next");
if (share->crashed)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
if (!scan_rows)
DBUG_RETURN(HA_ERR_END_OF_FILE);
scan_rows--;
......@@ -722,22 +723,23 @@ int ha_archive::rnd_pos(byte * buf, byte *pos)
}
/*
This method rebuilds the meta file. It does this by walking the datafile and
This method repairs the meta file. It does this by walking the datafile and
rewriting the meta file.
*/
int ha_archive::rebuild_meta_file(char *table_name, File meta_file)
int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt)
{
int rc;
byte *buf;
ulonglong rows_recorded= 0;
gzFile rebuild_file; /* Archive file we are working with */
gzFile rebuild_file; // Archive file we are working with
File meta_file; // Meta file we use
char data_file_name[FN_REFLEN];
DBUG_ENTER("ha_archive::rebuild_meta_file");
DBUG_ENTER("ha_archive::repair");
/*
Open up the meta file to recreate it.
*/
fn_format(data_file_name, table_name, "", ARZ,
fn_format(data_file_name, share->table_name, "", ARZ,
MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if ((rebuild_file= gzopen(data_file_name, "rb")) == NULL)
DBUG_RETURN(errno ? errno : -1);
......@@ -767,11 +769,18 @@ int ha_archive::rebuild_meta_file(char *table_name, File meta_file)
*/
if (rc == HA_ERR_END_OF_FILE)
{
(void)write_meta_file(meta_file, rows_recorded, FALSE);
fn_format(data_file_name,share->table_name,"",ARM,MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if ((meta_file= my_open(data_file_name, O_RDWR, MYF(0))) == -1)
{
rc= HA_ERR_CRASHED_ON_USAGE;
goto error;
}
(void)write_meta_file(meta_file, rows_recorded, TRUE);
rc= 0;
}
my_free((gptr) buf, MYF(0));
share->crashed= FALSE;
error:
gzclose(rebuild_file);
......@@ -790,13 +799,14 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
char block[IO_SIZE];
char writer_filename[FN_REFLEN];
/* Closing will cause all data waiting to be flushed */
gzclose(share->archive_write);
share->archive_write= NULL;
/* Lets create a file to contain the new data */
fn_format(writer_filename, share->table_name, "", ARN,
MY_REPLACE_EXT|MY_UNPACK_FILENAME);
/* Closing will cause all data waiting to be flushed, to be flushed */
gzclose(share->archive_write);
if ((reader= gzopen(share->data_file_name, "rb")) == NULL)
DBUG_RETURN(-1);
......@@ -814,16 +824,6 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
my_rename(writer_filename,share->data_file_name,MYF(0));
/*
We reopen the file in case some IO is waiting to go through.
In theory the table is closed right after this operation,
but it is possible for IO to still happen.
I may be being a bit too paranoid right here.
*/
if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL)
DBUG_RETURN(errno ? errno : -1);
share->dirty= FALSE;
DBUG_RETURN(0);
}
......@@ -880,13 +880,27 @@ THR_LOCK_DATA **ha_archive::store_lock(THD *thd,
void ha_archive::info(uint flag)
{
DBUG_ENTER("ha_archive::info");
/*
This should be an accurate number now, though bulk and delayed inserts can
cause the number to be inaccurate.
*/
records= share->rows_recorded;
deleted= 0;
/* Costs quite a bit more to get all information */
if (flag & HA_STATUS_TIME)
{
MY_STAT file_stat; // Stat information for the data file
VOID(my_stat(share->data_file_name, &file_stat, MYF(MY_WME)));
mean_rec_length= table->reclength + buffer.alloced_length();
data_file_length= file_stat.st_size;
create_time= file_stat.st_ctime;
update_time= file_stat.st_mtime;
max_data_file_length= share->rows_recorded * mean_rec_length;
}
delete_length= 0;
index_file_length=0;
DBUG_VOID_RETURN;
}
......@@ -900,7 +914,7 @@ void ha_archive::info(uint flag)
*/
void ha_archive::start_bulk_insert(ha_rows rows)
{
DBUG_ENTER("ha_archive::info");
DBUG_ENTER("ha_archive::start_bulk_insert");
bulk_insert= TRUE;
DBUG_VOID_RETURN;
}
......@@ -912,6 +926,7 @@ void ha_archive::start_bulk_insert(ha_rows rows)
*/
int ha_archive::end_bulk_insert()
{
DBUG_ENTER("ha_archive::end_bulk_insert");
bulk_insert= FALSE;
share->dirty= TRUE;
DBUG_RETURN(0);
......
......@@ -35,6 +35,7 @@ typedef struct st_archive_share {
File meta_file; /* Meta file we use */
gzFile archive_write; /* Archive file we are working with */
bool dirty; /* Flag for if a flush should occur */
bool crashed; /* Meta file is crashed */
ulonglong rows_recorded; /* Number of rows in tables */
} ARCHIVE_SHARE;
......@@ -91,13 +92,14 @@ class ha_archive: public handler
int write_meta_file(File meta_file, ulonglong rows, bool dirty);
ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table);
int free_share(ARCHIVE_SHARE *share);
int rebuild_meta_file(char *table_name, File meta_file);
bool auto_repair() const { return 1; } // For the moment we just do this
int read_data_header(gzFile file_to_read);
int write_data_header(gzFile file_to_write);
void position(const byte *record);
void info(uint);
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int repair(THD* thd, HA_CHECK_OPT* check_opt);
void start_bulk_insert(ha_rows rows);
int end_bulk_insert();
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
......
......@@ -6048,6 +6048,227 @@ bool Field_num::eq_def(Field *field)
}
/*
Bit field.
We store the first 0 - 6 uneven bits among the null bits
at the start of the record. The rest bytes are stored in
the record itself.
For example:
CREATE TABLE t1 (a int, b bit(17), c bit(21) not null, d bit(8));
We would store data as follows in the record:
Byte Bit
1 7 - reserve for delete
6 - null bit for 'a'
5 - null bit for 'b'
4 - first (high) bit of 'b'
3 - first (high) bit of 'c'
2 - second bit of 'c'
1 - third bit of 'c'
0 - forth bit of 'c'
2 7 - firth bit of 'c'
6 - null bit for 'd'
3 - 6 four bytes for 'a'
7 - 8 two bytes for 'b'
9 - 10 two bytes for 'c'
11 one byte for 'd'
*/
void Field_bit::make_field(Send_field *field)
{
/* table_cache_key is not set for temp tables */
field->db_name= (orig_table->table_cache_key ? orig_table->table_cache_key :
"");
field->org_table_name= orig_table->real_name;
field->table_name= orig_table->table_name;
field->col_name= field->org_col_name= field_name;
field->charsetnr= charset()->number;
field->length= field_length;
field->type= type();
field->flags= table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
field->decimals= 0;
}
int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
{
int delta;
for (; !*from && length; from++, length--); // skip left 0's
delta= field_length - length;
if (delta < -1 ||
(delta == -1 && (uchar) *from > ((1 << bit_len) - 1)) ||
(!bit_len && delta < 0))
{
set_rec_bits(0xff, bit_ptr, bit_ofs, bit_len);
memset(ptr, 0xff, field_length);
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
return 1;
}
/* delta is >= -1 here */
if (delta > 0)
{
if (bit_len)
clr_rec_bits(bit_ptr, bit_ofs, bit_len);
bzero(ptr, delta);
memcpy(ptr + delta, from, length);
}
else if (delta == 0)
{
if (bit_len)
clr_rec_bits(bit_ptr, bit_ofs, bit_len);
memcpy(ptr, from, length);
}
else
{
if (bit_len)
{
set_rec_bits((uchar) *from, bit_ptr, bit_ofs, bit_len);
from++;
}
memcpy(ptr, from, field_length);
}
return 0;
}
int Field_bit::store(double nr)
{
return (Field_bit::store((longlong) nr));
}
int Field_bit::store(longlong nr)
{
char buf[8];
mi_int8store(buf, nr);
return store(buf, 8, NULL);
}
double Field_bit::val_real(void)
{
return (double) Field_bit::val_int();
}
longlong Field_bit::val_int(void)
{
ulonglong bits= 0;
if (bit_len)
bits= get_rec_bits(bit_ptr, bit_ofs, bit_len);
bits<<= (field_length * 8);
switch (field_length) {
case 0: return bits;
case 1: return bits | (ulonglong) (uchar) ptr[0];
case 2: return bits | mi_uint2korr(ptr);
case 3: return bits | mi_uint3korr(ptr);
case 4: return bits | mi_uint4korr(ptr);
case 5: return bits | mi_uint5korr(ptr);
case 6: return bits | mi_uint6korr(ptr);
case 7: return bits | mi_uint7korr(ptr);
default: return mi_uint8korr(ptr + field_length - sizeof(longlong));
}
}
String *Field_bit::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
uint length= min(pack_length(), sizeof(longlong));
ulonglong bits= val_int();
val_buffer->alloc(length);
memcpy_fixed((char*) val_buffer->ptr(), (char*) &bits, length);
val_buffer->length(length);
val_buffer->set_charset(&my_charset_bin);
return val_buffer;
}
int Field_bit::key_cmp(const byte *str, uint length)
{
if (bit_len)
{
int flag;
uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len);
if ((flag= (int) (bits - *str)))
return flag;
str++;
length--;
}
return bcmp(ptr, str, length);
}
int Field_bit::cmp_offset(uint row_offset)
{
if (bit_len)
{
int flag;
uchar bits_a= get_rec_bits(bit_ptr, bit_ofs, bit_len);
uchar bits_b= get_rec_bits(bit_ptr + row_offset, bit_ofs, bit_len);
if ((flag= (int) (bits_a - bits_b)))
return flag;
}
return bcmp(ptr, ptr + row_offset, field_length);
}
void Field_bit::get_key_image(char *buff, uint length, imagetype type)
{
if (bit_len)
{
uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len);
*buff++= bits;
length--;
}
memcpy(buff, ptr, min(length, field_length));
}
void Field_bit::sql_type(String &res) const
{
CHARSET_INFO *cs= res.charset();
ulong length= cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"bit(%d)",
(int) field_length * 8 + bit_len);
res.length((uint) length);
}
char *Field_bit::pack(char *to, const char *from, uint max_length)
{
uint length= min(field_length + (bit_len > 0), max_length);
if (bit_len)
{
uchar bits= get_rec_bits(bit_ptr, bit_ofs, bit_len);
*to++= bits;
length--;
}
memcpy(to, from, length);
return to + length;
}
const char *Field_bit::unpack(char *to, const char *from)
{
if (bit_len)
{
set_rec_bits(*from, bit_ptr, bit_ofs, bit_len);
from++;
}
memcpy(to, from, field_length);
return from + field_length;
}
/*****************************************************************************
Handling of field and create_field
*****************************************************************************/
......@@ -6124,6 +6345,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
case FIELD_TYPE_GEOMETRY: return 4+portable_sizeof_char_ptr;
case FIELD_TYPE_SET:
case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen
case FIELD_TYPE_BIT: return length / 8;
default: return 0;
}
return 0; // Keep compiler happy
......@@ -6154,11 +6376,30 @@ Field *make_field(char *ptr, uint32 field_length,
const char *field_name,
struct st_table *table)
{
uchar *bit_ptr;
uchar bit_offset;
LINT_INIT(bit_ptr);
LINT_INIT(bit_offset);
if (field_type == FIELD_TYPE_BIT)
{
bit_ptr= null_pos;
bit_offset= null_bit;
if (f_maybe_null(pack_flag)) // if null field
{
bit_ptr+= (null_bit == 7); // shift bit_ptr and bit_offset
bit_offset= (bit_offset + 1) & 7;
}
}
if (!f_maybe_null(pack_flag))
{
null_pos=0;
null_bit=0;
}
else
{
null_bit= ((uchar) 1) << null_bit;
}
switch (field_type)
{
......@@ -6280,6 +6521,9 @@ Field *make_field(char *ptr, uint32 field_length,
unireg_check, field_name, table, field_charset);
case FIELD_TYPE_NULL:
return new Field_null(ptr,field_length,unireg_check,field_name,table, field_charset);
case FIELD_TYPE_BIT:
return new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr,
bit_offset, unireg_check, field_name, table);
default: // Impossible (Wrong version)
break;
}
......@@ -6338,6 +6582,9 @@ create_field::create_field(Field *old_field,Field *orig_field)
geom_type= ((Field_geom*)old_field)->geom_type;
break;
#endif
case FIELD_TYPE_BIT:
length= ((Field_bit *) old_field)->bit_len + length * 8;
break;
default:
break;
}
......
......@@ -80,7 +80,7 @@ class Field
FIELD_CAST_TIMESTAMP, FIELD_CAST_YEAR, FIELD_CAST_DATE, FIELD_CAST_NEWDATE,
FIELD_CAST_TIME, FIELD_CAST_DATETIME,
FIELD_CAST_STRING, FIELD_CAST_VARSTRING, FIELD_CAST_BLOB,
FIELD_CAST_GEOM, FIELD_CAST_ENUM, FIELD_CAST_SET
FIELD_CAST_GEOM, FIELD_CAST_ENUM, FIELD_CAST_SET, FIELD_CAST_BIT
};
utype unireg_check;
......@@ -211,6 +211,15 @@ class Field
ptr-=row_offset;
return tmp;
}
inline String *val_str(String *str, char *new_ptr)
{
char *old_ptr= ptr;
ptr= new_ptr;
val_str(str);
ptr= old_ptr;
return str;
}
virtual bool send_binary(Protocol *protocol);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{
......@@ -1173,6 +1182,53 @@ class Field_set :public Field_enum {
};
class Field_bit :public Field {
public:
uchar *bit_ptr; // position in record where 'uneven' bits store
uchar bit_ofs; // offset to 'uneven' high bits
uint bit_len; // number of 'uneven' high bits
Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
: Field(ptr_arg, len_arg >> 3, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
bit_ptr(bit_ptr_arg), bit_ofs(bit_ofs_arg), bit_len(len_arg & 7)
{ }
enum_field_types type() const { return FIELD_TYPE_BIT; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
uint32 key_length() const { return (uint32) field_length + (bit_len > 0); }
uint32 max_length() { return (uint32) field_length + (bit_len > 0); }
uint size_of() const { return sizeof(*this); }
Item_result result_type () const { return INT_RESULT; }
void make_field(Send_field *);
void reset(void) { bzero(ptr, field_length); }
int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr);
double val_real(void);
longlong val_int(void);
String *val_str(String*, String *);
int cmp(const char *a, const char *b)
{ return cmp_binary(a, b); }
int key_cmp(const byte *a, const byte *b)
{ return cmp_binary(a, b); }
int key_cmp(const byte *str, uint length);
int cmp_offset(uint row_offset);
void get_key_image(char *buff, uint length, imagetype type);
void set_key_image(char *buff, uint length)
{ Field_bit::store(buff, length, &my_charset_bin); }
void sort_string(char *buff, uint length)
{ get_key_image(buff, length, itRAW); }
uint32 pack_length() const
{ return (uint32) field_length + (bit_len > 0); }
void sql_type(String &str) const;
field_cast_enum field_cast_type() { return FIELD_CAST_BIT; }
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
const char *unpack(char* to, const char *from);
};
/*
Create field class for CREATE TABLE
*/
......
......@@ -485,6 +485,9 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
}
else
{
if (to->real_type() == FIELD_TYPE_BIT ||
from->real_type() == FIELD_TYPE_BIT)
return do_field_int;
// Check if identical fields
if (from->result_type() == STRING_RESULT)
{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1428,6 +1428,13 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
keydef[i].seg[j].bit_start= (uint) (field->pack_length() -
table_arg->blob_ptr_size);
}
else if (field->type() == FIELD_TYPE_BIT)
{
keydef[i].seg[j].bit_length= ((Field_bit *) field)->bit_len;
keydef[i].seg[j].bit_start= ((Field_bit *) field)->bit_ofs;
keydef[i].seg[j].bit_pos= (uint) (((Field_bit *) field)->bit_ptr -
(uchar*) table_arg->record[0]);
}
}
keyseg+=pos->key_parts;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment