194 Commits
Author SHA1 Message Date
Jayant Chaudhary f2a6e29267 [skip ci] Fix typos in ext/pdo_pgsql comments
Closes GH-24550
2026-10-22 21:02:55 +02:00
Matthias Dötsch c0018beb11 ext/pdo_pgsql: Convert integer columns without strtoll()
PostgreSQL sends int2/int4/int8 values in text format in canonical
decimal form: an optional minus sign followed by digits without leading
zeros. That is exactly what ZEND_HANDLE_NUMERIC_STR() accepts for
numeric array keys, including the range check. Use it instead of
calling strtoll() through ZEND_ATOL() for every value, and keep
ZEND_ATOL() as fallback for anything else.

fetchAll(PDO::FETCH_ASSOC) of 1M rows with 4 integer columns:
-11% instructions, -9% cycles.

Close GH-24385
2026-10-22 14:25:10 +01:00
David CarlierandArtem Ukrainskiy 296e8eac57 pdo_pgsql_request_shutdown() leaves statements of freed PDO objects prepared.
Track prepared statement names on the handle and close the leftovers.

Co-authored-by: Artem Ukrainskiy <art.ukrainskiy@gmail.com>
2026-10-22 12:05:20 +01:00
David Carlier 810a9e58dc Merge branch 'PHP-8.5'
* PHP-8.5:
  ext/pdo_pgsql: Fix CURSOR_SCROLL statements closing a nonexistent cursor

# Conflicts:
#	ext/pdo_pgsql/config.m4
#	ext/pdo_pgsql/pgsql_statement.c
2026-09-06 21:00:54 +01:00
David Carlier f3607f147f Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/pdo_pgsql: Fix CURSOR_SCROLL statements closing a nonexistent cursor

# Conflicts:
#	ext/pdo_pgsql/pgsql_statement.c
#	ext/pdo_pgsql/php_pdo_pgsql_int.h
2026-09-06 21:00:24 +01:00
武田 憲太郎 c1a7ab07ec ext/pdo_pgsql: Fix CURSOR_SCROLL statements closing a nonexistent cursor
The destructor of a statement created with
[PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL] tried to close the cursor even
when it did not exist. The attempted close causes an error on the server
that the destructor discards, so it cannot be observed by the user, but
inside a transaction it leaves subsequent statements failing for a reason
nobody can see.

is_prepared was overloaded to also mean "cursor declared" and was never
reset, so the cursor state now has its own flag. A close that fails no
longer aborts the caller's transaction.

Close GH-23490
2026-09-06 20:58:28 +01:00
武田 憲太郎 f4a17fdefd ext/pdo_pgsql: Add Pdo\Pgsql::ATTR_CHUNK_SIZE for chunked result fetching
Generalizes the lazy fetch added in GH-15287 by letting a statement choose
how many rows it fetches per chunk, trading memory for speed. ext/pgsql
already exposed this as pg_set_chunked_rows_size(); ext/pdo_pgsql had no
way to reach it.

ATTR_PREFETCH and ATTR_CHUNK_SIZE replace each other: setting one on the
connection clears the other, a statement given either does not inherit the
connection's value, and a chunk size of 1 or more wins when both are set on
the same statement. A chunk size cannot be combined with a statement-level
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, which throws a ValueError; a
connection-level chunk size is simply disabled by a scrollable statement.

Requires libpq 17 or later.

Close GH-23210
2026-08-27 05:12:15 +01:00
David Carlier 61c601c5f8 Merge branch 'PHP-8.5'
* PHP-8.5:
  ext/pdo_pgsql: Fix several lazy fetch defects
2026-08-11 19:46:03 +01:00
武田 憲太郎 0b91828b01 ext/pdo_pgsql: Fix several lazy fetch defects
With PDO::ATTR_PREFETCH => 0 a statement streams its result set, and the
cleanup reads the rest of it by calling PQgetResult() until it returns
NULL. That never happens while the connection is copying: PQgetResult()
hands out a fresh COPY result every time. A COPY run through a lazy fetch
has therefore spun at 100% CPU since 8.5.0, as soon as another lazy fetch
takes the connection over. The copy has to be ended first: a copy in with
PQputCopyEnd(), a copy out by draining PQgetCopyData().

The drain was skipped as well, because is_running_unbuffered was cleared
first, both in the cleanup's own abort path and in pgsql_stmt_fetch()
before it calls the cleanup. With PDO::ATTR_EMULATE_PREPARES or
Pdo\Pgsql::ATTR_DISABLE_PREPARES the connection then stayed busy and the
next lazy fetch failed with "another command is already in progress".

The connection's pointer to the statement streaming on it was only cleared
while closing a server-side prepared statement, which those two modes do
not create, so destroying one left the pointer dangling for the next lazy
fetch to read. And a statement whose stream was taken over kept its row
counters after its result had been freed, so fetch() returned a row of
NULLs rather than false.

