From f200b0fbf0594bc3f75dd93795722c499f1a0afb Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Tue, 25 May 2004 15:06:32 +0500 Subject: [PATCH 01/17] WL#1562 (Improving spatial code) A set of changes improving our RTree indexes and fixed few bugs found during the tests --- myisam/rt_index.c | 92 ++++++++++++++++++++++++++++++++++++++++- myisam/rt_index.h | 2 +- myisam/rt_key.c | 46 +-------------------- myisam/rt_key.h | 2 - myisam/rt_mbr.c | 103 +++++++++++++++++++++++++++++++++++++++++++++- myisam/rt_mbr.h | 2 + myisam/rt_split.c | 10 ++--- sql/spatial.cc | 7 +++- 8 files changed, 207 insertions(+), 57 deletions(-) diff --git a/myisam/rt_index.c b/myisam/rt_index.c index 30146b9fd67..824cb7a396f 100644 --- a/myisam/rt_index.c +++ b/myisam/rt_index.c @@ -22,6 +22,8 @@ #include "rt_mbr.h" #define REINSERT_BUFFER_INC 10 +#define PICK_BY_AREA +/*#define PICK_BY_PERIMETER*/ typedef struct st_page_level { @@ -436,6 +438,92 @@ int rtree_get_next(MI_INFO *info, uint keynr, uint key_length) } +/* + Choose non-leaf better key for insertion +*/ + +#ifdef PICK_BY_PERIMETER +static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, + uint key_length, uchar *page_buf, uint nod_flag) +{ + double increase; + double best_incr = DBL_MAX; + double perimeter; + double best_perimeter; + uchar *best_key; + uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); + uchar *last = rt_PAGE_END(page_buf); + + LINT_INIT(best_perimeter); + LINT_INIT(best_key); + + for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) + { + if ((increase = rtree_perimeter_increase(keyinfo->seg, k, key, key_length, + &perimeter)) == -1) + return NULL; + if (increase < best_incr) + { + best_key = k; + best_perimeter= perimeter; + best_incr = increase; + } + else + { + if ((increase == best_incr) && (perimeter < best_perimeter)) + { + best_key = k; + best_perimeter= perimeter; + best_incr = increase; + } + } + } + return best_key; +} + +#endif /*PICK_BY_PERIMETER*/ + +#ifdef PICK_BY_AREA +static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, + uint key_length, uchar *page_buf, uint nod_flag) +{ + double increase; + double best_incr = DBL_MAX; + double area; + double best_area; + uchar *best_key; + uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); + uchar *last = rt_PAGE_END(page_buf); + + LINT_INIT(best_area); + LINT_INIT(best_key); + + for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) + { + if ((increase = rtree_area_increase(keyinfo->seg, k, key, key_length, + &area)) == -1) + return NULL; + if (increase < best_incr) + { + best_key = k; + best_area = area; + best_incr = increase; + } + else + { + if ((increase == best_incr) && (area < best_area)) + { + best_key = k; + best_area = area; + best_incr = increase; + } + } + } + return best_key; +} + +#endif /*PICK_BY_AREA*/ + /* Go down and insert key into tree @@ -467,7 +555,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */ (ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */ { - if ((k = rtree_choose_key(info, keyinfo, key, key_length, page_buf, + if ((k = rtree_pick_key(info, keyinfo, key, key_length, page_buf, nod_flag)) == NULL) goto err1; switch ((res = rtree_insert_req(info, keyinfo, key, key_length, @@ -577,7 +665,7 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, mi_putint(new_root_buf, 2, nod_flag); if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == - HA_OFFSET_ERROR) + HA_OFFSET_ERROR) goto err1; new_key = new_root_buf + keyinfo->block_length + nod_flag; diff --git a/myisam/rt_index.h b/myisam/rt_index.h index 1a0fce72a82..42f5915b991 100644 --- a/myisam/rt_index.h +++ b/myisam/rt_index.h @@ -23,7 +23,7 @@ (nod_flag ? nod_flag : info->s->base.rec_reflength)) #define rt_PAGE_END(page) (page + mi_getint(page)) -#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length) / 2) +#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length) / 3) int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length); int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length); diff --git a/myisam/rt_key.c b/myisam/rt_key.c index f18d13af8d8..0384849e5e7 100644 --- a/myisam/rt_key.c +++ b/myisam/rt_key.c @@ -35,7 +35,8 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint page_size = mi_getint(page_buf); uint nod_flag = mi_test_if_nod(page_buf); - if (page_size + key_length + nod_flag <= keyinfo->block_length) + if (page_size + key_length + info->s->base.rec_reflength <= + keyinfo->block_length) { /* split won't be necessary */ if (nod_flag) @@ -94,46 +95,3 @@ int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length); } - - -/* - Choose non-leaf better key for insertion -*/ - -uchar *rtree_choose_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, uchar *page_buf, uint nod_flag) -{ - double increase; - double best_incr = DBL_MAX; - double area; - double best_area; - uchar *best_key; - uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); - uchar *last = rt_PAGE_END(page_buf); - - LINT_INIT(best_area); - LINT_INIT(best_key); - - for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag)) - { - if ((increase = rtree_area_increase(keyinfo->seg, key, k, key_length, - &area)) == -1) - return NULL; - if (increase < best_incr) - { - best_key = k; - best_area = area; - best_incr = increase; - } - else - { - if ((increase == best_incr) && (area < best_area)) - { - best_key = k; - best_area = area; - best_incr = increase; - } - } - } - return best_key; -} diff --git a/myisam/rt_key.h b/myisam/rt_key.h index dfd7b874b54..f0d0bdd176d 100644 --- a/myisam/rt_key.h +++ b/myisam/rt_key.h @@ -26,6 +26,4 @@ int rtree_delete_key(MI_INFO *info, uchar *page, uchar *key, uint key_length, uint nod_flag); int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, uint key_length, my_off_t child_page); -uchar *rtree_choose_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, - uint key_length, uchar *page_buf, uint nod_flag); #endif /* _rt_key_h */ diff --git a/myisam/rt_mbr.c b/myisam/rt_mbr.c index bb13c0769b3..da427e4b67a 100644 --- a/myisam/rt_mbr.c +++ b/myisam/rt_mbr.c @@ -563,9 +563,9 @@ Calculates MBR_AREA(a+b) - MBR_AREA(a) double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, uint key_length, double *ab_area) { - double a_area = 1; + double a_area= 1.0; - *ab_area = 1; + *ab_area= 1.0; for (; (int)key_length > 0; keyseg += 2) { key_length -= keyseg->length * 2; @@ -627,6 +627,105 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, return *ab_area - a_area; } +#define RT_PERIM_INC_KORR(type, korr_func, len) \ +{ \ + type amin, amax, bmin, bmax; \ + amin = korr_func(a); \ + bmin = korr_func(b); \ + p_inc(a, b, len); \ + amax = korr_func(a); \ + bmax = korr_func(b); \ + p_inc(a, b, len); \ + a_perim+= (((double)amax) - ((double)amin)); \ + *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ + break; \ +} + +#define RT_PERIM_INC_GET(type, get_func, len)\ +{\ + type amin, amax, bmin, bmax; \ + get_func(amin, a); \ + get_func(bmin, b); \ + p_inc(a, b, len); \ + get_func(amax, a); \ + get_func(bmax, b); \ + p_inc(a, b, len); \ + a_perim+= (((double)amax) - ((double)amin)); \ + *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ + break; \ +} + +/* +Calculates MBR_PERIMETER(a+b) - MBR_PERIMETER(a) +*/ +double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, + uint key_length, double *ab_perim) +{ + double a_perim = 0.0; + + *ab_perim= 0.0; + for (; (int)key_length > 0; keyseg += 2) + { + key_length -= keyseg->length * 2; + + /* Handle NULL part */ + if (keyseg->null_bit) + { + return -1; + } + + switch ((enum ha_base_keytype) keyseg->type) { + case HA_KEYTYPE_TEXT: + case HA_KEYTYPE_BINARY: + case HA_KEYTYPE_VARTEXT: + case HA_KEYTYPE_VARBINARY: + case HA_KEYTYPE_NUM: + default: + return 1; + break; + case HA_KEYTYPE_INT8: + { + int amin, amax, bmin, bmax; + amin = (int)*((signed char *)a); + bmin = (int)*((signed char *)b); + p_inc(a, b, 1); + amax = (int)*((signed char *)a); + bmax = (int)*((signed char *)b); + p_inc(a, b, 1); + a_perim+= (((double)amax) - ((double)amin)); + *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); + break; + } + case HA_KEYTYPE_SHORT_INT: + RT_PERIM_INC_KORR(int16, mi_sint2korr, 2); + case HA_KEYTYPE_USHORT_INT: + RT_PERIM_INC_KORR(uint16, mi_uint2korr, 2); + case HA_KEYTYPE_INT24: + RT_PERIM_INC_KORR(int32, mi_sint3korr, 3); + case HA_KEYTYPE_UINT24: + RT_PERIM_INC_KORR(int32, mi_uint3korr, 3); + case HA_KEYTYPE_LONG_INT: + RT_PERIM_INC_KORR(int32, mi_sint4korr, 4); + case HA_KEYTYPE_ULONG_INT: + RT_PERIM_INC_KORR(uint32, mi_uint4korr, 4); +#ifdef HAVE_LONG_LONG + case HA_KEYTYPE_LONGLONG: + RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8); + case HA_KEYTYPE_ULONGLONG: + RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8); +#endif + case HA_KEYTYPE_FLOAT: + RT_PERIM_INC_GET(float, mi_float4get, 4); + case HA_KEYTYPE_DOUBLE: + RT_PERIM_INC_GET(double, mi_float8get, 8); + case HA_KEYTYPE_END: + return *ab_perim - a_perim; + } + } + return *ab_perim - a_perim; +} + + #define RT_PAGE_MBR_KORR(type, korr_func, store_func, len) \ { \ type amin, amax, bmin, bmax; \ diff --git a/myisam/rt_mbr.h b/myisam/rt_mbr.h index a68807370f9..ee71a8b9a93 100644 --- a/myisam/rt_mbr.h +++ b/myisam/rt_mbr.h @@ -28,6 +28,8 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar *a, uchar *b, uint key_length); double rtree_area_increase(HA_KEYSEG *keyseg, uchar *a, uchar *b, uint key_length, double *ab_area); +double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, + uint key_length, double *ab_perim); int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf, uchar* c, uint key_length); #endif /* _rt_mbr_h */ diff --git a/myisam/rt_split.c b/myisam/rt_split.c index 62b8ea6a65b..e4b2212f959 100644 --- a/myisam/rt_split.c +++ b/myisam/rt_split.c @@ -265,12 +265,12 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, n_dim = keyinfo->keysegs / 2; - if (!my_multi_malloc(MYF(0), - &coord_buf, n_dim * 2 * sizeof(double) * (max_keys + 1 + 4), - &task, sizeof(SplitStruct) * (max_keys + 1), - NullS)) + if (!(coord_buf= my_alloca(n_dim * 2 * sizeof(double) * (max_keys + 1 + 4) + + sizeof(SplitStruct) * (max_keys + 1)))) return -1; + task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4)); + next_coord = coord_buf; stop = task + max_keys; @@ -343,6 +343,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, my_afree((byte*)new_page); split_err: - my_free((gptr) coord_buf, MYF(0)); + my_afree((byte*) coord_buf); return err_code; } diff --git a/sql/spatial.cc b/sql/spatial.cc index ab415d9af10..f26e7dc3e83 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -395,7 +395,7 @@ bool Gis_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb) if (trs->skip_char(',')) // Didn't find ',' break; } - if (n_points < 2) + if (n_points < 1) { trs->set_error_msg("Too few points in LINESTRING"); return 1; @@ -484,6 +484,11 @@ int Gis_line_string::is_closed(int *closed) const if (no_data(data, 4)) return 1; n_points= uint4korr(data); + if (n_points == 1) + { + *closed=1; + return 0; + } data+= 4; if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) return 1; From fb9257dc45c843cfe91e3e5049e6c9c0ff92107a Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Fri, 28 May 2004 11:15:59 +0300 Subject: [PATCH 02/17] InnoDB: Add diagnostics when tmpfile() fails at start (Bug #3919) --- innobase/dict/dict0dict.c | 2 +- innobase/include/os0file.h | 7 ++++++ innobase/lock/lock0lock.c | 2 +- innobase/os/os0file.c | 44 ++++++++++++++++++++++++++------------ 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 0fc4ac2b687..f14e2a4e58c 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -642,7 +642,7 @@ dict_init(void) rw_lock_create(&dict_operation_lock); rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION); - dict_foreign_err_file = tmpfile(); + dict_foreign_err_file = os_file_create_tmpfile(); mutex_create(&dict_foreign_err_mutex); mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH); } diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index de17e2302ae..43741f79855 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -133,6 +133,13 @@ Creates the seek mutexes used in positioned reads and writes. */ void os_io_init_simple(void); /*===================*/ +/*************************************************************************** +Creates a temporary file. In case of error, causes abnormal termination. */ + +FILE* +os_file_create_tmpfile(void); +/*========================*/ + /* out: temporary file handle (never NULL) */ /******************************************************************** A simple function to open or create a file. */ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 791b81366b2..d9848577728 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -510,7 +510,7 @@ lock_sys_create( /* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */ - lock_latest_err_file = tmpfile(); + lock_latest_err_file = os_file_create_tmpfile(); } /************************************************************************* diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 681c4e487e7..8cb2b171328 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -301,14 +301,11 @@ os_file_handle_error( /*=================*/ /* out: TRUE if we should retry the operation */ - os_file_t file, /* in: file pointer */ const char* name, /* in: name of a file or NULL */ const char* operation)/* in: operation */ { ulint err; - UT_NOT_USED(file); - err = os_file_get_last_error(); if (err == OS_FILE_DISK_FULL) { @@ -374,6 +371,25 @@ os_io_init_simple(void) } } +/*************************************************************************** +Creates a temporary file. In case of error, causes abnormal termination. */ + +FILE* +os_file_create_tmpfile(void) +/*========================*/ + /* out: temporary file handle (never NULL) */ +{ + FILE* file = tmpfile(); + if (file == NULL) { + ut_print_timestamp(stderr); + fputs(" InnoDB: Error: unable to create temporary file\n", + stderr); + os_file_handle_error(NULL, "tmpfile"); + ut_error; + } + return(file); +} + /******************************************************************** A simple function to open or create a file. */ @@ -430,7 +446,7 @@ try_again: if (file == INVALID_HANDLE_VALUE) { *success = FALSE; - retry = os_file_handle_error(file, name, + retry = os_file_handle_error(name, create_mode == OS_FILE_OPEN ? "open" : "create"); if (retry) { @@ -472,7 +488,7 @@ try_again: if (file == -1) { *success = FALSE; - retry = os_file_handle_error(file, name, + retry = os_file_handle_error(name, create_mode == OS_FILE_OPEN ? "open" : "create"); if (retry) { @@ -678,7 +694,7 @@ try_again: if (file == INVALID_HANDLE_VALUE) { *success = FALSE; - retry = os_file_handle_error(file, name, + retry = os_file_handle_error(name, create_mode == OS_FILE_OPEN ? "open" : "create"); if (retry) { @@ -766,7 +782,7 @@ try_again: if (file == -1) { *success = FALSE; - retry = os_file_handle_error(file, name, + retry = os_file_handle_error(name, create_mode == OS_FILE_OPEN ? "open" : "create"); if (retry) { @@ -801,7 +817,7 @@ os_file_close( return(TRUE); } - os_file_handle_error(file, NULL, "close"); + os_file_handle_error(NULL, "close"); return(FALSE); #else int ret; @@ -809,7 +825,7 @@ os_file_close( ret = close(file); if (ret == -1) { - os_file_handle_error(file, NULL, "close"); + os_file_handle_error(NULL, "close"); return(FALSE); } @@ -1029,7 +1045,7 @@ os_file_flush( return(TRUE); } - os_file_handle_error(file, NULL, "flush"); + os_file_handle_error(NULL, "flush"); /* It is a fatal error if a file flush does not succeed, because then the database can get corrupt on disk */ @@ -1063,7 +1079,7 @@ os_file_flush( fprintf(stderr, " InnoDB: Error: the OS said file flush did not succeed\n"); - os_file_handle_error(file, NULL, "flush"); + os_file_handle_error(NULL, "flush"); /* It is a fatal error if a file flush does not succeed, because then the database can get corrupt on disk */ @@ -1323,7 +1339,7 @@ try_again: #ifdef __WIN__ error_handling: #endif - retry = os_file_handle_error(file, NULL, "read"); + retry = os_file_handle_error(NULL, "read"); if (retry) { goto try_again; @@ -2278,7 +2294,7 @@ try_again: os_aio_array_free_slot(array, slot); - retry = os_file_handle_error(file, name, + retry = os_file_handle_error(name, type == OS_FILE_READ ? "aio read" : "aio write"); if (retry) { @@ -2378,7 +2394,7 @@ os_aio_windows_handle( ut_a(TRUE == os_file_flush(slot->file)); } } else { - os_file_handle_error(slot->file, slot->name, "Windows aio"); + os_file_handle_error(slot->name, "Windows aio"); ret_val = FALSE; } From 605962a9384912cf665ae33b105326abd5f6a486 Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Fri, 28 May 2004 15:01:16 +0500 Subject: [PATCH 03/17] a fix. (Bug#3738: SQL_CALC_FOUND_ROWS ignores WHERE if LIMIT used, Bug#3845: wrong FOUND_ROWS result) --- mysql-test/r/select_found.result | 17 +++++++++++++++++ mysql-test/t/select_found.test | 19 +++++++++++++++++++ sql/sql_select.cc | 6 ++++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result index 367bdd798b4..444124bcd67 100644 --- a/mysql-test/r/select_found.result +++ b/mysql-test/r/select_found.result @@ -206,3 +206,20 @@ WHERE ( r = 1 AND a IN ( 1, 2 ) AND ( u = 'w' OR u LIKE 'w/%' ) ) OR ( r = 1 AND a IN ( 3 ) AND ( u = 'w/U' OR u LIKE 'w/U/%' ) ) OR ( r = 1 AND a IN ( 1, 2, 3 ) AND ( u = 'w' ) ); drop table t1; +CREATE TABLE t1 (a VARCHAR(16), UNIQUE(a)); +INSERT INTO t1 VALUES ('1'), ('2'), ('3'); +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a = '2' LIMIT 0, 1; +a +2 +SELECT FOUND_ROWS(); +FOUND_ROWS() +1 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0), (0), (1), (2); +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a = 0 GROUP BY a HAVING a > 10; +a +SELECT FOUND_ROWS(); +FOUND_ROWS() +0 +DROP TABLE t1; diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test index e584fca206f..7599277a867 100644 --- a/mysql-test/t/select_found.test +++ b/mysql-test/t/select_found.test @@ -127,3 +127,22 @@ WHERE ( r = 1 AND a IN ( 1, 2 ) AND ( u = 'w' OR u LIKE 'w/%' ) ) OR ( r = 1 AND a IN ( 1, 2, 3 ) AND ( u = 'w' ) ); drop table t1; +# +# Bug #3738: we have a ref key +# + +CREATE TABLE t1 (a VARCHAR(16), UNIQUE(a)); +INSERT INTO t1 VALUES ('1'), ('2'), ('3'); +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a = '2' LIMIT 0, 1; +SELECT FOUND_ROWS(); +DROP TABLE t1; + +# +# Bug #3845: group by, having and empty result +# + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0), (0), (1), (2); +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a = 0 GROUP BY a HAVING a > 10; +SELECT FOUND_ROWS(); +DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b299e3af0b7..5b754186736 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5348,7 +5348,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group && !join->send_group_parts && !join->having && !jt->select_cond && !(jt->select && jt->select->quick) && - !(jt->table->file->table_flags() & HA_NOT_EXACT_COUNT)) + !(jt->table->file->table_flags() & HA_NOT_EXACT_COUNT) && + (jt->ref.key < 0)) { /* Join over all rows in table; Return number of found rows */ TABLE *table=jt->table; @@ -5429,7 +5430,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(-1); /* purecov: inspected */ if (end_of_records) { - join->send_records++; + if (!error) + join->send_records++; DBUG_RETURN(0); } if (!error && From 2e1ded2fe12ae42dfe41b4d536ddb85578ed9f8a Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Sat, 29 May 2004 17:52:20 +0200 Subject: [PATCH 04/17] backport wild_compare fix from 4.1 - bug#3924 --- include/my_sys.h | 2 +- mysys/mf_wcomp.c | 67 ++++++++++++++++++++++++++++++++---------------- mysys/mf_wfile.c | 4 +-- sql/sql_acl.cc | 10 ++++---- sql/sql_acl.h | 2 +- sql/sql_base.cc | 2 +- sql/sql_db.cc | 2 +- sql/sql_parse.cc | 4 +-- sql/sql_show.cc | 6 ++--- 9 files changed, 61 insertions(+), 38 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 8f0040055d6..4934df3c4e5 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -620,7 +620,7 @@ extern my_string my_path(my_string to,const char *progname, const char *own_pathname_part); extern my_string my_load_path(my_string to, const char *path, const char *own_path_prefix); -extern int wild_compare(const char *str,const char *wildstr); +extern int wild_compare(const char *str,const char *wildstr,pbool str_is_pattern); extern my_string my_strcasestr(const char *src,const char *suffix); extern int my_strcasecmp(const char *s,const char *t); extern int my_strsortcmp(const char *s,const char *t); diff --git a/mysys/mf_wcomp.c b/mysys/mf_wcomp.c index bdcfb0501d8..1a01388a3db 100644 --- a/mysys/mf_wcomp.c +++ b/mysys/mf_wcomp.c @@ -23,11 +23,12 @@ char wild_many='*'; char wild_one='?'; -char wild_prefix=0; +char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV */ -int wild_compare(register const char *str, register const char *wildstr) +int wild_compare(register const char *str, register const char *wildstr, + pbool str_is_pattern) { - reg3 int flag; + char cmp; DBUG_ENTER("wild_compare"); while (*wildstr) @@ -35,33 +36,55 @@ int wild_compare(register const char *str, register const char *wildstr) while (*wildstr && *wildstr != wild_many && *wildstr != wild_one) { if (*wildstr == wild_prefix && wildstr[1]) + { wildstr++; - if (*wildstr++ != *str++) DBUG_RETURN(1); + if (str_is_pattern && *str++ != wild_prefix) + DBUG_RETURN(1); + } + if (*wildstr++ != *str++) + DBUG_RETURN(1); } - if (! *wildstr ) DBUG_RETURN (*str != 0); + if (! *wildstr ) + DBUG_RETURN(*str != 0); if (*wildstr++ == wild_one) { - if (! *str++) DBUG_RETURN (1); /* One char; skipp */ + if (! *str || (str_is_pattern && *str == wild_many)) + DBUG_RETURN(1); /* One char; skip */ + if (*str++ == wild_prefix && str_is_pattern && *str) + str++; } else { /* Found '*' */ - if (!*wildstr) DBUG_RETURN(0); /* '*' as last char: OK */ - flag=(*wildstr != wild_many && *wildstr != wild_one); - do + while (str_is_pattern && *str == wild_many) + str++; + for (; *wildstr == wild_many || *wildstr == wild_one; wildstr++) + if (*wildstr == wild_many) + { + while (str_is_pattern && *str == wild_many) + str++; + } + else + { + if (str_is_pattern && *str == wild_prefix && str[1]) + str+=2; + else if (! *str++) + DBUG_RETURN (1); + } + if (!*wildstr) + DBUG_RETURN(0); /* '*' as last char: OK */ + if ((cmp= *wildstr) == wild_prefix && wildstr[1] && !str_is_pattern) + cmp=wildstr[1]; + for (;;str++) { - if (flag) - { - char cmp; - if ((cmp= *wildstr) == wild_prefix && wildstr[1]) - cmp=wildstr[1]; - while (*str && *str != cmp) - str++; - if (!*str) DBUG_RETURN (1); - } - if (wild_compare(str,wildstr) == 0) DBUG_RETURN (0); - } while (*str++ && wildstr[0] != wild_many); - DBUG_RETURN(1); + while (*str && *str != cmp) + str++; + if (!*str) + DBUG_RETURN (1); + if (wild_compare(str,wildstr,str_is_pattern) == 0) + DBUG_RETURN (0); + } + /* We will never come here */ } } - DBUG_RETURN (*str != '\0'); + DBUG_RETURN (*str != 0); } /* wild_compare */ diff --git a/mysys/mf_wfile.c b/mysys/mf_wfile.c index e9e12c72755..067e4b7acc5 100644 --- a/mysys/mf_wfile.c +++ b/mysys/mf_wfile.c @@ -106,7 +106,7 @@ int wf_test(register WF_PACK *wf_pack, register const char *name) not_pos=wf_pack->not_pos; for (i=0 ; i < not_pos; i++) - if (wild_compare(name,wf_pack->wild[i]) == 0) + if (wild_compare(name,wf_pack->wild[i],0) == 0) goto found; if (i) DBUG_RETURN(1); /* No-match */ @@ -115,7 +115,7 @@ found: /* Test that it isn't in not-list */ for (i=not_pos ; i < wf_pack->wilds; i++) - if (wild_compare(name,wf_pack->wild[i]) == 0) + if (wild_compare(name,wf_pack->wild[i],0) == 0) DBUG_RETURN(1); DBUG_RETURN(0); } /* wf_test */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 6d2f662b7df..9b676442995 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -834,7 +834,7 @@ static void acl_insert_db(const char *user, const char *host, const char *db, */ ulong acl_get(const char *host, const char *ip, const char *bin_ip, - const char *user, const char *db) + const char *user, const char *db, my_bool db_is_pattern) { ulong host_access,db_access; uint i,key_length; @@ -868,7 +868,7 @@ ulong acl_get(const char *host, const char *ip, const char *bin_ip, { if (compare_hostname(&acl_db->host,host,ip)) { - if (!acl_db->db || !wild_compare(db,acl_db->db)) + if (!acl_db->db || !wild_compare(db,acl_db->db,db_is_pattern)) { db_access=acl_db->access; if (acl_db->host.hostname) @@ -890,7 +890,7 @@ ulong acl_get(const char *host, const char *ip, const char *bin_ip, ACL_HOST *acl_host=dynamic_element(&acl_hosts,i,ACL_HOST*); if (compare_hostname(&acl_host->host,host,ip)) { - if (!acl_host->db || !wild_compare(db,acl_host->db)) + if (!acl_host->db || !wild_compare(db,acl_host->db,0)) { host_access=acl_host->access; // Fully specified. Take it break; @@ -1222,7 +1222,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, } return (!host->hostname || (hostname && !wild_case_compare(hostname,host->hostname)) || - (ip && !wild_compare(ip,host->hostname))); + (ip && !wild_compare(ip,host->hostname,0))); } @@ -1300,7 +1300,7 @@ static bool test_if_create_new_users(THD *thd) tl.db= (char*) "mysql"; tl.real_name= (char*) "user"; db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, - thd->priv_user, tl.db); + thd->priv_user, tl.db, 0); if (!(db_access & INSERT_ACL)) { if (check_grant(thd,INSERT_ACL,&tl,0,1)) diff --git a/sql/sql_acl.h b/sql/sql_acl.h index bf269e5a7e3..7d8dcfd2079 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -85,7 +85,7 @@ my_bool acl_init(THD *thd, bool dont_read_acl_tables); void acl_reload(THD *thd); void acl_free(bool end=0); ulong acl_get(const char *host, const char *ip, const char *bin_ip, - const char *user, const char *db); + const char *user, const char *db, my_bool db_is_pattern); ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *scramble, char **priv_user, char *priv_host, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6bf0b0bd2ba..c4cad8a8786 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -149,7 +149,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) if (wild) { strxmov(name,entry->table_cache_key,".",entry->real_name,NullS); - if (wild_compare(name,wild)) + if (wild_compare(name,wild,0)) continue; } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 865b2e1328f..2ee725e7432 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -410,7 +410,7 @@ bool mysql_change_db(THD *thd,const char *name) db_access=DB_ACLS; else db_access= (acl_get(thd->host,thd->ip,(char*) &thd->remote.sin_addr, - thd->priv_user,dbname) | + thd->priv_user,dbname,0) | thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7e68db0dcd2..7ddbf79c6fe 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2672,7 +2672,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (!(thd->master_access & SELECT_ACL) && (db && (!thd->db || strcmp(db,thd->db)))) db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, - thd->priv_user, db); /* purecov: inspected */ + thd->priv_user, db, 0); /* purecov: inspected */ *save_priv=thd->master_access | db_access; DBUG_RETURN(FALSE); } @@ -2692,7 +2692,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (db && (!thd->db || strcmp(db,thd->db))) db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, - thd->priv_user, db); /* purecov: inspected */ + thd->priv_user, db, 0); /* purecov: inspected */ else db_access=thd->db_access; // Remove SHOW attribute and access rights we already have diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a4ef735c715..26163ed9bef 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -78,7 +78,7 @@ mysqld_show_dbs(THD *thd,const char *wild) { if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, - thd->priv_user, file_name) || + thd->priv_user, file_name, 0) || (grant_option && !check_grant_db(thd, file_name))) { thd->packet.length(0); @@ -214,7 +214,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, #endif { if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat->st_mode) || - (wild && wild_compare(file->name,wild))) + (wild && wild_compare(file->name,wild, 0))) continue; } } @@ -232,7 +232,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, if (wild_case_compare(file->name,wild)) continue; } - else if (wild_compare(file->name,wild)) + else if (wild_compare(file->name,wild, 0)) continue; } } From 88647105ca8bbc203edf397edc71b6346d825a3e Mon Sep 17 00:00:00 2001 From: "miguel@light." <> Date: Sun, 30 May 2004 04:11:19 -0300 Subject: [PATCH 05/17] VC++ project for to compile the udf_example.cc on Windows --- .../examples/udf_example/udf_example.def | 9 ++ .../examples/udf_example/udf_example.dsp | 111 ++++++++++++++++++ .../examples/udf_example/udf_example.dsw | 29 +++++ 3 files changed, 149 insertions(+) create mode 100644 VC++Files/examples/udf_example/udf_example.def create mode 100644 VC++Files/examples/udf_example/udf_example.dsp create mode 100644 VC++Files/examples/udf_example/udf_example.dsw diff --git a/VC++Files/examples/udf_example/udf_example.def b/VC++Files/examples/udf_example/udf_example.def new file mode 100644 index 00000000000..c1cfeea63f8 --- /dev/null +++ b/VC++Files/examples/udf_example/udf_example.def @@ -0,0 +1,9 @@ +LIBRARY MYUDF +DESCRIPTION 'MySQL Sample for UDF' +VERSION 1.0 +EXPORTS + metaphon + myfunc_double + myfunc_int + sequence + avgcost \ No newline at end of file diff --git a/VC++Files/examples/udf_example/udf_example.dsp b/VC++Files/examples/udf_example/udf_example.dsp new file mode 100644 index 00000000000..bfe4d76bcc7 --- /dev/null +++ b/VC++Files/examples/udf_example/udf_example.dsp @@ -0,0 +1,111 @@ +# Microsoft Developer Studio Project File - Name="udf_example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=udf_example - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "udf_example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "udf_example.mak" CFG="udf_example - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "udf_example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "udf_example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "udf_example - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "UDF_EXAMPLE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "UDF_EXAMPLE_EXPORTS" /D "HAVE_DLOPEN" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x416 /d "NDEBUG" +# ADD RSC /l 0x416 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\lib\opt\strings.lib /nologo /dll /machine:I386 /out:"Release/myudf.dll" + +!ELSEIF "$(CFG)" == "udf_example - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "UDF_EXAMPLE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "UDF_EXAMPLE_EXPORTS" /D "HAVE_DLOPEN" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x416 /d "_DEBUG" +# ADD RSC /l 0x416 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\lib\debug\strings.lib /nologo /dll /debug /machine:I386 /out:"Debug/myudf.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "udf_example - Win32 Release" +# Name "udf_example - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\udf_example.cpp +# End Source File +# Begin Source File + +SOURCE=.\udf_example.def +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/VC++Files/examples/udf_example/udf_example.dsw b/VC++Files/examples/udf_example/udf_example.dsw new file mode 100644 index 00000000000..6716e107f6a --- /dev/null +++ b/VC++Files/examples/udf_example/udf_example.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "udf_example"=.\udf_example.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + From 9145dcef5e5b33bd4618d500118624b59332d20d Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Mon, 31 May 2004 13:53:10 +0500 Subject: [PATCH 06/17] mysql_get_parameter interface fixed --- include/mysql.h | 2 +- libmysql/libmysql.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mysql.h b/include/mysql.h index 1665dd5027e..7db6b36e667 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -263,7 +263,7 @@ typedef struct st_mysql_parameters int STDCALL mysql_server_init(int argc, char **argv, char **groups); void STDCALL mysql_server_end(void); -MYSQL_PARAMETERS *STDCALL mysql_get_parameters(); +MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void); /* Set up and bring down a thread; these function should be called diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 0a23954ae67..b3624ef3e94 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -124,7 +124,7 @@ void STDCALL mysql_server_end() static MYSQL_PARAMETERS mysql_internal_parameters= {&max_allowed_packet, &net_buffer_length}; -MYSQL_PARAMETERS *STDCALL mysql_get_parameters() +MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void) { return &mysql_internal_parameters; } From df8f60560941ed31c287e8e0277fe0849d8cd9ef Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 31 May 2004 16:33:45 +0300 Subject: [PATCH 07/17] InnoDB: Do not get a lock for consistent reads (Bug #3894) --- sql/ha_innodb.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index dee34b47ccb..e09a5e20d34 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4504,6 +4504,17 @@ ha_innobase::start_stmt( prepared for an update of a row */ prebuilt->select_lock_type = LOCK_X; + } else { + /* For other than temporary tables, we obtain + no lock for consistent read (plain SELECT), and + an exclusive lock for SELECT ... FOR UPDATE or + SELECT ... LOCK IN SHARE MODE. */ + + prebuilt->select_lock_type = + thd->lex.sql_command == SQLCOM_SELECT + && thd->lex.lock_option == TL_READ + ? LOCK_NONE + : LOCK_X; } /* Set the MySQL flag to mark that there is an active transaction */ From 2953c23ab04e89addc0daa8bc2d1d52a39da554c Mon Sep 17 00:00:00 2001 From: "jani@a80-186-24-72.elisa-laajakaista.fi" <> Date: Tue, 1 Jun 2004 17:29:24 +0300 Subject: [PATCH 08/17] Changed --log-warnings to be integer instead of boolean. Given --skip-log-warnings will disable warnings, --log-warnings will increment warning level by one, or the level can be given as an optional argument. Default level is 1. Changed aborted connection warning to be logged only if the level is > 1. --- sql/mysqld.cc | 12 ++++++++++-- sql/set_var.cc | 2 +- sql/sql_class.h | 2 +- sql/sql_parse.cc | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 65903d7ce8a..3cd42dbeac1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3944,11 +3944,11 @@ replicating a LOAD DATA INFILE command", 0, 0, 0, 0}, {"log-warnings", 'W', "Log some not critical warnings to the log file", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, 0, 0, 0}, {"warnings", 'W', "Deprecated ; Use --log-warnings instead", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, 0, 0, 0}, { "back_log", OPT_BACK_LOG, "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.", @@ -4656,6 +4656,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'V': print_version(); exit(0); + case 'W': + if (!argument) + global_system_variables.log_warnings++; + else if (argument == disabled_my_option) + global_system_variables.log_warnings= 0L; + else + global_system_variables.log_warnings= atoi(argument); + break; case 'I': case '?': usage(); diff --git a/sql/set_var.cc b/sql/set_var.cc index 525da26a5ac..4b66a621f62 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -133,7 +133,7 @@ sys_var_ulonglong_ptr sys_key_buffer_size("key_buffer_size", fix_key_buffer_size); sys_var_bool_ptr sys_local_infile("local_infile", &opt_local_infile); -sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings); +sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings); sys_var_thd_ulong sys_long_query_time("long_query_time", &SV::long_query_time); sys_var_thd_bool sys_low_priority_updates("low_priority_updates", diff --git a/sql/sql_class.h b/sql/sql_class.h index 9663957963f..484a442af20 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -333,8 +333,8 @@ struct system_variables ulong query_prealloc_size; ulong trans_alloc_block_size; ulong trans_prealloc_size; + ulong log_warnings; - my_bool log_warnings; my_bool low_priority_updates; my_bool new_mode; my_bool query_cache_wlock_invalidate; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7ddbf79c6fe..a9723108674 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -742,7 +742,7 @@ pthread_handler_decl(handle_one_connection,arg) free_root(&thd->mem_root,MYF(0)); if (net->error && net->vio != 0) { - if (!thd->killed && thd->variables.log_warnings) + if (!thd->killed && thd->variables.log_warnings > 1) sql_print_error(ER(ER_NEW_ABORTING_CONNECTION), thd->thread_id,(thd->db ? thd->db : "unconnected"), thd->user ? thd->user : "unauthenticated", From aac5c88bcd1b83a7465b9c18c0805abbb564b3a9 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 1 Jun 2004 19:19:48 +0300 Subject: [PATCH 09/17] row0mysql.c, row0mysql.h, ha_innodb.cc: Inside LOCK TABLES, use either LOCK_S or LOCK_X in locking reads; an improvent over the previous patch --- innobase/include/row0mysql.h | 3 +++ innobase/row/row0mysql.c | 1 + sql/ha_innodb.cc | 40 ++++++++++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index a74c5bf4c60..e088071a1c4 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -507,6 +507,9 @@ struct row_prebuilt_struct { dtuple_t* clust_ref; /* prebuilt dtuple used in sel/upd/del */ ulint select_lock_type;/* LOCK_NONE, LOCK_S, or LOCK_X */ + ulint stored_select_lock_type;/* inside LOCK TABLES, either + LOCK_S or LOCK_X depending on the lock + type */ ulint mysql_row_len; /* length in bytes of a row in the MySQL format */ ulint n_rows_fetched; /* number of rows fetched after diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 228f19c865f..4bbe901532c 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -380,6 +380,7 @@ row_create_prebuilt( prebuilt->clust_pcur = btr_pcur_create_for_mysql(); prebuilt->select_lock_type = LOCK_NONE; + prebuilt->stored_select_lock_type = 99999999; prebuilt->sel_graph = NULL; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e09a5e20d34..df193bde947 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4505,16 +4505,38 @@ ha_innobase::start_stmt( prebuilt->select_lock_type = LOCK_X; } else { - /* For other than temporary tables, we obtain - no lock for consistent read (plain SELECT), and - an exclusive lock for SELECT ... FOR UPDATE or - SELECT ... LOCK IN SHARE MODE. */ + /* When we first come here after LOCK TABLES, + select_lock_type is set to LOCK_S or LOCK_X. Store the value + in case we run also consistent reads and need to restore the + value later. */ - prebuilt->select_lock_type = - thd->lex.sql_command == SQLCOM_SELECT - && thd->lex.lock_option == TL_READ - ? LOCK_NONE - : LOCK_X; + if (prebuilt->select_lock_type != LOCK_NONE) { + prebuilt->stored_select_lock_type = + prebuilt->select_lock_type; + } + + if (prebuilt->stored_select_lock_type != LOCK_S + && prebuilt->stored_select_lock_type != LOCK_X) { + fprintf(stderr, +"InnoDB: Error: select_lock_type is %lu inside ::start_stmt()!\n", + prebuilt->stored_select_lock_type); + + ut_error; + } + + if (thd->lex.sql_command == SQLCOM_SELECT + && thd->lex.lock_option == TL_READ) { + + /* For other than temporary tables, we obtain + no lock for consistent read (plain SELECT) */ + + prebuilt->select_lock_type = LOCK_NONE; + } else { + /* Not a consistent read: restore the + select_lock_type value */ + prebuilt->select_lock_type = + prebuilt->stored_select_lock_type; + } } /* Set the MySQL flag to mark that there is an active transaction */ From 7650da771122c99cb0417bc3605c8335c2ace01e Mon Sep 17 00:00:00 2001 From: "paul@ice.snake.net" <> Date: Tue, 1 Jun 2004 14:18:34 -0500 Subject: [PATCH 10/17] README: Update README URL. (Bug #3678) --- mysql-test/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/README b/mysql-test/README index c5dc3e219de..6ad97adbd2b 100644 --- a/mysql-test/README +++ b/mysql-test/README @@ -8,7 +8,7 @@ conflict with it. All tests must pass. If one or more of them fail on your system, please read the following manual section of how to report the problem: -http://www.mysql.com/doc/M/y/MySQL_test_suite.html +http://dev.mysql.com/doc/mysql/en/MySQL_test_suite.html You can create your own test cases. To create a test case: From 5b905beee1ae8fbec075077b092818533be2dd35 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Tue, 1 Jun 2004 23:34:47 +0300 Subject: [PATCH 11/17] Updated version number Portability fix for netware. (We can't use TRY_RUN when cross compiling) --- configure.in | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index f2b66d1e09d..e346ebfa15e 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.0.20) +AM_INIT_AUTOMAKE(mysql, 4.0.21) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -767,7 +767,14 @@ AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT)) AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init)) # For compress in zlib -MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib) +case $SYSTEM_TYPE in + *netware*) + AC_DEFINE(HAVE_COMPRESS) + ;; + *) + MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib) + ;; +esac #-------------------------------------------------------------------- # Check for TCP wrapper support From 3b313f14f2986cc6069ab55ad9123afe73ba821e Mon Sep 17 00:00:00 2001 From: "greg@mysql.com" <> Date: Tue, 1 Jun 2004 19:35:09 -0100 Subject: [PATCH 12/17] Fix applied to allow building of 4.0.20 for NetWare --- client/mysqltest.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index cdf1648769b..22ce5208445 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -185,7 +185,7 @@ typedef struct */ static char *subst_env_var(const char *cmd); -static int my_popen(const char *cmd, const char *mode); +static FILE *my_popen(const char *cmd, const char *mode); #define popen(A,B) my_popen((A),(B)) #endif /* __NETWARE__ */ @@ -3509,6 +3509,7 @@ static void get_replace_column(struct st_query *q) static char *subst_env_var(const char *str) { char *result; + char *pos; result= pos= my_malloc(MAX_QUERY, MYF(MY_FAE)); while (*str) @@ -3528,7 +3529,7 @@ static char *subst_env_var(const char *str) *str && !isspace(*str) && *str != '\\' && *str != '/' && *str != '$'; str++) - *env_pos++ *str; + *env_pos++= *str; *env_pos= 0; if (!(subst= getenv(env_var))) @@ -3571,11 +3572,11 @@ static char *subst_env_var(const char *str) #undef popen /* Remove wrapper */ -int my_popen(const char *cmd, const char *mode __attribute__((unused)) t) +FILE *my_popen(const char *cmd, const char *mode __attribute__((unused))) { char *subst_cmd; - int res_file; - + FILE *res_file; + subst_cmd= subst_env_var(cmd); res_file= popen(subst_cmd, "r0"); my_free(subst_cmd, MYF(0)); From e6c5715126899bb3889ca3059ca92af2c64b3eb6 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 2 Jun 2004 12:13:49 +0300 Subject: [PATCH 13/17] after merge fixes --- innobase/os/os0file.c | 16 ++++++++-------- sql/ha_innodb.cc | 4 ++-- sql/sql_select.cc | 4 ---- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 6aca90885a6..fafed2a484c 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -539,7 +539,7 @@ os_file_opendir( if (dir == INVALID_HANDLE_VALUE) { if (error_is_fatal) { - os_file_handle_error(NULL, dirname, "opendir"); + os_file_handle_error(dirname, "opendir"); } return(NULL); @@ -550,7 +550,7 @@ os_file_opendir( dir = opendir(dirname); if (dir == NULL && error_is_fatal) { - os_file_handle_error(0, dirname, "opendir"); + os_file_handle_error(dirname, "opendir"); } return(dir); @@ -733,7 +733,7 @@ os_file_create_directory( if (!(rcode != 0 || (GetLastError() == ERROR_FILE_EXISTS && !fail_if_exists))) { /* failure */ - os_file_handle_error(NULL, pathname, "CreateDirectory"); + os_file_handle_error(Npathname, "CreateDirectory"); return(FALSE); } @@ -746,7 +746,7 @@ os_file_create_directory( if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) { /* failure */ - os_file_handle_error(0, pathname, "mkdir"); + os_file_handle_error(pathname, "mkdir"); return(FALSE); } @@ -1274,7 +1274,7 @@ loop: ret = unlink((const char*)name); if (ret != 0 && errno != ENOENT) { - os_file_handle_error(0, name, "delete"); + os_file_handle_error(name, "delete"); return(FALSE); } @@ -1336,7 +1336,7 @@ loop: ret = unlink((const char*)name); if (ret != 0) { - os_file_handle_error(0, name, "delete"); + os_file_handle_error(name, "delete"); return(FALSE); } @@ -1366,7 +1366,7 @@ os_file_rename( return(TRUE); } - os_file_handle_error(NULL, oldpath, "rename"); + os_file_handle_error(oldpath, "rename"); return(FALSE); #else @@ -1375,7 +1375,7 @@ os_file_rename( ret = rename((const char*)oldpath, (const char*)newpath); if (ret != 0) { - os_file_handle_error(0, oldpath, "rename"); + os_file_handle_error(oldpath, "rename"); return(FALSE); } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4f51d7c7361..dffffd9296e 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4677,8 +4677,8 @@ ha_innobase::start_stmt( ut_error; } - if (thd->lex.sql_command == SQLCOM_SELECT - && thd->lex.lock_option == TL_READ) { + if (thd->lex->sql_command == SQLCOM_SELECT + && thd->lex->lock_option == TL_READ) { /* For other than temporary tables, we obtain no lock for consistent read (plain SELECT) */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0abfb483820..b87f88a3988 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6463,11 +6463,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (error > 0) DBUG_RETURN(-1); /* purecov: inspected */ if (end_of_records) - { - if (!error) - join->send_records++; DBUG_RETURN(0); - } if (join->send_records >= join->unit->select_limit_cnt && join->do_send_rows) { From 7cf1d2596b0d01664d820cd22d315bf910d9d4d6 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 2 Jun 2004 19:11:57 +0500 Subject: [PATCH 14/17] wl 1562 (To improve RTree indexes) some changes to make code nicer --- include/myisampack.h | 7 + myisam/rt_index.c | 12 +- myisam/rt_mbr.c | 451 ++++++++++++++-------------------- myisam/rt_test.c | 62 ++++- mysql-test/r/gis-rtree.result | 10 +- 5 files changed, 264 insertions(+), 278 deletions(-) diff --git a/include/myisampack.h b/include/myisampack.h index 95793e2aaeb..06c94fea75f 100644 --- a/include/myisampack.h +++ b/include/myisampack.h @@ -21,6 +21,10 @@ better compression */ +/* these two are for uniformity */ +#define mi_sint1korr(A) (int8)(*A) +#define mi_uint1korr(A) (uint8)(*A) + #define mi_sint2korr(A) (int16) (((int16) ((uchar) (A)[1])) +\ ((int16) ((int16) (A)[0]) << 8)) #define mi_sint3korr(A) ((int32) ((((uchar) (A)[0]) & 128) ? \ @@ -75,6 +79,9 @@ (((uint32) ((uchar) (A)[0])) << 24))) <<\ 32)) +/* This one is for uniformity */ +#define mi_int1store(T,A) *((uchar*)(T))= (uchar) (A) + #define mi_int2store(T,A) { uint def_temp= (uint) (A) ;\ *((uchar*) ((T)+1))= (uchar)(def_temp); \ *((uchar*) ((T)+0))= (uchar)(def_temp >> 8); } diff --git a/myisam/rt_index.c b/myisam/rt_index.c index 824cb7a396f..8d8a5412c7b 100644 --- a/myisam/rt_index.c +++ b/myisam/rt_index.c @@ -462,21 +462,13 @@ static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, if ((increase = rtree_perimeter_increase(keyinfo->seg, k, key, key_length, &perimeter)) == -1) return NULL; - if (increase < best_incr) + if ((increase < best_incr)|| + (increase == best_incr && perimeter < best_perimeter)) { best_key = k; best_perimeter= perimeter; best_incr = increase; } - else - { - if ((increase == best_incr) && (perimeter < best_perimeter)) - { - best_key = k; - best_perimeter= perimeter; - best_incr = increase; - } - } } return best_key; } diff --git a/myisam/rt_mbr.c b/myisam/rt_mbr.c index da427e4b67a..1f036eff196 100644 --- a/myisam/rt_mbr.c +++ b/myisam/rt_mbr.c @@ -24,7 +24,7 @@ #define CONTAIN_CMP(amin, amax, bmin, bmax) ((bmin > amin) || (bmax < amax)) #define WITHIN_CMP(amin, amax, bmin, bmax) ((amin > bmin) || (amax < bmax)) #define DISJOINT_CMP(amin, amax, bmin, bmax) ((amin <= bmax) && (bmin <= amax)) -#define EQUAL_CMP(amix, amax, bmin, bmax) ((amix != bmin) || (amax != bmax)) +#define EQUAL_CMP(amin, amax, bmin, bmax) ((amin != bmin) || (amax != bmax)) #define FCMP(A, B) ((int)(A) - (int)(B)) #define p_inc(A, B, X) {A += X; B += X;} @@ -61,12 +61,9 @@ type amin, amax, bmin, bmax; \ amin = korr_func(a); \ bmin = korr_func(b); \ - p_inc(a, b, len); \ - amax = korr_func(a); \ - bmax = korr_func(b); \ + amax = korr_func(a+len); \ + bmax = korr_func(b+len); \ RT_CMP(nextflag); \ - p_inc(a, b, len); \ - break; \ } #define RT_CMP_GET(type, get_func, len, nextflag) \ @@ -74,12 +71,9 @@ type amin, amax, bmin, bmax; \ get_func(amin, a); \ get_func(bmin, b); \ - p_inc(a, b, len); \ - get_func(amax, a); \ - get_func(bmax, b); \ + get_func(amax, a+len); \ + get_func(bmax, b+len); \ RT_CMP(nextflag); \ - p_inc(a, b, len); \ - break; \ } /* @@ -98,54 +92,54 @@ int rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length, { for (; (int) key_length > 0; keyseg += 2 ) { - key_length -= keyseg->length * 2; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return 1; - break; case HA_KEYTYPE_INT8: - { - int amin,amax,bmin,bmax; - amin = (int)*((signed char *)a); - bmin = (int)*((signed char *)b); - p_inc(a, b, 1); - amax = (int)*((signed char *)a); - bmax = (int)*((signed char *)b); - RT_CMP(nextflag); - p_inc(a, b, 1); - break; - } + RT_CMP_KORR(int8, mi_sint1korr, 1, nextflag); + break; + case HA_KEYTYPE_BINARY: + RT_CMP_KORR(uint8, mi_uint1korr, 1, nextflag); + break; case HA_KEYTYPE_SHORT_INT: RT_CMP_KORR(int16, mi_sint2korr, 2, nextflag); + break; case HA_KEYTYPE_USHORT_INT: RT_CMP_KORR(uint16, mi_uint2korr, 2, nextflag); + break; case HA_KEYTYPE_INT24: RT_CMP_KORR(int32, mi_sint3korr, 3, nextflag); + break; case HA_KEYTYPE_UINT24: RT_CMP_KORR(uint32, mi_uint3korr, 3, nextflag); + break; case HA_KEYTYPE_LONG_INT: RT_CMP_KORR(int32, mi_sint4korr, 4, nextflag); + break; case HA_KEYTYPE_ULONG_INT: RT_CMP_KORR(uint32, mi_uint4korr, 4, nextflag); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_CMP_KORR(longlong, mi_sint8korr, 8, nextflag) + break; case HA_KEYTYPE_ULONGLONG: RT_CMP_KORR(ulonglong, mi_uint8korr, 8, nextflag) + break; #endif case HA_KEYTYPE_FLOAT: RT_CMP_GET(float, mi_float4get, 4, nextflag); + break; case HA_KEYTYPE_DOUBLE: RT_CMP_GET(double, mi_float8get, 8, nextflag); + break; case HA_KEYTYPE_END: goto end; + default: + return 1; } + uint32 keyseg_length= keyseg->length * 2; + key_length-= keyseg_length; + a+= keyseg_length; + b+= keyseg_length; } end: @@ -165,22 +159,16 @@ end: { \ type amin, amax; \ amin = korr_func(a); \ - a += len; \ - amax = korr_func(a); \ - a += len; \ + amax = korr_func(a+len); \ res *= (cast(amax) - cast(amin)); \ - break; \ } #define RT_VOL_GET(type, get_func, len, cast) \ { \ type amin, amax; \ get_func(amin, a); \ - a += len; \ - get_func(amax, a); \ - a += len; \ + get_func(amax, a+len); \ res *= (cast(amax) - cast(amin)); \ - break; \ } /* @@ -191,53 +179,54 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) double res = 1; for (; (int)key_length > 0; keyseg += 2) { - key_length -= keyseg->length * 2; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return 1; - break; case HA_KEYTYPE_INT8: - { - int amin, amax; - amin = (int)*((signed char *)a); - a += 1; - amax = (int)*((signed char *)a); - a += 1; - res *= ((double)amax - (double)amin); - break; - } + RT_VOL_KORR(int8, mi_sint1korr, 1, (double)); + break; + case HA_KEYTYPE_BINARY: + RT_VOL_KORR(uint8, mi_uint1korr, 1, (double)); + break; case HA_KEYTYPE_SHORT_INT: RT_VOL_KORR(int16, mi_sint2korr, 2, (double)); + break; case HA_KEYTYPE_USHORT_INT: RT_VOL_KORR(uint16, mi_uint2korr, 2, (double)); + break; case HA_KEYTYPE_INT24: RT_VOL_KORR(int32, mi_sint3korr, 3, (double)); + break; case HA_KEYTYPE_UINT24: RT_VOL_KORR(uint32, mi_uint3korr, 3, (double)); + break; case HA_KEYTYPE_LONG_INT: RT_VOL_KORR(int32, mi_sint4korr, 4, (double)); + break; case HA_KEYTYPE_ULONG_INT: RT_VOL_KORR(uint32, mi_uint4korr, 4, (double)); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_VOL_KORR(longlong, mi_sint8korr, 8, (double)); + break; case HA_KEYTYPE_ULONGLONG: RT_VOL_KORR(longlong, mi_sint8korr, 8, ulonglong2double); + break; #endif case HA_KEYTYPE_FLOAT: RT_VOL_GET(float, mi_float4get, 4, (double)); + break; case HA_KEYTYPE_DOUBLE: RT_VOL_GET(double, mi_float8get, 8, (double)); + break; case HA_KEYTYPE_END: key_length = 0; break; + default: + return -1; } + uint32 keyseg_length= keyseg->length * 2; + key_length-= keyseg_length; + a+= keyseg_length; } return res; } @@ -246,24 +235,18 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) { \ type amin, amax; \ amin = korr_func(a); \ - a += len; \ - amax = korr_func(a); \ - a += len; \ + amax = korr_func(a+len); \ *res++ = cast(amin); \ *res++ = cast(amax); \ - break; \ } #define RT_D_MBR_GET(type, get_func, len, cast) \ { \ type amin, amax; \ get_func(amin, a); \ - a += len; \ - get_func(amax, a); \ - a += len; \ + get_func(amax, a+len); \ *res++ = cast(amin); \ *res++ = cast(amax); \ - break; \ } /* @@ -273,54 +256,54 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) { for (; (int)key_length > 0; keyseg += 2) { - key_length -= keyseg->length * 2; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return 1; - break; case HA_KEYTYPE_INT8: - { - int amin, amax; - amin = (int)*((signed char *)a); - a += 1; - amax = (int)*((signed char *)a); - a += 1; - *res++ = (double)amin; - *res++ = (double)amax; - break; - } + RT_D_MBR_KORR(int8, mi_sint1korr, 1, (double)); + break; + case HA_KEYTYPE_BINARY: + RT_D_MBR_KORR(uint8, mi_uint1korr, 1, (double)); + break; case HA_KEYTYPE_SHORT_INT: RT_D_MBR_KORR(int16, mi_sint2korr, 2, (double)); + break; case HA_KEYTYPE_USHORT_INT: RT_D_MBR_KORR(uint16, mi_uint2korr, 2, (double)); + break; case HA_KEYTYPE_INT24: RT_D_MBR_KORR(int32, mi_sint3korr, 3, (double)); + break; case HA_KEYTYPE_UINT24: RT_D_MBR_KORR(uint32, mi_uint3korr, 3, (double)); + break; case HA_KEYTYPE_LONG_INT: RT_D_MBR_KORR(int32, mi_sint4korr, 4, (double)); + break; case HA_KEYTYPE_ULONG_INT: RT_D_MBR_KORR(uint32, mi_uint4korr, 4, (double)); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_D_MBR_KORR(longlong, mi_sint8korr, 8, (double)); + break; case HA_KEYTYPE_ULONGLONG: RT_D_MBR_KORR(longlong, mi_sint8korr, 8, ulonglong2double); + break; #endif case HA_KEYTYPE_FLOAT: RT_D_MBR_GET(float, mi_float4get, 4, (double)); + break; case HA_KEYTYPE_DOUBLE: RT_D_MBR_GET(double, mi_float8get, 8, (double)); + break; case HA_KEYTYPE_END: key_length = 0; break; + default: + return 1; } + uint32 keyseg_length= keyseg->length * 2; + key_length-= keyseg_length; + a+= keyseg_length; } return 0; } @@ -330,17 +313,12 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) type amin, amax, bmin, bmax; \ amin = korr_func(a); \ bmin = korr_func(b); \ - p_inc(a, b, len); \ - amax = korr_func(a); \ - bmax = korr_func(b); \ - p_inc(a, b, len); \ + amax = korr_func(a+len); \ + bmax = korr_func(b+len); \ amin = min(amin, bmin); \ amax = max(amax, bmax); \ store_func(c, amin); \ - c += len; \ - store_func(c, amax); \ - c += len; \ - break; \ + store_func(c+len, amax); \ } #define RT_COMB_GET(type, get_func, store_func, len) \ @@ -348,17 +326,12 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) type amin, amax, bmin, bmax; \ get_func(amin, a); \ get_func(bmin, b); \ - p_inc(a, b, len); \ - get_func(amax, a); \ - get_func(bmax, b); \ - p_inc(a, b, len); \ + get_func(amax, a+len); \ + get_func(bmax, b+len); \ amin = min(amin, bmin); \ amax = max(amax, bmax); \ store_func(c, amin); \ - c += len; \ - store_func(c, amax); \ - c += len; \ - break; \ + store_func(c+len, amax); \ } /* @@ -370,62 +343,57 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, uint key_length) { - for ( ; (int) key_length > 0 ; keyseg += 2) { - key_length -= keyseg->length * 2; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return 1; - break; case HA_KEYTYPE_INT8: - { - int amin, amax, bmin, bmax; - amin = (int)*((signed char *)a); - bmin = (int)*((signed char *)b); - p_inc(a, b, 1); - amax = (int)*((signed char *)a); - bmax = (int)*((signed char *)b); - p_inc(a, b, 1); - amin = min(amin, bmin); - amax = max(amax, bmax); - *((signed char*)c) = amin; - c += 1; - *((signed char*)c) = amax; - c += 1; - break; - } + RT_COMB_KORR(int8, mi_sint1korr, mi_int1store, 1); + break; + case HA_KEYTYPE_BINARY: + RT_COMB_KORR(uint8, mi_uint1korr, mi_int1store, 1); + break; case HA_KEYTYPE_SHORT_INT: RT_COMB_KORR(int16, mi_sint2korr, mi_int2store, 2); + break; case HA_KEYTYPE_USHORT_INT: RT_COMB_KORR(uint16, mi_uint2korr, mi_int2store, 2); + break; case HA_KEYTYPE_INT24: RT_COMB_KORR(int32, mi_sint3korr, mi_int3store, 3); + break; case HA_KEYTYPE_UINT24: RT_COMB_KORR(uint32, mi_uint3korr, mi_int3store, 3); + break; case HA_KEYTYPE_LONG_INT: RT_COMB_KORR(int32, mi_sint4korr, mi_int4store, 4); + break; case HA_KEYTYPE_ULONG_INT: RT_COMB_KORR(uint32, mi_uint4korr, mi_int4store, 4); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_COMB_KORR(longlong, mi_sint8korr, mi_int8store, 8); + break; case HA_KEYTYPE_ULONGLONG: RT_COMB_KORR(ulonglong, mi_uint8korr, mi_int8store, 8); + break; #endif case HA_KEYTYPE_FLOAT: RT_COMB_GET(float, mi_float4get, mi_float4store, 4); + break; case HA_KEYTYPE_DOUBLE: RT_COMB_GET(double, mi_float8get, mi_float8store, 8); + break; case HA_KEYTYPE_END: return 0; + default: + return 1; } + uint32 keyseg_length= keyseg->length * 2; + key_length-= keyseg_length; + a+= keyseg_length; + b+= keyseg_length; + c+= keyseg_length; } return 0; } @@ -435,16 +403,13 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, type amin, amax, bmin, bmax; \ amin = korr_func(a); \ bmin = korr_func(b); \ - p_inc(a, b, len); \ - amax = korr_func(a); \ - bmax = korr_func(b); \ - p_inc(a, b, len); \ + amax = korr_func(a+len); \ + bmax = korr_func(b+len); \ amin = max(amin, bmin); \ amax = min(amax, bmax); \ if (amin >= amax) \ return 0; \ res *= amax - amin; \ - break; \ } #define RT_OVL_AREA_GET(type, get_func, len) \ @@ -452,16 +417,13 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, type amin, amax, bmin, bmax; \ get_func(amin, a); \ get_func(bmin, b); \ - p_inc(a, b, len); \ - get_func(amax, a); \ - get_func(bmax, b); \ - p_inc(a, b, len); \ + get_func(amax, a+len); \ + get_func(bmax, b+len); \ amin = max(amin, bmin); \ amax = min(amax, bmax); \ if (amin >= amax) \ return 0; \ res *= amax - amin; \ - break; \ } /* @@ -473,58 +435,54 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, double res = 1; for (; (int) key_length > 0 ; keyseg += 2) { - key_length -= keyseg->length * 2; - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return -1; - break; case HA_KEYTYPE_INT8: - { - int amin, amax, bmin, bmax; - amin = (int)*((signed char *)a); - bmin = (int)*((signed char *)b); - p_inc(a, b, 1); - amax = (int)*((signed char *)a); - bmax = (int)*((signed char *)b); - p_inc(a, b, 1); - amin = max(amin, bmin); - amax = min(amax, bmax); - if (amin >= amax) - return 0; - res *= amax - amin; - break; - } + RT_OVL_AREA_KORR(int8, mi_sint1korr, 1); + break; + case HA_KEYTYPE_BINARY: + RT_OVL_AREA_KORR(uint8, mi_uint1korr, 1); + break; case HA_KEYTYPE_SHORT_INT: RT_OVL_AREA_KORR(int16, mi_sint2korr, 2); + break; case HA_KEYTYPE_USHORT_INT: RT_OVL_AREA_KORR(uint16, mi_uint2korr, 2); + break; case HA_KEYTYPE_INT24: RT_OVL_AREA_KORR(int32, mi_sint3korr, 3); + break; case HA_KEYTYPE_UINT24: RT_OVL_AREA_KORR(uint32, mi_uint3korr, 3); + break; case HA_KEYTYPE_LONG_INT: RT_OVL_AREA_KORR(int32, mi_sint4korr, 4); + break; case HA_KEYTYPE_ULONG_INT: RT_OVL_AREA_KORR(uint32, mi_uint4korr, 4); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8); + break; case HA_KEYTYPE_ULONGLONG: RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8); + break; #endif case HA_KEYTYPE_FLOAT: RT_OVL_AREA_GET(float, mi_float4get, 4); + break; case HA_KEYTYPE_DOUBLE: RT_OVL_AREA_GET(double, mi_float8get, 8); + break; case HA_KEYTYPE_END: return res; + default: + return -1; } + uint32 keyseg_length= keyseg->length * 2; + key_length-= keyseg_length; + a+= keyseg_length; + b+= keyseg_length; } return res; } @@ -534,13 +492,10 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, type amin, amax, bmin, bmax; \ amin = korr_func(a); \ bmin = korr_func(b); \ - p_inc(a, b, len); \ - amax = korr_func(a); \ - bmax = korr_func(b); \ - p_inc(a, b, len); \ + amax = korr_func(a+len); \ + bmax = korr_func(b+len); \ a_area *= (((double)amax) - ((double)amin)); \ *ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ - break; \ } #define RT_AREA_INC_GET(type, get_func, len)\ @@ -548,13 +503,10 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, type amin, amax, bmin, bmax; \ get_func(amin, a); \ get_func(bmin, b); \ - p_inc(a, b, len); \ - get_func(amax, a); \ - get_func(bmax, b); \ - p_inc(a, b, len); \ + get_func(amax, a+len); \ + get_func(bmax, b+len); \ a_area *= (((double)amax) - ((double)amin)); \ *ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ - break; \ } /* @@ -568,8 +520,6 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, *ab_area= 1.0; for (; (int)key_length > 0; keyseg += 2) { - key_length -= keyseg->length * 2; - /* Handle NULL part */ if (keyseg->null_bit) { @@ -577,52 +527,53 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, } switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return 1; - break; case HA_KEYTYPE_INT8: - { - int amin, amax, bmin, bmax; - amin = (int)*((signed char *)a); - bmin = (int)*((signed char *)b); - p_inc(a, b, 1); - amax = (int)*((signed char *)a); - bmax = (int)*((signed char *)b); - p_inc(a, b, 1); - a_area *= (((double)amax) - ((double)amin)); - *ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); - break; - } + RT_AREA_INC_KORR(int8, mi_sint1korr, 1); + break; + case HA_KEYTYPE_BINARY: + RT_AREA_INC_KORR(uint8, mi_uint1korr, 1); + break; case HA_KEYTYPE_SHORT_INT: RT_AREA_INC_KORR(int16, mi_sint2korr, 2); + break; case HA_KEYTYPE_USHORT_INT: RT_AREA_INC_KORR(uint16, mi_uint2korr, 2); + break; case HA_KEYTYPE_INT24: RT_AREA_INC_KORR(int32, mi_sint3korr, 3); + break; case HA_KEYTYPE_UINT24: RT_AREA_INC_KORR(int32, mi_uint3korr, 3); + break; case HA_KEYTYPE_LONG_INT: RT_AREA_INC_KORR(int32, mi_sint4korr, 4); + break; case HA_KEYTYPE_ULONG_INT: RT_AREA_INC_KORR(uint32, mi_uint4korr, 4); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_AREA_INC_KORR(longlong, mi_sint8korr, 8); + break; case HA_KEYTYPE_ULONGLONG: RT_AREA_INC_KORR(longlong, mi_sint8korr, 8); + break; #endif case HA_KEYTYPE_FLOAT: RT_AREA_INC_GET(float, mi_float4get, 4); + break; case HA_KEYTYPE_DOUBLE: RT_AREA_INC_GET(double, mi_float8get, 8); + break; case HA_KEYTYPE_END: return *ab_area - a_area; + default: + return -1; } + uint32 keyseg_length= keyseg->length * 2; + key_length-= keyseg_length; + a+= keyseg_length; + b+= keyseg_length; } return *ab_area - a_area; } @@ -632,13 +583,10 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, type amin, amax, bmin, bmax; \ amin = korr_func(a); \ bmin = korr_func(b); \ - p_inc(a, b, len); \ - amax = korr_func(a); \ - bmax = korr_func(b); \ - p_inc(a, b, len); \ + amax = korr_func(a+len); \ + bmax = korr_func(b+len); \ a_perim+= (((double)amax) - ((double)amin)); \ *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ - break; \ } #define RT_PERIM_INC_GET(type, get_func, len)\ @@ -646,13 +594,10 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, type amin, amax, bmin, bmax; \ get_func(amin, a); \ get_func(bmin, b); \ - p_inc(a, b, len); \ - get_func(amax, a); \ - get_func(bmax, b); \ - p_inc(a, b, len); \ + get_func(amax, a+len); \ + get_func(bmax, b+len); \ a_perim+= (((double)amax) - ((double)amin)); \ *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ - break; \ } /* @@ -666,8 +611,6 @@ double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, *ab_perim= 0.0; for (; (int)key_length > 0; keyseg += 2) { - key_length -= keyseg->length * 2; - /* Handle NULL part */ if (keyseg->null_bit) { @@ -675,52 +618,53 @@ double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, } switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return 1; - break; case HA_KEYTYPE_INT8: - { - int amin, amax, bmin, bmax; - amin = (int)*((signed char *)a); - bmin = (int)*((signed char *)b); - p_inc(a, b, 1); - amax = (int)*((signed char *)a); - bmax = (int)*((signed char *)b); - p_inc(a, b, 1); - a_perim+= (((double)amax) - ((double)amin)); - *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); - break; - } + RT_PERIM_INC_KORR(int8, mi_sint1korr, 1); + break; + case HA_KEYTYPE_BINARY: + RT_PERIM_INC_KORR(uint8, mi_uint1korr, 1); + break; case HA_KEYTYPE_SHORT_INT: RT_PERIM_INC_KORR(int16, mi_sint2korr, 2); + break; case HA_KEYTYPE_USHORT_INT: RT_PERIM_INC_KORR(uint16, mi_uint2korr, 2); + break; case HA_KEYTYPE_INT24: RT_PERIM_INC_KORR(int32, mi_sint3korr, 3); + break; case HA_KEYTYPE_UINT24: RT_PERIM_INC_KORR(int32, mi_uint3korr, 3); + break; case HA_KEYTYPE_LONG_INT: RT_PERIM_INC_KORR(int32, mi_sint4korr, 4); + break; case HA_KEYTYPE_ULONG_INT: RT_PERIM_INC_KORR(uint32, mi_uint4korr, 4); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8); + break; case HA_KEYTYPE_ULONGLONG: RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8); + break; #endif case HA_KEYTYPE_FLOAT: RT_PERIM_INC_GET(float, mi_float4get, 4); + break; case HA_KEYTYPE_DOUBLE: RT_PERIM_INC_GET(double, mi_float8get, 8); + break; case HA_KEYTYPE_END: return *ab_perim - a_perim; + default: + return -1; } + uint32 keyseg_length= keyseg->length * 2; + key_length-= keyseg_length; + a+= keyseg_length; + b+= keyseg_length; } return *ab_perim - a_perim; } @@ -746,7 +690,6 @@ double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, store_func(c, amax); \ c += len; \ inc += 2 * len; \ - break; \ } #define RT_PAGE_MBR_GET(type, get_func, store_func, len) \ @@ -769,7 +712,6 @@ double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, store_func(c, amax); \ c += len; \ inc += 2 * len; \ - break; \ } /* @@ -797,61 +739,48 @@ int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf, k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: - case HA_KEYTYPE_BINARY: - case HA_KEYTYPE_VARTEXT: - case HA_KEYTYPE_VARBINARY: - case HA_KEYTYPE_NUM: - default: - return 1; - break; case HA_KEYTYPE_INT8: - { - int amin, amax, bmin, bmax; - amin = (int)*((signed char *)(k + inc)); - amax = (int)*((signed char *)(k + inc + 1)); - k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); - for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) - { - bmin = (int)*((signed char *)(k + inc)); - bmax = (int)*((signed char *)(k + inc + 1)); - - if (amin > bmin) - amin = bmin; - if (amax < bmax) - amax = bmax; - } - *((signed char*)c) = amin; - c += 1; - *((signed char*)c) = amax; - c += 1; - inc += 1 * 2; - break; - } + RT_PAGE_MBR_KORR(int8, mi_sint1korr, mi_int1store, 1); + break; + case HA_KEYTYPE_BINARY: + RT_PAGE_MBR_KORR(uint8, mi_uint1korr, mi_int1store, 1); + break; case HA_KEYTYPE_SHORT_INT: RT_PAGE_MBR_KORR(int16, mi_sint2korr, mi_int2store, 2); + break; case HA_KEYTYPE_USHORT_INT: RT_PAGE_MBR_KORR(uint16, mi_uint2korr, mi_int2store, 2); + break; case HA_KEYTYPE_INT24: RT_PAGE_MBR_KORR(int32, mi_sint3korr, mi_int3store, 3); + break; case HA_KEYTYPE_UINT24: RT_PAGE_MBR_KORR(uint32, mi_uint3korr, mi_int3store, 3); + break; case HA_KEYTYPE_LONG_INT: RT_PAGE_MBR_KORR(int32, mi_sint4korr, mi_int4store, 4); + break; case HA_KEYTYPE_ULONG_INT: RT_PAGE_MBR_KORR(uint32, mi_uint4korr, mi_int4store, 4); + break; #ifdef HAVE_LONG_LONG case HA_KEYTYPE_LONGLONG: RT_PAGE_MBR_KORR(longlong, mi_sint8korr, mi_int8store, 8); + break; case HA_KEYTYPE_ULONGLONG: RT_PAGE_MBR_KORR(ulonglong, mi_uint8korr, mi_int8store, 8); + break; #endif case HA_KEYTYPE_FLOAT: RT_PAGE_MBR_GET(float, mi_float4get, mi_float4store, 4); + break; case HA_KEYTYPE_DOUBLE: RT_PAGE_MBR_GET(double, mi_float8get, mi_float8store, 8); + break; case HA_KEYTYPE_END: return 0; + default: + return 1; } } return 0; diff --git a/myisam/rt_test.c b/myisam/rt_test.c index bbeb8fce2d1..db4231aa0f5 100644 --- a/myisam/rt_test.c +++ b/myisam/rt_test.c @@ -31,6 +31,51 @@ static void create_record1(char *record,uint rownr); static void print_record(char * record,my_off_t offs,const char * tail); static int run_test(const char *filename); +static double rt_data[]= +{ + /*1*/ 0,10,0,10, + /*2*/ 5,15,0,10, + /*3*/ 0,10,5,15, + /*4*/ 10,20,10,20, + /*5*/ 0,10,0,10, + /*6*/ 5,15,0,10, + /*7*/ 0,10,5,15, + /*8*/ 10,20,10,20, + /*9*/ 0,10,0,10, + /*10*/ 5,15,0,10, + /*11*/ 0,10,5,15, + /*12*/ 10,20,10,20, + /*13*/ 0,10,0,10, + /*14*/ 5,15,0,10, + /*15*/ 0,10,5,15, + /*16*/ 10,20,10,20, + /*17*/ 5,15,0,10, + /*18*/ 0,10,5,15, + /*19*/ 10,20,10,20, + /*20*/ 0,10,0,10, + + /*1*/ 100,110,0,10, + /*2*/ 105,115,0,10, + /*3*/ 100,110,5,15, + /*4*/ 110,120,10,20, + /*5*/ 100,110,0,10, + /*6*/ 105,115,0,10, + /*7*/ 100,110,5,15, + /*8*/ 110,120,10,20, + /*9*/ 100,110,0,10, + /*10*/ 105,115,0,10, + /*11*/ 100,110,5,15, + /*12*/ 110,120,10,20, + /*13*/ 100,110,0,10, + /*14*/ 105,115,0,10, + /*15*/ 100,110,5,15, + /*16*/ 110,120,10,20, + /*17*/ 105,115,0,10, + /*18*/ 100,110,5,15, + /*19*/ 110,120,10,20, + /*20*/ 100,110,0,10, + -1 +}; int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) { @@ -55,7 +100,7 @@ int run_test(const char *filename) int key_type=HA_KEYTYPE_DOUBLE; int key_length=8; int null_fields=0; - int nrecords=300; + int nrecords=sizeof(rt_data)/(sizeof(double)*4);/* 3000;*/ int rec_length=0; int uniques=0; int i; @@ -399,7 +444,7 @@ static void create_record1(char *record,uint rownr) } -static void create_record(char *record,uint rownr) +static void create_record0(char *record,uint rownr) { int i; char * pos; @@ -419,3 +464,16 @@ static void create_record(char *record,uint rownr) pos+=sizeof(c); } } + +static void create_record(char *record,uint rownr) +{ + int i; + char *pos; + double *data= rt_data+rownr*4; + record[0]=0x01; /* DEL marker */ + for ( pos=record+1, i=0; i Date: Wed, 2 Jun 2004 18:19:28 +0300 Subject: [PATCH 15/17] fil0fil.c: Fix typo spotted by Paul DuBois: 'no continue' -> 'not continue' --- innobase/fil/fil0fil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 539e6aa8687..38d06c5bfba 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -2573,7 +2573,7 @@ fil_load_single_table_tablespace( fprintf(stderr, "InnoDB: Error: could not open single-table tablespace file\n" "InnoDB: %s!\n" -"InnoDB: We do no continue crash recovery, because the table will become\n" +"InnoDB: We do not continue crash recovery, because the table will become\n" "InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.\n" "InnoDB: To fix the problem and start mysqld:\n" "InnoDB: 1) If there is a permission problem in the file and mysqld cannot\n" @@ -2607,7 +2607,7 @@ fil_load_single_table_tablespace( fprintf(stderr, "InnoDB: Error: could not measure the size of single-table tablespace file\n" "InnoDB: %s!\n" -"InnoDB: We do no continue crash recovery, because the table will become\n" +"InnoDB: We do not continue crash recovery, because the table will become\n" "InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.\n" "InnoDB: To fix the problem and start mysqld:\n" "InnoDB: 1) If there is a permission problem in the file and mysqld cannot\n" From 42c35d45697b529dcb4d69c3c21b7c7772be38db Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 3 Jun 2004 01:55:47 +0300 Subject: [PATCH 16/17] Added authentication code that was missed in merge Added new windows configuration --- VC++Files/client/mysqlclient.dsp | 29 ++++++++++++++++ VC++Files/zlib/zlib.dsp | 27 +++++++++++++++ libmysql/libmysql.c | 52 +--------------------------- sql-common/client.c | 58 +++++++++++++++++++++++++++++++- 4 files changed, 114 insertions(+), 52 deletions(-) diff --git a/VC++Files/client/mysqlclient.dsp b/VC++Files/client/mysqlclient.dsp index c680ba28116..88ae9352139 100644 --- a/VC++Files/client/mysqlclient.dsp +++ b/VC++Files/client/mysqlclient.dsp @@ -19,6 +19,7 @@ CFG=mysqlclient - Win32 Debug !MESSAGE !MESSAGE "mysqlclient - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "mysqlclient - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "mysqlclient - Win32 authent" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project @@ -76,12 +77,38 @@ LIB32=xilink6.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"..\lib_debug\mysqlclient.lib" +!ELSEIF "$(CFG)" == "mysqlclient - Win32 authent" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "mysqlclient___Win32_authent" +# PROP BASE Intermediate_Dir "mysqlclient___Win32_authent" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "authent" +# PROP Intermediate_Dir "authent" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /D "MYSQL_CLIENT" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /D "MYSQL_CLIENT" /D "NDEBUG" /D "CHECK_LICENSE" /D LICENSE=Commercial /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=xilink6.exe -lib +# ADD BASE LIB32 /nologo /out:"..\lib_release\mysqlclient.lib" +# ADD LIB32 /nologo /out:"..\lib_authent\mysqlclient.lib" + !ENDIF # Begin Target # Name "mysqlclient - Win32 Release" # Name "mysqlclient - Win32 Debug" +# Name "mysqlclient - Win32 authent" # Begin Source File SOURCE=..\mysys\array.c @@ -256,6 +283,8 @@ SOURCE=..\mysys\mf_iocache2.c # ADD CPP /Od +!ELSEIF "$(CFG)" == "mysqlclient - Win32 authent" + !ENDIF # End Source File diff --git a/VC++Files/zlib/zlib.dsp b/VC++Files/zlib/zlib.dsp index 6edab34d93c..7093c51d558 100644 --- a/VC++Files/zlib/zlib.dsp +++ b/VC++Files/zlib/zlib.dsp @@ -19,6 +19,7 @@ CFG=zlib - Win32 Debug !MESSAGE !MESSAGE "zlib - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "zlib - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 authent" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project @@ -75,12 +76,38 @@ LIB32=xilink6.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"..\lib_debug\zlib.lib" +!ELSEIF "$(CFG)" == "zlib - Win32 authent" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_authent" +# PROP BASE Intermediate_Dir "zlib___Win32_authent" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlib___Win32_authent" +# PROP Intermediate_Dir "zlib___Win32_authent" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /D "DBUG_OFF" /D "_WINDOWS" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /G6 /MT /W3 /O2 /D "DBUG_OFF" /D "_WINDOWS" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=xilink6.exe -lib +# ADD BASE LIB32 /nologo /out:"..\lib_release\zlib.lib" +# ADD LIB32 /nologo /out:"..\lib_release\zlib.lib" + !ENDIF # Begin Target # Name "zlib - Win32 Release" # Name "zlib - Win32 Debug" +# Name "zlib - Win32 authent" # Begin Source File SOURCE=.\adler32.c diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index a3922313a40..b12965a85e7 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -616,60 +616,10 @@ mysql_connect(MYSQL *mysql,const char *host, #endif -#ifdef CHECK_LICENSE -/* - Check server side variable 'license'. - If the variable does not exist or does not contain 'Commercial', - we're talking to non-commercial server from commercial client. - SYNOPSIS - check_license() - RETURN VALUE - 0 success - !0 network error or the server is not commercial. - Error code is saved in mysql->net.last_errno. -*/ - -static int check_license(MYSQL *mysql) -{ - MYSQL_ROW row; - MYSQL_RES *res; - NET *net= &mysql->net; - static const char query[]= "SELECT @@license"; - static const char required_license[]= STRINGIFY_ARG(LICENSE); - - if (mysql_real_query(mysql, query, sizeof(query)-1)) - { - if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE) - { - net->last_errno= CR_WRONG_LICENSE; - sprintf(net->last_error, ER(net->last_errno), required_license); - } - return 1; - } - if (!(res= mysql_use_result(mysql))) - return 1; - row= mysql_fetch_row(res); - /* - If no rows in result set, or column value is NULL (none of these - two is ever true for server variables now), or column value - mismatch, set wrong license error. - */ - if (!net->last_errno && - (!row || !row[0] || - strncmp(row[0], required_license, sizeof(required_license)))) - { - net->last_errno= CR_WRONG_LICENSE; - sprintf(net->last_error, ER(net->last_errno), required_license); - } - mysql_free_result(res); - return net->last_errno; -} -#endif /* CHECK_LICENSE */ - - /************************************************************************** Change user and database **************************************************************************/ + int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) { NET *net= &mysql->net; diff --git a/sql-common/client.c b/sql-common/client.c index 591a0b9f0cb..87e62b5cd11 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -751,6 +751,58 @@ static my_bool is_NT(void) } #endif + +#ifdef CHECK_LICENSE +/* + Check server side variable 'license'. + If the variable does not exist or does not contain 'Commercial', + we're talking to non-commercial server from commercial client. + SYNOPSIS + check_license() + RETURN VALUE + 0 success + !0 network error or the server is not commercial. + Error code is saved in mysql->net.last_errno. +*/ + +static int check_license(MYSQL *mysql) +{ + MYSQL_ROW row; + MYSQL_RES *res; + NET *net= &mysql->net; + static const char query[]= "SELECT @@license"; + static const char required_license[]= STRINGIFY_ARG(LICENSE); + + if (mysql_real_query(mysql, query, sizeof(query)-1)) + { + if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE) + { + net->last_errno= CR_WRONG_LICENSE; + sprintf(net->last_error, ER(net->last_errno), required_license); + } + return 1; + } + if (!(res= mysql_use_result(mysql))) + return 1; + row= mysql_fetch_row(res); + /* + If no rows in result set, or column value is NULL (none of these + two is ever true for server variables now), or column value + mismatch, set wrong license error. + */ + if (!net->last_errno && + (!row || !row[0] || + strncmp(row[0], required_license, sizeof(required_license)))) + { + net->last_errno= CR_WRONG_LICENSE; + sprintf(net->last_error, ER(net->last_errno), required_license); + } + mysql_free_result(res); + return net->last_errno; +} +#endif /* CHECK_LICENSE */ + + /************************************************************************** Shut down connection **************************************************************************/ @@ -1996,10 +2048,14 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, goto error; } - if (client_flag & CLIENT_COMPRESS) /* We will use compression */ net->compress=1; +#ifdef CHECK_LICENSE + if (check_license(mysql)) + goto error; +#endif + if (db && mysql_select_db(mysql,db)) goto error; From 5ddf741a8d7fed2b84bf8ba41e6f0ef19a1cebda Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 3 Jun 2004 02:13:19 +0300 Subject: [PATCH 17/17] portability fix --- myisam/rt_mbr.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/myisam/rt_mbr.c b/myisam/rt_mbr.c index 09ec3f5e50a..7b556979904 100644 --- a/myisam/rt_mbr.c +++ b/myisam/rt_mbr.c @@ -94,6 +94,7 @@ int rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length, { for (; (int) key_length > 0; keyseg += 2 ) { + uint32 keyseg_length; switch ((enum ha_base_keytype) keyseg->type) { case HA_KEYTYPE_INT8: RT_CMP_KORR(int8, mi_sint1korr, 1, nextflag); @@ -138,7 +139,7 @@ int rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length, default: return 1; } - uint32 keyseg_length= keyseg->length * 2; + keyseg_length= keyseg->length * 2; key_length-= keyseg_length; a+= keyseg_length; b+= keyseg_length; @@ -181,6 +182,7 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) double res = 1; for (; (int)key_length > 0; keyseg += 2) { + uint32 keyseg_length; switch ((enum ha_base_keytype) keyseg->type) { case HA_KEYTYPE_INT8: RT_VOL_KORR(int8, mi_sint1korr, 1, (double)); @@ -226,7 +228,7 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) default: return -1; } - uint32 keyseg_length= keyseg->length * 2; + keyseg_length= keyseg->length * 2; key_length-= keyseg_length; a+= keyseg_length; } @@ -251,13 +253,16 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) *res++ = cast(amax); \ } + /* - Creates an MBR as an array of doubles. + Creates an MBR as an array of doubles. */ + int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) { for (; (int)key_length > 0; keyseg += 2) { + uint32 keyseg_length; switch ((enum ha_base_keytype) keyseg->type) { case HA_KEYTYPE_INT8: RT_D_MBR_KORR(int8, mi_sint1korr, 1, (double)); @@ -303,7 +308,7 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) default: return 1; } - uint32 keyseg_length= keyseg->length * 2; + keyseg_length= keyseg->length * 2; key_length-= keyseg_length; a+= keyseg_length; } @@ -347,6 +352,7 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, { for ( ; (int) key_length > 0 ; keyseg += 2) { + uint32 keyseg_length; switch ((enum ha_base_keytype) keyseg->type) { case HA_KEYTYPE_INT8: RT_COMB_KORR(int8, mi_sint1korr, mi_int1store, 1); @@ -391,7 +397,7 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, default: return 1; } - uint32 keyseg_length= keyseg->length * 2; + keyseg_length= keyseg->length * 2; key_length-= keyseg_length; a+= keyseg_length; b+= keyseg_length; @@ -400,6 +406,7 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, return 0; } + #define RT_OVL_AREA_KORR(type, korr_func, len) \ { \ type amin, amax, bmin, bmax; \ @@ -437,6 +444,7 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, double res = 1; for (; (int) key_length > 0 ; keyseg += 2) { + uint32 keyseg_length; switch ((enum ha_base_keytype) keyseg->type) { case HA_KEYTYPE_INT8: RT_OVL_AREA_KORR(int8, mi_sint1korr, 1); @@ -481,7 +489,7 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, default: return -1; } - uint32 keyseg_length= keyseg->length * 2; + keyseg_length= keyseg->length * 2; key_length-= keyseg_length; a+= keyseg_length; b+= keyseg_length; @@ -522,11 +530,10 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, *ab_area= 1.0; for (; (int)key_length > 0; keyseg += 2) { - /* Handle NULL part */ - if (keyseg->null_bit) - { + uint32 keyseg_length; + + if (keyseg->null_bit) /* Handle NULL part */ return -1; - } switch ((enum ha_base_keytype) keyseg->type) { case HA_KEYTYPE_INT8: @@ -572,7 +579,7 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, default: return -1; } - uint32 keyseg_length= keyseg->length * 2; + keyseg_length= keyseg->length * 2; key_length-= keyseg_length; a+= keyseg_length; b+= keyseg_length; @@ -613,11 +620,10 @@ double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, *ab_perim= 0.0; for (; (int)key_length > 0; keyseg += 2) { - /* Handle NULL part */ - if (keyseg->null_bit) - { + uint32 keyseg_length; + + if (keyseg->null_bit) /* Handle NULL part */ return -1; - } switch ((enum ha_base_keytype) keyseg->type) { case HA_KEYTYPE_INT8: @@ -663,7 +669,7 @@ double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, default: return -1; } - uint32 keyseg_length= keyseg->length * 2; + keyseg_length= keyseg->length * 2; key_length-= keyseg_length; a+= keyseg_length; b+= keyseg_length;