From 8109934e1d7af65d16eae90c0d301aa95f138d03 Mon Sep 17 00:00:00 2001 From: "patg@krsna.patg.net" <> Date: Sun, 31 Jul 2005 21:28:52 -0700 Subject: [PATCH 1/4] BUG 11104 (same as changeset 1.1891 on the 5.0 tree, but realised this needed to be fixed in earlier versions) Fixed the iteration of how substrings are handled with negative indexes in SUBSTRING_INDEX --- mysql-test/r/func_str.result | 117 +++++++++++++++++++++++++++++++++++ mysql-test/t/func_str.test | 39 ++++++++++++ sql/item_strfunc.cc | 16 ++++- 3 files changed, 170 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 6fe71f97edd..6fefbb16353 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -38,6 +38,123 @@ www. .se select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1); substring_index('.tcx.se','.',-2) substring_index('.tcx.se','.tcx',-1) tcx.se .se +select substring_index('aaaaaaaaa1','a',1); +substring_index('aaaaaaaaa1','a',1) + +select substring_index('aaaaaaaaa1','aa',1); +substring_index('aaaaaaaaa1','aa',1) + +select substring_index('aaaaaaaaa1','aa',2); +substring_index('aaaaaaaaa1','aa',2) +aa +select substring_index('aaaaaaaaa1','aa',3); +substring_index('aaaaaaaaa1','aa',3) +aaaa +select substring_index('aaaaaaaaa1','aa',4); +substring_index('aaaaaaaaa1','aa',4) +aaaaaa +select substring_index('aaaaaaaaa1','aa',5); +substring_index('aaaaaaaaa1','aa',5) +aaaaaaaaa1 +select substring_index('aaaaaaaaa1','aaa',1); +substring_index('aaaaaaaaa1','aaa',1) + +select substring_index('aaaaaaaaa1','aaa',2); +substring_index('aaaaaaaaa1','aaa',2) +aaa +select substring_index('aaaaaaaaa1','aaa',3); +substring_index('aaaaaaaaa1','aaa',3) +aaaaaa +select substring_index('aaaaaaaaa1','aaa',4); +substring_index('aaaaaaaaa1','aaa',4) +aaaaaaaaa1 +select substring_index('aaaaaaaaa1','aaaa',1); +substring_index('aaaaaaaaa1','aaaa',1) + +select substring_index('aaaaaaaaa1','aaaa',2); +substring_index('aaaaaaaaa1','aaaa',2) +aaaa +select substring_index('aaaaaaaaa1','1',1); +substring_index('aaaaaaaaa1','1',1) +aaaaaaaaa +select substring_index('aaaaaaaaa1','a',-1); +substring_index('aaaaaaaaa1','a',-1) +1 +select substring_index('aaaaaaaaa1','aa',-1); +substring_index('aaaaaaaaa1','aa',-1) +1 +select substring_index('aaaaaaaaa1','aa',-2); +substring_index('aaaaaaaaa1','aa',-2) +aa1 +select substring_index('aaaaaaaaa1','aa',-3); +substring_index('aaaaaaaaa1','aa',-3) +aaaa1 +select substring_index('aaaaaaaaa1','aa',-4); +substring_index('aaaaaaaaa1','aa',-4) +aaaaaa1 +select substring_index('aaaaaaaaa1','aa',-5); +substring_index('aaaaaaaaa1','aa',-5) +aaaaaaaaa1 +select substring_index('aaaaaaaaa1','aaa',-1); +substring_index('aaaaaaaaa1','aaa',-1) +1 +select substring_index('aaaaaaaaa1','aaa',-2); +substring_index('aaaaaaaaa1','aaa',-2) +aaa1 +select substring_index('aaaaaaaaa1','aaa',-3); +substring_index('aaaaaaaaa1','aaa',-3) +aaaaaa1 +select substring_index('aaaaaaaaa1','aaa',-4); +substring_index('aaaaaaaaa1','aaa',-4) + +select substring_index('the king of thethe hill','the',-2); +substring_index('the king of thethe hill','the',-2) +the hill +select substring_index('the king of the the hill','the',-2); +substring_index('the king of the the hill','the',-2) + the hill +select substring_index('the king of the the hill','the',-2); +substring_index('the king of the the hill','the',-2) + the hill +select substring_index('the king of the the hill',' the ',-1); +substring_index('the king of the the hill',' the ',-1) +hill +select substring_index('the king of the the hill',' the ',-2); +substring_index('the king of the the hill',' the ',-2) + the hill +select substring_index('the king of the the hill',' ',-1); +substring_index('the king of the the hill',' ',-1) +hill +select substring_index('the king of the the hill',' ',-2); +substring_index('the king of the the hill',' ',-2) +the hill +select substring_index('the king of the the hill',' ',-3); +substring_index('the king of the the hill',' ',-3) + the hill +select substring_index('the king of the the hill',' ',-4); +substring_index('the king of the the hill',' ',-4) +the the hill +select substring_index('the king of the the hill',' ',-5); +substring_index('the king of the the hill',' ',-5) +of the the hill +select substring_index('the king of the.the hill','the',-2); +substring_index('the king of the.the hill','the',-2) +.the hill +select substring_index('the king of thethethe.the hill','the',-3); +substring_index('the king of thethethe.the hill','the',-3) +the.the hill +select substring_index('the king of thethethe.the hill','the',-1); +substring_index('the king of thethethe.the hill','the',-1) + hill +select substring_index('the king of the the hill','the',1); +substring_index('the king of the the hill','the',1) + +select substring_index('the king of the the hill','the',2); +substring_index('the king of the the hill','the',2) +the king of +select substring_index('the king of the the hill','the',3); +substring_index('the king of the the hill','the',3) +the king of the select concat(':',ltrim(' left '),':',rtrim(' right '),':'); concat(':',ltrim(' left '),':',rtrim(' right '),':') :left : right: diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 9dac1d823d9..81d5daaf0ba 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -19,6 +19,45 @@ select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',s select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1); select substring_index('www.tcx.se','tcx',1),substring_index('www.tcx.se','tcx',-1); select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1); +select substring_index('aaaaaaaaa1','a',1); +select substring_index('aaaaaaaaa1','aa',1); +select substring_index('aaaaaaaaa1','aa',2); +select substring_index('aaaaaaaaa1','aa',3); +select substring_index('aaaaaaaaa1','aa',4); +select substring_index('aaaaaaaaa1','aa',5); +select substring_index('aaaaaaaaa1','aaa',1); +select substring_index('aaaaaaaaa1','aaa',2); +select substring_index('aaaaaaaaa1','aaa',3); +select substring_index('aaaaaaaaa1','aaa',4); +select substring_index('aaaaaaaaa1','aaaa',1); +select substring_index('aaaaaaaaa1','aaaa',2); +select substring_index('aaaaaaaaa1','1',1); +select substring_index('aaaaaaaaa1','a',-1); +select substring_index('aaaaaaaaa1','aa',-1); +select substring_index('aaaaaaaaa1','aa',-2); +select substring_index('aaaaaaaaa1','aa',-3); +select substring_index('aaaaaaaaa1','aa',-4); +select substring_index('aaaaaaaaa1','aa',-5); +select substring_index('aaaaaaaaa1','aaa',-1); +select substring_index('aaaaaaaaa1','aaa',-2); +select substring_index('aaaaaaaaa1','aaa',-3); +select substring_index('aaaaaaaaa1','aaa',-4); +select substring_index('the king of thethe hill','the',-2); +select substring_index('the king of the the hill','the',-2); +select substring_index('the king of the the hill','the',-2); +select substring_index('the king of the the hill',' the ',-1); +select substring_index('the king of the the hill',' the ',-2); +select substring_index('the king of the the hill',' ',-1); +select substring_index('the king of the the hill',' ',-2); +select substring_index('the king of the the hill',' ',-3); +select substring_index('the king of the the hill',' ',-4); +select substring_index('the king of the the hill',' ',-5); +select substring_index('the king of the.the hill','the',-2); +select substring_index('the king of thethethe.the hill','the',-3); +select substring_index('the king of thethethe.the hill','the',-1); +select substring_index('the king of the the hill','the',1); +select substring_index('the king of the the hill','the',2); +select substring_index('the king of the the hill','the',3); select concat(':',ltrim(' left '),':',rtrim(' right '),':'); select concat(':',trim(LEADING FROM ' left'),':',trim(TRAILING FROM ' right '),':'); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 930014de771..f070382e5c1 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1084,11 +1084,23 @@ String *Item_func_substr_index::val_str(String *str) } } else - { // Start counting at end - for (offset=res->length() ; ; offset-=delimeter_length-1) + { + /* + Negative index, start counting at the end + */ + for (offset=res->length(); offset ;) { + /* + this call will result in finding the position pointing to one + address space less than where the found substring is located + in res + */ if ((int) (offset=res->strrstr(*delimeter,offset)) < 0) return res; // Didn't find, return org string + /* + At this point, we've searched for the substring + the number of times as supplied by the index value + */ if (!++count) { offset+=delimeter_length; From 1dff783854d165611beb35a14f7ee7c853903bd6 Mon Sep 17 00:00:00 2001 From: "bell@52.0.168.192.in-addr.arpa" <> Date: Wed, 10 Aug 2005 18:58:55 +0300 Subject: [PATCH 2/4] block using QC in case of having tables locked by LOCK... (BUG#12385) --- mysql-test/r/query_cache_noembeded.result | 18 +++++++++++++ mysql-test/t/query_cache_noembeded.test | 33 +++++++++++++++++++++++ sql/sql_cache.cc | 7 +++-- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/query_cache_noembeded.result create mode 100644 mysql-test/t/query_cache_noembeded.test diff --git a/mysql-test/r/query_cache_noembeded.result b/mysql-test/r/query_cache_noembeded.result new file mode 100644 index 00000000000..f2b06eea45d --- /dev/null +++ b/mysql-test/r/query_cache_noembeded.result @@ -0,0 +1,18 @@ +set GLOBAL query_cache_size=1355776; +reset query cache; +flush status; +CREATE TABLE t1 ( a INT NOT NULL PRIMARY KEY AUTO_INCREMENT ) ENGINE = +MyISAM; +LOCK TABLE t1 READ LOCAL; +INSERT INTO t1 VALUES (), (), (); +SELECT * FROM t1; +a +SELECT * FROM t1; +a +1 +2 +3 +SELECT * FROM t1; +a +drop table t1; +set GLOBAL query_cache_size=default; diff --git a/mysql-test/t/query_cache_noembeded.test b/mysql-test/t/query_cache_noembeded.test new file mode 100644 index 00000000000..c909bfcdf3b --- /dev/null +++ b/mysql-test/t/query_cache_noembeded.test @@ -0,0 +1,33 @@ +-- source include/have_query_cache.inc +-- source include/not_embedded.inc + +# +# Tests with query cache +# +set GLOBAL query_cache_size=1355776; + +# Reset query cache variables. + +reset query cache; +flush status; + +# +# do not use QC if tables locked (BUG#12385) +# +connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock); +connection root; +CREATE TABLE t1 ( a INT NOT NULL PRIMARY KEY AUTO_INCREMENT ) ENGINE = +MyISAM; +LOCK TABLE t1 READ LOCAL; +connect (root2,localhost,root,,test,$MASTER_MYPORT,master.sock); +connection root2; +INSERT INTO t1 VALUES (), (), (); +connection root; +SELECT * FROM t1; +connection root2; +SELECT * FROM t1; +connection root; +SELECT * FROM t1; +drop table t1; + +set GLOBAL query_cache_size=default; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index d729a6cc301..667b6e546d3 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -739,7 +739,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) TABLE_COUNTER_TYPE local_tables; ulong tot_length; DBUG_ENTER("Query_cache::store_query"); - if (query_cache_size == 0) + if (query_cache_size == 0 || thd->locked_tables) DBUG_VOID_RETURN; if ((local_tables= is_cacheable(thd, thd->query_length, @@ -750,7 +750,10 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) STRUCT_LOCK(&structure_guard_mutex); if (query_cache_size == 0) + { + STRUCT_UNLOCK(&structure_guard_mutex); DBUG_VOID_RETURN; + } DUMP(this); /* Key is query + database + flag */ @@ -874,7 +877,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) byte flags; DBUG_ENTER("Query_cache::send_result_to_client"); - if (query_cache_size == 0 || + if (query_cache_size == 0 || thd->locked_tables || /* it is not possible to check has_transactions() function of handler because tables not opened yet From 66a055b4d6e944dd3e8467b67743954000c72bba Mon Sep 17 00:00:00 2001 From: "bell@51.0.168.192.in-addr.arpa" <> Date: Thu, 11 Aug 2005 09:29:50 +0300 Subject: [PATCH 3/4] make the same filenames as in 4.1 --- ...uery_cache_noembeded.result => query_cache_notembedded.result} | 0 .../{query_cache_noembeded.test => query_cache_notembedded.test} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename mysql-test/r/{query_cache_noembeded.result => query_cache_notembedded.result} (100%) rename mysql-test/t/{query_cache_noembeded.test => query_cache_notembedded.test} (100%) diff --git a/mysql-test/r/query_cache_noembeded.result b/mysql-test/r/query_cache_notembedded.result similarity index 100% rename from mysql-test/r/query_cache_noembeded.result rename to mysql-test/r/query_cache_notembedded.result diff --git a/mysql-test/t/query_cache_noembeded.test b/mysql-test/t/query_cache_notembedded.test similarity index 100% rename from mysql-test/t/query_cache_noembeded.test rename to mysql-test/t/query_cache_notembedded.test From 3b64651683a6f8d9276fd49843832f672312f880 Mon Sep 17 00:00:00 2001 From: "sanja@arthur.local" <> Date: Thu, 11 Aug 2005 13:07:08 +0300 Subject: [PATCH 4/4] query_cache_notembedded.test, query_cache_notembedded.result: postmerge fix --- mysql-test/r/query_cache_notembedded.result | 14 ++++++++++++++ mysql-test/t/query_cache_notembedded.test | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result index 16a397f78b6..e773a63525b 100644 --- a/mysql-test/r/query_cache_notembedded.result +++ b/mysql-test/r/query_cache_notembedded.result @@ -80,4 +80,18 @@ show status like "Qcache_free_blocks"; Variable_name Value Qcache_free_blocks 1 drop table t1, t2, t3, t11, t21; +CREATE TABLE t1 ( a INT NOT NULL PRIMARY KEY AUTO_INCREMENT ) ENGINE = +MyISAM; +LOCK TABLE t1 READ LOCAL; +INSERT INTO t1 VALUES (), (), (); +SELECT * FROM t1; +a +SELECT * FROM t1; +a +1 +2 +3 +SELECT * FROM t1; +a +drop table t1; set GLOBAL query_cache_size=0; diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index d29dc10ccae..fd4785ffe95 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -78,4 +78,23 @@ show status like "Qcache_total_blocks"; show status like "Qcache_free_blocks"; drop table t1, t2, t3, t11, t21; +# +# do not use QC if tables locked (BUG#12385) +# +connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock); +connection root; +CREATE TABLE t1 ( a INT NOT NULL PRIMARY KEY AUTO_INCREMENT ) ENGINE = +MyISAM; +LOCK TABLE t1 READ LOCAL; +connect (root2,localhost,root,,test,$MASTER_MYPORT,master.sock); +connection root2; +INSERT INTO t1 VALUES (), (), (); +connection root; +SELECT * FROM t1; +connection root2; +SELECT * FROM t1; +connection root; +SELECT * FROM t1; +drop table t1; + set GLOBAL query_cache_size=0;