What the…
...is going on here?
When a client application like isql queries the server, the conversation passes through several stages.During one of them — the “describe” phase — the engine reports type and nullability for each column that will appear in the result set.It does this in a data structure which is later also used to retrieve the actual row data.For columns flagged as NOT NULL by the server, there is no way to return NULLs to the client — unless the client flips back the flag before entering the data retrieval stage.Most client applications don’t do this.After all, if the server assures you that a column can’t contain NULLs, why would you think you know better, override the server’s decision and check for NULLs anyway?And yet that’s exactly what you should do if you want to avoid the risk of reporting false values to your users.
Ensuring the validity of your data
Here’s what you should do to make sure that your data are valid when adding a NOT NULL column to a populated table:
-
To prevent the nulls-in-not-null-columns problem from occurring at all, provide a default value when you add the new column:
alter table Adventures add id int default -1 not nullDefault values are normally not applied when adding fields to existing rows, but with
NOT NULLfields they are. -
Else, explicitly set the new fields to the value(s) they should have, right after adding the column.Verify that they are all valid with a “
SELECT … WHERE … IS NULL” query, which should return an empty set. -
If the damage has already been done and you find yourself with an unrestorable backup, use
gbak's-nswitch to ignore validity constraints when restoring.Then fix the data and reinstate the constraints manually.Again, verify with a “WHERE … IS NULL” query.ImportantFirebird versions up to and including 1.5.0 have an additional bug that causes
gbakto restoreNOT NULLconstraints even if you specify-n.With those versions, if you have backed up a database withNULLdata inNOT NULLfields, you’re completely stuck.Solution: install 1.5.1 or higher, restore with gbak-nand fix your data.