php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #25460 mysql_list_fields does NOT use link_identifier
Submitted: 2003-09-09 15:09 UTC Modified: 2004-04-08 01:52 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: beckman at purplecow dot com Assigned:
Status: Closed Package: Documentation problem
PHP Version: 4.3.3 OS: FreeBSD 5.0-RELEASE #0
Private report: No CVE-ID: None
 [2003-09-09 15:09 UTC] beckman at purplecow dot com
Description:
------------
Synopsis: mysql_list_fields should ignore the currently selected database, since the name of the database is clearly being passed to the function.  But the function uses the currently selected database rather than the database specified in the function.  

Evidence:
Using MySQL 4.0.14 and PHP 4.3.3, mysql_list_fields($db, $tbl, $link_identifier) uses the most recent connection to mysql, not the connection specified in $link_identifier.

I've tried to reproduce this problem, and the only place I can is in phpMyAdmin 2.5.4 dev.

It seems that mysql_list_fields ignores the link_identifier it is passed and uses either DB "mysql" or uses the most recent connection.

When testing, here's what I did.

In phpMyAdmin, I selected my database, then selected "Query."

I now get an error saying "#1146 - Table 'mysql.assignments' doesn't exist".

So I got into the code in db_details_qbe.php.  On line 132, this line occurs:

    $fld_results     = @PMA_mysql_list_fields($db, $tbl) or PMA_mysqlDie(PMA_mysql_error(), 'PMA_mysql_list_fields(' . $db . ', ' . $tbl . ')', FALSE, $err_url);

The function is as this:

    function PMA_mysql_list_fields($database_name, $table_name, $link_identifier = FALSE) {
        if ($link_identifier != FALSE) {
            return mysql_list_fields(PMA_convert_charset($database_name), PMA_convert_charset($table_name), $link_identifier);
        } else {
            return mysql_list_fields(PMA_convert_charset($database_name), PMA_convert_charset($table_name));
        }
    }

When echo'ed, it was executed as "mysql_list_fields("crt", "assignments").  So I decided I should try using the link identifier explicitly.

    $fld_results     = @PMA_mysql_list_fields($db, $tbl, $userlink) or PMA_mysqlDie(PMA_mysql_error(), 'PMA_mysql_list_fields(' . $db . ', ' . $tbl . ')', FALSE, $err_url);

Got the same error.  So then I was concerned that $userlink wasn't the correct link to the database in question.  So I did this on line 131:

   $r = mysql_query("Show tables from ".$db, $userlink);
   while($row = mysql_fetch_array($r)) { print_r($row); }

And it gave me a list of all the tables, including assignments (first).  So I dropped the $userlink from the above code and tried it again.  Worked.  So then I thought, maybe $userlink isn't using the mysql_select_db that I think it is.  So I changed the query to "select count(*) from assignments" and it failed, so I assume $userlink is working off of the assumption that the currently selected database is "mysql."  

mysql_list_fields should ignore the currently selected database, since the name of the database is clearly being passed to the function.  But the function uses the currently selected database rather than the database specified in the function.  

Reproduction:
I wasn't able to use a simple $link = mysql_connect, mysql_select_db, then see mysql_list_fields fail.  I went through the phpMyAdmin code as completely as possible, but I'm fairly certain that it is a fault in the php functions, based on the documentation.  I believe it may be related to or similar to Bug #22661.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-09-09 15:47 UTC] sniper@php.net
This works as advertised. phpMyadmin is broken.

 [2003-09-10 03:43 UTC] georg@php.net
mysql_list_fields is deprecated, use SHOW COLUMNS FROM table 
[LIKE 'foo'] instead. 
 
This should be documented in the manual. Reclassified as 
documentation bug. 
 [2003-09-10 03:43 UTC] georg@php.net
assigned to myself 
 [2003-09-10 03:50 UTC] georg@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.


 [2003-09-10 13:00 UTC] beckman at purplecow dot com
If your supposition is correct (phpMyAdmin is broken), then why would mysql_list_fields("crt", "assignments") with a currently valid open link to the database attempt to use the table mysql.assignments?  Even if you give it a link, it uses the mysql database to find the table.

While I'm not a C/C++ programmer, I read the code for that function.  I noticed that ZEND_FETCH_RESOURCE2 was added in 4.0 beta 3, and wonder if THAT function is somehow causing this obscure occurence of this bug.  

Why do I think it is a bug?  Because mysql_list_fields DOES work as advertised in the code I could come up with.  HOWEVER, in that specific example in phpMyAdmin, it does not.  I'm wondering if somehow ZEND_FETCH_RESOURCE2 is returning the wrong mysql->conn that is being used to connect to the DB and list the fields from a table.  

If any connection to a database can be used to read any DB from that connection, and just before running mysql_list_fields I can do a "show fields from crt.assignments" and it works using both a defined link_resource or leaving it blank (using the currently selected connection), why would mysql_list_fields("crt", "assignments") fail on the next line?

I swear it isn't bogus.  And if it is, I'll buy you a beer or something and hang my head in shame.
 [2003-09-10 13:03 UTC] beckman at purplecow dot com
Whoops.  Now that you've marked it depreciated, I withdrawal my bug report!  I'll get phpMyAdmin to stop using it, and thus this bug goes away.  But just for me feeling good, can you not mark it bogus?  That makes me feel like less of a man, and much less of a geek... :-)  A closed would be so much better.
 [2003-09-10 15:09 UTC] beckman at purplecow dot com
So are mysql_field_* depreciated as well?  Should they be marked as such in the documentation?  

You might want to put a nice replacement function in the documentation for mysql_list_fields (and other depreciated functions) to allow people to migrate away from mysql_list_fields smoothly and easily without doing trial and error.  I haven't yet figured out how to do this while continuing using mysql_field_* functions.  mysql_query("SHOW FIELDS FROM db.table") doesn't return the same data in the same format as mysql_list_fields does.
 [2003-09-10 15:19 UTC] beckman at purplecow dot com
changed to Documentation problem (if in fact mysql_field_* functions are depreciated and not listed as such).
 [2003-09-10 16:39 UTC] beckman at purplecow dot com
Please also add to the documentation an example of what to replace the now depreciated mysql_list_fields with:

 replace: $result = mysql_list_fields($db, $table [, $link])
    with: $result = mysql_query("SELECT * FROM ".$db.".".$table." LIMIT 1" [, $link])

 Works with mysql_field_* functions (at least it seems to) correctly.

 Since mysql_list_fields is now depreciated, you might want to check your code out soon/now to make sure you don't get screwed when the PHP team takes mysql_list_fields out of PHP entirely.
 [2004-04-08 01:52 UTC] irchtml@php.net
There are notes on the mysql_* function pages of deprecated functions and alternatives to use.  The mysql_field_* functions are not deprecated.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 21:01:36 2024 UTC