php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #35386 firebird: first row is null
Submitted: 2005-11-25 11:38 UTC Modified: 2007-10-30 22:51 UTC
Votes:46
Avg. Score:4.9 ± 0.3
Reproduced:40 of 40 (100.0%)
Same Version:18 (45.0%)
Same OS:25 (62.5%)
From: slapaf at hotmail dot com Assigned: jacques
Status: Closed Package: PDO related
PHP Version: 5CVS-2006-12-02 (snap) OS: winxp sp2
Private report: No CVE-ID:
 [2005-11-25 11:38 UTC] slapaf at hotmail dot com
Description:
------------
When using PDO for simple query in Firebird it returns first row as null.
I've tried using ADODB for control and it returns the correct results. 

Reproduce code:
---------------
$dbh = new PDO("firebird:dbname=localhost:test.fdb","****","******");
	$sql='SELECT EVENT_NAME FROM EVENTS';

	foreach($dbh->query($sql) as $row){
		print '<pre>'.gettype($row['EVENT_NAME']).' : '.$row['EVENT_NAME'];
	}

Expected result:
----------------
string : name 1

string : name 2

string : name 3

string : name 4

Actual result:
--------------
NULL : 

string : name 2

string : name 3

string : name 4

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-02-08 18:49 UTC] turyak at gmail dot com
yep, experiencing same problem..
php 5.1.2, firebird 1.5.2
is there solution already?
 [2006-02-11 17:25 UTC] thomas at last-it dot de
same problem on linux, php 5.1.2
I tried to debug the problem, but imho the problem is strange.
The reason why the first row is null is as following:
file: ext/pdo/pdo_stmt.c
line: 532
<code>
case PDO_PARAM_STR:
  if (value && !(value_len == 0 && stmt->dbh->oracle_nulls == PDO_NULL_EMPTY_STRING)) {
    ZVAL_STRINGL(dest, value, value_len, !caller_frees);
    if (caller_frees) {
      caller_frees = 0;
    }
    break;
  }
default:
ZVAL_NULL(dest);
</code>
With the first returned row from DB the first if clause above evaluates to false.
so ZVAL_NULL is called. thats the reason for the null values in the first result set.

Normally should "value" point to the argument "ptr" of the firebird_stmt_get_col function (in firebird_statement.c).

gdp says that ptr is filled with the data out of DB properly.

So why is "value" not the same as "ptr" and why is this only in the first result set??

greetz Thomas
 [2006-03-10 09:49 UTC] astro101 at hotmail dot com
Yes had same problem WinXP SP2 Firebird 1.5.3 and firebird 2 and PHP 5.1.2, PHP5.1.3RC1, PHP5.1.3RC2.
 [2006-03-21 16:11 UTC] salbefe at inf dot upv dot es
I have the same problem in Windows 2003 SP1.
 [2006-03-27 22:32 UTC] wez@php.net
Looking for someone to maintain the firebird driver.
 [2006-05-04 13:06 UTC] krovomi at msn dot com
Does someone got a solution to this problem ?
Thanks
 [2006-05-27 12:54 UTC] stefan at horochovec dot com dot br

 [2006-07-07 10:06 UTC] mark at verndalesystems dot co dot uk
We have the same problem on Linux running FB 2.0 with PHP 5.1.1
 [2006-08-10 08:15 UTC] jacques@php.net
I'll tinker with this.  No promises though.
 [2007-01-22 20:00 UTC] tomp at tomaspenc dot com
Crazy solution, but it works:

$stmt = $db->prepare('SELECT * FROM table WHERE 2>?');
$stmt->execute(array(1));
while($radek = $stmt->fetch())
    print_r($radek);

All rows will be printed on the screen including the first.
When you use "prepare statement" with one or more parameters, you get all rows.

P.S: Srry for my bad english.
 [2007-04-23 08:47 UTC] no at reply dot cz
Hack didn't work without WHERE at all, with where only first column. Absolutely useless extension, going to try ibase_*()
 [2007-08-20 15:47 UTC] dong_peng at 163 dot com
I have met the same problem.

OS : Windows XP SP2
PHP: 5.2.3
Firebird : WI-V6.3.1.12855 Firebird 2.0 

I have a simple table named school in my database, the CREATE TABLE statement is as below :

CREATE TABLE school
( school_code SMALLINT PRIMARY KEY,
  school_name VARCHAR(40) NOT NULL,
  short_name  VARCHAR(20)
);
And there were total 14 rows in the table, the school_code was from 1 to 14.

When I submitted such a simple query "SELECT * FROM school order by school_code ASC " to the Firebird Server using PDO, the first row it returned is NULL,NULL,NULL, while the rest rows can be returned correctly. In other words only the first row in which the field 'school_code' should be 1 was not right.

Then I tested another query "SELECT * FROM school order by school_code DESC ", this time the field 'school_code' in the first row should be 14, however, the result of the first row was still NULL,NULL,NULL, while other rows was returned correctly, even the row in which the field 'school_code' was 1.

