Bug #17718 Unitialized variable used after ref to function in another database
Submitted: 25 Feb 2006 17:00 Modified: 3 Jun 2006 15:25
Reporter: Dave Pullin (Basic Quality Contributor) Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.0.18 OS:Linux (Linux)
Assigned to: CPU Architecture:Any

[25 Feb 2006 17:00] Dave Pullin
Description:
A select references a table in the default database and a function that belongs to another, explicitly named, database.  The reference to the default database attempts to use an uninitialized variable.

This problem occurs on Linux. It does NOT occur on Windows.

Console log

mysql> DELIMITER //
mysql> create database if not exists test 
    -> //
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create database if not exists test2 
    -> //
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> drop function if exists test.fn 
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE FUNCTION test.fn() RETURNS int  RETURN 1;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> connect test
Connection id:    2035
Current database: test

mysql> /* this works when the current database == database for function */
mysql> select test.fn() from xxxx
    -> //
ERROR 1146 (42S02): Table 'test.xxxx' doesn't exist
mysql> connect test2
Connection id:    2036
Current database: test2

mysql> /* this fails when the current database != database for function */
mysql> select test.fn() from xxxx
    -> //
ERROR 1146 (42S02): Table '¨ëÝ  XÎÖ     .xxxx' doesn't exist

How to repeat:
DELIMITER //
create database if not exists test 
//
create database if not exists test2 
//
drop function if exists test.fn 
//
CREATE FUNCTION test.fn() RETURNS int  RETURN 1;
//
connect test
/* this works when the current database == database for function */
select test.fn() from xxxx
//
connect test2
/* this fails when the current database != database for function */
select test.fn() from xxxx
//
[2 Apr 2006 12:48] Valeriy Kravchuk
Thank you for a problem report. Sorry, but I was not able to repeat the behaviour you described with 5.0.21-BK on Linux:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9 to server version: 5.0.21

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database test2;
Query OK, 1 row affected (0.02 sec)

mysql> delimiter //
mysql> CREATE FUNCTION test.fn() RETURNS int  RETURN 1;//
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;
mysql> connect test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Connection id:    10
Current database: test

mysql> select test.fn();
+-----------+
| test.fn() |
+-----------+
| 1         |
+-----------+
1 row in set (0.01 sec)

mysql> select test.fn() from xxxx;
ERROR 1146 (42S02): Table 'test.xxxx' doesn't exist
mysql> connect test2;
Connection id:    11
Current database: test2

mysql> select test.fn() from xxxx;
ERROR 1146 (42S02): Table 'test2.xxxx' doesn't exist
mysql> exit
Bye
openxs@suse:~/dbs/5.0> uname -a
Linux suse 2.6.11.4-20a-default #1 Wed Mar 23 21:52:37 UTC 2005 i686 i686 i386 GNU/Linux

So, please, try to repeat with a newer version, 5.0.19.
[23 Apr 2006 12:41] Dave Pullin
Fails under 5.0.19 on linux. does not fail on windows.

mysql> DELIMITER //  
mysql> create database if not exists test 
    -> //
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create database if not exists test2 
    -> //
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> drop function if exists test.fn 
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE FUNCTION test.fn() RETURNS int  RETURN 1;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> connect test
Connection id:    132392
Current database: test

mysql> /* this works when the current database == database for function */
mysql> select test.fn() from xxxx
    -> //
ERROR 1146 (42S02): Table 'test.xxxx' doesn't exist
mysql> connect test2
Connection id:    132393
Current database: test2

mysql> /* this fails when the current database != database for function */
mysql> select test.fn() from xxxx
    -> //
ERROR 1146 (42S02): Table 'lÂ
                            .xxxx' doesn't exist
mysql> select version();
    -> //
+---------------------+
| version()           |
+---------------------+
| 5.0.19-standard-log |
+---------------------+
1 row in set (0.00 sec)

mysql> quit
Bye
$ uname -a
Linux ColdLogic1 2.6.14-1.1637_FC4smp #1 SMP Wed Nov 9 19:21:28 EST 2005 x86_64 x86_64 x86_64 GNU/Linux
[24 Apr 2006 9:00] Per-Erik Martin
This looks like it might be the same as BUG#18444.
[25 Apr 2006 9:09] Per-Erik Martin
With valgrind:

