Skip to content

[YSQL] Include DETAIL in duplicate key unique violation error for PG compatibility#31031

Open
jaydeep-pipaliya wants to merge 3 commits intoyugabyte:masterfrom
jaydeep-pipaliya:fix/unique-violation-detail-message
Open

[YSQL] Include DETAIL in duplicate key unique violation error for PG compatibility#31031
jaydeep-pipaliya wants to merge 3 commits intoyugabyte:masterfrom
jaydeep-pipaliya:fix/unique-violation-detail-message

Conversation

@jaydeep-pipaliya
Copy link
Copy Markdown

@jaydeep-pipaliya jaydeep-pipaliya commented Apr 9, 2026

Problem

Fixes #30992

PostgreSQL emits a DETAIL line for unique constraint violations:

ERROR:  duplicate key value violates unique constraint "err_pkey"
DETAIL: Key (k)=(1) already exists.

YugabyteDB only emits the ERROR line without DETAIL:

ERROR:  duplicate key value violates unique constraint "err_pkey"

This breaks PostgreSQL compatibility for applications and ORMs that parse error details to extract the conflicting key info (e.g., Prisma, SQLAlchemy, ActiveRecord).

Root Cause

In src/postgres/src/backend/utils/misc/pg_yb_utils.c, GetStatusMsgAndArgumentsByCode handles ERRCODE_UNIQUE_VIOLATION at line 960–965 by setting the error message and constraint name, but never populates detail_buf — so the DETAIL field is always empty.

Other error codes in the same switch statement (e.g., ERRCODE_YB_TXN_ABORTED at line 966, ERRCODE_YB_TXN_CONFLICT at line 975) already follow the pattern of passing the DocDB status message as the DETAIL field.

Fix

Pass the DocDB status message (status_msg) as detail_buf for ERRCODE_UNIQUE_VIOLATION, following the same pattern already established by other error codes in the same function:

case ERRCODE_UNIQUE_VIOLATION:
    *msg_buf = "duplicate key value violates unique constraint \"%s\"";
    *msg_nargs = 1;
    *msg_args = (const char **) palloc(sizeof(const char *));
    (*msg_args)[0] = FetchUniqueConstraintName(YBCStatusRelationOid(s));

    if (status_msg && status_msg[0] != '\0')
    {
        *detail_buf = status_msg;
        *detail_nargs = status_nargs;
        *detail_args = status_args;
    }
    break;

Testing

This change only affects the error output formatting — it adds the DETAIL line to unique violation errors without changing any error handling logic or control flow. The guard status_msg[0] != '\0' ensures we only add DETAIL when DocDB provides a non-empty message.


Phorge: D52066

PostgreSQL emits a DETAIL line for unique constraint violations:
  ERROR:  duplicate key value violates unique constraint "err_pkey"
  DETAIL: Key (k)=(1) already exists.

YugabyteDB was missing this DETAIL line because the ERRCODE_UNIQUE_VIOLATION
case in GetStatusMsgAndArgumentsByCode only set the error message but never
populated detail_buf.

Pass the DocDB status message as the DETAIL field, following the same
pattern already used by ERRCODE_YB_TXN_ABORTED and ERRCODE_YB_TXN_CONFLICT.

Fixes yugabyte#30992
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 9, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request modifies pg_yb_utils.c to improve PostgreSQL compatibility for unique violation error messages. It now includes the original DocDB status message as a DETAIL field when handling ERRCODE_YB_UNIQUE_VIOLATION, aligning with PostgreSQL's practice of providing detailed key information for unique constraint errors. There is no feedback to provide.

If the DocDB status message contains % characters (e.g., from column
names like 'discount%'), passing it directly as a format string could
cause a crash or memory corruption. Use '%s' as the format string and
pass status_msg as the sole argument instead.
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 11, 2026

Deploy Preview for infallible-bardeen-164bc9 ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 5ca956c
🔍 Latest deploy log https://app.netlify.com/projects/infallible-bardeen-164bc9/deploys/69d9d4ad3d45de0008551fa6
😎 Deploy Preview https://deploy-preview-31031--infallible-bardeen-164bc9.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@iSignal
Copy link
Copy Markdown
Contributor

iSignal commented Apr 15, 2026

trigger jenkins

@hari90
Copy link
Copy Markdown
Contributor

hari90 commented Apr 15, 2026

Phorge diff synced: D52066
Commit: 5ca956c6

Jenkins build has been triggered. Results will be posted here once it completes.


JenkinsBot

@hari90
Copy link
Copy Markdown
Contributor

hari90 commented Apr 15, 2026

Jenkins build for commit 5ca956c6: Fail

Exceptions:


🚫 Failed Landing Requirements

Checking for failures in 3+ build flavors
Multi-Build failures:

Checking test failure count per build versus limit of 20 (0 on mac).

Build Failures Status
D52066-mac14-clang-release #1 0 Okay
D52066-alma9-clang21-asan #1 42 FAILURE
D52066-alma8-clang21-tsan #1 31 FAILURE
D52066-alma8-gcc12-fastdebug #1 41 FAILURE
D52066-alma8-clang21-release #1 39 FAILURE
D52066-arm-mac14-clang-release #1 0 Okay
D52066-ubuntu22.04-clang21-debug #1 0 Okay
D52066-arm-alma8-clang21-release #1 41 FAILURE

🔨 DB Build/Test Job Summary

Build Total Passed Failed Failed After Retries
D52066-mac14-clang-release 2 2 0 0
D52066-alma9-clang21-asan 11782 11006 47 42
D52066-alma8-clang21-tsan 11694 10027 40 31
D52066-alma8-gcc12-fastdebug 11905 11403 44 41
D52066-alma8-clang21-release 11166 10703 44 39
D52066-arm-mac14-clang-release 17 17 0 0
D52066-ubuntu22.04-clang21-debug 2 2 0 0
D52066-arm-alma8-clang21-release 11164 10697 45 41

Full status


JenkinsBot

…e, not key info

The status_msg passed to GetStatusMsgAndArgumentsByCode for
ERRCODE_UNIQUE_VIOLATION is the SQLSTATE code string '23505', not
a human-readable error detail. This is because pg_perform_future.cc
replaces the original DocDB response (which contains 'Duplicate key
found in primary key or unique index') with a synthetic Status built
from PgsqlError(YB_PG_UNIQUE_VIOLATION), whose Message() is just
the SQLSTATE encoding.

Using this as DETAIL produced 'DETAIL: 23505' in error output, which
broke 30+ pgregress test suites that assert on exact error messages.

Remove the DETAIL addition. Generating the proper PostgreSQL-style
DETAIL ('Key (col)=(val) already exists.') requires DocDB to propagate
the conflicting key information through the error path.
@jaydeep-pipaliya
Copy link
Copy Markdown
Author

Root cause of CI failure

I traced the error path end-to-end and found that status_msg for ERRCODE_UNIQUE_VIOLATION is not a human-readable error detail — it's the SQLSTATE code "23505".

Why: In pg_perform_future.cc, when a PGSQL_STATUS_DUPLICATE_KEY_ERROR response comes back from DocDB, the original status (which contains the actual message "Duplicate key found in primary key or unique index") is replaced with a synthetic Status:

static const auto duplicate_key_status =
    STATUS(AlreadyPresent, PgsqlError(YBPgErrorCode::YB_PG_UNIQUE_VIOLATION));

This Status is constructed via Status(code, file, line, StatusErrorCode& error) which calls error.Message()PgsqlErrorTag::ToMessage(value)ToString(YBPgErrorCode), which returns the 5-char SQLSTATE encoding "23505".

So my previous DETAIL addition was producing DETAIL: 23505 — which is why 30+ pgregress test suites failed.

Fix: Removed the DETAIL addition. Added a comment explaining why DETAIL can't be added via this path and that it would require DocDB to propagate conflicting key information. The constraint name in the ERROR message (from FetchUniqueConstraintName) is still included — that part works correctly.

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.

[YSQL] [PG Compatibility] Conflict message dissimilarity

4 participants