Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YSQL] Single row update overwrites unmodified columns with default values to null #4127

Closed
ndeodhar opened this issue Mar 31, 2020 · 1 comment
Assignees
Labels
area/ysql Yugabyte SQL (YSQL) priority/high High Priority

Comments

@ndeodhar
Copy link
Contributor

ndeodhar commented Mar 31, 2020

If we have a single row UPDATE statement that only writes few columns, we end up overwriting other columns to NULL.
This also ends up breaking constraints like not null which may be set on those columns.

CREATE TABLE sbtest1 (
    id int primary key, 
    k int not null default 0,
    c text default '',
    pad text default '');

yugabyte=# insert into sbtest1 values(1000001, 10, 'foo','bar');
INSERT 0 1
yugabyte=# select * from sbtest1 where id=1000001;
   id    | k  |                                                            c                                                             |                             pad                              
---------+----+--------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------
 1000001 | 10 | foo                                                                                                                      | bar                                                         
(1 row)

yugabyte=# update sbtest1 set c='hello' where id=1000001;
UPDATE 1
yugabyte=# select * from sbtest1 where id=1000001;
   id    | k |                                                            c                                                             | pad 
---------+---+--------------------------------------------------------------------------------------------------------------------------+-----
 1000001 |   | hello                                                                                                                    | 
(1 row)

This does not happen while updating multiple rows:

yugabyte=# insert into sbtest1 values(1000002, 10, 'foo','bar'),(1000003, 10, 'foo','bar');
INSERT 0 2
yugabyte=# update sbtest1 set c='hello' where id in (1000002,1000003);
UPDATE 2
yugabyte=# select * from sbtest1 where id in(1000002,1000003);
   id    | k  |                                                            c                                                             |                             pad                              
---------+----+--------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------
 1000002 | 10 | hello                                                                                                                    | bar                                                         
 1000003 | 10 | hello                                                                                                                    | bar                                                         
(2 rows)

Update:
This happens for columns with default values but not for columns without any default values.

yugabyte=# create table foo(a int primary key, b int default 0, c int default 0, d int);                                                                                  CREATE TABLE
yugabyte=# insert into foo values(1,1,1,1);
INSERT 0 1
yugabyte=# update foo set b=10 where a=1;
UPDATE 1
yugabyte=# select * from foo;
 a | b  | c | d 
---+----+---+---
 1 | 10 |   | 1
(1 row)
@ndeodhar ndeodhar added area/ysql Yugabyte SQL (YSQL) priority/high High Priority labels Mar 31, 2020
@ndeodhar ndeodhar self-assigned this Mar 31, 2020
@ndeodhar ndeodhar changed the title [YSQL] Single row update of few columns overwrites other columns to null [YSQL] Update of few columns overwrites other columns to null Mar 31, 2020
@ndeodhar ndeodhar changed the title [YSQL] Update of few columns overwrites other columns to null [YSQL] Single row update of few columns overwrites other columns to null Mar 31, 2020
@m-iancu m-iancu changed the title [YSQL] Single row update of few columns overwrites other columns to null [YSQL] Single row update overwrites unmodified columns with default values to null Apr 1, 2020
m-iancu added a commit that referenced this issue Apr 3, 2020
…alues to null #4127

Summary:
Fix a regression for single-row updates and columns with default values
introduced commit 7e222b4.

Default values for columns need to be handled for INSERTs (i.e. to be used
in case there is no user-provided value).
However, UPDATEs should not modify columns that were explicitly set,
regardless of whether a default is set for that column.
Therefore, there is no need to distinguish columns with default for the
UPDATE case, so revert the change that did that.
Instead, we need to distinguish between single-row and non-single-row
execution for update, because non-single-row execution can have triggers
modifying columns values (set or defaults).

Test Plan: TestPgRegressDml (yb_dml_single_row), existing TestPgRegressBetaFeatures (yb_pg_triggers).

Reviewers: neha, sudheer

Reviewed By: neha

Subscribers: yql

Differential Revision: https://phabricator.dev.yugabyte.com/D8225
@m-iancu
Copy link
Contributor

m-iancu commented Apr 3, 2020

Fixed by d9a860f.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ysql Yugabyte SQL (YSQL) priority/high High Priority
Projects
None yet
Development

No branches or pull requests

2 participants