Skip to content

Add is_nullable to field_data() (#6335) - #22

Open
NielBuys wants to merge 4 commits into
developfrom
tasks/issue-6335-is-nullable
Open

NielBuys wants to merge 4 commits into
developfrom
tasks/issue-6335-is-nullable

Conversation

@NielBuys

@NielBuys NielBuys commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Implements upstream feature request bcit-ci/CodeIgniter#6335. Full review and decision record: docs/todo/archive/issue-6335-field-data-is-nullable.md.

What it does

Every driver's field_data() now sets is_nullable on each field: 1 if the column accepts NULL, 0 if it is NOT NULL. Drivers that cannot report it return 1, so code reading the property never hits an undefined-property warning, whatever the database.

Scope: real values only where it is safe

The property is additive. For ten drivers, though, a full implementation would change the SQL that field_data() already runs, and a wrong query there would break field_data() for existing callers. The rule applied: report the real value where no query changes or where CI can test the change; otherwise return 1 and leave the query alone.

Table metadata $db->field_data('t')
mysqli, mysql, cubrid, pdo_mysql, pdo_cubrid, sqlite, sqlite3, pdo_sqlite, oci8, pdo_oci Real value, read from data the query already returns
postgre, pdo_pgsql Real value; is_nullable added to the SELECT (covered by CI)
mssql, sqlsrv, pdo_dblib, pdo_sqlsrv, ibase, pdo_firebird, pdo_ibm, pdo_informix 1, query unchanged
Result metadata $query->field_data()
mysqli, mysql, cubrid, pdo (where the subdriver reports not_null, i.e. pdo/mysql), sqlsrv Real value from existing metadata
postgre, oci8, mssql, ibase, sqlite, sqlite3, odbc 1 (no API exists)

The user guide (database/metadata.rst) documents this, including the caveat that result metadata describes the result set: a LEFT JOIN column can be nullable when the base column is not. There is a changelog entry under 3.1.24.

Tests

New tests/codeigniter/database/DB_field_data_test.php runs in the six CI database jobs. Table metadata must report real values on all six; result metadata must be real on mysqli and pdo/mysql and 1 elsewhere.

  • Run locally (PHP 8.5.4): sqlite and pdo/sqlite pass. Both new tests fail without the driver changes. The full sqlite suite shows only the existing Calendar_test failure.
  • pdo/sqlite needed a temporary local change: its test DSN builds sqlite:/C:/..., which doesn't resolve on Windows, so it was edited for the run and restored.
  • Not run locally: mysqli, pdo/mysql, pgsql and pdo/pgsql (no travis user or ci_test database). This PR's CI run is their first test.

Not changed: existing defects recorded in the doc

  • pdo_oci_driver::field_data() assigns an unselected COLUMN_DEFAULT, so default is always NULL.
  • pdo_ibm_driver::field_data() uses CASE "keyseq" WHEN NULL, which never matches, so every column reports primary_key = 1.
  • pdo_informix_driver::field_data() appears to drop columns without a default (unverified).

Housekeeping

mysqli_result.php and pdo_mysql_driver.php had CRLF working copies left over from before .gitattributes. They were re-checked out as LF before editing. The repository content is unaffected.

🤖 Generated with Claude Code

NielBuys and others added 3 commits October 6, 2026 21:45
Every driver now sets is_nullable on the objects field_data() returns:
1 if the column accepts NULL, 0 if NOT NULL. Drivers that cannot report
it return 1, so code reading the property never hits an undefined
property, whatever the driver.

Real values come only from data the driver already has, or from a query
change CI can test:
- Table metadata: SHOW COLUMNS (MySQL, CUBRID), PRAGMA TABLE_INFO
  (SQLite), the NULLABLE column Oracle already selects, and PostgreSQL,
  where information_schema's is_nullable is added to the SELECT.
- Result metadata: mysqli flags, the mysql/cubrid field flags, PDO
  getColumnMeta() not_null (pdo/mysql), sqlsrv's Nullable key.

SQL Server, Firebird, DB2 and Informix table metadata return 1 with
their queries unchanged: changing SQL that cannot be tested here would
risk breaking field_data() for existing callers on those databases.

New DB_field_data_test runs in the six CI database jobs. The user guide
lists which drivers report a real value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Status updated to applied in ed531d3 with the middle-ground scope, which
replaces the earlier mysqli-only decision. Records three pre-existing
driver defects found while implementing (pdo_oci default, pdo_ibm
primary_key, pdo_informix sysdefaults join).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"$reports = (A) OR (B)" assigns A alone, as = binds tighter than OR, so
pdo/mysql was expected to report the default 1 and failed on the real
0 it correctly returns. Parenthesise the whole condition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NielBuys added a commit that referenced this pull request Oct 6, 2026
- CI_VERSION 3.1.13-dev -> 3.1.24; it now follows the release tag
- user guide conf.py version/release and the downloads "Current version"
  link (now the fork's 3.1.24 archive, plus a link to earlier releases)
- changelog: 3.1.24 release date Oct 7, 2026, and a note on CI_VERSION
- SECURITY.md and the 3.4.5 review record the CI_VERSION decision

PRs #21 (bcit-ci#6337) and #22 (bcit-ci#6335) are held for the next release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves the is_nullable changelog entry to the 3.1.25 section (held out
of 3.1.24) and corrects the review doc's dates to 2026-10-06.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant