Version / build tested against
origin/main @ 2886155
Deployment mode
Origin — single node (local)
Engine(s) involved
Document (schemaless), Key-Value, Timeseries
Summary
A single multi-row INSERT ... VALUES (...), (...), (...) emits one CommandComplete per row (INSERT 0 1 three times) instead of one INSERT 0 3. Drivers that read the affected-row count get 1 regardless of how many rows were inserted — verified with psycopg2, where cursor.rowcount is 1 after a 3-row insert. ORMs and applications that verify write counts (optimistic-locking checks, batch-load accounting, "exactly N inserted" assertions) see phantom under-counts. Separately, the kv and timeseries engines answer DML with a bare OK command tag instead of INSERT 0 n, which drivers cannot parse for a row count at all.
Steps to reproduce
CREATE COLLECTION multi (id INT PRIMARY KEY, v TEXT);
INSERT INTO multi (id, v) VALUES (1,'a'), (2,'b'), (3,'c');
-- psql prints:
-- INSERT 0 1
-- INSERT 0 1
-- INSERT 0 1 <- three CommandComplete messages for ONE statement; expected one INSERT 0 3
SELECT count(*) FROM multi; -- 3 (all rows did land)
-- kv / timeseries: no row count at all
CREATE COLLECTION kvp (k TEXT PRIMARY KEY, v TEXT) WITH (engine = 'kv');
INSERT INTO kvp (k, v) VALUES ('a', '1');
-- OK <- expected INSERT 0 1
Driver-level confirmation (psycopg2):
cur.execute("INSERT INTO multi (id, v) VALUES (10,'x'), (11,'y'), (12,'z')")
cur.rowcount -> 1 (expected 3)
cur.statusmessage -> 'INSERT 0 1'
Expected behavior
One statement, one CommandComplete: INSERT 0 3 for a 3-row insert, per the PostgreSQL protocol contract. All engines answer DML with the standard INSERT/UPDATE/DELETE tags so drivers can extract the count.
Actual behavior
The simple-query path emits one INSERT 0 1 per value tuple; the extended-query path reports rowcount 1 for any multi-row insert. kv and timeseries DML answers OK, which is not a PostgreSQL command tag.
What actually happened? (check all that are true)
Proposed severity
SEV-3 — Medium: feature wrong, but operational and a workaround exists
Reproducibility
Always — every attempt
Last known-good version / commit (if a regression)
Unknown.
Environment & logs
Linux x86_64, release build from a fresh data directory, trust mode. Tested via psql 16 (simple query) and psycopg2 (extended query).
Before submitting
Version / build tested against
origin/main @ 2886155
Deployment mode
Origin — single node (local)
Engine(s) involved
Document (schemaless), Key-Value, Timeseries
Summary
A single multi-row
INSERT ... VALUES (...), (...), (...)emits oneCommandCompleteper row (INSERT 0 1three times) instead of oneINSERT 0 3. Drivers that read the affected-row count get 1 regardless of how many rows were inserted — verified with psycopg2, wherecursor.rowcountis 1 after a 3-row insert. ORMs and applications that verify write counts (optimistic-locking checks, batch-load accounting, "exactly N inserted" assertions) see phantom under-counts. Separately, the kv and timeseries engines answer DML with a bareOKcommand tag instead ofINSERT 0 n, which drivers cannot parse for a row count at all.Steps to reproduce
Driver-level confirmation (psycopg2):
Expected behavior
One statement, one
CommandComplete:INSERT 0 3for a 3-row insert, per the PostgreSQL protocol contract. All engines answer DML with the standardINSERT/UPDATE/DELETEtags so drivers can extract the count.Actual behavior
The simple-query path emits one
INSERT 0 1per value tuple; the extended-query path reports rowcount 1 for any multi-row insert. kv and timeseries DML answersOK, which is not a PostgreSQL command tag.What actually happened? (check all that are true)
Proposed severity
SEV-3 — Medium: feature wrong, but operational and a workaround exists
Reproducibility
Always — every attempt
Last known-good version / commit (if a regression)
Unknown.
Environment & logs
Linux x86_64, release build from a fresh data directory, trust mode. Tested via psql 16 (simple query) and psycopg2 (extended query).
Before submitting
mainbuild (not a stale local branch).