From e5d0df2c06f1a60e2d2737e27ccef6e01b04df1a Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Nov 2002 13:54:27 +0100 Subject: [PATCH 01/30] fixing gone file ONCE AGAIN --- BitKeeper/etc/gone | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/BitKeeper/etc/gone b/BitKeeper/etc/gone index 204044a2cc5..2c21b8e7e03 100644 --- a/BitKeeper/etc/gone +++ b/BitKeeper/etc/gone @@ -199,9 +199,7 @@ BK|sql-bench/Results/ATIS-mysql-3.21-Linux_2.2.1_i686|19700101030959|02022|660fb BK|sql-bench/Results/ATIS-mysql-Linux_2.2.10_i686|19700101030959|02025|3fa4d167cceff7e8 BK|sql-bench/Results/ATIS-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02312|84ca3b85ff306133 BK|sql-bench/Results/ATIS-mysql-Linux_2.2.14_i686_xeon|19700101030959|02044|3e820c28bf4af63a -BK|sql-bench/Results/ATIS-mysql-SunOS_5.5.1_sun4u|19700101030959|02031|dfb4c5f6b6db3b49 BK|sql-bench/Results/ATIS-mysql-SunOS_5.6_sun4m|19700101030959|02032|62028e0375b3b8b -BK|sql-bench/Results/ATIS-mysql-SunOS_5.7_sun4u|19700101030959|02034|be0d9789776c5ed7 BK|sql-bench/Results/ATIS-mysql_3.21-Linux_2.0.35_i686|19700101030959|02036|c25425e045ca8dfc BK|sql-bench/Results/ATIS-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02304|cbe120d860296d2f BK|sql-bench/Results/ATIS-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02027|a74e7b82d3908fa9 @@ -265,9 +263,7 @@ BK|sql-bench/Results/RUN-mysql-3.21-Linux_2.2.1_i686|19700101030959|02050|f6fdd6 BK|sql-bench/Results/RUN-mysql-Linux_2.2.10_i686|19700101030959|02041|712f52be5d195406 BK|sql-bench/Results/RUN-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02038|8ee87b26b91c86fe BK|sql-bench/Results/RUN-mysql-Linux_2.2.14_i686_xeon|19700101030959|02055|17854e751e1d9d1d -BK|sql-bench/Results/RUN-mysql-SunOS_5.5.1_sun4u|19700101030959|02058|afbba182428e20df BK|sql-bench/Results/RUN-mysql-SunOS_5.6_sun4m|19700101030959|02059|eafc8188345e262b -BK|sql-bench/Results/RUN-mysql-SunOS_5.7_sun4u|19700101030959|02061|86e1dc0e25a8b8f BK|sql-bench/Results/RUN-mysql_3.21-Linux_2.0.35_i686|19700101030959|02064|ea8672d8473435 BK|sql-bench/Results/RUN-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02310|a902e1a967d79c42 BK|sql-bench/Results/RUN-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02030|413ab3b8a99e61e9 @@ -277,9 +273,7 @@ BK|sql-bench/Results/alter-table-mysql-3.21-Linux_2.2.1_i686|19700101030959|0207 BK|sql-bench/Results/alter-table-mysql-Linux_2.2.10_i686|19700101030959|02081|93b78a85b720a186 BK|sql-bench/Results/alter-table-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02314|4ae4b989301df98b BK|sql-bench/Results/alter-table-mysql-Linux_2.2.14_i686_xeon|19700101030959|02057|64cc4b874cd6fabf -BK|sql-bench/Results/alter-table-mysql-SunOS_5.5.1_sun4u|19700101030959|02087|9d7e75667fcb29ec BK|sql-bench/Results/alter-table-mysql-SunOS_5.6_sun4m|19700101030959|02088|8a1bd6589a189890 -BK|sql-bench/Results/alter-table-mysql-SunOS_5.7_sun4u|19700101030959|02090|ce74c2f623d3bb3 BK|sql-bench/Results/alter-table-mysql_3.21-Linux_2.0.35_i686|19700101030959|02092|762639f2560976bd BK|sql-bench/Results/alter-table-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02316|1390155aad5b6e86 BK|sql-bench/Results/alter-table-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02317|9090bebb62ef164b @@ -289,9 +283,7 @@ BK|sql-bench/Results/big-tables-mysql-3.21-Linux_2.2.1_i686|19700101030959|02106 BK|sql-bench/Results/big-tables-mysql-Linux_2.2.10_i686|19700101030959|02109|99daa1c5370d077d BK|sql-bench/Results/big-tables-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02315|2804ec3c95be436a BK|sql-bench/Results/big-tables-mysql-Linux_2.2.14_i686_xeon|19700101030959|02074|290c2c3de9d8e6b -BK|sql-bench/Results/big-tables-mysql-SunOS_5.5.1_sun4u|19700101030959|02115|7d7b6c0bf58b9b79 BK|sql-bench/Results/big-tables-mysql-SunOS_5.6_sun4m|19700101030959|02116|f351a7f3e1e2257e -BK|sql-bench/Results/big-tables-mysql-SunOS_5.7_sun4u|19700101030959|02118|ebc379b231312bbe BK|sql-bench/Results/big-tables-mysql_3.21-Linux_2.0.35_i686|19700101030959|02120|190e827e569c99a4 BK|sql-bench/Results/big-tables-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02318|c5eabcb89ceac698 BK|sql-bench/Results/big-tables-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02319|856d503725373684 @@ -301,9 +293,7 @@ BK|sql-bench/Results/connect-mysql-3.21-Linux_2.2.1_i686|19700101030959|02134|c0 BK|sql-bench/Results/connect-mysql-Linux_2.2.10_i686|19700101030959|02137|c92505d77e19d5ec BK|sql-bench/Results/connect-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02084|e7e2959b7387251f BK|sql-bench/Results/connect-mysql-Linux_2.2.14_i686_xeon|19700101030959|02071|ea19dc3ec55b3618 -BK|sql-bench/Results/connect-mysql-SunOS_5.5.1_sun4u|19700101030959|02142|a9493110fe62e0b1 BK|sql-bench/Results/connect-mysql-SunOS_5.6_sun4m|19700101030959|02143|a10e3ddfa26a3e7f -BK|sql-bench/Results/connect-mysql-SunOS_5.7_sun4u|19700101030959|02145|c67beb9e9d2cf32e BK|sql-bench/Results/connect-mysql_3.21-Linux_2.0.35_i686|19700101030959|02146|650abd213e6828c6 BK|sql-bench/Results/connect-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02320|ce69cc65bc827b5c BK|sql-bench/Results/connect-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02066|f801e08429a4f7c6 @@ -313,9 +303,7 @@ BK|sql-bench/Results/create-mysql-3.21-Linux_2.2.1_i686|19700101030959|02158|515 BK|sql-bench/Results/create-mysql-Linux_2.2.10_i686|19700101030959|02161|9e7822f66df6aa76 BK|sql-bench/Results/create-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02102|34ded91c5fc25de9 BK|sql-bench/Results/create-mysql-Linux_2.2.14_i686_xeon|19700101030959|02139|50d15991293030ef -BK|sql-bench/Results/create-mysql-SunOS_5.5.1_sun4u|19700101030959|02166|bbb5de66fc56de7b BK|sql-bench/Results/create-mysql-SunOS_5.6_sun4m|19700101030959|02221|9233114ae6f8c5f -BK|sql-bench/Results/create-mysql-SunOS_5.7_sun4u|19700101030959|02223|7ee13bfcafeab498 BK|sql-bench/Results/create-mysql_3.21-Linux_2.0.35_i686|19700101030959|02225|df1b037d17b33587 BK|sql-bench/Results/create-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02321|e985e71d552ff09e BK|sql-bench/Results/create-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02099|483dcf223d5abf81 @@ -325,9 +313,7 @@ BK|sql-bench/Results/insert-mysql-3.21-Linux_2.2.1_i686|19700101030959|02239|fd0 BK|sql-bench/Results/insert-mysql-Linux_2.2.10_i686|19700101030959|02242|763edf9aec633f51 BK|sql-bench/Results/insert-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02130|5be3d6f299738a31 BK|sql-bench/Results/insert-mysql-Linux_2.2.14_i686_xeon|19700101030959|02141|c683ee4b9d214298 -BK|sql-bench/Results/insert-mysql-SunOS_5.5.1_sun4u|19700101030959|02247|8a9ae41f9a79f79 BK|sql-bench/Results/insert-mysql-SunOS_5.6_sun4m|19700101030959|02248|3402d060ae20e19 -BK|sql-bench/Results/insert-mysql-SunOS_5.7_sun4u|19700101030959|02250|78efa132c6e252b9 BK|sql-bench/Results/insert-mysql_3.21-Linux_2.0.35_i686|19700101030959|02252|60c0965dff31db07 BK|sql-bench/Results/insert-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02322|ed252140ff399961 BK|sql-bench/Results/insert-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02114|29a3b8a1ca8aa9d @@ -337,9 +323,7 @@ BK|sql-bench/Results/select-mysql-3.21-Linux_2.2.1_i686|19700101030959|02265|ed3 BK|sql-bench/Results/select-mysql-Linux_2.2.10_i686|19700101030959|02268|a2e264d777b787d BK|sql-bench/Results/select-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02227|308117295c3bc096 BK|sql-bench/Results/select-mysql-Linux_2.2.14_i686_xeon|19700101030959|02152|ead3f11b46ac626f -BK|sql-bench/Results/select-mysql-SunOS_5.5.1_sun4u|19700101030959|02273|c9a1a498a052e268 BK|sql-bench/Results/select-mysql-SunOS_5.6_sun4m|19700101030959|02274|4da215905bce988d -BK|sql-bench/Results/select-mysql-SunOS_5.7_sun4u|19700101030959|02276|632c92971c61e34a BK|sql-bench/Results/select-mysql_3.21-Linux_2.0.35_i686|19700101030959|02278|5fadbac5f98696a BK|sql-bench/Results/select-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02323|e8c0871a668a610d BK|sql-bench/Results/select-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02127|963a98ed526e2be4 @@ -349,9 +333,7 @@ BK|sql-bench/Results/wisconsin-mysql-3.21-Linux_2.2.1_i686|19700101030959|02290| BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.10_i686|19700101030959|02288|301a82b12a84922b BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02280|d01900af34fb33b8 BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_i686_xeon|19700101030959|02154|7525b23938631801 -BK|sql-bench/Results/wisconsin-mysql-SunOS_5.5.1_sun4u|19700101030959|02297|379705afa2e12378 BK|sql-bench/Results/wisconsin-mysql-SunOS_5.6_sun4m|19700101030959|02298|ec61b14072715dc8 -BK|sql-bench/Results/wisconsin-mysql-SunOS_5.7_sun4u|19700101030959|02300|f27927f8c64ea8ad BK|sql-bench/Results/wisconsin-mysql_3.21-Linux_2.0.35_i686|19700101030959|02302|31703d40ea6b4f66 BK|sql-bench/Results/wisconsin-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02324|ec075a89dbdbbe6a BK|sql-bench/Results/wisconsin-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02325|233d5aa529979990 @@ -745,8 +727,6 @@ mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000029.xml|20001017133713| mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000030.xml|20001017133600|63205|c2b25781eefaee9 mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/README|20001013051514|26509|cd4bb681e5a0cd10 mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/mysqltest.xsl|20001013051514|27425|1b8f6ec4f1b5f634 -mwagner@work.mysql.com|mysql-test/r/3.23/sel000001.result|20001010091454|28284|383913ae4505ec86 -mwagner@work.mysql.com|mysql-test/r/3.23/sel000002.result|20001010091454|29230|d1787e6fd5dbc1cc nick@nick.leippe.com|mysql-test/r/rpl_empty_master_crash.result|20020531235552|47718|615f521be2132141 nick@nick.leippe.com|mysql-test/t/rpl_empty_master_crash.test|20020531235552|52328|99464e737639ccc6 sasha@mysql.sashanet.com|BitKeeper/etc/logging_ok|20000801000905|12967|5b7d847a2158554 @@ -754,36 +734,19 @@ sasha@mysql.sashanet.com|build-tags|20011125054855|05181|7afb7e785b80f97 sasha@mysql.sashanet.com|build-tags|20011201050944|25384|b6f6fff142121618 sasha@mysql.sashanet.com|libmysql_r/acconfig.h|20001128060846|51084|65f1202b3b5c345f sasha@mysql.sashanet.com|mysql-test/README.gcov|20001012045950|28177|5a6da067a30780ce -sasha@mysql.sashanet.com|mysql-test/README.gcov|20001214012355|41825|2de7575ca81155e5 sasha@mysql.sashanet.com|mysql-test/README|20001010001022|12739|108667adaeabe3f5 sasha@mysql.sashanet.com|mysql-test/r/3.23/alt000001.result|20001122072330|24729|393103dbf15f35c9 -sasha@mysql.sashanet.com|mysql-test/r/3.23/ins000001.result|20001018175743|49824|f45c599efdf8352b sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000001.a.result|20001118063528|39426|2987b17db06808c3 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000001.b.result|20001118063528|44057|62e1fa91167cacc3 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000002.result|20001118063528|46039|109f5ceed1e0d64 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000003.result|20001118063528|48148|68d6ee00beaa011 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000004.a.result|20001118063528|50132|3415f066cb91c460 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000004.b.result|20001118063528|52094|352b35351551485 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000005.result|20001118063528|54071|a50962bc2340ab9a -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000006.result|20001118063528|56081|5653051e8ce6b4aa -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000007.result|20001121063807|21606|e0c3b6134e0884da -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000008.result|20001121063807|23636|c5cfee19ca5a7da9 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000009.result|20001121063807|25633|ed8042446ab97926 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000010.result|20001122072330|29430|3228109b8965b0f8 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000011.result|20001125024912|48851|c29dce30aa97f265 -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000012.result|20001126062901|05938|35d6596da7b90fc5 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000012.status.result|20001126062901|09395|bbbd650b5beea32f -sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000013.result|20001202171150|03876|ac5024e6cf6daac6 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000013.status.result|20001202171150|06069|6bee190c298cc9fd -sasha@mysql.sashanet.com|mysql-test/r/3.23/sel000003.result|20001011230020|64653|d7b657b1e3a286a7 -sasha@mysql.sashanet.com|mysql-test/r/3.23/sel000100.res|20001205131218|23520|84ed46856cb3a69f sasha@mysql.sashanet.com|mysql-test/r/3.23/shw000001.result|20001121234128|16652|8b20b03d8319b9a5 sasha@mysql.sashanet.com|mysql-test/r/binlog-backup-restore.result|20010424233926|16010|605de78abda64d27 sasha@mysql.sashanet.com|mysql-test/r/df_crash.result|20010406010433|59989|4a3dbee64843953d sasha@mysql.sashanet.com|mysql-test/r/identity.result|20010910233028|16331|e41453a364242503 sasha@mysql.sashanet.com|mysql-test/r/mrg000002.result|20001212152450|11492|745be0854aaaaf5e -sasha@mysql.sashanet.com|mysql-test/r/slave-running.result|20001208141122|24303|f73e49462cf59e1f -sasha@mysql.sashanet.com|mysql-test/r/slave-stopped.result|20001208141122|28916|25c134b1a4f1993a sasha@mysql.sashanet.com|mysql-test/std_data/m.MRG|20001212152450|17736|3f5632c37af00f18 sasha@mysql.sashanet.com|mysql-test/std_data/m.frm|20001212152450|13897|e351dfe0b6824c0c sasha@mysql.sashanet.com|mysql-test/std_data/select-key.master|20001009234916|07315|e6b83af25df0ce5 From f980950bb3b19df3de3030c531ecff99ecb323e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Nov 2002 15:40:46 +0200 Subject: [PATCH 02/30] Some code optimisations related to EXPLAIN of derived tables and the resulting code cleanup in our main loop. --- mysql-test/r/subselect.result | 2 +- sql/mysql_priv.h | 3 +- sql/sql_derived.cc | 10 ++-- sql/sql_lex.cc | 1 + sql/sql_parse.cc | 107 +++++++++------------------------- sql/sql_select.cc | 4 +- 6 files changed, 37 insertions(+), 90 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index b1bf134fdde..5674bf3c473 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -71,8 +71,8 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from explain select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from (select * from t2 where a>1) as tt; id select_type table type possible_keys key key_len ref rows Extra -3 DERIVED t2 ALL NULL NULL NULL NULL 2 where used 1 PRIMARY system NULL NULL NULL NULL 1 +3 DERIVED t2 ALL NULL NULL NULL NULL 2 where used 2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 where used; Using filesort select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1); a diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c61621bf91d..a6771c9754d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -399,8 +399,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, select_result *result); int mysql_union(THD *thd, LEX *lex,select_result *result); -int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t, - bool tables_is_opened); +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item_result_field ***copy_func, Field **from_field, bool group,bool modify_item); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 1335618b90d..93627409d27 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -28,8 +28,7 @@ static const char *any_db="*any*"; // Special symbol for check_access -int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t, - bool tables_is_opened) +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) { /* TODO: make derived tables with union inside (now only 1 SELECT may be @@ -58,7 +57,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t, if (cursor->derived) { res= mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor, 0); + cursor); if (res) DBUG_RETURN(res); } } @@ -68,7 +67,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t, while ((item= it++)) item_list.push_back(item); - if (tables_is_opened || !(res=open_and_lock_tables(thd,tables))) + if (!(res=open_and_lock_tables(thd,tables))) { if (setup_fields(thd,tables,item_list,0,0,1)) { @@ -112,7 +111,8 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t, t->real_name=table->real_name; t->table=table; table->derived_select_number= sl->select_number; - sl->exclude(); + if (!lex->describe) + sl->exclude(); t->db= (tables && tables->db && tables->db[0]) ? t->db : thd->db; t->derived=(SELECT_LEX *)0; // just in case ... } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5327801bf9c..0865e6da05f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -959,6 +959,7 @@ void st_select_lex::init_query() table_list.next= (byte**) &table_list.first; item_list.empty(); join= 0; + olap= UNSPECIFIED_OLAP_TYPE; } void st_select_lex::init_select() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 57325ef19cf..4288773b00b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1328,74 +1328,24 @@ mysql_execute_command(THD *thd) #endif } - select_result *explain_result= 0; /* TODO: make derived tables processing 'inside' SELECT processing. TODO: solve problem with depended derived tables in subselects */ - if (lex->sql_command == SQLCOM_SELECT && - lex->describe && lex->derived_tables) - { - if (!(explain_result= new select_send())) - { - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_VOID_RETURN; - } - //check rights - for (cursor= tables; - cursor; - cursor= cursor->next) - if (cursor->derived) - { - TABLE_LIST *tables= - (TABLE_LIST *)((SELECT_LEX_UNIT *) - cursor->derived)->first_select()->table_list.first; - int res; - if (tables) - res= check_table_access(thd,SELECT_ACL, tables); - else - res= check_access(thd, SELECT_ACL, any_db); - if (res) - DBUG_VOID_RETURN; - } - thd->send_explain_fields(explain_result); - // EXPLAIN derived tables - for (cursor= tables; - cursor; - cursor= cursor->next) - if (cursor->derived) - { - SELECT_LEX *select_lex= ((SELECT_LEX_UNIT *) - cursor->derived)->first_select(); - if (!open_and_lock_tables(thd, - (TABLE_LIST*) select_lex->table_list.first)) - { - mysql_explain_select(thd, select_lex, - "DERIVED", explain_result); - // execute derived table SELECT to provide table for other SELECTs - if (mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor, 1)) - DBUG_VOID_RETURN; - } - else - DBUG_VOID_RETURN; - } - - } - else if (lex->derived_tables) +if (lex->derived_tables) { for (TABLE_LIST *cursor= tables; cursor; cursor= cursor->next) if (cursor->derived && (res=mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor, 0))) + cursor))) { if (res < 0) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); DBUG_VOID_RETURN; } - } + } if ((lex->select_lex.next_select_in_list() && lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && @@ -1435,19 +1385,18 @@ mysql_execute_command(THD *thd) { if (lex->describe) { - if (!explain_result) - if (!(explain_result= new select_send())) - { - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_VOID_RETURN; - } - else - thd->send_explain_fields(explain_result); + if (!(result= new select_send())) + { + send_error(thd, ER_OUT_OF_RESOURCES); + DBUG_VOID_RETURN; + } + else + thd->send_explain_fields(result); fix_tables_pointers(select_lex); - res= mysql_explain_union(thd, &thd->lex.unit, explain_result); + res= mysql_explain_union(thd, &thd->lex.unit, result); MYSQL_LOCK *save_lock= thd->lock; thd->lock= (MYSQL_LOCK *)0; - explain_result->send_eof(); + result->send_eof(); thd->lock= save_lock; } else @@ -2901,26 +2850,24 @@ void mysql_init_query(THD *thd) { DBUG_ENTER("mysql_init_query"); - thd->lex.unit.init_query(); - thd->lex.unit.init_select(); - thd->lex.select_lex.init_query(); - thd->lex.unit.slave= &thd->lex.select_lex; - thd->lex.unit.global_parameters= &thd->lex.select_lex; //Global limit & order - thd->lex.select_lex.master= &thd->lex.unit; - thd->lex.select_lex.prev= &thd->lex.unit.slave; - thd->select_number= thd->lex.select_lex.select_number= 1; - thd->lex.value_list.empty(); + LEX *lex=&thd->lex; + lex->unit.init_query(); + lex->unit.init_select(); + lex->select_lex.init_query(); + lex->value_list.empty(); + lex->param_list.empty(); + lex->unit.global_parameters= lex->unit.slave= lex->current_select= &lex->select_lex; + lex->select_lex.master= &lex->unit; + lex->select_lex.prev= &lex->unit.slave; + lex->olap=lex->describe=0; + lex->derived_tables= false; + thd->select_number= lex->select_lex.select_number= 1; thd->free_list= 0; - thd->lex.current_select= &thd->lex.select_lex; - thd->lex.olap=thd->lex.describe=0; - thd->lex.select_lex.olap= UNSPECIFIED_OLAP_TYPE; - thd->fatal_error= 0; // Safety thd->total_warn_count=0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; thd->sent_row_count= thd->examined_row_count= 0; - thd->rand_used=0; + thd->fatal_error= thd->rand_used=0; thd->safe_to_cache_query= 1; - thd->lex.param_list.empty(); DBUG_VOID_RETURN; } @@ -2932,7 +2879,6 @@ mysql_init_select(LEX *lex) select_lex->init_select(); select_lex->master_unit()->select_limit= select_lex->select_limit= lex->thd->variables.select_limit; - select_lex->olap= UNSPECIFIED_OLAP_TYPE; lex->exchange= 0; lex->result= 0; lex->proc_list.first= 0; @@ -3016,14 +2962,13 @@ mysql_parse(THD *thd, char *inBuf, uint length) mysql_init_query(thd); thd->query_length = length; - thd->lex.derived_tables= false; if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) { LEX *lex=lex_start(thd, (uchar*) inBuf, length); if (!yyparse() && ! thd->fatal_error) { if (mqh_used && thd->user_connect && - check_mqh(thd, thd->lex.sql_command)) + check_mqh(thd, lex->sql_command)) { thd->net.error = 0; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b9162daadaa..674caed0cd0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7458,8 +7458,10 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ((sl->next_select_in_list())?"PRIMARY": "SIMPLE"): ((sl == first)? + ((sl->linkage == DERIVED_TABLE_TYPE) ? + "DERIVED": ((sl->dependent)?"DEPENDENT SUBSELECT": - "SUBSELECT"): + "SUBSELECT")): ((sl->dependent)?"DEPENDENT UNION": "UNION"))), result); From 3cff56d096174c4b612d4b34649b595392d283d6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Nov 2002 15:09:24 +0100 Subject: [PATCH 03/30] typo fixed --- myisam/myisamchk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index ca4e430d49b..d39b1e75c15 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -1638,7 +1638,7 @@ err: volatile bool *killed_ptr(MI_CHECK *param) { - return (bool *)(param->thd); /* always NULL */ + return (bool *)(& param->thd); /* always NULL */ } /* print warnings and errors */ From 74985d1353ac1acf478047c8c8393b4323850342 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 10 Nov 2002 14:05:17 +0400 Subject: [PATCH 04/30] Fixes for fault about String::copy() --- client/mysql.cc | 4 ++-- client/sql_string.cc | 51 ++++++++++++++++++++++++++++---------------- client/sql_string.h | 43 ++++++++++++++++++++----------------- 3 files changed, 59 insertions(+), 39 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index fbd3b13ca83..e4a481a5290 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -952,7 +952,7 @@ static bool add_line(String &buffer,char *line,char *in_string) } if ((com=find_command(NullS,(char) inchar))) { - const String tmp(line,(uint) (out-line)); + const String tmp(line,(uint) (out-line), system_charset_info); buffer.append(tmp); if ((*com->func)(&buffer,pos-1) > 0) return 1; // Quit @@ -1709,7 +1709,7 @@ print_table_data(MYSQL_RES *result) print_field_types(result); mysql_field_seek(result,0); } - separator.copy("+",1); + separator.copy("+",1,system_charset_info); while ((field = mysql_fetch_field(result))) { uint length= column_names ? (uint) strlen(field->name) : 0; diff --git a/client/sql_string.cc b/client/sql_string.cc index 65854ece0ef..f0f31004544 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -40,19 +40,16 @@ extern void sql_element_free(void *ptr); bool String::real_alloc(uint32 arg_length) { arg_length=ALIGN_SIZE(arg_length+1); + str_length=0; if (Alloced_length < arg_length) { free(); if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME)))) - { - str_length=0; return TRUE; - } Alloced_length=arg_length; alloced=1; } Ptr[0]=0; - str_length=0; return FALSE; } @@ -94,36 +91,40 @@ bool String::realloc(uint32 alloc_length) return FALSE; } -bool String::set(longlong num) +bool String::set(longlong num, CHARSET_INFO *cs) { if (alloc(21)) return TRUE; str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr); + str_charset=cs; return FALSE; } -bool String::set(ulonglong num) +bool String::set(ulonglong num, CHARSET_INFO *cs) { if (alloc(21)) return TRUE; str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr); + str_charset=cs; return FALSE; } -bool String::set(double num,uint decimals) +bool String::set(double num,uint decimals, CHARSET_INFO *cs) { char buff[331]; + + str_charset=cs; if (decimals >= NOT_FIXED_DEC) { sprintf(buff,"%.14g",num); // Enough for a DATETIME - return copy(buff, (uint32) strlen(buff)); + return copy(buff, (uint32) strlen(buff), my_charset_latin1); } #ifdef HAVE_FCONVERT int decpt,sign; char *pos,*to; VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1)); - if (!isdigit(buff[1])) + if (!my_isdigit(system_charset_info, buff[1])) { // Nan or Inf pos=buff+1; if (sign) @@ -181,7 +182,7 @@ end: #else sprintf(buff,"%.*f",(int) decimals,num); #endif - return copy(buff,(uint32) strlen(buff)); + return copy(buff,(uint32) strlen(buff), my_charset_latin1); #endif } @@ -203,16 +204,18 @@ bool String::copy(const String &str) str_length=str.str_length; bmove(Ptr,str.Ptr,str_length); // May be overlapping Ptr[str_length]=0; + str_charset=str.str_charset; return FALSE; } -bool String::copy(const char *str,uint32 arg_length) +bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) { if (alloc(arg_length)) return TRUE; if ((str_length=arg_length)) memcpy(Ptr,str,arg_length); Ptr[arg_length]=0; + str_charset=cs; return FALSE; } @@ -489,7 +492,7 @@ void String::qs_append(double d) void String::qs_append(double *d) { double ld; - float8get(ld, d); + float8get(ld, (char*) d); qs_append(ld); } @@ -523,12 +526,23 @@ int sortcmp(const String *x,const String *y) #endif /* USE_STRCOLL */ x_len-=len; // For easy end space test y_len-=len; - while (len--) + if (x->str_charset->sort_order) { - if (x->str_charset->sort_order[(uchar) *s++] != + while (len--) + { + if (x->str_charset->sort_order[(uchar) *s++] != x->str_charset->sort_order[(uchar) *t++]) - return ((int) x->str_charset->sort_order[(uchar) s[-1]] - - (int) x->str_charset->sort_order[(uchar) t[-1]]); + return ((int) x->str_charset->sort_order[(uchar) s[-1]] - + (int) x->str_charset->sort_order[(uchar) t[-1]]); + } + } + else + { + while (len--) + { + if (*s++ != *t++) + return ((int) s[-1] - (int) t[-1]); + } } #ifndef CMP_ENDSPACE /* Don't compare end space in strings */ @@ -586,6 +600,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) return from; // Actually an error if ((to->str_length=min(from->str_length,from_length))) memcpy(to->Ptr,from->Ptr,to->str_length); + to->str_charset=from->str_charset; return to; } @@ -658,7 +673,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, { // Found wild_many wildstr++; /* Remove any '%' and '_' from the wild search string */ - for ( ; wildstr != wildend ; wildstr++) + for (; wildstr != wildend ; wildstr++) { if (*wildstr == wild_many) continue; @@ -787,7 +802,7 @@ int wild_compare(const char *str,const char *str_end, { // Found wild_many wildstr++; /* Remove any '%' and '_' from the wild search string */ - for ( ; wildstr != wildend ; wildstr++) + for (; wildstr != wildend ; wildstr++) { if (*wildstr == wild_many) continue; diff --git a/client/sql_string.h b/client/sql_string.h index 811e49a0d02..4ac4308f113 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -46,22 +46,22 @@ public: String(uint32 length_arg) { alloced=0; Alloced_length=0; (void) real_alloc(length_arg); - str_charset=default_charset_info; + str_charset=default_charset_info; } - String(const char *str) + String(const char *str, CHARSET_INFO *cs) { Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } - String(const char *str,uint32 len) + String(const char *str,uint32 len, CHARSET_INFO *cs) { Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } - String(char *str,uint32 len) + String(char *str,uint32 len, CHARSET_INFO *cs) { Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } String(const String &str) { @@ -74,6 +74,7 @@ public: { sql_element_free(ptr_arg); } ~String() { free(); } + inline void set_charset(CHARSET_INFO *charset) { str_charset=charset; } inline CHARSET_INFO *charset() const { return str_charset; } inline uint32 length() const { return str_length;} inline uint32 alloced_length() const { return Alloced_length;} @@ -102,28 +103,31 @@ public: Alloced_length=str.Alloced_length-offset; else Alloced_length=0; + str_charset=str.str_charset; } - inline void set(char *str,uint32 arg_length) + inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; + str_charset=cs; } - inline void set(const char *str,uint32 arg_length) + inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; + str_charset=cs; } - inline void set_quick(char *str,uint32 arg_length) + inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs) { if (!alloced) { Ptr=(char*) str; str_length=Alloced_length=arg_length; } + str_charset=cs; } - bool set(longlong num); - /* bool set(long num); */ - bool set(ulonglong num); - bool set(double num,uint decimals=2); + bool set(longlong num, CHARSET_INFO *cs); + bool set(ulonglong num, CHARSET_INFO *cs); + bool set(double num,uint decimals, CHARSET_INFO *cs); inline void free() { if (alloced) @@ -174,7 +178,7 @@ public: bool copy(); // Alloc string if not alloced bool copy(const String &s); // Allocate new string - bool copy(const char *s,uint32 arg_length); // Allocate new string + bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string bool append(const String &s); bool append(const char *s,uint32 arg_length=0); bool append(IO_CACHE* file, uint32 arg_length); @@ -208,16 +212,17 @@ public: uint32 numchars(); int charpos(int i,uint32 offset=0); -// added by Holyfoot for "geometry" needs int reserve(uint32 space_needed) { return realloc(str_length + space_needed); } int reserve(uint32 space_needed, uint32 grow_by); -// these append operations do NOT check alloced memory -// q_*** methods writes values of parameters itself -// qs_*** methods writes string representation of value + /* + The following append operations do NOT check alloced memory + q_*** methods writes values of parameters itself + qs_*** methods writes string representation of value + */ void q_append(const char &c) { Ptr[str_length++] = c; From 1a7533074ebe8e6ce1ed6af999a46be86f08d684 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 10 Nov 2002 14:45:21 +0400 Subject: [PATCH 05/30] Fix syntax to be more clean: SHOW CREATE DATABASE [WITH IF NOT EXISTS] dbname --- client/mysqldump.c | 2 +- sql/sql_yacc.yy | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 9470786705d..c99f1429a8b 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1252,7 +1252,7 @@ static int init_dumping(char *database) MYSQL_ROW row; MYSQL_RES *dbinfo; - sprintf(qbuf,"SHOW CREATE DATABASE IF NOT EXISTS %s",database); + sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s",database); if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock))) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6235d93c18f..d432a76770d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -549,7 +549,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); type int_type real_type order_dir opt_field_spec lock_option udf_type if_exists opt_local opt_table_options table_options table_option opt_if_not_exists opt_var_type opt_var_ident_type - delete_option + delete_option opt_with_if_not_exists %type ULONG_NUM raid_types merge_insert_types @@ -878,6 +878,10 @@ opt_if_not_exists: /* empty */ { $$= 0; } | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }; +opt_with_if_not_exists: + /* empty */ { $$= 0; } + | WITH IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }; + opt_create_table_options: /* empty */ | create_table_options; @@ -3106,7 +3110,7 @@ show_param: lex->grant_user=$3; lex->grant_user->password.str=NullS; } - | CREATE DATABASE opt_if_not_exists ident + | CREATE DATABASE opt_with_if_not_exists ident { Lex->sql_command=SQLCOM_SHOW_CREATE_DB; Lex->create_info.options=$3; From 992075e209b5cbed30fd23fc95b2618dc8e6bfe3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 10 Nov 2002 16:14:39 +0400 Subject: [PATCH 06/30] New field snprintf() in CHARSET_INFO structure --- include/m_ctype.h | 8 +++- mysys/charset.c | 1 + strings/ctype-big5.c | 3 +- strings/ctype-bin.c | 3 +- strings/ctype-czech.c | 3 +- strings/ctype-euc_kr.c | 3 +- strings/ctype-gb2312.c | 3 +- strings/ctype-gbk.c | 3 +- strings/ctype-latin1_de.c | 3 +- strings/ctype-simple.c | 64 ++++++++++++++++++++++++++ strings/ctype-sjis.c | 3 +- strings/ctype-tis620.c | 3 +- strings/ctype-ujis.c | 3 +- strings/ctype-utf8.c | 94 ++++++++++++++++++++++++++++++++++++++- strings/ctype-win1250ch.c | 3 +- strings/ctype.c | 72 ++++++++++++++++++++---------- 16 files changed, 234 insertions(+), 38 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 029a1a5db39..6a964bf3b97 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -112,8 +112,12 @@ typedef struct charset_info_st uint (*hash_caseup)(struct charset_info_st *cs, const byte *key, uint len); void (*hash_sort)(struct charset_info_st *cs, const uchar *key, uint len, ulong *nr1, ulong *nr2); - + char max_sort_char; /* For LIKE optimization */ + + /* Charset dependant snprintf() */ + int (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt, ...); + } CHARSET_INFO; @@ -150,6 +154,8 @@ extern int my_strncasecmp_8bit(CHARSET_INFO * cs, const char *, const char *, ui int my_mb_wc_8bit(CHARSET_INFO *cs,my_wc_t *wc, const uchar *s,const uchar *e); int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e); +int my_snprintf_8bit(struct charset_info_st *, char *to, uint n, const char *fmt, ...); + #ifdef USE_MB /* Functions for multibyte charsets */ diff --git a/mysys/charset.c b/mysys/charset.c index 9c977c7d145..3ad4b4e8faa 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -388,6 +388,7 @@ static CHARSET_INFO *add_charset(CHARSET_INFO *cs, myf flags) cs->wc_mb = my_wc_mb_8bit; cs->hash_caseup = my_hash_caseup_simple; cs->hash_sort = my_hash_sort_simple; + cs->snprintf = my_snprintf_8bit; set_max_sort_char(cs); create_fromuni(cs); diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index b9011ac12aa..8dff0d860a0 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6247,7 +6247,8 @@ CHARSET_INFO my_charset_big5 = my_strncasecmp_mb, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 0a90a1e26e5..e479053071b 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -177,7 +177,8 @@ static CHARSET_INFO my_charset_bin_st = my_strncasecmp_bin, /* strncasecmp */ my_hash_caseup_bin, /* hash_caseup */ my_hash_sort_bin, /* hash_sort */ - 255 /* max_sort_char */ + 255, /* max_sort_char */ + my_snprintf_8bit /* snprintf */ }; diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index e6cab722a8e..6ce2bf13fce 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -625,7 +625,8 @@ CHARSET_INFO my_charset_czech = my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; #endif diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index a7d6044b378..154fada271e 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8664,7 +8664,8 @@ CHARSET_INFO my_charset_euc_kr = my_strncasecmp_mb, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; #endif diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index e931c7c1f31..ecd15830b3f 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5714,7 +5714,8 @@ CHARSET_INFO my_charset_gb2312 = my_strncasecmp_mb, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; #endif diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 0f2de81ccb6..bdfdfb9b256 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9902,7 +9902,8 @@ CHARSET_INFO my_charset_gbk = my_strncasecmp_mb, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index 040bd11b5e9..574fbf41da3 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -443,7 +443,8 @@ CHARSET_INFO my_charset_latin1_de = my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; #endif diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index f27b113376b..9fef27cad10 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -15,8 +15,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include "my_sys.h" #include "m_ctype.h" +#include "m_string.h" #include "dbug.h" +#include "stdarg.h" #include "assert.h" int my_strnxfrm_simple(CHARSET_INFO * cs, @@ -120,6 +123,67 @@ int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, } +static int my_vsnprintf_8bit(char *to, size_t n, const char* fmt, va_list ap) +{ + char *start=to, *end=to+n-1; + for (; *fmt ; fmt++) + { + if (fmt[0] != '%') + { + if (to == end) /* End of buffer */ + break; + *to++= *fmt; /* Copy ordinary char */ + continue; + } + /* Skip if max size is used (to be compatible with printf) */ + fmt++; + while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-') + fmt++; + if (*fmt == 'l') + fmt++; + if (*fmt == 's') /* String parameter */ + { + reg2 char *par = va_arg(ap, char *); + uint plen,left_len = (uint)(end-to); + if (!par) par = (char*)"(null)"; + plen = (uint) strlen(par); + if (left_len <= plen) + plen = left_len - 1; + to=strnmov(to,par,plen); + continue; + } + else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ + { + register int iarg; + if ((uint) (end-to) < 16) + break; + iarg = va_arg(ap, int); + if (*fmt == 'd') + to=int10_to_str((long) iarg,to, -10); + else + to=int10_to_str((long) (uint) iarg,to,10); + continue; + } + /* We come here on '%%', unknown code or too long parameter */ + if (to == end) + break; + *to++='%'; /* % used as % or unknown code */ + } + DBUG_ASSERT(to <= end); + *to='\0'; /* End of errmessage */ + return (uint) (to - start); +} + + +int my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)), + char* to, uint n, const char* fmt, ...) +{ + va_list args; + va_start(args,fmt); + return my_vsnprintf_8bit(to, n, fmt, args); +} + + #ifndef NEW_HASH_FUNCTION diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 9c8ac8d0c16..d657405137e 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4489,7 +4489,8 @@ CHARSET_INFO my_charset_sjis = my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; #endif diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 88549e7ee69..de1a0e170fb 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -717,7 +717,8 @@ CHARSET_INFO my_charset_tis620 = my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index cb1da080951..85b51b0469c 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8458,7 +8458,8 @@ CHARSET_INFO my_charset_ujis = my_strncasecmp_mb, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 81671e28c3f..707ca8f5c77 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1983,7 +1983,8 @@ CHARSET_INFO my_charset_utf8 = my_strncasecmp_utf8, my_hash_caseup_utf8,/* hash_caseup */ my_hash_sort_utf8, /* hash_sort */ - 0 + 0, + my_snprintf_8bit }; @@ -2345,6 +2346,94 @@ static int my_mbcharlen_ucs2(CHARSET_INFO *cs __attribute__((unused)) , } +#include +#include +#include + +static int my_vsnprintf_ucs2(char *dst, uint n, const char* fmt, va_list ap) +{ + char *start=dst, *end=dst+n-1; + for (; *fmt ; fmt++) + { + if (fmt[0] != '%') + { + if (dst == end) /* End of buffer */ + break; + + *dst++='\0'; *dst++= *fmt; /* Copy ordinary char */ + continue; + } + + fmt++; + + /* Skip if max size is used (to be compatible with printf) */ + while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-') + fmt++; + + if (*fmt == 'l') + fmt++; + + if (*fmt == 's') /* String parameter */ + { + reg2 char *par = va_arg(ap, char *); + uint plen; + uint left_len = (uint)(end-dst); + if (!par) par = (char*)"(null)"; + plen = (uint) strlen(par); + if (left_len <= plen*2) + plen = left_len/2 - 1; + dst=strnmov(dst,par,plen); + for ( ; plen ; plen--, dst++, par++) + { + dst[0]='\0'; + dst[1]=par[0]; + } + continue; + } + else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ + { + register int iarg; + char nbuf[16]; + char *pbuf=nbuf; + + if ((uint) (end-dst) < 32) + break; + iarg = va_arg(ap, int); + if (*fmt == 'd') + dst=int10_to_str((long) iarg, nbuf, -10); + else + dst=int10_to_str((long) (uint) iarg,nbuf,10); + + for (; pbuf[0]; pbuf++) + { + *dst++='\0'; + *dst++=*pbuf; + } + continue; + } + + /* We come here on '%%', unknown code or too long parameter */ + if (dst == end) + break; + *dst++='\0'; + *dst++='%'; /* % used as % or unknown code */ + } + + DBUG_ASSERT(dst <= end); + *dst='\0'; /* End of errmessage */ + return (uint) (dst - start); +} + +static int my_snprintf_ucs2(CHARSET_INFO *cs __attribute__((unused)) + ,char* to, uint n, const char* fmt, ...) +{ + va_list args; + va_start(args,fmt); + return my_vsnprintf_ucs2(to, n, fmt, args); +} + + + CHARSET_INFO my_charset_ucs2 = { 35, /* number */ @@ -2376,7 +2465,8 @@ CHARSET_INFO my_charset_ucs2 = my_strncasecmp_ucs2, my_hash_caseup_ucs2,/* hash_caseup */ my_hash_sort_ucs2, /* hash_sort */ - 0 + 0, + my_snprintf_ucs2 }; diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index f64eddd2c2b..64697ce08f3 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -651,7 +651,8 @@ CHARSET_INFO my_charset_win1250ch = my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }; diff --git a/strings/ctype.c b/strings/ctype.c index 1358fced15c..8fc189f4b7f 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -2838,7 +2838,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -2874,7 +2875,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -2909,7 +2911,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -2944,7 +2947,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -2980,7 +2984,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3015,7 +3020,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3050,7 +3056,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3085,7 +3092,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3121,7 +3129,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3156,7 +3165,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3191,7 +3201,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3226,7 +3237,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3261,7 +3273,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3296,7 +3309,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3331,7 +3345,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3367,7 +3382,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3402,7 +3418,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3438,7 +3455,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3474,7 +3492,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3509,7 +3528,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3544,7 +3564,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3579,7 +3600,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3614,7 +3636,8 @@ static CHARSET_INFO compiled_charsets[] = { my_strncasecmp_8bit, my_hash_caseup_simple, my_hash_sort_simple, - 0 + 0, + my_snprintf_8bit }, #endif @@ -3650,7 +3673,8 @@ static CHARSET_INFO compiled_charsets[] = { NULL, NULL, /* hash_caseup */ NULL, /* hash_sort */ - 0 + 0, + NULL } }; From 446a5b0ad584bca06a83f96acc15a2e085d93f75 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 10 Nov 2002 17:44:36 +0400 Subject: [PATCH 07/30] my_snprintf_ucs2 bug fix --- strings/ctype-utf8.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 707ca8f5c77..87a91f18e5f 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2382,7 +2382,7 @@ static int my_vsnprintf_ucs2(char *dst, uint n, const char* fmt, va_list ap) plen = (uint) strlen(par); if (left_len <= plen*2) plen = left_len/2 - 1; - dst=strnmov(dst,par,plen); + for ( ; plen ; plen--, dst++, par++) { dst[0]='\0'; @@ -2400,9 +2400,9 @@ static int my_vsnprintf_ucs2(char *dst, uint n, const char* fmt, va_list ap) break; iarg = va_arg(ap, int); if (*fmt == 'd') - dst=int10_to_str((long) iarg, nbuf, -10); + int10_to_str((long) iarg, nbuf, -10); else - dst=int10_to_str((long) (uint) iarg,nbuf,10); + int10_to_str((long) (uint) iarg,nbuf,10); for (; pbuf[0]; pbuf++) { From 828c0e9ac197f92d4b6d11aa58c312aef2c12c20 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 00:15:38 +0200 Subject: [PATCH 08/30] fix of yet another join_free bug decreased number of check of "!join->select_lex->dependent" mysql-test/r/subselect.result: test of yet another join_free bug mysql-test/t/subselect.test: test of yet another join_free bug --- mysql-test/r/subselect.result | 21 +++++++++++++++ mysql-test/t/subselect.test | 26 ++++++++++++++++++- sql/sql_select.cc | 48 +++++++++++++++++++++++------------ 3 files changed, 78 insertions(+), 17 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 5674bf3c473..4eaacfe66f7 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -220,3 +220,24 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBSELECT No tables used 3 UNION No tables used drop table searchconthardwarefr3; +drop table if exists forumconthardwarefr7, searchconthardwarefr7; +CREATE TABLE `forumconthardwarefr7` ( +`numeropost` mediumint(8) unsigned NOT NULL auto_increment, +`maxnumrep` int(10) unsigned NOT NULL default '0', +PRIMARY KEY (`numeropost`), +UNIQUE KEY `maxnumrep` (`maxnumrep`) +) TYPE=MyISAM ROW_FORMAT=FIXED; +INSERT INTO forumconthardwarefr7 (numeropost,maxnumrep) VALUES (40143,1),(43506,2); +CREATE TABLE `searchconthardwarefr7` ( +`mot` varchar(30) NOT NULL default '', +`topic` mediumint(8) unsigned NOT NULL default '0', +`date` date NOT NULL default '0000-00-00', +`pseudo` varchar(35) NOT NULL default '', +PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`) +) TYPE=MyISAM ROW_FORMAT=DYNAMIC; +INSERT INTO searchconthardwarefr7 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce'); +SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FROM searchconthardwarefr7 WHERE (mot='joce') AND date >= '2002-10-21' AND forumconthardwarefr7.numeropost = searchconthardwarefr7.topic) ORDER BY maxnumrep DESC LIMIT 0, 20; +numeropost maxnumrep +43506 2 +40143 1 +drop table forumconthardwarefr7, searchconthardwarefr7; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 841e98dd96c..12df155bc7f 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -114,4 +114,28 @@ SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL -- error 1240 SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1; EXPLAIN SELECT 1 FROM searchconthardwarefr3 WHERE 1=(SELECT 1 UNION SELECT 1); -drop table searchconthardwarefr3; \ No newline at end of file +drop table searchconthardwarefr3; + +drop table if exists forumconthardwarefr7, searchconthardwarefr7; +CREATE TABLE `forumconthardwarefr7` ( + `numeropost` mediumint(8) unsigned NOT NULL auto_increment, + `maxnumrep` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`numeropost`), + UNIQUE KEY `maxnumrep` (`maxnumrep`) +) TYPE=MyISAM ROW_FORMAT=FIXED; + +INSERT INTO forumconthardwarefr7 (numeropost,maxnumrep) VALUES (40143,1),(43506,2); + +CREATE TABLE `searchconthardwarefr7` ( + `mot` varchar(30) NOT NULL default '', + `topic` mediumint(8) unsigned NOT NULL default '0', + `date` date NOT NULL default '0000-00-00', + `pseudo` varchar(35) NOT NULL default '', + PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`) + ) TYPE=MyISAM ROW_FORMAT=DYNAMIC; + +INSERT INTO searchconthardwarefr7 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce'); + +SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FROM searchconthardwarefr7 WHERE (mot='joce') AND date >= '2002-10-21' AND forumconthardwarefr7.numeropost = searchconthardwarefr7.topic) ORDER BY maxnumrep DESC LIMIT 0, 20; + +drop table forumconthardwarefr7, searchconthardwarefr7; \ No newline at end of file diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 674caed0cd0..ecf06f0971a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2911,27 +2911,43 @@ join_free(JOIN *join) */ if (join->tables > join->const_tables) // Test for not-const tables free_io_cache(join->table[join->const_tables]); - for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) - { - delete tab->select; - delete tab->quick; - x_free(tab->cache.buff); - if (tab->table) + if (join->select_lex->dependent) + for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) { - if (tab->table->key_read) + if (tab->table) { - tab->table->key_read=0; - tab->table->file->extra(HA_EXTRA_NO_KEYREAD); + if (tab->table->key_read) + { + tab->table->key_read= 0; + tab->table->file->extra(HA_EXTRA_NO_KEYREAD); + } + /* Don't free index if we are using read_record */ + if (!tab->read_record.table) + tab->table->file->index_end(); } - /* Don't free index if we are using read_record */ - if (!tab->read_record.table) - tab->table->file->index_end(); } - end_read_record(&tab->read_record); + else + { + for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) + { + delete tab->select; + delete tab->quick; + x_free(tab->cache.buff); + if (tab->table) + { + if (tab->table->key_read) + { + tab->table->key_read= 0; + tab->table->file->extra(HA_EXTRA_NO_KEYREAD); + } + /* Don't free index if we are using read_record */ + if (!tab->read_record.table) + tab->table->file->index_end(); + } + end_read_record(&tab->read_record); + } + join->table= 0; } - //TODO: is enough join_free at the end of mysql_select? - if (!join->select_lex->dependent) - join->table=0; } /* We are not using tables anymore From 4832ebce861836db812dd2863ee134e53c44963b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 10:49:41 +0200 Subject: [PATCH 09/30] prevent using expernal fields in derived tables mysql-test/r/subselect.result: test of derived table external field bug mysql-test/t/subselect.test: test of derived table external field bug sql/sql_derived.cc: lex->current_select always should point on current SELECT_LEX_NODE during query execution --- mysql-test/r/subselect.result | 2 ++ mysql-test/t/subselect.test | 2 ++ sql/item.cc | 29 ++++++++++++++++++++--------- sql/sql_derived.cc | 6 +++++- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 4eaacfe66f7..0d3617b7512 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -240,4 +240,6 @@ SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FRO numeropost maxnumrep 43506 2 40143 1 +SELECT (SELECT 1) as a FROM (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); +Unknown column 'a' in 'having clause' drop table forumconthardwarefr7, searchconthardwarefr7; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 12df155bc7f..93ad115155e 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -137,5 +137,7 @@ CREATE TABLE `searchconthardwarefr7` ( INSERT INTO searchconthardwarefr7 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce'); SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FROM searchconthardwarefr7 WHERE (mot='joce') AND date >= '2002-10-21' AND forumconthardwarefr7.numeropost = searchconthardwarefr7.topic) ORDER BY maxnumrep DESC LIMIT 0, 20; +-- error 1054 +SELECT (SELECT 1) as a FROM (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); drop table forumconthardwarefr7, searchconthardwarefr7; \ No newline at end of file diff --git a/sql/item.cc b/sql/item.cc index 9c70dad045c..ea797679957 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -444,13 +444,16 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) cause error ER_NON_UNIQ_ERROR in find_field_in_tables. */ SELECT_LEX *last= 0; - for (SELECT_LEX *sl= thd->lex.current_select->outer_select(); - sl; - sl= sl->outer_select()) - if ((tmp= find_field_in_tables(thd, this, - (last= sl)->get_table_list(), - 0)) != not_found_field) - break; + + // Prevent using outer fields in subselects, that is not supported now + if (thd->lex.current_select->linkage != DERIVED_TABLE_TYPE) + for (SELECT_LEX *sl= thd->lex.current_select->outer_select(); + sl; + sl= sl->outer_select()) + if ((tmp= find_field_in_tables(thd, this, + (last= sl)->get_table_list(), + 0)) != not_found_field) + break; if (!tmp) return -1; else if (tmp == not_found_field) @@ -812,10 +815,18 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) if (!ref) { SELECT_LEX *sl= thd->lex.current_select->outer_select(); + /* + Finding only in current select will be performed for selects that have + not outer one and for derived tables (which not support using outer + fields for now) + */ if ((ref= find_item_in_list(this, *(thd->lex.current_select->get_item_list()), - (sl ? REPORT_EXCEPT_NOT_FOUND : - REPORT_ALL_ERRORS))) == + ((sl && + thd->lex.current_select->linkage != + DERIVED_TABLE_TYPE) ? + REPORT_EXCEPT_NOT_FOUND : + REPORT_ALL_ERRORS))) == (Item **)not_found_item) { /* diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 93627409d27..5dbbf39e7d4 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -94,13 +94,17 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) unit->select_limit_cnt= HA_POS_ERROR; if (unit->select_limit_cnt == HA_POS_ERROR) sl->options&= ~OPTION_FOUND_ROWS; - + + SELECT_LEX_NODE *save_current_select= lex->current_select; + lex->current_select= sl; res= mysql_select(thd, tables, sl->item_list, sl->where, (ORDER *) sl->order_list.first, (ORDER*) sl->group_list.first, sl->having, (ORDER*) NULL, sl->options | thd->options | SELECT_NO_UNLOCK, derived_result, unit, sl, 0); + lex->current_select= save_current_select; + if (!res) { // Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables From f4ba3d90584ba8debfbd00c651499f027726b30c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 13:10:39 +0400 Subject: [PATCH 10/30] For coding convenuence cs->mbmaxlen is now 1 for 8bit charsets --- mysys/charset.c | 1 + mysys/test_charset.c | 2 +- sql/item_strfunc.cc | 6 ++--- sql/sql_show.cc | 2 +- strings/ctype-bin.c | 2 +- strings/ctype-czech.c | 2 +- strings/ctype-latin1_de.c | 2 +- strings/ctype-tis620.c | 2 +- strings/ctype-win1250ch.c | 2 +- strings/ctype.c | 46 +++++++++++++++++++-------------------- 10 files changed, 34 insertions(+), 33 deletions(-) diff --git a/mysys/charset.c b/mysys/charset.c index 3ad4b4e8faa..2f22c616325 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -389,6 +389,7 @@ static CHARSET_INFO *add_charset(CHARSET_INFO *cs, myf flags) cs->hash_caseup = my_hash_caseup_simple; cs->hash_sort = my_hash_sort_simple; cs->snprintf = my_snprintf_8bit; + cs->mbmaxlen = 1; set_max_sort_char(cs); create_fromuni(cs); diff --git a/mysys/test_charset.c b/mysys/test_charset.c index 47ed9062c05..d031007a1da 100644 --- a/mysys/test_charset.c +++ b/mysys/test_charset.c @@ -46,7 +46,7 @@ static void _print_csinfo(CHARSET_INFO *cs) cs->strnxfrm, cs->like_range); printf("multi-byte: %3s (%d, %p, %p, %p)\n", - cs->mbmaxlen ? "yes" : "no", + cs->mbmaxlen > 1 ? "yes" : "no", cs->mbmaxlen, cs->ismbchar, cs->ismbhead, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6f121ecdc06..83b94ea145b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1928,7 +1928,7 @@ String *Item_func_conv_charset::val_str(String *str) s=(const uchar*)arg->ptr(); se=s+arg->length(); - dmaxlen=arg->length()*(to->mbmaxlen?to->mbmaxlen:1)+1; + dmaxlen=arg->length()*to->mbmaxlen+1; str->alloc(dmaxlen); d0=d=(unsigned char*)str->ptr(); de=d+dmaxlen; @@ -1970,7 +1970,7 @@ outp: void Item_func_conv_charset::fix_length_and_dec() { - max_length = args[0]->max_length*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1); + max_length = args[0]->max_length*conv_charset->mbmaxlen; set_charset(conv_charset); } @@ -2002,7 +2002,7 @@ String *Item_func_conv_charset3::val_str(String *str) s=(const uchar*)arg->ptr(); se=s+arg->length(); - dmaxlen=arg->length()*(to_charset->mbmaxlen?to_charset->mbmaxlen:1)+1; + dmaxlen=arg->length()*to_charset->mbmaxlen+1; str->alloc(dmaxlen); d0=d=(unsigned char*)str->ptr(); de=d+dmaxlen; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d6fe2f3772a..bd8abda5e87 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1424,7 +1424,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) net_store_data(&packet2,convert,cs[0]->name); net_store_data(&packet2,(uint32) cs[0]->number); net_store_data(&packet2,(uint32) cs[0]->strxfrm_multiply); - net_store_data(&packet2,(uint32) (cs[0]->mbmaxlen ? cs[0]->mbmaxlen : 1)); + net_store_data(&packet2,(uint32) (cs[0]->mbmaxlen)); if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length())) goto err; diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index e479053071b..9a22b3f36bf 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -162,7 +162,7 @@ static CHARSET_INFO my_charset_bin_st = my_strnncoll_binary, /* strnncoll */ NULL, /* strxnfrm */ NULL, /* like_rabge */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 6ce2bf13fce..3ec4491001d 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -610,7 +610,7 @@ CHARSET_INFO my_charset_czech = my_strnncoll_czech, my_strnxfrm_czech, my_like_range_czech, - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index 574fbf41da3..d829296fd78 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -428,7 +428,7 @@ CHARSET_INFO my_charset_latin1_de = my_strnncoll_latin1_de, my_strnxfrm_latin1_de, my_like_range_latin1_de, - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index de1a0e170fb..44d0dde65f5 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -702,7 +702,7 @@ CHARSET_INFO my_charset_tis620 = my_strnncoll_tis620, my_strnxfrm_tis620, my_like_range_tis620, - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 64697ce08f3..9c418e2e6f5 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -636,7 +636,7 @@ CHARSET_INFO my_charset_win1250ch = my_strnncoll_win1250ch, my_strnxfrm_win1250ch, my_like_range_win1250ch, - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ diff --git a/strings/ctype.c b/strings/ctype.c index 8fc189f4b7f..96003f8baab 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -2823,7 +2823,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -2860,7 +2860,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -2896,7 +2896,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -2932,7 +2932,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -2969,7 +2969,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3005,7 +3005,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3041,7 +3041,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3077,7 +3077,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3114,7 +3114,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3150,7 +3150,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3186,7 +3186,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3222,7 +3222,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3258,7 +3258,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3294,7 +3294,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3330,7 +3330,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3367,7 +3367,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3403,7 +3403,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3440,7 +3440,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3477,7 +3477,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3513,7 +3513,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3549,7 +3549,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3585,7 +3585,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ @@ -3621,7 +3621,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 0, /* mbmaxlen */ + 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ From 10ba987c5ef223aa0af384822082c3d233f6d970 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 13:34:47 +0400 Subject: [PATCH 11/30] fix for HEAP rb-tree indexes and BIG_TABLES problem (serg: thanks for discovery) --- include/my_tree.h | 2 +- mysys/tree.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/my_tree.h b/include/my_tree.h index 05e93df8593..99194907ef9 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -91,7 +91,7 @@ void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos, int child_offs); void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs, int r_offs); -uint tree_record_pos(TREE *tree, const void *key, +ha_rows tree_record_pos(TREE *tree, const void *key, enum ha_rkey_function search_flag, void *custom_arg); #ifdef __cplusplus } diff --git a/mysys/tree.c b/mysys/tree.c index f72a4961312..3e20820ebd9 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -439,14 +439,14 @@ void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs, Expected that tree is fully balanced (each path from root to leaf has the same length) */ -uint tree_record_pos(TREE *tree, const void *key, +ha_rows tree_record_pos(TREE *tree, const void *key, enum ha_rkey_function flag, void *custom_arg) { int cmp; TREE_ELEMENT *element= tree->root; double left= 1; double right= tree->elements_in_tree; - uint last_equal_pos= HA_POS_ERROR; + ha_rows last_equal_pos= HA_POS_ERROR; while (element != &tree->null_element) { From 20ea534d0c63f2e7fb230ed05d5469284335330e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 14:04:50 +0200 Subject: [PATCH 12/30] small bug fix --- sql/sql_derived.cc | 1 + sql/sql_parse.cc | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 93627409d27..a439131c61d 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -111,6 +111,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) t->real_name=table->real_name; t->table=table; table->derived_select_number= sl->select_number; + table->tmp_table=TMP_TABLE; if (!lex->describe) sl->exclude(); t->db= (tables && tables->db && tables->db[0]) ? t->db : thd->db; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4288773b00b..e30773984fb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1332,13 +1332,18 @@ mysql_execute_command(THD *thd) TODO: make derived tables processing 'inside' SELECT processing. TODO: solve problem with depended derived tables in subselects */ -if (lex->derived_tables) + if ((lex->select_lex.next_select_in_list() && + lex->unit.create_total_list(thd, lex, &tables)) || + (table_rules_on && tables && thd->slave_thread && + !tables_ok(thd,tables))) + DBUG_VOID_RETURN; + if (lex->derived_tables) { for (TABLE_LIST *cursor= tables; cursor; cursor= cursor->next) if (cursor->derived && (res=mysql_derived(thd, lex, - (SELECT_LEX_UNIT *)cursor->derived, + (SELECT_LEX_UNIT *)cursor->derived, cursor))) { if (res < 0) @@ -1346,11 +1351,6 @@ if (lex->derived_tables) DBUG_VOID_RETURN; } } - if ((lex->select_lex.next_select_in_list() && - lex->unit.create_total_list(thd, lex, &tables)) || - (table_rules_on && tables && thd->slave_thread && - !tables_ok(thd,tables))) - DBUG_VOID_RETURN; thread_safe_increment(com_stat[lex->sql_command],&LOCK_status); switch (lex->sql_command) { @@ -2717,6 +2717,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, TABLE_LIST *org_tables=tables; for (; tables ; tables=tables->next) { + if (tables->derived) + continue; if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) && thd->db) tables->grant.privilege= want_access; From 50b32edc76d476a812a14727ccdfece3f85c7c72 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 16:46:11 +0400 Subject: [PATCH 13/30] thread charset related improvements --- sql/sql_string.cc | 83 ++++++++++++++++++++++++++++++++++++++++++----- sql/sql_string.h | 1 + 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index f0f31004544..403e8d3b1f7 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -93,18 +93,36 @@ bool String::realloc(uint32 alloc_length) bool String::set(longlong num, CHARSET_INFO *cs) { - if (alloc(21)) + uint l=20*cs->mbmaxlen+1; + + if (alloc(l)) return TRUE; - str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr); + if (cs->snprintf == my_snprintf_8bit) + { + str_length=(uint32) (longlong10_to_str(num,Ptr,-10)-Ptr); + } + else + { + str_length=cs->snprintf(cs,Ptr,l,"%d",num); + } str_charset=cs; return FALSE; } bool String::set(ulonglong num, CHARSET_INFO *cs) { - if (alloc(21)) + uint l=20*cs->mbmaxlen+1; + + if (alloc(l)) return TRUE; - str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr); + if (cs->snprintf == my_snprintf_8bit) + { + str_length=(uint32) (longlong10_to_str(num,Ptr,10)-Ptr); + } + else + { + str_length=cs->snprintf(cs,Ptr,l,"%d",num); + } str_charset=cs; return FALSE; } @@ -117,14 +135,14 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) if (decimals >= NOT_FIXED_DEC) { sprintf(buff,"%.14g",num); // Enough for a DATETIME - return copy(buff, (uint32) strlen(buff), my_charset_latin1); + return copy(buff, (uint32) strlen(buff), my_charset_latin1, cs); } #ifdef HAVE_FCONVERT int decpt,sign; char *pos,*to; VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1)); - if (!my_isdigit(system_charset_info, buff[1])) + if (!my_isdigit(my_charset_latin1, buff[1])) { // Nan or Inf pos=buff+1; if (sign) @@ -132,7 +150,7 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) buff[0]='-'; pos=buff; } - return copy(pos,(uint32) strlen(pos)); + return copy(pos,(uint32) strlen(pos), my_charset_latin1, cs); } if (alloc((uint32) ((uint32) decpt+3+decimals))) return TRUE; @@ -182,7 +200,7 @@ end: #else sprintf(buff,"%.*f",(int) decimals,num); #endif - return copy(buff,(uint32) strlen(buff), my_charset_latin1); + return copy(buff,(uint32) strlen(buff), my_charset_latin1, cs); #endif } @@ -219,6 +237,55 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) return FALSE; } +/* Copy with charset convertion */ +bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *from, CHARSET_INFO *to) +{ + uint32 new_length=to->mbmaxlen*arg_length; + int cnvres; + my_wc_t wc; + const uchar *s=(const uchar *)str; + const uchar *se=s+arg_length; + uchar *d, *de; + + if (alloc(new_length)) + return TRUE; + + d=(uchar *)Ptr; + de=d+new_length; + + for (str_length=new_length ; s < se && d < de ; ) + { + if ((cnvres=from->mb_wc(from,&wc,s,se)) > 0 ) + { + s+=cnvres; + } + else if (cnvres==MY_CS_ILSEQ) + { + s++; + wc='?'; + } + else + break; + +outp: + if((cnvres=to->wc_mb(to,wc,d,de)) >0 ) + { + d+=cnvres; + } + else if (cnvres==MY_CS_ILUNI && wc!='?') + { + wc='?'; + goto outp; + } + else + break; + } + Ptr[new_length]=0; + length((uint32) (d-(uchar *)Ptr)); + str_charset=to; + return FALSE; +} + /* This is used by mysql.cc */ bool String::fill(uint32 max_length,char fill_char) diff --git a/sql/sql_string.h b/sql/sql_string.h index 4ac4308f113..d9dce95e0a2 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -179,6 +179,7 @@ public: bool copy(); // Alloc string if not alloced bool copy(const String &s); // Allocate new string bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string + bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, CHARSET_INFO *csto); bool append(const String &s); bool append(const char *s,uint32 arg_length=0); bool append(IO_CACHE* file, uint32 arg_length); From 84b95682cf6dd1444ebcf6de6521dd78877d5b18 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 18:43:33 +0400 Subject: [PATCH 14/30] USER(), DATABASE() and CHARSET() functions are now UCS2 compatible Bug fix in ctype-utf8.c sql/item_strfunc.cc: USER(), DATABASE() and CHARSET() functions are now UCS2 compatible sql/item_strfunc.h: USER(), DATABASE() and CHARSET() functions are now UCS2 compatible sql/procedure.h: USER(), DATABASE() and CHARSET() functions are now UCS2 compatible strings/ctype-utf8.c: Bug fix --- sql/item_strfunc.cc | 22 +++++++++++++++------- sql/item_strfunc.h | 15 ++++++++++++--- sql/procedure.h | 10 +++++----- strings/ctype-utf8.c | 2 +- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 83b94ea145b..1a561c9eb34 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1366,17 +1366,25 @@ String *Item_func_database::val_str(String *str) if (!current_thd->db) str->length(0); else - str->set((const char*) current_thd->db,(uint) strlen(current_thd->db), default_charset_info); + str->copy((const char*) current_thd->db,(uint) strlen(current_thd->db), system_charset_info, thd_charset()); return str; } String *Item_func_user::val_str(String *str) { - THD *thd=current_thd; - if (str->copy((const char*) thd->user,(uint) strlen(thd->user), system_charset_info) || - str->append('@') || - str->append(thd->host ? thd->host : thd->ip ? thd->ip : "")) - return &empty_string; + THD *thd=current_thd; + CHARSET_INFO *cs=thd_charset(); + const char *host=thd->host ? thd->host : thd->ip ? thd->ip : ""; + uint32 res_length=(strlen(thd->user)+strlen(host)+10) * cs->mbmaxlen; + + if (str->alloc(res_length)) + { + null_value=1; + return 0; + } + res_length=cs->snprintf(cs, (char*)str->ptr(), res_length, "%s@%s",thd->user,host); + str->length(res_length); + str->set_charset(cs); return str; } @@ -2120,7 +2128,7 @@ String *Item_func_charset::val_str(String *str) if ((null_value=(args[0]->null_value || !res->charset()))) return 0; - str->copy(res->charset()->name,strlen(res->charset()->name),default_charset_info); + str->copy(res->charset()->name,strlen(res->charset()->name),my_charset_latin1,thd_charset()); return str; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 14dadc96891..1a3193318b6 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -310,7 +310,11 @@ class Item_func_database :public Item_str_func public: Item_func_database() {} String *val_str(String *); - void fix_length_and_dec() { max_length= MAX_FIELD_NAME; } + void fix_length_and_dec() + { + max_length= MAX_FIELD_NAME * thd_charset()->mbmaxlen; + set_charset(thd_charset()); + } const char *func_name() const { return "database"; } }; @@ -319,7 +323,11 @@ class Item_func_user :public Item_str_func public: Item_func_user() {} String *val_str(String *); - void fix_length_and_dec() { max_length= USERNAME_LENGTH+HOSTNAME_LENGTH+1; } + void fix_length_and_dec() + { + max_length= (USERNAME_LENGTH+HOSTNAME_LENGTH+1)*thd_charset()->mbmaxlen; + set_charset(thd_charset()); + } const char *func_name() const { return "user"; } }; @@ -567,7 +575,8 @@ public: const char *func_name() const { return "charset"; } void fix_length_and_dec() { - max_length=20; // should be enough + max_length=40; // should be enough + set_charset(thd_charset()); }; }; diff --git a/sql/procedure.h b/sql/procedure.h index 3434079a8fb..c3280b951d3 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -62,7 +62,7 @@ public: { value=atof(str); } double val() { return value; } longlong val_int() { return (longlong) value; } - String *val_str(String *s) { s->set(value,decimals,my_thd_charset); return s; } + String *val_str(String *s) { s->set(value,decimals,thd_charset()); return s; } unsigned int size_of() { return sizeof(*this);} }; @@ -80,7 +80,7 @@ public: { value=strtoll(str,NULL,10); } double val() { return (double) value; } longlong val_int() { return value; } - String *val_str(String *s) { s->set(value, my_thd_charset); return s; } + String *val_str(String *s) { s->set(value, thd_charset()); return s; } unsigned int size_of() { return sizeof(*this);} }; @@ -92,9 +92,9 @@ public: { this->max_length=length; } enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return FIELD_TYPE_STRING; } - void set(double nr) { str_value.set(nr, 2, my_thd_charset); } - void set(longlong nr) { str_value.set(nr, my_thd_charset); } - void set(const char *str, uint length) { str_value.copy(str,length, my_thd_charset); } + void set(double nr) { str_value.set(nr, 2, thd_charset()); } + void set(longlong nr) { str_value.set(nr, thd_charset()); } + void set(const char *str, uint length) { str_value.copy(str,length, thd_charset()); } double val() { return atof(str_value.ptr()); } longlong val_int() { return strtoll(str_value.ptr(),NULL,10); } String *val_str(String*) diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 87a91f18e5f..e4afa4a0cee 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2383,7 +2383,7 @@ static int my_vsnprintf_ucs2(char *dst, uint n, const char* fmt, va_list ap) if (left_len <= plen*2) plen = left_len/2 - 1; - for ( ; plen ; plen--, dst++, par++) + for ( ; plen ; plen--, dst+=2, par++) { dst[0]='\0'; dst[1]=par[0]; From b7d3c9ca6bbbf184fc0478ac44e26a87f904d60f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 17:28:58 +0200 Subject: [PATCH 15/30] fixed select_lex & max_join_size parameters with BIG_TABLES sql/set_var.h: new constaructor --- sql/mysqld.cc | 6 +++--- sql/set_var.cc | 10 +++++----- sql/set_var.h | 4 ++++ sql/sql_class.h | 4 ++-- sql/sql_parse.cc | 13 +++++++------ 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c57e0fc38d1..10766db57c1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3892,10 +3892,10 @@ static void set_options(void) /* Set default values for some variables */ global_system_variables.table_type=DB_TYPE_MYISAM; global_system_variables.tx_isolation=ISO_READ_COMMITTED; - global_system_variables.select_limit= (ulong) HA_POS_ERROR; + global_system_variables.select_limit= (ulonglong) HA_POS_ERROR; max_system_variables.select_limit= (ulong) HA_POS_ERROR; - global_system_variables.max_join_size= (ulong) HA_POS_ERROR; - max_system_variables.max_join_size= (ulong) HA_POS_ERROR; + global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; + max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; #ifdef __WIN__ /* Allow Win32 users to move MySQL anywhere */ diff --git a/sql/set_var.cc b/sql/set_var.cc index 72579664a3e..937bc600d81 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -154,11 +154,11 @@ sys_var_thd_ulong sys_max_error_count("max_error_count", &SV::max_error_count); sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size", &SV::max_heap_table_size); -sys_var_thd_ulong sys_max_join_size("max_join_size", +sys_var_thd_ulonglong sys_max_join_size("max_join_size", &SV::max_join_size, fix_max_join_size); #ifndef TO_BE_DELETED /* Alias for max_join_size */ -sys_var_thd_ulong sys_sql_max_join_size("sql_max_join_size", +sys_var_thd_ulonglong sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, fix_max_join_size); #endif @@ -282,7 +282,7 @@ static sys_var_thd_bit sys_unique_checks("unique_checks", /* Local state variables */ -static sys_var_thd_ulong sys_select_limit("sql_select_limit", +static sys_var_thd_ulonglong sys_select_limit("sql_select_limit", &SV::select_limit); static sys_var_timestamp sys_timestamp("timestamp"); static sys_var_last_insert_id sys_last_insert_id("last_insert_id"); @@ -594,7 +594,7 @@ static void fix_max_join_size(THD *thd, enum_var_type type) { if (type != OPT_GLOBAL) { - if (thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if (thd->variables.max_join_size == (ulonglong) HA_POS_ERROR) thd->options|= OPTION_BIG_SELECTS; else thd->options&= ~OPTION_BIG_SELECTS; @@ -769,7 +769,7 @@ bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) - global_system_variables.*offset= (ulong) option_limits->def_value; + global_system_variables.*offset= (ulonglong) option_limits->def_value; else thd->variables.*offset= global_system_variables.*offset; } diff --git a/sql/set_var.h b/sql/set_var.h index 31154d1e1d7..62fa977eb06 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -203,6 +203,10 @@ public: sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg) :sys_var_thd(name_arg), offset(offset_arg) {} + sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg, + sys_after_update_func func) + :sys_var_thd(name_arg,func), offset(offset_arg) + {} bool update(THD *thd, set_var *var); void set_default(THD *thd, enum_var_type type); SHOW_TYPE type() { return SHOW_LONGLONG; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 71f1625309f..08066e83ee7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -341,13 +341,14 @@ struct system_variables { ulonglong myisam_max_extra_sort_file_size; ulonglong myisam_max_sort_file_size; + ulonglong select_limit; + ulonglong max_join_size; ulong bulk_insert_buff_size; ulong join_buff_size; ulong long_query_time; ulong max_allowed_packet; ulong max_error_count; ulong max_heap_table_size; - ulong max_join_size; ulong max_prep_stmt_count; ulong max_sort_length; ulong max_tmp_tables; @@ -361,7 +362,6 @@ struct system_variables ulong query_cache_type; ulong read_buff_size; ulong read_rnd_buff_size; - ulong select_limit; ulong sortbuff_size; ulong table_type; ulong tmp_table_size; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4288773b00b..4069fa83b01 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -660,7 +660,7 @@ pthread_handler_decl(handle_one_connection,arg) goto end_thread; } - if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if ((ulong) thd->variables.max_join_size == (ulonglong) HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; if (thd->client_capabilities & CLIENT_COMPRESS) net->compress=1; // Use compression @@ -736,7 +736,7 @@ pthread_handler_decl(handle_bootstrap,arg) #endif - if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR) + if ((ulong) thd->variables.max_join_size == (ulonglong) HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; thd->proc_info=0; @@ -1373,10 +1373,11 @@ if (lex->derived_tables) break; // Error message is given } - unit->offset_limit_cnt= unit->global_parameters->offset_limit; - unit->select_limit_cnt= unit->global_parameters->select_limit+ - unit->global_parameters->offset_limit; - if (unit->select_limit_cnt < unit->global_parameters->select_limit) + unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit; + unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+ + unit->global_parameters->offset_limit); + if (unit->select_limit_cnt < + (ha_rows) unit->global_parameters->select_limit) unit->select_limit_cnt= HA_POS_ERROR; // no limit if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; From 736e3c3c17a251af2732ca63cd9688398f99e414 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 17:45:23 +0200 Subject: [PATCH 16/30] some bug fixes related to derived tables --- mysql-test/r/derived.result | 13 +++++++++++++ mysql-test/t/derived.test | 10 ++++++++++ sql/sql_base.cc | 4 +++- sql/sql_parse.cc | 10 +++++----- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index d3fbd557156..b99664835a2 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -17,6 +17,19 @@ select t1.a,t4.y from t1,(select t2.a as y from t2,(select t3.b from t3 where t3 a y 3 3 3 3 +SELECT a FROM (SELECT 1 FROM (SELECT 1) HAVING a=1); +Unknown column 'a' in 'having clause' +SELECT a,b as a FROM (SELECT '1' as a,'2' as b) HAVING a=1; +Column: 'a' in having clause is ambiguous +SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=2; +a a +1 2 +SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=1; +a a +SELECT 1 FROM (SELECT 1) WHERE a=2; +Unknown column 'a' in 'where clause' +SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1); +Unknown column 'a' in 'having clause' drop table if exists t1.t2,t3; select * from (select 1); 1 diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 87910c29706..6f32cfa0390 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -8,6 +8,16 @@ select t1.a,t3.a from t1,(select * from t2 where b='c') as t3 where t1.a = t3. CREATE TABLE t3 (a int not null, b char (10) not null); insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c'); select t1.a,t4.y from t1,(select t2.a as y from t2,(select t3.b from t3 where t3.a>3) as t5 where t2.b=t5.b) as t4 where t1.a = t4.y; +--error 1054 +SELECT a FROM (SELECT 1 FROM (SELECT 1) HAVING a=1); +--error 1052 +SELECT a,b as a FROM (SELECT '1' as a,'2' as b) HAVING a=1; +SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=2; +SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=1; +--error 1054 +SELECT 1 FROM (SELECT 1) WHERE a=2; +--error 1054 +SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1); drop table if exists t1.t2,t3; select * from (select 1); select a from (select 1 as a); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 77253d49ed0..fd6c2c48020 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1748,7 +1748,9 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, } else { - Field **ptr=table->field; + Field **ptr; + if (!(ptr=table->field)) + return (Field *)0; while ((field = *ptr++)) { if (!my_strcasecmp(system_charset_info, field->field_name, name)) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e30773984fb..758c2c405e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1332,11 +1332,6 @@ mysql_execute_command(THD *thd) TODO: make derived tables processing 'inside' SELECT processing. TODO: solve problem with depended derived tables in subselects */ - if ((lex->select_lex.next_select_in_list() && - lex->unit.create_total_list(thd, lex, &tables)) || - (table_rules_on && tables && thd->slave_thread && - !tables_ok(thd,tables))) - DBUG_VOID_RETURN; if (lex->derived_tables) { for (TABLE_LIST *cursor= tables; @@ -1351,6 +1346,11 @@ mysql_execute_command(THD *thd) DBUG_VOID_RETURN; } } + if ((lex->select_lex.next_select_in_list() && + lex->unit.create_total_list(thd, lex, &tables)) || + (table_rules_on && tables && thd->slave_thread && + !tables_ok(thd,tables))) + DBUG_VOID_RETURN; thread_safe_increment(com_stat[lex->sql_command],&LOCK_status); switch (lex->sql_command) { From f6f23ce8d0c698d241b1ca88c5df0168d750399a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2002 14:58:59 +0400 Subject: [PATCH 17/30] MONTHNAME() & DAYNAME() are now UCS2 compatible --- sql/item_timefunc.cc | 12 +++++++++--- sql/item_timefunc.h | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 8a1bd0be291..b208713eea0 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -153,14 +153,17 @@ longlong Item_func_month::val_int() String* Item_func_monthname::val_str(String* str) { - uint month=(uint) Item_func_month::val_int(); + uint month=(uint) Item_func_month::val_int(); if (!month) // This is also true for NULL { null_value=1; return (String*) 0; } null_value=0; - return &month_names[month-1]; + + String *m=&month_names[month-1]; + str->copy(m->ptr(), m->length(), m->charset(), thd_charset()); + return str; } // Returns the quarter of the year @@ -234,7 +237,10 @@ String* Item_func_dayname::val_str(String* str) uint weekday=(uint) val_int(); // Always Item_func_daynr() if (null_value) return (String*) 0; - return &day_names[weekday]; + + String *d=&day_names[weekday]; + str->copy(d->ptr(), d->length(), d->charset(), thd_charset()); + return str; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index de2860d24ef..c3dc9bfb6d4 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -85,7 +85,12 @@ public: const char *func_name() const { return "monthname"; } String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } - void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=10*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -192,7 +197,12 @@ class Item_func_dayname :public Item_func_weekday const char *func_name() const { return "dayname"; } String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } - void fix_length_and_dec() { decimals=0; max_length=9; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=9*thd_charset()->mbmaxlen; + maybe_null=1; + } }; From a70a9ab6377df20d03107661c658ea5a48822969 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2002 14:40:32 +0200 Subject: [PATCH 18/30] some code cleanup as per CTO's instructions plus a small bug fix with a corresponding test case.... --- mysql-test/r/derived.result | 3 +++ mysql-test/t/derived.test | 1 + sql/sql_derived.cc | 2 +- sql/sql_parse.cc | 4 ++-- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index b99664835a2..0290d0755d5 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -37,3 +37,6 @@ select * from (select 1); select a from (select 1 as a); a 1 +select 1 from (select 1); +1 +1 diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 6f32cfa0390..501d4db26fa 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -21,3 +21,4 @@ SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1); drop table if exists t1.t2,t3; select * from (select 1); select a from (select 1 as a); +select 1 from (select 1); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index b4de767189e..7cbc1ea6db3 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -118,7 +118,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) table->tmp_table=TMP_TABLE; if (!lex->describe) sl->exclude(); - t->db= (tables && tables->db && tables->db[0]) ? t->db : thd->db; + t->db=""; t->derived=(SELECT_LEX *)0; // just in case ... } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 758c2c405e6..f16bc63636f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2717,7 +2717,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, TABLE_LIST *org_tables=tables; for (; tables ; tables=tables->next) { - if (tables->derived) + if (tables->derived || (tables->table && (int)tables->table->tmp_table)) continue; if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) && thd->db) @@ -2735,7 +2735,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, found=1; } } - else if (tables->db && check_access(thd,want_access,tables->db,&tables->grant.privilege, + else if (check_access(thd,want_access,tables->db,&tables->grant.privilege, 0, no_errors)) return TRUE; } From f779dba31c434b42afeef16a1ad5829227fded56 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2002 15:25:09 +0200 Subject: [PATCH 19/30] fixed 2 typo in BUG_TABLES using remuved 'unstable' variable from test include/myisampack.h: fixed 2 typo mysql-test/r/variables.result: remuved 'unstable' variable mysql-test/t/variables.test: remuved 'unstable' variable --- include/myisampack.h | 4 ++-- mysql-test/r/variables.result | 5 +---- mysql-test/t/variables.test | 3 ++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/myisampack.h b/include/myisampack.h index 31666bb184c..51c9876c246 100644 --- a/include/myisampack.h +++ b/include/myisampack.h @@ -212,9 +212,9 @@ /* Fix to avoid warnings when sizeof(ha_rows) == sizeof(long) */ -#ifdef BIG_TABLE +#ifdef BIG_TABLES #define mi_rowstore(T,A) mi_int8store(T,A) -#define mi_rowkorr(T,A) mi_uint8korr(T) +#define mi_rowkorr(T) mi_uint8korr(T) #else #define mi_rowstore(T,A) { mi_int4store(T,0); mi_int4store(((T)+4),A); } #define mi_rowkorr(T) mi_uint4korr((T)+4) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index f708ddd2ee7..03454f101d4 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -48,9 +48,6 @@ set max_join_size=100; show variables like 'max_join_size'; Variable_name Value max_join_size 100 -show global variables like 'max_join_size'; -Variable_name Value -max_join_size 4294967295 set GLOBAL max_join_size=2000; show global variables like 'max_join_size'; Variable_name Value @@ -62,7 +59,7 @@ max_join_size 2000 set GLOBAL max_join_size=DEFAULT; show global variables like 'max_join_size'; Variable_name Value -max_join_size 4294967295 +max_join_size 18446744073709551615 set @@max_join_size=1000, @@global.max_join_size=2000; select @@local.max_join_size, @@global.max_join_size; @@session.max_join_size @@global.max_join_size diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 7a1d01c2cb5..564a6b864e8 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -34,7 +34,8 @@ drop table t1; set max_join_size=100; show variables like 'max_join_size'; -show global variables like 'max_join_size'; +# Removed, because it has different value with/without BIG_TABLES +#show global variables like 'max_join_size'; set GLOBAL max_join_size=2000; show global variables like 'max_join_size'; set max_join_size=DEFAULT; From e6eaecbfb7173ec6e5b767a8e5e5f4cd6b4002e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2002 17:32:36 +0400 Subject: [PATCH 20/30] These functions are now UCS2 compatible: CURDATE() FROM_DAYS() CURTIME() NOW() SEC_TO_TIME() FROM_UNIXTIME() DATE_ADD_INTERVAL() --- sql/item_timefunc.cc | 82 ++++++++++++++++------- sql/item_timefunc.h | 151 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 181 insertions(+), 52 deletions(-) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index b208713eea0..cec83428e24 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -402,16 +402,16 @@ String *Item_date::val_str(String *str) return (String*) 0; if (!value) // zero daynr { - str->copy("0000-00-00",10,my_charset_latin1); + str->copy("0000-00-00",10,my_charset_latin1,thd_charset()); return str; } - if (str->alloc(11)) - return &empty_string; /* purecov: inspected */ - sprintf((char*) str->ptr(),"%04d-%02d-%02d", + + char tmpbuff[11]; + sprintf(tmpbuff,"%04d-%02d-%02d", (int) (value/10000L) % 10000, (int) (value/100)%100, (int) (value%100)); - str->length(10); + str->copy(tmpbuff,10,my_charset_latin1,thd_charset()); return str; } @@ -448,7 +448,10 @@ void Item_func_curdate::fix_length_and_dec() { struct tm tm_tmp,*start; time_t query_start=current_thd->query_start(); - decimals=0; max_length=10; + + set_charset(thd_charset()); + decimals=0; + max_length=10*thd_charset()->mbmaxlen; localtime_r(&query_start,&tm_tmp); start=&tm_tmp; value=(longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+ @@ -473,27 +476,48 @@ bool Item_func_curdate::get_date(TIME *res, return 0; } +String *Item_func_curtime::val_str(String *str) +{ + str_value.set(buff,buff_length,thd_charset()); + return &str_value; +} + void Item_func_curtime::fix_length_and_dec() { struct tm tm_tmp,*start; time_t query_start=current_thd->query_start(); - decimals=0; max_length=8; + CHARSET_INFO *cs=thd_charset(); + + decimals=0; + max_length=8*cs->mbmaxlen; localtime_r(&query_start,&tm_tmp); start=&tm_tmp; + set_charset(cs); value=(longlong) ((ulong) ((uint) start->tm_hour)*10000L+ (ulong) (((uint) start->tm_min)*100L+ (uint) start->tm_sec)); - buff_length= my_sprintf(buff, (buff,"%02d:%02d:%02d", + + buff_length=cs->snprintf(cs,buff,sizeof(buff),"%02d:%02d:%02d", (int) start->tm_hour, (int) start->tm_min, - (int) start->tm_sec)); + (int) start->tm_sec); +} + +String *Item_func_now::val_str(String *str) +{ + str_value.set(buff,buff_length,thd_charset()); + return &str_value; } void Item_func_now::fix_length_and_dec() { struct tm tm_tmp,*start; time_t query_start=current_thd->query_start(); - decimals=0; max_length=19; + CHARSET_INFO *cs=thd_charset(); + + decimals=0; + max_length=19*cs->mbmaxlen; + set_charset(cs); localtime_r(&query_start,&tm_tmp); start=&tm_tmp; value=((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+ @@ -502,13 +526,14 @@ void Item_func_now::fix_length_and_dec() (longlong) ((ulong) ((uint) start->tm_hour)*10000L+ (ulong) (((uint) start->tm_min)*100L+ (uint) start->tm_sec))); - buff_length= (uint) my_sprintf(buff, (buff,"%04d-%02d-%02d %02d:%02d:%02d", + + buff_length= (uint) cs->snprintf(cs,buff, sizeof(buff),"%04d-%02d-%02d %02d:%02d:%02d", ((int) (start->tm_year+1900)) % 10000, (int) start->tm_mon+1, (int) start->tm_mday, (int) start->tm_hour, (int) start->tm_min, - (int) start->tm_sec)); + (int) start->tm_sec); /* For getdate */ ltime.year= start->tm_year+1900; ltime.month= start->tm_mon+1; @@ -539,7 +564,7 @@ int Item_func_now::save_in_field(Field *to) String *Item_func_sec_to_time::val_str(String *str) { - char buff[23]; + char buff[23*2]; const char *sign=""; longlong seconds=(longlong) args[0]->val_int(); ulong length; @@ -553,7 +578,7 @@ String *Item_func_sec_to_time::val_str(String *str) uint sec= (uint) ((ulonglong) seconds % 3600); length= my_sprintf(buff,(buff,"%s%02lu:%02u:%02u",sign,(long) (seconds/3600), sec/60, sec % 60)); - str->copy(buff, length, my_charset_latin1); + str->copy(buff, length, my_charset_latin1, thd_charset()); return str; } @@ -897,20 +922,26 @@ String *Item_func_from_unixtime::val_str(String *str) { struct tm tm_tmp,*start; time_t tmp=(time_t) args[0]->val_int(); + uint32 l; + CHARSET_INFO *cs=thd_charset(); + if ((null_value=args[0]->null_value)) return 0; localtime_r(&tmp,&tm_tmp); start=&tm_tmp; - if (str->alloc(20)) + + l=20*cs->mbmaxlen+32; + if (str->alloc(l)) return str; /* purecov: inspected */ - sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d", + l=cs->snprintf(cs,(char*) str->ptr(),l,"%04d-%02d-%02d %02d:%02d:%02d", (int) start->tm_year+1900, (int) start->tm_mon+1, (int) start->tm_mday, (int) start->tm_hour, (int) start->tm_min, (int) start->tm_sec); - str->length(19); + str->length(l); + str->set_charset(cs); return str; } @@ -1041,26 +1072,31 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) String *Item_date_add_interval::val_str(String *str) { TIME ltime; + CHARSET_INFO *cs=thd_charset(); + uint32 l; if (Item_date_add_interval::get_date(<ime,0)) return 0; if (ltime.time_type == TIMESTAMP_DATE) { - if (str->alloc(11)) + l=11*cs->mbmaxlen+32; + if (str->alloc(l)) goto null_date; - sprintf((char*) str->ptr(),"%04d-%02d-%02d", + l=cs->snprintf(cs,(char*) str->ptr(),l,"%04d-%02d-%02d", ltime.year,ltime.month,ltime.day); - str->length(10); + str->length(l); } else { - if (str->alloc(20)) + l=20*cs->mbmaxlen+32; + if (str->alloc(l)) goto null_date; - sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d", + l=cs->snprintf(cs,(char*) str->ptr(),l,"%04d-%02d-%02d %02d:%02d:%02d", ltime.year,ltime.month,ltime.day, ltime.hour,ltime.minute,ltime.second); - str->length(19); + str->length(l); } + str->set_charset(cs); return str; null_date: diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index c3dc9bfb6d4..07cdfde115b 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -27,7 +27,10 @@ public: Item_func_period_add(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "period_add"; } - void fix_length_and_dec() { max_length=6; } + void fix_length_and_dec() + { + max_length=6*thd_charset()->mbmaxlen; + } }; @@ -37,7 +40,11 @@ public: Item_func_period_diff(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "period_diff"; } - void fix_length_and_dec() { decimals=0; max_length=6; } + void fix_length_and_dec() + { + decimals=0; + max_length=6*thd_charset()->mbmaxlen; + } }; @@ -47,7 +54,12 @@ public: Item_func_to_days(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "to_days"; } - void fix_length_and_dec() { decimals=0; max_length=6; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=6*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -57,7 +69,12 @@ public: Item_func_dayofmonth(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "dayofmonth"; } - void fix_length_and_dec() { decimals=0; max_length=2; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=2*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -74,7 +91,13 @@ public: } const char *func_name() const { return "month"; } enum Item_result result_type () const { return INT_RESULT; } - void fix_length_and_dec() { decimals=0; max_length=2; maybe_null=1; } + void fix_length_and_dec() + { + set_charset(thd_charset()); + decimals=0; + max_length=2*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -86,8 +109,9 @@ public: String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() - { - decimals=0; + { + set_charset(thd_charset()); + decimals=0; max_length=10*thd_charset()->mbmaxlen; maybe_null=1; } @@ -100,7 +124,12 @@ public: Item_func_dayofyear(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "dayofyear"; } - void fix_length_and_dec() { decimals=0; max_length=3; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=3*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -110,7 +139,12 @@ public: Item_func_hour(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "hour"; } - void fix_length_and_dec() { decimals=0; max_length=2; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=2*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -120,7 +154,12 @@ public: Item_func_minute(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "minute"; } - void fix_length_and_dec() { decimals=0; max_length=2; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=2*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -130,7 +169,12 @@ public: Item_func_quarter(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "quarter"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=1*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -140,7 +184,12 @@ public: Item_func_second(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "second"; } - void fix_length_and_dec() { decimals=0; max_length=2; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=2*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -150,7 +199,12 @@ public: Item_func_week(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "week"; } - void fix_length_and_dec() { decimals=0; max_length=2; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=2*thd_charset()->mbmaxlen; + maybe_null=1; + } }; class Item_func_yearweek :public Item_int_func @@ -159,7 +213,12 @@ public: Item_func_yearweek(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "yearweek"; } - void fix_length_and_dec() { decimals=0; max_length=6; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=6*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -169,7 +228,12 @@ public: Item_func_year(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "year"; } - void fix_length_and_dec() { decimals=0; max_length=4; maybe_null=1; } + void fix_length_and_dec() + { + decimals=0; + max_length=4*thd_charset()->mbmaxlen; + maybe_null=1; + } }; @@ -181,13 +245,20 @@ public: :Item_func(a), odbc_type(type_arg) {} longlong val_int(); double val() { return (double) val_int(); } - String *val_str(String *str) { + String *val_str(String *str) + { str->set(val_int(), thd_charset()); return null_value ? 0 : str; } const char *func_name() const { return "weekday"; } enum Item_result result_type () const { return INT_RESULT; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1; } + void fix_length_and_dec() + { + set_charset(thd_charset()); + decimals=0; + max_length=1*thd_charset()->mbmaxlen; + maybe_null=1; + } }; class Item_func_dayname :public Item_func_weekday @@ -199,6 +270,7 @@ class Item_func_dayname :public Item_func_weekday enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { + set_charset(thd_charset()); decimals=0; max_length=9*thd_charset()->mbmaxlen; maybe_null=1; @@ -216,7 +288,8 @@ public: const char *func_name() const { return "timestamp"; } void fix_length_and_dec() { - decimals=0; max_length=10; + decimals=0; + max_length=10*thd_charset()->mbmaxlen; } }; @@ -229,7 +302,8 @@ public: const char *func_name() const { return "time_to_sec"; } void fix_length_and_dec() { - decimals=0; max_length=10; + decimals=0; + max_length=10*thd_charset()->mbmaxlen; } }; @@ -245,7 +319,12 @@ public: String *val_str(String *str); double val() { return (double) val_int(); } const char *func_name() const { return "date"; } - void fix_length_and_dec() { decimals=0; max_length=10; } + void fix_length_and_dec() + { + set_charset(thd_charset()); + decimals=0; + max_length=10*thd_charset()->mbmaxlen; + } int save_in_field(Field *to); void make_field(Send_field *tmp_field) { @@ -279,7 +358,7 @@ public: class Item_func_curtime :public Item_func { longlong value; - char buff[9]; + char buff[9*2+32]; uint buff_length; public: Item_func_curtime() :Item_func() {} @@ -287,8 +366,7 @@ public: enum Item_result result_type () const { return STRING_RESULT; } double val() { return (double) value; } longlong val_int() { return value; } - String *val_str(String *str) - { str_value.set(buff,buff_length,default_charset_info); return &str_value; } + String *val_str(String *str); const char *func_name() const { return "curtime"; } void fix_length_and_dec(); void make_field(Send_field *tmp_field) @@ -319,7 +397,7 @@ public: class Item_func_now :public Item_date_func { longlong value; - char buff[20]; + char buff[20*2+32]; // +32 to make my_snprintf_{8bit|ucs2} happy uint buff_length; TIME ltime; public: @@ -329,8 +407,7 @@ public: double val() { return (double) value; } longlong val_int() { return value; } int save_in_field(Field *to); - String *val_str(String *str) - { str_value.set(buff,buff_length,default_charset_info); return &str_value; } + String *val_str(String *str); const char *func_name() const { return "now"; } void fix_length_and_dec(); bool get_date(TIME *res,bool fuzzy_date); @@ -369,7 +446,12 @@ class Item_func_from_unixtime :public Item_date_func longlong val_int(); String *val_str(String *str); const char *func_name() const { return "from_unixtime"; } - void fix_length_and_dec() { decimals=0; max_length=19; } + void fix_length_and_dec() + { + set_charset(thd_charset()); + decimals=0; + max_length=19*thd_charset()->mbmaxlen; + } // enum Item_result result_type () const { return STRING_RESULT; } bool get_date(TIME *res,bool fuzzy_date); }; @@ -382,7 +464,12 @@ public: double val() { return (double) Item_func_sec_to_time::val_int(); } longlong val_int(); String *val_str(String *); - void fix_length_and_dec() { maybe_null=1; max_length=13; } + void fix_length_and_dec() + { + set_charset(thd_charset()); + maybe_null=1; + max_length=13*thd_charset()->mbmaxlen; + } const char *func_name() const { return "sec_to_time"; } void make_field(Send_field *tmp_field) { @@ -414,7 +501,13 @@ public: :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {} String *val_str(String *); const char *func_name() const { return "date_add_interval"; } - void fix_length_and_dec() { maybe_null=1; max_length=19; value.alloc(32);} + void fix_length_and_dec() + { + set_charset(thd_charset()); + maybe_null=1; + max_length=19*thd_charset()->mbmaxlen; + value.alloc(32); + } double val() { return (double) val_int(); } longlong val_int(); bool get_date(TIME *res,bool fuzzy_date); From ccf7226c2759bf6549c2cdd615ef55e95318520b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2002 19:21:11 +0400 Subject: [PATCH 21/30] bdb-deadlock test: added reap commands --- mysql-test/r/bdb-deadlock.result | 8 ++++---- mysql-test/t/bdb-deadlock.test | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/bdb-deadlock.result b/mysql-test/r/bdb-deadlock.result index 74798a34a53..55b3d3ea2a5 100644 --- a/mysql-test/r/bdb-deadlock.result +++ b/mysql-test/r/bdb-deadlock.result @@ -9,23 +9,23 @@ set autocommit=0; update t2 set x = 1 where id = 0; select x from t1 where id = 0; select x from t2 where id = 0; -commit; Deadlock found when trying to get lock; Try restarting transaction commit; x 1 +commit; select * from t1; +id x +0 1 select * from t2; id x 0 1 commit; +select * from t1; id x 0 1 -select * from t1; select * from t2; id x 0 1 commit; -id x -0 1 drop table t1,t2; diff --git a/mysql-test/t/bdb-deadlock.test b/mysql-test/t/bdb-deadlock.test index 27fcb5c6149..5ecfe592ce4 100644 --- a/mysql-test/t/bdb-deadlock.test +++ b/mysql-test/t/bdb-deadlock.test @@ -35,9 +35,11 @@ select x from t2 where id = 0; connection con2; --error 1213 +reap; commit; connection con1; +reap; commit; connection con2; From 2707f00cdba45e7112f03acb264ad3e7460df0ed Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2002 01:14:39 +0200 Subject: [PATCH 22/30] fixed error handling fixed subselects in ORDER bug mysql-test/r/subselect.result: test of subselects in ORDER clause test of error handling bug mysql-test/t/subselect.test: test of subselects in ORDER clause test of error handling bug sql/item_subselect.cc: fixed subselects in ORDER bug sql/item_subselect.h: fixed subselects in ORDER bug sql/sql_select.cc: fixed error handling --- mysql-test/r/subselect.result | 14 ++++++++++++++ mysql-test/t/subselect.test | 16 ++++++++++++++-- sql/item_subselect.cc | 2 +- sql/item_subselect.h | 3 ++- sql/sql_select.cc | 2 +- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 0d3617b7512..77499625bcd 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -236,6 +236,9 @@ CREATE TABLE `searchconthardwarefr7` ( PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`) ) TYPE=MyISAM ROW_FORMAT=DYNAMIC; INSERT INTO searchconthardwarefr7 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce'); +select numeropost as a FROM forumconthardwarefr7 GROUP BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); +a +40143 SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FROM searchconthardwarefr7 WHERE (mot='joce') AND date >= '2002-10-21' AND forumconthardwarefr7.numeropost = searchconthardwarefr7.topic) ORDER BY maxnumrep DESC LIMIT 0, 20; numeropost maxnumrep 43506 2 @@ -243,3 +246,14 @@ numeropost maxnumrep SELECT (SELECT 1) as a FROM (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); Unknown column 'a' in 'having clause' drop table forumconthardwarefr7, searchconthardwarefr7; +drop table if exists forumconthardwarefr7; +CREATE TABLE `forumconthardwarefr7` ( +`numeropost` mediumint(8) unsigned NOT NULL auto_increment, +`maxnumrep` int(10) unsigned NOT NULL default '0', +PRIMARY KEY (`numeropost`), +UNIQUE KEY `maxnumrep` (`maxnumrep`) +) TYPE=MyISAM ROW_FORMAT=FIXED; +INSERT INTO forumconthardwarefr7 (numeropost,maxnumrep) VALUES (1,0),(2,1); +select numeropost as a FROM forumconthardwarefr7 GROUP BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); +Subselect returns more than 1 record +drop table if exists forumconthardwarefr7; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 93ad115155e..1ee9881c404 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -135,9 +135,21 @@ CREATE TABLE `searchconthardwarefr7` ( ) TYPE=MyISAM ROW_FORMAT=DYNAMIC; INSERT INTO searchconthardwarefr7 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce'); - +select numeropost as a FROM forumconthardwarefr7 GROUP BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FROM searchconthardwarefr7 WHERE (mot='joce') AND date >= '2002-10-21' AND forumconthardwarefr7.numeropost = searchconthardwarefr7.topic) ORDER BY maxnumrep DESC LIMIT 0, 20; -- error 1054 SELECT (SELECT 1) as a FROM (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); +drop table forumconthardwarefr7, searchconthardwarefr7; -drop table forumconthardwarefr7, searchconthardwarefr7; \ No newline at end of file +drop table if exists forumconthardwarefr7; +CREATE TABLE `forumconthardwarefr7` ( + `numeropost` mediumint(8) unsigned NOT NULL auto_increment, + `maxnumrep` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`numeropost`), + UNIQUE KEY `maxnumrep` (`maxnumrep`) +) TYPE=MyISAM ROW_FORMAT=FIXED; + +INSERT INTO forumconthardwarefr7 (numeropost,maxnumrep) VALUES (1,0),(2,1); +-- error 1240 +select numeropost as a FROM forumconthardwarefr7 GROUP BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); +drop table if exists forumconthardwarefr7; \ No newline at end of file diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 703173b191c..37c85501b06 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -33,7 +33,7 @@ SUBSELECT TODO: #include "sql_select.h" Item_subselect::Item_subselect(): - Item(), engine_owner(1), value_assigned(0) + Item_result_field(), engine_owner(1), value_assigned(0) { assign_null(); /* diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 33f82982708..58726f16ba9 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -28,7 +28,7 @@ class subselect_engine; /* base class for subselects */ -class Item_subselect :public Item +class Item_subselect :public Item_result_field { my_bool engine_owner; /* Is this item owner of engine */ my_bool value_assigned; /* value already assigned to subselect */ @@ -116,6 +116,7 @@ public: Item *new_item() { return new Item_singleval_subselect(this); } enum Item_result result_type() const { return res_type; } void fix_length_and_dec(); + friend class select_singleval_subselect; }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ecf06f0971a..1d1c4656508 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4528,7 +4528,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) if (error == -1) table->file->print_error(my_errno,MYF(0)); } - DBUG_RETURN(error); + DBUG_RETURN(error || join->thd->net.report_error); } From 6ed18d1c9fa444eec6cbb5c5662a13ce7f759e4d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2002 11:59:03 +0200 Subject: [PATCH 23/30] fixed bug of derived table in subselect fixed bug in error handling mysql-test/r/subselect.result: test of error handling test of derived tables inside subselect mysql-test/t/subselect.test: test of error handling test of derived tables inside subselect sql/sql_class.cc: fixed error handling error sql/sql_lex.h: fifex layout sql/sql_parse.cc: fixed processing of derived tables sql/sql_select.cc: more quick abort on error --- mysql-test/r/subselect.result | 8 ++++++++ mysql-test/t/subselect.test | 11 ++++++++++- sql/sql_class.cc | 1 - sql/sql_lex.h | 2 +- sql/sql_parse.cc | 25 ++++++++++++++----------- sql/sql_select.cc | 5 +++-- 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 77499625bcd..5820c3259be 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -256,4 +256,12 @@ UNIQUE KEY `maxnumrep` (`maxnumrep`) INSERT INTO forumconthardwarefr7 (numeropost,maxnumrep) VALUES (1,0),(2,1); select numeropost as a FROM forumconthardwarefr7 GROUP BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); Subselect returns more than 1 record +select numeropost as a FROM forumconthardwarefr7 ORDER BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); +Subselect returns more than 1 record drop table if exists forumconthardwarefr7; +drop table if exists iftest; +CREATE TABLE iftest (field char(1) NOT NULL DEFAULT 'b'); +INSERT INTO iftest VALUES (); +SELECT field FROM iftest WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) HAVING field='b'); +Subselect returns more than 1 record +drop table iftest; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1ee9881c404..cfd22bc48c9 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -152,4 +152,13 @@ CREATE TABLE `forumconthardwarefr7` ( INSERT INTO forumconthardwarefr7 (numeropost,maxnumrep) VALUES (1,0),(2,1); -- error 1240 select numeropost as a FROM forumconthardwarefr7 GROUP BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); -drop table if exists forumconthardwarefr7; \ No newline at end of file +-- error 1240 +select numeropost as a FROM forumconthardwarefr7 ORDER BY (SELECT 1 FROM forumconthardwarefr7 HAVING a=1); +drop table if exists forumconthardwarefr7; + +drop table if exists iftest; +CREATE TABLE iftest (field char(1) NOT NULL DEFAULT 'b'); +INSERT INTO iftest VALUES (); +-- error 1240 +SELECT field FROM iftest WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) HAVING field='b'); +drop table iftest; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 887ee262777..f33d0f2ca28 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -873,7 +873,6 @@ bool select_singleval_subselect::send_data(List &items) DBUG_ENTER("select_singleval_subselect::send_data"); Item_singleval_subselect *it= (Item_singleval_subselect *)item; if (it->assigned()){ - thd->fatal_error= 1; my_message(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ea944ef34c8..6bafef8a469 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -336,7 +336,7 @@ public: } st_select_lex* outer_select(); st_select_lex* next_select() { return (st_select_lex*) next; } - st_select_lex* next_select_in_list() + st_select_lex* next_select_in_list() { return (st_select_lex*) link_next; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 52a6c67dda9..60b9cb47946 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1334,17 +1334,20 @@ mysql_execute_command(THD *thd) */ if (lex->derived_tables) { - for (TABLE_LIST *cursor= tables; - cursor; - cursor= cursor->next) - if (cursor->derived && (res=mysql_derived(thd, lex, - (SELECT_LEX_UNIT *)cursor->derived, - cursor))) - { - if (res < 0) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); - DBUG_VOID_RETURN; - } + for (SELECT_LEX *sl= &lex->select_lex; sl; sl= sl->next_select_in_list()) + if (sl->linkage != DERIVED_TABLE_TYPE) + for (TABLE_LIST *cursor= sl->get_table_list(); + cursor; + cursor= cursor->next) + if (cursor->derived && (res=mysql_derived(thd, lex, + (SELECT_LEX_UNIT *) + cursor->derived, + cursor))) + { + if (res < 0) + send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + DBUG_VOID_RETURN; + } } if ((lex->select_lex.next_select_in_list() && lex->unit.create_total_list(thd, lex, &tables)) || diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1d1c4656508..5f4bfc5462a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -994,7 +994,8 @@ JOIN::exec() } having=having_list; // Actually a parameter thd->proc_info="Sending data"; - error=do_select(this, &fields_list, NULL, procedure); + error= thd->net.report_error || + do_select(this, &fields_list, NULL, procedure); DBUG_VOID_RETURN; } @@ -1078,7 +1079,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, goto err; } - if (free_join && join->global_optimize()) + if (thd->net.report_error || (free_join && join->global_optimize())) goto err; join->exec(); From a464676f64a4a6e61f17b75c6ec1693ac948b303 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2002 15:00:25 +0400 Subject: [PATCH 24/30] my_snprintf() doesn't support things like %04X so use vsprintf() instead --- strings/ctype-simple.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 9fef27cad10..3393ed09ee0 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -123,6 +123,7 @@ int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, } +#ifdef NOT_USED static int my_vsnprintf_8bit(char *to, size_t n, const char* fmt, va_list ap) { char *start=to, *end=to+n-1; @@ -173,14 +174,22 @@ static int my_vsnprintf_8bit(char *to, size_t n, const char* fmt, va_list ap) *to='\0'; /* End of errmessage */ return (uint) (to - start); } - +#endif int my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)), - char* to, uint n, const char* fmt, ...) + char* to, uint n __attribute__((unused)), + const char* fmt, ...) { va_list args; va_start(args,fmt); +#ifdef NOT_USED return my_vsnprintf_8bit(to, n, fmt, args); +#endif + /* + FIXME: generally not safe, but it is OK for now + FIXME: as far as it's not called unsafely in the current code + */ + return vsprintf(to,fmt,args); /* FIXME */ } From 0fb5b32422b5dbf624660dec70aa617364cd884c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2002 13:07:58 +0200 Subject: [PATCH 25/30] fixed possible bug --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 60b9cb47946..6a2c8e17185 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1297,7 +1297,7 @@ mysql_execute_command(THD *thd) that is not a SHOW command or a select that only access local variables, but for now this is probably good enough. */ - if (tables) + if (tables || lex->select_lex.next_select_in_list()) mysql_reset_errors(thd); /* Save old warning count to be able to send to client how many warnings we From 81d428bd5a61708b711d18814becde5c16502c74 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2002 17:13:29 +0400 Subject: [PATCH 26/30] Preparing to embed string to number conversion functions into charset structure --- include/m_ctype.h | 13 ++++ mysys/charset.c | 4 ++ strings/ctype-big5.c | 7 ++- strings/ctype-czech.c | 7 ++- strings/ctype-euc_kr.c | 7 ++- strings/ctype-gb2312.c | 7 ++- strings/ctype-gbk.c | 7 ++- strings/ctype-latin1_de.c | 7 ++- strings/ctype-simple.c | 30 ++++++++++ strings/ctype-sjis.c | 7 ++- strings/ctype-tis620.c | 7 ++- strings/ctype-ujis.c | 7 ++- strings/ctype-utf8.c | 44 +++++++++++++- strings/ctype-win1250ch.c | 7 ++- strings/ctype.c | 122 +++++++++++++++++++++++++++++++++++++- 15 files changed, 270 insertions(+), 13 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 6a964bf3b97..fd10d7325c2 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -118,6 +118,12 @@ typedef struct charset_info_st /* Charset dependant snprintf() */ int (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt, ...); + long (*strtol)(struct charset_info_st *, const char *s, char **e, int base); + ulong (*strtoul)(struct charset_info_st *, const char *s, char **e, int base); + longlong (*strtoll)(struct charset_info_st *, const char *s, char **e, int base); + ulonglong (*strtoull)(struct charset_info_st *, const char *s, char **e, int base); + double (*strtod)(struct charset_info_st *, const char *s, char **e); + } CHARSET_INFO; @@ -156,6 +162,13 @@ int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e); int my_snprintf_8bit(struct charset_info_st *, char *to, uint n, const char *fmt, ...); +long my_strtol_8bit(CHARSET_INFO *, const char *s, char **e, int base); +ulong my_strtoul_8bit(CHARSET_INFO *, const char *s, char **e, int base); +longlong my_strtoll_8bit(CHARSET_INFO *, const char *s, char **e, int base); +ulonglong my_strtoull_8bit(CHARSET_INFO *, const char *s, char **e, int base); +double my_strtod_8bit(CHARSET_INFO *, const char *s, char **e); + + #ifdef USE_MB /* Functions for multibyte charsets */ diff --git a/mysys/charset.c b/mysys/charset.c index 2f22c616325..6242b6a3866 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -389,6 +389,10 @@ static CHARSET_INFO *add_charset(CHARSET_INFO *cs, myf flags) cs->hash_caseup = my_hash_caseup_simple; cs->hash_sort = my_hash_sort_simple; cs->snprintf = my_snprintf_8bit; + cs->strtol = my_strtol_8bit; + cs->strtoul = my_strtoul_8bit; + cs->strtoll = my_strtoll_8bit; + cs->strtoull = my_strtoull_8bit; cs->mbmaxlen = 1; set_max_sort_char(cs); diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 8dff0d860a0..0efa36d4a19 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6248,7 +6248,12 @@ CHARSET_INFO my_charset_big5 = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 3ec4491001d..46ba1af13b2 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -626,7 +626,12 @@ CHARSET_INFO my_charset_czech = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; #endif diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 154fada271e..4e5a0e3b525 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8665,7 +8665,12 @@ CHARSET_INFO my_charset_euc_kr = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; #endif diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index ecd15830b3f..c7a34f73f46 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5715,7 +5715,12 @@ CHARSET_INFO my_charset_gb2312 = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; #endif diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index bdfdfb9b256..81a95eea026 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9903,7 +9903,12 @@ CHARSET_INFO my_charset_gbk = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index d829296fd78..65c66f8cca8 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -444,7 +444,12 @@ CHARSET_INFO my_charset_latin1_de = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; #endif diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 3393ed09ee0..73978ffeeb5 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -244,3 +244,33 @@ void my_hash_sort_simple(CHARSET_INFO *cs, nr2[0]+=3; } } + +long my_strtol_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtol(s,e,base); +} + +ulong my_strtoul_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtoul(s,e,base); +} + +longlong my_strtoll_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtoll(s,e,base); +} + +ulonglong my_strtoull_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtoul(s,e,base); +} + +double my_strtod_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e) +{ + return strtod(s,e); +} diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index d657405137e..5d5beed0d44 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4490,7 +4490,12 @@ CHARSET_INFO my_charset_sjis = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; #endif diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 44d0dde65f5..04bf7107647 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -718,7 +718,12 @@ CHARSET_INFO my_charset_tis620 = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 85b51b0469c..0eb82cc91dc 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8459,7 +8459,12 @@ CHARSET_INFO my_charset_ujis = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index e4afa4a0cee..898cc72b65c 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1984,7 +1984,12 @@ CHARSET_INFO my_charset_utf8 = my_hash_caseup_utf8,/* hash_caseup */ my_hash_sort_utf8, /* hash_sort */ 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; @@ -2433,6 +2438,36 @@ static int my_snprintf_ucs2(CHARSET_INFO *cs __attribute__((unused)) } +static long my_strtol_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtol(s,e,base); +} + +static ulong my_strtoul_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtoul(s,e,base); +} + +static longlong my_strtoll_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtoll(s,e,base); +} + +static ulonglong my_strtoull_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e, int base) +{ + return strtoul(s,e,base); +} + +double my_strtod_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *s, char **e) +{ + return strtod(s,e); +} + CHARSET_INFO my_charset_ucs2 = { @@ -2466,7 +2501,12 @@ CHARSET_INFO my_charset_ucs2 = my_hash_caseup_ucs2,/* hash_caseup */ my_hash_sort_ucs2, /* hash_sort */ 0, - my_snprintf_ucs2 + my_snprintf_ucs2, + my_strtol_ucs2, + my_strtoul_ucs2, + my_strtoll_ucs2, + my_strtoull_ucs2, + my_strtod_ucs2 }; diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 9c418e2e6f5..3ef5b426bb4 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -652,7 +652,12 @@ CHARSET_INFO my_charset_win1250ch = my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }; diff --git a/strings/ctype.c b/strings/ctype.c index 96003f8baab..4c16c47ae07 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -2839,7 +2839,12 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_caseup_simple, my_hash_sort_simple, 0, - my_snprintf_8bit + my_snprintf_8bit, + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -2877,6 +2882,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -2913,6 +2923,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -2949,6 +2964,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -2986,6 +3006,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3022,6 +3047,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3058,6 +3088,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3094,6 +3129,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3131,6 +3171,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3167,6 +3212,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3203,6 +3253,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3239,6 +3294,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3275,6 +3335,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3311,6 +3376,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3347,6 +3417,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3384,6 +3459,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3420,6 +3500,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3457,6 +3542,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3494,6 +3584,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3530,6 +3625,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3566,6 +3666,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3602,6 +3707,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3638,6 +3748,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit }, #endif @@ -3674,6 +3789,11 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* hash_caseup */ NULL, /* hash_sort */ 0, + NULL, + NULL, + NULL, + NULL, + NULL, NULL } }; From 7721c7582a5d0b03435e4c0a7001fd3b4bf424de Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Nov 2002 17:58:07 +0400 Subject: [PATCH 27/30] Some macros to make life easier --- include/m_ctype.h | 6 ++++++ sql/gstream.cc | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index fd10d7325c2..bee6e51c483 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -233,6 +233,12 @@ extern int my_strncasecmp_mb(CHARSET_INFO * cs,const char *, const char *t, uint #define my_strcasecmp(s, a, b) ((s)->strcasecmp((s), (a), (b))) #define my_strncasecmp(s, a, b, l) ((s)->strncasecmp((s), (a), (b), (l))) +#define my_strtol(s, a, b, c) ((s)->strtol((s),(a),(b),(c))) +#define my_strtoul(s, a, b, c) ((s)->strtoul((s),(a),(b),(c))) +#define my_strtoll(s, a, b, c) ((s)->strtoll((s),(a),(b),(c))) +#define my_strtoull(s, a, b, c) ((s)->strtoull((s),(a),(b),(c))) +#define my_strtod(s, a, b) ((s)->strtod((s),(a),(b))) + /* XXX: still need to take care of this one */ #ifdef MY_CHARSET_TIS620 diff --git a/sql/gstream.cc b/sql/gstream.cc index 5a58fef6744..bd2345212c3 100644 --- a/sql/gstream.cc +++ b/sql/gstream.cc @@ -99,7 +99,7 @@ int GTextReadStream::get_next_number(double *d) char *endptr; - *d = strtod(cur, &endptr); + *d = my_strtod(my_charset_latin1, cur, &endptr); if(endptr) { From 81a5afb925e9c41f7f43e58e8f36d93b5befd364 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2002 00:26:18 +0200 Subject: [PATCH 28/30] fixed cyclic reference bug mysql-test/r/subselect.result: test of cyclic reference mysql-test/t/subselect.test: test of cyclic reference sql/share/czech/errmsg.txt: new error message sql/share/danish/errmsg.txt: new error message sql/share/dutch/errmsg.txt: new error message sql/share/english/errmsg.txt: new error message sql/share/estonian/errmsg.txt: new error message sql/share/french/errmsg.txt: new error message sql/share/german/errmsg.txt: new error message sql/share/greek/errmsg.txt: new error message sql/share/hungarian/errmsg.txt: new error message sql/share/italian/errmsg.txt: new error message sql/share/japanese/errmsg.txt: new error message sql/share/korean/errmsg.txt: new error message sql/share/norwegian-ny/errmsg.txt: new error message sql/share/norwegian/errmsg.txt: new error message sql/share/polish/errmsg.txt: new error message sql/share/portuguese/errmsg.txt: new error message sql/share/romanian/errmsg.txt: new error message sql/share/russian/errmsg.txt: new error message sql/share/serbian/errmsg.txt: new error message sql/share/slovak/errmsg.txt: new error message sql/share/spanish/errmsg.txt: new error message sql/share/swedish/errmsg.txt: new error message sql/share/ukrainian/errmsg.txt: new error message --- include/mysqld_error.h | 3 ++- mysql-test/r/subselect.result | 4 +++- mysql-test/t/subselect.test | 4 +++- sql/item.cc | 27 ++++++++++++++++++++++++++ sql/item.h | 8 ++++++-- sql/item_cmpfunc.cc | 32 +++++++++++++++++++++++++++++++ sql/item_cmpfunc.h | 10 ++++++++++ sql/item_func.cc | 29 ++++++++++++++++++++++++++++ sql/item_func.h | 9 +++++++++ sql/item_strfunc.h | 21 ++++++++++++++++++++ sql/item_subselect.cc | 25 ++++++++++++++++++++++++ sql/item_subselect.h | 24 +++++++++++++---------- sql/share/czech/errmsg.txt | 3 ++- sql/share/danish/errmsg.txt | 3 ++- sql/share/dutch/errmsg.txt | 3 ++- sql/share/english/errmsg.txt | 3 ++- sql/share/estonian/errmsg.txt | 3 ++- sql/share/french/errmsg.txt | 3 ++- sql/share/german/errmsg.txt | 3 ++- sql/share/greek/errmsg.txt | 3 ++- sql/share/hungarian/errmsg.txt | 3 ++- sql/share/italian/errmsg.txt | 3 ++- sql/share/japanese/errmsg.txt | 3 ++- sql/share/korean/errmsg.txt | 3 ++- sql/share/norwegian-ny/errmsg.txt | 3 ++- sql/share/norwegian/errmsg.txt | 3 ++- sql/share/polish/errmsg.txt | 3 ++- sql/share/portuguese/errmsg.txt | 3 ++- sql/share/romanian/errmsg.txt | 3 ++- sql/share/russian/errmsg.txt | 3 ++- sql/share/serbian/errmsg.txt | 3 ++- sql/share/slovak/errmsg.txt | 3 ++- sql/share/spanish/errmsg.txt | 3 ++- sql/share/swedish/errmsg.txt | 3 ++- sql/share/ukrainian/errmsg.txt | 3 ++- sql/sql_class.h | 1 + sql/sql_parse.cc | 3 ++- sql/sql_select.cc | 18 +++++++++++++++++ sql/sql_select.h | 3 ++- 39 files changed, 250 insertions(+), 40 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 125059af7fd..456d675a045 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -259,4 +259,5 @@ #define ER_SUBSELECT_NO_1_ROW 1240 #define ER_UNKNOWN_STMT_HANDLER 1241 #define ER_CORRUPT_HELP_DB 1242 -#define ER_ERROR_MESSAGES 243 +#define ER_CYCLIC_REFERENCE 1243 +#define ER_ERROR_MESSAGES 244 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 5820c3259be..1b799a6cb63 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -8,6 +8,8 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); (SELECT (SELECT 0 UNION SELECT 0)) 0 +SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; +Cyclic reference on subqueries drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); @@ -46,7 +48,7 @@ a b 1 7 2 7 3 8 -select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) +select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); a b 1 7 diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index cfd22bc48c9..f690a823f85 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1,6 +1,8 @@ select (select 2); SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); +-- error 1243 +SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); @@ -18,7 +20,7 @@ insert into t3 values (6),(7),(3); select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) union (select * from t4 order by a limit 2) limit 3; -select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) +select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); explain select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); diff --git a/sql/item.cc b/sql/item.cc index ea797679957..f317759553b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -42,6 +42,20 @@ Item::Item() decimals=0; max_length=0; next=current_thd->free_list; // Put in free list current_thd->free_list=this; + loop_id= 0; +} + +bool Item::check_loop(uint id) +{ + DBUG_ENTER("Item::check_loop"); + DBUG_PRINT("info", ("id %u, name %s", id, name)); + if (loop_id == id) + { + DBUG_PRINT("info", ("id match")); + DBUG_RETURN(1); + } + loop_id= id; + DBUG_RETURN(0); } void Item::set_name(const char *str,uint length) @@ -862,6 +876,11 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { depended_from= last; thd->lex.current_select->mark_as_dependent(last); + if (check_loop(thd->check_loops_counter++)) + { + my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0)); + return 1; + } } } else if (!ref) @@ -873,6 +892,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) return 0; } +bool Item_ref::check_loop(uint id) +{ + DBUG_ENTER("Item_ref::check_loop"); + if (Item_ident::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN((*ref)->check_loop(id)); +} + /* ** If item is a const function, calculate it and return a const item ** The original item is freed if not returned diff --git a/sql/item.h b/sql/item.h index fb6bed75d51..c67c16c50ad 100644 --- a/sql/item.h +++ b/sql/item.h @@ -20,10 +20,11 @@ #endif struct st_table_list; -void item_init(void); /* Init item functions */ +void item_init(void); /* Init item functions */ class Item { - Item(const Item &); /* Prevent use of these */ + uint loop_id; /* Used to find selfrefering loops */ + Item(const Item &); /* Prevent use of these */ void operator=(Item &); public: static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } @@ -88,6 +89,8 @@ public: virtual CHARSET_INFO *charset() const { return str_value.charset(); }; virtual bool binary() const { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; } virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } + + virtual bool check_loop(uint id); }; @@ -434,6 +437,7 @@ public: void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } enum Item_result result_type () const { return (*ref)->result_type(); } table_map used_tables() const { return (*ref)->used_tables(); } + bool check_loop(uint id); }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b6ea4beb339..744ed1bceca 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -344,6 +344,14 @@ void Item_func_interval::update_used_tables() const_item_cache&=item->const_item(); } +bool Item_func_interval::check_loop(uint id) +{ + DBUG_ENTER("Item_func_interval::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); +} + void Item_func_between::fix_length_and_dec() { max_length=1; @@ -776,6 +784,16 @@ Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +bool Item_func_case::check_loop(uint id) +{ + DBUG_ENTER("Item_func_case::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + + DBUG_RETURN((first_expr && first_expr->check_loop(id)) || + (else_expr && else_expr->check_loop(id))); +} + void Item_func_case::update_used_tables() { Item_func::update_used_tables(); @@ -1137,6 +1155,20 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +bool Item_cond::check_loop(uint id) +{ + DBUG_ENTER("Item_cond::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + List_iterator li(list); + Item *item; + while ((item= li++)) + { + if (item->check_loop(id)) + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} void Item_cond::split_sum_func(List &fields) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c0dcc2bba8f..489d54ae786 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -186,6 +186,7 @@ public: ~Item_func_interval() { delete item; } const char *func_name() const { return "interval"; } void update_used_tables(); + bool check_loop(uint id); }; @@ -262,6 +263,7 @@ public: void print(String *str); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); Item *find_item(String *str); + bool check_loop(uint id); }; @@ -424,6 +426,13 @@ class Item_func_in :public Item_int_func enum Functype functype() const { return IN_FUNC; } const char *func_name() const { return " IN "; } void update_used_tables(); + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_in::check_loop"); + if (Item_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; @@ -563,6 +572,7 @@ public: void print(String *str); void split_sum_func(List &fields); friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); + bool check_loop(uint id); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 543a96107dc..aa39b3cc857 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -126,6 +126,22 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +bool Item_func::check_loop(uint id) +{ + DBUG_ENTER("Item_func::check_loop"); + if (Item_result_field::check_loop(id)) + DBUG_RETURN(1); + if (arg_count) + { + Item **arg,**arg_end; + for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) + { + if ((*arg)->check_loop(id)) + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} void Item_func::split_sum_func(List &fields) { @@ -2264,6 +2280,19 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) return 0; } +bool Item_func_match::check_loop(uint id) +{ + DBUG_ENTER("Item_func_match::check_loop"); + if (Item_real_func::check_loop(id)) + DBUG_RETURN(1); + + List_iterator li(fields); + Item *item; + while ((item= li++)) + if (item->check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} bool Item_func_match::fix_index() { diff --git a/sql/item_func.h b/sql/item_func.h index 1e1f2ba39fc..581809fc9cb 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -128,6 +128,7 @@ public: bool is_null() { (void) val_int(); return null_value; } friend class udf_handler; Field *tmp_table_field(TABLE *t_arg); + bool check_loop(uint id); }; @@ -606,6 +607,13 @@ public: const_item_cache&= item->const_item(); with_sum_func= with_sum_func || item->with_sum_func; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_field::check_loop"); + if (Item_int_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; @@ -971,6 +979,7 @@ public: bool fix_index(); void init_search(bool no_order); + bool check_loop(uint id); }; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 1a3193318b6..2b308630b48 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -105,6 +105,13 @@ public: || Item_func::fix_fields(thd, tlist, ref)); } const char *func_name() const { return "concat_ws"; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_concat_ws::check_loop"); + if (Item_str_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(separator->check_loop(id)); + } }; class Item_func_reverse :public Item_str_func @@ -361,6 +368,13 @@ public: void fix_length_and_dec(); void update_used_tables(); const char *func_name() const { return "elt"; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_elt::check_loop"); + if (Item_str_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; @@ -381,6 +395,13 @@ public: void fix_length_and_dec(); void update_used_tables(); const char *func_name() const { return "make_set"; } + bool check_loop(uint id) + { + DBUG_ENTER("Item_func_make_set::check_loop"); + if (Item_str_func::check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(item->check_loop(id)); + } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 37c85501b06..1f1944026ef 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -95,6 +95,15 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return res; } +bool Item_subselect::check_loop(uint id) +{ + DBUG_ENTER("Item_subselect::check_loop"); + if (Item_result_field::check_loop(id)) + DBUG_RETURN(1); + + DBUG_RETURN(engine->check_loop(id)); +} + void Item_subselect::fix_length_and_dec() { engine->fix_length_and_dec(); @@ -228,6 +237,7 @@ subselect_single_select_engine::subselect_single_select_engine(THD *thd, thd->fatal_error= 1; my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); } + unit->item= item; this->select_lex= select_lex; } @@ -353,3 +363,18 @@ bool subselect_union_engine::depended() { return unit->dependent; } + +bool subselect_single_select_engine::check_loop(uint id) +{ + DBUG_ENTER("subselect_single_select_engine::check_loop"); + DBUG_RETURN(join->check_loop(id)); +} + +bool subselect_union_engine::check_loop(uint id) +{ + DBUG_ENTER("subselect_union_engine::check_loop"); + for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) + if (sl->join && sl->join->check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 58726f16ba9..3ad6c68a6ba 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -70,6 +70,7 @@ public: bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); virtual void fix_length_and_dec(); table_map used_tables() const; + bool check_loop(uint id); friend class select_subselect; }; @@ -176,6 +177,7 @@ public: virtual uint cols()= 0; /* return number of columnss in select */ virtual bool depended()= 0; /* depended from outer select */ enum Item_result type() { return res_type; } + virtual bool check_loop(uint id)= 0; }; class subselect_single_select_engine: public subselect_engine @@ -189,11 +191,12 @@ public: subselect_single_select_engine(THD *thd, st_select_lex *select, select_subselect *result, Item_subselect *item); - virtual int prepare(); - virtual void fix_length_and_dec(); - virtual int exec(); - virtual uint cols(); - virtual bool depended(); + int prepare(); + void fix_length_and_dec(); + int exec(); + uint cols(); + bool depended(); + bool check_loop(uint id); }; class subselect_union_engine: public subselect_engine @@ -204,9 +207,10 @@ public: st_select_lex_unit *u, select_subselect *result, Item_subselect *item); - virtual int prepare(); - virtual void fix_length_and_dec(); - virtual int exec(); - virtual uint cols(); - virtual bool depended(); + int prepare(); + void fix_length_and_dec(); + int exec(); + uint cols(); + bool depended(); + bool check_loop(uint id); }; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index c8ac594f00b..d43a433da06 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -252,4 +252,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 5638260277e..3a947bcbe38 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -246,4 +246,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index acbda2829d0..1cb81849be1 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -254,4 +254,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 36d8831fd39..6e96fdb393e 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 96bd758cc6a..394c40c5778 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -248,4 +248,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 932182a2c94..b18d3f8fb38 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index febd723df89..49ea31dd05b 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -246,4 +246,5 @@ "Subselect return more than 1 field", "Subselect return more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 9d9aa07af8d..b203c63949b 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index d596c8f3433..07081e689ad 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index d9ccf54d7ea..0a380e2b48f 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 22a53801efd..2e0a083ca06 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 27a8fdde027..19fcf98e3c7 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 8e8b5aa7e61..810aaf38f74 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 0f4650c186c..a74a0a910b8 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -245,4 +245,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 758e96e5ca3..efde31ff4c9 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -247,4 +247,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 21ebe5c39dc..e90d5844b9b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index c84049d6192..18f0bf7f79d 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -247,4 +247,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 0ee79ce5811..790d738031c 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -246,4 +246,5 @@ "Подзапрос возвращает более одного поля", "Подзапрос возвращает более одной записи", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Циклическая ссылка на подзапрос", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index d120630b636..e8186d38a5b 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -239,4 +239,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index eb9e2a240a0..216d46fcd3a 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -251,4 +251,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 0b7de283481..5076b1b6679 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -244,4 +244,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 052cd1506d3..a3bb40fb4f5 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -243,4 +243,5 @@ "Subselect returns more than 1 field", "Subselect returns more than 1 record", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Cyclic reference on subqueries", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 5cfad494a32..426c2a14e3b 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -248,4 +248,5 @@ "Пiдзапит поверта╓ бiльш нiж 1 стовбець", "Пiдзапит поверта╓ бiльш нiж 1 запис", "Unknown prepared statement handler (%ld) given to %s", -"Help database is corrupt or does not exist", \ No newline at end of file +"Help database is corrupt or does not exist", +"Циклiчне посилання на пiдзапит", diff --git a/sql/sql_class.h b/sql/sql_class.h index 08066e83ee7..6f6547a358c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -494,6 +494,7 @@ public: uint32 query_length; uint32 db_length; uint select_number; //number of select (used for EXPLAIN) + uint check_loops_counter; //last id used to check loops /* variables.transaction_isolation is reset to this after each commit */ enum_tx_isolation session_tx_isolation; char scramble[9]; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6a2c8e17185..1586469de42 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2867,7 +2867,8 @@ mysql_init_query(THD *thd) lex->select_lex.prev= &lex->unit.slave; lex->olap=lex->describe=0; lex->derived_tables= false; - thd->select_number= lex->select_lex.select_number= 1; + thd->check_loops_counter= thd->select_number= + lex->select_lex.select_number= 1; thd->free_list= 0; thd->total_warn_count=0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5f4bfc5462a..dd84b2a46c8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1035,6 +1035,24 @@ JOIN::cleanup(THD *thd) DBUG_RETURN(error); } +bool JOIN::check_loop(uint id) +{ + DBUG_ENTER("JOIN::check_loop"); + Item *item; + List_iterator it(all_fields); + DBUG_PRINT("info", ("all_fields:")); + while ((item= it++)) + if (item->check_loop(id)) + DBUG_RETURN(1); + DBUG_PRINT("info", ("where:")); + if (select_lex->where && select_lex->where->check_loop(id)) + DBUG_RETURN(1); + DBUG_PRINT("info", ("having:")); + if (select_lex->having && select_lex->having->check_loop(id)) + DBUG_RETURN(1); + DBUG_RETURN(0); +} + int mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, ORDER *order, ORDER *group,Item *having, ORDER *proc_param, diff --git a/sql/sql_select.h b/sql/sql_select.h index c5b5357be50..3b89c1ce0d3 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -244,7 +244,8 @@ class JOIN :public Sql_alloc int global_optimize(); int reinit(); void exec(); - int cleanup(THD *thd); + int cleanup(THD *thd); + bool check_loop(uint id); }; From 948a867123539742518d033c856eeb2caa94525d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2002 09:43:24 +0200 Subject: [PATCH 29/30] fixed bug in cyclic reference refinition mysql-test/r/subselect.result: test of cyclic reference mysql-test/t/subselect.test: test of cyclic reference sql/sql_parse.cc: fixed layout fixed bug in cyclic reference refinition --- mysql-test/r/subselect.result | 2 ++ mysql-test/t/subselect.test | 2 ++ sql/item.cc | 6 +----- sql/sql_class.cc | 9 +++++++++ sql/sql_class.h | 2 ++ sql/sql_parse.cc | 4 +++- sql/sql_select.cc | 17 +++++++++++++++++ 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1b799a6cb63..d1a3056d8e9 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -10,6 +10,8 @@ SELECT (SELECT (SELECT 0 UNION SELECT 0)); 0 SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; Cyclic reference on subqueries +SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; +Cyclic reference on subqueries drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index f690a823f85..63f689d2608 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3,6 +3,8 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); -- error 1243 SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; +-- error 1243 +SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); diff --git a/sql/item.cc b/sql/item.cc index f317759553b..48ec11d02c2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -876,11 +876,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { depended_from= last; thd->lex.current_select->mark_as_dependent(last); - if (check_loop(thd->check_loops_counter++)) - { - my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0)); - return 1; - } + thd->add_possible_loop(this); } } else if (!ref) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f33d0f2ca28..e6acab6a244 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -434,6 +434,15 @@ void THD::close_active_vio() } #endif +void THD::add_possible_loop (Item *item) +{ + if (!possible_loops) + { + possible_loops= new List; + } + possible_loops->push_back(item); +} + /***************************************************************************** ** Functions to provide a interface to select results *****************************************************************************/ diff --git a/sql/sql_class.h b/sql/sql_class.h index 6f6547a358c..a619e8e3aff 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -482,6 +482,7 @@ public: USER_CONN *user_connect; CHARSET_INFO *db_charset; CHARSET_INFO *thd_charset; + List *possible_loops; // Items that may cause loops in subselects List warn_list; uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; uint total_warn_count, old_total_warn_count; @@ -632,6 +633,7 @@ public: net.last_errno= 0; net.report_error= 0; } + void add_possible_loop(Item *); }; /* diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1586469de42..8df74f332eb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2862,7 +2862,8 @@ mysql_init_query(THD *thd) lex->select_lex.init_query(); lex->value_list.empty(); lex->param_list.empty(); - lex->unit.global_parameters= lex->unit.slave= lex->current_select= &lex->select_lex; + lex->unit.global_parameters= lex->unit.slave= lex->current_select= + &lex->select_lex; lex->select_lex.master= &lex->unit; lex->select_lex.prev= &lex->unit.slave; lex->olap=lex->describe=0; @@ -2875,6 +2876,7 @@ mysql_init_query(THD *thd) thd->sent_row_count= thd->examined_row_count= 0; thd->fatal_error= thd->rand_used=0; thd->safe_to_cache_query= 1; + thd->possible_loops= 0; DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dd84b2a46c8..b3838628d35 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1087,6 +1087,23 @@ mysql_select(THD *thd, TABLE_LIST *tables, List &fields, COND *conds, { DBUG_RETURN(-1); } + if (thd->possible_loops) + { + Item *item; + while(thd->possible_loops->elements) + { + item= thd->possible_loops->pop(); + if (item->check_loop(thd->check_loops_counter++)) + { + delete thd->possible_loops; + thd->possible_loops= 0; + my_message(ER_CYCLIC_REFERENCE, ER(ER_CYCLIC_REFERENCE), MYF(0)); + return 1; + } + } + delete thd->possible_loops; + thd->possible_loops= 0; + } } switch (join->optimize()) From e7bbe3aa0b2f9dda5f6883a3e1998377a9071db5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2002 16:07:29 +0400 Subject: [PATCH 30/30] New wildcmp() function in CHARSET_INFO structure --- include/m_ctype.h | 22 ++++-- strings/ctype-big5.c | 1 + strings/ctype-bin.c | 105 +++++++++++++++++++++++++++-- strings/ctype-czech.c | 1 + strings/ctype-euc_kr.c | 3 +- strings/ctype-gb2312.c | 3 +- strings/ctype-gbk.c | 1 + strings/ctype-latin1_de.c | 15 +++-- strings/ctype-mb.c | 138 ++++++++++++++++++++++++++++++++++++++ strings/ctype-simple.c | 95 +++++++++++++++++++++++++- strings/ctype-sjis.c | 1 + strings/ctype-tis620.c | 15 +++-- strings/ctype-ujis.c | 5 +- strings/ctype-utf8.c | 24 ++++--- strings/ctype-win1250ch.c | 3 +- strings/ctype.c | 30 ++++++++- 16 files changed, 420 insertions(+), 42 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index bee6e51c483..414bd86a412 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -83,19 +83,23 @@ typedef struct charset_info_st my_bool (*like_range)(struct charset_info_st *, const char *, uint, pchar, uint, char *, char *, uint *, uint *); - + int (*wildcmp)(struct charset_info_st *, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape,int w_one, int w_many); + /* Multibyte routines */ uint mbmaxlen; int (*ismbchar)(struct charset_info_st *, const char *, const char *); my_bool (*ismbhead)(struct charset_info_st *, uint); int (*mbcharlen)(struct charset_info_st *, uint); - + /* Unicode convertion */ int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc, const unsigned char *s,const unsigned char *e); int (*wc_mb)(struct charset_info_st *cs,my_wc_t wc, unsigned char *s,unsigned char *e); - + /* Functions for case and sort convertion */ void (*caseup_str)(struct charset_info_st *, char *); void (*casedn_str)(struct charset_info_st *, char *); @@ -107,7 +111,7 @@ typedef struct charset_info_st int (*strcasecmp)(struct charset_info_st *, const char *, const char *); int (*strncasecmp)(struct charset_info_st *, const char *, const char *, uint); - + /* Hash calculation */ uint (*hash_caseup)(struct charset_info_st *cs, const byte *key, uint len); void (*hash_sort)(struct charset_info_st *cs, const uchar *key, uint len, @@ -169,6 +173,11 @@ ulonglong my_strtoull_8bit(CHARSET_INFO *, const char *s, char **e, int base); double my_strtod_8bit(CHARSET_INFO *, const char *s, char **e); +int my_wildcmp_8bit(CHARSET_INFO *, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many); + #ifdef USE_MB /* Functions for multibyte charsets */ @@ -178,6 +187,10 @@ extern void my_caseup_mb(CHARSET_INFO *, char *, uint); extern void my_casedn_mb(CHARSET_INFO *, char *, uint); extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *); extern int my_strncasecmp_mb(CHARSET_INFO * cs,const char *, const char *t, uint); +int my_wildcmp_mb(CHARSET_INFO *, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many); #endif @@ -219,6 +232,7 @@ extern int my_strncasecmp_mb(CHARSET_INFO * cs,const char *, const char *t, uint #define my_strnncoll(s, a, b, c, d) ((s)->strnncoll((s), (a), (b), (c), (d))) #define my_like_range(s, a, b, c, d, e, f, g, h) \ ((s)->like_range((s), (a), (b), (c), (d), (e), (f), (g), (h))) +#define my_wildcmp(cs,s,se,w,we,e,o,m) ((cs)->wildcmp,(s),(se),(w),(we),(e),(o),(m)) #define use_mb(s) ((s)->ismbchar != NULL) #define my_ismbchar(s, a, b) ((s)->ismbchar((s), (a), (b))) diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 0efa36d4a19..aae8da72c13 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6232,6 +6232,7 @@ CHARSET_INFO my_charset_big5 = my_strnncoll_big5, my_strnxfrm_big5, my_like_range_big5, + my_wildcmp_mb, 2, /* mbmaxlen */ ismbchar_big5, ismbhead_big5, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 9a22b3f36bf..f9f6d60e373 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -145,11 +145,101 @@ void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)), } +static int my_wildcmp_bin(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many) +{ + int result= -1; // Not found, using wildcards + + while (wildstr != wildend) + { + while (*wildstr != w_many && *wildstr != w_one) + { + if (*wildstr == escape && wildstr+1 != wildend) + wildstr++; + if (str == str_end || *wildstr++ != *str++) + { + return(1); + } + if (wildstr == wildend) + { + return(str != str_end); // Match if both are at end + } + result=1; // Found an anchor char + } + if (*wildstr == w_one) + { + do + { + if (str == str_end) // Skip one char if possible + return(result); + str++; + } while (*++wildstr == w_one && wildstr != wildend); + if (wildstr == wildend) + break; + } + if (*wildstr == w_many) + { // Found w_many + char cmp; + + wildstr++; + /* Remove any '%' and '_' from the wild search string */ + for (; wildstr != wildend ; wildstr++) + { + if (*wildstr == w_many) + continue; + if (*wildstr == w_one) + { + if (str == str_end) + { + return(-1); + } + str++; + continue; + } + break; // Not a wild character + } + if (wildstr == wildend) + { + return(0); // Ok if w_many is last + } + if (str == str_end) + { + return(-1); + } + + if ((cmp= *wildstr) == escape && wildstr+1 != wildend) + cmp= *++wildstr; + wildstr++; // This is compared trough cmp + do + { + while (str != str_end && *str != cmp) + str++; + if (str++ == str_end) + { + return(-1); + } + { + int tmp=my_wildcmp_bin(cs,str,str_end,wildstr,wildend,escape,w_one,w_many); + if (tmp <= 0) + { + return(tmp); + } + } + } while (str != str_end && wildstr[0] != w_many); + return(-1); + } + } + return(str != str_end ? 1 : 0); +} + + static CHARSET_INFO my_charset_bin_st = { - 63, /* number */ - MY_CS_COMPILED|MY_CS_BINSORT,/* state */ + 63, /* number */ + MY_CS_COMPILED|MY_CS_BINSORT,/* state */ "binary", /* name */ "", /* comment */ NULL, /* ctype */ @@ -161,7 +251,8 @@ static CHARSET_INFO my_charset_bin_st = 0, /* strxfrm_multiply */ my_strnncoll_binary, /* strnncoll */ NULL, /* strxnfrm */ - NULL, /* like_rabge */ + NULL, /* like_range */ + my_wildcmp_bin, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -178,7 +269,13 @@ static CHARSET_INFO my_charset_bin_st = my_hash_caseup_bin, /* hash_caseup */ my_hash_sort_bin, /* hash_sort */ 255, /* max_sort_char */ - my_snprintf_8bit /* snprintf */ + my_snprintf_8bit, /* snprintf */ + my_strtol_8bit, + my_strtoul_8bit, + my_strtoll_8bit, + my_strtoull_8bit, + my_strtod_8bit + }; diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 46ba1af13b2..4d5479bba0f 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -610,6 +610,7 @@ CHARSET_INFO my_charset_czech = my_strnncoll_czech, my_strnxfrm_czech, my_like_range_czech, + my_wildcmp_8bit, 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 4e5a0e3b525..4142b2d3941 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8649,7 +8649,8 @@ CHARSET_INFO my_charset_euc_kr = my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 2, /* mbmaxlen */ + my_wildcmp_mb, /* wildcmp */ + 2, /* mbmaxlen */ ismbchar_euc_kr, ismbhead_euc_kr, mbcharlen_euc_kr, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index c7a34f73f46..6a54757ab4c 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5699,7 +5699,8 @@ CHARSET_INFO my_charset_gb2312 = my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ - 2, /* mbmaxlen */ + my_wildcmp_mb, /* wildcmp */ + 2, /* mbmaxlen */ ismbchar_gb2312, ismbhead_gb2312, mbcharlen_gb2312, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 81a95eea026..c7264078d13 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9887,6 +9887,7 @@ CHARSET_INFO my_charset_gbk = my_strnncoll_gbk, my_strnxfrm_gbk, my_like_range_gbk, + my_wildcmp_mb, /* wildcmp */ 2, /* mbmaxlen */ ismbchar_gbk, ismbhead_gbk, diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index 65c66f8cca8..1fc395638a6 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -414,10 +414,10 @@ static my_bool my_like_range_latin1_de(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_latin1_de = { - 31, /* number */ - MY_CS_COMPILED, /* state */ - "latin1_de", /* name */ - "", /* comment */ + 31, /* number */ + MY_CS_COMPILED, /* state */ + "latin1_de", /* name */ + "", /* comment */ ctype_latin1_de, to_lower_latin1_de, to_upper_latin1_de, @@ -428,17 +428,18 @@ CHARSET_INFO my_charset_latin1_de = my_strnncoll_latin1_de, my_strnxfrm_latin1_de, my_like_range_latin1_de, + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ - my_mb_wc_8bit, /* mb_wc */ - my_wc_mb_8bit, /* wc_mb */ + my_mb_wc_8bit, /* mb_wc */ + my_wc_mb_8bit, /* wc_mb */ my_caseup_str_8bit, my_casedn_str_8bit, my_caseup_8bit, my_casedn_8bit, - NULL, /* tosort */ + NULL, /* tosort */ my_strcasecmp_8bit, my_strncasecmp_8bit, my_hash_caseup_simple, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index aa475e281d0..092b7aa4f0f 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -138,4 +138,142 @@ int my_strncasecmp_mb(CHARSET_INFO * cs, return 0; } + +/* +** Compare string against string with wildcard +** 0 if matched +** -1 if not matched with wildcard +** 1 if matched with wildcard +*/ + +#define INC_PTR(cs,A,B) A+=((use_mb_flag && \ + my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1) + +#ifdef LIKE_CMP_TOUPPER +#define likeconv(s,A) (uchar) my_toupper(s,A) +#else +#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)] +#endif + +int my_wildcmp_mb(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many) +{ + int result= -1; // Not found, using wildcards + + bool use_mb_flag=use_mb(cs); + + while (wildstr != wildend) + { + while (*wildstr != w_many && *wildstr != w_one) + { + int l; + if (*wildstr == escape && wildstr+1 != wildend) + wildstr++; + if (use_mb_flag && + (l = my_ismbchar(cs, wildstr, wildend))) + { + if (str+l > str_end || memcmp(str, wildstr, l) != 0) + return 1; + str += l; + wildstr += l; + } + else + if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++)) + return(1); // No match + if (wildstr == wildend) + return (str != str_end); // Match if both are at end + result=1; // Found an anchor char + } + if (*wildstr == w_one) + { + do + { + if (str == str_end) // Skip one char if possible + return (result); + INC_PTR(cs,str,str_end); + } while (++wildstr < wildend && *wildstr == w_one); + if (wildstr == wildend) + break; + } + if (*wildstr == w_many) + { // Found w_many + uchar cmp; + const char* mb = wildstr; + int mblen; + + wildstr++; + /* Remove any '%' and '_' from the wild search string */ + for (; wildstr != wildend ; wildstr++) + { + if (*wildstr == w_many) + continue; + if (*wildstr == w_one) + { + if (str == str_end) + return (-1); + INC_PTR(cs,str,str_end); + continue; + } + break; // Not a wild character + } + if (wildstr == wildend) + return(0); // Ok if w_many is last + if (str == str_end) + return -1; + + if ((cmp= *wildstr) == escape && wildstr+1 != wildend) + cmp= *++wildstr; + + mb=wildstr; + LINT_INIT(mblen); + if (use_mb_flag) + mblen = my_ismbchar(cs, wildstr, wildend); + INC_PTR(cs,wildstr,wildend); // This is compared trough cmp + cmp=likeconv(cs,cmp); + do + { + if (use_mb_flag) + { + for (;;) + { + if (str >= str_end) + return -1; + if (mblen) + { + if (str+mblen <= str_end && memcmp(str, mb, mblen) == 0) + { + str += mblen; + break; + } + } + else if (!my_ismbchar(cs, str, str_end) && + likeconv(cs,*str) == cmp) + { + str++; + break; + } + INC_PTR(cs,str, str_end); + } + } + else + { + while (str != str_end && likeconv(cs,*str) != cmp) + str++; + if (str++ == str_end) return (-1); + } + { + int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,w_many); + if (tmp <= 0) + return (tmp); + } + } while (str != str_end && wildstr[0] != w_many); + return(-1); + } + } + return (str != str_end ? 1 : 0); +} + + #endif diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 73978ffeeb5..9f8cc4e1aa9 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -18,7 +18,6 @@ #include "my_sys.h" #include "m_ctype.h" #include "m_string.h" -#include "dbug.h" #include "stdarg.h" #include "assert.h" @@ -274,3 +273,97 @@ double my_strtod_8bit(CHARSET_INFO *cs __attribute__((unused)), { return strtod(s,e); } + + +/* +** Compare string against string with wildcard +** 0 if matched +** -1 if not matched with wildcard +** 1 if matched with wildcard +*/ + +#ifdef LIKE_CMP_TOUPPER +#define likeconv(s,A) (uchar) my_toupper(s,A) +#else +#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)] +#endif + +#define INC_PTR(cs,A,B) A++ + + +int my_wildcmp_8bit(CHARSET_INFO *cs, + const char *str,const char *str_end, + const char *wildstr,const char *wildend, + int escape, int w_one, int w_many) +{ + int result= -1; // Not found, using wildcards + + while (wildstr != wildend) + { + while (*wildstr != w_many && *wildstr != w_one) + { + if (*wildstr == escape && wildstr+1 != wildend) + wildstr++; + + if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++)) + return(1); // No match + if (wildstr == wildend) + return (str != str_end); // Match if both are at end + result=1; // Found an anchor char + } + if (*wildstr == w_one) + { + do + { + if (str == str_end) // Skip one char if possible + return (result); + INC_PTR(cs,str,str_end); + } while (++wildstr < wildend && *wildstr == w_one); + if (wildstr == wildend) + break; + } + if (*wildstr == w_many) + { // Found w_many + uchar cmp; + + wildstr++; + /* Remove any '%' and '_' from the wild search string */ + for (; wildstr != wildend ; wildstr++) + { + if (*wildstr == w_many) + continue; + if (*wildstr == w_one) + { + if (str == str_end) + return (-1); + INC_PTR(cs,str,str_end); + continue; + } + break; // Not a wild character + } + if (wildstr == wildend) + return(0); // Ok if w_many is last + if (str == str_end) + return -1; + + if ((cmp= *wildstr) == escape && wildstr+1 != wildend) + cmp= *++wildstr; + + INC_PTR(cs,wildstr,wildend); // This is compared trough cmp + cmp=likeconv(cs,cmp); + do + { + while (str != str_end && likeconv(cs,*str) != cmp) + str++; + if (str++ == str_end) return (-1); + { + int tmp=my_wildcmp_8bit(cs,str,str_end,wildstr,wildend,escape,w_one,w_many); + if (tmp <= 0) + return (tmp); + } + } while (str != str_end && wildstr[0] != w_many); + return(-1); + } + } + return (str != str_end ? 1 : 0); +} diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 5d5beed0d44..b670c0a5f5d 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4474,6 +4474,7 @@ CHARSET_INFO my_charset_sjis = my_strnncoll_sjis, my_strnxfrm_sjis, my_like_range_sjis, + my_wildcmp_mb, /* wildcmp */ 2, /* mbmaxlen */ ismbchar_sjis, ismbhead_sjis, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 04bf7107647..70f746c1605 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -688,10 +688,10 @@ void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length) CHARSET_INFO my_charset_tis620 = { - 18, /* number */ - MY_CS_COMPILED, /* state */ - "tis620", /* name */ - "", /* comment */ + 18, /* number */ + MY_CS_COMPILED, /* state */ + "tis620", /* name */ + "", /* comment */ ctype_tis620, to_lower_tis620, to_upper_tis620, @@ -702,17 +702,18 @@ CHARSET_INFO my_charset_tis620 = my_strnncoll_tis620, my_strnxfrm_tis620, my_like_range_tis620, + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ NULL, /* mbcharlen */ - my_mb_wc_8bit, /* mb_wc */ - my_wc_mb_8bit, /* wc_mb */ + my_mb_wc_8bit, /* mb_wc */ + my_wc_mb_8bit, /* wc_mb */ my_caseup_str_8bit, my_casedn_str_8bit, my_caseup_8bit, my_casedn_8bit, - NULL, /* tosort */ + NULL, /* tosort */ my_strcasecmp_8bit, my_strncasecmp_8bit, my_hash_caseup_simple, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 0eb82cc91dc..439db91294a 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8430,9 +8430,9 @@ my_wc_mb_euc_jp(CHARSET_INFO *c,my_wc_t wc, unsigned char *s, unsigned char *e) CHARSET_INFO my_charset_ujis = { 12, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED, /* state */ "ujis", /* name */ - "", /* comment */ + "", /* comment */ ctype_ujis, to_lower_ujis, to_upper_ujis, @@ -8443,6 +8443,7 @@ CHARSET_INFO my_charset_ujis = NULL, /* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_mb, /* wildcmp */ 3, /* mbmaxlen */ ismbchar_ujis, ismbhead_ujis, diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 898cc72b65c..d561702fc6f 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1955,9 +1955,9 @@ static int my_mbcharlen_utf8(CHARSET_INFO *cs __attribute__((unused)) , uint c) CHARSET_INFO my_charset_utf8 = { 33, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED, /* state */ "utf8", /* name */ - "", /* comment */ + "", /* comment */ ctype_utf8, /* ctype */ to_lower_utf8, /* to_lower */ to_upper_utf8, /* to_upper */ @@ -1968,6 +1968,7 @@ CHARSET_INFO my_charset_utf8 = my_strnncoll_utf8, /* strnncoll */ my_strnxfrm_utf8, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_mb, /* wildcmp */ 3, /* mbmaxlen */ my_ismbchar_utf8, /* ismbchar */ my_ismbhead_utf8, /* ismbhead */ @@ -1978,11 +1979,11 @@ CHARSET_INFO my_charset_utf8 = my_casedn_str_utf8, my_caseup_utf8, my_casedn_utf8, - NULL, /* tosort */ + NULL, /* tosort */ my_strcasecmp_utf8, my_strncasecmp_utf8, - my_hash_caseup_utf8,/* hash_caseup */ - my_hash_sort_utf8, /* hash_sort */ + my_hash_caseup_utf8,/* hash_caseup */ + my_hash_sort_utf8, /* hash_sort */ 0, my_snprintf_8bit, my_strtol_8bit, @@ -2372,7 +2373,7 @@ static int my_vsnprintf_ucs2(char *dst, uint n, const char* fmt, va_list ap) fmt++; /* Skip if max size is used (to be compatible with printf) */ - while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-') + while ( (*fmt>='0' && *fmt<='9') || *fmt == '.' || *fmt == '-') fmt++; if (*fmt == 'l') @@ -2472,9 +2473,9 @@ double my_strtod_ucs2(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_ucs2 = { 35, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED, /* state */ "ucs2", /* name */ - "", /* comment */ + "", /* comment */ ctype_ucs2, /* ctype */ to_lower_ucs2, /* to_lower */ to_upper_ucs2, /* to_upper */ @@ -2485,6 +2486,7 @@ CHARSET_INFO my_charset_ucs2 = my_strnncoll_ucs2, /* strnncoll */ my_strnxfrm_ucs2, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_mb, /* wildcmp */ 2, /* mbmaxlen */ my_ismbchar_ucs2, /* ismbchar */ my_ismbhead_ucs2, /* ismbhead */ @@ -2495,11 +2497,11 @@ CHARSET_INFO my_charset_ucs2 = my_casedn_str_ucs2, my_caseup_ucs2, my_casedn_ucs2, - NULL, /* tosort */ + NULL, /* tosort */ my_strcasecmp_ucs2, my_strncasecmp_ucs2, - my_hash_caseup_ucs2,/* hash_caseup */ - my_hash_sort_ucs2, /* hash_sort */ + my_hash_caseup_ucs2,/* hash_caseup */ + my_hash_sort_ucs2, /* hash_sort */ 0, my_snprintf_ucs2, my_strtol_ucs2, diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 3ef5b426bb4..dbb8d0e1a2f 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -636,6 +636,7 @@ CHARSET_INFO my_charset_win1250ch = my_strnncoll_win1250ch, my_strnxfrm_win1250ch, my_like_range_win1250ch, + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -646,7 +647,7 @@ CHARSET_INFO my_charset_win1250ch = my_casedn_str_8bit, my_caseup_8bit, my_casedn_8bit, - NULL, /* tosort */ + NULL, /* tosort */ my_strcasecmp_8bit, my_strncasecmp_8bit, my_hash_caseup_simple, diff --git a/strings/ctype.c b/strings/ctype.c index 4c16c47ae07..02774140c8d 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -2823,6 +2823,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -2865,6 +2866,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -2906,6 +2908,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -2947,6 +2950,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -2989,6 +2993,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3030,6 +3035,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3071,6 +3077,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3112,6 +3119,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3154,6 +3162,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3195,6 +3204,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3236,6 +3246,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3277,6 +3288,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3318,6 +3330,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3359,6 +3372,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3400,6 +3414,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3442,6 +3457,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3483,6 +3499,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3525,6 +3542,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3567,6 +3585,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3608,6 +3627,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3649,6 +3669,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3690,6 +3711,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3731,6 +3753,7 @@ static CHARSET_INFO compiled_charsets[] = { my_strnncoll_simple,/* strnncoll */ NULL, /* strnxfrm */ NULL, /* like_range */ + my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ NULL, /* ismbchar */ NULL, /* ismbhead */ @@ -3768,9 +3791,10 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ 0, - NULL, - NULL, - NULL, + NULL, /* strnncoll */ + NULL, /* strnxfrm */ + NULL, /* like_range */ + NULL, /* wildcmp */ 0, NULL, NULL,