Skip to content

fix: PostgreSQL insert_row fails for tables with text primary keys#22

Merged
mikkeldamsgaard merged 1 commit intomainfrom
fix/postgres-text-pk
Feb 25, 2026
Merged

fix: PostgreSQL insert_row fails for tables with text primary keys#22
mikkeldamsgaard merged 1 commit intomainfrom
fix/postgres-text-pk

Conversation

@mikkeldamsgaard
Copy link
Contributor

The insert_row function always used RETURNING COALESCE(CAST("id" AS BIGINT), 0) even when no auto_id_column was specified, defaulting to the "id" column. For tables with text primary keys (like NetBird's accounts, users, groups), CAST to BIGINT fails with a generic "db error".
Fix: Only use RETURNING clause when auto_id_column is explicitly set. When no auto_id is needed, use a simple INSERT without RETURNING.

The insert_row function always used RETURNING COALESCE(CAST(id AS BIGINT), 0)
even when no auto_id_column was specified, defaulting to the id column.
For tables with text primary keys (like NetBird's accounts, users, groups),
CAST to BIGINT fails with a generic db error.
Fix: Only use RETURNING clause when auto_id_column is explicitly set.
When no auto_id is needed, use a simple INSERT without RETURNING.
Copilot AI review requested due to automatic review settings February 25, 2026 11:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes PostgreSQL seeding failures when inserting into tables that have non-numeric (e.g., text) primary keys by avoiding a RETURNING ... CAST(... AS BIGINT) clause unless an auto_id_column is explicitly configured.

Changes:

  • Update PostgresDb::insert_row to only include a RETURNING clause when auto_id_column is Some(...).
  • Use a plain INSERT (no RETURNING) when no auto-generated numeric ID is required, returning Ok(None).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +323 to +349
if let Some(auto_col) = auto_id_column {
let returning_col = sanitize_identifier(auto_col);
let sql = format!(
"INSERT INTO \"{}\" ({}) VALUES ({}) RETURNING COALESCE(CAST(\"{}\" AS BIGINT), 0)",
sanitize_identifier(table),
col_list.join(", "),
value_list.join(", "),
returning_col
);
let row = self
.client
.query_one(&sql, &[])
.map_err(|e| format!("inserting row into '{}': {}", table, e))?;
let id: i64 = row.get(0);
Ok(Some(id))
} else {
let sql = format!(
"INSERT INTO \"{}\" ({}) VALUES ({})",
sanitize_identifier(table),
col_list.join(", "),
value_list.join(", "),
);
self.client
.execute(&sql, &[])
.map_err(|e| format!("inserting row into '{}': {}", table, e))?;
Ok(None)
}
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Postgres insert_row behavior (skipping RETURNING when auto_id_column is None) fixes the reported bug, but it isn’t covered by tests. There are existing Postgres seeding integration tests, but none exercise inserting into a table with a non-numeric primary key and no auto_id config; adding an integration test/fixture for that case would prevent regressions.

Copilot uses AI. Check for mistakes.
@mikkeldamsgaard mikkeldamsgaard merged commit ee3fd56 into main Feb 25, 2026
9 checks passed
@mikkeldamsgaard mikkeldamsgaard deleted the fix/postgres-text-pk branch February 25, 2026 11:54
mikkeldamsgaard added a commit that referenced this pull request Feb 25, 2026
The insert_row function always used RETURNING COALESCE(CAST(id AS BIGINT), 0)
even when no auto_id_column was specified, defaulting to the id column.
For tables with text primary keys (like NetBird's accounts, users, groups),
CAST to BIGINT fails with a generic db error.
Fix: Only use RETURNING clause when auto_id_column is explicitly set.
When no auto_id is needed, use a simple INSERT without RETURNING.
mikkeldamsgaard added a commit that referenced this pull request Feb 25, 2026
* feat: add integration tests with docker-compose (#7) - wait-for, render, fetch, exec, seed PostgreSQL/MySQL with cross-table refs, idempotency, reset, create database/schema, create-if-missing tests

* fix: use inline escaped values in postgres insert_row/row_exists to fix TEXT-to-INTEGER coercion

* fix: reverse seed set order during reset to respect foreign key constraints

* fix: separate reset (reverse) and seed (forward) passes for FK-safe reset mode

* refactor: remove placeholder seed_sets from test specs and move inline seed specs to files

* Update .github/workflows/integration.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: PostgreSQL insert_row fails for tables with text primary keys (#22)

The insert_row function always used RETURNING COALESCE(CAST(id AS BIGINT), 0)
even when no auto_id_column was specified, defaulting to the id column.
For tables with text primary keys (like NetBird's accounts, users, groups),
CAST to BIGINT fails with a generic db error.
Fix: Only use RETURNING clause when auto_id_column is explicitly set.
When no auto_id is needed, use a simple INSERT without RETURNING.

* fix: address PR #21 review comments - remove unused CI client install, add cfg feature guards, fix README test name, document escaped literals rationale, reword CHANGELOG

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants