Uploaded image for project: 'phpBB3'
  1. phpBB3
  2. PHPBB3-10858

$db->sql_fetchfield returns false with mssqlnative

    Details

      Description

      hi,

      I'm debugging a mod in mssql and have trouble with sql_fetchfield in mssql. it returns false every time. However the query is ok when i run it in a session.

      $db->sql_fetchfield calls sql_rowseek and then the result_mssqlnative class is initialised. Thereby it calls sqlsrv_fetch_array a first time and loops the row once.

      After that it passes through the sql_fetchrow function in mssqlnative.php and calls sqlsrv_fetch_array a second time. this time the $row is empty because there is no next row to be fetched.

      $db->sql_fetchfield then returns false to the caller.

      So i think there's a bug in this class.

        Activity

        Hide
        Noxwizard Patrick Webster added a comment -

        It's currently passing unit tests for fetchfield. Can you show how you're using it? Also, is sqlsrv_fetch_array returning NULL or false? If it's NULL, then there are no more rows, if it's false, then there was an error and you can try printing out the contents of sqlsrv_errors() to see if there are any messages.

        Show
        Noxwizard Patrick Webster added a comment - It's currently passing unit tests for fetchfield. Can you show how you're using it? Also, is sqlsrv_fetch_array returning NULL or false? If it's NULL, then there are no more rows, if it's false, then there was an error and you can try printing out the contents of sqlsrv_errors() to see if there are any messages.
        Hide
        Sajaki Sajaki added a comment - - edited

        in dbal.sql_fetchfield, if rownum is not false,

        $row = $this->sql_fetchrow($query_id);

        returns false

        and sqlsrv_errors is an array of 1.
        code = (int) -22
        message = (string:121) There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.

        if i call dbal.sql_fetchfield only with the field argument it returns the correct value.

        so for example in this scalar query,

        $racingcount = ( int ) $db->sql_fetchfield ( 'racingcount');
        works, but
        $racingcount = ( int ) $db->sql_fetchfield ( 'racingcount', 0, $result);
        will not work.

        So the issue is with the second argument. i'll have to work around this (bug?) by always omitting a rownum.

        Show
        Sajaki Sajaki added a comment - - edited in dbal.sql_fetchfield, if rownum is not false, $row = $this->sql_fetchrow($query_id); returns false and sqlsrv_errors is an array of 1. code = (int) -22 message = (string:121) There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved. if i call dbal.sql_fetchfield only with the field argument it returns the correct value. so for example in this scalar query, $racingcount = ( int ) $db->sql_fetchfield ( 'racingcount'); works, but $racingcount = ( int ) $db->sql_fetchfield ( 'racingcount', 0, $result); will not work. So the issue is with the second argument. i'll have to work around this (bug?) by always omitting a rownum.
        Hide
        Noxwizard Patrick Webster added a comment -

        The problem is with how the authors implemented the rowseek() functionality. When a result_mssqlnative object is initialized, it drains the entire result set into its own array. If you try to call sqlsrv_fetch_array() again, it will tell you that there are no more rows available since it's already been drained. The problem shows up here because you're trying to fetch a column row zero, which issues a rowseek() before issuing a fetchrow(). mssqlnative's rowseek() actually returns the correct row, but that function is supposed to return a boolean, so it's current implementation isn't useful. Row seeking should have been implemented like it was in the other drivers that don't offer seeking (firebird and odbc): throw away the current resource, issue the query again and fetch to the desired row. The result_mssqlnative object is only useful if you create it when the query is first issued and make the seek and fetchrow operations against that object.

        Show
        Noxwizard Patrick Webster added a comment - The problem is with how the authors implemented the rowseek() functionality. When a result_mssqlnative object is initialized, it drains the entire result set into its own array. If you try to call sqlsrv_fetch_array() again, it will tell you that there are no more rows available since it's already been drained. The problem shows up here because you're trying to fetch a column row zero, which issues a rowseek() before issuing a fetchrow(). mssqlnative's rowseek() actually returns the correct row, but that function is supposed to return a boolean, so it's current implementation isn't useful. Row seeking should have been implemented like it was in the other drivers that don't offer seeking (firebird and odbc): throw away the current resource, issue the query again and fetch to the desired row. The result_mssqlnative object is only useful if you create it when the query is first issued and make the seek and fetchrow operations against that object.

          People

          • Assignee:
            bantu Andreas Fischer
            Reporter:
            Sajaki Sajaki
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development