feat: expand PDO parity across maintained PHP drivers#559
Open
Guikingone wants to merge 1 commit into
Open
Conversation
Implement PHP-version-aware PDO parity across SQLite, MySQL, PostgreSQL, OCI, SQL Server, Firebird, CUBRID, ODBC, DBLIB, Informix, and IBM drivers. Add native and Docker live coverage, libpq-backed GSSAPI, documentation, and regressions for runtime hash handling and supported Oracle Instant Client setup.
Guikingone
force-pushed
the
worktree-moonlit-finding-pelican
branch
from
July 19, 2026 16:24
98d68d2 to
c4864ef
Compare
Member
|
Hi @Guikingone, thanks for this. Will look at this soon. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR takes the PDO compatibility campaign from the original SQLite/PostgreSQL/MySQL bridge to the complete eleven-driver matrix tracked for supported PHP releases. It also fixes the compiler/runtime defects exposed by the expanded PDO test corpus, adds version-aware API surfaces for PHP 8.0 through 8.6, and introduces build plus live-database CI for the new profiles.
The normative compatibility scope is PHP 8.2 through 8.5. PHP 8.0 and 8.1 remain historical compatibility targets, while PHP 8.6 is treated as a preview surface until upstream stabilizes.
PDO core and versioned surface
--php-versionandELEPHC_PHP_VERSION, with CLI precedence and explicit 8.0 through 8.6 selection.PDO::connect()and the driver-specific subclass construction path.PDO::getAvailableDrivers()andpdo_drivers()only report drivers present in the selected bridge archive.pdo.dsn.*aliases and PHP-compatible INI/environment precedence, includinguri:DSNs and credential precedence.Driver matrix
Default bridge:
Optional profiles:
pdo-libpq-gss: full libpq connection lifetime for PHP-style GSSAPI/Kerberos, service/pass files,PG*defaults, encrypted-key options, and libpq-version-dependent keywords.pdo-dblib: FreeTDS DB-Library withPdo\Dblib, versioned aliases, attributes, and live SQL Server acceptance.pdo-firebird: Firebird wire client withPdo\Firebird, versioned aliases, transactions, attributes, metadata, and live acceptance.pdo-odbc: unixODBC/iODBC driver-manager path withPdo\Odbc, attributes, diagnostics, metadata, and live PostgreSQL-over-ODBC acceptance.pdo-informix: Informix CLI/ODBC profile with the PECL surface and explicit external Client SDK boundary.pdo-ibm: IBM CLI/ODBC profile withPdo\Ibm, PHP-versioned aliases, attributes, and explicit external driver boundary.pdo-sqlsrv: Microsoft PDO_SQLSRV 5.13 profile through ODBC Driver 17/18, including its version availability and complete attribute range.pdo-oci: PDO_OCI through Oracle Instant Client/ODPI-C, including the PHP 8.3 bundled-to-PECL transition.pdo-cubrid: official CUBRID CCI path, including attributes, schema/metadata, scrolling, rowsets, LOBs, quoting, and the extension-specific surface.Compiler and runtime fixes uncovered by PDO
CI and examples
PDO Live Databasesworkflow for PostgreSQL 16, MySQL 8.4, SQL Server 2022, Firebird 5, ODBC, Oracle 23ai, CUBRID 11.4, and the libpq GSS/Kerberos fixture.Documentation
--php-versionandELEPHC_PHP_VERSIONin the CLI reference.src/codegen_supportlayout.Post-merge integration fixes
array_key_exists()checker with its dynamicMixed/Unionruntime dispatch afteris_array()guards.MixedPDO option state across control-flow joins and normalizes session option keys at the helper boundary.__elephc_ptr_read_stringalias and preserves declared method casing in private-access diagnostics.test_pdo_constants_presentplus focused narrowing, prelude-parity, private-factory, and corpus regressions.Validation performed
Focused validation during the campaign includes:
git diff --checkclean.The new GitHub workflows provide the authoritative full supported-target and live-service qualification after push.
Explicit qualification boundaries
Integration with current main
origin/maininto the feature branch and resolves the compiler, EIR, runtime, test-runner, documentation, and CI workflow overlaps.is_array()narrows amixedvalue, joins nullableMixedoption accumulators correctly across conditional loop bodies, and normalizes session keys at the typed helper boundary. This restores PHP 8.4/8.5 session options after the shared version-profile merge.Post-merge focused validation passed:
cargo check, formatting, diff hygiene, PHP-version/CLI/PDO-prelude unit tests, the DCE regression, PDO constants, SQLite exec/fetch, all SQLite callable forms,pdo-cubridandpdo-libpq-gssfeature checks, the mixed-array/control-flow regressions plus the four previously failing PHP web-session scenarios, workflow YAML parsing, builtin extraction, and the complete documentation audits above.Final current-main regression closure
origin/main, including the upstream nested Mixed-write work, and resolves its interaction with PDO branch value-read semantics.ArrayGetForWrite,HashGetForWrite, andMixedArrayGetForWriteoperations plusMixedClone, keeping ordinary reads detached while nested writes retain a writable owner path.ArrayAccessparent shapes without leaking updates into aliases.Final focused validation:
cargo check; formatting/diff/assembly-comment hygiene; 17 nested-write regressions with EIR optimization enabled and disabled; heap-debug-clean static COW coverage; GNU assembly of the final generated Linux x86_64 program; all 10 PDO prelude version tests underpdo-informix; and the compiled PHP 8.2 plus PHP 8.4 Informix API-surface tests.Concurrent PDO column-buffer isolation
elephc_pdo_column_data_ptr()reused one process-global byte buffer, so parallel driver reads could invalidate each other before the returned pointer was copied.elephc-pdolibrary tests pass (2 live tests remain intentionally ignored without servers); formatting and diff hygiene pass.Resource-aware Mixed value reads
Mixedreads duplicated ownership of a raw resource without retaining it, so releasing the first temporary could close the stream still stored in the PDO row.__rt_mixed_clonelowering across EIR, indexed arrays, hashes, dynamic Mixed containers, and objects. Ordinary PHP values still receive detached zvals; resource tag 9 intentionally retains the existing cell so aliases share cursor and destructor lifetime as in PHP.byteabytes;cargo check, formatting, diff, and assembly-comment hygiene pass.Eval reference writeback integration
__rt_mixed_array_get_sharedmode. Ordinary PHP reads remain detached, nested-write fetches keep their COW/detach behavior, and only eval runtime handles retain stored identity with owned refcounts.call_user_func_array()writeback paths.cargo check, formatting, assembly-comment alignment, and diff hygiene pass.macOS dead-strip closure
__rt_mixed_array_getimplementation entry as a Mach-O alternate entry because the ordinary-read, nested-write, and eval-shared wrappers are distinct runtime atoms under-dead_strip.Driver-specific PDO placeholder scanning
#temptable caused the reused MySQL scanner to treat the rest of the statement as a comment and hide a following named bind.#comments and whitespace-sensitive--behavior; DBLIB, Firebird, ODBC, Informix, IBM, and SQLSRV use the generic PDO scanner without#comments.#temp … :labelregression, updates the PDO guide and changelog, and validates MySQL, DBLIB, Firebird, ODBC, Informix, IBM, and SQLSRV feature builds/tests locally.SQLSRV zero-column execution
SQLFetchon successful INSERT/UPDATE/DDL statements with no result columns as an invalid cursor state.SQLRowCountand return immediately whenSQLNumResultColsis zero; real rowsets retain the existing fetch/materialization path.SQLSRV native floating-point binds
SQL_C_DOUBLEfor the completeSQLExecutelifetime.DECIMAL/NUMERIC; when Driver 17/18 reports an unknown or text descriptor, the bind falls back toSQL_FLOATinstead of the previous long-text type.12.5 -> DECIMAL(10,2)failure, adds a focused mapping regression, and updates both the PDO guide and changelog.cargo build; SQLSRV mapping and unit tests; all five compiled SQLSRV surface tests; ODBC, Informix, and IBM feature checks; formatting and diff hygiene. The existing live SQLSRV round-trip is the authoritative Driver 18 regression gate in CI.SQLSRV value-driven parameter defaults
TEXT, which SQL Server cannot convert toDATETIME2.SQLDescribeParam: UTF-8 text usesSQL_WVARCHAR, system text usesSQL_VARCHAR, binary strings useSQL_VARBINARY, integers selectSQL_INTEGER/SQL_BIGINT, doubles useSQL_FLOAT, and NULL follows text/binary encoding.SQLDescribeParamon the other CLI profiles, where it is part of PDO_ODBC/Informix/IBM behavior; SQLSRV Always Encrypted metadata remains a capability of the installed Microsoft stack.cargo build; all 11 active SQLSRV ODBC unit tests; the exact five compiled SQLSRV version-surface tests; ODBC, Informix, and IBM feature checks; formatting and diff hygiene.Latest-main object
::classintegrationorigin/mainthrough PR feat: support ::class on object expressions #569, including runtime$object::classsupport.ObjectClassNameAST node and recursively visits its receiver, restoring exhaustive merged-PR compilation without inventing mutation semantics.cargo build; all five matching object-class-name/eval regressions; SQLSRV parameter mapping regression; formatting and diff hygiene.SQLSRV buffered-cursor crash fix
SQLSRV prepare-order follow-up
The extended bridge regression exposed that Microsoft ODBC rejects SQL_ATTR_CURSOR_TYPE changes after SQLPrepare. Commit f8f711b now carries the final SQLSRV cursor selection through the internal prepare mode, validates the PDO scroll/driver scroll combination before allocating the statement, applies SQL_CURSOR_STATIC or SQL_CURSOR_FORWARD_ONLY before SQLPrepare, and only verifies the already-applied option afterward. This matches the ordering in msphpsql and keeps invalid scroll-type combinations catchable instead of reaching ODBC in an inconsistent state.
SQLSRV Mixed-hash
isset()closureMixedcell, butHashIssetalways treated the payload as a box and attempted to unbox raw values such as integer42.Mixedentries before unboxing. The PDO prelude therefore retains its PHP-compatibleforeach ([1000, ..., 1009])option dispatch without a SQLSRV-specific static workaround.Mixedentries by a by-reference loop.isset()ownership regression pass; SQLSRV bridge unit/live tests, its exact live compiled test, and all five version-surface tests pass in the authoritative workflow.Supported Oracle Instant Client qualification
libaiocompatibility name, and exposes the complete package throughLD_LIBRARY_PATH.Authoritative PDO live result
GitHub Actions run 29687884748 completed successfully on commit
e5ce7e4aa(43m46s). It passed every configured bridge/unit/surface/live gate for:The amd64 and arm64 CI images for the same commit also completed successfully. GitHub Actions run 29687884727 completed successfully for the same head with 112 jobs and zero failures: builds, docs/stub parity, non-codegen, web, codegen, and eval-codegen shards all passed across macOS AArch64, Linux AArch64, and Linux x86_64 (the benchmark job was intentionally skipped on the PR event).
Squashed delivery
c4864ef71, directly on top of the currentmainbranch.