@@ -364,61 +364,65 @@ public function prepare(string $sql): Promise
364364 throw new \Error ("The connection to the database has been closed " );
365365 }
366366
367- $ modifiedSql = Internal \parseNamedParams ($ sql , $ names );
367+ return call (function () use ($ sql ) {
368+ $ modifiedSql = Internal \parseNamedParams ($ sql , $ names );
368369
369- $ name = Handle::STATEMENT_NAME_PREFIX . \sha1 ($ sql );
370+ $ name = Handle::STATEMENT_NAME_PREFIX . \sha1 ($ modifiedSql );
370371
371- if (isset ($ this ->statements [$ name ])) {
372- $ storage = $ this ->statements [$ name ];
372+ if (isset ($ this ->statements [$ name ])) {
373+ $ storage = $ this ->statements [$ name ];
373374
374- if ($ storage ->promise instanceof Promise) {
375- return $ storage ->promise ;
376- }
375+ if ($ storage ->promise instanceof Promise) {
376+ // Do not return promised prepared statement object, as the $names array may differ.
377+ yield $ storage ->promise ;
378+ }
377379
378- ++$ storage ->refCount ; // Only increase refCount when returning a new object.
380+ ++$ storage ->refCount ;
379381
380- return new Success ( new PgSqlStatement ($ this , $ name , $ sql , $ names) );
381- }
382+ return new PgSqlStatement ($ this , $ name , $ sql , $ names );
383+ }
382384
383- $ storage = new class {
384- use Struct;
385- public $ refCount = 1 ;
386- public $ promise ;
387- };
385+ $ storage = new class {
386+ use Struct;
387+ public $ refCount = 1 ;
388+ public $ promise ;
389+ };
388390
389- $ this ->statements [$ name ] = $ storage ;
391+ $ this ->statements [$ name ] = $ storage ;
390392
391- return $ storage ->promise = call (function () use ($ storage , $ name , $ names , $ sql , $ modifiedSql ) {
392393 try {
393- /** @var resource $result PostgreSQL result resource. */
394- $ result = yield from $ this ->send ("pg_send_prepare " , $ name , $ modifiedSql );
394+ yield ($ storage ->promise = call (function () use ($ name , $ modifiedSql ) {
395+ $ result = yield from $ this ->send ("pg_send_prepare " , $ name , $ modifiedSql );
396+
397+ switch (\pg_result_status ($ result , \PGSQL_STATUS_LONG )) {
398+ case \PGSQL_COMMAND_OK :
399+ return $ name ; // Statement created successfully.
400+
401+ case \PGSQL_NONFATAL_ERROR :
402+ case \PGSQL_FATAL_ERROR :
403+ $ diagnostics = [];
404+ foreach (self ::DIAGNOSTIC_CODES as $ fieldCode => $ description ) {
405+ $ diagnostics [$ description ] = \pg_result_error_field ($ result , $ fieldCode );
406+ }
407+ throw new QueryExecutionError (\pg_result_error ($ result ), $ diagnostics );
408+
409+ case \PGSQL_BAD_RESPONSE :
410+ throw new FailureException (\pg_result_error ($ result ));
411+
412+ default :
413+ // @codeCoverageIgnoreStart
414+ throw new FailureException ("Unknown result status " );
415+ // @codeCoverageIgnoreEnd
416+ }
417+ }));
395418 } catch (\Throwable $ exception ) {
396419 unset($ this ->statements [$ name ]);
397420 throw $ exception ;
398421 } finally {
399422 $ storage ->promise = null ;
400423 }
401424
402- switch (\pg_result_status ($ result , \PGSQL_STATUS_LONG )) {
403- case \PGSQL_COMMAND_OK :
404- return new PgSqlStatement ($ this , $ name , $ sql , $ names );
405-
406- case \PGSQL_NONFATAL_ERROR :
407- case \PGSQL_FATAL_ERROR :
408- $ diagnostics = [];
409- foreach (self ::DIAGNOSTIC_CODES as $ fieldCode => $ description ) {
410- $ diagnostics [$ description ] = \pg_result_error_field ($ result , $ fieldCode );
411- }
412- throw new QueryExecutionError (\pg_result_error ($ result ), $ diagnostics );
413-
414- case \PGSQL_BAD_RESPONSE :
415- throw new FailureException (\pg_result_error ($ result ));
416-
417- default :
418- // @codeCoverageIgnoreStart
419- throw new FailureException ("Unknown result status " );
420- // @codeCoverageIgnoreEnd
421- }
425+ return new PgSqlStatement ($ this , $ name , $ sql , $ names );
422426 });
423427 }
424428
0 commit comments