Skip to content

nullability false-negative in PostgreSQL query #4332

Description

@kbongort

I have found these related issues/pull requests

I have searched for existing issues, but none appear to be about this particular bug.

Description

The sqlx::query! macro incorrectly infers a non-nullable value for hash in the following query:

INSERT INTO files (hash)
VALUES ('\xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef'::bytea)
ON CONFLICT (hash) DO NOTHING
RETURNING old.hash

Given the schema:

CREATE TABLE files (
  hash BYTEA CHECK (LENGTH(hash) = 32)

  PRIMARY KEY (hash)
);

In practice (and per the documentation), old.hash is null when there is no conflict. This results in an "unexpected null" error when using the macro with this query.

The output from EXPLAIN (VERBOSE, FORMAT JSON) is:

[
  {
    "Plan": {
      "Node Type": "ModifyTable",
      "Operation": "Insert",
      "Parallel Aware": false,
      "Async Capable": false,
      "Relation Name": "files",
      "Schema": "public",
      "Alias": "files",
      "Startup Cost": 0.00,
      "Total Cost": 0.01,
      "Plan Rows": 1,
      "Plan Width": 64,
      "Disabled": false,
      "Output": ["old.hash"],
      "Conflict Resolution": "NOTHING",
      "Conflict Arbiter Indexes": ["files_pkey"],
      "Plans": [
        {
          "Node Type": "Result",
          "Parent Relationship": "Outer",
          "Parallel Aware": false,
          "Async Capable": false,
          "Startup Cost": 0.00,
          "Total Cost": 0.01,
          "Plan Rows": 1,
          "Plan Width": 64,
          "Disabled": false,
          "Output": ["'\\xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef'::bytea", "NULL::bytea[]"]
        }
      ]
    }
  }
]

Reproduction steps

See above.

SQLx version

0.8.6

Enabled SQLx features

"postgres", "runtime-tokio", "tls-native-tls"

Database server and version

PostgreSQL 18.4

Operating system

Mac OS

Rust version

rustc 1.92.0 (ded5c06cf 2025-12-08)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions