Changes for version 0.900004 - 2026-11-08
- Storage
- The text of an error names the type, the column, the constraint and the table, never a value: the key of a PRIMARY KEY, UNIQUE or FOREIGN KEY violation (Problematic key value is ("A" = ***, "B" = ***)) and the string of a conversion error are masked, also for short bound values and a value holding quotes, commas or line breaks; the refusals for a boolean or numeric column name the column only. $dbh->errstr stays raw.
- Three transports: DBD::Firebird (DBIO::Firebird::Storage), DBD::InterBase (Storage::InterBase) and DBD::ODBC (DBIO::Firebird::Storage::ODBC, ADR 0010); the ODBC storage is declared as storage_type and untested against a Firebird ODBC driver.
- SQL dialect 3 is forced on connect, also on a connection an AccessBroker opens. Another ib_dialect in the DSN or as an attribute is refused, naming the place, never the DSN or a password.
- Dates and timestamps are read in the ISO formats by default (ib_time_all 'ISO' on every native connection, not on Storage::ODBC).
- Text is UTF8 on every native connection: ib_charset=UTF8 and ib_enable_utf8 => 1 are added, also to every AccessBroker answer, unless the connect info names its own. Text comes back as characters and unflagged strings are flagged when bound.
- ib_ attributes from an AccessBroker connect over dbi:Firebird: (not on Storage::ODBC). A HostBound view (Replicated) is bound into the DSN as db=host[/port]:path, host= / hostname= with port=, or a local database name; any other form is refused naming the form.
- Reading and writing keeps working after DDL and after a rolled back transaction with statement caching on; a statement handle the DBD destroyed is prepared anew (ADR 0011).
- A commit or DDL statement the server refuses dies with the server's error (a DBIO::Exception::Server) on the same connection, and is not repeated after a reconnect.
- A BOOLEAN value is checked on both the single and the bulk path: 1, 0 and undef pass, 'true' and 'false' (any case) are translated, '' is FALSE, anything else dies naming the column. Not on the ODBC storage.
- A text or binary BLOB column can be searched by value; a value too long to compare on Firebird is refused before the DBD, naming table and column. The placeholders are found by core's scanner, so a ? in a literal, quoted name or comment is left alone.
- A value that is no number is refused for a numeric column instead of being stored as 0. Not on Storage::ODBC.
- Boolean, numeric and UTF8 adjustments of bound values run through core's _adjust_bind_values and leave the caller's bind list alone.
- $rs->rand orders by RAND(), $rs->explain returns the plan without running the statement (refused over ODBC), and $rs->results_exist works. $rs->except, except_all, intersect and intersect_all are refused: Firebird has only UNION (ADR 0039).
- transactional_ddl is declared 0: a whole deploy batch is not bracketed (see "Transactional DDL -- not claimed" in DBIO::Firebird::Deploy).
- DDL
- install_ddl writes declared sizes (varchar, char, numeric, decimal) and Firebird's type names: TIMESTAMP, BIGINT, SMALLINT, DOUBLE PRECISION, BOOLEAN, and BLOB SUB_TYPE TEXT for an unsized string and mediumtext/longtext.
- Every identifier is double-quoted, as the storage quotes it, so the installed table is the table the ORM queries. A column without is_nullable is NOT NULL.
- boolean is a BOOLEAN column (Firebird 3 is the minimum) with DEFAULT TRUE / FALSE from 0, 1, 'true' or 'false'. is_auto_increment is GENERATED BY DEFAULT AS IDENTITY; an identity with a default or on a non-integer type dies.
- Foreign keys and unique constraints are written after all CREATE TABLE statements, so table order and cycles do not matter; on_delete and on_update come from the belongs_to or from the has_many's cascade_delete and cascade_copy; is_deferrable is refused.
- The canonical index declaration (idx, indices; core ADR 0061) creates plain or unique indexes and refuses expression, partial and descending ones. An index the primary key, a unique constraint or a foreign key already provides is not built twice.
- A string default with an apostrophe is quoted correctly.
- Refused with a DBIO::Exception naming table and column: bit, enum, time zone types, binary and varbinary below Firebird 4, NUMERIC/DECIMAL above 18 digits (DBD::Firebird cannot bind or read an INT128), and a table or view name with a dot.
- Diff
- Foreign keys, unique constraints and primary keys are part of the diff (DBIO::Firebird::Diff::Constraint): new tables get them after every CREATE TABLE, existing tables get DROP CONSTRAINT / ADD CONSTRAINT, compared by what they say, not by name. The order lets an index or key on a dropped column go first, and DROP TABLE runs child before parent.
- Views are created, replaced and dropped from rdb$view_source; a changed definition is dropped before the table changes and created again after. A name that is a table on one side and a view on the other is refused.
- A column change the server always refuses (narrowing CHAR, character to non-character, no conversion, fewer digits, a type change of a key column) is refused before the first statement. Adding or removing IDENTITY on an existing column is refused.
- A name that differs from the schema's only in letter case is refused, naming every pair, instead of DROP + CREATE (see "NAMES THAT DIFFER ONLY IN CASE" in DBIO::Firebird::Diff).
- A default the declaration no longer has is dropped; the column size is carried on ADD and ALTER ... TYPE.
- Deploy
- DBIO::Firebird::Deploy inherits apply and upgrade from DBIO::Deploy::Base (ADR 0013): a diff that drops something or changes a column lossily runs with allow_destructive => 1 and stops before its first statement without it; dry_run returns the diff and executes nothing. Widening pairs (smallint to integer, date to timestamp, char to varchar, a larger size) are not lossy.
- apply also refuses, naming table and column, a NOT NULL column without a default added to a table that holds rows and a column that becomes NOT NULL over a NULL.
- diff, upgrade and install work on a schema connected through an AccessBroker (a coderef or dbh_maker answer is refused). The temporary database is created on the server also when the DSN spells host and path as attributes; its errors do not quote the password.
- Introspect
- The model reads columns, indexes, unique constraints, foreign keys and primary key names from the rdb$ tables (see "THE INTROSPECTED MODEL" in DBIO::Firebird::Introspect); field types follow the server, including NUMERIC/DECIMAL, boolean, int128, decfloat and time zone types.
- A foreign key names its constraint under constraint_name (core ADR 0021); is_auto_increment is read from rdb$identity_type.
- Dependencies
- Requires DBIO 0.900004 and DBD::Firebird; DateTime::Format::Strptime is recommended.
- Tests and documentation
- DBIO::Firebird::Test::Conformance answers core's DDL, Diff and Bind case tables (ADR 0012), including conformance_upgrade and the deploy cases.
- README states where the driver stands for async use.
Documentation
Modules
Firebird-specific schema management for DBIO
Generate Firebird DDL from DBIO Result classes
DateTime formatter for Firebird / InterBase
Deploy and upgrade Firebird schemas via test-deploy-and-compare
Compare two introspected Firebird models
Diff operations for Firebird columns
Diff operations for Firebird primary keys, foreign keys and unique constraints
Diff operations for Firebird indexes
Diff operations for Firebird tables
Diff operations for Firebird views
Introspect a Firebird database via rdb$ system tables
Introspect Firebird columns via rdb$fields / rdb$relation_fields
Introspect Firebird foreign keys via rdb$relation_constraints
Introspect Firebird indexes via rdb$indices / rdb$index_segments
Introspect Firebird tables and views via rdb$relations
Introspect Firebird UNIQUE constraints via rdb$relation_constraints
Firebird-specific SQL generation for DBIO
Driver for the Firebird RDBMS via DBD::Firebird
Shared Firebird / InterBase storage logic
Driver for the Firebird RDBMS via DBD::InterBase
Driver for the Firebird RDBMS via DBD::ODBC
Answers the shared conformance case table for the Firebird driver
Test result class for Firebird sequence/generator tests
Firebird type-system mapping (introspection + DDL directions)
Shared Firebird-specific helper functions for DBIO
`use DBIO -fb` shortcut for the Firebird driver