From 36d1659a80ce09f480e2af9efa9c6eb32157ec02 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 7 Nov 2007 18:02:12 +0200 Subject: [PATCH 01/46] Bug #31928: Search fails on '1000-00-00' date after sql_mode change When constructing a key image stricter date checking (from sql_mode) should not be enabled, because it will reject invalid dates that the server would otherwise accept for searching when there's no index. Fixed by disabling strict date checking when constructing a key image. mysql-test/r/type_date.result: Bug #31928: test case mysql-test/t/type_date.test: Bug #31928: test case sql/sql_select.h: Bug #31928: Disable strict date checking when consructing a key image --- mysql-test/r/type_date.result | 39 ++++++++++++++++++++++++++++++++++- mysql-test/t/type_date.test | 20 ++++++++++++++++++ sql/sql_select.h | 11 ++++++---- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index bd2a43569dd..3cf1a166e7f 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -202,7 +202,6 @@ a Warnings: Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1 Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1 -Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1 SELECT * FROM t2 WHERE a = '0000-00-00'; a 0000-00-00 @@ -214,4 +213,42 @@ INSERT INTO t1 VALUES ('0000-00-00'); ERROR 22007: Incorrect date value: '0000-00-00' for column 'a' at row 1 SET SQL_MODE=DEFAULT; DROP TABLE t1,t2; +CREATE TABLE t1 (a DATE); +CREATE TABLE t2 (a DATE); +CREATE INDEX i ON t1 (a); +INSERT INTO t1 VALUES ('1000-00-00'),('1000-00-00'); +INSERT INTO t2 VALUES ('1000-00-00'),('1000-00-00'); +SELECT * FROM t1 WHERE a = '1000-00-00'; +a +1000-00-00 +1000-00-00 +SELECT * FROM t2 WHERE a = '1000-00-00'; +a +1000-00-00 +1000-00-00 +SET SQL_MODE=TRADITIONAL; +EXPLAIN SELECT * FROM t1 WHERE a = '1000-00-00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i i 4 const 1 Using where; Using index +Warnings: +Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1 +Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1 +SELECT * FROM t1 WHERE a = '1000-00-00'; +a +1000-00-00 +1000-00-00 +Warnings: +Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1 +Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1 +SELECT * FROM t2 WHERE a = '1000-00-00'; +a +1000-00-00 +1000-00-00 +Warnings: +Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1 +Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1 +INSERT INTO t1 VALUES ('1000-00-00'); +ERROR 22007: Incorrect date value: '1000-00-00' for column 'a' at row 1 +SET SQL_MODE=DEFAULT; +DROP TABLE t1,t2; End of 5.0 tests diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 507537457d3..885fad3b623 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -190,4 +190,24 @@ INSERT INTO t1 VALUES ('0000-00-00'); SET SQL_MODE=DEFAULT; DROP TABLE t1,t2; +# +# Bug #31928: Search fails on '1000-00-00' date after sql_mode change +# + +CREATE TABLE t1 (a DATE); +CREATE TABLE t2 (a DATE); +CREATE INDEX i ON t1 (a); +INSERT INTO t1 VALUES ('1000-00-00'),('1000-00-00'); +INSERT INTO t2 VALUES ('1000-00-00'),('1000-00-00'); +SELECT * FROM t1 WHERE a = '1000-00-00'; +SELECT * FROM t2 WHERE a = '1000-00-00'; +SET SQL_MODE=TRADITIONAL; +EXPLAIN SELECT * FROM t1 WHERE a = '1000-00-00'; +SELECT * FROM t1 WHERE a = '1000-00-00'; +SELECT * FROM t2 WHERE a = '1000-00-00'; +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('1000-00-00'); +SET SQL_MODE=DEFAULT; +DROP TABLE t1,t2; + --echo End of 5.0 tests diff --git a/sql/sql_select.h b/sql/sql_select.h index 4fc32e7fdb3..42be8d3ec68 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -548,14 +548,17 @@ public: enum store_key_result copy() { enum store_key_result result; - enum_check_fields saved_count_cuted_fields= - to_field->table->in_use->count_cuted_fields; + THD *thd= to_field->table->in_use; + enum_check_fields saved_count_cuted_fields= thd->count_cuted_fields; + ulong sql_mode= thd->variables.sql_mode; + thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE); - to_field->table->in_use->count_cuted_fields= CHECK_FIELD_IGNORE; + thd->count_cuted_fields= CHECK_FIELD_IGNORE; result= copy_inner(); - to_field->table->in_use->count_cuted_fields= saved_count_cuted_fields; + thd->count_cuted_fields= saved_count_cuted_fields; + thd->variables.sql_mode= sql_mode; return result; } From 06323c2b742a16ed54069251321b4b57085930ca Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 10 Nov 2007 16:54:25 +0400 Subject: [PATCH 02/46] Bug #32063 "create table like" works case-significant only in "embedded" server (libmysqld) in mysql_creata_like_table() we 'downcase' the complete path to the .frm file. It works fine in standalone case as there usually we only have './' as a path to the datahome, but doesn't work in the embedded server where we add the real path there, so if a directory has uppercase letters in it's name, it won't be found. Fixed by 'downcasing' only database/table pair. sql/sql_table.cc: Bug #32063 "create table like" works case-significant only in "embedded" server (libmysqld) do not lowercase the database directory --- sql/sql_table.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0316d6a3c10..a1df7e21b73 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2429,12 +2429,12 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, strxmov(src_path, (*tmp_table)->path, reg_ext, NullS); else { - strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table, - reg_ext, NullS); + char *tablename_pos= strxmov(src_path, mysql_data_home, "/", NullS); + strxmov(tablename_pos, src_db, "/", src_table, reg_ext, NullS); + if (lower_case_table_names) + my_casedn_str(files_charset_info, tablename_pos); /* Resolve symlinks (for windows) */ fn_format(src_path, src_path, "", "", MYF(MY_UNPACK_FILENAME)); - if (lower_case_table_names) - my_casedn_str(files_charset_info, src_path); if (access(src_path, F_OK)) { my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); From eb347921b736c06651189623b1dcd92a6d6d1039 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Nov 2007 10:51:47 +0400 Subject: [PATCH 03/46] Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data) max_length parameter for BLOB-returning functions must be big enough for any possible content. Otherwise the field created for a table will be too small. mysql-test/r/gis.result: Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data) test result mysql-test/t/gis.test: Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data) test case sql/field.cc: Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data) max_field_size used instead of numeric value sql/field.h: Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data) max_field_size constant defined sql/item_geofunc.cc: Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data) max_length parameter fixed --- mysql-test/r/gis.result | 26 +++++++++++++++++++++++++- mysql-test/t/gis.test | 31 +++++++++++++++++++++++++++++++ sql/field.cc | 2 +- sql/field.h | 1 + sql/item_geofunc.cc | 2 +- 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 55f70e59fcf..ff4673d4c0f 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -668,7 +668,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63 g select asbinary(g) from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def asbinary(g) 252 8192 0 Y 128 0 63 +def asbinary(g) 252 4294967295 0 Y 128 0 63 asbinary(g) drop table t1; create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); @@ -730,4 +730,28 @@ select geomfromtext(col9,col89) as a from t1; a NULL DROP TABLE t1; +CREATE TABLE t1 ( +geomdata polygon NOT NULL, +SPATIAL KEY index_geom (geomdata) +) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED; +CREATE TABLE t2 ( +geomdata polygon NOT NULL, +SPATIAL KEY index_geom (geomdata) +) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED; +CREATE TABLE t3 +select +aswkb(ws.geomdata) AS geomdatawkb +from +t1 ws +union +select +aswkb(ws.geomdata) AS geomdatawkb +from +t2 ws; +describe t3; +Field Type Null Key Default Extra +geomdatawkb longblob YES NULL +drop table t1; +drop table t2; +drop table t3; End of 4.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index cf5c3b31bc1..3b9514bebbd 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -427,4 +427,35 @@ INSERT INTO `t1` VALUES ('','0000-00-00'); select geomfromtext(col9,col89) as a from t1; DROP TABLE t1; +# +# Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data) +# + +CREATE TABLE t1 ( + geomdata polygon NOT NULL, + SPATIAL KEY index_geom (geomdata) +) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED; + +CREATE TABLE t2 ( + geomdata polygon NOT NULL, + SPATIAL KEY index_geom (geomdata) +) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED; + +CREATE TABLE t3 +select + aswkb(ws.geomdata) AS geomdatawkb + from + t1 ws +union + select + aswkb(ws.geomdata) AS geomdatawkb + from + t2 ws; + +describe t3; + +drop table t1; +drop table t2; +drop table t3; + --echo End of 4.1 tests diff --git a/sql/field.cc b/sql/field.cc index 5b43b9b1955..ed6523e9299 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6975,7 +6975,7 @@ uint32 Field_blob::max_length() case 3: return 16777215 * field_charset->mbmaxlen; case 4: - return (uint32) 4294967295U; + return max_field_size; default: DBUG_ASSERT(0); // we should never go here return 0; diff --git a/sql/field.h b/sql/field.h index 20f1209a439..29be9ef38d4 100644 --- a/sql/field.h +++ b/sql/field.h @@ -26,6 +26,7 @@ #define NOT_FIXED_DEC 31 #define DATETIME_DEC 6 +const uint32 max_field_size= (uint32) 4294967295U; class Send_field; class Protocol; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 6cb8c790319..7900396e5d8 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -29,7 +29,7 @@ void Item_geometry_func::fix_length_and_dec() { collation.set(&my_charset_bin); decimals=0; - max_length=MAX_BLOB_WIDTH; + max_length= max_field_size; maybe_null= 1; } From 0cfa3267fb222a8ce15ab80865400ea4293295a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Nov 2007 14:46:36 +0400 Subject: [PATCH 04/46] Bug#30294 blackhole engine causes 100% with 2 alter table statements running Implement neccessary shared lock structure for table locks. This is the backport of bug26241 fix. sql/ha_blackhole.cc: Implement neccessary shared lock structure for table locks. sql/ha_blackhole.h: Declare shared structure for table locks sql/handler.cc: added BLACKHOLE_DB case --- sql/ha_blackhole.cc | 122 ++++++++++++++++++++++++++++++++++++++++---- sql/ha_blackhole.h | 18 ++++++- sql/handler.cc | 4 ++ 3 files changed, 132 insertions(+), 12 deletions(-) diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index 3f4285ec595..93d085bbc88 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -22,6 +22,14 @@ #ifdef HAVE_BLACKHOLE_DB #include "ha_blackhole.h" +/* Static declarations for shared structures */ + +static pthread_mutex_t blackhole_mutex; +static HASH blackhole_open_tables; +static int blackhole_init= FALSE; + +static st_blackhole_share *get_share(const char *table_name); +static void free_share(st_blackhole_share *share); /* Blackhole storage engine handlerton */ @@ -30,7 +38,7 @@ handlerton blackhole_hton= { SHOW_OPTION_YES, "/dev/null storage engine (anything you write to it disappears)", DB_TYPE_BLACKHOLE_DB, - NULL, + blackhole_db_init, 0, /* slot */ 0, /* savepoint size. */ NULL, /* close_connection */ @@ -70,15 +78,18 @@ const char **ha_blackhole::bas_ext() const int ha_blackhole::open(const char *name, int mode, uint test_if_locked) { DBUG_ENTER("ha_blackhole::open"); - thr_lock_init(&thr_lock); - thr_lock_data_init(&thr_lock,&lock,NULL); + + if (!(share= get_share(name))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + thr_lock_data_init(&share->lock, &lock, NULL); DBUG_RETURN(0); } int ha_blackhole::close(void) { DBUG_ENTER("ha_blackhole::close"); - thr_lock_delete(&thr_lock); + free_share(share); DBUG_RETURN(0); } @@ -161,17 +172,23 @@ int ha_blackhole::external_lock(THD *thd, int lock_type) } -uint ha_blackhole::lock_count(void) const -{ - DBUG_ENTER("ha_blackhole::lock_count"); - DBUG_RETURN(0); -} - THR_LOCK_DATA **ha_blackhole::store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type) { DBUG_ENTER("ha_blackhole::store_lock"); + if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) + { + if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && + lock_type <= TL_WRITE) && !thd->in_lock_tables) + lock_type = TL_WRITE_ALLOW_WRITE; + + if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) + lock_type = TL_READ; + + lock.type= lock_type; + } + *to++= &lock; DBUG_RETURN(to); } @@ -226,4 +243,89 @@ int ha_blackhole::index_last(byte * buf) DBUG_RETURN(HA_ERR_END_OF_FILE); } + +static st_blackhole_share *get_share(const char *table_name) +{ + st_blackhole_share *share; + uint length; + + length= (uint) strlen(table_name); + pthread_mutex_lock(&blackhole_mutex); + + if (!(share= (st_blackhole_share*) hash_search(&blackhole_open_tables, + (byte*) table_name, length))) + { + if (!(share= (st_blackhole_share*) my_malloc(sizeof(st_blackhole_share) + + length, + MYF(MY_WME | MY_ZEROFILL)))) + goto error; + + share->table_name_length= length; + strmov(share->table_name, table_name); + + if (my_hash_insert(&blackhole_open_tables, (byte*) share)) + { + my_free((gptr) share, MYF(0)); + share= NULL; + goto error; + } + + thr_lock_init(&share->lock); + } + share->use_count++; + +error: + pthread_mutex_unlock(&blackhole_mutex); + return share; +} + +static void free_share(st_blackhole_share *share) +{ + pthread_mutex_lock(&blackhole_mutex); + if (!--share->use_count) + hash_delete(&blackhole_open_tables, (byte*) share); + pthread_mutex_unlock(&blackhole_mutex); +} + + +static byte* blackhole_get_key(st_blackhole_share *share, uint *length, + my_bool not_used __attribute__((unused))) +{ + *length= share->table_name_length; + return (byte*) share->table_name; +} + + +bool blackhole_db_init() +{ + DBUG_ENTER("blackhole_db_init"); + if (pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST)) + goto error; + if (hash_init(&blackhole_open_tables, &my_charset_bin, 32, 0, 0, + (hash_get_key) blackhole_get_key, 0, 0)) + { + VOID(pthread_mutex_destroy(&blackhole_mutex)); + } + else + { + blackhole_init= TRUE; + DBUG_RETURN(FALSE); + } +error: + have_blackhole_db= SHOW_OPTION_DISABLED; // If we couldn't use handler + DBUG_RETURN(TRUE); +} + + +bool blackhole_db_end() +{ + if (blackhole_init) + { + hash_free(&blackhole_open_tables); + VOID(pthread_mutex_destroy(&blackhole_mutex)); + } + blackhole_init= 0; + return FALSE; +} + #endif /* HAVE_BLACKHOLE_DB */ diff --git a/sql/ha_blackhole.h b/sql/ha_blackhole.h index 4dcb37c637d..45ed0351457 100644 --- a/sql/ha_blackhole.h +++ b/sql/ha_blackhole.h @@ -17,6 +17,18 @@ #pragma interface /* gcc class implementation */ #endif + +/* + Shared structure for correct LOCK operation +*/ +struct st_blackhole_share { + THR_LOCK lock; + uint use_count; + uint table_name_length; + char table_name[1]; +}; + + /* Class definition for the blackhole storage engine "Dumbest named feature ever" @@ -24,7 +36,7 @@ class ha_blackhole: public handler { THR_LOCK_DATA lock; /* MySQL lock */ - THR_LOCK thr_lock; + st_blackhole_share *share; public: ha_blackhole(TABLE *table_arg); @@ -76,10 +88,12 @@ public: void position(const byte *record); int info(uint flag); int external_lock(THD *thd, int lock_type); - uint lock_count(void) const; int create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); }; + +bool blackhole_db_init(void); +bool blackhole_db_end(void); diff --git a/sql/handler.cc b/sql/handler.cc index bfb7e8c369f..27204ae725b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -515,6 +515,10 @@ int ha_panic(enum ha_panic_function flag) if (have_berkeley_db == SHOW_OPTION_YES) error|=berkeley_end(); #endif +#ifdef HAVE_BLACKHOLE_DB + if (have_blackhole_db == SHOW_OPTION_YES) + error|= blackhole_db_end(); +#endif #ifdef HAVE_INNOBASE_DB if (have_innodb == SHOW_OPTION_YES) error|=innobase_end(); From 1c1dd1f25c42081c7bf72042ccfcb83896298aab Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Nov 2007 13:58:09 +0300 Subject: [PATCH 05/46] Fix for bug #32241: memory corruption due to large index map in 'Range checked for each record' The problem was in incorrectly calculated length of the buffer used to store a hexadecimal representation of an index map in select_describe(). This could result in buffer overrun and stack corruption under some circumstances. Fixed by correcting the calculation. mysql-test/r/explain.result: Added a test case for bug #32241. mysql-test/t/explain.test: Added a test case for bug #32241. sql/sql_select.cc: Corrected the buffer length calculation. Count one hex digit as 4 bits, not 8. --- mysql-test/r/explain.result | 20 ++++++++++++++++++++ mysql-test/t/explain.test | 28 ++++++++++++++++++++++++++++ sql/sql_select.cc | 3 ++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index 24ff44945bf..a4c8432d2a4 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -87,3 +87,23 @@ Warnings: Note 1003 select '1' AS `f1`,'1' AS `f2` from `test`.`t1` having 1 drop view v1; drop table t1; +CREATE TABLE t1(c INT); +INSERT INTO t1 VALUES (),(); +CREATE TABLE t2 (b INT, +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b)); +INSERT INTO t2 VALUES (),(),(); +EXPLAIN SELECT 1 FROM +(SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2; +id select_type table type possible_keys key key_len ref rows Extra +X X X X X X X X X const row not found +X X X X X X X X X +X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF) +DROP TABLE t2; +DROP TABLE t1; diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index 04cf37f457a..c9ae8aceaf6 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -66,4 +66,32 @@ explain extended select * from t1 having 1; drop view v1; drop table t1; +# +# Bug #32241: memory corruption due to large index map in 'Range checked for +# each record' +# + +CREATE TABLE t1(c INT); +INSERT INTO t1 VALUES (),(); + +CREATE TABLE t2 (b INT, +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b), +KEY(b),KEY(b),KEY(b),KEY(b),KEY(b)); + +INSERT INTO t2 VALUES (),(),(); + +# We only need to make sure that there is no buffer overrun and the index map +# is displayed correctly +--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X +EXPLAIN SELECT 1 FROM + (SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2; +DROP TABLE t2; +DROP TABLE t1; + # End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 24d1639edf1..4ff80185a85 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15282,7 +15282,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { if (tab->use_quick == 2) { - char buf[MAX_KEY/8+1]; + /* 4 bits per 1 hex digit + terminating '\0' */ + char buf[MAX_KEY / 4 + 1]; extra.append(STRING_WITH_LEN("; Range checked for each " "record (index map: 0x")); extra.append(tab->keys.print(buf)); From 5e9933d7ff7d7fdd0e8b117b0344b127d5f23ffa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Nov 2007 17:43:15 +0100 Subject: [PATCH 06/46] Bug #32180: DATE_ADD treats datetime numeric argument as DATE instead of DATETIME This is a regression from 2007-05-18 when code to zero out the returned struct was added to number_to_datetime(); zero for time_type corresponds to MYSQL_TIMESTAMP_DATE. We now explicitly set the type we return (MYSQL_TIMESTAMP_DATETIME). mysql-test/r/func_time.result: show that DATE_ADD() behaves the same for YYYYMMDDhhmmss given as string and as integer. mysql-test/t/func_time.test: show that DATE_ADD() behaves the same for YYYYMMDDhhmmss given as string and as integer. sql-common/my_time.c: explictly set return type in number_to_datetime() --- mysql-test/r/func_time.result | 12 ++++++++++++ mysql-test/t/func_time.test | 10 ++++++++++ sql-common/my_time.c | 9 ++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 74859be4d04..71234385c0d 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1270,4 +1270,16 @@ select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation 'concat' set lc_time_names=en_US; drop table t1; +select DATE_ADD('20071108181000', INTERVAL 1 DAY); +DATE_ADD('20071108181000', INTERVAL 1 DAY) +2007-11-09 18:10:00 +select DATE_ADD(20071108181000, INTERVAL 1 DAY); +DATE_ADD(20071108181000, INTERVAL 1 DAY) +2007-11-09 18:10:00 +select DATE_ADD('20071108', INTERVAL 1 DAY); +DATE_ADD('20071108', INTERVAL 1 DAY) +2007-11-09 +select DATE_ADD(20071108, INTERVAL 1 DAY); +DATE_ADD(20071108, INTERVAL 1 DAY) +2007-11-09 End of 5.0 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index c0a449ac3f4..f8249b7cf7c 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -787,4 +787,14 @@ select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1; set lc_time_names=en_US; drop table t1; +# +# Bug#32180: DATE_ADD treats datetime numeric argument as DATE +# instead of DATETIME +# + +select DATE_ADD('20071108181000', INTERVAL 1 DAY); +select DATE_ADD(20071108181000, INTERVAL 1 DAY); +select DATE_ADD('20071108', INTERVAL 1 DAY); +select DATE_ADD(20071108, INTERVAL 1 DAY); + --echo End of 5.0 tests diff --git a/sql-common/my_time.c b/sql-common/my_time.c index f5d5828e024..a39cc754c88 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1113,9 +1113,14 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, long part1,part2; *was_cut= 0; + bzero((char*) time_res, sizeof(*time_res)); + time_res->time_type=MYSQL_TIMESTAMP_DATE; if (nr == LL(0) || nr >= LL(10000101000000)) + { + time_res->time_type=MYSQL_TIMESTAMP_DATETIME; goto ok; + } if (nr < 101) goto err; if (nr <= (YY_PART_YEAR-1)*10000L+1231L) @@ -1139,6 +1144,9 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, } if (nr < 101000000L) goto err; + + time_res->time_type=MYSQL_TIMESTAMP_DATETIME; + if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959)) { nr= nr+LL(20000000000000); /* YYMMDDHHMMSS, 2000-2069 */ @@ -1152,7 +1160,6 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res, ok: part1=(long) (nr/LL(1000000)); part2=(long) (nr - (longlong) part1*LL(1000000)); - bzero((char*) time_res, sizeof(*time_res)); time_res->year= (int) (part1/10000L); part1%=10000L; time_res->month= (int) part1 / 100; time_res->day= (int) part1 % 100; From 8a8d634b23f38b1d7eb454036fc734e8e7d27966 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 17 Nov 2007 17:11:05 +0400 Subject: [PATCH 07/46] merging --- mysql-test/r/gis.result | 66 ++--------------------------------------- 1 file changed, 2 insertions(+), 64 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 334a285b93f..84b7b449cb5 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -680,7 +680,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63 g select asbinary(g) from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def asbinary(g) 252 8192 0 Y 128 0 63 +def asbinary(g) 252 4294967295 0 Y 128 0 63 asbinary(g) drop table t1; create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); @@ -730,69 +730,6 @@ point(b, b) IS NULL linestring(b) IS NULL polygon(b) IS NULL multipoint(b) IS NU 1 1 1 1 1 1 1 0 1 1 1 1 1 1 drop table t1; -select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))); -(asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))) -POINT(10 10) -select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))); -(asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))) -POINT(10 10) -create table t1 (g GEOMETRY); -select * from t1; -Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def test t1 t1 g g 255 4294967295 0 Y 144 0 63 -g -select asbinary(g) from t1; -Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def asbinary(g) 252 4294967295 0 Y 128 0 63 -asbinary(g) -drop table t1; -create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b)); -alter table t1 disable keys; -load data infile '../../std_data/bad_gis_data.dat' into table t1; -ERROR 01000: Data truncated; NULL supplied to NOT NULL column 'b' at row 1 -alter table t1 enable keys; -drop table t1; -create table t1 (a int, b blob); -insert into t1 values (1, ''), (2, NULL), (3, '1'); -select * from t1; -a b -1 -2 NULL -3 1 -select -geometryfromtext(b) IS NULL, geometryfromwkb(b) IS NULL, astext(b) IS NULL, -aswkb(b) IS NULL, geometrytype(b) IS NULL, centroid(b) IS NULL, -envelope(b) IS NULL, startpoint(b) IS NULL, endpoint(b) IS NULL, -exteriorring(b) IS NULL, pointn(b, 1) IS NULL, geometryn(b, 1) IS NULL, -interiorringn(b, 1) IS NULL, multipoint(b) IS NULL, isempty(b) IS NULL, -issimple(b) IS NULL, isclosed(b) IS NULL, dimension(b) IS NULL, -numgeometries(b) IS NULL, numinteriorrings(b) IS NULL, numpoints(b) IS NULL, -area(b) IS NULL, glength(b) IS NULL, srid(b) IS NULL, x(b) IS NULL, -y(b) IS NULL -from t1; -geometryfromtext(b) IS NULL geometryfromwkb(b) IS NULL astext(b) IS NULL aswkb(b) IS NULL geometrytype(b) IS NULL centroid(b) IS NULL envelope(b) IS NULL startpoint(b) IS NULL endpoint(b) IS NULL exteriorring(b) IS NULL pointn(b, 1) IS NULL geometryn(b, 1) IS NULL interiorringn(b, 1) IS NULL multipoint(b) IS NULL isempty(b) IS NULL issimple(b) IS NULL isclosed(b) IS NULL dimension(b) IS NULL numgeometries(b) IS NULL numinteriorrings(b) IS NULL numpoints(b) IS NULL area(b) IS NULL glength(b) IS NULL srid(b) IS NULL x(b) IS NULL y(b) IS NULL -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -select -within(b, b) IS NULL, contains(b, b) IS NULL, overlaps(b, b) IS NULL, -equals(b, b) IS NULL, disjoint(b, b) IS NULL, touches(b, b) IS NULL, -intersects(b, b) IS NULL, crosses(b, b) IS NULL -from t1; -within(b, b) IS NULL contains(b, b) IS NULL overlaps(b, b) IS NULL equals(b, b) IS NULL disjoint(b, b) IS NULL touches(b, b) IS NULL intersects(b, b) IS NULL crosses(b, b) IS NULL -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -select -point(b, b) IS NULL, linestring(b) IS NULL, polygon(b) IS NULL, multipoint(b) IS NULL, -multilinestring(b) IS NULL, multipolygon(b) IS NULL, -geometrycollection(b) IS NULL -from t1; -point(b, b) IS NULL linestring(b) IS NULL polygon(b) IS NULL multipoint(b) IS NULL multilinestring(b) IS NULL multipolygon(b) IS NULL geometrycollection(b) IS NULL -0 1 1 1 1 1 1 -1 1 1 1 1 1 1 -0 1 1 1 1 1 1 -drop table t1; CREATE TABLE t1(a POINT) ENGINE=MyISAM; INSERT INTO t1 VALUES (NULL); SELECT * FROM t1; @@ -1020,3 +957,4 @@ COUNT(*) 2 DROP TABLE t1, t2; End of 5.0 tests +End of 5.0 tests From 99054db64c8a41acbe570756e286a8d78811197c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 18 Nov 2007 00:02:55 +0400 Subject: [PATCH 08/46] Fixed bug #32335. Comparison of a BIGINT NOT NULL column with a constant arithmetic expression that evaluates to NULL caused error 1048: "Column '...' cannot be null". Made convert_constant_item() check if the constant expression is NULL before attempting to store it in a field. Attempts to store NULL in a NOT NULL field caused query errors. sql/item_cmpfunc.cc: Fixed bug #32335. 1. Made convert_constant_item() check if the constant expression is NULL before attempting to store it in a field. Attempts to store NULL in a NOT NULL field caused query errors. 2. Also minor bug has been fixed: the thd->count_cuted_fields value was not restored in case of successful conversion. mysql-test/t/select.test: Added test case for bug #32335. mysql-test/r/select.result: Added test case for bug #32335. --- mysql-test/r/select.result | 6 ++++++ mysql-test/t/select.test | 11 +++++++++++ sql/item_cmpfunc.cc | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index a1ba58a536c..3ca84bcf34b 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4322,4 +4322,10 @@ c3 DROP TABLE t1; DROP TABLE t2; +CREATE TABLE t1 (c1 BIGINT NOT NULL); +INSERT INTO t1 (c1) VALUES (1); +SELECT * FROM t1 WHERE c1 > NULL + 1; +c1 +DROP TABLE t1; + End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 31c8a3f7d11..c48f2771aa8 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3661,4 +3661,15 @@ DROP TABLE t2; ########################################################################### +# +# Bug #32335: Error on BIGINT > NULL + 1 +# + +CREATE TABLE t1 (c1 BIGINT NOT NULL); +INSERT INTO t1 (c1) VALUES (1); +SELECT * FROM t1 WHERE c1 > NULL + 1; +DROP TABLE t1; + +--echo + --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 85ec8fa40d6..f9744baf19e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -350,11 +350,12 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item) thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | MODE_INVALID_DATES; thd->count_cuted_fields= CHECK_FIELD_IGNORE; - if (!(*item)->save_in_field(field, 1) && !((*item)->null_value)) + if (!(*item)->is_null() && !(*item)->save_in_field(field, 1)) { Item *tmp=new Item_int_with_ref(field->val_int(), *item, test(field->flags & UNSIGNED_FLAG)); thd->variables.sql_mode= orig_sql_mode; + thd->count_cuted_fields= orig_count_cuted_fields; if (tmp) thd->change_item_tree(item, tmp); return 1; // Item was replaced From da1efa3387e62df85d48f05e81ac9b324c455e83 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Nov 2007 11:03:03 +0400 Subject: [PATCH 09/46] Bug #30284 spatial key corruption. SPATIAL key is fine actually, but the chk_key() function mistakenly returns error. It tries to compare checksums of btree and SPATIAL keys while the checksum for the SPATIAL isn't calculated (always 0). Same thing with FULLTEXT keys is handled using full_text_keys counter, so fixed by counting both SPATIAL and FULLTEXT keys in that counter. myisam/mi_check.c: Bug #30284 spatial key corruption full_text_keys counts both FULL_TEXT and SPATIAL keys mysql-test/r/gis.result: Bug #30284 spatial key corruption test result mysql-test/t/gis.test: Bug #30284 spatial key corruption. test case --- myisam/mi_check.c | 2 +- mysql-test/r/gis.result | 8 ++++++++ mysql-test/t/gis.test | 11 +++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index ce8fb04874e..64aa0b76877 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -454,7 +454,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) if ((!(param->testflag & T_SILENT))) printf ("- check data record references index: %d\n",key+1); - if (keyinfo->flag & HA_FULLTEXT) + if (keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL)) full_text_keys++; if (share->state.key_root[key] == HA_OFFSET_ERROR && (info->state->records == 0 || keyinfo->flag & HA_FULLTEXT)) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 55f70e59fcf..3c5b0491148 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -730,4 +730,12 @@ select geomfromtext(col9,col89) as a from t1; a NULL DROP TABLE t1; +create table t1(col1 geometry not null,col15 geometrycollection not +null,spatial index(col15),index(col1(15)))engine=myisam; +insert into t1 set col15 = GeomFromText('POINT(6 5)'); +insert into t1 set col15 = GeomFromText('POINT(6 5)'); +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; End of 4.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index cf5c3b31bc1..77e73e0d590 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -427,4 +427,15 @@ INSERT INTO `t1` VALUES ('','0000-00-00'); select geomfromtext(col9,col89) as a from t1; DROP TABLE t1; +# +# Bug #30284 spatial key corruption +# + +create table t1(col1 geometry not null,col15 geometrycollection not +null,spatial index(col15),index(col1(15)))engine=myisam; +insert into t1 set col15 = GeomFromText('POINT(6 5)'); +insert into t1 set col15 = GeomFromText('POINT(6 5)'); +check table t1 extended; +drop table t1; + --echo End of 4.1 tests From 1f7678fe52ae199b87602bea5f35dd3e8e4bc04e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Nov 2007 15:27:44 +0300 Subject: [PATCH 10/46] Changed the help text for --comments to make it clear which option disables the option explicitely. Changed the option location in code so that --help will show it in lexical option order. This is for bug #26215: mysql command line client should not strip comments from SQL statements client/mysql.cc: Changed the help text for --comments to make it clear which option disables the option explicitely. Changed the option location in code so that --help will show it in lexical option order. --- client/mysql.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index a8d88bec274..6af33670ca5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -595,6 +595,10 @@ static struct my_option my_long_options[] = {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", (gptr*) &default_charset, (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"comments", 'c', "Preserve comments. Send comments to the server." + " The default is --skip-comments (discard comments), enable with --comments", + (gptr*) &preserve_comments, (gptr*) &preserve_comments, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use compression in server/client protocol.", (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -755,10 +759,6 @@ static struct my_option my_long_options[] = {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.", (gptr*) &show_warnings, (gptr*) &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"comments", 'c', "Preserve comments. Send comments to the server." - " Comments are discarded by default, enable with --enable-comments", - (gptr*) &preserve_comments, (gptr*) &preserve_comments, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; From c4d0901d00bdeb496aeffedc80e6d583711086d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Nov 2007 18:59:25 +0300 Subject: [PATCH 11/46] Fix for bug #32221: bug25714, mytest, mysql_client_test complaints and crashes. MySQL distributions contain a number of programs that are used only by the MySQL test suite internally, i.e. they are not indended to be invoked directly by a user. As a result, such programs are not documented, do not have any built-in help or proper error reporting, which may confuse users. This patch fixes the problem with the following changes: - mytest, libmysqltest and all references to them were removed from the distribution since they are not used anymore - bug25714 now displays an error message when run with incorrect arguments or with the --help option - mysql_client_test now does not call abort() in case of errors, instead it does a clean exit() with a proper error status. BitKeeper/deleted/.del-mytest.c: Delete: libmysql/mytest.c BitKeeper/deleted/.del-myTest-package.dsp: Delete: VC++Files/libmysqltest/myTest-package.dsp BitKeeper/deleted/.del-myTest-package_ia64.dsp: Delete: VC++Files/libmysqltest/myTest-package_ia64.dsp BitKeeper/deleted/.del-myTest.dsp~4a8c480769193952: Delete: VC++Files/libmysqltest/myTest.dsp BitKeeper/deleted/.del-myTest.vcproj: Delete: VC++Files/libmysqltest/myTest.vcproj BitKeeper/deleted/.del-myTest_ia64.dsp: Delete: VC++Files/libmysqltest/myTest_ia64.dsp BitKeeper/deleted/.del-mytest.c~9a99338689e5de8: Delete: VC++Files/libmysqltest/mytest.c BitKeeper/deleted/.del-mytest.dsw~2324698861155335: Delete: VC++Files/libmysqltest/mytest.dsw VC++Files/copy_mysql_files.bat: Removed references to libmysqltest. libmysql/CMakeLists.txt: Removed rules for myTest. libmysql/Makefile.am: Removed mytest.c from EXTRA_DIST. tests/bug25714.c: Display a meaningful error message when run incorrectly or with the --help option. tests/mysql_client_test.c: In case of error, don't cause abnormal program termination, do a clean exit() with an error status. --- VC++Files/copy_mysql_files.bat | 5 - VC++Files/libmysqltest/myTest-package.dsp | 92 --------- .../libmysqltest/myTest-package_ia64.dsp | 92 --------- VC++Files/libmysqltest/myTest.dsp | 92 --------- VC++Files/libmysqltest/myTest.vcproj | 146 --------------- VC++Files/libmysqltest/myTest_ia64.dsp | 94 ---------- VC++Files/libmysqltest/mytest.c | 175 ------------------ VC++Files/libmysqltest/mytest.dsw | 28 --- libmysql/CMakeLists.txt | 3 - libmysql/Makefile.am | 2 +- libmysql/mytest.c | 175 ------------------ tests/bug25714.c | 6 +- tests/mysql_client_test.c | 2 +- 13 files changed, 7 insertions(+), 905 deletions(-) delete mode 100644 VC++Files/libmysqltest/myTest-package.dsp delete mode 100644 VC++Files/libmysqltest/myTest-package_ia64.dsp delete mode 100644 VC++Files/libmysqltest/myTest.dsp delete mode 100644 VC++Files/libmysqltest/myTest.vcproj delete mode 100644 VC++Files/libmysqltest/myTest_ia64.dsp delete mode 100644 VC++Files/libmysqltest/mytest.c delete mode 100644 VC++Files/libmysqltest/mytest.dsw delete mode 100644 libmysql/mytest.c diff --git a/VC++Files/copy_mysql_files.bat b/VC++Files/copy_mysql_files.bat index 7d6070eb1a8..8a296187cf3 100644 --- a/VC++Files/copy_mysql_files.bat +++ b/VC++Files/copy_mysql_files.bat @@ -78,11 +78,6 @@ copy include\conf*.h c:\mysql\include copy include\my_global.h c:\mysql\include\my_global.h copy libmysql\libmysql.def c:\mysql\include -REM Copy test files - -copy libmysqltest\*.* c:\mysql\examples\libmysqltest -copy libmysqltest\release\myTest.exe c:\mysql\examples\libmysqltest - REM Copy share, docs etc xcopy share\*.* c:\mysql\share /E /Y diff --git a/VC++Files/libmysqltest/myTest-package.dsp b/VC++Files/libmysqltest/myTest-package.dsp deleted file mode 100644 index a5c73d447b3..00000000000 --- a/VC++Files/libmysqltest/myTest-package.dsp +++ /dev/null @@ -1,92 +0,0 @@ -# Microsoft Developer Studio Project File - Name="myTest" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=myTest - 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 "myTest.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 "myTest.mak" CFG="myTest - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "myTest - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "myTest - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -RSC=rc.exe - -!IF "$(CFG)" == "myTest - 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 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /W3 /O2 /I "..\..\include" /D "NDEBUG" /D "DBUG_UFF" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.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 /subsystem:console /machine:I386 -# ADD LINK32 ..\..\lib\opt\libmysql.lib 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 /subsystem:console /machine:I386 /libpath:"..\lib_release" - -!ELSEIF "$(CFG)" == "myTest - 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 /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /Fr /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.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 /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ..\..\lib\debug\libmysql.lib 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 /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"..\lib_debug" - -!ENDIF - -# Begin Target - -# Name "myTest - Win32 Release" -# Name "myTest - Win32 Debug" -# Begin Source File - -SOURCE=.\Mytest.c -# End Source File -# End Target -# End Project diff --git a/VC++Files/libmysqltest/myTest-package_ia64.dsp b/VC++Files/libmysqltest/myTest-package_ia64.dsp deleted file mode 100644 index ef80a773815..00000000000 --- a/VC++Files/libmysqltest/myTest-package_ia64.dsp +++ /dev/null @@ -1,92 +0,0 @@ -# Microsoft Developer Studio Project File - Name="myTest" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=myTest - 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 "myTest.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 "myTest.mak" CFG="myTest - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "myTest - WinIA64 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "myTest - WinIA64 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -RSC=rc.exe - -!IF "$(CFG)" == "myTest - WinIA64 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 /W3 /GX /O2 /D "WIN64" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /I "..\include" /D"NDEBUG" /D"DBUG_UFF" /D"_CONSOLE" /D"_MBCS" /FD /c /O2 /G2 /EHsc /D"_IA64_" /Zi /D"WIN64" /D"WIN32" /D"_AFX_NO_DAO_SUPPORT" /Wp64 /Zm600 -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.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 /subsystem:console /machine:IA64 -# ADD LINK32 ..\lib_release\libmysql.lib 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 /subsystem:console /machine:IA64 /libpath:"..\lib_release" /incremental:no - -!ELSEIF "$(CFG)" == "myTest - WinIA64 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 /W3 /Gm /GX /Zi /Od /D "WIN64" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Z7 /I "..\include" /D"_DEBUG" /D"_CONSOLE" /D"_MBCS" /FD /c /Od /G2 /EHsc /D"_IA64_" /Zi /D"WIN64" /D"WIN32" /D"_AFX_NO_DAO_SUPPORT" /Wp64 /Zm600 -# SUBTRACT CPP /Fr /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.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 /subsystem:console /debug /machine:IA64 -# ADD LINK32 ..\lib_debug\libmysql.lib 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 /subsystem:console /debug /machine:IA64 /libpath:"..\lib_debug" /incremental:no - -!ENDIF - -# Begin Target - -# Name "myTest - WinIA64 Release" -# Name "myTest - WinIA64 Debug" -# Begin Source File - -SOURCE=.\Mytest.c -# End Source File -# End Target -# End Project diff --git a/VC++Files/libmysqltest/myTest.dsp b/VC++Files/libmysqltest/myTest.dsp deleted file mode 100644 index ca0f9e6e147..00000000000 --- a/VC++Files/libmysqltest/myTest.dsp +++ /dev/null @@ -1,92 +0,0 @@ -# Microsoft Developer Studio Project File - Name="myTest" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=myTest - 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 "myTest.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 "myTest.mak" CFG="myTest - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "myTest - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "myTest - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -RSC=rc.exe - -!IF "$(CFG)" == "myTest - 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 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /W3 /O2 /I "..\include" /D "DBUG_UFF" /D "_CONSOLE" /D "_MBCS" /D "NDEBUG" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.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 /subsystem:console /machine:I386 -# ADD LINK32 libmysql.lib 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 /subsystem:console /machine:I386 /libpath:"..\lib_release" - -!ELSEIF "$(CFG)" == "myTest - 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 /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "..\include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /Fr /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.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 /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 libmysql.lib 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 /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"..\lib_debug" - -!ENDIF - -# Begin Target - -# Name "myTest - Win32 Release" -# Name "myTest - Win32 Debug" -# Begin Source File - -SOURCE=.\Mytest.c -# End Source File -# End Target -# End Project diff --git a/VC++Files/libmysqltest/myTest.vcproj b/VC++Files/libmysqltest/myTest.vcproj deleted file mode 100644 index 53f93a7e05d..00000000000 --- a/VC++Files/libmysqltest/myTest.vcproj +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VC++Files/libmysqltest/myTest_ia64.dsp b/VC++Files/libmysqltest/myTest_ia64.dsp deleted file mode 100644 index 4affa81ef54..00000000000 --- a/VC++Files/libmysqltest/myTest_ia64.dsp +++ /dev/null @@ -1,94 +0,0 @@ -# Microsoft Developer Studio Project File - Name="myTest" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=myTest - WinIA64 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 "myTest_ia64.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 "myTest_ia64.mak" CFG="myTest - WinIA64 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "myTest - WinIA64 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "myTest - WinIA64 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "myTest - WinIA64 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 "" -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN64" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /Zi /O2 /I "..\include" /D "DBUG_UFF" /D "_CONSOLE" /D "_MBCS" /D "NDEBUG" /D "_IA64_" /D "WIN64" /D "WIN32" /D "_AFX_NO_DAO_SUPPORT" /FD /G2 /EHsc /Wp64 /Zm600 /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /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 /subsystem:console /machine:IA64 -# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib bufferoverflowU.lib /nologo /subsystem:console /libpath:"..\lib_release" /machine:IA64 - -!ELSEIF "$(CFG)" == "myTest - WinIA64 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 "" -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN64" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Zi /Od /I "..\include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_IA64_" /D "WIN64" /D "WIN32" /D "_AFX_NO_DAO_SUPPORT" /FD /G2 /EHsc /Wp64 /Zm600 /c -# SUBTRACT CPP /Fr /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /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 /subsystem:console /debug /machine:IA64 -# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib bufferoverflowU.lib /nologo /subsystem:console /incremental:no /debug /libpath:"..\lib_debug" /machine:IA64 - -!ENDIF - -# Begin Target - -# Name "myTest - WinIA64 Release" -# Name "myTest - WinIA64 Debug" -# Begin Source File - -SOURCE=.\Mytest.c -# End Source File -# End Target -# End Project diff --git a/VC++Files/libmysqltest/mytest.c b/VC++Files/libmysqltest/mytest.c deleted file mode 100644 index a1dc13db39f..00000000000 --- a/VC++Files/libmysqltest/mytest.c +++ /dev/null @@ -1,175 +0,0 @@ -/*C4*/ -/****************************************************************/ -/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */ -/* Date: 02/18/1998 */ -/* mytest.c : do some testing of the libmySQL.DLL.... */ -/* */ -/* History: */ -/* 02/18/1998 jw3 also sprach zarathustra.... */ -/****************************************************************/ - - -#include -#include -#include - -#include - -#define DEFALT_SQL_STMT "SELECT * FROM db" -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - - -/******************************************************** -** -** main :- -** -********************************************************/ - -int -main( int argc, char * argv[] ) -{ - - char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ; - const char *pszT; - int i, j, k, l, x ; - MYSQL * myData ; - MYSQL_RES * res ; - MYSQL_FIELD * fd ; - MYSQL_ROW row ; - - //....just curious.... - printf( "sizeof( MYSQL ) == %d\n", (int) sizeof( MYSQL ) ) ; - if ( argc == 2 ) - { - strcpy( szDB, argv[ 1 ] ) ; - strcpy( szSQL, DEFALT_SQL_STMT ) ; - if (!strcmp(szDB,"--debug")) - { - strcpy( szDB, "mysql" ) ; - printf("Some mysql struct information (size and offset):\n"); - printf("net:\t%3d %3d\n",(int) sizeof(myData->net), - (int) offsetof(MYSQL,net)); - printf("host:\t%3d %3d\n",(int) sizeof(myData->host), - (int) offsetof(MYSQL,host)); - printf("port:\t%3d %3d\n", (int) sizeof(myData->port), - (int) offsetof(MYSQL,port)); - printf("protocol_version:\t%3d %3d\n", - (int) sizeof(myData->protocol_version), - (int) offsetof(MYSQL,protocol_version)); - printf("thread_id:\t%3d %3d\n",(int) sizeof(myData->thread_id), - (int) offsetof(MYSQL,thread_id)); - printf("affected_rows:\t%3d %3d\n",(int) sizeof(myData->affected_rows), - (int) offsetof(MYSQL,affected_rows)); - printf("packet_length:\t%3d %3d\n",(int) sizeof(myData->packet_length), - (int) offsetof(MYSQL,packet_length)); - printf("status:\t%3d %3d\n",(int) sizeof(myData->status), - (int) offsetof(MYSQL,status)); - printf("fields:\t%3d %3d\n",(int) sizeof(myData->fields), - (int) offsetof(MYSQL,fields)); - printf("field_alloc:\t%3d %3d\n",(int) sizeof(myData->field_alloc), - (int) offsetof(MYSQL,field_alloc)); - printf("free_me:\t%3d %3d\n",(int) sizeof(myData->free_me), - (int) offsetof(MYSQL,free_me)); - printf("options:\t%3d %3d\n",(int) sizeof(myData->options), - (int) offsetof(MYSQL,options)); - puts(""); - } - } - else if ( argc > 2 ) { - strcpy( szDB, argv[ 1 ] ) ; - strcpy( szSQL, argv[ 2 ] ) ; - } - else { - strcpy( szDB, "mysql" ) ; - strcpy( szSQL, DEFALT_SQL_STMT ) ; - } - //.... - - if ( (myData = mysql_init((MYSQL*) 0)) && - mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT, - NULL, 0 ) ) - { - myData->reconnect= 1; - if ( mysql_select_db( myData, szDB ) < 0 ) { - printf( "Can't select the %s database !\n", szDB ) ; - mysql_close( myData ) ; - return 2 ; - } - } - else { - printf( "Can't connect to the mysql server on port %d !\n", - MYSQL_PORT ) ; - mysql_close( myData ) ; - return 1 ; - } - //.... - if ( ! mysql_query( myData, szSQL ) ) { - res = mysql_store_result( myData ) ; - i = (int) mysql_num_rows( res ) ; l = 1 ; - printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ; - //....we can get the field-specific characteristics here.... - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - //.... - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Record #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - mysql_free_result( res ) ; - } - else printf( "Couldn't execute %s on the server !\n", szSQL ) ; - //.... - puts( "==== Diagnostic info ====" ) ; - pszT = mysql_get_client_info() ; - printf( "Client info: %s\n", pszT ) ; - //.... - pszT = mysql_get_host_info( myData ) ; - printf( "Host info: %s\n", pszT ) ; - //.... - pszT = mysql_get_server_info( myData ) ; - printf( "Server info: %s\n", pszT ) ; - //.... - res = mysql_list_processes( myData ) ; l = 1 ; - if (res) - { - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Process #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - } - else - { - printf("Got error %s when retreiving processlist\n",mysql_error(myData)); - } - //.... - res = mysql_list_tables( myData, "%" ) ; l = 1 ; - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Table #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - //.... - pszT = mysql_stat( myData ) ; - puts( pszT ) ; - //.... - mysql_close( myData ) ; - return 0 ; - -} diff --git a/VC++Files/libmysqltest/mytest.dsw b/VC++Files/libmysqltest/mytest.dsw deleted file mode 100644 index 1aa804386bc..00000000000 --- a/VC++Files/libmysqltest/mytest.dsw +++ /dev/null @@ -1,28 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 5.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "myTest"=".\myTest.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 59e70d68a6d..7de504aa2f0 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -125,9 +125,6 @@ TARGET_LINK_LIBRARIES(mysqlclient) ADD_DEPENDENCIES(mysqlclient_notls GenError) TARGET_LINK_LIBRARIES(mysqlclient_notls) -ADD_EXECUTABLE(myTest mytest.c) -TARGET_LINK_LIBRARIES(myTest libmysql) - IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("myTest" "asInvoker") ENDIF(EMBED_MANIFESTS) diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 38680c98d53..13497331683 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -31,7 +31,7 @@ include $(srcdir)/Makefile.shared libmysqlclient_la_SOURCES = $(target_sources) libmysqlclient_la_LIBADD = $(target_libadd) $(yassl_las) libmysqlclient_la_LDFLAGS = $(target_ldflags) -EXTRA_DIST = Makefile.shared libmysql.def dll.c mytest.c CMakeLists.txt +EXTRA_DIST = Makefile.shared libmysql.def dll.c CMakeLists.txt noinst_HEADERS = client_settings.h # This is called from the toplevel makefile diff --git a/libmysql/mytest.c b/libmysql/mytest.c deleted file mode 100644 index 2d5c576b72a..00000000000 --- a/libmysql/mytest.c +++ /dev/null @@ -1,175 +0,0 @@ -/*C4*/ -/****************************************************************/ -/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */ -/* Date: 02/18/1998 */ -/* mytest.c : do some testing of the libmySQL.DLL.... */ -/* */ -/* History: */ -/* 02/18/1998 jw3 also sprach zarathustra.... */ -/****************************************************************/ - - -#include -#include -#include - -#include - -#define DEFALT_SQL_STMT "SELECT * FROM db" -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - - -/******************************************************** -** -** main :- -** -********************************************************/ - -int -main( int argc, char * argv[] ) -{ - - char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ; - const char *pszT; - int i, j, k, l, x ; - MYSQL * myData ; - MYSQL_RES * res ; - MYSQL_FIELD * fd ; - MYSQL_ROW row ; - - //....just curious.... - printf( "sizeof( MYSQL ) == %d\n", (int) sizeof( MYSQL ) ) ; - if ( argc == 2 ) - { - strcpy( szDB, argv[ 1 ] ) ; - strcpy( szSQL, DEFALT_SQL_STMT ) ; - if (!strcmp(szDB,"--debug")) - { - strcpy( szDB, "mysql" ) ; - printf("Some mysql struct information (size and offset):\n"); - printf("net:\t%3d %3d\n",(int) sizeof(myData->net), - (int) offsetof(MYSQL,net)); - printf("host:\t%3d %3d\n",(int) sizeof(myData->host), - (int) offsetof(MYSQL,host)); - printf("port:\t%3d %3d\n", (int) sizeof(myData->port), - (int) offsetof(MYSQL,port)); - printf("protocol_version:\t%3d %3d\n", - (int) sizeof(myData->protocol_version), - (int) offsetof(MYSQL,protocol_version)); - printf("thread_id:\t%3d %3d\n",(int) sizeof(myData->thread_id), - (int) offsetof(MYSQL,thread_id)); - printf("affected_rows:\t%3d %3d\n",(int) sizeof(myData->affected_rows), - (int) offsetof(MYSQL,affected_rows)); - printf("packet_length:\t%3d %3d\n",(int) sizeof(myData->packet_length), - (int) offsetof(MYSQL,packet_length)); - printf("status:\t%3d %3d\n",(int) sizeof(myData->status), - (int) offsetof(MYSQL,status)); - printf("fields:\t%3d %3d\n",(int) sizeof(myData->fields), - (int) offsetof(MYSQL,fields)); - printf("field_alloc:\t%3d %3d\n",(int) sizeof(myData->field_alloc), - (int) offsetof(MYSQL,field_alloc)); - printf("free_me:\t%3d %3d\n",(int) sizeof(myData->free_me), - (int) offsetof(MYSQL,free_me)); - printf("options:\t%3d %3d\n",(int) sizeof(myData->options), - (int) offsetof(MYSQL,options)); - puts(""); - } - } - else if ( argc > 2 ) { - strcpy( szDB, argv[ 1 ] ) ; - strcpy( szSQL, argv[ 2 ] ) ; - } - else { - strcpy( szDB, "mysql" ) ; - strcpy( szSQL, DEFALT_SQL_STMT ) ; - } - //.... - - if ( (myData = mysql_init((MYSQL*) 0)) && - mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT, - NULL, 0 ) ) - { - myData->reconnect= 1; - if ( mysql_select_db( myData, szDB ) < 0 ) { - printf( "Can't select the %s database !\n", szDB ) ; - mysql_close( myData ) ; - return 2 ; - } - } - else { - printf( "Can't connect to the mysql server on port %d !\n", - MYSQL_PORT ) ; - mysql_close( myData ) ; - return 1 ; - } - //.... - if ( ! mysql_query( myData, szSQL ) ) { - res = mysql_store_result( myData ) ; - i = (int) mysql_num_rows( res ) ; l = 1 ; - printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ; - //....we can get the field-specific characteristics here.... - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - //.... - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Record #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - mysql_free_result( res ) ; - } - else printf( "Couldn't execute %s on the server !\n", szSQL ) ; - //.... - puts( "==== Diagnostic info ====" ) ; - pszT = mysql_get_client_info() ; - printf( "Client info: %s\n", pszT ) ; - //.... - pszT = mysql_get_host_info( myData ) ; - printf( "Host info: %s\n", pszT ) ; - //.... - pszT = mysql_get_server_info( myData ) ; - printf( "Server info: %s\n", pszT ) ; - //.... - res = mysql_list_processes( myData ) ; l = 1 ; - if (res) - { - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Process #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - } - else - { - printf("Got error %s when retreiving processlist\n",mysql_error(myData)); - } - //.... - res = mysql_list_tables( myData, "%" ) ; l = 1 ; - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Table #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - //.... - pszT = mysql_stat( myData ) ; - puts( pszT ) ; - //.... - mysql_close( myData ) ; - return 0 ; - -} diff --git a/tests/bug25714.c b/tests/bug25714.c index e9b2be44209..88485aa1962 100644 --- a/tests/bug25714.c +++ b/tests/bug25714.c @@ -29,8 +29,12 @@ int main (int argc, char **argv) MY_INIT(argv[0]); - if (argc != 2) + if (argc != 2 || !strcmp(argv[1], "--help")) + { + fprintf(stderr, "This program is a part of the MySQL test suite. " + "It is not intended to be executed directly by a user.\n"); return -1; + } mysql_init(&conn); if (!mysql_real_connect( diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b9f39021114..8ab8f209ae6 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -123,7 +123,7 @@ static void die(const char *file, int line, const char *expr) fflush(stdout); fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr); fflush(stderr); - abort(); + exit(1); } From ea739898281a86c074275f2f0a084840d7ed3e44 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Nov 2007 21:34:21 +0400 Subject: [PATCH 12/46] Fixed bug #32282: TEXT silently truncates when value is exactly 65536 bytes length. The server has been modified to report warnings on truncation to 65536 bytes as usual. sql/sql_string.cc: Fixed bug #32282. The well_formed_copy_nchars function returned an incorrect value of copied bytes of the truncated input string: extra length of the first truncated character added to the *from_end_pos pointer. That has been fixed. mysql-test/r/type_blob.result: Added test case for bug #32282. mysql-test/t/type_blob.test: Added test case for bug #32282. --- mysql-test/r/type_blob.result | 14 ++++++++++++++ mysql-test/t/type_blob.test | 11 +++++++++++ sql/sql_string.cc | 5 ++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index c72ee005428..80d233ee16a 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -807,4 +807,18 @@ set @@sql_mode='TRADITIONAL'; create table t1 (a text default ''); ERROR 42000: BLOB/TEXT column 'a' can't have a default value set @@sql_mode=''; +CREATE TABLE t (c TEXT CHARSET ASCII); +INSERT INTO t (c) VALUES (REPEAT('1',65537)); +Warnings: +Warning 1265 Data truncated for column 'c' at row 1 +INSERT INTO t (c) VALUES (REPEAT('2',65536)); +Warnings: +Warning 1265 Data truncated for column 'c' at row 1 +INSERT INTO t (c) VALUES (REPEAT('3',65535)); +SELECT LENGTH(c), CHAR_LENGTH(c) FROM t; +LENGTH(c) CHAR_LENGTH(c) +65535 65535 +65535 65535 +65535 65535 +DROP TABLE t; End of 5.0 tests diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index ba9f374a24c..d79b749dd65 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -436,4 +436,15 @@ set @@sql_mode='TRADITIONAL'; create table t1 (a text default ''); set @@sql_mode=''; +# +# Bug #32282: TEXT silently truncates when value is exactly 65536 bytes +# + +CREATE TABLE t (c TEXT CHARSET ASCII); +INSERT INTO t (c) VALUES (REPEAT('1',65537)); +INSERT INTO t (c) VALUES (REPEAT('2',65536)); +INSERT INTO t (c) VALUES (REPEAT('3',65535)); +SELECT LENGTH(c), CHAR_LENGTH(c) FROM t; +DROP TABLE t; + --echo End of 5.0 tests diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 9d7df73cd7a..606a9ddb26d 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -858,7 +858,7 @@ outp: with optional left padding (for binary -> UCS2 conversion) SYNOPSIS - well_formed_copy_nhars() + well_formed_copy_nchars() to Store result here to_length Maxinum length of "to" string to_cs Character set of "to" string @@ -997,7 +997,10 @@ outp: goto outp; } else + { + from= from_prev; break; + } } *from_end_pos= from; res= to - to_start; From 13105534fa6107c5afb139a4459c659329525b2e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Nov 2007 20:00:25 +0000 Subject: [PATCH 13/46] Bug#31048: Many nested subqueries may cause server crash. This bug is actually two. The first one manifests itself on an EXPLAIN SELECT query with nested subqueries that employs the filesort algorithm. The whole SELECT under explain is marked as UNCACHEABLE_EXPLAIN to preserve some temporary structures for explain. As a side-effect of this values of nested subqueries weren't cached and subqueries were re-evaluated many times. Each time buffer for filesort was allocated but wasn't freed because freeing occurs at the end of topmost SELECT. Thus all available memory was eaten up step by step and OOM event occur. The second bug manifests itself on SELECT queries with conditions where a subquery result is compared with a key field and the subquery itself also has such condition. When a long chain of such nested subqueries is present the stack overrun occur. This happens because at some point the range optimizer temporary puts the PARAM structure on the stack. Its size if about 8K and the stack is exhausted very fast. Now the subselect_single_select_engine::exec function allows subquery result caching when the UNCACHEABLE_EXPLAIN flag is set. Now the SQL_SELECT::test_quick_select function calls the check_stack_overrun function for stack checking purposes to prevent server crash. mysql-test/t/subselect.test: Added a test case for the bug#31048: Many nested subqueries may cause server crash. mysql-test/r/subselect.result: Added a test case for the bug#31048: Many nested subqueries may cause server crash. sql/opt_range.cc: Bug#31048: Many nested subqueries may cause server crash. Now the SQL_SELECT::test_quick_select function calls the check_stack_overrun function for stack checking purposes to preven server crash. sql/item_subselect.cc: Bug31048: Many nested subqueries may cause server crash. Now the subselect_single_select_engine::exec function allows subquery result caching when the UNCACHEABLE_EXPLAIN flag is set. --- mysql-test/r/subselect.result | 104 ++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 95 +++++++++++++++++++++++++++++++ sql/item_subselect.cc | 4 +- sql/opt_range.cc | 6 ++ 4 files changed, 208 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index be99bdb1afc..50017cc1485 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4139,4 +4139,108 @@ SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1; (SELECT SUM(t1.a) FROM t2 WHERE a=1) 3 DROP TABLE t1,t2; +create table t1(a int,b int,key(a),key(b)); +insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5), +(6,7),(7,4),(5,3); +select sum(a),a from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +sum(a) a +select sum(a),a from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +ERROR HY000: Thread stack overrun detected +explain select sum(a),a from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index a a 5 NULL 9 Using where; Using index +2 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +3 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +4 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +5 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +6 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +7 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +8 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +9 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +10 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +11 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +12 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort +13 SUBQUERY t1 range a a 5 NULL 1 Using where; Using temporary; Using filesort +14 SUBQUERY t1 index NULL a 5 NULL 9 Using index +explain select sum(a),a from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( +select sum(a) from t1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1 +)group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +ERROR HY000: Thread stack overrun detected +drop table t1; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index d076ca6bd33..1f912cadd4b 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2987,4 +2987,99 @@ SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1; SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1; DROP TABLE t1,t2; +# +# Bug31048: Many nested subqueries may cause server crash. +# +create table t1(a int,b int,key(a),key(b)); +insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5), + (6,7),(7,4),(5,3); +# test for the stack overflow bug +select sum(a),a from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +--replace_regex /overrun.*$/overrun detected/ +--error 1436 +select sum(a),a from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +# test for the memory consumption & subquery slowness bug +explain select sum(a),a from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +--replace_regex /overrun.*$/overrun detected/ +--error 1436 +explain select sum(a),a from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( + select sum(a) from t1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1 + )group by b limit 1)group by b limit 1)group by b limit 1) +group by a; +drop table t1; --echo End of 5.0 tests. diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 0020dd35c61..19eb7708539 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1800,7 +1800,9 @@ int subselect_single_select_engine::exec() DBUG_RETURN(1); } } - if (select_lex->uncacheable && executed) + if (select_lex->uncacheable && + select_lex->uncacheable != UNCACHEABLE_EXPLAIN + && executed) { if (join->reinit()) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 969777d4792..dbdb2b919dc 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1978,12 +1978,18 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, keys_to_use.intersect(head->keys_in_use_for_query); if (!keys_to_use.is_clear_all()) { +#ifndef EMBEDDED_LIBRARY // Avoid compiler warning + char buff[STACK_BUFF_ALLOC]; +#endif MEM_ROOT alloc; SEL_TREE *tree= NULL; KEY_PART *key_parts; KEY *key_info; PARAM param; + if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) + DBUG_RETURN(0); // Fatal error flag is set + /* set up parameter that is passed to all functions */ param.thd= thd; param.baseflag=head->file->table_flags(); From 4addb6b71777706f4050163c66f3c1d9dc896cfe Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Nov 2007 21:05:17 +0000 Subject: [PATCH 14/46] Bug#30384: Having SQL_BUFFER_RESULT option in the CREATE .. KEY(..) .. SELECT led to creating corrupted index. Corrected fix. The new method called prepare2 is added to the select_create class. As all preparations are done by the select_create::prepare function it doesn't do anything. Slightly changed algorithm of calling the start_bulk_insert function. Now it's called from the select_insert::prepare2 function when the SQL_BUFFER_RESULT flags is set. The is_bulk_insert_mode flag is removed as it is not needed anymore. sql/sql_class.h: Bug#30384: Having SQL_BUFFER_RESULT option in the CREATE .. KEY(..) .. SELECT led to creating corrupted index. Corrected fix. The new method called prepare2 is added to the select_create class. As all preparetions are done by the select_create::prepare function it doesn't do anything. The is_bulk_insert_mode flag is removed as it is not needed anymore. sql/sql_insert.cc: Bug#30384: Having SQL_BUFFER_RESULT option in the CREATE .. KEY(..) .. SELECT led to creating corrupted index. Slightly changed algorithm of calling the start_bulk_insert function. Now it's called from the select_insert::prepare2 function when the SQL_BUFFER_RESULT flags is set. Corrected fix. The is_bulk_insert_mode flag is removed as it is not needed anymore. --- sql/sql_class.h | 4 ++-- sql/sql_insert.cc | 18 +++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index e6d65f3133a..936798c9344 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2029,14 +2029,13 @@ class select_insert :public select_result_interceptor { ulonglong last_insert_id; COPY_INFO info; bool insert_into_view; - bool is_bulk_insert_mode; select_insert(TABLE_LIST *table_list_par, TABLE *table_par, List *fields_par, List *update_fields, List *update_values, enum_duplicates duplic, bool ignore); ~select_insert(); int prepare(List &list, SELECT_LEX_UNIT *u); - int prepare2(void); + virtual int prepare2(void); bool send_data(List &items); virtual void store_values(List &values); void send_error(uint errcode,const char *err); @@ -2071,6 +2070,7 @@ public: void send_error(uint errcode,const char *err); bool send_eof(); void abort(); + int prepare2(void) { return 0; } }; #include diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 770bbd1349d..48c1ee8e51f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2645,8 +2645,7 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, bool ignore_check_option_errors) :table_list(table_list_par), table(table_par), fields(fields_par), last_insert_id(0), - insert_into_view(table_list_par && table_list_par->view != 0), - is_bulk_insert_mode(FALSE) + insert_into_view(table_list_par && table_list_par->view != 0) { bzero((char*) &info,sizeof(info)); info.handle_duplicates= duplic; @@ -2755,14 +2754,14 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) Is table which we are changing used somewhere in other parts of query */ - if (!(lex->current_select->options & OPTION_BUFFER_RESULT) && - unique_table(thd, table_list, table_list->next_global, 0)) + if (unique_table(thd, table_list, table_list->next_global, 0)) { /* Using same table for INSERT and SELECT */ lex->current_select->options|= OPTION_BUFFER_RESULT; lex->current_select->join->select_options|= OPTION_BUFFER_RESULT; } - else if (!thd->prelocked_mode) + else if (!(lex->current_select->options & OPTION_BUFFER_RESULT) && + !thd->prelocked_mode) { /* We must not yet prepare the result table if it is the same as one of the @@ -2831,11 +2830,8 @@ int select_insert::prepare2(void) { DBUG_ENTER("select_insert::prepare2"); if (thd->lex->current_select->options & OPTION_BUFFER_RESULT && - !thd->prelocked_mode && !is_bulk_insert_mode) - { + !thd->prelocked_mode) table->file->start_bulk_insert((ha_rows) 0); - is_bulk_insert_mode= TRUE; - } DBUG_RETURN(0); } @@ -2941,7 +2937,6 @@ bool select_insert::send_eof() DBUG_ENTER("select_insert::send_eof"); error= (!thd->prelocked_mode) ? table->file->end_bulk_insert():0; - is_bulk_insert_mode= FALSE; table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); @@ -3277,10 +3272,7 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) if (info.handle_duplicates == DUP_UPDATE) table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE); if (!thd->prelocked_mode) - { table->file->start_bulk_insert((ha_rows) 0); - is_bulk_insert_mode= TRUE; - } thd->abort_on_warning= (!info.ignore && (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | From a8dd1299cc7b1cedd24533a4369970d22a7ba65d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Nov 2007 17:04:24 +0400 Subject: [PATCH 15/46] test case added for the bug #31155 mysql-test/r/gis.result: test result complete mysql-test/t/gis.test: test case added for the bug --- mysql-test/r/gis.result | 6 ++++++ mysql-test/t/gis.test | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 84b7b449cb5..953dd94be7a 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -957,4 +957,10 @@ COUNT(*) 2 DROP TABLE t1, t2; End of 5.0 tests +create table `t1` (`col002` point)engine=myisam; +insert into t1 values (),(),(); +select min(`col002`) from t1 union select `col002` from t1; +min(`col002`) +NULL +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 2520c9c478e..c115396ec03 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -631,4 +631,13 @@ SELECT 1; -- source include/gis_keys.inc +# +# Bug #31155 gis types in union'd select cause crash +# + +create table `t1` (`col002` point)engine=myisam; +insert into t1 values (),(),(); +select min(`col002`) from t1 union select `col002` from t1; +drop table t1; + --echo End of 5.0 tests From 429abc58452ce57256d6aacaece77d1672bccadf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Nov 2007 16:07:24 +0200 Subject: [PATCH 16/46] Bug #32268: Indexed queries give bogus MIN and MAX results Loose index scan does the grouping so the temp table does not need to do it, even when sorting. Fixed by checking if the grouping is already done before doing sorting and grouping in a temp table and do only sorting. mysql-test/r/group_min_max.result: Bug #32268: test case mysql-test/t/group_min_max.test: Bug #32268: test case sql/sql_select.cc: Bug #32268: don't group in the temp table if already done --- mysql-test/r/group_min_max.result | 46 +++++++++++++++++++++++++++++++ mysql-test/t/group_min_max.test | 24 ++++++++++++++++ sql/sql_select.cc | 3 +- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 2e5193f8563..5982931e677 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2307,3 +2307,49 @@ a 2 4 DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3); +INSERT INTO t1 SELECT a + 1, b FROM t1; +INSERT INTO t1 SELECT a + 2, b FROM t1; +EXPLAIN +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; +a MIN(b) MAX(b) +4 1 3 +3 1 3 +2 1 3 +1 1 3 +CREATE INDEX break_it ON t1 (a, b); +EXPLAIN +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL break_it 10 NULL 7 Using index for group-by +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a; +a MIN(b) MAX(b) +1 1 3 +2 1 3 +3 1 3 +4 1 3 +EXPLAIN +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL break_it 10 NULL 7 Using index for group-by; Using temporary; Using filesort +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; +a MIN(b) MAX(b) +4 1 3 +3 1 3 +2 1 3 +1 1 3 +EXPLAIN +SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL break_it 10 NULL 12 Using index +SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; +a MIN(b) MAX(b) AVG(b) +4 1 3 2.0000 +3 1 3 2.0000 +2 1 3 2.0000 +1 1 3 2.0000 +DROP TABLE t1; diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index e1010c9fcfe..7f2607b513d 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -888,7 +888,31 @@ SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1; DROP TABLE t1; +# +# Bug #32268: Indexed queries give bogus MIN and MAX results +# +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3); +INSERT INTO t1 SELECT a + 1, b FROM t1; +INSERT INTO t1 SELECT a + 2, b FROM t1; +EXPLAIN +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; +CREATE INDEX break_it ON t1 (a, b); +EXPLAIN +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a; +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a; + +EXPLAIN +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; +SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC; + +EXPLAIN +SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; +SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC; + +DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3d3b8668a79..757bfb3a29e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10256,7 +10256,8 @@ Next_select_func setup_end_select_func(JOIN *join) /* Set up select_end */ if (table) { - if (table->group && tmp_tbl->sum_func_count) + if (table->group && tmp_tbl->sum_func_count && + !tmp_tbl->precomputed_group_by) { if (table->s->keys) { From 0a91f285ad4a8d017a508e32a1c5d4deb7e0203a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Nov 2007 20:15:20 +0400 Subject: [PATCH 17/46] Fixed bug #32533. 8bit escape characters, termination and enclosed characters were silently ignored by SELECT INTO query, but LOAD DATA INFILE algorithm is 8bit-clean, so data was corrupted during encoding. sql/sql_class.cc: Fixed bug #32533. SELECT INTO OUTFILE encoding was not 8bit clear, it has been fixed for a symmetry with the LOAD DATA INFILE decoding algorithm. mysql-test/t/outfile_loaddata.test: Added test case for bug #32533. mysql-test/r/outfile_loaddata.result: Added test case for bug #32533. --- mysql-test/r/outfile_loaddata.result | 18 ++++++++++++++++++ mysql-test/t/outfile_loaddata.test | 24 ++++++++++++++++++++++++ sql/sql_class.cc | 17 ++++++++++------- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/outfile_loaddata.result b/mysql-test/r/outfile_loaddata.result index 1bcaf308b7c..4a9bdcf412d 100644 --- a/mysql-test/r/outfile_loaddata.result +++ b/mysql-test/r/outfile_loaddata.result @@ -82,4 +82,22 @@ c1 c2 -r- =raker= DROP TABLE t2; DROP TABLE t1; +# +# Bug#32533: SELECT INTO OUTFILE never escapes multibyte character +# +CREATE TABLE t1 (c1 VARCHAR(256)); +INSERT INTO t1 VALUES (0xC3); +SELECT HEX(c1) FROM t1; +HEX(c1) +C3 +SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' FIELDS ENCLOSED BY 0xC3 FROM t1; +TRUNCATE t1; +SELECT HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt')); +HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt')) +C35CC3C30A +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3; +SELECT HEX(c1) FROM t1; +HEX(c1) +C3 +DROP TABLE t1; # End of 5.0 tests. diff --git a/mysql-test/t/outfile_loaddata.test b/mysql-test/t/outfile_loaddata.test index 2f6ac998b3d..2a120871e7d 100644 --- a/mysql-test/t/outfile_loaddata.test +++ b/mysql-test/t/outfile_loaddata.test @@ -86,4 +86,28 @@ DROP TABLE t2; DROP TABLE t1; +--echo # +--echo # Bug#32533: SELECT INTO OUTFILE never escapes multibyte character +--echo # + +CREATE TABLE t1 (c1 VARCHAR(256)); +INSERT INTO t1 VALUES (0xC3); +SELECT HEX(c1) FROM t1; + +--let $file=$MYSQLTEST_VARDIR/tmp/bug32533.txt + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval SELECT * INTO OUTFILE '$file' FIELDS ENCLOSED BY 0xC3 FROM t1 +TRUNCATE t1; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval SELECT HEX(LOAD_FILE('$file')) + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval LOAD DATA INFILE '$file' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3 +SELECT HEX(c1) FROM t1; + +--remove_file $file +DROP TABLE t1; + --echo # End of 5.0 tests. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ef199b6f883..93f5a34d5c6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1219,16 +1219,18 @@ select_export::prepare(List &list, SELECT_LEX_UNIT *u) } } field_term_length=exchange->field_term->length(); - field_term_char= field_term_length ? (*exchange->field_term)[0] : INT_MAX; + field_term_char= field_term_length ? + (int) (uchar) (*exchange->field_term)[0] : INT_MAX; if (!exchange->line_term->length()) exchange->line_term=exchange->field_term; // Use this if it exists - field_sep_char= (exchange->enclosed->length() ? (*exchange->enclosed)[0] : - field_term_char); - escape_char= (exchange->escaped->length() ? (*exchange->escaped)[0] : -1); + field_sep_char= (exchange->enclosed->length() ? + (int) (uchar) (*exchange->enclosed)[0] : field_term_char); + escape_char= (exchange->escaped->length() ? + (int) (uchar) (*exchange->escaped)[0] : -1); is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char)); is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char)); line_sep_char= (exchange->line_term->length() ? - (*exchange->line_term)[0] : INT_MAX); + (int) (uchar) (*exchange->line_term)[0] : INT_MAX); if (!field_term_length) exchange->opt_enclosed=0; if (!exchange->enclosed->length()) @@ -1385,10 +1387,11 @@ bool select_export::send_data(List &items) Don't escape field_term_char by doubling - doubling is only valid for ENCLOSED BY characters: */ - (enclosed || !is_ambiguous_field_term || *pos != field_term_char)) + (enclosed || !is_ambiguous_field_term || + (int) (uchar) *pos != field_term_char)) { char tmp_buff[2]; - tmp_buff[0]= ((int) *pos == field_sep_char && + tmp_buff[0]= ((int) (uchar) *pos == field_sep_char && is_ambiguous_field_sep) ? field_sep_char : escape_char; tmp_buff[1]= *pos ? *pos : '0'; From 870d46819e517ec9dcd7b0e077147c69dbafa929 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Nov 2007 19:18:21 +0200 Subject: [PATCH 18/46] Bug #32400: Complex SELECT query returns correct result only on some occasions Referencing an element from the SELECT list in a WHERE clause is not permitted. The namespace of the WHERE clause is the table columns only. This was not enforced correctly when resolving outer references in sub-queries. Fixed by not allowing references to aliases in a sub-query in WHERE. mysql-test/include/ps_query.inc: Bug #32400: fixed old test queries mysql-test/r/ps_2myisam.result: Bug #32400: fixed old test queries mysql-test/r/ps_3innodb.result: Bug #32400: fixed old test queries mysql-test/r/ps_4heap.result: Bug #32400: fixed old test queries mysql-test/r/ps_5merge.result: Bug #32400: fixed old test queries mysql-test/r/ps_6bdb.result: Bug #32400: fixed old test queries mysql-test/r/ps_7ndb.result: Bug #32400: fixed old test queries mysql-test/r/subselect.result: Bug #32400: test case mysql-test/t/subselect.test: Bug #32400: test case sql/item.cc: Bug #32400: don't allow references to aliases in WHERE tests/mysql_client_test.c: Bug #32400: fixed old test queries --- mysql-test/include/ps_query.inc | 4 +-- mysql-test/r/ps_2myisam.result | 12 ++++---- mysql-test/r/ps_3innodb.result | 12 ++++---- mysql-test/r/ps_4heap.result | 12 ++++---- mysql-test/r/ps_5merge.result | 24 ++++++++-------- mysql-test/r/ps_6bdb.result | 12 ++++---- mysql-test/r/ps_7ndb.result | 12 ++++---- mysql-test/r/subselect.result | 47 +++++++++++++++++++++++++------ mysql-test/t/subselect.test | 50 +++++++++++++++++++++++++++++---- sql/item.cc | 2 +- tests/mysql_client_test.c | 2 +- 11 files changed, 128 insertions(+), 61 deletions(-) diff --git a/mysql-test/include/ps_query.inc b/mysql-test/include/ps_query.inc index e96d666eaec..ae6027a0e07 100644 --- a/mysql-test/include/ps_query.inc +++ b/mysql-test/include/ps_query.inc @@ -434,8 +434,8 @@ execute stmt1 ; let $1= 3 ; while ($1) { - prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; + prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; deallocate prepare stmt1 ; dec $1 ; diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 57932a6c455..3e0308330fa 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -783,20 +783,20 @@ a b 2 two 3 three 4 four -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index fd24c29d558..f3cdbedce6f 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -783,20 +783,20 @@ a b 2 two 3 three 4 four -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index b4596ab85bc..8477c05c787 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -784,20 +784,20 @@ a b 2 two 3 three 4 four -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 18982db937a..1bb16cf0a85 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -826,20 +826,20 @@ a b 2 two 3 three 4 four -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 @@ -3848,20 +3848,20 @@ a b 2 two 3 three 4 four -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 0e4086bc202..2a52aedbde0 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -783,20 +783,20 @@ a b 2 two 3 three 4 four -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 7a20fb3146d..2da7e7e40c2 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -783,20 +783,20 @@ a b 2 two 3 three 4 four -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 deallocate prepare stmt1 ; -prepare stmt1 from ' SELECT a as ccc from t1 where a+1= - (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) '; +prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1= + (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) '; execute stmt1 ; ccc 1 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index d3c40ce5bd5..3f22118c1f7 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -77,10 +77,9 @@ ERROR HY000: Incorrect usage of PROCEDURE and subquery SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); ERROR HY000: Incorrect parameters to procedure 'ANALYSE' SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; -a +ERROR 42S22: Unknown column 'a' in 'field list' SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL; -a -1 +ERROR 42S22: Unknown column 'a' in 'field list' SELECT (SELECT 1,2,3) = ROW(1,2,3); (SELECT 1,2,3) = ROW(1,2,3) 1 @@ -2304,24 +2303,27 @@ drop table t1,t2; CREATE TABLE t1 ( a int, b int ); CREATE TABLE t2 ( c int, d int ); INSERT INTO t1 VALUES (1,2), (2,3), (3,4); -SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc); +SELECT a AS abc, b FROM t1 outr WHERE b = +(SELECT MIN(b) FROM t1 WHERE a=outr.a); abc b 1 2 2 3 3 4 -INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc); +INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = +(SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t2; c d 1 2 2 3 3 4 -CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc); +CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = +(SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t3; abc b 1 2 2 3 3 4 -prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);"; +prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);"; execute stmt1; deallocate prepare stmt1; select * from t2; @@ -2333,7 +2335,7 @@ c d 2 3 3 4 drop table t3; -prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);"; +prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);"; execute stmt1; select * from t3; abc b @@ -2515,7 +2517,9 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680 INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF'); INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM'); /*!40000 ALTER TABLE t1 ENABLE KEYS */; -SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200); +SELECT DISTINCT Continent AS c FROM t1 outr WHERE +Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND +Population < 200); c Oceania drop table t1; @@ -4303,4 +4307,29 @@ LEFT(t1.a1,1) SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3); a2 DROP TABLE t1, t2, t3; +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4); +EXPLAIN +SELECT a AS out_a, MIN(b) FROM t1 +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) +GROUP BY a; +ERROR 42S22: Unknown column 'out_a' in 'where clause' +SELECT a AS out_a, MIN(b) FROM t1 +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) +GROUP BY a; +ERROR 42S22: Unknown column 'out_a' in 'where clause' +EXPLAIN +SELECT a AS out_a, MIN(b) FROM t1 t1_outer +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a) +GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1_outer ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using where +SELECT a AS out_a, MIN(b) FROM t1 t1_outer +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a) +GROUP BY a; +out_a MIN(b) +1 2 +2 4 +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index ba6abbacf50..8c3775a1ba4 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -32,7 +32,9 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1)); -- error 1108 SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); +-- error ER_BAD_FIELD_ERROR SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; +-- error ER_BAD_FIELD_ERROR SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL; SELECT (SELECT 1,2,3) = ROW(1,2,3); SELECT (SELECT 1,2,3) = ROW(1,2,1); @@ -1346,17 +1348,20 @@ drop table t1,t2; CREATE TABLE t1 ( a int, b int ); CREATE TABLE t2 ( c int, d int ); INSERT INTO t1 VALUES (1,2), (2,3), (3,4); -SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc); -INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc); +SELECT a AS abc, b FROM t1 outr WHERE b = + (SELECT MIN(b) FROM t1 WHERE a=outr.a); +INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = + (SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t2; -CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc); +CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = + (SELECT MIN(b) FROM t1 WHERE a=outr.a); select * from t3; -prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);"; +prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);"; execute stmt1; deallocate prepare stmt1; select * from t2; drop table t3; -prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);"; +prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);"; execute stmt1; select * from t3; deallocate prepare stmt1; @@ -1529,7 +1534,9 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680 INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF'); INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM'); /*!40000 ALTER TABLE t1 ENABLE KEYS */; -SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200); +SELECT DISTINCT Continent AS c FROM t1 outr WHERE + Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND + Population < 200); drop table t1; # @@ -3140,4 +3147,35 @@ SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3; SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3); DROP TABLE t1, t2, t3; +# +# Bug #32400: Complex SELECT query returns correct result only on some +# occasions +# + +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4); + +--error ER_BAD_FIELD_ERROR +EXPLAIN +SELECT a AS out_a, MIN(b) FROM t1 +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) +GROUP BY a; + +--error ER_BAD_FIELD_ERROR +SELECT a AS out_a, MIN(b) FROM t1 +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) +GROUP BY a; + +EXPLAIN +SELECT a AS out_a, MIN(b) FROM t1 t1_outer +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a) +GROUP BY a; + +SELECT a AS out_a, MIN(b) FROM t1 t1_outer +WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a) +GROUP BY a; + +DROP TABLE t1; + + --echo End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 431d82af331..3555df40060 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3641,7 +3641,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) } /* Search in SELECT and GROUP lists of the outer select. */ - if (outer_context->resolve_in_select_list) + if (place != IN_WHERE && place != IN_ON) { if (!(ref= resolve_ref_in_select_and_group(thd, this, select))) return -1; /* Some error occurred (e.g. ambiguous names). */ diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 65e18da97f1..823878db23d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -9283,7 +9283,7 @@ static void test_subqueries_ref() { MYSQL_STMT *stmt; int rc, i; - const char *query= "SELECT a as ccc from t1 where a+1=(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1)"; + const char *query= "SELECT a as ccc from t1 outr where a+1=(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1)"; myheader("test_subqueries_ref"); From 3a0d1f300bd3982f8332659270c531ecd8d1f288 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2007 02:48:01 +0300 Subject: [PATCH 19/46] sql_select.cc: Additional stack check for the bug#31048. sql/sql_select.cc: Additional stack check for the bug#31048. --- sql/sql_select.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3d3b8668a79..e25d0d78c87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2332,6 +2332,11 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, { int error; DBUG_ENTER("get_quick_record_count"); +#ifndef EMBEDDED_LIBRARY // Avoid compiler warning + char buff[STACK_BUFF_ALLOC]; +#endif + if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) + DBUG_RETURN(0); // Fatal error flag is set if (select) { select->head=table; From e9832ceeac70a62b53d72a6c48e672165d658d8f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2007 11:40:05 +0200 Subject: [PATCH 20/46] Bug #30788: Inconsistent retrieval of char/varchar Index lookup does not always guarantee that we can simply remove the relevant conditions from the WHERE clause. Reasons can be e.g. conversion errors, partial indexes etc. The optimizer was removing these parts of the WHERE condition without any further checking. This leads to "false positives" when using indexes. Fixed by checking the index reference conditions (using WHERE) when using indexes with sub-queries. mysql-test/r/subselect.result: Bug #30788: - using where - test case mysql-test/r/subselect3.result: Bug #30788: using where mysql-test/t/subselect.test: Bug #30788: test case sql/item.h: Bug #30788: - Declare eq() method of Item_cache descendants : this is used in test_if_ref() - preserve the field that is being cached for type comparisions sql/sql_select.cc: Bug #30788: Don't remove the WHERE when using index lookup with subqueries. --- mysql-test/r/subselect.result | 47 ++++++++++++++++++++++++++++------ mysql-test/r/subselect3.result | 2 +- mysql-test/t/subselect.test | 25 ++++++++++++++++++ sql/item.h | 22 +++++++++++++++- sql/sql_select.cc | 26 +++++++++++-------- 5 files changed, 101 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index be99bdb1afc..b4b6506a4de 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1307,7 +1307,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 Using where; Using index 2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using where Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY where (`test`.`t1`.`b` <> 30)))) +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY where ((`test`.`t1`.`b` <> 30) and ((`test`.`t2`.`a`) = `test`.`t1`.`a`))))) select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 @@ -1315,8 +1315,8 @@ a explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 Using where; Using index -2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 func 1 Using where -2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where; Using index +2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 func 1 +2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using index Warnings: Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and ((`test`.`t2`.`a`) = `test`.`t1`.`a`)))) drop table t1, t2, t3; @@ -1334,9 +1334,9 @@ a explain extended select * from t2 where t2.a in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index -2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 Using index +2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 Using index; Using where Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a))) +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where ((`test`.`t2`.`a`) = `test`.`t1`.`a`)))) select * from t2 where t2.a in (select a from t1 where t1.b <> 30); a 2 @@ -1346,7 +1346,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index 2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 Using index; Using where Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where (`test`.`t1`.`b` <> 30)))) +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and ((`test`.`t2`.`a`) = `test`.`t1`.`a`))))) select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); a 2 @@ -1373,7 +1373,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index 2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 Using index; Using where Warnings: -Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where (`test`.`t1`.`b` <> 30)))) +Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and ((`test`.`t2`.`a`) = `test`.`t1`.`a`))))) drop table t1, t2, t3; create table t1 (a int, b int); create table t2 (a int, b int); @@ -1737,7 +1737,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 12 Using where 2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using index; Using where Warnings: -Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not((`test`.`t1`.`id`,(((`test`.`t1`.`id`) in t1 on PRIMARY where (`test`.`t1`.`id` < 8)))))) +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not((`test`.`t1`.`id`,(((`test`.`t1`.`id`) in t1 on PRIMARY where ((`test`.`t1`.`id` < 8) and ((`test`.`t1`.`id`) = `test`.`t1`.`id`))))))) explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY tt ALL NULL NULL NULL NULL 12 Using where @@ -4139,4 +4139,35 @@ SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1; (SELECT SUM(t1.a) FROM t2 WHERE a=1) 3 DROP TABLE t1,t2; +CREATE TABLE t1 (a CHAR(1), b VARCHAR(10)); +INSERT INTO t1 VALUES ('a', 'aa'); +INSERT INTO t1 VALUES ('a', 'aaa'); +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); +a b +CREATE INDEX I1 ON t1 (a); +CREATE INDEX I2 ON t1 (b); +EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); +a b +CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); +INSERT INTO t2 SELECT * FROM t1; +CREATE INDEX I1 ON t2 (a); +CREATE INDEX I2 ON t2 (b); +EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 2 Using index; Using where +SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); +a b +EXPLAIN +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); +a b +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 098dacc8189..bdf00e4c307 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -757,6 +757,6 @@ a EXPLAIN SELECT a FROM t1 WHERE a NOT IN (SELECT a FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where -2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 Using index +2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 Using index; Using where DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index d076ca6bd33..9154e67c4fb 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2987,4 +2987,29 @@ SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1; SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1; DROP TABLE t1,t2; +# +# Bug #30788: Inconsistent retrieval of char/varchar +# + +CREATE TABLE t1 (a CHAR(1), b VARCHAR(10)); +INSERT INTO t1 VALUES ('a', 'aa'); +INSERT INTO t1 VALUES ('a', 'aaa'); +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); +CREATE INDEX I1 ON t1 (a); +CREATE INDEX I2 ON t1 (b); +EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1); + +CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10)); +INSERT INTO t2 SELECT * FROM t1; +CREATE INDEX I1 ON t2 (a); +CREATE INDEX I2 ON t2 (b); +EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); +SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2); +EXPLAIN +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); +SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500); + +DROP TABLE t1,t2; + --echo End of 5.0 tests. diff --git a/sql/item.h b/sql/item.h index b611c59b8f1..ba65014d5e6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2452,8 +2452,18 @@ class Item_cache: public Item protected: Item *example; table_map used_table_map; + /* + Field that this object will get value from. This is set/used by + index-based subquery engines to detect and remove the equality injected + by IN->EXISTS transformation. + For all other uses of Item_cache, cached_field doesn't matter. + */ + Field *cached_field; public: - Item_cache(): example(0), used_table_map(0) {fixed= 1; null_value= 1;} + Item_cache(): example(0), used_table_map(0), cached_field(0) + { + fixed= 1; null_value= 1; + } void set_used_tables(table_map map) { used_table_map= map; } @@ -2465,6 +2475,8 @@ public: decimals= item->decimals; collation.set(item->collation); unsigned_flag= item->unsigned_flag; + if (item->type() == FIELD_ITEM) + cached_field= ((Item_field *)item)->field; return 0; }; virtual void store(Item *)= 0; @@ -2475,6 +2487,14 @@ public: // to prevent drop fixed flag (no need parent cleanup call) void cleanup() {} void print(String *str); + bool eq_def(Field *field) + { + return cached_field ? cached_field->eq_def (field) : FALSE; + } + bool eq(const Item *item, bool binary_cmp) const + { + return this == item; + } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7af39071561..211ac416c6d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -217,6 +217,7 @@ static void select_describe(JOIN *join, bool need_tmp_table,bool need_order, bool distinct, const char *message=NullS); static Item *remove_additional_cond(Item* conds); static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab); +static bool test_if_ref(Item_field *left_item,Item *right_item); /* @@ -673,9 +674,6 @@ err: without "checking NULL", remove the predicates that were pushed down into the subquery. - We can remove the equalities that will be guaranteed to be true by the - fact that subquery engine will be using index lookup. - If the subquery compares scalar values, we can remove the condition that was wrapped into trig_cond (it will be checked when needed by the subquery engine) @@ -685,6 +683,12 @@ err: and non-NULL values, we'll do a full table scan and will rely on the equalities corresponding to non-NULL parts of left tuple to filter out non-matching records. + + TODO: We can remove the equalities that will be guaranteed to be true by the + fact that subquery engine will be using index lookup. This must be done only + for cases where there are no conversion errors of significance, e.g. 257 + that is searched in a byte. But this requires homogenization of the return + codes of all Field*::store() methods. */ void JOIN::remove_subq_pushed_predicates(Item **where) @@ -692,17 +696,13 @@ void JOIN::remove_subq_pushed_predicates(Item **where) if (conds->type() == Item::FUNC_ITEM && ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC && ((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM && - ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM) + ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM && + test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1], + ((Item_func *)conds)->arguments()[0])) { *where= 0; return; } - if (conds->type() == Item::COND_ITEM && - ((class Item_func *)this->conds)->functype() == - Item_func::COND_AND_FUNC) - { - *where= remove_additional_cond(conds); - } } @@ -1219,7 +1219,7 @@ JOIN::optimize() { if (!having) { - Item *where= 0; + Item *where= conds; if (join_tab[0].type == JT_EQ_REF && join_tab[0].ref.items[0]->name == in_left_expr_name) { @@ -11862,8 +11862,12 @@ static bool test_if_ref(Item_field *left_item,Item *right_item) Item *ref_item=part_of_refkey(field->table,field); if (ref_item && ref_item->eq(right_item,1)) { + right_item= right_item->real_item(); if (right_item->type() == Item::FIELD_ITEM) return (field->eq_def(((Item_field *) right_item)->field)); + /* remove equalities injected by IN->EXISTS transformation */ + else if (right_item->type() == Item::CACHE_ITEM) + return ((Item_cache *)right_item)->eq_def (field); if (right_item->const_item() && !(right_item->is_null())) { /* From a7c04594b8aced94b04329605f7789bb644baf91 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2007 22:56:42 +0400 Subject: [PATCH 21/46] Fixed bug #32556: assert in "using index for group-by" : is_last_prefix <= 0, file .\opt_range.cc. SELECT ... GROUP BY bit field failed with an assertion if the bit length of that field was not divisible by 8. sql/key.cc: Fixed bug #32556. Copying of "uneven" bits of a bit field was duplicated in the key_copy() and in the Field_bit::get_key_image(). So, instead of copying of the rest of a bit field, Field_bit::get_key_image() copied "uneven" bits to key image again, and the lowest field byte was not copied to key at all. Duplicated code has been removed from the key_copy function. mysql-test/t/type_bit.test: Added test case for bug #32556. mysql-test/r/type_bit.result: Added test case for bug #32556. --- mysql-test/r/type_bit.result | 10 ++++++++++ mysql-test/t/type_bit.test | 15 +++++++++++++++ sql/key.cc | 13 ------------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 4c1b80c2fd5..917f78d8f17 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -672,4 +672,14 @@ COUNT(DISTINCT b,c) 2 2 DROP TABLE t2; +CREATE TABLE t1(a BIT(13), KEY(a)); +INSERT INTO t1(a) VALUES +(65535),(65525),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535); +EXPLAIN SELECT 1 FROM t1 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL a 3 NULL 6 Using index for group-by +SELECT 1 FROM t1 GROUP BY a; +1 +1 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 4978f55d776..3095311bfbc 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -318,4 +318,19 @@ INSERT INTO t2 VALUES (3, 2, 'two'), (2, 3, 'three'), (2, 0, 'zero'), SELECT COUNT(DISTINCT b,c) FROM t2 GROUP BY a; DROP TABLE t2; +# +# BUG#32556 assert in "using index for group-by" : is_last_prefix <= 0, +# file .\opt_range.cc + +CREATE TABLE t1(a BIT(13), KEY(a)); +--disable_warnings +INSERT INTO t1(a) VALUES +(65535),(65525),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535); +--enable_warnings + +EXPLAIN SELECT 1 FROM t1 GROUP BY a; +SELECT 1 FROM t1 GROUP BY a; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/key.cc b/sql/key.cc index 2bdde46b6b3..1c044f3dc7d 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -106,19 +106,6 @@ void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length) key_part->null_bit); key_length--; } - if (key_part->type == HA_KEYTYPE_BIT) - { - Field_bit *field= (Field_bit *) (key_part->field); - if (field->bit_len) - { - uchar bits= get_rec_bits((uchar*) from_record + - key_part->null_offset + - (key_part->null_bit == 128), - field->bit_ofs, field->bit_len); - *to_key++= bits; - key_length--; - } - } if (key_part->key_part_flag & HA_BLOB_PART || key_part->key_part_flag & HA_VAR_LENGTH_PART) { From ae5ec36bcb2f20fc63c7b069330d3b826a68f9da Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Nov 2007 17:13:12 +0300 Subject: [PATCH 22/46] Fixed build failures on Windows introduced by the patch for bug #32221. We do not have any executables in libmysql/release/ anymore. --- scripts/make_win_bin_dist | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist index 849226c94ea..d065e171bb0 100755 --- a/scripts/make_win_bin_dist +++ b/scripts/make_win_bin_dist @@ -152,7 +152,6 @@ if [ x"$TARGET" != x"release" ] ; then cp server-tools/instance-manager/$TARGET/*.pdb $DESTDIR/bin/ fi cp tests/$TARGET/*.exe $DESTDIR/bin/ -cp libmysql/$TARGET/*.exe $DESTDIR/bin/ cp libmysql/$TARGET/libmysql.dll $DESTDIR/bin/ # FIXME really needed?! From a197c4e95ddd69cf9ebe3a6b2796a68f420c009a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Nov 2007 00:16:17 +0300 Subject: [PATCH 23/46] opt_range.cc: Fix for the bug#31048 for 64bit platforms. subselect.test, subselect.result: Corrected text case for the bug#31048. mysql-test/t/subselect.test: Corrected text case for the bug#31048. mysql-test/r/subselect.result: Corrected text case for the bug#31048. sql/opt_range.cc: Fix for the bug#31048 for 64bit platforms. --- mysql-test/r/subselect.result | 15 ++++++--------- mysql-test/t/subselect.test | 10 ++++------ sql/opt_range.cc | 2 +- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index a99b5e5925b..4c398b12a8c 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4148,9 +4148,8 @@ select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( -select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( -select sum(a) from t1 -)group by b limit 1)group by b limit 1)group by b limit 1 +select sum(a) from t1 where a> ( select sum(a) from t1 +)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1) @@ -4191,9 +4190,8 @@ select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( -select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( -select sum(a) from t1 -)group by b limit 1)group by b limit 1)group by b limit 1 +select sum(a) from t1 where a> ( select sum(a) from t1 +)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1) @@ -4210,9 +4208,8 @@ id select_type table type possible_keys key key_len ref rows Extra 9 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort 10 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort 11 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort -12 SUBQUERY t1 range a a 5 NULL 9 Using where; Using temporary; Using filesort -13 SUBQUERY t1 range a a 5 NULL 1 Using where; Using temporary; Using filesort -14 SUBQUERY t1 index NULL a 5 NULL 9 Using index +12 SUBQUERY t1 range a a 5 NULL 1 Using where; Using temporary; Using filesort +13 SUBQUERY t1 index NULL a 5 NULL 9 Using index explain select sum(a),a from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 64b390e413d..562794ba501 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3000,9 +3000,8 @@ select sum(a),a from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( - select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( - select sum(a) from t1 - )group by b limit 1)group by b limit 1)group by b limit 1 + select sum(a) from t1 where a> ( select sum(a) from t1 + )group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1) @@ -3044,9 +3043,8 @@ explain select sum(a),a from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( - select sum(a) from t1 where a> ( select sum(a) from t1 where a> ( - select sum(a) from t1 - )group by b limit 1)group by b limit 1)group by b limit 1 + select sum(a) from t1 where a> ( select sum(a) from t1 + )group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1 )group by b limit 1)group by b limit 1)group by b limit 1) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index dbdb2b919dc..1a3c2bec621 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1987,7 +1987,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, KEY *key_info; PARAM param; - if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) + if (check_stack_overrun(thd, 2*STACK_MIN_SIZE, buff)) DBUG_RETURN(0); // Fatal error flag is set /* set up parameter that is passed to all functions */ From e4dc9a8e6e13405859afda2d472e4cc4b6dc169c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 24 Nov 2007 14:57:09 +0400 Subject: [PATCH 24/46] merging fix mysql-test/r/gis.result: result fixed mysql-test/t/gis.test: test fixed --- mysql-test/r/gis.result | 2 +- mysql-test/t/gis.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 9c7f2bb4beb..4334a34c3ff 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -742,7 +742,7 @@ select geomfromtext(col9,col89) as a from t1; a NULL DROP TABLE t1; -create table t1(col1 geometry not null,col15 geometrycollection not +create table t1(col1 geometry default null,col15 geometrycollection not null,spatial index(col15),index(col1(15)))engine=myisam; insert into t1 set col15 = GeomFromText('POINT(6 5)'); insert into t1 set col15 = GeomFromText('POINT(6 5)'); diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 6d7ec046c4c..d578b5c9955 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -443,7 +443,7 @@ DROP TABLE t1; # Bug #30284 spatial key corruption # -create table t1(col1 geometry not null,col15 geometrycollection not +create table t1(col1 geometry default null,col15 geometrycollection not null,spatial index(col15),index(col1(15)))engine=myisam; insert into t1 set col15 = GeomFromText('POINT(6 5)'); insert into t1 set col15 = GeomFromText('POINT(6 5)'); From f3f9855d133060c5279349edac49546748ceae57 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Nov 2007 13:36:24 +0200 Subject: [PATCH 25/46] Bug #32036: EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 There was a difference in how UNIONs are handled on top level and when in sub-query. Because the rules for sub-queries were syntactically allowing cases that are not currently supported by the server we had crashes (this bug) or wrong results (bug 32051). Fixed by making the syntax rules for UNIONs match the ones at top level. These rules however do not support nesting UNIONs, e.g. (SELECT a FROM t1 UNION ALL SELECT b FROM t2) UNION (SELECT c FROM t3 UNION ALL SELECT d FROM t4) Supports for statements with nested UNIONs will be added in a future version. mysql-test/r/subselect.result: Bug #32036: test case mysql-test/t/subselect.test: Bug #32036: test case sql/sql_yacc.yy: Bug #32036: Make the syntax rules for UNIONs in subqueries the same as for top level UNIONs. --- mysql-test/r/subselect.result | 35 +++++++++++++++++++++------- mysql-test/t/subselect.test | 31 ++++++++++++++++++++++++- sql/sql_yacc.yy | 43 ++++++++++++----------------------- 3 files changed, 72 insertions(+), 37 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index bfacfc86eef..352519badcd 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3558,22 +3558,19 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS (SELECT i FROM t1) UNION (SELECT i FROM t1) ); -i +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION +(SELECT i FROM t1) +)' at line 3 SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); -i +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION (SELECT i FROM t1)))' at line 2 explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union (select t12.i from t1 t12)) from t1' at line 1 explain select * from t1 where not exists ((select t11.i from t1 t11) union (select t12.i from t1 t12)); -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used -3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table -4 UNION t12 system NULL NULL NULL NULL 0 const row not found -NULL UNION RESULT ALL NULL NULL NULL NULL NULL +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union (select t12.i from t1 t12))' at line 2 DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b)); insert into t1 (a) values (FLOOR(rand() * 100)); @@ -4150,4 +4147,26 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; 0 0 DROP TABLE t1, t2; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); +2 +2 +2 +EXPLAIN EXTENDED +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 AS `1` from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) +EXPLAIN EXTENDED +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION +(SELECT 1 FROM t2 WHERE t1.a = t2.a)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION +(SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2 +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index b5279331a5f..43e8c2532bf 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2448,12 +2448,16 @@ DROP TABLE t1, t2; CREATE TABLE t1 (i INT); (SELECT i FROM t1) UNION (SELECT i FROM t1); +#TODO:not supported +--error ER_PARSE_ERROR SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS ( (SELECT i FROM t1) UNION (SELECT i FROM t1) ); +#TODO:not supported +--error ER_PARSE_ERROR SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); @@ -2461,7 +2465,9 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); --error 1064 explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; -#supported + +#TODO:not supported +--error ER_PARSE_ERROR explain select * from t1 where not exists ((select t11.i from t1 t11) union (select t12.i from t1 t12)); @@ -3002,4 +3008,27 @@ INSERT INTO t2 VALUES (103, 203); SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1; DROP TABLE t1, t2; +# +# Bug #32036: EXISTS within a WHERE clause with a UNION crashes MySQL 5.122 +# + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); + +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (1),(2); + +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); +EXPLAIN EXTENDED +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a)); + + +#TODO:not supported +--error ER_PARSE_ERROR +EXPLAIN EXTENDED +SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION + (SELECT 1 FROM t2 WHERE t1.a = t2.a)); + +DROP TABLE t1,t2; + --echo End of 5.0 tests. diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3401bf739b3..2e2a9b180d0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1137,7 +1137,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type internal_variable_name -%type subselect subselect_init +%type subselect take_first_select get_select_lex %type comp_op @@ -9422,35 +9422,22 @@ union_option: | ALL { $$=0; } ; -subselect: - SELECT_SYM subselect_start subselect_init subselect_end +take_first_select: /* empty */ { - $$= $3; - } - | '(' subselect_start subselect ')' - { - THD *thd= YYTHD; - /* - note that a local variable can't be used for - $3 as it's used in local variable construction - and some compilers can't guarnatee the order - in which the local variables are initialized. - */ - List_iterator it($3->item_list); - Item *item; - /* - we must fill the items list for the "derived table". - */ - while ((item= it++)) - add_item_to_list(thd, item); - } - union_clause subselect_end { $$= $3; }; + $$= Lex->current_select->master_unit()->first_select(); + }; -subselect_init: - select_init2 - { - $$= Lex->current_select->master_unit()->first_select(); - }; +subselect: + SELECT_SYM subselect_start select_init2 take_first_select + subselect_end + { + $$= $4; + } + | '(' subselect_start select_paren take_first_select + subselect_end ')' + { + $$= $4; + }; subselect_start: { From 7257ed0e103abe0550c256b1b2cc46c4c918755f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Nov 2007 16:25:18 +0400 Subject: [PATCH 26/46] Bug #31900 Wrong confusing comment in mysql_com.h header file. comment fixed as we truly need const_item to be 1 to mark constant function include/mysql_com.h: Bug #31900 Wrong confusing comment in mysql_com.h header file. comment fixed --- include/mysql_com.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 56c7f7d2ab5..016df41476b 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -325,11 +325,11 @@ typedef struct st_udf_args typedef struct st_udf_init { - my_bool maybe_null; /* 1 if function can return NULL */ - unsigned int decimals; /* for real functions */ - unsigned long max_length; /* For string functions */ - char *ptr; /* free pointer for function data */ - my_bool const_item; /* 0 if result is independent of arguments */ + my_bool maybe_null; /* 1 if function can return NULL */ + unsigned int decimals; /* for real functions */ + unsigned long max_length; /* For string functions */ + char *ptr; /* free pointer for function data */ + my_bool const_item; /* 1 if function always returns the same value */ } UDF_INIT; /* Constants when using compression */ From 1836b736000595b3b63c03b1a6db01003b01e395 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Nov 2007 18:36:05 +0300 Subject: [PATCH 27/46] 5.0 version of the fix for bug #9481: mysql_insert_id() returns 0 after insert ... select. The 5.0 manual page for mysql_insert_id() does not mention anything about INSERT ... SELECT, though its current behavior is incosistent with what the manual says about the plain INSERT. Fixed by changing the AUTO_INCREMENT and mysql_insert_id() handling logic in INSERT ... SELECT to be consistent with the INSERT behavior, the manual, and the changes in 5.1 introduced by WL3146: - mysql_insert_id() now returns the first automatically generated AUTO_INCREMENT value that was successfully inserted by INSERT ... SELECT - if an INSERT ... SELECT statement is executed, and no automatically generated value is successfully inserted, mysql_insert_id() now returns the ID of the last inserted row. sql/sql_class.h: Replaced last_insert_id with autoinc_value_of_last_inserted_row to be consistent with 5.1 code. sql/sql_insert.cc: Revised the AUTO_INCREMENT and mysql_insert_id() handling logic in INSERT ... SELECT to be consistent with INSERT behavior, the manual, and changes in 5.1 introduced by WL3146: - mysql_insert_id() now returns the first automatically generated AUTO_INCREMENT value that was successfully inserted; - if an INSERT ... SELECT statement is executed, and no automatically generated value is successfully inserted, mysql_insert_id() now returns the ID of the last inserted row. tests/mysql_client_test.c: Backported the test cases related to INSERT ... SELECT and mysql_insert_id() from WL3146 patch to 5.0. --- sql/sql_class.h | 3 +- sql/sql_insert.cc | 48 ++++++++-- tests/mysql_client_test.c | 182 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+), 9 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index 93a9d4d6da2..5a5607469d9 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2048,7 +2048,8 @@ class select_insert :public select_result_interceptor { TABLE_LIST *table_list; TABLE *table; List *fields; - ulonglong last_insert_id; + ulonglong autoinc_value_of_last_inserted_row; // not autogenerated + ulonglong autoinc_value_of_first_inserted_row; // autogenerated COPY_INFO info; bool insert_into_view; bool is_bulk_insert_mode; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 770bbd1349d..70f73f90be4 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2644,7 +2644,8 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, enum_duplicates duplic, bool ignore_check_option_errors) :table_list(table_list_par), table(table_par), fields(fields_par), - last_insert_id(0), + autoinc_value_of_last_inserted_row(0), + autoinc_value_of_first_inserted_row(0), insert_into_view(table_list_par && table_list_par->view != 0), is_bulk_insert_mode(FALSE) { @@ -2901,15 +2902,25 @@ bool select_insert::send_data(List &values) } if (table->next_number_field) { + /* + If no value has been autogenerated so far, we need to remember the + value we just saw, we may need to send it to client in the end. + */ + if (!thd->insert_id_used) + autoinc_value_of_last_inserted_row= table->next_number_field->val_int(); /* Clear auto-increment field for the next record, if triggers are used we will clear it twice, but this should be cheap. */ table->next_number_field->reset(); - if (!last_insert_id && thd->insert_id_used) - last_insert_id= thd->last_insert_id; + if (!autoinc_value_of_last_inserted_row && thd->insert_id_used) + autoinc_value_of_last_inserted_row= thd->last_insert_id; } } + + if (thd->insert_id_used && !autoinc_value_of_first_inserted_row) + autoinc_value_of_first_inserted_row= thd->last_insert_id; + DBUG_RETURN(error); } @@ -2938,6 +2949,7 @@ bool select_insert::send_eof() { int error, error2; bool changed, transactional_table= table->file->has_transactions(); + ulonglong id; DBUG_ENTER("select_insert::send_eof"); error= (!thd->prelocked_mode) ? table->file->end_bulk_insert():0; @@ -2959,8 +2971,17 @@ bool select_insert::send_eof() DBUG_ASSERT(transactional_table || !changed || thd->transaction.stmt.modified_non_trans_table); - if (last_insert_id) - thd->insert_id(info.copied ? last_insert_id : 0); // For binary log + // For binary log + if (autoinc_value_of_last_inserted_row) + { + if (info.copied) + thd->insert_id(autoinc_value_of_last_inserted_row); + else + { + autoinc_value_of_first_inserted_row= 0; + thd->insert_id(0); + } + } /* Write to binlog before commiting transaction */ if (mysql_bin_log.is_open()) { @@ -2987,7 +3008,9 @@ bool select_insert::send_eof() thd->row_count_func= info.copied + info.deleted + ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? info.touched : info.updated); - ::send_ok(thd, (ulong) thd->row_count_func, last_insert_id, buff); + id= autoinc_value_of_first_inserted_row > 0 ? + autoinc_value_of_first_inserted_row : thd->last_insert_id; + ::send_ok(thd, (ulong) thd->row_count_func, id, buff); DBUG_RETURN(0); } @@ -3016,8 +3039,17 @@ void select_insert::abort() if ((changed= info.copied || info.deleted || info.updated) && !transactional_table) { - if (last_insert_id) - thd->insert_id(last_insert_id); // For binary log + // For binary log + if (autoinc_value_of_last_inserted_row) + { + if (info.copied) + thd->insert_id(autoinc_value_of_last_inserted_row); + else + { + autoinc_value_of_first_inserted_row= 0; + thd->insert_id(0); + } + } if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 65e18da97f1..5b619886fba 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15199,6 +15199,187 @@ static void test_bug14169() } +/* + Test that mysql_insert_id() behaves as documented in our manual +*/ + +static void test_mysql_insert_id() +{ + my_ulonglong res; + int rc; + + myheader("test_mysql_insert_id"); + + rc= mysql_query(mysql, "drop table if exists t1"); + myquery(rc); + /* table without auto_increment column */ + rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))"); + myquery(rc); + rc= mysql_query(mysql, "insert into t1 values (1,'a')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "insert into t1 values (null,'b')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "insert into t1 select 5,'c'"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "insert into t1 select null,'d'"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 300); + rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)"); + myquery(rc); + res= mysql_insert_id(mysql); + /* + Behaviour change: old code used to return 0; but 400 is consistent + with INSERT VALUES, and the manual's section of mysql_insert_id() does not + say INSERT SELECT should be different. + */ + DIE_UNLESS(res == 400); + + /* table with auto_increment column */ + rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))"); + myquery(rc); + rc= mysql_query(mysql, "insert into t2 values (1,'a')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 1); + /* this should not influence next INSERT if it doesn't have auto_inc */ + rc= mysql_query(mysql, "insert into t1 values (10,'e')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + + rc= mysql_query(mysql, "insert into t2 values (null,'b')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 2); + rc= mysql_query(mysql, "insert into t2 select 5,'c'"); + myquery(rc); + res= mysql_insert_id(mysql); + /* + Manual says that for multirow insert this should have been 5, but does not + say for INSERT SELECT. This is a behaviour change: old code used to return + 0. We try to be consistent with INSERT VALUES. + */ + DIE_UNLESS(res == 5); + rc= mysql_query(mysql, "insert into t2 select null,'d'"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 6); + /* with more than one row */ + rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 11); + rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'"); + myquery(rc); + res= mysql_insert_id(mysql); + /* + Manual says that for multirow insert this should have been 13, but does + not say for INSERT SELECT. This is a behaviour change: old code used to + return 0. We try to be consistent with INSERT VALUES. + */ + DIE_UNLESS(res == 13); + rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 14); + rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 16); + rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'"); + myquery_r(rc); + rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')"); + myquery_r(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + /* mixing autogenerated and explicit values */ + rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')"); + myquery_r(rc); + rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')"); + myquery_r(rc); + rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))"); + myquery(rc); + res= mysql_insert_id(mysql); + /* + according to the manual, this might be 20 or 300, but it looks like + auto_increment column takes priority over last_insert_id(). + */ + DIE_UNLESS(res == 20); + /* If first autogenerated number fails and 2nd works: */ + rc= mysql_query(mysql, "drop table t2"); + myquery(rc); + rc= mysql_query(mysql, "create table t2 (f1 int not null primary key " + "auto_increment, f2 varchar(255), unique (f2))"); + myquery(rc); + rc= mysql_query(mysql, "insert into t2 values (null,'e')"); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 1); + rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 2); + /* If autogenerated fails and explicit works: */ + rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 3); + /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */ + rc= mysql_query(mysql, "update t2 set f1=14 where f1=12"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "update t2 set f1=NULL where f1=14"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 372); + /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */ + rc= mysql_query(mysql, "insert into t2 values (null,'g')"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 15); + rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 0); + /* + Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row, + mysql_insert_id() returns the id of the row, instead of not being + affected. + */ + rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key " + "update f2=concat('we updated ',f2)"); + myquery(rc); + res= mysql_insert_id(mysql); + DIE_UNLESS(res == 15); + + rc= mysql_query(mysql, "drop table t1,t2"); + myquery(rc); +} + + /* Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer */ @@ -16237,6 +16418,7 @@ static struct my_tests_st my_tests[]= { { "test_bug17667", test_bug17667 }, { "test_bug19671", test_bug19671 }, { "test_bug15752", test_bug15752 }, + { "test_mysql_insert_id", test_mysql_insert_id }, { "test_bug21206", test_bug21206 }, { "test_bug21726", test_bug21726 }, { "test_bug15518", test_bug15518 }, From 67bf39f241bb1742dfa221218ff3d50842f58490 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Nov 2007 18:58:54 +0300 Subject: [PATCH 28/46] Fix for bug #28837: MyISAM storage engine error (134) doing delete with self-join When doing DELETE with self-join on a MyISAM or MERGE table, it could happen that a record being retrieved in join_read_next_same() has already been deleted by previous iterations. That caused the engine's index_next_same() method to fail with HA_ERR_RECORD_DELETED error and the whole DELETE query to be aborted with an error. Fixed by suppressing the HA_ERR_RECORD_DELETED error in hy_myisam::index_next_same() and ha_myisammrg::index_next_same(). Since HA_ERR_RECORD_DELETED can only be returned by MyISAM, there is no point in filtering this error in the SQL layer. mysql-test/r/merge.result: Added a test case for bug #28837. mysql-test/r/myisam.result: Added a test case for bug #28837. mysql-test/t/merge.test: Added a test case for bug #28837. mysql-test/t/myisam.test: Added a test case for bug #28837. sql/ha_myisam.cc: Skip HA_ERR_RECORD_DELETED silently when calling mi_rnext_same(). sql/ha_myisammrg.cc: Skip HA_ERR_RECORD_DELETED silently when calling mi_rnext_same(). --- mysql-test/r/merge.result | 37 +++++++++++++++++++++++++++++++++++++ mysql-test/r/myisam.result | 22 ++++++++++++++++++++++ mysql-test/t/merge.test | 22 ++++++++++++++++++++++ mysql-test/t/myisam.test | 17 +++++++++++++++++ sql/ha_myisam.cc | 8 ++++++-- sql/ha_myisammrg.cc | 8 ++++++-- 6 files changed, 110 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 42669eeb66f..7e8a0df6908 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -876,4 +876,41 @@ CHECK TABLE tm1; Table Op Msg_type Msg_text test.tm1 check status OK DROP TABLE tm1, t1, t2; +CREATE TABLE t1 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MyISAM; +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4); +INSERT INTO t1 SELECT * FROM t2; +INSERT INTO t1 SELECT * FROM t2; +CREATE TABLE t3 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MERGE +UNION(t1); +SELECT * FROM t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref; +id ref ref +4 4 5 +4 4 5 +4 4 5 +4 4 5 +SELECT * FROM t3; +id ref +1 3 +2 1 +3 2 +4 5 +4 4 +1 3 +2 1 +3 2 +4 5 +4 4 +DELETE FROM a USING t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref; +SELECT * FROM t3; +id ref +1 3 +2 1 +3 2 +4 5 +1 3 +2 1 +3 2 +4 5 +DROP TABLE t1, t2, t3; End of 5.0 tests diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 7fc29cd13ca..79a9891b15c 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1806,4 +1806,26 @@ SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1; a 1 DROP TABLE t1; +CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id)) ENGINE=MyISAM; +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref; +id ref ref +4 4 5 +SELECT * FROM t1; +id ref +1 3 +2 1 +3 2 +4 5 +4 4 +DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref; +SELECT * FROM t1; +id ref +1 3 +2 1 +3 2 +4 5 +DROP TABLE t1, t2; End of 5.0 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index c3e5cef5e63..7e64daf076a 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -507,4 +507,26 @@ SELECT * FROM tm1; CHECK TABLE tm1; DROP TABLE tm1, t1, t2; +# +# Bug #28837: MyISAM storage engine error (134) doing delete with self-join +# + +CREATE TABLE t1 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MyISAM; +CREATE TABLE t2 LIKE t1; + +INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4); +INSERT INTO t1 SELECT * FROM t2; +INSERT INTO t1 SELECT * FROM t2; + +CREATE TABLE t3 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MERGE + UNION(t1); + +SELECT * FROM t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref; +SELECT * FROM t3; +DELETE FROM a USING t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref; +SELECT * FROM t3; + +DROP TABLE t1, t2, t3; + + --echo End of 5.0 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index d5f403616c8..ab00af4cc1a 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1161,4 +1161,21 @@ ALTER TABLE t1 ENABLE KEYS; SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1; DROP TABLE t1; +# +# Bug#28837: MyISAM storage engine error (134) doing delete with self-join +# + +CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id)) ENGINE=MyISAM; +CREATE TABLE t2 LIKE t1; + +INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4); +INSERT INTO t1 SELECT * FROM t2; + +SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref; +SELECT * FROM t1; +DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref; +SELECT * FROM t1; + +DROP TABLE t1, t2; + --echo End of 5.0 tests diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 92fa9e405e1..86f04672676 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1602,10 +1602,14 @@ int ha_myisam::index_next_same(byte * buf, const byte *key __attribute__((unused)), uint length __attribute__((unused))) { + int error; DBUG_ASSERT(inited==INDEX); statistic_increment(table->in_use->status_var.ha_read_next_count, - &LOCK_status); - int error=mi_rnext_same(file,buf); + &LOCK_status); + do + { + error= mi_rnext_same(file,buf); + } while (error == HA_ERR_RECORD_DELETED); table->status=error ? STATUS_NOT_FOUND: 0; return error; } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 60aa4bd6adc..78492d2843d 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -294,9 +294,13 @@ int ha_myisammrg::index_next_same(byte * buf, const byte *key __attribute__((unused)), uint length __attribute__((unused))) { + int error; statistic_increment(table->in_use->status_var.ha_read_next_count, - &LOCK_status); - int error=myrg_rnext_same(file,buf); + &LOCK_status); + do + { + error= myrg_rnext_same(file,buf); + } while (error == HA_ERR_RECORD_DELETED); table->status=error ? STATUS_NOT_FOUND: 0; return error; } From d068dd1aabf29d7080a040469cf6ca58996f6fea Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Nov 2007 19:14:48 +0400 Subject: [PATCH 29/46] Fixed bug #32403: query causes a crash due to stack and memory corruptions. The right pointer field of the SEL_ARG structure was not initialized in the constructor and sometimes that led to server crashes. There is no testcase because the bug occurs only when uninitialized memory has particular values, which can't be re-created in the test suite. sql/opt_range.cc: Fixed bug #32403. The eq_tree function requires that SEL_ARG::left and SEL_ARG::right are equal to null pointer if SEL_ARG type is MAYBE_KEY, but SEL_ARG::right was not initialized and contained garbage. --- sql/opt_range.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 969777d4792..58ce6c8da7a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -250,6 +250,9 @@ public: Field *field; char *min_value,*max_value; // Pointer to range + /* + eq_tree() requires that left == right == 0 if the type is MAYBE_KEY. + */ SEL_ARG *left,*right; /* R-B tree children */ SEL_ARG *next,*prev; /* Links for bi-directional interval list */ SEL_ARG *parent; /* R-B tree parent */ @@ -265,7 +268,7 @@ public: SEL_ARG(Field *field, uint8 part, char *min_value, char *max_value, uint8 min_flag, uint8 max_flag, uint8 maybe_flag); SEL_ARG(enum Type type_arg) - :min_flag(0),elements(1),use_count(1),left(0),next_key_part(0), + :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0), color(BLACK), type(type_arg) {} inline bool is_same(SEL_ARG *arg) From 63b65169534c97f0c225859d2d6d49f3cee2bc10 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Nov 2007 17:16:52 +0200 Subject: [PATCH 30/46] Bug #30355: Incorrect ordering of UDF results There's currently no way of knowing the determinicity of an UDF. And the optimizer and the sequence() UDFs were making wrong assumptions about what the is_const member means. Plus there was no implementation of update_system_tables() causing the optimizer to overwrite the information returned by the _init function. Fixed by equating the assumptions about the semantics of is_const and providing a implementation of update_used_tables(). Added a TODO item for the UDF API change needed to make a better implementation. include/mysql_com.h: Bug #30355: comment added mysql-test/r/udf.result: Bug #30355: test case mysql-test/t/udf.test: Bug #30355: test case sql/item_func.cc: Bug #30355: keep const_item_cache and used_tables_cache in sync sql/item_func.h: Bug #30355: - a better implementation of update_used_tables() - keep const_item_cache and used_tables_cache in sync sql/udf_example.c: Bug #30355: Wrong value for const_item fixed. --- include/mysql_com.h | 4 ++++ mysql-test/r/udf.result | 27 ++++++++++++++++++++++ mysql-test/t/udf.test | 21 +++++++++++++++++ sql/item_func.cc | 6 +++++ sql/item_func.h | 50 +++++++++++++++++++++++++++++++++++++++++ sql/udf_example.c | 10 ++++----- 6 files changed, 112 insertions(+), 6 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 889579e3622..fc03d98194b 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -393,6 +393,10 @@ typedef struct st_udf_init char *ptr; /* free pointer for function data */ my_bool const_item; /* 0 if result is independent of arguments */ } UDF_INIT; +/* + TODO: add a notion for determinism of the UDF. + See Item_udf_func::update_used_tables () +*/ /* Constants when using compression */ #define NET_HEADER_SIZE 4 /* standard header size */ diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index e6797796ea0..a79be1c3189 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -327,4 +327,31 @@ DROP FUNCTION check_const_len; DROP PROCEDURE check_const_len_sp; DROP TRIGGER check_const_len_trigger; DROP TABLE const_len_bug; +CREATE FUNCTION sequence RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (4),(3),(2),(1); +INSERT INTO t2 SELECT * FROM t1; +SELECT sequence() AS seq, a FROM t1 ORDER BY seq ASC; +seq a +1 4 +2 3 +3 2 +4 1 +SELECT sequence() AS seq, a FROM t1 ORDER BY seq DESC; +seq a +4 1 +3 2 +2 3 +1 4 +SELECT * FROM t1 WHERE a = sequence(); +a +SELECT * FROM t2 WHERE a = sequence(); +a +1 +2 +3 +4 +DROP FUNCTION sequence; +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index 22b8ed10a49..648494b3df9 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -362,4 +362,25 @@ DROP PROCEDURE check_const_len_sp; DROP TRIGGER check_const_len_trigger; DROP TABLE const_len_bug; + +# +# Bug #30355: Incorrect ordering of UDF results +# + +--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB +eval CREATE FUNCTION sequence RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB"; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (4),(3),(2),(1); +INSERT INTO t2 SELECT * FROM t1; + +SELECT sequence() AS seq, a FROM t1 ORDER BY seq ASC; +SELECT sequence() AS seq, a FROM t1 ORDER BY seq DESC; + +SELECT * FROM t1 WHERE a = sequence(); +SELECT * FROM t2 WHERE a = sequence(); + +DROP FUNCTION sequence; +DROP TABLE t1,t2; + --echo End of 5.0 tests. diff --git a/sql/item_func.cc b/sql/item_func.cc index 264d9265bca..0309c1a17cb 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2968,6 +2968,12 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, func->max_length=min(initid.max_length,MAX_BLOB_WIDTH); func->maybe_null=initid.maybe_null; const_item_cache=initid.const_item; + /* + Keep used_tables_cache in sync with const_item_cache. + See the comment in Item_udf_func::update_used tables. + */ + if (!const_item_cache && !used_tables_cache) + used_tables_cache= RAND_TABLE_BIT; func->decimals=min(initid.decimals,NOT_FIXED_DEC); } initialized=1; diff --git a/sql/item_func.h b/sql/item_func.h index a31294c0395..734b215ddc0 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1016,6 +1016,56 @@ public: fixed= 1; return res; } + void update_used_tables() + { + /* + TODO: Make a member in UDF_INIT and return if a UDF is deterministic or + not. + Currently UDF_INIT has a member (const_item) that is an in/out + parameter to the init() call. + The code in udf_handler::fix_fields also duplicates the arguments + handling code in Item_func::fix_fields(). + + The lack of information if a UDF is deterministic makes writing + a correct update_used_tables() for UDFs impossible. + One solution to this would be : + - Add a is_deterministic member of UDF_INIT + - (optionally) deprecate the const_item member of UDF_INIT + - Take away the duplicate code from udf_handler::fix_fields() and + make Item_udf_func call Item_func::fix_fields() to process its + arguments as for any other function. + - Store the deterministic flag returned by _init into the + udf_handler. + - Don't implement Item_udf_func::fix_fields, implement + Item_udf_func::fix_length_and_dec() instead (similar to non-UDF + functions). + - Override Item_func::update_used_tables to call + Item_func::update_used_tables() and add a RAND_TABLE_BIT to the + result of Item_func::update_used_tables() if the UDF is + non-deterministic. + - (optionally) rename RAND_TABLE_BIT to NONDETERMINISTIC_BIT to + better describe its usage. + + The above would require a change of the UDF API. + Until that change is done here's how the current code works: + We call Item_func::update_used_tables() only when we know that + the function depends on real non-const tables and is deterministic. + This can be done only because we know that the optimizer will + call update_used_tables() only when there's possibly a new const + table. So update_used_tables() can only make a Item_func more + constant than it is currently. + That's why we don't need to do anything if a function is guaranteed + to return non-constant (it's non-deterministic) or is already a + const. + */ + if ((used_tables_cache & ~PSEUDO_TABLE_BITS) && + !(used_tables_cache & RAND_TABLE_BIT)) + { + Item_func::update_used_tables(); + if (!const_item_cache && !used_tables_cache) + used_tables_cache= RAND_TABLE_BIT; + } + } void cleanup(); Item_result result_type () const { return udf.result_type(); } table_map not_null_tables() const { return 0; } diff --git a/sql/udf_example.c b/sql/udf_example.c index df3a69755ad..4ca6133da03 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -648,13 +648,11 @@ my_bool sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return 1; } bzero(initid->ptr,sizeof(longlong)); - /* - Fool MySQL to think that this function is a constant - This will ensure that MySQL only evalutes the function - when the rows are sent to the client and not before any ORDER BY - clauses + /* + sequence() is a non-deterministic function : it has different value + even if called with the same arguments. */ - initid->const_item=1; + initid->const_item=0; return 0; } From 7c0db983ad8eb8e1d37cf8468bbfd32de87a14ad Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Nov 2007 18:24:24 +0100 Subject: [PATCH 31/46] Bug#32707: misdimensioned buffer in protocol layer Miscalculation in protocol-layer: size buffer correctly so even really long error messages cannot overflow our buffer. sql/protocol.cc: size buffer correctly so really long error messages cannot overflow it. --- sql/protocol.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/protocol.cc b/sql/protocol.cc index 7c7dfaf7bef..f7a34fde94a 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -56,7 +56,10 @@ void send_error(THD *thd, uint sql_errno, const char *err) { #ifndef EMBEDDED_LIBRARY uint length; - char buff[MYSQL_ERRMSG_SIZE+2], *pos; + /* + buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512 + */ + char buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos; #endif const char *orig_err= err; NET *net= &thd->net; From 1d062682f5098ea5c30b9b3fef844195790a095e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Nov 2007 10:37:07 +0400 Subject: [PATCH 32/46] Bug #32624 Error with multi queries in MySQL embedded server 5.1.22. server status wasn't properly sent to the client after the error by the embedded server. Wasn't noticed before as one usually stopped retrieving results after he gets an error. libmysqld/lib_sql.cc: Bug #32624 Error with multi queries in MySQL embedded server 5.1.22. server status transferred to the client after errors sql/protocol.cc: Bug #32624 Error with multi queries in MySQL embedded server 5.1.22. set server status before net_send_error_packet() call as this function sends it to the client in the embedded server tests/mysql_client_test.c: Bug #32624 Error with multi queries in MySQL embedded server 5.1.22. testcase added --- libmysqld/lib_sql.cc | 2 ++ sql/protocol.cc | 5 +++-- tests/mysql_client_test.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 7ac663480c8..ce692169a5f 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -73,6 +73,7 @@ void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data) net->last_errno= ei->last_errno; strmake(net->last_error, ei->info, sizeof(net->last_error)); memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate)); + mysql->server_status= ei->server_status; my_free((gptr) data, MYF(0)); } @@ -1027,6 +1028,7 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err) ei->last_errno= sql_errno; strmake(ei->info, err, sizeof(ei->info)-1); strmov(ei->sqlstate, mysql_errno_to_sqlstate(sql_errno)); + ei->server_status= thd->server_status; thd->cur_data= 0; } diff --git a/sql/protocol.cc b/sql/protocol.cc index 2bdbe83eea1..ac562a9f5ab 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -110,13 +110,14 @@ void net_send_error(THD *thd, uint sql_errno, const char *err) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, sql_errno, err); } + /* Abort multi-result sets */ + thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; + net_send_error_packet(thd, sql_errno, err); thd->is_fatal_error=0; // Error message is given thd->net.report_error= 0; - /* Abort multi-result sets */ - thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; DBUG_VOID_RETURN; } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 29935a4924d..33e7d66cb04 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -5643,6 +5643,20 @@ DROP TABLE IF EXISTS test_multi_tab"; (void) my_process_result_set(result); mysql_free_result(result); + /* + Check if errors in one of the queries handled properly. + */ + rc= mysql_query(mysql_local, "select 1; select * from not_existing_table"); + myquery(rc); + result= mysql_store_result(mysql_local); + mysql_free_result(result); + + rc= mysql_next_result(mysql_local); + DIE_UNLESS(rc > 0); + + rc= mysql_next_result(mysql_local); + DIE_UNLESS(rc < 0); + mysql_close(mysql_local); } From 23e402bf4595c6310bef2d7e6a3bcfefb4cb8173 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Nov 2007 14:52:36 +0400 Subject: [PATCH 33/46] Bug #29085 A small double precision number becomes zero. Denormalized DOUBLE-s can't be properly handled by old MIPS processors. So we need to enable specific mode for them so IRIX will do use software round to handle such numbers. sql/mysqld.cc: Bug #29085 A small double precision number becomes zero. reset_floating_point_exeption() renamed as set_proper_floating_point_mode() #ifdef __sgi code added to enable denormalized DOUBLE-s on IRIX --- sql/mysqld.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 51332053df6..62105e0093a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -193,7 +193,7 @@ typedef fp_except fp_except_t; this on freebsd */ -inline void reset_floating_point_exceptions() +inline void set_proper_floating_point_mode() { /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */ #if defined(__i386__) @@ -204,8 +204,22 @@ inline void reset_floating_point_exceptions() FP_X_IMP)); #endif } +#elif defined(__sgi) +/* for IRIX to use set_fpc_csr() */ +#include + +inline void set_proper_floating_point_mode() +{ + /* Enable denormalized DOUBLE values support for IRIX */ + { + union fpc_csr n; + n.fc_word = get_fpc_csr(); + n.fc_struct.flush = 0; + set_fpc_csr(n.fc_word); + } +} #else -#define reset_floating_point_exceptions() +#define set_proper_floating_point_mode() #endif /* __FreeBSD__ && HAVE_IEEEFP_H */ } /* cplusplus */ @@ -2876,7 +2890,7 @@ static int init_server_components() query_cache_init(); query_cache_resize(query_cache_size); randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2); - reset_floating_point_exceptions(); + set_proper_floating_point_mode(); init_thr_lock(); #ifdef HAVE_REPLICATION init_slave_list(); From 89a208850a714d5653207cffa2d654e86063a7e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Nov 2007 06:32:04 +0100 Subject: [PATCH 34/46] Bug#31177: Server variables can't be set to their current values Default values of variables were not subject to upper/lower bounds and step, while setting variables was. Bounds and step are also applied to defaults now; defaults are corrected quietly, values given by the user are corrected, and a correction-warning is thrown as needed. Lastly, very large values could wrap around, starting from 0 again. They are bounded at the maximum value for the respective data-type now if no lower maximum is specified in the variable's definition. client/mysql.cc: correct maxima in options array client/mysqltest.c: adjust minimum for "sleep" option so default value is no longer out of bounds. include/m_string.h: ullstr() - the unsigned brother of llstr() include/my_getopt.h: Flag if we bounded the value (that is, correct anything aside from making value a multiple of block-size) mysql-test/r/delayed.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/index_merge.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/innodb.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/innodb_mysql.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/key_cache.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/packet.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/ps.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/subselect.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/type_bit.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/type_bit_innodb.result: We throw a warning now when we adjust out of range parameters. mysql-test/r/variables.result: correct results: bounds and step apply to variables' default values, too mysql-test/t/variables.test: correct results: bounds and step apply to variables' default values, too mysys/my_getopt.c: - apply bounds/step to default values of variables (based on work by serg) - print complaints about incorrect values for variables (truncation etc., by requestion of consulting) - if no lower maximum is specified in variable definition, bound unsigned values at their maximum to prevent wrap-around - some calls to error_reporter had a \n, some didn't. remove \n from calls, let reporter-function handle it, so the default reporter behaves like that in mysqld sql/mysql_priv.h: correct RANGE_ALLOC_BLOCK_SIZE (cleared with monty) sql/mysqld.cc: correct maxima to correct data-type. correct minima where higher than default. correct range-alloc-block-size. correct inno variables so GET_* corresponds to actual variable's type. sql/set_var.cc: When the new value for a variable is out of bounds, we'll send the client a warning (but not if the value was simply not a multiple of 'blocksize'). sys_var_thd_ulong had this, sys_var_long_ptr_global didn't; broken out and streamlined to avoid duplication of code. strings/llstr.c: ullstr() - the unsigned brother of llstr() --- client/mysql.cc | 13 ++- client/mysqltest.c | 2 +- include/m_string.h | 1 + include/my_getopt.h | 3 +- mysql-test/r/delayed.result | 16 +++ mysql-test/r/index_merge.result | 2 + mysql-test/r/innodb.result | 4 + mysql-test/r/innodb_mysql.result | 2 + mysql-test/r/key_cache.result | 2 + mysql-test/r/packet.result | 8 ++ mysql-test/r/ps.result | 2 + mysql-test/r/subselect.result | 4 + mysql-test/r/type_bit.result | 2 + mysql-test/r/type_bit_innodb.result | 2 + mysql-test/r/variables.result | 30 ++++- mysql-test/t/variables.test | 2 +- mysys/my_getopt.c | 175 ++++++++++++++++++++-------- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 80 ++++++------- sql/set_var.cc | 70 +++++++---- strings/llstr.c | 6 + 21 files changed, 307 insertions(+), 121 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index aa34c69b945..05516183c9d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -737,9 +737,9 @@ static struct my_option my_long_options[] = 0, 1}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "Max packet length to send to, or receive from server", - (gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, GET_ULONG, - REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L, - MALLOC_OVERHEAD, 1024, 0}, + (gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, + GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096, + (longlong) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "Buffer for TCP/IP and socket communication", (gptr*) &opt_net_buffer_length, (gptr*) &opt_net_buffer_length, 0, GET_ULONG, @@ -747,12 +747,13 @@ static struct my_option my_long_options[] = {"select_limit", OPT_SELECT_LIMIT, "Automatic limit for SELECT when using --safe-updates", (gptr*) &select_limit, - (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, + (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX, + 0, 1, 0}, {"max_join_size", OPT_MAX_JOIN_SIZE, "Automatic limit for rows in a join when using --safe-updates", (gptr*) &max_join_size, - (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, - 0}, + (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX, + 0, 1, 0}, {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it" " uses old (pre-4.1.1) protocol", (gptr*) &opt_secure_auth, (gptr*) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/client/mysqltest.c b/client/mysqltest.c index eae3b05f61a..4dbf1b11323 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -4986,7 +4986,7 @@ static struct my_option my_long_options[] = "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"sleep", 'T', "Sleep always this many seconds on sleep commands.", - (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, 0, 0, + (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", (gptr*) &unix_sock, (gptr*) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, diff --git a/include/m_string.h b/include/m_string.h index 981111b8718..c26d0fb9260 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -219,6 +219,7 @@ double my_strtod(const char *str, char **end, int *error); double my_atof(const char *nptr); extern char *llstr(longlong value,char *buff); +extern char *ullstr(longlong value,char *buff); #ifndef HAVE_STRTOUL extern long strtol(const char *str, char **ptr, int base); extern ulong strtoul(const char *str, char **ptr, int base); diff --git a/include/my_getopt.h b/include/my_getopt.h index dcd6ad9d79b..f5688a37231 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -67,7 +67,8 @@ extern void my_print_variables(const struct my_option *options); extern void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint, const struct my_option *)); -ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp); +ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, + bool *fixed); my_bool getopt_compare_strings(const char *s, const char *t, uint length); C_MODE_END diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result index b37679847be..3b2a5027af5 100644 --- a/mysql-test/r/delayed.result +++ b/mysql-test/r/delayed.result @@ -109,12 +109,20 @@ c1 DROP TABLE t1; SET @@auto_increment_offset= @bug20627_old_auto_increment_offset; +Warnings: +Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@auto_increment_increment= @bug20627_old_auto_increment_increment; +Warnings: +Warning 1292 Truncated incorrect auto-increment-increment value: '0' SET @@session.auto_increment_offset= @bug20627_old_session_auto_increment_offset; +Warnings: +Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@session.auto_increment_increment= @bug20627_old_session_auto_increment_increment; +Warnings: +Warning 1292 Truncated incorrect auto-increment-increment value: '0' SET @bug20830_old_auto_increment_offset= @@auto_increment_offset= 2; SET @bug20830_old_auto_increment_increment= @@ -237,12 +245,20 @@ SUM(c1) DROP TABLE t1; SET @@auto_increment_offset= @bug20830_old_auto_increment_offset; +Warnings: +Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@auto_increment_increment= @bug20830_old_auto_increment_increment; +Warnings: +Warning 1292 Truncated incorrect auto-increment-increment value: '0' SET @@session.auto_increment_offset= @bug20830_old_session_auto_increment_offset; +Warnings: +Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@session.auto_increment_increment= @bug20830_old_session_auto_increment_increment; +Warnings: +Warning 1292 Truncated incorrect auto-increment-increment value: '0' CREATE TABLE t1(a BIT); INSERT DELAYED INTO t1 VALUES(1); FLUSH TABLE t1; diff --git a/mysql-test/r/index_merge.result b/mysql-test/r/index_merge.result index 15aa636d740..3a152fb2327 100644 --- a/mysql-test/r/index_merge.result +++ b/mysql-test/r/index_merge.result @@ -340,6 +340,8 @@ create table t4 (a int); insert into t4 values (1),(4),(3); set @save_join_buffer_size=@@join_buffer_size; set join_buffer_size= 4000; +Warnings: +Warning 1292 Truncated incorrect join_buffer_size value: '4000' explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) from t0 as A force index(i1,i2), t0 as B force index (i1,i2) where (A.key1 < 500000 or A.key2 < 3) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 6082a30bce3..d27bf8df2fa 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1833,6 +1833,8 @@ show variables like "innodb_thread_concurrency"; Variable_name Value innodb_thread_concurrency 8 set global innodb_thread_concurrency=1001; +Warnings: +Warning 1292 Truncated incorrect innodb_thread_concurrency value: '1001' show variables like "innodb_thread_concurrency"; Variable_name Value innodb_thread_concurrency 1000 @@ -1852,6 +1854,8 @@ show variables like "innodb_concurrency_tickets"; Variable_name Value innodb_concurrency_tickets 1000 set global innodb_concurrency_tickets=0; +Warnings: +Warning 1292 Truncated incorrect innodb_concurrency_tickets value: '0' show variables like "innodb_concurrency_tickets"; Variable_name Value innodb_concurrency_tickets 1 diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index d5f014b6840..b073e4bd6ce 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -712,6 +712,8 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2; UPDATE t2 SET c='2007-01-03'; INSERT INTO t1(b,c) SELECT b,c FROM t2; set @@sort_buffer_size=8192; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '8192' SELECT COUNT(*) FROM t1; COUNT(*) 3072 diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 08d8059f61b..9ada5dc0784 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -276,6 +276,8 @@ Variable_name Value Key_blocks_unused KEY_BLOCKS_UNUSED set global keycache2.key_buffer_size=0; set global keycache3.key_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect key_buffer_size value: '100' set global keycache3.key_buffer_size=0; create table t1 (mytext text, FULLTEXT (mytext)); insert t1 values ('aaabbb'); diff --git a/mysql-test/r/packet.result b/mysql-test/r/packet.result index dfb5595e02d..df0d9ff9adc 100644 --- a/mysql-test/r/packet.result +++ b/mysql-test/r/packet.result @@ -1,7 +1,15 @@ set global max_allowed_packet=100; +Warnings: +Warning 1292 Truncated incorrect max_allowed_packet value: '100' set max_allowed_packet=100; +Warnings: +Warning 1292 Truncated incorrect max_allowed_packet value: '100' set global net_buffer_length=100; +Warnings: +Warning 1292 Truncated incorrect net_buffer_length value: '100' set net_buffer_length=100; +Warnings: +Warning 1292 Truncated incorrect net_buffer_length value: '100' SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; len 1024 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 4db588e5cac..648d6468c0a 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -806,6 +806,8 @@ select @@max_prepared_stmt_count; @@max_prepared_stmt_count 0 set global max_prepared_stmt_count=10000000000000000; +Warnings: +Warning 1292 Truncated incorrect max_prepared_stmt_count value: '10000000000000000' select @@max_prepared_stmt_count; @@max_prepared_stmt_count 1048576 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index be99bdb1afc..42381e2768e 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3666,6 +3666,8 @@ CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b)); CREATE TABLE t2 (x int auto_increment, y int, z int, PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b)); SET SESSION sort_buffer_size = 32 * 1024; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '32768' SELECT SQL_NO_CACHE COUNT(*) FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM t1) t; @@ -4101,6 +4103,8 @@ INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26'); INSERT INTO `t2` VALUES ('abcdefghijk'); INSERT INTO `t2` VALUES ('asdf'); SET session sort_buffer_size=8192; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '8192' SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2; d1 1 diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 4c1b80c2fd5..0ee38426fbf 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -269,6 +269,8 @@ a+0 b+0 56 379 68 454 set @@max_length_for_sort_data=0; +Warnings: +Warning 1292 Truncated incorrect max_length_for_sort_data value: '0' select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; a+0 b+0 57 135 diff --git a/mysql-test/r/type_bit_innodb.result b/mysql-test/r/type_bit_innodb.result index c4506231f27..d0cf15e59a5 100644 --- a/mysql-test/r/type_bit_innodb.result +++ b/mysql-test/r/type_bit_innodb.result @@ -269,6 +269,8 @@ a+0 b+0 56 379 68 454 set @@max_length_for_sort_data=0; +Warnings: +Warning 1292 Truncated incorrect max_length_for_sort_data value: '0' select a+0, b+0 from t1 where a > 40 and a < 70 order by 2; a+0 b+0 57 135 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 47cd96b90b7..9c360ef4ab3 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -214,6 +214,8 @@ net_read_timeout 600 net_retry_count 10 net_write_timeout 500 set net_buffer_length=1; +Warnings: +Warning 1292 Truncated incorrect net_buffer_length value: '1' show variables like 'net_buffer_length'; Variable_name Value net_buffer_length 1024 @@ -238,7 +240,7 @@ show variables like '%alloc%'; Variable_name Value query_alloc_block_size 8192 query_prealloc_size 8192 -range_alloc_block_size 2048 +range_alloc_block_size 4096 transaction_alloc_block_size 8192 transaction_prealloc_size 4096 set @@range_alloc_block_size=1024*16; @@ -263,7 +265,7 @@ show variables like '%alloc%'; Variable_name Value query_alloc_block_size 8192 query_prealloc_size 8192 -range_alloc_block_size 2048 +range_alloc_block_size 4096 transaction_alloc_block_size 8192 transaction_prealloc_size 4096 SELECT @@version LIKE 'non-existent'; @@ -321,6 +323,8 @@ select @@autocommit, @@big_tables; @@autocommit @@big_tables 1 1 set global binlog_cache_size=100; +Warnings: +Warning 1292 Truncated incorrect binlog_cache_size value: '100' set bulk_insert_buffer_size=100; set character set cp1251_koi8; set character set default; @@ -349,17 +353,27 @@ set global flush_time=100; set insert_id=1; set interactive_timeout=100; set join_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect join_buffer_size value: '100' set last_insert_id=1; set global local_infile=1; set long_query_time=100; set low_priority_updates=1; set max_allowed_packet=100; +Warnings: +Warning 1292 Truncated incorrect max_allowed_packet value: '100' set global max_binlog_cache_size=100; +Warnings: +Warning 1292 Truncated incorrect max_binlog_cache_size value: '100' set global max_binlog_size=100; +Warnings: +Warning 1292 Truncated incorrect max_binlog_size value: '100' set global max_connect_errors=100; set global max_connections=100; set global max_delayed_threads=100; set max_heap_table_size=100; +Warnings: +Warning 1292 Truncated incorrect max_heap_table_size value: '100' set max_join_size=100; set max_sort_length=100; set max_tmp_tables=100; @@ -370,17 +384,25 @@ select @@max_user_connections; set global max_write_lock_count=100; set myisam_sort_buffer_size=100; set net_buffer_length=100; +Warnings: +Warning 1292 Truncated incorrect net_buffer_length value: '100' set net_read_timeout=100; set net_write_timeout=100; set global query_cache_limit=100; set global query_cache_size=100; set global query_cache_type=demand; set read_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect read_buffer_size value: '100' set read_rnd_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect read_rnd_buffer_size value: '100' set global rpl_recovery_rank=100; set global server_id=100; set global slow_launch_time=100; set sort_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '100' set @@max_sp_recursion_depth=10; select @@max_sp_recursion_depth; @@max_sp_recursion_depth @@ -420,6 +442,8 @@ set storage_engine=myisam; set global thread_cache_size=100; set timestamp=1, timestamp=default; set tmp_table_size=100; +Warnings: +Warning 1292 Truncated incorrect tmp_table_size value: '100' set tx_isolation="READ-COMMITTED"; set wait_timeout=100; set log_warnings=1; @@ -570,6 +594,8 @@ SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; Variable_name Value myisam_data_pointer_size 7 SET GLOBAL table_cache=-1; +Warnings: +Warning 1292 Truncated incorrect table_cache value: '0' SHOW VARIABLES LIKE 'table_cache'; Variable_name Value table_cache 1 diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index a352665379e..be7e7c2b413 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -126,7 +126,7 @@ set GLOBAL query_cache_size=100000; set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; set GLOBAL myisam_max_sort_file_size=default; ---replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE +--replace_result 2147482624 FILE_SIZE 2146435072 FILE_SIZE show variables like 'myisam_max_sort_file_size'; set global net_retry_count=10, session net_retry_count=10; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 71630e1b4c2..f41e8166876 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -31,6 +31,7 @@ my_bool getopt_compare_strings(const char *s, const char *t, uint length); static longlong getopt_ll(char *arg, const struct my_option *optp, int *err); +static longlong getopt_ll_limit_value(longlong, const struct my_option *); static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err); static void init_variables(const struct my_option *options); @@ -70,6 +71,7 @@ static void default_reporter(enum loglevel level, fprintf(stderr, "%s", "Info: "); vfprintf(stderr, format, args); va_end(args); + fputc('\n', stderr); fflush(stderr); } @@ -133,7 +135,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: Option '-O' requires an argument\n", + "%s: Option '-O' requires an argument", my_progname); return EXIT_ARGUMENT_REQUIRED; } @@ -151,7 +153,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: Option '--set-variable' requires an argument\n", + "%s: Option '--set-variable' requires an argument", my_progname); return EXIT_ARGUMENT_REQUIRED; } @@ -165,7 +167,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: Option '--set-variable' requires an argument\n", + "%s: Option '--set-variable' requires an argument", my_progname); return EXIT_ARGUMENT_REQUIRED; } @@ -228,7 +230,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: ambiguous option '--%s-%s' (--%s-%s)\n", + "%s: ambiguous option '--%s-%s' (--%s-%s)", my_progname, special_opt_prefix[i], cur_arg, special_opt_prefix[i], prev_found); @@ -265,7 +267,7 @@ int handle_options(int *argc, char ***argv, if (my_getopt_print_errors) my_getopt_error_reporter(option_is_loose ? WARNING_LEVEL : ERROR_LEVEL, - "%s: unknown variable '%s'\n", + "%s: unknown variable '%s'", my_progname, cur_arg); if (!option_is_loose) return EXIT_UNKNOWN_VARIABLE; @@ -273,9 +275,9 @@ int handle_options(int *argc, char ***argv, else { if (my_getopt_print_errors) - my_getopt_error_reporter(option_is_loose ? + my_getopt_error_reporter(option_is_loose ? WARNING_LEVEL : ERROR_LEVEL, - "%s: unknown option '--%s'\n", + "%s: unknown option '--%s'", my_progname, cur_arg); if (!option_is_loose) return EXIT_UNKNOWN_OPTION; @@ -293,7 +295,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: variable prefix '%s' is not unique\n", + "%s: variable prefix '%s' is not unique", my_progname, opt_str); return EXIT_VAR_PREFIX_NOT_UNIQUE; } @@ -301,7 +303,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: ambiguous option '--%s' (%s, %s)\n", + "%s: ambiguous option '--%s' (%s, %s)", my_progname, opt_str, prev_found, optp->name); return EXIT_AMBIGUOUS_OPTION; @@ -324,7 +326,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '%s' cannot take an argument\n", + "%s: option '%s' cannot take an argument", my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } @@ -337,7 +339,7 @@ int handle_options(int *argc, char ***argv, { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '--%s' cannot take an argument\n", + "%s: option '--%s' cannot take an argument", my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } @@ -359,7 +361,7 @@ int handle_options(int *argc, char ***argv, { my_getopt_error_reporter(WARNING_LEVEL, "%s: ignoring option '--%s' due to \ -invalid value '%s'\n", +invalid value '%s'", my_progname, optp->name, optend); continue; } @@ -390,7 +392,7 @@ invalid value '%s'\n", { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '--%s' requires an argument\n", + "%s: option '--%s' requires an argument", my_progname, optp->name); return EXIT_ARGUMENT_REQUIRED; } @@ -450,7 +452,7 @@ invalid value '%s'\n", { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: option '-%c' requires an argument\n", + "%s: option '-%c' requires an argument", my_progname, optp->id); return EXIT_ARGUMENT_REQUIRED; } @@ -463,7 +465,7 @@ invalid value '%s'\n", set_maximum_value))) { my_getopt_error_reporter(ERROR_LEVEL, - "%s: Error while setting value '%s' to '%s'\n", + "%s: Error while setting value '%s' to '%s'", my_progname, argument, optp->name); return error; } @@ -475,7 +477,7 @@ invalid value '%s'\n", { if (my_getopt_print_errors) my_getopt_error_reporter(ERROR_LEVEL, - "%s: unknown option '-%c'\n", + "%s: unknown option '-%c'", my_progname, *optend); return EXIT_UNKNOWN_OPTION; } @@ -486,13 +488,13 @@ invalid value '%s'\n", if ((error= setval(optp, value, argument, set_maximum_value))) { my_getopt_error_reporter(ERROR_LEVEL, - "%s: Error while setting value '%s' to '%s'\n", + "%s: Error while setting value '%s' to '%s'", my_progname, argument, optp->name); return error; } get_one_option(optp->id, optp, argument); - (*argc)--; /* option handled (short or long), decrease argument count */ + (*argc)--; /* option handled (short or long), decrease argument count */ } else /* non-option found */ (*argv)[argvpos++]= cur_arg; @@ -575,13 +577,17 @@ static int setval(const struct my_option *opts, gptr *value, char *argument, *((my_bool*) result_pos)= (my_bool) atoi(argument) != 0; break; case GET_INT: - case GET_UINT: /* fall through */ *((int*) result_pos)= (int) getopt_ll(argument, opts, &err); break; + case GET_UINT: + *((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err); + break; case GET_LONG: - case GET_ULONG: /* fall through */ *((long*) result_pos)= (long) getopt_ll(argument, opts, &err); break; + case GET_ULONG: + *((long*) result_pos)= (long) getopt_ull(argument, opts, &err); + break; case GET_LL: *((longlong*) result_pos)= getopt_ll(argument, opts, &err); break; @@ -733,23 +739,46 @@ static longlong eval_num_suffix (char *argument, int *error, char *option_name) static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) { - longlong num; + longlong num=eval_num_suffix(arg, err, (char*) optp->name); + return getopt_ll_limit_value(num, optp); +} + +/* + function: getopt_ll_limit_value + + Applies min/max/block_size to a numeric value of an option. + Returns "fixed" value. +*/ + +static longlong getopt_ll_limit_value(longlong num, + const struct my_option *optp) +{ + longlong old= num; + bool trunc= FALSE; + char buf1[255], buf2[255]; ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L); - - num= eval_num_suffix(arg, err, (char*) optp->name); - if (num > 0 && (ulonglong) num > (ulonglong) optp->max_value && + + if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) && optp->max_value) /* if max value is not set -> no upper limit */ { - char buf[22]; - my_getopt_error_reporter(WARNING_LEVEL, - "Truncated incorrect %s value: '%s'", - optp->name, llstr(num, buf)); - num= (ulonglong) optp->max_value; + trunc= TRUE; } + num= ((num - optp->sub_size) / block_size); num= (longlong) (num * block_size); - return max(num, optp->min_value); + + if (num < optp->min_value) + { + num= optp->min_value; + trunc= TRUE; + } + + if (trunc) + my_getopt_error_reporter(WARNING_LEVEL, + "option '%s': signed value %s adjusted to %s", + optp->name, llstr(old, buf1), llstr(num, buf2)); + return num; } /* @@ -761,25 +790,67 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err) { - ulonglong num; - - num= eval_num_suffix(arg, err, (char*) optp->name); - return getopt_ull_limit_value(num, optp); + ulonglong num= eval_num_suffix(arg, err, (char*) optp->name); + return getopt_ull_limit_value(num, optp, NULL); } -ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp) +ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, + bool *fix) { + bool adjusted= FALSE; + ulonglong old= num, mod; + char buf1[255], buf2[255]; + if ((ulonglong) num > (ulonglong) optp->max_value && optp->max_value) /* if max value is not set -> no upper limit */ + { num= (ulonglong) optp->max_value; + adjusted= TRUE; + } + + switch ((optp->var_type & GET_TYPE_MASK)) { + case GET_UINT: + if (num > (ulonglong) UINT_MAX) + { + num= ((ulonglong) UINT_MAX); + adjusted= TRUE; + } + break; + case GET_ULONG: +#if SIZEOF_LONG < SIZEOF_LONG_LONG + if (num > (ulonglong) ULONG_MAX) + { + num= ((ulonglong) ULONG_MAX); + adjusted= TRUE; + } +#endif + break; + default: + DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL); + break; + } + if (optp->block_size > 1) { num/= (ulonglong) optp->block_size; num*= (ulonglong) optp->block_size; } + if (num < (ulonglong) optp->min_value) + { num= (ulonglong) optp->min_value; + adjusted= TRUE; + } + + if (adjusted) + my_getopt_error_reporter(WARNING_LEVEL, + "option '%s': unsigned value %s adjusted to %s", + optp->name, ullstr(old, buf1), ullstr(num, buf2)); + + if (fix) + *fix= adjusted; + return num; } @@ -789,38 +860,43 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp) SYNOPSIS init_one_value() - option Option to initialize - value Pointer to variable + optp Option to initialize + value Pointer to variable */ -static void init_one_value(const struct my_option *option, gptr *variable, +static void init_one_value(const struct my_option *optp, gptr *variable, longlong value) { - switch ((option->var_type & GET_TYPE_MASK)) { + DBUG_ENTER("init_one_value"); + + switch ((optp->var_type & GET_TYPE_MASK)) { case GET_BOOL: *((my_bool*) variable)= (my_bool) value; break; case GET_INT: - *((int*) variable)= (int) value; + *((int*) variable)= (int) getopt_ll_limit_value(value, optp); break; case GET_UINT: - *((uint*) variable)= (uint) value; + *((uint*) variable)= (uint) getopt_ull_limit_value(value, optp, NULL); break; case GET_LONG: - *((long*) variable)= (long) value; + *((long*) variable)= (long) getopt_ll_limit_value(value, optp); break; case GET_ULONG: - *((ulong*) variable)= (ulong) value; + *((ulong*) variable)= (ulong) getopt_ull_limit_value(value, optp, NULL); break; case GET_LL: - *((longlong*) variable)= (longlong) value; + *((longlong*) variable)= (longlong) getopt_ll_limit_value(value, optp); break; case GET_ULL: - *((ulonglong*) variable)= (ulonglong) value; + *((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value(value, optp, + NULL); break; default: /* dummy default to avoid compiler warnings */ break; } + + DBUG_VOID_RETURN; } @@ -839,9 +915,11 @@ static void init_one_value(const struct my_option *option, gptr *variable, static void init_variables(const struct my_option *options) { + DBUG_ENTER("init_variables"); for (; options->name; options++) { gptr *variable; + DBUG_PRINT("options", ("name: '%s'", options->name)); /* We must set u_max_value first as for some variables options->u_max_value == options->value and in this case we want to @@ -855,6 +933,7 @@ static void init_variables(const struct my_option *options) (variable= (*getopt_get_addr)("", 0, options))) init_one_value(options, variable, options->def_value); } + DBUG_VOID_RETURN; } @@ -957,8 +1036,8 @@ void my_print_variables(const struct my_option *options) (*getopt_get_addr)("", 0, optp) : optp->value); if (value) { - printf("%s", optp->name); - length= (uint) strlen(optp->name); + printf("%s ", optp->name); + length= (uint) strlen(optp->name)+1; for (; length < name_space; length++) putchar(' '); switch ((optp->var_type & GET_TYPE_MASK)) { @@ -977,7 +1056,7 @@ void my_print_variables(const struct my_option *options) printf("%d\n", *((uint*) value)); break; case GET_LONG: - printf("%lu\n", *((long*) value)); + printf("%ld\n", *((long*) value)); break; case GET_ULONG: printf("%lu\n", *((ulong*) value)); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 47396748da6..4334dedfe4e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -186,7 +186,7 @@ MY_LOCALE *my_locale_by_number(uint number); #define QUERY_ALLOC_PREALLOC_SIZE 8192 #define TRANS_ALLOC_BLOCK_SIZE 4096 #define TRANS_ALLOC_PREALLOC_SIZE 4096 -#define RANGE_ALLOC_BLOCK_SIZE 2048 +#define RANGE_ALLOC_BLOCK_SIZE 4096 #define ACL_ALLOC_BLOCK_SIZE 1024 #define UDF_ALLOC_BLOCK_SIZE 1024 #define TABLE_ALLOC_BLOCK_SIZE 1024 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4c459d34a55..3900f74da7e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4958,7 +4958,7 @@ Disable with --skip-bdb (will save memory).", {"concurrent-insert", OPT_CONCURRENT_INSERT, "Use concurrent insert with MyISAM. Disable with --concurrent-insert=0", (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert, - 0, GET_LONG, OPT_ARG, 1, 0, 2, 0, 0, 0}, + 0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0}, {"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.", (gptr*) &opt_console, (gptr*) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -5127,7 +5127,7 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, {"innodb_max_purge_lag", OPT_INNODB_MAX_PURGE_LAG, "Desired maximum length of the purge queue (0 = no limit)", (gptr*) &srv_max_purge_lag, - (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L, + (gptr*) &srv_max_purge_lag, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0}, {"innodb_rollback_on_timeout", OPT_INNODB_ROLLBACK_ON_TIMEOUT, "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)", @@ -5237,7 +5237,8 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, #ifdef HAVE_MMAP {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.", (gptr*) &opt_tc_log_size, (gptr*) &opt_tc_log_size, 0, GET_ULONG, - REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ~0L, 0, TC_LOG_PAGE_SIZE, 0}, + REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0, + TC_LOG_PAGE_SIZE, 0}, #endif {"log-update", OPT_UPDATE_LOG, "The update log is deprecated since version 5.0, is replaced by the binary \ @@ -5660,8 +5661,8 @@ log and this option does nothing anymore.", NO_ARG, 0, 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_ULONG, OPT_ARG, 1, 0, ~0L, - 0, 0, 0}, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, + 1, 0, ULONG_MAX, 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.", (gptr*) &back_log, (gptr*) &back_log, 0, GET_ULONG, @@ -5670,29 +5671,29 @@ log and this option does nothing anymore.", { "bdb_cache_size", OPT_BDB_CACHE_SIZE, "The buffer that is allocated to cache index and rows for BDB tables.", (gptr*) &berkeley_cache_size, (gptr*) &berkeley_cache_size, 0, GET_ULONG, - REQUIRED_ARG, KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE, 0}, + REQUIRED_ARG, KEY_CACHE_SIZE, 20*1024, ULONG_MAX, 0, IO_SIZE, 0}, /* QQ: The following should be removed soon! (bdb_max_lock preferred) */ {"bdb_lock_max", OPT_BDB_MAX_LOCK, "Synonym for bdb_max_lock.", (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, - REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0}, + REQUIRED_ARG, 10000, 0, ULONG_MAX, 0, 1, 0}, {"bdb_log_buffer_size", OPT_BDB_LOG_BUFFER_SIZE, "The buffer that is allocated to cache index and rows for BDB tables.", (gptr*) &berkeley_log_buffer_size, (gptr*) &berkeley_log_buffer_size, 0, - GET_ULONG, REQUIRED_ARG, 0, 256*1024L, ~0L, 0, 1024, 0}, + GET_ULONG, REQUIRED_ARG, 0, 256*1024L, ULONG_MAX, 0, 1024, 0}, {"bdb_max_lock", OPT_BDB_MAX_LOCK, "The maximum number of locks you can have active on a BDB table.", (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, - REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0}, + REQUIRED_ARG, 10000, 0, ULONG_MAX, 0, 1, 0}, #endif /* HAVE_BERKELEY_DB */ {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE, "The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.", (gptr*) &binlog_cache_size, (gptr*) &binlog_cache_size, 0, GET_ULONG, - REQUIRED_ARG, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE, 0}, + REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0}, {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE, "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!", (gptr*) &global_system_variables.bulk_insert_buff_size, (gptr*) &max_system_variables.bulk_insert_buff_size, - 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ~0L, 0, 1, 0}, + 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0}, {"connect_timeout", OPT_CONNECT_TIMEOUT, "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.", (gptr*) &connect_timeout, (gptr*) &connect_timeout, @@ -5715,7 +5716,7 @@ log and this option does nothing anymore.", {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT, "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.", (gptr*) &delayed_insert_limit, (gptr*) &delayed_insert_limit, 0, GET_ULONG, - REQUIRED_ARG, DELAYED_LIMIT, 1, ~0L, 0, 1, 0}, + REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0}, {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT, "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.", (gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0, @@ -5723,7 +5724,7 @@ log and this option does nothing anymore.", { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE, "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.", (gptr*) &delayed_queue_size, (gptr*) &delayed_queue_size, 0, GET_ULONG, - REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1, 0}, + REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0}, {"div_precision_increment", OPT_DIV_PRECINCREMENT, "Precision of the result of '/' operator will be increased on that value.", (gptr*) &global_system_variables.div_precincrement, @@ -5760,16 +5761,16 @@ log and this option does nothing anymore.", (gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN, - "The maximum length of the result of function group_concat.", + "The maximum length of the result of function group_concat.", (gptr*) &global_system_variables.group_concat_max_len, (gptr*) &max_system_variables.group_concat_max_len, 0, GET_ULONG, - REQUIRED_ARG, 1024, 4, (long) ~0, 0, 1, 0}, + REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0}, #ifdef HAVE_INNOBASE_DB {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE, "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.", (gptr*) &innobase_additional_mem_pool_size, (gptr*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG, - 1*1024*1024L, 512*1024L, ~0L, 0, 1024, 0}, + 1*1024*1024L, 512*1024L, LONG_MAX, 0, 1024, 0}, {"innodb_autoextend_increment", OPT_INNODB_AUTOEXTEND_INCREMENT, "Data file autoextend increment in megabytes", (gptr*) &srv_auto_extend_increment, @@ -5793,7 +5794,7 @@ log and this option does nothing anymore.", SQL query after it has once got the ticket", (gptr*) &srv_n_free_tickets_to_enter, (gptr*) &srv_n_free_tickets_to_enter, - 0, GET_LONG, REQUIRED_ARG, 500L, 1L, ~0L, 0, 1L, 0}, + 0, GET_ULONG, REQUIRED_ARG, 500L, 1L, ULONG_MAX, 0, 1L, 0}, {"innodb_file_io_threads", OPT_INNODB_FILE_IO_THREADS, "Number of file I/O threads in InnoDB.", (gptr*) &innobase_file_io_threads, (gptr*) &innobase_file_io_threads, 0, GET_LONG, REQUIRED_ARG, 4, 4, 64, 0, @@ -5809,7 +5810,7 @@ log and this option does nothing anymore.", {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE, "The size of the buffer which InnoDB uses to write log to the log files on disk.", (gptr*) &innobase_log_buffer_size, (gptr*) &innobase_log_buffer_size, 0, - GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, ~0L, 0, 1024, 0}, + GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, LONG_MAX, 0, 1024, 0}, {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE, "Size of each log file in a log group.", (gptr*) &innobase_log_file_size, (gptr*) &innobase_log_file_size, 0, @@ -5827,24 +5828,24 @@ log and this option does nothing anymore.", {"innodb_open_files", OPT_INNODB_OPEN_FILES, "How many files at the maximum InnoDB keeps open at the same time.", (gptr*) &innobase_open_files, (gptr*) &innobase_open_files, 0, - GET_LONG, REQUIRED_ARG, 300L, 10L, ~0L, 0, 1L, 0}, + GET_LONG, REQUIRED_ARG, 300L, 10L, LONG_MAX, 0, 1L, 0}, {"innodb_sync_spin_loops", OPT_INNODB_SYNC_SPIN_LOOPS, "Count of spin-loop rounds in InnoDB mutexes", (gptr*) &srv_n_spin_wait_rounds, (gptr*) &srv_n_spin_wait_rounds, - 0, GET_LONG, REQUIRED_ARG, 20L, 0L, ~0L, 0, 1L, 0}, + 0, GET_ULONG, REQUIRED_ARG, 20L, 0L, ULONG_MAX, 0, 1L, 0}, {"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY, "Helps in performance tuning in heavily concurrent environments. " "Sets the maximum number of threads allowed inside InnoDB. Value 0" " will disable the thread throttling.", (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency, - 0, GET_LONG, REQUIRED_ARG, 8, 0, 1000, 0, 1, 0}, + 0, GET_ULONG, REQUIRED_ARG, 8, 0, 1000, 0, 1, 0}, {"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY, "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0" " disable a sleep", (gptr*) &srv_thread_sleep_delay, (gptr*) &srv_thread_sleep_delay, - 0, GET_LONG, REQUIRED_ARG, 10000L, 0L, ~0L, 0, 1L, 0}, + 0, GET_ULONG, REQUIRED_ARG, 10000L, 0L, ULONG_MAX, 0, 1L, 0}, #endif /* HAVE_INNOBASE_DB */ {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT, "The number of seconds the server waits for activity on an interactive connection before closing it.", @@ -5874,7 +5875,7 @@ log and this option does nothing anymore.", (gptr*) &dflt_key_cache_var.param_age_threshold, (gptr*) 0, 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, - 300, 100, ~0L, 0, 100, 0}, + 300, 100, ULONG_MAX, 0, 100, 0}, {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "The default size of key cache blocks", (gptr*) &dflt_key_cache_var.param_block_size, @@ -5910,7 +5911,7 @@ log and this option does nothing anymore.", {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE, "Can be used to restrict the total size used to cache a multi-transaction query.", (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0, - GET_ULONG, REQUIRED_ARG, ~0L, IO_SIZE, ~0L, 0, IO_SIZE, 0}, + GET_ULONG, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0}, {"max_binlog_size", OPT_MAX_BINLOG_SIZE, "Binary log will be rotated automatically when the size exceeds this \ value. Will also apply to relay logs if max_relay_log_size is 0. \ @@ -5920,7 +5921,7 @@ The minimum value for this variable is 4096.", {"max_connect_errors", OPT_MAX_CONNECT_ERRORS, "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.", (gptr*) &max_connect_errors, (gptr*) &max_connect_errors, 0, GET_ULONG, - REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0}, + REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0}, {"max_connections", OPT_MAX_CONNECTIONS, "The number of simultaneous clients allowed.", (gptr*) &max_connections, (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, @@ -5963,7 +5964,7 @@ The minimum value for this variable is 4096.", "Limit assumed max number of seeks when looking up rows based on a key", (gptr*) &global_system_variables.max_seeks_for_key, (gptr*) &max_system_variables.max_seeks_for_key, 0, GET_ULONG, - REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0 }, + REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 }, {"max_sort_length", OPT_MAX_SORT_LENGTH, "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).", (gptr*) &global_system_variables.max_sort_length, @@ -5978,20 +5979,20 @@ The minimum value for this variable is 4096.", "Maximum number of temporary tables a client can keep open at a time.", (gptr*) &global_system_variables.max_tmp_tables, (gptr*) &max_system_variables.max_tmp_tables, 0, GET_ULONG, - REQUIRED_ARG, 32, 1, ~0L, 0, 1, 0}, + REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0}, {"max_user_connections", OPT_MAX_USER_CONNECTIONS, "The maximum number of active connections for a single user (0 = no limit).", (gptr*) &max_user_connections, (gptr*) &max_user_connections, 0, GET_UINT, - REQUIRED_ARG, 0, 1, ~0, 0, 1, 0}, + REQUIRED_ARG, 0, 0, (uint) ~0, 0, 1, 0}, {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT, "After this many write locks, allow some read locks to run in between.", (gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG, - REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0}, {"multi_range_count", OPT_MULTI_RANGE_COUNT, "Number of key ranges to request at once.", (gptr*) &global_system_variables.multi_range_count, (gptr*) &max_system_variables.multi_range_count, 0, - GET_ULONG, REQUIRED_ARG, 256, 1, ~0L, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0}, {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "Block size to be used for MyISAM index pages.", (gptr*) &opt_myisam_block_size, @@ -6019,7 +6020,7 @@ The minimum value for this variable is 4096.", "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.", (gptr*) &global_system_variables.myisam_repair_threads, (gptr*) &max_system_variables.myisam_repair_threads, 0, - GET_ULONG, REQUIRED_ARG, 1, 1, ~0L, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0}, {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE, "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.", (gptr*) &global_system_variables.myisam_sort_buff_size, @@ -6045,7 +6046,7 @@ The minimum value for this variable is 4096.", "If a read on a communication port is interrupted, retry this many times before giving up.", (gptr*) &global_system_variables.net_retry_count, (gptr*) &max_system_variables.net_retry_count,0, - GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0}, {"net_write_timeout", OPT_NET_WRITE_TIMEOUT, "Number of seconds to wait for a block to be written to a connection before aborting the write.", (gptr*) &global_system_variables.net_write_timeout, @@ -6074,7 +6075,7 @@ The minimum value for this variable is 4096.", "Allocation block size for query parsing and execution", (gptr*) &global_system_variables.query_alloc_block_size, (gptr*) &max_system_variables.query_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0}, #ifdef HAVE_QUERY_CACHE {"query_cache_limit", OPT_QUERY_CACHE_LIMIT, "Don't cache results that are bigger than this.", @@ -6107,12 +6108,13 @@ The minimum value for this variable is 4096.", (gptr*) &global_system_variables.query_prealloc_size, (gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG, REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE, - ~0L, 0, 1024, 0}, + ULONG_MAX, 0, 1024, 0}, {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE, "Allocation block size for storing ranges during optimization", (gptr*) &global_system_variables.range_alloc_block_size, (gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 4096, ~0L, 0, 1024, 0}, + REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX, + 0, 1024, 0}, {"read_buffer_size", OPT_RECORD_BUFFER, "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.", (gptr*) &global_system_variables.read_buff_size, @@ -6182,7 +6184,7 @@ The minimum value for this variable is 4096.", "Synchronously flush binary log to disk after every #th event. " "Use 0 (default) to disable synchronous flushing.", (gptr*) &sync_binlog_period, (gptr*) &sync_binlog_period, 0, GET_ULONG, - REQUIRED_ARG, 0, 0, ~0L, 0, 1, 0}, + REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0}, {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.", (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -6206,7 +6208,7 @@ The minimum value for this variable is 4096.", {"thread_stack", OPT_THREAD_STACK, "The stack size for each thread.", (gptr*) &thread_stack, (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, - 1024L*128L, ~0L, 0, 1024, 0}, + 1024L*128L, ULONG_MAX, 0, 1024, 0}, { "time_format", OPT_TIME_FORMAT, "The TIME format (for future).", (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], @@ -6222,12 +6224,12 @@ The minimum value for this variable is 4096.", "Allocation block size for various transaction-related structures", (gptr*) &global_system_variables.trans_alloc_block_size, (gptr*) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0}, {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE, "Persistent buffer for various transaction-related structures", (gptr*) &global_system_variables.trans_prealloc_size, (gptr*) &max_system_variables.trans_prealloc_size, 0, GET_ULONG, - REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0}, + REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0}, {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT, "1 = YES = Don't issue an error message (warning only) if a VIEW without presence of a key of the underlying table is used in queries with a LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which does not contain a key of the underlying table and the query uses a LIMIT clause (usually get from GUI tools).", (gptr*) &global_system_variables.updatable_views_with_limit, diff --git a/sql/set_var.cc b/sql/set_var.cc index 066b879fa6b..84b3f92c1ca 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -113,6 +113,9 @@ static int check_max_delayed_threads(THD *thd, set_var *var); static void fix_thd_mem_root(THD *thd, enum_var_type type); static void fix_trans_mem_root(THD *thd, enum_var_type type); static void fix_server_id(THD *thd, enum_var_type type); +static ulonglong fix_unsigned(THD *thd, ulonglong num, + const struct my_option *option_limits); +static void throw_bounds_warning(THD *thd, const char *name, ulonglong num); static KEY_CACHE *create_key_cache(const char *name, uint length); void fix_sql_mode_var(THD *thd, enum_var_type type); static byte *get_error_count(THD *thd); @@ -1448,6 +1451,27 @@ static void fix_server_id(THD *thd, enum_var_type type) } +static void throw_bounds_warning(THD *thd, const char *name, ulonglong num) +{ + char buf[22]; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), name, + ullstr(num, buf)); +} + +static ulonglong fix_unsigned(THD *thd, ulonglong num, + const struct my_option *option_limits) +{ + bool fixed= FALSE; + ulonglong out= getopt_ull_limit_value(num, option_limits, &fixed); + + if (fixed) + throw_bounds_warning(thd, option_limits->name, num); + return out; +} + + sys_var_long_ptr:: sys_var_long_ptr(const char *name_arg, ulong *value_ptr_arg, sys_after_update_func after_update_arg) @@ -1468,9 +1492,20 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var) ulonglong tmp= var->save_result.ulonglong_value; pthread_mutex_lock(guard); if (option_limits) - *value= (ulong) getopt_ull_limit_value(tmp, option_limits); + *value= (ulong) fix_unsigned(thd, tmp, option_limits); else + { +#if SIZEOF_LONG < SIZEOF_LONG_LONG + /* Avoid overflows on 32 bit systems */ + if (tmp > (ulonglong) ~(ulong) 0) + { + tmp= ((ulonglong) ~(ulong) 0); + throw_bounds_warning(thd, name, var->save_result.ulonglong_value); + } +#endif *value= (ulong) tmp; + } + pthread_mutex_unlock(guard); return 0; } @@ -1489,7 +1524,7 @@ bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var) ulonglong tmp= var->save_result.ulonglong_value; pthread_mutex_lock(&LOCK_global_system_variables); if (option_limits) - *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits); + *value= (ulonglong) fix_unsigned(thd, tmp, option_limits); else *value= (ulonglong) tmp; pthread_mutex_unlock(&LOCK_global_system_variables); @@ -1539,38 +1574,29 @@ bool sys_var_thd_ulong::check(THD *thd, set_var *var) bool sys_var_thd_ulong::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; - char buf[22]; - bool truncated= false; /* Don't use bigger value than given with --maximum-variable-name=.. */ if ((ulong) tmp > max_system_variables.*offset) { - truncated= true; - llstr(tmp, buf); + throw_bounds_warning(thd, name, tmp); tmp= max_system_variables.*offset; } -#if SIZEOF_LONG == 4 - /* Avoid overflows on 32 bit systems */ - if (tmp > (ulonglong) ~(ulong) 0) + if (option_limits) + tmp= (ulong) fix_unsigned(thd, tmp, option_limits); +#if SIZEOF_LONG < SIZEOF_LONG_LONG + else if (tmp > (ulonglong) ~(ulong) 0) { - truncated= true; - llstr(tmp, buf); tmp= ((ulonglong) ~(ulong) 0); + throw_bounds_warning(thd, name, var->save_result.ulonglong_value); } #endif - if (truncated) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TRUNCATED_WRONG_VALUE, - ER(ER_TRUNCATED_WRONG_VALUE), name, - buf); - if (option_limits) - tmp= (ulong) getopt_ull_limit_value(tmp, option_limits); if (var->type == OPT_GLOBAL) global_system_variables.*offset= (ulong) tmp; else thd->variables.*offset= (ulong) tmp; + return 0; } @@ -1605,7 +1631,7 @@ bool sys_var_thd_ha_rows::update(THD *thd, set_var *var) tmp= max_system_variables.*offset; if (option_limits) - tmp= (ha_rows) getopt_ull_limit_value(tmp, option_limits); + tmp= (ha_rows) fix_unsigned(thd, tmp, option_limits); if (var->type == OPT_GLOBAL) { /* Lock is needed to make things safe on 32 bit systems */ @@ -1649,7 +1675,7 @@ bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) tmp= max_system_variables.*offset; if (option_limits) - tmp= getopt_ull_limit_value(tmp, option_limits); + tmp= fix_unsigned(thd, tmp, option_limits); if (var->type == OPT_GLOBAL) { /* Lock is needed to make things safe on 32 bit systems */ @@ -2493,7 +2519,7 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var) } key_cache->param_buff_size= - (ulonglong) getopt_ull_limit_value(tmp, option_limits); + (ulonglong) fix_unsigned(thd, tmp, option_limits); /* If key cache didn't existed initialize it, else resize it */ key_cache->in_init= 1; @@ -2541,7 +2567,7 @@ bool sys_var_key_cache_long::update(THD *thd, set_var *var) goto end; *((ulong*) (((char*) key_cache) + offset))= - (ulong) getopt_ull_limit_value(tmp, option_limits); + (ulong) fix_unsigned(thd, tmp, option_limits); /* Don't create a new key cache if it didn't exist diff --git a/strings/llstr.c b/strings/llstr.c index 12aea63e014..643cf36a311 100644 --- a/strings/llstr.c +++ b/strings/llstr.c @@ -32,3 +32,9 @@ char *llstr(longlong value,char *buff) longlong10_to_str(value,buff,-10); return buff; } + +char *ullstr(longlong value,char *buff) +{ + longlong10_to_str(value,buff,10); + return buff; +} From cef31e05e58b43ec4f7c02569432df70c60969f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Nov 2007 17:08:00 +0400 Subject: [PATCH 35/46] Bug #32374 crash with filesort when selecting from federated table and view. filesort() uses file->estimate_rows_upper_bound() call to allocate internal buffers. If this function returns a value smaller than a number of row that will be returned later in find_all_keys(), that can cause server crash. Fixed by implementing ha_federated::estimate_rows_upper_bound() to return maximum possible number of rows. Present estimation for FEDERATED always returns 0 if the linked to the VIEW. mysql-test/r/federated.result: Bug #32374 crash with filesort when selecting from federated table and view. test result mysql-test/t/federated.test: Bug #32374 crash with filesort when selecting from federated table and view. test case sql/ha_federated.cc: Bug #32374 crash with filesort when selecting from federated table and view. ha_federated::estimate_rows_upper_bound() implemented sql/ha_federated.h: Bug #32374 crash with filesort when selecting from federated table and view. ha_federated::estimate_rows_upper_bound() interface --- mysql-test/r/federated.result | 111 ++++++++++++++++++++++++++++++++++ mysql-test/t/federated.test | 31 ++++++++++ sql/ha_federated.cc | 18 ++++++ sql/ha_federated.h | 1 + 4 files changed, 161 insertions(+) diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index 2e7d0ddcea7..a005db4deac 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -1934,6 +1934,117 @@ select * from federated.t2; a 1 drop table federated.t1, federated.t2; +create table t1 (a varchar(256)); +drop view if exists v1; +create view v1 as select a from t1; +create table t1 +(a varchar(256)) engine=federated +connection='mysql://root@127.0.0.1:SLAVE_PORT/test/v1'; +select 1 from t1 order by a; +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +drop table t1; +drop table t1; +drop view v1; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; DROP TABLE IF EXISTS federated.t1; diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index cc66a6ab4bc..d4f22650a32 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1686,4 +1686,35 @@ insert into federated.t1 (a) values (1); select * from federated.t2; drop table federated.t1, federated.t2; +# +# Bug #32374 crash with filesort when selecting from federated table and view +# +connection slave; +create table t1 (a varchar(256)); +--disable_warnings +drop view if exists v1; +--enable_warnings +create view v1 as select a from t1; +--disable_query_log +let $n= 100; +while ($n) +{ + insert into t1 values (repeat('a',200)); + dec $n; +} +--enable_query_log + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval create table t1 + (a varchar(256)) engine=federated + connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/v1'; + +select 1 from t1 order by a; +drop table t1; +connection slave; +drop table t1; +drop view v1; + + source include/federated_cleanup.inc; diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index d7f2309657b..ac1e0962ffb 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -2166,6 +2166,24 @@ error: } +/* + This method is used exlusevely by filesort() to check if we + can create sorting buffers of necessary size. + If the handler returns more records that it declares + here server can just crash on filesort(). + We cannot guarantee that's not going to happen with + the FEDERATED engine, as we have records==0 always if the + client is a VIEW, and for the table the number of + records can inpredictably change during execution. + So we return maximum possible value here. +*/ + +ha_rows ha_federated::estimate_rows_upper_bound() +{ + return HA_POS_ERROR; +} + + /* Initialized at each key walk (called multiple times unlike rnd_init()) */ int ha_federated::index_init(uint keynr) diff --git a/sql/ha_federated.h b/sql/ha_federated.h index dc4f976c578..349c596ae5a 100644 --- a/sql/ha_federated.h +++ b/sql/ha_federated.h @@ -277,6 +277,7 @@ public: int update_row(const byte *old_data, byte *new_data); int delete_row(const byte *buf); int index_init(uint keynr); + ha_rows estimate_rows_upper_bound(); int index_read(byte *buf, const byte *key, uint key_len, enum ha_rkey_function find_flag); int index_read_idx(byte *buf, uint idx, const byte *key, From 53f7db282dc982e48c0a944e9c3f68ebc3d26db3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 3 Dec 2007 10:01:56 +0100 Subject: [PATCH 36/46] Bug#31177: Server variables can't be set to their current values additional fixes for 64-bit mysql-test/t/variables.test: replace 32-bit and 64-bit values mysys/my_getopt.c: 'mod' no longer used. on 64-bit, limit to (signed) (LONG)LONG_MAX to prevent badness in classes using longlong. --- mysql-test/t/variables.test | 2 +- mysys/my_getopt.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index be7e7c2b413..a30ba758c27 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -126,7 +126,7 @@ set GLOBAL query_cache_size=100000; set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; set GLOBAL myisam_max_sort_file_size=default; ---replace_result 2147482624 FILE_SIZE 2146435072 FILE_SIZE +--replace_result 9223372036853727232 FILE_SIZE 2146435072 FILE_SIZE show variables like 'myisam_max_sort_file_size'; set global net_retry_count=10, session net_retry_count=10; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index f41e8166876..9174d91dce7 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -799,7 +799,7 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, bool *fix) { bool adjusted= FALSE; - ulonglong old= num, mod; + ulonglong old= num; char buf1[255], buf2[255]; if ((ulonglong) num > (ulonglong) optp->max_value && @@ -824,6 +824,8 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, num= ((ulonglong) ULONG_MAX); adjusted= TRUE; } +#else + num= min(num, LONG_MAX); #endif break; default: From b4a146a6ebe0ad14d40f241c0a37c9a43c7fd7f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 3 Dec 2007 10:08:58 +0100 Subject: [PATCH 37/46] Bug#30234: Unexpected behavior using DELETE with AS and USING Anti-patch. This patch undoes the previously pushed patch. It is null-merged in versions 5.1 and above since there the original patch is still desired. mysql-test/r/delete.result: Bug#30234: Anti-patch mysql-test/t/delete.test: Bug#30234: Anti-patch sql/sql_yacc.yy: Bug#30234: Anti-patch --- mysql-test/r/delete.result | 37 -------------------------------- mysql-test/t/delete.test | 44 -------------------------------------- sql/sql_yacc.yy | 19 ++-------------- 3 files changed, 2 insertions(+), 98 deletions(-) diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 5084498c01c..27eee6ef578 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -234,40 +234,3 @@ ERROR 42S22: Unknown column 't2.x' in 'order clause' DELETE FROM t1 ORDER BY (SELECT x); ERROR 42S22: Unknown column 'x' in 'field list' DROP TABLE t1; -CREATE TABLE t1 ( -a INT -); -CREATE TABLE t2 ( -a INT -); -CREATE DATABASE db1; -CREATE TABLE db1.t1 ( -a INT -); -INSERT INTO db1.t1 (a) SELECT * FROM t1; -CREATE DATABASE db2; -CREATE TABLE db2.t1 ( -a INT -); -INSERT INTO db2.t1 (a) SELECT * FROM t2; -DELETE FROM t1 alias USING t1, t2 alias WHERE t1.a = alias.a; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'alias USING t1, t2 alias WHERE t1.a = alias.a' at line 1 -DELETE FROM alias USING t1, t2 alias WHERE t1.a = alias.a; -DELETE FROM t1, alias USING t1, t2 alias WHERE t1.a = alias.a; -DELETE FROM t1, t2 USING t1, t2 alias WHERE t1.a = alias.a; -ERROR 42S02: Unknown table 't2' in MULTI DELETE -DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a' at line 1 -DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a; -ERROR 42S02: Unknown table 'alias' in MULTI DELETE -DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a; -DELETE FROM t1 USING t1 WHERE a = 1; -SELECT * FROM t1; -a -DELETE FROM t1 alias USING t1 alias WHERE a = 2; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'alias USING t1 alias WHERE a = 2' at line 1 -SELECT * FROM t1; -a -DROP TABLE t1, t2; -DROP DATABASE db1; -DROP DATABASE db2; diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 8a03cb6c715..495b0c0b001 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -233,47 +233,3 @@ DELETE FROM t1 ORDER BY t2.x; DELETE FROM t1 ORDER BY (SELECT x); DROP TABLE t1; - -# -# Bug #30234: Unexpected behavior using DELETE with AS and USING -# ' -CREATE TABLE t1 ( - a INT -); - -CREATE TABLE t2 ( - a INT -); - -CREATE DATABASE db1; -CREATE TABLE db1.t1 ( - a INT -); -INSERT INTO db1.t1 (a) SELECT * FROM t1; - -CREATE DATABASE db2; -CREATE TABLE db2.t1 ( - a INT -); -INSERT INTO db2.t1 (a) SELECT * FROM t2; - ---error ER_PARSE_ERROR -DELETE FROM t1 alias USING t1, t2 alias WHERE t1.a = alias.a; -DELETE FROM alias USING t1, t2 alias WHERE t1.a = alias.a; -DELETE FROM t1, alias USING t1, t2 alias WHERE t1.a = alias.a; ---error ER_UNKNOWN_TABLE -DELETE FROM t1, t2 USING t1, t2 alias WHERE t1.a = alias.a; ---error ER_PARSE_ERROR -DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a; ---error ER_UNKNOWN_TABLE -DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a; -DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a; -DELETE FROM t1 USING t1 WHERE a = 1; -SELECT * FROM t1; ---error ER_PARSE_ERROR -DELETE FROM t1 alias USING t1 alias WHERE a = 2; -SELECT * FROM t1; - -DROP TABLE t1, t2; -DROP DATABASE db1; -DROP DATABASE db2; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 82100b3d3dd..c4bc4616841 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1162,8 +1162,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); field_opt_list opt_binary table_lock_list table_lock ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use opt_delete_options opt_delete_option varchar nchar nvarchar - opt_outer table_list table_name table_alias_ref_list table_alias_ref - opt_option opt_place + opt_outer table_list table_name opt_option opt_place opt_attribute opt_attribute_list attribute column_list column_list_id opt_column_list grant_privileges grant_ident grant_list grant_option object_privilege object_privilege_list user_list rename_list @@ -6554,20 +6553,6 @@ table_name: } ; -table_alias_ref_list: - table_alias_ref - | table_alias_ref_list ',' table_alias_ref; - -table_alias_ref: - table_ident - { - if (!Select->add_table_to_list(YYTHD, $1, NULL, - TL_OPTION_UPDATING | TL_OPTION_ALIAS, - Lex->lock_option )) - MYSQL_YYABORT; - } - ; - if_exists: /* empty */ { $$= 0; } | IF EXISTS { $$= 1; } @@ -6838,7 +6823,7 @@ single_multi: if (multi_delete_set_locks_and_link_aux_tables(Lex)) MYSQL_YYABORT; } - | FROM table_alias_ref_list + | FROM table_wild_list { mysql_init_multi_delete(Lex); } USING join_table_list where_clause { From 4618d68d6d85141cd2422c892ed5053c72aa097a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Dec 2007 01:28:01 +0100 Subject: [PATCH 38/46] Bug#31177: Server variables can't be set to their current values additional fixes for BDB and correct assignment of both signed and unsigned 64-bit data to unsigned system variables mysql-test/r/ps_2myisam.result: account for UNSIGNED_FLAG mysql-test/r/ps_3innodb.result: account for UNSIGNED_FLAG mysql-test/r/ps_4heap.result: account for UNSIGNED_FLAG mysql-test/r/ps_5merge.result: account for UNSIGNED_FLAG mysql-test/r/ps_6bdb.result: account for UNSIGNED_FLAG mysql-test/r/ps_7ndb.result: account for UNSIGNED_FLAG mysys/my_getopt.c: We have correct signed/unsigned information now, so we no longer need to err on the side of caution. sql/item_func.cc: Copy unsigned info over from entry so the item's data correctly describe it. sql/mysqld.cc: BDB log buffer size: default can't be less than minimum sql/set_var.cc: Handle signedness of in-values correctly when assigning to unsigned types, all the way up to 64-bit. Use handler from all three unsigned sysvar types. sql/set_var.h: thd_ulonglong: Override default check with one for unsigned types --- mysql-test/r/ps_2myisam.result | 16 ++++++++-------- mysql-test/r/ps_3innodb.result | 16 ++++++++-------- mysql-test/r/ps_4heap.result | 16 ++++++++-------- mysql-test/r/ps_5merge.result | 32 ++++++++++++++++---------------- mysql-test/r/ps_6bdb.result | 16 ++++++++-------- mysql-test/r/ps_7ndb.result | 16 ++++++++-------- mysys/my_getopt.c | 2 -- sql/item_func.cc | 2 ++ sql/mysqld.cc | 2 +- sql/set_var.cc | 32 ++++++++++++++++++++++++-------- sql/set_var.h | 1 + 11 files changed, 84 insertions(+), 67 deletions(-) diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 57932a6c455..ac3ce99716c 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1933,7 +1933,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -1980,7 +1980,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2030,7 +2030,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2070,7 +2070,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2118,7 +2118,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2162,7 +2162,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2208,7 +2208,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2246,7 +2246,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index fd24c29d558..745b0ac53c9 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1916,7 +1916,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -1963,7 +1963,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2013,7 +2013,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2053,7 +2053,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2101,7 +2101,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2145,7 +2145,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2191,7 +2191,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2229,7 +2229,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index b4596ab85bc..7b6b89100bc 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1917,7 +1917,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -1964,7 +1964,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2014,7 +2014,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2054,7 +2054,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2102,7 +2102,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2146,7 +2146,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2192,7 +2192,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2230,7 +2230,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 18982db937a..74042d395c9 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1853,7 +1853,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -1900,7 +1900,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -1950,7 +1950,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -1990,7 +1990,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2038,7 +2038,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2082,7 +2082,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2128,7 +2128,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2166,7 +2166,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -4875,7 +4875,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -4922,7 +4922,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -4972,7 +4972,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -5012,7 +5012,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -5060,7 +5060,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -5104,7 +5104,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -5150,7 +5150,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -5188,7 +5188,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 0e4086bc202..da12409257c 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -1916,7 +1916,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -1963,7 +1963,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2013,7 +2013,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2053,7 +2053,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2101,7 +2101,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2145,7 +2145,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2191,7 +2191,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2229,7 +2229,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 7a20fb3146d..4cb315c408e 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -1916,7 +1916,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -1963,7 +1963,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2013,7 +2013,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2053,7 +2053,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2101,7 +2101,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2145,7 +2145,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 @@ -2191,7 +2191,7 @@ def @arg13 253 8192 10 Y 128 31 63 def @arg14 253 8192 19 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 +def @arg17 253 20 4 Y 160 0 63 def @arg18 253 20 1 Y 128 0 63 def @arg19 253 20 1 Y 128 0 63 def @arg20 253 8192 1 Y 0 31 8 @@ -2229,7 +2229,7 @@ def @arg13 253 8192 0 Y 128 31 63 def @arg14 253 8192 0 Y 128 31 63 def @arg15 253 8192 19 Y 128 31 63 def @arg16 253 8192 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 +def @arg17 253 20 0 Y 160 0 63 def @arg18 253 20 0 Y 128 0 63 def @arg19 253 20 0 Y 128 0 63 def @arg20 253 8192 0 Y 0 31 8 diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 9174d91dce7..3bb500616a1 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -824,8 +824,6 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp, num= ((ulonglong) ULONG_MAX); adjusted= TRUE; } -#else - num= min(num, LONG_MAX); #endif break; default: diff --git a/sql/item_func.cc b/sql/item_func.cc index 2ee9973c785..019df9176c9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4597,6 +4597,8 @@ void Item_func_get_user_var::fix_length_and_dec() if (var_entry) { + unsigned_flag= var_entry->unsigned_flag; + collation.set(var_entry->collation); switch (var_entry->type) { case REAL_RESULT: diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3900f74da7e..23a05485796 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5679,7 +5679,7 @@ log and this option does nothing anymore.", {"bdb_log_buffer_size", OPT_BDB_LOG_BUFFER_SIZE, "The buffer that is allocated to cache index and rows for BDB tables.", (gptr*) &berkeley_log_buffer_size, (gptr*) &berkeley_log_buffer_size, 0, - GET_ULONG, REQUIRED_ARG, 0, 256*1024L, ULONG_MAX, 0, 1024, 0}, + GET_ULONG, REQUIRED_ARG, 256*1024L, 256*1024L, ULONG_MAX, 0, 1024, 0}, {"bdb_max_lock", OPT_BDB_MAX_LOCK, "The maximum number of locks you can have active on a BDB table.", (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, diff --git a/sql/set_var.cc b/sql/set_var.cc index 84b3f92c1ca..58b9b93b17f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -115,6 +115,7 @@ static void fix_trans_mem_root(THD *thd, enum_var_type type); static void fix_server_id(THD *thd, enum_var_type type); static ulonglong fix_unsigned(THD *thd, ulonglong num, const struct my_option *option_limits); +static bool get_unsigned(THD *thd, set_var *var); static void throw_bounds_warning(THD *thd, const char *name, ulonglong num); static KEY_CACHE *create_key_cache(const char *name, uint length); void fix_sql_mode_var(THD *thd, enum_var_type type); @@ -1471,6 +1472,18 @@ static ulonglong fix_unsigned(THD *thd, ulonglong num, return out; } +static bool get_unsigned(THD *thd, set_var *var) +{ + if (var->value->unsigned_flag) + var->save_result.ulonglong_value= (ulonglong) var->value->val_int(); + else + { + longlong v= var->value->val_int(); + var->save_result.ulonglong_value= (ulonglong) ((v < 0) ? 0 : v); + } + return 0; +} + sys_var_long_ptr:: sys_var_long_ptr(const char *name_arg, ulong *value_ptr_arg, @@ -1482,9 +1495,7 @@ sys_var_long_ptr(const char *name_arg, ulong *value_ptr_arg, bool sys_var_long_ptr_global::check(THD *thd, set_var *var) { - longlong v= var->value->val_int(); - var->save_result.ulonglong_value= v < 0 ? 0 : v; - return 0; + return get_unsigned(thd, var); } bool sys_var_long_ptr_global::update(THD *thd, set_var *var) @@ -1497,9 +1508,9 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var) { #if SIZEOF_LONG < SIZEOF_LONG_LONG /* Avoid overflows on 32 bit systems */ - if (tmp > (ulonglong) ~(ulong) 0) + if (tmp > ULONG_MAX) { - tmp= ((ulonglong) ~(ulong) 0); + tmp= ULONG_MAX; throw_bounds_warning(thd, name, var->save_result.ulonglong_value); } #endif @@ -1567,7 +1578,7 @@ byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) bool sys_var_thd_ulong::check(THD *thd, set_var *var) { - return (sys_var_thd::check(thd, var) || + return (get_unsigned(thd, var) || (check_func && (*check_func)(thd, var))); } @@ -1585,9 +1596,9 @@ bool sys_var_thd_ulong::update(THD *thd, set_var *var) if (option_limits) tmp= (ulong) fix_unsigned(thd, tmp, option_limits); #if SIZEOF_LONG < SIZEOF_LONG_LONG - else if (tmp > (ulonglong) ~(ulong) 0) + else if (tmp > ULONG_MAX) { - tmp= ((ulonglong) ~(ulong) 0); + tmp= ULONG_MAX; throw_bounds_warning(thd, name, var->save_result.ulonglong_value); } #endif @@ -1667,6 +1678,11 @@ byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type, return (byte*) &(thd->variables.*offset); } +bool sys_var_thd_ulonglong::check(THD *thd, set_var *var) +{ + return get_unsigned(thd, var); +} + bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; diff --git a/sql/set_var.h b/sql/set_var.h index 7b3f864f44c..93402e21258 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -365,6 +365,7 @@ public: void set_default(THD *thd, enum_var_type type); SHOW_TYPE show_type() { return SHOW_LONGLONG; } byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); + bool check(THD *thd, set_var *var); bool check_default(enum_var_type type) { return type == OPT_GLOBAL && !option_limits; From d776054e00b917e1d6fbf0195b924a052466320a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Dec 2007 17:14:59 -0800 Subject: [PATCH 39/46] Fixed bug #32815. The index (key_part_1, key_part-2) was erroneously considered as compatible with the required ordering in the function test_test_if_order_by_key when a query with an ORDER BY clause contained a condition of the form key_part_1=const OR key_part_1 IS NULL and the order list contained only key_part_2. This happened because the value of the const_key_parts field in the KEYUSE structure was not formed correctly for the keys that could be used for ref_or_null access. This was fixed in the code of the update_ref_and_keys function. The problem could not manifest itself for MyISAM databases because the implementation of the keys_to_use_for_scanning() handler function always returns an empty bitmap for the MyISAM engine. mysql-test/r/innodb_mysql.result: Added a test case for bug #32815. mysql-test/t/innodb_mysql.test: Added a test case for bug #32815. sql/sql_select.cc: Fixed bug #32815. The index (key_part_1, key_part-2) was erroneously considered as compatible with the required ordering in the function test_test_if_order_by_key when a query with an ORDER BY clause contained a condition of the form key_part_1=const OR key_part_1 IS NULL and the order list contained only key_part_2. This happened because the value of the const_key_parts field in the KEYUSE structure was not formed correctly for the keys that could be used for ref_or_null access. This was fixed in the code of the update_ref_and_keys function. --- mysql-test/r/innodb_mysql.result | 12 ++++++++++++ mysql-test/t/innodb_mysql.test | 15 +++++++++++++++ sql/sql_select.cc | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index b073e4bd6ce..7450d8c349b 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1213,4 +1213,16 @@ a b 3 2 1 1 DROP TABLE t1; +CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); +EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL idx NULL NULL NULL 3 Using where; Using filesort +SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; +id type d +191 member 1 +NULL member 3 +NULL member 4 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index f64efd600c5..f1b15d05a60 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -960,4 +960,19 @@ SELECT * FROM t1 ORDER BY b DESC, a ASC; DROP TABLE t1; +# +# Bug #32815: query with ORDER BY and a possible ref_or_null access +# + +CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB; +INSERT INTO t1 VALUES + (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); + +EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; +SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; + +DROP TABLE t1; + + + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bcf538cdde2..d1bd018878a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3691,7 +3691,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, found_eq_constant=0; for (i=0 ; i < keyuse->elements-1 ; i++,use++) { - if (!use->used_tables) + if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL) use->table->const_key_parts[use->key]|= use->keypart_map; if (use->keypart != FT_KEYPART) { From b1b2e0d053029ef2111b37f6aa624af364186bde Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Dec 2007 23:36:58 -0800 Subject: [PATCH 40/46] Fixed bug #27545. Both arguments of the function NAME_CONST must be constant expressions. This constraint is checked in the Item_name_const::fix_fields method. Yet if the argument of the function was not a constant expression no error message was reported. As a result the client hanged waiting for a response. Now the function Item_name_const::fix_fields reports an error message when any of the additional context conditions imposed on the function NAME_CONST is not satisfied. mysql-test/r/func_misc.result: Added a test case for bug #26545. mysql-test/t/func_misc.test: Added a test case for bug #26545. --- mysql-test/r/func_misc.result | 5 +++++ mysql-test/t/func_misc.test | 13 +++++++++++++ sql/item.cc | 14 +++++++------- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index c941790c35b..d04c22c0c9d 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -207,4 +207,9 @@ test SELECT NAME_CONST('test', 'test'); test test +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (5), (2); +SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t; +ERROR HY000: The 'NAME_CONST' syntax is reserved for purposes internal to the MySQL server +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 2c34f77b1ff..e8ee76b3a96 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -204,5 +204,18 @@ SELECT NAME_CONST('test', 1.0); SELECT NAME_CONST('test', -1.0); SELECT NAME_CONST('test', 'test'); +# +# Bug #27545: erroneous usage of NAME_CONST with a name as the first parameter +# resolved against a column name of a derived table hangs the client +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (5), (2); + +--error ER_RESERVED_SYNTAX +SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 3555df40060..4eeb2b2aa84 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1221,14 +1221,14 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) s.length(0); if (value_item->fix_fields(thd, &value_item) || - name_item->fix_fields(thd, &name_item)) + name_item->fix_fields(thd, &name_item) || + !value_item->const_item() || + !name_item->const_item() || + !(item_name= name_item->val_str(&s))) // Can't have a NULL name + { + my_error(ER_RESERVED_SYNTAX, MYF(0), "NAME_CONST"); return TRUE; - if (!(value_item->const_item() && name_item->const_item())) - return TRUE; - - if (!(item_name= name_item->val_str(&s))) - return TRUE; /* Can't have a NULL name */ - + } set_name(item_name->ptr(), (uint) item_name->length(), system_charset_info); max_length= value_item->max_length; decimals= value_item->decimals; From b3d8ff4ebd16c418dbce2731a5553c3ae6a47a7f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 8 Dec 2007 23:05:00 +0200 Subject: [PATCH 41/46] Fix for BUG#32694 "NOT NULL table field in a subquery produces invalid results" The problem was that when convert_constant_item is called for subqueries, this happens when we already started executing the top-level query, and the field argument of convert_constant_item pointed to a valid table row. In turn convert_constant_item used the field buffer to compute the value of its item argument. This copied the item's value into the field, and made equalities with outer references always true. The fix saves/restores the original field's value when it belongs to an outer table. mysql-test/r/type_datetime.result: Test for BUG#32694. mysql-test/t/type_datetime.test: Test for BUG#32694. sql/item_cmpfunc.cc: - Changed convert_constant_item() so that it doesn't destroy the contents of its field argument when the field originates from table in an outer query. --- mysql-test/r/type_datetime.result | 55 +++++++++++++++++++++++++ mysql-test/t/type_datetime.test | 37 +++++++++++++++++ sql/item_cmpfunc.cc | 67 +++++++++++++++++++------------ 3 files changed, 133 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 73edfb75ff6..3814e2f8348 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -505,4 +505,59 @@ select sum(a) from t1 group by convert(a, datetime); sum(a) NULL drop table t1; +create table t1 (id int(10) not null, cur_date datetime not null); +create table t2 (id int(10) not null, cur_date date not null); +insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22'); +insert into t2 (id, cur_date) values (1, '2007-04-25'); +explain extended +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 +Note 1003 select '1' AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` where ('1',(select 1 AS `Not_used` from `test`.`t1` `x1` where 0)) +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +id cur_date +explain extended +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 +Note 1003 select '1' AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` where ('1',(select 1 AS `Not_used` from `test`.`t2` `x1` where 0)) +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +id cur_date +insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22'); +insert into t2 (id, cur_date) values (2, '2007-04-26'); +explain extended +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` where (`test`.`t1`.`id`,(select 1 AS `Not_used` from `test`.`t1` `x1` where ((`test`.`t1`.`cur_date` = 0) and ((`test`.`t1`.`id`) = `test`.`x1`.`id`)))) +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +id cur_date +explain extended +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` where (`test`.`t2`.`id`,(select 1 AS `Not_used` from `test`.`t2` `x1` where ((`test`.`t2`.`cur_date` = 0) and ((`test`.`t2`.`id`) = `test`.`x1`.`id`)))) +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +id cur_date +drop table t1,t2; End of 5.0 tests diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 08a94384aec..1f7c11ae8e6 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -338,4 +338,41 @@ insert into t1 values (), (), (); select sum(a) from t1 group by convert(a, datetime); drop table t1; +# +# Bug #32694: NOT NULL table field in a subquery produces invalid results +# +create table t1 (id int(10) not null, cur_date datetime not null); +create table t2 (id int(10) not null, cur_date date not null); +insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22'); +insert into t2 (id, cur_date) values (1, '2007-04-25'); + +explain extended +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); + +explain extended +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); + +insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22'); +insert into t2 (id, cur_date) values (2, '2007-04-26'); + +explain extended +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); + +explain extended +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); + +drop table t1,t2; + --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f9744baf19e..1881d2f7f1f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -24,7 +24,8 @@ #include #include "sql_select.h" -static bool convert_constant_item(THD *thd, Field *field, Item **item); +static bool convert_constant_item(THD *thd, Item_field *field_item, + Item **item); static Item_result item_store_type(Item_result a, Item *item, my_bool unsigned_flag) @@ -317,7 +318,7 @@ longlong Item_func_nop_all::val_int() SYNOPSIS convert_constant_item() thd thread handle - field item will be converted using the type of this field + field_item item will be converted using the type of this field item [in/out] reference to the item to convert DESCRIPTION @@ -340,30 +341,46 @@ longlong Item_func_nop_all::val_int() 1 Item was replaced with an integer version of the item */ -static bool convert_constant_item(THD *thd, Field *field, Item **item) +static bool convert_constant_item(THD *thd, Item_field *field_item, + Item **item) { + Field *field= field_item->field; + int result= 0; + if (!(*item)->with_subselect && (*item)->const_item()) { /* For comparison purposes allow invalid dates like 2000-01-32 */ ulong orig_sql_mode= thd->variables.sql_mode; enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields; + ulonglong orig_field_val; /* original field value if valid */ thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | MODE_INVALID_DATES; thd->count_cuted_fields= CHECK_FIELD_IGNORE; + /* + Store the value of the field if it references an outer field because + the call to save_in_field below overrides that value. + */ + if (field_item->depended_from) + orig_field_val= field->val_int(); if (!(*item)->is_null() && !(*item)->save_in_field(field, 1)) { Item *tmp=new Item_int_with_ref(field->val_int(), *item, test(field->flags & UNSIGNED_FLAG)); - thd->variables.sql_mode= orig_sql_mode; - thd->count_cuted_fields= orig_count_cuted_fields; if (tmp) thd->change_item_tree(item, tmp); - return 1; // Item was replaced + result= 1; // Item was replaced + } + /* Restore the original field value. */ + if (field_item->depended_from) + { + result= field->store(orig_field_val, TRUE); + /* orig_field_val must be a valid value that can be restored back. */ + DBUG_ASSERT(!result); } thd->variables.sql_mode= orig_sql_mode; thd->count_cuted_fields= orig_count_cuted_fields; } - return 0; + return result; } @@ -411,15 +428,14 @@ void Item_bool_func2::fix_length_and_dec() thd= current_thd; if (!thd->is_context_analysis_only()) { - Item *arg_real_item= args[0]->real_item(); - if (arg_real_item->type() == FIELD_ITEM) + if (args[0]->real_item()->type() == FIELD_ITEM) { - Field *field=((Item_field*) arg_real_item)->field; - if (field->can_be_compared_as_longlong() && - !(arg_real_item->is_datetime() && + Item_field *field_item= (Item_field*) (args[0]->real_item()); + if (field_item->field->can_be_compared_as_longlong() && + !(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT)) { - if (convert_constant_item(thd, field,&args[1])) + if (convert_constant_item(thd, field_item, &args[1])) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. @@ -428,15 +444,14 @@ void Item_bool_func2::fix_length_and_dec() } } } - arg_real_item= args[1]->real_item(); - if (arg_real_item->type() == FIELD_ITEM) + if (args[1]->real_item()->type() == FIELD_ITEM) { - Field *field=((Item_field*) arg_real_item)->field; - if (field->can_be_compared_as_longlong() && - !(arg_real_item->is_datetime() && + Item_field *field_item= (Item_field*) (args[1]->real_item()); + if (field_item->field->can_be_compared_as_longlong() && + !(field_item->is_datetime() && args[0]->result_type() == STRING_RESULT)) { - if (convert_constant_item(thd, field,&args[0])) + if (convert_constant_item(thd, field_item, &args[0])) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. @@ -1889,16 +1904,16 @@ void Item_func_between::fix_length_and_dec() thd->lex->sql_command != SQLCOM_CREATE_VIEW && thd->lex->sql_command != SQLCOM_SHOW_CREATE) { - Field *field=((Item_field*) (args[0]->real_item()))->field; - if (field->can_be_compared_as_longlong()) + Item_field *field_item= (Item_field*) (args[0]->real_item()); + if (field_item->field->can_be_compared_as_longlong()) { /* The following can't be recoded with || as convert_constant_item changes the argument */ - if (convert_constant_item(thd, field,&args[1])) + if (convert_constant_item(thd, field_item, &args[1])) cmp_type=INT_RESULT; // Works for all types. - if (convert_constant_item(thd, field,&args[2])) + if (convert_constant_item(thd, field_item, &args[2])) cmp_type=INT_RESULT; // Works for all types. } } @@ -3491,13 +3506,13 @@ void Item_func_in::fix_length_and_dec() thd->lex->sql_command != SQLCOM_SHOW_CREATE && cmp_type != INT_RESULT) { - Field *field= ((Item_field*) (args[0]->real_item()))->field; - if (field->can_be_compared_as_longlong()) + Item_field *field_item= (Item_field*) (args[0]->real_item()); + if (field_item->field->can_be_compared_as_longlong()) { bool all_converted= TRUE; for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) { - if (!convert_constant_item (thd, field, &arg[0])) + if (!convert_constant_item (thd, field_item, &arg[0])) all_converted= FALSE; } if (all_converted) From 1cdd95f7d1a27723c1ae1d3a6f457a0042b44795 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 9 Dec 2007 11:53:07 -0800 Subject: [PATCH 42/46] Forced compilers to remove the warning appeared after the patch with a fix for bug 32694. --- sql/item_cmpfunc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1881d2f7f1f..4b584f5cb0b 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -353,6 +353,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item, ulong orig_sql_mode= thd->variables.sql_mode; enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields; ulonglong orig_field_val; /* original field value if valid */ + LINT_INIT(orig_field_val); thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | MODE_INVALID_DATES; thd->count_cuted_fields= CHECK_FIELD_IGNORE; From c6675cd1876a90468ca2e2cb10471af93728aa6c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Dec 2007 13:38:22 +0300 Subject: [PATCH 43/46] BUG#32198: Comparison of DATE with DATETIME still not using indexes correctly - Make conditions like "date_col $CMP$ 'datetime-const'" range-sargable mysql-test/r/range.result: BUG#32198: Comparison of DATE with DATETIME still not using indexes correctly - Testcase mysql-test/t/range.test: BUG#32198: Comparison of DATE with DATETIME still not using indexes correctly - Testcase sql/field.cc: BUG#32198: Comparison of DATE with DATETIME still not using indexes correctly - Added comments --- mysql-test/r/range.result | 18 ++++++++++++++++++ mysql-test/t/range.test | 20 ++++++++++++++++++++ sql/field.cc | 3 +++ sql/opt_range.cc | 27 ++++++++++++++++++++++++++- 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 58f8d077ac5..e0084b53320 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1135,3 +1135,21 @@ item started price A1 2005-11-01 08:00:00 1000.000 A1 2005-11-15 00:00:00 2000.000 DROP TABLE t1; + +BUG#32198 "Comparison of DATE with DATETIME still not using indexes correctly" + +CREATE TABLE t1 ( +id int(11) NOT NULL auto_increment, +dateval date default NULL, +PRIMARY KEY (id), +KEY dateval (dateval) +) AUTO_INCREMENT=173; +INSERT INTO t1 VALUES +(1,'2007-01-01'),(2,'2007-01-02'),(3,'2007-01-03'),(4,'2007-01-04'), +(5,'2007-01-05'),(6,'2007-01-06'),(7,'2007-01-07'),(8,'2007-01-08'), +(9,'2007-01-09'),(10,'2007-01-10'),(11,'2007-01-11'); +This must use range access: +explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range dateval dateval 4 NULL 2 Using where +drop table t1; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index b8d4b91f03d..87ba3510326 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -935,4 +935,24 @@ SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; DROP TABLE t1; +--echo +--echo BUG#32198 "Comparison of DATE with DATETIME still not using indexes correctly" +--echo +CREATE TABLE t1 ( + id int(11) NOT NULL auto_increment, + dateval date default NULL, + PRIMARY KEY (id), + KEY dateval (dateval) +) AUTO_INCREMENT=173; + +INSERT INTO t1 VALUES +(1,'2007-01-01'),(2,'2007-01-02'),(3,'2007-01-03'),(4,'2007-01-04'), +(5,'2007-01-05'),(6,'2007-01-06'),(7,'2007-01-07'),(8,'2007-01-08'), +(9,'2007-01-09'),(10,'2007-01-10'),(11,'2007-01-11'); + +--echo This must use range access: +explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59'; + +drop table t1; + # End of 5.0 tests diff --git a/sql/field.cc b/sql/field.cc index 86853389c64..955694933a0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5259,6 +5259,9 @@ void Field_date::sql_type(String &res) const 1 Value was cut during conversion 2 Wrong date string 3 Datetime value that was cut (warning level NOTE) + This is used by opt_range.cc:get_mm_leaf(). Note that there is a + nearly-identical class Field_date doesn't ever return 3 from its + store function. */ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 7a51dbbe76c..5d8bba69422 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4414,6 +4414,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, { tree= new (alloc) SEL_ARG(field, 0, 0); tree->type= SEL_ARG::IMPOSSIBLE; + goto end; } else { @@ -4422,8 +4423,32 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, for the cases like int_field > 999999999999999999999999 as well. */ tree= 0; + if (err == 3 && field->type() == FIELD_TYPE_DATE && + (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC || + type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) ) + { + /* + We were saving DATETIME into a DATE column, the conversion went ok + but a non-zero time part was cut off. + + In MySQL's SQL dialect, DATE and DATETIME are compared as datetime + values. Index over a DATE column uses DATE comparison. Changing + from one comparison to the other is possible: + + datetime(date_col)< '2007-12-10 12:34:55' -> date_col<='2007-12-10' + datetime(date_col)<='2007-12-10 12:34:55' -> date_col<='2007-12-10' + + datetime(date_col)> '2007-12-10 12:34:55' -> date_col>='2007-12-10' + datetime(date_col)>='2007-12-10 12:34:55' -> date_col>='2007-12-10' + + but we'll need to convert '>' to '>=' and '<' to '<='. This will + be done together with other types at the end of this function + (grep for field_is_equal_to_item) + */ + } + else + goto end; } - goto end; } if (err < 0) { From f1d980542233ac18d3e4acc6911b8adfc432bb09 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Dec 2007 15:47:23 +0400 Subject: [PATCH 44/46] after merge fix --- mysql-test/r/delayed.result | 16 ---------------- mysql-test/r/func_misc.result | 2 +- mysql-test/t/func_misc.test | 3 +-- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result index e7ee23b3e2a..9f6ebea7e1b 100644 --- a/mysql-test/r/delayed.result +++ b/mysql-test/r/delayed.result @@ -109,20 +109,12 @@ c1 DROP TABLE t1; SET @@auto_increment_offset= @bug20627_old_auto_increment_offset; -Warnings: -Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@auto_increment_increment= @bug20627_old_auto_increment_increment; -Warnings: -Warning 1292 Truncated incorrect auto-increment-increment value: '0' SET @@session.auto_increment_offset= @bug20627_old_session_auto_increment_offset; -Warnings: -Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@session.auto_increment_increment= @bug20627_old_session_auto_increment_increment; -Warnings: -Warning 1292 Truncated incorrect auto-increment-increment value: '0' SET @bug20830_old_auto_increment_offset= @@auto_increment_offset; SET @bug20830_old_auto_increment_increment= @@ -245,20 +237,12 @@ SUM(c1) DROP TABLE t1; SET @@auto_increment_offset= @bug20830_old_auto_increment_offset; -Warnings: -Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@auto_increment_increment= @bug20830_old_auto_increment_increment; -Warnings: -Warning 1292 Truncated incorrect auto-increment-increment value: '0' SET @@session.auto_increment_offset= @bug20830_old_session_auto_increment_offset; -Warnings: -Warning 1292 Truncated incorrect auto-increment-offset value: '0' SET @@session.auto_increment_increment= @bug20830_old_session_auto_increment_increment; -Warnings: -Warning 1292 Truncated incorrect auto-increment-increment value: '0' CREATE TABLE t1(a BIT); INSERT DELAYED INTO t1 VALUES(1); FLUSH TABLE t1; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 4ba5ee674a9..4f6b6d3a0d8 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -210,7 +210,7 @@ test CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (5), (2); SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t; -ERROR HY000: The 'NAME_CONST' syntax is reserved for purposes internal to the MySQL server +ERROR HY000: Incorrect arguments to NAME_CONST DROP TABLE t1; CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (), (), (); diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 82db9ddbd67..ccb59df5677 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -212,12 +212,11 @@ SELECT NAME_CONST('test', 'test'); CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (5), (2); ---error ER_RESERVED_SYNTAX +--error ER_WRONG_ARGUMENTS SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t; DROP TABLE t1; ---echo End of 5.0 tests # # Bug #32559: connection hangs on query with name_const From e51e6097b98eb4faae8fec4704feab251d8031dc Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Dec 2007 21:13:08 +0400 Subject: [PATCH 45/46] valgrind error fix --- sql/ha_blackhole.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index 93d085bbc88..f098ef71a43 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -296,13 +296,21 @@ static byte* blackhole_get_key(st_blackhole_share *share, uint *length, } +static void blackhole_free_key(st_blackhole_share *share) +{ + thr_lock_delete(&share->lock); + my_free((byte*) share, MYF(0)); +} + + bool blackhole_db_init() { DBUG_ENTER("blackhole_db_init"); if (pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST)) goto error; if (hash_init(&blackhole_open_tables, &my_charset_bin, 32, 0, 0, - (hash_get_key) blackhole_get_key, 0, 0)) + (hash_get_key) blackhole_get_key, + (hash_free_key) blackhole_free_key, 0)) { VOID(pthread_mutex_destroy(&blackhole_mutex)); } From 12504d906bfabdd64938e313d3ac2d88b490834d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Dec 2007 23:46:29 +0400 Subject: [PATCH 46/46] additional fix --- sql/ha_blackhole.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index f098ef71a43..e477686d18e 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -299,7 +299,7 @@ static byte* blackhole_get_key(st_blackhole_share *share, uint *length, static void blackhole_free_key(st_blackhole_share *share) { thr_lock_delete(&share->lock); - my_free((byte*) share, MYF(0)); + my_free((gptr) share, MYF(0)); }