==18360== Invalid read of size 1
==18360==    at 0x401D600: stpcpy (mac_replace_strmem.c:447)
==18360==    by 0x820DBC4: open_table(THD*, st_table_list*, st_mem_root*, bool*, unsigned) (sql_base.cc:1110)
==18360==    by 0x820EBFF: open_tables(THD*, st_table_list**, unsigned*, unsigned) (sql_base.cc:2051)
==18360==    by 0x820FCCF: open_and_lock_tables(THD*, st_table_list*) (sql_base.cc:2342)
==18360==    by 0x81E4C0F: mysql_execute_command(THD*) (sql_parse.cc:2449)
==18360==    by 0x81EC5D5: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:5678)
==18360==    by 0x81ECE61: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1719)
==18360==    by 0x81EE066: do_command(THD*) (sql_parse.cc:1515)
==18360==    by 0x81EED7D: handle_one_connection (sql_parse.cc:1158)
==18360==    by 0x405D296: start_thread (in /lib/tls/libpthread-2.3.5.so)
==18360==    by 0x419837D: clone (in /lib/tls/libc-2.3.5.so)
==18360==    by 0x7A59BAF: ???
==18360==  Address 0x55FB8C0 is 0 bytes inside a block of size 6 free'd
==18360==    at 0x401BF57: free (vg_replace_malloc.c:235)
==18360==    by 0x8511B81: my_no_flags_free (my_malloc.c:60)
==18360==    by 0x82C53C9: mysql_change_db(THD*, char const*, bool) (sql_db.cc:1184)
==18360==    by 0x83298A5: sp_use_new_db(THD*, char*, char*, unsigned, bool, bool*) (sp.cc:1856)
==18360==    by 0x832B39D: db_load_routine(THD*, int, sp_name*, sp_head**, unsigned long, char const*, char const*, char const*, st_sp_chistics&, char const*, long long, long long) (sp.cc:455)
==18360==    by 0x832B99E: db_find_routine(THD*, int, sp_name*, sp_head**) (sp.cc:391)
==18360==    by 0x832BB4A: sp_cache_routines_and_add_tables_aux(THD*, st_lex*, Sroutine_hash_entry*, bool, bool*) (sp.cc:1578)
==18360==    by 0x832BE93: sp_cache_routines_and_add_tables(THD*, st_lex*, bool, bool*) (sp.cc:1667)
==18360==    by 0x820EB16: open_tables(THD*, st_table_list**, unsigned*, unsigned) (sql_base.cc:2010)
==18360==    by 0x820FCCF: open_and_lock_tables(THD*, st_table_list*) (sql_base.cc:2342)
==18360==    by 0x81E4C0F: mysql_execute_command(THD*) (sql_parse.cc:2449)
==18360==    by 0x81EC5D5: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:5678)
==18360==    by 0x81ECE61: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1719)
==18360==    by 0x81EE066: do_command(THD*) (sql_parse.cc:1515)
==18360==    by 0x81EED7D: handle_one_connection (sql_parse.cc:1158)
==18360==    by 0x405D296: start_thread (in /lib/tls/libpthread-2.3.5.so)
==18360== 
==18360== Invalid read of size 1
==18360==    at 0x401D60A: stpcpy (mac_replace_strmem.c:447)
==18360==    by 0x820DBC4: open_table(THD*, st_table_list*, st_mem_root*, bool*, unsigned) (sql_base.cc:1110)
==18360==    by 0x820EBFF: open_tables(THD*, st_table_list**, unsigned*, unsigned) (sql_base.cc:2051)
==18360==    by 0x820FCCF: open_and_lock_tables(THD*, st_table_list*) (sql_base.cc:2342)
==18360==    by 0x81E4C0F: mysql_execute_command(THD*) (sql_parse.cc:2449)
==18360==    by 0x81EC5D5: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:5678)
==18360==    by 0x81ECE61: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1719)
==18360==    by 0x81EE066: do_command(THD*) (sql_parse.cc:1515)
==18360==    by 0x81EED7D: handle_one_connection (sql_parse.cc:1158)
==18360==    by 0x405D296: start_thread (in /lib/tls/libpthread-2.3.5.so)
==18360==    by 0x419837D: clone (in /lib/tls/libc-2.3.5.so)
==18360==    by 0x7A59BAF: ???
==18360==  Address 0x55FB8C1 is 1 bytes inside a block of size 6 free'd
==18360==    at 0x401BF57: free (vg_replace_malloc.c:235)
==18360==    by 0x8511B81: my_no_flags_free (my_malloc.c:60)
==18360==    by 0x82C53C9: mysql_change_db(THD*, char const*, bool) (sql_db.cc:1184)
==18360==    by 0x83298A5: sp_use_new_db(THD*, char*, char*, unsigned, bool, bool*) (sp.cc:1856)
==18360==    by 0x832B39D: db_load_routine(THD*, int, sp_name*, sp_head**, unsigned long, char const*, char const*, char const*, st_sp_chistics&, char const*, long long, long long) (sp.cc:455)
==18360==    by 0x832B99E: db_find_routine(THD*, int, sp_name*, sp_head**) (sp.cc:391)
==18360==    by 0x832BB4A: sp_cache_routines_and_add_tables_aux(THD*, st_lex*, Sroutine_hash_entry*, bool, bool*) (sp.cc:1578)
==18360==    by 0x832BE93: sp_cache_routines_and_add_tables(THD*, st_lex*, bool, bool*) (sp.cc:1667)
==18360==    by 0x820EB16: open_tables(THD*, st_table_list**, unsigned*, unsigned) (sql_base.cc:2010)
==18360==    by 0x820FCCF: open_and_lock_tables(THD*, st_table_list*) (sql_base.cc:2342)
==18360==    by 0x81E4C0F: mysql_execute_command(THD*) (sql_parse.cc:2449)
==18360==    by 0x81EC5D5: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:5678)
==18360==    by 0x81ECE61: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1719)
==18360==    by 0x81EE066: do_command(THD*) (sql_parse.cc:1515)
==18360==    by 0x81EED7D: handle_one_connection (sql_parse.cc:1158)
==18360==    by 0x405D296: start_thread (in /lib/tls/libpthread-2.3.5.so)
/...etc.../
[3 Jun 2006 15:25] Valeriy Kravchuk
I was not able to repeat with -debug builds of 5.0.23-BK and 5.1.12-BK:

openxs@suse:~/dbs/5.1> bin/mysql -uroot test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2 to server version: 5.1.12-beta-debug

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> delimiter //
mysql> create database if not exists test2 //
Query OK, 1 row affected (0.00 sec)

mysql> drop function if exists test.fn //
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> CREATE FUNCTION test.fn() RETURNS int  RETURN 1;
    -> //
Query OK, 0 rows affected (0.01 sec)

mysql> connect test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Connection id:    3
Current database: test

mysql> select test.fn() from xxxx//
ERROR 1146 (42S02): Table 'test.xxxx' doesn't exist
mysql> connect test2
Connection id:    4
Current database: test2

mysql> select test.fn() from xxxx//
ERROR 1146 (42S02): Table 'test2.xxxx' doesn't exist

I'll try to reverify later, when bug #18444 will be officially fixed. With both -debug and -valgrind builds.