Close GH-23065
2026-08-11 19:45:04 +01:00
David Carlier 8b343897df Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix GH-21683: PDOStatement::fetch() throws on empty result With PDO::ATTR_FETCH attribute.
2026-04-18 05:27:52 +01:00
Thomas Schiet ec79850c50 Fix GH-21683: PDOStatement::fetch() throws on empty result With PDO::ATTR_FETCH attribute.
close GH-21684.
2026-04-18 05:24:28 +01:00
Ben Ramsey eca7fb4115 license-update: ext/pdo_pgsql source headers
RFC: https://wiki.php.net/rfc/php_license_update
2026-04-11 21:20:54 -05:00
David Carlier 5668b16ad2 Revert "Pdo\Pgsql: Fix getColumnMeta() for GH-15287 Pdo\Pgsql::setAttribute(PDO::ATTR_PREFETCH, 0)"
This reverts commit 898235127b.
2025-09-29 14:43:51 +01:00
Guillaume Outters 898235127b Pdo\Pgsql: Fix getColumnMeta() for GH-15287 Pdo\Pgsql::setAttribute(PDO::ATTR_PREFETCH, 0)
As stated in the UPGRADING, using the passthrough ("single-row") mode of libpq (introduced in #15287)
forbids passing a new query while the current one's results have not been entirely consumed.
… But I didn't notice that ext/pdo_pgsql internally used new queries to fetch metadata (example use case:
a call to getColumnMeta() while fetch()ing row by row will interleave the getColumnMeta()-triggered
internal query to the database, with the results fetching for the user-called query).

This PR makes those internal calls return NULL for non-essential metadata, instead of letting libpq abort the user-called query.

It moreover includes a small tweak to table oid-to-name translation, with a 1-slot cache.
This may by chance allow the internal call to return something instead of NULL,
but it will nonetheless avoid 30 server calls to get the table name of 30 columns of the same table.

optimize calls to foreach(columns of the same table) getColumnMeta()

- each call queried the DB to know the name associated with the table's OID:
  cache the result between two calls
- make pdo_pgsql_translate_oid_to_table higher-level,
  with the last parameter being the handle instead of the raw connection;
  thus the statement is cleaner, letting the handle do all memory handling on the table oid-to-name translation cache
  (which by the way is a driver feature more than a statement one)

close GH-16249
2025-09-28 22:37:19 +01:00
Tim Düsterhus b965ea3a05 pdo_pgsql: Use true / false instead of 1 / 0 when assigning to bool
Changes done with Coccinelle:

    @@
    bool b;
    @@

    - b = 0
    + b = false

    @@
    bool b;
    @@

    - b = 1
    + b = true
