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 NULL
s 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 NULL
s, why would you think you know better, override the server’s decision and check for NULL
s 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 null
Default values are normally not applied when adding fields to existing rows, but with
NOT NULL
fields 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-n
switch 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
gbak
to restoreNOT NULL
constraints even if you specify-n
.With those versions, if you have backed up a database withNULL
data inNOT NULL
fields, you’re completely stuck.Solution: install 1.5.1 or higher, restore with gbak-n
and fix your data.