I have a table with a SERIAL primary key, and also an ltree column, whose value I want to be the concatenation of those primary keys. e.g.
id | path
----------
1 1
2 1.2
3 1.2.3
4 1.4
5 1.5
I’m curious if there’s a way to do such an insert in one query, e.g.
INSERT INTO foo (id, ltree) VALUES (DEFAULT, THIS.id::text)
I’m probably overreaching here and trying to do in one query what I should be doing in two (grouped in a transaction).
You could use a CTE to retrieve the value from the sequence once and use it repeatedly:
The CTE with a data-modifying command requires Postgres 9.1 or later.
If you are not sure about the name of the sequence, use
pg_get_serial_sequence()instead:If the table name “foo” might not be unique across all schemas in the DB, schema-qualify it. And if the spelling of any name is non-standard, you have to double-quote:
Quick tests indicated @Mark’s idea with
lastval()might work too:You can just leave
idout of the query, theserialcolumn will be assigned automatically. Makes no difference.There shouldn’t be a race condition between rows. I quote the manual:
Bold emphasis mine.
But, as @Bernard commented, it can fail after all: there is no guarantee that the default value is filled (and
nextval()called in the process) beforelastval()is called to fill the 2nd columnltree. So stick with the first solution andnextval()to be sure.