Skip to content

sql: incorrect "violates not-null constraint" error when UPSERTing a subset of columns #133146

Closed
@mgartner

Description

When an UPSERT updates a subset of columns of an existing row, the values of non-updated columns are maintained. However, there is a bug were NOT NULL constraints are checked against the default column values, rather than the existing values. This causes UPSERT statements to incorrectly error with constraint violation errors. For example:

CREATE TABLE t (  
  id INT PRIMARY KEY DEFAULT unique_rowid(),  
  a INT NOT NULL,
  b INT
);  

INSERT INTO t (id, a, b) VALUES (1, 1, 1);  
-- INSERT 0 1

-- This should succeed. This UPSERT results in an update to the existing row,
-- and the existing value of "a" should be maintained. Therefore, the new row
-- does not violate the uniqueness check.
UPSERT INTO t (id, b) VALUES (1, 2);  
-- ERROR: null value in column "a" violates not-null constraint
-- SQLSTATE: 23502

This bug does not affect check constraints:

CREATE TABLE t (  
  id INT PRIMARY KEY DEFAULT unique_rowid(),  
  a INT DEFAULT -1 CHECK (a > 0),
  b INT
);  

INSERT INTO t (id, a, b) VALUES (1, 1, 1);  
-- INSERT 0 1

-- This succeeds as expected.
UPSERT INTO t (id, b) VALUES (1, 2);  
-- INSERT 0 1

SELECT * FROM t;

-- This fails as expected.
UPSERT INTO t (id, b) VALUES (2, 3);  
-- ERROR: failed to satisfy CHECK constraint (a > 0:::INT8)
-- SQLSTATE: 23514

This bug has existed since v20.1.0 or before.

Jira issue: CRDB-43475

Metadata

Assignees

Labels

C-bugCode not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior.P-2Issues/test failures with a fix SLA of 3 monthsS-2Medium-high impact: many users impacted, risks of availability and difficult-to-fix data errorsT-sql-queriesSQL Queries Teambranch-release-20.1Used to mark GA and release blockers, technical advisories, and bugs for 20.1branch-release-20.2Used to mark GA and release blockers, technical advisories, and bugs for 20.2branch-release-21.1Used to mark GA and release blockers, technical advisories, and bugs for 21.1branch-release-21.2Used to mark GA and release blockers, technical advisories, and bugs for 21.2branch-release-22.1Used to mark GA and release blockers, technical advisories, and bugs for 22.1branch-release-22.2Used to mark GA and release blockers, technical advisories, and bugs for 22.2branch-release-23.1Used to mark GA and release blockers, technical advisories, and bugs for 23.1branch-release-23.2Used to mark GA and release blockers, technical advisories, and bugs for 23.2branch-release-24.1Used to mark GA and release blockers, technical advisories, and bugs for 24.1branch-release-24.2Used to mark GA and release blockers, technical advisories, and bugs for 24.2branch-release-24.3Used to mark GA and release blockers, technical advisories, and bugs for 24.3

Type

No type

Projects

  • Status

    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions