php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #44190 SELECT 1 and PDO::FETCH_BOTH
Submitted: 2008-02-20 19:01 UTC Modified: 2008-02-21 14:18 UTC
From: uwendel at mysql dot com Assigned:
Status: Not a bug Package: PDO related
PHP Version: 5.3CVS-2008-02-20 (CVS) OS: Linux 64
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: uwendel at mysql dot com
New email:
PHP Version: OS:

 

 [2008-02-20 19:01 UTC] uwendel at mysql dot com
Description:
------------
"PDO::FETCH_BOTH (default): returns an array indexed by both column name and 0-indexed column number as returned in your result set",
http://de.php.net/manual/en/function.PDOStatement-fetch.php

[1] This looks like a wrong result for PDO::FETCH_BOTH to me: 

 SELECT 1 -> 
 array(1 => "1", 2 => "2")

Looks as if PDO uses the "1" as an index offset and does not start the column numbering at 0 but at "1". 

[2] Try the same with SELECT 2 and you see what I mean:

 SELECT 2 ->
 array(2 => "2", 3 => "2")

I'd rather expect something like:

 SELECT 1 ->
 array(0 => "1", 1 => "1")

Or in pseudo-code:

 FETCH::BOTH == array_merge(FETCH::ASSOC, FETCH_NUM)









Reproduce code:
---------------
[1] LD_LIBRARY_PATH=/usr/lib/oracle/10.2.0.3/client/lib sapi/cli/php -r '$pdo=new PDO("oci:dbname=//localhost:1521/XE", "SYSTEM", "oracle"); var_dump($pdo->query("SELECT 1 FROM DUAL")->fetch(PDO::FETCH_BOTH));'
array(2) {
  [1]=>
  string(1) "1"
  [2]=>
  string(1) "1"
}

[2] nixnutz@ulflinux:~/php53> LD_LIBRARY_PATH=/usr/lib/oracle/10.2.0.3/client/lib sapi/cli/php -r '$pdo=new PDO("sqlite:/tmp/foo.db"); var_dump($pdo->query("SELECT 2")->fetch(PDO::FETCH_BOTH));'
array(2) {
  [2]=>
  string(1) "2"
  [3]=>
  string(1) "2"
}



This is my failing MySQL test, don't know if its for use of you. Someone would need to port it to all other drivers to make it useful.

--TEST--
MySQL PDOStatement->fetch()
--SKIPIF--
<?php
require_once('skipif.inc');
require_once('mysql_pdo_test.inc');
MySQLPDOTest::skip();
$db = MySQLPDOTest::factory();
?>
--FILE--
<?php
	require_once('mysql_pdo_test.inc');
	$db = MySQLPDOTest::factory();

	function fetch($offset, &$db, $query, $expect = null) {

		try {
			$stmt = $db->query('SELECT 1');
			$num = $stmt->fetch(PDO::FETCH_NUM);

			$stmt = $db->query('SELECT 1');
			$assoc = $stmt->fetch(PDO::FETCH_ASSOC);

			$stmt = $db->query('SELECT 1');
			$both = $stmt->fetch(PDO::FETCH_BOTH);

			$computed_both = array_merge($num, $assoc);
			if ($computed_both != $both) {
				printf("[%03d] Suspicious FETCH_BOTH result, dumping\n", $offset);
				var_dump($computed_both);
				var_dump($both);
			}

			if (!is_null($expect) && ($expect != $both)) {
				printf("[%03d] Expected differes from returned data, dumping\n", $offset);
				var_dump($expect);
				var_dump($both);
			}

		} catch (PDOException $e) {

			printf("[%03d] %s, [%s] %s\n",
				$offset,
				$e->getMessage(), $db->errroCode(), implode(' ', $db->errorInfo()));

		}

	}

	try {

		fetch(2, &$db, 'SELECT 1', array(0 => '1', '1' => '1'));

	} catch (PDOException $e) {
		printf("[001] %s [%s] %s\n",
			$e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
	}
	print "done!";
--BUGFREE_EXPECTF--
done!
--EXPECTF--
[002] Suspicious FETCH_BOTH result, dumping
array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "1"
}
array(2) {
  [1]=>
  string(1) "1"
  [2]=>
  string(1) "1"
}
[002] Expected differes from returned data, dumping
array(2) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "1"
}
array(2) {
  [1]=>
  string(1) "1"
  [2]=>
  string(1) "1"
}
done!


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-02-21 13:16 UTC] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

The name of the column conflicts with numeric indexes.
 [2008-02-21 13:48 UTC] uwendel at mysql dot com
Sure, the name does conflict with the column index. That's the purpose of the test.

According to the manual PDO::FETCH_BOTH is said to return an array indexed by:

 a) column name
 b) 0-indexed column number

If you have only one column, the 0-indexed column number is 0. But the current implementation does not reflect that.

Let's compute the result manually for a query like SELECT 1 AS "1" FROM DUAL and apply the rules from the manual.

 a) column name - "1"
 b) 0-indexed column number - 0

Putting that together you get:

 array([a] "1" => "1", [b] 0 => "1")


And its not like this:

 a) column name - "1"
 b) 0-indexed, hmm, lets consider the column name as an offset - 2

This result remains wrong:

 array([a] "1" => "1", [b] 2 => "1")
 [2008-02-21 14:18 UTC] uwendel at mysql dot com
Ok, got it. The fun is stuff like SELECT 1, 2.

What about a hint in the documentation?
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 19:01:29 2024 UTC