2025-09-24 18:51:40 +02:00
Gina Peter Banyard d9000b3094 tree: replace some unnecessary uses of spprintf (#19354) 2025-08-05 17:25:47 +01:00
Gina Peter Banyard 09791ed1d1 ext/pdo: Convert database_object_handle zval to zend_object* (#17629)
This saves 8 bytes on the PDO statement struct.

We change the PGSQL PDO driver API to take a zend_object* instead of a zval* at the same time.
2025-01-30 18:34:03 +00:00
Niels Dossche 6f4579af85 Introduce php_pdo_stmt_valid_db_obj_handle() (#17567) 2025-01-28 21:54:11 +01:00
Guillaume Outters 68537fd9f4 Fix / implement GH-15287: add a lazy fetch to Pdo\PgSql
Make Pdo\PgSql accept Pdo::setAttribute(PDO::ATTR_PREFETCH, 0) to enter libpq's single row mode.
This avoids storing the whole result set in memory before being able to call the first fetch().

close GH-15750
2024-09-29 08:33:14 +01:00
David Carlier f35ad560b4 GH-12940 ext/pdo_pgsql: using PQclosePrepared to free statement resources.
PQclosePrepared allows the statement's name to be reused thus allowing
cache solutions to work properly ; whereas, for now, the `DEALLOCATE
<statement>` query is used which free entirely the statement's resources.

close GH-13316
2024-09-24 12:09:56 +01:00
Arnaud Le Blanc 11accb5cdf Preferably include from build dir (#13516)
* Include from build dir first

This fixes out of tree builds by ensuring that configure artifacts are included
from the build dir.

Before, out of tree builds would preferably include files from the src dir, as
the include path was defined as follows (ignoring includes from ext/ and sapi/) :

    -I$(top_builddir)/main
    -I$(top_srcdir)
    -I$(top_builddir)/TSRM
    -I$(top_builddir)/Zend
    -I$(top_srcdir)/main
    -I$(top_srcdir)/Zend
    -I$(top_srcdir)/TSRM
    -I$(top_builddir)/

As a result, an out of tree build would include configure artifacts such as
`main/php_config.h` from the src dir.

After this change, the include path is defined as follows:

    -I$(top_builddir)/main
    -I$(top_builddir)
    -I$(top_srcdir)/main
    -I$(top_srcdir)
    -I$(top_builddir)/TSRM
    -I$(top_builddir)/Zend
    -I$(top_srcdir)/Zend
    -I$(top_srcdir)/TSRM

* Fix extension include path for out of tree builds

* Include config.h with the brackets form

`#include "config.h"` searches in the directory containing the including-file
before any other include path. This can include the wrong config.h when building
out of tree and a config.h exists in the source tree.

Using `#include <config.h>` uses exclusively the include path, and gives
priority to the build dir.
2024-06-26 00:26:43 +02:00
Peter Kokot 678a481f62 Fix unused variable warning when using libpq < 12 (#14630)
The variable S is not used if PQresultMemorySize is not available in
this switch at this point.
2024-06-22 00:09:21 +02:00
Peter Kokot df481ef941 Simplify PDO include paths (#14444)
PDO include paths can be simplified and synced as done in other
extensions: either the project root directory or the phpincludedir (for
the system installation). The 'ext' include is automatically appended
when doing phpize build. In php-src it is only present on Windows build.
The PHP_CHECK_PDO_INCLUDES is left intact working as before and checks
if PDO headers are found.
2024-06-03 12:56:21 +02:00
武田 憲太郎 b7dd3d8347 ext/pdo_pgsql: Retrieve the memory usage of the query result resource (#14260)
`getAttribute()` can now retrieve the memory usage of query results.
`PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE` was added for this feature.

closes #14260
2024-05-20 09:08:54 +09:00
Yurun 6d10a69898 Fix the incorrect data type of float values in PDO query results
Close GH-12476
2023-10-20 12:49:25 +01:00
Christoph M. Becker b5cad508fe Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0:
  Fix GH-9411: PgSQL large object resource is incorrectly closed
2022-09-05 17:26:13 +02:00
YurunandChristoph M. Becker 6ac3f7c84d Fix GH-9411: PgSQL large object resource is incorrectly closed
Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de>

Closes GH-9411.
2022-09-05 16:37:54 +02:00
Philip Hofstetter ace8fba759 Fix bug #81343: inconsistent type conversion after closeCursor
S->cols is already freed in the statement destructor and since
caa710037e the column data is only
populated on the first execute() which means that on subsequent
execute()s after closeCursor was called, all meta-data for column types
was removed and never restored

Closes GH-7355.
2021-08-11 18:24:13 +02:00
Nikita Popov efbb2198d4 Return value from ZEND_ATOL
Instead of assigning it as part of the macro itself, which makes
usage quite awkward.
2021-07-12 16:51:24 +02:00
KsaR 01b3fc03c3 Update http->https in license (#6945)
1. Update: http://www.php.net/license/3_01.txt to https, as there is anyway server header "Location:" to https.
2. Update few license 3.0 to 3.01 as 3.0 states "php 5.1.1, 4.1.1, and earlier".
3. In some license comments is "at through the world-wide-web" while most is without "at", so deleted.
4. fixed indentation in some files before |
2021-05-06 12:16:35 +02:00
Matteo Beccati f84936b30c Merge branch 'PHP-8.0'
* PHP-8.0:
  Revert "Fix #80892: PDO::PARAM_INT is treated the same as PDO::PARAM_STR"
2021-04-29 12:06:11 +02:00
Matteo Beccati 7bc9df4af2 Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4:
  Revert "Fix #80892: PDO::PARAM_INT is treated the same as PDO::PARAM_STR"
2021-04-29 12:05:49 +02:00
Matteo Beccati b8e49fe872 Revert "Fix #80892: PDO::PARAM_INT is treated the same as PDO::PARAM_STR"
This reverts commit 340a06778c.
2021-04-29 11:59:16 +02:00
Matteo Beccati d0229374ce Merge branch 'PHP-8.0'
* PHP-8.0:
  Fix #80892: PDO::PARAM_INT is treated the same as PDO::PARAM_STR
2021-04-12 08:06:38 +02:00
Matteo Beccati 4f236635e7 Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4:
  Fix #80892: PDO::PARAM_INT is treated the same as PDO::PARAM_STR
2021-04-12 08:05:41 +02:00
Matteo Beccati 340a06778c Fix #80892: PDO::PARAM_INT is treated the same as PDO::PARAM_STR 2021-04-12 08:03:07 +02:00
George Peter Banyard 5caaf40b43 Introduce pseudo-keyword ZEND_FALLTHROUGH
And use it instead of comments
2021-04-07 00:46:29 +01:00
Nikita Popov 3e01f5afb1 Replace zend_bool uses with bool
We're starting to see a mix between uses of zend_bool and bool.
Replace all usages with the standard bool type everywhere.

Of course, zend_bool is retained as an alias.
2021-01-15 12:33:06 +01:00
Nikita Popov 422d1665a2 Make convert_to_*_ex simple aliases of convert_to_*
Historically, the _ex variants separated the zval first, if a
conversion was necessary. This distinction no longer makes sense
since PHP 7.

The only difference that was still left is that _ex checked whether
the type is the same first, but the usage of these macros did not
actually distinguish on whether such an inlined check is valuable
or not in a given context.

Also drop the unused convert_to_explicit_type macros.
2021-01-14 12:11:11 +01:00
Nikita Popov ec58a6f1b0 Remove SEPARATE_ZVAL_IF_NOT_REF() macro
This macro hasn't made sense since PHP 7. The correct pattern to
use is ZVAL_DEREF + SEPARATE_ZVAL_NOREF.
2021-01-14 11:08:44 +01:00
Nikita Popov 7aa00369b0 Switch bound_param_map to zend_string 2021-01-07 15:53:47 +00:00
Nikita Popov caa710037e Rewrite PDO result binding
Instead of requiring the type to be determined in advance by the
describer function and then requiring get_col to return a buffer
of appropriate type, allow get_col to return an arbitrary zval.
See UPGRADING.INTERNALS for a more detailed description of the
change.

This makes the result fetching simpler, more efficient and more
flexible. The general possibility already existed via the special
PDO_PARAM_ZVAL type, but the usage was very inconvenient and/or
inefficient. Now it's possible to easily implement behavior like
"return int if it fits, otherwise string" and to avoid any kind
of complex management of temporary buffers.

This also fixes bug #40913 (our second highest voted bug of all
time, for some reason). PARAM_LOB result bindings will now
consistently return a stream resource, independently of the used
database driver.

I've tried my best to update all PDO drivers for this change, but
some of the changes may be broken, as I cannot test or even build
some of these drivers (in particular PDO dblib and PDO oci).
Fixes are appreciated -- a working CI setup would be even more
appreciated ;)
2020-12-22 15:56:34 +01:00
Nikita Popov 7904a087ec Back memory stream by a zend_string
This allows reusing an existing zend_string inside a memory stream
without reallocating. For non-readonly streams, the string will
only get separated on write.
2020-12-18 17:07:07 +01:00
Nikita Popov 2d51c203f0 PDO: Store/pass query_string as zend_string
Rather than storing char* + size_t, use a zend_string*. Also
avoid various copies of the query string.
2020-12-14 10:43:28 +01:00
Nikita Popov a5527577e7 Allow drivers to omit error code
And thus generate error messages that match what PDO emulation
would generate.

This fixes the error message regression from the previous commit.
2020-12-10 16:04:33 +01:00
Nikita Popov 15b51a215a Fixed bug #79131
When a driver reports an error during EVT_ALLOC (and some over EVTs),
make sure we handle it as usual, i.e. warn or throw.

This requires some adjustments in PDO PgSQL to stop manually doing
this through an impl error.

Unfortunately the PDO PgSQL error messages regress because of this,
as they now include a completely arbitrary error code. There doesn't
seem to be an ability to skip it right now.
2020-12-10 15:53:23 +01:00
Matteo Beccati 42b6b8a3ae Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  Fix #80027 Terrible performance using $query->fetch on queries with many bind parameters
2020-08-31 11:08:26 +02:00
Matteo Beccati 44ade0e875 Fix #80027 Terrible performance using $query->fetch on queries with many bind parameters
Added new flags that allow skipping param_evt(s) that are not used by drivers,
in a backwards and forward compatible manner. Updated the pgsql, mysql, sqlite
and oci drivers to properly use the new flags. I've left out pdo_dblib, which
doesn't have a param_hook, and pdo_firebird, which seems to be using
PARAM_EVT_NORMALIZE in a wrong context (param type vs event type).
2020-08-31 11:03:03 +02:00
Matteo Beccati ee2506cc02 Fix #80027 Terrible performance using $query->fetch on queries with many bind parameters
Added new flags that allow skipping param_evt(s) that are not used by drivers,
in a backwards and forward compatible manner. Updated the pgsql, mysql, sqlite
and oci drivers to properly use the new flags. I've left out pdo_dblib, which
doesn't have a param_hook, and pdo_firebird, which seems to be using
PARAM_EVT_NORMALIZE in a wrong context (param type vs event type).
2020-08-31 11:02:34 +02:00
George Peter Banyard c85ded7632 Fix [-Wundef] warning in PDO PostgreSQL extension 2020-05-20 16:29:53 +02:00