Skip to content

Extended protocol INSERT/UPDATE/DELETE crashes with 'index out of range [1] with length 1' #2316

@johannesdb

Description

@johannesdb

Description

All INSERT, UPDATE, and DELETE queries with bind parameters ($1, $2, etc.) via the PostgreSQL extended query protocol crash with:

runtime error: index out of range [1] with length 1

SELECT queries with bind parameters work fine. Only write operations are affected.

Reproduction

Using SQLx 0.8 (Rust) with the extended query protocol:

// This crashes DoltgreSQL:
sqlx::query("INSERT INTO users (name, email) VALUES ($1, $2)")
    .bind("Alice")
    .bind("alice@example.com")
    .execute(&pool)
    .await?;

// This also crashes:
sqlx::query("UPDATE users SET name = $1 WHERE id = $2")
    .bind("Bob")
    .bind(some_uuid)
    .execute(&pool)
    .await?;

// But this works fine:
sqlx::query_as::<_, User>("SELECT * FROM users WHERE email = $1")
    .bind("alice@example.com")
    .fetch_optional(&pool)
    .await?;

The same SQL works via psql (simple query protocol).

Server log

Listener recovered panic: runtime error: index out of range [1] with length 1

Related issues

Both were closed but the underlying issue persists for general INSERT/UPDATE/DELETE with bind parameters.

Workaround

We use sqlx::raw_sql() which sends queries via the simple query protocol, with a custom sql_fmt! macro for safe SQL literal formatting (escaping single quotes, formatting UUIDs, etc.). This bypasses the extended protocol entirely.

// Instead of bind parameters, we format safe SQL literals:
let sql = format!(
    "INSERT INTO users (name, email) VALUES ('{}', '{}')",
    name.replace('\'', "''"),
    email.replace('\'', "''")
);
pool.execute(sqlx::raw_sql(&sql)).await?;

This is a significant workaround — we had to convert 50+ queries across 13 database files.

Environment

  • DoltgreSQL: dolthub/doltgresql:latest (Docker) — tested on 0.54.4 through 0.55.0
  • Client: SQLx 0.8 (Rust) via extended query protocol
  • Also reproducible with any PostgreSQL client using prepared statements for write operations

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions