10

Is there a way to add a not null constraint to a column and replace all existing null values with a default in one statement?

alter table t
alter column c set default 0,
alter column c set not null;

Doesn't seem to work, gives an error:

column "c" contains null values
2
  • What's wrong with multiple statements? Commented Feb 5, 2022 at 2:19
  • Environment specific issue where there are only permissions to modify the schema, not the data. Commented Feb 5, 2022 at 2:20

2 Answers 2

12

Actually, yes. Pretty simple, too:

ALTER TABLE t
  ALTER COLUMN c TYPE int USING (COALESCE(c, 0))
, ALTER COLUMN c SET DEFAULT 0
, ALTER COLUMN c SET NOT NULL;

db<>fiddle here

You just have to think around a corner. We change the type from int to int, so no actual change. But it allows us to slip in the USING clause that does the magic.

Sign up to request clarification or add additional context in comments.

2 Comments

And it's even faster than using a separate UPDATE statement. Just measured USING approach is 6 times faster than UPDATE+ALTER on 8M rows (no index on changed field)
⚠️This approach locks the whole table until it finished. If you can, better use slower UPDATE, but without a lock.
1

You can do:

alter table t
alter column a type int using coalesce(a, 567),
alter column a set not null;

See running example at DB Fiddle.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.