I have tested the following PDO functions :

1.foreach ( $conn->query($query) as $row )
    print_r( $row );

2.$rs=$conn->query($query);
  while( $row=$rs->fetch( ) )
      print_r( $row );

3.$rs=$conn->query($query);
  $data=$rs->fetchall( );
  foreach( $data as $row )
      print_r( $row );

I met the same problem in every test.

So, I tried to access Firebird directly. I used the ibase_* functions to query the same SQL statement, every row was returned correctly.

And, I have to use PDO to maintain my code in the future, so I tried to access firebird database via ODBC. This time, I also submitted the same query using PDO, fortunately, there was no error. Therefore,
I can continue my work with PDO/ODBC/Firebird. I think I can change the PDO DSN if this bug was corrected in the future.

So, I think there must be something wrong in the Firebird PDO driver.
I hope this problem will be solved as soon as possible.

Brook Dong Peng from China
2007-8-20
 [2007-10-04 09:11 UTC] tetikr at spytech dot cz
This is quite an old bug (2 years!) and yet not fixed in 5.2.4. Ridiculous! I'm using Doctrine with Firebird and it makes me crazy. Do something about it, please.
 [2007-10-09 00:07 UTC] acerb at softhome dot net
System : 
   Windows NT 5.1 build 2600 (MS Windows XP SP2)
   Apache 2.0
   PHP 5.1.2 & 5.2.3

I tried several methods :
   PDOStatement->fetchAll(), PDOStatement->fetch(), PDO->query()

with arguments :
   PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_LAZY, 
   PDO::FETCH_COLUMN, PDO::FETCH_GROUP

same result : First row is missing 
   Array ( 
      [LAN_ID] => 
      [LAN_NAME_EN] => 
      [LAN_CODE] => )
   Array ( 
      [LAN_ID] => 2 
      [LAN_NAME_EN] => FRENCH 
      [LAN_CODE] => FR )
   Array (
      [LAN_ID] => 3 
      [LAN_NAME_EN] => ENGLISH 
      [LAN_CODE] => EN )

I tried with different tables and select statements and I always got the same result. As it seems to be a pretty obvious bug/error, could it be corrected in the next release (of PHP), please ?
 [2007-10-12 17:31 UTC] Lars dot Westermann at privat dot dk
Well, tried to dig into this ...

After some trial and error, I found this little quick and dirty trick, which solves (or rather works around) another quick and dirty trick ...

Try this in etc/pdo_firebird/firebird_statement.c:

/* called by PDO to retrieve information about the fields being returned */
static int firebird_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{ */
{
    pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
    struct pdo_column_data *col = &stmt->columns[colno];
    XSQLVAR *var = &S->out_sqlda.sqlvar[colno];

    /* allocate storage for the column */
    var->sqlind = (void*)emalloc(var->sqllen + 2*sizeof(short));
    var->sqldata = &((char*)var->sqlind)[sizeof(short)];

    col->precision = -var->sqlscale;
    col->maxlen = var->sqllen;
    col->namelen = var->aliasname_length;
    col->name = estrndup(var->aliasname,var->aliasname_length);

    /* ====================================================
     * Compensates for hack in another function:
     * Force data-type in column to string
     */    
    col->param_type = PDO_PARAM_STR;
    /* ================================================= */

    return 1;
}
/* }}} */


The same hack is found in same module, in another function, but AFTER the columntype is set for the first row - hence it works for the subsequent rows ...

static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,  /* {{{ */
    unsigned long *len, int *caller_frees TSRMLS_DC)
{
    pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
    XSQLVAR const *var = &S->out_sqlda.sqlvar[colno];

    if (*var->sqlind == -1) {
        /* A NULL value */
        *ptr = NULL;
        *len = 0;
    } else {
        /* override the column param type */
        /* set_param_type(&stmt->columns[colno].param_type,var); */
=====>        stmt->columns[colno].param_type = PDO_PARAM_STR;

        if (var->sqlscale < 0) {
            static ISC_INT64 const scales[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
                100000000, 1000000000, 1000000000, LL_LIT(10000000000),LL_LIT(100000000000),


The row pointed to above (=====>) could/should be removed, as columntype definition _should_ be handled in firebird_stmt_describe() function (where my hack resides).

I have tested this with PHP 5.2.4 on Fedora Core 7 - and this hack works. I miss the total overview of PDO, so I can't reactivate the code-parts originally handling conversion from native Firebird/Interbase sql-type to PDO datatype constants. But this work should be done. If I have/get the time, and come to understand the code better, I would be happy to contribute.

For now I hope the above can help anyone, who compile the source, and that this quick and dirty hack can make it into the next release (5.2.5?) of PHP. It works, but is not the long term solution, I think.

Greetings,
Lars
 [2007-10-30 22:51 UTC] lwe@php.net
Fixed in CVS (PHP_5_3 branch)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Mon Apr 21 12:02:07 2014 UTC