PostgreSQL 10 Identity Column gets "null value" when inserting multiple rows with default keyword
This is in fact a bug. I verified it. I went to go see if it was filed and it seems it already is. It's not just filed, the commit is there.
You can see their test, exactly like yours
+-- VALUES RTEs
+INSERT INTO itest3 VALUES (DEFAULT, 'a');
+INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c');
+SELECT * FROM itest3;
So just wait, it's there for PostgreSQL 10.2.
Possible work around for PostgreSQL < 10.2
If you absolutely must have this, and using the implicit column isn't acceptable. One easy solution would be to retrieve the sequence with the catalog info function
pg_get_serial_sequence(table_name, column_name)
Which I believe should work, and to set that as a default.
ALTER TABLE ONLY test
ALTER COLUMN id
DEFAULT nextval('seqname');
It's a bug as @Evan discovered, so until it is fixed we have to work around it.
As you probably know, it's easy to work around the case for multiple column inserts where not all values are default
— just omit the column(s) where you want the default
value inserted entirely, default
is the default:
INSERT INTO test (t) VALUES ('b'), ('c');
SELECT * FROM test;
id | t -: | :- 1 | b 2 | c
dbfiddle here
If there are multiple columns and you want them all to be default, you can still use a CTE:
WITH w AS (INSERT INTO test (t) VALUES (DEFAULT) RETURNING t ) INSERT INTO test (t) SELECT w.t FROM w CROSS JOIN generate_series(1, 1);
SELECT * FROM test;
id | t -: | :-- 1 | foo 2 | foo
dbfiddle here
Unfortunately, there is no easy workaround if you need all columns to be populated with default
:
For the case when there is only one column and it's a serial, I see no way to use the default.