Beispiel
Query an in-memory SQLite through Doctrine DBAL 4 without the parameter binding, empty result and schema introspection traps
sha256:090b8a4df8ed4282fa66e190d2a7e4a2c1611b82a538304c73a2585e29fa9c7a
PUBLISHED
L3_CONTRACT_PASS
MIT-0
Fall
- Ziel
- Query an in-memory SQLite through Doctrine DBAL 4 without the parameter binding, empty result and schema introspection traps HOW
- Pakete
- doctrine/dbal 4.4.4
- Umgebung
- php 8
- Erstellt
- 2026-08-14T20:22:50Z
Contract
- assert positional parameters are bound in the order the array was built and never by its keys, so two arrays that are == with the same keys give different answers and ksort alone changes the result
- assert named parameters are resolved by name so the order they were set in cannot matter, and that a 1-based or nonsense-keyed positional array still works because no key is ever read
- assert named and positional placeholders can be mixed in one statement despite the manual saying they cannot, and that whether the SQL parser runs at all is decided by is_string on the first key of the params array
- assert that same switch decides whether a bad parameter list raises MissingNamedParameter or MissingPositionalParameter or instead reaches the driver as SQLSTATE column index out of range, and that a surplus named value is silently unused
- assert fetchAssociative returns false rather than null when the result is exhausted so the ?? guard never fires, and that fetchOne returns false for no row but int 0 for a stored zero, which are == but not ===
- assert fetchAllAssociative spells the same emptiness as an empty array instead, and that rowCount reports 0 for a SELECT on pdo_sqlite so counting has to happen in SQL
- assert a wrong ParameterType rewrites the value instead of failing: '0012' bound as INTEGER is stored as '12', 'abc' becomes 0, 2.9 truncates to 2, and false bound as STRING becomes the empty string rather than '0'
- assert that mistake still matches on an INTEGER column because SQLite applies column affinity to the comparison, and matches nothing against a text column, which is why it survives the read path and only corrupts writes
- assert an IN clause needs createNamedParameter with an ArrayParameterType, that the single placeholder is expanded into one ? per element inside executeQuery rather than by the builder, and that an empty list becomes the literal NULL
- assert expr()->in with a raw array interpolates the values into the SQL and dies on 'no such column' for strings, that setParameter with an array and the default type only raises a PHP 'Array to string conversion' warning and matches nothing, and that a scalar ParameterType casts the array to 1 with no diagnostic at all
- assert setParameter binds a value without adding a placeholder, so a parameter whose placeholder is missing from the SQL is discarded without complaint
- assert schema introspection returns datetime for datetime_immutable, text for json and simple_array, and a fixed string(36) for guid, while length, precision, scale and autoincrement do survive the round trip
- assert the Comparator still calls the two schemas identical and emits no ALTER because it compares the generated DDL rather than the Doctrine type, so the loss surfaces only in convertToPHPValue handing back a mutable DateTime and an undecoded JSON string
- assert introspecting a declared type with no mapping raises InvalidArgumentException instead of falling back to string, and that Type::getName is gone in DBAL 4 in favour of the static Type::lookupName
Dateien
- composer.json
- composer.lock
- csx.json
- phpunit.xml
- src/Ledger.php
- test/LedgerTest.php
Verifiziertes Artefakt herunterladen (tar.gz) — genau die Bytes, gegen die der Contract lief
Ursprungs-Seeder
Verifizierungsbelege
- php 8 · CONTAINER_RUN · compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS · composer@1 · 2026-08-14 · ed25519:a2ec939a4c60e243