ext-openswoole icon indicating copy to clipboard operation
ext-openswoole copied to clipboard

[BUG] Postgresql fetch: reset internal pointer on row in some cases

Open mrVrAlex opened this issue 3 years ago • 2 comments

  1. What did you do? If possible, provide a simple script for reproducing the error.
$pg = new Swoole\Coroutine\PostgreSQL();
$conn = $pg->connect("host=127.0.0.1;port=5432;dbname=test;user=postgres;password=***");
$pg->query('BEGIN');
$result = $pg->query('SELECT * FROM test');
$row1 = $pg->fetchAssoc($result); // Get First row
$pg->query('SELECT 1'); // Some another query
$row2 = $pg->fetchAssoc($result); // Try get second query BUT get row 1 again 
$pg->query('COMMIT');

  1. What did you expect to see?
$row1 - first row of SELECT * FROM test
$row2 - second row

  1. What did you see instead?
$row1 & $row2 - is same

  1. What version of OpenSwoole are you using (show your php --ri openswoole)?
4.11.1

  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
PHP 8.1

I used example from docs, but without transaction for SQL result is same.

Even using prepare queries can possible reproduce this bug:

$pg = new Swoole\Coroutine\PostgreSQL();
$conn = $pg->connect("host=127.0.0.1;port=5432;dbname=test;user=postgres;password=***");
$pg->prepare('selectOne', 'SELECT * FROM test');
$result = $pg->execute('selectOne', []);
$row1 = $pg->fetchAssoc($result); // Get First row
// now make some INSERT or UPDATE query to ANY table
$pg->prepare('update',"UPDATE test SET ....'");
$pg->execute('update', []);
// Try get second row
$row2 = $pg->fetchAssoc($result);  // NOW row2 is same as row1

I believe bug not only in fetchAssoc method and in others too.

P.S. Yes I remember about second param in method. If I will use it - fetch will work fine. But PDO works right without parameterm so I expect what openswoole client will be works too)

mrVrAlex avatar Jun 08 '22 12:06 mrVrAlex

Maybe if just backport this solution https://github.com/swoole/swoole-src/pull/4720 issue will solved?

mrVrAlex avatar Sep 17 '22 15:09 mrVrAlex

With separate Statement class not needed use:

object->object = ZEND_THIS;
// and
pg_result = php_swoole_postgresql_coro_get_object(ZEND_THIS);

and then pg_result object will not overwrite when run different queries.

P.S. It will be great see it in v22.0.0 release)

mrVrAlex avatar Sep 17 '22 15:09 mrVrAlex

We have added a test for this issue https://github.com/openswoole/swoole-src/blob/6ab9106f498af45d53eb545d1045eadf97f32eee/tests/swoole_postgres_coro/issue227.phpt

The current behavior is correct. If you still see issues please provide more use cases.

doubaokun avatar Dec 12 '22 19:12 doubaokun

@doubaokun Yes, I still see issue. Your test actually not checked this case. Issue not in execute part, this is fetch issue during parallel fetching results from 2 and more SQL queries. I changed test to demonstrate my expectations, please look: https://github.com/mrVrAlex/swoole-src/blob/issue227-case/tests/swoole_postgres_coro/issue227.phpt

mrVrAlex avatar Dec 12 '22 21:12 mrVrAlex

@mrVrAlex I still can't reproduce errors with your tests, please send PR of a failed test case.

doubaokun avatar Dec 18 '22 21:12 doubaokun

@doubaokun Reproduced (also look comments in code) & created PR with failed test, please look it. Very strange results..)

mrVrAlex avatar Dec 22 '22 15:12 mrVrAlex

@doubaokun Please look https://github.com/openswoole/swoole-src/pull/293 what you say about it?

mrVrAlex avatar Jan 08 '23 17:01 mrVrAlex